Merge "Parser: Refactor parsing of [[File:...|link=...]] syntax for reusability"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 26 Sep 2018 19:18:34 +0000 (19:18 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 26 Sep 2018 19:18:34 +0000 (19:18 +0000)
1  2 
includes/parser/Parser.php

@@@ -292,8 -292,8 +292,8 @@@ class Parser 
                        self::EXT_LINK_URL_CLASS . '*)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F\\x{FFFD}]*?)\]/Su';
                if ( isset( $conf['preprocessorClass'] ) ) {
                        $this->mPreprocessorClass = $conf['preprocessorClass'];
 -              } elseif ( defined( 'HPHP_VERSION' ) ) {
 -                      # Preprocessor_Hash is much faster than Preprocessor_DOM under HipHop
 +              } elseif ( wfIsHHVM() ) {
 +                      # Under HHVM Preprocessor_Hash is much faster than Preprocessor_DOM
                        $this->mPreprocessorClass = Preprocessor_Hash::class;
                } elseif ( extension_loaded( 'domxml' ) ) {
                        # PECL extension that conflicts with the core DOM extension (T15770)
                                                                break;
                                                        case 'gallery-internal-link':
                                                                $linkValue = strip_tags( $this->replaceLinkHoldersText( $match ) );
-                                                               $chars = self::EXT_LINK_URL_CLASS;
-                                                               $addr = self::EXT_LINK_ADDR;
-                                                               $prots = $this->mUrlProtocols;
-                                                               // check to see if link matches an absolute url, if not then it must be a wiki link.
                                                                if ( preg_match( '/^-{R|(.*)}-$/', $linkValue ) ) {
                                                                        // Result of LanguageConverter::markNoConversion
                                                                        // invoked on an external link.
                                                                        $linkValue = substr( $linkValue, 4, -2 );
                                                                }
-                                                               if ( preg_match( "/^($prots)$addr$chars*$/u", $linkValue ) ) {
-                                                                       $link = $linkValue;
-                                                                       $this->mOutput->addExternalLink( $link );
-                                                               } else {
-                                                                       $localLinkTitle = Title::newFromText( $linkValue );
-                                                                       if ( $localLinkTitle !== null ) {
-                                                                               $this->mOutput->addLink( $localLinkTitle );
-                                                                               $link = $localLinkTitle->getLinkURL();
-                                                                       }
+                                                               list( $type, $target ) = $this->parseLinkParameter( $linkValue );
+                                                               if ( $type === 'link-url' ) {
+                                                                       $link = $target;
+                                                                       $this->mOutput->addExternalLink( $target );
+                                                               } elseif ( $type === 'link-title' ) {
+                                                                       $link = $target->getLinkURL();
+                                                                       $this->mOutput->addLink( $target );
                                                                }
                                                                break;
                                                        default:
                                                                $value = $this->stripAltText( $value, $holders );
                                                                break;
                                                        case 'link':
-                                                               $chars = self::EXT_LINK_URL_CLASS;
-                                                               $addr = self::EXT_LINK_ADDR;
-                                                               $prots = $this->mUrlProtocols;
-                                                               if ( $value === '' ) {
-                                                                       $paramName = 'no-link';
-                                                                       $value = true;
+                                                               list( $paramName, $value ) = $this->parseLinkParameter( $value );
+                                                               if ( $paramName ) {
                                                                        $validated = true;
-                                                               } elseif ( preg_match( "/^((?i)$prots)/", $value ) ) {
-                                                                       if ( preg_match( "/^((?i)$prots)$addr$chars*$/u", $value, $m ) ) {
-                                                                               $paramName = 'link-url';
-                                                                               $this->mOutput->addExternalLink( $value );
+                                                                       if ( $paramName === 'no-link' ) {
+                                                                               $value = true;
+                                                                       }
+                                                                       if ( $paramName === 'link-url' ) {
                                                                                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;
                return $ret;
        }
  
+       /**
+        * Parse the value of 'link' parameter in image syntax (`[[File:Foo.jpg|link=<value>]]`).
+        *
+        * Adds an entry to appropriate link tables.
+        *
+        * @since 1.32
+        * @return array of `[ type, target ]`, where:
+        *   - `type` is one of:
+        *     - `null`: Given value is not a valid link target, use default
+        *     - `'no-link'`: Given value is empty, do not generate a link
+        *     - `'link-url'`: Given value is a valid external link
+        *     - `'link-title'`: Given value is a valid internal link
+        *   - `target` is:
+        *     - When `type` is `null` or `'no-link'`: `false`
+        *     - When `type` is `'link-url'`: URL string corresponding to given value
+        *     - When `type` is `'link-title'`: Title object corresponding to given value
+        */
+       public function parseLinkParameter( $value ) {
+               $chars = self::EXT_LINK_URL_CLASS;
+               $addr = self::EXT_LINK_ADDR;
+               $prots = $this->mUrlProtocols;
+               $type = null;
+               $target = false;
+               if ( $value === '' ) {
+                       $type = 'no-link';
+               } elseif ( preg_match( "/^((?i)$prots)/", $value ) ) {
+                       if ( preg_match( "/^((?i)$prots)$addr$chars*$/u", $value, $m ) ) {
+                               $this->mOutput->addExternalLink( $value );
+                               $type = 'link-url';
+                               $target = $value;
+                       }
+               } else {
+                       $linkTitle = Title::newFromText( $value );
+                       if ( $linkTitle ) {
+                               $this->mOutput->addLink( $linkTitle );
+                               $type = 'link-title';
+                               $target = $linkTitle;
+                       }
+               }
+               return [ $type, $target ];
+       }
        /**
         * @param string $caption
         * @param LinkHolderArray|bool $holders