diff --git a/README.markdown b/README.markdown index 23dec0ee..853a37ee 100644 --- a/README.markdown +++ b/README.markdown @@ -100,10 +100,10 @@ permissions like so: ```php new UserClass("anonymous", "base", [ - "create_comment" => True, - "edit_image_tag" => True, - "edit_image_source" => True, - "create_image_report" => True, + Permissions::CREATE_COMMENT => True, + Permissions::EDIT_IMAGE_TAG => True, + Permissions::EDIT_IMAGE_SOURCE => True, + Permissions::CREATE_IMAGE_REPORT => True, ]); ``` @@ -111,12 +111,12 @@ For a moderator class, being a regular user who can delete images and comments: ```php new UserClass("moderator", "user", [ - "delete_image" => True, - "delete_comment" => True, + Permissions::DELETE_IMAGE => True, + Permissions::DELETE_COMMENT => True, ]); ``` -For a list of permissions, see `core/userclass.php` +For a list of permissions, see `core/permissions.php` # Development Info diff --git a/core/_bootstrap.php b/core/_bootstrap.php index 6dffbf14..a003ed6e 100644 --- a/core/_bootstrap.php +++ b/core/_bootstrap.php @@ -15,6 +15,11 @@ require_once "vendor/autoload.php"; _version_check(); _sanitise_environment(); +// The trace system has a certain amount of memory consumption every time it is used, +// so to prevent running out of memory during complex operations code that uses it should +// check if tracer output is enabled before making use of it. +$tracer_enabled = constant('TRACE_FILE')!==null; + // load base files $_tracer->begin("Bootstrap"); $_tracer->begin("Opening files"); diff --git a/core/database.php b/core/database.php index 003816d4..2cbf077f 100644 --- a/core/database.php +++ b/core/database.php @@ -190,10 +190,12 @@ class Database private function count_time(string $method, float $start, string $query, ?array $args): void { - global $_tracer; + global $_tracer, $tracer_enabled; $dur = microtime(true) - $start; - $query = trim(preg_replace('/^[\t ]+/m', '', $query)); // trim leading whitespace - $_tracer->complete($start * 1000000, $dur * 1000000, "DB Query", ["query"=>$query, "args"=>$args, "method"=>$method]); + if($tracer_enabled) { + $query = trim(preg_replace('/^[\t ]+/m', '', $query)); // trim leading whitespace + $_tracer->complete($start * 1000000, $dur * 1000000, "DB Query", ["query"=>$query, "args"=>$args, "method"=>$method]); + } $this->query_count++; $this->dbtime += $dur; } diff --git a/core/event.php b/core/event.php index 349a6ce0..c9064c3e 100644 --- a/core/event.php +++ b/core/event.php @@ -60,7 +60,7 @@ class PageRequestEvent extends Event // if path is not specified, use the default front page if (empty($path)) { /* empty is faster than strlen */ - $path = $config->get_string('front_page'); + $path = $config->get_string(SetupConfig::FRONT_PAGE); } // break the path into parts diff --git a/core/imageboard/image.php b/core/imageboard/image.php index 90ab9e6a..598a2ab7 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -129,7 +129,7 @@ class Image } if (SPEED_HAX) { - if (!$user->can("big_search") and count($tags) > 3) { + if (!$user->can(Permissions::BIG_SEARCH) and count($tags) > 3) { throw new SCoreException("Anonymous users may only search for up to 3 tags at a time"); } } @@ -813,7 +813,7 @@ class Image $tmpl = str_replace('$size', "{$this->width}x{$this->height}", $tmpl); $tmpl = str_replace('$filesize', to_shorthand_int($this->filesize), $tmpl); $tmpl = str_replace('$filename', $_escape($base_fname), $tmpl); - $tmpl = str_replace('$title', $_escape($config->get_string("title")), $tmpl); + $tmpl = str_replace('$title', $_escape($config->get_string(SetupConfig::TITLE)), $tmpl); $tmpl = str_replace('$date', $_escape(autodate($this->posted, false)), $tmpl); // nothing seems to use this, sending the event out to 50 exts is a lot of overhead diff --git a/core/page.php b/core/page.php index e31ed7d3..7efa2833 100644 --- a/core/page.php +++ b/core/page.php @@ -299,9 +299,55 @@ class Page $this->add_cookie("flash_message", "", -1, "/"); } usort($this->blocks, "blockcmp"); + $pnbe = new PageNavBuildingEvent(); + send_event($pnbe); + + $nav_links = $pnbe->links; + + $active_link = null; + // To save on event calls, we check if one of the top-level links has already been marked as active + foreach ($nav_links as $link) { + if($link->active===true) { + $active_link = $link; + break; + } + } + $sub_links = null; + // If one is, we just query for sub-menu options under that one tab + if($active_link!==null) { + $psnbe = new PageSubNavBuildingEvent($active_link->name); + send_event($psnbe); + $sub_links = $psnbe->links; + } else { + // Otherwise we query for the sub-items under each of the tabs + foreach ($nav_links as $link) { + $psnbe = new PageSubNavBuildingEvent($link->name); + send_event($psnbe); + + // Now we check for a current link so we can identify the sub-links to show + foreach ($psnbe->links as $sub_link) { + if($sub_link->active===true) { + $sub_links = $psnbe->links; + break; + } + } + // If the active link has been detected, we break out + if($sub_links!==null) { + $link->active = true; + break; + } + } + } + + + + $sub_links = $sub_links??[]; + usort($nav_links, "sort_nav_links"); + usort($sub_links, "sort_nav_links"); + $this->add_auto_html_headers(); $layout = new Layout(); - $layout->display_page($page); + $layout->display_page($page, $nav_links, $sub_links); break; case PageMode::DATA: header("Content-Length: " . strlen($this->data)); @@ -405,7 +451,7 @@ class Page global $config; $data_href = get_base_href(); - $theme_name = $config->get_string('theme', 'default'); + $theme_name = $config->get_string(SetupConfig::THEME, 'default'); $this->add_html_header("", 40); @@ -471,3 +517,99 @@ class Page $this->add_html_header("", 44); } } + +class PageNavBuildingEvent extends Event +{ + public $links = []; + + public function add_nav_link(string $name, Link $link, string $desc, ?bool $active = null, int $order = 50) + { + $this->links[] = new NavLink($name, $link, $desc, $active, $order); + } +} + +class PageSubNavBuildingEvent extends Event +{ + public $parent; + + public $links = []; + + public function __construct(string $parent) + { + $this->parent= $parent; + } + + public function add_nav_link(string $name, Link $link, string $desc, ?bool $active = null, int $order = 50) + { + $this->links[] = new NavLink($name, $link, $desc, $active,$order); + } +} + +class NavLink +{ + public $name; + public $link; + public $description; + public $order; + public $active = false; + + public function __construct(String $name, Link $link, String $description, ?bool $active = null, int $order = 50) + { + global $config; + + $this->name = $name; + $this->link = $link; + $this->description = $description; + $this->order = $order; + if($active==null) { + $query = ltrim(_get_query(), "/"); + if ($query === "") { + // This indicates the front page, so we check what's set as the front page + $front_page = trim($config->get_string(SetupConfig::FRONT_PAGE), "/"); + + if ($front_page === $link->page) { + $this->active = true; + } else { + $this->active = self::is_active([$link->page], $front_page); + } + } elseif($query===$link->page) { + $this->active = true; + }else { + $this->active = self::is_active([$link->page]); + } + } else { + $this->active = $active; + } + + } + + public static function is_active(array $pages_matched, string $url = null): bool + { + /** + * Woo! We can actually SEE THE CURRENT PAGE!! (well... see it highlighted in the menu.) + */ + $url = $url??ltrim(_get_query(), "/"); + + $re1='.*?'; + $re2='((?:[a-z][a-z_]+))'; + + if (preg_match_all("/".$re1.$re2."/is", $url, $matches)) { + $url=$matches[1][0]; + } + + $count_pages_matched = count($pages_matched); + + for ($i=0; $i < $count_pages_matched; $i++) { + if ($url == $pages_matched[$i]) { + return true; + } + } + + return false; + } +} + +function sort_nav_links(NavLink $a, NavLink $b) +{ + return $a->order - $b->order; +} diff --git a/core/permissions.php b/core/permissions.php new file mode 100644 index 00000000..4378a9c0 --- /dev/null +++ b/core/permissions.php @@ -0,0 +1,70 @@ +begin(get_class($event)); // SHIT: http://bugs.php.net/bug.php?id=35106 $my_event_listeners = $_shm_event_listeners[get_class($event)]; diff --git a/core/sys_config.php b/core/sys_config.php index 9ce0d8d0..5dc80459 100644 --- a/core/sys_config.php +++ b/core/sys_config.php @@ -40,7 +40,7 @@ _d("SEARCH_ACCEL", false); // boolean use search accelerator _d("WH_SPLITS", 1); // int how many levels of subfolders to put in the warehouse _d("VERSION", '2.7-beta'); // string shimmie version _d("TIMEZONE", null); // string timezone -_d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,setup,upgrade,handle_404,handle_static,comment,tag_list,index,tag_edit,alias_editor,media"); // extensions to always enable +_d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,setup,upgrade,handle_404,handle_static,comment,tag_list,index,tag_edit,alias_editor,media,help_pages,system"); // extensions to always enable _d("EXTRA_EXTS", ""); // string optional extra extensions _d("BASE_URL", null); // string force a specific base URL (default is auto-detect) _d("MIN_PHP_VERSION", '7.1');// string minimum supported PHP version diff --git a/core/urls.php b/core/urls.php index e4fc0977..457bfe1b 100644 --- a/core/urls.php +++ b/core/urls.php @@ -3,6 +3,23 @@ * HTML Generation * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +class Link +{ + public $page; + public $query; + + public function __construct(?string $page=null, ?string $query=null) + { + $this->page = $page; + $this->query = $query; + } + + public function make_link(): string + { + return make_link($this->page, $this->query); + } +} + /** * Figure out the correct way to link to a page, taking into account * things like the nice URLs setting. @@ -14,7 +31,7 @@ function make_link(?string $page=null, ?string $query=null): string global $config; if (is_null($page)) { - $page = $config->get_string('main_page'); + $page = $config->get_string(SetupConfig::MAIN_PAGE); } if (!is_null(BASE_URL)) { diff --git a/core/userclass.php b/core/userclass.php index bcd05c36..a66ad6f7 100644 --- a/core/userclass.php +++ b/core/userclass.php @@ -72,134 +72,138 @@ class UserClass // action = create / view / edit / delete // object = image / user / tag / setting new UserClass("base", null, [ - "change_setting" => false, # modify web-level settings, eg the config table - "override_config" => false, # modify sys-level settings, eg shimmie.conf.php - "big_search" => false, # search for more than 3 tags at once (speed mode only) + Permissions::CHANGE_SETTING => false, # modify web-level settings, eg the config table + Permissions::OVERRIDE_CONFIG => false, # modify sys-level settings, eg shimmie.conf.php + Permissions::BIG_SEARCH => false, # search for more than 3 tags at once (speed mode only) - "manage_extension_list" => false, - "manage_alias_list" => false, - "mass_tag_edit" => false, + Permissions::MANAGE_EXTENSION_LIST => false, + Permissions::MANAGE_ALIAS_LIST => false, + Permissions::MASS_TAG_EDIT => false, - "view_ip" => false, # view IP addresses associated with things - "ban_ip" => false, + Permissions::VIEW_IP => false, # view IP addresses associated with things + Permissions::BAN_IP => false, - "edit_user_name" => false, - "edit_user_password" => false, - "edit_user_info" => false, # email address, etc - "edit_user_class" => false, - "delete_user" => false, + Permissions::EDIT_USER_NAME => false, + Permissions::EDIT_USER_PASSWORD => false, + Permissions::EDIT_USER_INFO => false, # email address, etc + Permissions::EDIT_USER_CLASS => false, + Permissions::DELETE_USER => false, - "create_comment" => false, - "delete_comment" => false, - "bypass_comment_checks" => false, # spam etc + Permissions::CREATE_COMMENT => false, + Permissions::DELETE_COMMENT => false, + Permissions::BYPASS_COMMENT_CHECKS => false, # spam etc - "replace_image" => false, - "create_image" => false, - "edit_image_tag" => false, - "edit_image_source" => false, - "edit_image_owner" => false, - "edit_image_lock" => false, - "bulk_edit_image_tag" => false, - "bulk_edit_image_source" => false, - "delete_image" => false, + Permissions::REPLACE_IMAGE => false, + Permissions::CREATE_IMAGE => false, + Permissions::EDIT_IMAGE_TAG => false, + Permissions::EDIT_IMAGE_SOURCE => false, + Permissions::EDIT_IMAGE_OWNER => false, + Permissions::EDIT_IMAGE_LOCK => false, + Permissions::EDIT_IMAGE_TITLE => false, + Permissions::BULK_EDIT_IMAGE_TAG => false, + Permissions::BULK_EDIT_IMAGE_SOURCE => false, + Permissions::DELETE_IMAGE => false, - "ban_image" => false, + Permissions::BAN_IMAGE => false, - "view_eventlog" => false, - "ignore_downtime" => false, + Permissions::VIEW_EVENTLOG => false, + Permissions::IGNORE_DOWNTIME => false, - "create_image_report" => false, - "view_image_report" => false, # deal with reported images + Permissions::CREATE_IMAGE_REPORT => false, + Permissions::VIEW_IMAGE_REPORT => false, # deal with reported images - "edit_wiki_page" => false, - "delete_wiki_page" => false, + Permissions::EDIT_WIKI_PAGE => false, + Permissions::DELETE_WIKI_PAGE => false, - "manage_blocks" => false, + Permissions::MANAGE_BLOCKS => false, - "manage_admintools" => false, + Permissions::MANAGE_ADMINTOOLS => false, - "view_other_pms" => false, - "edit_feature" => false, - "bulk_edit_vote" => false, - "edit_other_vote" => false, - "view_sysinfo" => false, + Permissions::VIEW_OTHER_PMS => false, + Permissions::EDIT_FEATURE => false, + Permissions::BULK_EDIT_VOTE => false, + Permissions::EDIT_OTHER_VOTE => false, + Permissions::VIEW_SYSINTO => false, - "hellbanned" => false, - "view_hellbanned" => false, + Permissions::HELLBANNED => false, + Permissions::VIEW_HELLBANNED => false, - "protected" => false, # only admins can modify protected users (stops a moderator changing an admin's password) + Permissions::PROTECTED => false, # only admins can modify protected users (stops a moderator changing an admin's password) - "edit_image_rating" => false, - "bulk_edit_image_rating" => false, + Permissions::EDIT_IMAGE_RATING => false, + Permissions::BULK_EDIT_IMAGE_RATING => false, - "view_trash" => false, - "perform_bulk_actions" => false, + Permissions::VIEW_TRASH => false, + + Permissions::PERFORM_BULK_ACTIONS => false, ]); new UserClass("anonymous", "base", [ ]); new UserClass("user", "base", [ - "big_search" => true, - "create_image" => true, - "create_comment" => true, - "edit_image_tag" => true, - "edit_image_source" => true, - "create_image_report" => true, - "edit_image_rating" => true, + Permissions::BIG_SEARCH => true, + Permissions::CREATE_IMAGE => true, + Permissions::CREATE_COMMENT => true, + Permissions::EDIT_IMAGE_TAG => true, + Permissions::EDIT_IMAGE_SOURCE => true, + Permissions::EDIT_IMAGE_TITLE => true, + Permissions::CREATE_IMAGE_REPORT => true, + Permissions::EDIT_IMAGE_RATING => true, ]); new UserClass("admin", "base", [ - "change_setting" => true, - "override_config" => true, - "big_search" => true, - "edit_image_lock" => true, - "view_ip" => true, - "ban_ip" => true, - "edit_user_name" => true, - "edit_user_password" => true, - "edit_user_info" => true, - "edit_user_class" => true, - "delete_user" => true, - "create_image" => true, - "delete_image" => true, - "ban_image" => true, - "create_comment" => true, - "delete_comment" => true, - "bypass_comment_checks" => true, - "replace_image" => true, - "manage_extension_list" => true, - "manage_alias_list" => true, - "edit_image_tag" => true, - "edit_image_source" => true, - "edit_image_owner" => true, - "bulk_edit_image_tag" => true, - "bulk_edit_image_source" => true, - "mass_tag_edit" => true, - "create_image_report" => true, - "view_image_report" => true, - "edit_wiki_page" => true, - "delete_wiki_page" => true, - "view_eventlog" => true, - "manage_blocks" => true, - "manage_admintools" => true, - "ignore_downtime" => true, - "view_other_pms" => true, - "edit_feature" => true, - "bulk_edit_vote" => true, - "edit_other_vote" => true, - "view_sysinfo" => true, - "view_hellbanned" => true, - "protected" => true, - "edit_image_rating" => true, - "bulk_edit_image_rating" => true, - "view_trash" => true, - "perform_bulk_actions" => true, + Permissions::CHANGE_SETTING => true, + Permissions::OVERRIDE_CONFIG => true, + Permissions::BIG_SEARCH => true, + Permissions::EDIT_IMAGE_LOCK => true, + Permissions::VIEW_IP => true, + Permissions::BAN_IP => true, + Permissions::EDIT_USER_NAME => true, + Permissions::EDIT_USER_PASSWORD => true, + Permissions::EDIT_USER_INFO => true, + Permissions::EDIT_USER_CLASS => true, + Permissions::DELETE_USER => true, + Permissions::CREATE_IMAGE => true, + Permissions::DELETE_IMAGE => true, + Permissions::BAN_IMAGE => true, + Permissions::CREATE_COMMENT => true, + Permissions::DELETE_COMMENT => true, + Permissions::BYPASS_COMMENT_CHECKS => true, + Permissions::REPLACE_IMAGE => true, + Permissions::MANAGE_EXTENSION_LIST => true, + Permissions::MANAGE_ALIAS_LIST => true, + Permissions::EDIT_IMAGE_TAG => true, + Permissions::EDIT_IMAGE_SOURCE => true, + Permissions::EDIT_IMAGE_OWNER => true, + Permissions::EDIT_IMAGE_TITLE => true, + Permissions::BULK_EDIT_IMAGE_TAG => true, + Permissions::BULK_EDIT_IMAGE_SOURCE => true, + Permissions::MASS_TAG_EDIT => true, + Permissions::CREATE_IMAGE_REPORT => true, + Permissions::VIEW_IMAGE_REPORT => true, + Permissions::EDIT_WIKI_PAGE => true, + Permissions::DELETE_WIKI_PAGE => true, + Permissions::VIEW_EVENTLOG => true, + Permissions::MANAGE_BLOCKS => true, + Permissions::MANAGE_ADMINTOOLS => true, + Permissions::IGNORE_DOWNTIME => true, + Permissions::VIEW_OTHER_PMS => true, + Permissions::EDIT_FEATURE => true, + Permissions::BULK_EDIT_VOTE => true, + Permissions::EDIT_OTHER_VOTE => true, + Permissions::VIEW_SYSINTO => true, + Permissions::VIEW_HELLBANNED => true, + Permissions::PROTECTED => true, + Permissions::EDIT_IMAGE_RATING => true, + Permissions::BULK_EDIT_IMAGE_RATING => true, + Permissions::VIEW_TRASH => true, + Permissions::PERFORM_BULK_ACTIONS => true, ]); new UserClass("hellbanned", "user", [ - "hellbanned" => true, + Permissions::HELLBANNED => true, ]); @include_once "data/config/user-classes.conf.php"; diff --git a/core/util.php b/core/util.php index 91e467ff..7017078d 100644 --- a/core/util.php +++ b/core/util.php @@ -16,7 +16,7 @@ function mtimefile(string $file): string function get_theme(): string { global $config; - $theme = $config->get_string("theme", "default"); + $theme = $config->get_string(SetupConfig::THEME, "default"); if (!file_exists("themes/$theme")) { $theme = "default"; } @@ -588,8 +588,8 @@ function show_ip(string $ip, string $ban_reason): string global $user; $u_reason = url_escape($ban_reason); $u_end = url_escape("+1 week"); - $ban = $user->can("ban_ip") ? ", Ban" : ""; - $ip = $user->can("view_ip") ? $ip.$ban : ""; + $ban = $user->can(Permissions::BAN_IP) ? ", Ban" : ""; + $ip = $user->can(Permissions::VIEW_IP) ? $ip.$ban : ""; return $ip; } diff --git a/ext/admin/main.php b/ext/admin/main.php index 4ebae35e..423460c8 100644 --- a/ext/admin/main.php +++ b/ext/admin/main.php @@ -54,7 +54,7 @@ class AdminPage extends Extension global $page, $user; if ($event->page_matches("admin")) { - if (!$user->can("manage_admintools")) { + if (!$user->can(Permissions::MANAGE_ADMINTOOLS)) { $this->theme->display_permission_denied(); } else { if ($event->count_args() == 0) { @@ -108,10 +108,20 @@ class AdminPage extends Extension $this->theme->display_form(); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::MANAGE_ADMINTOOLS)) { + $event->add_nav_link("admin", new Link('admin'), "Board Admin"); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("manage_admintools")) { + if ($user->can(Permissions::MANAGE_ADMINTOOLS)) { $event->add_link("Board Admin", make_link("admin")); } } diff --git a/ext/alias_editor/main.php b/ext/alias_editor/main.php index 07f9f289..36edbfbb 100644 --- a/ext/alias_editor/main.php +++ b/ext/alias_editor/main.php @@ -36,7 +36,7 @@ class AliasEditor extends Extension if ($event->page_matches("alias")) { if ($event->get_arg(0) == "add") { - if ($user->can("manage_alias_list")) { + if ($user->can(Permissions::MANAGE_ALIAS_LIST)) { if (isset($_POST['oldtag']) && isset($_POST['newtag'])) { try { $aae = new AddAliasEvent($_POST['oldtag'], $_POST['newtag']); @@ -49,7 +49,7 @@ class AliasEditor extends Extension } } } elseif ($event->get_arg(0) == "remove") { - if ($user->can("manage_alias_list")) { + if ($user->can(Permissions::MANAGE_ALIAS_LIST)) { if (isset($_POST['oldtag'])) { $database->execute("DELETE FROM aliases WHERE oldtag=:oldtag", ["oldtag" => $_POST['oldtag']]); log_info("alias_editor", "Deleted alias for ".$_POST['oldtag'], "Deleted alias"); @@ -85,7 +85,7 @@ class AliasEditor extends Extension $page->set_filename("aliases.csv"); $page->set_data($this->get_alias_csv($database)); } elseif ($event->get_arg(0) == "import") { - if ($user->can("manage_alias_list")) { + if ($user->can(Permissions::MANAGE_ALIAS_LIST)) { if (count($_FILES) > 0) { $tmp = $_FILES['alias_file']['tmp_name']; $contents = file_get_contents($tmp); @@ -117,10 +117,17 @@ class AliasEditor extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="tags") { + $event->add_nav_link("aliases", new Link('alias/list'), "Aliases", NavLink::is_active(["alias"])); + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("manage_alias_list")) { + if ($user->can(Permissions::MANAGE_ALIAS_LIST)) { $event->add_link("Alias Editor", make_link("alias/list")); } } diff --git a/ext/alias_editor/theme.php b/ext/alias_editor/theme.php index ec12348e..732139d4 100644 --- a/ext/alias_editor/theme.php +++ b/ext/alias_editor/theme.php @@ -11,7 +11,7 @@ class AliasEditorTheme extends Themelet { global $page, $user; - $can_manage = $user->can("manage_alias_list"); + $can_manage = $user->can(Permissions::MANAGE_ALIAS_LIST); if ($can_manage) { $h_action = "Action"; $h_add = " diff --git a/ext/artists/main.php b/ext/artists/main.php index 568933de..b1f6efcc 100644 --- a/ext/artists/main.php +++ b/ext/artists/main.php @@ -47,12 +47,23 @@ class Artists extends Extension public function onSearchTermParse(SearchTermParseEvent $event) { $matches = []; - if (preg_match("/^author[=|:](.*)$/i", $event->term, $matches)) { + if (preg_match("/^(author|artist)[=|:](.*)$/i", $event->term, $matches)) { $char = $matches[1]; $event->add_querylet(new Querylet("Author = :author_char", ["author_char"=>$char])); } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Artist"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + + public function onInitExt(InitExtEvent $event) { global $config, $database; diff --git a/ext/artists/theme.php b/ext/artists/theme.php index aebd2757..1e5e5afb 100644 --- a/ext/artists/theme.php +++ b/ext/artists/theme.php @@ -545,4 +545,14 @@ class ArtistsTheme extends Themelet } return $html; } + + public function get_help_html() + { + return '

