From 20da76524c4e76f3e984bfd0404e32dc6256065f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaime=20Pe=CC=81rez=20Crespo?= <jaime.perez@uninett.no>
Date: Tue, 18 Jul 2017 13:20:59 +0200
Subject: [PATCH] Add a TemplateControllerInterface.

This new interface allows themes to define a class that can be hooked at certain specific points of template initialization/handling, so that they can do stuff like automatically adding variables for all templates, or adding twig extensions. This classes must implement the new TemplateControllerInterface, and be specified in the "theme.controller" configuration option. This way, we avoid the performance hit if we use traditional hooks, and we also avoid hooks from other modules causing trouble.

For now, the interface offers two entry points: setUpTwig(), which allows managing the twig environment after initialization (e.g. to add an extension or define filters); and display(), which offers all the data passed to the template, and allows adding or modifying it.
---
 lib/SimpleSAML/XHTML/Template.php             | 27 ++++++++++++++++
 .../XHTML/TemplateControllerInterface.php     | 32 +++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 lib/SimpleSAML/XHTML/TemplateControllerInterface.php

diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php
index 7a4e3d616..38a8066c3 100644
--- a/lib/SimpleSAML/XHTML/Template.php
+++ b/lib/SimpleSAML/XHTML/Template.php
@@ -70,6 +70,17 @@ class SimpleSAML_XHTML_Template
      */
     private $module;
 
+    /**
+     * A template controller, if any.
+     *
+     * Used to intercept certain parts of the template handling, while keeping away unwanted/unexpected hooks. Set
+     * the 'theme.controller' configuration option to a class that implements the
+     * SimpleSAML\XHTML\TemplateControllerInterface interface to use it.
+     *
+     * @var SimpleSAML\XHTML\TemplateControllerInterface
+     */
+    private $controller;
+
 
     /**
      * Whether we are using a non-default theme or not.
@@ -107,6 +118,15 @@ class SimpleSAML_XHTML_Template
         // initialize internationalization system
         $this->translator = new SimpleSAML\Locale\Translate($configuration, $defaultDictionary);
         $this->localization = new \SimpleSAML\Locale\Localization($configuration);
+
+        // check if we need to attach a theme controller
+        $controller = $this->configuration->getString('theme.controller', false);
+        if ($controller && class_exists($controller) &&
+            class_implements($controller, '\SimpleSAML\XHTML\TemplateControllerInterface')
+        ) {
+            $this->controller = new $controller();
+        }
+
         $this->twig = $this->setupTwig();
     }
 
@@ -221,6 +241,10 @@ class SimpleSAML_XHTML_Template
         $twig->addGlobal('queryParams', $queryParams);
         $twig->addGlobal('templateId', str_replace('.twig', '', $this->normalizeTemplateName($this->template)));
 
+        if ($this->controller) {
+            $this->controller->setUpTwig($twig);
+        }
+
         return $twig;
     }
 
@@ -369,6 +393,9 @@ class SimpleSAML_XHTML_Template
     {
         if ($this->twig !== false) {
             $this->twigDefaultContext();
+            if ($this->controller) {
+                $this->controller->display($this->data);
+            }
             echo $this->twig->render($this->twig_template, $this->data);
         } else {
             $filename = $this->findTemplatePath($this->template);
diff --git a/lib/SimpleSAML/XHTML/TemplateControllerInterface.php b/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
new file mode 100644
index 000000000..bd54907c4
--- /dev/null
+++ b/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace SimpleSAML\XHTML;
+
+/**
+ * Interface that allows modules to run several hooks for templates.
+ *
+ * @package SimpleSAMLphp
+ */
+interface TemplateControllerInterface {
+
+    /**
+     * Implement to modify the twig environment after its initialization (e.g. add filters or extensions).
+     *
+     * @param \Twig_Environment $twig The current twig environment.
+     *
+     * @return void
+     */
+    public function setUpTwig(\Twig_Environment &$twig);
+
+
+    /**
+     * Implement to add, delete or modify the data passed to the template.
+     *
+     * This method will be called right before displaying the template.
+     *
+     * @param array $data The current data used by the template.
+     *
+     * @return void
+     */
+    public function display(&$data);
+}
-- 
GitLab