Пример #1
0
 /**
  * @param Parser $parser
  * @param string $date
  * @param string $defaultPref
  *
  * @return string
  */
 public static function formatDate($parser, $date, $defaultPref = null)
 {
     $lang = $parser->getFunctionLang();
     $df = DateFormatter::getInstance($lang);
     $date = trim($date);
     $pref = $parser->getOptions()->getDateFormat();
     // Specify a different default date format other than the normal default
     // if the user has 'default' for their setting
     if ($pref == 'default' && $defaultPref) {
         $pref = $defaultPref;
     }
     $date = $df->reformat($pref, $date, array('match-whole'));
     return $date;
 }
Пример #2
0
 /**
  * Helper function for parse() that transforms wiki markup into
  * HTML. Only called for $mOutputType == self::OT_HTML.
  *
  * @private
  */
 function internalParse($text)
 {
     $isMain = true;
     wfProfileIn(__METHOD__);
     # Hook to suspend the parser in this state
     if (!wfRunHooks('ParserBeforeInternalParse', array(&$this, &$text, &$this->mStripState))) {
         wfProfileOut(__METHOD__);
         return $text;
     }
     $text = $this->replaceVariables($text);
     $text = Sanitizer::removeHTMLtags($text, array(&$this, 'attributeStripCallback'), false, array_keys($this->mTransparentTagHooks));
     wfRunHooks('InternalParseBeforeLinks', array(&$this, &$text, &$this->mStripState));
     // Tables need to come after variable replacement for things to work
     // properly; putting them before other transformations should keep
     // exciting things like link expansions from showing up in surprising
     // places.
     $text = $this->doTableStuff($text);
     $text = preg_replace('/(^|\\n)-----*/', '\\1<hr />', $text);
     $text = $this->doDoubleUnderscore($text);
     $text = $this->doHeadings($text);
     if ($this->mOptions->getUseDynamicDates()) {
         $df = DateFormatter::getInstance();
         $text = $df->reformat($this->mOptions->getDateFormat(), $text);
     }
     $text = $this->doAllQuotes($text);
     $text = $this->replaceInternalLinks($text);
     $text = $this->replaceExternalLinks($text);
     # replaceInternalLinks may sometimes leave behind
     # absolute URLs, which have to be masked to hide them from replaceExternalLinks
     $text = str_replace($this->mUniqPrefix . 'NOPARSE', '', $text);
     $text = $this->doMagicLinks($text);
     $text = $this->formatHeadings($text, $isMain);
     wfProfileOut(__METHOD__);
     return $text;
 }
Пример #3
0
 /**
  * Helper function for parse() that transforms wiki markup into
  * HTML. Only called for $mOutputType == self::OT_HTML.
  *
  * @private
  *
  * @param $text string
  * @param $isMain bool
  * @param $frame bool
  *
  * @return string
  */
 function internalParse($text, $isMain = true, $frame = false)
 {
     wfProfileIn(__METHOD__);
     $origText = $text;
     # Hook to suspend the parser in this state
     if (!wfRunHooks('ParserBeforeInternalParse', array(&$this, &$text, &$this->mStripState))) {
         wfProfileOut(__METHOD__);
         return $text;
     }
     # if $frame is provided, then use $frame for replacing any variables
     if ($frame) {
         # use frame depth to infer how include/noinclude tags should be handled
         # depth=0 means this is the top-level document; otherwise it's an included document
         if (!$frame->depth) {
             $flag = 0;
         } else {
             $flag = Parser::PTD_FOR_INCLUSION;
         }
         $dom = $this->preprocessToDom($text, $flag);
         $text = $frame->expand($dom);
     } else {
         # if $frame is not provided, then use old-style replaceVariables
         $text = $this->replaceVariables($text);
     }
     wfRunHooks('InternalParseBeforeSanitize', array(&$this, &$text, &$this->mStripState));
     $text = Sanitizer::removeHTMLtags($text, array(&$this, 'attributeStripCallback'), false, array_keys($this->mTransparentTagHooks));
     wfRunHooks('InternalParseBeforeLinks', array(&$this, &$text, &$this->mStripState));
     # Tables need to come after variable replacement for things to work
     # properly; putting them before other transformations should keep
     # exciting things like link expansions from showing up in surprising
     # places.
     $text = $this->doTableStuff($text);
     $text = preg_replace('/(^|\\n)-----*/', '\\1<hr />', $text);
     $text = $this->doDoubleUnderscore($text);
     $text = $this->doHeadings($text);
     if ($this->mOptions->getUseDynamicDates()) {
         $df = DateFormatter::getInstance();
         $text = $df->reformat($this->mOptions->getDateFormat(), $text);
     }
     $text = $this->replaceInternalLinks($text);
     $text = $this->doAllQuotes($text);
     $text = $this->replaceExternalLinks($text);
     # replaceInternalLinks may sometimes leave behind
     # absolute URLs, which have to be masked to hide them from replaceExternalLinks
     $text = str_replace($this->mUniqPrefix . 'NOPARSE', '', $text);
     $text = $this->doMagicLinks($text);
     $text = $this->formatHeadings($text, $origText, $isMain);
     wfProfileOut(__METHOD__);
     return $text;
 }
