Disallow customization of system critical templates
authorAlexander Ebert <ebert@woltlab.com>
Tue, 18 Jul 2017 12:30:42 +0000 (14:30 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 18 Jul 2017 12:30:42 +0000 (14:30 +0200)
Closes #2335

wcfsetup/install/files/acp/templates/templateList.tpl
wcfsetup/install/files/lib/data/template/Template.class.php
wcfsetup/install/files/lib/system/template/TemplateEngine.class.php

index 76d6839c4df83f07b0024b69763ef16e210acb66..81796f51363c1cb9de354de06c3c26c8d0a1fd86 100644 (file)
                        
                        <tbody>
                                {foreach from=$objects item=template}
-                                       <tr class="jsTemplateRow">
-                                               <td class="columnIcon">
-                                                       <a href="{link controller='TemplateAdd'}copy={@$template->templateID}{/link}" title="{lang}wcf.acp.template.copy{/lang}" class="jsTooltip"><span class="icon icon16 fa-files-o"></span></a>
+                                       {if $template->canCopy()}
+                                               <tr class="jsTemplateRow">
+                                                       <td class="columnIcon">
+                                                               <a href="{link controller='TemplateAdd'}copy={@$template->templateID}{/link}" title="{lang}wcf.acp.template.copy{/lang}" class="jsTooltip"><span class="icon icon16 fa-files-o"></span></a>
+                                                               
+                                                               {if $template->templateGroupID}
+                                                                       <a href="{link controller='TemplateDiff' id=$template->templateID}{/link}" title="{lang}wcf.acp.template.diff{/lang}" class="jsTooltip"><span class="icon icon16 fa-exchange"></span></a>
+                                                                       <a href="{link controller='TemplateEdit' id=$template->templateID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
+                                                                       <span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$template->templateID}" data-confirm-message-html="{lang __encode=true}wcf.acp.template.delete.sure{/lang}"></span>
+                                                               {else}
+                                                                       <span class="icon icon16 fa-exchange disabled" title="{lang}wcf.acp.template.diff{/lang}"></span>
+                                                                       <span class="icon icon16 fa-pencil disabled" title="{lang}wcf.global.button.edit{/lang}"></span>
+                                                                       <span class="icon icon16 fa-times disabled" title="{lang}wcf.global.button.delete{/lang}"></span>
+                                                               {/if}
+                                                               
+                                                               {event name='rowButtons'}
+                                                       </td>
+                                                       <td class="columnID">{@$template->templateID}</td>
+                                                       <td class="columnTitle columnTemplateName">{if $template->application != 'wcf'}<span class="badge label">{$template->application}</span> {/if}{if $template->templateGroupID}<a href="{link controller='TemplateEdit' id=$template->templateID}{/link}">{$template->templateName}</a>{else}{$template->templateName}{/if}</td>
+                                                       <td class="columnDate columnLastModificationTime">{@$template->lastModificationTime|time}</td>
                                                        
-                                                       {if $template->templateGroupID}
-                                                               <a href="{link controller='TemplateDiff' id=$template->templateID}{/link}" title="{lang}wcf.acp.template.diff{/lang}" class="jsTooltip"><span class="icon icon16 fa-exchange"></span></a>
-                                                               <a href="{link controller='TemplateEdit' id=$template->templateID}{/link}" title="{lang}wcf.global.button.edit{/lang}" class="jsTooltip"><span class="icon icon16 fa-pencil"></span></a>
-                                                               <span class="icon icon16 fa-times jsDeleteButton jsTooltip pointer" title="{lang}wcf.global.button.delete{/lang}" data-object-id="{@$template->templateID}" data-confirm-message-html="{lang __encode=true}wcf.acp.template.delete.sure{/lang}"></span>
-                                                       {else}
-                                                               <span class="icon icon16 fa-exchange disabled" title="{lang}wcf.acp.template.diff{/lang}"></span>
-                                                               <span class="icon icon16 fa-pencil disabled" title="{lang}wcf.global.button.edit{/lang}"></span>
-                                                               <span class="icon icon16 fa-times disabled" title="{lang}wcf.global.button.delete{/lang}"></span>
-                                                       {/if}
-                                                       
-                                                       {event name='rowButtons'}
-                                               </td>
-                                               <td class="columnID">{@$template->templateID}</td>
-                                               <td class="columnTitle columnTemplateName">{if $template->application != 'wcf'}<span class="badge label">{$template->application}</span> {/if}{if $template->templateGroupID}<a href="{link controller='TemplateEdit' id=$template->templateID}{/link}">{$template->templateName}</a>{else}{$template->templateName}{/if}</td>
-                                               <td class="columnDate columnLastModificationTime">{@$template->lastModificationTime|time}</td>
-                                               
-                                               {event name='columns'}
-                                       </tr>
+                                                       {event name='columns'}
+                                               </tr>
+                                       {/if}
                                {/foreach}
                        </tbody>
                </table>
