File: //opt/cpanel/ea-php54/root/usr/share/pear/RVSeagullMod/lib/SGL/Task/Install.php
<?php
/* Reminder: always indent with 4 spaces (no tabs). */
// +---------------------------------------------------------------------------+
// | Copyright (c) 2008, Demian Turner |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution. |
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +---------------------------------------------------------------------------+
// | Seagull 0.6 |
// +---------------------------------------------------------------------------+
// | Install.php |
// +---------------------------------------------------------------------------+
// | Author: Demian Turner <demian@phpkitchen.com> |
// +---------------------------------------------------------------------------+
require_once dirname(__FILE__) . '/../Task.php';
require_once dirname(__FILE__) . '/../Install/Common.php';
/**
* @package Task
*/
class SGL_Task_SetBaseUrlMinimal extends SGL_Task
{
public function run($data = null)
{
// no data if we're running installer
if (!defined('SGL_INSTALLED')) {
$conf = array(
'site' => array(
'setup' => true,
'frontScriptName' => 'index.php',
'defaultModule' => 'default',
'defaultManager' => 'default',
),
'cookie' => array('name' => ''),
);
//RVS START rewrite front Script Name
if (defined('RVS_AUTO_SETUP')) {
// auto-correct frontScriptName for CGI users
if (preg_match("/cgi|apache2filter/i", php_sapi_name())) {
$conf['site']['frontScriptName'] = 'rvsindex.php?';
} else {
$conf['site']['frontScriptName'] = 'rvsindex.php';
}
}
//RVS END rewrite
// create default config values for install
$c = SGL_Config::singleton($autoLoad = false);
$c->merge($conf);
}
// resolve value for $_SERVER['PHP_SELF'] based in host
SGL_URL::resolveServerVars();
$url = new SGL_URL($_SERVER['PHP_SELF'], true, new SGL_UrlParser_SefStrategy());
$err = $url->init();
if (defined('SGL_BASE_URL') === false) {
define('SGL_BASE_URL', $url->getBase());
}
}
}
/**
* @package Task
*/
class SGL_Task_SetTimeout extends SGL_Task
{
public function run($data=null)
{
if (array_key_exists('storeTranslationsInDB', $data)
&& $data['storeTranslationsInDB'] == 1)
{
$ok = set_time_limit(60*(count($data['installLangs'])));
} else {
$ok = set_time_limit(120);
}
return $ok;
}
}
/**
* @package Task
*/
class SGL_Task_CreateConfig extends SGL_Task
{
public function run($data=null)
{
//print_r($data); exit;
$c = SGL_Config::singleton($autoLoad = false);
$oldConf = $c->getAll(); // save old config on re-install
$conf = $c->load(SGL_ETC_DIR . '/default.conf.dist.ini');
$c->replace($conf);
$c->merge($oldConf); // overwrite with old values
// set module page title $conf[$module]['title']
foreach ($data['aModuleList'] as $module) {
if ( isset($data[$module . '_title']) === true) {
$pageTitle = $data[$module . '_title'] != '' ? $data[$module . '_title'] : $data['siteName'];
$c->set($module, array('title' => $pageTitle));
}
}
//set home page title
if ( isset($data['home_title']) === true && $data['home_title'] != '') {
$c->set('home', array('title' => $data['home_title']));
} else {
$c->set('home', array('title' => $data['siteName']));
}
// admin emails
$c->set('email', array('admin' => $data['adminEmail']));
$c->set('email', array('info' => $data['adminEmail']));
$c->set('email', array('support' => $data['adminEmail']));
// correct db prefix
if (!empty($data['prefix']) && substr($data['prefix'], -1) != '_') {
// enforce underscore in prefix
$data['prefix'] .= '_';
}
// mysql storage
$mysqlStorageEngine = !empty($data['dbMysqlDefaultStorageEngine'])
? $data['dbMysqlDefaultStorageEngine']
: false;
// db details
$c->set('db', array('prefix' => $data['prefix']));
$c->set('db', array('host' => $data['host']));
$c->set('db', array('name' => $data['name']));
$c->set('db', array('user' => $data['databaseUser']));
$c->set('db', array('pass' => $data['databaseUserPass']));
$c->set('db', array('port' => $data['dbPort']['port']));
$c->set('db', array('protocol' => $data['dbProtocol']['protocol']));
$c->set('db', array('socket' => $data['socket']));
$c->set('db', array('type' => $data['dbType']['type']));
$c->set('db', array('postConnect' => $data['postConnect']));
$c->set('db', array('mysqlDefaultStorageEngine' => $mysqlStorageEngine));
$c->set('db', array('sepTableForEachSequence' => !$data['dbSequencesInOneTable']['dbSequences']));
// version
$c->set('tuples', array('version' => $data['frameworkVersion']));
// demo mode
if (is_file(SGL_VAR_DIR . '/DEMO_MODE')) {
$c->set('tuples', array('demoMode' => true));
}
// paths
$c->set('path', array('installRoot' => $data['installRoot']));
$c->set('path', array('webRoot' => $data['webRoot']));
// reset moduleOverride on re-install
$c->set('path', array('moduleDirOverride' => ''));
// various
$c->set('site', array('serverTimeOffset' => $data['serverTimeOffset']));
$c->set('site', array('baseUrl' => SGL_BASE_URL));
$c->set('site', array('name' => $data['siteName']));
$c->set('site', array('description' => $data['siteDesc']));
$c->set('site', array('keywords' => $data['siteKeywords']));
$c->set('site', array('blocksEnabled' => true));
$c->set('cookie', array('name' => $data['siteCookie']));
// store translations in db
(array_key_exists('storeTranslationsInDB', $data)
&& $data['storeTranslationsInDB'] == 1)
? $c->set('translation', array('container' => 'db'))
: $c->set('translation', array('container' => 'file'));
// add missing translations to db
(array_key_exists('addMissingTranslationsToDB', $data)
&& $data['addMissingTranslationsToDB'] == 1)
? $c->set('translation', array('addMissingTrans' => true))
: $c->set('translation', array('addMissingTrans' => false));
// translation fallback language
$fallbackLang = str_replace('-', '_', $data['siteLanguage']);
$c->set('translation', array('fallbackLang' => $fallbackLang));
// auto-correct frontScriptName for CGI users
if (preg_match("/cgi|apache2filter/i", php_sapi_name())) {
$c->set('site', array('frontScriptName' => 'index.php?'));
}
// parse custom config overrides
foreach ($data as $k => $v) {
if (is_array($v)) {
foreach ($v as $kk => $vv) {
if ($c->exists(array($k => $kk))) {
$c->set($k, array($kk => $vv));
}
}
}
}
// remove setup key before writing out file
$ok = $c->remove(array('site', 'setup'));
//RVS START rewrite front script name
if (defined('RVS_AUTO_SETUP')) {
// auto-correct frontScriptName for CGI users
if (preg_match("/cgi|apache2filter/i", php_sapi_name())) {
$c->set('site', array('frontScriptName' => 'rvsindex.php?'));
} else {
$c->set('site', array('frontScriptName' => 'rvsindex.php'));
}
}
//RVS END
// save
$configFile = SGL_VAR_DIR . '/' . SGL_SERVER_NAME . '.conf.php';
$ok = $c->save($configFile);
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
// store site language for post-install task
$_SESSION['install_language'] = $data['siteLanguage'];
// and tz
$_SESSION['install_timezone'] = $data['serverTimeOffset'];
// store old prefix for tables drop
if (isset($oldConf['db']['prefix'])
&& $oldConf['db']['prefix'] != $data['prefix']) {
$_SESSION['install_dbPrefix'] = $oldConf['db']['prefix'];
}
return $ok;
}
}
/**
* @package Task
*/
class SGL_UpdateHtmlTask extends SGL_Task
{
public function updateHtml($id, $displayHtml)
{
if (SGL::runningFromCli() || defined('SGL_ADMIN_REBUILD')) {
return false;
}
if ($id == 'status') {
$msg = $displayHtml;
$displayHtml = '<span class=\\"pageTitle\\">' . $msg . '</span>';
}
echo "<script>
document.getElementById('$id').innerHTML=\"$displayHtml\";
</script>";
// echo 5K+ worth of spaces, since some browsers will buffer internally until they get 4K
echo str_repeat(' ', 5120);
flush();
}
public function setup()
{
$c = SGL_Config::singleton();
$this->conf = $c->getAll();
// setup db type vars
$this->dbType = $this->conf['db']['type'];
switch ($this->conf['db']['type']) {
case 'pgsql':
$this->filename1 = '/schema.pg.sql';
$this->filename2 = '/data.default.pg.sql';
$this->filename3 = '/data.sample.pg.sql';
$this->filename4 = '/data.block.add.pg.sql';
$this->filename5 = '/data.custom.pg.sql';
$this->filename6 = '/data.test.pg.sql';
$this->filename7 = '/constraints.pg.sql';
break;
case 'mysql':
case 'mysqli':
case 'mysql_SGL':
case 'mysqli_SGL':
$this->filename1 = '/schema.my.sql';
$this->filename2 = '/data.default.my.sql';
$this->filename3 = '/data.sample.my.sql';
$this->filename4 = '/data.block.add.my.sql';
$this->filename5 = '/data.custom.my.sql';
$this->filename6 = '/data.test.my.sql';
$this->filename7 = '/constraints.my.sql';
//RVS START Add file update schema, file update data for
$this->fileupdate1 = '/schema.my.{x}.sql';
$this->fileupdate2 = '/data.default.my.{x}.sql';
//RVS END
break;
case 'oci8_SGL':
$this->dbType = 'oci8'; // exception to dbType naming
$this->filename1 = '/schema.oci.sql';
$this->filename2 = '/data.default.oci.sql';
$this->filename3 = '/data.sample.oci.sql';
$this->filename4 = '/data.block.add.oci.sql';
$this->filename5 = '/data.custom.oci.sql';
$this->filename6 = '/data.test.oci.sql';
$this->filename7 = '/constraints.oci.sql';
break;
}
// these hold what to display in results grid, depending on outcome
$this->success = '<img src=\\"' . SGL_BASE_URL . '/themes/default/images/enabled.gif\\" border=\\"0\\" width=\\"22\\" height=\\"22\\">' ;
$this->failure = '<span class=\\"error\\">ERROR</span>';
$this->noFile = '<strong>N/A</strong>';
}
}
/**
* @package Task
*/
class SGL_Task_DefineTableAliases extends SGL_Task
{
public function run($data = null)
{
SGL::logMessage("run =====", PEAR_LOG_DEBUG);
$c = SGL_Config::singleton();
// get table prefix
$prefix = $c->get(array('db' => 'prefix'));
foreach ($data['aModuleList'] as $module) {
$tableAliasIniPath = SGL_MOD_DIR . '/' . $module . '/data/tableAliases.ini';
if (file_exists($tableAliasIniPath)) {
$aData = parse_ini_file($tableAliasIniPath);
foreach ($aData as $k => $v) {
$c->set('table', array($k => $prefix . $v));
}
} else {
$tableAliasIniPath = SGL_WEB_ROOT . '/' . $module . '/tableAliases.ini';
if (file_exists($tableAliasIniPath)) {
$aData = parse_ini_file($tableAliasIniPath);
//print_r($aData);exit;
foreach ($aData as $k => $v) {
$c->set('table', array($k => $prefix . $v));
}
}
}
}
// save
$configFile = (SGL::runningFromCli())
? SGL_VAR_DIR . '/' . $data['serverName']. '.conf.php'
: SGL_VAR_DIR . '/' . SGL_SERVER_NAME . '.conf.php';
$ok = $c->save($configFile);
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
return $ok;
}
}
/**
* @package Task
*/
class SGL_Task_DisableForeignKeyChecks extends SGL_Task
{
public function run($data=null)
{
$c = SGL_Config::singleton();
$this->conf = $c->getAll();
// disable fk constraints if mysql (>= 4.1.x)
if ($this->conf['db']['type'] == 'mysql_SGL'
|| $this->conf['db']['type'] == 'mysql'
|| $this->conf['db']['type'] == 'mysqli'
|| $this->conf['db']['type'] == 'mysqli_SGL') {
$dbh = SGL_DB::singleton();
if (SGL::isError($dbh)) {
SGL_Install_Common::errorPush($dbh);
return $dbh;
}
$query = 'SET FOREIGN_KEY_CHECKS=0;';
$res = $dbh->query($query);
if (SGL::isError($res)) {
SGL_Install_Common::errorPush($res);
}
return $res;
}
}
}
/**
* @package Task
*/
class SGL_Task_CreateDatabase extends SGL_Task
{
public function run($data=null)
{
$c = SGL_Config::singleton();
$this->conf = $c->getAll();
if ($this->conf['db']['type'] == 'pgsql') {
$excludeDbName = false;
} else {
$excludeDbName = true;
}
$dsn = SGL_DB::getDsn(SGL_DSN_STRING, $excludeDbName);
$dbh = SGL_DB::singleton($dsn);
$query = SGL_Sql::buildDbCreateStatement($this->conf['db']['type'],
$dbh->quoteIdentifier($this->conf['db']['name']));
$res = $dbh->query($query);
if (SGL::isError($res)) {
SGL_Install_Common::errorPush($res);
}
}
}
/**
* @package Task
*/
class SGL_Task_DropDatabase extends SGL_Task
{
public function run($data=null)
{
$c = SGL_Config::singleton();
$this->conf = $c->getAll();
$dbh = SGL_DB::singleton();
require_once SGL_CORE_DIR . '/Sql.php';
$query = SGL_Sql::buildDbDropStatement($this->conf['db']['type'],
$dbh->quoteIdentifier($this->conf['db']['name']));
$res = $dbh->query($query);
if (SGL::isError($res)) {
SGL_Install_Common::errorPush($res);
}
}
}
/**
* @package Task
*/
class SGL_Task_PrepareInstallationProgressTable extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
SGL_Install_Common::printHeader('Building Database');
if (!(SGL::runningFromCli() || defined('SGL_ADMIN_REBUILD'))) {
echo '<span class="title">Status: </span><span id="status"></span>
<div id="progress_bar">
<img src="' . SGL_BASE_URL . '/themes/default/images/progress_bar.gif" border="0" width="150" height="13">
</div>
<div id="additionalInfo"></div>';
flush();
}
if (array_key_exists('createTables', $data) && $data['createTables'] == 1) {
$this->setup();
$statusText = 'Fetching modules';
$this->updateHtml('status', $statusText);
// Print table shell, with module names; we'll update statuses as we execute sql below
$out = '<table class="wide">
<tr>
<th class="alignCenter">Module</th>
';
if (!array_key_exists('useExistingData', $data) || $data['useExistingData'] == 0) {
$out .= '<th class="alignCenter">Drop Table</th>
';
}
$out .= '<th class="alignCenter">Create Table</th>
<th class="alignCenter">Load Default Data</th>
';
if (array_key_exists('insertSampleData', $data) && $data['insertSampleData'] == 1) {
$out .= '<th class="alignCenter">Load Sample Data</th>
';
}
$out .= '<th class="alignCenter">Add Constraints</th>
</tr>';
if (!(SGL::runningFromCli() || defined('SGL_ADMIN_REBUILD'))) {
echo $out;
}
foreach ($data['aModuleList'] as $module) {
$out = '<tr>
<td class="title">' . ucfirst($module) . '</td>
';
if (!array_key_exists('useExistingData', $data) || $data['useExistingData'] == 0) {
$out .= '<td id="' . $module . '_drop" class="alignCenter"></td>
';
}
$out .= '<td id="' . $module . '_schema" class="alignCenter"></td>
<td id="' . $module . '_data" class="alignCenter"></td>
';
if (array_key_exists('insertSampleData', $data) && $data['insertSampleData'] == 1) {
$out .='<td id="' . $module . '_dataSample" class="alignCenter"></td>
';
}
$out .= '<td id="' . $module . '_constraints" class="alignCenter"></td>
</tr>';
if (!(SGL::runningFromCli() || defined('SGL_ADMIN_REBUILD'))) {
echo $out;
}
}
if (!(SGL::runningFromCli() || defined('SGL_ADMIN_REBUILD'))) {
echo '</table>';
flush();
}
}
}
}
/**
* @package Task
*/
class SGL_Task_DropTables extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
require_once SGL_CORE_DIR . '/Sql.php';
$errorNoTable = (SGL_DB_DRIVER === 'DB')
? DB_ERROR_NOSUCHTABLE
: MDB2_ERROR_NOSUCHTABLE;
if (array_key_exists('createTables', $data) && $data['createTables'] == 1
&& (!array_key_exists('useExistingData', $data) || $data['useExistingData'] == 0)) {
$this->setup();
$statusText = 'dropping existing tables';
$this->updateHtml('status', $statusText);
$c = SGL_Config::singleton();
$dbh = SGL_DB::singleton();
// set old db prefix if any
if (isset($_SESSION['install_dbPrefix'])) {
$currentPrefix = $c->get(array('db' => 'prefix'));
$c->set('db', array('prefix' => $_SESSION['install_dbPrefix']));
}
// drop 'sequence' table unless we're installing a module
$aTable = $dbh->getListOf('tables');
if ($this->conf['db']['type'] == 'mysql_SGL' && !array_key_exists('moduleInstall', $data)) {
$aSeqTableName = SGL_Sql::extractTableNamesFromSchema(SGL_ETC_DIR . '/sequence.my.sql');
foreach ($aSeqTableName as $seqTableName) {
if (in_array($tableName, $aTable) === false) {
continue;
}
$query = 'DROP TABLE '. $dbh->quoteIdentifier($seqTableName);
$seqResult = $dbh->query($query);
//if (SGL::isError($seqResult, DB_ERROR_NOSUCHTABLE)) {
if (SGL::isError($seqResult, $errorNoTable)) {
SGL_Error::pop();
}
}
}
// Load each module's schema, if there is a sql file in /data
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
// Load the module's schema
if (file_exists($modulePath . $this->filename1)) {
$aTableNames = SGL_Sql::extractTableNamesFromSchema($modulePath . $this->filename1);
$tableExists = true;
$dropSucceeded = true;
foreach ($aTableNames as $tableName) {
if (in_array($tableName, $aTable) === false) {
continue;
}
$query = 'DROP TABLE ' . $dbh->quoteIdentifier($tableName);
$result = $dbh->query($query);
if (SGL::isError($result)) {
//if (SGL::isError($result, DB_ERROR_NOSUCHTABLE)) {
if (SGL::isError($result, $errorNoTable)) {
SGL_Error::pop();
$tableExists = false;
} else {
$dropSucceeded = false;
}
}
}
if (!$dropSucceeded) {
$displayHtml = $this->failure;
} elseif (!$tableExists) {
$displayHtml = $this->noFile;
} else {
$displayHtml = $this->success;
}
// remove tablename in Config
if (isset($data['moduleInstall'])) {
foreach ($aTableNames as $tableName) {
$c->remove(array('table', $tableName));
}
// save
$fileName = SGL_VAR_DIR . '/' . SGL_SERVER_NAME . '.conf.php';
$ok = $c->save($fileName);
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
}
$this->updateHtml($module . '_drop', $displayHtml);
} else {
$this->updateHtml($module . '_drop', $this->noFile);
}
}
// remove translation tables and lang table
if (!array_key_exists('moduleInstall', $data)) {
$conf = $c->getAll();
if ($conf['translation']['container'] == 'db') {
$statusText = 'dropping translation tables';
$this->updateHtml('status', $statusText);
$trans = SGL_Translation::singleton('admin');
$aLangs = $trans->getLangs('ids');
if (!SGL::isError($aLangs)) {
// removeme
if (empty($aLangs)) {
// basically $aLangs should be a PEAR_Error instance
// in that case, but calling method doesn't
// return it
SGL_Error::pop();
}
// dropping language tables
foreach ($aLangs as $langId) {
// force to drop translation table
$ok = $trans->removeLang($langId, $force = true);
//if (SGL::isError($ok, DB_ERROR_NOSUCHTABLE)) {
if (SGL::isError($ok, $errorNoTable)) {
SGL_Error::pop();
}
}
//} elseif (SGL::isError($aLangs, DB_ERROR_NOSUCHTABLE)) {
} elseif (SGL::isError($aLangs, $errorNoTable)) {
SGL_Error::pop();
}
// drop language table
$langTable = &$trans->storage->options['langs_avail_table'];
$query = 'DROP TABLE ' . $dbh->quoteIdentifier($langTable);
$ok = $dbh->query($query);
//if (SGL::isError($ok, DB_ERROR_NOSUCHTABLE)) {
if (SGL::isError($ok, $errorNoTable)) {
SGL_Error::pop();
}
// removeme: it looks like a hack
if (isset($currentPrefix)) {
$pattern = "/^{$conf['db']['prefix']}/";
$langTable = preg_replace($pattern, '', $langTable);
$langTable = $currentPrefix . $langTable;
}
}
}
// restore db prefix
if (isset($currentPrefix)) {
$c->set('db', array('prefix' => $currentPrefix));
}
}
}
}
/**
* @package Task
*/
class SGL_Task_CreateTables extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
require_once SGL_CORE_DIR . '/Sql.php';
if (array_key_exists('createTables', $data) && $data['createTables'] == 1) {
$this->setup();
$statusText = 'creating and loading tables';
$this->updateHtml('status', $statusText);
// load 'sequence' table
if ($this->conf['db']['type'] == 'mysql_SGL' || $this->conf['db']['type'] == 'mysqli_SGL') {
$result = SGL_Sql::parse(SGL_ETC_DIR . '/sequence.my.sql', 0, array('SGL_Sql', 'execute'));
}
// Load each module's schema, if there is a sql file in /data
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
// Load the module's schema
if (file_exists($modulePath . $this->filename1)) {
$result = SGL_Sql::parse($modulePath . $this->filename1, 0, array('SGL_Sql', 'execute'));
if (SGL::isError($result)) {
return $result;
}
$displayHtml = $result ? $this->success : $this->failure;
$this->updateHtml($module . '_schema', $displayHtml);
} else {
$this->updateHtml($module . '_schema', $this->noFile);
}
//RVS START Make module database lavel install in config
if (defined('RVS_AUTO_SETUP')) {
$c = SGL_Config::singleton();
$c->set('rvs_db_level', array($module => '1'));
}
//RVS END
}
// RVS START - Save Config files
if (defined('RVS_AUTO_SETUP')) {
$config = SGL_VAR_DIR . '/' . SGL_SERVER_NAME . '.conf.php';
$ok = $c->save($config);
}
// RVS END - Save Config files
// catch 'table already exists' error
$errorAlreadyExists = (SGL_DB_DRIVER === 'DB')
? DB_ERROR_ALREADY_EXISTS
: MDB2_ERROR_ALREADY_EXISTS;
//if (isset($result) && SGL::isError($result, DB_ERROR_ALREADY_EXISTS)) {
if (isset($result) && SGL::isError($result, $errorAlreadyExists)) {
if (SGL::runningFromCli() || defined('SGL_ADMIN_REBUILD')) {
die('Tables already exist, DB error');
} else {
$this->updateHtml('status', 'Tables already exist');
$body = 'It appears that the schema already exists. Click <a href=\\"index.php\\">here</a> to return to the configuration screen and choose \\"Only set DB connection details\\".';
$this->updateHtml('additionalInfo', $body);
$this->updateHtml('progress_bar', '');
exit;
}
}
}
}
}
/**
* @package Task
*/
class SGL_Task_LoadDefaultData extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
$result = false;
if (array_key_exists('createTables', $data) && $data['createTables'] == 1) {
$this->setup();
$statusText = 'loading default data';
$this->updateHtml('status', $statusText);
// Go back and load each module's default data, if there is a sql file in /data
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
// Load the module's data
if (file_exists($modulePath . $this->filename2)) {
$result = SGL_Sql::parse($modulePath . $this->filename2, 0, array('SGL_Sql', 'execute'));
if (SGL::isError($result)) {
return $result;
}
$displayHtml = $result ? $this->success : $this->failure;
$this->updateHtml($module . '_data', $displayHtml);
} else {
$this->updateHtml($module . '_data', $this->noFile);
}
}
}
return $result;
}
}
/**
* @package Task
*/
class SGL_Task_LoadSampleData extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
$result = false;
if (array_key_exists('insertSampleData', $data) && $data['insertSampleData'] == 1) {
$this->setup();
$statusText = 'loading sample data';
$this->updateHtml('status', $statusText);
// Go back and load each module's default data, if there is a sql file in /data
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
// Load the module's data
if (file_exists($modulePath . $this->filename3)) {
$result = SGL_Sql::parse($modulePath . $this->filename3, 0, array('SGL_Sql', 'execute'));
$displayHtml = $result ? $this->success : $this->failure;
$this->updateHtml($module . '_dataSample', $displayHtml);
} else {
$this->updateHtml($module . '_dataSample', $this->noFile);
}
}
}
return $result;
}
}
/**
* @package Task
*/
class SGL_Task_LoadCustomData extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
$this->setup();
$statusText = 'loading custom data';
$this->updateHtml('status', $statusText);
$result = false;
// Go back and load each module's custom data, if there is a custom sql file in /data
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
// Load the module's custom data if exists
if (file_exists($modulePath . $this->filename5)) {
$result = SGL_Sql::parse($modulePath . $this->filename5, 0, array('SGL_Sql', 'execute'));
}
}
return $result;
}
}
/**
* @package Task
*/
class SGL_Task_RemoveDefaultData extends SGL_Task
{
public function run($data=null)
{
require_once SGL_MOD_DIR . '/default/classes/DefaultDAO.php';
$da = DefaultDAO::singleton();
// get perms associated with module
$aPermNames = $da->getPermNamesByModuleId($data['moduleId']);
// delete role_permissions
foreach ($aPermNames as $permName) {
$permId = $da->getPermissionIdByPermName($permName);
$ok = $da->deleteRolePermissionByPermId($permId);
}
// then delete perms
$ok = $da->deletePermsByModuleId($data['moduleId']);
}
}
/**
* @package Task
*/
class SGL_Task_LoadBlockData extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
$result = false;
if (array_key_exists('createTables', $data) && $data['createTables'] == 1
&& (!array_key_exists('useExistingData', $data) || $data['useExistingData'] == 0)) {
$this->setup();
$statusText = 'loading block data';
$this->updateHtml('status', $statusText);
// Go back and load each module's default data, if there is a sql file in /data
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
// Load the module's data
if (file_exists($modulePath . $this->filename4)) {
$result = SGL_Sql::parse($modulePath . $this->filename4, 0, array('SGL_Sql', 'execute'));
}
}
}
return $result;
}
}
/**
* @package Task
*/
class SGL_Task_RemoveBlockData extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
$this->setup();
// Go back and load each module's default data, if there is a sql file in /data
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
// remove the module's block data
// switch 'add' to 'remove'
$filename = str_replace('add', 'remove', $this->filename4);
if (is_file($modulePath . $filename)) {
$result = SGL_Sql::parse($modulePath . $filename, 0, array('SGL_Sql', 'execute'));
}
}
}
}
/**
* @package Task
*/
class SGL_Task_CreateConstraints extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
if (array_key_exists('createTables', $data) && $data['createTables'] == 1) {
$this->setup();
$statusText = 'loading constraints';
$this->updateHtml('status', $statusText);
// Go back and load module foreign keys/constraints, if any
foreach ($data['aModuleList'] as $module) {
$modulePath = SGL_MOD_DIR . '/' . $module . '/data';
if (file_exists($modulePath . $this->filename7)) {
$result = SGL_Sql::parse($modulePath . $this->filename7, 0, array('SGL_Sql', 'execute'));
$displayHtml = $result ? $this->success : $this->failure;
$this->updateHtml($module . '_constraints', $displayHtml);
} else {
$this->updateHtml($module . '_constraints', $this->noFile);
}
}
}
}
}
define('SGL_NODE_USER', 2); // nested set parent_id
define('SGL_NODE_ADMIN', 4); // nested set parent_id
define('SGL_NODE_GROUP', 1);
/**
* @package Task
*/
class SGL_Task_BuildNavigation extends SGL_UpdateHtmlTask
{
var $groupId = null;
var $childId = null;
public function run($data=null)
{
if (array_key_exists('createTables', $data) && $data['createTables'] == 1
&& (!array_key_exists('useExistingData', $data) || $data['useExistingData'] == 0)
&& SGL_Config::get('navigation.driver') != 'ArrayDriver') {
require_once SGL_MOD_DIR . '/navigation/classes/NavigationDAO.php';
$da = NavigationDAO::singleton();
foreach ($data['aModuleList'] as $module) {
$navigationPath = SGL_MOD_DIR . '/' . $module . '/data/navigation.php';
if (file_exists($navigationPath)) {
require_once $navigationPath;
if (isset($aSections)) {
foreach ($aSections as $aSection) {
// check if section is designated as child to last insert
if ($aSection['parent_id'] == SGL_NODE_GROUP) {
$aSection['parent_id'] = $this->groupId;
}
$id = $da->addSimpleSection($aSection);
if (!SGL::isError($id)) {
if ($aSection['parent_id'] == SGL_NODE_ADMIN
|| $aSection['parent_id'] == SGL_NODE_USER) {
$this->groupId = $id;
} else {
$this->childId = $id;
}
} else {
SGL_Install_Common::errorPush($id);
}
}
}
}
}
} elseif (SGL_Config::get('navigation.driver') == 'ArrayDriver') {
require_once SGL_MOD_DIR . '/navigation/classes/ArrayDriver.php';
$aNodes = ArrayDriver::getNavigationStructure();
$ok = ArrayDriver::saveNodes($aNodes);
if (!$ok) {
SGL::raiseError('ArrayDriver: can\'t save nodes');
}
}
}
}
/**
* @package Task
*/
class SGL_Task_RemoveNavigation extends SGL_Task
{
public function run($data=null)
{
require_once SGL_MOD_DIR . '/navigation/classes/NavigationDAO.php';
$da = NavigationDAO::singleton();
foreach ($data['aModuleList'] as $module) {
$navigationPath = SGL_MOD_DIR . '/' . $module . '/data/navigation.php';
if (file_exists($navigationPath)) {
require_once $navigationPath;
foreach ($aSections as $aSection) {
$sectionId = $da->getSectionIdByTitle($aSection['title']);
if ($sectionId) {
$ok = $da->deleteSectionById($sectionId);
}
}
}
}
}
}
/**
* @package Task
*/
class SGL_Task_DeregisterModule extends SGL_Task
{
public function run($data=null)
{
$ok = false;
foreach ($data['aModuleList'] as $module) {
$rm = DB_DataObject::factory(SGL_Config::get('table.module'));
$rm->get($data['moduleId']);
$ok = $rm->delete();
}
return $ok;
}
}
/**
* @package Task
*/
class SGL_Task_EnableDebugBlock extends SGL_Task
{
public function run($data=null)
{
require_once SGL_MOD_DIR . '/block/classes/BlockDAO.php';
$da = BlockDAO::singleton();
if (!empty($da->conf['debug']['enableDebugBlock'])) {
$oBlock = new stdClass();
$oBlock->name = 'Default_Block_Debug';
$oBlock->title = 'Debug Block';
$oBlock->is_enabled = 1;
$oBlock->position = 'Left';
$oBlock->sections = array(0); // all
$oBlock->roles = array(SGL_ADMIN);
$ok = $da->addBlock($oBlock);
}
}
}
/**
* @package Task
*/
class SGL_Task_LoadTranslations extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
$c = SGL_Config::singleton();
$aLangOptions = SGL_Util::getLangsDescriptionMap();
if (array_key_exists('storeTranslationsInDB', $data) && $data['storeTranslationsInDB'] == 1) {
$trans = SGL_Translation::singleton('admin');
$this->setup();
$statusText = 'loading languages';
$this->updateHtml('status', $statusText);
// fetch available languages
$availableLanguages = & $GLOBALS['_SGL']['LANGUAGE'];
// add languages to config
$this->installedLanguages = $data['installLangs'];
$langString = (is_array($data['installLangs']))
? implode(',', str_replace('-', '_', $data['installLangs']))
: '';
$c->set('translation', array('installedLanguages' => $langString));
// iterate through languages adding to langs table
foreach ($data['installLangs'] as $aLang) {
$globalLangFile = $availableLanguages[$aLang][1] .'.php';
$langID = str_replace('-', '_', $aLang);
// skip language creation during module install
if (empty($data['skipLangTablesCreation'])) {
$prefix = $this->conf['db']['prefix'] .
$this->conf['translation']['tablePrefix'] . '_';
$encoding = substr($aLang, strpos('-', $aLang));
$langData = array(
'lang_id' => $langID,
'table_name' => $prefix . $langID,
'meta' => '',
'name' => $aLangOptions[$aLang],
'error_text' => 'not available',
'encoding' => $encoding
);
// switch phptype to mysql when using mysql_SGL otherwise the langs table
// and index's will not be created.
if (($oldType = $trans->storage->db->phptype) == 'mysql_SGL') {
$trans->storage->db->phptype = 'mysql';
}
$result = $trans->addLang($langData);
$trans->storage->db->phptype = $oldType;
}
// iterate through modules
foreach ($data['aModuleList'] as $module) {
$statusText = 'loading languages - '. $module .' ('. str_replace('_','-', $langID) .')';
$this->updateHtml('status', $statusText);
$modulePath = SGL_MOD_DIR . '/' . $module . '/lang';
if (file_exists($modulePath .'/'. $globalLangFile)) {
// load current module lang file
require $modulePath .'/'. $globalLangFile;
// defaultWords clause
$words = ($module == 'default') ? $defaultWords : $words;
// add current translation to db
if (count($words)) {
foreach ($words as $tk => $tValue) {
if (is_array($tValue) && $tk) { // if an array
// create key|value|| string
$value = '';
foreach ($tValue as $k => $aValue) {
$value .= $k . '|' . $aValue .'||';
}
$string = array($langID => $value);
$result = $trans->add($tk, $module, $string);
} elseif ($tk && $tValue) {
$string = array($langID => $tValue);
$result = $trans->add($tk, $module, $string);
}
}
unset($words);
}
}
}
}
} else {
// set installed languages
$installedLangs = (is_array($aLangOptions))
? str_replace('-', '_', implode(',', array_keys($aLangOptions)))
: '';
$c->set('translation', array('installedLanguages' => $installedLangs));
}
$fileName = SGL_VAR_DIR . '/' . SGL_SERVER_NAME . '.conf.php';
$ok = $c->save($fileName);
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
return $ok;
}
}
/**
* @package Task
*/
class SGL_Task_EnableForeignKeyChecks extends SGL_Task
{
public function run($data=null)
{
SGL::logMessage("run =====", PEAR_LOG_DEBUG);
$c = SGL_Config::singleton();
$this->conf = $c->getAll();
$res = true;
// re-enable fk constraints if mysql (>= 4.1.x)
if ($this->conf['db']['type'] == 'mysql_SGL'
|| $this->conf['db']['type'] == 'mysql'
|| $this->conf['db']['type'] == 'mysqli'
|| $this->conf['db']['type'] == 'mysqli_SGL') {
$dbh = SGL_DB::singleton();
$query = 'SET FOREIGN_KEY_CHECKS=1;';
$res = $dbh->query($query);
}
return $res;
}
}
/**
* @package Task
*/
class SGL_Task_VerifyDbSetup extends SGL_UpdateHtmlTask
{
public function run($data=null)
{
SGL::logMessage("run =====", PEAR_LOG_DEBUG);
$this->setup();
// verify db
$dbh = SGL_DB::singleton();
$query = "SELECT COUNT(*) FROM {$this->conf['table']['permission']}";
$res = $dbh->getAll($query);
$errorNoTable = (SGL_DB_DRIVER === 'DB')
? DB_ERROR_NOSUCHTABLE
: MDB2_ERROR_NOSUCHTABLE;
//if (SGL::isError($res, DB_ERROR_NOSUCHTABLE)) {
if (SGL::isError($res, $errorNoTable)) {
SGL_Install_Common::errorPush(
SGL::raiseError('No tables exist in DB - was schema created?'));
} elseif (!(count($res))) {
SGL_Install_Common::errorPush(
SGL::raiseError('Perms inserts failed', SGL_ERROR_DBFAILURE));
}
// create error message if appropriate
if (SGL_Install_Common::errorsExist()) {
SGL_Install_Common::errorPrint();
$backText = '<br /><div class=\"errorContent\">Please back to \"Publish\" step, and choose \"force re-setup database\" under \"Optional for publish issue.\"</div>';
$statusText = 'Some problems were encountered.' . $backText;
$this->updateHtml('status', $statusText);
//$body = 'please diagnose and try again';
} else {
if (array_key_exists('createTables', $data) && $data['createTables'] == 1) {
// note: must all be on one line for DOM text replacement
$message = 'Database initialisation complete!';
$this->updateHtml('status', $message);
$body = '<p><a href=\\"' . SGL_BASE_URL . '/setup.php?start\\">LAUNCH SEAGULL</a> </p>NOTE: <strong>N/A</strong> indicates that a schema or data is not needed for this module';
// else only a DB connect was requested
} else {
$statusText = 'DB setup succeeded';
$statusText .= ', schema creation skipped';
$this->updateHtml('status', $statusText);
$body = '<p><a href=\\"' . SGL_BASE_URL . '/setup.php?start\\">LAUNCH SEAGULL</a> </p>';
}
}
// done, create "launch seagull" link
$this->updateHtml('additionalInfo', $body);
$this->updateHtml('progress_bar', '');
SGL_Install_Common::printFooter();
}
}
/**
* @package Task
*/
class SGL_Task_CreateFileSystem extends SGL_Task
{
public function run($data=null)
{
SGL::logMessage("run =====", PEAR_LOG_DEBUG);
require_once 'System.php';
$err = false;
// pass paths as arrays to avoid widows space parsing prob
// create cache dir
if (!is_dir(SGL_CACHE_DIR)) {
$cacheDir = System::mkDir(array(SGL_CACHE_DIR));
if (is_dir($cacheDir)) {
@chmod($cacheDir, 0777);
}
if (!($cacheDir)) {
SGL_Install_Common::errorPush(SGL::raiseError('Problem creating cache dir'));
}
}
// create entities dir
if (!is_dir(SGL_ENT_DIR)) {
$entDir = System::mkDir(array(SGL_ENT_DIR));
if (is_dir($entDir)) {
@chmod($entDir, 0777);
}
if (!($entDir)) {
SGL_Install_Common::errorPush(SGL::raiseError('Problem creating entity dir'));
}
}
// create tmp dir, mostly for sessions
if (!is_writable(SGL_TMP_DIR) || !is_dir(SGL_TMP_DIR)) {
$tmpDir = System::mkDir(array(SGL_TMP_DIR));
$htAccessContent = <<< EOF
Order allow,deny
Deny from all
EOF;
$ok = file_put_contents(SGL_TMP_DIR . '/.htaccess', $htAccessContent);
if (!$tmpDir) {
$err = SGL::raiseError('The tmp directory does not '.
'appear to be writable, please give the webserver permissions to write to it');
SGL_Install_Common::errorPush($err);
}
}
return $err;
}
}
/**
* @package Task
*/
class SGL_Task_CreateDataObjectEntities extends SGL_Task
{
public function run($data = null)
{
SGL::logMessage("run =====", PEAR_LOG_DEBUG);
$err = false;
$c = SGL_Config::singleton();
$conf = $c->getAll();
// init DB_DataObject
$oTask = new SGL_Task_InitialiseDbDataObject();
$ok = $oTask->run($conf);
require_once 'DB/DataObject/Generator.php';
ob_start();
// remove original dbdo keys file as it is unable to update an existing file
$keysFile = SGL_ENT_DIR . '/' . $conf['db']['name'] . '.ini';
if (is_file($keysFile)) {
$ok = unlink($keysFile);
}
// drop old entities on re-install
if (isset($_SESSION['install_dbPrefix'])) {
if (is_writable(SGL_ENT_DIR)) {
if ($dh = opendir(SGL_ENT_DIR)) {
$prefix = $_SESSION['install_dbPrefix'];
while (($file = readdir($dh)) !== false) {
if ($file != '.' && $file != '..'
&& substr($file, -3) == 'php'
&& substr($file, 0, strlen($prefix)) == ucfirst($prefix)) {
$ok = unlink(SGL_ENT_DIR . '/' . $file);
}
}
}
}
}
$generator = new DB_DataObject_Generator();
$generator->start();
$out = ob_get_contents();
ob_end_clean();
if (SGL::isError($out)) {
$err = SGL::raiseError('generating DB_DataObject entities failed');
SGL_Install_Common::errorPush($err);
}
return $err;
}
}
/**
* @package Task
*/
class SGL_Task_CreateDataObjectLinkFile extends SGL_Task
{
public function run($data=null)
{
$err = false;
$c = SGL_Config::singleton();
$conf = $c->getAll();
// original dbdo links file
$linksFile = SGL_ENT_DIR . '/' . $conf['db']['name'] . '.links.ini';
// read existing data if any
if (is_readable($linksFile)) {
$aOrigData = parse_ini_file($linksFile, true);
// only remove when not installing modules, ie for sgl-rebuild
if (empty($data['moduleInstall']) && is_writable($linksFile)) {
unlink($linksFile);
}
}
$linkData = '';
foreach ($data['aModuleList'] as $module) {
if ($module == 'block' && in_array('cms', $data['aModuleList'])) {
$linksPath = SGL_MOD_DIR . '/' . $module . '/data/dataobjectLinks.cms.ini';
} else {
$linksPath = SGL_MOD_DIR . '/' . $module . '/data/dataobjectLinks.ini';
}
if (is_file($linksPath)) {
$linkData .= file_get_contents($linksPath);
$linkData .= "\n\n";
}
}
if (!empty($linkData)) {
// first check to ensure key doesn't exist if a module is being installed
if (!empty($data['moduleInstall'])) {
$aNewData = parse_ini_file($linksPath, true);
// compare with existing data if there is any
if (!empty($aOrigData)) {
foreach ($aNewData as $key => $aValues) {
$tableName = $conf['db']['prefix'] . $key;
if (array_key_exists($tableName, $aOrigData)) {
// key already exists, so return instead of adding it
return;
}
}
}
}
// we don't forget about prefixes
if (!empty($conf['db']['prefix'])) {
// prefix containers
$linkData = preg_replace('/\[(\w+)\]/i',
'[' . SGL_Sql::addTablePrefix('$1') . ']', $linkData);
// prefix references
$linkData = preg_replace('/(\w+):/i',
SGL_Sql::addTablePrefix('$1') . ':' , $linkData);
}
if (is_writable($linksFile) || !file_exists($linksFile)) {
if (!$handle = fopen($linksFile, 'a+')) {
$err = SGL::raiseError('could not open links file for writing');
SGL_Install_Common::errorPush($err);
}
if (fwrite($handle, $linkData) === false) {
$err = SGL::raiseError('could not write to file' . $linksFile);
SGL_Install_Common::errorPush($err);
}
}
}
return $err;
}
}
/**
* @package Task
*/
class SGL_Task_SymLinkWwwData extends SGL_Task
{
public function run($data=null)
{
$ret = true;
foreach ($data['aModuleList'] as $module) {
$wwwDir = SGL_MOD_DIR . '/' . $module . '/www';
if (file_exists($wwwDir)) {
/// Begin: Fixed Not make link if found this www data ::: boom
if (is_link(SGL_WEB_ROOT . "/$module") && is_dir(SGL_WEB_ROOT . "/$module")) {
continue;
}
/// End: Fixed Not make link if found this www data ::: boom
if (is_writable(SGL_WEB_ROOT)) {
// windows
if (strpos(PHP_OS, 'WIN') !== false) {
// if linkd binary is present
$ret = symlink($wwwDir, SGL_WEB_ROOT . "/$module");
// otherwise just copy
if (!$ret) {
require_once SGL_CORE_DIR . '/File.php';
$ret = SGL_File::copyDir($wwwDir, SGL_WEB_ROOT . "/$module");
}
} elseif (is_link(SGL_WEB_ROOT . "/$module")) {
$ret = SGL::raiseError('A www directory was detected in ' .
' one of the modules therefore an attempt to create ' .
' a corresponding symlink was made ' .
' but the symlink already exists ' .
' in seagull/www');
} else {
/// START modify create link---------------
/// By : siwakorn
/// date : 26 - 01 - 2009
if (function_exists('symlink')) {
$ret = symlink($wwwDir, SGL_WEB_ROOT . "/$module");
// otherwise just copy
if (!$ret) {
require_once SGL_CORE_DIR . '/File.php';
$ret = SGL_File::copyDir($wwwDir, SGL_WEB_ROOT . "/$module");
}
} else {
// otherwise just copy
require_once SGL_CORE_DIR . '/File.php';
$ret = SGL_File::copyDir($wwwDir, SGL_WEB_ROOT . "/$module");
}
/// END modify----------------------------------
}
} else {
$ret = SGL::raiseError('A www directory was detected in one of the modules '.
' but the required webserver' .
' write perms on seagull/www do not exist, so the symlink could'.
' not be created');
}
}
}
return $ret;
}
}
/**
* @package Task
*/
class SGL_Task_UnLinkWwwData extends SGL_Task
{
public function run($data=null)
{
$ret = true;
foreach ($data['aModuleList'] as $module) {
if (empty($module)) {
continue;
}
$wwwDir = SGL_MOD_DIR . '/' . $module . '/www';
// if we're windows
if ((strpos(PHP_OS, 'WIN') !== false) && is_dir(SGL_WEB_ROOT . "/$module")) {
require_once SGL_CORE_DIR . '/File.php';
if (readlink(SGL_WEB_ROOT . "/$module")) {
SGL_File::rmDir(SGL_WEB_ROOT . "/$module");
} else {
SGL_File::rmDir(SGL_WEB_ROOT . "/$module", '-r');
}
} elseif (file_exists($wwwDir)) {
/// Begin: Fixed Not unlink if this www data is directory ::: boom
if (is_dir(SGL_WEB_ROOT . "/$module") || !is_writable(SGL_WEB_ROOT)) {
continue;
}
/// End: Fixed Not unlink if this www data is directory ::: boom
if (is_writable(SGL_WEB_ROOT)) {
if (is_link(SGL_WEB_ROOT . "/$module")) {
unlink(SGL_WEB_ROOT . "/$module");
}
} else {
$ret = SGL::raiseError('An attempt to remove an existing ' .
' symlink failed, the webserver no longer has ' .
' required write perms on seagull/www dir');
}
}
}
return $ret;
}
}
/**
* @package Task
*/
class SGL_Task_AddTestDataToConfig extends SGL_UpdateHtmlTask
{
/**
* Updates test config file.
*
* 1. Reads ini file with php extension (used for security)
* 2. Updates keys in file
* 3. Saves file as ini
* 4. Modifies file adding security
* 5. Changes extension to php
* 6. Removes saved ini file
*
* @param unknown_type $data
*/
public function run($data = null)
{
$this->setup();
// get relevant module directory
$globalConf = SGL_Config::singleton();
$moduleDir = ($globalConf->get(array('path' => 'moduleDirOverride')))
? $globalConf->get(array('path' => 'moduleDirOverride'))
: 'modules';
$c = new SGL_Config();
foreach ($data['aModuleList'] as $module) {
$dataDir = SGL_MOD_DIR . '/' . $module . '/data';
// get available data files
$aFiles = array();
if (is_file($dataDir . $this->filename1)) {
$aFiles['schema'] = 1;
}
if (is_file($dataDir . $this->filename2)) {
$aFiles['dataDefault'] = 1;
}
if (is_file($dataDir . $this->filename6)) {
$aFiles['dataTest'] = 1;
}
// load current test config
if (is_file(SGL_VAR_DIR . '/test.conf.ini.php')) {
$aTestData = parse_ini_file(SGL_VAR_DIR . '/test.conf.ini.php', true);
// and add schema/data files
$update = false;
if (isset($aFiles['schema'])) {
$nextId = $this->getNextKey($aTestData['schemaFiles']);
$aTestData['schemaFiles']['file'.$nextId] = $moduleDir . '/' . $module . '/data/schema.my.sql';
$update = true;
}
if (isset($aFiles['dataDefault'])) {
$nextId = $this->getNextKey($aTestData['dataFiles']);
$aTestData['dataFiles']['file'.$nextId] = $moduleDir . '/' . $module . '/data/data.default.my.sql';
$update = true;
}
if (isset($aFiles['dataTest'])) {
$nextId = $this->getNextKey($aTestData['dataFiles']);
$aTestData['dataFiles']['file'.$nextId] = $moduleDir . '/' . $module . '/data/data.test.my.sql';
$update = true;
}
if ($update) {
$c->replace($aTestData);
$ok = $c->save(SGL_VAR_DIR . '/test.conf.ini');
SGL_Util::makeIniUnreadable(SGL_VAR_DIR . '/test.conf.ini');
}
}
}
}
public function getNextKey($aKeys)
{
$keys = array_keys($aKeys);
$out = array();
foreach ($keys as $k) {
preg_match("/[0-9].*/", $k, $matches);
$out[] = $matches[0];
}
return (max($out)) +1;
}
}
/**
* @package Task
*/
class SGL_Task_RemoveTestDataFromConfig extends SGL_UpdateHtmlTask
{
public function run($data = null)
{
if (is_file(SGL_VAR_DIR . '/test.conf.ini.php')) {
$this->setup();
$c = new SGL_Config();
foreach ($data['aModuleList'] as $module) {
// load current test config
$aTestData = parse_ini_file(SGL_VAR_DIR . '/test.conf.ini.php', true);
// and add schema/data files
$update = false;
foreach ($aTestData['schemaFiles'] as $k => $line) {
if (preg_match("/$module/", $line)) {
unset($aTestData['schemaFiles'][$k]);
$update = true;
}
}
foreach ($aTestData['dataFiles'] as $k => $line) {
if (preg_match("/$module/", $line)) {
unset($aTestData['dataFiles'][$k]);
$update = true;
}
}
if ($update) {
$c->replace($aTestData);
$ok = $c->save(SGL_VAR_DIR . '/test.conf.ini');
SGL_Util::makeIniUnreadable(SGL_VAR_DIR . '/test.conf.ini');
}
}
}
}
}
/**
* @package Task
*/
class SGL_Task_SyncSequences extends SGL_Task
{
/**
* Creates new or updates existing sequences, based on max(primary key).
* Default is to act on all tables in db, unless specified in $tables.
*
* @access public
* @static
* @param mixed $tables string table name or array of string table names
* @return true | PEAR Error
* @todo we need to reinstate this method's ability to receive an array of tables as an argument
*/
public function run($data=null)
{
$locator = SGL_ServiceLocator::singleton();
$dbh = $locator->get('DB');
if (!$dbh) {
$dbh = SGL_DB::singleton();
$locator->register('DB', $dbh);
}
$c = SGL_Config::singleton();
$conf = $c->getAll();
// postgres sequence routine creates errors, get initial count
$initialErrorCount = SGL_Error::count();
$tables = null;
$phptype = $dbh->phptype;
// if it is SGL MySQL driver
if (strpos($dbh->phptype, 'mysql') === 0
&& strpos($dbh->phptype, '_SGL')) {
// and all sequences should NOT be in one table
if (SGL_Config::get('db.sepTableForEachSequence')) {
// fake it as regular MySQL driver
$phptype = str_replace('_SGL', '', $dbh->phptype);
}
}
switch ($phptype) {
case 'mysql':
case 'mysqli':
$data = array();
$aTables = (count( (array) $tables) > 0) ? (array) $tables : $dbh->getListOf('tables');
// "%_seq" is the default, but in case they screwed around with PEAR::DB...
$suffix = $dbh->getOption('seqname_format');
$suffixRaw = str_replace('%s', '', $suffix);
$suffixRawStart = (0 - strlen($suffixRaw));
/*// ปิดไว้ก่อน เพราะทำให้ SQL Server overload จนทำให้ timeout ในบาง server
// get views
$aViews = SGL_Task_SyncSequences::_getViews();
if (SGL::isError($aViews)) {
SGL_Error::pop();
$aViews = array(); // no views by default
}
*/
if (SGL_DB_DRIVER === 'MDB2') {
$aNewUpdateTable = array();
$updateengineFile = SGL_VAR_DIR . '/updateengine.ini';
$aUpdateTable = explode(',', file_get_contents($updateengineFile));
}
foreach ($aTables as $table) {
$primary_field = '';
if (SGL_DB_DRIVER === 'MDB2' && !in_array($table, $aUpdateTable)) {
$dbh->query("ALTER TABLE {$table} ENGINE = MYISAM");
$aNewUpdateTable[] = $table;
}
// we only build sequences for tables that are not sequences themselves
if ($table == $conf['table']['sequence'] || substr($table, $suffixRawStart) == $suffixRaw) {
continue;
}
/*// ปิดไว้ก่อน เพราะทำให้ SQL Server overload จนทำให้ timeout ในบาง server
// skip views
if (in_array($table, $aViews)) {
continue;
}
*/
$info = $dbh->tableInfo($dbh->quoteIdentifier($table));
foreach ($info as $field) {
if (preg_match('/primary_key/', $field['flags'])) {
$primary_field = $field['name'];
break;
}
}
if ($primary_field != '') {
$maxId = $dbh->getOne('SELECT MAX(' . $primary_field . ') FROM ' . $dbh->quoteIdentifier($table) . ' WHERE 1');
if (!is_null($maxId) && (is_numeric($maxId))) {
$data[] = array($table, $maxId);
}
}
}
foreach ($data as $k) {
$tableName = $k[0];
$seqName = $dbh->quoteIdentifier(sprintf($suffix, $tableName));
if (SGL_DB_DRIVER === 'MDB2' && !in_array($seqName, $aUpdateTable)) {
$dbh->query("ALTER TABLE {$seqName} ENGINE = MYISAM");
$aNewUpdateTable[] = $seqName;
}
$maxVal = $k[1];
$currVal = $dbh->nextId($tableName, true);
if (SGL::isError($currVal) === true) {
continue;
}
$sql = 'UPDATE ' . $seqName . ' SET id=' . $maxVal . ' WHERE id=' . $currVal;
$result = $dbh->query($sql);
}
if (SGL_DB_DRIVER === 'MDB2' && count($aNewUpdateTable)) {
$aTables = array_merge($aUpdateTable, $aNewUpdateTable);
$handle = fopen($updateengineFile, 'w');
if (SGL::isError($handle) === true) {
SGL_Error::pop();
} else {
fwrite($handle, implode(',', $aTables));
fclose();
}
}
break;
case 'mysqli_SGL':
case 'mysql_SGL':
$data = array();
$aTables = (count( (array) $tables) > 0) ? (array) $tables : $dbh->getListOf('tables');
// make sure sequence table exists
if (!in_array('sequence',$aTables)) {
require_once SGL_CORE_DIR . '/Sql.php';
SGL_Sql::parse(SGL_ETC_DIR . '/sequence.my.sql', 0, array('SGL_Sql', 'execute'));
}
// get views
$aViews = SGL_Task_SyncSequences::_getViews();
if (SGL::isError($aViews)) {
SGL_Error::pop();
$aViews = array(); // no views by default
}
foreach ($aTables as $table) {
// skip views
if (in_array($table, $aViews)) {
continue;
}
$primary_field = '';
if ($table != $conf['table']['sequence']) {
$info = $dbh->tableInfo($dbh->quoteIdentifier($table));
foreach ($info as $field) {
if (isset($field['flags']) && preg_match('/primary_key/', $field['flags'])) {
$primary_field = $field['name'];
break;
}
}
if ($primary_field != '') {
$maxId = $dbh->getOne('SELECT MAX(' . $primary_field .
') FROM ' . $dbh->quoteIdentifier($table) . ' WHERE 1');
if (is_numeric($maxId)) {
$data[] = array($table, $maxId);
} else {
$data[] = array($table, 0);
}
} else {
$data[] = array($table, 0);
}
}
}
$sth = $dbh->prepare("REPLACE INTO {$conf['table']['sequence']} (name, id) VALUES(?,?)");
$dbh->executeMultiple($sth, $data);
break;
case 'pgsql':
$data = array();
$aTables = (count( (array) $tables) > 0) ? (array) $tables : $dbh->getListOf('tables');
foreach ($aTables as $table) {
$primary_field = '';
if ($table != $conf['table']['sequence']) {
$info = $dbh->tableInfo($dbh->quoteIdentifier($table));
foreach ($info as $field) {
if (preg_match('/primary_key/', $field['flags'])) {
$primary_field = $field['name'];
break;
}
}
if ($primary_field != '') {
$data[] = array($table, $dbh->getOne('SELECT MAX(' .
$primary_field . ') FROM ' . $table . ' WHERE true'));
}
}
}
// "%_seq" is the default, but in case they screwed around with PEAR::DB...
$suffix = $dbh->getOption('seqname_format');
// we'll just create the sequences manually...why not?
$errorAlreadyExists = (SGL_DB_DRIVER === 'DB')
? DB_ERROR_ALREADY_EXISTS
: MDB2_ERROR_ALREADY_EXISTS;
foreach ($data as $k) {
$tableName = $k[0];
$seqName = sprintf($suffix, $tableName);
$maxVal = $k[1] + 1;
$sql = 'CREATE SEQUENCE ' . $seqName . ' START ' . $maxVal;
$result = $dbh->query($sql);
//if (SGL::isError($result) && $result->code == DB_ERROR_ALREADY_EXISTS) {
if (SGL::isError($result) && $result->code == $errorAlreadyExists) {
$sql = 'ALTER SEQUENCE ' . $seqName . ' RESTART WITH ' . $maxVal;
$result = $dbh->query($sql);
}
}
break;
case 'oci8':
case 'db2':
$dbh->autoCommit(false);
$data = '';
$aTables = (count( (array) $tables) > 0) ? (array) $tables : $dbh->getListOf('sequences');
foreach ($aTables as $sequence) {
$primary_field = '';
// get tablename
if (preg_match("/^(.*)_seq$/",$sequence,$table)) {
$info = $dbh->tableInfo($dbh->quoteIdentifier($table[1]));
foreach ($info as $field) {
if (preg_match('/primary_key/', $field['flags'])) {
$primary_field = $field['name'];
break;
}
}
if ($primary_field != '') {
$maxId = $dbh->getOne('SELECT MAX(' .
$primary_field . ') + 1 FROM ' . $table[1]);
} else {
$maxId = 1;
}
// check for NULL
if (!$maxId) {
$maxId = 1;
}
// drop and recreate sequence
$success = false;
/*fix PHP 5.3 :: nipaporn : ปรับ DB::isError */
if (!SGL::isError($dbh->dropSequence($table[1]))) {
$success = $dbh->query('CREATE SEQUENCE ' .
$dbh->getSequenceName($table[1]) . ' START WITH ' . $maxId);
}
if (!$success) {
$dbh->rollback();
$dbh->autoCommit(true);
SGL_Install_Common::errorPush(SGL::raiseError('Sequence rebuild failed'));
}
}
}
$success = $dbh->commit();
$dbh->autoCommit(true);
if (!$success) {
SGL_Install_Common::errorPush(SGL::raiseError('Sequence rebuild failed'));
}
break;
default:
SGL_Install_Common::errorPush(
SGL::raiseError('This feature currently is implemented only for MySQL, Oracle and PostgreSQL.'));
}
// remove irrelevant errors
$finalErrorCount = SGL_Error::count();
if ($finalErrorCount > $initialErrorCount) {
$numErrors = $finalErrorCount - $initialErrorCount;
for ($x = 0; $x < $numErrors; $x++) {
SGL_Error::pop();
}
}
}
private static function _getViews()
{
$locator = SGL_ServiceLocator::singleton();
$dbh = $locator->get('DB');
$dbName = SGL_Config::get('db.name');
if (SGL_DB_DRIVER === 'DB') {
$dbName = $dbh->escapeSimple($dbName);
} else {
$dbName = $dbh->escape($dbName);
}
$query = "
SELECT table_name
FROM information_schema.views
WHERE table_schema = '" . $dbName . "'
";
return $dbh->getCol($query);
}
}
/**
* @package Task
*/
class SGL_Task_CreateAdminUser extends SGL_Task
{
public function run($data=null)
{
$ok = true;
if (array_key_exists('createTables', $data) && $data['createTables'] == 1) {
require_once SGL_MOD_DIR . '/user/classes/UserDAO.php';
$da = UserDAO::singleton();
$oUser = $da->getUserById();
$oUser->username = $data['adminUserName'];
$oUser->first_name = $data['adminFirstName'];
$oUser->last_name = $data['adminLastName'];
$oUser->email = $data['adminEmail'];
$oUser->passwd = !empty($data['adminPasswordIsHash'])
? $data['adminPassword']
: md5($data['adminPassword']);
$oUser->organisation_id = 1;
$oUser->is_acct_active = 1;
$oUser->country = 'GB';
$oUser->role_id = SGL_ADMIN;
$oUser->date_created = $oUser->last_updated = SGL_Date::getTime();
$oUser->created_by = $oUser->updated_by = SGL_ADMIN;
$ok = $da->addUser($oUser);
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
}
return $ok;
}
}
/**
* @package Task
*/
class SGL_Task_CreateMemberUser extends SGL_Task
{
public function run($data=null)
{
if (array_key_exists('createTables', $data) && $data['createTables'] == 1) {
require_once SGL_MOD_DIR . '/user/classes/UserDAO.php';
$da = UserDAO::singleton();
$oUser = $da->getUserById();
$oUser->username = 'member';
$oUser->first_name = 'Example';
$oUser->last_name = 'Member User';
$oUser->email = 'example@seagullproject.org';
$oUser->passwd = md5('password');
$oUser->organisation_id = 1;
$oUser->is_acct_active = 1;
$oUser->country = 'GB';
$oUser->role_id = 2;
$oUser->date_created = $oUser->last_updated = SGL_Date::getTime();
$oUser->created_by = $oUser->updated_by = SGL_ADMIN;
$success = $da->addUser($oUser);
if (SGL::isError($success)) {
SGL_Install_Common::errorPush($success);
}
}
}
}
/**
* @package Task
*/
class SGL_Task_InstallerCleanup extends SGL_Task
{
public function run($data=null)
{
$newFile = <<<PHP
<?php
#{$data['installPassword']}
?>
PHP;
if (is_writable(SGL_VAR_DIR)) {
$ok = file_put_contents(SGL_VAR_DIR . '/INSTALL_COMPLETE.php', $newFile);
} else {
SGL_Install_Common::errorPush(SGL::raiseError('var dir is not writable'));
}
// update lang in default prefs
require_once SGL_MOD_DIR . '/user/classes/UserDAO.php';
$da = UserDAO::singleton();
$lang = isset($_SESSION['install_language'])
? $_SESSION['install_language']
: $data['aPrefs']['language'];
$ok = $da->updateMasterPrefs(array('language' => $lang));
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
// update lang in admin prefs
$aMapping = $da->getPrefsMapping();
$langPrefId = $aMapping['language'];
$ok = $da->updatePrefsByUserId(array($langPrefId => $lang), SGL_ADMIN);
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
// update tz in default prefs
$tz = isset($_SESSION['install_timezone'])
? $_SESSION['install_timezone']
: $data['aPrefs']['timezone'];
$ok = $da->updateMasterPrefs(array('timezone' => $tz));
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
// update tz in admin prefs
$tzPrefId = $aMapping['timezone'];
$ok = $da->updatePrefsByUserId(array($tzPrefId => $tz), SGL_ADMIN);
if (SGL::isError($ok)) {
SGL_Install_Common::errorPush($ok);
}
return $ok;
}
}
if (strpos(PHP_OS, 'WIN') !== false) {
if (!function_exists('symlink')) {
function symlink($target, $link) {
// it's Vista
if (isset($_SERVER['HTTP_USER_AGENT'])
&& strpos($_SERVER['HTTP_USER_AGENT'], 'Windows NT 6') !== false) {
// mklink utility doesn't understand ".."
$ds = DIRECTORY_SEPARATOR;
$linkDir = realpath(dirname($link)) . $ds . basename($link);
$targetDir = realpath(dirname($target)) . $ds . basename($target);
exec('mklink /D ' . $linkDir . ' ' . $targetDir, $ret);
// other Windows version
} else {
exec('linkd ' . $link . ' ' . $target, $ret);
}
return $ret;
}
}
if (!function_exists('readlink')) {
function readlink($link) {
// it's Vista
if (isset($_SERVER['HTTP_USER_AGENT'])
&& strpos($_SERVER['HTTP_USER_AGENT'], 'Windows NT 6') !== false) {
// todo: find linkd native equivalent for reading links
$ret = true;
// other Windows version
} else {
exec('linkd ' . $link, $ret);
}
return $ret;
}
}
}
?>