Пример #4
0
 /**
  * Helper function for parse() that transforms wiki markup into
  * HTML. Only called for $mOutputType == OT_HTML.
  *
  * @private
  */
 function internalParse($text)
 {
     $args = array();
     $isMain = true;
     $fname = 'Parser::internalParse';
     wfProfileIn($fname);
     # Hook to suspend the parser in this state
     if (!wfRunHooks('ParserBeforeInternalParse', array(&$this, &$text, &$this->mStripState))) {
         wfProfileOut($fname);
         return $text;
     }
     # Remove <noinclude> tags and <includeonly> sections
     $text = strtr($text, array('<onlyinclude>' => '', '</onlyinclude>' => ''));
     $text = strtr($text, array('<noinclude>' => '', '</noinclude>' => ''));
     $text = StringUtils::delimiterReplace('<includeonly>', '</includeonly>', '', $text);
     $text = Sanitizer::removeHTMLtags($text, array(&$this, 'attributeStripCallback'), array(), array_keys($this->mTransparentTagHooks));
     $text = $this->replaceVariables($text, $args);
     wfRunHooks('InternalParseBeforeLinks', array(&$this, &$text, &$this->mStripState));
     // Tables need to come after variable replacement for things to work
     // properly; putting them before other transformations should keep
     // exciting things like link expansions from showing up in surprising
     // places.
     $text = $this->doTableStuff($text);
     $text = preg_replace('/(^|\\n)-----*/', '\\1<hr />', $text);
     $text = $this->stripToc($text);
     $this->stripNoGallery($text);
     $text = $this->doHeadings($text);
     if ($this->mOptions->getUseDynamicDates()) {
         $df =& DateFormatter::getInstance();
         $text = $df->reformat($this->mOptions->getDateFormat(), $text);
     }
     $text = $this->doAllQuotes($text);
     $text = $this->replaceInternalLinks($text);
     $text = $this->replaceExternalLinks($text);
     # replaceInternalLinks may sometimes leave behind
     # absolute URLs, which have to be masked to hide them from replaceExternalLinks
     $text = str_replace($this->mUniqPrefix . "NOPARSE", "", $text);
     $text = $this->doMagicLinks($text);
     $text = $this->formatHeadings($text, $isMain);
     wfProfileOut($fname);
     return $text;
 }
