Help extension

Provides foundation for help pages that are generated from loaded extensions, starting with comprehensive search documentation. Addresses #522
This commit is contained in:
Matthew Barbour 2019-08-02 15:05:49 -05:00 committed by matthew
parent 00464d2579
commit a18589ee0a
31 changed files with 769 additions and 6 deletions

View file

@ -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,system"); // 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

View file

@ -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;

View file

@ -545,4 +545,14 @@ class ArtistsTheme extends Themelet
}
return $html;
}
public function get_help_html()
{
return '<p>Search for images with a particular artist.</p>
<div class="command_example">
<pre>artist=leonardo</pre>
<p>Returns images with the artist "leonardo".</p>
</div>
';
}
}

View file

@ -366,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)
{

View file

@ -290,4 +290,28 @@ class CommentListTheme extends Themelet
</div>
';
}
public function get_help_html()
{
return '<p>Search for images containing a certain number of comments, or comments by a particular individual.</p>
<div class="command_example">
<pre>comments=1</pre>
<p>Returns images with exactly 1 comment.</p>
</div>
<div class="command_example">
<pre>comments>0</pre>
<p>Returns images with 1 or more comments. </p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =.</p>
<div class="command_example">
<pre>commented_by:username</pre>
<p>Returns images that have been commented on by "username". </p>
</div>
<div class="command_example">
<pre>commented_by_userno:123</pre>
<p>Returns images that have been commented on by user 123. </p>
</div>
';
}
}

View file

@ -155,6 +155,16 @@ 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;

View file

