Awight has uploaded a new change for review.

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

Change subject: (FR #1845) Assert no unconsumed tokens while rendering 
thank-yous
......................................................................

(FR #1845) Assert no unconsumed tokens while rendering thank-yous

This improves the check by intercepting content before it's written to
disk, making it much harder to accidentally commit bad templates.

Deployment:
* drush rr

Change-Id: Ic269f66a8623e63411c7dc612762c2018f8f6c65
---
D sites/all/modules/thank_you/FindUnconsumedTokens.php
M sites/all/modules/thank_you/find_unconsumed_tokens.drush.inc
A sites/all/modules/thank_you/generators/FindUnconsumedTokens.php
M sites/all/modules/thank_you/generators/RenderTranslatedPage.php
D sites/all/modules/thank_you/generators/ThankYou2012.php
M sites/all/modules/thank_you/make_thank_you.drush.inc
M sites/all/modules/thank_you/thank_you.info
M sites/all/modules/wmf_communication/Templating.php
8 files changed, 130 insertions(+), 104 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/crm 
refs/changes/84/150884/1

diff --git a/sites/all/modules/thank_you/FindUnconsumedTokens.php 
b/sites/all/modules/thank_you/FindUnconsumedTokens.php
deleted file mode 100644
index 3f3f8e8..0000000
--- a/sites/all/modules/thank_you/FindUnconsumedTokens.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-class FindUnconsumedTokens {
-    static function searchTokens() {
-        watchdog( 'thank_you', "Searching for unconsumed tokens in thank-you 
pages..." );
-        $ret = 0;
-        $languages = thank_you_get_languages();
-        foreach ( $languages as $lang ) {
-            $err = FindUnconsumedTokens::searchToken( $lang );
-            $ret = $err || $ret;
-        }
-        if ( $ret ) {
-            throw new Exception( "Bad news, you have errors." );
-        }
-    }
-
-    static function searchToken( $lang ) {
-        // Turn on all the lights
-        $params = array(
-            // FIXME: name should be run through both branches
-            'first_name' => 'fix',
-            'last_name' => 'me',
-            'recurring' => true,
-            'RecurringRestarted' => true,
-
-            'receive_date' => time(),
-
-            'locale' => $lang,
-        );
-        $buf = thank_you_render( $params );
-
-        $bad_punctuation_re = '/
-            # Square brackets, but not a numbered footnote
-            \[ (?: (?! \d+ \] ) . )+ \]
-            |
-            # Other exotic punctuation that indicates a failed token
-            (
-                [${}]+
-                |
-                # This is a hash, but is not part of an URL fragment?
-                (?: (?! https?:\/\/ ) . )+ \K [#]
-            )
-            # Token name if we are lucky
-            (?: [-a-zA-Z0-9_]+ )?
-        /x';
-        if ( $count = preg_match_all( $bad_punctuation_re, $buf, $matches ) ) {
-            $bad_punc = implode( ', ', $matches[0] );
-            watchdog( 'thank_you',
-                "Found {$count} likely tokens [{$bad_punc}] in thank-you 
translation [{$lang}].",
-                null, WATCHDOG_ERROR
-            );
-            return -1;
-        }
-    }
-}
diff --git a/sites/all/modules/thank_you/find_unconsumed_tokens.drush.inc 
b/sites/all/modules/thank_you/find_unconsumed_tokens.drush.inc
index 82e9783..fdf3c12 100644
--- a/sites/all/modules/thank_you/find_unconsumed_tokens.drush.inc
+++ b/sites/all/modules/thank_you/find_unconsumed_tokens.drush.inc
@@ -1,5 +1,7 @@
 <?php
 
+use thank_you\generators\FindUnconsumedTokens;
+
 function find_unconsumed_tokens_drush_command() {
        $items = array();
 
@@ -11,5 +13,5 @@
 }
 
 function drush_find_unconsumed_tokens() {
-    FindUnconsumedTokens::searchTokens();
+    FindUnconsumedTokens::findAllTokens();
 }
diff --git a/sites/all/modules/thank_you/generators/FindUnconsumedTokens.php 
b/sites/all/modules/thank_you/generators/FindUnconsumedTokens.php
new file mode 100644
index 0000000..3c40110
--- /dev/null
+++ b/sites/all/modules/thank_you/generators/FindUnconsumedTokens.php
@@ -0,0 +1,95 @@
+<?php
+namespace thank_you\generators;
+
+use wmf_communication\Templating;
+
+class FindUnconsumedTokens {
+    /**
+     * Search all locally translated languages for unconsumed tokens
+     * @throws UnconsumedTokenException
+     */
+    static function findAllTokens() {
+        watchdog( 'thank_you',
+            "Searching for unconsumed tokens in thank-you pages...", NULL, 
WATCHDOG_INFO );
+        $failure = false;
+        $languages = thank_you_get_languages();
+        foreach ( $languages as $lang ) {
+            try {
+                $err = FindUnconsumedTokens::findTokensInLanguage( $lang );
+            } catch ( UnconsumedTokenException $ex ) {
+                watchdog( 'thank_you', $ex->getMessage(), null, WATCHDOG_ERROR 
);
+                $failure = true;
+            }
+        }
+        if ( $failure ) {
+            throw new UnconsumedTokenException( "Bad news, see errors above." 
);
+        }
+    }
+
+    static protected function getRandomTemplateParams( $locale ) {
+        // Turn on all the lights
+        $params = array(
+            // FIXME: name should be run through both branches
+            'first_name' => 'fix',
+            'last_name' => 'me',
+            'recurring' => true,
+            'RecurringRestarted' => true,
+
+            'receive_date' => time(),
+
+            'locale' => $locale,
+        );
+        return $params;
+    }
+
+    // TODO: refactor out of this class
+    static function renderLanguage( $lang ) {
+        $params = FindUnconsumedTokens::getRandomTemplateParams( $lang );
+        $buf = thank_you_render( $params );
+        return $buf;
+    }
+
+    /**
+     * @throws UnconsumedTokenException
+     */
+    static function findTokensInLanguage( $lang ) {
+        $buf = FindUnconsumedTokens::renderLanguage( $lang );
+        FindUnconsumedTokens::findTokens( $buf );
+    }
+
+    /**
+     * @throws UnconsumedTokenException
+     */
+    static function renderAndFindTokens( $template, $locale ) {
+        $rendered = Templating::renderStringTemplate( $template, 
FindUnconsumedTokens::getRandomTemplateParams( $locale ) );
+        FindUnconsumedTokens::findTokens( $buf );
+    }
+
+    /**
+     * Search a buffer for unconsumed tokens
+     * @throws UnconsumedTokenException
+     */
+    static function findTokens( $buf ) {
+        $bad_punctuation_re = '/
+            # Square brackets, but not a numbered footnote
+            \[ (?: (?! \d+ \] ) . )+ \]
+            |
+            # Other exotic punctuation that indicates a failed token
+            (
+                [${}]+
+                |
+                # This is a hash, but is not part of an URL fragment?
+                (?: (?! https?:\/\/ ) . )+ \K [#]
+            )
+            # Grab the token name for debugging, if available
+            (?: [-a-zA-Z0-9_]+ )?
+        /x';
+        if ( $count = preg_match_all( $bad_punctuation_re, $buf, $matches ) ) {
+            $bad_punc = implode( ', ', $matches[0] );
+            throw new UnconsumedTokenException(
+                "Found {$count} likely tokens [{$bad_punc}] in rendered 
thank-you translation." );
+        }
+    }
+}
+
+class UnconsumedTokenException extends TranslationException {}
diff --git a/sites/all/modules/thank_you/generators/RenderTranslatedPage.php 
b/sites/all/modules/thank_you/generators/RenderTranslatedPage.php
index c90ee72..318b0ee 100644
--- a/sites/all/modules/thank_you/generators/RenderTranslatedPage.php
+++ b/sites/all/modules/thank_you/generators/RenderTranslatedPage.php
@@ -24,16 +24,6 @@
 
        protected $review_history;
 
-       /**
-        * @var string[] Translation states that this module will accept as 
acceptable
-        * to include in a composite message.
-        */
-       protected $valid_translation_states = array(
-               'ready',
-               'proofread',
-               'translated', // what exactly is this state?
-       );
-
        public function execute($wantedLangs = array()) {
                watchdog(
                        'make-thank-you',
@@ -58,6 +48,9 @@
                                $page_content = str_replace( '|</p>|', 
"</p>\n", $page_content );
 
                                $file = str_replace( '$1', $lang, 
$this->proto_file );
+
+                               // Assert no garbage
+                               FindUnconsumedTokens::renderAndFindTokens( 
$page_content, $lang );
 
                                if (file_put_contents( $file, $page_content )) {
                                        watchdog( 'make-thank-you', "$lang -- 
Wrote translation into $file", null, WATCHDOG_INFO );
@@ -315,6 +308,7 @@
                foreach( $this->substitutions as $k => $v ) {
                        $content = preg_replace( $k, $v, $content );
                }
+
                return $content;
        }
 }
diff --git a/sites/all/modules/thank_you/generators/ThankYou2012.php 
b/sites/all/modules/thank_you/generators/ThankYou2012.php
deleted file mode 100644
index f0d8b2f..0000000
--- a/sites/all/modules/thank_you/generators/ThankYou2012.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php namespace thank_you\generators;
-
-class ThankYou2012 extends RenderTranslatedPage {
-       function __construct() {
-               $this->title = 'Fundraising_2012/Translation/Thank_you_letter';
-               $this->proto_file = __DIR__ . 
'/../templates/html/thank_you.$1.html';
-
-               $this->substitutions = array(
-                       '/\[given name\]/' => '{{ first_name }}',
-                       '/\[date\]/' => '{{ receive_date }}',
-                       '/\[amount\]/' => '{{ (currency ~ " " ~ amount) | 
l10n_currency(locale) }}',
-                       '/\[contributionId\]/' => '{{ transaction_id }}',
-
-                       '/\[ifRecurring\]/' => '{% if recurring %}',
-                       '/\[endifRecurring\]/' => '{% endif %}',
-
-                       '/\[#twitter ((?:(?!\]).)*)\]/' => '<a 
href="https://twitter.com/Wikipedia";>$1</a>',
-                       '/\[#identica ((?:(?!\]).)*)\]/' => '<a 
href="https://identi.ca/wikipedia";>$1</a>',
-                       '/\[#google ((?:(?!\]).)*)\]/' => '<a 
href="https://plus.google.com/+Wikipedia/posts";>$1</a>',
-                       '/\[#facebook ((?:(?!\]).)*)\]/' => '<a 
href="https://www.facebook.com/wikipedia";>$1</a>',
-                       '/\[#blog ((?:(?!\]).)*)\]/' => '<a 
href="https://blog.wikimedia.org";>$1</a>',
-                       // TODO: DO WE HAVE TRANSLATIONS FOR THE ANNUAL REPORT
-                       '/\[#annual ((?:(?!\]).)*)\]/' => '<a 
href="https://meta.wikimedia.org/wiki/Special:MyLanguage/Wikimedia_Foundation/Annual_Report/2012-2013/Front";>$1</a>',
-                       // TODO: DO WE HAVE TRANSLATIONS FOR THE ANNUAL PLAN
-                       '/\[#plan ((?:(?!\]).)*)\]/' => '<a 
href="http://upload.wikimedia.org/wikipedia/foundation/4/4f/2012-13_Wikimedia_Foundation_Plan_FINAL_FOR_WEBSITE.pdf";>$1</a>',
-                       // TODO: DO WE HAVE TRANSLATIONS FOR THE 5-YEAR, 
STRATEGIC PLAN
-                       '/\[#strategic ((?:(?!\]).)*)\]/' => '<a 
href="https://wikimediafoundation.org/wiki/Wikimedia_Movement_Strategic_Plan_Summary";>$1</a>',
-                       '/\[#shop ((?:(?!\]).)*)\]/' => '<a 
href="https://shop.wikimedia.org";>$1</a>',
-                       '/\[#unsubscribe ((?:(?!\]).)*)\]/' => '<a href="{{ 
unsubscribe_link | raw }}">$1</a>',
-                       '/\[#recurringCancel ((?:(?!\]).)*)\]/' => '<a 
href="https://wikimediafoundation.org/wiki/Special:LandingCheck?landing_page=Cancel_or_change_recurring_payments&basic=true&language={{
 locale }}">$1</a>',
-                       '/\[#translate ((?:(?!\]).)*)\]/' => '<a 
href="https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Fundraising+2012%2FTranslation%2FThank+you+letter";>$1</a>',
-               );
-       }
-}
diff --git a/sites/all/modules/thank_you/make_thank_you.drush.inc 
b/sites/all/modules/thank_you/make_thank_you.drush.inc
index dfc0146..7e3370a 100644
--- a/sites/all/modules/thank_you/make_thank_you.drush.inc
+++ b/sites/all/modules/thank_you/make_thank_you.drush.inc
@@ -35,8 +35,6 @@
         $generator = new $generators[$genname]();
         $generator->execute($langs);
     }
