File Manager

Current Directory: /home/astoriaah/www/old15/administrator/components/com_admintools/models
Viewing File: /home/astoriaah/www/old15/administrator/components/com_admintools/models/dbprefix.php
<?php /** * @package AdminTools * @copyright Copyright (c)2010-2015 Nicholas K. Dionysopoulos * @license GNU General Public License version 3, or later * @version $Id$ */ // Protect from unauthorized access defined('_JEXEC') or die; /** * A feature to change the site's database prefix - Model */ class AdmintoolsModelDbprefix extends F0FModel { /** * Checks if the site is using the default database prefix (jos_) * * @return unknown_type */ public function isDefaultPrefix() { $prefix = $this->getCurrentPrefix(); return ($prefix == 'jos_'); } /** * Returns the currently used database prefix * * @return string */ public function getCurrentPrefix() { $config = JFactory::getConfig(); if (version_compare(JVERSION, '3.0', 'ge')) { $prefix = $config->get('dbprefix', ''); } else { $prefix = $config->getValue('config.dbprefix', ''); } return $prefix; } /** * Gets a random database prefix of a specified length. For instance, if the requested * length is 3, it will consist of three random letters and an underscore. * * @param $length int The requested alpha portion length of the prefix (3-6) * * @return string */ public function getRandomPrefix($length = 3) { $validchars = 'abcdefghijklmnopqrstuvwxyz'; $charslength = strlen($validchars); if ($length < 3) { $length = 3; } if ($length > 6) { $length = 6; } $prefix = ''; for ($i = 0; $i < $length; $i++) { $rand = rand(0, $charslength - 1); $prefix .= substr($validchars, $rand, 1); } $prefix .= '_'; return $prefix; } /** * Validates a prefix. The prefix must be 3-6 lowercase characters followed by * an underscore and must not alrady exist in the current database. It must * also not be jos_ or bak_. * * @param $prefix string The prefix to check * * @return string|bool The validated prefix or false if the prefix is invalid */ public function validatePrefix($prefix) { // Check that the prefix is not jos_ or bak_ if (($prefix == 'jos_') || ($prefix == 'bak_')) { return false; } // Check that we're not trying to reuse the same prefix $config = JFactory::getConfig(); if (version_compare(JVERSION, '3.0', 'ge')) { $oldprefix = $config->get('dbprefix', ''); } else { $oldprefix = $config->getValue('config.dbprefix', ''); } if ($prefix == $oldprefix) { return false; } // Check the length $pLen = strlen($prefix); if (($pLen < 4) || ($pLen > 6)) { return false; } // Check that the prefix ends with an underscore if (substr($prefix, -1) != '_') { return false; } // Check that the part before the underscore is lowercase letters $valid = preg_match('/[\w]_/i', $prefix); if ($valid === 0) { return false; } // Turn the prefix into lowercase $prefix = strtolower($prefix); // Check if the prefix already exists in the database $db = $this->getDBO(); if (version_compare(JVERSION, '3.0', 'ge')) { $dbname = $config->get('db', ''); } else { $dbname = $config->getValue('config.db', ''); } $sql = "SHOW TABLES WHERE `Tables_in_{$dbname}` like '{$prefix}%'"; $db->setQuery($sql); if (version_compare(JVERSION, '3.0', 'ge')) { $existing_tables = $db->loadColumn(); } else { $existing_tables = $db->loadResultArray(); } if (count($existing_tables)) { // Sometimes we have false alerts, e.g. a prefix of dev_ will match tables starting with dev15_ or dev16_ $realCount = 0; foreach ($existing_tables as $check) { if (substr($check, 0, $pLen) == $prefix) { $realCount++; break; } } if ($realCount) { return false; } } return $prefix; } /** * Updates the configuration.php file with the given prefix * * @param $prefix string The prefix to write to the configuration.php file * * @return bool False if writing to the file was not possible */ public function updateConfiguration($prefix) { // Load the configuration and replace the db prefix $config = JFactory::getConfig(); if (version_compare(JVERSION, '3.0', 'ge')) { $oldprefix = $config->get('dbprefix', $prefix); } else { $oldprefix = $config->getValue('config.dbprefix', $prefix); } if (version_compare(JVERSION, '3.0', 'ge')) { $config->set('dbprefix', $prefix); } else { $config->setValue('config.dbprefix', $prefix); } // As of Joomla! 3.2 the JRegistryFormatPHP is broken. So I can't use these two lines: /** * $newConfig = $config->toString('PHP', 'config', array('class' => 'JConfig')); * // On some occasions, Joomla! 1.6 ignores the configuration and produces "class c". Let's fix this! * $newConfig = str_replace('class c {','class JConfig {',$newConfig); **/ // Instead I will have to do everything by myself. $object = $config->toObject(); $vars = ''; $objectVars = get_object_vars($object); // At runtime, JConfig is polluted with crap by core plugins! Let's remove the crap. $doNotAddKeys = array('language', 'useStrongEncryption', 'theme', 'themeParams'); foreach ($doNotAddKeys as $dnaKey) { if (array_key_exists($dnaKey, $objectVars)) { unset ($objectVars[$dnaKey]); } } foreach ($objectVars as $k => $v) { if (is_scalar($v)) { $vars .= "\tpublic $" . $k . " = '" . addcslashes($v, '\\\'') . "';\n"; } elseif (is_array($v) || is_object($v)) { $vars .= "\tpublic $" . $k . " = " . $this->getArrayString((array)$v) . ";\n"; } } $newConfig = "<?php\nclass JConfig {\n$vars\n}"; if (version_compare(JVERSION, '3.0', 'ge')) { $config->set('dbprefix', $oldprefix); } else { $config->setValue('config.dbprefix', $oldprefix); } // Try to write out the configuration.php $filename = JPATH_ROOT . '/configuration.php'; $result = self::write($filename, $newConfig); if ($result !== false) { return true; } else { return false; } } /** * Performs the actual schema change * * @param $prefix string The new prefix * * @return bool False if the schema could not be changed */ public function changeSchema($prefix) { $config = JFactory::getConfig(); if (version_compare(JVERSION, '3.0', 'ge')) { $oldprefix = $config->get('dbprefix', ''); $dbname = $config->get('db', ''); } else { $oldprefix = $config->getValue('config.dbprefix', ''); $dbname = $config->getValue('config.db', ''); } $db = $this->getDBO(); $sql = "SHOW TABLES WHERE `Tables_in_{$dbname}` like '{$oldprefix}%'"; $db->setQuery($sql); if (version_compare(JVERSION, '3.0', 'ge')) { $oldTables = $db->loadColumn(); } else { $oldTables = $db->loadResultArray(); } if (empty($oldTables)) { return false; } foreach ($oldTables as $table) { $newTable = $prefix . substr($table, strlen($oldprefix)); $sql = "RENAME TABLE `$table` TO `$newTable`"; $db->setQuery($sql); if (!$db->execute()) { // Something went wrong; I am pulling the plug and hope for the best return false; } } return true; } /** * Performs the actual database changes and configuration updates * * @param $prefix string The new prefix * * @return bool|string True on success, the error message string on failure */ public function performChanges($prefix) { // Cache the old prefix $config = JFactory::getConfig(); if (version_compare(JVERSION, '3.0', 'ge')) { $oldprefix = $config->get('config', ''); } else { $oldprefix = $config->getValue('config.dbprefix', ''); } // Validate the prefix $prefix = $this->validatePrefix($prefix); if ($prefix === false) { return JText::sprintf('ATOOLS_ERR_DBPREFIX_INVALIDPREFIX', $prefix); } // Try to change the configuration.php if (!$this->updateConfiguration($prefix)) { return JText::_('ATOOLS_ERR_DBPREFIX_CANTSAVECONFIGURATION'); } // Try to perform the database changes if (!$this->changeSchema($prefix)) { // Revert the configuration.php $this->updateConfiguration($oldprefix); // and return an error string return JText::_('ATOOLS_ERR_DBPREFIX_COULDNTCHANGESCHEMA'); } // All done. Hopefully nothing broke. return true; } private function write($file, $buffer) { // Initialize variables JLoader::import('joomla.client.helper'); $FTPOptions = JClientHelper::getCredentials('ftp'); // If the destination directory doesn't exist we need to create it if (!file_exists(dirname($file))) { JLoader::import('joomla.filesystem.folder'); JFolder::create(dirname($file)); } if ($FTPOptions['enabled'] == 1) { // Connect the FTP client JLoader::import('joomla.client.ftp'); if (version_compare(JVERSION, '3.0', 'ge')) { $ftp = JClientFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); } else { $ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); } // Translate path for the FTP account and use FTP write buffer to file $file = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/'); $ret = $ftp->write($file, $buffer); } else { $ret = @file_put_contents($file, $buffer); } if (!$ret) { JLoader::import('joomla.filesystem.file'); JFile::write($file, $buffer); } return $ret; } }