This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/modules/module/module.inc.php
2011-05-03 09:49:01 +10:00

1293 lines
36 KiB
PHP

<?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
*
* Originally authored by Tony Landis, AgileBill LLC
*
* Recent modifications by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
*
* @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
* @subpackage Modules:Module
*/
/**
* The main AgileBill Module Class
*
* @package AgileBill
* @subpackage Modules:Module
*/
class module extends OSB_module {
/**
* Initialise the module
*/
public function __construct() {
parent::__construct();
$this->dev_inst_excl = array(
'staff','staff_department',
'blocked_email','blocked_ip',
'module','module_method',
'setup_email','email_template','email_template_translate',
'group_method',
'backup',
'login_log',
'session',
'weblog',
'temporary_data',
'setup',
'session_auth_cache'
);
}
/** MODULE INSTALLATION **/
/**
* Main module installer
*
* This function will install a module.
* @uses CORE_xml
*/
public function install($VAR) {
global $smarty,$C_translate;
static $list = array();
if (! $list)
$list = $this->getlist();
$module = trim($VAR['install_name']);
$nodata = isset($VAR['no-data']) ? $VAR['no-data'] : false;
$type = isset($VAR['type']) ? $VAR['type'] : false;
$installed = false;
# If module is installed, we'll just return
$db = &DB();
$result = $db->Execute(sqlSelect($db,'module','name',array('name'=>$module)));
if ($result && $result->RecordCount() > 0)
$installed = true;
# Check this module for any errors
if ($installed || $this->install_error_check($VAR)) {
printf('- Module [%s] install check passed(%s).<br/>',$module,$nodata);
$error = array();
$arr_s = array();
$arr_sub = '';
# See if this module has any defined sub_modules
if ($type && isset($list[$type][$module]['sub_modules']))
$arr_sub .= $list[$type][$module]['sub_modules'];
# See if this module has any defined sub_modules as a result of being a parent.
if ($type && isset($list[$type][$module]['modules']) && count($list[$type][$module]['modules']))
$arr_sub .= implode(',',array_keys($list[$type][$module]['modules']));
# Get sub_modules of this package
if ($arr_sub) {
if (preg_match('/,/',$arr_sub))
$arr_s = explode(',',$arr_sub);
else
array_push($arr_s,$arr_sub);
printf('- Module [%s] has sub modules [%s] (%s).<br/>',$module,implode('|',$arr_s),$nodata);
foreach ($arr_s as $submodule) {
$result = $db->Execute(sqlSelect($db,'module','name',array('name'=>$submodule)));
$installed = false;
if ($result && $result->RecordCount() > 0)
$installed = true;
if (! $installed && ! $this->install_error_check(array(
'install_name'=>$submodule,
'module_group'=>$VAR['module_group'],
'no-data'=>isset($VAR['no-data']) ? $VAR['no-data'] : false,
'no-class'=>isset($VAR['no-class']) ? $VAR['no-class'] : false
)))
array_push($error,$C_translate->translate('install_sub_module_err','module','sub_module='.$submodule));
}
}
# Check for error
if (count($error)) {
array_push($error,$C_translate->translate('install_failed','module',''));
# Set the errors as a Smarty Object
if ($smarty)
$smarty->assign('form_validation',$error);
return false;
}
# Install the SQL
printf('- Module [%s] install SQL.<br/>',$module);
if ($this->install_sql($module,$nodata)) {
# Loop through the sub-modules and install each of them
for ($i=0; $i<count($arr_s); $i++) {
if (! $this->install_sql($arr_s[$i],$nodata))
return false;
# Insert default data
if (! $nodata)
$this->install_sql_data($arr_s[$i]);
}
} else
return false;
if ($nodata)
return true;
printf('- Module [%s] install DATA.<br/>',$module);
# Insert default data
$this->install_sql_data($module);
} else {
#printf('- Module [%s] failed install check.<br/>',$module);
return false;
}
# Update the current user's authentication so the update group access applies to them
global $C_auth;
if ($C_auth)
$C_auth->auth_update();
return true;
}
/**
* Module installation checking
*/
public function install_error_check($VAR) {
global $smarty, $C_translate;
# Core modules just install the database, so we'll return OK here.
if (isset($VAR['type']) && $VAR['type'] == 'core')
return true;
$error = array();
$module = isset($VAR['install_name']) ? trim($VAR['install_name']) : '';
# Check that the module name is defined
if (! trim($module))
array_push($error,$C_translate->translate('install_enter_name','module',''));
# Check that at least one group is defined:
if (! isset($VAR['module_group']))
array_push($error,$C_translate->translate('install_select_group','module',''));
# Check if the module already exists in the Database
$db = &DB();
$result = $db->Execute(sqlSelect($db,'module','name',array('name'=>$module)));
if ($result && $result->RecordCount() > 0)
array_push($error,$C_translate->translate('install_module_exists','module',''));
$xml_construct = sprintf('%s%s/%s_install.xml',PATH_MODULES,$module,$module);
# Check if the module exists in the file structure:
if (! is_dir(sprintf('%s%s',PATH_MODULES,$module)))
array_push($error,$C_translate->translate('install_missing_dir','module',''));
if (! file_exists(sprintf('%s%s/%s.inc.php',PATH_MODULES,$module,$module)) && (! isset($VAR['no-class']) || ! $VAR['no-class']))
array_push($error,$C_translate->translate('install_missing_class','module',''));
if (! file_exists($xml_construct))
array_push($error,$C_translate->translate('install_missing_construct','module',''));
if (! file_exists(sprintf('%s%s/%s_install.xml',PATH_MODULES,$module,$module)))
array_push($error,$C_translate->translate('install_missing_install','module',''));
if (count($error)) {
array_push($error,$C_translate->translate('install_failed','module',''));
# Set the errors as a Smarty Object
if ($smarty)
$smarty->assign('form_validation',$error);
#printf('Problem with: %s',$module);
#echo '<PRE>';print_r($error);
return false;
}
# Load the install XML file...
$C_xml = new CORE_xml;
$install = $C_xml->xml_to_array($xml_construct);
$this->install = $install;
# Get the module properties:
$name = $install['install']['module_properties']['name'];
if (isset($install['install']['module_properties']['parent']) && $install['install']['module_properties']['parent'] != $module)
$parent = $install['install']['module_properties']['parent'];
else
$parent = '';
# Get dependancies
if (isset($install['install']['module_properties']['dependancy']))
$dependancy = sprintf('%s,%s',$parent,$install['install']['module_properties']['dependancy']);
else
$dependancy = $parent;
if ($dependancy) {
if (preg_match('/,/', $dependancy))
$depend = explode(',',$dependancy);
else
$depend = array($dependancy);
# Check to be sure the dependancies are installed:
for ($i=0; $i < count($depend); $i++) {
$result = $db->Execute(sqlSelect($db,'module','name',array('name'=>$depend[$i],'status'=>1)));
if (! $result || ($result && ! $result->RecordCount()))
array_push($error,sprintf(_('Module %s depends on %s, which is not installed?'),$module,$depend[$i]));
}
}
# check for error:
if (count($error)) {
array_push($error,$C_translate->translate('install_failed','module',''));
# Set the errors as a Smarty Object
if ($smarty)
$smarty->assign('form_validation',$error);
else {
printf('Problem with: %s',$module);
echo '<PRE>';print_r($error);
}
return false;
}
return true;
}
/**
* Module SQL Install
*/
public function install_sql($module,$nodata=false) {
global $VAR,$smarty;
#printf('Installing Step 1: <b>%s</b>...<br/>',$module);
# Load the install XML file
$C_xml = new CORE_xml;
$xml = sprintf('%s%s/%s_install.xml',PATH_MODULES,$module,$module);
if (! is_file($xml))
return false;
$install = $C_xml->xml_to_array($xml);
# Load the construct XML file
$C_xml = new CORE_xml;
$xml = sprintf('%s%s/%s_construct.xml',PATH_MODULES,$module,$module);
if (! is_file($xml))
return false;
$construct = $C_xml->xml_to_array($xml);
$db = &DB();
$t = $db->MetaTables();
# Check that this Module has any db installation required
if (isset($construct['construct']['table']) && ! in_array(AGILE_DB_PREFIX.$construct['construct']['table'],$t)) {
# 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 = '';
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 (preg_match('/[(]/',$t_s)) {
$ts = explode('(',$t_s);
$type = $ts[0];
$size = preg_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
$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(__FILE__,__METHOD__,$db->ErrorMsg().' '.print_r($sqlarray[0],true));
echo $db->ErrorMsg();
return false;
}
# Create unique index on site_id,id (mysql specific)
$db->Execute(sprintf('CREATE UNIQUE INDEX IDS on %s%s (site_id,id)',AGILE_DB_PREFIX,$table));
# Create any custom indexes
if (isset($construct['construct']['index']) && count($construct['construct']['index'])) {
$new_indexes = $construct['construct']['index'];
while (list($index,$fields) = each($new_indexes)) {
$dict = NewDataDictionary($db);
if (preg_match('/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]);
}
}
}
}
if ($nodata)
return true;
#printf('Installing Step 2: <b>%s</b>...<br/>',$module);
# Get the module properties:
$menu_display = isset($install['install']['module_properties']['menu_display']) ? $install['install']['module_properties']['menu_display'] : '';
$notes = isset($install['install']['module_properties']['notes']) ? $install['install']['module_properties']['notes'] : '';
# Get the parent module...
$db = &DB();
$module_id = $db->GenID(AGILE_DB_PREFIX.'module_id');
if (isset($install['install']['module_properties']['parent'])) {
$result = $db->Execute(sqlSelect($db,'module','id',array('name'=>$install['install']['module_properties']['parent'])));
# Error checking
if ($result === false) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
}
if (! trim($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... */
$result = $db->Execute(sqlInsert($db,'module',array(
'name'=>$module,
'parent_id'=>$parent_id,
'notes'=>$notes,
'status'=>1,
'menu_display'=>$menu_display,
'date_orig'=>time(),
'date_last'=>time()),$module_id)
);
#printf('Installing Step 3: <b>%s</b>...<br/>',$module);
# Create the module_method records, and get the ID for each one
if (isset($install['install']['module_method']))
$methods = $install['install']['module_method'];
else
$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');
$notes = isset($methods[$key]['notes']) ? $methods[$key]['notes'] : '';
$page = isset($methods[$key]['page']) ? $methods[$key]['page'] : '';
$menu_display = isset($methods[$key]['menu_display']) ? 1 : 0;
$result = $db->Execute(sqlInsert($db,'module_method',array(
'name'=>$name,
'module_id'=>$module_id,
'notes'=>$notes,
'page'=>$page,
'menu_display'=>$menu_display
),$method_id));
# Error checking
if ($result === false) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
}
#printf('Installing Step 4: <b>%s:%s</b>...<br/>',$module,$name);
/* 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++) {
$db = &DB();
$result = $db->Execute(sqlInsert($db,'group_method',array('method_id'=>$method_id,'module_id'=>$module_id,'group_id'=>$VAR['module_group'][$i])));
# Error checking
if ($result === false) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
}
}
}
}
printf('Finished <b>%s</b>...<br/>',$module);
# All done!
return true;
}
/**
* Install Default Data
*/
public function install_sql_data($module) {
# Check the file
$f = sprintf('%s%s/%s_install_data.xml',PATH_MODULES,$module,$module);
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 = sprintf('INSERT INTO %s%s SET ',AGILE_DB_PREFIX,$table);
if (is_array($records)) {
$sql = '';
$sqlcount = 0;
# Loop through each of the fields for this module
while (list($fld,$val) = each($records)) {
if (is_array($val)) {
$sql = '';
$sqlcount = 0;
# Loop through each of the fields for this module
while (list($fld2,$val2) = each($val)) {
if ($sqlcount != 0)
$sql .= ', ';
$sql .= $fld2 .' = '.$db->qstr($val2);
$sqlcount++;
}
$result = $db->Execute(sprintf('%s %s',$sqls,$sql));
} else {
if ($sqlcount != 0)
$sql .= ', ';
$sql .= sprintf('%s = %s',$fld,$db->qstr($val));
$sqlcount++;
$runsql = true;
}
}
if ($runsql) {
$result = $db->Execute(sprintf('%s %s',$sqls,$sql));
if ($result === false)
@$this->error .= sprintf('<br/> %s %s',$sqls,$sql);
}
}
}
}
}
}
/**
* Check Version
*/
public 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'));
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);
}
/** OLD FUNCTIONS **/
### 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;
}
##############################
## 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($j=0; $j<count($core); $j++) {
if($core[$j] == $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(DEFAULT_SITE==1 && 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]);
}
}
}
}
/**
* Module upgrader
*
* This function will update the schema if required
*/
public 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','*',sprintf('id=::%s:: OR name=::%s::',$modules[$i],$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 = sprintf('%s%s/%s_install.xml',PATH_MODULES,$module_name,$module_name);
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
$method_db = $db->Execute(sqlSelect($db,'module_method','*',array('name'=>$key,'module_id'=>$module_id)));
if ($method_db === false) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$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(__FILE__,__METHOD__,$db->ErrorMsg());
}
# Create the group_method records, with the ID from each
for ($ii=0; $ii<count($VAR['module_group']); $ii++) {
$result = $db->Execute(sqlInsert($db,'group_method',array('method_id'=>$method_id,'module_id'=>$module_id,'group_id'=>$VAR['module_group'][$ii])));
if ($result === false) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
}
}
}
}
}
}
# Update the DB Fields from the <module>_construct.xml file get the install xml file
$construct_xml = sprintf('%s%s/%s_construct.xml',PATH_MODULES,$module_name,$module_name);
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:
$flds = array();
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 (preg_match('/[(]/',$t_s)) {
$ts = explode('(',$t_s);
$type = $ts[0];
$size = preg_replace('/[)]/','',$ts[1]);
array_push($flds,array($field,$type,$size));
} else {
array_push($flds,array($field,$t_s));
}
}
}
# Add any new columns:
if (count($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(__FILE__,__METHOD__,$db->ErrorMsg());
echo $db->ErrorMsg();
}
}
# Remove any unused columns
$flds = array();
while (list ($key,$value) = each($db_fields)) {
$fieldname = strtolower($key);
if (! isset($construct['construct']['field'][$fieldname]))
array_push($flds,$key);
}
if (count($flds)) {
$dict = NewDataDictionary($db);
$sqlarray = $dict->DropColumnSQL(AGILE_DB_PREFIX.$table,$flds);
$result = $db->Execute($sqlarray[0]);
if ($result === false) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
echo $db->ErrorMsg();
}
}
# 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->Execute(sprintf('ALTER TABLE %s DROP PRIMARY KEY',AGILE_DB_PREFIX.$table));
$db->Execute(sprintf('CREATE UNIQUE INDEX IDS ON %s (site_id,id)',AGILE_DB_PREFIX.$table));
}
$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 (preg_match('/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 (preg_match('/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]);
}
}
# 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 = sprintf('Successfully checked %s module(s), %s method(s), and %s db fields.<br/>Added %s method(s) and %s db field(s).',
$module_count,$method_count,$fields_count,$method_new_count,$fields_new_count);
if (! empty($fields_new_count) > 0) {
global $smarty;
if (is_object($smarty))
$smarty->assign('js','<script type="text/javascript" language="javascript">document.getElementById("module_add").submit();</script>');
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);
}
}
?>