Matmarex has uploaded a new change for review.

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


Change subject: Store compressed JSON since size is limited
......................................................................

Store compressed JSON since size is limited

We only have 65535 bytes, let's use them wisely.

But only compress if necessary; page properties are sometimes shown as
plaintext (e.g. on Special:PagesWithProp) and it would be nice to
avoid showing the user binary data if possible.

Support compressed and uncompressed inputs in TemplateDataBlob::newFromJSON;
no backwards-incompatible changes were made in public methods. Added
TemplateDataBlob#getJSONForDatabase for the sometimes-compressed form,
used it where applicable.

Bug: 51740
Change-Id: Ie66b0dd6b6dab6f8648e78595c41e52d9c704d57
---
M TemplateData.hooks.php
M TemplateDataBlob.php
2 files changed, 36 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/TemplateData 
refs/changes/30/75330/1

diff --git a/TemplateData.hooks.php b/TemplateData.hooks.php
index 25d2921..91e6547 100644
--- a/TemplateData.hooks.php
+++ b/TemplateData.hooks.php
@@ -87,7 +87,7 @@
                        return '<div class="error">' . $status->getHtml() . 
'</div>';
                }
 
-               $parser->getOutput()->setProperty( 'templatedata', 
$ti->getJSON() );
+               $parser->getOutput()->setProperty( 'templatedata', 
$ti->getJSONForDatabase() );
 
                $parser->getOutput()->addModules( 'ext.templateData' );
 
diff --git a/TemplateDataBlob.php b/TemplateDataBlob.php
index 5a17124..a845dde 100644
--- a/TemplateDataBlob.php
+++ b/TemplateDataBlob.php
@@ -12,6 +12,8 @@
  * @class
  */
 class TemplateDataBlob {
+       // Size of MySQL 'blob' field; page_props table where the data is 
stored uses one.
+       const MAX_LENGTH = 65535;
 
        /**
         * @var stdClass
@@ -24,11 +26,23 @@
        private $status;
 
        /**
-        *  @param string $json
+        * Validate passed JSON (possibly gzip-compressed) and create new 
TemplateDataBlob object. 
+        *
+        * @param string $json
+        * @throws MWException
         * @return TemplateInfo
         */
        public static function newFromJSON( $json ) {
-               $tdb = new self( json_decode( $json ) );
+               if ( substr( $json, 0, 2 ) === "\037\213" ) {
+                       // GZIP header
+                       $tdb = new self( json_decode( gzdecode( $json ) ) );
+               } elseif ( substr( $json, 0, 1 ) === "{" ) {
+                       // Probably raw JSON
+                       $tdb = new self( json_decode( $json ) );
+               } else {
+                       throw new MWException( "Invalid data passed to 
TemplateDataBlob::newFromJSON" );
+               }
+
                $status = $tdb->parse();
 
                if ( !$status->isOK() ) {
@@ -304,12 +318,11 @@
                        }
                }
 
-               // Size of MySQL 'blob' field; page_props table where this is 
stored uses one.
-               $maxlength = 65535;
-               $length = strlen( $this->getJSON() );
-
-               if ( $length > $maxlength ) {
-                       return Status::newFatal( 'templatedata-invalid-length', 
$length, $maxlength );
+               // Check against compressed length to avoid confusion when size 
suddenly drops
+               // after exceeding the maximum
+               $length = strlen( $this->getJSONForDatabase( /* $alwaysCompress 
= */true ) );
+               if ( $length > self::MAX_LENGTH ) {
+                       return Status::newFatal( 'templatedata-invalid-length', 
$length, self::MAX_LENGTH );
                }
 
                return Status::newGood();
@@ -345,6 +358,20 @@
                return json_encode( $this->data );
        }
 
+       /**
+        * @return string JSON, possible gzip-compressed
+        */
+       public function getJSONForDatabase( $alwaysCompress = false ) {
+               $json = $this->getJSON();
+               // Only compress if necessary; page properties are sometimes 
shown as plaintext
+               // and it would be nice to avoid showing the user binary data 
if possible
+               if ( $alwaysCompress || strlen( $json ) > self::MAX_LENGTH ) {
+                       $json = gzencode( $json );
+               }
+
+               return $json;
+       }
+
        public function getHtml( IContextSource $context ) {
                global $wgContLang;
                $langCode = $wgContLang->getCode();

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie66b0dd6b6dab6f8648e78595c41e52d9c704d57
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/TemplateData
Gerrit-Branch: master
Gerrit-Owner: Matmarex <matma....@gmail.com>

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

Reply via email to