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

Source for file BitThemes1.php

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

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