]>'; /** * ------------------------------------------------------------------ * Error Functions * ------------------------------------------------------------------ */ private function __construct() {} /** * Get the only permitted instance of this object. It will be created if necessary * * @return object */ public static function &get_instance() { if( !isset(self::$_instance) ) { $c = __CLASS__; self::$_instance = new $c; } return self::$_instance; } /** * Set an error condition * * @ignore * @deprecated * @param string $str The string to set for the error * @return void */ protected function SetError($str = '') { $this->_errors = $str; } /** * Return the last error * * @ignore * @deprecated * @return string The last error, if any */ public function GetLastError() { return $this->_errors; } /** * Creates an xml data package from the module directory. * * @param mixed $modinstance The instance of the module object * @param string $message Reference to a string which will be filled with the message * created by the run of the method * @param integer $filecount Reference to an interger which will be filled with the * total # of files in the package * @return string an XML string comprising the module and its files */ function CreateXMLPackage( &$modinstance, &$message, &$filecount ) { // get a file list $filecount = 0; $dir = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR."modules".DIRECTORY_SEPARATOR.$modinstance->GetName(); $files = get_recursive_file_list( $dir, $this->xml_exclude_files ); $xmltxt = ''; $xmltxt .= $this->xmldtd."\n"; $xmltxt .= "\n"; $xmltxt .= " ".MODULE_DTD_VERSION."\n"; $xmltxt .= " ".$modinstance->GetName()."\n"; $xmltxt .= " ".$modinstance->GetVersion()."\n"; $xmltxt .= " ".$modinstance->MinimumCMSVersion()."\n"; $xmltxt .= " GetHelpPage())."]]>\n"; $xmltxt .= " GetAbout())."]]>\n"; $desc = $modinstance->GetAdminDescription(); if( $desc != '' ) { $xmltxt .= " \n"; } $depends = $modinstance->GetDependencies(); foreach( $depends as $key=>$val ) { $xmltxt .= " \n"; $xmltxt .= " $key\n"; $xmltxt .= " $val\n"; $xmltxt .= " \n"; } foreach( $files as $file ) { // strip off the beginning if (substr($file,0,strlen($dir)) == $dir) { $file = substr($file,strlen($dir)); } if( $file == '' ) continue; $xmltxt .= " \n"; $filespec = $dir.DIRECTORY_SEPARATOR.$file; $xmltxt .= " $file\n"; if( @is_dir( $filespec ) ) { $xmltxt .= " 1\n"; } else { $xmltxt .= " 0\n"; $data = base64_encode(file_get_contents($filespec)); $xmltxt .= " \n"; } $xmltxt .= " \n"; ++$filecount; } $xmltxt .= "\n"; $message = 'XML package of '.strlen($xmltxt).' bytes created for '.$modinstance->GetName(); $message .= ' including '.$filecount.' files'; return $xmltxt; } /** * Unpackage a module from an xml string * does not touch the database * * @param string $xml The xml data for the package * @param boolean $overwrite Should we overwrite files if they exist? * @param boolean $brief If set to true, less checking is done and no errors are returned * @return array A hash of details about the installed module */ function ExpandXMLPackage( $xmluri, $overwrite = 0, $brief = 0 ) { $gCms = cmsms(); $this->SetError(''); // first make sure that we can actually write to the module directory $dir = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR."modules"; if( !is_writable( $dir ) && $brief == 0 ) { // directory not writable $this->SetError( lang( 'errordirectorynotwritable' ) ); return false; } $reader = new XMLReader(); $ret = $reader->open($xmluri); if( $ret == 0 ) { $this->SetError( lang( 'errorcouldnotparsexml' ) ); return false; } $this->SetError(''); $havedtdversion = false; $moduledetails = array(); if( is_file($xmluri) ) $moduledetails['size'] = filesize($xmluri); $required = array(); while( $reader->read() ) { switch($reader->nodeType) { case XMLREADER::ELEMENT: switch( strtoupper($reader->localName) ) { case 'NAME': $reader->read(); $moduledetails['name'] = $reader->value; // check if this module is already installed if( isset( $this->_modules[$moduledetails['name']] ) && $overwrite == 0 && $brief == 0 ) { $this->SetError( lang( 'moduleinstalled' ) ); return TRUE; } break; case 'DTDVERSION': $reader->read(); if( $reader->value != MODULE_DTD_VERSION ) { $this->SetError( lang( 'errordtdmismatch' ) ); return false; } $havedtdversion = true; break; case 'VERSION': $reader->read(); $moduledetails['version'] = $reader->value; $tmpinst = $this->get_module_instance($moduledetails['name']); if( $tmpinst && $brief == 0 ) { $version = $tmpinst->GetVersion(); if( version_compare($moduledetails['version'],$version) < 0 ) { $this->SetError( lang('errorattempteddowngrade') ); return false; } else if (version_compare($moduledetails['version'],$version) == 0 ) { $this->SetError( lang('moduleinstalled') ); return TRUE; } } break; case 'MINCMSVERSION': case 'MAXCMSVERSION': case 'DESCRIPTION': case 'FILENAME': case 'ISDIR': $name = $reader->localName; $reader->read(); $moduledetails[$name] = $reader->value; break; case 'HELP': case 'ABOUT': $name = $reader->localName; $reader->read(); $moduledetails[$name] = base64_decode($reader->value); break; case 'REQUIREDNAME': $reader->read(); $requires['name'] = $reader->value; break; case 'REQUIREDVERSION': $reader->read(); $requires['version'] = $reader->value; break; case 'DATA': $reader->read(); $moduledetails['filedata'] = $reader->value; break; } break; case XMLReader::END_ELEMENT: switch( strtoupper($reader->localName) ) { case 'REQUIRES': if( count($requires) != 2 ) continue; if( !isset( $moduledetails['requires'] ) ) $moduledetails['requires'] = array(); $moduledetails['requires'][] = $requires; $requires = array(); break; case 'FILE': if( $brief != 0 ) continue; // finished a first file if( !isset( $moduledetails['name'] ) || !isset( $moduledetails['version'] ) || !isset( $moduledetails['filename'] ) || !isset( $moduledetails['isdir'] ) ) { $this->SetError( lang('errorincompletexml') ); return false; } // ready to go $moduledir=$dir.DIRECTORY_SEPARATOR.$moduledetails['name']; $filename=$moduledir.$moduledetails['filename']; if( !file_exists( $moduledir ) ) { if( !@mkdir( $moduledir ) && !is_dir( $moduledir ) ) { $this->SetError(lang('errorcantcreatefile').' '.$moduledir); break; } } else if( $moduledetails['isdir'] ) { if( !@mkdir( $filename ) && !is_dir( $filename ) ) { $this->SetError(lang('errorcantcreatefile').' '.$filename); break; } } else { $data = $moduledetails['filedata']; if( strlen( $data ) ) $data = base64_decode( $data ); $fp = @fopen( $filename, "w" ); if( !$fp ) $this->SetError(lang('errorcantcreatefile').' '.$filename); if( strlen( $data ) ) @fwrite( $fp, $data ); @fclose( $fp ); } unset( $moduledetails['filedata'] ); unset( $moduledetails['filename'] ); unset( $moduledetails['isdir'] ); break; } break; } } // while $reader->close(); if( $havedtdversion == false ) { $this->SetError( lang( 'errordtdmismatch' ) ); return false; } // we've created the module's directory unset( $moduledetails['filedata'] ); unset( $moduledetails['filename'] ); unset( $moduledetails['isdir'] ); if( $this->GetLastError() != "" ) return false; if( !$brief ) audit('','Module', 'Expanded module: '.$moduledetails['name'].' version '.$moduledetails['version']); return $moduledetails; } private function _install_module(CmsModule& $module_obj) { debug_buffer('install_module '.$module_obj->GetName()); $gCms = cmsms(); // preserve the global. $db = $gCms->GetDb(); // todo, check to make sure the module isn't already installed. $result = $module_obj->Install(); if( !isset($result) || $result === FALSE) { // install returned nothing, or FALSE $query = 'DELETE FROM '.cms_db_prefix().'modules WHERE module_name = ?'; $dbr = $db->Execute($query,array($module_obj->GetName())); $lazyload_fe = (method_exists($module_obj,'LazyLoadFrontend') && $module_obj->LazyLoadFrontend())?1:0; $lazyload_admin = (method_exists($module_obj,'LazyLoadAdmin') && $module_obj->LazyLoadAdmin())?1:0; $query = 'INSERT INTO '.cms_db_prefix().'modules (module_name,version,status,admin_only,active,allow_fe_lazyload,allow_admin_lazyload) VALUES (?,?,?,?,?,?,?)'; $dbr = $db->Execute($query,array($module_obj->GetName(),$module_obj->GetVersion(),'installed', ($module_obj->IsAdminOnly()==true)?1:0, 1,$lazyload_fe,$lazyload_admin)); $deps = $module_obj->GetDependencies(); if( is_array($deps) && count($deps) ) { $query = 'INSERT INTO '.cms_db_prefix().'module_deps (parent_module,child_module,minimum_version,create_date,modified_date) VALUES (?,?,?,NOW(),NOW())'; foreach( $deps as $depname => $depversion ) { if( !$depname || !$depversion ) continue; $dbr = $db->Execute($query,array($depname,$module_obj->GetName(),$depversion)); } } $this->_moduleinfo[$module_obj->GetName()] = array('module_name'=>$module_obj->GetName(), 'version'=>$module_obj->GetVersion(), 'status'=>'installed', 'active'=>1, 'admn_only'=>($module_obj->IsAdminOnly()==true)?1:0, 'allow_fe_lazyload'=>($module_obj->LazyLoadFrontend()==TRUE)?1:0, 'allow_admin_lazyload'=>($module_obj->LazyLoadAdmin()==TRUE)?1:0); Events::SendEvent('Core', 'ModuleInstalled', array('name' => $module_obj->GetName(), 'version' => $module_obj->GetVersion())); audit('',$module_obj->GetName(), 'Installed version '.$module_obj->GetVersion()); $gCms->clear_cached_files(); return array(TRUE,$module_obj->InstallPostMessage()); } return array(FALSE,$result); } /** * Install a module into the database * * @internal * @param string $module The name of the module to install * @param boolean $loadifnecessary If true, loads the module before trying to install it * @return array Returns a tuple of whether the install was successful and a message if applicable */ public function InstallModule($module, $loadifnecessary = false) { // get an instance of the object (force it). $modinstance = $this->get_module_instance($module,'',TRUE); if( !$modinstance ) return array(false,lang('errormodulenotloaded')); // check for dependencies $deps = $modinstance->GetDependencies(); if( is_array($deps) && count($deps) ) { foreach( $deps as $mname => $mversion ) { if( $mname == '' || $mversion == '' ) continue; // invalid entry. $newmod = $this->get_module_instance($mname); if( !is_object($newmod) || version_compare($newmod->GetVersion(),$mversion) < 0 ) { return array(false,lang('missingdependency').': '.$mname); } } } // do the actual installation stuff. $res = $this->_install_module($modinstance); if( $res[0] == FALSE && $res[1] == '') $res[1] = lang('errorinstallfailed'); return $res; } private function &_get_module_info() { if( !is_array($this->_moduleinfo) || count($this->_moduleinfo) == 0 ) { $query = 'SELECT * FROM '.cms_db_prefix().'modules ORDER BY module_name'; $db = cmsms()->GetDb(); $tmp = $db->GetArray($query); if( is_array($tmp) ) { $config = cmsms()->GetConfig(); $dir = $config['root_path'].'/modules'; $this->_moduleinfo = array(); for( $i = 0; $i < count($tmp); $i++ ) { $name = $tmp[$i]['module_name']; if( is_file($dir."/$name/$name.module.php") ) { if( !isset($this->_moduleinfo[$name]) ) $this->_moduleinfo[$name] = $tmp[$i]; } } } } return $this->_moduleinfo; } private function _load_module($module_name,$force_load = FALSE,$dependents = TRUE) { $config = cmsms()->GetConfig(); $dir = $config['root_path'].'/modules'; $info = $this->_get_module_info(); if( !isset($info[$module_name]) && !$force_load ) { debug_buffer("Nothing is known about $module_name... cant load it"); return FALSE; } if( (!isset($info[$module_name]['active']) || $info[$module_name]['active'] == 0) && !$force_load ) { debug_buffer('Requested deactivated module '.$module_name); return FALSE; } global $CMS_INSTALL_PAGE; global $CMS_VERSION; global $CMS_PREVENT_AUTOINSTALL; global $CMS_FORCE_MODULE_LOAD; $allow_auto = (isset($CMS_PREVENT_AUTOINSTALL) && $CMS_PREVENT_AUTOINSTALL)?0:1; $gCms = cmsms(); // backwards compatibility... set the global. if( !class_exists($module_name) ) { $fname = $dir."/$module_name/$module_name.module.php"; if( !is_file($fname) ) { debug_buffer("Cannot load $module_name because the module file does not exist"); return FALSE; } debug_buffer('loading module '.$module_name); require_once($fname); } // load dependencies. if( !isset($config['modules_noloaddependants']) && $dependents == TRUE ) { $deps = $this->get_module_dependencies($module_name); if( is_array($deps) && count($deps) ) { $res = true; foreach( $deps as $name => $ver ) { // this is the start of a recursive routine. // get_module_instance may call _load_module. $obj2 = $this->get_module_instance($name,$ver); if( !is_object($obj2) ) { $res = false; break; } } if( !$res && !isset($CMS_FORCE_MODULE_LOAD)) { audit('','Core',"Cannot load module $module_name ... Problem loading dependent module $name version $ver"); debug_buffer("Cannot load $module_name... cannot load it's dependants."); unset($obj); return FALSE; } } } $obj = new $module_name; if( !is_object($obj) ) { // oops, some problem loading. audit('','Core',"Cannot load module $module_name ... some problem instantiating the class"); debug_buffer("Cannot load $module_name ... some problem instantiating the class"); return FALSE; } if (version_compare($obj->MinimumCMSVersion(),$CMS_VERSION) == 1 ) { // oops, not compatible.... can't load. audit('','Core','Cannot load module '.$module_name.' it is not compatible wth this version of CMSMS'); debug_buffer("Cannot load $module_name... It is not compatible with this version of CMSMS"); unset($obj); return FALSE; } if( isset($info[$module_name]) && $info[$module_name]['status'] != 'installed' && (isset($CMS_INSTALL_PAGE) || $this->_is_queued_for_install($module_name)) ) { // not installed, can we auto-install it? if( (in_array($module_name,$this->cmssystemmodules) || $obj->AllowAutoInstall() == true || $this->_is_queued_for_install($module_name)) && $allow_auto ) { $res = $this->_install_module($obj); if( !isset($_SESSION['moduleoperations_result']) ) $_SESSION['moduleoperations_result'] = array(); $_SESSION['moduleoperations_result'][$module_name] = $res; } else if( !isset($CMS_FORCE_MODULE_LOAD) ) { // nope, can't auto install... unset($obj); return FALSE; } } // check to see if an upgrade is needed. allow_admin_lang(TRUE); // isn't this ugly. if( isset($info[$module_name]) && $info[$module_name]['status'] == 'installed' ) { $dbversion = $info[$module_name]['version']; if( version_compare($dbversion, $obj->GetVersion()) == -1 ) { // upgrade is needed if( ($obj->AllowAutoUpgrade() == TRUE || $this->_is_queued_for_install($module_name)) && $allow_auto ) { // we're allowed to upgrade $res = $this->_upgrade_module($obj); if( !isset($_SESSION['moduleoperations_result']) ) $_SESSION['moduleoperations_result'] = array(); if( $res ) { $res2 = array(TRUE,lang('moduleupgraded')); $_SESSION['moduleoperations_result'][$module_name] = $res2; return TRUE; } else { $res2 = array(FALSE,lang('moduleupgradeerror')); $_SESSION['moduleoperations_result'][$module_name] = $res2; return FALSE; } if( !$res ) { // upgrade failed allow_admin_lang(FALSE); // isn't this ugly. debug_buffer("Automatic upgrade of $module_name failed"); unset($obj); return FALSE; } } else if( !isset($CMS_FORCE_MODULE_LOAD) ) { // nope, can't auto upgrade either allow_admin_lang(FALSE); // isn't this ugly. unset($obj); return FALSE; } } } if( (isset($info[$module_name]) && $info[$module_name]['status'] == 'installed') || $force_load ) { if( is_object($obj) ) $this->_modules[$module_name] = $obj; return TRUE; } return FALSE; } /** * A function to return a list of all modules that appear to exist properly in the modules directory. * * @internal * @return array of complete specifications to module files */ public function FindAllModules() { $dir = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR."modules"; $result = array(); if( $handle = @opendir($dir) ) { while( ($file = readdir($handle)) !== false ) { $fn = "$dir/$file/$file.module.php"; if( @is_file($fn) ) $result[] = $file; } } sort($result); return $result; } /** * Finds all modules in the filesystem, and builds a database about them * * @since 1.10 * @access private * @internal */ private function _load_all_modules() { $this->_moduleinfo = array(); $info = $this->_get_module_info(); $names = $this->FindAllModules(); foreach( $names as $name ) { if( isset($this->_moduleinfo[$name]) ) continue; // already know about this module. // this module isn't in the database, but is in the filesystem... make up some dummy info. $rec = array('module_name'=>$name,'status'=>'not installed','version'=>'0.0', 'admin_only'=>0,'active'=>0,'allow_fe_lazyload'=>0,'allow_admin_lazyload'=>0); $this->_moduleinfo[$name] = $rec; } ksort($this->_moduleinfo); } /** * Finds all modules that are available to be loaded... * this method uses the information in the database to load the modules that are necessary to load * it also, will go through any queued installs/upgrades and force those modules to load, which * will in turn do the upgrading and installing if necessary. * * @access public * @internal * @param loadall boolean indicates wether ALL modules in the filesystem should be loaded, default is false * @param noadmin boolean indicates that modules marked as admin_only in the database should not be loaded, default is false * @param no_lazyload boolean indicates that modules marked as lazy_loadable should be loaded anywayz, default is falze * @return void */ public function LoadModules($loadall = false,$noadmin = false, $no_lazyload = false) { if( $loadall ) $this->_load_all_modules(); global $CMS_ADMIN_PAGE; global $CMS_STYLESHEET; $config = cmsms()->GetConfig(); $allinfo = $this->_get_module_info(); if( !is_array($allinfo) ) return; // no modules installed, probably an empty database... edge case. foreach( $allinfo as $module_name => $info ) { if( $info['status'] != 'installed' ) continue; if( !$info['active'] ) continue; if( ($info['admin_only'] || (isset($info['allow_fe_lazyload']) && $info['allow_fe_lazyload'])) && !isset($CMS_ADMIN_PAGE) ) continue; if( isset($config['admin_loadnomodules']) && isset($CMS_ADMIN_PAGE) ) continue; if( isset($info['allow_admin_lazyload']) && $info['allow_admin_lazyload'] && isset($CMS_ADMIN_PAGE) ) continue; if( isset($CMS_STYLESHEET) && !isset($CMS_STYLESHEET) ) continue; $this->get_module_instance($module_name); } if( isset($_SESSION['moduleoperations']) && is_array($_SESSION['moduleoperations']) && count($_SESSION['moduleoperations']) ) { // there are modules queued for install/upgrade that may not have been loaded. foreach($_SESSION['moduleoperations'] as $module_name => $info ) { if( !isset($allinfo[$module_name]) ) { // we don't know about this module yet... $rec = array('module_name'=>$module_name,'status'=>'not installed','version'=>'0.0', 'admin_only'=>0,'active'=>0,'allow_fe_lazyload'=>0,'allow_admin_lazyload'=>0); $this->_moduleinfo[$module_name] = $rec; } $this->get_module_instance($module_name,'',TRUE); unset($_SESSION['moduleiperations'][$module_name]); } // by here... we should not have anything left queued unset($_SESSION['moduleoperations']); } return; } private function _upgrade_module( &$module_obj, $to_version = '' ) { // we can't upgrade a module if the schema is not up to date. $db = cmsms()->GetDb(); $tmp = $db->GetOne('SELECT version FROM '.cms_db_prefix().'version'); if( $tmp && $tmp < CMS_SCHEMA_VERSION ) return FALSE; $info = $this->_get_module_info(); $module_name = $module_obj->GetName(); $dbversion = $info[$module_name]['version']; if( $to_version == '' ) $to_version = $module_obj->GetVersion(); $result = $module_obj->Upgrade($dbversion,$to_version); if( $result !== FALSE ) { $db = cmsms()->GetDb(); $lazyload_fe = (method_exists($module_obj,'LazyLoadFrontend') && $module_obj->LazyLoadFrontend())?1:0; $lazyload_admin = (method_exists($module_obj,'LazyLoadAdmin') && $module_obj->LazyLoadAdmin())?1:0; $query = 'UPDATE '.cms_db_prefix().'modules SET version = ?, allow_fe_lazyload = ?,allow_admin_lazyload = ? WHERE module_name = ?'; $dbr = $db->Execute($query,array($module_obj->GetVersion(),$lazyload_fe,$lazyload_admin,$module_obj->GetName())); $info[$module_obj->GetName()]['version'] = $module_obj->GetVersion(); audit('','Module', 'Upgraded module '.$module_obj->GetName().' to version '.$module_obj->GetVersion()); Events::SendEvent('Core', 'ModuleUpgraded', array('name' => $module_obj->GetName(), 'oldversion' => $dbversion, 'newversion' => $module_obj->GetVersion())); cmsms()->clear_cached_files(); return TRUE; } return FALSE; } /** * Upgrade a module * * This is an internal method, subject to change in later releases. It should never be called for upgrading arbitrary modules. * Any use of this function by third party code will not be supported. Use at your own risk and do not report bugs or issues * related to your use of this module. * * @param string $module The name of the module to upgrade * @return boolean Whether or not the upgrade was successful */ public function UpgradeModule( $module_name, $to_version = '') { $module_obj = $this->get_module_instance($module_name); if( !is_object($module_obj) ) return FALSE; return $this->_upgrade_module($module_obj,$to_version); } /** * Uninstall a module * * @param string $module The name of the module to upgrade * @return boolean Whether or not the upgrade was successful * @internal */ public function UninstallModule( $module) { $gCms = cmsms(); $db = $gCms->GetDb(); $modinstance = cms_utils::get_module($module); if( !$modinstance ) return FALSE; $cleanup = $modinstance->AllowUninstallCleanup(); $result = $modinstance->Uninstall(); if (!isset($result) || $result === FALSE) { // now delete the record $query = "DELETE FROM ".cms_db_prefix()."modules WHERE module_name = ?"; $db->Execute($query, array($module)); // delete any dependencies $query = "DELETE FROM ".cms_db_prefix()."module_deps WHERE child_module = ?"; $db->Execute($query, array($module)); // clean up, if permitted if ($cleanup) { $db->Execute('DELETE FROM '.cms_db_prefix().'module_templates where module_name=?',array($module)); $db->Execute('DELETE FROM '.cms_db_prefix().'event_handlers where module_name=?',array($module)); $db->Execute('DELETE FROM '.cms_db_prefix().'events where originator=?',array($module)); $db->Execute('DELETE FROM '.cms_db_prefix().'module_smarty_plugins where module=?',array($module)); $db->Execute('DELETE FROM '.cms_db_prefix(). "siteprefs WHERE sitepref_name LIKE '". str_replace("'",'',$db->qstr($module)). "_mapi_pref%'"); $db->Execute('DELETE FROM '.cms_db_prefix().'routes WHERE dest = ?',array($module)); $db->Execute('DELETE FROM '.cms_db_prefix().'module_smarty_plugins WHERE module = ?',array($module)); } // clear the cache. $gCms->clear_cached_files(); // Removing module from info unset($this->_moduleinfo[$module]); Events::SendEvent('Core', 'ModuleUninstalled', array('name' => $module)); audit('','Module','Uninstalled module '.$module); } else { $this->setError($result); return false; } return true; } /** * Test if a module is active */ public function IsModuleActive($module_name) { if( !$module_name ) return FALSE; $info = $this->_get_module_info(); if( !isset($info[$module_name]) ) return FALSE; return (bool)$info[$module_name]['active']; } /** * Activate a module * * @param string module name * @param boolean flag indicating wether to activate or deactivate the module * @return boolean */ public function ActivateModule($module_name,$activate = true) { if( !$module_name ) return FALSE; $info = $this->_get_module_info(); if( !isset($info[$module_name]) ) return FALSE; $o_state = $info['module_name']['active']; if( $activate ) { $info['module_name']['active'] = 1; } else { $info['module_name']['active'] = 0; } if( $info['module_name']['active'] != $o_state ) { $db = cmsms()->GetDb(); $query = 'UPDATE '.cms_db_prefix.' SET active = ? WHERE module_name = ?'; $dbr = $db->Execute($query,array($info['module_name']['active'],$module_name)); } return TRUE; } /** * Returns a hash of all loaded modules. This will include all * modules loaded into memory at the current time * * @return array The hash of all loaded modules */ public function &GetLoadedModules() { return $this->_modules; } /** * Return an array of the names of all modules that we currently know about */ public function GetAllModuleNames() { return array_keys($this->_get_module_info()); } /** * Returns an array of the names of all installed modules. * * @return array of strings */ public function GetInstalledModules($include_all = FALSE) { $result = array(); $info = $this->_get_module_info(); if( is_array($info) ) { foreach( $info as $name => $rec ) { if( $rec['status'] != 'installed' ) continue; if( !$rec['active'] && $include_all == FALSE ) continue; $result[] = $name; } } return $result; } /** * Returns an array of installed modules that have a certain capabilies * This method will force the loading of all modules regardless of the module settings. * * @param string $capability The capability name * @param mixed $args Capability arguments * @return array List of all the module objects with that capability */ public static function get_modules_with_capability($capability, $args= '') { if( !is_array($args) ) { if( !empty($args) ) { $args = array($args); } else { $args = array(); } } return module_meta::get_instance()->module_list_by_capability($capability,$args); } /** * A function to return a list of dependencies from a module. * this method works by reading the dependencies from the database. * * @since 1.11.8 * @author Robert Campbell * @param string The module name * @return mixed. Null if there are no dependencies. Otherwise, a hash of dependent module names, and their versions. */ public function get_module_dependencies($module_name) { if( !$module_name ) return; if( !is_array($this->_moduledeps) ) { $fn = TMP_CACHE_LOCATION.'/f'.md5(__FILE__.'deps').'.dat'; if( file_exists($fn) ) { $data = file_get_contents($fn); $this->_moduledeps = unserialize($data); } else { $this->_moduledeps = array(); $db = cmsms()->GetDb(); $query = 'SELECT parent_module,child_module,minimum_version FROM '.cms_db_prefix().'module_deps'; $dbr = $db->GetArray($query); if( is_array($dbr) && count($dbr) ) { foreach( $dbr as $row ) { if( !isset($this->_moduledeps[$row['child_module']]) ) $this->_moduledeps[$row['child_module']] = array(); $this->_moduledeps[$row['child_module']][$row['parent_module']] = $row['minimum_version']; } } file_put_contents($fn,serialize($this->_moduledeps)); } } if( isset($this->_moduledeps[$module_name]) ) return $this->_moduledeps[$module_name]; } /** * A function to return the object reference to the module object * if the module is not already loaded, it will be loaded. Version checks are done * with the module to allow only loading versions of modules that are greater than the * specified value. * * @param string The module name * @param string an optional version string. * @param boolean an optional flag to indicate wether the module should be force loaded if necesary. * @return mixed Null on failure, or an object of type CmsModule on success. */ public function &get_module_instance($module_name,$version = '',$force = FALSE) { if( empty($module_name) && isset($this->variables['module'])) { $module_name = $this->variables['module']; } $obj = null; if( isset($this->_modules[$module_name]) ) { $obj =& $this->_modules[$module_name]; } if( !is_object($obj) ) { // gotta load it. $res = $this->_load_module($module_name,$force); if( $res ) { $obj =& $this->_modules[$module_name]; } } if( is_object($obj) && !empty($version) ) { $res = version_compare($obj->GetVersion(),$version); if( $res < 0 OR $res === FALSE ) $obj = null; } return $obj; } /** * Test if the specified module name is a system module * * @param string The module name * @return boolean */ public function IsSystemModule($module_name) { return in_array($module_name,$this->cmssystemmodules); } /** * Return the current syntax highlighter module object * * This method retrieves the specified syntax highlighter module, or uses the current current user preference for the syntax hightlighter module * for a name. * * @param string allows bypassing the automatic detection process and specifying a wysiwyg module. * @return null on failure, an object of type CmsModule On success. * @since 1.10 */ public function &GetSyntaxHighlighter($module_name = '') { $obj = null; if( !$module_name ) { global $CMS_ADMIN_PAGE; if( isset($CMS_ADMIN_PAGE) ) $module_name = get_preference(get_userid(FALSE),'syntaxhighlighter'); } if( !$module_name ) return $obj; $obj = $this->get_module_instance($module_name); if( !$obj ) return $obj; if( !$obj->IsSyntaxHighlighter() ) return $obj; return $obj; } /** * Return the current wysiwyg module object * * This method makes an attempt to find the appropriate wysiwyg module given the current request context * and admin user preference. * * @param string allows bypassing the automatic detection process and specifying a wysiwyg module. * @return null on failure, an object of type CmsModule On success. * @since 1.10 * @deprecated */ public function &GetWYSIWYGModule($module_name = '') { global $CMS_ADMIN_PAGE; $obj = null; if( !$module_name ) { if( !isset($CMS_ADMIN_PAGE) ) { $module_name = get_site_preference('frontendwysiwyg'); } else { $module_name = get_preference(get_userid(FALSE),'wysiwyg'); } } if( !$module_name || $module_name == -1 ) return $obj; $obj = $this->get_module_instance($module_name); if( !$obj ) return $obj; if( $obj->IsWYSIWYG() ) return $obj; $obj = null; return $obj; } /** * Return the current search module object * * This method returns module object for the currently selected search module. * * @return null on failure, an object of type CmsModule on success * @since 1.10 */ public function &GetSearchModule() { $obj = null; $module_name = get_site_preference('searchmodule','Search'); if( $module_name && $module_name != 'none' && $module_name != '-1' ) { $obj = $this->get_module_instance($module_name); } return $obj; } /** * Alias for the GetSyntaxHiglighter method. * * @see GetSyntaxHighlighter * @deprecated * @since 1.10 */ public function &GetSyntaxModule($module_name = '') { return $this->GetSyntaxHighlighter($module_name); } private function _is_queued_for_install($module_name) { if( !isset($_SESSION['moduleoperations']) ) return FALSE; if( !isset($_SESSION['moduleoperations'][$module_name]) ) return FALSE; return TRUE; } /** * Queue a module for install * * @internal * @since 1.10 * @param string module name * @return void */ public function QueueForInstall($module_name) { if( !$module_name ) return; if( !isset($_SESSION['moduleoperations']) ) $_SESSION['moduleoperations'] = array(); if( !isset($_SESSION['moduleoperations'][$module_name]) ) $_SESSION['moduleoperations'][$module_name] = 1; } /** * Get list of modules queued for install. * * @internal * @since 1.10 * @param string module name * @return void */ public function GetQueueResults() { if( isset($_SESSION['moduleoperations_result']) ) { $data = $_SESSION['moduleoperations_result']; unset($_SESSION['moduleoperations_result']); return $data; } } /** * Unload a module from memory * * @internal * @since 1.10 * @param string module name * @return void */ public function unload_module($module_name) { if( !isset($this->_modules[$module_name]) || !is_object($this->_modules[$module_name]) ) return; unset($this->_modules[$module_name]); } } // end of class # vim:ts=4 sw=4 noet ?>