/** * Render <place> tag * * @param string $content tag content (will be ignored) * @param array $attributes tag attributes * @param Parser $parser MW parser instance * @param PPFrame $frame parent frame with the context * @return string HTML output of the tag */ public static function renderPlaceTag($content, array $attributes, Parser $parser, PPFrame $frame) { wfProfileIn(__METHOD__); // wrap data in a model object $placeModel = PlaceModel::newFromAttributes($attributes); // are we rendering for RTE? $inRTE = !empty(F::app()->wg->RTEParserEnabled); if ($inRTE) { $wikitext = RTEData::get('wikitext', self::$lastWikitextId); $data = array('wikitext' => $wikitext, 'placeholder' => 1); $rteData = RTEData::convertDataToAttributes($data); } else { $rteData = false; } // render parser hook $html = F::app()->sendRequest('Places', 'placeFromModel', array('model' => $placeModel, 'rteData' => $rteData))->toString(); // add JS snippets code if (!$inRTE) { $html .= self::getJSSnippet(); } // add model to be stored in database (new PlacesHooks())->setModelToSave($placeModel); $html = self::cleanHTML($html); wfProfileOut(__METHOD__); return $html; }
public static function replaceIdxByData($var) { $data = RTEData::get('data', intval($var[1])); if (isset($data['type'])) { if (isset($data['wikitextIdx'])) { $data['wikitext'] = RTEData::get('wikitext', $data['wikitextIdx']); // macbre: correctly handle and unmark entities inside links wikitext (RT #38844) $data['wikitext'] = htmlspecialchars_decode($data['wikitext']); $data['wikitext'] = RTEParser::unmarkEntities($data['wikitext']); unset($data['wikitextIdx']); if (strpos($data['wikitext'], '_rte_wikitextidx') !== false) { RTE::$edgeCases[] = 'COMPLEX.01'; } else { if (strpos($data['wikitext'], '_rte_dataidx') !== false) { RTE::$edgeCases[] = 'COMPLEX.02'; } else { if ($data['type'] == 'double-brackets') { if (strrpos($data['wikitext'], '{{') !== 0 && strpos($data['wikitext'], '{{') !== strlen($data['wikitext']) - 2) { RTE::$edgeCases[] = 'COMPLEX.03'; } } else { if (strpos($data['wikitext'], "") !== false) { RTE::$edgeCases[] = 'COMPLEX.07'; } } } } } } return self::convertDataToAttributes($data); }
/** * Callback function for preg_replace_callback which handle placeholer markers. * Called from RTEParser class. * * @author: Inez KorczyDski */ public static function replacePlaceholder($var) { $data = RTEData::get('placeholder', intval($var[1])); if ($data) { return RTE::renderPlaceholder($data['type'], $data); } }
public function renderTag($input, $params, Parser $parser, PPFrame $frame) { //$this->frame = $frame; global $wgRTEParserEnabled, $wgHTTPProxy, $wgFogbugzAPIConfig, $wgCaptchaDirectory, $wgCaptchaDirectoryLevels, $wgStylePath; if (!isset($params['id'])) { return ''; } $output = Xml::openElement('span', array('class' => 'fogbugz_tck', 'data-id' => $parser->recursiveTagParse($params['id'], $frame))); //$output .= $input; $output .= Xml::openElement('img', array('src' => $wgStylePath . '/common/images/ajax.gif')); $output .= Xml::closeElement('span'); $data = array('wikitext' => RTEData::get('wikitext', self::$mWikitextIdx), 'placeholder' => 1); //$dataIdx = RTEData::put('data', $data); //$output = RTEData::addIdxToTag($dataIdx, $output); $output .= F::build('JSSnippets')->addToStack(array('/extensions/wikia/FogbugzTag/js/FogbugzTag.js')); return $output; }
/** * Return the text to be used for a given extension tag. * This is the ghost of strip(). * * @param $params Associative array of parameters: * name PPNode for the tag name * attr PPNode for unparsed text where tag attributes are thought to be * attributes Optional associative array of parsed attributes * inner Contents of extension element * noClose Original text did not have a close tag * @param $frame PPFrame * * @return string */ function extensionSubstitution($params, $frame) { $name = $frame->expand($params['name']); $attrText = !isset($params['attr']) ? null : $frame->expand($params['attr']); $content = !isset($params['inner']) ? null : $frame->expand($params['inner']); # RTE (Rich Text Editor) - begin # @author: Inez Korczyński global $wgRTEParserEnabled; if (!empty($wgRTEParserEnabled)) { $wikitextIdx = RTEMarker::getDataIdx(RTEMarker::EXT_WIKITEXT, $content); # Allow parser extensions to generate their own placeholders (instead of default one from RTE) # @author: Macbre if (wfRunHooks('RTEUseDefaultPlaceholder', array($name, $params, $frame, $wikitextIdx))) { if ($wikitextIdx !== null) { $dataIdx = RTEData::put('placeholder', array('type' => 'ext', 'wikitextIdx' => $wikitextIdx)); return RTEMarker::generate(RTEMarker::PLACEHOLDER, $dataIdx); } } else { RTE::log(__METHOD__, "skipped default placeholder for <{$name}>"); // restore value of $content $content = RTEData::get('wikitext', $wikitextIdx); // keep inner content of tag $content = preg_replace('#^<[^>]+>(.*)<[^>]+>$#s', '\\1', $content); } } # RTE - end $marker = "{$this->mUniqPrefix}-{$name}-" . sprintf('%08X', $this->mMarkerIndex++) . self::MARKER_SUFFIX; $isFunctionTag = isset($this->mFunctionTagHooks[strtolower($name)]) && ($this->ot['html'] || $this->ot['pre']); if ($isFunctionTag) { $markerType = 'none'; } else { $markerType = 'general'; } if ($this->ot['html'] || $isFunctionTag) { $name = strtolower($name); # PLB - begin # @author: Tomasz Odrobny $this->mCurrentTagName = $name; # PLB - end $attributes = Sanitizer::decodeTagAttributes($attrText); if (isset($params['attributes'])) { $attributes = $attributes + $params['attributes']; } if (isset($this->mTagHooks[$name])) { # Workaround for PHP bug 35229 and similar if (!is_callable($this->mTagHooks[$name])) { throw new MWException("Tag hook for {$name} is not callable\n"); } wfRunHooks('ParserTagHooksBeforeInvoke', [$name, $marker, $content, $attributes, $this, $frame]); $output = call_user_func_array($this->mTagHooks[$name], array($content, $attributes, $this, $frame)); } elseif (isset($this->mFunctionTagHooks[$name])) { list($callback, $flags) = $this->mFunctionTagHooks[$name]; if (!is_callable($callback)) { throw new MWException("Tag hook for {$name} is not callable\n"); } $output = call_user_func_array($callback, array(&$this, $frame, $content, $attributes)); } else { $output = '<span class="error">Invalid tag extension name: ' . htmlspecialchars($name) . '</span>'; } if (is_array($output)) { # Extract flags to local scope (to override $markerType) $flags = $output; $output = $flags[0]; unset($flags[0]); extract($flags); } } else { if (is_null($attrText)) { $attrText = ''; } if (isset($params['attributes'])) { foreach ($params['attributes'] as $attrName => $attrValue) { $attrText .= ' ' . htmlspecialchars($attrName) . '="' . htmlspecialchars($attrValue) . '"'; } } if ($content === null) { $output = "<{$name}{$attrText}/>"; } else { $close = is_null($params['close']) ? '' : $frame->expand($params['close']); $output = "<{$name}{$attrText}>{$content}{$close}"; } } if ($markerType === 'none') { return $output; } elseif ($markerType === 'nowiki') { $this->mStripState->addNoWiki($marker, $output); } elseif ($markerType === 'general') { $this->mStripState->addGeneral($marker, $output); } else { throw new MWException(__METHOD__ . ': invalid marker type'); } return $marker; }
/** * Render gallery placeholder for RTE * * @param $gallery WikiaPhotoGallery * @param $width Integer * $param $height Integer */ public static function renderGalleryPlaceholder($gallery, $width, $height) { wfProfileIn(__METHOD__); $data = $gallery->getData(); $class = 'media-placeholder image-gallery'; if ($data['type'] == WikiaPhotoGallery::WIKIA_PHOTO_SLIDESHOW) { $class .= ' image-slideshow'; } // support "position" attribute (gallery alignment) switch ($gallery->getParam('position')) { case 'left': $class .= ' alignLeft'; break; case 'center': $class .= ' alignCenter'; break; case 'right': $class .= ' alignRight'; break; } if ($data['type'] == WikiaPhotoGallery::WIKIA_PHOTO_SLIDER) { $class .= ' image-gallery-slider'; } global $wgBlankImgUrl; $attribs = array('src' => $wgBlankImgUrl, 'class' => $class, 'type' => 'image-gallery', 'height' => $height, 'width' => $width); // render image for media placeholder $ret = Xml::element('img', $attribs); // store wikitext $data['wikitext'] = RTEData::get('wikitext', self::$mWikitextIdx); // store data and mark HTML $dataIdx = RTEData::put('data', $data); $ret = RTEData::addIdxToTag($dataIdx, $ret); wfProfileOut(__METHOD__); return $ret; }
/** * Returns placeholder for broken image link * * This one is called directly by RTEParser::makeImage() * */ public static function makeBrokenImageLinkObj($title, $html = '', $query = '', $trail = '', $prefix = '', $time = false, $wikitextIdx = null) { wfProfileIn(__METHOD__); if (!$title instanceof Title) { throw new \Exception('$title is not Title class instance'); } // try to resolve internal links in broken image caption (RT #90616) $wikitext = RTEData::get('wikitext', $wikitextIdx); if (RTEData::resolveLinksInMediaCaption($wikitext)) { // update wikitext data $wikitextIdx = RTEData::put('wikitext', $wikitext); } $ret = RTEMarker::generate(RTEMarker::PLACEHOLDER, RTEData::put('placeholder', array('type' => 'broken-image', 'wikitextIdx' => $wikitextIdx, 'title' => $title->getDBkey()))); wfProfileOut(__METHOD__); return $ret; }
/** * Return XML object for parser when RTE enabled * called from Parser::replaceInternalLinks2 * * @param $poll WikiaPoll * @param $nt Title * @param $RTE_wikitextIdx */ public static function generateRTE($poll, $nt, $RTE_wikitextIdx) { global $wgBlankImgUrl; $data = array(); $data['type'] = 'poll'; $data['pollId'] = $nt->getArticleId(); $data['wikitext'] = RTEData::get('wikitext', $RTE_wikitextIdx); $pollData = $poll->getData(); if (isset($pollData['question'])) { $data['question'] = $pollData['question']; } if (isset($pollData['answers'])) { foreach ($pollData["answers"] as $answer) { $data['answers'][] = $answer['text']; } } // store data and mark HTML $dataIdx = RTEData::put('data', $data); // render poll placeholder $tag = Xml::element('img', array('_rte_dataidx' => sprintf('%04d', $dataIdx), 'class' => "media-placeholder placeholder-poll", 'src' => $wgBlankImgUrl, 'type' => 'poll')); return RTEData::addIdxToTag($dataIdx, $tag); }
/** * Parse image options text and use it to make an image * @param Title $title * @param string $options * @param LinkHolderArray $holders * @param int $wikitextIdx */ function makeImage($title, $options, $holders = false) { wfProfileIn(__METHOD__); $wikitextIdx = RTEMarker::getDataIdx(RTEMarker::IMAGE_DATA, $options); // store wikitext for media placeholder rendering method self::$lastWikitext = RTEData::get('wikitext', $wikitextIdx); // call MW parser - image params will be populated parent::makeImage($title, $options, $holders); // maybe it's an image placeholder global $wgEnableImagePlaceholderExt; if (!empty($wgEnableImagePlaceholderExt)) { $isImagePlaceholder = ImagePlaceholderIsPlaceholder($title->getText()); // pass rendered image placeholder if ($isImagePlaceholder) { // return HTML stored by renderMediaPlaceholder() method $ret = self::$mediaPlaceholder; wfProfileOut(__METHOD__); return $ret; } } // check that given image exists $image = wfFindFile($title); $isBrokenImage = empty($image); // render broken image placeholder if ($isBrokenImage) { // handle not existing images $ret = RTELinkerHooks::makeBrokenImageLinkObj($title, '', '', '', '', false, $wikitextIdx); wfProfileOut(__METHOD__); return $ret; } // get and merge image parameters returned by Parser::makeImage $params = array_merge(self::$imageParams['frame'], self::$imageParams['handler']); // cleanup if (isset($params['title'])) { unset($params['title']); } // generate image data $data = array('type' => 'image', 'wikitext' => RTEData::get('wikitext', $wikitextIdx), 'title' => $title->getDBkey()); // try to resolve internal links in image caption (RT #90616) if (RTEData::resolveLinksInMediaCaption($data['wikitext'])) { // now resolve link markers in caption parsed to HTML if (!empty($holders)) { $holders->replace($params['caption']); } RTE::log(__METHOD__ . ': resolved internal link'); } // trigger an edgecase when image caption contains double brackets markers if (RTEData::checkWikitextForMarkers($data['wikitext'])) { RTE::$edgeCases[] = 'COMPLEX.09'; } // small fix: set value of thumbnail entry if (isset($params['thumbnail'])) { $params['thumbnail'] = true; } // keep caption only for thumbs and framed images if (!isset($params['thumbnail']) && !isset($params['framed'])) { $params['caption'] = ''; } // get "unparsed" caption from original wikitext and store parsed one as 'captionParsed' if ($params['caption'] != '') { $wikitext = trim($data['wikitext'], '[]'); $wikitextParts = self::explodeImageArgs($wikitext); // let's assume caption is the last part of image wikitext $originalCaption = end($wikitextParts); $originalCaption = htmlspecialchars_decode($originalCaption); // keep parsed caption and store its wikitext $params['captionParsed'] = $params['caption']; $params['caption'] = $originalCaption; } // pass link image parameter (BugId:6506) // this can be either link-title (internal links) or link-url (external links) if (isset($params['link-title']) && $params['link-title'] instanceof Title) { $params['link'] = $params['link-title']->getPrefixedText(); unset($params['link-title']); } else { if (isset($params['link-url'])) { $params['link'] = $params['link-url']; unset($params['link-url']); } } // parameters are cleaned up - store them in image's meta data $data['params'] = $params; RTE::log(__METHOD__, $data); // image width $imageWidth = intval($image->getWidth()); if (!empty($data['params']['width'])) { // width provided in wikitext $width = $data['params']['width']; // images with width provided should not be resized larger than the original file resolution (RT #41805) if ($imageWidth < $width) { $width = $imageWidth; } } else { if (!empty($data['params']['height'])) { $height = $data['params']['height']; $width = round($image->getWidth() * ($height / $image->getHeight())); } else { if (isset($data['params']['thumbnail'])) { // width not provided - get default for thumbs global $wgUser, $wgThumbLimits; $wopt = $wgUser->getOption('thumbsize'); if (!isset($wgThumbLimits[$wopt])) { $wopt = User::getDefaultOption('thumbsize'); } $width = $wgThumbLimits[$wopt]; // thumbed images should not be resized larger than the original file resolution if ($imageWidth < $width) { $width = $imageWidth; } } else { // full size $width = $image->getWidth(); } } } // add extra CSS classes $imgClass = array('image'); if (isset($data['params']['thumbnail'])) { $imgClass[] = 'thumb'; } if (isset($data['params']['framed'])) { $imgClass[] = 'frame'; } if (isset($data['params']['frameless'])) { $imgClass[] = 'frameless'; } if (isset($data['params']['border'])) { $imgClass[] = 'border'; } if (isset($data['params']['align'])) { $imgClass[] = 'align' . ucfirst($data['params']['align']); } if ($data['params']['caption'] != '') { $imgClass[] = 'withCaption'; } // generate image thumbnail $thumb = $image->transform(array('width' => $width)); $thumbClass = get_class($thumb); // RT #25329 if ($thumbClass == 'OggAudioDisplay') { $data['type'] = 'ogg-file'; $ret = RTEMarker::generate(RTEMarker::PLACEHOLDER, RTEData::put('placeholder', $data)); wfProfileOut(__METHOD__); return $ret; } $ret = $thumb->toHtml(array('img-class' => implode(' ', $imgClass))); // add type attribute $ret = substr($ret, 0, -2) . ' type="image" />'; RTE::log(__METHOD__, $ret); // store data and mark HTML $ret = RTEData::addIdxToTag(RTEData::put('data', $data), $ret); wfProfileOut(__METHOD__); return $ret; }