public function testGetOutgoingLinks() { $parserOutput = new ParserOutput(); $parserOutput->addLink(Title::makeTitle(NS_MAIN, 'Foo_bar'), 1); $parserOutput->addLink(Title::makeTitle(NS_HELP, 'Contents'), 2); $searchDataExtractor = new ParserOutputSearchDataExtractor(); // this indexes links with db key $this->assertEquals(['Foo_bar', 'Help:Contents'], $searchDataExtractor->getOutgoingLinks($parserOutput)); }
/** * @covers LinksUpdate::addLink */ public function testUpdate_pagelinks() { list($t, $po) = $this->makeTitleAndParserOutput("Testing", 111); $po->addLink(Title::newFromText("Foo")); $po->addLink(Title::newFromText("Special:Foo")); // special namespace should be ignored $po->addLink(Title::newFromText("linksupdatetest:Foo")); // interwiki link should be ignored $po->addLink(Title::newFromText("#Foo")); // hash link should be ignored $update = $this->assertLinksUpdate($t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array(array(NS_MAIN, 'Foo'))); $this->assertArrayEquals(array(Title::makeTitle(NS_MAIN, 'Foo')), $update->getAddedLinks()); $po = new ParserOutput(); $po->setTitleText($t->getPrefixedText()); $po->addLink(Title::newFromText("Bar")); $po->addLink(Title::newFromText("Talk:Bar")); $update = $this->assertLinksUpdate($t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array(array(NS_MAIN, 'Bar'), array(NS_TALK, 'Bar'))); $this->assertArrayEquals(array(Title::makeTitle(NS_MAIN, 'Bar'), Title::makeTitle(NS_TALK, 'Bar')), $update->getAddedLinks()); $this->assertArrayEquals(array(Title::makeTitle(NS_MAIN, 'Foo')), $update->getRemovedLinks()); }
/** * @covers ParserOutput::addLink */ public function testUpdate_pagelinks() { /** @var Title $t */ /** @var ParserOutput $po */ list($t, $po) = $this->makeTitleAndParserOutput("Testing", self::$testingPageId); $po->addLink(Title::newFromText("Foo")); $po->addLink(Title::newFromText("Special:Foo")); // special namespace should be ignored $po->addLink(Title::newFromText("linksupdatetest:Foo")); // interwiki link should be ignored $po->addLink(Title::newFromText("#Foo")); // hash link should be ignored $update = $this->assertLinksUpdate($t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = ' . self::$testingPageId, [[NS_MAIN, 'Foo']]); $this->assertArrayEquals([Title::makeTitle(NS_MAIN, 'Foo')], $update->getAddedLinks()); $po = new ParserOutput(); $po->setTitleText($t->getPrefixedText()); $po->addLink(Title::newFromText("Bar")); $po->addLink(Title::newFromText("Talk:Bar")); $update = $this->assertLinksUpdate($t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = ' . self::$testingPageId, [[NS_MAIN, 'Bar'], [NS_TALK, 'Bar']]); $this->assertArrayEquals([Title::makeTitle(NS_MAIN, 'Bar'), Title::makeTitle(NS_TALK, 'Bar')], $update->getAddedLinks()); $this->assertArrayEquals([Title::makeTitle(NS_MAIN, 'Foo')], $update->getRemovedLinks()); }
/** * Parse image options text and use it to make an image * * @param $title Title * @param $options String * @param $holders LinkHolderArray|bool * @return string HTML */ function makeImage($title, $options, $holders = false) { # Check if the options text is of the form "options|alt text" # Options are: # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang # * left no resizing, just left align. label is used for alt= only # * right same, but right aligned # * none same, but not aligned # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox # * center center the image # * frame Keep original image size, no magnify-button. # * framed Same as "frame" # * frameless like 'thumb' but without a frame. Keeps user preferences for width # * upright reduce width for upright images, rounded to full __0 px # * border draw a 1px border around the image # * alt Text for HTML alt attribute (defaults to empty) # * class Set a class for img node # * link Set the target of the image link. Can be external, interwiki, or local # vertical-align values (no % or length right now): # * baseline # * sub # * super # * top # * text-top # * middle # * bottom # * text-bottom $parts = StringUtils::explode("|", $options); # Give extensions a chance to select the file revision for us $options = array(); $descQuery = false; wfRunHooks('BeforeParserFetchFileAndTitle', array($this, $title, &$options, &$descQuery)); # Fetch and register the file (file title may be different via hooks) list($file, $title) = $this->fetchFileAndTitle($title, $options); # Get parameter map $handler = $file ? $file->getHandler() : false; list($paramMap, $mwArray) = $this->getImageParams($handler); if (!$file) { $this->addTrackingCategory('broken-file-category'); } # Process the input parameters $caption = ''; $params = array('frame' => array(), 'handler' => array(), 'horizAlign' => array(), 'vertAlign' => array()); foreach ($parts as $part) { $part = trim($part); list($magicName, $value) = $mwArray->matchVariableStartToEnd($part); $validated = false; if (isset($paramMap[$magicName])) { list($type, $paramName) = $paramMap[$magicName]; # Special case; width and height come in one variable together if ($type === 'handler' && $paramName === 'width') { $parsedWidthParam = $this->parseWidthParam($value); if (isset($parsedWidthParam['width'])) { $width = $parsedWidthParam['width']; if ($handler->validateParam('width', $width)) { $params[$type]['width'] = $width; $validated = true; } } if (isset($parsedWidthParam['height'])) { $height = $parsedWidthParam['height']; if ($handler->validateParam('height', $height)) { $params[$type]['height'] = $height; $validated = true; } } # else no validation -- bug 13436 } else { if ($type === 'handler') { # Validate handler parameter $validated = $handler->validateParam($paramName, $value); } else { # Validate internal parameters switch ($paramName) { case 'manualthumb': case 'alt': case 'class': # @todo FIXME: Possibly check validity here for # manualthumb? downstream behavior seems odd with # missing manual thumbs. $validated = true; $value = $this->stripAltText($value, $holders); break; case 'link': $chars = self::EXT_LINK_URL_CLASS; $prots = $this->mUrlProtocols; if ($value === '') { $paramName = 'no-link'; $value = true; $validated = true; } elseif (preg_match("/^(?i){$prots}/", $value)) { if (preg_match("/^((?i){$prots}){$chars}+\$/u", $value, $m)) { $paramName = 'link-url'; $this->mOutput->addExternalLink($value); if ($this->mOptions->getExternalLinkTarget()) { $params[$type]['link-target'] = $this->mOptions->getExternalLinkTarget(); } $validated = true; } } else { $linkTitle = Title::newFromText($value); if ($linkTitle) { $paramName = 'link-title'; $value = $linkTitle; $this->mOutput->addLink($linkTitle); $validated = true; } } break; default: # Most other things appear to be empty or numeric... $validated = $value === false || is_numeric(trim($value)); } } if ($validated) { $params[$type][$paramName] = $value; } } } if (!$validated) { $caption = $part; } } # Process alignment parameters if ($params['horizAlign']) { $params['frame']['align'] = key($params['horizAlign']); } if ($params['vertAlign']) { $params['frame']['valign'] = key($params['vertAlign']); } $params['frame']['caption'] = $caption; # Will the image be presented in a frame, with the caption below? $imageIsFramed = isset($params['frame']['frame']) || isset($params['frame']['framed']) || isset($params['frame']['thumbnail']) || isset($params['frame']['manualthumb']); # In the old days, [[Image:Foo|text...]] would set alt text. Later it # came to also set the caption, ordinary text after the image -- which # makes no sense, because that just repeats the text multiple times in # screen readers. It *also* came to set the title attribute. # # Now that we have an alt attribute, we should not set the alt text to # equal the caption: that's worse than useless, it just repeats the # text. This is the framed/thumbnail case. If there's no caption, we # use the unnamed parameter for alt text as well, just for the time be- # ing, if the unnamed param is set and the alt param is not. # # For the future, we need to figure out if we want to tweak this more, # e.g., introducing a title= parameter for the title; ignoring the un- # named parameter entirely for images without a caption; adding an ex- # plicit caption= parameter and preserving the old magic unnamed para- # meter for BC; ... if ($imageIsFramed) { # Framed image if ($caption === '' && !isset($params['frame']['alt'])) { # No caption or alt text, add the filename as the alt text so # that screen readers at least get some description of the image $params['frame']['alt'] = $title->getText(); } # Do not set $params['frame']['title'] because tooltips don't make sense # for framed images } else { # Inline image if (!isset($params['frame']['alt'])) { # No alt text, use the "caption" for the alt text if ($caption !== '') { $params['frame']['alt'] = $this->stripAltText($caption, $holders); } else { # No caption, fall back to using the filename for the # alt text $params['frame']['alt'] = $title->getText(); } } # Use the "caption" for the tooltip text $params['frame']['title'] = $this->stripAltText($caption, $holders); } wfRunHooks('ParserMakeImageParams', array($title, $file, &$params, $this)); # Linker does the rest $time = isset($options['time']) ? $options['time'] : false; $ret = Linker::makeImageLink($this, $title, $file, $params['frame'], $params['handler'], $time, $descQuery, $this->mOptions->getThumbSize()); # Give the handler a chance to modify the parser object if ($handler) { $handler->parserTransformHook($this, $file); } return $ret; }