Converted article search to ISearchProvider implementation
authorMarcel Werk <burntime@woltlab.com>
Sat, 11 Dec 2021 13:04:21 +0000 (14:04 +0100)
committerMarcel Werk <burntime@woltlab.com>
Sat, 11 Dec 2021 13:04:21 +0000 (14:04 +0100)
com.woltlab.wcf/templates/pageHeaderSearch.tpl
com.woltlab.wcf/templates/searchArticle.tpl
wcfsetup/install/files/lib/system/search/ArticleSearch.class.php

index 9272122d440293fa26e0474e5984be4ecb8da018..6ff3b15ae2ae4ff019605f5dc7b441b4299954d1 100644 (file)
@@ -12,7 +12,7 @@
        {assign var='__searchObjectTypeName' value='com.woltlab.wcf.article'}
        
        {capture assign='__searchTypesScoped'}
-               {if $category|isset}<li><a href="#" data-extended-link="{link controller='Search'}types[]=com.woltlab.wcf.article{/link}" data-object-type="com.woltlab.wcf.article" data-parameters='{ "articleCategoryIDs[]": {@$category->categoryID} }'>{$category->getTitle()}</a></li>{/if}
+               {if $category|isset}<li><a href="#" data-extended-link="{link controller='Search'}type=com.woltlab.wcf.article&extended=1{/link}" data-object-type="com.woltlab.wcf.article" data-parameters='{ "articleCategoryID": {@$category->categoryID} }'>{$category->getTitle()}</a></li>{/if}
        {/capture}
        {assign var='__searchAreaInitialized' value=true}
 {/if}
index 6c6a5615b68a5d8e7ed01918467243d87af55238..a32b0beee85212b8e023bd464de62445b028700c 100644 (file)
@@ -1,13 +1,12 @@
 <dl>
        <dt><label>{lang}wcf.article.search.categories{/lang}</label></dt>
        <dd>
-               <ul class="scrollableCheckboxList">
+               <select name="articleCategoryID">
+                       <option value="">{lang}wcf.global.language.noSelection{/lang}</option>
                        {foreach from=$articleCategoryList item=category}
-                               <li{if $category->getDepth() > 1} style="padding-left: {$category->getDepth()*20-20}px"{/if}>
-                                       <label><input type="checkbox" name="articleCategoryIDs[]" value="{@$category->categoryID}"{if $category->categoryID|in_array:$articleCategoryIDs} checked{/if}> {$category->getTitle()}</label>
-                               </li>
+                               <option value="{@$category->categoryID}">{if $category->getDepth() > 1}{@'&nbsp;&nbsp;&nbsp;&nbsp;'|str_repeat:-1+$category->getDepth()}{/if}{$category->getTitle()}</option>
                        {/foreach}
-               </ul>
+               </select>
        </dd>
 </dl>
 
index 9b9592ef1128fa5352ac5cc1ffdf9393e8dead72..62edea017c770c4391a4415c4d58f6121c5b73e8 100644 (file)
@@ -7,16 +7,12 @@ use wcf\data\article\category\ArticleCategory;
 use wcf\data\article\category\ArticleCategoryNodeTree;
 use wcf\data\article\content\SearchResultArticleContent;
 use wcf\data\article\content\SearchResultArticleContentList;
-use wcf\form\IForm;
-use wcf\form\SearchForm;
+use wcf\data\search\ISearchResultObject;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
-use wcf\system\exception\PermissionDeniedException;
-use wcf\system\page\PageLocationManager;
 use wcf\system\WCF;
-use wcf\util\ArrayUtil;
 
 /**
- * An implementation of ISearchableObjectType for searching in articles.
+ * An implementation of ISearchProvider for searching in articles.
  *
  * @author      Marcel Werk
  * @copyright   2001-2019 WoltLab GmbH
@@ -24,24 +20,22 @@ use wcf\util\ArrayUtil;
  * @package WoltLabSuite\Core\System\Search
  * @since   3.0
  */
