File Manager
<?php
final class cge_jsloader
{
static $_required = array();
static $_cache;
private function __construct() {}
private static function _load_cache()
{
if( !is_array(self::$_cache) ) {
$cache = array();
$cache_key = 'c'.md5(__CLASS__);
$tmp = cms_siteprefs::get($cache_key);
if( $tmp ) $cache = unserialize($tmp);
self::$_cache = $cache;
}
}
private static function _save_cache()
{
$cache_key = 'c'.md5(__CLASS__);
cms_siteprefs::set($cache_key,serialize(self::$_cache));
}
public static function register(cgjsloader_libdefn $rec)
{
if( !$rec->valid() ) throw new CmsInvalidDataException('attempt to register js lib with invalid cgjsloader_libdefn object');
$lib = self::_find_lib($rec->name);
if( is_object($lib) && $lib->module != $rec->module ) return; // nothing to do.
// add this item
self::_load_cache();
self::$_cache[$rec->name] = $rec;
self::_save_cache();
}
public static function unregister_by_module($module_name)
{
self::_load_cache();
$out = array();
foreach( self::$_cache as $key => $rec ) {
if( $rec->module != $module_name ) $out[$key] = $rec;
return;
}
self::$_cache = $out;
self::_save_cache();
}
public static function require_lib($name)
{
if( !is_array($name) ) $name = explode(',',$name);
foreach( $name as $one_name ) {
$lib = self::_find_lib($one_name);
if( !$lib ) throw new \Exception("Unknown required js lib $one_name");
$obj = $lib;
}
self::$_required[] = $obj;
}
public static function require_jsext($url)
{
// externals cannot have dependencies...
$obj = new stdClass;
$obj->jsurl = $url;
self::$_required[] = $obj;
}
public static function add_jsfile($file,$depends = null)
{
if( !$file || !is_string($file) ) return;
// assume full path
$tryfiles = array($file);
// assume relative to module directory
$module_name = cge_tmpdata::get('module');
if( $module_name ) {
$mod = cms_utils::get_module($module_name);
if( $mod ) $tryfiles[] = $mod->GetModulePath()."/$file";
}
// assume relative to uploads path
$config = cmsms()->GetConfig();
$tryfiles[] = $config['uploads_path']."/$file";
// assume relative to root path
$tryfiles[] = $config['root_path']."/$file";
$fnd = null;
foreach( $tryfiles as $fn ) {
if( file_exists($fn) ) {
$fnd = $fn;
break;
}
}
if( !$fnd ) throw new CmsInvalidDataException("could not find jsfile $file in any of the searched directories");
$obj = new StdClass;
$obj->jsfile = $fnd;
if( $depends ) {
if( !is_array($depends) ) $depends = array($depends);
$obj->depends = $depends;
}
self::$_required[] = $obj;
}
public static function add_js($code,$depends = null)
{
if( !$code || !is_string($code) ) return;
// todo: remove script tags
$obj = new StdClass;
$obj->code = $code;
if( $depends ) {
if( !is_array($depends) ) $depends = array($depends);
$obj->depends = $depends;
}
self::$_required[] = $obj;
}
/*
* do this for 2.0
*/
public static function require_css($name,$depends = null)
{
$obj = new stdClass;
$obj->cssname = trim($name);
if( $depends ) {
if( !is_array($depends) ) $depends = array($depends);
$obj->depends = $depends;
}
self::$_required[] = $obj;
}
public static function require_cssext($url)
{
// externals cannot have dependencies...
$obj = new stdClass;
$obj->cssurl = $url;
self::$_required[] = $obj;
}
public static function add_cssfile($file,$depends = null)
{
if( !$file || !is_string($file) ) return;
// assume full path
$tryfiles = array($file);
// assume relative to module directory
$module_name = cge_tmpdata::get('module');
if( $module_name ) {
$mod = cms_utils::get_module($module_name);
if( $mod ) $tryfiles[] = $mod->GetModulePath()."/$file";
}
// assume relative to uploads path
$config = cmsms()->GetConfig();
$tryfiles[] = $config['uploads_path']."/$file";
$tryfiles[] = $config['root_path']."/$file";
$fnd = null;
foreach( $tryfiles as $fn ) {
if( file_exists($fn) ) {
$fnd = $fn;
break;
}
}
if( !$fnd ) throw new CmsInvalidDataException("could not find jsfile $file in any of the searched directories");
$obj = new StdClass;
$obj->cssfile = $fnd;
if( $depends ) {
if( !is_array($depends) ) $depends = array($depends);
$obj->depends = $depends;
}
self::$_required[] = $obj;
}
public static function add_css($styles,$depends)
{
if( !$styles || !is_string($styles) ) return;
// todo: remove script tags
$obj = new StdClass;
$obj->styles = $styles;
if( $depends ) {
if( !is_array($depends) ) $depends = array($depends);
$obj->depends = $depends;
}
self::$_required[] = $obj;
}
private static function _find_lib($name)
{
self::_load_cache();
if( isset(self::$_cache[$name]) ) return self::$_cache[$name];
}
private static function _resolve_dependencies($rec,&$out,$excludes)
{
self::_load_cache();
if( isset($rec->lib) && in_array($rec->lib,$excludes) ) return;
if( isset($rec->name) && in_array($rec->name,$excludes) ) return;
// if this rec depends on something else
if( isset($rec->depends) ) {
$depends = $rec->depends;
if( !is_array($depends) ) $depends = explode(',',$depends);
foreach( $depends as $dependency ) {
$dep = self::_find_lib($dependency);
if( !$dep ) throw new \Exception('Missing js dependency: '.$dependency);
self::_resolve_dependencies($dep,$out,$excludes);
}
}
// now handle this item.
$sig = md5(serialize($rec));
if( !isset($out[$sig]) ) $out[$sig] = $rec;
}
public static function render($opts = null)
{
if( count(self::$_required) == 0 ) return; // nothing to do.
// process options
$options = array();
$options['excludes'] = array();
if( !cmsms()->is_frontend_request() ) {
// the cmsms admin console includes versions of these.
$excludes = array();
$excludes[] = 'jquery';
$excludes[] = 'ui';
$excludes[] = 'fileupload';
$options['excludes'] = $excludes;
}
if( is_array($opts) ) $options = array_merge_recursive($options,$opts);
if( isset($options['no_jquery']) && !in_array('jquery',$options['excludes']) ) {
$options['excludes'][] = 'jquery';
}
if( isset($options['excludes']) && count($options['excludes']) ) {
// clean up the excludes
$out = array();
foreach( $options['excludes'] as &$str ) {
$str = strtolower(trim($str));
if( !$str ) continue;
if( !in_array($str,$out) ) $out[] = $str;
}
$options['excludes'] = $out;
}
// expand some options to simple variables.
$config = cmsms()->GetConfig();
$cache_lifetime = (int)cge_utils::get_param($config,'cgejs_cachelife',24);
$cache_lifetime = (isset($options['cache_lifetime'])) ? (int)$options['cache_lifetime'] : $cache_lifetime;
$nocache = cge_utils::get_param($config,'cgejs_nocache',0);
$nocache = (isset($options['nocache']) || $nocache)?TRUE:$nocache;
$nominify = cge_utils::get_param($config,'cgejs_nominify',0);
$nominify = (isset($options['nominify']) || $nominify)?TRUE:$nominify;
$nocsssmarty = (isset($options['nocsssmarty']) || $nominify)?TRUE:$nocache;
$addkey = cge_utils::get_param($options,'addkey','');
$do_js = (isset($options['no_js']))?FALSE:TRUE;
$do_css = (isset($options['no_css']))?FALSE:TRUE;
$js_fmt = '<script type="text/javascript" src="%s"></script>';
$css_fmt = '<link type="text/css" rel="stylesheet" href="%s"/>';
if( !$nocache && !$nominify ) require_once(dirname(__FILE__).'/jsmin.php');
$get_relative_url = function($filename) {
$config = cmsms()->GetConfig();
$relative_url = '';
if( startswith($filename,$config['root_path']) ) {
$relative_url = str_replace($config['root_path'],$config['root_url'],dirname($filename));
if( !endswith($relative_url,'/') ) $relative_url .= '/';
if( startswith($relative_url,'http:') ) $relative_url = substr($relative_url,5);
if( startswith($relative_url,'https:') ) $relative_url = substr($relative_url,6);
}
return $relative_url;
};
$fix_css_urls = function($css,$url_prefix) {
$css_search = '#url\(\s*[\'"]?(.*?)[\'"]?\s*\)#';
$css_url_fix = function($matches) use ($url_prefix) {
if( startswith($matches[1],'data:') ) return $matches[0];
if( startswith($matches[1],'http:') ) return $matches[0];
if( startswith($matches[1],'https:') ) return $matches[0];
if( startswith($matches[1],'//') ) return $matches[0];
//$str = substr($matches[1],0,-1);
$str = $matches[1];
return "url('{$url_prefix}{$str}')";
};
$out = preg_replace_callback($css_search,$css_url_fix,$css);
return $out;
};
// determine if we have to process all this cruft (which could potentially be very expensive)
$sig = md5(serialize(self::$_required).serialize($options));
$cache_js = TMP_CACHE_LOCATION."/cgejs_{$sig}.js";
$cache_css = TMP_CACHE_LOCATION."/cgejs_{$sig}.css";
$do_processing = TRUE;
if( !$nocache ) {
if( file_exists($cache_js) || file_exists($cache_css) ) {
$etime = time() - $cache_lifetime * 3600;
$mtime1 = @filemtime($cache_js);
$mtime2 = @filemtime($cache_css);
if( $mtime1 < $etime && $mtime2 < $etime ) $do_processing = FALSE;
}
}
if( $do_processing ) {
// okay, we have work to do.
$required = array();
// now expand all our dependencies.
$list_0 = array();
foreach( self::$_required as $rec ) {
if( isset($rec->depends) ) {
self::_resolve_dependencies($rec,$list_0,$options['excludes']);
}
else {
$sig = md5(serialize($rec));
$list_0[$sig] = $rec;
}
}
// now check for callback items
// and get their code... this may be an expensive process
// note: may also have dependencies
$list = array();
foreach( $list_0 as $rec ) {
if( isset($rec->callback) ) {
$tmp = call_user_func($rec->callback,$rec->name);
if( is_object($tmp) && (isset($tmp->code) || isset($tmp->styles)) ) {
$list[] = $tmp;
}
}
else {
$list[] = $rec;
}
}
//
// process js
//
if( $do_js && $list && count($list) ) {
$txt = null;
foreach( $list as $rec ) {
$js = null;
// get js for this item
if( isset($rec->jsfile) ) {
$jsfile = $rec->jsfile;
if( !is_array($jsfile) ) $jsfile = array($jsfile);
foreach( $jsfile as $one_file ) {
$js .= file_get_contents($one_file);
}
}
else if( isset($rec->code) ) {
$js = $rec->code;
}
if( $js ) $txt .= $js."\n";
}
if( !$nocache && !$nominify ) $txt = JSMin::minify($txt);
if( $txt ) file_put_contents($cache_js,$txt);
} // do_js
//
// process css
//
if( $do_css && $list && count($list) ) {
$txt = null;
foreach( $list as $rec ) {
$css = null;
if( isset($rec->cssfile) ) {
$cssfile = $rec->cssfile;
if( !is_array($cssfile) ) $cssfile = array($cssfile);
foreach( $cssfile as $one_file ) {
$tmp = file_get_contents($one_file);
$relative_url = $get_relative_url($one_file);
$tmp = $fix_css_urls($tmp,$relative_url);
$css .= $tmp;
}
}
else if( isset($rec->cssname) ) {
if( version_compare(CMS_VERSION,'1.99-alpha0') < 0 ) {
$query = 'SELECT css_id, css_name, css_text FROM '.cms_db_prefix().'css WHERE css_name = ?';
$db = cmsms()->GetDb();
$row = $db->GetRow($query,array($rec->cssname));
if( !is_array($row) ) return;
$css = trim($row['css_text']);
}
else {
$css = CmsLayoutStylesheet::load($rec->cssname)->get_content();
}
}
else if( isset($rec->styles) ) {
$css = $rec->styles;
}
// todo: fix up relative urls in css
if( $css ) $txt .= $css."\n";
}
// process this stuff through smarty with [[ and ]] delimiters
// todo: or lesscss
if( !$nocsssmarty ) {
// sorry, not done yet.
}
if( !$nocache && !$nominify ) $txt = JSMin::minify($txt);
if( $txt ) file_put_contents($cache_css,$txt);
} // do_css
} // do processing
// do the output.
if( $nocache ) {
$cache_js .= '?_t='.time();
$cache_css .= '?_t='.time();
}
$out = null;
$cache_url = $config['root_url'].'/tmp/cache/'.basename($cache_js);
$out .= trim(sprintf($js_fmt,$cache_url))."\n";
$cache_url = $config['root_url'].'/tmp/cache/'.basename($cache_css);
$out .= trim(sprintf($css_fmt,$cache_url))."\n";
// all freaking done
return $out;
}
}
?>
File Manager Version 1.0, Coded By Lucas
Email: hehe@yahoo.com