0byt3m1n1
Path:
/
data
/
applications
/
aps.bak
/
joomla
/
3.3.1-2
/
standard
/
scripts
/
[
Home
]
File: joomla25-upgrade.php
<?php function upgrade_joomla25($root_dir, $db_host, $db_user, $db_password, $db_database, $db_prefix) { //First delete old joomla files (Plesk bug) deleteOldJoomlaFiles($root_dir); //Joomla Database Upgrade $updater = APSJoomlaUpgrade::getInstance($root_dir, $db_host, $db_user, $db_password, $db_database, $db_prefix); $updater->upgrade(); } class APSJoomlaUpgrade{ var $rootdir = null; var $db = null; var $folder = null; var $changeItems = array(); public function __construct($root_dir, $db_host, $db_user, $db_password, $db_database, $db_prefix) { $this->rootdir=$root_dir; $this->db = APSJoomlaDB::getInstance($db_host, $db_user, $db_password, $db_database, $db_prefix); } public static function getInstance($root_dir, $db_host, $db_user, $db_password, $db_database, $db_prefix) { static $instance; if (!is_object($instance)) { $instance = new APSJoomlaUpgrade($root_dir, $db_host, $db_user, $db_password, $db_database, $db_prefix); } return $instance; } private function fixSchemaVersion($schema_version) { // Delete old row $this->db->setQuery("DELETE FROM #__schemas WHERE extension_id=700"); $this->db->executeQuery(); //Add new row $this->db->setQuery("INSERT INTO #__schemas (extension_id, version_id) VALUES (700, '".$schema_version."')"); $this->db->executeQuery(); } private function getItems() { $folder = $this->rootdir . '/components/com_admin/sql/updates/mysql'; $changeSet = JSchemaChangesetAPS::getInstance($this->rootdir, $this->db, $folder, $this->getJoomlaVersionFromDatabase()); return $changeSet; } public function upgrade() { $changeSet = $this->getItems(); $changeSet->fix(); $schema_version = $changeSet->getSchema(); $this->fixSchemaVersion($schema_version); $this->updateJoomlaManifestCache($schema_version); $this->fixTagsMenuLinkBug(); } private function getJoomlaVersionFromDatabase() { //Get actual version id $this->db->setQuery("SELECT version_id FROM #__schemas WHERE extension_id=700"); $version_id=$this->db->loadResult(); //If joomla schema version_id is not set if(!$version_id) { $this->db->setQuery("SELECT manifest_cache FROM #__extensions WHERE extension_id=700"); $manifest_cache=$this->db->loadResult(); if($manifest_cache) { $manifest_cache = preg_replace('/^"{/', '{', $manifest_cache); $manifest_cache = preg_replace('/}"$/', '}', $manifest_cache); $manifest_cache_array = json_decode( $manifest_cache, true ); $version_id = $manifest_cache_array['version']; } } if(!$version_id) { $version_id="1.6.0"; } return $version_id; } private function updateJoomlaManifestCache($schema_version) { $this->db->setQuery("SELECT manifest_cache FROM #__extensions WHERE extension_id=700"); $manifest_cache=$this->db->loadResult(); // removing trailing ". Found them in some installations for unknown reason $manifest_cache = preg_replace('/^"{/', '{', $manifest_cache); $manifest_cache = preg_replace('/}"$/', '}', $manifest_cache); if(strlen($manifest_cache) > 0) { $manifest_cache_array = json_decode( $manifest_cache, true ); if ($manifest_cache_array['version'] && $manifest_cache_array['version'] != $schema_version) { $manifest_cache_array['version'] = $schema_version; $manifest_cache = json_encode( $manifest_cache_array ); $this->db->setQuery("UPDATE #__extensions SET manifest_cache = '$manifest_cache' WHERE extension_id=700"); $this->db->executeQuery(); } } } private function fixTagsMenuLinkBug() { // INSERT MENU LINK $this->db->setQuery("INSERT IGNORE INTO `#__menu` (`id`, `menutype`, `title`, `alias`, `note`, `path`, `link`, `type`, `published`, `parent_id`, `level`, `component_id`, `checked_out`, `checked_out_time`, `browserNav`, `access`, `img`, `template_style_id`, `params`, `lft`, `rgt`, `home`, `language`, `client_id`) VALUES(23, 'main', 'com_tags', 'Tags', '', 'Tags', 'index.php?option=com_tags', 'component', 0, 1, 1, 29, 0, '0000-00-00 00:00:00', 0, 1, 'class:tags', 0, '', 45, 46, 0, '', 1);"); $this->db->executeQuery(); } } class JSchemaChangesetAPS { protected $changeItems = array(); protected $rootdir = null; protected $db = null; protected $folder = null; public function __construct($rootdir, $db, $folder = null, $fromversion = null) { $this->rootdir=$rootdir; $this->db = $db; $this->folder = $folder; $updateFiles = $this->getUpdateFiles(); $updateQueries = $this->getUpdateQueries($updateFiles); foreach ($updateQueries as $obj) { $this->changeItems[] = JSchemaChangeItemAPS::getInstance($db, $obj->file, $obj->updateQuery, $fromversion); } } public static function getInstance($rootdir, $db, $folder, $fromversion) { static $instance; if (!is_object($instance)) { $instance = new JSchemaChangeSetAPS($rootdir, $db, $folder, $fromversion); } return $instance; } public function check() { $errors = array(); foreach ($this->changeItems as $item) { if ($item->check() === -2) { // error found $errors[] = $item; } } return $errors; } public function fix() { $this->check(); foreach ($this->changeItems as $item) { $item->fix(); } } public function getStatus() { $result = array('unchecked' => array(), 'ok' => array(), 'error' => array(), 'skipped' => array()); foreach ($this->changeItems as $item) { switch ($item->checkStatus) { case 0: $result['unchecked'][] = $item; break; case 1: $result['ok'][] = $item; break; case -2: $result['error'][] = $item; break; case -1: $result['skipped'][] = $item; break; } } return $result; } public function getSchema() { foreach ($this->changeItems as $item) { $result = $item->file; } $result = new SplFileInfo($item->file); return $result->getBasename('.sql'); } private function getUpdateFiles() { // get the folder from the database name $sqlFolder = 'mysql'; // Default folder to core com_admin $this->folder = $this->rootdir.'/administrator/components/com_admin/sql/updates/'.$sqlFolder; return APSJoomlaFiles::files($this->folder, '\.sql$', 1, true); } private function getUpdateQueries(array $sqlfiles) { $result = array(); // hold results as array of objects foreach ($sqlfiles as $file) { $buffer = file_get_contents($file); // Create an array of queries from the sql file $queries = $this->db->splitSql($buffer); foreach ($queries as $query) { if (trim($query)) { $fileQueries = new stdClass(); $fileQueries->file = $file; $fileQueries->updateQuery = $query; $result[] = $fileQueries; } } } return $result; } } class JSchemaChangeitemAPS { public $file = null; public $updateQuery = null; public $checkQuery = null; public $checkQueryExpected = 1; public $db = null; public $queryType = null; public $msgElements = array(); public $checkStatus = 0; public $rerunStatus = 0; protected $fromversion = null; public function __construct($db, $file, $updateQuery, $fromversion) { $this->updateQuery = $updateQuery; $this->file = $file; $this->db = $db; $this->fromversion = $fromversion; $this->buildCheckQuery(); } public static function getInstance($db, $file, $query, $fromversion) { $instance = new JSchemaChangeitemAPS($db, $file, $query, $fromversion); return $instance; } public function check() { $this->checkStatus = -1; if ($this->checkQuery) { $this->db->setQuery($this->checkQuery); $rows = $this->db->loadObject(); if ($rows !== false) { if (count($rows) === $this->checkQueryExpected) { $this->checkStatus = 1; } else { $this->checkStatus = -2; } } else { $this->checkStatus = -2; } } return $this->checkStatus; } public function fix() { //Lanzado de las querys if ($this->checkStatus === -2) { // at this point we have a failed query $this->db->setQuery($this->updateQuery); if ($this->db->executeQuery()) { if ($this->check()) { $this->checkStatus = 1; $this->rerunStatus = 1; } else { $this->rerunStatus = -2; } } else { $this->rerunStatus = -2; } } else if ($this->checkStatus === -1) { //Check if I need to insert by version id $result = new SplFileInfo($this->file); if ( version_compare( $this->fromversion, $result->getBasename('.sql'), 'le' ) ) { $this->db->setQuery($this->updateQuery); if ($this->db->executeQuery()) { if ($this->check()) { $this->checkStatus = 1; $this->rerunStatus = 1; } else { $this->rerunStatus = -2; } } else { $this->rerunStatus = -2; } } } } protected function buildCheckQuery() { // Initialize fields in case we can't create a check query $this->checkStatus = -1; // change status to skipped $result = null; // remove any newlines $this->updateQuery = str_replace("\n", ' ', $this->updateQuery); // fix up extra spaces around () and in general $find = array('#((\s*)\(\s*([^)\s]+)\s*)(\))#', '#(\s)(\s*)#'); $replace = array('($3)', '$1'); $updateQuery = preg_replace($find, $replace, $this->updateQuery); $wordArray = explode(' ', $updateQuery); // first, make sure we have an array of at least 6 elements // if not, we can't make a check query for this one if (count($wordArray) < 6) { return; // done with method } // we can only make check queries for alter table and create table queries $command = strtoupper($wordArray[0] . ' ' . $wordArray[1]); if ($command === 'ALTER TABLE') { $alterCommand = strtoupper($wordArray[3] . ' ' . $wordArray[4]); if ($alterCommand == 'ADD COLUMN') { $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = ' . $this->fixQuote($wordArray[5]); $this->queryType = 'ADD_COLUMN'; $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[5])); } elseif ($alterCommand == 'ADD INDEX' || $alterCommand == 'ADD UNIQUE') { if ($pos = strpos($wordArray[5], '(')) { $index = $this->fixQuote(substr($wordArray[5], 0, $pos)); } else { $index = $this->fixQuote($wordArray[5]); } $result = 'SHOW INDEXES IN ' . $wordArray[2] . ' WHERE Key_name = ' . $index; $this->queryType = 'ADD_INDEX'; $this->msgElements = array($this->fixQuote($wordArray[2]), $index); } elseif ($alterCommand == 'DROP INDEX') { $index = $this->fixQuote($wordArray[5]); $result = 'SHOW INDEXES IN ' . $wordArray[2] . ' WHERE Key_name = ' . $index; $this->queryType = 'DROP_INDEX'; $this->checkQueryExpected = 0; $this->msgElements = array($this->fixQuote($wordArray[2]), $index); } elseif (strtoupper($wordArray[3]) == 'MODIFY') { // Kludge to fix problem with "integer unsigned" $type = $this->fixQuote($wordArray[5]); if (isset($wordArray[6])) { $type = $this->fixQuote($this->fixInteger($wordArray[5], $wordArray[6])); } $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = ' . $this->fixQuote($wordArray[4]) . ' AND type = ' . $type; $this->queryType = 'CHANGE_COLUMN_TYPE'; $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[4]), $type); } elseif (strtoupper($wordArray[3]) == 'CHANGE') { // Kludge to fix problem with "integer unsigned" $type = $this->fixQuote($this->fixInteger($wordArray[6], $wordArray[7])); $result = 'SHOW COLUMNS IN ' . $wordArray[2] . ' WHERE field = ' . $this->fixQuote($wordArray[4]) . ' AND type = ' . $type; $this->queryType = 'CHANGE_COLUMN_TYPE'; $this->msgElements = array($this->fixQuote($wordArray[2]), $this->fixQuote($wordArray[4]), $type); } } if ($command == 'CREATE TABLE') { if (strtoupper($wordArray[2].$wordArray[3].$wordArray[4]) == 'IFNOTEXISTS') { $table = $wordArray[5]; } else { $table = $wordArray[2]; } $result = 'SHOW TABLES LIKE ' . $this->fixQuote($table); $this->queryType = 'CREATE_TABLE'; $this->msgElements = array($this->fixQuote($table)); } // set fields based on results if ($this->checkQuery = $result) { $this->checkStatus = 0; // unchecked status } else { $this->checkStatus = -1; // skipped } } private function fixInteger($type1, $type2) { $result = $type1; if (strtolower($type1) == "integer" && strtolower(substr($type2, 0, 8)) == 'unsigned') { $result = 'int(10) unsigned'; } return $result; } private function fixQuote($string) { $string = str_replace('`', '', $string); $string = str_replace(';', '', $string); $string = str_replace('#__', $this->db->getPrefix(), $string); return $this->db->quote($string); } } class APSJoomlaFiles{ public static function files($path, $filter = '.', $recurse = false, $full = false) { // Check to make sure the path valid and clean $path = trim($path); $path = preg_replace('#[/\\\\]+#', DIRECTORY_SEPARATOR, $path); // Is the path a folder? if (!is_dir($path)) { return false; } // Compute the excludefilter string $excludefilter = array('^\..*', '.*~'); if (count($excludefilter)) { $excludefilter_string = '/(' . implode('|', $excludefilter) . ')/'; } else { $excludefilter_string = ''; } $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'); // Get the files $arr = APSJoomlaFiles::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, true); // Sort the files natsort($arr); return array_values($arr); } public static function _items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles) { @set_time_limit(ini_get('max_execution_time')); // Initialise variables. $arr = array(); // Read the source directory if (!($handle = @opendir($path))) { return $arr; } while (($file = readdir($handle)) !== false) { if ($file != '.' && $file != '..' && !in_array($file, $exclude) && (empty($excludefilter_string) || !preg_match($excludefilter_string, $file))) { // Compute the fullpath $fullpath = $path . '/' . $file; // Compute the isDir flag $isDir = is_dir($fullpath); if (($isDir xor $findfiles) && preg_match("/$filter/", $file)) { // (fullpath is dir and folders are searched or fullpath is not dir and files are searched) and file matches the filter if ($full) { // Full path is requested $arr[] = $fullpath; } else { // Filename is requested $arr[] = $file; } } if ($isDir && $recurse) { // Search recursively if (is_integer($recurse)) { // Until depth 0 is reached $arr = array_merge($arr, $this->_items($fullpath, $filter, $recurse - 1, $full, $exclude, $excludefilter_string, $findfiles)); } else { $arr = array_merge($arr, $this->_items($fullpath, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles)); } } } } closedir($handle); return $arr; } } class APSJoomlaDB{ var $host = null; var $user = null; var $password = null; var $database = null; var $prefix = null; private $query = null; public function __construct($db_host, $db_user, $db_password, $db_database, $db_prefix) { $this->host=$db_host; $this->user=$db_user; $this->password=$db_password; $this->database=$db_database; $this->prefix=$db_prefix; } public static function getInstance($db_host, $db_user, $db_password, $db_database, $db_prefix) { static $instance; if (!is_object($instance)) { $instance = new APSJoomlaDB($db_host, $db_user, $db_password, $db_database, $db_prefix); } return $instance; } function setQuery($query){ $this->query=$query; } public function loadObject() { // Initialise variables. $ret = null; // Execute the query and get the result set cursor. if (!($cursor = $this->executeQueryResult())) { return null; } // Get the first row from the result set as an object of type $class. if ($object = mysql_fetch_object($cursor)) { $ret = $object; } // Free up system resources and return. mysql_free_result($cursor); return $ret; } public function loadResult() { // Initialise variables. $ret = null; // Execute the query and get the result set cursor. if (!($cursor = $this->executeQueryResult())) { return null; } // Get the first row from the result set as an array. if ($row = mysql_fetch_row($cursor)) { $ret = $row[0]; } // Free up system resources and return. if ($cursor !== TRUE && $cursor != FALSE) { mysql_free_result($cursor); } return $ret; } public function executeQueryResult() { //Replace prefix $this->query = str_replace("#__", $this->prefix, $this->query); //Connect mysql_db_connect($this->host, $this->user,$this->password,$this->database); // Execute the query. $cursor = mysql_query($this->query); return $cursor; } public function executeQuery() { //Replace prefix $this->query = str_replace("#__", $this->prefix, $this->query); //Connect mysql_db_connect($this->host, $this->user,$this->password,$this->database); // Execute the query. $cursor = mysql_query($this->query); $resul=true; if(!$cursor) $resul = false; if ($cursor !== TRUE && $cursor != FALSE) { mysql_free_result($cursor); } return $resul; } public static function splitSql($sql) { $start = 0; $open = false; $char = ''; $end = strlen($sql); $queries = array(); for ($i = 0; $i < $end; $i++) { $current = substr($sql, $i, 1); if (($current == '"' || $current == '\'')) { $n = 2; while (substr($sql, $i - $n + 1, 1) == '\\' && $n < $i) { $n++; } if ($n % 2 == 0) { if ($open) { if ($current == $char) { $open = false; $char = ''; } } else { $open = true; $char = $current; } } } if (($current == ';' && !$open) || $i == $end - 1) { $queries[] = substr($sql, $start, ($i - $start + 1)); $start = $i + 1; } } return $queries; } public function getPrefix(){ return $this->prefix; } public static function quote($text) { return '\'' . addslashes($text) . '\''; } }