-class ArticleSearch extends AbstractSearchableObjectType
+class ArticleSearch extends AbstractSearchProvider
 {
     /**
-     * ids of the selected categories
-     * @var int[]
+     * @var int
      */
-    public $articleCategoryIDs = [];
+    private $articleCategoryID = 0;
 
     /**
-     * message data cache
      * @var SearchResultArticleContent[]
      */
-    public $messageCache = [];
+    private $messageCache = [];
 
     /**
      * @inheritDoc
      */
-    public function cacheObjects(array $objectIDs, ?array $additionalData = null)
+    public function cacheObjects(array $objectIDs, ?array $additionalData = null): void
     {
         $list = new SearchResultArticleContentList();
         $list->setObjectIDs($objectIDs);
@@ -54,7 +48,7 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getObject($objectID)
+    public function getObject(int $objectID): ?ISearchResultObject
     {
         return $this->messageCache[$objectID] ?? null;
     }
@@ -62,7 +56,7 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getTableName()
+    public function getTableName(): string
     {
         return 'wcf' . WCF_N . '_article_content';
     }
@@ -70,7 +64,7 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getIDFieldName()
+    public function getIDFieldName(): string
     {
         return $this->getTableName() . '.articleContentID';
     }
@@ -78,7 +72,7 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getSubjectFieldName()
+    public function getSubjectFieldName(): string
     {
         return $this->getTableName() . '.title';
     }
@@ -86,7 +80,7 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getUsernameFieldName()
+    public function getUsernameFieldName(): string
     {
         return 'wcf' . WCF_N . '_article.username';
     }
@@ -94,7 +88,7 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getTimeFieldName()
+    public function getTimeFieldName(): string
     {
         return 'wcf' . WCF_N . '_article.time';
     }
@@ -102,35 +96,55 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getConditions(?IForm $form = null)
+    public function getConditionBuilder(array $parameters): ?PreparedStatementConditionBuilder
     {
-        // accessible category ids
-        if (isset($_POST['articleCategoryIDs'])) {
-            $this->articleCategoryIDs = ArrayUtil::toIntegerArray($_POST['articleCategoryIDs']);
+        if (!empty($parameters['articleCategoryID'])) {
+            $this->articleCategoryID = \intval($parameters['articleCategoryID']);
         }
+
+        $articleCategoryIDs = $this->getArticleCategoryIDs($this->articleCategoryID);
         $accessibleCategoryIDs = ArticleCategory::getAccessibleCategoryIDs();
-        if (!empty($this->articleCategoryIDs)) {
-            $this->articleCategoryIDs = \array_intersect($accessibleCategoryIDs, $this->articleCategoryIDs);
-        } else {
-            $this->articleCategoryIDs = $accessibleCategoryIDs;
+        if (!empty($articleCategoryIDs)) {
+            $articleCategoryIDs = \array_intersect($articleCategoryIDs, $accessibleCategoryIDs);
         }
-        if (empty($this->articleCategoryIDs)) {
-            throw new PermissionDeniedException();
+        else {
+            $articleCategoryIDs = $accessibleCategoryIDs;
         }
 
         $conditionBuilder = new PreparedStatementConditionBuilder();
-        $conditionBuilder->add(
-            'wcf' . WCF_N . '_article.categoryID IN (?) AND wcf' . WCF_N . '_article.publicationStatus = ?',
-            [$this->articleCategoryIDs, Article::PUBLISHED]
-        );
-
+        if (empty($articleCategoryIDs)) {
+            $conditionBuilder->add('1=0');
+        }
+        else {
+            $conditionBuilder->add(
+                'wcf' . WCF_N . '_article.categoryID IN (?) AND wcf' . WCF_N . '_article.publicationStatus = ?',
+                [$articleCategoryIDs, Article::PUBLISHED]
+            );
+        }
+        
         return $conditionBuilder;
     }
 
+    private function getArticleCategoryIDs(int $categoryID): array
+    {
+        $categoryIDs = [];
+
+        if ($categoryID) {
+            if (($category = ArticleCategory::getCategory($categoryID)) !== null) {
+                $categoryIDs[] = $categoryID;
+                foreach ($category->getAllChildCategories() as $childCategory) {
+                    $categoryIDs[] = $childCategory->categoryID;
+                }
+            }
+        }
+        
+        return $categoryIDs;
+    }
+
     /**
      * @inheritDoc
      */
-    public function getJoins()
+    public function getJoins(): string
     {
         return '
             INNER JOIN  wcf' . WCF_N . '_article
@@ -140,7 +154,7 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getFormTemplateName()
+    public function getFormTemplateName(): string
     {
         return 'searchArticle';
     }
@@ -148,15 +162,15 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function getAdditionalData()
+    public function getAdditionalData(): ?array
     {
-        return ['articleCategoryIDs' => $this->articleCategoryIDs];
+        return ['articleCategoryID' => $this->articleCategoryID];
     }
 
     /**
      * @inheritDoc
      */
-    public function isAccessible()
+    public function isAccessible(): bool
     {
         return MODULE_ARTICLE && SEARCH_ENABLE_ARTICLES;
     }
@@ -164,27 +178,10 @@ class ArticleSearch extends AbstractSearchableObjectType
     /**
      * @inheritDoc
      */
-    public function show(?IForm $form = null)
+    public function assignVariables(): void
     {
-        /** @var SearchForm $form */
-
-        // get existing values
-        if ($form !== null && isset($form->searchData['additionalData']['com.woltlab.wcf.article'])) {
-            $this->articleCategoryIDs = $form->searchData['additionalData']['com.woltlab.wcf.article']['articleCategoryIDs'];
-        }
-
         WCF::getTPL()->assign([
-            'articleCategoryIDs' => $this->articleCategoryIDs,
             'articleCategoryList' => (new ArticleCategoryNodeTree('com.woltlab.wcf.article.category'))->getIterator(),
         ]);
     }
-
-    /**
-     * @inheritDoc
-     * @since   3.0
-     */
-    public function setLocation()
-    {
-        PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.ArticleList');
-    }
 }