%PDF- %PDF-
| Direktori : /home1/lightco1/www/ilfanale.com.au/administrator/components/com_easyslider/ |
| Current File : //home1/lightco1/www/ilfanale.com.au/administrator/components/com_easyslider/jsninstaller.php |
<?php
/**
* @version $Id$
* @package JSN_EasySlider
* @author JoomlaShine Team <support@joomlashine.com>
* @copyright Copyright (C) 2012 JoomlaShine.com. All Rights Reserved.
* @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
*
* Websites: http://www.joomlashine.com
* Technical Support: Feedback - http://www.joomlashine.com/contact-us/get-support.html
*/
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// Disable notice and warning by default for our products.
// The reason for doing this is if any notice or warning appeared then handling JSON string will fail in our code.
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);
/**
* Class for finalizing JSN extension installation.
*
* @package JSN_EasySlider
* @since 1.0.0
*/
abstract class JSNInstallerScript
{
/**
* Variable for holding backed up data.
*
* @var SimpleXMLElement
*/
protected $jsnesdata;
/**
* XML manifest.
*
* @var SimpleXMLElement
*/
protected $manifest;
/**
* Implement preflight hook.
*
* This step will be verify permission for install/update process.
*
* @param string $mode Install or update?
* @param object $parent JInstaller object.
*
* @return boolean
*/
public function preflight($mode, $parent)
{
// Initialize variables
$this->app = JFactory::getApplication();
$this->parentInstaller = $parent->getParent();
//check if EasySlider is installed and version is smaller than 2.x.x or not
$easyslider = $this->getExtInfo();
if (count($easyslider))
{
$extManifest = json_decode($easyslider->manifest_cache);
$installedVersion = $extManifest->version;
if (version_compare($installedVersion, '2.0.0', '<'))
{
if ($this->app->input->getVar('jsn_es_status', '') == '')
{
$this->showWarningMessage($this->parentInstaller);
return false;
}
elseif ($this->app->input->getVar('jsn_es_status', '') == 'yes')
{
$config = JFactory::getConfig();
$tmpPath = $config->get('tmp_path');
if (!is_writable($tmpPath))
{
$this->app->enqueueMessage('Cannot install "JSN EasySlider" because folder "/tmp" is Unwritable. Please set Writable permission (CHMOD 777) for it before performing update operations', 'error');
return false;
}
//Backup date for version 1.x.x
$rbackup = $this->backup($extManifest);
if (!$rbackup)
{
$this->app->enqueueMessage('Cannot install "JSN EasySlider" because the backup function cannot backup your data. Please check and make sure "/tmp" folder is WRITABLE', 'error');
return false;
}
}
else
{
//do nothing
}
}
}
$this->manifest = $this->parentInstaller->getManifest();
// Get installed extension directory and name
$this->path = $this->parentInstaller->getPath('extension_administrator');
$this->name = substr(basename($this->path), 4);
// Check if installed Joomla version is compatible
$joomlaVersion = new JVersion;
$canInstall = substr($joomlaVersion->RELEASE, 0, 1) == substr((string) $this->manifest['version'], 0, 1) ? true : false;
if ( ! $canInstall)
{
$this->app->enqueueMessage(sprintf('Cannot install "%s" because the installation package is not compatible with your installed Joomla version', (string) $this->manifest->name), 'error');
}
// Parse dependency
$this->parseDependency($this->parentInstaller);
// Skip checking folder permission if FTP layer is enabled
$config = JFactory::getConfig();
if ($config->get('ftp_enable'))
{
// Try to backup user edited language file
return $this->backupLanguage();
}
// Check environment
$canInstallExtension = true;
$canInstallSiteLanguage = is_writable(JPATH_SITE . '/language');
$canInstallAdminLanguage = is_writable(JPATH_ADMINISTRATOR . '/language');
$canInstallProduct = is_writable($config->get('tmp_path'));
if (! $canInstallProduct)
{
$this->app->enqueueMessage(sprintf('Cannot install because "%s" is not writable', $config->get('tmp_path')), 'error');
}
if ( ! $canInstallSiteLanguage)
{
$this->app->enqueueMessage(sprintf('Cannot install language file at "%s"', JPATH_SITE . '/language'), 'error');
}
else
{
foreach (glob(JPATH_SITE . '/language/*', GLOB_ONLYDIR) AS $dir)
{
if ( ! is_writable($dir))
{
$canInstallSiteLanguage = false;
$this->app->enqueueMessage(sprintf('Cannot install language file at "%s"', $dir), 'error');
}
}
}
if ( ! $canInstallAdminLanguage)
{
$this->app->enqueueMessage(sprintf('Cannot install language file at "%s"', JPATH_ADMINISTRATOR . '/language'), 'error');
}
else
{
foreach (glob(JPATH_ADMINISTRATOR . '/language/*', GLOB_ONLYDIR) AS $dir)
{
if ( ! is_writable($dir))
{
$canInstallAdminLanguage = false;
$this->app->enqueueMessage(sprintf('Cannot install language file at "%s"', $dir), 'error');
}
}
}
// Checking directory permissions for dependency installation
foreach ($this->dependencies AS & $extension)
{
// Simply continue if extension is set to be removed
if (isset($extension->remove) AND (int) $extension->remove > 0)
{
continue;
}
// Check if dependency can be installed
switch ($extension->type = strtolower($extension->type))
{
case 'component':
$sitePath = JPATH_SITE . '/components';
$adminPath = JPATH_ADMINISTRATOR . '/components';
if ( ! is_dir($sitePath) OR ! is_writable($sitePath))
{
$canInstallExtension = false;
$this->app->enqueueMessage(sprintf('Cannot install "%s" %s because "%s" is not writable', $extension->name, $extension->type, $sitePath), 'error');
}
if ( ! is_dir($adminPath) OR ! is_writable($adminPath))
{
$canInstallExtension = false;
$this->app->enqueueMessage(sprintf('Cannot install "%s" %s because "%s" is not writable', $extension->name, $extension->type, $adminPath), 'error');
}
break;
case 'plugin':
$path = JPATH_ROOT . '/plugins/' . $extension->folder;
if ((is_dir($path) AND ! is_writable($path)) OR ( ! is_dir($path) AND ! is_writable(dirname($path))))
{
$canInstallExtension = false;
$this->app->enqueueMessage(sprintf('Cannot install "%s" %s because "%s" is not writable', $extension->name, $extension->type, $path), 'error');
}
break;
case 'module':
case 'template':
$path = ($extension->client == 'site' ? JPATH_SITE : JPATH_ADMINISTRATOR) . "/{$extension->type}s";
if ( ! is_dir($path) OR ! is_writable($path))
{
$canInstallExtension = false;
$this->app->enqueueMessage(sprintf('Cannot install "%s" %s because "%s" is not writable', $extension->name, $extension->type, $path), 'error');
}
break;
}
if ($canInstallProduct AND $canInstall AND $canInstallExtension AND $canInstallSiteLanguage AND $canInstallAdminLanguage AND isset($extension->source))
{
// Backup dependency parameters
$db = JFactory::getDbo();
$q = $db->getQuery(true);
$q->select('params');
$q->from('#__extensions');
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
$db->setQuery($q);
$extension->params = $db->loadResult();
}
}
if ($canInstallProduct AND $canInstall AND $canInstallExtension AND $canInstallSiteLanguage AND $canInstallAdminLanguage)
{
$rBackupLanguage = $this->backupLanguage();
//if is old version then clean redundant files
if ($rBackupLanguage && count($easyslider))
{
$this->removeRedundantFiles();
}
return $rBackupLanguage;
}
else
{
return false;
}
}
/**
* Implement postflight hook.
*
* @param string $type Extension type.
* @param object $parent JInstaller object.
*
* @return void
*/
public function postflight($type, $parent)
{
// Get original installer
isset($this->parentInstaller) OR $this->parentInstaller = $parent->getParent();
// Update language file
$this->updateLanguage();
// Process dependency installation
foreach ($this->dependencies AS $extension)
{
// Remove installed extension if requested
if (isset($extension->remove) AND (int) $extension->remove > 0)
{
$this->removeExtension($extension);
continue;
}
// Install only dependency that has local installation package
if (isset($extension->source))
{
// Install and update dependency status
$this->installExtension($extension);
}
elseif ( ! isset($this->missingDependency))
{
$this->missingDependency = true;
}
}
// Create dependency declaration constant
if ( ! defined('JSN_' . strtoupper($this->name) . '_DEPENDENCY'))
{
// Get Joomla config
$config = JFactory::getConfig();
// Unset some unnecessary properties
foreach ($this->dependencies AS & $dependency)
{
unset($dependency->source);
unset($dependency->upToDate);
}
$this->dependencies = json_encode($this->dependencies);
// Store dependency declaration
file_exists($defines = $this->path . '/defines.php')
OR file_exists($defines = $this->path . "/{$this->name}.defines.php")
OR $defines = $this->path . "/{$this->name}.php";
if ($config->get('ftp_enable') OR is_writable($defines))
{
$buffer = preg_replace(
'/(defined\s*\(\s*._JEXEC.\s*\)[^\n]+\n)/',
'\1' . "\ndefine('JSN_" . strtoupper($this->name) . "_DEPENDENCY', '" . $this->dependencies . "');\n",
JFile::read($defines)
);
JFile::write($defines, $buffer);
}
}
// Clean latest product version cache file
$cache = JFactory::getConfig()->get('tmp_path') . '/JoomlaShineUpdates.json';
if (file_exists($cache))
{
jimport('joomla.filesystem.file');
JFile::delete($cache);
}
// Register check update link for Joomla
$JVersion = new JVersion;
// Check if current joomla version is 2.5.x
$isJoomla25 = (version_compare($JVersion->getShortVersion(), '2.5', '>=') AND version_compare($JVersion->getShortVersion(), '3.0', '<'));
//if (version_compare($JVersion->RELEASE, '3.1', '>='))
//{
// Get id for the extension just installed
$ext = JTable::getInstance('Extension');
$ext->load(array(
'name' => $this->name,
'element' => basename($this->path),
'type' => 'component'
));
if ($ext->extension_id)
{
// Get current check update data
$db = JFactory::getDbo();
$q = $db->getQuery(true);
$q->select('update_site_id');
$q->from('#__update_sites');
$q->where('name = ' . $q->quote(strtolower(trim($this->name))));
$q->where('type = ' . $q->quote('collection'));
$db->setQuery($q);
if ($uid = $db->loadResult())
{
// Clean-up current check update data
$q = $db->getQuery(true);
$q->delete('#__update_sites');
$q->where('update_site_id = ' . (int) $uid);
$db->setQuery($q);
if ($isJoomla25)
{
$db->query();
}
else
{
$db->execute();
}
$q = $db->getQuery(true);
$q->delete('#__update_sites_extensions');
$q->where('update_site_id = ' . (int) $uid);
$db->setQuery($q);
if ($isJoomla25)
{
$db->query();
}
else
{
$db->execute();
}
}
// Register check update data
$ln = 'http://www.joomlashine.com/versioning/extensions/' . $ext->element . '.xml';
$q = $db->getQuery(true);
$q->insert('#__update_sites');
$q->columns('`name`, `type`, `location`, `enabled`');
$q->values($q->quote(strtolower(trim($this->name))) . ', ' . $q->quote('collection') . ', ' . $q->quote($ln) . ', 1');
$db->setQuery($q);
if ($isJoomla25)
{
$db->query();
}
else
{
$db->execute();
}
if ($uid = $db->insertid())
{
$q = $db->getQuery(true);
$q->insert('#__update_sites_extensions');
$q->columns('`update_site_id`, `extension_id`');
$q->values((int) $uid . ', ' . (int) $ext->extension_id);
$db->setQuery($q);
if ($isJoomla25)
{
$db->query();
}
else
{
$db->execute();
}
}
}
//}
// Check if redirect should be disabled
if ($this->app->input->getBool('tool_redirect', true))
{
// Do we have any missing dependency
if ($this->missingDependency)
{
if (strpos($_SERVER['HTTP_REFERER'], '/administrator/index.php?option=com_installer') !== false)
{
// Set redirect to finalize dependency installation
$this->parentInstaller->setRedirectURL('index.php?option=com_' . $this->name . '&view=installer');
}
else
{
// Let Ajax client redirect
echo '
<script type="text/javascript">
if (window.parent)
window.parent.location.href ="' . JUri::root() . 'administrator/index.php?option=com_' . $this->name . '&view=installer";
else
location.href ="' . JUri::root() . 'administrator/index.php?option=com_' . $this->name . '&view=installer";
</script>';
exit;
}
}
}
}
/**
* Implement uninstall hook.
*
* @param object $parent JInstaller object.
*
* @return void
*/
public function uninstall($parent)
{
// Initialize variables
isset($this->parentInstaller) OR $this->parentInstaller = $parent->getParent();
$this->app = JFactory::getApplication();
$this->manifest = $this->parentInstaller->getManifest();
// Get installed extension directory and name
$this->path = $this->parentInstaller->getPath('extension_administrator');
$this->name = substr(basename($this->path), 4);
// Parse dependency
$this->parseDependency($this->parentInstaller);
// Remove all dependency
foreach ($this->dependencies AS $extension)
{
$this->removeExtension($extension);
}
}
/**
* Retrieve dependency from manifest file.
*
* @param object $installer JInstaller object.
*
* @return object Return itself for method chaining.
*/
protected function parseDependency($installer)
{
// Continue only if dependency not checked before
if ( ! isset($this->dependencies) OR ! is_array($this->dependencies))
{
// Preset dependency list
$this->dependencies = array();
if (isset($this->manifest->subinstall) AND $this->manifest->subinstall instanceOf SimpleXMLElement)
{
// Loop on each node to retrieve dependency information
foreach ($this->manifest->subinstall->children() AS $node)
{
// Verify tag name
if (strcasecmp($node->getName(), 'extension') != 0)
{
continue;
}
// Re-create serializable dependency object
$extension = (array) $node;
$extension = (object) $extension['@attributes'];
$extension->title = trim((string) $node != '' ? (string) $node : ($node['title'] ? (string) $node['title'] : (string) $node['name']));
// Validate dependency
if ( ! isset($extension->name) OR ! isset($extension->type) OR ! in_array($extension->type, array('template', 'plugin', 'module', 'component')) OR ($extension->type == 'plugin' AND ! isset($extension->folder)))
{
continue;
}
// Check if dependency has local installation package
if (isset($extension->dir) AND is_dir($source = $installer->getPath('source') . '/' . $extension->dir))
{
$extension->source = $source;
}
$this->dependencies[] = $extension;
}
}
}
return $this;
}
/**
* Install a dependency.
*
* @param object $extension Object containing extension details.
*
* @return void
*/
public function installExtension($extension)
{
// Get application object
isset($this->app) OR $this->app = JFactory::getApplication();
// Get database object
$db = JFactory::getDbo();
$q = $db->getQuery(true);
// Build query to get dependency installation status
$q->select('manifest_cache, custom_data');
$q->from('#__extensions');
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
// Execute query
$db->setQuery($q);
if ($status = $db->loadObject())
{
// Initialize variables
$JVersion = new JVersion;
$manifest = json_decode($status->manifest_cache);
// Get information about the dependency to be installed
$xml = JPATH::clean($extension->source . '/' . $extension->name . '.xml');
if (is_file($xml) AND ($xml = simplexml_load_file($xml)))
{
if ($JVersion->RELEASE == (string) $xml['version'] AND version_compare($manifest->version, (string) $xml->version, '<'))
{
// The dependency to be installed is newer than the existing one, mark for update
$doInstall = true;
}
if ($JVersion->RELEASE != (string) $xml['version'] AND version_compare($manifest->version, (string) $xml->version, '<='))
{
// The dependency to be installed might not newer than the existing one but Joomla version is difference, mark for update
$doInstall = true;
}
}
}
elseif (isset($extension->source))
{
// The dependency to be installed not exist, mark for install
$doInstall = true;
}
if (isset($doInstall) AND $doInstall)
{
// Install dependency
$installer = new JInstaller;
if ( ! $installer->install($extension->source))
{
$this->app->enqueueMessage(sprintf('Error installing "%s - %s" %s', $extension->folder, $extension->name, $extension->type), 'error');
}
else
{
$this->app->enqueueMessage(sprintf('Install "%s - %s" %s was successfull', $extension->folder, $extension->name, $extension->type));
// Update dependency status
$this->updateExtension($extension);
// Build query to get dependency installation status
$q = $db->getQuery(true);
$q->select('manifest_cache, custom_data');
$q->from('#__extensions');
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
$db->setQuery($q);
// Load dependency installation status
$status = $db->loadObject();
}
}
// Update dependency tracking
if (isset($status))
{
$ext = isset($this->name) ? $this->name : substr($this->app->input->getCmd('option'), 4);
$dep = ! empty($status->custom_data) ? (array) json_decode($status->custom_data) : array();
// Backward compatible: move all dependency data from params to custom_data column
if (is_array($params = (isset($extension->params) AND $extension->params != '{}') ? (array) json_decode($extension->params) : null))
{
foreach (array('imageshow', 'poweradmin', 'easyslider') AS $com)
{
if ($com != $ext AND isset($params[$com]))
{
$dep[] = $com;
}
}
}
// Update dependency list
in_array($ext, $dep) OR $dep[] = $ext;
$status->custom_data = array_unique($dep);
// Build query to update dependency data
$q = $db->getQuery(true);
$q->update('#__extensions');
$q->set("custom_data = '" . json_encode($status->custom_data) . "'");
// Backward compatible: keep data in this column for older product to recognize
$manifestCache = json_decode($status->manifest_cache);
$manifestCache->dependency = $status->custom_data;
$q->set("manifest_cache = '" . json_encode($manifestCache) . "'");
// Backward compatible: keep data in this column also for another old product to recognize
$params = is_array($params)
? array_merge($params, array_combine($status->custom_data, $status->custom_data))
: array_combine($status->custom_data, $status->custom_data);
$q->set("params = '" . json_encode($params) . "'");
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
$db->setQuery($q);
$db->execute();
}
}
/**
* Update dependency status.
*
* @param object $extension Extension to update.
*
* @return object Return itself for method chaining.
*/
protected function updateExtension($extension)
{
// Get object to working with extensions table
$table = JTable::getInstance('Extension');
// Load extension record
$condition = array(
'type' => $extension->type,
'element' => $extension->name
);
if ($extension->type == 'plugin')
{
$condition['folder'] = $extension->folder;
}
$table->load($condition);
// Update extension record
$table->enabled = (isset($extension->publish) AND (int) $extension->publish > 0) ? 1 : 0;
$table->protected = (isset($extension->lock) AND (int) $extension->lock > 0) ? 1 : 0;
$table->client_id = (isset($extension->client) AND $extension->client == 'site') ? 0 : 1;
// Store updated extension record
$table->store();
// Update module instance
if ($extension->type == 'module')
{
// Get object to working with modules table
$module = JTable::getInstance('module');
// Load module instance
$module->load(array('module' => $extension->name));
// Update module instance
$module->title = $extension->title;
$module->ordering = isset($extension->ordering) ? $extension->ordering : 0;
$module->published = (isset($extension->publish) AND (int) $extension->publish > 0) ? 1 : 0;
if ($hasPosition = (isset($extension->position) AND (string) $extension->position != ''))
{
$module->position = (string) $extension->position;
}
// Store updated module instance
$module->store();
// Set module instance to show in all page
if ($hasPosition AND (int) $module->id > 0)
{
// Get database object
$db = JFactory::getDbo();
$q = $db->getQuery(true);
try
{
// Remove all menu assignment records associated with this module instance
$q->delete('#__modules_menu');
$q->where("moduleid = {$module->id}");
// Execute query
$db->setQuery($q);
$db->execute();
// Build query to show this module instance in all page
$q->insert('#__modules_menu');
$q->columns('moduleid, menuid');
$q->values("{$module->id}, 0");
// Execute query
$db->setQuery($q);
$db->execute();
}
catch (Exception $e)
{
throw $e;
}
}
}
return $this;
}
/**
* Disable a dependency.
*
* @param object $extension Extension to update.
*
* @return object Return itself for method chaining.
*/
protected function disableExtension($extension)
{
// Get database object
$db = JFactory::getDbo();
$q = $db->getQuery(true);
// Build query
$q->update('#__extensions');
$q->set('enabled = 0');
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
// Execute query
$db->setQuery($q);
$db->execute();
return $this;
}
/**
* Unlock a dependency.
*
* @param object $extension Extension to update.
*
* @return object Return itself for method chaining.
*/
protected function unlockExtension($extension)
{
// Get database object
$db = JFactory::getDbo();
$q = $db->getQuery(true);
// Build query
$q->update('#__extensions');
$q->set('protected = 0');
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
// Execute query
$db->setQuery($q);
$db->execute();
return $this;
}
/**
* Remove a dependency.
*
* @param object $extension Extension to update.
*
* @return object Return itself for method chaining.
*/
protected function removeExtension($extension)
{
// Get application object
isset($this->app) OR $this->app = JFactory::getApplication();
// Preset dependency status
$extension->removable = true;
// Get database object
$db = JFactory::getDbo();
$q = $db->getQuery(true);
// Build query to get dependency installation status
$q->select('extension_id, manifest_cache, custom_data, params');
$q->from('#__extensions');
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
// Execute query
$db->setQuery($q);
if ($status = $db->loadObject())
{
// Initialize variables
$id = $status->extension_id;
$ext = isset($this->name) ? $this->name : substr($this->app->input->getCmd('option'), 4);
$deps = ! empty($status->custom_data) ? (array) json_decode($status->custom_data) : array();
// Update dependency tracking
$status->custom_data = array();
foreach ($deps AS $dep)
{
// Backward compatible: ensure that product is not removed
// if ($dep != $ext)
if ($dep != $ext AND is_dir(JPATH_BASE . '/components/com_' . $dep))
{
$status->custom_data[] = $dep;
}
}
if (count($status->custom_data))
{
// Build query to update dependency data
$q = $db->getQuery(true);
$q->update('#__extensions');
$q->set("custom_data = '" . json_encode($status->custom_data) . "'");
// Backward compatible: keep data in this column for older product to recognize
$manifestCache = json_decode($status->manifest_cache);
$manifestCache->dependency = $status->custom_data;
$q->set("manifest_cache = '" . json_encode($manifestCache) . "'");
// Backward compatible: keep data in this column also for another old product to recognize
$params = is_array($params = (isset($status->params) AND $status->params != '{}') ? (array) json_decode($status->params) : null)
? array_merge($params, array_combine($status->custom_data, $status->custom_data))
: array_combine($status->custom_data, $status->custom_data);
$q->set("params = '" . json_encode($params) . "'");
$q->where("element = '{$extension->name}'");
$q->where("type = '{$extension->type}'");
$extension->type != 'plugin' OR $q->where("folder = '{$extension->folder}'");
$db->setQuery($q);
$db->execute();
// Indicate that extension is not removable
$extension->removable = false;
}
}
else
{
// Extension was already removed
$extension->removable = false;
}
if ($extension->removable)
{
// Disable and unlock dependency
$this->disableExtension($extension);
$this->unlockExtension($extension);
// Remove dependency
$installer = new JInstaller;
if ($installer->uninstall($extension->type, $id))
{
$this->app->enqueueMessage(sprintf('"%s" %s has been uninstalled', $extension->name, $extension->type));
}
else
{
$this->app->enqueueMessage(sprintf('Cannot uninstall "%s" %s', $extension->name, $extension->type));
}
}
return $this;
}
/**
* Attemp to backup user edited language file before re-install/update.
*
* @return boolean FALSE if backup fail for any reason, TRUE otherwise.
*/
protected function backupLanguage()
{
// Load language utility class
$langUtil = (class_exists('JSNUtilsLanguage') AND method_exists('JSNUtilsLanguage', 'edited'))
? 'JSNUtilsLanguage' : 'JSNUtilsLanguageTmp';
if ($langUtil != 'JSNUtilsLanguage')
{
file_exists($this->parentInstaller->getPath('source') . '/admin/libraries/joomlashine/utils/language.php')
? require_once $this->parentInstaller->getPath('source') . '/admin/libraries/joomlashine/utils/language.php'
: ($langUtil = null);
}
if ($langUtil)
{
// Get list of component's supported language
$admin = is_dir($this->path . '/language/admin') ? JFolder::folders($this->path . '/language/admin') : null;
$site = is_dir($this->path . '/language/site') ? JFolder::folders($this->path . '/language/site') : null;
if ($admin AND $site)
{
$langs = array_merge($admin, $site);
}
elseif ($admin OR $site)
{
$langs = $admin ? $admin : $site;
}
$langs = isset($langs) ? array_unique($langs) : array();
// Loop thru supported language list and get all language files installed in Joomla's language folder
foreach ($langs AS $lang)
{
// Check if language is installed in Joomla's language folder and manually edited by user
$isEdited = array(
'admin' => call_user_func(array($langUtil, 'edited'), $lang, false, "com_{$this->name}"),
'site' => call_user_func(array($langUtil, 'edited'), $lang, true, "com_{$this->name}")
);
foreach ($isEdited AS $client => $edited)
{
if ($edited)
{
// Get list of language file
$files = glob($this->path . "/language/{$client}/{$lang}/{$lang}.*.ini");
// Backup all language file installed in Joomla's language folder
foreach ($files AS $file)
{
// Generate path to user edited language file in Joomla's language folder
$f = ($client == 'admin' ? JPATH_ADMINISTRATOR : JPATH_SITE) . "/language/{$lang}/" . basename($file);
// Backup user edited language file to temporary directory
if (is_readable($f))
{
if ( ! JFile::copy($f, "{$f}.jsn-installer-backup"))
{
$backupFails[] = str_replace(JPATH_ROOT, 'JOOMLA_ROOT', $f);
}
}
}
}
}
}
if (isset($backupFails))
{
$this->app->enqueueMessage(
'Cannot backup following user edited language file(s): <ul><li>' . implode('</li><li>', $backupFails) . '</li></ul>',
'warning'
);
return false;
}
}
return true;
}
/**
* Update all language file installed in Joomla's language folder.
*
* @return boolean FALSE if update fail for any reason, TRUE otherwise.
*/
protected function updateLanguage()
{
// Load language utility class
$langUtil = (class_exists('JSNUtilsLanguage') AND method_exists('JSNUtilsLanguage', 'edited'))
? 'JSNUtilsLanguage' : 'JSNUtilsLanguageTmp';
if ($langUtil != 'JSNUtilsLanguage')
{
file_exists($this->parentInstaller->getPath('source') . '/admin/libraries/joomlashine/utils/language.php')
? require_once $this->parentInstaller->getPath('source') . '/admin/libraries/joomlashine/utils/language.php'
: ($langUtil = null);
}
if ($langUtil)
{
// Get list of component's supported language
$admin = is_dir($this->path . '/language/admin') ? JFolder::folders($this->path . '/language/admin') : null;
$site = is_dir($this->path . '/language/site') ? JFolder::folders($this->path . '/language/site') : null;
if ($admin AND $site)
{
$langs = array_merge($admin, $site);
}
elseif ($admin OR $site)
{
$langs = $admin ? $admin : $site;
}
$langs = isset($langs) ? array_unique($langs) : array();
// Loop thru supported language list and get all language files installed in Joomla's language folder
foreach ($langs AS $lang)
{
// Check if language is installed in Joomla's language folder
$isInstalled = array(
'admin' => call_user_func(array($langUtil, 'installed'), $lang, false, "com_{$this->name}"),
'site' => call_user_func(array($langUtil, 'installed'), $lang, true, "com_{$this->name}")
);
foreach ($isInstalled AS $client => $installed)
{
if ($installed)
{
// Install new language file
call_user_func(array($langUtil, 'install'), (array) $lang, $client != 'admin' ? true : false, true, "com_{$this->name}");
// Get list of language file
$files = glob($this->path . "/language/{$client}/{$lang}/{$lang}.*.ini");
// Check if any installed language file has backup
foreach ($files AS $file)
{
// Clean all possible new-line character left by 'glob' function
$file = preg_replace('/(\r|\n)/', '', $file);
// Generate path to installed language file in Joomla's language folder
$f = ($client == 'admin' ? JPATH_ADMINISTRATOR : JPATH_SITE) . "/language/{$lang}/" . basename($file);
// If language file has backup, merge all user's translation into new language file
if (is_readable("{$f}.jsn-installer-backup"))
{
// Read content of new language file to array
$new = file($file);
// Read content of backup file to associative array
foreach (file("{$f}.jsn-installer-backup") AS $line)
{
if ( ! empty($line) AND ! preg_match('/^\s*;/', $line) AND preg_match('/^\s*([^=]+)="([^\r\n]+)"\s*$/', $line, $match))
{
$bak[$match[1]] = $match[2];
}
}
// Merge user's translation into new language file
foreach ($new AS & $line)
{
if ( ! empty($line) AND ! preg_match('/^\s*;/', $line) AND preg_match('/^\s*([^=]+)="([^\r\n]+)"\s*$/', $line, $match))
{
if (isset($bak[$match[1]]))
{
$line = str_replace($match[2], $bak[$match[1]], $line);
// Mark as merged
isset($merged) OR $merged = true;
}
}
}
// Update installed language file with merged content
if (isset($merged) AND $merged)
{
$new = implode($new);
if ( ! JFile::write($f, $new))
{
$mergeFails[] = str_replace(JPATH_ROOT, 'JOOMLA_ROOT', $f);
}
}
// Remove backup file
JFile::delete("{$f}.jsn-installer-backup");
}
}
}
}
}
if (isset($mergeFails))
{
$this->app->enqueueMessage(
'Cannot merge user edited translation back to following language file(s): <ul><li>' . implode('</li><li>', $mergeFails) . '</li></ul>',
'warning'
);
return false;
}
}
return true;
}
/**
* Show warning message when update from version 1.x.x to 2.x.x
*
* @param object $parentInstaller JInstaller object.
* @return void
*/
protected function showWarningMessage($parentInstaller)
{
$path = $parentInstaller->getPath('source');
$html = '<form enctype="multipart/form-data" action="' . JRoute::_('index.php?option=com_installer&view=install') . '" method="post" name="JSNESAdminForm" id="JSNESAdminForm" class="form-horizontal" style="display: none;">';
$html .= '<input type="text" name="install_directory" class="span5 input_box" size="70" value="' . $path . '" />';
$html .= '<button type="submit" id="JSNESNInstallationBtn">Upload and Install</button>';
$html .= '<input type="hidden" name="type" value="" />';
$html .= '<input type="hidden" name="installtype" value="folder" />';
$html .= '<input type="hidden" name="task" value="install.install" />';
$html .= '<input type="hidden" name="jsn_es_status" value="yes" />';
$html .= JHtml::_('form.token');
$html .= '</form>';
$html .= '<p>JSN EasySlider version 2.x.x contains many changes from 1.x.x to provide better User Interface and tons of new features to your sliders. We will auto-backup and migrate your data from 1.x.x to latest version. The backup file will be put in folder <strong>/tmp</strong>. You should revise all your sliders after this update.</p>';
$html .= '<p><input type="checkbox" id="JSNESNYesInstallationCheckBox" value="yes" style="margin: 0 5px;"><label for="JSNESNYesInstallationCheckBox" style="display: inline-block;"><strong>I have clearly understand this message and want to update.</strong>
</label></p>';
$html .= '<a href="' . JRoute::_('index.php?option=com_easyslider') . '" class="btn" id="JSNESNNOInstallationBtn">No</a> ';
$html .= '<button type="button" class="btn btn-primary" id="JSNESNYesInstallationBtn" disabled="disabled">Yes</button>';
//$document = JFactory::getDocument();
$html .= '<script type="text/javascript">
try
{
jQuery(document).ready(function ($) {
jQuery("#JSNESNYesInstallationCheckBox").on("click", function(){
if(jQuery(this).is(":checked"))
{
jQuery("#JSNESNYesInstallationBtn").prop("disabled", false);
}
else
{
jQuery("#JSNESNYesInstallationBtn").prop("disabled", true);
}
});
jQuery("#JSNESNYesInstallationBtn").on("click", function(){
jQuery("#loading").css("display", "block");
var form = document.getElementById("JSNESAdminForm");
form.submit();
});
});
}catch(e){
}</script>';
$app = JFactory::getApplication();
//Check if user update and upgrade via EasySlider
if (strpos(@ $_SERVER['HTTP_REFERER'], '?option=' . $app->input->getCmd('option')) !== false
&& (strpos(@ $_SERVER['HTTP_REFERER'], '&view=update') !== false || strpos(@ $_SERVER['HTTP_REFERER'], '&view=upgrade') !== false))
{
echo $html;
exit();
}
$app->redirect('index.php?option=com_installer&view=install', $html, 'error');
return false;
}
/**
* Get EasySlider information
*
* @return object
*/
protected function getExtInfo()
{
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__extensions');
$query->where($db->quoteName('element') . '=' . $db->quote('com_easyslider'));
$query->where($db->quoteName('type') . '=' . $db->quote('component'));
$db->setQuery($query);
$result = $db->loadObject();
return $result;
}
/**
* Backup selected database tables
*
* @param object $info Manifest information.
*
* @return boolean
*/
protected function backup($info)
{
jimport('joomla.filesystem.file');
// Get Joomla config and version object
$config = JFactory::getConfig();
$name = 'jsn_easyslider_data_version_1.x.x_' . date('YmdHis');
$name = array(
'zip' => "{$name}.zip",
'xml' => "jsn_easyslider_backup_db.xml"
);
$this->jsnesdata = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><backup></backup>');
$this->jsnesdata->addAttribute('extension-name', 'JSN EasySlider');
$this->jsnesdata->addAttribute('extension-version', $info->version);
$this->jsnesdata->addAttribute('joomla-version', '3.0.0');
// Backup data from selected tables
$this->backupTables();
//Do any extra work needed after doing real data backup
$result = $this->afterBackup($name);
if (!$result) return false;
if (isset($this->zippedBackup))
{
// Store zipped backup to file system
$rwriteFile = JFile::write($config->get('tmp_path') . '/' . $name['zip'], $this->zippedBackup);
if (!$rwriteFile)
{
return false;
}
else
{
$session = JFactory::getSession();
$session->set('JSN_EASYSLIDER_BACKUP_OLD_DATA_PATH', $config->get('tmp_path') . '/' . $name['zip']);
return true;
}
}
return false;
}
/**
* Backup data from selected database tables.
*
* @return void
*/
protected function backupTables()
{
$tables = array('#__jsn_easyslider_config', '#__jsn_easyslider_messages', '#__jsn_easyslider_sliders');
// Create parent node for storing dumped data
$this->jsnesdata->addChild('tables');
// Get database object
$db = JFactory::getDbo();
foreach ($tables AS $table)
{
$query = $db->getQuery(true);
$query->select('*');
$query->from($table);
$db->setQuery($query);
if ($rows = $db->loadAssocList())
{
$this->storeTableData($table, $rows);
}
}
}
/**
* Store backed up table data to XML object.
*
* @param array $table Name of data table.
* @param array $rows Dumped data from the table.
*
* @return void
*/
protected function storeTableData($table, $rows)
{
// Create new node for storing backed up table data
$node = $this->jsnesdata->tables->addChild('table');
$node->addAttribute('name', $table);
// Store backed up table data to table node
$node = $node->addChild('rows');
foreach ($rows AS $row)
{
// Create new node for storing current row of data
$rowNode = $node->addChild('row');
foreach ($row AS $name => $value)
{
$rowNode->addChild($name, htmlspecialchars($value, ENT_QUOTES, 'UTF-8', false));
}
}
}
/**
* Do any extra work needed after doing real data backup.
*
* @param array &$options Backup options.
* @param array &$name array('zip' => 'zip_backup_file_name', 'xml' => 'xml_backup_file_name')
*
* @return void
*/
protected function afterBackup($name)
{
// Create zip file containing all backed up data and/or files
return $this->finalizeBackup($name);
}
/**
* Create downloadable zip-archived backup file.
*
* @param array $name array('zip' => 'zip_backup_file_name', 'xml' => 'xml_backup_file_name')
*
* @return void
*/
protected function finalizeBackup($name)
{
// Get XML data from XML object
if (($data = $this->jsnesdata->asXML()) === false)
{
return false;
}
if (!class_exists('JSNUtilsArchive'))
{
if (file_exists(JPATH_ROOT . '/plugins/system/jsnframework/libraries/joomlashine/utils/archive.php'))
{
require_once JPATH_ROOT . '/plugins/system/jsnframework/libraries/joomlashine/utils/archive.php';
}
else
{
return false;
}
}
// Prepend XML file to the array of backed up files
//array_unshift($this->files, array($name['xml'] => $data));
$file = array(array($name['xml'] => $data));
// Create zip file containing all backed up data and/or files
try
{
if (!($this->zippedBackup = JSNUtilsArchive::createZip($file)))
{
return false;
}
}
catch (Exception $e)
{
return false;
}
return true;
}
/**
* Remove redundant files when update.
*
* @return void
*/
protected function removeRedundantFiles()
{
jimport('joomla.filesystem.folder');
jimport('joomla.filesystem.file');
$folders = array();
$folders [JPATH_ROOT . '/administrator/components/'] = JPATH_ROOT . '/administrator/components/com_easyslider';
$folders [JPATH_ROOT . '/modules/'] = JPATH_ROOT . '/modules/mod_easyslider';
$folders [JPATH_ROOT . '/plugins/content/'] = JPATH_ROOT . '/plugins/content/jsneasyslider';
$folders [JPATH_ROOT . '/plugins/editors-xtd/'] = JPATH_ROOT . '/plugins/editors-xtd/jsneasyslider';
$folders [JPATH_ROOT . '/plugins/system/'] = JPATH_ROOT . '/plugins/system/easyslider';
foreach ($folders as $key => $folder)
{
$rootPath = $key;
if (file_exists($folder))
{
$fileList = JFolder::files($folder, '.', false, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'easyslider.xml', 'mod_easyslider.xml', 'jsneasyslider.xml'));
$subFolderList = JFolder::folders($folder);
if (count($fileList))
{
foreach($fileList as $file)
{
$tmpFile = $folder . '/' . $file;
if (file_exists($tmpFile) && strpos($tmpFile, 'easyslider') !== false)
{
try
{
JFile::delete($tmpFile);
}
catch (Exception $e)
{
// do nothing
}
}
}
}
if (count($subFolderList))
{
foreach($subFolderList as $subFolder)
{
$tmpFolder = $folder . '/' . $subFolder;
if (file_exists($tmpFolder) && is_writable($tmpFolder) && strpos($tmpFolder, 'easyslider') !== false)
{
try
{
JFolder::delete($tmpFolder);
}
catch (Exception $e)
{
// do nothing
}
}
}
}
}
}
}
}