%PDF- %PDF-
| Direktori : /home1/lightco1/www/lightingrepublic.com.au/administrator/components/com_akeeba/models/ |
| Current File : //home1/lightco1/www/lightingrepublic.com.au/administrator/components/com_akeeba/models/cpanels.php |
<?php
/**
* @package AkeebaBackup
* @copyright Copyright (c)2009-2013 Nicholas K. Dionysopoulos
* @license GNU General Public License version 3, or later
* @since 1.3
*/
// Protect from unauthorized access
defined('_JEXEC') or die();
/**
* The Control Panel model
*
*/
class AkeebaModelCpanels extends FOFModel
{
/** @var string The root of the database installation files */
private $dbFilesRoot = '/components/com_akeeba/sql/';
/** @var array If any of these tables is missing we run the install SQL file and ignore the $dbChecks array */
private $dbBaseCheck = array(
'tables' => array(
'ak_profiles', 'ak_stats',
'ak_storage',
),
'file' => 'install/mysql/install.sql'
);
/** @var array Database update checks */
private $dbChecks = array(
/**
array(
'table' => 'ak_something',
'field' => 'some_field',
'files' =>array(
'updates/mysql/x.y.z-2013-01-01.sql',
)
),
**/
);
/**
* Get an array of icon definitions for the Control Panel
*
* @return array
*/
public function getIconDefinitions()
{
AEPlatform::getInstance()->load_version_defines();
$core = $this->loadIconDefinitions(JPATH_COMPONENT_ADMINISTRATOR.'/views');
if(AKEEBA_PRO) {
$pro = $this->loadIconDefinitions(JPATH_COMPONENT_ADMINISTRATOR.'/plugins/views');
} else {
$pro = array();
}
$ret = array_merge_recursive($core, $pro);
return $ret;
}
private function loadIconDefinitions($path)
{
$ret = array();
if(!@file_exists($path.'/views.ini')) return $ret;
$ini_data = AEUtilINI::parse_ini_file($path.'/views.ini', true);
if(!empty($ini_data))
{
foreach($ini_data as $view => $def)
{
$task = array_key_exists('task',$def) ? $def['task'] : null;
$ret[$def['group']][] = $this->_makeIconDefinition($def['icon'], JText::_($def['label']), $view, $task);
}
}
return $ret;
}
/**
* Returns a list of available backup profiles, to be consumed by JHTML in order to build
* a drop-down
*
* @return array
*/
public function getProfilesList()
{
$db = $this->getDbo();
$query = $db->getQuery(true)
->select(array(
$db->qn('id'),
$db->qn('description')
))->from($db->qn('#__ak_profiles'))
->order($db->qn('id')." ASC");
$db->setQuery($query);
$rawList = $db->loadAssocList();
$options = array();
if(!is_array($rawList)) return $options;
foreach($rawList as $row)
{
$options[] = JHTML::_('select.option', $row['id'], $row['description']);
}
return $options;
}
/**
* Returns the active Profile ID
*
* @return int The active profile ID
*/
public function getProfileID()
{
$session = JFactory::getSession();
return $session->get('profile', null, 'akeeba');
}
/**
* Creates an icon definition entry
*
* @param string $iconFile The filename of the icon on the GUI button
* @param string $label The label below the GUI button
* @param string $view The view to fire up when the button is clicked
* @return array The icon definition array
*/
public function _makeIconDefinition($iconFile, $label, $view = null, $task = null )
{
return array(
'icon' => $iconFile,
'label' => $label,
'view' => $view,
'task' => $task
);
}
/**
* Was the last backup a failed one? Used to apply magic settings as a means of
* troubleshooting.
*
* @return bool
*/
public function isLastBackupFailed()
{
// Get the last backup record ID
$list = AEPlatform::getInstance()->get_statistics_list(array('limitstart' => 0, 'limit' => 1));
if(empty($list)) return false;
$id = $list[0];
$record = AEPlatform::getInstance()->get_statistics($id);
return ($record['status'] == 'fail');
}
/**
* Checks that the media permissions are 0755 for directories and 0644 for files
* and fixes them if they are incorrect.
*
* @param $force bool Forcibly check subresources, even if the parent has correct permissions
*
* @return bool False if we couldn't figure out what's going on
*/
public function fixMediaPermissions($force = false)
{
// Are we on Windows?
if (function_exists('php_uname'))
{
$isWindows = stristr(php_uname(), 'windows');
}
else
{
$isWindows = (DIRECTORY_SEPARATOR == '\\');
}
// No point changing permissions on Windows, as they have ACLs
if($isWindows) return true;
// Check the parent permissions
$parent = JPATH_ROOT.'/media/com_akeeba';
$parentPerms = fileperms($parent);
// If we can't determine the parent's permissions, bail out
if($parentPerms === false) return false;
// Fix the parent's permissions if required
if(($parentPerms != 0755) && ($parentPerms != 40755)) {
$this->chmod($parent, 0755);
} else {
if(!$force) return true;
}
// During development we use symlinks and we don't wanna see that big fat warning
if(@is_link($parent)) return true;
JLoader::import('joomla.filesystem.folder');
$result = true;
// Loop through subdirectories
$folders = JFolder::folders($parent,'.',3,true);
foreach($folders as $folder) {
$perms = fileperms($folder);
if(($perms != 0755) && ($perms != 40755)) $result &= $this->chmod($folder, 0755);
}
// Loop through files
$files = JFolder::files($parent,'.',3,true);
foreach($files as $file) {
$perms = fileperms($file);
if(($perms != 0644) && ($perms != 0100644)) {
$result &= $this->chmod($file, 0644);
}
}
return $result;
}
/**
* Tries to change a folder/file's permissions using direct access or FTP
*
* @param string $path The full path to the folder/file to chmod
* @param int $mode New permissions
*/
private function chmod($path, $mode)
{
if(is_string($mode))
{
$mode = octdec($mode);
if( ($mode < 0600) || ($mode > 0777) ) $mode = 0755;
}
// Initialize variables
JLoader::import('joomla.client.helper');
$ftpOptions = JClientHelper::getCredentials('ftp');
// Check to make sure the path valid and clean
$path = JPath::clean($path);
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']
);
}
}
if(@chmod($path, $mode))
{
$ret = true;
} elseif ($ftpOptions['enabled'] == 1) {
// Translate path and delete
$path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/');
// FTP connector throws an error
$ret = $ftp->chmod($path, $mode);
} else {
$ret = false;
}
return $ret;
}
/**
* Checks if we should enable settings encryption and applies the change
*/
public function checkSettingsEncryption()
{
// Do we have a key file?
JLoader::import('joomla.filesystem.file');
$filename = JPATH_COMPONENT_ADMINISTRATOR.'/akeeba/serverkey.php';
if(JFile::exists($filename)) {
// We have a key file. Do we need to disable it?
if(AEPlatform::getInstance()->get_platform_configuration_option('useencryption', -1) == 0) {
// User asked us to disable encryption. Let's do it.
$this->disableSettingsEncryption();
}
} else {
if(!AEUtilSecuresettings::supportsEncryption()) return;
if(AEPlatform::getInstance()->get_platform_configuration_option('useencryption', -1) != 0) {
// User asked us to enable encryption (or he left us with the default setting!). Let's do it.
$this->enableSettingsEncryption();
}
}
}
private function disableSettingsEncryption()
{
// Load the server key file if necessary
JLoader::import('joomla.filesystem.file');
$filename = JPATH_COMPONENT_ADMINISTRATOR.'/akeeba/serverkey.php';
$key = AEUtilSecuresettings::getKey();
// Loop all profiles and decrypt their settings
$profilesModel = FOFModel::getTmpInstance('Profiles','AkeebaModel');
$profiles = $profilesModel->getList(true);
$db = $this->getDBO();
foreach($profiles as $profile)
{
$id = $profile->id;
$config = AEUtilSecuresettings::decryptSettings($profile->configuration, $key);
$sql = $db->getQuery(true)
->update($db->qn('#__ak_profiles'))
->set($db->qn('configuration').' = '.$db->q($config))
->where($db->qn('id').' = '. $db->q($id));
$db->setQuery($sql);
$db->execute();
}
// Finally, remove the key file
JFile::delete($filename);
}
private function enableSettingsEncryption()
{
$key = $this->createSettingsKey();
if(empty($key) || ($key==false)) return;
// Loop all profiles and encrypt their settings
$profilesModel = FOFModel::getTmpInstance('Profiles','AkeebaModel');
$profiles = $profilesModel->getList(true);
$db = $this->getDBO();
if(!empty($profiles)) foreach($profiles as $profile)
{
$id = $profile->id;
$config = AEUtilSecuresettings::encryptSettings($profile->configuration, $key);
$sql = $db->getQuery(true)
->update($db->qn('#__ak_profiles'))
->set($db->qn('configuration').' = '.$db->q($config))
->where($db->qn('id').' = '. $db->q($id));
$db->setQuery($sql);
$db->execute();
}
}
private function createSettingsKey()
{
JLoader::import('joomla.filesystem.file');
$seedA = md5( JFile::read(JPATH_ROOT.'/configuration.php') );
$seedB = md5( microtime() );
$seed = $seedA.$seedB;
$md5 = md5($seed);
for($i = 0; $i < 1000; $i++) {
$md5 = md5( $md5 . md5(rand(0, 2147483647)) );
}
$key = base64_encode( $md5 );
$filecontents = "<?php defined('AKEEBAENGINE') or die(); define('AKEEBA_SERVERKEY', '$key'); ?>";
$filename = JPATH_COMPONENT_ADMINISTRATOR.'/akeeba/serverkey.php';
$result = JFile::write($filename, $filecontents);
if(!$result) {
return false;
} else {
return base64_decode($key);
}
}
/**
* Update the cached live site's URL for the front-end backup feature (altbackup.php)
* and the detected Joomla! libraries path
*/
public function updateMagicParameters()
{
$component = JComponentHelper::getComponent( 'com_akeeba' );
if(is_object($component->params) && ($component->params instanceof JRegistry)) {
$params = $component->params;
} else {
$params = new JParameter($component->params);
}
$params->set( 'siteurl', str_replace('/administrator','',JURI::base()) );
if(defined('JPATH_LIBRARIES')) {
$params->set('jlibrariesdir', AEUtilFilesystem::TranslateWinPath(JPATH_LIBRARIES));
} elseif(defined("JPATH_PLATFORM")) {
$params->set('jlibrariesdir', AEUtilFilesystem::TranslateWinPath(JPATH_PLATFORM));
}
$joomla16 = true;
$params->set( 'jversion', '1.6' );
$db = JFactory::getDBO();
$data = $params->toString();
$sql = $db->getQuery(true)
->update($db->qn('#__extensions'))
->set($db->qn('params').' = '.$db->q($data))
->where($db->qn('element').' = '.$db->q('com_akeeba'))
->where($db->qn('type').' = '.$db->q('component'));
$db->setQuery($sql);
$db->execute();
}
public function needsDownloadID()
{
// Do I need a Download ID?
$ret = true;
$isPro = AKEEBA_PRO;
if(!$isPro) {
$ret = false;
} else {
JLoader::import('joomla.application.component.helper');
$dlid = AEUtilComconfig::getValue('update_dlid', '');
if(preg_match('/^([0-9]{1,}:)?[0-9a-f]{32}$/i', $dlid)) {
$ret = false;
}
}
// Deactivate update site for Akeeba Backup
JLoader::import('joomla.application.component.helper');
$component = JComponentHelper::getComponent('com_akeeba');
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('update_site_id')
->from($db->qn('#__update_sites_extensions'))
->where($db->qn('extension_id').' = '.$db->q($component->id));
$db->setQuery($query);
$updateSite = $db->loadResult();
if($updateSite) {
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites'))
->where($db->qn('update_site_id').' = '.$db->q($updateSite));
$db->setQuery($query);
$db->execute();
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites_extensions'))
->where($db->qn('update_site_id').' = '.$db->q($updateSite));
$db->setQuery($query);
$db->execute();
}
// Deactivate the update site for FOF
$query = $db->getQuery(true)
->select('update_site_id')
->from($db->qn('#__update_sites'))
->where($db->qn('location').' = '.$db->q('http://cdn.akeebabackup.com/updates/libraries/fof'));
$db->setQuery($query);
$updateSite = $db->loadResult();
if($updateSite) {
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites'))
->where($db->qn('update_site_id').' = '.$db->q($updateSite));
$db->setQuery($query);
$db->execute();
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites_extensions'))
->where($db->qn('update_site_id').' = '.$db->q($updateSite));
$db->setQuery($query);
$db->execute();
}
return $ret;
}
/**
* Makes sure that the Professional release can be updated using Joomla!'s
* own update system. THIS IS AN AKEEBA ORIGINAL!
*/
public function applyJoomlaExtensionUpdateChanges($isPro = -1)
{
$ret = true;
// Don';'t bother if this is not Joomla! 1.7+
if(!version_compare(JVERSION, '1.7.0', 'ge')) return $ret;
// Do we have Admin Tools Professional?
if($isPro === -1) {
$isPro = AKEEBA_PRO;
}
// Action parameters
$action = 'none'; // What to do: none, update, create, delete
$purgeUpdates = false; // Should I purge existing updates?
$fetchUpdates = false; // Should I fetch new udpater
// Init
$db = $this->getDbo();
// Figure out the correct XML update stream URL
if($isPro) {
$update_url = 'https://www.akeebabackup.com/index.php?option=com_ars&view=update&task=stream&format=xml&id=6';
JLoader::import('joomla.application.component.helper');
$params = JComponentHelper::getParams('com_akeeba');
if(version_compare(JVERSION, '3.0', 'ge')) {
$dlid = $params->get('update_dlid','');
} else {
$dlid = $params->getValue('update_dlid','');
}
if(!preg_match('/^[0-9a-f]{32}$/i', $dlid)) {
$ret = false;
$dlid = '';
}
if($dlid) {
$dlid = $dlid;
$url = $update_url.'&dlid='.$dlid.'/extension.xml';
} else {
$url = '';
}
} else {
$url = 'http://cdn.akeebabackup.com/updates/atcore.xml';
}
// Get the extension ID
$extensionID = JComponentHelper::getComponent('com_akeeba')->id;
// Get the update site record
$query = $db->getQuery(true)
->select(array(
$db->qn('us').'.*',
))->from(
$db->qn('#__update_sites_extensions').' AS '.$db->qn('map')
)->innerJoin(
$db->qn('#__update_sites').' AS '.$db->qn('us').' ON ('.
$db->qn('us').'.'.$db->qn('update_site_id').' = '.
$db->qn('map').'.'.$db->qn('update_site_id').')'
)
->where(
$db->qn('map').'.'.$db->qn('extension_id').' = '.$db->q($extensionID)
);
$db->setQuery($query);
$update_site = $db->loadObject();
// Decide on the course of action to take
if($url) {
if(!is_object($update_site)) {
$action = 'create';
$fetchUpdates = true;
} else {
$action = ($update_site->location != $url) ? 'update' : 'none';
$purgeUpdates = $action == 'update';
$fetchUpdates = $action == 'update';
}
} else {
// Disable the update site for Akeeba Backup
if(!is_object($update_site)) {
$action = 'none';
} else {
$action = 'delete';
$purgeUpdates = true;
}
}
switch($action)
{
case 'none':
// No change
break;
case 'create':
case 'update':
// Remove old update site
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites'))
->where($db->qn('name') .' = '. $db->q('Akeeba Backup updates'));
$db->setQuery($query);
$db->execute();
// Create new update site
$oUpdateSite = (object)array(
'name' => 'Akeeba Backup updates',
'type' => 'extension',
'location' => $url,
'enabled' => 1,
'last_check_timestamp' => 0,
);
$db->insertObject('#__update_sites', $oUpdateSite);
// Get the update site ID
$usID = $db->insertid();
// Delete existing #__update_sites_extensions records
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites_extensions'))
->where($db->qn('extension_id') .' = '. $db->q($extensionID));
$db->setQuery($query);
$db->execute();
// Create new #__update_sites_extensions record
$oUpdateSitesExtensions = (object)array(
'update_site_id' => $usID,
'extension_id' => $extensionID
);
$db->insertObject('#__update_sites_extensions', $oUpdateSitesExtensions);
break;
case 'delete':
// Remove update sites
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites'))
->where($db->qn('update_site_id') .' = '. $db->q($update_site->update_site_id));
$db->setQuery($query);
$db->execute();
// Delete existing #__update_sites_extensions records
$query = $db->getQuery(true)
->delete($db->qn('#__update_sites_extensions'))
->where($db->qn('extension_id') .' = '. $db->q($extensionID));
$db->setQuery($query);
$db->execute();
break;
}
// Do I have to purge updates?
if($purgeUpdates) {
$query = $db->getQuery(true)
->delete($db->qn('#__updates'))
->where($db->qn('element').' = '.$db->q('com_akeeba'));
$db->setQuery($query);
$db->execute();
}
// Do I have to fetch updates?
if($fetchUpdates) {
JLoader::import('joomla.update.update');
$x = new JUpdater();
$x->findUpdates($extensionID);
}
return $ret;
}
/**
* Checks the database for missing / outdated tables using the $dbChecks
* data and runs the appropriate SQL scripts if necessary.
*
* @return AkeebasubsModelCpanels
*/
public function checkAndFixDatabase()
{
$db = $this->getDbo();
// Initialise
$tableFields = array();
$sqlFiles = array();
// Get a listing of database tables known to Joomla!
$allTables = $db->getTableList();
$dbprefix = JFactory::getConfig()->get('dbprefix', '');
// Perform the base check. If any of these tables is missing we have to run the installation SQL file
if(!empty($this->dbBaseCheck)) {
foreach($this->dbBaseCheck['tables'] as $table)
{
$tableName = $dbprefix . $table;
$check = in_array($tableName, $allTables);
if (!$check) break;
}
if (!$check)
{
$sqlFiles[] = JPATH_ADMINISTRATOR . $this->dbFilesRoot . $this->dbBaseCheck['file'];
}
}
// If the base check was successful and we have further database checks run them
if (empty($sqlFiles) && !empty($this->dbChecks)) foreach($this->dbChecks as $dbCheck)
{
// Always check that the table exists
$tableName = $dbprefix . $dbCheck['table'];
$check = in_array($tableName, $allTables);
// If the table exists and we have a field, check that the field exists too
if (!empty($dbCheck['field']) && $check)
{
if (!array_key_exists($tableName, $tableFields))
{
$tableFields[$tableName] = $db->getTableColumns('#__' . $dbCheck['table'], true);
}
if (is_array($tableFields[$tableName]))
{
$check = array_key_exists($dbCheck['field'], $tableFields[$tableName]);
}
else
{
$check = false;
}
}
// Something's missing. Add the file to the list of SQL files to run
if (!$check)
{
foreach ($dbCheck['files'] as $file)
{
$sqlFiles[] = JPATH_ADMINISTRATOR . $this->dbFilesRoot . $file;
}
}
}
// If we have SQL files to run, well, RUN THEM!
if (!empty($sqlFiles))
{
JLoader::import('joomla.filesystem.file');
foreach($sqlFiles as $file)
{
$sql = JFile::read($file);
if($sql) {
$commands = explode(';', $sql);
foreach($commands as $query) {
$db->setQuery($query);
$db->execute();
}
}
}
}
return $this;
}
}