<?php
/**
 * -------------------------------------------------------------------------
 *
 * The module for searching records stored in the database.
 *
 * -------------------------------------------------------------------------
 *
 * How did this file run?
 *
 *     ├─> .htaccess
 *     └─> index.php
 *           ├─> tiny.news.feed/Config.php
 *           ├─> mimimi.core/Routines.php
 *           │               │
 *           │               └─<─ routine mimimiInclude()
 *           │
 *           ├─> [MAKE THE $app GLOBAL VARIABLE]
 *           │
 *           ├─> tiny.news.feed/Constants.php
 *           │                                      ┌─<─ class mimimi.core/Module.php
 *           │                                      │                        └─> __construct()
 *           │               ┌─<─ class mimimi.core/NodeModule.php
 *           │               │                           └─> __construct()
 *           └─> tiny.news.feed/Application.php
 *                              │    └─> run()                ┌─<─ class mimimi.core/Module.php
 *                              │         │                   │                        └─> __construct()
 *                              │         ├─> mimimi.core/Has/Has.php
 *                              │         │                    └─> __get()
 *                              │         │
 *                              │         │                         ┌─<─ class mimimi.core/Module.php
 *                              │         │                         │                        └─> __construct()
 *                              │         └─> tiny.news.feed/Router/Router.php
 *                              │                                   │  └─> run()
 *                              ├─<─ method getLatest()             │       │
 *                              ├─<─ method getViewers()            │       ├─> [MAKE THE $item GLOBAL VARIABLE  ]
 *                              ├─<─ method getSitemap()            │       ├─> [MAKE THE $items GLOBAL VARIABLE ]
 *                              ├─<─ method getList()               │       ├─> [MAKE THE $page GLOBAL VARIABLE  ]
 *                              ├─<─ method getPage()               │       ├─> [MAKE THE $viewer GLOBAL VARIABLE]
 *                              └─<─ method amIAdmin()              │       ├─> [MAKE THE $url GLOBAL VARIABLE   ]
 *                                                                  │       │
 *                                                                  │       │                              ┌─<─ class mimimi.core/Module.php
 *                                                                  │       ├─> cutViewer()                │                        └─> __construct()
 *                                                                  │       │       └─> mimimi.modules/Url/Url.php
 *                                                                  │       │                               ├─> cutSegment()
 *                                                                  │       │                               └─> cutPaginator()        ┌─<─ class mimimi.core/Module.php
 *                                                                  │       │                                                         │                        └─> __construct()
 *                                                                  │       │                                  ┌─<─ class mimimi.core/NodeModule.php
 *                                                                  │       ├─> checkFor()                     │                           └─> __construct()
 *                                                                  │       │       └─> tiny.news.feed/Viewers/Viewers.php
 *                                                                  │       │                                  │  │                                 ┌─<─ class mimimi.core/Module.php
 *                                                                  │       │                                  │  │                                 │                        └─> __construct()
 *                                                                  │       │                                  │  └─> tiny.news.feed/Viewers/Search/Search.php
 *                                                                  │       │                                  │                                    │  │
 *                                                                  │       │                                  ├─<─ method getViewerNames()         │  │  ┌─ run()       ─┐
 *                                                                  │       │                                  ├─<─ method filterNames()            │  │  ├─ getItem()   ─┤
 *                                                                  │       └─> [RENDER A THEME TEMPLATE]      ├─<─ method cropList()               │  └─>├─ getItems()  ─┤
 *                                                                  │                                          ├─<─ method getQueryParam()          │     ├─ getRecent() ─┤
 *                                                                  ├─<─ method checkFor()                     └─<─ method parseQuery()             │     └─ getSitemap() ┘
 *                                                                  ├─<─ method findMe()                                                            │
 *                                                                  ├─<─ method cutViewer()                                                         └─<─ method searchBy()
 *                                                                  ├─<─ method cutPagenum()
 *                                                                  └─<─ method cutCommand()
 *
 * The down-right arrows show the order in which app files are loaded and
 * their methods that are called when processing a request to the site.
 * The left-down arrows show the classes from which the corresponding
 * application file is derived. The left-up arrows show some of the public
 * routines or some of the public methods that the corresponding file
 * exposes to other application modules.
 *
 * -------------------------------------------------------------------------
 *
 * @package    MimimiFramework
 * @subpackage Examples / Tiny News Feed site
 * @license    GPL-2.0
 *             https://opensource.org/license/gpl-2-0/
 * @copyright  2022 MiMiMi Community
 *             https://mimimi.software/
 *
 * -------------------------------------------------------------------------
 */

                                                        // -----------------
mimimiInclude(                                          // load a file              ( see file mimimi.core/Routines.php -> mimimiInclude )
    'Module.php'                                        // . . with this base class ( see file mimimi.core/Module.php   -> MimimiModule )
);                                                      //
                                                        //
class MyMimimiViewersSearch extends MimimiModule {      // define required "My..." class for this module named SEARCH

