Massive update to plugin system architecture. Please test! Not all core plugins...
[squirrelmail.git] / class / template / Template.class.php
index 70705ae20835f4f4e3543f314512ae99b1424656..1f4a6d7d6480c0b7a67f64cdc9083b768c68840d 100644 (file)
@@ -37,7 +37,7 @@ require(SM_PATH . 'functions/template.php');
   *     append_by_ref()
   *     apply_template()
   *
-  * @author Paul Lesniewski
+  * @author Paul Lesniewski <paul at squirrelmail.org>
   * @package squirrelmail
   *
   */
@@ -238,7 +238,7 @@ class Template
         //
         $found_it = FALSE;
         foreach ($aTemplateSet as $aTemplate) {
-            if ($aTemplate['ID'] == $templateset_fallback) {
+            if ($aTemplate['ID'] === $templateset_fallback) {
                 $found_it = TRUE;
                 break;
             }
@@ -289,7 +289,7 @@ class Template
         //
         $found_it = FALSE;
         foreach ($aTemplateSet as $aTemplate) {
-            if ($aTemplate['ID'] == $templateset_default) {
+            if ($aTemplate['ID'] === $templateset_default) {
                 $found_it = TRUE;
                 break;
             }
@@ -840,6 +840,22 @@ class Template
       *                         slash, indicating that all files
       *                         for that directory name should
       *                         be returned.
+      * @param boolean $directories_ok When TRUE, directory names
+      *                                are acceptable search values,
+      *                                and when returning a list of
+      *                                directory contents, sub-directory
+      *                                names will also be included
+      *                                (optional; default FALSE).
+      *                                NOTE that empty directories 
+      *                                are NOT included in the cache!
+      * @param boolean $directories_only When TRUE, only directory names
+      *                                  are included in the returned
+      *                                  results.  (optional; default 
+      *                                  FALSE).  Setting this argument
+      *                                  to TRUE forces $directories_ok 
+      *                                  to TRUE as well.
+      *                                  NOTE that empty directories 
+      *                                  are NOT included in the cache!
       *
       * @return mixed The full path to the template file or a list
       *               of all files in the given directory if $filename
@@ -849,8 +865,15 @@ class Template
       *               file is not found.
       *
       */
-    function get_template_file_path($filename) {
+    function get_template_file_path($filename, 
+                                    $directories_ok=FALSE, 
+                                    $directories_only=FALSE) {
 
+        if ($directories_only) $directories_ok = TRUE;
+
+
+        // only looking for directory listing first...
+        //
         // return list of all files in a directory (and that
         // of any ancestors)
         //
@@ -862,30 +885,73 @@ class Template
                 // only want files in the requested directory
                 // (AND not in a subdirectory!)
                 //
-                if (strpos($file, $filename) === 0 
+                if (!$directories_only && strpos($file, $filename) === 0 
                  && strpos($file, '/', strlen($filename)) === FALSE)
                     $return_array[] = SM_PATH . $file_info['PATH'];
 
+                // directories too?  detect by finding any
+                // array key that matches a file in a sub-directory
+                // of the directory being processed
+                //
+                if ($directories_ok && strpos($file, $filename) === 0
+                 && ($pos = strpos($file, '/', strlen($filename))) !== FALSE
+                 && strpos($file, '/', $pos + 1) === FALSE) {
+                    $directory_name = SM_PATH 
+                                    . substr($file_info['PATH'], 
+                                             0, 
+                                             strrpos($file_info['PATH'], '/'));
+                    if (!in_array($directory_name, $return_array))
+                        $return_array[] = $directory_name;
+                }
+
             }
             return $return_array;
 
         }
 
+
+        // just looking for singular file or directory below...
+        //
         // figure out what to do with files not found
         //
-        if (empty($this->template_file_cache[$filename]['PATH'])) {
+        if ($directories_only || empty($this->template_file_cache[$filename]['PATH'])) {
+
+            // if looking for directories...
+            // have to iterate through cache and detect
+            // directory by matching any file inside of it
+            //
+            if ($directories_ok) {
+                foreach ($this->template_file_cache as $file => $file_info) {
+                    if (strpos($file, $filename) === 0
+                     && ($pos = strpos($file, '/', strlen($filename))) !== FALSE
+                     && strpos($file, '/', $pos + 1) === FALSE) {
+                        return SM_PATH . substr($file_info['PATH'], 
+                                                0, 
+                                                strrpos($file_info['PATH'], '/'));
+                    }
+                }
+
+                if ($directories_only) return '';
+            }
 
-            // plugins get one more chance below; any other
-            // files we just give up now
+            // plugins get one more chance 
             //
-            if (strpos($filename, 'plugins/') !== 0) 
-                return '';
+            if (strpos($filename, 'plugins/') === 0) {
 
-            $plugin_name = substr($filename, 8, strpos($filename, '/', 8) - 8);
-            $file = substr($filename, strlen($plugin_name) + 9);
+                $plugin_name = substr($filename, 8, strpos($filename, '/', 8) - 8);
+                $file = substr($filename, strlen($plugin_name) + 9);
 
-            if (!$this->find_and_cache_plugin_template_file($plugin_name, $file))
-                return '';
+                if (!$this->find_and_cache_plugin_template_file($plugin_name, $file))
+                    return '';
+                //FIXME: technically I guess we should check for directories
+                //       here too, but that's overkill (no need) presently
+                //       (plugin-provided alternate stylesheet dirs?!?  bah.)
+
+            }
+
+            // nothing... return empty string (yes, the else is intentional!)
+            //
+            else return '';
 
         }
 
@@ -1010,14 +1076,13 @@ class Template
     /**
       * Return all alternate stylesheets provided by template.  
       *
-      * All files found in the template set's "css/alternates" 
-      * directory (and that of its ancestors) with the extension
-      * ".css" are returned.
+      * All (non-empty) directories found in the template set's 
+      * "css/alternates" directory (and that of its ancestors) 
+      * are returned.
       *
       * Note that prettified names are constructed herein by
-      * taking the file name, changing underscores to spaces,
-      * removing the ".css" from the end of the file, and 
-      * capitalizing each word in the resultant name.
+      * taking the directory name, changing underscores to spaces
+      * and capitalizing each word in the resultant name.
       *
       * @param boolean $full_path When FALSE, only the file names
       *                           are included in the return array;
@@ -1039,25 +1104,24 @@ class Template
         // all alternate css files from ancestor 
         // template sets, not just this set
         //
-        //$directory = SM_PATH . $this->get_template_file_directory() . 'css/alternates';
-        //$css_files = list_files($directory, '.css', !$full_path);
-        //
-        $css_files = $this->get_template_file_path('css/alternates/');
+        $css_directories = $this->get_template_file_path('css/alternates/', TRUE, TRUE);
 
 
-        // parse out .css files only
+        // prettify names
         //
         $return_array = array();
-        foreach ($css_files as $file) {
+        foreach ($css_directories as $directory) {
 
-            if (substr($file, strlen($file) - 4) != '.css') continue;
+            // CVS directories are not wanted
+            //
+            if (strpos($directory, '/CVS') === strlen($directory) - 4) continue;
 
-            $pretty_name = ucwords(str_replace('_', ' ', substr(basename($file), 0, -4)));
+            $pretty_name = ucwords(str_replace('_', ' ', basename($directory)));
 
             if ($full_path) {
-                $return_array[$file] = $pretty_name;
+                $return_array[$directory] = $pretty_name;
             } else {
-                $return_array[basename($file)] = $pretty_name;
+                $return_array[basename($directory)] = $pretty_name;
             }
 
         }
@@ -1273,7 +1337,7 @@ FIXME: We could make the incoming array more complex so it can
 
             $aPluginOutput = array();
             $aPluginOutput = concat_hook_function('template_construct_' . $file,
-                                                  array($aPluginOutput, $this));
+                                                  $temp=array(&$aPluginOutput, &$this));
             $this->assign('plugin_output', $aPluginOutput);
 
             //$output = $this->apply_template($template);
@@ -1285,7 +1349,7 @@ FIXME: We could make the incoming array more complex so it can
             // using this hook will probably be rejected by the
             // SquirrelMail team.
             //
-            $output = filter_hook_function('template_output', $output);
+            do_hook('template_output', $output);
 
             return $output;