Add simple pip entry list filter
authorMatthias Schmidt <gravatronics@live.com>
Sun, 7 Oct 2018 08:33:32 +0000 (10:33 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 7 Oct 2018 08:33:32 +0000 (10:33 +0200)
See #2545

wcfsetup/install/files/acp/templates/devtoolsProjectPipEntryList.tpl
wcfsetup/install/files/lib/acp/page/DevtoolsProjectPipEntryListPage.class.php
wcfsetup/install/files/lib/system/devtools/pip/DevtoolsPipEntryList.class.php
wcfsetup/install/files/lib/system/devtools/pip/IDevtoolsPipEntryList.class.php

index 7067bef227b99ad73b4125ce2eb5d371e3efe9aa..f600ba938b100ceb5eedccc3bee6148eae9b57b9 100644 (file)
        </nav>
 </header>
 
+<form method="post" action="{link controller='DevtoolsProjectPipEntryList' id=$project->projectID pip=$pip}{/link}">
+       <section class="section">
+               <h2 class="sectionTitle">{lang}wcf.global.filter{/lang}</h2>
+               
+               <dl>
+                       <dt></dt>
+                       <dd>
+                               <input type="text" id="search" name="entryFilter" value="{$entryFilter}" placeholder="{lang}wcf.global.filter{/lang}" class="long">
+                       </dd>
+               </dl>
+               
+               <div class="formSubmit">
+                       <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s">
+                       {@SECURITY_TOKEN_INPUT_TAG}
+               </div>
+       </section>
+</form>
+
 {hascontent}
        <div class="paginationTop">
                {content}
index eaecf818e86c6e85a75581249783873314558f04..1be94b722e389f287247ec256c21a09469c3d24f 100644 (file)
@@ -5,6 +5,7 @@ use wcf\page\AbstractPage;
 use wcf\system\devtools\pip\DevtoolsPip;
 use wcf\system\devtools\pip\IDevtoolsPipEntryList;
 use wcf\system\exception\IllegalLinkException;
+use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\StringUtil;
 
@@ -29,6 +30,12 @@ class DevtoolsProjectPipEntryListPage extends AbstractPage {
         */
        public $endIndex = 0;
        
+       /**
+        * entry filter string
+        * @var string
+        */
+       public $entryFilter;
+       
        /**
         * pip entry list
         * @var IDevtoolsPipEntryList
@@ -41,6 +48,11 @@ class DevtoolsProjectPipEntryListPage extends AbstractPage {
         */
        public $entryType;
        
+       /**
+        * @inheritDoc
+        */
+       public $forceCanonicalURL = true;
+       
        /**
         * number of items shown per page
         * @var integer
@@ -113,6 +125,7 @@ class DevtoolsProjectPipEntryListPage extends AbstractPage {
        
        /**
         * @inheritDoc
+        * @throws      IllegalLinkException
         */
        public function readParameters() {
                parent::readParameters();
@@ -161,6 +174,16 @@ class DevtoolsProjectPipEntryListPage extends AbstractPage {
                if ($this->entryType !== null) {
                        $this->linkParameters .= '&entryType=' . $this->entryType;
                }
+               
+               if (isset($_REQUEST['entryFilter'])) $this->entryFilter = StringUtil::trim($_REQUEST['entryFilter']);
+               
+               if ($this->entryFilter !== null && $this->entryFilter !== '') {
+                       $this->linkParameters .= '&entryFilter=' . $this->entryFilter;
+               }
+               
+               $this->canonicalURL = LinkHandler::getInstance()->getLink('DevtoolsProjectPipEntryList', [
+                       'id' => $this->project->projectID,
+               ], $this->linkParameters);
        }
        
        /**
@@ -172,6 +195,10 @@ class DevtoolsProjectPipEntryListPage extends AbstractPage {
                /** @var IDevtoolsPipEntryList entryList */
                $this->entryList = $this->pipObject->getPip()->getEntryList();
                
+               if ($this->entryFilter !== null && $this->entryFilter !== '') {
+                       $this->entryList->filterEntries($this->entryFilter);
+               }
+               
                $this->items = count($this->entryList->getEntries());
                $this->pages = intval(ceil($this->items / $this->itemsPerPage));
                
@@ -194,6 +221,7 @@ class DevtoolsProjectPipEntryListPage extends AbstractPage {
                
                WCF::getTPL()->assign([
                        'endIndex' => $this->endIndex,
+                       'entryFilter' => $this->entryFilter,
                        'entryList' => $this->entryList,
                        'entryType' => $this->entryType,
                        'items' => $this->items,
index 2d54cc6a51a324bfa67aa9e513471e5d1d186cf9..7971a23d918b4d936504d5c6cd30ad4f7268a461 100644 (file)
@@ -52,6 +52,52 @@ class DevtoolsPipEntryList implements IDevtoolsPipEntryList {
                $this->entries[$id] = $entry;
        }
        
+       /**
+        * @inheritDoc
+        */
+       public function filterEntries($filter) {
+               $filterType = gettype($filter);
+               
+               switch ($filterType) {
+                       case 'array':
+                               $unknownFilters = array_diff(array_keys($filter), array_keys($this->keys));
+                               
+                               if (!empty($unknownFilters)) {
+                                       throw new \InvalidArgumentException("Unknown filter" . (count($unknownFilters) > 1 ? 's' : '') . " '". implode(', ', $unknownFilters) ."'.");
+                               }
+                               
+                               $filteredEntries = [];
+                               foreach ($this->entries as $id => $entry) {
+                                       foreach ($filter as $filterKey => $filterString) {
+                                               if (isset($entry[$filterKey]) && strpos($entry[$filterKey], $filterString) !== false) {
+                                                       $filteredEntries[$id] = $entry;
+                                               }
+                                       }
+                               }
+                               
+                               $this->entries = $filteredEntries;
+                               
+                               break;
+                               
+                       case 'string':
+                               $filteredEntries = [];
+                               foreach ($this->entries as $id => $entry) {
+                                       foreach ($this->keys as $key => $label) {
+                                               if (isset($entry[$key]) && strpos($entry[$key], $filter) !== false) {
+                                                       $filteredEntries[$id] = $entry;
+                                               }
+                                       }
+                               }
+                               
+                               $this->entries = $filteredEntries;
+                               
+                               break;
+                               
+                       default:
+                               throw new \InvalidArgumentException("Cannot use '{$filterType}' to filter entries.");
+               }
+       }
+       
        /**
         * @inheritDoc
         */
index ddfd95d11218d9a88db3ce57ee04323ac41b73f4..1eab69ddc5b35577821deefae7696295626a69f8 100644 (file)
@@ -22,6 +22,19 @@ interface IDevtoolsPipEntryList {
         */
        public function addEntry($id, array $entry);
        
+       /**
+        * Internally filters the entries using the given filter.
+        * `getEntries()` will only return filter entries afterwards.
+        * 
+        * This filter is applied to the elements currently in the list.
+        * Entries added afterwards are not affected by this filter.
+        * 
+        * Applying a second filter will filter the pre-filtered entries.
+        * 
+        * @param       string|array    $filter         either a string that is used to search all entry elements or filter map `key => searchString`
+        */
+       public function filterEntries($filter);
+       
        /**
         * Returns all entries in the list.
         *