@ -34,4 +34,28 @@ class FavoritesTheme extends Themelet
$page->add_block(new Block("Favorited By", $html, "left", 25));
}
public function get_help_html()
{
return '<p>Search for images that have been favorited a certain number of times, or favorited by a particular individual.</p>
<div class="command_example">
<pre>favorites=1</pre>
<p>Returns images that have been favorited once.</p>
</div>
<div class="command_example">
<pre>favorites>0</pre>
<p>Returns images that have been favorited 1 or more times</p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =.</p>
<div class="command_example">
<pre>favorited_by:username</pre>
<p>Returns images that have been favorited by "username". </p>
</div>
<div class="command_example">
<pre>favorited_by_userno:123</pre>
<p>Returns images that have been favorited by user 123. </p>
</div>
';
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

94
ext/help_pages/main.php Normal file
View file

@ -0,0 +1,94 @@
<?php
/**
* Name: Help Pages
* Author: Matthew Barbour <matthew@darkholme.net>
* 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"));
}
}

13
ext/help_pages/style.css Normal file
View file

@ -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;
}

31
ext/help_pages/theme.php Normal file
View file

@ -0,0 +1,31 @@
<?php
class HelpPagesTheme extends Themelet
{
public function display_list_page(array $pages)
{
global $page;
$page->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 .= "<a href='{$link}'>".html_escape($desc)."</a><br/>";
}
$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");
}
}

View file

@ -344,6 +344,17 @@ class Index extends Extension
}
}
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 = [];
@ -392,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]));

View file

@ -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 '<p>Searching is largely based on tags, with a number of special keywords available that allow searching based on properties of the images.</p>
<div class="command_example">
<pre>tagname</pre>
<p>Returns images that are tagged with "tagname".</p>
</div>
<div class="command_example">
<pre>tagname othertagname</pre>
<p>Returns images that are tagged with "tagname" and "othertagname".</p>
</div>
<p>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.</p>
<div class="command_example">
<pre>-tagname</pre>
<p>Returns images that are not tagged with "tagname".</p>
</div>
<div class="command_example">
<pre>-tagname -othertagname</pre>
<p>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.</p>
</div>
<div class="command_example">
<pre>tagname -othertagname</pre>
<p>Returns images that are tagged with "tagname", but are not tagged with "othertagname".</p>
</div>
<p>Wildcard searches are possible as well using * for "any one, more, or none" and ? for "any one".</p>
<div class="command_example">
<pre>tagn*</pre>
<p>Returns images that are tagged with "tagname", "tagnot", or anything else that starts with "tagn".</p>
</div>
<div class="command_example">
<pre>tagn?me</pre>
<p>Returns images that are tagged with "tagname", "tagnome", or anything else that starts with "tagn", has one character, and ends with "me".</p>
</div>
<div class="command_example">
<pre>tags=1</pre>
<p>Returns images with exactly 1 tag.</p>
</div>
<div class="command_example">
<pre>tags>0</pre>
<p>Returns images with 1 or more tags. </p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =.</p>
<hr/>
<p>Search for images by aspect ratio</p>
<div class="command_example">
<pre>ratio=4:3</pre>
<p>Returns images with an aspect ratio of 4:3.</p>
</div>
<div class="command_example">
<pre>ratio>16:9</pre>
<p>Returns images with an aspect ratio greater than 16:9. </p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =. The relation is calculated by dividing width by height.</p>
<hr/>
<p>Search for images by file size</p>
<div class="command_example">
<pre>filesize=1</pre>
<p>Returns images exactly 1 byte in size.</p>
</div>
<div class="command_example">
<pre>filesize>100mb</pre>
<p>Returns images greater than 100 megabytes in size. </p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =. Supported suffixes are kb, mb, and gb. Uses multiples of 1024.</p>
<hr/>
<p>Search for images by MD5 hash</p>
<div class="command_example">
<pre>hash=0D3512CAA964B2BA5D7851AF5951F33B</pre>
<p>Returns image with an MD5 hash 0D3512CAA964B2BA5D7851AF5951F33B.</p>
</div>
<hr/>
<p>Search for images by file type</p>
<div class="command_example">
<pre>filetype=jpg</pre>
<p>Returns images that are of type "jpg".</p>
</div>
<hr/>
<p>Search for images by file name</p>
<div class="command_example">
<pre>filename=picasso.jpg</pre>
<p>Returns images that are named "picasso.jpg".</p>
</div>
<hr/>
<p>Search for images by source</p>
<div class="command_example">
<pre>source=http://google.com/</pre>
<p>Returns images with a source of "http://google.com/".</p>
</div>
<div class="command_example">
<pre>source=any</pre>
<p>Returns images with a source set.</p>
</div>
<div class="command_example">
<pre>source=none</pre>
<p>Returns images without a source set.</p>
</div>
<hr/>
<p>Search for images by date posted.</p>
<div class="command_example">
<pre>posted>=07-19-2019</pre>
<p>Returns images posted on or after 07-19-2019.</p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =. Date format is mm-dd-yyyy. Date posted includes time component, so = will not work unless the time is exact.</p>
<hr/>
<p>Search for images by image dimensions</p>
<div class="command_example">
<pre>size=640x480</pre>
<p>Returns images exactly 640 pixels wide by 480 pixels high.</p>
</div>
<div class="command_example">
<pre>size>1920x1080</pre>
<p>Returns images with a width larger than 1920 and a height larger than 1080.</p>
</div>
<div class="command_example">
<pre>width=1000</pre>
<p>Returns images exactly 1000 pixels wide.</p>
</div>
<div class="command_example">
<pre>height=1000</pre>
<p>Returns images exactly 1000 pixels high.</p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =.</p>
<hr/>
<p>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.</p>
<div class="command_example">
<pre>order:id_asc</pre>
<p>Returns images sorted by ID, smallest first.</p>
</div>
<div class="command_example">
<pre>order:width_desc</pre>
<p>Returns images sorted by width, largest first.</p>
</div>
<p>These fields are supported:
<ul>
<li>id</li>
<li>width</li>
<li>height</li>
<li>filesize</li>
<li>filename</li>
</ul>
</p>
';
}
}

View file

@ -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 = [];

View file

@ -28,4 +28,20 @@ class MediaTheme extends Themelet
</form>
";
}
public function get_help_html()
{
return '<p>Search for items based on the type of media.</p>
<div class="command_example">
<pre>content:audio</pre>
<p>Returns items that contain audio, including videos and audio files.</p>
</div>
<div class="command_example">
<pre>content:video</pre>
<p>Returns items that contain video, including animated GIFs.</p>
</div>
<p>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.</p>
';
}
}

View file

@ -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.

View file

@ -247,4 +247,29 @@ class NotesTheme extends Themelet
$this->display_paginator($page, "note/updated", null, $pageNumber, $totalPages);
}
public function get_help_html()
{
return '<p>Search for images with notes.</p>
<div class="command_example">
<pre>note=noted</pre>
<p>Returns images with a note matching "noted".</p>
</div>
<div class="command_example">
<pre>notes>0</pre>
<p>Returns images with 1 or more notes.</p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =.</p>
<div class="command_example">
<pre>notes_by=username</pre>
<p>Returns images with note(s) by "username".</p>
</div>
<div class="command_example">
<pre>notes_by_user_id=123</pre>
<p>Returns images with note(s) by user 123.</p>
</div>
';
}
}

View file

@ -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 = [];

View file

@ -91,4 +91,47 @@ class NumericScoreTheme extends Themelet
$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 '<p>Search for images that have received numeric scores by the score or by the scorer.</p>
<div class="command_example">
<pre>score=1</pre>
<p>Returns images with a score of 1.</p>
</div>
<div class="command_example">
<pre>score>0</pre>
<p>Returns images with a score of 1 or more.</p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =.</p>
<div class="command_example">
<pre>upvoted_by=username</pre>
<p>Returns images upvoted by "username".</p>
</div>
<div class="command_example">
<pre>upvoted_by_id=123</pre>
<p>Returns images upvoted by user 123.</p>
</div>
<div class="command_example">
<pre>downvoted_by=username</pre>
<p>Returns images downvoted by "username".</p>
</div>
<div class="command_example">
<pre>downvoted_by_id=123</pre>
<p>Returns images downvoted by user 123.</p>
</div>
<div class="command_example">
<pre>order:score_desc</pre>
<p>Sorts the search results by score, descending.</p>
</div>
<div class="command_example">
<pre>order:score_asc</pre>
<p>Sorts the search results by score, ascending.</p>
</div>
';
}
}

View file

@ -372,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 = [];

View file

@ -403,4 +403,32 @@ class PoolsTheme extends Themelet
{
return "<input type='text' name='bulk_pool_new' placeholder='New pool' required='required' value='".(implode(" ",$search_terms))."' />";
}
public function get_help_html()
{
return '<p>Search for images that are in a pool.</p>
<div class="command_example">
<pre>pool=1</pre>
<p>Returns images in pool #1.</p>
</div>
<div class="command_example">
<pre>pool=any</pre>
<p>Returns images in any pool.</p>
</div>
<div class="command_example">
<pre>pool=none</pre>
<p>Returns images not in any pool.</p>
</div>
<div class="command_example">
<pre>pool_by_name=swimming</pre>
<p>Returns images in the "swimming" pool.</p>
</div>
<div class="command_example">
<pre>pool_by_name=swimming_pool</pre>
<p>Returns images in the "swimming pool" pool. Note that the underscore becomes a space</p>
</div>
';
}
}

View file

@ -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;

View file

@ -55,4 +55,32 @@ class RatingsTheme extends Themelet
<option value='u'>Unrated</option>
</select>";
}
public function get_help_html(array $ratings)
{
$output = '<p>Search for images with one or more possible ratings.</p>
<div class="command_example">
<pre>rating:'.$ratings[0]->search_term.'</pre>
<p>Returns images with the '.$ratings[0]->name.' rating.</p>
</div>
<p>Ratings can be abbreviated to a single letter as well</p>
<div class="command_example">
<pre>rating:'.$ratings[0]->code.'</pre>
<p>Returns images with the '.$ratings[0]->name.' rating.</p>
</div>
<p>If abbreviations are used, multiple ratings can be searched for.</p>
<div class="command_example">
<pre>rating:'.$ratings[0]->code.$ratings[1]->code.'</pre>
<p>Returns images with the '.$ratings[0]->name.' or '.$ratings[1]->name.' rating.</p>
</div>
<p>Available ratings:</p>
<table>
<tr><th>Name</th><th>Search Term</th><th>Abbreviation</th></tr>
';
foreach ($ratings as $rating) {
$output .= "<tr><td>{$rating->name}</td><td>{$rating->search_term}</td><td>{$rating->code}</td></tr>";
}
$output .= "</table>";
return $output;
}
}

View file

@ -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 = [];

View file

@ -46,4 +46,32 @@ class RelationshipsTheme extends Themelet
"</tr>\n";
return $html;
}
public function get_help_html()
{
return '<p>Search for images that have parent/child relationships.</p>
<div class="command_example">
<pre>parent=any</pre>
<p>Returns images that have a parent.</p>
</div>
<div class="command_example">
<pre>parent=none</pre>
<p>Returns images that have no parent.</p>
</div>
<div class="command_example">
<pre>parent=123</pre>
<p>Returns images that have image 123 set as parent.</p>
</div>
<div class="command_example">
<pre>child=any</pre>
<p>Returns images that have at least 1 child.</p>
</div>
<div class="command_example">
<pre>child=none</pre>
<p>Returns images that have no children.</p>
</div>
';
}
}

View file

@ -70,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 (
@ -90,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;

View file

@ -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 '<p>Search for images containing a certain number of tags with the specified tag category.</p>
<div class="command_example">
<pre>persontags=1</pre>
<p>Returns images with exactly 1 tag with the tag category "person".</p>
</div>
<div class="command_example">
<pre>cattags>0</pre>
<p>Returns images with 1 or more tags with the tag category "cat". </p>
</div>
<p>Can use &lt;, &lt;=, &gt;, &gt;=, or =.</p>
<p>Category name is not case sensitive, category must exist for search to work.</p>
';
}
}

View file

@ -93,6 +93,20 @@ class Trash extends Extension
}
}
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) {

View file

@ -11,4 +11,16 @@ class TrashTheme extends Themelet
";
return $html; }
public function get_help_html()
{
return '<p>Search for images in the trash.</p>
<div class="command_example">
<pre>in:trash</pre>
<p>Returns images that are in the trash.</p>
</div>
';
}
}

View file

@ -364,6 +364,17 @@ class UserPage extends Extension
}
}
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;

View file

@ -343,4 +343,30 @@ class UserPageTheme extends Themelet
return $html;
}
// }}}
public function get_help_html()
{
global $user;
$output = '<p>Search for images posted by particular individuals.</p>
<div class="command_example">
<pre>poster=username</pre>
<p>Returns images posted by "username".</p>
</div>
<div class="command_example">
<pre>poster_id=123</pre>
<p>Returns images posted by user 123.</p>
</div>
';
if ($user->can(Permissions::VIEW_IP)) {
$output .="
<div class=\"command_example\">
<pre>poster_ip=127.0.0.1</pre>
<p>Returns images posted from IP 127.0.0.1.</p>
</div>
";
}
return $output;
}
}