Xataface 2.0
Xataface Application Framework
Dataface/ModuleTool.php
Go to the documentation of this file.
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 
 All Data Structures Namespaces Files Functions Variables Enumerations