Пример #5
0
function renderDynamicPageList($input, $args, $mwParser)
{
    global $wgUser, $wgContLang;
    global $wgDisableCounters;
    // to determine if to allow sorting by #hits.
    global $wgDLPmaxCategories, $wgDLPMaxResultCount, $wgDLPMaxCacheTime;
    global $wgDLPAllowUnlimitedResults, $wgDLPAllowUnlimitedCategories;
    if ($wgDLPMaxCacheTime !== false) {
        $mwParser->getOutput()->updateCacheExpiry($wgDLPMaxCacheTime);
    }
    $countSet = false;
    $startList = '<ul>';
    $endList = '</ul>';
    $startItem = '<li>';
    $endItem = '</li>';
    $inlineMode = false;
    $useGallery = false;
    $galleryFileSize = false;
    $galleryFileName = true;
    $galleryImageHeight = 0;
    $galleryImageWidth = 0;
    $galleryNumbRows = 0;
    $galleryCaption = '';
    $gallery = null;
    $orderMethod = 'categoryadd';
    $order = 'descending';
    $redirects = 'exclude';
    $stable = $quality = 'include';
    $flaggedRevs = false;
    $namespaceFiltering = false;
    $namespaceIndex = 0;
    $offset = 0;
    $googleHack = false;
    $suppressErrors = false;
    $showNamespace = true;
    $addFirstCategoryDate = false;
    $dateFormat = '';
    $stripYear = false;
    $linkOptions = array();
    $categories = array();
    $excludeCategories = array();
    $parameters = explode("\n", $input);
    $parser = new Parser();
    $poptions = new ParserOptions();
    foreach ($parameters as $parameter) {
        $paramField = explode('=', $parameter, 2);
        if (count($paramField) < 2) {
            continue;
        }
        $type = trim($paramField[0]);
        $arg = trim($paramField[1]);
        switch ($type) {
            case 'category':
                $title = Title::makeTitleSafe(NS_CATEGORY, $parser->transformMsg($arg, $poptions));
                if (is_null($title)) {
                    continue;
                }
                $categories[] = $title;
                break;
            case 'notcategory':
                $title = Title::makeTitleSafe(NS_CATEGORY, $parser->transformMsg($arg, $poptions));
                if (is_null($title)) {
                    continue;
                }
                $excludeCategories[] = $title;
                break;
            case 'namespace':
                $ns = $wgContLang->getNsIndex($arg);
                if ($ns != null) {
                    $namespaceIndex = $ns;
                    $namespaceFiltering = true;
                } else {
                    // Note, since intval("some string") = 0
                    // this considers pretty much anything
                    // invalid here as the main namespace.
                    // This was probably originally a bug,
                    // but is now depended upon by people
                    // writing things like namespace=main
                    // so be careful when changing this code.
                    $namespaceIndex = intval($arg);
                    if ($namespaceIndex >= 0) {
                        $namespaceFiltering = true;
                    } else {
                        $namespaceFiltering = false;
                    }
                }
                break;
            case 'count':
                // ensure that $count is a number;
                $count = intval($arg);
                $countSet = true;
                break;
            case 'offset':
                $offset = intval($arg);
                break;
            case 'imagewidth':
                $galleryImageWidth = intval($arg);
                break;
            case 'imageheight':
                $galleryImageHeight = intval($arg);
                break;
            case 'imagesperrow':
                $galleryNumbRows = intval($arg);
                break;
            case 'mode':
                switch ($arg) {
                    case 'gallery':
                        $useGallery = true;
                        $gallery = new ImageGallery();
                        $startList = '';
                        $endList = '';
                        $startItem = '';
                        $endItem = '';
                        break;
                    case 'none':
                        $startList = '';
                        $endList = '';
                        $startItem = '';
                        $endItem = '<br />';
                        $inlineMode = false;
                        break;
                    case 'ordered':
                        $startList = '<ol>';
                        $endList = '</ol>';
                        $startItem = '<li>';
                        $endItem = '</li>';
                        $inlineMode = false;
                        break;
                    case 'inline':
                        // aka comma seperated list
                        $startList = '';
                        $endList = '';
                        $startItem = '';
                        $endItem = '';
                        $inlineMode = true;
                        break;
                    case 'unordered':
                    default:
                        $startList = '<ul>';
                        $endList = '</ul>';
                        $startItem = '<li>';
                        $endItem = '</li>';
                        $inlineMode = false;
                        break;
                }
                break;
            case 'gallerycaption':
                // Should perhaps actually parse caption instead
                // as links and what not in caption might be useful.
                $galleryCaption = $parser->transformMsg($arg, $poptions);
                break;
            case 'galleryshowfilesize':
                switch ($arg) {
                    case 'no':
                    case 'false':
                        $galleryFileSize = false;
                        break;
                    case 'true':
                    default:
                        $galleryFileSize = true;
                }
                break;
            case 'galleryshowfilename':
                switch ($arg) {
                    case 'no':
                    case 'false':
                        $galleryFileName = false;
                        break;
                    case 'true':
                    default:
                        $galleryFileName = true;
                        break;
                }
                break;
            case 'order':
                switch ($arg) {
                    case 'ascending':
                        $order = 'ascending';
                        break;
                    case 'descending':
                    default:
                        $order = 'descending';
                        break;
                }
                break;
            case 'ordermethod':
                switch ($arg) {
                    case 'lastedit':
                        $orderMethod = 'lastedit';
                        break;
                    case 'length':
                        $orderMethod = 'length';
                        break;
                    case 'created':
                        $orderMethod = 'created';
                        break;
                    case 'sortkey':
                    case 'categorysortkey':
                        $orderMethod = 'categorysortkey';
                        break;
                    case 'popularity':
                        if (!$wgDisableCounters) {
                            $orderMethod = 'popularity';
                        } else {
                            $orderMethod = 'categoyadd';
                            // default if hitcounter disabled.
                        }
                        break;
                    case 'categoryadd':
                    default:
                        $orderMethod = 'categoryadd';
                        break;
                }
                break;
            case 'redirects':
                switch ($arg) {
                    case 'include':
                        $redirects = 'include';
                        break;
                    case 'only':
                        $redirects = 'only';
                        break;
                    case 'exclude':
                    default:
                        $redirects = 'exclude';
                        break;
                }
                break;
            case 'stablepages':
                switch ($arg) {
                    case 'include':
                        $stable = 'include';
                        break;
                    case 'only':
                        $flaggedRevs = true;
                        $stable = 'only';
                        break;
                    case 'exclude':
                    default:
                        $flaggedRevs = true;
                        $stable = 'exclude';
                        break;
                }
                break;
            case 'qualitypages':
                switch ($arg) {
                    case 'include':
                        $quality = 'include';
                        break;
                    case 'only':
                        $flaggedRevs = true;
                        $quality = 'only';
                        break;
                    case 'exclude':
                    default:
                        $flaggedRevs = true;
                        $quality = 'exclude';
                        break;
                }
                break;
            case 'suppresserrors':
                if ($arg == 'true') {
                    $suppressErrors = true;
                } else {
                    $suppressErrors = false;
                }
                break;
            case 'addfirstcategorydate':
                if ($arg == 'true') {
                    $addFirstCategoryDate = true;
                } elseif (preg_match('/^(?:[ymd]{2,3}|ISO 8601)$/', $arg)) {
                    // if it more or less is valid dateformat.
                    $addFirstCategoryDate = true;
                    $dateFormat = $arg;
                    if (strlen($dateFormat) == 2) {
                        $dateFormat = $dateFormat . 'y';
                        # DateFormatter does not support no year. work around
                        $stripYear = true;
                    }
                } else {
                    $addFirstCategoryDate = false;
                }
                break;
            case 'shownamespace':
                if ('false' == $arg) {
                    $showNamespace = false;
                } else {
                    $showNamespace = true;
                }
                break;
            case 'googlehack':
                if ('false' == $arg) {
                    $googleHack = false;
                } else {
                    $googleHack = true;
                }
                break;
            case 'nofollow':
                # bug 6658
                if ('false' != $arg) {
                    $linkOptions['rel'] = 'nofollow';
                }
                break;
        }
        // end main switch()
    }
    // end foreach()
    $catCount = count($categories);
    $excludeCatCount = count($excludeCategories);
    $totalCatCount = $catCount + $excludeCatCount;
    if ($catCount < 1 && false == $namespaceFiltering) {
        if ($suppressErrors == false) {
            return htmlspecialchars(wfMsgForContent('intersection_noincludecats'));
            // "!!no included categories!!";
        } else {
            return '';
        }
    }
    if ($totalCatCount > $wgDLPmaxCategories && !$wgDLPAllowUnlimitedCategories) {
        if ($suppressErrors == false) {
            return htmlspecialchars(wfMsgForContent('intersection_toomanycats'));
            // "!!too many categories!!";
        } else {
            return '';
        }
    }
    if ($countSet) {
        if ($count < 1) {
            $count = 1;
        }
        if ($count > $wgDLPMaxResultCount) {
            $count = $wgDLPMaxResultCount;
        }
    } elseif (!$wgDLPAllowUnlimitedResults) {
        $count = $wgDLPMaxResultCount;
        $countSet = true;
    }
    // disallow showing date if the query doesn't have an inclusion category parameter
    if ($catCount < 1) {
        $addFirstCategoryDate = false;
        // don't sort by fields relating to categories if there are no categories.
        if ($orderMethod == 'categoryadd' || $orderMethod == 'categorysortkey') {
            $orderMethod = 'created';
        }
    }
    // build the SQL query
    $dbr = wfGetDB(DB_SLAVE);
    $tables = array('page');
    $fields = array('page_namespace', 'page_title');
    $where = array();
    $join = array();
    $options = array();
    if ($googleHack) {
        $fields[] = 'page_id';
    }
    if ($addFirstCategoryDate) {
        $fields[] = 'c1.cl_timestamp';
    }
    if ($namespaceFiltering == true) {
        $where['page_namespace'] = $namespaceIndex;
    }
    // Bug 14943 - Allow filtering based on FlaggedRevs stability.
    // Check if the extension actually exists before changing the query...
    if ($flaggedRevs && defined('FLAGGED_REVISIONS')) {
        $tables[] = 'flaggedpages';
        $join['flaggedpages'] = array('LEFT JOIN', 'page_id = fp_page_id');
        switch ($stable) {
            case 'only':
                $where[] = 'fp_stable IS NOT NULL';
                break;
            case 'exclude':
                $where['fp_stable'] = null;
                break;
        }
        switch ($quality) {
            case 'only':
                $where[] = 'fp_quality >= 1';
                break;
            case 'exclude':
                $where[] = 'fp_quality = 0 OR fp_quality IS NULL';
                break;
        }
    }
    switch ($redirects) {
        case 'only':
            $where['page_is_redirect'] = 1;
            break;
        case 'exclude':
            $where['page_is_redirect'] = 0;
            break;
    }
    $currentTableNumber = 1;
    $categorylinks = $dbr->tableName('categorylinks');
    for ($i = 0; $i < $catCount; $i++) {
        $join["{$categorylinks} AS c{$currentTableNumber}"] = array('INNER JOIN', array("page_id = c{$currentTableNumber}.cl_from", "c{$currentTableNumber}.cl_to={$dbr->addQuotes($categories[$i]->getDBKey())}"));
        $tables[] = "{$categorylinks} AS c{$currentTableNumber}";
        $currentTableNumber++;
    }
    for ($i = 0; $i < $excludeCatCount; $i++) {
        $join["{$categorylinks} AS c{$currentTableNumber}"] = array('LEFT OUTER JOIN', array("page_id = c{$currentTableNumber}.cl_from", "c{$currentTableNumber}.cl_to={$dbr->addQuotes($excludeCategories[$i]->getDBKey())}"));
        $tables[] = "{$categorylinks} AS c{$currentTableNumber}";
        $where["c{$currentTableNumber}.cl_to"] = null;
        $currentTableNumber++;
    }
    if ('descending' == $order) {
        $sqlOrder = 'DESC';
    } else {
        $sqlOrder = 'ASC';
    }
    switch ($orderMethod) {
        case 'lastedit':
            $sqlSort = 'page_touched';
            break;
        case 'length':
            $sqlSort = 'page_len';
            break;
        case 'created':
            $sqlSort = 'page_id';
            # Since they're never reused and increasing
            break;
        case 'categorysortkey':
            $sqlSort = "c1.cl_type {$sqlOrder}, c1.cl_sortkey";
            break;
        case 'popularity':
            $sqlSort = 'page_counter';
            break;
        case 'categoryadd':
        default:
            $sqlSort = 'c1.cl_timestamp';
            break;
    }
    $options['ORDER BY'] = "{$sqlSort} {$sqlOrder}";
    if ($countSet) {
        $options['LIMIT'] = $count;
    }
    if ($offset > 0) {
        $options['OFFSET'] = $offset;
    }
    // process the query
    $res = $dbr->select($tables, $fields, $where, __METHOD__, $options, $join);
    $sk = $wgUser->getSkin();
    if ($dbr->numRows($res) == 0) {
        if ($suppressErrors == false) {
            return htmlspecialchars(wfMsgForContent('intersection_noresults'));
        } else {
            return '';
        }
    }
    // start unordered list
    $output = $startList . "\n";
    $categoryDate = '';
    $df = null;
    if ($dateFormat != '' && $addFirstCategoryDate) {
        $df = DateFormatter::getInstance();
    }
    // process results of query, outputing equivalent of <li>[[Article]]</li>
    // for each result, or something similar if the list uses other
    // startlist/endlist
    $articleList = array();
    foreach ($res as $row) {
        $title = Title::makeTitle($row->page_namespace, $row->page_title);
        if (true == $addFirstCategoryDate) {
            if ($dateFormat != '') {
                # this is a tad ugly
                # use DateFormatter, and support disgarding year.
                $categoryDate = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
                if ($stripYear) {
                    $categoryDate = $wgContLang->getMonthName(substr($categoryDate, 5, 2)) . ' ' . substr($categoryDate, 8, 2);
                } else {
                    $categoryDate = substr($categoryDate, 0, 10);
                }
                $categoryDate = $df->reformat($dateFormat, $categoryDate, array('match-whole'));
            } else {
                $categoryDate = $wgContLang->date(wfTimestamp(TS_MW, $row->cl_timestamp));
            }
            if (!$useGallery) {
                $categoryDate .= wfMsgForContent('colon-separator');
            } else {
                $categoryDate .= ' ';
            }
        }
        $query = array();
        if ($googleHack == true) {
            $query['dpl_id'] = intval($row->page_id);
        }
        if ($showNamespace == true) {
            $titleText = $title->getPrefixedText();
        } else {
            $titleText = $title->getText();
        }
        if ($useGallery) {
            # Note, $categoryDate is treated as raw html
            # this is safe since the only html present
            # would come from the dateformatter <span>.
            $gallery->add($title, $categoryDate);
        } else {
            $articleList[] = $categoryDate . $sk->link($title, htmlspecialchars($titleText), $linkOptions, $query, array('forcearticlepath', 'known'));
        }
    }
    // end unordered list
    if ($useGallery) {
        $gallery->setHideBadImages();
        $gallery->setShowFilename($galleryFileName);
        $gallery->setShowBytes($galleryFileSize);
        if ($galleryImageHeight > 0) {
            $gallery->setHeights($galleryImageHeight);
        }
        if ($galleryImageWidth > 0) {
            $gallery->setWidths($galleryImageWidth);
        }
        if ($galleryNumbRows > 0) {
            $gallery->setPerRow($galleryNumbRows);
        }
        if ($galleryCaption != '') {
            $gallery->setCaption($galleryCaption);
            # gallery class escapes string
        }
        $output = $gallery->toHtml();
    } else {
        $output .= $startItem;
        if ($inlineMode) {
            $output .= $wgContLang->commaList($articleList);
        } else {
            $output .= implode("{$endItem} \n{$startItem}", $articleList);
        }
        $output .= $endItem;
        $output .= $endList . "\n";
    }
    return $output;
}
Пример #6
0
/**
 * @todo document
 */
function wfMainDateReplace($matches)
{
    $df =& DateFormatter::getInstance();
    return $df->replace($matches);
}