index d4c40b174f30aa22c3a4236ef261f9939b5d2730..ce0bcc4e4bb831f52a776f35a240354f7f399fd6 100644 (file)
@@ -22,6 +22,12 @@ use wcf\util\FileUtil;
  * @property-read      integer         $lastModificationTime   timestamp at which the template has been edited the last time
  */
 class Template extends DatabaseObject {
+       /**
+        * list of system critical templates
+        * @var string[]
+        */
+       protected static $systemCriticalTemplates = ['headIncludeJavaScript', 'wysiwyg', 'wysiwygToolbar'];
+       
        /** @noinspection PhpMissingParentConstructorInspection */
        /**
         * @inheritDoc
@@ -81,4 +87,31 @@ class Template extends DatabaseObject {
        public function getSource() {
                return @file_get_contents($this->getPath());
        }
+       
+       /**
+        * Returns true if current template is considered system critical and
+        * may not be customized at any point.
+        * 
+        * @return      boolean
+        */
+       public function canCopy() {
+               if (self::isSystemCritical($this->templateName)) {
+                       // system critical templates cannot be modified, because whatever the
+                       // gain of a customized version is, the damage potential is much higher
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       /**
+        * Returns true if current template is considered system critical and
+        * may not be customized at any point.
+        * 
+        * @param       string          $templateName
+        * @return      boolean
+        */
+       public static function isSystemCritical($templateName) {
+               return in_array($templateName, self::$systemCriticalTemplates);
+       }
 }
index 17ef91c7343cf62c3aefc5e241b164100989058c..5084db06b7708dd47b46e24dbafbeacbf06ad454 100755 (executable)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\system\template;
+use wcf\data\template\Template;
 use wcf\system\cache\builder\TemplateGroupCacheBuilder;
 use wcf\system\cache\builder\TemplateListenerCodeCacheBuilder;
 use wcf\system\event\EventHandler;
@@ -47,7 +48,7 @@ class TemplateEngine extends SingletonFactory {
         * active template compiler
         * @var TemplateCompiler
         */
-       protected $compilerObj = null;
+       protected $compilerObj;
        
        /**
         * forces the template engine to recompile all included templates
@@ -358,17 +359,19 @@ class TemplateEngine extends SingletonFactory {
         * @return      string
         */
        protected function getPath($templatePath, $templateName) {
-               $templateGroupID = $this->getTemplateGroupID();
-               
-               while ($templateGroupID != 0) {
-                       $templateGroup = $this->templateGroupCache[$templateGroupID];
+               if (!Template::isSystemCritical($templateName)) {
+                       $templateGroupID = $this->getTemplateGroupID();
                        
-                       $path = $templatePath.$templateGroup->templateGroupFolderName.$templateName.'.tpl';
-                       if (file_exists($path)) {
-                               return $path;
+                       while ($templateGroupID != 0) {
+                               $templateGroup = $this->templateGroupCache[$templateGroupID];
+                               
+                               $path = $templatePath . $templateGroup->templateGroupFolderName . $templateName . '.tpl';
+                               if (file_exists($path)) {
+                                       return $path;
+                               }
+                               
+                               $templateGroupID = $templateGroup->parentTemplateGroupID;
                        }
-                       
-                       $templateGroupID = $templateGroup->parentTemplateGroupID;
                }
                
                // use default template