Ejemplo n.º 1
0
 /**
  * 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;
 }