Example #1
0
 /**
  * The real callback function for converting the input text to wiki text output
  *
  * @access	public
  * @param	string	Raw User Input
  * @param	object	Mediawiki Parser object.
  * @param	array	End Reset Booleans
  * @param	array	End Eliminate Booleans
  * @param	boolean	[Optional] Called as a parser tag
  * @return	string	Wiki/HTML Output
  */
 public function parse($input, \Parser $parser, &$reset, &$eliminate, $isParserTag = false)
 {
     wfProfileIn(__METHOD__);
     $dplStartTime = microtime(true);
     $this->parser = $parser;
     //Reset headings when being ran more than once in the same page load.
     Article::resetHeadings();
     //Check that we are not in an infinite transclusion loop
     if (isset($this->parser->mTemplatePath[$this->parser->mTitle->getPrefixedText()])) {
         $this->logger->addMessage(\DynamicPageListHooks::WARN_TRANSCLUSIONLOOP, $this->parser->mTitle->getPrefixedText());
         return $this->getFullOutput();
     }
     //Check if DPL shall only be executed from protected pages.
     if (Config::getSetting('runFromProtectedPagesOnly') === true && !$this->parser->mTitle->isProtected('edit')) {
         //Ideally we would like to allow using a DPL query if the query istelf is coded on a template page which is protected. Then there would be no need for the article to be protected.  However, how can one find out from which wiki source an extension has been invoked???
         $this->logger->addMessage(\DynamicPageListHooks::FATAL_NOTPROTECTED, $this->parser->mTitle->getPrefixedText());
         return $this->getFullOutput();
     }
     /************************************/
     /* Check for URL Arguments in Input */
     /************************************/
     if (strpos($input, '{%DPL_') >= 0) {
         for ($i = 1; $i <= 5; $i++) {
             $this->urlArguments[] = 'DPL_arg' . $i;
         }
     }
     $input = $this->resolveUrlArguments($input, $this->urlArguments);
     $this->getUrlArgs($this->parser);
     $this->parameters->setParameter('offset', $this->wgRequest->getInt('DPL_offset', $this->parameters->getData('offset')['default']));
     $offset = $this->parameters->getParameter('offset');
     /***************************************/
     /* User Input preparation and parsing. */
     /***************************************/
     $cleanParameters = $this->prepareUserInput($input);
     if (!is_array($cleanParameters)) {
         //Short circuit for dumb things.
         $this->logger->addMessage(\DynamicPageListHooks::FATAL_NOSELECTION);
         return $this->getFullOutput();
     }
     $cleanParameters = $this->parameters->sortByPriority($cleanParameters);
     $this->parameters->setParameter('includeuncat', false);
     // to check if pseudo-category of Uncategorized pages is included
     foreach ($cleanParameters as $parameter => $option) {
         foreach ($option as $_option) {
             //Parameter functions return true or false.  The full parameter data will be passed into the Query object later.
             if ($this->parameters->{$parameter}($_option) === false) {
                 //Do not build this into the output just yet.  It will be collected at the end.
                 $this->logger->addMessage(\DynamicPageListHooks::WARN_WRONGPARAM, $parameter, $_option);
             }
         }
     }
     /*************************/
     /* Execute and Exit Only */
     /*************************/
     if ($this->parameters->getParameter('execandexit') !== null) {
         //The keyword "geturlargs" is used to return the Url arguments and do nothing else.
         if ($this->parameters->getParameter('execandexit') == 'geturlargs') {
             return;
         }
         //In all other cases we return the value of the argument which may contain parser function calls.
         return $this->parameters->getParameter('execandexit');
     }
     //Construct internal keys for TableRow according to the structure of "include".  This will be needed in the output phase.
     if ($this->parameters->getParameter('seclabels') !== null) {
         $this->parameters->setParameter('tablerow', $this->updateTableRowKeys($this->parameters->getParameter('tablerow'), $this->parameters->getParameter('seclabels')));
     }
     /****************/
     /* Check Errors */
     /****************/
     $errors = $this->doQueryErrorChecks();
     if ($errors === false) {
         //WHAT HAS HAPPENED OH NOOOOOOOOOOOOO.
         return $this->getFullOutput();
     }
     $calcRows = false;
     if (!Config::getSetting('allowUnlimitedResults') && $this->parameters->getParameter('goal') != 'categories' && strpos($this->parameters->getParameter('resultsheader') . $this->parameters->getParameter('noresultsheader') . $this->parameters->getParameter('resultsfooter'), '%TOTALPAGES%') !== false) {
         $calcRows = true;
     }
     /*********/
     /* Query */
     /*********/
     try {
         $this->query = new Query($this->parameters);
         $result = $this->query->buildAndSelect($calcRows);
     } catch (MWException $e) {
         $this->logger->addMessage(\DynamicPageListHooks::FATAL_SQLBUILDERROR, $e->getMessage());
         return $this->getFullOutput();
     }
     $numRows = $this->DB->numRows($result);
     $articles = $this->processQueryResults($result);
     $this->addOutput('{{Extension DPL}}');
     //Preset these to defaults.
     $this->setVariable('TOTALPAGES', 0);
     $this->setVariable('PAGES', 0);
     $this->setVariable('VERSION', DPL_VERSION);
     /*********************/
     /* Handle No Results */
     /*********************/
     if ($numRows <= 0 || empty($articles)) {
         //Shortcut out since there is no processing to do.
         $this->DB->freeResult($result);
         return $this->getFullOutput(0, false);
     }
     $foundRows = null;
     if ($calcRows) {
         $foundRows = $this->query->getFoundRows();
     }
     //Backward scrolling: If the user specified only titlelt with descending reverse the output order.
     if ($this->parameters->getParameter('titlelt') && !$this->parameters->getParameter('titlegt') && $this->parameters->getParameter('order') == 'descending') {
         $articles = array_reverse($articles);
     }
     //Special sort for card suits (Bridge)
     if ($this->parameters->getParameter('ordersuitsymbols')) {
         $articles = $this->cardSuitSort($articles);
     }
     /*******************/
     /* Generate Output */
     /*******************/
     $listMode = new ListMode($this->parameters->getParameter('mode'), $this->parameters->getParameter('secseparators'), $this->parameters->getParameter('multisecseparators'), $this->parameters->getParameter('inlinetext'), $this->parameters->getParameter('listattr'), $this->parameters->getParameter('itemattr'), $this->parameters->getParameter('listseparators'), $offset, $this->parameters->getParameter('dominantsection'));
     $hListMode = new ListMode($this->parameters->getParameter('headingmode'), $this->parameters->getParameter('secseparators'), $this->parameters->getParameter('multisecseparators'), '', $this->parameters->getParameter('hlistattr'), $this->parameters->getParameter('hitemattr'), $this->parameters->getParameter('listseparators'), $offset, $this->parameters->getParameter('dominantsection'));
     $this->dpl = new DynamicPageList(Article::getHeadings(), $this->parameters->getParameter('headingcount'), $this->parameters->getParameter('columns'), $this->parameters->getParameter('rows'), $this->parameters->getParameter('rowsize'), $this->parameters->getParameter('rowcolformat'), $articles, $this->parameters->getParameter('ordermethods')[0], $hListMode, $listMode, $this->parameters->getParameter('escapelinks'), $this->parameters->getParameter('addexternallink'), $this->parameters->getParameter('incpage'), $this->parameters->getParameter('includemaxlen'), $this->parameters->getParameter('seclabels'), $this->parameters->getParameter('seclabelsmatch'), $this->parameters->getParameter('seclabelsnotmatch'), $this->parameters->getParameter('incparsed'), $this->parser, $this->parameters->getParameter('replaceintitle'), $this->parameters->getParameter('titlemaxlen'), $this->parameters->getParameter('defaulttemplatesuffix'), $this->parameters->getParameter('tablerow'), $this->parameters->getParameter('includetrim'), $this->parameters->getParameter('tablesortcol'), $this->parameters->getParameter('updaterules'), $this->parameters->getParameter('deleterules'));
     if ($foundRows === null) {
         $foundRows = $this->dpl->getRowCount();
     }
     $this->addOutput($this->dpl->getText());
     /*******************************/
     /* Replacement Variables       */
     /*******************************/
     $this->setVariable('TOTALPAGES', $foundRows);
     //Guaranteed to be an accurate count if SQL_CALC_FOUND_ROWS was used.  Otherwise only accurate if results are less than the SQL LIMIT.
     $this->setVariable('PAGES', $this->dpl->getRowCount());
     //This could be different than TOTALPAGES.  PAGES represents the total results within the constraints of SQL LIMIT.
     //Replace %DPLTIME% by execution time and timestamp in header and footer
     $nowTimeStamp = date('Y/m/d H:i:s');
     $dplElapsedTime = sprintf('%.3f sec.', microtime(true) - $dplStartTime);
     $dplTime = "{$dplElapsedTime} ({$nowTimeStamp})";
     $this->setVariable('DPLTIME', $dplTime);
     //Replace %LASTTITLE% / %LASTNAMESPACE% by the last title found in header and footer
     if (($n = count($articles)) > 0) {
         $firstNamespaceFound = str_replace(' ', '_', $articles[0]->mTitle->getNamespace());
         $firstTitleFound = str_replace(' ', '_', $articles[0]->mTitle->getText());
         $lastNamespaceFound = str_replace(' ', '_', $articles[$n - 1]->mTitle->getNamespace());
         $lastTitleFound = str_replace(' ', '_', $articles[$n - 1]->mTitle->getText());
     }
     $this->setVariable('FIRSTNAMESPACE', $firstNamespaceFound);
     $this->setVariable('FIRSTTITLE', $firstTitleFound);
     $this->setVariable('LASTNAMESPACE', $lastNamespaceFound);
     $this->setVariable('LASTTITLE', $lastTitleFound);
     $this->setVariable('SCROLLDIR', $this->parameters->getParameter('scrolldir'));
     /*******************************/
     /* Scroll Variables            */
     /*******************************/
     $scrollVariables = ['DPL_firstNamespace' => $firstNamespaceFound, 'DPL_firstTitle' => $firstTitleFound, 'DPL_lastNamespace' => $lastNamespaceFound, 'DPL_lastTitle' => $lastTitleFound, 'DPL_scrollDir' => $this->parameters->getParameter('scrolldir'), 'DPL_time' => $dplTime, 'DPL_count' => $this->parameters->getParameter('count'), 'DPL_totalPages' => $foundRows, 'DPL_pages' => $this->dpl->getRowCount()];
     $this->defineScrollVariables($scrollVariables);
     if ($this->parameters->getParameter('allowcachedresults')) {
         $this->parser->getOutput()->updateCacheExpiry($this->parameters->getParameter('cacheperiod') ? $this->parameters->getParameter('cacheperiod') : 3600);
     } else {
         $this->parser->disableCache();
     }
     $finalOutput = $this->getFullOutput($foundRows, false);
     $this->triggerEndResets($finalOutput, $reset, $eliminate, $isParserTag);
     wfProfileOut(__METHOD__);
     return $finalOutput;
 }