Pmiazga has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/372473 )

Change subject: Verify the existance of `url` key when parsing lang objects
......................................................................

Verify the existance of `url` key when parsing lang objects

Some langLink retrieved from API do not contain url property, only
code and title. If that happens do not throw PHP notice error. Log
the error and skip broken lang object.

Changes:
 - extracted langObject validation to a separate function
 - added url property existence check
 - renamed $code to $index as $langLinks is an array without keys
 - introduced MobileContext::LOGGER_CHANNEL as it's used in couple
   places

Bug: T172316
Change-Id: I4ef5b1ad4a37b96407f7f758680a6177cafdf128
---
M includes/MobileContext.php
M includes/specials/SpecialMobileLanguages.php
M tests/phpunit/specials/SpecialMobileLanguagesTest.php
3 files changed, 67 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend 
refs/changes/73/372473/1

diff --git a/includes/MobileContext.php b/includes/MobileContext.php
index fbadd60..a04e2ca 100644
--- a/includes/MobileContext.php
+++ b/includes/MobileContext.php
@@ -21,7 +21,7 @@
        const LAZY_LOAD_IMAGES_COOKIE_VALUE = 'A';
        const LAZY_LOAD_REFERENCES_COOKIE_NAME = 'mfLazyLoadReferences';
        const LAZY_LOAD_REFERENCES_COOKIE_VALUE = 'A';
-
+       const LOGGER_CHANNEL = 'mobile';
        /**
         * Saves the testing mode user has opted in: 'beta' or 'stable'
         * @var string $mobileMode
diff --git a/includes/specials/SpecialMobileLanguages.php 
b/includes/specials/SpecialMobileLanguages.php
index 91e9783..735645e 100644
--- a/includes/specials/SpecialMobileLanguages.php
+++ b/includes/specials/SpecialMobileLanguages.php
@@ -58,15 +58,14 @@
                        // Set the name of each language based on the system 
list of language names
                        $languageMap = Language::fetchLanguageNames();
                        $languages = $page['langlinks'];
-                       foreach ( $page['langlinks'] as $code => $langObject ) {
-                               if ( !isset( $languageMap[$langObject['lang']] 
) ) {
-                                       // Bug T93500: DB might still have 
preantiquated rows with bogus languages
-                                       unset( $languages[$code] );
+                       foreach ( $page['langlinks'] as $index => $langObject ) 
{
+                               if ( !$this->isLanguageObjectValid( 
$languageMap, $langObject ) ) {
+                                       unset( $languages[$index] );
                                        continue;
                                }
                                $langObject['langname'] = 
$languageMap[$langObject['lang']];
                                $langObject['url'] = 
MobileContext::singleton()->getMobileUrl( $langObject['url'] );
-                               $languages[$code] = $langObject;
+                               $languages[$index] = $langObject;
                        }
                        $compareLanguage = function ( $a, $b ) {
                                return strcasecmp( $a['langname'], 
$b['langname'] );
@@ -80,6 +79,33 @@
        }
 
        /**
+        * Verify if passed language object contains all necessary information
+        *
+        * @see https://phabricator.wikimedia.org/T93500
+        * @see https://phabricator.wikimedia.org/T172316
+        * @param array $languageMap array of language names, indexed by code.
+        * @param array $langObject array of lang objects
+        * @return bool
+        */
+       private function isLanguageObjectValid( $languageMap, $langObject ) {
+               if ( !isset( $languageMap[$langObject['lang']] ) ) {
+                       // Bug T93500: DB might still have preantiquated rows 
with bogus languages
+                       return false;
+               }
+               if ( !array_key_exists( 'url', $langObject ) ) {
+                       // Bug T172316: Some lang objects do not have url. We 
would like to log those instances
+                       \MediaWiki\Logger\LoggerFactory::getInstance( 
MobileContext::LOGGER_CHANNEL )->warning(
+                               '`url` key is undefined in language object',
+                               [
+                                       'uri' => 
RequestContext::getMain()->getRequest()->getFullRequestURL(),
+                                       'langObject' => $langObject,
+                               ]
+                       );
+                       return false;
+               }
+               return true;
+       }
+       /**
         * Returns an array of language variants that the page is available in
         * @return array
         */
diff --git a/tests/phpunit/specials/SpecialMobileLanguagesTest.php 
b/tests/phpunit/specials/SpecialMobileLanguagesTest.php
index 385bb48..1f8d27c 100644
--- a/tests/phpunit/specials/SpecialMobileLanguagesTest.php
+++ b/tests/phpunit/specials/SpecialMobileLanguagesTest.php
@@ -115,6 +115,7 @@
        /**
         * @dataProvider providerProcessLanguages
         * @covers SpecialMobileLanguages::processLanguages
+        * @covers SpecialMobileLanguages::isLanguageObjectValid
         */
        public function testProcessLanguages( $langlinks, $expected ) {
                $apiResult = [
@@ -132,4 +133,38 @@
                        'Property langname should be added, URL should be 
transformed, and languages should be sorted.'
                );
        }
+
+       /**
+        * Test an edge case when URL key is missing in langObject
+        *
+        * @covers SpecialMobileLanguages::processLanguages
+        * @covers SpecialMobileLanguages::isLanguageObjectValid
+        */
+       public function testProcessLanguagesWhenURLKeyIsMissing() {
+               $testUri = 'http://localhost/test';
+               $langObject = [
+                       'lang' => 'pl',
+                       'title' => 'Polski'
+               ];
+               $expected = [];
+
+               $loggerMock = $this->getMock( \Psr\Log\LoggerInterface::class );
+               $loggerMock->expects( $this->once() )
+                       ->method( 'warning' )
+                       ->with( $this->isType( 'string' ), $this->equalTo(
+                               [
+                                       'uri' => $testUri,
+                                       'langObject' => $langObject
+                               ]
+               ) );
+               $this->setLogger( MobileContext::LOGGER_CHANNEL, $loggerMock );
+
+               $requestMock = $this->getMock( FauxRequest::class );
+               $requestMock->expects( $this->once() )
+                       ->method( 'getFullRequestURL' )
+                       ->willReturn( $testUri );
+
+               RequestContext::getMain()->setRequest( $requestMock );
+               $this->testProcessLanguages( [ $langObject ], $expected );
+       }
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/372473
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4ef5b1ad4a37b96407f7f758680a6177cafdf128
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Pmiazga <pmia...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to