Search for images with a particular artist.

+
+
artist=leonardo
+

Returns images with the artist "leonardo".

+
+ '; + } } diff --git a/ext/ban_words/main.php b/ext/ban_words/main.php index c668e514..5e0761b3 100644 --- a/ext/ban_words/main.php +++ b/ext/ban_words/main.php @@ -58,7 +58,7 @@ xanax public function onCommentPosting(CommentPostingEvent $event) { global $user; - if (!$user->can("bypass_comment_checks")) { + if (!$user->can(Permissions::BYPASS_COMMENT_CHECKS)) { $this->test_text($event->comment, new CommentPostingException("Comment contains banned terms")); } } diff --git a/ext/blocks/main.php b/ext/blocks/main.php index cb9c375c..197b5d9f 100644 --- a/ext/blocks/main.php +++ b/ext/blocks/main.php @@ -26,10 +26,20 @@ class Blocks extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::MANAGE_BLOCKS)) { + $event->add_nav_link("blocks", new Link('blocks/list'), "Blocks Editor"); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("manage_blocks")) { + if ($user->can(Permissions::MANAGE_BLOCKS)) { $event->add_link("Blocks Editor", make_link("blocks/list")); } } @@ -52,7 +62,7 @@ class Blocks extends Extension } } - if ($event->page_matches("blocks") && $user->can("manage_blocks")) { + if ($event->page_matches("blocks") && $user->can(Permissions::MANAGE_BLOCKS)) { if ($event->get_arg(0) == "add") { if ($user->check_auth_token()) { $database->execute(" diff --git a/ext/blotter/main.php b/ext/blotter/main.php index cb88490b..3e18b1a9 100644 --- a/ext/blotter/main.php +++ b/ext/blotter/main.php @@ -56,6 +56,17 @@ class Blotter extends Extension $event->panel->add_block($sb); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->is_admin()) { + $event->add_nav_link("blotter", new Link('blotter/editor'), "Blotter Editor"); + } + } + } + + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; diff --git a/ext/browser_search/main.php b/ext/browser_search/main.php index 7c1fcc82..301ca0db 100644 --- a/ext/browser_search/main.php +++ b/ext/browser_search/main.php @@ -27,14 +27,14 @@ class BrowserSearch extends Extension // Add in header code to let the browser know that the search plugin exists // We need to build the data for the header - $search_title = $config->get_string('title'); + $search_title = $config->get_string(SetupConfig::TITLE); $search_file_url = make_link('browser_search/please_dont_use_this_tag_as_it_would_break_stuff__search.xml'); $page->add_html_header(""); // The search.xml file that is generated on the fly if ($event->page_matches("browser_search/please_dont_use_this_tag_as_it_would_break_stuff__search.xml")) { // First, we need to build all the variables we'll need - $search_title = $config->get_string('title'); + $search_title = $config->get_string(SetupConfig::TITLE); $search_form_url = make_link('post/list/{searchTerms}'); $suggenton_url = make_link('browser_search/')."{searchTerms}"; $icon_b64 = base64_encode(file_get_contents("ext/handle_static/static/favicon.ico")); diff --git a/ext/bulk_actions/main.php b/ext/bulk_actions/main.php index d8dde6d9..0bfaf1da 100644 --- a/ext/bulk_actions/main.php +++ b/ext/bulk_actions/main.php @@ -85,11 +85,11 @@ class BulkActions extends Extension { global $user; - if ($user->can("delete_image")) { + if ($user->can(Permissions::DELETE_IMAGE)) { $event->add_action("bulk_delete", "(D)elete", "d", "Delete selected images?", $this->theme->render_ban_reason_input(), 10); } - if ($user->can("bulk_edit_image_tag")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG)) { $event->add_action( "bulk_tag", @@ -100,7 +100,7 @@ class BulkActions extends Extension 10); } - if ($user->can("bulk_edit_image_source")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_SOURCE)) { $event->add_action("bulk_source", "Set (S)ource", "s","", $this->theme->render_source_input(), 10); } } @@ -111,7 +111,7 @@ class BulkActions extends Extension switch ($event->action) { case "bulk_delete": - if ($user->can("delete_image")) { + if ($user->can(Permissions::DELETE_IMAGE)) { $i = $this->delete_items($event->items); flash_message("Deleted $i items"); } @@ -120,7 +120,7 @@ class BulkActions extends Extension if (!isset($_POST['bulk_tags'])) { return; } - if ($user->can("bulk_edit_image_tag")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG)) { $tags = $_POST['bulk_tags']; $replace = false; if (isset($_POST['bulk_tags_replace']) && $_POST['bulk_tags_replace'] == "true") { @@ -135,7 +135,7 @@ class BulkActions extends Extension if (!isset($_POST['bulk_source'])) { return; } - if ($user->can("bulk_edit_image_source")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_SOURCE)) { $source = $_POST['bulk_source']; $i = $this->set_source($event->items, $source); flash_message("Set source for $i items"); @@ -147,7 +147,7 @@ class BulkActions extends Extension public function onPageRequest(PageRequestEvent $event) { global $page, $user; - if ($event->page_matches("bulk_action") && $user->can("perform_bulk_actions")) { + if ($event->page_matches("bulk_action") && $user->can(Permissions::PERFORM_BULK_ACTIONS)) { if (!isset($_POST['bulk_action'])) { return; } diff --git a/ext/comment/main.php b/ext/comment/main.php index 1dfdc03b..f58a3076 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -157,6 +157,21 @@ class CommentList extends Extension } } + + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("comment", new Link('comment/list'), "Comments"); + } + + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="comment") { + $event->add_nav_link("comment_list", new Link('comment/list'), "All"); + $event->add_nav_link("comment_help", new Link('ext_doc/comment'), "Help"); + } + } + public function onPageRequest(PageRequestEvent $event) { if ($event->page_matches("comment")) { @@ -189,7 +204,7 @@ class CommentList extends Extension private function onPageRequest_delete(PageRequestEvent $event) { global $user, $page; - if ($user->can("delete_comment")) { + if ($user->can(Permissions::DELETE_COMMENT)) { // FIXME: post, not args if ($event->count_args() === 3) { send_event(new CommentDeletionEvent($event->get_arg(1))); @@ -209,7 +224,7 @@ class CommentList extends Extension private function onPageRequest_bulk_delete() { global $user, $database, $page; - if ($user->can("delete_comment") && !empty($_POST["ip"])) { + if ($user->can(Permissions::DELETE_COMMENT) && !empty($_POST["ip"])) { $ip = $_POST['ip']; $comment_ids = $database->get_col(" @@ -288,7 +303,7 @@ class CommentList extends Extension $this->theme->display_image_comments( $event->image, $this->get_comments($event->image->id), - $user->can("create_comment") + $user->can(Permissions::CREATE_COMMENT) ); } @@ -351,6 +366,16 @@ class CommentList extends Extension } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Comments"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + // page building {{{ private function build_page(int $current_page) { @@ -399,7 +424,7 @@ class CommentList extends Extension } } - $this->theme->display_comment_list($images, $current_page, $total_pages, $user->can("create_comment")); + $this->theme->display_comment_list($images, $current_page, $total_pages, $user->can(Permissions::CREATE_COMMENT)); } // }}} @@ -574,7 +599,7 @@ class CommentList extends Extension { global $database, $page; - if (!$user->can("bypass_comment_checks")) { + if (!$user->can(Permissions::BYPASS_COMMENT_CHECKS)) { // will raise an exception if anything is wrong $this->comment_checks($image_id, $user, $comment); } @@ -600,7 +625,7 @@ class CommentList extends Extension global $config, $page; // basic sanity checks - if (!$user->can("create_comment")) { + if (!$user->can(Permissions::CREATE_COMMENT)) { throw new CommentPostingException("Anonymous posting has been disabled"); } elseif (is_null(Image::by_id($image_id))) { throw new CommentPostingException("The image does not exist"); diff --git a/ext/comment/theme.php b/ext/comment/theme.php index a17131af..7e62da6b 100644 --- a/ext/comment/theme.php +++ b/ext/comment/theme.php @@ -218,9 +218,9 @@ class CommentListTheme extends Themelet if (!array_key_exists($comment->poster_ip, $this->anon_map)) { $this->anon_map[$comment->poster_ip] = $this->anon_id; } - #if($user->can("view_ip")) { + #if($user->can(UserAbilities::VIEW_IP)) { #$style = " style='color: ".$this->get_anon_colour($comment->poster_ip).";'"; - if ($user->can("view_ip") || $config->get_bool("comment_samefags_public", false)) { + if ($user->can(Permissions::VIEW_IP) || $config->get_bool("comment_samefags_public", false)) { if ($this->anon_map[$comment->poster_ip] != $this->anon_id) { $anoncode2 = '('.$this->anon_map[$comment->poster_ip].')'; } @@ -248,9 +248,9 @@ class CommentListTheme extends Themelet $h_avatar = "
"; } $h_reply = " - Reply"; - $h_ip = $user->can("view_ip") ? "
".show_ip($comment->poster_ip, "Comment posted {$comment->posted}") : ""; + $h_ip = $user->can(Permissions::VIEW_IP) ? "
".show_ip($comment->poster_ip, "Comment posted {$comment->posted}") : ""; $h_del = ""; - if ($user->can("delete_comment")) { + if ($user->can(Permissions::DELETE_COMMENT)) { $comment_preview = substr(html_unescape($tfe->stripped), 0, 50); $j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview"); $h_delete_script = html_escape("return confirm($j_delete_confirm_message);"); @@ -290,4 +290,28 @@ class CommentListTheme extends Themelet '; } + + public function get_help_html() + { + return '

Search for images containing a certain number of comments, or comments by a particular individual.

+
+
comments=1
+

Returns images with exactly 1 comment.

+
+
+
comments>0
+

Returns images with 1 or more comments.

+
+

Can use <, <=, >, >=, or =.

+
+
commented_by:username
+

Returns images that have been commented on by "username".

+
+
+
commented_by_userno:123
+

Returns images that have been commented on by user 123.

+
+ '; + + } } diff --git a/ext/custom_html_headers/main.php b/ext/custom_html_headers/main.php index 3125f3b1..58715e9b 100644 --- a/ext/custom_html_headers/main.php +++ b/ext/custom_html_headers/main.php @@ -65,7 +65,7 @@ class custom_html_headers extends Extension global $config, $page; // get config values - $site_title = $config->get_string("title"); + $site_title = $config->get_string(SetupConfig::TITLE); $sitename_in_title = $config->get_int("sitename_in_title"); // if feature is enabled & sitename isn't already in title diff --git a/ext/danbooru_api/main.php b/ext/danbooru_api/main.php index ce13295b..cb55766f 100644 --- a/ext/danbooru_api/main.php +++ b/ext/danbooru_api/main.php @@ -297,7 +297,7 @@ class DanbooruApi extends Extension // Now we check if a file was uploaded or a url was provided to transload // Much of this code is borrowed from /ext/upload - if (!$user->can("create_image")) { + if (!$user->can(Permissions::CREATE_IMAGE)) { $page->set_code(409); $page->add_http_header("X-Danbooru-Errors: authentication error"); return; diff --git a/ext/downtime/main.php b/ext/downtime/main.php index 891d87c3..97f8682e 100644 --- a/ext/downtime/main.php +++ b/ext/downtime/main.php @@ -32,7 +32,7 @@ class Downtime extends Extension global $config, $page, $user; if ($config->get_bool("downtime")) { - if (!$user->can("ignore_downtime") && !$this->is_safe_page($event)) { + if (!$user->can(Permissions::IGNORE_DOWNTIME) && !$this->is_safe_page($event)) { $msg = $config->get_string("downtime_message"); $this->theme->display_message($msg); if (!defined("UNITTEST")) { // hax D: diff --git a/ext/downtime/theme.php b/ext/downtime/theme.php index caedcfda..99c4cffc 100644 --- a/ext/downtime/theme.php +++ b/ext/downtime/theme.php @@ -21,7 +21,7 @@ class DowntimeTheme extends Themelet public function display_message(string $message) { global $config, $user, $page; - $theme_name = $config->get_string('theme'); + $theme_name = $config->get_string(SetupConfig::THEME); $data_href = get_base_href(); $login_link = make_link("user_admin/login"); $auth = $user->get_auth_html(); diff --git a/ext/et/main.php b/ext/et/main.php index e3e9b9c7..576765dd 100644 --- a/ext/et/main.php +++ b/ext/et/main.php @@ -18,16 +18,28 @@ class ET extends Extension { global $user; if ($event->page_matches("system_info")) { - if ($user->can("view_sysinfo")) { + if ($user->can(Permissions::VIEW_SYSINTO)) { $this->theme->display_info_page($this->get_info()); } } } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::VIEW_SYSINTO)) { + $event->add_nav_link("system_info", new Link('system_info'), "System Info", null, 10); + } + } + } + + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("view_sysinfo")) { + if ($user->can(Permissions::VIEW_SYSINTO)) { $event->add_link("System Info", make_link("system_info")); } } @@ -40,8 +52,8 @@ class ET extends Extension global $config, $database; $info = []; - $info['site_title'] = $config->get_string("title"); - $info['site_theme'] = $config->get_string("theme"); + $info['site_title'] = $config->get_string(SetupConfig::TITLE); + $info['site_theme'] = $config->get_string(SetupConfig::THEME); $info['site_url'] = "http://" . $_SERVER["HTTP_HOST"] . get_base_href(); $info['sys_shimmie'] = VERSION; diff --git a/ext/ext_manager/main.php b/ext/ext_manager/main.php index 03ee3bb1..39c7f572 100644 --- a/ext/ext_manager/main.php +++ b/ext/ext_manager/main.php @@ -118,7 +118,7 @@ class ExtManager extends Extension { global $page, $user; if ($event->page_matches("ext_manager")) { - if ($user->can("manage_extension_list")) { + if ($user->can(Permissions::MANAGE_EXTENSION_LIST)) { if ($event->get_arg(0) == "set" && $user->check_auth_token()) { if (is_writable("data/config")) { $this->set_things($_POST); @@ -162,11 +162,22 @@ class ExtManager extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::MANAGE_EXTENSION_LIST)) { + $event->add_nav_link("ext_manager", new Link('ext_manager'), "Extension Manager"); + } else { + $event->add_nav_link("ext_doc", new Link('ext_doc'), "Board Help"); + } + } + } public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("manage_extension_list")) { + if ($user->can(Permissions::MANAGE_EXTENSION_LIST)) { $event->add_link("Extension Manager", make_link("ext_manager")); } else { $event->add_link("Help", make_link("ext_doc")); diff --git a/ext/favorites/main.php b/ext/favorites/main.php index e8b7f6fe..950d6178 100644 --- a/ext/favorites/main.php +++ b/ext/favorites/main.php @@ -155,6 +155,30 @@ class Favorites extends Extension } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Favorites"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent=="posts") { + $event->add_nav_link("posts_favorites", new Link("post/list/favorited_by={$user->name}/1"), "My Favorites"); + } + + if($event->parent==="user") { + if ($user->can(Permissions::MANAGE_ADMINTOOLS)) { + $username = url_escape($user->name); + $event->add_nav_link("favorites", new Link("post/list/favorited_by=$username/1"), "My Favorites"); + } + } + } private function install() { diff --git a/ext/favorites/theme.php b/ext/favorites/theme.php index 89509ce2..22367347 100644 --- a/ext/favorites/theme.php +++ b/ext/favorites/theme.php @@ -34,4 +34,28 @@ class FavoritesTheme extends Themelet $page->add_block(new Block("Favorited By", $html, "left", 25)); } + + public function get_help_html() + { + return '

Search for images that have been favorited a certain number of times, or favorited by a particular individual.

+
+
favorites=1
+

Returns images that have been favorited once.

+
+
+
favorites>0
+

Returns images that have been favorited 1 or more times

+
+

Can use <, <=, >, >=, or =.

+
+
favorited_by:username
+

Returns images that have been favorited by "username".

+
+
+
favorited_by_userno:123
+

Returns images that have been favorited by user 123.

+
+ '; + + } } diff --git a/ext/featured/main.php b/ext/featured/main.php index 4b713424..ae5946dd 100644 --- a/ext/featured/main.php +++ b/ext/featured/main.php @@ -32,7 +32,7 @@ class Featured extends Extension global $config, $page, $user; if ($event->page_matches("featured_image")) { if ($event->get_arg(0) == "set" && $user->check_auth_token()) { - if ($user->can("edit_feature") && isset($_POST['image_id'])) { + if ($user->can(Permissions::EDIT_FEATURE) && isset($_POST['image_id'])) { $id = int_escape($_POST['image_id']); if ($id > 0) { $config->set_int("featured_id", $id); @@ -86,7 +86,7 @@ class Featured extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user; - if ($user->can("edit_feature")) { + if ($user->can(Permissions::EDIT_FEATURE)) { $event->add_part($this->theme->get_buttons_html($event->image->id)); } } diff --git a/ext/handle_static/main.php b/ext/handle_static/main.php index fb20dd59..69918964 100644 --- a/ext/handle_static/main.php +++ b/ext/handle_static/main.php @@ -17,7 +17,7 @@ class HandleStatic extends Extension if ($page->mode == PageMode::PAGE && (!isset($page->blocks) || $this->count_main($page->blocks) == 0)) { $h_pagename = html_escape(implode('/', $event->args)); $f_pagename = preg_replace("/[^a-z_\-\.]+/", "_", $h_pagename); - $theme_name = $config->get_string("theme", "default"); + $theme_name = $config->get_string(SetupConfig::THEME, "default"); $theme_file = "themes/$theme_name/static/$f_pagename"; $static_file = "ext/handle_static/static/$f_pagename"; diff --git a/ext/hellban/main.php b/ext/hellban/main.php index 42bfec27..541f7620 100644 --- a/ext/hellban/main.php +++ b/ext/hellban/main.php @@ -9,9 +9,9 @@ class HellBan extends Extension { global $page, $user; - if ($user->can("hellbanned")) { + if ($user->can(Permissions::HELLBANNED)) { $s = ""; - } elseif ($user->can("view_hellbanned")) { + } elseif ($user->can(Permissions::VIEW_HELLBANNED)) { $s = "DIV.hb, TR.hb TD {border: 1px solid red !important;}"; } else { $s = ".hb {display: none !important;}"; diff --git a/ext/help_pages/baseline_help_outline_black_18dp.png b/ext/help_pages/baseline_help_outline_black_18dp.png new file mode 100644 index 00000000..b6126844 Binary files /dev/null and b/ext/help_pages/baseline_help_outline_black_18dp.png differ diff --git a/ext/help_pages/main.php b/ext/help_pages/main.php new file mode 100644 index 00000000..d2821b00 --- /dev/null +++ b/ext/help_pages/main.php @@ -0,0 +1,94 @@ + + * License: MIT + * Description: Provides documentation screens + */ + +class HelpPageListBuildingEvent extends Event +{ + public $pages = []; + + public function add_page(string $key, string $name) + { + $this->pages[$key] = $name; + } + +} + +class HelpPageBuildingEvent extends Event +{ + public $key; + public $blocks = []; + + public function __construct(string $key) + { + $this->key = $key; + } + + function add_block(Block $block, int $position = 50) + { + if(!array_key_exists("$position",$this->blocks)) + { + $this->blocks["$position"] = []; + } + $this->blocks["$position"][] = $block; + } +} + +class HelpPages extends Extension +{ + public const SEARCH = "search"; + + public function onPageRequest(PageRequestEvent $event) + { + global $page, $user; + + if ($event->page_matches("help")) { + $e = new HelpPageListBuildingEvent(); + send_event($e); + $page->set_mode(PageMode::PAGE); + + if ($event->count_args() == 0) { + $this->theme->display_list_page($e->pages); + } else { + $name = $event->get_arg(0); + $title = $name; + if(array_key_exists($name, $e->pages)) { + $title = $e->pages[$name]; + } + + $this->theme->display_help_page($title); + + $hpbe = new HelpPageBuildingEvent($name); + send_event($hpbe); + asort($hpbe->blocks); + + foreach ($hpbe->blocks as $key=>$value) { + foreach($value as $block) { + $page->add_block($block); + } + } + } + } + } + + public function onHelpPageListBuilding(HelpPageListBuildingEvent $event) + { + $event->add_page("search", "Searching"); + } + + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("help", new Link('help'), "Help"); + } + + public function onUserBlockBuilding(UserBlockBuildingEvent $event) + { + global $user; + $event->add_link("Help", make_link("help")); + } + + +} diff --git a/ext/help_pages/style.css b/ext/help_pages/style.css new file mode 100644 index 00000000..85a40f5b --- /dev/null +++ b/ext/help_pages/style.css @@ -0,0 +1,13 @@ +.command_example { + margin: 12pt; + padding-left: 16pt; +} + +.command_example pre { + padding:4pt; + border: dashed 2px black; +} + +.command_example p { + padding-left: 16pt; +} \ No newline at end of file diff --git a/ext/help_pages/theme.php b/ext/help_pages/theme.php new file mode 100644 index 00000000..2b3b7818 --- /dev/null +++ b/ext/help_pages/theme.php @@ -0,0 +1,31 @@ +set_title("Help Pages"); + $page->set_heading("Help Pages"); + + $nav_block = new Block("Help", "", "left", 0); + foreach ($pages as $link=>$desc) { + $link = make_link("help/{$link}"); + $nav_block->body .= "".html_escape($desc)."
"; + } + + $page->add_block($nav_block); + $page->add_block(new Block("Help Pages", "See list of pages to left")); + } + + public function display_help_page(String $title) + { + global $page; + + $page->set_title("Help - $title"); + $page->set_heading("Help - $title"); + } + +} diff --git a/ext/home/main.php b/ext/home/main.php index 34b9422f..156035c6 100644 --- a/ext/home/main.php +++ b/ext/home/main.php @@ -22,8 +22,8 @@ class Home extends Extension global $config, $page; if ($event->page_matches("home")) { $base_href = get_base_href(); - $sitename = $config->get_string('title'); - $theme_name = $config->get_string('theme'); + $sitename = $config->get_string(SetupConfig::TITLE); + $theme_name = $config->get_string(SetupConfig::THEME); $body = $this->get_body(); @@ -52,7 +52,7 @@ class Home extends Extension // returns just the contents of the body global $config; $base_href = get_base_href(); - $sitename = $config->get_string('title'); + $sitename = $config->get_string(SetupConfig::TITLE); $contact_link = contact_link(); if (is_null($contact_link)) { $contact_link = ""; diff --git a/ext/image/main.php b/ext/image/main.php index 099bdd65..9969c3e8 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -73,7 +73,7 @@ class ImageIO extends Extension { if ($event->page_matches("image/delete")) { global $page, $user; - if ($user->can("delete_image") && isset($_POST['image_id']) && $user->check_auth_token()) { + if ($user->can(Permissions::DELETE_IMAGE) && isset($_POST['image_id']) && $user->check_auth_token()) { $image = Image::by_id($_POST['image_id']); if ($image) { send_event(new ImageDeletionEvent($image)); @@ -87,7 +87,7 @@ class ImageIO extends Extension } } elseif ($event->page_matches("image/replace")) { global $page, $user; - if ($user->can("replace_image") && isset($_POST['image_id']) && $user->check_auth_token()) { + if ($user->can(Permissions::REPLACE_IMAGE) && isset($_POST['image_id']) && $user->check_auth_token()) { $image = Image::by_id($_POST['image_id']); if ($image) { $page->set_mode(PageMode::REDIRECT); @@ -110,11 +110,11 @@ class ImageIO extends Extension { global $user; - if ($user->can("delete_image")) { + if ($user->can(Permissions::DELETE_IMAGE)) { $event->add_part($this->theme->get_deleter_html($event->image->id)); } /* In the future, could perhaps allow users to replace images that they own as well... */ - if ($user->can("replace_image")) { + if ($user->can(Permissions::REPLACE_IMAGE)) { $event->add_part($this->theme->get_replace_html($event->image->id)); } } diff --git a/ext/image_hash_ban/main.php b/ext/image_hash_ban/main.php index c2e3ec3a..cc3a7ca1 100644 --- a/ext/image_hash_ban/main.php +++ b/ext/image_hash_ban/main.php @@ -64,7 +64,7 @@ class ImageBan extends Extension global $database, $page, $user; if ($event->page_matches("image_hash_ban")) { - if ($user->can("ban_image")) { + if ($user->can(Permissions::BAN_IMAGE)) { if ($event->get_arg(0) == "add") { $image = isset($_POST['image_id']) ? Image::by_id(int_escape($_POST['image_id'])) : null; $hash = isset($_POST["hash"]) ? $_POST["hash"] : $image->hash; @@ -103,10 +103,21 @@ class ImageBan extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::BAN_IMAGE)) { + $event->add_nav_link("image_bans", new Link('image_hash_ban/list/1'), "Image Bans", NavLink::is_active(["image_hash_ban"])); + } + } + } + + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("ban_image")) { + if ($user->can(Permissions::BAN_IMAGE)) { $event->add_link("Image Bans", make_link("image_hash_ban/list/1")); } } @@ -130,7 +141,7 @@ class ImageBan extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user; - if ($user->can("ban_image")) { + if ($user->can(Permissions::BAN_IMAGE)) { $event->add_part($this->theme->get_buttons_html($event->image)); } } diff --git a/ext/index/main.php b/ext/index/main.php index eab9d7b3..9bf22091 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -332,6 +332,29 @@ class Index extends Extension } } + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("posts", new Link('post/list'), "Posts", NavLink::is_active(["post","view"]),20); + } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="posts") { + $event->add_nav_link("posts_all", new Link('post/list'), "All"); + } + } + + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "General"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block, 0); + } + } + + public function onSearchTermParse(SearchTermParseEvent $event) { $matches = []; @@ -380,6 +403,7 @@ class Index extends Extension $event->add_querylet(new Querylet('images.source LIKE :src', ["src"=>"%$source%"])); } } elseif (preg_match("/^posted([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])([0-9-]*)$/i", $event->term, $matches)) { + // TODO Make this able to search = without needing a time component. $cmp = ltrim($matches[1], ":") ?: "="; $val = $matches[2]; $event->add_querylet(new Querylet("images.posted $cmp :posted{$this->stpen}", ["posted{$this->stpen}"=>$val])); diff --git a/ext/index/theme.php b/ext/index/theme.php index 5b58d627..e216ea06 100644 --- a/ext/index/theme.php +++ b/ext/index/theme.php @@ -110,7 +110,7 @@ and of course start organising your images :-) global $config; if (count($this->search_terms) == 0) { - $page_title = $config->get_string('title'); + $page_title = $config->get_string(SetupConfig::TITLE); } else { $search_string = implode(' ', $this->search_terms); $page_title = html_escape($search_string); @@ -144,4 +144,201 @@ and of course start organising your images :-) $this->display_paginator($page, "post/list", null, $this->page_number, $this->total_pages, true); } } + + public function get_help_html() + { + return '

Searching is largely based on tags, with a number of special keywords available that allow searching based on properties of the images.

+ +
+
tagname
+

Returns images that are tagged with "tagname".

+
+ +
+
tagname othertagname
+

Returns images that are tagged with "tagname" and "othertagname".

+
+ +

Most tags and keywords can be prefaced with a negative sign (-) to indicate that you want to search for images that do not match something.

+ +
+
-tagname
+

Returns images that are not tagged with "tagname".

+
+ +
+
-tagname -othertagname
+

Returns images that are not tagged with "tagname" and "othertagname". This is different than without the negative sign, as images with "tagname" or "othertagname" can still be returned as long as the other one is not present.

+
+ +
+
tagname -othertagname
+

Returns images that are tagged with "tagname", but are not tagged with "othertagname".

+
+ +

Wildcard searches are possible as well using * for "any one, more, or none" and ? for "any one".

+ +
+
tagn*
+

Returns images that are tagged with "tagname", "tagnot", or anything else that starts with "tagn".

+
+ +
+
tagn?me
+

Returns images that are tagged with "tagname", "tagnome", or anything else that starts with "tagn", has one character, and ends with "me".

+
+ +
+
tags=1
+

Returns images with exactly 1 tag.

+
+ +
+
tags>0
+

Returns images with 1 or more tags.

+
+ +

Can use <, <=, >, >=, or =.

+ +
+ +

Search for images by aspect ratio

+ +
+
ratio=4:3
+

Returns images with an aspect ratio of 4:3.

+
+ +
+
ratio>16:9
+

Returns images with an aspect ratio greater than 16:9.

+
+ +

Can use <, <=, >, >=, or =. The relation is calculated by dividing width by height.

+ +
+ +

Search for images by file size

+ +
+
filesize=1
+

Returns images exactly 1 byte in size.

+
+ +
+
filesize>100mb
+

Returns images greater than 100 megabytes in size.

+
+ +

Can use <, <=, >, >=, or =. Supported suffixes are kb, mb, and gb. Uses multiples of 1024.

+ +
+ +

Search for images by MD5 hash

+ +
+
hash=0D3512CAA964B2BA5D7851AF5951F33B
+

Returns image with an MD5 hash 0D3512CAA964B2BA5D7851AF5951F33B.

+
+ +
+ +

Search for images by file type

+ +
+
filetype=jpg
+

Returns images that are of type "jpg".

+
+ +
+ +

Search for images by file name

+ +
+
filename=picasso.jpg
+

Returns images that are named "picasso.jpg".

+
+ +
+ +

Search for images by source

+ +
+
source=http://google.com/
+

Returns images with a source of "http://google.com/".

+
+ +
+
source=any
+

Returns images with a source set.

+
+ +
+
source=none
+

Returns images without a source set.

+
+ +
+ +

Search for images by date posted.

+ +
+
posted>=07-19-2019
+

Returns images posted on or after 07-19-2019.

+
+ +

Can use <, <=, >, >=, or =. Date format is mm-dd-yyyy. Date posted includes time component, so = will not work unless the time is exact.

+ +
+ +

Search for images by image dimensions

+ +
+
size=640x480
+

Returns images exactly 640 pixels wide by 480 pixels high.

+
+ +
+
size>1920x1080
+

Returns images with a width larger than 1920 and a height larger than 1080.

+
+ +
+
width=1000
+

Returns images exactly 1000 pixels wide.

+
+ +
+
height=1000
+

Returns images exactly 1000 pixels high.

+
+ +

Can use <, <=, >, >=, or =.

+ +
+ +

Sorting search results can be done using the pattern order:field_direction. _direction can be either _asc or _desc, indicating ascending (123) or descending (321) order.

+ +
+
order:id_asc
+

Returns images sorted by ID, smallest first.

+
+ +
+
order:width_desc
+

Returns images sorted by width, largest first.

+
+ +

These fields are supported: +

+

+ '; + + } } diff --git a/ext/ipban/main.php b/ext/ipban/main.php index d6feb092..90eb198a 100644 --- a/ext/ipban/main.php +++ b/ext/ipban/main.php @@ -66,7 +66,7 @@ class IPBan extends Extension { if ($event->page_matches("ip_ban")) { global $page, $user; - if ($user->can("ban_ip")) { + if ($user->can(Permissions::BAN_IP)) { if ($event->get_arg(0) == "add" && $user->check_auth_token()) { if (isset($_POST['ip']) && isset($_POST['reason']) && isset($_POST['end'])) { if (empty($_POST['end'])) { @@ -105,10 +105,20 @@ class IPBan extends Extension $event->panel->add_block($sb); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::BAN_IP)) { + $event->add_nav_link("ip_bans", new Link('ip_ban/list'), "IP Bans", NavLink::is_active(["ip_ban"])); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("ban_ip")) { + if ($user->can(Permissions::BAN_IP)) { $event->add_link("IP Bans", make_link("ip_ban/list")); } } diff --git a/ext/log_db/main.php b/ext/log_db/main.php index 2f1d761a..4002b68c 100644 --- a/ext/log_db/main.php +++ b/ext/log_db/main.php @@ -48,7 +48,7 @@ class LogDatabase extends Extension { global $database, $user; if ($event->page_matches("log/view")) { - if ($user->can("view_eventlog")) { + if ($user->can(Permissions::VIEW_EVENTLOG)) { $wheres = []; $args = []; $page_num = int_escape($event->get_arg(0)); @@ -120,10 +120,20 @@ class LogDatabase extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::VIEW_EVENTLOG)) { + $event->add_nav_link("event_log", new Link('log/view'), "Event Log"); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("view_eventlog")) { + if ($user->can(Permissions::VIEW_EVENTLOG)) { $event->add_link("Event Log", make_link("log/view")); } } diff --git a/ext/media/main.php b/ext/media/main.php index a4fba3ba..012507b3 100644 --- a/ext/media/main.php +++ b/ext/media/main.php @@ -316,7 +316,7 @@ class Media extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user; - if ($user->can("delete_image")) { + if ($user->can(Permissions::DELETE_IMAGE)) { $event->add_part($this->theme->get_buttons_html($event->image->id)); } } @@ -419,6 +419,17 @@ class Media extends Extension } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Media"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + + public function onTagTermParse(TagTermParseEvent $event) { $matches = []; diff --git a/ext/media/theme.php b/ext/media/theme.php index 12d77f32..7871ee69 100644 --- a/ext/media/theme.php +++ b/ext/media/theme.php @@ -28,4 +28,20 @@ class MediaTheme extends Themelet "; } + + public function get_help_html() + { + return '

Search for items based on the type of media.

+
+
content:audio
+

Returns items that contain audio, including videos and audio files.

+
+
+
content:video
+

Returns items that contain video, including animated GIFs.

+
+

These search terms depend on the items being scanned for media content. Automatic scanning was implemented in mid-2019, so items uploaded before, or items uploaded on a system without ffmpeg, will require additional scanning before this will work.

+ '; + + } } diff --git a/ext/not_a_tag/main.php b/ext/not_a_tag/main.php index 18486e9c..369ab0ff 100644 --- a/ext/not_a_tag/main.php +++ b/ext/not_a_tag/main.php @@ -58,10 +58,20 @@ class NotATag extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="tags") { + if ($user->can(Permissions::BAN_IMAGE)) { + $event->add_nav_link("untags", new Link('untag/list/1'), "UnTags"); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("ban_image")) { + if ($user->can(Permissions::BAN_IMAGE)) { $event->add_link("UnTags", make_link("untag/list/1")); } } @@ -71,7 +81,7 @@ class NotATag extends Extension global $database, $page, $user; if ($event->page_matches("untag")) { - if ($user->can("ban_image")) { + if ($user->can(Permissions::BAN_IMAGE)) { if ($event->get_arg(0) == "add") { $tag = $_POST["tag"]; $redirect = isset($_POST['redirect']) ? $_POST['redirect'] : "DNP"; diff --git a/ext/notes/main.php b/ext/notes/main.php index aafa928f..18c45f82 100644 --- a/ext/notes/main.php +++ b/ext/notes/main.php @@ -210,12 +210,22 @@ class Notes extends Extension } $event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM notes WHERE user_id = $user_id)")); - } elseif (preg_match("/^notes_by_userno[=|:](\d+)$/i", $event->term, $matches)) { - $user_id = int_escape($matches[1]); + } elseif (preg_match("/^(notes_by_userno|notes_by_user_id)[=|:](\d+)$/i", $event->term, $matches)) { + $user_id = int_escape($matches[2]); $event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM notes WHERE user_id = $user_id)")); } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Notes"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + /** * HERE WE GET ALL NOTES FOR DISPLAYED IMAGE. diff --git a/ext/notes/theme.php b/ext/notes/theme.php index 912ec615..6878c9c2 100644 --- a/ext/notes/theme.php +++ b/ext/notes/theme.php @@ -247,4 +247,29 @@ class NotesTheme extends Themelet $this->display_paginator($page, "note/updated", null, $pageNumber, $totalPages); } + + public function get_help_html() + { + return '

Search for images with notes.

+
+
note=noted
+

Returns images with a note matching "noted".

+
+
+
notes>0
+

Returns images with 1 or more notes.

+
+

Can use <, <=, >, >=, or =.

+
+
notes_by=username
+

Returns images with note(s) by "username".

+
+
+
notes_by_user_id=123
+

Returns images with note(s) by user 123.

+
+ '; + + } + } diff --git a/ext/numeric_score/main.php b/ext/numeric_score/main.php index 5275dfa7..0b93c369 100644 --- a/ext/numeric_score/main.php +++ b/ext/numeric_score/main.php @@ -45,7 +45,7 @@ class NumericScore extends Extension public function onUserPageBuilding(UserPageBuildingEvent $event) { global $user; - if ($user->can("edit_other_vote")) { + if ($user->can(Permissions::EDIT_OTHER_VOTE)) { $this->theme->get_nuller($event->display_user); } @@ -98,7 +98,7 @@ class NumericScore extends Extension $page->set_redirect(make_link("post/view/$image_id")); } } elseif ($event->page_matches("numeric_score/remove_votes_on") && $user->check_auth_token()) { - if ($user->can("edit_other_vote")) { + if ($user->can(Permissions::EDIT_OTHER_VOTE)) { $image_id = int_escape($_POST['image_id']); $database->execute( "DELETE FROM numeric_score_votes WHERE image_id=?", @@ -112,7 +112,7 @@ class NumericScore extends Extension $page->set_redirect(make_link("post/view/$image_id")); } } elseif ($event->page_matches("numeric_score/remove_votes_by") && $user->check_auth_token()) { - if ($user->can("edit_other_vote")) { + if ($user->can(Permissions::EDIT_OTHER_VOTE)) { $this->delete_votes_by(int_escape($_POST['user_id'])); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link()); @@ -228,6 +228,16 @@ class NumericScore extends Extension $event->replace('$score', $event->image->numeric_score); } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Numeric Score"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + public function onSearchTermParse(SearchTermParseEvent $event) { $matches = []; @@ -294,6 +304,16 @@ class NumericScore extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="posts") { + $event->add_nav_link("numeric_score_day", new Link('popular_by_day'), "Popular by Day"); + $event->add_nav_link("numeric_score_month", new Link('popular_by_month'), "Popular by Month"); + $event->add_nav_link("numeric_score_year", new Link('popular_by_year'), "Popular by Year"); + + } + } + private function install() { global $database; diff --git a/ext/numeric_score/theme.php b/ext/numeric_score/theme.php index c2dc31c7..e6dbe7fa 100644 --- a/ext/numeric_score/theme.php +++ b/ext/numeric_score/theme.php @@ -32,7 +32,7 @@ class NumericScoreTheme extends Themelet "; - if ($user->can("edit_other_vote")) { + if ($user->can(Permissions::EDIT_OTHER_VOTE)) { $html .= "
".$user->get_auth_html()." @@ -87,8 +87,51 @@ class NumericScoreTheme extends Themelet $nav_html = "Index"; - $page->set_heading($config->get_string('title')); + $page->set_heading($config->get_string(SetupConfig::TITLE)); $page->add_block(new Block("Navigation", $nav_html, "left", 10)); $page->add_block(new Block(null, $html, "main", 30)); } + + + public function get_help_html() + { + return '

Search for images that have received numeric scores by the score or by the scorer.

+
+
score=1
+

Returns images with a score of 1.

+
+
+
score>0
+

Returns images with a score of 1 or more.

+
+

Can use <, <=, >, >=, or =.

+ +
+
upvoted_by=username
+

Returns images upvoted by "username".

+
+
+
upvoted_by_id=123
+

Returns images upvoted by user 123.

+
+
+
downvoted_by=username
+

Returns images downvoted by "username".

+
+
+
downvoted_by_id=123
+

Returns images downvoted by user 123.

+
+ +
+
order:score_desc
+

Sorts the search results by score, descending.

+
+
+
order:score_asc
+

Sorts the search results by score, ascending.

+
+ '; + + } } diff --git a/ext/oekaki/main.php b/ext/oekaki/main.php index 1da9cc90..94e1b061 100644 --- a/ext/oekaki/main.php +++ b/ext/oekaki/main.php @@ -12,7 +12,7 @@ class Oekaki extends Extension global $user, $page; if ($event->page_matches("oekaki")) { - if ($user->can("create_image")) { + if ($user->can(Permissions::CREATE_IMAGE)) { if ($event->get_arg(0) == "create") { $this->theme->display_page(); $this->theme->display_block(); @@ -84,7 +84,7 @@ class Oekaki extends Extension public function onPostListBuilding(PostListBuildingEvent $event) { global $user; - if ($user->can("create_image")) { + if ($user->can(Permissions::CREATE_IMAGE)) { $this->theme->display_block(); } } diff --git a/ext/ouroboros_api/main.php b/ext/ouroboros_api/main.php index d701fbea..d654b6f0 100644 --- a/ext/ouroboros_api/main.php +++ b/ext/ouroboros_api/main.php @@ -410,7 +410,7 @@ class OuroborosAPI extends Extension if ($event->page_matches('post')) { if ($this->match('create')) { // Create - if ($user->can("create_image")) { + if ($user->can(Permissions::CREATE_IMAGE)) { $md5 = !empty($_REQUEST['md5']) ? filter_var($_REQUEST['md5'], FILTER_SANITIZE_STRING) : null; $this->postCreate(new OuroborosPost($_REQUEST['post']), $md5); } else { diff --git a/ext/pm/main.php b/ext/pm/main.php index 123d6368..d2c7f44d 100644 --- a/ext/pm/main.php +++ b/ext/pm/main.php @@ -93,6 +93,19 @@ class PrivMsg extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="user") { + if (!$user->is_anonymous()) { + $count = $this->count_pms($user); + $h_count = $count > 0 ? " ($count)" : ""; + $event->add_nav_link("pm", new Link('user#private-messages'), "Private Messages$h_count"); + } + } + } + + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; @@ -108,7 +121,7 @@ class PrivMsg extends Extension global $page, $user; $duser = $event->display_user; if (!$user->is_anonymous() && !$duser->is_anonymous()) { - if (($user->id == $duser->id) || $user->can("view_other_pms")) { + if (($user->id == $duser->id) || $user->can(Permissions::VIEW_OTHER_PMS)) { $this->theme->display_pms($page, $this->get_pms($duser)); } if ($user->id != $duser->id) { @@ -128,7 +141,7 @@ class PrivMsg extends Extension $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]); if (is_null($pm)) { $this->theme->display_error(404, "No such PM", "There is no PM #$pm_id"); - } elseif (($pm["to_id"] == $user->id) || $user->can("view_other_pms")) { + } elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) { $from_user = User::by_id(int_escape($pm["from_id"])); if ($pm["to_id"] == $user->id) { $database->execute("UPDATE private_message SET is_read='Y' WHERE id = :id", ["id" => $pm_id]); @@ -145,7 +158,7 @@ class PrivMsg extends Extension $pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]); if (is_null($pm)) { $this->theme->display_error(404, "No such PM", "There is no PM #$pm_id"); - } elseif (($pm["to_id"] == $user->id) || $user->can("view_other_pms")) { + } elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) { $database->execute("DELETE FROM private_message WHERE id = :id", ["id" => $pm_id]); $database->cache->delete("pm-count-{$user->id}"); log_info("pm", "Deleted PM #$pm_id", "PM deleted"); diff --git a/ext/pm/theme.php b/ext/pm/theme.php index bb9a0f49..f69240d9 100644 --- a/ext/pm/theme.php +++ b/ext/pm/theme.php @@ -27,7 +27,7 @@ class PrivMsgTheme extends Themelet $h_subject = "$h_subject"; $readYN = "N"; } - $hb = $from->can("hellbanned") ? "hb" : ""; + $hb = $from->can(Permissions::HELLBANNED) ? "hb" : ""; $html .= " $readYN $h_subject diff --git a/ext/pools/main.php b/ext/pools/main.php index 37a1cc01..71d3f492 100644 --- a/ext/pools/main.php +++ b/ext/pools/main.php @@ -145,6 +145,23 @@ class Pools extends Extension $event->panel->add_block($sb); } + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("pool", new Link('pool/list'), "Pools"); + } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="pool") { + $event->add_nav_link("pool_list", new Link('pool/list'), "List"); + $event->add_nav_link("pool_new", new Link('pool/new'), "Create"); + $event->add_nav_link("pool_updated", new Link('pool/updated'), "Changes"); + $event->add_nav_link("pool_help", new Link('ext_doc/pools'), "Help"); + } + } + + + public function onPageRequest(PageRequestEvent $event) { global $page, $user, $database; @@ -355,6 +372,17 @@ class Pools extends Extension } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Pools"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + + public function onSearchTermParse(SearchTermParseEvent $event) { $matches = []; diff --git a/ext/pools/theme.php b/ext/pools/theme.php index bb798c8d..86a2406c 100644 --- a/ext/pools/theme.php +++ b/ext/pools/theme.php @@ -403,4 +403,32 @@ class PoolsTheme extends Themelet { return ""; } + + + public function get_help_html() + { + return '

Search for images that are in a pool.

+
+
pool=1
+

Returns images in pool #1.

+
+
+
pool=any
+

Returns images in any pool.

+
+
+
pool=none
+

Returns images not in any pool.

+
+
+
pool_by_name=swimming
+

Returns images in the "swimming" pool.

+
+
+
pool_by_name=swimming_pool
+

Returns images in the "swimming pool" pool. Note that the underscore becomes a space

+
+ '; + + } } diff --git a/ext/post_titles/config.php b/ext/post_titles/config.php new file mode 100644 index 00000000..5499bfad --- /dev/null +++ b/ext/post_titles/config.php @@ -0,0 +1,9 @@ +image = $image; + $this->title = $title; + } +} \ No newline at end of file diff --git a/ext/post_titles/main.php b/ext/post_titles/main.php new file mode 100644 index 00000000..50f550c3 --- /dev/null +++ b/ext/post_titles/main.php @@ -0,0 +1,107 @@ + + * License: MIT + * Description: Add titles to media posts + */ + +require_once "config.php"; +require_once "events/post_title_set_event.php"; + +class PostTitles extends Extension +{ + public function get_priority(): int + { + return 60; + } + + public function onInitExt(InitExtEvent $event) + { + global $config, $database; + + $config->set_default_bool(PostTitlesConfig::DEFAULT_TO_FILENAME, false); + $config->set_default_bool(PostTitlesConfig::SHOW_IN_WINDOW_TITLE, false); + + if ($config->get_int(PostTitlesConfig::VERSION) < 1) { + $this->install(); + } + } + + private function install() + { + global $config, $database; + + if ($config->get_int(PostTitlesConfig::VERSION) < 1) { + $database->Execute("ALTER TABLE images ADD COLUMN title varchar(255) NULL"); + $config->set_int(PostTitlesConfig::VERSION, 1); + } + } + + public function onDisplayingImage(DisplayingImageEvent $event) + { + global $config; + + if($config->get_bool(PostTitlesConfig::SHOW_IN_WINDOW_TITLE)) { + $event->set_title(self::get_title($event->get_image())); + } + } + + public function onImageInfoBoxBuilding(ImageInfoBoxBuildingEvent $event) + { + global $user; + + $event->add_part($this->theme->get_title_set_html(self::get_title($event->image), $user->can(Permissions::EDIT_IMAGE_TITLE)), 10); + } + + public function onImageInfoSet(ImageInfoSetEvent $event) + { + global $user; + + if ($user->can(Permissions::EDIT_IMAGE_TITLE) && isset($_POST["post_title"])) { + $title = $_POST["post_title"]; + send_event(new PostTitleSetEvent($event->image, $title)); + } + } + + public function onPostTitleSet(PostTitleSetEvent $event) + { + $this->set_title($event->image->id, $event->title); + } + + public function onSetupBuilding(SetupBuildingEvent $event) + { + $sb = new SetupBlock("Post Titles"); + $sb->start_table(); + $sb->add_bool_option(PostTitlesConfig::DEFAULT_TO_FILENAME,"Default to filename", true); + $sb->add_bool_option(PostTitlesConfig::SHOW_IN_WINDOW_TITLE,"Show in window title", true); + $sb->end_table(); + + $event->panel->add_block($sb); + } + + + + private function set_title(int $image_id, string $title) + { + global $database; + $database->Execute("UPDATE images SET title=? WHERE id=?", [$title, $image_id]); + log_info("post_titles", "Title for Image #{$image_id} set to: ".$title); + } + + public static function get_title(Image $image): string + { + global $config; + + $title = $image->title??""; + if(empty($title) && $config->get_bool(PostTitlesConfig::DEFAULT_TO_FILENAME)) { + $info = pathinfo($image->filename); + if(array_key_exists("extension",$info)) { + $title = basename($image->filename, '.' . $info['extension']); + } else { + $title = $image->filename; + } + } + return $title; + } +} diff --git a/ext/post_titles/theme.php b/ext/post_titles/theme.php new file mode 100644 index 00000000..53a6c1b5 --- /dev/null +++ b/ext/post_titles/theme.php @@ -0,0 +1,25 @@ + + Title + + ".($can_set ? " + ".html_escape($title)." + + + + " : html_escape(" + $title + "))." + + + "; + return $html; + } +} diff --git a/ext/random_image/main.php b/ext/random_image/main.php index fc0424f7..b03d21e4 100644 --- a/ext/random_image/main.php +++ b/ext/random_image/main.php @@ -75,4 +75,11 @@ class RandomImage extends Extension } } } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="posts") { + $event->add_nav_link("posts_random", new Link('random_image/view'), "Random Image"); + } + } } diff --git a/ext/random_list/main.php b/ext/random_list/main.php index 7333905d..47c55b9c 100644 --- a/ext/random_list/main.php +++ b/ext/random_list/main.php @@ -74,4 +74,11 @@ class RandomList extends Extension $event->panel->add_block($sb); } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="posts") { + $event->add_nav_link("posts_random", new Link('random'), "Shuffle"); + } + } } diff --git a/ext/rating/main.php b/ext/rating/main.php index 7b43d914..e4dc0180 100644 --- a/ext/rating/main.php +++ b/ext/rating/main.php @@ -126,6 +126,21 @@ class Ratings extends Extension $event->replace('$rating', $this->rating_to_human($event->image->rating)); } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + global $user; + + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Ratings"; + + $ratings = self::get_sorted_ratings(); + + $block->body = $this->theme->get_help_html($ratings); + $event->add_block($block); + } + } + public function onSearchTermParse(SearchTermParseEvent $event) { global $user; @@ -169,7 +184,7 @@ class Ratings extends Extension { global $user; - if ($user->can("bulk_edit_image_rating")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_RATING)) { $event->add_action("bulk_rate","Set (R)ating", "r","",$this->theme->get_selection_rater_html("u","bulk_rating")); } } @@ -183,7 +198,7 @@ class Ratings extends Extension if (!isset($_POST['bulk_rating'])) { return; } - if ($user->can("bulk_edit_image_rating")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_RATING)) { $rating = $_POST['bulk_rating']; $total = 0; foreach ($event->items as $image) { @@ -201,7 +216,7 @@ class Ratings extends Extension global $user, $page; if ($event->page_matches("admin/bulk_rate")) { - if (!$user->can("bulk_edit_image_rating")) { + if (!$user->can(Permissions::BULK_EDIT_IMAGE_RATING)) { throw new PermissionDeniedException(); } else { $n = 0; diff --git a/ext/rating/theme.php b/ext/rating/theme.php index d414e3f6..faec02dc 100644 --- a/ext/rating/theme.php +++ b/ext/rating/theme.php @@ -55,4 +55,32 @@ class RatingsTheme extends Themelet "; } + + public function get_help_html(array $ratings) + { + $output = '

Search for images with one or more possible ratings.

+
+
rating:'.$ratings[0]->search_term.'
+

Returns images with the '.$ratings[0]->name.' rating.

+
+

Ratings can be abbreviated to a single letter as well

+
+
rating:'.$ratings[0]->code.'
+

Returns images with the '.$ratings[0]->name.' rating.

+
+

If abbreviations are used, multiple ratings can be searched for.

+
+
rating:'.$ratings[0]->code.$ratings[1]->code.'
+

Returns images with the '.$ratings[0]->name.' or '.$ratings[1]->name.' rating.

+
+

Available ratings:

+ + + '; + foreach ($ratings as $rating) { + $output .= ""; + } + $output .= "
NameSearch TermAbbreviation
{$rating->name}{$rating->search_term}{$rating->code}
"; + return $output; + } } diff --git a/ext/regen_thumb/main.php b/ext/regen_thumb/main.php index 637febbf..62e80664 100644 --- a/ext/regen_thumb/main.php +++ b/ext/regen_thumb/main.php @@ -28,14 +28,14 @@ class RegenThumb extends Extension { global $database, $page, $user; - if ($event->page_matches("regen_thumb/one") && $user->can("delete_image") && isset($_POST['image_id'])) { + if ($event->page_matches("regen_thumb/one") && $user->can(Permissions::DELETE_IMAGE) && isset($_POST['image_id'])) { $image = Image::by_id(int_escape($_POST['image_id'])); $this->regenerate_thumbnail($image); $this->theme->display_results($page, $image); } - if ($event->page_matches("regen_thumb/mass") && $user->can("delete_image") && isset($_POST['tags'])) { + if ($event->page_matches("regen_thumb/mass") && $user->can(Permissions::DELETE_IMAGE) && isset($_POST['tags'])) { $tags = Tag::explode(strtolower($_POST['tags']), false); $images = Image::find_images(0, 10000, $tags); @@ -51,7 +51,7 @@ class RegenThumb extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user; - if ($user->can("delete_image")) { + if ($user->can(Permissions::DELETE_IMAGE)) { $event->add_part($this->theme->get_buttons_html($event->image->id)); } } @@ -59,7 +59,7 @@ class RegenThumb extends Extension // public function onPostListBuilding(PostListBuildingEvent $event) // { // global $user; - // if ($user->can("delete_image") && !empty($event->search_terms)) { + // if ($user->can(UserAbilities::DELETE_IMAGE) && !empty($event->search_terms)) { // $event->add_control($this->theme->mtr_html(Tag::implode($event->search_terms))); // } // } @@ -68,7 +68,7 @@ class RegenThumb extends Extension { global $user; - if ($user->can("delete_image")) { + if ($user->can(Permissions::DELETE_IMAGE)) { $event->add_action("bulk_regen", "Regen Thumbnails", "","", $this->theme->bulk_html()); } } @@ -79,7 +79,7 @@ class RegenThumb extends Extension switch ($event->action) { case "bulk_regen": - if ($user->can("delete_image")) { + if ($user->can(Permissions::DELETE_IMAGE)) { $force = true; if (isset($_POST["bulk_regen_thumb_missing_only"]) &&$_POST["bulk_regen_thumb_missing_only"]=="true") { diff --git a/ext/relatationships/main.php b/ext/relatationships/main.php index eaae08b9..905bc1e8 100644 --- a/ext/relatationships/main.php +++ b/ext/relatationships/main.php @@ -81,6 +81,17 @@ class Relationships extends Extension } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Relationships"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + + public function onTagTermParse(TagTermParseEvent $event) { $matches = []; diff --git a/ext/relatationships/theme.php b/ext/relatationships/theme.php index 15c92310..40c0fe8c 100644 --- a/ext/relatationships/theme.php +++ b/ext/relatationships/theme.php @@ -46,4 +46,32 @@ class RelationshipsTheme extends Themelet "\n"; return $html; } + + + public function get_help_html() + { + return '

Search for images that have parent/child relationships.

+
+
parent=any
+

Returns images that have a parent.

+
+
+
parent=none
+

Returns images that have no parent.

+
+
+
parent=123
+

Returns images that have image 123 set as parent.

+
+
+
child=any
+

Returns images that have at least 1 child.

+
+
+
child=none
+

Returns images that have no children.

+
+ '; + + } } diff --git a/ext/report_image/main.php b/ext/report_image/main.php index d3ee2c81..d5436e6b 100644 --- a/ext/report_image/main.php +++ b/ext/report_image/main.php @@ -74,7 +74,7 @@ class ReportImage extends Extension } } elseif ($event->get_arg(0) == "remove") { if (!empty($_POST['id'])) { - if ($user->can("view_image_report")) { + if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { send_event(new RemoveReportedImageEvent($_POST['id'])); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("image_report/list")); @@ -83,13 +83,13 @@ class ReportImage extends Extension $this->theme->display_error(500, "Missing input", "Missing image ID"); } } elseif ($event->get_arg(0) == "remove_reports_by" && $user->check_auth_token()) { - if ($user->can("view_image_report")) { + if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { $this->delete_reports_by(int_escape($_POST['user_id'])); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link()); } } elseif ($event->get_arg(0) == "list") { - if ($user->can("view_image_report")) { + if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { $this->theme->display_reported_images($page, $this->get_reported_images()); } } @@ -118,7 +118,7 @@ class ReportImage extends Extension public function onUserPageBuilding(UserPageBuildingEvent $event) { global $user; - if ($user->can("view_image_report")) { + if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { $this->theme->get_nuller($event->display_user); } } @@ -126,16 +126,30 @@ class ReportImage extends Extension public function onDisplayingImage(DisplayingImageEvent $event) { global $user; - if ($user->can('create_image_report')) { + if ($user->can(Permissions::CREATE_IMAGE_REPORT)) { $reps = $this->get_reports($event->image); $this->theme->display_image_banner($event->image, $reps); } } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { + $count = $this->count_reported_images(); + $h_count = $count > 0 ? " ($count)" : ""; + + $event->add_nav_link("image_report", new Link('image_report/list'), "Reported Images$h_count"); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("view_image_report")) { + if ($user->can(Permissions::VIEW_IMAGE_REPORT)) { $count = $this->count_reported_images(); $h_count = $count > 0 ? " ($count)" : ""; $event->add_link("Reported Images$h_count", make_link("image_report/list")); diff --git a/ext/rss_comments/main.php b/ext/rss_comments/main.php index b00f92aa..f64869e1 100644 --- a/ext/rss_comments/main.php +++ b/ext/rss_comments/main.php @@ -14,7 +14,7 @@ class RSS_Comments extends Extension public function onPostListBuilding(PostListBuildingEvent $event) { global $config, $page; - $title = $config->get_string('title'); + $title = $config->get_string(SetupConfig::TITLE); $page->add_html_header(""); @@ -60,7 +60,7 @@ class RSS_Comments extends Extension "; } - $title = $config->get_string('title'); + $title = $config->get_string(SetupConfig::TITLE); $base_href = make_http(get_base_href()); $version = $config->get_string('version'); $xml = <<set_data($xml); } } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="comment") { + $event->add_nav_link("comment_rss", new Link('rss/comments'), "Feed"); + } + } + } diff --git a/ext/rss_images/main.php b/ext/rss_images/main.php index b11fad92..6e5f9026 100644 --- a/ext/rss_images/main.php +++ b/ext/rss_images/main.php @@ -12,7 +12,7 @@ class RSS_Images extends Extension public function onPostListBuilding(PostListBuildingEvent $event) { global $config, $page; - $title = $config->get_string('title'); + $title = $config->get_string(SetupConfig::TITLE); if (count($event->search_terms) > 0) { $search = html_escape(implode(' ', $event->search_terms)); @@ -47,7 +47,7 @@ class RSS_Images extends Extension $data .= $this->thumb($image); } - $title = $config->get_string('title'); + $title = $config->get_string(SetupConfig::TITLE); $base_href = make_http(get_base_href()); $search = ""; if (count($search_terms) > 0) { @@ -116,4 +116,11 @@ class RSS_Images extends Extension return $data; } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="posts") { + $event->add_nav_link("posts_rss", new Link('rss/images'), "Feed"); + } + } } diff --git a/ext/rule34/main.php b/ext/rule34/main.php index b26fb166..3e9c650c 100644 --- a/ext/rule34/main.php +++ b/ext/rule34/main.php @@ -50,7 +50,7 @@ class Rule34 extends Extension public function onUserPageBuilding(UserPageBuildingEvent $event) { global $database, $user, $config; - if ($user->can("change_setting") && $config->get_bool('r34_comic_integration')) { + if ($user->can(Permissions::CHANGE_SETTING) && $config->get_bool('r34_comic_integration')) { $current_state = bool_escape($database->get_one("SELECT comic_admin FROM users WHERE id=?", [$event->display_user->id])); $this->theme->show_comic_changer($event->display_user, $current_state); } @@ -59,7 +59,7 @@ class Rule34 extends Extension public function onThumbnailGeneration(ThumbnailGenerationEvent $event) { global $database, $user; - if ($user->can("manage_admintools")) { + if ($user->can(Permissions::MANAGE_ADMINTOOLS)) { $database->execute("NOTIFY shm_image_bans, '{$event->hash}';"); } } @@ -72,7 +72,7 @@ class Rule34 extends Extension { global $database, $page, $user; - if ($user->can("delete_user")) { // deleting users can take a while + if ($user->can(Permissions::DELETE_USER)) { // deleting users can take a while $database->execute("SET statement_timeout TO ".(DATABASE_TIMEOUT+15000).";"); } @@ -81,7 +81,7 @@ class Rule34 extends Extension } if ($event->page_matches("rule34/comic_admin")) { - if ($user->can("change_setting") && $user->check_auth_token()) { + if ($user->can(Permissions::CHANGE_SETTING) && $user->check_auth_token()) { $input = validate_input([ 'user_id' => 'user_id,exists', 'is_admin' => 'bool', @@ -102,7 +102,7 @@ class Rule34 extends Extension } if ($event->page_matches("admin/cache_purge")) { - if (!$user->can("manage_admintools")) { + if (!$user->can(Permissions::MANAGE_ADMINTOOLS)) { $this->theme->display_permission_denied(); } else { if ($user->check_auth_token()) { @@ -130,7 +130,7 @@ class Rule34 extends Extension if ($event->page_matches("sys_ip_ban")) { global $page, $user; - if ($user->can("ban_ip")) { + if ($user->can(Permissions::BAN_IP)) { if ($event->get_arg(0) == "list") { $bans = (isset($_GET["all"])) ? $this->get_bans() : $this->get_active_bans(); $this->theme->display_bans($page, $bans); diff --git a/ext/setup/config.php b/ext/setup/config.php new file mode 100644 index 00000000..2b5be64e --- /dev/null +++ b/ext/setup/config.php @@ -0,0 +1,12 @@ +set_default_string("title", "Shimmie"); - $config->set_default_string("front_page", "post/list"); - $config->set_default_string("main_page", "post/list"); - $config->set_default_string("theme", "default"); - $config->set_default_bool("word_wrap", true); - $config->set_default_bool("comment_captcha", false); + $config->set_default_string(SetupConfig::TITLE, "Shimmie"); + $config->set_default_string(SetupConfig::FRONT_PAGE, "post/list"); + $config->set_default_string(SetupConfig::MAIN_PAGE, "post/list"); + $config->set_default_string(SetupConfig::THEME, "default"); + $config->set_default_bool(SetupConfig::WORD_WRAP, true); } public function onPageRequest(PageRequestEvent $event) @@ -293,7 +294,7 @@ class Setup extends Extension } if ($event->page_matches("setup")) { - if (!$user->can("change_setting")) { + if (!$user->can(Permissions::CHANGE_SETTING)) { $this->theme->display_permission_denied(); } else { if ($event->get_arg(0) == "save" && $user->check_auth_token()) { @@ -368,11 +369,11 @@ class Setup extends Extension "; $sb = new SetupBlock("General"); $sb->position = 0; - $sb->add_text_option("title", "Site title: "); - $sb->add_text_option("front_page", "
Front page: "); - $sb->add_text_option("main_page", "
Main page: "); + $sb->add_text_option(SetupConfig::TITLE, "Site title: "); + $sb->add_text_option(SetupConfig::FRONT_PAGE, "
Front page: "); + $sb->add_text_option(SetupConfig::MAIN_PAGE, "
Main page: "); $sb->add_text_option("contact_link", "
Contact URL: "); - $sb->add_choice_option("theme", $themes, "
Theme: "); + $sb->add_choice_option(SetupConfig::THEME, $themes, "
Theme: "); //$sb->add_multichoice_option("testarray", array("a" => "b", "c" => "d"), "
Test Array: "); $sb->add_bool_option("nice_urls", "
Nice URLs: "); $sb->add_label("(Javascript inactive, can't test!)$nicescript"); @@ -410,10 +411,20 @@ class Setup extends Extension log_warning("setup", "Cache cleared"); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::CHANGE_SETTING)) { + $event->add_nav_link("setup", new Link('setup'), "Board Config", null, 0); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("change_setting")) { + if ($user->can(Permissions::CHANGE_SETTING)) { $event->add_link("Board Config", make_link("setup")); } } diff --git a/ext/sitemap/main.php b/ext/sitemap/main.php index 4ff80f88..6bf8b4a3 100644 --- a/ext/sitemap/main.php +++ b/ext/sitemap/main.php @@ -74,7 +74,7 @@ class XMLSitemap extends Extension // add index $index = []; - $index[0] = $config->get_string("front_page"); + $index[0] = $config->get_string(SetupConfig::FRONT_PAGE); $this->add_sitemap_queue($index, "weekly", "1"); /* --- Add 20 most used tags --- */ diff --git a/ext/source_history/main.php b/ext/source_history/main.php index 591fd217..3fd47cab 100644 --- a/ext/source_history/main.php +++ b/ext/source_history/main.php @@ -35,13 +35,13 @@ class Source_History extends Extension if ($event->page_matches("source_history/revert")) { // this is a request to revert to a previous version of the source - if ($user->can("edit_image_tag")) { + if ($user->can(Permissions::EDIT_IMAGE_TAG)) { if (isset($_POST['revert'])) { $this->process_revert_request($_POST['revert']); } } } elseif ($event->page_matches("source_history/bulk_revert")) { - if ($user->can("bulk_edit_image_tag") && $user->check_auth_token()) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG) && $user->check_auth_token()) { $this->process_bulk_revert_request(); } } elseif ($event->page_matches("source_history/all")) { @@ -82,10 +82,20 @@ class Source_History extends Extension $this->add_source_history($event->image, $event->source); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG)) { + $event->add_nav_link("source_history", new Link('source_history/all/1'), "Source Changes", NavLink::is_active(["source_history"])); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("bulk_edit_image_tag")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG)) { $event->add_link("Source Changes", make_link("source_history/all/1")); } } diff --git a/ext/source_history/theme.php b/ext/source_history/theme.php index 9d6faeac..fbe5a332 100644 --- a/ext/source_history/theme.php +++ b/ext/source_history/theme.php @@ -20,7 +20,7 @@ class Source_HistoryTheme extends Themelet $current_source = html_escape($fields['source']); $name = $fields['name']; $date_set = autodate($fields['date_set']); - $h_ip = $user->can("view_ip") ? " ".show_ip($fields['user_ip'], "Sourcing Image #$image_id as '$current_source'") : ""; + $h_ip = $user->can(Permissions::VIEW_IP) ? " ".show_ip($fields['user_ip'], "Sourcing Image #$image_id as '$current_source'") : ""; $setter = "".html_escape($name)."$h_ip"; $selected = ($n == 2) ? " checked" : ""; @@ -72,7 +72,7 @@ class Source_HistoryTheme extends Themelet $image_id = $fields['image_id']; $current_source = html_escape($fields['source']); $name = $fields['name']; - $h_ip = $user->can("view_ip") ? " ".show_ip($fields['user_ip'], "Sourcing Image #$image_id as '$current_source'") : ""; + $h_ip = $user->can(Permissions::VIEW_IP) ? " ".show_ip($fields['user_ip'], "Sourcing Image #$image_id as '$current_source'") : ""; $setter = "".html_escape($name)."$h_ip"; $history_list .= ' diff --git a/ext/system/main.php b/ext/system/main.php new file mode 100644 index 00000000..2cce82c1 --- /dev/null +++ b/ext/system/main.php @@ -0,0 +1,31 @@ + + * License: MIT + * Description: Provides system screen + */ + +class System extends Extension +{ + public function onPageRequest(PageRequestEvent $event) + { + global $page, $user; + + if ($event->page_matches("system")) { + $e = new PageSubNavBuildingEvent("system"); + send_event($e); + usort($e->links, "sort_nav_links"); + $link = $e->links[0]->link; + + $page->set_redirect($link->make_link()); + $page->set_mode(PageMode::REDIRECT); + } + } + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("system", new Link('system'), "System"); + } + + +} diff --git a/ext/tag_categories/config.php b/ext/tag_categories/config.php new file mode 100644 index 00000000..ee6b6637 --- /dev/null +++ b/ext/tag_categories/config.php @@ -0,0 +1,8 @@ +set_default_bool("tag_categories_split_on_view", true); + $config->set_default_bool(TagCategoriesConfig::SPLIT_ON_VIEW, true); - if ($config->get_int("ext_tag_categories_version") < 1) { + if ($config->get_int(TagCategoriesConfig::VERSION) < 1) { // primary extension database, holds all our stuff! $database->create_table( 'image_tag_categories', @@ -26,7 +28,7 @@ class TagCategories extends Extension color VARCHAR(7)' ); - $config->set_int("ext_tag_categories_version", 1); + $config->set_int(TagCategoriesConfig::VERSION, 1); log_info("tag_categories", "extension installed"); } @@ -68,11 +70,12 @@ class TagCategories extends Extension if (preg_match("/^(.+)tags([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])([0-9]+)$/i", $event->term, $matches)) { global $database; - $type = $matches[1]; + $type = strtolower($matches[1]); $cmp = ltrim($matches[2], ":") ?: "="; $count = $matches[3]; - $types = $database->get_col('SELECT category FROM image_tag_categories'); + $types = $database->get_col( + $database->scoreql_to_sql('SELECT SCORE_STRNORM(category) FROM image_tag_categories')); if (in_array($type, $types)) { $event->add_querylet( new Querylet($database->scoreql_to_sql("EXISTS ( @@ -88,6 +91,16 @@ class TagCategories extends Extension } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Tag Categories"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + public function getDict() { global $database; diff --git a/ext/tag_categories/theme.php b/ext/tag_categories/theme.php index df09beaf..c1894a27 100644 --- a/ext/tag_categories/theme.php +++ b/ext/tag_categories/theme.php @@ -98,4 +98,21 @@ class TagCategoriesTheme extends Themelet // add html to stuffs $page->add_block(new Block("Editing", $html, "main", 10)); } + + public function get_help_html() + { + return '

Search for images containing a certain number of tags with the specified tag category.

+
+
persontags=1
+

Returns images with exactly 1 tag with the tag category "person".

+
+
+
cattags>0
+

Returns images with 1 or more tags with the tag category "cat".

+
+

Can use <, <=, >, >=, or =.

+

Category name is not case sensitive, category must exist for search to work.

+ '; + + } } diff --git a/ext/tag_edit/main.php b/ext/tag_edit/main.php index aa443797..df6d8b43 100644 --- a/ext/tag_edit/main.php +++ b/ext/tag_edit/main.php @@ -161,7 +161,7 @@ class TagEdit extends Extension global $user, $page; if ($event->page_matches("tag_edit")) { if ($event->get_arg(0) == "replace") { - if ($user->can("mass_tag_edit") && isset($_POST['search']) && isset($_POST['replace'])) { + if ($user->can(Permissions::MASS_TAG_EDIT) && isset($_POST['search']) && isset($_POST['replace'])) { $search = $_POST['search']; $replace = $_POST['replace']; $this->mass_tag_edit($search, $replace); @@ -170,7 +170,7 @@ class TagEdit extends Extension } } if ($event->get_arg(0) == "mass_source_set") { - if ($user->can("mass_tag_edit") && isset($_POST['tags']) && isset($_POST['source'])) { + if ($user->can(Permissions::MASS_TAG_EDIT) && isset($_POST['tags']) && isset($_POST['source'])) { $this->mass_source_edit($_POST['tags'], $_POST['source']); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); @@ -182,7 +182,7 @@ class TagEdit extends Extension // public function onPostListBuilding(PostListBuildingEvent $event) // { // global $user; - // if ($user->can("bulk_edit_image_source") && !empty($event->search_terms)) { + // if ($user->can(UserAbilities::BULK_EDIT_IMAGE_SOURCE) && !empty($event->search_terms)) { // $event->add_control($this->theme->mss_html(Tag::implode($event->search_terms))); // } // } @@ -190,7 +190,7 @@ class TagEdit extends Extension public function onImageInfoSet(ImageInfoSetEvent $event) { global $user; - if ($user->can("edit_image_owner") && isset($_POST['tag_edit__owner'])) { + if ($user->can(Permissions::EDIT_IMAGE_OWNER) && isset($_POST['tag_edit__owner'])) { $owner = User::by_name($_POST['tag_edit__owner']); if ($owner instanceof User) { send_event(new OwnerSetEvent($event->image, $owner)); @@ -206,7 +206,7 @@ class TagEdit extends Extension send_event(new SourceSetEvent($event->image, $_POST['tag_edit__source'])); } } - if ($user->can("edit_image_lock")) { + if ($user->can(Permissions::EDIT_IMAGE_LOCK)) { $locked = isset($_POST['tag_edit__locked']) && $_POST['tag_edit__locked']=="on"; send_event(new LockSetEvent($event->image, $locked)); } @@ -215,7 +215,7 @@ class TagEdit extends Extension public function onOwnerSet(OwnerSetEvent $event) { global $user; - if ($user->can("edit_image_owner") && (!$event->image->is_locked() || $user->can("edit_image_lock"))) { + if ($user->can(Permissions::EDIT_IMAGE_OWNER) && (!$event->image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK))) { $event->image->set_owner($event->owner); } } @@ -223,7 +223,7 @@ class TagEdit extends Extension public function onTagSet(TagSetEvent $event) { global $user; - if ($user->can("edit_image_tag") && (!$event->image->is_locked() || $user->can("edit_image_lock"))) { + if ($user->can(Permissions::EDIT_IMAGE_TAG) && (!$event->image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK))) { $event->image->set_tags($event->tags); } $event->image->parse_metatags($event->metatags, $event->image->id); @@ -232,7 +232,7 @@ class TagEdit extends Extension public function onSourceSet(SourceSetEvent $event) { global $user; - if ($user->can("edit_image_source") && (!$event->image->is_locked() || $user->can("edit_image_lock"))) { + if ($user->can(Permissions::EDIT_IMAGE_SOURCE) && (!$event->image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK))) { $event->image->set_source($event->source); } } @@ -240,7 +240,7 @@ class TagEdit extends Extension public function onLockSet(LockSetEvent $event) { global $user; - if ($user->can("edit_image_lock")) { + if ($user->can(Permissions::EDIT_IMAGE_LOCK)) { $event->image->set_locked($event->locked); } } @@ -255,6 +255,15 @@ class TagEdit extends Extension $this->theme->display_mass_editor(); } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="tags") { + $event->add_nav_link("tags_help", new Link('ext_doc/tag_edit'), "Help"); + } + } + + /** * When an alias is added, oldtag becomes inaccessible. */ @@ -288,13 +297,13 @@ class TagEdit extends Extension private function can_tag(Image $image): bool { global $user; - return ($user->can("edit_image_tag") || !$image->is_locked()); + return ($user->can(Permissions::EDIT_IMAGE_TAG) || !$image->is_locked()); } private function can_source(Image $image): bool { global $user; - return ($user->can("edit_image_source") || !$image->is_locked()); + return ($user->can(Permissions::EDIT_IMAGE_SOURCE) || !$image->is_locked()); } private function mass_tag_edit(string $search, string $replace) diff --git a/ext/tag_edit/theme.php b/ext/tag_edit/theme.php index ee978e42..fa95d7fa 100644 --- a/ext/tag_edit/theme.php +++ b/ext/tag_edit/theme.php @@ -51,7 +51,7 @@ class TagEditTheme extends Themelet Tags - ".($user->can("edit_image_tag") ? " + ".($user->can(Permissions::EDIT_IMAGE_TAG) ? " $h_tag_links " : " @@ -68,12 +68,12 @@ class TagEditTheme extends Themelet $h_owner = html_escape($image->get_owner()->name); $h_av = $image->get_owner()->get_avatar_html(); $h_date = autodate($image->posted); - $h_ip = $user->can("view_ip") ? " (".show_ip($image->owner_ip, "Image posted {$image->posted}").")" : ""; + $h_ip = $user->can(Permissions::VIEW_IP) ? " (".show_ip($image->owner_ip, "Image posted {$image->posted}").")" : ""; return " Uploader - ".($user->can("edit_image_owner") ? " + ".($user->can(Permissions::EDIT_IMAGE_OWNER) ? " $h_owner$h_ip, $h_date " : " @@ -95,7 +95,7 @@ class TagEditTheme extends Themelet Source - ".($user->can("edit_image_source") ? " + ".($user->can(Permissions::EDIT_IMAGE_SOURCE) ? "
$f_source
" : " @@ -132,7 +132,7 @@ class TagEditTheme extends Themelet Locked - ".($user->can("edit_image_lock") ? " + ".($user->can(Permissions::EDIT_IMAGE_LOCK) ? " $b_locked " : " diff --git a/ext/tag_editcloud/main.php b/ext/tag_editcloud/main.php index 24e6d1a3..0ae9088c 100644 --- a/ext/tag_editcloud/main.php +++ b/ext/tag_editcloud/main.php @@ -180,6 +180,6 @@ class TagEditCloud extends Extension private function can_tag(Image $image): bool { global $user; - return ($user->can("edit_image_tag") && (!$image->is_locked() || $user->can("edit_image_lock"))); + return ($user->can(Permissions::EDIT_IMAGE_TAG) && (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK))); } } diff --git a/ext/tag_history/main.php b/ext/tag_history/main.php index 618bd85a..b317abd3 100644 --- a/ext/tag_history/main.php +++ b/ext/tag_history/main.php @@ -35,13 +35,13 @@ class Tag_History extends Extension if ($event->page_matches("tag_history/revert")) { // this is a request to revert to a previous version of the tags - if ($user->can("edit_image_tag")) { + if ($user->can(Permissions::EDIT_IMAGE_TAG)) { if (isset($_POST['revert'])) { $this->process_revert_request($_POST['revert']); } } } elseif ($event->page_matches("tag_history/bulk_revert")) { - if ($user->can("bulk_edit_image_tag") && $user->check_auth_token()) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG) && $user->check_auth_token()) { $this->process_bulk_revert_request(); } } elseif ($event->page_matches("tag_history/all")) { @@ -82,10 +82,21 @@ class Tag_History extends Extension $this->add_tag_history($event->image, $event->tags); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG)) { + $event->add_nav_link("tag_history", new Link('tag_history/all/1'), "Tag Changes", NavLink::is_active(["tag_history"])); + } + } + } + + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if ($user->can("bulk_edit_image_tag")) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG)) { $event->add_link("Tag Changes", make_link("tag_history/all/1")); } } diff --git a/ext/tag_history/theme.php b/ext/tag_history/theme.php index dfa1ab41..9e51ccb8 100644 --- a/ext/tag_history/theme.php +++ b/ext/tag_history/theme.php @@ -25,7 +25,7 @@ class Tag_HistoryTheme extends Themelet $current_tags = html_escape($fields['tags']); $name = $fields['name']; $date_set = autodate($fields['date_set']); - $h_ip = $user->can("view_ip") ? " ".show_ip($fields['user_ip'], "Tagging Image #$image_id as '$current_tags'") : ""; + $h_ip = $user->can(Permissions::VIEW_IP) ? " ".show_ip($fields['user_ip'], "Tagging Image #$image_id as '$current_tags'") : ""; $setter = "".html_escape($name)."$h_ip"; $selected = ($n == 2) ? " checked" : ""; @@ -84,7 +84,7 @@ class Tag_HistoryTheme extends Themelet $image_id = $fields['image_id']; $current_tags = html_escape($fields['tags']); $name = $fields['name']; - $h_ip = $user->can("view_ip") ? " ".show_ip($fields['user_ip'], "Tagging Image #$image_id as '$current_tags'") : ""; + $h_ip = $user->can(Permissions::VIEW_IP) ? " ".show_ip($fields['user_ip'], "Tagging Image #$image_id as '$current_tags'") : ""; $setter = "".html_escape($name)."$h_ip"; $history_list .= ' diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php index ac5484a8..9d0e8a53 100644 --- a/ext/tag_list/main.php +++ b/ext/tag_list/main.php @@ -93,6 +93,21 @@ class TagList extends Extension } } + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("tags", new Link('tags/map'), "Tags"); + } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="tags") { + $event->add_nav_link("tags_map", new Link('tags/map'), "Map"); + $event->add_nav_link("tags_alphabetic", new Link('tags/alphabetic'), "Alphabetic"); + $event->add_nav_link("tags_popularity", new Link('tags/popularity'), "Popularity"); + $event->add_nav_link("tags_categories", new Link('tags/categories'), "Categories"); + } + } + public function onDisplayingImage(DisplayingImageEvent $event) { global $config, $page; @@ -100,7 +115,7 @@ class TagList extends Extension if ($config->get_string('tag_list_image_type') == 'related') { $this->add_related_block($page, $event->image); } else { - if (class_exists("TagCategories") and $config->get_bool('tag_categories_split_on_view')) { + if (class_exists("TagCategories") and $config->get_bool(TagCategoriesConfig::SPLIT_ON_VIEW)) { $this->add_split_tags_block($page, $event->image); } else { $this->add_tags_block($page, $event->image); diff --git a/ext/tagger/main.php b/ext/tagger/main.php index 631da7b4..2653634c 100644 --- a/ext/tagger/main.php +++ b/ext/tagger/main.php @@ -12,7 +12,7 @@ class Tagger extends Extension { global $page, $user; - if ($user->can("edit_image_tag") && ($event->image->is_locked() || $user->can("edit_image_lock"))) { + if ($user->can(Permissions::EDIT_IMAGE_TAG) && ($event->image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK))) { $this->theme->build_tagger($page, $event); } } diff --git a/ext/tips/main.php b/ext/tips/main.php index 7e5610a6..60564028 100644 --- a/ext/tips/main.php +++ b/ext/tips/main.php @@ -73,6 +73,16 @@ class Tips extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->is_admin()) { + $event->add_nav_link("tips", new Link('tips/list'), "Tips Editor"); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; diff --git a/ext/trash/main.php b/ext/trash/main.php index 89be2aee..e8732c64 100644 --- a/ext/trash/main.php +++ b/ext/trash/main.php @@ -37,7 +37,7 @@ class Trash extends Extension { global $page, $user; - if ($event->page_matches("trash_restore") && $user->can("view_trash")) { + if ($event->page_matches("trash_restore") && $user->can(Permissions::VIEW_TRASH)) { // Try to get the image ID $image_id = int_escape($event->get_arg(0)); if (empty($image_id)) { @@ -59,7 +59,7 @@ class Trash extends Extension { global $user, $page; - if($event->image->trash===true && !$user->can("view_trash")) { + if($event->image->trash===true && !$user->can(Permissions::VIEW_TRASH)) { $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } @@ -87,12 +87,26 @@ class Trash extends Extension if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) { - if($user->can("view_trash")) { + if($user->can(Permissions::VIEW_TRASH)) { $event->add_querylet(new Querylet($database->scoreql_to_sql("trash = SCORE_BOOL_Y "))); } } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + global $user; + if($event->key===HelpPages::SEARCH) { + if($user->can(Permissions::VIEW_TRASH)) { + $block = new Block(); + $block->header = "Trash"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + } + + private function no_trash_query(array $context): bool { foreach ($context as $term) { @@ -114,7 +128,7 @@ class Trash extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $config, $database, $user; - if($event->image->trash===true && $user->can("view_trash")) { + if($event->image->trash===true && $user->can(Permissions::VIEW_TRASH)) { $event->add_part($this->theme->get_image_admin_html($event->image->id)); } } @@ -123,7 +137,7 @@ class Trash extends Extension { global $user; - if ($user->can("view_trash")&&in_array("in:trash", $event->search_terms)) { + if ($user->can(Permissions::VIEW_TRASH)&&in_array("in:trash", $event->search_terms)) { $event->add_action("bulk_trash_restore","(U)ndelete", "u"); } } @@ -134,7 +148,7 @@ class Trash extends Extension switch ($event->action) { case "bulk_trash_restore": - if ($user->can("view_trash")) { + if ($user->can(Permissions::VIEW_TRASH)) { $total = 0; foreach ($event->items as $image) { self::set_trash($image->id, false); diff --git a/ext/trash/theme.php b/ext/trash/theme.php index 5e4e2e15..3211aa1f 100644 --- a/ext/trash/theme.php +++ b/ext/trash/theme.php @@ -11,4 +11,16 @@ class TrashTheme extends Themelet "; return $html; } + + + public function get_help_html() + { + return '

Search for images in the trash.

+
+
in:trash
+

Returns images that are in the trash.

+
+ '; + + } } diff --git a/ext/upload/main.php b/ext/upload/main.php index e0274346..8c9d313f 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -138,6 +138,21 @@ class Upload extends Extension $event->panel->add_block($sb); } + + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("upload",new Link('upload'), "Upload"); + } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="upload") { + if (class_exists("Wiki")) { + $event->add_nav_link("upload_guidelines", new Link('wiki/upload_guidelines'), "Guidelines"); + } + } + } + public function onDataUpload(DataUploadEvent $event) { global $config; @@ -155,7 +170,7 @@ class Upload extends Extension { global $database, $page, $user; - if ($user->can("create_image")) { + if ($user->can(Permissions::CREATE_IMAGE)) { if ($this->is_full) { $this->theme->display_full($page); } else { @@ -165,7 +180,7 @@ class Upload extends Extension if ($event->page_matches("upload/replace")) { // check if the user is an administrator and can upload files. - if (!$user->can("replace_image")) { + if (!$user->can(Permissions::REPLACE_IMAGE)) { $this->theme->display_permission_denied(); } else { if ($this->is_full) { @@ -221,7 +236,7 @@ class Upload extends Extension } } } elseif ($event->page_matches("upload")) { - if (!$user->can("create_image")) { + if (!$user->can(Permissions::CREATE_IMAGE)) { $this->theme->display_permission_denied(); } else { /* Regular Upload Image */ @@ -371,7 +386,7 @@ class Upload extends Extension $ok = true; // Checks if user is admin > check if you want locked. - if ($user->can("edit_image_lock") && !empty($_GET['locked'])) { + if ($user->can(Permissions::EDIT_IMAGE_LOCK) && !empty($_GET['locked'])) { $locked = bool_escape($_GET['locked']); } diff --git a/ext/upload/theme.php b/ext/upload/theme.php index 6b3b503a..efa407c8 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -189,7 +189,7 @@ class UploadTheme extends Themelet global $config; $link = make_http(make_link("upload")); $main_page = make_http(make_link()); - $title = $config->get_string('title'); + $title = $config->get_string(SetupConfig::TITLE); $max_size = $config->get_int('upload_size'); $max_kb = to_shorthand_int($max_size); $delimiter = $config->get_bool('nice_urls') ? '?' : '&'; @@ -235,7 +235,7 @@ class UploadTheme extends Themelet if (class_exists("VideoFileHandler")) { $supported_ext .= " flv mp4 ogv webm m4v"; } - $title = "Booru to " . $config->get_string('title'); + $title = "Booru to " . $config->get_string(SetupConfig::TITLE); // CA=0: Ask to use current or new tags | CA=1: Always use current tags | CA=2: Always use new tags $html .= '

can('delete_user') && @$_GET['email']) { + if ($user->can(Permissions::DELETE_USER) && @$_GET['email']) { $q .= " AND SCORE_STRNORM(email) LIKE SCORE_STRNORM(:email)"; $a["email"] = '%' . $_GET['email'] . '%'; } @@ -212,7 +212,7 @@ class UserPage extends Extension global $user, $config; $h_join_date = autodate($event->display_user->join_date); - if ($event->display_user->can("hellbanned")) { + if ($event->display_user->can(Permissions::HELLBANNED)) { $h_class = $event->display_user->class->parent->name; } else { $h_class = $event->display_user->class->name; @@ -237,6 +237,17 @@ class UserPage extends Extension } } + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + global $user; + if ($user->is_anonymous()) { + $event->add_nav_link("user", new Link('user_admin/login'), "Account", null, 10); + } else { + $event->add_nav_link("user", new Link('user'), "Account", null, 10); + } + } + + private function display_stats(UserPageBuildingEvent $event) { global $user, $page, $config; @@ -250,7 +261,7 @@ class UserPage extends Extension $this->theme->display_user_links($page, $user, $ubbe->parts); } if ( - ($user->can("view_ip") || ($user->is_logged_in() && $user->id == $event->display_user->id)) && # admin or self-user + ($user->can(Permissions::VIEW_IP) || ($user->is_logged_in() && $user->id == $event->display_user->id)) && # admin or self-user ($event->display_user->id != $config->get_int('anon_id')) # don't show anon's IP list, it is le huge ) { $this->theme->display_ip_list( @@ -305,11 +316,21 @@ class UserPage extends Extension $event->panel->add_block($sb); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent==="system") { + if ($user->can(Permissions::EDIT_USER_CLASS)) { + $event->add_nav_link("user_admin", new Link('user_admin/list'), "User List", NavLink::is_active(["user_admin"])); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; $event->add_link("My Profile", make_link("user")); - if ($user->can("edit_user_class")) { + if ($user->can(Permissions::EDIT_USER_CLASS)) { $event->add_link("User List", make_link("user_admin/list"), 98); } $event->add_link("Log Out", make_link("user_admin/logout"), 99); @@ -337,12 +358,23 @@ class UserPage extends Extension } elseif (preg_match("/^(?:poster|user)_id[=|:]([0-9]+)$/i", $event->term, $matches)) { $user_id = int_escape($matches[1]); $event->add_querylet(new Querylet("images.owner_id = $user_id")); - } elseif ($user->can("view_ip") && preg_match("/^(?:poster|user)_ip[=|:]([0-9\.]+)$/i", $event->term, $matches)) { + } elseif ($user->can(Permissions::VIEW_IP) && preg_match("/^(?:poster|user)_ip[=|:]([0-9\.]+)$/i", $event->term, $matches)) { $user_ip = $matches[1]; // FIXME: ip_escape? $event->add_querylet(new Querylet("images.owner_ip = '$user_ip'")); } } + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + if($event->key===HelpPages::SEARCH) { + $block = new Block(); + $block->header = "Users"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + + private function show_user_info() { global $user, $page; @@ -517,8 +549,8 @@ class UserPage extends Extension if ( ($a->name == $b->name) || - ($b->can("protected") && $a->class->name == "admin") || - (!$b->can("protected") && $a->can("edit_user_info")) + ($b->can(Permissions::PROTECTED) && $a->class->name == "admin") || + (!$b->can(Permissions::PROTECTED) && $a->can(Permissions::EDIT_USER_INFO)) ) { return true; } else { @@ -544,7 +576,7 @@ class UserPage extends Extension { global $user; - if ($user->can('edit_user_name') && $this->user_can_edit_user($user, $duser)) { + if ($user->can(Permissions::EDIT_USER_NAME) && $this->user_can_edit_user($user, $duser)) { $duser->set_name($name); flash_message("Username changed"); // TODO: set login cookie if user changed themselves @@ -652,7 +684,7 @@ class UserPage extends Extension $page->set_heading("Error"); $page->add_block(new NavBlock()); - if (!$user->can("delete_user")) { + if (!$user->can(Permissions::DELETE_USER)) { $page->add_block(new Block("Not Admin", "Only admins can delete accounts")); } elseif (!isset($_POST['id']) || !is_numeric($_POST['id'])) { $page->add_block(new Block( diff --git a/ext/user/theme.php b/ext/user/theme.php index 45f6f08f..dab26e8c 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -26,7 +26,7 @@ class UserPageTheme extends Themelet $html .= ""; $html .= "Name"; - if ($user->can('delete_user')) { + if ($user->can(Permissions::DELETE_USER)) { $html .= "Email"; } $html .= "Class"; @@ -39,7 +39,7 @@ class UserPageTheme extends Themelet $html .= "" . make_form("user_admin/list", "GET"); $html .= ""; - if ($user->can('delete_user')) { + if ($user->can(Permissions::DELETE_USER)) { $html .= ""; } $html .= ""; @@ -55,7 +55,7 @@ class UserPageTheme extends Themelet $html .= ""; $html .= "$h_name"; - if ($user->can('delete_user')) { + if ($user->can(Permissions::DELETE_USER)) { $html .= "$h_email"; } $html .= "$h_class"; @@ -256,7 +256,7 @@ class UserPageTheme extends Themelet $html = ""; if ($duser->id != $config->get_int('anon_id')) { //justa fool-admin protection so they dont mess around with anon users. - if ($user->can('edit_user_name')) { + if ($user->can(Permissions::EDIT_USER_NAME)) { $html .= "

".make_form(make_link("user_admin/change_name"))." @@ -298,7 +298,7 @@ class UserPageTheme extends Themelet $i_user_id = int_escape($duser->id); - if ($user->can("edit_user_class")) { + if ($user->can(Permissions::EDIT_USER_CLASS)) { global $_shm_user_classes; $class_html = ""; foreach ($_shm_user_classes as $name => $values) { @@ -319,7 +319,7 @@ class UserPageTheme extends Themelet "; } - if ($user->can("delete_user")) { + if ($user->can(Permissions::DELETE_USER)) { $html .= "

".make_form(make_link("user_admin/delete_user"))." @@ -343,4 +343,30 @@ class UserPageTheme extends Themelet return $html; } // }}} + + public function get_help_html() + { + global $user; + $output = '

Search for images posted by particular individuals.

+
+
poster=username
+

Returns images posted by "username".

+
+
+
poster_id=123
+

Returns images posted by user 123.

+
+ '; + + + if ($user->can(Permissions::VIEW_IP)) { + $output .=" +
+
poster_ip=127.0.0.1
+

Returns images posted from IP 127.0.0.1.

+
+ "; + } + return $output; + } } diff --git a/ext/view/events/displaying_image_event.php b/ext/view/events/displaying_image_event.php new file mode 100644 index 00000000..3ac3090f --- /dev/null +++ b/ext/view/events/displaying_image_event.php @@ -0,0 +1,23 @@ +image = $image; + } + + public function get_image(): Image + { + return $this->image; + } + + public function set_title(String $title) { + $this->title = $title; + } +} \ No newline at end of file diff --git a/ext/view/events/image_admin_block_building_event.php b/ext/view/events/image_admin_block_building_event.php new file mode 100644 index 00000000..0211065a --- /dev/null +++ b/ext/view/events/image_admin_block_building_event.php @@ -0,0 +1,25 @@ +image = $image; + $this->user = $user; + } + + public function add_part(string $html, int $position=50) + { + while (isset($this->parts[$position])) { + $position++; + } + $this->parts[$position] = $html; + } +} \ No newline at end of file diff --git a/ext/view/events/image_info_box_building_event.php b/ext/view/events/image_info_box_building_event.php new file mode 100644 index 00000000..cb626349 --- /dev/null +++ b/ext/view/events/image_info_box_building_event.php @@ -0,0 +1,25 @@ +image = $image; + $this->user = $user; + } + + public function add_part(string $html, int $position=50) + { + while (isset($this->parts[$position])) { + $position++; + } + $this->parts[$position] = $html; + } +} \ No newline at end of file diff --git a/ext/view/events/image_info_set_event.php b/ext/view/events/image_info_set_event.php new file mode 100644 index 00000000..e6d77d59 --- /dev/null +++ b/ext/view/events/image_info_set_event.php @@ -0,0 +1,12 @@ +image = $image; + } +} \ No newline at end of file diff --git a/ext/view/main.php b/ext/view/main.php index bb2ee8c6..11c9f74e 100644 --- a/ext/view/main.php +++ b/ext/view/main.php @@ -14,80 +14,12 @@ * wish to appear on the "view" page should listen for this, * which only appears when an image actually exists. */ -class DisplayingImageEvent extends Event -{ - /** @var Image */ - public $image; - public function __construct(Image $image) - { - $this->image = $image; - } +require_once "events/displaying_image_event.php"; +require_once "events/image_info_box_building_event.php"; +require_once "events/image_info_set_event.php"; +require_once "events/image_admin_block_building_event.php"; - public function get_image(): Image - { - return $this->image; - } -} - -class ImageInfoBoxBuildingEvent extends Event -{ - /** @var array */ - public $parts = []; - /** @var Image */ - public $image; - /** @var User */ - public $user; - - public function __construct(Image $image, User $user) - { - $this->image = $image; - $this->user = $user; - } - - public function add_part(string $html, int $position=50) - { - while (isset($this->parts[$position])) { - $position++; - } - $this->parts[$position] = $html; - } -} - -class ImageInfoSetEvent extends Event -{ - /** @var Image */ - public $image; - - public function __construct(Image $image) - { - $this->image = $image; - } -} - -class ImageAdminBlockBuildingEvent extends Event -{ - /** @var string[] */ - public $parts = []; - /** @var ?Image */ - public $image = null; - /** @var ?User */ - public $user = null; - - public function __construct(Image $image, User $user) - { - $this->image = $image; - $this->user = $user; - } - - public function add_part(string $html, int $position=50) - { - while (isset($this->parts[$position])) { - $position++; - } - $this->parts[$position] = $html; - } -} class ViewImage extends Extension { @@ -140,7 +72,9 @@ class ViewImage extends Extension $image = Image::by_id($image_id); if (!is_null($image)) { - send_event(new DisplayingImageEvent($image)); + $die = new DisplayingImageEvent($image); + send_event($die); + $page->set_title(html_escape($die->title)); $iabbe = new ImageAdminBlockBuildingEvent($image, $user); send_event($iabbe); ksort($iabbe->parts); @@ -169,6 +103,9 @@ class ViewImage extends Extension send_event($iibbe); ksort($iibbe->parts); $this->theme->display_meta_headers($event->get_image()); + + $event->title = "Image {$event->get_image()->id}: ".$event->get_image()->get_tag_list(); + $this->theme->display_page($event->get_image(), $iibbe->parts); } } diff --git a/ext/view/theme.php b/ext/view/theme.php index 82bd51f4..ba085159 100644 --- a/ext/view/theme.php +++ b/ext/view/theme.php @@ -20,8 +20,6 @@ class ViewImageTheme extends Themelet public function display_page(Image $image, $editor_parts) { global $page; - - $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list())); $page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0)); $page->add_block(new Block(null, $this->build_info($image, $editor_parts), "main", 20)); @@ -81,8 +79,8 @@ class ViewImageTheme extends Themelet $html .= $part; } if ( - (!$image->is_locked() || $user->can("edit_image_lock")) && - $user->can("edit_image_tag") + (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) && + $user->can(Permissions::EDIT_IMAGE_TAG) ) { $html .= " diff --git a/ext/wiki/main.php b/ext/wiki/main.php index 7279b630..2bb04b0a 100644 --- a/ext/wiki/main.php +++ b/ext/wiki/main.php @@ -176,6 +176,21 @@ class Wiki extends Extension } } + + public function onPageNavBuilding(PageNavBuildingEvent $event) + { + $event->add_nav_link("wiki",new Link('wiki'), "Wiki"); + } + + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="wiki") { + $event->add_nav_link("wiki_rules", new Link('wiki/rules'), "Rules"); + $event->add_nav_link("wiki_help", new Link('ext_doc/wiki'), "Help"); + } + } + public function onWikiUpdate(WikiUpdateEvent $event) { global $database; @@ -206,7 +221,7 @@ class Wiki extends Extension } // anon / user can edit if allowed by config - if ($user->can("edit_wiki_page")) { + if ($user->can(Permissions::EDIT_WIKI_PAGE)) { return true; } diff --git a/themes/danbooru/comment.theme.php b/themes/danbooru/comment.theme.php index 03e094bc..0b40f418 100644 --- a/themes/danbooru/comment.theme.php +++ b/themes/danbooru/comment.theme.php @@ -104,7 +104,7 @@ class CustomCommentListTheme extends CommentListTheme $h_userlink = "$h_name"; $h_del = ""; - if ($user->can("delete_comment")) { + if ($user->can(Permissions::DELETE_COMMENT)) { $comment_preview = substr(html_unescape($tfe->stripped), 0, 50); $j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview"); $h_delete_script = html_escape("return confirm($j_delete_confirm_message);"); diff --git a/themes/danbooru/index.theme.php b/themes/danbooru/index.theme.php index ef59ef69..9d55abd6 100644 --- a/themes/danbooru/index.theme.php +++ b/themes/danbooru/index.theme.php @@ -11,7 +11,7 @@ class CustomIndexTheme extends IndexTheme if (count($this->search_terms) == 0) { $query = null; - $page_title = $config->get_string('title'); + $page_title = $config->get_string(SetupConfig::TITLE); } else { $search_string = implode(' ', $this->search_terms); $query = url_escape($search_string); diff --git a/themes/danbooru/layout.class.php b/themes/danbooru/layout.class.php index 9a22681a..6be406a4 100644 --- a/themes/danbooru/layout.class.php +++ b/themes/danbooru/layout.class.php @@ -44,11 +44,11 @@ Tips class Layout { - public function display_page(Page $page) + public function display_page(Page $page, array $nav_links, array $sub_links) { global $config, $user; - $theme_name = $config->get_string('theme'); + $theme_name = $config->get_string(SetupConfig::THEME); //$base_href = $config->get_string('base_href'); $data_href = get_base_href(); $contact_link = contact_link(); @@ -92,89 +92,21 @@ class Layout $subheading = "
{$this->subheading}
"; } - $site_name = $config->get_string('title'); // bzchan: change from normal default to get title for top of page - $main_page = $config->get_string('main_page'); // bzchan: change from normal default to get main page for top of page + $site_name = $config->get_string(SetupConfig::TITLE); // bzchan: change from normal default to get title for top of page + $main_page = $config->get_string(SetupConfig::MAIN_PAGE); // bzchan: change from normal default to get main page for top of page - // bzchan: CUSTOM LINKS are prepared here, change these to whatever you like $custom_links = ""; - if ($user->is_anonymous()) { - $custom_links .= $this->navlinks(make_link('user_admin/login'), "My Account", ["user", "user_admin", "setup", "admin"]); - } else { - $custom_links .= $this->navlinks(make_link('user'), "My Account", ["user", "user_admin", "setup", "admin"]); - } - $custom_links .= $this->navlinks(make_link('post/list'), "Posts", ["post"]); - $custom_links .= $this->navlinks(make_link('comment/list'), "Comments", ["comment"]); - $custom_links .= $this->navlinks(make_link('tags'), "Tags", ["tags"]); - if (class_exists("Pools")) { - $custom_links .= $this->navlinks(make_link('pool/list'), "Pools", ["pool"]); - } - $custom_links .= $this->navlinks(make_link('upload'), "Upload", ["upload"]); - if (class_exists("Wiki")) { - $custom_links .= $this->navlinks(make_link('wiki'), "Wiki", ["wiki"]); - $custom_links .= $this->navlinks(make_link('wiki/more'), "More »", ["wiki/more"]); + foreach ($nav_links as $nav_link) { + $custom_links .= "
  • ".$this->navlinks($nav_link->link, $nav_link->description, $nav_link->active)."
  • "; } $custom_sublinks = ""; - // hack - $username = url_escape($user->name); - // hack - $qp = explode("/", ltrim(_get_query(), "/")); - // php sucks - switch ($qp[0]) { - default: - $custom_sublinks .= $user_block_html; - break; - case "": - # FIXME: this assumes that the front page is - # post/list; in 99% of case it will either be - # post/list or home, and in the latter case - # the subnav links aren't shown, but it would - # be nice to be correct - case "post": - case "upload": - if (class_exists("NumericScore")) { - $custom_sublinks .= "
  • Popular by Day/Month/Year
  • "; - } - $custom_sublinks .= "
  • All
  • "; - if (class_exists("Favorites")) { - $custom_sublinks .= "
  • My Favorites
  • "; - } - if (class_exists("RSS_Images")) { - $custom_sublinks .= "
  • Feed
  • "; - } - if (class_exists("RandomImage")) { - $custom_sublinks .= "
  • Random Image
  • "; - } - if (class_exists("Wiki")) { - $custom_sublinks .= "
  • Help
  • "; - } else { - $custom_sublinks .= "
  • Help
  • "; - } - break; - case "comment": - $custom_sublinks .= "
  • All
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; - case "pool": - $custom_sublinks .= "
  • List
  • "; - $custom_sublinks .= "
  • Create
  • "; - $custom_sublinks .= "
  • Changes
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; - case "wiki": - $custom_sublinks .= "
  • Index
  • "; - $custom_sublinks .= "
  • Rules
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; - case "tags": - case "alias": - $custom_sublinks .= "
  • Map
  • "; - $custom_sublinks .= "
  • Alphabetic
  • "; - $custom_sublinks .= "
  • Popularity
  • "; - $custom_sublinks .= "
  • Categories
  • "; - $custom_sublinks .= "
  • Aliases
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; + if(!empty($sub_links)) { + $custom_sublinks = "
    "; + foreach ($sub_links as $nav_link) { + $custom_sublinks .= "
  • ".$this->navlinks($nav_link->link, $nav_link->description, $nav_link->active)."
  • "; + } + $custom_sublinks .= "
    "; } @@ -246,31 +178,16 @@ EOD; /** * #param string[] $pages_matched */ - private function navlinks(string $link, string $desc, array $pages_matched): string + + public function navlinks(Link $link, string $desc, bool $active): ?string { - /** - * Woo! We can actually SEE THE CURRENT PAGE!! (well... see it highlighted in the menu.) - */ $html = null; - $url = ltrim(_get_query(), "/"); + if ($active) { + $html = "{$desc}"; + } else { + $html = "{$desc}"; + } - $re1='.*?'; - $re2='((?:[a-z][a-z_]+))'; - - if (preg_match_all("/".$re1.$re2."/is", $url, $matches)) { - $url=$matches[1][0]; - } - - $count_pages_matched = count($pages_matched); - - for ($i=0; $i < $count_pages_matched; $i++) { - if ($url == $pages_matched[$i]) { - $html = "
  • $desc
  • "; - } - } - if (is_null($html)) { - $html = "
  • $desc
  • "; - } return $html; } } diff --git a/themes/danbooru/view.theme.php b/themes/danbooru/view.theme.php index f113541a..51adbe1b 100644 --- a/themes/danbooru/view.theme.php +++ b/themes/danbooru/view.theme.php @@ -5,7 +5,6 @@ class CustomViewImageTheme extends ViewImageTheme public function display_page(Image $image, $editor_parts) { global $page; - $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list())); $page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0)); $page->add_block(new Block("Statistics", $this->build_stats($image), "left", 15)); @@ -23,7 +22,7 @@ class CustomViewImageTheme extends ViewImageTheme $h_filesize = to_shorthand_int($image->filesize); global $user; - if ($user->can("view_ip")) { + if ($user->can(Permissions::VIEW_IP)) { $h_ownerlink .= " ($h_ip)"; } diff --git a/themes/danbooru2/comment.theme.php b/themes/danbooru2/comment.theme.php index f043f445..94d56eda 100644 --- a/themes/danbooru2/comment.theme.php +++ b/themes/danbooru2/comment.theme.php @@ -105,7 +105,7 @@ class CustomCommentListTheme extends CommentListTheme $h_userlink = "$h_name"; $h_del = ""; - if ($user->can("delete_comment")) { + if ($user->can(Permissions::DELETE_COMMENT)) { $comment_preview = substr(html_unescape($tfe->stripped), 0, 50); $j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview"); $h_delete_script = html_escape("return confirm($j_delete_confirm_message);"); diff --git a/themes/danbooru2/index.theme.php b/themes/danbooru2/index.theme.php index 51455d43..a62fdf8c 100644 --- a/themes/danbooru2/index.theme.php +++ b/themes/danbooru2/index.theme.php @@ -11,7 +11,7 @@ class CustomIndexTheme extends IndexTheme if (count($this->search_terms) == 0) { $query = null; - $page_title = $config->get_string('title'); + $page_title = $config->get_string(SetupConfig::TITLE); } else { $search_string = implode(' ', $this->search_terms); $query = url_escape($search_string); diff --git a/themes/danbooru2/layout.class.php b/themes/danbooru2/layout.class.php index 6c4514f2..440d0c88 100644 --- a/themes/danbooru2/layout.class.php +++ b/themes/danbooru2/layout.class.php @@ -44,11 +44,11 @@ Tips class Layout { - public function display_page($page) + public function display_page($page, array $nav_links, array $sub_links) { global $config, $user; - //$theme_name = $config->get_string('theme'); + //$theme_name = $config->get_string(SetupConfig::THEME); //$base_href = $config->get_string('base_href'); //$data_href = get_base_href(); $contact_link = contact_link(); @@ -92,115 +92,21 @@ class Layout $subheading = "
    {$this->subheading}
    "; } - $site_name = $config->get_string('title'); // bzchan: change from normal default to get title for top of page - $main_page = $config->get_string('main_page'); // bzchan: change from normal default to get main page for top of page + $site_name = $config->get_string(SetupConfig::TITLE); // bzchan: change from normal default to get title for top of page + $main_page = $config->get_string(SetupConfig::MAIN_PAGE); // bzchan: change from normal default to get main page for top of page - // bzchan: CUSTOM LINKS are prepared here, change these to whatever you like $custom_links = ""; - if ($user->is_anonymous()) { - $custom_links .= $this->navlinks(make_link('user_admin/login'), "Sign in", ["user", "user_admin", "setup", "admin"]); - } else { - $custom_links .= $this->navlinks(make_link('user'), "My Account", ["user", "user_admin"]); - } - if ($user->is_admin()) { - $custom_links .= $this->navlinks(make_link('admin'), "Admin", ["admin", "ext_manager", "setup"]); - } - $custom_links .= $this->navlinks(make_link('post/list'), "Posts", ["post", "upload", "", "random_image"]); - $custom_links .= $this->navlinks(make_link('comment/list'), "Comments", ["comment"]); - $custom_links .= $this->navlinks(make_link('tags'), "Tags", ["tags", "alias"]); - if (class_exists("Pools")) { - $custom_links .= $this->navlinks(make_link('pool/list'), "Pools", ["pool"]); - } - if (class_exists("Wiki")) { - $custom_links .= $this->navlinks(make_link('wiki'), "Wiki", ["wiki"]); - $custom_links .= $this->navlinks(make_link('wiki/more'), "More »", ["wiki/more"]); + foreach ($nav_links as $nav_link) { + $custom_links .= "
  • ".$this->navlinks($nav_link->link, $nav_link->description, $nav_link->active)."
  • "; } $custom_sublinks = ""; - // hack - $username = url_escape($user->name); - // hack - $qp = explode("/", ltrim(_get_query(), "/")); - // php sucks - switch ($qp[0]) { - default: - case "ext_doc": - $custom_sublinks .= $user_block_html; - break; - case "user": - case "user_admin": - if ($user->is_anonymous()) { - $custom_sublinks .= "
  • Sign up
  • "; - // $custom_sublinks .= "
  • Reset Password
  • "; - // $custom_sublinks .= "
  • Login Reminder
  • "; - } else { - $custom_sublinks .= "
  • Sign out
  • "; - } - break; - case "": - # FIXME: this assumes that the front page is - # post/list; in 99% of case it will either be - # post/list or home, and in the latter case - # the subnav links aren't shown, but it would - # be nice to be correct - case "random_image": - case "post": - case "upload": - if (class_exists("NumericScore")) { - $custom_sublinks .= "
  • Popular by Day/Month/Year
  • "; - } - $custom_sublinks .= "
  • Listing
  • "; - if (class_exists("Favorites")) { - $custom_sublinks .= "
  • My Favorites
  • "; - } - if (class_exists("RSS_Images")) { - $custom_sublinks .= "
  • Feed
  • "; - } - if (class_exists("RandomImage")) { - $custom_sublinks .= "
  • Random
  • "; - } - $custom_sublinks .= "
  • Upload
  • "; - if (class_exists("Wiki")) { - $custom_sublinks .= "
  • Help
  • "; - } else { - $custom_sublinks .= "
  • Help
  • "; - } - break; - case "comment": - $custom_sublinks .= "
  • All
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; - case "pool": - $custom_sublinks .= "
  • List
  • "; - $custom_sublinks .= "
  • Create
  • "; - $custom_sublinks .= "
  • Changes
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; - case "wiki": - $custom_sublinks .= "
  • Index
  • "; - $custom_sublinks .= "
  • Rules
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; - case "tags": - case "alias": - $custom_sublinks .= "
  • Map
  • "; - $custom_sublinks .= "
  • Alphabetic
  • "; - $custom_sublinks .= "
  • Popularity
  • "; - $custom_sublinks .= "
  • Categories
  • "; - $custom_sublinks .= "
  • Aliases
  • "; - $custom_sublinks .= "
  • Help
  • "; - break; - case "admin": - case "ext_manager": - case "setup": - if ($user->is_admin()) { - $custom_sublinks .= "
  • Extension Manager
  • "; - $custom_sublinks .= "
  • Board Config
  • "; - $custom_sublinks .= "
  • Alias Editor
  • "; - } else { - $custom_sublinks .= "
  • I think you might be lost
  • "; - } - break; + if(!empty($sub_links)) { + $custom_sublinks = "
    "; + foreach ($sub_links as $nav_link) { + $custom_sublinks .= "
  • ".$this->navlinks($nav_link->link, $nav_link->description, $nav_link->active)."
  • "; + } + $custom_sublinks .= "
    "; } @@ -269,28 +175,15 @@ $header_html EOD; } - private function navlinks(string $link, string $desc, array $pages_matched): string + public function navlinks(Link $link, string $desc, bool $active): ?string { - $html = ""; - $url = _get_query(); + $html = null; + if ($active) { + $html = "{$desc}"; + } else { + $html = "{$desc}"; + } - $re1='.*?'; - $re2='((?:[a-z][a-z_]+))'; - - if (preg_match_all("/".$re1.$re2."/is", $url, $matches)) { - $url=$matches[1][0]; - } - - $count_pages_matched = count($pages_matched); - - for ($i=0; $i < $count_pages_matched; $i++) { - if ($url == $pages_matched[$i]) { - $html = "
  • $desc
  • "; - } - } - if (empty($html)) { - $html = "
  • $desc
  • "; - } return $html; } } diff --git a/themes/danbooru2/view.theme.php b/themes/danbooru2/view.theme.php index 237f1a8c..7f3439b5 100644 --- a/themes/danbooru2/view.theme.php +++ b/themes/danbooru2/view.theme.php @@ -5,7 +5,6 @@ class CustomViewImageTheme extends ViewImageTheme public function display_page(Image $image, $editor_parts) { global $page; - $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list())); $page->add_block(new Block("Search", $this->build_navigation($image), "left", 0)); $page->add_block(new Block("Information", $this->build_information($image), "left", 15)); @@ -22,7 +21,7 @@ class CustomViewImageTheme extends ViewImageTheme $h_filesize = to_shorthand_int($image->filesize); global $user; - if ($user->can("view_ip")) { + if ($user->can(Permissions::VIEW_IP)) { $h_ownerlink .= " ($h_ip)"; } diff --git a/themes/default/layout.class.php b/themes/default/layout.class.php index e67309bb..c1468e7f 100644 --- a/themes/default/layout.class.php +++ b/themes/default/layout.class.php @@ -7,11 +7,11 @@ class Layout /** * turns the Page into HTML */ - public function display_page(Page $page) + public function display_page(Page $page, array $nav_links) { global $config; - //$theme_name = $config->get_string('theme', 'default'); + //$theme_name = $config->get_string(SetupConfig::THEME, 'default'); //$data_href = get_base_href(); $contact_link = contact_link(); $header_html = $page->get_all_html_headers(); diff --git a/themes/futaba/comment.theme.php b/themes/futaba/comment.theme.php index 2fd0a6ad..5ae42be1 100644 --- a/themes/futaba/comment.theme.php +++ b/themes/futaba/comment.theme.php @@ -11,7 +11,7 @@ class CustomCommentListTheme extends CommentListTheme //$prev = $page_number - 1; //$next = $page_number + 1; - $page_title = $config->get_string('title'); + $page_title = $config->get_string(SetupConfig::TITLE); $page->set_title($page_title); $page->set_heading($page_title); $page->disable_left(); @@ -78,7 +78,7 @@ class CustomCommentListTheme extends CommentListTheme $h_userlink = "$h_name"; $h_date = $comment->posted; $h_del = ""; - if ($user->can("delete_comment")) { + if ($user->can(Permissions::DELETE_COMMENT)) { $comment_preview = substr(html_unescape($tfe->stripped), 0, 50); $j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview"); $h_delete_script = html_escape("return confirm($j_delete_confirm_message);"); diff --git a/themes/futaba/layout.class.php b/themes/futaba/layout.class.php index faccb090..98076afb 100644 --- a/themes/futaba/layout.class.php +++ b/themes/futaba/layout.class.php @@ -6,7 +6,7 @@ class Layout { global $config; - $theme_name = $config->get_string('theme', 'default'); + $theme_name = $config->get_string(SetupConfig::THEME, 'default'); $data_href = get_base_href(); $contact_link = contact_link(); $header_html = $page->get_all_html_headers(); diff --git a/themes/futaba/view.theme.php b/themes/futaba/view.theme.php index feb06743..4bbba64a 100644 --- a/themes/futaba/view.theme.php +++ b/themes/futaba/view.theme.php @@ -5,7 +5,6 @@ class CustomViewImageTheme extends ViewImageTheme public function display_page(Image $image, $editor_parts) { global $page; - $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list())); $page->add_block(new Block(null, $this->build_info($image, $editor_parts), "main", 10)); } diff --git a/themes/lite/layout.class.php b/themes/lite/layout.class.php index 747b0086..f11cbe70 100644 --- a/themes/lite/layout.class.php +++ b/themes/lite/layout.class.php @@ -9,12 +9,12 @@ */ class Layout { - public function display_page(Page $page) + public function display_page(Page $page, array $nav_links, array $sub_links) { global $config, $user; - $theme_name = $config->get_string('theme', 'lite'); - $site_name = $config->get_string('title'); + $theme_name = $config->get_string(SetupConfig::THEME, 'lite'); + $site_name = $config->get_string(SetupConfig::TITLE); $data_href = get_base_href(); $contact_link = contact_link(); $header_html = $page->get_all_html_headers(); @@ -23,24 +23,11 @@ class Layout {$site_name} "; - + // Custom links: These appear on the menu. $custom_links = ""; - if ($user->is_anonymous()) { - $custom_links .= $this->navlinks(make_link('user_admin/login'), "Account", ["user", "user_admin", "setup", "admin", "profile"]); - } else { - $custom_links .= $this->navlinks(make_link('user'), "Account", ["user", "setup", "user_admin", "admin", "profile"]); - } - $custom_links .= $this->navlinks(make_link('post/list'), "Posts", ["post", "view"]); - $custom_links .= $this->navlinks(make_link('comment/list'), "Comments", ["comment"]); - $custom_links .= $this->navlinks(make_link('tags'), "Tags", ["tags"]); - if (class_exists("Pools")) { - $custom_links .= $this->navlinks(make_link('pool/list'), "Pools", ["pool"]); - } - $custom_links .= $this->navlinks(make_link('upload'), "Upload", ["upload"]); - if (class_exists("Wiki")) { - $custom_links .= $this->navlinks(make_link('wiki/rules'), "Rules", ["wiki/rules"]); - $custom_links .= $this->navlinks(make_link('wiki'), "Wiki", ["wiki"]); + foreach ($nav_links as $nav_link) { + $custom_links .= $this->navlinks($nav_link->link, $nav_link->description, $nav_link->active); } $menu .= "{$custom_links}"; @@ -69,87 +56,13 @@ class Layout } } - $custom_sublinks = "
    "; - // hack - $username = url_escape($user->name); - // hack - $qp = explode("/", ltrim(_get_query(), "/")); - $cs = ""; - - // php sucks - switch ($qp[0]) { - default: - $cs = $user_block_html; - break; - case "": - # FIXME: this assumes that the front page is - # post/list; in 99% of case it will either be - # post/list or home, and in the latter case - # the subnav links aren't shown, but it would - # be nice to be correct - case "post": - if (class_exists("NumericScore")) { - $cs .= "Popular by Day/Month/Year "; - } - $cs .= "All"; - if (class_exists("Favorites")) { - $cs .= "My Favorites"; - } - if (class_exists("RSS_Images")) { - $cs .= "Feed"; - } - if (class_exists("Random_Image")) { - $cs .= "Random Image"; - } - if (class_exists("Wiki")) { - $cs .= "Help"; - } else { - $cs .= "Help"; - } - break; - case "comment": - $cs .= "All"; - $cs .= "Feed"; - $cs .= "Help"; - break; - case "pool": - $cs .= "List"; - $cs .= "Create"; - $cs .= "Changes"; - $cs .= "Help"; - break; - case "wiki": - $cs .= "Index"; - $cs .= "Rules"; - $cs .= "Help"; - break; - case "tags": - case "alias": - $cs .= "Map"; - $cs .= "Alphabetic"; - $cs .= "Popularity"; - $cs .= "Categories"; - $cs .= "Aliases"; - $cs .= "Help"; - break; - case "upload": - if (class_exists("Wiki")) { - $cs .= "Guidelines"; - } - break; - case "random": - $cs .= "Shuffle"; - $cs .= "Download"; - break; - case "featured": - $cs .= "Download"; - break; - } - - if ($cs == "") { - $custom_sublinks = ""; - } else { - $custom_sublinks .= "$cs
    "; + $custom_sublinks = ""; + if(!empty($sub_links)) { + $custom_sublinks = "
    "; + foreach ($sub_links as $nav_link) { + $custom_sublinks .= $this->navlinks($nav_link->link, $nav_link->description, $nav_link->active); + } + $custom_sublinks .= "
    "; } $debug = get_debug_info(); @@ -240,31 +153,13 @@ EOD; /** * #param string[] $pages_matched */ - public function navlinks(string $link, string $desc, array $pages_matched): ?string + public function navlinks(Link $link, string $desc, bool $active): ?string { - /** - * Woo! We can actually SEE THE CURRENT PAGE!! (well... see it highlighted in the menu.) - */ $html = null; - $url = ltrim(_get_query(), "/"); - - $re1='.*?'; - $re2='((?:[a-z][a-z_]+))'; - - if (preg_match_all("/".$re1.$re2."/is", $url, $matches)) { - $url=$matches[1][0]; - } - - $count_pages_matched = count($pages_matched); - - for ($i=0; $i < $count_pages_matched; $i++) { - if ($url == $pages_matched[$i]) { - $html = "{$desc}"; - } - } - - if (is_null($html)) { - $html = "{$desc}"; + if ($active) { + $html = "{$desc}"; + } else { + $html = "{$desc}"; } return $html; diff --git a/themes/lite/view.theme.php b/themes/lite/view.theme.php index a4613467..f9ce414f 100644 --- a/themes/lite/view.theme.php +++ b/themes/lite/view.theme.php @@ -5,7 +5,6 @@ class CustomViewImageTheme extends ViewImageTheme public function display_page(Image $image, $editor_parts) { global $page; - $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list())); $page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0)); $page->add_block(new Block("Statistics", $this->build_stats($image), "left", 15)); @@ -23,7 +22,7 @@ class CustomViewImageTheme extends ViewImageTheme $h_filesize = to_shorthand_int($image->filesize); global $user; - if ($user->can("view_ip")) { + if ($user->can(Permissions::VIEW_IP)) { $h_ownerlink .= " ($h_ip)"; } diff --git a/themes/material/layout.class.php b/themes/material/layout.class.php index 4c923456..ada06030 100644 --- a/themes/material/layout.class.php +++ b/themes/material/layout.class.php @@ -11,10 +11,10 @@ class Layout { global $config; - $theme_name = $config->get_string('theme', 'material'); - $site_name = $config->get_string('title'); + $theme_name = $config->get_string(SetupConfig::THEME, 'material'); + $site_name = $config->get_string(SetupConfig::TITLE); $data_href = get_base_href(); - $main_page = $config->get_string('main_page'); + $main_page = $config->get_string(SetupConfig::MAIN_PAGE); $contact_link = contact_link(); $site_link = make_link(); $header_html = $page->get_all_html_headers(); diff --git a/themes/material/view.theme.php b/themes/material/view.theme.php index eafdf3f4..601faf94 100644 --- a/themes/material/view.theme.php +++ b/themes/material/view.theme.php @@ -8,7 +8,6 @@ class CustomViewImageTheme extends ViewImageTheme public function display_page(Image $image, $editor_parts) { global $page; - $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list())); $page->add_block(new Block(null, $this->build_pin($image), "subtoolbar", 0)); $page->add_block(new Block(null, $this->build_info($image, $editor_parts), "left", 20)); @@ -57,8 +56,8 @@ class CustomViewImageTheme extends ViewImageTheme $html .= $part; } if ( - (!$image->is_locked() || $user->can("edit_image_lock")) && - $user->can("edit_image_tag") + (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) && + $user->can(Permissions::EDIT_IMAGE_TAG) ) { $html .= " diff --git a/themes/warm/layout.class.php b/themes/warm/layout.class.php index 20259570..1d3017fb 100644 --- a/themes/warm/layout.class.php +++ b/themes/warm/layout.class.php @@ -11,10 +11,10 @@ class Layout { global $config; - //$theme_name = $config->get_string('theme', 'default'); - $site_name = $config->get_string('title'); + //$theme_name = $config->get_string(SetupConfig::THEME, 'default'); + $site_name = $config->get_string(SetupConfig::TITLE); $data_href = get_base_href(); - $main_page = $config->get_string('main_page'); + $main_page = $config->get_string(SetupConfig::MAIN_PAGE); $contact_link = contact_link(); $header_html = $page->get_all_html_headers();