    /**
     * ---------------------------------------------------------------------
     *
     * Custom routing of the requested page URL.
     *
     * ---------------------------------------------------------------------
     *
     * Please use this method if the right side of the URL needs to be
     * routed in some non-standard way. In this case, you should parse the
     * URL according to some rules for the SEARCH module, read the associated
     * database records, prepare the necessary variables, and return the
     * file name of the corresponding template.
     *
     * ---------------------------------------------------------------------
     *
     * An example of custom routing:
     *
     *     public function run ( $params = '' ) {
     *         global $items;
     *                $items = FALSE;
     *         $template = $this->app->router->findMe('search-list.tpl');
     *         if ( $template ) {
     *             global $page;
     *                    $page    = $this->app->router->cutPagenum($params);
     *             $pagesize       = 12;
     *             $administrative = $this->app->amIAdmin();
     *             global $url;
     *                    $url     = $params;
     *             switch ( $params ) {
     *                 case '':
     *                     $query = $this->owner->getQueryParam('q');
     *                     $items = $this->searchBy($query, $page, $pagesize, $administrative);
     *                     break;
     *                 default:
     *                     $type = $this->app->router->cutViewer($params);
     *                     switch ( $type ) {
     *                         case 'tags':
     *                             $items = $this->searchByTag($params, $page, $pagesize, $administrative);
     *                             break;
     *                         case 'archive':
     *                             $items = $this->searchByDate($params, $page, $pagesize, $administrative);
     *                             break;
     *                     }
     *             }
     *         }
     *         return $items !== FALSE ? $template : '';
     *     }
     *
     * That example routes these URLs:
     *
     *      https://your.site/search?q=STRING-FOR-SEARCH
     *      https://your.site/search/page-NNN?q=STRING-FOR-SEARCH
     *      https://your.site/search/tags/TAG-FOR-SEARCH
     *      https://your.site/search/tags/TAG-FOR-SEARCH/page-NNN
     *      https://your.site/search/archive/DATE-FOR-SEARCH
     *      https://your.site/search/archive/DATE-FOR-SEARCH/page-NNN
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   string       $params  (optional) The URL path of the requested page.
     * @return  string|bool           STRING       if we parse the URL ourselves and find the corresponding page template.
     *                                EMPTY STRING if the URL was parsed successfully but an Error404 was encountered.
     *                                FALSE        to parse the URL in a standard way.
     *
     * ---------------------------------------------------------------------
     */

    public function run ( $params = '' ) {              // -----------------
        global $items;                                  // there is no template
               $items = FALSE;                          //
                                                        // -----------------
        $file = $this                                   // get associated template
                ->app                                   // . . via APPLICATION module ( see file tiny.news.feed/Application.php )
                ->router                                // . . via ROUTER module      ( see file tiny.news.feed/Router/Router.php -> findMe )
                ->findMe(                               // . . using this method
                    'search-list.tpl'                   // . . . . with this filename
                );                                      //
                                                        // -----------------
        if ( $file ) {                                  // if successful
            global $page;                               //     initialize a secondary template variable
                   $page = $this                        //     . . equal to the page number (that is, trim paginator - it's the last segment of URL)
                           ->app                        //         . . via APPLICATION module ( see file tiny.news.feed/Application.php )
                           ->router                     //         . . via ROUTER module      ( see file tiny.news.feed/Router/Router.php -> cutPagenum )
                           ->cutPagenum(                //         . . using this method
                               $params                  //         . . . . from this URL path
                           );                           //
                                                        // -----------------
            global $url;                                //     initialize a secondary template variable
                   $url = $params;                      //     . . equal to the pure path portion of the URL
                                                        // -----------------
            if ( $params == '' ) {                      //     if that URL path contains only paginator
                $ok = $this                             //         am I admin?
                      ->app                             //         . . via APPLICATION module ( see file tiny.news.feed/Application.php -> amIAdmin )
                      ->amIAdmin();                     //         . . using this method
                                                        // -----------------
                $query = $this                          //         get value of searching form
                         ->owner                        //         . . via VIEWERS module ( see file tiny.news.feed/Viewers/Viewers.php -> getQueryParam )
                         ->getQueryParam('q');          //         . . using this method
                                                        // -----------------
                $items = $this->searchBy(               //         find results
                             $query,                    //         . . with this query
                             $page,                     //         . . located on this page
                             12,                        //         . . expected list capacity
                             $ok                        //         . . if I'm admin, get items even if they are disabled
                         );                             //
            }                                           //
        }                                               //
                                                        // -----------------
        return $items !== FALSE                         // return a template filename
                      ? $file                           // . . for success case
                      : '';                             // . . for Error404 case
    }                                                   // -----------------

    /**
     * ---------------------------------------------------------------------
     *
     * Retrieves sitemap results.
     *
     * ---------------------------------------------------------------------
     *
     * This is a dummy method because it doesn't makes sense for search
     * functionality. What does "sitemap results" mean? Therefore, this
     * method should not do anything and therefore always returns FALSE.
     * We declared it because every viewer module must have a specific set
     * of public methods (see file tiny.news.feed/Viewers/Viewers.php for
     * details).
     *
     * ---------------------------------------------------------------------
     */