-
-    FindUnconsumedTokens::searchTokens();
 }
 
 /**
diff --git a/sites/all/modules/thank_you/thank_you.info 
b/sites/all/modules/thank_you/thank_you.info
index c0d8ca2..1ed382e 100644
--- a/sites/all/modules/thank_you/thank_you.info
+++ b/sites/all/modules/thank_you/thank_you.info
@@ -6,8 +6,7 @@
 dependencies[] = wmf_communication
 package = Wikimedia
 configure = admin/config/thank_you
-files[] = FindUnconsumedTokens.php
 files[] = Html2Text.php
+files[] = generators/FindUnconsumedTokens.php
 files[] = generators/RenderTranslatedPage.php
-files[] = generators/ThankYou2012.php
 files[] = generators/ThankYou.php
diff --git a/sites/all/modules/wmf_communication/Templating.php 
b/sites/all/modules/wmf_communication/Templating.php
index 27f6fad..9dbf10d 100644
--- a/sites/all/modules/wmf_communication/Templating.php
+++ b/sites/all/modules/wmf_communication/Templating.php
@@ -2,6 +2,12 @@
 
 use \Exception;
 
+// FIXME: encapsulate here, not in wmf_common
+use \Twig_Environment;
+use \Twig_Loader_String;
+
+use \TwigLocalization;
+
 /**
  * Single-use template.
  */
@@ -132,4 +138,25 @@
         }
         return null;
     }
+
+    /**
+     * Evaluate a template passed as string literal
+     *
+     * TODO: clean up interface
+     */
+    static function renderStringTemplate( $template, $params ) {
+        // TODO: autoload instead
+        if ( !class_exists( 'Twig_Loader_String' ) ) {
+            module_load_include( 'inc', 'wmf_common', 'twig' );
+
+            // FIXME: throwaway call to initialize
+            wmf_common_get_twig( __DIR__ );
+        }
+
+        $loader = new Twig_Loader_String();
+        $twig = new Twig_Environment( $loader );
+        $twig->addExtension( new TwigLocalization() );
+
+        return $twig->render( $template, $params );
+    }
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic269f66a8623e63411c7dc612762c2018f8f6c65
Gerrit-PatchSet: 1
Gerrit-Project: wikimedia/fundraising/crm
Gerrit-Branch: master
Gerrit-Owner: Awight <[email protected]>

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

Reply via email to