themes
[ class tree: themes ] [ index: themes ] [ all elements ]

Source for file BitThemes.php

Documentation is available at BitThemes.php

  1. <?php
  2. /**
  3.  * @package themes
  4.  */
  5.  
  6. /**
  7.  * Set-up
  8.  */
  9. require_onceKERNEL_PKG_PATH.'BitCache.php' );
  10. /**
  11.  * BitThemes
  12.  *
  13.  * @package themes
  14.  * @uses BitBase
  15.  */
  16. class BitThemes extends BitSingleton {
  17.     // Array that contains a full description of the current layout
  18.     var $mLayout = array();
  19.  
  20.     // contains the currently active style
  21.     var $mStyle;
  22.  
  23.     // an array with style information
  24.     var $mStyles = array();
  25.  
  26.     // Ajax libraries needed by current Ajax framework (MochiKit libs, etc.)
  27.     var $mAjaxLibs = array();
  28.  
  29.     // Auxiliary Javascript and Css Files
  30.     var $mAuxFiles = array(
  31.         'js'  => array(),
  32.         'css' => array()
  33.     );
  34.  
  35.     // Raw Javascript and Css Files
  36.     var $mRawFiles = array(
  37.         'js'  => array(),
  38.         'css' => array()
  39.     );
  40.  
  41.     // Display Mode
  42.     var $mDisplayMode;
  43.  
  44.     // When all modules are loaded they are loaded here
  45.     var $mModules = array();
  46.  
  47.  
  48.     /**
  49.      * Initiate class
  50.      *
  51.      * @return void 
  52.      */
  53.     function __construct({
  54.         parent::__construct();
  55.  
  56.         // start up caching engine
  57.         $this->mThemeCache new BitCache'themes'TRUE );
  58.     }
  59.  
  60.     public static function isCacheableClass({
  61.         return false;
  62.     }
  63.  
  64.     // {{{ =================== Styles ====================
  65.     /**
  66.      * load up style related information that must be
  67.      * loaded before template rendering begins
  68.      *
  69.      * @note this is a interim method as we continue sorting
  70.      *  out the optimal order of operations for rendering
  71.      *  pages. there was some conflict between rendering
  72.      *  module templates and loading styles, where some
  73.      *  style information needs to be loaded before the templates
  74.      *  are rendered, and some such as packing javascript and css
  75.      *  should happen after
  76.      *
  77.      * @see BitSystem::preDisplay
  78.      */
  79.     function preLoadStyle(){
  80.         // define style url and path
  81.         if!defined'THEMES_STYLE_URL' ) ) {
  82.             define'THEMES_STYLE_URL'$this->getStyleUrl() );
  83.         }
  84.         if!defined'THEMES_STYLE_PATH' ) ) {
  85.             define'THEMES_STYLE_PATH'$this->getStylePath() );
  86.         }
  87.     }
  88.  
  89.  
  90.     /*
  91.      * load up all style related information
  92.      * populates mStyle and mStyles
  93.      *
  94.      * @access public
  95.      * @return void
  96.      */
  97.     function loadStyle({
  98.         global $gBitSystem;
  99.         // load default css files
  100.         ifempty$this->mStyles['styleSheet')) {
  101.             $this->mStyles['styleSheet'$this->getStyleCssFileNULLTRUE );
  102.         }
  103.  
  104.         // load tpl files that need to be included
  105.         $this->loadTplFiles"html_head_inc" );
  106.         $this->loadTplFiles"footer_inc" );
  107.  
  108.         // join javascript files that have been loaded
  109.         $this->mStyles['joined_javascript'$this->joinAuxFiles'js' );
  110.  
  111.         // layout is called as the viry first, package css is around pos 300 and theme / browser are called last
  112.         // css inserted in <pkg>/html_head_inc.tpl is called before these files since these are inserted last
  113. //        $this->loadCss( $this->getLayoutCssFile(),       TRUE, 1,    TRUE, TRUE );
  114.         $this->loadCss$this->getStyleCssFile(),        TRUE998,    TRUETRUE );
  115.         $this->loadCss$this->getBrowserStyleCssFile()TRUE999,    TRUETRUE );
  116.         // check for customized CSS file
  117.         iffile_existsCONFIG_PKG_PATH.'css/config.css' ) ) {
  118.             $this->loadCssCONFIG_PKG_PATH.'css/config.css' );
  119.         }
  120.         $this->mStyles['joined_css'$this->joinAuxFiles'css' );
  121.     }
  122.  
  123.     /**
  124.      * figure out the current style
  125.      *
  126.      * @param string pScanFile file to be looked for
  127.      * @return none 
  128.      * @access public
  129.      */
  130.     function getStyle({
  131.         global $gBitSystem;
  132.         ifempty$this->mStyle )) {
  133.             $this->mStyle = $gBitSystem->getConfig'style' );
  134.         }
  135.         return $this->mStyle;
  136.     }
  137.  
  138.     /**
  139.      * figure out the current style
  140.      *
  141.      * @param string pScanFile file to be looked for
  142.      * @return none 
  143.      * @access public
  144.      */
  145.     function setStyle$pStyle {
  146.         global $gBitSmarty;
  147.         $this->mStyle = $pStyle;
  148.         $gBitSmarty->verifyCompileDir();
  149.     }
  150.  
  151.     /**
  152.      * figure out the current style
  153.      *
  154.      * @param string pScanFile file to be looked for
  155.      * @return none 
  156.      * @access public
  157.      */
  158.     function getStyleCssFile$pStyle NULL$pUrl FALSE {
  159.         global $gBitSystem;
  160.         ifempty$pStyle )) {
  161.             $pStyle $this->getStyle();
  162.         }
  163.         $ret '';
  164.  
  165.         if$pUrl {
  166.             $base $this->getStyleUrl();
  167.         else {
  168.             $base $this->getStylePath();
  169.         }
  170.  
  171.         if$gBitSystem->getConfig'style_variation' && is_readable$this->getStylePath().'alternate/'.$gBitSystem->getConfig'style_variation' ).'.css' )) {
  172.             $ret $base.'alternate/'.$gBitSystem->getConfig'style_variation' ).'.css';
  173.         elseifis_readable$this->getStylePath().$pStyle.'.css' )) {
  174.             $ret $base.$pStyle.'.css';
  175.         }
  176.         return $ret;
  177.     }
  178.  
  179.     /**
  180.      * get browser specific css file
  181.      *
  182.      * @param none 
  183.      * @return path to browser specific css file
  184.      * @access public
  185.      */
  186.     function getBrowserStyleCssFile$pUrl FALSE {
  187.         global $gSniffer;
  188.  
  189.         if$pUrl {
  190.             $base $this->getStyleUrl();
  191.         else {
  192.             $base $this->getStylePath();
  193.         }
  194.         $subpath $this->getStyle().'_'.$gSniffer->property'browser' );
  195.  
  196.         // Allow us to split by major version with a fallback for others
  197.         iffile_exists$this->getStylePath().$subpath.$gSniffer->property'maj_ver' ).'.css' )) {
  198.             $ret $base.$subpath.$gSniffer->property'maj_ver' ).'.css';
  199.         elseiffile_exists$this->getStylePath().$subpath.'.css' )) {
  200.             $ret $base.$subpath.'.css';
  201.         }
  202.         return !empty$ret $ret NULL;
  203.     }
  204.  
  205.     /**
  206.      * get browser specific css file
  207.      *
  208.      * @param none 
  209.      * @return path to browser specific css file
  210.      * @access public
  211.      */
  212.     function getLayoutCssFile({
  213.         global $gBitSystem;
  214.         if$gBitSystem->isFeatureActive'site_style_layout' )) {
  215.             $ret realpathTHEMES_PKG_PATH."layouts/".$gBitSystem->getConfig'site_style_layout' ).".css" );
  216.         }
  217.         return !empty$ret $ret NULL;
  218.     }
  219.  
  220.     /**
  221.      * figure out the current style URL
  222.      *
  223.      * @param string pScanFile file to be looked for
  224.      * @return none 
  225.      * @access public
  226.      */
  227.     function getStyleUrl$pStyle NULL {
  228.         ifempty$pStyle )) {
  229.             $pStyle $this->getStyle();
  230.         }
  231.         return CONFIG_PKG_URL.'themes/'.$pStyle.'/';
  232.     }
  233.  
  234.     /**
  235.      * figure out the current style URL
  236.      *
  237.      * @param string pScanFile file to be looked for
  238.      * @return none 
  239.      * @access public
  240.      */
  241.     function getStylePath$pStyle NULL {
  242.         ifempty$pStyle )) {
  243.             $pStyle $this->getStyle();
  244.         }
  245.         return CONFIG_PKG_PATH.'themes/'.$pStyle.'/';
  246.     }
  247.  
  248.     /**
  249.      * getStyles
  250.      *
  251.      * @param array $pDir 
  252.      * @param array $pNullOption 
  253.      * @param array $bIncludeCustom 
  254.      * @access public
  255.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  256.      */
  257.     function getStyles$pDir NULL$pNullOption NULL$bIncludeCustom FALSE {
  258.         global $gBitSystem$gBitUser;
  259.  
  260.         ifempty$pDir )) {
  261.             $pDir CONFIG_PKG_PATH.'themes/';
  262.         }
  263.         $ret array();
  264.  
  265.         if!empty$pNullOption )) {
  266.             $ret['';
  267.         }
  268.  
  269.         ifis_dir$pDir )) {
  270.             $h opendir$pDir );
  271.             while$file readdir$h )) {
  272.                 if is_dir$pDir."$file&& $file != '.' && $file != '..' && $file != 'CVS' && $file != 'slideshows' && $file != 'blank' )) {
  273.                     $ret[$file;
  274.                 }
  275.             }
  276.             closedir$h );
  277.         }
  278.  
  279.         if$bIncludeCustom && $gBitSystem->getConfig'themes_edit_css' )) {
  280.             // Include the users custom css if they have created one
  281.             $customCSSPath $gBitUser->getStoragePathNULL,$gBitUser->mUserId );
  282.             $customCSSFile $customCSSPath.'custom.css';
  283.  
  284.             if (file_exists($customCSSFile)) {
  285.                 $ret['custom';
  286.             }
  287.         }
  288.  
  289.         ifcount$ret )) {
  290.             sort$ret );
  291.         }
  292.  
  293.         return $ret;
  294.     }
  295.  
  296.     /**
  297.      * getStyleLayouts
  298.      *
  299.      * @access public
  300.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  301.      */
  302.     function getStyleLayouts({
  303.         $ret array();
  304.  
  305.         ifis_dirTHEMES_PKG_PATH.'layouts/' )) {
  306.             $h opendirTHEMES_PKG_PATH.'layouts/' );
  307.             // collect all layouts
  308.             whileFALSE !== $file readdir$h ))) {
  309.                 if !preg_match"/^\./"$file )) {
  310.                     $ret[substr$file0strrpos$file'.' )))][substr$filestrrpos$file'.' ))$file;
  311.                 }
  312.             }
  313.             closedir$h );
  314.  
  315.             // weed out any files that don't have a css file associated with them
  316.             foreach$ret as $key => $layout {
  317.                 ifempty$layout['css')) {
  318.                     unset$ret[$key);
  319.                 }
  320.             }
  321.  
  322.             ksort$ret );
  323.         }
  324.         return $ret;
  325.     }
  326.  
  327.     /**
  328.     * @param $pSubDirs a subdirectory to scan as well - you can pass in multiple dirs using an array
  329.      *
  330.      * @param array $pDir 
  331.      * @param array $pNullOption 
  332.      * @param array $pSubDirs 
  333.      * @access public
  334.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  335.      */
  336.     function getStylesList$pDir NULL$pNullOption NULL$pSubDirs NULL {
  337.         global $gBitSystem;
  338.  
  339.         $ret array();
  340.  
  341.         ifempty$pSubDirs )) {
  342.             $subDirs[array'' );
  343.         elseif!is_array$pSubDirs )) {
  344.             $subDirs[$pSubDirs;
  345.         else {
  346.             $subDirs $pSubDirs;
  347.         }
  348.  
  349.         ifempty$pDir )) {
  350.             $pDir CONFIG_PKG_PATH.'themes/';
  351.         }
  352.  
  353.         if!empty$pNullOption )) {
  354.             $ret['';
  355.         }
  356.  
  357.         // open directories
  358.         ifis_dir$pDir )) {
  359.             $h opendir$pDir );
  360.             // cycle through files / dirs
  361.             whileFALSE !== $file readdir$h ))) {
  362.                 if is_dir$pDir.$file && $file != '.' && $file != '..' && $file != 'CVS' && $file != 'slideshows' && $file != 'blank' )) {
  363.                     $ret[$file]['style'$file;
  364.                     // check if we want to have a look in any subdirs
  365.                     foreach$subDirs as $dir {
  366.                         ifis_dir$infoDir $pDir.$file.'/'.$dir.'/' )) {
  367.                             $dh opendir$infoDir );
  368.                             // cycle through files / dirs
  369.                             whileFALSE !== $f readdir$dh ))) {
  370.                                 ifis_readable$infoDir.$f && $f != '.' &&  $f != '..' &&  $f != 'CVS' )) {
  371.                                     $ret[$file][$dir][preg_replace"/\..*/"""$f )CONFIG_PKG_URL.basenamedirnamedirname$infoDir ))).'/'.$file.'/'.$dir.'/'.$f;
  372.  
  373.                                     ifpreg_match"/\.htm$/"$f )) {
  374.                                         $fh fopen$infoDir.$f"r" );
  375.                                         $ret[$file][$dir][preg_replace"/\.htm$/"""$f )fread$fhfilesize$infoDir.$f ));
  376.                                         fclose$fh );
  377.                                     }
  378.                                 }
  379.                             }
  380.                             // sort the returned items
  381.                             @ksort$ret[$file][$dir);
  382.                             closedir$dh );
  383.                         }
  384.                     }
  385.                 }
  386.             }
  387.             closedir$h );
  388.         }
  389.  
  390.         ifcount$ret )) {
  391.             ksort$ret );
  392.         }
  393.  
  394.         return $ret;
  395.     }
  396.  
  397.     /**
  398.      * get the icon cache path
  399.      *
  400.      * @access public
  401.      * @return absolute path on where the system should store it's icons
  402.      */
  403.     function getIconCachePath({
  404.         global $gSniffer$gBitSystem$gBitLanguage;
  405.  
  406.         // use bitweaver version as dir in case there has been changes since the last version
  407.         $version $gBitSystem->getBitVersionFALSE );
  408.  
  409.         // some browsers need special treatment due to different biticon feed.
  410.         if$gSniffer->_browser_info['browser'== 'ie' {
  411.             $browser $gSniffer->_browser_info['browser'].$gSniffer->_browser_info['maj_ver'];
  412.         else {
  413.             $browser 'default';
  414.         }
  415.  
  416.         $cachedir TEMP_PKG_PATH.'themes/biticon/'.$version.'/'.$gBitSystem->getConfig'site_icon_style'DEFAULT_ICON_STYLE ).'/'.$gBitLanguage->getLanguage().'/'.$browser.'/';
  417.         if!is_dir$cachedir )) {
  418.             mkdir_p$cachedir );
  419.         }
  420.         return $cachedir;
  421.     }
  422.  
  423.  
  424.     // }}}
  425.     // {{{ =================== Layout ====================
  426.     /**
  427.      * load current layout into mLayout
  428.      *
  429.      * @param  $pParamHash 
  430.      * @return none 
  431.      * @access public
  432.      */
  433.     function loadLayout$pParamHash NULL {
  434.         global $gBitSystem;
  435.         ifempty$this->mLayout || !count$this->mLayout )){
  436.             $this->mLayout = $this->getLayout$pParamHash );
  437.  
  438.             /**
  439.              * this needs to occur after loading the layout to ensure that we don't distrub the fallback process during layout loading
  440.              * we can disable clumns using various criteria:
  441.              *     <package>_hide_<area>_col
  442.              *     <display_mode>_hide_<area>_col
  443.              *     <package>_<display_mode>_hide_<area>_col
  444.              */
  445.             $areas array't' => 'top''l' => 'left''r' => 'right''b' => 'bottom' );
  446.             foreach$areas as $layout => $area {
  447.                 if(
  448.                     $gBitSystem->isFeatureActive"{$this->mDisplayMode}_hide_{$area}_col" ) ||
  449.                     $gBitSystem->isFeatureActive"{$gBitSystem->mActivePackage}_hide_{$area}_col" ) ||
  450.                     $gBitSystem->isFeatureActive"{$gBitSystem->mActivePackage}_{$this->mDisplayMode}_hide_{$area}_col" )
  451.                 ) {
  452.                     unset( $this->mLayout[$layout);
  453.                 }
  454.             }
  455.         }
  456.     }
  457.  
  458.     function hasColumnModules( $pColumn ) {
  459.         return count( $this->mLayout[$pColumn);
  460.     }
  461.  
  462.     function displayLayoutColumn( $pColumn ) {
  463.         if( $colHtml = $this->fetchLayoutColumn$pColumn ) ) {
  464.             print $colHtml;
  465.         }
  466.     }
  467.  
  468.     function fetchLayoutColumn( $pColumn ) {
  469.         global $gBitSmarty, $gBitSystem;
  470.         $ret = '';
  471.         if( !empty( $this->mLayout[$pColumn) ) {
  472.             for ($i = 0; $i < count( $this->mLayout[$pColumn)$i++{
  473.                 $r = &$this->mLayout[$pColumn][$i];
  474.                 if!empty$r['visible')) {
  475.                     try {
  476.                         // @TODO MODULE UPGRADE under new module organization this is not reliable as tpls are in sub dir in modules/ change this when upgrade is complete
  477.                         list( $package, $template ) = explode(  '/', $r['module_rsrc'] );
  478.                         // deal with custom modules
  479.                         if( $package == '_custom:custom' ) {
  480.                             global $gBitLanguage;
  481.  
  482.                             // We're gonna run our own cache mechanism for user_modules
  483.                             // the cache is here to avoid calls to consumming queries,
  484.                             // each module is different for each language because of the strings
  485.                             $cacheDir = TEMP_PKG_PATH.'modules/cache/';
  486.                             if( !is_dir( $cacheDir )) {
  487.                                 mkdir_p( $cacheDir );
  488.                             }
  489.                             $cachefile = $cacheDir.'_custom.'.$gBitLanguage->mLanguage.'.'.$template.'.tpl.cache';
  490.  
  491.                             if!empty$r["cache_time"&& file_exists$cachefile && !(( $gBitSystem->getUTCTime(filemtime$cachefile )) $r["cache_time")) {
  492.                                 $fp = fopen( $cachefile, "r" );
  493.                                 $data = fread( $fp, filesize( $cachefile ));
  494.                                 fclose( $fp );
  495.                                 $r["data"] = $data;
  496.                             } else {
  497.                                 if( $moduleParams = $this->getCustomModule$template )) {
  498.                                     $moduleParams = array_merge( $r, $moduleParams );
  499.                                     $gBitSmarty->assign_by_ref'moduleParams'$moduleParams );
  500.                                     $ret .= $gBitSmarty->fetch'bitpackage:themes/custom_module.tpl' );
  501.  
  502.                                     if!empty$r["cache_time") ) {
  503.                                         // write to chache file
  504.                                         $fp = fopen( $cachefile, "w+" );
  505.                                         fwrite( $fp, $data, strlen( $data ));
  506.                                         fclose( $fp );
  507.                                     }
  508.                                     $r["data"] = $data;
  509.                                 }
  510.                             }
  511.                             unset( $data );
  512.                         } else {
  513.                             $explosion = explode( '/', $r['module_rsrc'] );
  514.                             $template = array_pop( $explosion );
  515.  
  516.                             // using $module_rows, $module_params and $module_title is deprecated. please use $moduleParams hash instead
  517.                             global $module_rows, $module_params, $module_title, $gBitLanguage;
  518.  
  519.                             $cacheDir = TEMP_PKG_PATH.'modules/cache/';
  520.                             if( !is_dir( $cacheDir )) {
  521.                                 mkdir_p( $cacheDir );
  522.                             }
  523.  
  524.                             // include tpl name and module id to uniquely identify
  525.                             $cachefile = $cacheDir.'_module_'.$r['module_id'].'.'.$gBitLanguage->mLanguage.'.'.$template.'.cache';
  526.  
  527.                             // if the time is right get the cache else get it fresh
  528.                             if!empty$r["cache_time"&& file_exists$cachefile && filesize$cachefile && !(( $gBitSystem->getUTCTime(filemtime$cachefile )) $r["cache_time") ) {
  529.                                 $fp = fopen( $cachefile, "r" );
  530.                                 $data = fread( $fp, filesize( $cachefile ));
  531.                                 fclose( $fp );
  532.                                 $r["data"] = $data;
  533.                             } else {
  534.                                 $module_params = $r['module_params']; // backwards compatability
  535.                                 if( !$r['module_rows'] ) {
  536.                                     $r['module_rows'] = 10;
  537.                                 }
  538.  
  539.                                 // if there's no custom title, get one from file name
  540.                                 if( !$r['title'] = ( isset( $r['title'] ) ? tra( $r['title'] ) : NULL )) {
  541.                                     $pattern[0] = "/.*\/mod_(.*)\.tpl/";
  542.                                     $replace[0] = "$1";
  543.                                     $pattern[1] = "/_/";
  544.                                     $replace[1] = " ";
  545.                                     $r['title'] = ( !empty( $r['title'] ) ? tra( $r['title'] ) : tra( ucwords( preg_replace( $pattern, $replace, $r['module_rsrc'] ))));
  546.                                 }
  547.  
  548.                                 // moduleParams are extracted in BitSmarty::getSiblingAttachments() and passed on the the module php file
  549.                                 $moduleParams = $r;
  550.                                 $gBitSmarty->assign_by_ref'moduleParams'$moduleParams );
  551.                                 // assign the custom module title
  552.                                 $ret .= $gBitSmarty->fetch$r['module_rsrc');
  553.  
  554.                                 if!empty$r["cache_time") ) {
  555.                                     // write to chache file
  556.                                     $fp = fopen( $cachefile, "w+" );
  557.                                     fwrite( $fp, $data, strlen( $data ));
  558.                                     fclose( $fp );
  559.                                 }
  560.                                 $r["data"] = $data;
  561.                             }
  562.  
  563.                             unset( $moduleParams );
  564.                         }
  565.                     } catch( Exception $e ) {
  566.                         print( '<div class="alert alert-warning">'.$e->getMessage() ).'</div>';
  567.                     }
  568.                     if( !empty( $ret ) && ($pColumn == 'l' || $pColumn == 'r') ) { 
  569.                         $ret = '<div class="panel-group col-xs-12">'.$ret.'</div>';
  570.                     }
  571.                 }
  572.             }
  573.         }
  574.         return $ret;
  575.     }
  576.  
  577.     /**
  578.      * get the current layout from the database, layouts are fetched in this order in this order until one is successfully loaded: 'layout', 'fallback_layout', ACTIVE_PACKGE, DEFAULT_PACKAGE"
  579.      *
  580.      * @param array $pParamHash
  581.      * @access public
  582.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  583.      */
  584.     function getLayout( $pParamHash = NULL ) {
  585.         global $gCenterPieces, $gBitUser, $gBitSystem, $gBitSmarty;
  586.         $ret = array( 'l' => NULL, 'c' => NULL, 'r' => NULL );
  587.  
  588.         $layouts =  array();
  589.         if( !empty( $pParamHash['layout'] )) {
  590.             $layouts[] = $pParamHash['layout'];
  591.         }
  592.         if( !empty( $pParamHash['fallback_layout'] )) {
  593.             $layouts[] = $pParamHash['fallback_layout'];
  594.         }
  595.         if( defined( 'ACTIVE_PACKAGE') ) {
  596.             $layouts[] = ACTIVE_PACKAGE;
  597.         }
  598.         $layouts[] = DEFAULT_PACKAGE;
  599.  
  600.         foreach( $layouts AS $l ) {
  601.             $query =   "SELECT tl.*
  602.                         FROM `".BIT_DB_PREFIX."themes_layouts` tl
  603.                         WHERE  tl.`layout`=? ORDER BY ".$this->mDb->convertSortmode"pos_asc" );
  604.  
  605.             $result $this->mDb->query$queryarray$l ) );
  606.             if$result && $result->RecordCount() ) {
  607.                 break;
  608.             }
  609.         }
  610.         if( !empty( $result ) && $result->RecordCount() ) {
  611.             $row = $result->fetchRow();
  612.             // Check to see if we have ACTIVE_PACKAGE modules at the top of the results
  613.             ifisset$row['layout'&& $row['layout'!= DEFAULT_PACKAGE && ACTIVE_PACKAGE != DEFAULT_PACKAGE )) {
  614.                 $skipDefaults = TRUE;
  615.             } else {
  616.                 $skipDefaults = FALSE;
  617.             }
  618.  
  619.             if ( !is_array( $gCenterPieces ) ){
  620.                 $gCenterPieces = array();
  621.             }
  622.             while( $row ) {
  623.                 if( $skipDefaults && $row['layout'] == DEFAULT_PACKAGE ) {
  624.                     // we're done! we've got all the non-DEFAULT_PACKAGE modules
  625.                     break;
  626.                 }
  627.  
  628.                 if ( defined ('ROLE_MODEL') ) {
  629.                     // transform roles to managable array
  630.                     if( empty( $row["roles"] )) {
  631.                         // default is that module is visible at all times
  632.                         $row["visible"] = TRUE;
  633.                         $row["module_roles"] = array();
  634.                     } else {
  635.                         $row['module_roles'] = $this->parseRoles$row['roles');
  636.  
  637.                         if$gBitUser->isAdmin() ) {
  638.                             if ( $gBitSystem->isFeatureActive('site_mods_req_admn_grp') ) {
  639.                                 if( in_array(1, $row['module_roles']) ) {
  640.                                     $row['visible'] = TRUE;
  641.                                 }
  642.                             }
  643.                             else {
  644.                                 $row["visible"] = TRUE;
  645.                             }
  646.                         } else {
  647.                             // Check for the right roles
  648.                             foreach( $row["module_roles"] as $modRoleId ) {
  649.                                 if( $gBitUser->isInRole$modRoleId )) {
  650.                                     $row["visible"] = TRUE;
  651.                                     break; // no need to continue looping
  652.                                 }
  653.                             }
  654.                         }
  655.                     }
  656.                 } else {
  657.                     // transform groups to managable array
  658.                     if( empty( $row["groups"] )) {
  659.                         // default is that module is visible at all times
  660.                         $row["visible"] = TRUE;
  661.                         $row["module_groups"] = array();
  662.                     } else {
  663.                         $row['module_groups'] = $this->parseGroups$row['groups');
  664.  
  665.                         if$gBitUser->isAdmin() ) {
  666.                             if ( $gBitSystem->isFeatureActive('site_mods_req_admn_grp') ) {
  667.                                 if( in_array(1, $row['module_groups']) ) {
  668.                                     $row['visible'] = TRUE;
  669.                                 }
  670.                             }
  671.                             else {
  672.                                 $row["visible"] = TRUE;
  673.                             }
  674.                         } else {
  675.                             // Check for the right groups
  676.                             foreach( $row["module_groups"] as $modGroupId ) {
  677.                                 if( $gBitUser->isInGroup$modGroupId )) {
  678.                                     $row["visible"] = TRUE;
  679.                                     break; // no need to continue looping
  680.                                 }
  681.                             }
  682.                         }
  683.                     }
  684.                 }
  685.  
  686.                 if( empty( $ret[$row['layout_area']] )) {
  687.                     $ret[$row['layout_area']] = array();
  688.                 }
  689.  
  690.                 $row['module_params'] = $this->parseString$row['params');
  691.  
  692.                 if!empty$pParamHash['load_config') ) {
  693.                     global $moduleParams;
  694.                     $row['config'] = $gBitSmarty->getModuleConfig$row['module_rsrc');
  695.                 }
  696.  
  697.                 if( $row['layout_area'] == CENTER_COLUMN ) {
  698.                     array_push( $gCenterPieces, $row );
  699.                 }
  700.  
  701.                 if( !empty( $row["visible"] )) {
  702.                     array_push( $ret[$row['layout_area']], $row );
  703.                 }
  704.  
  705.                 $row = $result->fetchRow();
  706.             }
  707.         }
  708.         return $ret;
  709.     }
  710.  
  711.     /**
  712.      * isModuleLoaded will check if a given modules is being used in the currently active layout
  713.      *
  714.      * @param string $pModuleResource the module resource
  715.      * @param string $pArea optionally specify the area the module should be found in
  716.      * @access public
  717.      * @return TRUE on success, FALSE on failure
  718.      */
  719.     function isModuleLoaded( $pModuleResource, $pArea = NULL ) {
  720.         // load the layout if it hasn't been done yet
  721.         $this->loadLayout();
  722.  
  723.         if!$this->verifyArea$pArea && !empty$this->mLayout[$pArea)) {
  724.             foreach( $this->mLayout[$pAreaas $module {
  725.                 if( $pModuleResource == $module['module_rsrc'] ) {
  726.                     return TRUE;
  727.                 }
  728.             }
  729.         } else {
  730.             foreach( array_keys( $this->mLayout as $area {
  731.                 if( !empty( $this->mLayout[$area)) {
  732.                     foreach( $this->mLayout[$areaas $module {
  733.                         if( $pModuleResource == $module['module_rsrc'] ) {
  734.                             return TRUE;
  735.                         }
  736.                     }
  737.                 }
  738.             }
  739.         }
  740.         return FALSE;
  741.     }
  742.  
  743.     /**
  744.      * fix postional data in database using increments of 10 to make it easy for inserting new modules
  745.      *
  746.      * @access public
  747.      * @return void
  748.      */
  749.     function fixPositions( $pLayout = NULL ) {
  750.         $layouts = $this->getAllLayouts();
  751.  
  752.         // if we only want to fix the positions of a given layout, strip down the hash
  753.         if!empty$pLayout && !empty$layouts[$pLayout)) {
  754.             $layouts = array( $layouts[$pLayout] );
  755.         }
  756.  
  757.         foreach( $layouts as $layout ) {
  758.             foreach( $layout as $column ) {
  759.                 $i = 5;
  760.                 foreach( $column as $module ) {
  761.                     $this->mDb->query"UPDATE `".BIT_DB_PREFIX."themes_layouts` SET pos=? WHERE `module_id`=?"array$i$module['module_id'));
  762.                     $i += 5;
  763.                 }
  764.             }
  765.         }
  766.     }
  767.  
  768.     /**
  769.      * get a brief summary of set layouts
  770.      *
  771.      * @access public
  772.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  773.      */
  774.     function getAllLayouts() {
  775.         $layouts = array();
  776.         $modules = $this->mDb->getAll"SELECT tl.* FROM `".BIT_DB_PREFIX."themes_layouts` tl ORDER BY ".$this->mDb->convertSortmode"pos_asc" ));
  777.         foreach$modules as $module {
  778.             if( defined ( 'ROLE_MODEL') ) {
  779.                 $module['module_roles'] = $this->parseRoles$module['roles');
  780.             } else {
  781.                 $module['module_groups'] = $this->parseGroups$module['groups');
  782.             }
  783.             $layouts[$module['layout']][$module['layout_area']][] = $module;
  784.         }
  785.         ksort( $layouts );
  786.         // Take the default/kernel layout and make sure it is the first item in hash
  787.         if( ( count( $layouts ) > 1 ) && isset( $layouts['kernel'] ) ) {
  788.             $kernel_layout = $layouts['kernel'];
  789.             unset( $layouts['kernel'] );
  790.             $layouts = array('kernel' => $kernel_layout) + $layouts;
  791.         }
  792.         return $layouts;
  793.     }
  794.  
  795.     /**
  796.      * cloneLayout
  797.      *
  798.      * @param array $pFromLayout
  799.      * @param array $pToLayout
  800.      * @access public
  801.      * @return boolean TRUE
  802.      */
  803.     function cloneLayout( $pFromLayout, $pToLayout ) {
  804.         global $gBitSystem;
  805.         if( !empty( $pFromLayout ) && !empty( $pToLayout ) ) {
  806.             // nuke existing layout
  807.             $this->mDb->query"DELETE FROM `".BIT_DB_PREFIX."themes_layouts` WHERE `layout`=?"array$pToLayout ));
  808.             // get requested layout
  809.             $team defined('ROLE_MODEL''roles' 'groups';
  810.             $layout $this->mDb->getAll"
  811.                 SELECT `title`, `layout_area`, `module_rows`, `module_rsrc`, `params`, `cache_time`, `$team`, `pos`
  812.                 FROM `".BIT_DB_PREFIX."themes_layouts` WHERE `layout`=?", array( $pFromLayout ));
  813.             foreach( $layout as $module ) {
  814.                 $module['layout'] = $pToLayout;
  815.                 $this->storeModule$module );
  816.             }
  817.         }
  818.         return TRUE;
  819.     }
  820.  
  821.     /**
  822.      * expungeLayout
  823.      *
  824.      * @param array $pLayout
  825.      * @access public
  826.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  827.      */
  828.     function expungeLayout( $pLayout = NULL ) {
  829.         $bindVars = array();
  830.         if( !empty( $pLayout )) {
  831.             $whereSql = "WHERE `layout`=?";
  832.             $bindVars[] = $pLayout;
  833.         }
  834.         $this->mDb->query"DELETE FROM `".BIT_DB_PREFIX."themes_layouts` $whereSql", $bindVars );
  835.     }
  836.  
  837.     /**
  838.      * transform groups string to handy array
  839.      *
  840.      * @param array $pParseString either space separated list of groups or serialised array
  841.      * @access public
  842.      * @return array of groups
  843.      */
  844.     function parseGroups( $pParseString ) {
  845.         $ret = array();
  846.         // convert groups string to hash
  847.         if( preg_match( '/[A-Za-z]/', $pParseString )) {
  848.             // old style serialized group names
  849.             if( $grps = @unserialize( $pParseString )) {
  850.                 foreach( $grps as $grp ) {
  851.                     global $gBitUser;
  852.                     if( !( $groupId = array_search( $grp, $gBitUser->mGroups ))) {
  853.                         if( $gBitUser->isAdmin() ) {
  854.                             $ret[] = $gBitUser->groupExists$grp'*' );
  855.                         }
  856.                     }
  857.  
  858.                     if( @$this->verifyId$groupId )) {
  859.                         $ret[] = $groupId;
  860.                     }
  861.                 }
  862.             }
  863.         } else {
  864.             // new imploded style
  865.             $ret = explode( ' ', $pParseString );
  866.         }
  867.         return $ret;
  868.     }
  869.  
  870.     /**
  871.      * transform roles string to handy array
  872.      *
  873.      * @param array $pParseString either space separated list of roles or serialised array
  874.      * @access public
  875.      * @return array of roles
  876.      */
  877.     function parseRoles( $pParseString ) {
  878.         $ret = array();
  879.         // convert role string to hash
  880.         if( preg_match( '/[A-Za-z]/', $pParseString )) {
  881.             // old style serialized role names
  882.             if( $grps = @unserialize( $pParseString )) {
  883.                 foreach( $grps as $grp ) {
  884.                     global $gBitUser;
  885.                     if( !( $roleId = array_search( $grp, $gBitUser->mRoles ))) {
  886.                         if( $gBitUser->isAdmin() ) {
  887.                             $ret[] = $gBitUser->rollExists$grp'*' );
  888.                         }
  889.                     }
  890.  
  891.                     if( @$this->verifyId$roleId )) {
  892.                         $ret[] = $roleId;
  893.                     }
  894.                 }
  895.             }
  896.         } else {
  897.             // new imploded style
  898.             $ret = explode( ' ', $pParseString );
  899.         }
  900.         return $ret;
  901.     }
  902.  
  903.  
  904.     // }}}
  905.     // {{{ =================== Modules ====================
  906.     /**
  907.      * Verfiy module parameters when storing a new module
  908.      *
  909.      * @param array $pHash
  910.      * @access public
  911.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  912.      */
  913.     function verifyModuleParams( &$pHash ) {
  914.         // we need at least a module_id or a module_rsrc
  915.         if( empty( $pHash['module_id'] ) && empty( $pHash['module_rsrc'] )) {
  916.             $this->mErrors['module_rsrc'tra'No module id or module file given.' );
  917.         } elseif( !empty( $pHash['module_id'] )) {
  918.             $pHash['store']['module_id'] = $pHash['module_id'];
  919.         } elseif( !empty( $pHash['module_rsrc'] )) {
  920.             $pHash['store']['module_rsrc'] = $pHash['module_rsrc'];
  921.         }
  922.  
  923.         // if we don't have a valid area, we'll just shove it in the left column
  924.         if( $this->verifyArea$pHash['layout_area')) {
  925.             $pHash['store']['layout_area'] = $pHash['layout_area'];
  926.         } else {
  927.             $pHash['store']['layout_area'] = 'l';
  928.         }
  929.  
  930.         $pHash['store']['title']         = ( !empty( $pHash['title'] )             ? $pHash['title']         : NULL );
  931.         $pHash['store']['params']        = ( !empty( $pHash['params'] )            ? $pHash['params']        : NULL );
  932.         $pHash['store']['layout']        = ( !empty( $pHash['layout'] )            ? $pHash['layout']        : DEFAULT_PACKAGE );
  933.         $pHash['store']['module_rows']   = ( @is_numeric( $pHash['module_rows'] )  ? $pHash['module_rows']   : NULL );
  934.         $pHash['store']['cache_time']    = ( @is_numeric( $pHash['cache_time'] )   ? $pHash['cache_time']    : NULL );
  935.         $pHash['store']['pos']           = ( @is_numeric( $pHash['pos'] )          ? $pHash['pos']           : 1 );
  936.  
  937.         if( !empty( $pHash['roles'] ) && is_array( $pHash['roles'] )) {
  938.             $pHash['store']['roles'] = implode( ' ', $pHash['roles'] );
  939.         } elseif( !empty( $pHash['groups'] ) && is_array( $pHash['groups'] )) {
  940.             $pHash['store']['groups'] = implode( ' ', $pHash['groups'] );
  941.         } elseif (defined('ROLE_MODEL') ) {
  942.             $pHash['store']['roles'] = NULL;
  943.         } else {
  944.             $pHash['store']['groups'] = NULL;
  945.         }
  946.  
  947.         if( !empty( $pHash['config'] ) ) {
  948.             $pHash['store']['params'] = '';
  949.             foreach( $pHash['config'] as $paramName=>$paramValue ) {
  950.                 $pHash['store']['params'] .= $paramName.'='.urlencode( $paramValue ).'&';
  951.             }
  952.         } else {
  953.             $pHash['store']['params']        = ( !empty( $pHash['params'] )            ? $pHash['params']        : NULL );
  954.         }
  955.  
  956.         return( count( $this->mErrors == );
  957.     }
  958.  
  959.     /**
  960.      * storeModule
  961.      *
  962.      * @param array $pHash
  963.      * @access public
  964.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  965.      */
  966.     function storeModule( &$pHash ) {
  967.         if( $this->verifyModuleParams$pHash )) {
  968.             $table = BIT_DB_PREFIX."themes_layouts";
  969.  
  970.             if( @BitBase::verifyId( $pHash['store']['module_id'] )) {
  971.                 // if we've been passed a module_id, we are updating an entry in the DB
  972.                 $result = $this->mDb->associateUpdate$table$pHash['store']array'module_id' => $pHash['store']['module_id'));
  973.             } else {
  974.                 // no module_id yet - let's get one
  975.                 $pHash['store']['module_id'] = $this->mDb->GenID'themes_layouts_module_id_seq' );
  976.                 $result $this->mDb->associateInsert$table$pHash['store');
  977.             }
  978.         }
  979.         return( count( $this->mErrors == );
  980.     }
  981.  
  982.     /**
  983.      * getModuleData
  984.      *
  985.      * @param array $pModuleId
  986.      * @access public
  987.      * @return module details of the requested module id
  988.      */
  989.     function getModuleData( $pModuleId ) {
  990.         if( @BitBase::verifyId( $pModuleId )) {
  991.             $ret = $this->mDb->getRow"SELECT tl.* FROM `".BIT_DB_PREFIX."themes_layouts` tl WHERE `module_id`=? "array$pModuleId ));
  992.             $ret['module_params'$this->parseString$ret['params');
  993.             return $ret;
  994.         }
  995.     }
  996.  
  997.     /**
  998.      * moduleUp
  999.      *
  1000.      * @param array $pModuleId
  1001.      * @access public
  1002.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1003.      */
  1004.     function moveModuleUp( $pModuleId ) {
  1005.         if( @BitBase::verifyId( $pModuleId )) {
  1006.             $this->moveModule$pModuleId'up' );
  1007.         }
  1008.         return( count( $this->mErrors == );
  1009.     }
  1010.  
  1011.     /**
  1012.      * moduleDown
  1013.      *
  1014.      * @param array $pModuleId
  1015.      * @access public
  1016.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1017.      */
  1018.     function moveModuleDown( $pModuleId ) {
  1019.         if( @BitBase::verifyId( $pModuleId )) {
  1020.             $this->moveModule$pModuleId'down' );
  1021.         }
  1022.         return( count( $this->mErrors == );
  1023.     }
  1024.  
  1025.     /**
  1026.      * generic function to move module up or down
  1027.      *
  1028.      * @param array $pModuleId
  1029.      * @param string $pOrientation
  1030.      * @access public
  1031.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1032.      */
  1033.     function moveModule( $pModuleId, $pDirection = 'down' ) {
  1034.         if( @BitBase::verifyId( $pModuleId )) {
  1035.             // first we get next module we want to swap with
  1036.             $moduleData = $this->getModuleData$pModuleId );
  1037.             if$pDirection == 'up' {
  1038.                 $pos_check = 'AND `pos`<=?';
  1039.                 $pos_set   = 'SET `pos`=`pos`-1';
  1040.                 $order     = 'ORDER BY pos DESC';
  1041.             } else {
  1042.                 $pos_check = 'AND `pos`>=?';
  1043.                 $pos_set   = 'SET `pos`=`pos`+1';
  1044.                 $order     = 'ORDER BY pos ASC';
  1045.             }
  1046.             $query  = "SELECT `module_id` FROM `".BIT_DB_PREFIX."themes_layouts` WHERE `layout`=? AND `layout_area`=? $pos_check AND `module_id` <> ? $order";
  1047.             $swapModuleId = $this->mDb->getOne$queryarray$moduleData['layout']$moduleData['layout_area']$moduleData['pos']$moduleData['module_id'));
  1048.             if$moduleSwap $this->getModuleData$swapModuleId )) {
  1049.                 if( $moduleData['pos'] == $moduleSwap['pos'] ) {
  1050.                     $query = "UPDATE `".BIT_DB_PREFIX."themes_layouts` $pos_set WHERE `module_id`=?";
  1051.                     $result = $this->mDb->query$queryarray$moduleData['module_id'));
  1052.                 } else {
  1053.                     $query = "UPDATE `".BIT_DB_PREFIX."themes_layouts` SET `pos`=? WHERE `module_id`=?";
  1054.                     $result = $this->mDb->query$queryarray$moduleSwap['pos']$moduleData['module_id'));
  1055.                     $result $this->mDb->query$queryarray$moduleData['pos']$moduleSwap['module_id'));
  1056.                 }
  1057.             }
  1058.         }
  1059.         return( count( $this->mErrors == );
  1060.     }
  1061.  
  1062.     /**
  1063.      * setModulePosition
  1064.      *
  1065.      * @param array $pModuleId
  1066.      * @param array $pPos
  1067.      * @access public
  1068.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1069.      */
  1070.     function setModulePosition( $pModuleId, $pPos, $pCol=NULL ) {
  1071.         if( @BitBase::verifyId( $pModuleId )) {
  1072.             $bindVars = array();
  1073.             $updateSql = '';
  1074.             if( !empty( $pCol ) ) {
  1075.                 $updateSql .= ' `layout_area`=?, ';
  1076.                 $bindVars[] = $pCol;
  1077.             }
  1078.             $bindVars[] = $pPos;
  1079.             $bindVars[] = $pModuleId;
  1080.             $query = "UPDATE `".BIT_DB_PREFIX."themes_layouts` SET ".$updateSql." `pos`=? WHERE `module_id`=?";
  1081.             $result = $this->mDb->query$query$bindVars );
  1082.         }
  1083.         return TRUE;
  1084.     }
  1085.  
  1086.     /**
  1087.      * moveModuleToArea
  1088.      *
  1089.      * @param array $pModuleId
  1090.      * @param array $pArea
  1091.      * @access public
  1092.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1093.      */
  1094.     function moveModuleToArea( $pModuleId, $pArea ) {
  1095.         if( !$this->verifyArea$pArea )) {
  1096.             $pArea = 'l';
  1097.         }
  1098.  
  1099.         if( @BitBase::verifyId( $pModuleId )) {
  1100.             $query = "UPDATE `".BIT_DB_PREFIX."themes_layouts` SET `layout_area`=? WHERE `module_id`=?";
  1101.             $result = $this->mDb->query$queryarray$pArea$pModuleId ));
  1102.         }
  1103.         return TRUE;
  1104.     }
  1105.  
  1106.     /**
  1107.      * unassignModule
  1108.      *
  1109.      * @param array $pModuleId can be a module id or a resource path. if it is a resource path, all modules with that resource will be removed
  1110.      * @access public
  1111.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1112.      */
  1113.     function unassignModule( $pModuleMixed ) {
  1114.         $ret = FALSE;
  1115.         if( @BitBase::verifyId( $pModuleMixed )) {
  1116.             if( $this->mDb->query"DELETE FROM `".BIT_DB_PREFIX."themes_layouts` WHERE `module_id`=?"array$pModuleMixed ))) {
  1117.                 $ret = TRUE;
  1118.             }
  1119.         } elseif( !empty( $pModuleMixed )) {
  1120.             if( $this->mDb->query"DELETE FROM `".BIT_DB_PREFIX."themes_layouts` WHERE `module_rsrc`=?"array$pModuleMixed ))) {
  1121.                 $ret = TRUE;
  1122.             }
  1123.         }
  1124.         return $ret;
  1125.     }
  1126.  
  1127.     /**
  1128.      * if the specified area doesn't make any sense, we just dump it in the left column
  1129.      *
  1130.      * @param array $pArea l --> left       r --> right       c --> center       b --> bottom       t --> top
  1131.      * @access public
  1132.      * @return valid area
  1133.      */
  1134.     function verifyArea( &$pArea ) {
  1135.         return( !empty( $pArea ) && preg_match( '/^[lrctb]$/', $pArea ));
  1136.     }
  1137.  
  1138.     /**
  1139.      * generates module names on full hash by reference
  1140.      *
  1141.      * @param array $p2DHash layout hash
  1142.      * @access public
  1143.      * @return void
  1144.      */
  1145.     function generateModuleNames( &$p2DHash ) {
  1146.         if( is_array( $p2DHash )) {
  1147.             // Generate human friendly names
  1148.             foreach( array_keys( $p2DHash ) as $col ) {
  1149.                 if( count( $p2DHash[$col] )) {
  1150.                     foreach( array_keys( $p2DHash["$col"] ) as $mod ) {
  1151.                         list( $rsrc, $specifier ) = explode( ':', $p2DHash[$col][$mod]['module_rsrc'], 2 );
  1152.                         $specelems = explode( '/', $specifier );
  1153.                         $package = current( $specelems );
  1154.                         if( $package == 'temp' ) $package = next( $specelems );
  1155.                         // handle special case for custom modules
  1156.                         if( !isset( $package )) {
  1157.                             $package = $rsrc;
  1158.                         }
  1159.                         $file = end( $specelems );
  1160.                         $file = str_replace( 'mod_', '', $file );
  1161.                         $file = str_replace( '.tpl', '', $file );
  1162.                         $p2DHash[$col][$mod]['name'] = $package.' &raquo; '.str_replace( '_', ' ', $file );
  1163.                     }
  1164.                 }
  1165.             }
  1166.         }
  1167.     }
  1168.  
  1169.     /**
  1170.      * getAllModules
  1171.      *
  1172.      * @param string $pDir
  1173.      * @param string $pPrefix
  1174.      * @access public
  1175.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1176.      */
  1177.     function getAllModules( $pDir='modules', $pPrefix='mod_' ) {
  1178.         global $gBitSystem;
  1179.         // @TODO MODULE UPGRADE
  1180.         // hash for carrying references to modules:
  1181.         // $this->mModules[$pDir][$pPrefix]
  1182.         // this is ugly but is to smooth the transition until all modules are upgraded to directory and registration structure
  1183.         // it will be unncessary once all packages are caught up
  1184.         if(( $modules = $this->getCustomModuleList() ) && $pPrefix == 'mod_' {
  1185.             foreach( $modules as $m ) {
  1186.                 $this->mModules[$pDir][$pPrefix][tra'Custom Modules' )]['_custom:custom/'.$m["name"]] array'title' => $m["name");
  1187.             }
  1188.             asort( $this->mModules[$pDir][$pPrefix][tra'Custom Modules' ));
  1189.         }
  1190.  
  1191.         // iterate through all packages and look for all possible modules
  1192.         foreach( array_keys( $gBitSystem->mPackages as $key {
  1193.             if( $gBitSystem->isPackageActive$key )) {
  1194.                 $loc = BIT_ROOT_PATH.$gBitSystem->mPackages[$key]['dir'].'/'.$pDir;
  1195.                 if@is_dir$loc )) {
  1196.                     $h = opendir( $loc );
  1197.                     if( $h ) {
  1198.                         while (($file = readdir($h)) !== false) {
  1199.                             // match on legacy module files which require a prefix
  1200.                             if ( preg_match( "/^$pPrefix(.*)\.tpl$/", $file, $match )) {
  1201.                                 $this->mModules[$pDir][$pPrefix][ucfirst$key )]['bitpackage:'.$key.'/'.$filearray'title' => str_replace'_'' '$match[1),
  1202.                                                                                                                          'template' => $file,
  1203.                                                                                                                         );
  1204.                             }
  1205.                             // loop over nested directories which contain modern modules
  1206.                             // these modules are only accessible from gBitThemes
  1207.                             elseif ( !in_array( $file, array('.','..','CVS') ) && @is_dir( $loc.'/'.$file ) ){
  1208.                                 $conf_file = $loc.'/'.$file.'/config_inc.php';
  1209.                                 // we expect a configuration file
  1210.                                 if( @is_file( $conf_file ) ){
  1211.                                     require_once( $conf_file );
  1212.                                 }
  1213.                             }
  1214.                         }
  1215.                         closedir ($h);
  1216.                         if( !empty( $this->mModules[$pDir][$pPrefix][ucfirst$key )) ) {
  1217.                             asort( $this->mModules[$pDir][$pPrefix][ucfirst$key ));
  1218.                         }
  1219.                     }
  1220.                 }
  1221.                 // we scan temp/<pkg>/modules for module files as well for on the fly generated modules (e.g. nexus)
  1222.                 if( $pDir == 'modules' ) {
  1223.                     $loc = TEMP_PKG_PATH.$gBitSystem->mPackages[$key]['name'].'/'.$pDir;
  1224.                     if@is_dir$loc )) {
  1225.                         $h = opendir( $loc );
  1226.                         if( $h ) {
  1227.                             while (($file = readdir($h)) !== false) {
  1228.                                 if ( preg_match( "/^$pPrefix(.*)\.tpl$/", $file, $match )) {
  1229.                                     $this->mModules[$pDir][$pPrefix][ucfirst$key )]['bitpackage:temp/'.$key.'/'.$filearray'title' => str_replace'_'' '$match[1),
  1230.                                                                                                                                   'template' => $file,
  1231.                                                                                                                                 );
  1232.                                 }
  1233.                             }
  1234.                             closedir ($h);
  1235.                             if( !empty( $this->mModules[$pDir][$pPrefix][ucfirst($key)) ) {
  1236.                                 asort( $this->mModules[$pDir][$pPrefix][ucfirst($key));
  1237.                             }
  1238.                         }
  1239.                     }
  1240.                 }
  1241.             }
  1242.         }
  1243.         return $this->mModules[$pDir][$pPrefix];
  1244.     }
  1245.  
  1246.     function registerModule( $pMixed ){
  1247.         $pkg = $pMixed['package'];
  1248.         $dir = $pMixed['directory'];
  1249.         $tpl = $pMixed['template'];
  1250.         $legacy_dir = $pMixed['legacy_dir'];
  1251.         $legacy_prefix = $pMixed['legacy_prefix'];
  1252.         $this->mModules[$legacy_dir][$legacy_prefix][ucfirst$pkg )]['bitpackage:'.$pkg.'/'.$dir.'/'.$tpl$pMixed;
  1253.     }
  1254.  
  1255.     // utility function for other packages when they upgrade their modules to the new module system
  1256.     // see themes/admin/upgrades/3.0.0.php for an example of usages
  1257.     function upgradeModulesPaths(){
  1258.         $this->getAllModules();
  1259.         $legacy_mods array();
  1260.         $upgrade_mods array();
  1261.  
  1262.         foreach$this->mModules['modules']['mod_'as $pkg => $modules ){
  1263.             foreach( $modules as $modulepath => $module ){
  1264.                 $parts =  explode( "/", $modulepath );
  1265.                 if( count( $parts ) > 2 ){
  1266.                     $upgrade_mods[array_pop( $parts )] = $modulepath;
  1267.                 }
  1268.             }
  1269.         }
  1270.  
  1271.         $sql1 = "SELECT DISTINCT `module_rsrc` FROM `".BIT_DB_PREFIX."themes_layouts`";
  1272.         $legacy_mods = $this->mDb->getArray$sql1 );
  1273.  
  1274.         // fix everything
  1275.         // transaction will save us if something goes bad
  1276.         $this->mDb->StartTrans();
  1277.  
  1278.         foreach$legacy_mods as $old ){
  1279.             $key =  array_pop( explode( "/", $old['module_rsrc'] ) );
  1280.             if( in_array( $key, array_keys($upgrade_mods) ) && $old['module_rsrc'] != $upgrade_mods[$key]){
  1281.                 $storeHash = array( 'module_rsrc' => $upgrade_mods[$key] );
  1282.                 $this->mDb->associateUpdateBIT_DB_PREFIX."themes_layouts"$storeHasharray'module_rsrc' => $old['module_rsrc'));
  1283.             }
  1284.         }
  1285.  
  1286.         $this->mDb->CompleteTrans();
  1287.     }
  1288.  
  1289.     /**
  1290.      * get a module-specfic parameters
  1291.      *
  1292.      * @param array $pModuleId
  1293.      * @access public
  1294.      * @return array or parameters
  1295.      */
  1296.     function getModuleParameters( $pModuleId ) {
  1297.         $ret = array();
  1298.         if( @BitBase::verifyId( $pModuleId )) {
  1299.             $module = $this->getModuleData$pModuleId );
  1300.             $ret $module['module_params'];
  1301.         } else {
  1302.             deprecated( 'Please use the module parameters found in vd( $moduleParams[\'module_params\'] ); or pass in the module id for a database lookup.' );
  1303.         }
  1304.         return $ret;
  1305.     }
  1306.  
  1307.     /**
  1308.      * parse URL-like parameter string
  1309.      *
  1310.      * @param array $pParseString
  1311.      * @access public
  1312.      * @return array or parameters
  1313.      */
  1314.     function parseString( $pParseString ) {
  1315.         $ret = array();
  1316.         if( !empty( $pParseString )) {
  1317.             // only call crazy regex when params are too complex for parse_str()
  1318.             if( strpos( trim( $pParseString ), ' ' )) {
  1319.                 $ret = parse_xml_attributes( $pParseString );
  1320.             } else {
  1321.                 parse_str( $pParseString, $ret );
  1322.             }
  1323.         }
  1324.         return $ret;
  1325.     }
  1326.  
  1327.  
  1328.     // }}}
  1329.     // {{{ =================== Custom Modules ====================
  1330.     /**
  1331.      * verifyCustomModule
  1332.      *
  1333.      * @param array $pParamHash
  1334.      * @access public
  1335.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1336.      */
  1337.     function verifyCustomModule( &$pParamHash ) {
  1338.         if( !empty( $pParamHash['name'] ) && preg_match( "/[a-zA-Z]/", $pParamHash['name'] )) {
  1339.             $pParamHash['store']['name'] = substr( strtolower( preg_replace( "/[^\w]*/", "", $pParamHash['name'] )), 0, 40 );
  1340.         }
  1341.  
  1342.         if( empty( $pParamHash['store']['name'] )) {
  1343.             $this->mErrors[tra'You need to provide a name for your custom module. Only alphanumeric characters are allowed and you need to use at least one letter.' );
  1344.         }
  1345.  
  1346.         if( !empty( $pParamHash['title'] )) {
  1347.             $pParamHash['store']['title'] = substr( $pParamHash['title'], 0, 200 );
  1348.         }
  1349.  
  1350.         if( !empty( $pParamHash['data'] )) {
  1351.             $pParamHash['store']['data'] = $pParamHash['data'];
  1352.         }
  1353.  
  1354.         return( count( $this->mErrors == );
  1355.     }
  1356.  
  1357.     /**
  1358.      * storeCustomModule
  1359.      *
  1360.      * @param array $pParamHash
  1361.      * @access public
  1362.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1363.      */
  1364.     function storeCustomModule( $pParamHash ) {
  1365.         if( $this->verifyCustomModule$pParamHash )) {
  1366.             $table = "`".BIT_DB_PREFIX."themes_custom_modules`";
  1367.             $result = $this->mDb->query"DELETE FROM $table WHERE `name`=?", array( $pParamHash['store']['name'] ));
  1368.             $result = $this->mDb->associateInsert$table$pParamHash['store');
  1369.         }
  1370.         return( count( $this->mErrors == );
  1371.     }
  1372.  
  1373.     /**
  1374.      * getCustomModule
  1375.      *
  1376.      * @param array $pName
  1377.      * @access public
  1378.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1379.      */
  1380.     function getCustomModule( $pName ) {
  1381.         if( !empty( $pName )) {
  1382.             return $this->mDb->getRow"SELECT * FROM `".BIT_DB_PREFIX."themes_custom_modules` WHERE `name`=?"array$pName ));
  1383.         }
  1384.     }
  1385.  
  1386.     /**
  1387.      * getCustomModuleList
  1388.      *
  1389.      * @access public
  1390.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1391.      */
  1392.     function getCustomModuleList() {
  1393.         return( $this->mDb->getAll"SELECT * FROM `".BIT_DB_PREFIX."themes_custom_modules`" ));
  1394.     }
  1395.  
  1396.     /**
  1397.      * expungeCustomModule
  1398.      *
  1399.      * @param array $pName
  1400.      * @access public
  1401.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1402.      */
  1403.     function expungeCustomModule( $pName ) {
  1404.         if( !empty( $pName )) {
  1405.             $this->unassignModule'_custom:custom/'.$pName );
  1406.             $result $this->mDb->query"DELETE FROM `".BIT_DB_PREFIX."themes_custom_modules` WHERE `name`=?"array$pName ));
  1407.         }
  1408.         return TRUE;
  1409.     }
  1410.  
  1411.     /**
  1412.      * isCustomModule
  1413.      *
  1414.      * @param array $pMixed either name of module or the rsrc of a module
  1415.      * @access public
  1416.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1417.      */
  1418.     function isCustomModule( $pMixed ) {
  1419.         if( strpos( $pMixed, "_custom:custom" ) !== FALSE ) {
  1420.             return TRUE;
  1421.         } elseif( strpos( $pMixed, "bitpackage:" ) !== FALSE ) {
  1422.             return FALSE;
  1423.         } else {
  1424.             $result = $this->mDb->getOne"SELECT `name` FROM `".BIT_DB_PREFIX."themes_custom_modules` WHERE `name`=?"array$pMixed ));
  1425.             return!empty$result ));
  1426.         }
  1427.     }
  1428.  
  1429.  
  1430.     // }}}
  1431.     // {{{ =================== Javascript and CSS related Methods ====================
  1432.     /**
  1433.      * Statically callable function to see if browser supports javascript
  1434.      * determined by cookie set in bitweaver.js
  1435.      * @access public
  1436.      */
  1437.     function isJavascriptEnabled() {
  1438.     //    return( !empty( $_COOKIE['javascript_enabled'] ) && $_COOKIE['javascript_enabled'] == 'y' );
  1439.         return TRUE; // This function is fuckt as cookie is empty for first query. And cookie privacy browsers are perfjects JS enabled
  1440.     }
  1441.  
  1442.     /**
  1443.      * Statically callable function to determine if the current call was made using Ajax
  1444.      *
  1445.      * @access public
  1446.      */
  1447.     function isAjaxRequest() {
  1448.         return(( !empty( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) || !empty( $_REQUEST['ajax_xml'] ));
  1449.     }
  1450.  
  1451.     // {{{ Javascript and CSS load methods
  1452.     /**
  1453.      * Load Ajax libraries
  1454.      *
  1455.      * @param array $pAjaxLib Name of the library we want to use e.g.: prototype or mochikit
  1456.      * @param array $pLibHash Array of additional libraries we need to load
  1457.      * @param boolean $pPack Set to true if you want to pack the javascript file
  1458.      * @access public
  1459.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1460.      */
  1461.     function loadAjax( $pAjaxLib, $pLibHash=NULL, $pLibPath=NULL, $pPack = FALSE ) {
  1462.         global $gBitSystem, $gBitSmarty, $gSniffer;
  1463.         $ret = FALSE;
  1464.         $joined = TRUE;
  1465.         $ajaxLib = strtolower( $pAjaxLib );
  1466.         if( $this->isJavascriptEnabled() ) {
  1467.             // set the javascript lib path if not set yet
  1468.             if( empty( $pLibPath )) {
  1469.                 switch( $ajaxLib ) {
  1470.                     case 'mochikit':
  1471.                         $pLibPath = UTIL_PKG_PATH."javascript/MochiKit/";
  1472.                         $pos = 100;
  1473.                         break;
  1474.                     case 'yui':
  1475.                         $pLibPath = UTIL_PKG_PATH."javascript/yui/";
  1476.                         $pos = 100;
  1477.                         break;
  1478.                     case 'jquerylocal':
  1479.                         $pLibPath = UTIL_PKG_PATH."javascript/jquery/";
  1480.                         $pos = 100;
  1481.                         break;
  1482.                     default:
  1483.                         $pLibPath = UTIL_PKG_PATH."javascript/";
  1484.                         $pos = 200;
  1485.                         break;
  1486.                 }
  1487.             }
  1488.  
  1489.             if( !$this->isAjaxLib$ajaxLib )) {
  1490.                 // load core javascript files for ajax libraries
  1491.                 $jqueryMin = $gBitSystem->isLive('.min' '';
  1492.                 $bootstrapSrc CONFIG_PKG_PATH.'themes/bootstrap/js/bootstrap'.$jqueryMin.'.js';
  1493.                 switch$ajaxLib {
  1494.                     case 'jquery':
  1495.                         $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
  1496.                         $jqueryVersion = $gBitSystem->getConfig'jquery_version''1.10.1' );
  1497.                         $jqueryUiVersion $gBitSystem->getConfig'jquery_ui_version''1.9.2' );
  1498.                         $jqueryTheme $gBitSystem->getConfig'jquery_theme''base' );
  1499.                         $jquerySrc $protocol.'://ajax.googleapis.com/ajax/libs/jquery/'.$jqueryVersion.'/jquery'.$jqueryMin.'.js';
  1500.                         $this->mRawFiles['js'][$jquerySrc;
  1501.                         $this->mRawFiles['js'][$protocol.'://ajax.googleapis.com/ajax/libs/jqueryui/'.$jqueryUiVersion.'/jquery-ui'.$jqueryMin.'.js';
  1502.                         $this->mRawFiles['css'][$protocol.'://ajax.googleapis.com/ajax/libs/jqueryui/'.$jqueryUiVersion.'/themes/'.$jqueryTheme.'/jquery-ui.css';
  1503.                         // bootstrap needs to load after jquery
  1504.                         iffile_exists$bootstrapSrc ) ) {
  1505.                             $this->mRawFiles['js'][$bootstrapSrc;
  1506.                         }
  1507.  
  1508.                         $gBitSmarty->assign'jquerySrc'$jquerySrc );
  1509.                         break;
  1510.                     case 'jquerylocal':
  1511.                         $joined FALSE;
  1512.                         $this->loadJavascriptTHEMES_PKG_PATH.'js/jquery'.$jqueryMin.'.js'FALSE$pos++$joined );
  1513.                         $this->loadJavascriptTHEMES_PKG_PATH.'js/jquery-ui-1.10.3.custom'.$jqueryMin.'.js'FALSE$pos++$joined );
  1514.                         $this->loadJavascriptTHEMES_PKG_PATH.'bootstrap/js/bootstrap'.$jqueryMin.'.js'FALSE$pos++$joined );
  1515.                         $this->loadCssTHEMES_PKG_PATH.'bootstrap/colourstrap/colourstrap.css'FALSE$pos++$joined );
  1516.                         $this->loadCssTHEMES_PKG_PATH.'bootstrap/colourstrap/colourstrap-icons.css'FALSE$pos++$joined );
  1517.                         break;
  1518.                     case 'yui':
  1519.                         $this->loadJavascript$pLibPath.'yuiloader-dom-event/yuiloader-dom-event.js'FALSE$pos++ );
  1520.                         break;
  1521.                 }
  1522.                 $this->mAjaxLibs[$ajaxLibTRUE;
  1523.             }
  1524.  
  1525.             if( is_array( $pLibHash )) {
  1526.                 foreach( $pLibHash as $lib ) {
  1527.                     $fullLib = ($lib[0] == '/' ? '' : $pLibPath).$lib;
  1528.                     $this->loadJavascript$fullLib$pPack$pos++$joined );
  1529.                 }
  1530.             }
  1531.  
  1532.             $ret = TRUE;
  1533.         }
  1534.         return $ret;
  1535.     }
  1536.  
  1537.     /**
  1538.      * check to see if a given ajax library is loaded
  1539.      *
  1540.      * @param array $pAjaxLib
  1541.      * @access public
  1542.      * @return TRUE on success, FALSE on failure
  1543.      */
  1544.     function isAjaxLib( $pAjaxLib ) {
  1545.         if( !empty( $this->mAjaxLibs && !empty$pAjaxLib )) {
  1546.             return in_array( strtolower( $pAjaxLib ), array_keys( $this->mAjaxLibs ));
  1547.         }
  1548.     }
  1549.  
  1550.     /**
  1551.      * scan packages for <pkg>/templates/html_head_inc.tpl or footer_inc.tpl files
  1552.      *
  1553.      * @param string $pFilename Name of template file we want to scan for and collect
  1554.      * @access private
  1555.      * @return void
  1556.      */
  1557.     function loadTplFiles( $pFilename ) {
  1558.         global $gBitSystem;
  1559.         // these package templates will be included last
  1560.         $prepend = array( 'kernel' );
  1561.         $append = array( 'themes' );
  1562.         $anti = $mid = $post = array();
  1563.         foreach( $gBitSystem->mPackages as $package => $info {
  1564.             if( !empty( $info['path'] )) {
  1565.                 $file = "{$info['path']}templates/{$pFilename}.tpl";
  1566.                 $out = "bitpackage:{$package}/{$pFilename}.tpl";
  1567.                 if( is_readable( $file )) {
  1568.                     if( in_array( $package, $prepend )) {
  1569.                         $anti[] = $out;
  1570.                     } elseif( in_array( $package, $append )) {
  1571.                         $post[] = $out;
  1572.                     } else {
  1573.                         $mid[] = $out;
  1574.                     }
  1575.                 }
  1576.             }
  1577.         }
  1578.         $this->mAuxFiles['templates'][$pFilenamearray_merge$anti$mid$post );
  1579.     }
  1580.  
  1581.     /**
  1582.      * loadAuxFile will add a file to the mAuxFiles hash for later processing
  1583.      *
  1584.      * @param array $pFile Full path to the file in question
  1585.      * @param string $pType specifies what files to join. typical values include 'js', 'css'
  1586.      * @param numeric $pPosition Specify the position of the javascript file in the load process.
  1587.      *                           If the selected position is occupied, it will search for the next free position in the hash.
  1588.      * @access public
  1589.      * @return TRUE on success, FALSE on failure
  1590.      */
  1591.     function loadAuxFile( $pFile = NULL, $pType = NULL, $pPosition = 1, $pAuxFile = TRUE ) {
  1592.         if( !empty( $pFile ) && !empty( $pType )) {
  1593. //            if( $pFile = realpath( $pFile )) {
  1594.                 if( $pAuxFile ) {
  1595.                     $fileHash =& $this->mAuxFiles;
  1596.                 } else {
  1597.                     $fileHash =& $this->mRawFiles;
  1598.                 }
  1599.  
  1600.                 if( !$this->isAuxFile$pFile$pType$pAuxFile )) {
  1601.                     // if the selected position is occupied, we'll try to load it in the next position
  1602.                     if( !empty( $fileHash[$pType][$pPosition] )) {
  1603.                         $this->loadAuxFile$pFile$pType++$pPosition$pAuxFile );
  1604.                     } else {
  1605.                         $fileHash[$pType][$pPosition] = $pFile;
  1606.                         // ensure that hash is sorted correctly
  1607.                         ksort( $fileHash[$pType] );
  1608.  
  1609.                         return TRUE;
  1610.                     }
  1611.                 }
  1612. //            }
  1613.         }
  1614.         return FALSE;
  1615.     }
  1616.  
  1617.     /**
  1618.      * Load an addition javascript file
  1619.      *
  1620.      * @param string $pJavascriptFile Full path to javascript file
  1621.      * @param boolean $pPack Set to true if you want to pack the javascript file
  1622.      * @param numeric $pPosition Specify the position of the javascript file in the load process
  1623.      * @note
  1624.      *  - generic javascript libraries are loaded between 1 and 99
  1625.      *  - ajax javascript libraries use position numbers between 100 and 599
  1626.      *  - by default all loaded javascript files are after 600.
  1627.      * @access public
  1628.      * @return TRUE on success, FALSE on failure
  1629.      */
  1630.     function loadJavascript( $pJavascriptFile, $pPack = FALSE, $pPosition = 600, $pJoined = TRUE ) {
  1631.         global $gBitSystem;
  1632.         $ret = FALSE;
  1633.         if( !empty( $pJavascriptFile )) {
  1634.             if( $pPack && $gBitSystem->isFeatureActive'themes_packed_js_css' && function_exists'shell_exec' && shell_exec'which java' ) ) {
  1635.                 if( is_file( $pJavascriptFile )) {
  1636.                     // get a name for the cache file we're going to store
  1637.                     $cachefile = md5( $pJavascriptFile ).'.js';
  1638.  
  1639.                     // if the file hasn't been packed and cached yet, we do that now.
  1640.                     if( !$this->mThemeCache->isCached$cachefilefilemtime$pJavascriptFile ))) {
  1641.                         /* DEPRECATED in favor of better yui compressor
  1642.                         require_once( UTIL_PKG_PATH.'javascript/class.JavaScriptPacker.php' );
  1643.                         $packer = new JavaScriptPacker( file_get_contents( $pJavascriptFile ) );
  1644.                         $this->mThemeCache->writeCacheFile( $cachefile, $packer->pack() );
  1645.                         */
  1646.                         $cacheData = shell_exec( 'java -jar '.UTIL_PKG_PATH.'yui/yuicompressor-2.4.2.jar --type js '.$pJavascriptFile );
  1647.                         $this->mThemeCache->writeCacheFile$cachefile$cacheData );
  1648.                     }
  1649.  
  1650.                     // update javascript file with new path
  1651.                     $pJavascriptFile = $this->mThemeCache->getCacheFile$cachefile );
  1652.                 }
  1653.             }
  1654.  
  1655.             $ret = $this->loadAuxFile$pJavascriptFile'js'$pPosition$pJoined && $gBitSystem->isFeatureActive'themes_joined_js_css' )));
  1656.         }
  1657.         return $ret;
  1658.     }
  1659.  
  1660.     /**
  1661.      * Load an additional CSS file
  1662.      *
  1663.      * @param array $pCssFile Full path to CSS file
  1664.      * @param numeric $pPosition Specify the position of the javascript file in the load process
  1665.      * @param boolean $pJoined Adds the file to the list of files to be concatenated into a single file
  1666.      * @param boolean $pForce Forces the css file to always be loaded, should only be used by active style
  1667.      * @access public
  1668.      * @return TRUE on success, FALSE on failure
  1669.      */
  1670.     function loadCss( $pCssFile, $pPack = TRUE, $pPosition = 300, $pJoined = TRUE, $pForce = FALSE ) {
  1671.         global $gBitSystem;
  1672.         $ret = FALSE;
  1673.         if( !empty( $pCssFile ) && ( !$gBitSystem->isFeatureActive'themes_disable_pkg_css' || $pForce )) {
  1674.             // only manipulate css file if we're joining or packing the files
  1675.             if(( $pJoined && $gBitSystem->isFeatureActive'themes_joined_js_css' )) || $pPack && $gBitSystem->isFeatureActive'themes_packed_js_css' ))) {
  1676.                 $pCssFile = $this->packCss$pCssFile$pPack && $gBitSystem->isFeatureActive'themes_packed_js_css' )));
  1677.             }
  1678.  
  1679.             $ret = $this->loadAuxFile$pCssFile'css'$pPosition$pJoined && $gBitSystem->isFeatureActive'themes_joined_js_css' )));
  1680.         }
  1681.         return $ret;
  1682.     }
  1683.  
  1684.     /**
  1685.      * simply pack css file by removing excess whitespace and comments
  1686.      *
  1687.      * @param array $pCssFile full path to css file
  1688.      * @access private
  1689.      * @return TRUE on success, FALSE on failure
  1690.      */
  1691.     function packCss( $pCssFile, $pPack = TRUE ) {
  1692.         $ret = FALSE;
  1693.         if( !empty( $pCssFile ) && is_readable( $pCssFile )) {
  1694.             $cachefile = md5( $pCssFile ).'.css';
  1695.  
  1696.             if( !$this->mThemeCache->isCached$cachefilefilemtime$pCssFile ))) {
  1697.                 $content = file_get_contents( $pCssFile )."\n";
  1698.  
  1699.                 // now that @import has been dealt with, there still might be some url()s in the file.
  1700.                 // if we have any url() in the CSS file, we need to fix the path to the file with an absolute URL
  1701.                 if( preg_match_all( "#\burl\s*\((.*?)\)#i", $content, $urls )) {
  1702.                     foreach( $urls[1] as $key => $url ) {
  1703.                         if( $url = $this->relativeToAbsolute$url$pCssFile )) {
  1704.                             $content = str_replace( $urls[1][$key], $url, $content );
  1705.                         }
  1706.                     }
  1707.                 }
  1708.  
  1709.                 // if we have an @import(), we fetch that file and insert it
  1710.                 if( preg_match_all( "#@import([^;]*);#", $content, $imports )) {
  1711.                     foreach( $imports[1] as $key => $import ) {
  1712.                         if( $file = $this->relativeToAbsolute$import$pCssFileFALSE )) {
  1713.                             // since we're packing later on, we don't pack here, otherwise the same sections will be packed multiple times
  1714.                             $content = str_replace( $imports[0][$key], file_get_contents( $this->packCss$fileFALSE ))$content );
  1715.                         }
  1716.                     }
  1717.                 }
  1718.  
  1719.                 // now pack the css file if wanted
  1720.                 if( $pPack ) {
  1721.                     $packer = array(
  1722. //                        "#/\*.*\*/#"           => "",       // one line comments -- disabled for now since it causes problems when someone has a multiline comment and closes it with /* */
  1723.                         "#\n\s*#s"             => "\n",     // leading whitespace
  1724.                         "#[\t ]+#"             => " ",      // reduce whitespace
  1725.                         "#,\s*#s"              => ",",      // whitespace after ,
  1726.                         "#[ \t]*([:;])[ \t]*#" => "$1",     // whitespace around : ;
  1727.                         "#;\n+#"               => ";",      // newlines after ;
  1728.                         "#\s*([\{\}])\s*#"     => "$1",     // whitespace around { }
  1729.                         "#\}#"                 => "}\n",    // insert newlines after } for readability
  1730.                         "#{([^\}]*){#"         => "{\n$1{", // insert newlines after { when there's a second { on that line ( e.g.: @media{body{...} )
  1731.                         "#.*{\s*\}#"           => '',       // remove empty definitions ( thanks to the ',' regex above, things like h1,h2,h3 {} should all be on one line )
  1732.                         "#\n+#"                => "\n",     // excess newlines
  1733.                     );
  1734.                     $content = preg_replace( array_keys( $packer ), array_values( $packer ), $content );
  1735.                 }
  1736.  
  1737.                 // css files have been compressed and url()s have been fixed
  1738.                 $this->mThemeCache->writeCacheFile$cachefile$content );
  1739.             }
  1740.             $ret = $this->mThemeCache->getCacheFile$cachefile );
  1741.         }
  1742.         return $ret;
  1743.     }
  1744.  
  1745.     /**
  1746.      * relativeToAbsolute convert a relative or absolute URL to an absolute URL or path
  1747.      *
  1748.      * @param string $pUrl url() in the css file
  1749.      * @param string $pCssFile full path to the css file calling the url()
  1750.      * @param boolean $pReturnUrl return URL or path to file
  1751.      * @access private
  1752.      * @return URL/path on success, FALSE on failure
  1753.      */
  1754.     function relativeToAbsolute( $pUrl, $pCssFile, $pReturnUrl = TRUE ) {
  1755.         $ret = FALSE;
  1756.         if( !empty( $pUrl ) && !empty( $pCssFile )) {
  1757.             // clean up url
  1758.             if( preg_match( "#url\s*\(#", $pUrl )) {
  1759.                 $pUrl = trim( preg_replace( "#url\s*\(([^\)]*)\)#", "$1", $pUrl ));
  1760.             }
  1761.  
  1762.             $pUrl = trim( preg_replace( "#[\"']#", "", $pUrl ));
  1763.  
  1764.             if( strpos( $pUrl, "http" ) === 0 ) {
  1765.                 // don't do anything
  1766.             } elseif( strpos( $pUrl, "/" ) === 0 ) {
  1767.                 // if this is an absolute url, we check if the file exists
  1768.                 $ret = substr_replace( $pUrl, BIT_ROOT_PATH, 0, strlen( BIT_ROOT_URL ));
  1769.             } else {
  1770.                 // this url is relative to the original file
  1771.                 $ret = realpath( dirname( $pCssFile )."/".$pUrl );
  1772.             }
  1773.  
  1774.             if( $pReturnUrl ) {
  1775.                 if (is_windows() ) {
  1776.                     $ret = str_replace( '\\', '/',  $ret );
  1777.                     // Put first forward slash back
  1778.                     $ret = substr_replace($ret, '\\', 2, 1 );
  1779.                     $winBitRootPath = str_replace( '\\', '/',  BIT_ROOT_PATH );
  1780.                     // Put first forward slash back
  1781.                     $winBitRootPath = substr_replace($winBitRootPath, '\\', 2, 1 );
  1782.                     $ret = str_replace( $winBitRootPath, BIT_ROOT_URL, $ret );
  1783.                 } else {
  1784.                     $ret = str_replace( BIT_ROOT_PATH, BIT_ROOT_URL, $ret );
  1785.                 }
  1786.             } else if (is_windows() ) {
  1787.                 $ret = str_replace(  '/', '\\', $ret );
  1788.             }
  1789.         }
  1790.         return $ret;
  1791.     }
  1792.  
  1793.     /**
  1794.      * joinAuxFiles will join all files in mAuxFiles[hash] into one cached file. This helps keep our HTTP requests down to a minimum.
  1795.      *
  1796.      * @param string $pType specifies what files to join. typical values include 'js', 'css'
  1797.      * @access private
  1798.      * @return url to cached file
  1799.      */
  1800.     function joinAuxFiles( $pType ) {
  1801.         global $gBitSystem;
  1802.         $ret = FALSE;
  1803.  
  1804.         // remove conflicting aux files
  1805.         $this->cleanAuxFiles$pType );
  1806.  
  1807.         if(( $pType == 'js' || $pType == 'css' && !$gBitSystem->isFeatureActive'themes_joined_js_css' )) {
  1808.             return $ret;
  1809.         }
  1810.  
  1811.         if( !empty( $pType ) && !empty( $this->mAuxFiles[$pType&& is_array$this->mAuxFiles[$pType)) {
  1812.             $cachestring = '';
  1813.             $lastmodified = 0;
  1814.             // get a unique cachefile name for this set of javascript files
  1815.             foreach( $this->mAuxFiles[$pTypeas $file {
  1816.                 if( is_file( $file )) {
  1817.                     $cachestring .= '|'.$file;
  1818.                     $lastmodified = max( $lastmodified, filemtime( $file ));
  1819.                 }
  1820.             }
  1821.             $cachefile = md5( $cachestring ).'.'.$pType;
  1822.  
  1823.             if( !$this->mThemeCache->isCached$cachefile$lastmodified )) {
  1824.                 $contents = '';
  1825.                 foreach( $this->mAuxFiles[$pTypeas $file {
  1826.                     // if we have an extension to check against, we'll do that
  1827.                     $chars = 0 - ( strlen( $pType ) + 1 );
  1828.                     if( !empty( $pType ) && substr( $file, $chars ) == '.'.$pType && is_readable( $file )) {
  1829.                         $contents .= file_get_contents( $file )."\n";
  1830.                     }
  1831.                 }
  1832.                 $this->mThemeCache->writeCacheFile$cachefile$contents );
  1833.             }
  1834.  
  1835.             $ret = $this->mThemeCache->getCacheUrl$cachefile );
  1836.         }
  1837.         return $ret;
  1838.     }
  1839.  
  1840.     /**
  1841.      * cleanAuxFiles will remove unwanted aux files if conflicting files have been loaded
  1842.      *
  1843.      * @param string $pType specifies what files to clean up. typical values include 'js', 'css'
  1844.      * @access private
  1845.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  1846.      * @note  It is regrettable that we have this method here but our previous
  1847.      *        use of prototype requires this cleanup and might be needed in the
  1848.      *        future as well
  1849.      */
  1850.     function cleanAuxFiles( $pType ) {
  1851.         // unload files that are not wanted by users
  1852.         if( !empty( $this->mUnloadFiles[$pType)) {
  1853.             foreach( $this->mUnloadFiles[$pTypeas $file {
  1854.                 if( !empty( $this->mAuxFiles[$pType)) {
  1855.                     if( $key = array_search( $file, $this->mAuxFiles[$pType)) {
  1856.                         unset( $this->mAuxFiles[$pType][$key);
  1857.                     }
  1858.                 }
  1859.  
  1860.                 if( !empty( $this->mRawFiles[$pType)) {
  1861.                     if( $key = array_search( $file, $this->mRawFiles[$pType)) {
  1862.                         unset( $this->mRawFiles[$pType][$key);
  1863.                     }
  1864.                 }
  1865.             }
  1866.         }
  1867.  
  1868.         // remove conflicting files
  1869.         if( !empty( $pType ) && !empty( $this->mAuxFiles[$pType)) {
  1870.             if( $pType = 'js' ) {
  1871.                 // prototype is loaded for a reason. we'll remove mochikit
  1872.                 if( $this->isAjaxLib'prototype' && $this->isAjaxLib'mochikit' )) {
  1873.                     foreach( $this->mAuxFiles[$pTypeas $key => $js {
  1874.                         if( strstr( $js, 'Mochi' )) {
  1875.                             unset( $this->mAuxFiles[$pType][$key);
  1876.                         }
  1877.                     }
  1878.                 }
  1879.             }
  1880.         }
  1881.  
  1882.         // convert full file path to URL in mRawFiles hash
  1883.         if( !empty( $this->mRawFiles[$pType)) {
  1884.             foreach( $this->mRawFiles[$pTypeas $pos => $file {
  1885.                 if (is_windows() ) {
  1886.                     $file = str_replace( '\\', '/',  $file );
  1887.                     // Put first forward slash back
  1888.                     $file = substr_replace( $file, '\\', 2, 1 );
  1889.                     $winBitRootPath = str_replace( '\\', '/',  BIT_ROOT_PATH );
  1890.                     // Put first forward slash back
  1891.                     $winBitRootPath = substr_replace($winBitRootPath, '\\', 2, 1 );
  1892.                     if ( strpos( $file, $winBitRootPath ) !== FALSE ) {
  1893.                         $this->mRawFiles[$pType][$posBIT_ROOT_URL.substr$filestrlen$winBitRootPath ));
  1894.                     }
  1895.                 } else if ( strpos( $file, BIT_ROOT_PATH ) !== FALSE ) {
  1896.                     $this->mRawFiles[$pType][$posBIT_ROOT_URL.substr$filestrlenBIT_ROOT_PATH ));
  1897.                 }
  1898.             }
  1899.         }
  1900.     }
  1901.  
  1902.     // }}}
  1903.     // {{{ Javascript and CSS unload methods
  1904.     /**
  1905.      * unloadAuxFile
  1906.      *
  1907.      * @param string $pType specifies what files to clean up. typical values include 'js', 'css'
  1908.      * @param array $pFile Full path to the file in question
  1909.      * @access private
  1910.      * @return void
  1911.      */
  1912.     function unloadAuxFile( $pType, $pFile ) {
  1913.         if( !empty( $pType ) && !empty( $pFile ) && is_file( $pFile )) {
  1914.             $this->mUnloadFiles[$pType][$pFile;
  1915.         }
  1916.     }
  1917.  
  1918.     /**
  1919.      * unloadCss
  1920.      *
  1921.      * @param array $pFile Full path to the file in question
  1922.      * @access public
  1923.      * @return void
  1924.      */
  1925.     function unloadCss( $pFile ) {
  1926.         return $this->unloadAuxFile'css'$pFile );
  1927.     }
  1928.  
  1929.     /**
  1930.      * unloadJvascript
  1931.      *
  1932.      * @param array $pFile Full path to the file in question
  1933.      * @access public
  1934.      * @return void
  1935.      */
  1936.     function unloadJavascript( $pFile ) {
  1937.         return $this->unloadAuxFile'js'$pFile );
  1938.     }
  1939.  
  1940.     // }}}
  1941.     // {{{ Javascript and CSS override methods
  1942.     /**
  1943.      * overrideAuxFile Override an aux file
  1944.      *
  1945.      * @param string $pType specifies what files to clean up. typical values include 'js', 'css'
  1946.      * @param array $pOriginalFile Path to old file
  1947.      * @param array $pNewFile Path to new file
  1948.      * @access private
  1949.      * @return boolean TRUE on success, FALSE on failure
  1950.      * @note This can only be used after the original file has been loaded since we're swapping the original one with a new one
  1951.      */
  1952.     function overrideAuxFile( $pType, $pOriginalFile, $pNewFile ) {
  1953.         $ret = FALSE;
  1954.         if( is_file( $pNewFile )) {
  1955.             if( $key = array_search( $pOriginalFile, $this->mAuxFiles[$pType)) {
  1956.                 $this->mAuxFiles[$pType][$key$pNewFile;
  1957.                 $ret TRUE;
  1958.             }
  1959.  
  1960.             if( $key = array_search( $pOriginalFile, $this->mRawFiles[$pType)) {
  1961.                 $this->mRawFiles[$pType][$key$pNewFile;
  1962.                 $ret TRUE;
  1963.             }
  1964.         }
  1965.         return $ret;
  1966.     }
  1967.  
  1968.     /**
  1969.      * overrideCss
  1970.      *
  1971.      * @param array $pOriginalFile Path to old file
  1972.      * @param array $pNewFile Path to new file
  1973.      * @access public
  1974.      * @return boolean TRUE on success, FALSE on failure
  1975.      * @note See overrideAuxFile note
  1976.      */
  1977.     function overrideCss( $pOriginalFile, $pNewFile ) {
  1978.         return $this->overrideAuxFile'css'$pOriginalFile$pNewFile );
  1979.     }
  1980.  
  1981.     /**
  1982.      * overrideJavascript
  1983.      *
  1984.      * @param array $pOriginalFile Path to old file
  1985.      * @param array $pNewFile Path to new file
  1986.      * @access public
  1987.      * @return boolean TRUE on success, FALSE on failure
  1988.      * @note See overrideAuxFile note
  1989.      */
  1990.     function overrideJavascript( $pOriginalFile, $pNewFile ) {
  1991.         return $this->overrideAuxFile'js'$pOriginalFile$pNewFile );
  1992.     }
  1993.     // }}}
  1994.     /**
  1995.      * isAuxFile
  1996.      *
  1997.      * @param array $pFile Full path to file
  1998.      * @param string $pType specifies what files to check. typical values include 'js', 'css'
  1999.      * @access public
  2000.      * @return TRUE on success, FALSE on failure
  2001.      */
  2002.     function isAuxFile( $pFile = NULL, $pType = NULL, $pAuxFile = TRUE ) {
  2003.         if( $pAuxFile ) {
  2004.             $fileHash =& $this->mAuxFiles;
  2005.         } else {
  2006.             $fileHash =& $this->mRawFiles;
  2007.         }
  2008.  
  2009.         if( !empty( $pFile ) && !empty( $pType ) && !empty( $fileHash[$pType] )) {
  2010.             return( in_array( $pFile, $fileHash[$pType] ));
  2011.         }
  2012.     }
  2013.  
  2014.  
  2015.     // }}}
  2016.     // {{{ =================== Miscellaneous Stuff ====================
  2017.     /**
  2018.      * setDisplayMode
  2019.      *
  2020.      * @param string $pDisplayMode
  2021.      * @access public
  2022.      * @return void
  2023.      */
  2024.     function setDisplayMode( $pDisplayMode ) {
  2025.         if( !empty( $pDisplayMode )) {
  2026.             $this->mDisplayMode = $pDisplayMode;
  2027.         }
  2028.     }
  2029.  
  2030.     /**
  2031.      * Set the proper headers for requested output
  2032.      *
  2033.      * @param  $pFormat the output headers. Available options include: html, json, xml or none
  2034.      * @access public
  2035.      */
  2036.     function setFormatHeader( $pFormat = 'html' ) {
  2037.         // this will tell BitSystem::display what headers have been set in case it's been called independently
  2038.         $this->mFormatHeader $pFormat;
  2039.  
  2040.         switch$pFormat {
  2041.             case "xml" :
  2042.                 //since we are returning xml we must report so in the header
  2043.                 //we also need to tell the browser not to cache the page
  2044.                 //see: http://mapki.com/index.php?title=Dynamic_XML
  2045.                 // Date in the past
  2046.                 header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
  2047.                 // always modified
  2048.                 header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" )." GMT" );
  2049.                 // HTTP/1.1
  2050.                 header( "Cache-Control: no-store, no-cache, must-revalidate" );
  2051.                 header( "Cache-Control: post-check=0, pre-check=0", FALSE );
  2052.                 // HTTP/1.0
  2053.                 header( "Pragma: no-cache" );
  2054.                 //XML Header
  2055.                 header( "Content-Type: text/xml" );
  2056.                 break;
  2057.  
  2058.             case "json" :
  2059.                 header( 'Content-type: application/json' );
  2060.                 break;
  2061.  
  2062.             case "none" :
  2063.             case "center_only" :
  2064.                 break;
  2065.  
  2066.             case "html" :
  2067.             default :
  2068.                 header( 'Content-Type: text/html; charset=utf-8' );
  2069.                 break;
  2070.         }
  2071.     }
  2072.  
  2073.     /**
  2074.      * getGraphvizGraphAttributes
  2075.      *
  2076.      * @param array $pParams Override any of the settings coming out of this function
  2077.      * @access public
  2078.      * @return array Hash of default values
  2079.      */
  2080.     function getGraphvizGraphAttributes( $pParams = array() ) {
  2081.         global $gBitSystem;
  2082.         $ret = array(
  2083.             'bgcolor'  => $gBitSystem->getConfig'graphviz_graph_bgcolor''transparent' ),
  2084.             'color'    => $gBitSystem->getConfig'graphviz_graph_color''#000000' ),
  2085.             'fontname' => $gBitSystem->getConfig'graphviz_graph_fontname''Helvetica' ),
  2086.             'fontsize' => $gBitSystem->getConfig'graphviz_graph_fontsize'10 ),
  2087.             'nodesep'  => $gBitSystem->getConfig'graphviz_graph_nodesep''.1' ),
  2088.             'overlap'  => $gBitSystem->getConfig'graphviz_graph_overlap''scale' ),
  2089.             'rankdir'  => $gBitSystem->getConfig'graphviz_graph_rankdir''LR' ),
  2090.             'size'     => '',
  2091.         );
  2092.  
  2093.         foreach$pParams as $key => $value {
  2094.             // any parameter can be prefixed that they can be passed in all at once
  2095.             if( empty( $value ) || preg_match( "@^(edge_|node_)@", $key )) {
  2096.                 unset( $pParams[$key] );
  2097.             } elseif( isset( $ret[preg_replace( '@^graph_@', '', $key )] )) {
  2098.                 $ret[preg_replace( '@^graph_@', '', $key )] = $value;
  2099.             }
  2100.         }
  2101.         return $ret;
  2102.     }
  2103.  
  2104.     /**
  2105.      * getGraphvizNodeAttributes
  2106.      *
  2107.      * @param array $pParams Override any of the settings coming out of this function
  2108.      * @access public
  2109.      * @return array Hash of default values
  2110.      */
  2111.     function getGraphvizNodeAttributes( $pParams = array() ) {
  2112.         global $gBitSystem;
  2113.         $ret = array(
  2114.             'color'     => $gBitSystem->getConfig'graphviz_node_color''#aaaaaa' ),
  2115.             'fillcolor' => $gBitSystem->getConfig'graphviz_node_fillcolor''white' ),
  2116.             'fontname'  => $gBitSystem->getConfig'graphviz_node_fontname''Helvetica' ),
  2117.             'fontsize'  => $gBitSystem->getConfig'graphviz_node_fontsize'10 ),
  2118.             'fontcolor' => $gBitSystem->getConfig'graphviz_node_fontcolor''black' ),
  2119.             'height'    => $gBitSystem->getConfig'graphviz_node_height''.1' ),
  2120.             'overlap'   => $gBitSystem->getConfig'graphviz_node_overlap''scale' ),
  2121.             'penwidth'  => $gBitSystem->getConfig'graphviz_node_penwidth''1' ),
  2122.             'shape'     => $gBitSystem->getConfig'graphviz_node_shape''box' ),
  2123.             'style'     => $gBitSystem->getConfig'graphviz_node_style''rounded,filled' ),
  2124.             'width'     => $gBitSystem->getConfig'graphviz_node_width''.1' ),
  2125.         );
  2126.  
  2127.         foreach$pParams as $key => $value {
  2128.             // any parameter can be prefixed that they can be passed in all at once
  2129.             if( empty( $value ) || preg_match( "@^(edge_|graph_)@", $key )) {
  2130.                 unset( $pParams[$key] );
  2131.             } elseif( isset( $ret[preg_replace( '@^node_@', '', $key )] )) {
  2132.                 $ret[preg_replace( '@^node_@', '', $key )] = $value;
  2133.             }
  2134.         }
  2135.         return $ret;
  2136.     }
  2137.  
  2138.     /**
  2139.      * getGraphvizEdgeAttributes
  2140.      *
  2141.      * @param array $pParams Override any of the settings coming out of this function
  2142.      * @access public
  2143.      * @return array Hash of default values
  2144.      */
  2145.     function getGraphvizEdgeAttributes( $pParams = array() ) {
  2146.         global $gBitSystem;
  2147.         $ret = array(
  2148.             'color'     => $gBitSystem->getConfig'graphviz_edge_color''#888888' ),
  2149.             'fontcolor' => $gBitSystem->getConfig'graphviz_edge_fontcolor''black' ),
  2150.             'fontname'  => $gBitSystem->getConfig'graphviz_edge_fontname''Helvetica' ),
  2151.             'fontsize'  => $gBitSystem->getConfig'graphviz_edge_fontsize'10 ),
  2152.             'style'     => $gBitSystem->getConfig'graphviz_edge_style''solid' ),
  2153.             'dir'       => '',
  2154.             'label'     => '',
  2155.         );
  2156.  
  2157.         foreach$pParams as $key => $value {
  2158.             // any parameter can be prefixed that they can be passed in all at once
  2159.             if( empty( $value ) || preg_match( "@^(node_|graph_)@", $key )) {
  2160.                 unset( $pParams[$key] );
  2161.             } elseif( isset( $ret[preg_replace( '@^edge_@', '', $key )] )) {
  2162.                 $ret[preg_replace( '@^edge_@', '', $key )] = $value;
  2163.             }
  2164.         }
  2165.         return $ret;
  2166.     }
  2167.  
  2168.  
  2169.     // }}}
  2170.     // {{{ =================== Deprecated code ====================
  2171.     // deprecated stuff and temporary place holders
  2172.     //                                                                         --------------- all of these functions will be removed quite soon
  2173.     /**
  2174.      * @deprecated deprecated since version 2.0.0
  2175.      */
  2176.     function storeLayout() {
  2177.         deprecated( 'Please remove this function and use storeModule instead' );
  2178.     }
  2179.     /**
  2180.      * @deprecated deprecated since version 2.0.0
  2181.      */
  2182.     function storeModuleParameters($mod_rsrc, $user_id, $params) {
  2183.         deprecated( 'This method does not work as expected due to changes in the layout schema. we have not found a suitable replacement yet.' );
  2184.     }
  2185.     /**
  2186.      * @deprecated deprecated since version 2.0.0
  2187.      */
  2188.     function getModuleId($mod_rsrc) {
  2189.         deprecated( 'This method does not work as expected due to changes in the layout schema. we have not found a suitable replacement yet.' );
  2190.     }
  2191.     /**
  2192.      * @deprecated deprecated since version 2.0.0
  2193.      */
  2194.     function getStyleCss( $pStyle = NULL ) {
  2195.         deprecated( 'Please use: BitThemes::getStyleCssFile()' );
  2196.         return $this->getStyleCssFile$pStyleTRUE );
  2197.     }
  2198.     // }}}
  2199. }
  2200.  
  2201. function themes_feedback_to_html( $params ) {
  2202.  
  2203.     detoxify( $params );
  2204.     if( !empty( $params['hash'] ) ) {
  2205.         $hash = &$params['hash'];
  2206.     } else {
  2207.         // maybe params were passed in separately
  2208.         $hash = &$params;
  2209.     }
  2210.     $feedback = '';
  2211.     $i = 0;
  2212.     $color = isset( $hash['color'] )?$hash['color']:"000000";
  2213.     foreach( $hash as $key => $val ) {
  2214.         if( $val ) {
  2215.             $keys = array( 'warning', 'success', 'error', 'important', 'note' );
  2216.             if( in_array( $key, $keys )) {
  2217.                 switch( $key ) {
  2218.                     case 'success':
  2219.                         $alertClass = 'alert alert-success';
  2220.                         break;
  2221.                     case 'warning':
  2222.                         $alertClass = 'alert alert-warning';
  2223.                         break;
  2224.                     case 'error':
  2225.                         $alertClass = 'alert alert-danger';
  2226.                         break;
  2227.                     case 'note':
  2228.                     case 'important':
  2229.                     default:
  2230.                         $alertClass = 'alert alert-info';
  2231.                         break;
  2232.                 }
  2233.  
  2234.                 if( !is_array( $val ) ) {
  2235.                     $val = array( $val );
  2236.                 }
  2237.  
  2238.                 foreach( $val as $valText ) {
  2239.                     if( is_array( $valText ) ) {
  2240.                         foreach( $valText as $text ) {
  2241.                             $feedback .= '<span class="inline-block '.$alertClass.'">'.$text.'</span>';
  2242.                         }
  2243.                     } else {
  2244.                         $feedback .= '<span class="inline-block '.$alertClass.'">'.$valText.'</span>';
  2245.                     }
  2246.                 }
  2247.  
  2248.             } else {
  2249.                 /* unfortunately this plugin was written a little strictly and so it expects all params to be display text
  2250.                  * to allow setting of a background color we have to exclude that param when rendering out the html
  2251.                  * otherwise we'll render the color as text. -wjames5
  2252.                  */ 
  2253.                 if ( $key != 'color' ) {
  2254.                     if( is_array( $val ) ) {
  2255.                         foreach( $val as $text ) {
  2256.                             $feedback .= '<span class="'.$key.'">'.$text.'</span>';
  2257.                         }
  2258.                     } else {
  2259.                         $feedback .= '<span class="'.$key.'">'.$val.'</span>';
  2260.                     }
  2261.                 }
  2262.             }
  2263.         }
  2264.     }
  2265.  
  2266.     $html = '';
  2267.     if( !empty( $feedback ) ) {
  2268.         $html .= $feedback;
  2269.     }
  2270.     return $html;
  2271. }
  2272.  
  2273. /**
  2274.  * load content specific theme picked by user
  2275.  *
  2276.  * @param array $pContent
  2277.  * @access public
  2278.  * @return void
  2279.  */
  2280. function themes_content_display( $pContent ) {
  2281.     global $gBitSystem, $gBitSmarty, $gBitThemes, $gBitUser, $gQueryUser;
  2282.  
  2283.     // users_themes='u' is for all users content
  2284.     if( is_a( $pContent, 'LibertyContent' ) && $pContent->getPreference'style' ) ) {
  2285.         $theme = $pContent->getPreference'style' );
  2286.     } elseif( $gBitSystem->getConfig'users_themes' == 'u' {
  2287.         if( $gBitSystem->isFeatureActive'users_preferences' && is_object$pContent && $pContent->isValid() ) {
  2288.             if( $pContent->getField'user_id' == $gBitUser->mUserId {
  2289.                 // small optimization to reduce checking when we are looking at our own content, which is frequent
  2290.                 if( $userStyle = $gBitUser->getPreference'theme' )) {
  2291.                     $theme = $userStyle;
  2292.                 }
  2293.             } else {
  2294.                 $theme = BitUser::getUserPreference( 'theme', NULL, $pContent->getField'user_id' ) );
  2295.             }
  2296.         }
  2297.     }
  2298.  
  2299.     if( !empty( $theme ) && $theme != DEFAULT_THEME ) {
  2300.         $gBitThemes->setStyle$theme );
  2301.         if!is_object$gQueryUser ) ) {
  2302.             $userClass = $gBitSystem->getConfig'user_class''BitPermUser' );
  2303.             require_onceUSERS_PKG_PATH $userClass .'.php' );
  2304.             $gQueryUser new $userClass$pContent->getField'user_id' ) );
  2305.             $gQueryUser->load();
  2306.             $gBitSmarty->assign_by_ref'gQueryUser'$gQueryUser );
  2307.         }
  2308.     }
  2309. }
  2310.  
  2311. /**
  2312.  * themes_content_list
  2313.  *
  2314.  * @param array $pContent
  2315.  * @param array $pListHash
  2316.  * @access public
  2317.  * @return void
  2318.  */
  2319. function themes_content_list( $pContent, $pListHash ) {
  2320.     global $gBitSystem, $gBitSmarty, $gBitThemes, $gBitUser, $gQueryUser;
  2321.     // users_themes='u' is for all users content
  2322.     if( $gBitSystem->getConfig'users_themes' == 'u' {
  2323.         if( $gBitSystem->isFeatureActive'users_preferences' && !empty$pListHash['user_id') ) {
  2324.             if( $pListHash['user_id'] == $gBitUser->mUserId {
  2325.                 // small optimization to reduce checking when we are looking at our own content, which is frequent
  2326.                 if( $userStyle = $gBitUser->getPreference('theme') ) {
  2327.                     $theme = $userStyle;
  2328.                 }
  2329.             } else {
  2330.                 $theme = BitUser::getUserPreference( 'theme', NULL, $pListHash['user_id'] );
  2331.             }
  2332.         }
  2333.     }
  2334.     if( !empty( $theme ) && $theme != DEFAULT_THEME ) {
  2335.         $gBitThemes->setStyle$theme );
  2336.         if!is_object$gQueryUser ) ) {
  2337.             $userClass = $gBitSystem->getConfig'user_class''BitPermUser' );
  2338.             require_onceUSERS_PKG_PATH $userClass .'.php' );
  2339.             $gQueryUser new $userClass$pListHash['user_id');
  2340.             $gQueryUser->load();
  2341.             $gBitSmarty->assign_by_ref'gQueryUser'$gQueryUser );
  2342.         }
  2343.     }
  2344. }
  2345.  
  2346. /* vim: :set fdm=marker : */

Documentation generated on Wed, 29 Jul 2015 13:56:05 +0000 by phpDocumentor 1.5.0-lsces