<?php /** * AgileBill - Open Billing Software * * This body of work is free software; you can redistribute it and/or * modify it under the terms of the Open AgileBill License * License as published at http://www.agileco.com/agilebill/license1-4.txt * * For questions, help, comments, discussion, etc., please join the * Agileco community forums at http://forum.agileco.com/ * * @link http://www.agileco.com/ * @copyright 2004-2008 Agileco, LLC. * @license http://www.agileco.com/agilebill/license1-4.txt * @author Tony Landis <tony@agileco.com> * @package AgileBill * @version 1.4.93 */ class module { # Open the constructor for this mod function module() { # name of this module: $this->module = "module"; # location of the construct XML file: $this->xml_construct = PATH_MODULES . "" . $this->module . "/" . $this->module . "_construct.xml"; # open the construct file for parsing $C_xml = new CORE_xml; $construct = $C_xml->xml_to_array($this->xml_construct); $this->method = $construct["construct"]["method"]; $this->trigger = $construct["construct"]["trigger"]; $this->field = $construct["construct"]["field"]; $this->table = $construct["construct"]["table"]; $this->module = $construct["construct"]["module"]; $this->cache = $construct["construct"]["cache"]; $this->order_by = $construct["construct"]["order_by"]; $this->limit = $construct["construct"]["limit"]; # core modules for installation/deletion: $this->core_mods= Array( 'account', 'account_admin', 'account_group', 'backup', 'blocked_email', 'blocked_ip', 'country', 'currency', 'email_template', 'email_template_translate', 'group', 'group_method', 'login_lock', 'login_log', 'log_error', 'module', 'module_method', 'newsletter', 'newsletter_subscriber', 'session', 'session_auth_inc', 'setup', 'setup_email', 'staff', 'staff_department', 'static_relation', 'static_var', 'static_var_record', 'task', 'temporary_data' ); $this->dev_inst_excl = Array( 'module', 'module_method', 'group_method', 'backup', 'login_log', 'session', 'weblog', 'temporary_data', 'setup', 'session_auth_cache'); } ### Send php/mysql/server/license details and check versions function remote_version_check($VAR) { global $C_auth; if(!$C_auth->auth_method_by_name("module","upgrade")) return false; if(is_file(PATH_AGILE.'Version.txt')) $f['version']=trim(file_get_contents(PATH_AGILE.'Version.txt')); else $f['version']='SVN'; $f['license']=LICENSE_KEY; $f['php']=phpversion(); $f['mysql']=mysql_get_client_info(); $f['os']=$_ENV['OS']; $f['proc']=$_ENV['PROCESSOR_ARCHITECTURE']; $f['arch']=$_ENV['PROCESSOR_ARCHITEW6432']; $f['server']=$_SERVER["SERVER_SOFTWARE"]; global $smarty; $smarty->assign('send', $f); } ### Get remote hash file and check for inconsitancys in local files function remote_update($VAR) { $ver = $VAR['ver']; $mis=0; $md5=0; $i=0; $msg = ''; # Get the core modules & compare if(defined('DEMO_VERSION')) $url_core = 'http://agileco.com/downloads/trial/'.$ver.'.hash.txt'; else $url_core = 'http://agileco.com/downloads/commercial/'.$ver.'.hash.txt'; @$data = file_get_contents($url_core); if(empty($data)) { $msg .= 'Failed to retrieve MD5 Hash file at http://agileco.com/downloads/commercial/'.$ver.'.hash.txt...<BR>'; } else { $arr = explode("|",$data); foreach($arr as $arx) { $rx = explode(',',$arx); @$ar['name'] = $rx[1]; @$ar['md5'] = $rx[0]; if(!empty($ar['name']) && !empty($ar['md5']) && !ereg("^install/", $ar['name']) && !ereg("^test.php", $ar['name'])) { if(!is_file(PATH_AGILE.$ar["name"])) { $core_mis[] = $ar["name"]; $mis++; } elseif(md5_file(PATH_AGILE.$ar["name"]) != $ar["md5"]) { $core_md5[] = $ar["name"]; $md5++; } } $i++; } $smart[] = Array ('name' => 'Core', 'md5' => @$core_md5, 'mis' => @$core_mis ); } ### Get each optional module && compare if(!defined('DEMO_VERSION')) { @$modules = $VAR["module"]; foreach($modules as $module) { $data = ''; @$data = file_get_contents('http://agileco.com/downloads/commercial/'.$module.'.hash.txt'); if(empty($data)) { $msg .= 'Failed to retrieve MD5 Hash file at http://agileco.com/downloads/commercial/'.$module.'.hash.txt...<BR>'; } else { $arr = explode("|",$data); foreach($arr as $arx) { $rx = explode(',',$arx); @$ar['name'] = $rx[1]; @$ar['md5'] = $rx[0]; # check if file exists locally... if(!empty($ar['name']) && !empty($ar['md5']) ) { if(!is_file(PATH_AGILE.$ar["name"])) { $f_mis[] = $ar["name"]; $mis++; } elseif(md5_file(PATH_AGILE.$ar["name"]) != $ar["md5"]) { $f_md5[] = $ar["name"]; $md5++; } } $i++; } $smart[] = Array ('name' => $module, 'md5' => @$f_md5, 'mis' => @$f_mis ); unset($f_mis); unset($f_md5); } } } global $smarty; $smarty->assign('modules', $smart); $smarty->assign('md5', $md5); $smarty->assign('mis', $mis); if(!empty($msg)) { global $C_debug; $C_debug->alert($msg); } } ############################## ## TRANSLATE ## ############################## function translate($VAR) { if(!isset($VAR['translate_language']) || !isset($VAR['translate_module'])) { echo "error!"; return; } if($VAR['translate_module'] == "") { echo "error!"; return; } # Get the default language file: if(!$file = fopen(PATH_LANGUAGE . '' . $VAR["translate_module"] . "/english_" . $VAR["translate_module"] . ".xml", "r")) { echo 'Unable to open base translation!'; } else { $systran_text=''; while(!feof($file)) { $systran_text .= fgetc($file); } } fclose($file); for($i=0; $i<count($VAR['translate_language']); $i++) { if(isset($VAR['translate_language'][$i]) && $VAR['translate_language'][$i] != "") { $systran_lp = $VAR['translate_language'][$i]; $language = $VAR['translate_lang'][$systran_lp]; ### Get the translation from systran: $language_xml = trim($this->systran($systran_text,$systran_lp)); # write the language packs $file = fopen(PATH_LANGUAGE . '' . $VAR["translate_module"] . "/".$language."_" . $VAR["translate_module"] . ".xml", "w+"); fputs($file, $language_xml); fclose($file); } } } ############################## ## SYSTRAN TRANSLATION ## ############################## function systran($text, $lang) { $systran_id = "SystranSoft-en"; $systran_charset = "ISO-8859-1"; $host = 'systranbox.com'; $form = '/systran/box'; $pass = array( 'systran_id' => $systran_id, 'systran_charset' => $systran_charset, 'systran_lp' => $lang, 'systran_text' => $text ); // CREATE THE RECORD require_once(PATH_CORE . 'post.inc.php'); $post= new CORE_post; $result = $post->post_data($host, $form, $pass); $pat = "\n"; $arr = explode($pat, $result); $ret=''; for($i=0; $i<count($arr); $i++) if($i>5) $ret.= $arr[$i]; return $ret; } ############################## ## ADD ## ############################## function add($VAR) { $type = "add"; $this->method["$type"] = explode(",", $this->method["$type"]); $db = new CORE_database; $db->add($VAR, $this, $type); } ############################## ## VIEW ## ############################## function view($VAR) { $type = "view"; $this->method["$type"] = explode(",", $this->method["$type"]); $db = new CORE_database; $db->view($VAR, $this, $type); } ############################## ## UPDATE ## ############################## function update($VAR) { $type = "update"; $this->method["$type"] = explode(",", $this->method["$type"]); $db = new CORE_database; $db->update($VAR, $this, $type); } ############################## ## DELETE ## ############################## function delete($VAR) { # set the core modules: $core = $this->core_mods; if(isset($VAR["delete_id"])) $id = explode(',',$VAR["delete_id"]); elseif (isset($VAR["id"])) $id = explode(',',$VAR["id"]); for($i=0; $i<count($id); $i++) { if($id[$i] != '') { # get the module id $module_id = $id[$i]; # is this module part of the core? $db = &DB(); $q = "SELECT name FROM ".AGILE_DB_PREFIX."module WHERE id = ".$db->qstr($module_id)." AND site_id = ".$db->qstr(DEFAULT_SITE); $result = $db->Execute($q); $module_name = $result->fields['name']; # loop through the core array and see if this module is part of the core for($i=0; $i<count($core); $i++) { if($core[$i] == $module_name) { # alert message translated echo "This module is part of the core - it cannot be uninstalled!"; return; } } # get each each group_method for this module & delete it $q = "SELECT id FROM ".AGILE_DB_PREFIX."module_method WHERE module_id = ".$db->qstr($module_id)." AND site_id = ".$db->qstr(DEFAULT_SITE); $result = $db->Execute($q); while(!$result->EOF) { # delete the group methods... $q = "DELETE FROM ".AGILE_DB_PREFIX."group_method WHERE module_id = ".$db->qstr($module_id)." OR method_id = ".$db->qstr($result->fields['id'])." AND site_id = ".$db->qstr(DEFAULT_SITE); $db->Execute($q); $result->MoveNext(); } # delete each module_method $db = &DB(); $q = "DELETE FROM ".AGILE_DB_PREFIX."module_method WHERE module_id = ".$db->qstr($module_id)." AND site_id = ".$db->qstr(DEFAULT_SITE); $db->Execute($q); # delete the module record $db = &DB(); $q = "DELETE FROM ".AGILE_DB_PREFIX."module WHERE id = ".$db->qstr($module_id)." AND site_id = ".$db->qstr(DEFAULT_SITE); $db->Execute($q); # drop the associated database for this module ### Load the construct XML file to get the table name... $C_xml = new CORE_xml; $xml_construct = PATH_MODULES . "" . $module_name . "/" . $module_name . "_construct.xml"; $construct = $C_xml->xml_to_array($xml_construct); ### Check that this Module has any db installation required... if(isset($construct["construct"]["table"])) { ### Create the module DB table $table = $construct["construct"]["table"]; $db = &DB(); $dict = NewDataDictionary($db); $sql = $dict->DropTableSQL(AGILE_DB_PREFIX.''.$table); $db->Execute($sql[0]); $table = $construct["construct"]["table"].'_id'; $sql = $dict->DropTableSQL(AGILE_DB_PREFIX.''.$table); $db->Execute($sql[0]); } } } } ############################## ## SEARCH FORM ## ############################## function search_form($VAR) { $type = "search"; $this->method["$type"] = explode(",", $this->method["$type"]); $db = new CORE_database; $db->search_form($VAR, $this, $type); } ############################## ## SEARCH ## ############################## function search($VAR) { $type = "search"; $this->method["$type"] = explode(",", $this->method["$type"]); $db = new CORE_database; $db->search($VAR, $this, $type); } ############################## ## SEARCH SHOW ## ############################## function search_show($VAR) { $type = "search"; $this->method["$type"] = explode(",", $this->method["$type"]); $db = new CORE_database; $db->search_show($VAR, $this, $type); } ################################### ## INSTALL ERROR CHECKING: MODULE ## ################################### function install_error_check($VAR) { global $smarty, $C_translate; ########################################### ### Check that the module name is defined: if(!isset($VAR["install_name"])) { $error[] = $C_translate->translate('install_enter_name','module',''); } else if ($VAR["install_name"] == '') { $error[] = $C_translate->translate('install_enter_name','module',''); } $module = trim($VAR["install_name"]); ########################################### ### Check that at least one group is defined: if(!isset($VAR["module_group"])) $error[] = $C_translate->translate('install_select_group','module',''); ########################################### ### Check if the module already exists in the Database: $db = &DB(); $q = 'SELECT name FROM '.AGILE_DB_PREFIX.'module WHERE name = '.$db->qstr($module).' AND site_id = '.$db->qstr(DEFAULT_SITE); $result = $db->Execute($q); if($result->RecordCount() > 0) $error[] = $C_translate->translate('install_module_exists','module',''); ####################################################### ### Check if the module exists in the file structure: if (!is_dir(PATH_MODULES . '' . $module)) $error[] = $C_translate->translate('install_missing_dir','module',''); if (!file_exists(PATH_MODULES . '' . $module . '/' . $module . '.inc.php')) $error[] = $C_translate->translate('install_missing_class','module',''); if (!file_exists(PATH_MODULES . '' . $module . '/' . $module . '_construct.xml')) $error[] = $C_translate->translate('install_missing_construct','module',''); if (!file_exists(PATH_MODULES . '' . $module . '/' . $module . '_install.xml')) $error[] = $C_translate->translate('install_missing_install','module',''); if(isset($error)) { $error[] = $C_translate->translate('install_failed','module',''); # set the errors as a Smarty Object $smarty->assign('form_validation', $error); return false; } ########################################### ### Load the install XML file... $xml_construct = PATH_MODULES . "" . $module . "/" . $module . "_install.xml"; $C_xml = new CORE_xml; $install = $C_xml->xml_to_array($xml_construct); $this->install = $install; /* echo "<pre>"; print_r($install); echo "</pre>"; */ ########################################### ### Get the module properties: $name = $install["install"]["module_properties"]["name"]; if(isset($install["install"]["module_properties"]["parent"])) $parent = $install["install"]["module_properties"]["parent"]; else $parent = 0; ############################################ ### Get dependancies.... if(isset($install["install"]["module_properties"]["dependancy"])) $dependancy = $install["install"]["module_properties"]["dependancy"]; else $dependancy = false; if($dependancy) { if(ereg(',', $dependancy)) $depend = explode(',', $dependancy); else $depend[0] = $dependancy; ################################################### ### Check to be sure the dependancies are installed: for($i=0; $i < count($depend); $i++) { $db = &DB(); $q = 'SELECT name FROM '.AGILE_DB_PREFIX.'module WHERE name = '.$db->qstr($depend["$i"]).' AND status = '.$db->qstr("1").' AND site_id = '.$db->qstr(DEFAULT_SITE); $result = $db->Execute($q); if($result->RecordCount() == 0) $error[] = $C_translate->translate('install_module_depend','module','depend='.$depend["$i"]); } } # check for error: if(isset($error)) { $error[] = $C_translate->translate('install_failed','module',''); # set the errors as a Smarty Object $smarty->assign('form_validation', $error); return false; } return true; } ##################################### ## INSTALL ERROR CHECKING: MODULE ## ##################################### function install_error_check_sub($module) { global $smarty; if ($module == '') { return true; } ######################################################## ### Check if the module already exists in the Database: $db = &DB(); $q = 'SELECT name FROM '.AGILE_DB_PREFIX.'module WHERE name = '.$db->qstr($module).' AND site_id = '.$db->qstr(DEFAULT_SITE); $result = $db->Execute($q); if($result->RecordCount() > 0) $error[] = 'This module already exists in the database!'; ###################################################### ### Check if the module exists in the file structure: if (!is_dir(PATH_MODULES . '' . $module)) $error[] = 'The specified module <b>directory</b> does not exist!'; if (!file_exists(PATH_MODULES . '' . $module . '/' . $module . '.inc.php')) $error[] = 'The specified module <b>class file</b> does not exist!'; if (!file_exists(PATH_MODULES . '' . $module . '/' . $module . '_construct.xml')) $error[] = 'The specified module <b>construct file</b> does not exist!'; if (!file_exists(PATH_MODULES . '' . $module . '/' . $module . '_install.xml')) $error[] = 'The specified module <b>installation file</b> does not exist!'; if(isset($error)) { $error[] = '<B>Module Installation Failed</B>'; # set the errors as a Smarty Object $smarty->assign('form_validation', $error); return false; } return true; } ################################### ## INSTALL ERROR CHECKING ## ################################### function install_sql($module) { global $VAR, $smarty; ########################################### ### Load the install XML file... $C_xml = new CORE_xml; $xml_install = PATH_MODULES . "" . $module . "/" . $module . "_install.xml"; $install = $C_xml->xml_to_array($xml_install); ########################################### ### Load the construct XML file... $C_xml = new CORE_xml; $xml_construct = PATH_MODULES . "" . $module . "/" . $module . "_construct.xml"; $construct = $C_xml->xml_to_array($xml_construct); ### Check that this Module has any db installation required... if(isset($construct["construct"]["table"])) { ### Create the module DB table $table = $construct["construct"]["table"]; ### Create the module DB fields $arr_field = $construct["construct"]["field"]; ### Loop through the fields to build the list: #$index_flds = 'id,site_id'; $index_flds = ''; while (list ($key, $value) = each($arr_field)) { $field = $key; $t_s = $arr_field["$key"]["type"]; if(isset($arr_field["$key"]["index"])) { if(empty($index_flds)) $index_flds .= $key; else $index_flds .= ','.$key; } if(ereg('[(]',$t_s)) { $ts = explode('(',$t_s); $type = $ts[0]; $size = ereg_replace('[)]', '', $ts[1]); $flds[] = Array($field, $type, $size); } else { $flds[] = Array($field, $t_s); } } ### Multi site? if(DEFAULT_SITE==1) { ### Create the table & colums using the ADODB Data Dictionary functions: $db = &DB(); $dict = NewDataDictionary($db); $table_options = array('mysql' => 'TYPE=MyISAM'); $sqlarray = $dict->CreateTableSQL(AGILE_DB_PREFIX.''.$table, $flds, $table_options); $result = $db->Execute($sqlarray[0]); if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','install_db (1)', $db->ErrorMsg() . ' '. print_r($sqlarray[0])); return false; } # Create unique index on site_id,id (mysql specific) $db->Execute("CREATE UNIQUE INDEX IDS on ".AGILE_DB_PREFIX."$table (site_id, id)"); # Create any custom indexes if(@$new_indexes = $construct["construct"]["index"]) { while (list ($index, $fields) = each($new_indexes)) { $dict = NewDataDictionary($db); if(eregi("fulltext", $index) && AGILE_DB_TYPE == 'mysql') $sqlarray = $dict->CreateIndexSQL($index, AGILE_DB_PREFIX.$table, $fields, array('FULLTEXT')); else $sqlarray = $dict->CreateIndexSQL($index, AGILE_DB_PREFIX.$table, $fields); $db->Execute($sqlarray[0]); } } } } ################################################################## ### Get the module properties: if(isset($install["install"]["module_properties"]["menu_display"])) $menu_display = $install["install"]["module_properties"]["menu_display"]; else $menu_display = ''; if(isset($install["install"]["module_properties"]["notes"])) $notes = $install["install"]["module_properties"]["notes"]; else $notes = ''; ################################################################### ### Get the parent module... $db = &DB(); $module_id = $db->GenID(AGILE_DB_PREFIX . "" . 'module_id'); if(isset($install["install"]["module_properties"]["parent"])) { $q = 'SELECT id FROM '.AGILE_DB_PREFIX.'module WHERE site_id = '.$db->qstr(DEFAULT_SITE).' AND name = '.$db->qstr($install["install"]["module_properties"]["parent"]); $result = $db->Execute($q); # Error checking if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','install_db', $db->ErrorMsg()); return false; } if($result->fields["id"] == '') $parent_id = $module_id; else $parent_id = $result->fields["id"]; } else { $parent_id = $module_id; } ################################################################## ### Create the module record, & get the module ID ### get the ID of the parent, and create it as child if needed... ### else the record is a child of itself... $q = 'INSERT INTO '.AGILE_DB_PREFIX.'module SET id = ' .$db->qstr($module_id).', site_id = ' .$db->qstr(DEFAULT_SITE).', name = ' .$db->qstr($module).', parent_id = ' .$db->qstr($parent_id).', notes = ' .$db->qstr($notes).', status = ' .$db->qstr('1').', menu_display = '.$db->qstr($menu_display); $result = $db->Execute($q); ################################################################### ### Create the module_method records, and get the ID for each one @$methods = $install["install"]["sql_inserts"]["module_method"]; if(!empty($methods) && is_array($methods)) { while (list ($key, $value) = each($methods)) { $name = $key; $method_id = $db->GenID(AGILE_DB_PREFIX.'module_method_id'); if(isset($methods[$key]["notes"])) $notes = $methods[$key]["notes"]; else $notes = ''; if(isset($methods[$key]["page"])) $page = $methods[$key]["page"]; else $page = ''; if(isset($methods[$key]["menu_display"])) $menu_display = '1'; else $menu_display = '0'; $q = 'INSERT INTO '.AGILE_DB_PREFIX .'module_method SET id = '.$db->qstr($method_id).', site_id = '.$db->qstr(DEFAULT_SITE).', name = '.$db->qstr($name).', module_id = '.$db->qstr($module_id).', notes = '.$db->qstr($notes).', page = '.$db->qstr($page).', menu_display = '.$db->qstr($menu_display); $result = $db->Execute($q); # Error checking if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','install_db :: module_method', $db->ErrorMsg()); return false; } ############################################################### ### Create the group_method records, with the ID from each ### of the above methods... ### Get the groups to add to (FROM THE install.tpl form!) for($i=0; $i<count($VAR["module_group"]); $i++) { $group_method_id = $db->GenID(AGILE_DB_PREFIX . 'group_method_id'); $q = 'INSERT INTO '.AGILE_DB_PREFIX .'group_method SET id = '.$db->qstr($group_method_id).', site_id = '.$db->qstr(DEFAULT_SITE).', method_id = '.$db->qstr($method_id).', module_id = '.$db->qstr($module_id).', group_id = '.$db->qstr($VAR["module_group"][$i]); $result = $db->Execute($q); # Error checking if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','install_db :: group_method_id', $db->ErrorMsg()); return false; } } } } //$db->Execute ( sqlDelete(&$db, 'module', "name IS NULL or name = '' OR parent_id IS NULL or parent_id = ''") ); # all done! return true; } ############################################## ## INSTALL DEFAULT DATA ## ############################################## function install_sql_data($module) { # check the file: $f = PATH_MODULES . '' . $module . '/' . $module . '_install_data.xml'; if(is_file($f)) { # open the XML backup file: $C_xml = new CORE_xml; $backup = $C_xml->xml_to_array($f); $db = &DB(); $arr = $backup['install']; # loop through each table in this array if(is_array($arr) ) { while (list ($table,$records) = each ($arr)) { $runsql = false; $sqls = 'INSERT INTO '.AGILE_DB_PREFIX.'' . $table . ' SET '; if (is_array($records) ) { # loop through each of the fields for this module $sql = ''; $sqlcount = 0; while (list ($fld,$val) = each ($records)) { if (is_array($val)) { # loop through each of the fields for this module $sql = ''; $sqlcount = 0; while (list ($fld2,$val2) = each ($val)) { if ($sqlcount != 0) $sql .= ', '; $sql .= $fld2 .' = '.$db->qstr($val2); $sqlcount++; } ## echo '<BR>' . $sqls. ' ' . $sql; $result = $db->Execute($sqls. ' ' . $sql); } else { if ($sqlcount != 0) $sql .= ', '; $sql .= $fld .' = '.$db->qstr($val); $sqlcount++; $runsql = true; } } if ($runsql) { ## echo '<BR>' . $sqls. ' ' . $sql; $result = $db->Execute($sqls. ' ' . $sql); if($result === false) @$this->error .= "<BR>". $sqls. ' ' . $sql; } } } } } } ################################### ## MAIN INSTALLER ## ################################### function install($VAR) { global $smarty, $C_translate; # check this module for any errors: if($this->install_error_check($VAR)) { ### Get sub_modules of this package if(isset($this->install["install"]["module_properties"]["sub_modules"])) { ### Check Each Sub-module: $arr_sub = $this->install["install"]["module_properties"]["sub_modules"]; if(ereg(',', $arr_sub)) $arr_s = explode(',', $arr_sub); else $arr_s[] = $arr_sub; for($i=0; $i<count($arr_s); $i++) { if(!$this->install_error_check_sub($arr_s[$i])) $error[] = $C_translate->translate('install_sub_module_err','module','sub_module='.$arr_s[$i]); } } # check for error: if(isset($error)) { $error[] = $C_translate->translate('install_failed','module',''); # set the errors as a Smarty Object $smarty->assign('form_validation', $error); return false; } ### install the SQL... $module = trim($VAR["install_name"]); if($this->install_sql($module)) { ### Loop through the sub-modules and install each of them if(isset($arr_s)) { for($i=0; $i<count($arr_s); $i++) { if(!$this->install_sql($arr_s[$i])) { ### Errors in install_sql(), then delete any SQL changes! ### set smarty error return; } } } } else { ### Errors in install_sql(), then delete any SQL changes! ### set smarty error return; } ### Insert default data: $this->install_sql_data($module); } # update the current user's authentication so the update group access applies # to them global $C_auth; $C_auth->auth_update(); } ################################### ## AUTO UPGRADER ## ################################### function upgrade($VAR) { if(!isset($VAR['module_name']) || !isset($VAR['module_group'])) { echo "You must select both the module(s) to upgrade and the groups to grant access to new methods to."; return; } $module_count = 0; $method_count = 0; $fields_count = 0; $method_new_count = 0; $fields_new_count = 0; # loop through each module $modules = $VAR['module_name']; for($i=0; $i<count($modules); $i++) { # increment module count $module_count++; # get the module details $db = &DB(); $db_module = $db->Execute(sqlSelect($db,"module","*","id=::{$modules[$i]}:: or name=::{$modules[$i]}::")); $module_name = $db_module->fields['name']; $module_id = $db_module->fields['id']; ######################################################################### # Update the Methods from the <module>_install.xml file # get the install xml file ######################################################################### $install_xml = PATH_MODULES.$module_name.'/'.$module_name.'_install.xml'; if(is_file($install_xml)) { $C_xml = new CORE_xml; @$methods = $C_xml->xml_to_array($install_xml); @$methods = $methods['install']['sql_inserts']['module_method']; # loop through the methods if(is_array($methods)) { while (list ($key, $value) = each($methods)) { # increment method count $method_count++; # see if this method exists $sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . 'module_method WHERE name = ' . $db->qstr( $key ) . ' AND module_id = ' . $db->qstr( $module_id ) . ' AND site_id = ' . $db->qstr(DEFAULT_SITE); $method_db = $db->Execute($sql); if ($method_db === false) { global $C_debug; $C_debug->error('module.inc.php','upgrade', $db->ErrorMsg()); } if($method_db->RecordCount() == 0) { # increment method count $method_new_count++; ### add this method @$notes = $methods[$key]["notes"]; @$page = $methods[$key]["page"]; @$menu_display = $methods[$key]["menu_display"]; $method_id = sqlGenID($db, 'module_method'); $fields=Array('name'=>$key, 'module_id'=>$module_id, 'notes'=>$notes, 'page'=>$page, 'menu_display'=>$menu_display); $db->Execute(sqlInsert($db,"module_method",$fields, $method_id)); if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','upgrade', $db->ErrorMsg()); } ### Create the group_method records, with the ID from each for($ii=0; $ii<count($VAR["module_group"]); $ii++) { $group_method_id = $db->GenID(AGILE_DB_PREFIX . "" . 'group_method_id'); $q = 'INSERT INTO '.AGILE_DB_PREFIX .'group_method SET id = '.$db->qstr($group_method_id).', site_id = '.$db->qstr(DEFAULT_SITE).', method_id = '.$db->qstr($method_id).', module_id = '.$db->qstr($module_id).', group_id = '.$db->qstr($VAR["module_group"][$ii]); $result = $db->Execute($q); if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','upgrade', $db->ErrorMsg()); } } } } } } ######################################################################### # Update the DB Fields from the <module>_construct.xml file # get the install xml file ######################################################################### $construct_xml = PATH_MODULES.$module_name.'/'.$module_name.'_construct.xml'; if(is_file($construct_xml)) { $C_xml = new CORE_xml; $construct = $C_xml->xml_to_array($construct_xml); @$fields = $construct['construct']['field']; ### Check that this Module has any db installation required... if(!empty($construct["construct"]["table"]) && $construct["construct"]["table"] == $module_name) { ### Create the module DB table $table = $construct["construct"]["table"]; $db = &DB(); $db_fields = $db->MetaColumns(AGILE_DB_PREFIX.$table, true); ### Create the module DB fields $arr_field = $construct["construct"]["field"]; ### Loop through the fields to build the list: while (list ($key, $value) = each($arr_field)) { $field = $key; $FIELD = strtoupper($key); if(!isset($db_fields[$FIELD])) { # increment field count $fields_new_count++; $t_s = $arr_field["$key"]["type"]; if(ereg('[(]',$t_s)) { $ts = explode('[(]',$t_s); $type = $ts[0]; $size = ereg_replace(')', '', $ts[1]); $flds[] = Array($field, $type, $size); } else { $flds[] = Array($field, $t_s); } } } ### Add any new columns: if(is_array(@$flds)) { $dict = NewDataDictionary($db); $sqlarray = $dict->AddColumnSQL(AGILE_DB_PREFIX.$table, $flds); $result = $db->Execute($sqlarray[0]); if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','install_db', $db->ErrorMsg()); echo $db->ErrorMsg(); } unset($flds); } ### Remove any unused columns while (list ($key, $value) = each($db_fields)) { $fieldname = strtolower($key); if(!isset($construct["construct"]["field"][$fieldname])) $flds[] = $key; } if(is_array(@$flds)) { $dict = NewDataDictionary($db); $sqlarray = $dict->DropColumnSQL(AGILE_DB_PREFIX.$table, $flds); $sqlarray[0]; $result = $db->Execute($sqlarray[0]); if ($result === false) { global $C_debug; $C_debug->error('module.inc.php','install_db', $db->ErrorMsg()); echo $db->ErrorMsg(); } unset($flds); } #################################################### ### Update Indexes: # Get old database indexes $dict = NewDataDictionary($db); $oldindex = $dict->MetaIndexes(AGILE_DB_PREFIX.$table); # check if the 'site_id' index exists: if(!empty($oldindex['site_id']) && $oldindex['site_id'] = 'id,site_id') { $dict = NewDataDictionary($db); $sqlarray = $dict->DropIndexSQL('site_id', AGILE_DB_PREFIX.$table); $db->Execute($sqlarray[0]); } # check that that UNIQUE index for site_id,id exists if(empty($oldindex['IDS']) || $oldindex['IDS']['unique'] != 1) { $db=&DB(); $db->Execute("alter table ".AGILE_DB_PREFIX."$table drop primary key"); $db->Execute("CREATE UNIQUE INDEX IDS on ".AGILE_DB_PREFIX."$table (site_id, id)"); } $dict = NewDataDictionary($db); $oldindex = $dict->MetaIndexes(AGILE_DB_PREFIX.$table); # Current construct invoices if(@$new_indexes = $construct["construct"]["index"]) { while (list ($index, $fields) = each($new_indexes)) { if(is_array(@$oldindex[$index])) { # already exists - compare fields: $oldfields = implode(",", $oldindex[$index]['columns']); if($oldfields != $fields) { # index changed - drop: $dict = NewDataDictionary($db); $sqlarray = $dict->DropIndexSQL($index, AGILE_DB_PREFIX.$table); $db->Execute($sqlarray[0]); # create index $dict = NewDataDictionary($db); if(eregi("fulltext", $index) && AGILE_DB_TYPE == 'mysql') $sqlarray = $dict->CreateIndexSQL($index, AGILE_DB_PREFIX.$table, $fields, array('FULLTEXT')); else $sqlarray = $dict->CreateIndexSQL($index, AGILE_DB_PREFIX.$table, $fields); $db->Execute($sqlarray[0]); } } else { # index does not exist - create! $dict = NewDataDictionary($db); if(eregi("fulltext", $index) && AGILE_DB_TYPE == 'mysql') $sqlarray = $dict->CreateIndexSQL($index, AGILE_DB_PREFIX.$table, $fields, array('FULLTEXT')); else $sqlarray = $dict->CreateIndexSQL($index, AGILE_DB_PREFIX.$table, $fields); $db->Execute($sqlarray[0]); } $verify_index[] = $index; } # Check for removed indexes: if(!empty($oldindex)) { reset($oldindex); while (list ($index, $fields) = each($oldindex)) { if(!isset($new_indexes[$index]) && $index != 'IDS') { $dict = NewDataDictionary($db); $sqlarray = $dict->DropIndexSQL($index, AGILE_DB_PREFIX.$table); $db->Execute($sqlarray[0]); } } } } else { # remove all old indexes if(!empty($oldindex)) { reset($oldindex); while (list ($index, $fields) = each($oldindex)) { if($index != 'IDS') { $dict = NewDataDictionary($db); $sqlarray = $dict->DropIndexSQL($index, AGILE_DB_PREFIX.$table); $db->Execute($sqlarray[0]); } } } } } } } $msg = "Successfully checked $module_count module(s), $method_count method(s), ". "and $fields_count db fields. <BR>". "Added $method_new_count method(s) and $fields_new_count db field(s)."; if(!empty($fields_new_count) > 0) { $js = '<script language="javascript">document.getElementById("module_add").submit();</script>'; global $smarty; if(is_object($smarty)) $smarty->assign('js', $js); else echo '<script language="javascript">document.refresh();</script>'; } # Display the message. global $C_debug; if(is_object($C_debug)) $C_debug->alert($msg); else echo $msg; # update the current user's authentication so the update group access applies # to them global $C_auth; if(is_object($C_auth)) $C_auth->auth_update(); } # Create the install XML file for specified modules function dev_install_gen($VAR) { # loop through each module passed... include_once('dev.inc.php'); $db = &DB(); if(is_array($VAR['module'])) { for($ix = 0; $ix<count($VAR['module']); $ix++) { $sql = "SELECT * FROM ".AGILE_DB_PREFIX."module WHERE id = ".$db->qstr($VAR['module'][$ix])." AND site_id = ".$db->qstr(DEFAULT_SITE); $result = $db->Execute($sql); while(!$result->EOF) { # update the {module}_install.xml file data $xml = dev_install_xml_gen($result->fields['name'],$result->fields['id']); # write the file $file = fopen(PATH_MODULES . '' . $result->fields['name'] . '/'. $result->fields['name'] . "_install.xml", "w+"); fputs($file, $xml); fclose($file); $do = true; for($i=0; $i<count($this->dev_inst_excl); $i++) { if ( $this->dev_inst_excl[$i] == $result->fields['name']) { $do = false; } } if ($do) { # update/create the {$module}_install_data.xml file data $xml = dev_install_xml_data($result->fields['name'],$result->fields['id']); } else { /* $xml = '<?xml version="1.0" encoding="ISO-8859-1" ?'.''.'>'; $xml .= ' <install> </install>'; */ $xml = false; } # write the file if($xml != false) { $file = fopen(PATH_MODULES . '' . $result->fields['name'] . '/'. $result->fields['name'] . "_install_data.xml", "w+"); fputs($file, $xml); fclose($file); } # next module $result->MoveNext(); } } } } # add a new module construct function dev_add($VAR) { # check if the needed directories exist & attempt to create... if (!is_dir(PATH_MODULES . '' . $VAR["module"])) { echo "<BR>Path does not exist, attempting to create: ".PATH_MODULES . '' . $VAR["module"]; if(!mkdir(PATH_MODULES . '' . $VAR["module"])) { echo "<BR><BR>Error: Module creation failed, please check path permissions...<BR>"; return false; } } if (!is_dir(PATH_LANGUAGE . '' . $VAR["module"])) { echo "<BR>Path does not exist, attempting to create: ".PATH_LANGUAGE . '' . $VAR["module"]; if(!mkdir(PATH_LANGUAGE . '' . $VAR["module"])) { echo "<BR><BR>Error: Module creation failed, please check path permissions...<BR>"; return false; } } if (!is_dir(PATH_THEMES . 'default/blocks/' . $VAR["module"])) { echo "<BR>Path does not exist, attempting to create: ".PATH_THEMES . 'default/blocks/' . $VAR["module"]; if(!mkdir(PATH_THEMES . 'default/blocks/' . $VAR["module"])) { echo "<BR><BR>Error: Module creation failed, please check path permissions...<BR>"; return false; } } # include the dev functions: include('dev.inc.php'); $construct_xml = dev_construct_xml($VAR); # write the consruct XML $file = fopen(PATH_MODULES . '' . $VAR["module"] . '/'. $VAR["module"] . "_construct.xml", "w+"); fputs($file,$construct_xml); fclose($file); $construct_php = dev_construct_php($VAR); # write the construct PHP $file=fopen(PATH_MODULES . '' . $VAR["module"] . '/'. $VAR["module"] . ".inc.php", "w+"); fputs($file,$construct_php); fclose($file); $language_xml = dev_language_xml($VAR); # write the language packs $file=fopen(PATH_LANGUAGE . '' . $VAR["module"] . "/english_" . $VAR["module"] . ".xml", "w+"); fputs($file, $language_xml); fclose($file); $install_xml = dev_install_xml($VAR); # write the language packs $file = fopen(PATH_MODULES . '' . $VAR["module"] . '/'. $VAR["module"] . "_install.xml", "w+"); fputs($file, $install_xml); fclose($file); # generate the main block $main_tpl = dev_block_main($VAR); # write the block $file = fopen(PATH_THEMES . 'default/blocks/' . $VAR["module"] . "/main.tpl", "w+"); fputs($file, $main_tpl); fclose($file); # generate the add block $add_tpl = dev_block_add($VAR); # write the block $file = fopen(PATH_THEMES . 'default/blocks/' . $VAR["module"] . "/add.tpl", "w+"); fputs($file, $add_tpl); fclose($file); # generate the view block $view_tpl = dev_block_view($VAR); # write the block $file = fopen(PATH_THEMES . 'default/blocks/' . $VAR["module"] . "/view.tpl", "w+"); fputs($file, $view_tpl); fclose($file); # generate the search_form block $search_form_tpl = dev_block_search_form($VAR); # write the block $file = fopen(PATH_THEMES . 'default/blocks/' . $VAR["module"] . "/search_form.tpl", "w+"); fputs($file, $search_form_tpl); fclose($file); # generate the search_show block $search_show_tpl = dev_block_search_show($VAR); # write the block $file = fopen(PATH_THEMES . 'default/blocks/' . $VAR["module"] . "/search_show.tpl", "w+"); fputs($file, $search_show_tpl); fclose($file); } } ?>