includes/template.php
changeset 471 7906fb190fc1
parent 468 194a19711346
child 472 bc4b58034f4d
equal deleted inserted replaced
470:a044ad834691 471:7906fb190fc1
    14  
    14  
    15 class template {
    15 class template {
    16   var $tpl_strings, $tpl_bool, $theme, $style, $no_headers, $additional_headers, $sidebar_extra, $sidebar_widgets, $toolbar_menu, $theme_list, $named_theme_list, $default_theme, $default_style, $plugin_blocks, $namespace_string, $style_list, $theme_loaded;
    16   var $tpl_strings, $tpl_bool, $theme, $style, $no_headers, $additional_headers, $sidebar_extra, $sidebar_widgets, $toolbar_menu, $theme_list, $named_theme_list, $default_theme, $default_style, $plugin_blocks, $namespace_string, $style_list, $theme_loaded;
    17   
    17   
    18   /**
    18   /**
       
    19    * The list of themes that are critical for Enano operation. This doesn't include oxygen which
       
    20    * remains a user theme. By default this is admin and printable which have to be loaded on demand.
       
    21    * @var array
       
    22    */
       
    23   
       
    24   var $system_themes = array('admin', 'printable');
       
    25   
       
    26   /**
    19    * Set to true if the site is disabled and thus a message needs to be shown. This should ONLY be changed by common.php.
    27    * Set to true if the site is disabled and thus a message needs to be shown. This should ONLY be changed by common.php.
    20    * @var bool
    28    * @var bool
    21    * @access private
    29    * @access private
    22    */
    30    */
    23   
    31   
    45                               <a style="background-image: none; padding-right: 0;" href="http://enanocms.org/" onclick="window.open(this.href); return false;"><img style="border-width: 0;" alt=" " src="'.scriptPath.'/images/about-powered-enano.png" onmouseover="domOpacity(this, 100, 0, 500);" onmouseout="domOpacity(this, 0, 100, 500);" /></a>
    53                               <a style="background-image: none; padding-right: 0;" href="http://enanocms.org/" onclick="window.open(this.href); return false;"><img style="border-width: 0;" alt=" " src="'.scriptPath.'/images/about-powered-enano.png" onmouseover="domOpacity(this, 100, 0, 500);" onmouseout="domOpacity(this, 0, 100, 500);" /></a>
    46                             </div>';
    54                             </div>';
    47     
    55     
    48     $this->theme_list = Array();
    56     $this->theme_list = Array();
    49     $this->named_theme_list = Array();
    57     $this->named_theme_list = Array();
    50     $e = $db->sql_query('SELECT theme_id,theme_name,enabled,default_style FROM '.table_prefix.'themes WHERE enabled=1 ORDER BY theme_order;');
    58     
    51     if(!$e) $db->_die('The list of themes could not be selected.');
    59     $q = $db->sql_query('SELECT theme_id, theme_name, enabled, default_style, group_policy, group_list FROM ' . table_prefix . 'themes;');
    52     for($i=0;$i < $db->numrows(); $i++)
    60     if ( !$q )
    53     {
    61       $db->_die('template.php selecting theme list');
    54       $this->theme_list[$i] = $db->fetchrow();
    62     
    55       $this->named_theme_list[$this->theme_list[$i]['theme_id']] = $this->theme_list[$i];
    63     $i = 0;
    56     }
    64     while ( $row = $db->fetchrow() )
    57     $db->free_result();
    65     {
    58     $this->default_theme = $this->theme_list[0]['theme_id'];
    66       $this->theme_list[$i] = $row;
    59     $dir = ENANO_ROOT.'/themes/'.$this->default_theme.'/css/';
    67       $i++;
    60     $list = Array();
    68     }
    61     // Open a known directory, and proceed to read its contents
    69     // List out all CSS files for this theme
    62     if (is_dir($dir)) {
    70     foreach ( $this->theme_list as $i => &$theme )
    63       if ($dh = opendir($dir)) {
    71     {
    64         while (($file = readdir($dh)) !== false) {
    72       $theme['css'] = array();
    65           if(preg_match('#^(.*?)\.css$#i', $file) && $file != '_printable.css') {
    73       $dir = ENANO_ROOT . "/themes/{$theme['theme_id']}/css";
    66             $list[] = substr($file, 0, strlen($file)-4);
    74       if ( $dh = @opendir($dir) )
    67           }
    75       {
       
    76         while ( ( $file = @readdir($dh) ) !== false )
       
    77         {
       
    78           if ( preg_match('/\.css$/', $file) )
       
    79             $theme['css'][] = preg_replace('/\.css$/', '', $file);
    68         }
    80         }
    69         closedir($dh);
    81         closedir($dh);
    70       }
    82       }
    71     }
    83       // No CSS files? If so, nuke it.
    72     
    84       if ( count($theme['css']) < 1 )
    73     $def = ENANO_ROOT.'/themes/'.$this->default_theme.'/css/'.$this->named_theme_list[$this->default_theme]['default_style'];
    85       {
    74     if(file_exists($def))
    86         unset($this->theme_list[$i]);
    75     {
    87       }
    76       $this->default_style = substr($this->named_theme_list[$this->default_theme]['default_style'], 0, strlen($this->named_theme_list[$this->default_theme]['default_style'])-4);
    88     }
    77     } else {
    89     $this->theme_list = array_values($this->theme_list);
    78       $this->default_style = $list[0];
    90     // Create associative array of themes
    79     }
    91     foreach ( $this->theme_list as $i => &$theme )
    80     
    92       $this->named_theme_list[ $theme['theme_id'] ] =& $this->theme_list[$i];
    81     $this->style_list = $list;
    93     
    82     
    94     $this->default_theme = ( $_ = getConfig('theme_default') ) ? $_ : $this->theme_list[0]['theme_id'];
    83   }
    95     // Come up with the default style. If the CSS file specified in default_style exists, we're good, just
       
    96     // use that. Otherwise, use the first stylesheet that comes to mind.
       
    97     $df_data =& $this->named_theme_list[ $this->default_theme ];
       
    98     $this->default_style = ( in_array($df_data['default_style'], $df_data['css']) ) ? $df_data['default_style'] : $df_data['css'][0];
       
    99   }
       
   100   
       
   101   /**
       
   102    * Systematically deletes themes if they're blocked by theme security settings. Called when session->start() finishes.
       
   103    */
       
   104   
       
   105   function process_theme_acls()
       
   106   {
       
   107     global $db, $session, $paths, $template, $plugins; // Common objects
       
   108     
       
   109     // For each theme, check ACLs and delete from RAM if not authorized
       
   110     foreach ( $this->theme_list as $i => $theme )
       
   111     {
       
   112       if ( !$theme['group_list'] )
       
   113         continue;
       
   114       switch ( $theme['group_policy'] )
       
   115       {
       
   116         case 'allow_all':
       
   117           // Unconditionally allowed
       
   118           continue;
       
   119           break;
       
   120         case 'whitelist':
       
   121           // If we're not on the list, off to the left please
       
   122           $list = enano_json_decode($theme['group_list']);
       
   123           $allowed = false;
       
   124           foreach ( $list as $acl )
       
   125           {
       
   126             if ( !preg_match('/^(u|g):([0-9]+)$/', $acl, $match) )
       
   127               // Invalid list entry, silently allow (maybe not a good idea but
       
   128               // really, these things are checked before they're inserted)
       
   129               continue 2;
       
   130             $mode = $match[1];
       
   131             $id = intval($match[2]);
       
   132             switch ( $mode )
       
   133             {
       
   134               case 'u':
       
   135                 $allowed = ( $id == $session->user_id );
       
   136                 if ( $allowed )
       
   137                   break 2;
       
   138                 break;
       
   139               case 'g':
       
   140                 $allowed = ( isset($session->groups[$id]) );
       
   141                 if ( $allowed )
       
   142                   break 2;
       
   143             }
       
   144           }
       
   145           if ( !$allowed )
       
   146           {
       
   147             unset($this->theme_list[$i]);
       
   148           }
       
   149           break;
       
   150         case 'blacklist':
       
   151           // If we're ON the list, off to the left please
       
   152           $list = enano_json_decode($theme['group_list']);
       
   153           $allowed = true;
       
   154           foreach ( $list as $acl )
       
   155           {
       
   156             if ( !preg_match('/^(u|g):([0-9]+)$/', $acl, $match) )
       
   157               // Invalid list entry, silently allow (maybe not a good idea but
       
   158               // really, these things are checked before they're inserted)
       
   159               continue 2;
       
   160             $mode = $match[1];
       
   161             $id = intval($match[2]);
       
   162             switch ( $mode )
       
   163             {
       
   164               case 'u':
       
   165                 $allowed = ( $id != $session->user_id );
       
   166                 if ( !$allowed )
       
   167                   break 2;
       
   168                 break;
       
   169               case 'g':
       
   170                 $allowed = ( !isset($session->groups[$id]) );
       
   171                 if ( !$allowed )
       
   172                   break 2;
       
   173             }
       
   174           }
       
   175           if ( !$allowed )
       
   176           {
       
   177             unset($this->theme_list[$i]);
       
   178           }
       
   179           break;
       
   180       }
       
   181     }
       
   182     
       
   183     $this->theme_list = array_values($this->theme_list);
       
   184     
       
   185     // Rebuild associative theme list
       
   186     $this->named_theme_list = array();
       
   187     foreach ( $this->theme_list as $i => &$theme )
       
   188       $this->named_theme_list[ $theme['theme_id'] ] =& $this->theme_list[$i];
       
   189   }
       
   190   
    84   function sidebar_widget($t, $h, $use_normal_section = false)
   191   function sidebar_widget($t, $h, $use_normal_section = false)
    85   {
   192   {
    86     global $db, $session, $paths, $template, $plugins; // Common objects
   193     global $db, $session, $paths, $template, $plugins; // Common objects
    87     if(!defined('ENANO_TEMPLATE_LOADED'))
   194     if(!defined('ENANO_TEMPLATE_LOADED'))
    88     {
   195     {
   118     if ( !file_exists(ENANO_ROOT . '/themes/' . $this->theme . '/' . $path) )
   225     if ( !file_exists(ENANO_ROOT . '/themes/' . $this->theme . '/' . $path) )
   119     {
   226     {
   120       echo "/* WARNING: Falling back to default file because file $path does not exist */\n";
   227       echo "/* WARNING: Falling back to default file because file $path does not exist */\n";
   121       $path = 'css/' . $this->style_list[0] . '.css';
   228       $path = 'css/' . $this->style_list[0] . '.css';
   122     }
   229     }
   123     return $this->process_template($path);
   230     return '<enano:no-opt>' . $this->process_template($path) . '</enano:no-opt>';
   124   }
   231   }
   125   function load_theme($name = false, $css = false)
   232   function load_theme($name = false, $css = false)
   126   {
   233   {
   127     global $db, $session, $paths, $template, $plugins; // Common objects
   234     global $db, $session, $paths, $template, $plugins; // Common objects
   128     $this->theme = ( $name ) ? $name : $session->theme;
   235     $this->theme = ( $name ) ? $name : $session->theme;
   130     if ( !$this->theme )
   237     if ( !$this->theme )
   131     {
   238     {
   132       $this->theme = $this->theme_list[0]['theme_id'];
   239       $this->theme = $this->theme_list[0]['theme_id'];
   133       $this->style = preg_replace('/\.css$/', '', $this->theme_list[0]['default_style']);
   240       $this->style = preg_replace('/\.css$/', '', $this->theme_list[0]['default_style']);
   134     }
   241     }
       
   242     // Make sure we're allowed to use this theme.
       
   243     if ( (
       
   244         // If it was removed, it's probably blocked by an ACL, or it was uninstalled
       
   245         !isset($this->named_theme_list[$this->theme]) ||
       
   246         // Check if the theme is disabled
       
   247         ( isset($this->named_theme_list[$this->theme]) && $this->named_theme_list[$this->theme]['enabled'] == 0 ) )
       
   248         // Above all, if it's a system theme, don't inhibit the loading process.
       
   249         && !in_array($this->theme, $this->system_themes)
       
   250       )
       
   251     {
       
   252       // No, something is preventing it - fall back to site default
       
   253       $this->theme = $this->default_theme;
       
   254       
       
   255       // Come up with the default style. If the CSS file specified in default_style exists, we're good, just
       
   256       // use that. Otherwise, use the first stylesheet that comes to mind.
       
   257       $df_data =& $this->named_theme_list[ $this->theme ];
       
   258       $this->style = ( in_array($df_data['default_style'], $df_data['css']) ) ? $df_data['default_style'] : $df_data['css'][0];
       
   259     }
       
   260     // The list of styles for the currently selected theme
       
   261     $this->style_list =& $this->named_theme_list[ $this->theme ]['css'];
   135     $this->theme_loaded = true;
   262     $this->theme_loaded = true;
   136   }
   263   }
   137   
   264   
   138   function init_vars()
   265   function init_vars()
   139   {
   266   {