Cicalese has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/263581

Change subject: Add page_props table access class
......................................................................

Add page_props table access class

Change-Id: I022b9e3ca47dc63650b8a62260603b0893a80e69
---
M autoload.php
A includes/PageProps.php
M includes/actions/InfoAction.php
A tests/phpunit/includes/PagePropsTest.php
4 files changed, 403 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/81/263581/1

diff --git a/autoload.php b/autoload.php
index 49a3faf..bfeebe0 100644
--- a/autoload.php
+++ b/autoload.php
@@ -871,6 +871,7 @@
        'OrphanStats' => __DIR__ . '/maintenance/storage/orphanStats.php',
        'Orphans' => __DIR__ . '/maintenance/orphans.php',
        'OutputPage' => __DIR__ . '/includes/OutputPage.php',
+       'PageProps' => __DIR__ . '/includes/PageProps.php',
        'PNGHandler' => __DIR__ . '/includes/media/PNG.php',
        'PNGMetadataExtractor' => __DIR__ . 
'/includes/media/PNGMetadataExtractor.php',
        'PPCustomFrame_DOM' => __DIR__ . 
'/includes/parser/Preprocessor_DOM.php',
diff --git a/includes/PageProps.php b/includes/PageProps.php
new file mode 100644
index 0000000..25620ec
--- /dev/null
+++ b/includes/PageProps.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Access to properties of a page.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Gives access to properties of a page.
+ *
+ * @since 1.27
+ *
+ */
+class PageProps {
+
+       /** @var int $pageId page ID of the page being queried */
+       private $pageId;
+
+       /**
+        * Create a PageProps object
+        *
+        * @param Title $title
+        *
+        */
+       public function __construct( Title $title ) {
+               $this->pageId = $title->getArticleID();
+       }
+
+       /**
+        * Get page property value for a given property name.
+        *
+        * @param string $propertyName
+        *
+        * @return string|bool property value array or false if not found
+        *
+        */
+       public function getProperty( $propertyName ) {
+
+               if ( $this->pageId < 1 ) {
+                       return false;
+               }
+
+               $propertyValue = self::getCachedProperty( $this->pageId, 
$propertyName );
+               if ( $propertyValue !== false ) {
+                       return $propertyValue;
+               }
+
+               $dbr = wfGetDB( DB_SLAVE );
+               $row = $dbr->selectRow(
+                       'page_props',
+                       array( 'pp_value' ),
+                       array(
+                               'pp_page' => $this->pageId,
+                               'pp_propname' => $propertyName
+                       ),
+                       __METHOD__
+               );
+
+               if ( $row !== false ) {
+                       $propertyValue = $row->pp_value;
+                       self::cacheProperty( $this->pageId, $propertyName, 
$propertyValue );
+                       return $propertyValue;
+               }
+
+               return false;
+       }
+
+       /**
+        * Get all page property values.
+        *
+        * @return array property value array
+        *
+        */
+       public function getProperties() {
+
+               if ( $this->pageId < 1 ) {
+                       return array();
+               }
+
+               $pageProperties = self::getCachedProperties( $this->pageId );
+               if ( $pageProperties !== false ) {
+                       return $pageProperties;
+               }
+
+               $dbr = wfGetDB( DB_SLAVE );
+               $result = $dbr->select(
+                       'page_props',
+                       array(
+                               'pp_propname',
+                               'pp_value'
+                       ),
+                       array(
+                               'pp_page' => $this->pageId
+                       ),
+                       __METHOD__
+               );
+
+               $pageProperties = array();
+
+               foreach ( $result as $row ) {
+                       $pageProperties[$row->pp_propname] = $row->pp_value;
+               }
+
+               self::cacheProperties( $this->pageId, $pageProperties );
+
+               return $pageProperties;
+       }
+
+       /** Cache parameters */
+       const CACHE_TTL = 10; // integer; TTL in seconds
+       const CACHE_SIZE = 100; // integer; max cached pages
+
+       /** Property cache */
+       private static $cache = null;
+
+       /**
+        * Get a property from the cache.
+        *
+        * @param int $pageId page ID of page being queried
+        * @param string $propertyName name of property being queried
+        *
+        * @return string|bool property value array or false if not found
+        *
+        */
+       private static function getCachedProperty( $pageId, $propertyName ) {
+               if ( is_null( self::$cache ) ) {
+                       return false;
+               }
+               if ( self::$cache->has( $pageId, $propertyName, self::CACHE_TTL 
) ) {
+                       return self::$cache->get( $pageId, $propertyName );
+               }
+               if ( self::$cache->has( 0, $pageId, self::CACHE_TTL ) ) {
+                       $pageProperties = self::$cache->get( 0, $pageId  );
+                       if ( isset( $pageProperties[$propertyName] ) ) {
+                               return $pageProperties[$propertyName];
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Get properties from the cache.
+        *
+        * @param int $pageId page ID of page being queried
+        *
+        * @return string|bool property value array or false if not found
+        *
+        */
+       private static function getCachedProperties( $pageId ) {
+               if ( is_null( self::$cache ) ) {
+                       return false;
+               }
+               if ( self::$cache->has( 0, $pageId, self::CACHE_TTL ) ) {
+                       return self::$cache->get( 0, $pageId );
+               }
+               return false;
+       }
+
+       /**
+        * Save a property to the cache.
+        *
+        * @param int $pageId page ID of page being cached
+        * @param string $propertyName name of property being cached
+        * @param mixed $propertyValue value of property
+        *
+        */
+       private static function cacheProperty( $pageId, $propertyName,
+               $propertyValue ) {
+               if ( is_null( self::$cache ) ) {
+                       self::$cache = new ProcessCacheLRU( self::CACHE_SIZE );
+               }
+               self::$cache->set( $pageId, $propertyName, $propertyValue );
+       }
+
+       /**
+        * Save properties to the cache.
+        *
+        * @param int $pageId page ID of page being cached
+        * @param array $pageProperties associative array of page properties to 
be cached
+        *
+        */
+       private static function cacheProperties( $pageId, $pageProperties ) {
+               if ( is_null( self::$cache ) ) {
+                       self::$cache = new ProcessCacheLRU( self::CACHE_SIZE );
+               }
+               self::$cache->clear( $pageId );
+               self::$cache->set( 0, $pageId, $pageProperties );
+       }
+}
diff --git a/includes/actions/InfoAction.php b/includes/actions/InfoAction.php
index 7389ae2..ff909f5 100644
--- a/includes/actions/InfoAction.php
+++ b/includes/actions/InfoAction.php
@@ -203,19 +203,8 @@
 
                $pageCounts = $this->pageCounts( $this->page );
 
-               // Get page properties
-               $dbr = wfGetDB( DB_SLAVE );
-               $result = $dbr->select(
-                       'page_props',
-                       array( 'pp_propname', 'pp_value' ),
-                       array( 'pp_page' => $id ),
-                       __METHOD__
-               );
-
-               $pageProperties = array();
-               foreach ( $result as $row ) {
-                       $pageProperties[$row->pp_propname] = $row->pp_value;
-               }
+               $props = new PageProps( $title );
+               $pageProperties = $props->getProperties();
 
                // Basic information
                $pageInfo = array();
diff --git a/tests/phpunit/includes/PagePropsTest.php 
b/tests/phpunit/includes/PagePropsTest.php
new file mode 100644
index 0000000..2567368
--- /dev/null
+++ b/tests/phpunit/includes/PagePropsTest.php
@@ -0,0 +1,196 @@
+<?php
+
+/**
+ * @group Database
+ *     ^--- tell jenkins this test needs the database
+ *
+ * @group medium
+ *     ^--- tell phpunit that these test cases may take longer than 2 seconds.
+ */
+class TestPageProps extends MediaWikiLangTestCase {
+
+       /**
+        * @var WikiPage $the_page
+        */
+       private $the_page;
+
+       /**
+        * @var int $the_page_id
+        */
+       private $the_page_id;
+
+       protected function setUp() {
+               global $wgExtraNamespaces, $wgNamespaceContentModels, 
$wgContentHandlers, $wgContLang;
+
+               parent::setUp();
+
+               $wgExtraNamespaces[12312] = 'Dummy';
+               $wgExtraNamespaces[12313] = 'Dummy_talk';
+
+               $wgNamespaceContentModels[12312] = 'DUMMY';
+               $wgContentHandlers['DUMMY'] = 'DummyContentHandlerForTesting';
+
+               MWNamespace::getCanonicalNamespaces( true ); # reset namespace 
cache
+               $wgContLang->resetNamespaces(); # reset namespace cache
+               if ( !$this->the_page ) {
+                       $this->the_page = $this->createPage(
+                               'PagePropsTest_the_page',
+                               "just a dummy page",
+                               CONTENT_MODEL_WIKITEXT
+                       );
+
+                       $this->the_page_id = 
$this->the_page->getTitle()->getArticleID();
+
+                       $properties = array(
+                               "property1" => "value1",
+                               "property2" => "value2",
+                               "property3" => "value3",
+                               "property4" => "value4"
+                       );
+                       $this->setProperties( $properties );
+               }
+       }
+
+       protected function tearDown() {
+               global $wgExtraNamespaces, $wgNamespaceContentModels, 
$wgContentHandlers, $wgContLang;
+
+               parent::tearDown();
+
+               unset( $wgExtraNamespaces[12312] );
+               unset( $wgExtraNamespaces[12313] );
+
+               unset( $wgNamespaceContentModels[12312] );
+               unset( $wgContentHandlers['DUMMY'] );
+
+               MWNamespace::getCanonicalNamespaces( true ); # reset namespace 
cache
+               $wgContLang->resetNamespaces(); # reset namespace cache
+       }
+
+       public function testGetSingleProperty() {
+               $title = $this->the_page->getTitle();
+               $props = new PageProps( $title );
+               $value = $props->getProperty( "property1" );
+               $this->assertEquals( $value, "value1", "Get property" );
+       }
+
+       public function testGetAllProperties() {
+               $title = $this->the_page->getTitle();
+               $props = new PageProps( $title );
+               $this->assertEquals( $this->getProperties(), 
$props->getProperties(), "Get all properties" );
+       }
+
+       public function testSingleCache() {
+               $title = $this->the_page->getTitle();
+               $props = new PageProps( $title );
+               $value1 = $props->getProperty( "property1" );
+               $this->setProperty( "property1", "another value" );
+               $value2 = $props->getProperty( "property1" );
+               $this->assertEquals( $value1, $value2, "Single cache" );
+       }
+
+       public function testMultiCache() {
+               $title = $this->the_page->getTitle();
+               $props = new PageProps( $title );
+               $properties1 = $props->getProperties();
+               $this->setProperty( "property1", "another value" );
+               $properties2 = $props->getProperties();
+               $this->assertEquals( $properties1, $properties2, "Multi Cache" 
);
+       }
+
+       public function testClearCache() {
+               $title = $this->the_page->getTitle();
+               $props = new PageProps( $title );
+               $value1 = $props->getProperty( "property1" );
+               $this->setProperty( "property1", "another value" );
+               $props->getProperties();
+               $value2 = $props->getProperty( "property1" );
+               $this->assertNotEquals( $value1, $value2, "Clear cache" );
+       }
+
+       protected function createPage( $page, $text, $model = null ) {
+               if ( is_string( $page ) ) {
+                       if ( !preg_match( '/:/', $page ) &&
+                               ( $model === null || $model === 
CONTENT_MODEL_WIKITEXT )
+                       ) {
+                               $ns = $this->getDefaultWikitextNS();
+                               $page = MWNamespace::getCanonicalName( $ns ) . 
':' . $page;
+                       }
+
+                       $page = Title::newFromText( $page );
+               }
+
+               if ( $page instanceof Title ) {
+                       $page = new WikiPage( $page );
+               }
+
+               if ( $page->exists() ) {
+                       $page->doDeleteArticle( "done" );
+               }
+
+               $content = ContentHandler::makeContent( $text, 
$page->getTitle(), $model );
+               $page->doEditContent( $content, "testing", EDIT_NEW );
+
+               return $page;
+       }
+
+       protected function setProperties( $properties ) {
+
+               $rows = array();
+
+               foreach ( $properties as $propertyName => $propertyValue ) {
+
+                       $row = array(
+                               'pp_page' => $this->the_page_id,
+                               'pp_propname' => $propertyName,
+                               'pp_value' => $propertyValue
+                       );
+
+                       $rows[] = $row;
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->replace(
+                       'page_props',
+                       array (
+                               array (
+                                       'pp_page',
+                                       'pp_propname'
+                               )
+                       ),
+                       $rows,
+                       __METHOD__
+               );
+       }
+
+       protected function getProperties() {
+
+               $dbr = wfGetDB( DB_SLAVE );
+               $result = $dbr->select(
+                       'page_props',
+                       array(
+                               'pp_propname',
+                               'pp_value'
+                       ),
+                       array(
+                               'pp_page' => $this->the_page_id,
+                       ),
+                       __METHOD__
+               );
+
+               $pageProperties = array();
+
+               foreach ( $result as $row ) {
+                       $pageProperties[$row->pp_propname] = $row->pp_value;
+               }
+
+               return $pageProperties;
+       }
+       protected function setProperty( $propertyName, $propertyValue ) {
+
+               $properties = array();
+               $properties[$propertyName] = $propertyValue;
+
+               $this->setProperties( $properties );
+
+       }
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I022b9e3ca47dc63650b8a62260603b0893a80e69
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Cicalese <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to