    public function getSitemap ( $mapsize = 50000 ) {   // -----------------
        return FALSE;                                   // no sence for this module
    }                                                   // -----------------

    /**
     * ---------------------------------------------------------------------
     *
     * Retrieves the result by its URL.
     *
     * ---------------------------------------------------------------------
     *
     * This is a dummy method because it doesn't makes sense for search
     * functionality. What does "the result by its URL" mean? Therefore,
     * this method should not do anything and therefore always returns FALSE.
     * We declared it because every viewer module must have a specific set
     * of public methods (see file tiny.news.feed/Viewers/Viewers.php for
     * details).
     *
     * ---------------------------------------------------------------------
     */

    public function getItem ( $url, $any = FALSE ) {    // -----------------
        return FALSE;                                   // no sence for this module
    }                                                   // -----------------

    /**
     * ---------------------------------------------------------------------
     *
     * Retrieves results listed on the numbered page.
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   int    $page  The requested page number.
     * @param   int    $size  (optional) The capacity of the page. Default size is 12 (that is 3 * 4 news).
     * @param   bool   $any   (optional) TRUE to retrieve results even if they are disabled.
     *                                        FALSE to retrieve only enabled results.
     * @return  array         ARRAY OF ARRAYS, each nested item is an array like a database table row.
     *
     * ---------------------------------------------------------------------
     */

    public function getItems ( $page, $size = 12, $any = FALSE ) {
                                                        // -----------------
        $query = $this                                  // get the query string
                 ->owner                                // . . via VIEWERS module ( see file tiny.news.feed/Viewers/Viewers.php -> getQueryParam )
                 ->getQueryParam(                       // . . using this method
                     'q'                                //     . . from this POST or GET parameter
                 );                                     //
                                                        // -----------------
        return $this->searchBy(                         // return results
                   $query,                              // . . for this query
                   $page,                               // . . located on this page
                   $size,                               // . . expected list capacity
                   $any                                 // . . if I'm admin, get items even if they are disabled
               );                                       //
    }                                                   // -----------------

    /**
     * ---------------------------------------------------------------------
     *
     * Searches for results listed on the numbered page.
     *
     * ---------------------------------------------------------------------
     *
     * @public
     * @param   string  $query  The query string to search for.
     * @param   int     $page   The requested page number.
     * @param   int     $size   (optional) The capacity of the page. Default size is 12 (that is 3 * 4 news).
     * @param   bool    $any    (optional) TRUE to search results even if they are disabled.
     *                                          FALSE to search only enabled results.
     * @return  array           ARRAY OF ARRAYS, each nested item is an array like a database table row.
     *
     * ---------------------------------------------------------------------
     */

    public function searchBy ( $query, $page, $size = 12, $any = FALSE ) {
                                                        // -----------------
        $result = [];                                   // there are no results
        if ( is_string($query) ) {                      // if there is a query
                                                        // -----------------
            $list = $this                               //     get viewer names
                    ->owner                             //     . . via VIEWERS module ( see file tiny.news.feed/Viewers/Viewers.php -> getViewerNames )
                    ->getViewerNames();                 //     . . using this method
            if ( $list ) {                              //     it must be a non-empty list
                                                        // -----------------
                foreach ( $list as $viewer ) {          //         walk through the viewer names
                    if ( $viewer != 'search' ) {        //             except name of this viewer
                        $rows = $this                   //                 find results
                                ->owner                 //                 . . via VIEWERS module   ( see file tiny.news.feed/Viewers/Viewers.php )
                                ->$viewer               //                 . . using this submodule ( see file tiny.news.feed/Viewers/[$viewer]/[$viewer].php -> searchBy )
                                ->searchBy(             //                 . . using this method
                                    $query,             //                     . . with this query
                                    $page,              //                     . . located on this page
                                    $size,              //                     . . expected list capacity
                                    $any                //                     . . if I'm admin, get items even if they are disabled
                                );                      //
                                                        // -----------------
                        if ( $rows ) {                  //                 if results are found
                            $result[$viewer] = $rows;   //                     add them to the final list as an indexed element
                        }                               //
                    }                                   //
                }                                       //
            }                                           //
        }                                               //
                                                        // -----------------
        return $result;                                 // return results
    }                                                   // -----------------

    /**
     * ---------------------------------------------------------------------
     *
     * Retrieves the latest results.
     *
     * ---------------------------------------------------------------------
     *
     * This is a dummy method because it doesn't makes sense for search
     * functionality. What does "the latest results" mean? Therefore, this
     * method should not do anything and therefore always returns FALSE.
     * We declared it because every viewer module must have a specific set
     * of public methods (see file tiny.news.feed/Viewers/Viewers.php for
     * details).
     *
     * ---------------------------------------------------------------------
     */

    public function getRecent ( $size = 6, $any = FALSE ) {
                                                        // -----------------
        return FALSE;                                   // no sence for this module
    }                                                   // -----------------
};