home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / CMS / xoops-2.0.18.1.exe / xoops-2.0.18.1 / htdocs / class / theme.php < prev    next >
Encoding:
PHP Script  |  2007-10-19  |  18.2 KB  |  564 lines

  1. <?php
  2. /**
  3. * xos_opal_Theme component class file
  4. *
  5. * @copyright    The Xoops project http://www.xoops.org/
  6. * @license      http://www.fsf.org/copyleft/gpl.html GNU public license
  7. * @author       Skalpa Keo <skalpa@xoops.org>
  8. * @since        2.3.0
  9. * @version        $Id: theme.php 1100 2007-10-19 01:36:05Z dugris $
  10. * @package         xos_opal
  11. * @subpackage     xos_opal_Theme
  12. */
  13.  
  14. /**
  15. * xos_opal_ThemeFactory
  16. *
  17. * @author         Skalpa Keo
  18. * @package        xos_opal
  19. * @subpackage    xos_opal_Theme
  20. * @since        2.3.0
  21. */
  22. class xos_opal_ThemeFactory {
  23.  
  24.     var $xoBundleIdentifier = 'xos_opal_ThemeFactory';
  25.     /**
  26.      * Currently enabled themes (if empty, all the themes in themes/ are allowed)
  27.      * @var array
  28.      */
  29.     var $allowedThemes = array();
  30.     /**
  31.      * Default theme to instanciate if none specified
  32.      * @var string
  33.      */
  34.     var $defaultTheme = 'default';
  35.     /**
  36.      * If users are allowed to choose a custom theme
  37.      * @var bool
  38.      */
  39.     var $allowUserSelection = true;
  40.  
  41.     /**
  42.      * Instanciate the specified theme
  43.      */
  44.     function &createInstance( $options = array(), $initArgs = array() ) {
  45.         // Grab the theme folder from request vars if present
  46.         if ( @empty( $options['folderName'] ) ) {
  47.             if ( ( $req = @$_REQUEST['xoops_theme_select'] ) && $this->isThemeAllowed( $req ) ) {
  48.                 $options['folderName'] = $req;
  49.                 if ( isset( $_SESSION ) && $this->allowUserSelection ) {
  50.                     $_SESSION[ $this->xoBundleIdentifier ]['defaultTheme'] = $req;
  51.                 }
  52.             } elseif ( isset( $_SESSION[ $this->xoBundleIdentifier ]['defaultTheme'] ) ) {
  53.                 $options['folderName'] = $_SESSION[ $this->xoBundleIdentifier ]['defaultTheme'];
  54.             } elseif ( @empty( $options['folderName'] ) || !$this->isThemeAllowed( $options['folderName'] ) ) {
  55.                 $options['folderName'] = $this->defaultTheme;
  56.             }
  57.             $GLOBALS['xoopsConfig']['theme_set'] = $options['folderName'];
  58.         }
  59.         $options['path'] = XOOPS_THEME_PATH . '/' . $options['folderName'];
  60.         $inst =& new xos_opal_Theme();
  61.         foreach ( $options as $k => $v ) $inst->$k = $v;
  62.         $inst->xoInit();
  63.         return $inst;
  64.     }
  65.  
  66.     /**
  67.      * Checks if the specified theme is enabled or not
  68.      * @param string $name
  69.      * @return bool
  70.      */
  71.     function isThemeAllowed( $name ) {
  72.         return ( empty( $this->allowedThemes ) || in_array( $name, $this->allowedThemes ) );
  73.     }
  74.  
  75. }
  76.  
  77. class xos_opal_Theme {
  78.    /**
  79.     * The name of this theme
  80.     * @var string
  81.     */
  82.     var $folderName = '';
  83.    /**
  84.     * Physical path of this theme folder
  85.     * @var string
  86.     */
  87.     var $path = '';
  88.     var $url = '';
  89.  
  90.    /**
  91.     * Whether or not the theme engine should include the output generated by php
  92.     * @var string
  93.     */
  94.     var $bufferOutput = true;
  95.     /**
  96.     * Canvas-level template to use
  97.     * @var string
  98.     */
  99.     var $canvasTemplate = 'theme.html';
  100.     /**
  101.     * Content-level template to use
  102.     * @var string
  103.     */
  104.     var $contentTemplate = '';
  105.  
  106.     var $contentCacheLifetime = 0;
  107.     var $contentCacheId = null;
  108.  
  109.     /**
  110.     * Text content to display right after the contentTemplate output
  111.     * @var string
  112.     */
  113.     var $content = '';
  114.     /**
  115.     * Page construction plug-ins to use
  116.     * @var array
  117.     * @access public
  118.     */
  119.     var $plugins = array( 'xos_logos_PageBuilder' );
  120.  
  121.     var $renderCount = 0;
  122.     /**
  123.      * Pointer to the theme template engine
  124.      * @var XoopsTpl
  125.      */
  126.     var $template = false;
  127.  
  128.     /**
  129.      * Array containing the document meta-information
  130.      * @var array
  131.      */
  132.     var $metas = array(
  133.         'http' => array(
  134.             'Content-Script-Type' => 'text/javascript',
  135.             'Content-Style-Type' => 'text/css',
  136.         ),
  137.         'meta' => array(),
  138.         'link' => array(),
  139.         'script' => array(),
  140.     );
  141.  
  142.     /**
  143.      * Array of strings to be inserted in the head tag of HTML documents
  144.      * @var array
  145.      */
  146.     var $htmlHeadStrings = array();
  147.     /**
  148.      * Custom variables that will always be assigned to the template
  149.      * @var array
  150.      */
  151.     var $templateVars = array();
  152.  
  153.     /**
  154.      * User extra information for cache id, like language, user groups
  155.      *
  156.      * @var boolean
  157.      */
  158.     var $use_extra_cache_id = true;
  159.  
  160.    /**#@-*/
  161.  
  162.     /**#@+ @tasktype 10 Initialization*/
  163.     /**
  164.      * Initializes this theme
  165.      *
  166.      * Upon initialization, the theme creates its template engine and instanciates the
  167.      * plug-ins from the specified {@link $plugins} list. If the theme is a 2.0 theme, that does not
  168.      * display redirection messages, the HTTP redirections system is disabled to ensure users will
  169.      * see the redirection screen.
  170.      *
  171.      * @param array $options
  172.      * @return bool
  173.      */
  174.    function xoInit( $options = array() ) {
  175.         global $xoops;
  176.  
  177.         $this->path = XOOPS_THEME_PATH . '/' . $this->folderName;
  178.         $this->url = XOOPS_THEME_URL . '/' . $this->folderName;
  179.  
  180.         $this->template =& new XoopsTpl();
  181.         $this->template->currentTheme =& $this;
  182.         $this->template->assign_by_ref( 'xoTheme', $this );
  183.  
  184.         global $xoopsConfig, $xoopsModule, $xoopsUser;
  185.         $this->template->assign( array(
  186.             'xoops_theme' => $xoopsConfig['theme_set'],
  187.             'xoops_imageurl' => XOOPS_THEME_URL.'/'.$xoopsConfig['theme_set'].'/',
  188.             'xoops_themecss'=> xoops_getcss($xoopsConfig['theme_set']),
  189.             'xoops_requesturi' => htmlspecialchars( $_SERVER['REQUEST_URI'], ENT_QUOTES),
  190.             'xoops_sitename' => htmlspecialchars($xoopsConfig['sitename'], ENT_QUOTES),
  191.             'xoops_slogan' => htmlspecialchars($xoopsConfig['slogan'], ENT_QUOTES),
  192.             'xoops_dirname' => @$xoopsModule ? $xoopsModule->getVar( 'dirname' ) : 'system',
  193.             'xoops_banner' => $xoopsConfig['banners'] ? xoops_getbanner() : ' ',
  194.             'xoops_pagetitle' => isset($xoopsModule) && is_object($xoopsModule) ? $xoopsModule->getVar('name') : htmlspecialchars( $xoopsConfig['slogan'], ENT_QUOTES ),
  195.         ) );
  196.         if ( isset($xoopsUser) && is_object($xoopsUser) ) {
  197.             $this->template->assign( array(
  198.                 'xoops_isuser' => true,
  199.                 'xoops_userid' => $xoopsUser->getVar('uid'),
  200.                 'xoops_uname' => $xoopsUser->getVar('uname'),
  201.                 'xoops_isadmin' => $GLOBALS['xoopsUserIsAdmin'],
  202.             ) );
  203.         } else {
  204.             $this->template->assign( array( 'xoops_isuser' => false, 'xoops_isadmin' => false ) );
  205.         }
  206.         // Meta tags
  207.         $config_handler =& xoops_gethandler('config');
  208.         $criteria = new CriteriaCompo(new Criteria('conf_modid', 0));
  209.         $criteria->add(new Criteria('conf_catid', XOOPS_CONF_METAFOOTER));
  210.         $config = $config_handler->getConfigs($criteria, true);
  211.         foreach ( array_keys($config) as $i ) {
  212.             $name = $config[$i]->getVar( 'conf_name', 'n' );
  213.             $value = $config[$i]->getVar( 'conf_value', 'n' );
  214.             if ( substr( $name, 0, 5 ) == 'meta_' ) {
  215.                 $this->addMeta( 'meta', substr( $name, 5 ), $value );
  216.             } else {
  217.                 // prefix each tag with 'xoops_'
  218.                 $this->template->assign( "xoops_$name", $value );
  219.             }
  220.         }
  221.  
  222.         if ( $this->bufferOutput ) {
  223.             ob_start();
  224.         }
  225.         $GLOBALS['xoTheme'] =& $this;
  226.         $GLOBALS['xoopsTpl'] =& $this->template;
  227.         // Instanciate and initialize all the theme plugins
  228.         foreach ( $this->plugins as $k => $bundleId ) {
  229.             if ( !is_object( $bundleId ) ) {
  230.                 $this->plugins[$bundleId] =& new $bundleId();
  231.                 $this->plugins[$bundleId]->theme =& $this;
  232.                 $this->plugins[$bundleId]->xoInit();
  233.                 unset( $this->plugins[$k] );
  234.             }
  235.         }
  236.         return true;
  237.     }
  238.     /**#@-*/
  239.  
  240.     /**
  241.      * Generate cache id based on extra information of language and user groups
  242.      *
  243.      * User groups other than anonymous should be detected to avoid disclosing group sensitive contents
  244.      *
  245.      * @param string    $cache_id        raw cache id
  246.      * @param string    $extraString    extra string
  247.      *
  248.      * @return string    complete cache id
  249.      */
  250.     function generateCacheId($cache_id, $extraString = '') {
  251.         static $extra_string;
  252.  
  253.         if (!$this->use_extra_cache_id) {
  254.             return $cache_id;
  255.         }
  256.  
  257.         if (empty($extraString)) {
  258.             if (empty($extra_string)) {
  259.                 global $xoopsUser, $xoopsConfig;
  260.  
  261.                 // Generate language section
  262.                 $extra_string = $xoopsConfig['language'];
  263.  
  264.                 // Generate group section
  265.                 if ( !@is_object( $xoopsUser ) ) {
  266.                     $extra_string .= '|' . XOOPS_GROUP_ANONYMOUS;
  267.                 } else {
  268.                     $groups = $xoopsUser->getGroups();
  269.                     sort($groups);
  270.                     // Generate group string for non-anonymous groups,
  271.                     // XOOPS_DB_PASS and XOOPS_DB_NAME (before we find better variables) are used to protect group sensitive contents
  272.                     $extra_string .= '|' . implode(",", $groups).substr( md5(XOOPS_DB_PASS.XOOPS_DB_NAME), 0, strlen(XOOPS_DB_USER) * 2 );
  273.                 }
  274.             }
  275.             $extraString = $extra_string;
  276.         }
  277.         $cache_id .= '|' . $extraString;
  278.  
  279.         return $cache_id;
  280.     }
  281.  
  282.     function checkCache() {
  283.         global $xoopsModule, $xoopsLogger;
  284.  
  285.         if ( $_SERVER['REQUEST_METHOD'] != 'POST' && $this->contentCacheLifetime ) {
  286.             $template = $this->contentTemplate ? $this->contentTemplate : 'db:system_dummy.html';
  287.             $dirname = $xoopsModule->getVar( 'dirname', 'n' );
  288.  
  289.             $this->template->caching = 2;
  290.             $this->template->cache_lifetime = $this->contentCacheLifetime;
  291.             $uri = str_replace( XOOPS_URL, '', $_SERVER['REQUEST_URI'] );
  292.             // Clean uri by removing session id
  293.             if (defined('SID') && SID && strpos($uri, SID)) {
  294.                 $uri = preg_replace("/([\?&])(".SID."$|".SID."&)/", "\\1", $uri);
  295.             }
  296.             $this->contentCacheId = $this->generateCacheId($dirname . '|' . $uri);
  297.  
  298.             if ( $this->template->is_cached( $template, $this->contentCacheId ) ) {
  299.                 $xoopsLogger->addExtra( $template,    sprintf('Cached (regenerates every %d seconds)', $this->contentCacheLifetime  ) );
  300.                 $this->render( null, null, $template );
  301.                 return true;
  302.             }
  303.         }
  304.         return false;
  305.     }
  306.  
  307.     /**
  308.      * Render the page
  309.      *
  310.      * The theme engine builds pages from 2 templates: canvas and content.
  311.      *
  312.      * A module can call this method directly and specify what templates the theme engine must use.
  313.      * If render() hasn't been called before, the theme defaults will be used for the canvas and
  314.      * page template (and xoopsOption['template_main'] for the content).
  315.      *
  316.      * @param string $canvasTpl        The canvas template, if different from the theme default
  317.      * @param string $pageTpl        The page template, if different from the theme default (unsupported, 2.3+ only)
  318.      * @param string $contentTpl    The content template
  319.      * @param array     $vars            Template variables to send to the template engine
  320.      */
  321.     function render( $canvasTpl = null, $pageTpl = null, $contentTpl = null, $vars = array() ) {
  322.         global $xoops, $xoopsLogger, $xoopsOption;
  323.  
  324.         if ( $this->renderCount ) {
  325.             return false;
  326.         }
  327.         $xoopsLogger->startTime( 'Page rendering' );
  328.  
  329.         // @internal: Lame fix to ensure the metas specified in the xoops config page don't appear twice
  330.         $old = array( 'robots', 'keywords', 'description', 'rating', 'author', 'copyright' );
  331.         foreach ( $this->metas['meta'] as $name => $value ) {
  332.             if ( in_array( $name, $old ) ) {
  333.                 $this->template->assign( "xoops_meta_$name", htmlspecialchars( $value, ENT_QUOTES ) );
  334.                 unset( $this->metas['meta'][$name] );
  335.             }
  336.         }
  337.  
  338.         if ( $canvasTpl )        $this->canvasTemplate    = $canvasTpl;
  339.         if ( $contentTpl )        $this->contentTemplate    = $contentTpl;
  340.  
  341.         if ( !empty( $vars ) ) {
  342.             $this->template->assign( $vars );
  343.         }
  344.         if ( $this->contentTemplate ) {
  345.             $this->content = $this->template->fetch( $this->contentTemplate, $this->contentCacheId );
  346.         }
  347.         if ( $this->bufferOutput ) {
  348.             $this->content .= ob_get_contents();
  349.             ob_end_clean();
  350.         }
  351.         $this->template->assign_by_ref( 'xoops_contents', $this->content );
  352.  
  353.         $header = empty($xoopsOption['xoops_module_header']) ? $this->template->get_template_vars( 'xoops_module_header' ) : $xoopsOption['xoops_module_header'];
  354.         $this->template->assign( 'xoops_module_header', $header . "\n" . $this->renderMetas( null, true ) );
  355.  
  356.         if ( !empty($xoopsOption['xoops_pagetitle']) ) {
  357.             $this->template->assign( 'xoops_pagetitle', $xoopsOption['xoops_pagetitle'] );
  358.         }
  359.  
  360.         // Do not cache the main (theme.html) template output
  361.         $this->template->caching = 0;
  362.         $this->template->display( $this->path . '/' . $this->canvasTemplate );
  363.  
  364.         $this->renderCount++;
  365.         $xoopsLogger->stopTime( 'Page rendering' );
  366.     }
  367.  
  368.     /**#@+ @tasktype 20 Manipulating page meta-information*/
  369.     /**
  370.     * Adds script code to the document head
  371.     *
  372.     * This methods allows the insertion of an external script file (if $src is provided), or
  373.     * of a script snippet. The file URI is parsed to take benefit of the theme resource
  374.     * overloading system.
  375.     *
  376.     * The $attributes parameter allows you to specify the attributes that will be added to the
  377.     * inserted <script> tag. If unspecified, the <var>type</var> attribute value will default to
  378.     * 'text/javascript'.
  379.     *
  380.     * <code>
  381.     * // Add an external script using a physical path
  382.     * $theme->addScript( 'www/script.js', null, '' );
  383.     * $theme->addScript( 'modules/newbb/script.js', null, '' );
  384.     * // Specify attributes for the <script> tag
  385.     * $theme->addScript( 'mod_xoops_SiteManager#common.js', array( 'type' => 'application/x-javascript' ), '' );
  386.     * // Insert a code snippet
  387.     * $theme->addScript( null, array( 'type' => 'application/x-javascript' ), 'window.open("Hello world");' );
  388.     * </code>
  389.     *
  390.     * @param string $src path to an external script file
  391.     * @param array $attributes hash of attributes to add to the <script> tag
  392.     * @param string $content Code snippet to output within the <script> tag
  393.     *
  394.     * @return void
  395.     **/
  396.     function addScript( $src = '', $attributes = array(), $content = '' ) {
  397.         global $xoops;
  398.         if ( empty( $attributes ) )             $attributes = array();
  399.         if ( !empty( $src ) )                     $attributes['src'] = $xoops->url( $this->resourcePath( $src ) );
  400.         if ( !empty( $content ) )                $attributes['_'] = $content;
  401.         if ( !isset( $attributes['type'] ) )     $attributes['type'] = 'text/javascript';
  402.         $this->addMeta( 'script', $src, $attributes );
  403.     }
  404.     /**
  405.      * Add StyleSheet or CSS code to the document head
  406.      * @param string $src path to .css file
  407.      * @param array $attributes name => value paired array of attributes such as title
  408.      * @param string $content CSS code to output between the <style> tags (in case $src is empty)
  409.      *
  410.      * @return void
  411.      **/
  412.     function addStylesheet( $src = '', $attributes = array(), $content = '' ) {
  413.         global $xoops;
  414.         if ( empty( $attributes ) )             $attributes = array();
  415.         if ( !empty( $src ) )                     $attributes['href'] = $xoops->url( $this->resourcePath( $src ) );
  416.         if ( !isset($attributes['type']) )         $attributes['type'] = 'text/css';
  417.         if ( !empty( $content ) )                 $attributes['_'] = $content;
  418.         $this->addMeta( 'stylesheet', $src, $attributes );
  419.     }
  420.     /**
  421.       * Add a <link> to the header
  422.       * @param string    $rel        Relationship from the current doc to the anchored one
  423.       * @param string    $href        URI of the anchored document
  424.       * @param array        $attributes    Additional attributes to add to the <link> element
  425.       */
  426.     function addLink( $rel, $href = '', $attributes = array() ) {
  427.         global $xoops;
  428.         if ( empty( $attributes ) )             $attributes = array();
  429.         if ( !empty( $href ) )                     $attributes['href'] = $href;
  430.         $this->addMeta( 'link', $rel, $attributes );
  431.     }
  432.     /**
  433.      * Set a meta http-equiv value
  434.      */
  435.     function addHttpMeta( $name, $value = null ) {
  436.         if ( isset($value) ) {
  437.             return $this->addMeta( 'http', $name, $value );
  438.         }
  439.         unset( $this->metas['http'][$name] );
  440.     }
  441.     /**
  442.      * Change output page meta-information
  443.      */
  444.     function addMeta( $type = 'meta', $name = '', $value = '' ) {
  445.         if ( !isset( $this->metas[$type] ) ) {
  446.             $this->metas[$type] = array();
  447.         }
  448.         if ( isset($name) ) {
  449.             $this->metas[$type][$name] = $value;
  450.         } else {
  451.             $this->metas[$type][] =     $value;
  452.         }
  453.         return $value;
  454.     }
  455.  
  456.     function headContent( $params, $content, &$smarty, &$repeat ) {
  457.         if ( !$repeat ) {
  458.             $this->htmlHeadStrings[] = $content;
  459.         }
  460.     }
  461.  
  462.     function renderMetas( $type = null, $return = false ) {
  463.         $str = '';
  464.         if ( !isset($type) ) {
  465.             foreach ( array_keys($this->metas) as $type ) {
  466.                 $str .= $this->renderMetas( $type, true );
  467.             }
  468.             $str .= implode( "\n", $this->htmlHeadStrings );
  469.         } else {
  470.             switch ( $type ) {
  471.             case 'script':
  472.                 foreach ( $this->metas[$type] as $attrs ) {
  473.                     $str .= '<script' . $this->renderAttributes( $attrs ) . ">\n";
  474.                     if ( @$attrs['_'] ) {
  475.                         $str .= "\n//<![CDATA[\n" . $attrs['_'] . "\n//]]>";
  476.                     }
  477.                     $str .= "</script>\n";
  478.                 }
  479.                 break;
  480.             case 'link':
  481.                 foreach ( $this->metas[$type] as $rel => $attrs ) {
  482.                     $str .= '<link rel="' . $rel . '"' . $this->renderAttributes( $attrs ) . " />\n";
  483.                 }
  484.                 break;
  485.             case 'stylesheet':
  486.                 foreach ( $this->metas[$type] as $attrs ) {
  487.                     if ( @$attrs['_'] ) {
  488.                         $str .= '<style' . $this->renderAttributes($attrs) . ">\n/* <![CDATA[ */\n" . $attrs['_'] . "\n/* //]]> */\n</style>";
  489.                     } else {
  490.                         $str .= '<link rel="stylesheet"' . $this->renderAttributes($attrs) . " />\n";
  491.                     }
  492.                 }
  493.                 break;
  494.             case 'http':
  495.                 foreach ( $this->metas[$type] as $name => $content ) {
  496.                     $str .= '<meta http-equiv="' . htmlspecialchars( $name, ENT_QUOTES ) . '" content="' . htmlspecialchars( $content, ENT_QUOTES) . "\" />\n";
  497.                 }
  498.                 break;
  499.             default:
  500.                 foreach ( $this->metas[$type] as $name => $content ) {
  501.                     $str .= '<meta name="' . htmlspecialchars( $name, ENT_QUOTES ) . '" content="' . htmlspecialchars( $content, ENT_QUOTES) . "\" />\n";
  502.                 }
  503.                 break;
  504.             }
  505.         }
  506.         if ( $return ) {
  507.             return $str;
  508.         }
  509.         echo $str;
  510.         return true;
  511.     }
  512.  
  513.     /**
  514.      * Generates a unique element ID
  515.      * @param string $tagName
  516.      * @return string
  517.      */
  518.     function genElementId( $tagName = 'xos' ) {
  519.         static $cache = array();
  520.         if ( !isset( $cache[ $tagName ] ) ) {
  521.             $cache[$tagName] = 1;
  522.         }
  523.         return $tagName . '-' . $cache[$tagName]++;
  524.     }
  525.  
  526.     /**
  527.      * Transform an attributes collection to an XML string
  528.      * @param array $coll
  529.      * @return string
  530.      */
  531.     function renderAttributes( $coll ) {
  532.         $str = '';
  533.         foreach ( $coll as $name => $val ) {
  534.             if ( $name != '_' ) {
  535.                 $str .= ' ' . $name . '="' . htmlspecialchars( $val, ENT_QUOTES ) . '"';
  536.             }
  537.         }
  538.         return $str;
  539.     }
  540.  
  541.     /**
  542.      * Return a themable file resource path
  543.      *
  544.      * @param string $path
  545.      * @return string
  546.      */
  547.     function resourcePath( $path ) {
  548.         global $xoops;
  549.         if ( substr( $path, 0, 1 ) == '/' ) {
  550.             $path = substr( $path, 1 );
  551.         }
  552.         if ( file_exists( "$this->path/$path" ) ) {
  553.             return "themes/$this->folderName/$path";
  554.         }
  555.         return $path;
  556.     }
  557.  
  558.  
  559.  
  560.  
  561. }
  562.  
  563.  
  564. ?>