![]() |
Xataface 2.0
Xataface Application Framework
|
00001 <?php 00006 class Dataface_ModuleTool { 00007 00008 var $_modules; 00009 00010 var $_db_versions; 00011 00012 00013 public static function &getInstance(){ 00014 static $instance = 0; 00015 00016 if ( !is_object($instance) ){ 00017 $instance = new Dataface_ModuleTool(); 00018 00019 } 00020 return $instance; 00021 00022 } 00023 00024 00028 public function getDbVersion($modname){ 00029 if ( !isset($this->_db_versions) ){ 00030 $this->_db_versions = array(); 00031 $sql = "select module_name, module_version from dataface__modules"; 00032 $res = mysql_query($sql, df_db()); 00033 if ( !$res ){ 00034 $res = mysql_query("create table dataface__modules ( 00035 module_name varchar(255) not null primary key, 00036 module_version int(11) 00037 )", df_db()); 00038 if ( !$res ) throw new Exception(mysql_error(df_db())); 00039 $res = mysql_query($sql, df_db()); 00040 } 00041 if ( !$res ) throw new Exception(mysql_error(df_db())); 00042 while ($row = mysql_fetch_assoc($res) ){ 00043 $this->_db_versions[$row['module_name']] = $row['module_version']; 00044 } 00045 @mysql_free_result($res); 00046 00047 } 00048 $out = @$this->_db_versions[$modname]; 00049 if ( !$out ) return 0; 00050 return $out; 00051 } 00052 00065 public function getFsVersion($modname, $path){ 00066 $versionPath = dirname($path).DIRECTORY_SEPARATOR.'version.txt'; 00067 if ( !file_exists($versionPath) ) return 0; 00068 $str = trim(file_get_contents($versionPath)); 00069 if ( preg_match('/(\d+)$/', $str, $matches) ){ 00070 return intval($matches[1]); 00071 } else { 00072 return 0; 00073 } 00074 } 00075 00082 public function updateModule($modname, $path){ 00083 $installpath = dirname($path).DIRECTORY_SEPARATOR.'installer.php'; 00084 if ( file_exists($installpath) ){ 00085 import($installpath); 00086 $classname = $modname.'_installer'; 00087 $installer = new $classname; 00088 00089 $methods = get_class_methods($classname); 00090 $methods = preg_grep('/^update_([0-9]+)$/', $methods); 00091 00092 $updates = array(); 00093 $fsversion = $this->getFsVersion($modname, $path); 00094 $dbversion = $this->getDbVersion($modname); 00095 00096 foreach ($methods as $method){ 00097 preg_match('/^update_([0-9]+)$/', $method, $matches); 00098 $version = intval($matches[1]); 00099 if ( $version > $dbversion and $version <= $fsversion ){ 00100 $updates[] = $version; 00101 } 00102 } 00103 00104 sort($updates); 00105 00106 if ( $dbversion == 0 ){ 00107 $res = mysql_query("insert into dataface__modules (module_name,module_version) 00108 values ('".addslashes($modname)."',-1)", df_db()); 00109 if ( !$res ) throw new Exception(mysql_error(df_db())); 00110 } 00111 00112 foreach ($updates as $update ){ 00113 $method = 'update_'.$update; 00114 $res = $installer->$method(); 00115 if ( PEAR::isError($res) ) return $res; 00116 $res = mysql_query("update dataface__modules set `module_version`='".addslashes($update)."'", df_db()); 00117 if ( !$res ) throw new Exception(mysql_error(df_db()), E_USER_ERROR); 00118 } 00119 00120 00121 00122 } 00123 00124 00125 } 00126 00150 public function getModuleURL($file){ 00151 00152 if ( realpath($file) == realpath(DATAFACE_SITE_PATH.'/modules/'.basename(dirname($file)).'/'.basename($file)) ){ 00153 return DATAFACE_SITE_URL.'/modules/'.rawurlencode(basename(dirname($file))); 00154 } else if (realpath($file) == realpath(DATAFACE_PATH.'/modules/'.basename(dirname($file)).'/'.basename($file)) ){ 00155 return DATAFACE_URL.'/modules/'.rawurlencode(basename(dirname($file))); 00156 } else { 00157 throw new Exception("Could not find URL for file $file in module tool"); 00158 } 00159 } 00160 00171 function displayBlock($blockName, $params=array()){ 00172 //echo "here"; 00173 $app =& Dataface_Application::getInstance(); 00174 if ( !isset($app->_conf['_modules']) or count($app->_conf['_modules']) == 0 ){ 00175 return false; 00176 } 00177 $out = false; 00178 foreach ($app->_conf['_modules'] as $name=>$path){ 00179 //echo "Checking $name : $path"; 00180 $mod =& $this->loadModule($name); 00181 if ( method_exists($mod,'block__'.$blockName) ){ 00182 //echo "Method exists"; 00183 $res = call_user_func(array(&$mod, 'block__'.$blockName), $params); 00184 if ( !$res !== false ){ 00185 $out = true; 00186 } 00187 00188 } 00189 } 00190 return $out; 00191 } 00192 00198 function &loadModule($name, $path=null){ 00199 if ( !isset($path) ){ 00200 if ( preg_match('/^modules_/', $name) ){ 00201 $s = DIRECTORY_SEPARATOR; 00202 $path = preg_replace('/^modules_/', 'modules'.$s, $name).$s.substr($name, strpos($name, '_')+1).'.php'; 00203 } 00204 00205 } 00206 $app =& Dataface_Application::getInstance(); 00207 00208 if ( isset($this->_modules[$name]) ) return $this->_modules[$name]; 00209 if ( class_exists($name) ){ 00210 $this->_modules[$name] = new $name; 00211 return $this->_modules[$name]; 00212 } 00213 00214 if ( !isset($path) and (!@$app->_conf['_modules'] or !is_array($app->_conf['_modules']) or !isset($app->_conf['_modules'][$name])) ){ 00215 return PEAR::raiseError( 00216 df_translate( 00217 'scripts.Dataface.ModuleTool.loadModule.ERROR_MODULE_DOES_NOT_EXIST', 00218 "The module '$name' does not exist.", 00219 array('name'=>$name) 00220 ) 00221 ); 00222 } 00223 if ( !isset($app->_conf['_modules'][$name]) and isset($path) ){ 00224 $app->_conf['_modules'][$name] = $path; 00225 import($path); 00226 if ( $this->getFsVersion($name, $path) > $this->getDbVersion($name) ){ 00227 $this->updateModule($name, $path); 00228 } 00229 00230 } else { 00231 import($app->_conf['_modules'][$name]); 00232 if ( $this->getFsVersion($name, $app->_conf['_modules'][$name]) > $this->getDbVersion($name) ){ 00233 $this->updateModule($name, $app->_conf['_modules'][$name]); 00234 } 00235 } 00236 if ( !class_exists($name) ){ 00237 return PEAR::raiseError( 00238 df_translate( 00239 'scripts.Dataface.ModuleTool.loadModule.ERROR_CLASS_DOES_NOT_EXIST', 00240 "Attempted to load the module '$name' from path '{$app->_conf['_modules'][$name]}' but after loading - no such class was found. Please check to make sure that the class is defined. Or you can disable this module by commenting out the line that says '{$name}={$app->_conf['_modules'][$name]}' in the conf.ini file.", 00241 array('name'=>$name,'path'=>$app->_conf['_modules'][$name]) 00242 ) 00243 ); 00244 } 00245 $this->_modules[$name] = new $name; 00246 return $this->_modules[$name]; 00247 } 00248 00252 function loadModules(){ 00253 $app =& Dataface_Application::getInstance(); 00254 if ( @$app->_conf['_modules'] and is_array($app->_conf['_modules']) ){ 00255 foreach ( array_keys($app->_conf['_modules']) as $module){ 00256 $this->loadModule($module); 00257 } 00258 } 00259 } 00260 00261 00266 function getMigrations(){ 00267 $this->loadModules(); 00268 $out = array(); 00269 foreach ($this->_modules as $name=>$mod ){ 00270 if ( method_exists($mod, 'requiresMigration') and ( $req = $mod->requiresMigration()) ){ 00271 $out[$name] = $req; 00272 } 00273 } 00274 00275 return $out; 00276 00277 } 00278 00279 00280 00281 00287 function migrate($modules=array()){ 00288 $log = array(); 00289 $this->loadModules(); 00290 $migrations = $this->getMigrations(); 00291 foreach ($modules as $mod){ 00292 $mod_obj = $this->loadModule($mod); 00293 if ( isset($migrations[$mod]) and method_exists( $mod_obj, 'migrate' ) ){ 00294 $log[$mod] = $mod_obj->migrate(); 00295 } 00296 unset($mod_obj); 00297 } 00298 00299 return $log; 00300 } 00301 00307 function install($modules=array()){ 00308 $log = array(); 00309 $this->loadModules(); 00310 $migrations = $this->getMigrations(); 00311 foreach ($modules as $mod){ 00312 $mod_obj = $this->loadModule($mod); 00313 00314 if ( !$this->isInstalled($mod) and method_exists($mod_obj,'install') ){ 00315 $log[$mod] = $mod_obj->install(); 00316 } 00317 00318 unset($mod_obj); 00319 } 00320 00321 return $log; 00322 } 00323 00337 00350