Done !
| Server IP : 46.105.57.169 / Your IP : 216.73.216.67 Web Server : Apache System : Linux webm002.cluster120.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64 User : verseaumee ( 152031) PHP Version : 8.5.7 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/verseaumee/123click/assets/ |
Upload File : |
PK ! [�lz� � installscript/installscript.phpnu &1i� <?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
* @note This file has been modified by the Joomla! Project and no longer reflects the original work of its author.
*/
defined('FOF_INCLUDED') or die;
JLoader::import('joomla.filesystem.folder');
JLoader::import('joomla.filesystem.file');
JLoader::import('joomla.installer.installer');
JLoader::import('joomla.utilities.date');
/**
* A helper class which you can use to create component installation scripts
*/
abstract class FOFUtilsInstallscript
{
/**
* The component's name
*
* @var string
*/
protected $componentName = 'com_foobar';
/**
* The title of the component (printed on installation and uninstallation messages)
*
* @var string
*/
protected $componentTitle = 'Foobar Component';
/**
* The list of extra modules and plugins to install on component installation / update and remove on component
* uninstallation.
*
* @var array
*/
protected $installation_queue = array(
// modules => { (folder) => { (module) => { (position), (published) } }* }*
'modules' => array(
'admin' => array(),
'site' => array()
),
// plugins => { (folder) => { (element) => (published) }* }*
'plugins' => array(
'system' => array(),
)
);
/**
* The list of obsolete extra modules and plugins to uninstall on component upgrade / installation.
*
* @var array
*/
protected $uninstallation_queue = array(
// modules => { (folder) => { (module) }* }*
'modules' => array(
'admin' => array(),
'site' => array()
),
// plugins => { (folder) => { (element) }* }*
'plugins' => array(
'system' => array(),
)
);
/**
* Obsolete files and folders to remove from the free version only. This is used when you move a feature from the
* free version of your extension to its paid version. If you don't have such a distinction you can ignore this.
*
* @var array
*/
protected $removeFilesFree = array(
'files' => array(
// Use pathnames relative to your site's root, e.g.
// 'administrator/components/com_foobar/helpers/whatever.php'
),
'folders' => array(
// Use pathnames relative to your site's root, e.g.
// 'administrator/components/com_foobar/baz'
)
);
/**
* Obsolete files and folders to remove from both paid and free releases. This is used when you refactor code and
* some files inevitably become obsolete and need to be removed.
*
* @var array
*/
protected $removeFilesAllVersions = array(
'files' => array(
// Use pathnames relative to your site's root, e.g.
// 'administrator/components/com_foobar/helpers/whatever.php'
),
'folders' => array(
// Use pathnames relative to your site's root, e.g.
// 'administrator/components/com_foobar/baz'
)
);
/**
* A list of scripts to be copied to the "cli" directory of the site
*
* @var array
*/
protected $cliScriptFiles = array(
// Use just the filename, e.g.
// 'my-cron-script.php'
);
/**
* The path inside your package where cli scripts are stored
*
* @var string
*/
protected $cliSourcePath = 'cli';
/**
* The path inside your package where FOF is stored
*
* @var string
*/
protected $fofSourcePath = 'fof';
/**
* The path inside your package where Akeeba Strapper is stored
*
* @var string
*/
protected $strapperSourcePath = 'strapper';
/**
* The path inside your package where extra modules are stored
*
* @var string
*/
protected $modulesSourcePath = 'modules';
/**
* The path inside your package where extra plugins are stored
*
* @var string
*/
protected $pluginsSourcePath = 'plugins';
/**
* Is the schemaXmlPath class variable a relative path? If set to true the schemaXmlPath variable contains a path
* relative to the component's back-end directory. If set to false the schemaXmlPath variable contains an absolute
* filesystem path.
*
* @var boolean
*/
protected $schemaXmlPathRelative = true;
/**
* The path where the schema XML files are stored. Its contents depend on the schemaXmlPathRelative variable above
* true => schemaXmlPath contains a path relative to the component's back-end directory
* false => schemaXmlPath contains an absolute filesystem path
*
* @var string
*/
protected $schemaXmlPath = 'sql/xml';
/**
* The minimum PHP version required to install this extension
*
* @var string
*/
protected $minimumPHPVersion = '5.3.3';
/**
* The minimum Joomla! version required to install this extension
*
* @var string
*/
protected $minimumJoomlaVersion = '2.5.6';
/**
* The maximum Joomla! version this extension can be installed on
*
* @var string
*/
protected $maximumJoomlaVersion = '3.9.99';
/**
* Is this the paid version of the extension? This only determines which files / extensions will be removed.
*
* @var boolean
*/
protected $isPaid = false;
/**
* Post-installation message definitions for Joomla! 3.2 or later.
*
* This array contains the message definitions for the Post-installation Messages component added in Joomla! 3.2 and
* later versions. Each element is also a hashed array. For the keys used in these message definitions please
* @see FOFUtilsInstallscript::addPostInstallationMessage
*
* @var array
*/
protected $postInstallationMessages = array();
/**
* Joomla! pre-flight event. This runs before Joomla! installs or updates the component. This is our last chance to
* tell Joomla! if it should abort the installation.
*
* @param string $type Installation type (install, update, discover_install)
* @param JInstaller $parent Parent object
*
* @return boolean True to let the installation proceed, false to halt the installation
*/
public function preflight($type, $parent)
{
// Check the minimum PHP version
if (!empty($this->minimumPHPVersion))
{
if (defined('PHP_VERSION'))
{
$version = PHP_VERSION;
}
elseif (function_exists('phpversion'))
{
$version = phpversion();
}
else
{
$version = '5.0.0'; // all bets are off!
}
if (!version_compare($version, $this->minimumPHPVersion, 'ge'))
{
$msg = "<p>You need PHP $this->minimumPHPVersion or later to install this component</p>";
if (version_compare(JVERSION, '3.0', 'gt'))
{
JLog::add($msg, JLog::WARNING, 'jerror');
}
else
{
JError::raiseWarning(100, $msg);
}
return false;
}
}
// Check the minimum Joomla! version
if (!empty($this->minimumJoomlaVersion) && !version_compare(JVERSION, $this->minimumJoomlaVersion, 'ge'))
{
$msg = "<p>You need Joomla! $this->minimumJoomlaVersion or later to install this component</p>";
if (version_compare(JVERSION, '3.0', 'gt'))
{
JLog::add($msg, JLog::WARNING, 'jerror');
}
else
{
JError::raiseWarning(100, $msg);
}
return false;
}
// Check the maximum Joomla! version
if (!empty($this->maximumJoomlaVersion) && !version_compare(JVERSION, $this->maximumJoomlaVersion, 'le'))
{
$msg = "<p>You need Joomla! $this->maximumJoomlaVersion or earlier to install this component</p>";
if (version_compare(JVERSION, '3.0', 'gt'))
{
JLog::add($msg, JLog::WARNING, 'jerror');
}
else
{
JError::raiseWarning(100, $msg);
}
return false;
}
// Always reset the OPcache if it's enabled. Otherwise there's a good chance the server will not know we are
// replacing .php scripts. This is a major concern since PHP 5.5 included and enabled OPcache by default.
if (function_exists('opcache_reset'))
{
opcache_reset();
}
// Workarounds for JInstaller issues
if (in_array($type, array('install', 'discover_install')))
{
// Bugfix for "Database function returned no error"
$this->bugfixDBFunctionReturnedNoError();
}
else
{
// Bugfix for "Can not build admin menus"
$this->bugfixCantBuildAdminMenus();
}
return true;
}
/**
* Runs after install, update or discover_update. In other words, it executes after Joomla! has finished installing
* or updating your component. This is the last chance you've got to perform any additional installations, clean-up,
* database updates and similar housekeeping functions.
*
* @param string $type install, update or discover_update
* @param JInstaller $parent Parent object
*/
public function postflight($type, $parent)
{
// Install or update database
$dbInstaller = new FOFDatabaseInstaller(array(
'dbinstaller_directory' =>
($this->schemaXmlPathRelative ? JPATH_ADMINISTRATOR . '/components/' . $this->componentName : '') . '/' .
$this->schemaXmlPath
));
$dbInstaller->updateSchema();
// Install subextensions
$status = $this->installSubextensions($parent);
// Install FOF
$fofInstallationStatus = $this->installFOF($parent);
// Install Akeeba Straper
$strapperInstallationStatus = $this->installStrapper($parent);
// Make sure menu items are installed
$this->_createAdminMenus($parent);
// Make sure menu items are published (surprise goal in the 92' by JInstaller wins the cup for "most screwed up
// bug in the history of Joomla!")
$this->_reallyPublishAdminMenuItems($parent);
// Which files should I remove?
if ($this->isPaid)
{
// This is the paid version, only remove the removeFilesAllVersions files
$removeFiles = $this->removeFilesAllVersions;
}
else
{
// This is the free version, remove the removeFilesAllVersions and removeFilesFree files
$removeFiles = array('files' => array(), 'folders' => array());
if (isset($this->removeFilesAllVersions['files']))
{
if (isset($this->removeFilesFree['files']))
{
$removeFiles['files'] = array_merge($this->removeFilesAllVersions['files'], $this->removeFilesFree['files']);
}
else
{
$removeFiles['files'] = $this->removeFilesAllVersions['files'];
}
}
elseif (isset($this->removeFilesFree['files']))
{
$removeFiles['files'] = $this->removeFilesFree['files'];
}
if (isset($this->removeFilesAllVersions['folders']))
{
if (isset($this->removeFilesFree['folders']))
{
$removeFiles['folders'] = array_merge($this->removeFilesAllVersions['folders'], $this->removeFilesFree['folders']);
}
else
{
$removeFiles['folders'] = $this->removeFilesAllVersions['folders'];
}
}
elseif (isset($this->removeFilesFree['folders']))
{
$removeFiles['folders'] = $this->removeFilesFree['folders'];
}
}
// Remove obsolete files and folders
$this->removeFilesAndFolders($removeFiles);
// Copy the CLI files (if any)
$this->copyCliFiles($parent);
// Show the post-installation page
$this->renderPostInstallation($status, $fofInstallationStatus, $strapperInstallationStatus, $parent);
// Uninstall obsolete subextensions
$uninstall_status = $this->uninstallObsoleteSubextensions($parent);
// Clear the FOF cache
$platform = FOFPlatform::getInstance();
if (method_exists($platform, 'clearCache'))
{
FOFPlatform::getInstance()->clearCache();
}
// Make sure the Joomla! menu structure is correct
$this->_rebuildMenu();
// Add post-installation messages on Joomla! 3.2 and later
$this->_applyPostInstallationMessages();
}
/**
* Runs on uninstallation
*
* @param JInstaller $parent The parent object
*/
public function uninstall($parent)
{
// Uninstall database
$dbInstaller = new FOFDatabaseInstaller(array(
'dbinstaller_directory' =>
($this->schemaXmlPathRelative ? JPATH_ADMINISTRATOR . '/components/' . $this->componentName : '') . '/' .
$this->schemaXmlPath
));
$dbInstaller->removeSchema();
// Uninstall modules and plugins
$status = $this->uninstallSubextensions($parent);
// Uninstall post-installation messages on Joomla! 3.2 and later
$this->uninstallPostInstallationMessages();
// Show the post-uninstallation page
$this->renderPostUninstallation($status, $parent);
}
/**
* Copies the CLI scripts into Joomla!'s cli directory
*
* @param JInstaller $parent
*/
protected function copyCliFiles($parent)
{
$src = $parent->getParent()->getPath('source');
$cliPath = JPATH_ROOT . '/cli';
if (!JFolder::exists($cliPath))
{
JFolder::create($cliPath);
}
foreach ($this->cliScriptFiles as $script)
{
if (JFile::exists($cliPath . '/' . $script))
{
JFile::delete($cliPath . '/' . $script);
}
if (JFile::exists($src . '/' . $this->cliSourcePath . '/' . $script))
{
JFile::copy($src . '/' . $this->cliSourcePath . '/' . $script, $cliPath . '/' . $script);
}
}
}
/**
* Renders the message after installing or upgrading the component
*/
protected function renderPostInstallation($status, $fofInstallationStatus, $strapperInstallationStatus, $parent)
{
$rows = 0;
?>
<table class="adminlist table table-striped" width="100%">
<thead>
<tr>
<th class="title" colspan="2">Extension</th>
<th width="30%">Status</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"></td>
</tr>
</tfoot>
<tbody>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key" colspan="2"><?php echo $this->componentTitle ?></td>
<td><strong style="color: green">Installed</strong></td>
</tr>
<?php if ($fofInstallationStatus['required']): ?>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key" colspan="2">
<strong>Framework on Framework (FOF) <?php echo $fofInstallationStatus['version'] ?></strong>
[<?php echo $fofInstallationStatus['date'] ?>]
</td>
<td><strong>
<span
style="color: <?php echo $fofInstallationStatus['required'] ? ($fofInstallationStatus['installed'] ? 'green' : 'red') : '#660' ?>; font-weight: bold;">
<?php echo $fofInstallationStatus['required'] ? ($fofInstallationStatus['installed'] ? 'Installed' : 'Not Installed') : 'Already up-to-date'; ?>
</span>
</strong></td>
</tr>
<?php endif; ?>
<?php if ($strapperInstallationStatus['required']): ?>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key" colspan="2">
<strong>Akeeba Strapper <?php echo $strapperInstallationStatus['version'] ?></strong>
[<?php echo $strapperInstallationStatus['date'] ?>]
</td>
<td><strong>
<span
style="color: <?php echo $strapperInstallationStatus['required'] ? ($strapperInstallationStatus['installed'] ? 'green' : 'red') : '#660' ?>; font-weight: bold;">
<?php echo $strapperInstallationStatus['required'] ? ($strapperInstallationStatus['installed'] ? 'Installed' : 'Not Installed') : 'Already up-to-date'; ?>
</span>
</strong></td>
</tr>
<?php endif; ?>
<?php if (count($status->modules)) : ?>
<tr>
<th>Module</th>
<th>Client</th>
<th></th>
</tr>
<?php foreach ($status->modules as $module) : ?>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key"><?php echo $module['name']; ?></td>
<td class="key"><?php echo ucfirst($module['client']); ?></td>
<td><strong
style="color: <?php echo ($module['result']) ? "green" : "red" ?>"><?php echo ($module['result']) ? 'Installed' : 'Not installed'; ?></strong>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php if (count($status->plugins)) : ?>
<tr>
<th>Plugin</th>
<th>Group</th>
<th></th>
</tr>
<?php foreach ($status->plugins as $plugin) : ?>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key"><?php echo ucfirst($plugin['name']); ?></td>
<td class="key"><?php echo ucfirst($plugin['group']); ?></td>
<td><strong
style="color: <?php echo ($plugin['result']) ? "green" : "red" ?>"><?php echo ($plugin['result']) ? 'Installed' : 'Not installed'; ?></strong>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php
}
/**
* Renders the message after uninstalling the component
*/
protected function renderPostUninstallation($status, $parent)
{
$rows = 1;
?>
<table class="adminlist table table-striped" width="100%">
<thead>
<tr>
<th class="title" colspan="2"><?php echo JText::_('Extension'); ?></th>
<th width="30%"><?php echo JText::_('Status'); ?></th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"></td>
</tr>
</tfoot>
<tbody>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key" colspan="2"><?php echo $this->componentTitle; ?></td>
<td><strong style="color: green">Removed</strong></td>
</tr>
<?php if (count($status->modules)) : ?>
<tr>
<th>Module</th>
<th>Client</th>
<th></th>
</tr>
<?php foreach ($status->modules as $module) : ?>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key"><?php echo $module['name']; ?></td>
<td class="key"><?php echo ucfirst($module['client']); ?></td>
<td><strong
style="color: <?php echo ($module['result']) ? "green" : "red" ?>"><?php echo ($module['result']) ? 'Removed' : 'Not removed'; ?></strong>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php if (count($status->plugins)) : ?>
<tr>
<th>Plugin</th>
<th>Group</th>
<th></th>
</tr>
<?php foreach ($status->plugins as $plugin) : ?>
<tr class="row<?php echo($rows++ % 2); ?>">
<td class="key"><?php echo ucfirst($plugin['name']); ?></td>
<td class="key"><?php echo ucfirst($plugin['group']); ?></td>
<td><strong
style="color: <?php echo ($plugin['result']) ? "green" : "red" ?>"><?php echo ($plugin['result']) ? 'Removed' : 'Not removed'; ?></strong>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php
}
/**
* Bugfix for "DB function returned no error"
*/
protected function bugfixDBFunctionReturnedNoError()
{
$db = FOFPlatform::getInstance()->getDbo();
// Fix broken #__assets records
$query = $db->getQuery(true);
$query->select('id')
->from('#__assets')
->where($db->qn('name') . ' = ' . $db->q($this->componentName));
$db->setQuery($query);
try
{
$ids = $db->loadColumn();
}
catch (Exception $exc)
{
return;
}
if (!empty($ids))
{
foreach ($ids as $id)
{
$query = $db->getQuery(true);
$query->delete('#__assets')
->where($db->qn('id') . ' = ' . $db->q($id));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
}
// Fix broken #__extensions records
$query = $db->getQuery(true);
$query->select('extension_id')
->from('#__extensions')
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('element') . ' = ' . $db->q($this->componentName));
$db->setQuery($query);
$ids = $db->loadColumn();
if (!empty($ids))
{
foreach ($ids as $id)
{
$query = $db->getQuery(true);
$query->delete('#__extensions')
->where($db->qn('extension_id') . ' = ' . $db->q($id));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
}
// Fix broken #__menu records
$query = $db->getQuery(true);
$query->select('id')
->from('#__menu')
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('menutype') . ' = ' . $db->q('main'))
->where($db->qn('link') . ' LIKE ' . $db->q('index.php?option=' . $this->componentName));
$db->setQuery($query);
$ids = $db->loadColumn();
if (!empty($ids))
{
foreach ($ids as $id)
{
$query = $db->getQuery(true);
$query->delete('#__menu')
->where($db->qn('id') . ' = ' . $db->q($id));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
}
}
/**
* Joomla! 1.6+ bugfix for "Can not build admin menus"
*/
protected function bugfixCantBuildAdminMenus()
{
$db = FOFPlatform::getInstance()->getDbo();
// If there are multiple #__extensions record, keep one of them
$query = $db->getQuery(true);
$query->select('extension_id')
->from('#__extensions')
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('element') . ' = ' . $db->q($this->componentName));
$db->setQuery($query);
try
{
$ids = $db->loadColumn();
}
catch (Exception $exc)
{
return;
}
if (count($ids) > 1)
{
asort($ids);
$extension_id = array_shift($ids); // Keep the oldest id
foreach ($ids as $id)
{
$query = $db->getQuery(true);
$query->delete('#__extensions')
->where($db->qn('extension_id') . ' = ' . $db->q($id));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
}
// If there are multiple assets records, delete all except the oldest one
$query = $db->getQuery(true);
$query->select('id')
->from('#__assets')
->where($db->qn('name') . ' = ' . $db->q($this->componentName));
$db->setQuery($query);
$ids = $db->loadObjectList();
if (count($ids) > 1)
{
asort($ids);
$asset_id = array_shift($ids); // Keep the oldest id
foreach ($ids as $id)
{
$query = $db->getQuery(true);
$query->delete('#__assets')
->where($db->qn('id') . ' = ' . $db->q($id));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
}
// Remove #__menu records for good measure! –– I think this is not necessary and causes the menu item to
// disappear on extension update.
/**
$query = $db->getQuery(true);
$query->select('id')
->from('#__menu')
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('menutype') . ' = ' . $db->q('main'))
->where($db->qn('link') . ' LIKE ' . $db->q('index.php?option=' . $this->componentName));
$db->setQuery($query);
try
{
$ids1 = $db->loadColumn();
}
catch (Exception $exc)
{
$ids1 = array();
}
if (empty($ids1))
{
$ids1 = array();
}
$query = $db->getQuery(true);
$query->select('id')
->from('#__menu')
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('menutype') . ' = ' . $db->q('main'))
->where($db->qn('link') . ' LIKE ' . $db->q('index.php?option=' . $this->componentName . '&%'));
$db->setQuery($query);
try
{
$ids2 = $db->loadColumn();
}
catch (Exception $exc)
{
$ids2 = array();
}
if (empty($ids2))
{
$ids2 = array();
}
$ids = array_merge($ids1, $ids2);
if (!empty($ids))
{
foreach ($ids as $id)
{
$query = $db->getQuery(true);
$query->delete('#__menu')
->where($db->qn('id') . ' = ' . $db->q($id));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
}
/**/
}
/**
* Installs subextensions (modules, plugins) bundled with the main extension
*
* @param JInstaller $parent
*
* @return JObject The subextension installation status
*/
protected function installSubextensions($parent)
{
$src = $parent->getParent()->getPath('source');
$db = FOFPlatform::getInstance()->getDbo();;
$status = new JObject();
$status->modules = array();
$status->plugins = array();
// Modules installation
if (isset($this->installation_queue['modules']) && count($this->installation_queue['modules']))
{
foreach ($this->installation_queue['modules'] as $folder => $modules)
{
if (count($modules))
{
foreach ($modules as $module => $modulePreferences)
{
// Install the module
if (empty($folder))
{
$folder = 'site';
}
$path = "$src/" . $this->modulesSourcePath . "/$folder/$module";
if (!is_dir($path))
{
$path = "$src/" . $this->modulesSourcePath . "/$folder/mod_$module";
}
if (!is_dir($path))
{
$path = "$src/" . $this->modulesSourcePath . "/$module";
}
if (!is_dir($path))
{
$path = "$src/" . $this->modulesSourcePath . "/mod_$module";
}
if (!is_dir($path))
{
continue;
}
// Was the module already installed?
$sql = $db->getQuery(true)
->select('COUNT(*)')
->from('#__modules')
->where($db->qn('module') . ' = ' . $db->q('mod_' . $module));
$db->setQuery($sql);
try
{
$count = $db->loadResult();
}
catch (Exception $exc)
{
$count = 0;
}
$installer = new JInstaller;
$result = $installer->install($path);
$status->modules[] = array(
'name' => 'mod_' . $module,
'client' => $folder,
'result' => $result
);
// Modify where it's published and its published state
if (!$count)
{
// A. Position and state
list($modulePosition, $modulePublished) = $modulePreferences;
$sql = $db->getQuery(true)
->update($db->qn('#__modules'))
->set($db->qn('position') . ' = ' . $db->q($modulePosition))
->where($db->qn('module') . ' = ' . $db->q('mod_' . $module));
if ($modulePublished)
{
$sql->set($db->qn('published') . ' = ' . $db->q('1'));
}
$db->setQuery($sql);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
// B. Change the ordering of back-end modules to 1 + max ordering
if ($folder == 'admin')
{
try
{
$query = $db->getQuery(true);
$query->select('MAX(' . $db->qn('ordering') . ')')
->from($db->qn('#__modules'))
->where($db->qn('position') . '=' . $db->q($modulePosition));
$db->setQuery($query);
$position = $db->loadResult();
$position++;
$query = $db->getQuery(true);
$query->update($db->qn('#__modules'))
->set($db->qn('ordering') . ' = ' . $db->q($position))
->where($db->qn('module') . ' = ' . $db->q('mod_' . $module));
$db->setQuery($query);
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
// C. Link to all pages
try
{
$query = $db->getQuery(true);
$query->select('id')->from($db->qn('#__modules'))
->where($db->qn('module') . ' = ' . $db->q('mod_' . $module));
$db->setQuery($query);
$moduleid = $db->loadResult();
$query = $db->getQuery(true);
$query->select('*')->from($db->qn('#__modules_menu'))
->where($db->qn('moduleid') . ' = ' . $db->q($moduleid));
$db->setQuery($query);
$assignments = $db->loadObjectList();
$isAssigned = !empty($assignments);
if (!$isAssigned)
{
$o = (object)array(
'moduleid' => $moduleid,
'menuid' => 0
);
$db->insertObject('#__modules_menu', $o);
}
}
catch (Exception $exc)
{
// Nothing
}
}
}
}
}
}
// Plugins installation
if (isset($this->installation_queue['plugins']) && count($this->installation_queue['plugins']))
{
foreach ($this->installation_queue['plugins'] as $folder => $plugins)
{
if (count($plugins))
{
foreach ($plugins as $plugin => $published)
{
$path = "$src/" . $this->pluginsSourcePath . "/$folder/$plugin";
if (!is_dir($path))
{
$path = "$src/" . $this->pluginsSourcePath . "/$folder/plg_$plugin";
}
if (!is_dir($path))
{
$path = "$src/" . $this->pluginsSourcePath . "/$plugin";
}
if (!is_dir($path))
{
$path = "$src/" . $this->pluginsSourcePath . "/plg_$plugin";
}
if (!is_dir($path))
{
continue;
}
// Was the plugin already installed?
$query = $db->getQuery(true)
->select('COUNT(*)')
->from($db->qn('#__extensions'))
->where($db->qn('element') . ' = ' . $db->q($plugin))
->where($db->qn('folder') . ' = ' . $db->q($folder));
$db->setQuery($query);
try
{
$count = $db->loadResult();
}
catch (Exception $exc)
{
$count = 0;
}
$installer = new JInstaller;
$result = $installer->install($path);
$status->plugins[] = array('name' => 'plg_' . $plugin, 'group' => $folder, 'result' => $result);
if ($published && !$count)
{
$query = $db->getQuery(true)
->update($db->qn('#__extensions'))
->set($db->qn('enabled') . ' = ' . $db->q('1'))
->where($db->qn('element') . ' = ' . $db->q($plugin))
->where($db->qn('folder') . ' = ' . $db->q($folder));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $exc)
{
// Nothing
}
}
}
}
}
}
// Clear com_modules and com_plugins cache (needed when we alter module/plugin state)
FOFUtilsCacheCleaner::clearPluginsAndModulesCache();
return $status;
}
/**
* Uninstalls subextensions (modules, plugins) bundled with the main extension
*
* @param JInstaller $parent The parent object
*
* @return stdClass The subextension uninstallation status
*/
protected function uninstallSubextensions($parent)
{
$db = FOFPlatform::getInstance()->getDbo();
$status = new stdClass();
$status->modules = array();
$status->plugins = array();
$src = $parent->getParent()->getPath('source');
// Modules uninstallation
if (isset($this->installation_queue['modules']) && count($this->installation_queue['modules']))
{
foreach ($this->installation_queue['modules'] as $folder => $modules)
{
if (count($modules))
{
foreach ($modules as $module => $modulePreferences)
{
// Find the module ID
$sql = $db->getQuery(true)
->select($db->qn('extension_id'))
->from($db->qn('#__extensions'))
->where($db->qn('element') . ' = ' . $db->q('mod_' . $module))
->where($db->qn('type') . ' = ' . $db->q('module'));
$db->setQuery($sql);
try
{
$id = $db->loadResult();
}
catch (Exception $exc)
{
$id = 0;
}
// Uninstall the module
if ($id)
{
$installer = new JInstaller;
$result = $installer->uninstall('module', $id, 1);
$status->modules[] = array(
'name' => 'mod_' . $module,
'client' => $folder,
'result' => $result
);
}
}
}
}
}
// Plugins uninstallation
if (isset($this->installation_queue['plugins']) && count($this->installation_queue['plugins']))
{
foreach ($this->installation_queue['plugins'] as $folder => $plugins)
{
if (count($plugins))
{
foreach ($plugins as $plugin => $published)
{
$sql = $db->getQuery(true)
->select($db->qn('extension_id'))
->from($db->qn('#__extensions'))
->where($db->qn('type') . ' = ' . $db->q('plugin'))
->where($db->qn('element') . ' = ' . $db->q($plugin))
->where($db->qn('folder') . ' = ' . $db->q($folder));
$db->setQuery($sql);
try
{
$id = $db->loadResult();
}
catch (Exception $exc)
{
$id = 0;
}
if ($id)
{
$installer = new JInstaller;
$result = $installer->uninstall('plugin', $id, 1);
$status->plugins[] = array(
'name' => 'plg_' . $plugin,
'group' => $folder,
'result' => $result
);
}
}
}
}
}
// Clear com_modules and com_plugins cache (needed when we alter module/plugin state)
FOFUtilsCacheCleaner::clearPluginsAndModulesCache();
return $status;
}
/**
* Removes obsolete files and folders
*
* @param array $removeList The files and directories to remove
*/
protected function removeFilesAndFolders($removeList)
{
// Remove files
if (isset($removeList['files']) && !empty($removeList['files']))
{
foreach ($removeList['files'] as $file)
{
$f = JPATH_ROOT . '/' . $file;
if (!JFile::exists($f))
{
continue;
}
JFile::delete($f);
}
}
// Remove folders
if (isset($removeList['folders']) && !empty($removeList['folders']))
{
foreach ($removeList['folders'] as $folder)
{
$f = JPATH_ROOT . '/' . $folder;
if (!JFolder::exists($f))
{
continue;
}
JFolder::delete($f);
}
}
}
/**
* Installs FOF if necessary
*
* @param JInstaller $parent The parent object
*
* @return array The installation status
*/
protected function installFOF($parent)
{
// Get the source path
$src = $parent->getParent()->getPath('source');
$source = $src . '/' . $this->fofSourcePath;
if (!JFolder::exists($source))
{
return array(
'required' => false,
'installed' => false,
'version' => '0.0.0',
'date' => '2011-01-01',
);
}
// Get the target path
if (!defined('JPATH_LIBRARIES'))
{
$target = JPATH_ROOT . '/libraries/f0f';
}
else
{
$target = JPATH_LIBRARIES . '/f0f';
}
// Do I have to install FOF?
$haveToInstallFOF = false;
if (!JFolder::exists($target))
{
// FOF is not installed; install now
$haveToInstallFOF = true;
}
else
{
// FOF is already installed; check the version
$fofVersion = array();
if (JFile::exists($target . '/version.txt'))
{
$rawData = JFile::read($target . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$fofVersion['installed'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
}
else
{
$fofVersion['installed'] = array(
'version' => '0.0',
'date' => new JDate('2011-01-01')
);
}
$rawData = @file_get_contents($source . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$fofVersion['package'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
$haveToInstallFOF = $fofVersion['package']['date']->toUNIX() > $fofVersion['installed']['date']->toUNIX();
}
$installedFOF = false;
if ($haveToInstallFOF)
{
$versionSource = 'package';
$installer = new JInstaller;
$installedFOF = $installer->install($source);
}
else
{
$versionSource = 'installed';
}
if (!isset($fofVersion))
{
$fofVersion = array();
if (JFile::exists($target . '/version.txt'))
{
$rawData = @file_get_contents($source . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$fofVersion['installed'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
}
else
{
$fofVersion['installed'] = array(
'version' => '0.0',
'date' => new JDate('2011-01-01')
);
}
$rawData = @file_get_contents($source . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$fofVersion['package'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
$versionSource = 'installed';
}
if (!($fofVersion[$versionSource]['date'] instanceof JDate))
{
$fofVersion[$versionSource]['date'] = new JDate();
}
return array(
'required' => $haveToInstallFOF,
'installed' => $installedFOF,
'version' => $fofVersion[$versionSource]['version'],
'date' => $fofVersion[$versionSource]['date']->format('Y-m-d'),
);
}
/**
* Installs Akeeba Strapper if necessary
*
* @param JInstaller $parent The parent object
*
* @return array The installation status
*/
protected function installStrapper($parent)
{
$src = $parent->getParent()->getPath('source');
$source = $src . '/' . $this->strapperSourcePath;
$target = JPATH_ROOT . '/media/akeeba_strapper';
if (!JFolder::exists($source))
{
return array(
'required' => false,
'installed' => false,
'version' => '0.0.0',
'date' => '2011-01-01',
);
}
$haveToInstallStrapper = false;
if (!JFolder::exists($target))
{
$haveToInstallStrapper = true;
}
else
{
$strapperVersion = array();
if (JFile::exists($target . '/version.txt'))
{
$rawData = JFile::read($target . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$strapperVersion['installed'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
}
else
{
$strapperVersion['installed'] = array(
'version' => '0.0',
'date' => new JDate('2011-01-01')
);
}
$rawData = JFile::read($source . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$strapperVersion['package'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
$haveToInstallStrapper = $strapperVersion['package']['date']->toUNIX() > $strapperVersion['installed']['date']->toUNIX();
}
$installedStraper = false;
if ($haveToInstallStrapper)
{
$versionSource = 'package';
$installer = new JInstaller;
$installedStraper = $installer->install($source);
}
else
{
$versionSource = 'installed';
}
if (!isset($strapperVersion))
{
$strapperVersion = array();
if (JFile::exists($target . '/version.txt'))
{
$rawData = JFile::read($target . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$strapperVersion['installed'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
}
else
{
$strapperVersion['installed'] = array(
'version' => '0.0',
'date' => new JDate('2011-01-01')
);
}
$rawData = JFile::read($source . '/version.txt');
$rawData = ($rawData === false) ? "0.0.0\n2011-01-01\n" : $rawData;
$info = explode("\n", $rawData);
$strapperVersion['package'] = array(
'version' => trim($info[0]),
'date' => new JDate(trim($info[1]))
);
$versionSource = 'installed';
}
if (!($strapperVersion[$versionSource]['date'] instanceof JDate))
{
$strapperVersion[$versionSource]['date'] = new JDate();
}
return array(
'required' => $haveToInstallStrapper,
'installed' => $installedStraper,
'version' => $strapperVersion[$versionSource]['version'],
'date' => $strapperVersion[$versionSource]['date']->format('Y-m-d'),
);
}
/**
* Uninstalls obsolete subextensions (modules, plugins) bundled with the main extension
*
* @param JInstaller $parent The parent object
*
* @return stdClass The subextension uninstallation status
*/
protected function uninstallObsoleteSubextensions($parent)
{
JLoader::import('joomla.installer.installer');
$db = FOFPlatform::getInstance()->getDbo();
$status = new stdClass();
$status->modules = array();
$status->plugins = array();
$src = $parent->getParent()->getPath('source');
// Modules uninstallation
if (isset($this->uninstallation_queue['modules']) && count($this->uninstallation_queue['modules']))
{
foreach ($this->uninstallation_queue['modules'] as $folder => $modules)
{
if (count($modules))
{
foreach ($modules as $module)
{
// Find the module ID
$sql = $db->getQuery(true)
->select($db->qn('extension_id'))
->from($db->qn('#__extensions'))
->where($db->qn('element') . ' = ' . $db->q('mod_' . $module))
->where($db->qn('type') . ' = ' . $db->q('module'));
$db->setQuery($sql);
$id = $db->loadResult();
// Uninstall the module
if ($id)
{
$installer = new JInstaller;
$result = $installer->uninstall('module', $id, 1);
$status->modules[] = array(
'name' => 'mod_' . $module,
'client' => $folder,
'result' => $result
);
}
}
}
}
}
// Plugins uninstallation
if (isset($this->uninstallation_queue['plugins']) && count($this->uninstallation_queue['plugins']))
{
foreach ($this->uninstallation_queue['plugins'] as $folder => $plugins)
{
if (count($plugins))
{
foreach ($plugins as $plugin)
{
$sql = $db->getQuery(true)
->select($db->qn('extension_id'))
->from($db->qn('#__extensions'))
->where($db->qn('type') . ' = ' . $db->q('plugin'))
->where($db->qn('element') . ' = ' . $db->q($plugin))
->where($db->qn('folder') . ' = ' . $db->q($folder));
$db->setQuery($sql);
$id = $db->loadResult();
if ($id)
{
$installer = new JInstaller;
$result = $installer->uninstall('plugin', $id, 1);
$status->plugins[] = array(
'name' => 'plg_' . $plugin,
'group' => $folder,
'result' => $result
);
}
}
}
}
}
return $status;
}
/**
* @param JInstallerAdapterComponent $parent
*
* @return bool
*
* @throws Exception When the Joomla! menu is FUBAR
*/
private function _createAdminMenus($parent)
{
$db = $db = FOFPlatform::getInstance()->getDbo();
/** @var JTableMenu $table */
$table = JTable::getInstance('menu');
$option = $parent->get('element');
// If a component exists with this option in the table then we don't need to add menus - check only 'main' menutype
$query = $db->getQuery(true)
->select('m.id, e.extension_id')
->from('#__menu AS m')
->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id')
->where('m.parent_id = 1')
->where('m.client_id = 1')
->where('m.menutype = ' . $db->q('main'))
->where($db->qn('e') . '.' . $db->qn('type') . ' = ' . $db->q('component'))
->where('e.element = ' . $db->quote($option));
$db->setQuery($query);
$componentrow = $db->loadObject();
// Check if menu items exist
if ($componentrow)
{
// @todo Return if the menu item already exists to save some time
//return true;
}
// Let's find the extension id
$query->clear()
->select('e.extension_id')
->from('#__extensions AS e')
->where('e.type = ' . $db->quote('component'))
->where('e.element = ' . $db->quote($option));
$db->setQuery($query);
$component_id = $db->loadResult();
// Ok, now its time to handle the menus. Start with the component root menu, then handle submenus.
$menuElement = $parent->get('manifest')->administration->menu;
// We need to insert the menu item as the last child of Joomla!'s menu root node. By default this is the
// menu item with ID=1. However, some crappy upgrade scripts enjoy screwing it up. Hey, ho, the workaround
// way I go.
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('id') . ' = ' . $db->q(1));
$rootItemId = $db->setQuery($query)->loadResult();
if (is_null($rootItemId))
{
// Guess what? The Problem has happened. Let's find the root node by title.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('title') . ' = ' . $db->q('Menu_Item_Root'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// For crying out loud, did that idiot changed the title too?! Let's find it by alias.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('alias') . ' = ' . $db->q('root'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// Dude. Dude! Duuuuuuude! The alias is screwed up, too?! Find it by component ID.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('component_id') . ' = ' . $db->q('0'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// Your site is more of a "shite" than a "site". Let's try with minimum lft value.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->order($db->qn('lft') . ' ASC');
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// I quit. Your site is broken. What the hell are you doing with it? I'll just throw an error.
throw new Exception("Your site is broken. There is no root menu item. As a result it is impossible to create menu items. The installation of this component has failed. Please fix your database and retry!", 500);
}
if ($menuElement)
{
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = (string)trim($menuElement);
$data['alias'] = (string)$menuElement;
$data['link'] = 'index.php?option=' . $option;
$data['type'] = 'component';
$data['published'] = 0;
$data['parent_id'] = 1;
$data['component_id'] = $component_id;
$data['img'] = ((string)$menuElement->attributes()->img) ? (string)$menuElement->attributes()->img : 'class:component';
$data['home'] = 0;
$data['path'] = '';
$data['params'] = '';
}
// No menu element was specified, Let's make a generic menu item
else
{
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = $option;
$data['alias'] = $option;
$data['link'] = 'index.php?option=' . $option;
$data['type'] = 'component';
$data['published'] = 0;
$data['parent_id'] = 1;
$data['component_id'] = $component_id;
$data['img'] = 'class:component';
$data['home'] = 0;
$data['path'] = '';
$data['params'] = '';
}
try
{
$table->setLocation($rootItemId, 'last-child');
}
catch (InvalidArgumentException $e)
{
if (class_exists('JLog'))
{
JLog::add($e->getMessage(), JLog::WARNING, 'jerror');
}
return false;
}
if (!$table->bind($data) || !$table->check() || !$table->store())
{
// The menu item already exists. Delete it and retry instead of throwing an error.
$query->clear()
->select('id')
->from('#__menu')
->where('menutype = ' . $db->quote('main'))
->where('client_id = 1')
->where('link = ' . $db->quote('index.php?option=' . $option))
->where('type = ' . $db->quote('component'))
->where('parent_id = 1')
->where('home = 0');
$db->setQuery($query);
$menu_ids_level1 = $db->loadColumn();
if (empty($menu_ids_level1))
{
// Oops! Could not get the menu ID. Go back and rollback changes.
JError::raiseWarning(1, $table->getError());
return false;
}
else
{
$ids = implode(',', $menu_ids_level1);
$query->clear()
->select('id')
->from('#__menu')
->where('menutype = ' . $db->quote('main'))
->where('client_id = 1')
->where('type = ' . $db->quote('component'))
->where('parent_id in (' . $ids . ')')
->where('level = 2')
->where('home = 0');
$db->setQuery($query);
$menu_ids_level2 = $db->loadColumn();
$ids = implode(',', array_merge($menu_ids_level1, $menu_ids_level2));
// Remove the old menu item
$query->clear()
->delete('#__menu')
->where('id in (' . $ids . ')');
$db->setQuery($query);
$db->query();
// Retry creating the menu item
$table->setLocation($rootItemId, 'last-child');
if (!$table->bind($data) || !$table->check() || !$table->store())
{
// Install failed, warn user and rollback changes
JError::raiseWarning(1, $table->getError());
return false;
}
}
}
/*
* Since we have created a menu item, we add it to the installation step stack
* so that if we have to rollback the changes we can undo it.
*/
$parent->getParent()->pushStep(array('type' => 'menu', 'id' => $component_id));
/*
* Process SubMenus
*/
if (!$parent->get('manifest')->administration->submenu)
{
return true;
}
$parent_id = $table->id;
foreach ($parent->get('manifest')->administration->submenu->menu as $child)
{
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = (string)trim($child);
$data['alias'] = (string)$child;
$data['type'] = 'component';
$data['published'] = 0;
$data['parent_id'] = $parent_id;
$data['component_id'] = $component_id;
$data['img'] = ((string)$child->attributes()->img) ? (string)$child->attributes()->img : 'class:component';
$data['home'] = 0;
// Set the sub menu link
if ((string)$child->attributes()->link)
{
$data['link'] = 'index.php?' . $child->attributes()->link;
}
else
{
$request = array();
if ((string)$child->attributes()->act)
{
$request[] = 'act=' . $child->attributes()->act;
}
if ((string)$child->attributes()->task)
{
$request[] = 'task=' . $child->attributes()->task;
}
if ((string)$child->attributes()->controller)
{
$request[] = 'controller=' . $child->attributes()->controller;
}
if ((string)$child->attributes()->view)
{
$request[] = 'view=' . $child->attributes()->view;
}
if ((string)$child->attributes()->layout)
{
$request[] = 'layout=' . $child->attributes()->layout;
}
if ((string)$child->attributes()->sub)
{
$request[] = 'sub=' . $child->attributes()->sub;
}
$qstring = (count($request)) ? '&' . implode('&', $request) : '';
$data['link'] = 'index.php?option=' . $option . $qstring;
}
$table = JTable::getInstance('menu');
try
{
$table->setLocation($parent_id, 'last-child');
}
catch (InvalidArgumentException $e)
{
return false;
}
if (!$table->bind($data) || !$table->check() || !$table->store())
{
// Install failed, rollback changes
return false;
}
/*
* Since we have created a menu item, we add it to the installation step stack
* so that if we have to rollback the changes we can undo it.
*/
$parent->getParent()->pushStep(array('type' => 'menu', 'id' => $component_id));
}
return true;
}
/**
* Make sure the Component menu items are really published!
*
* @param JInstallerAdapterComponent $parent
*
* @return bool
*/
private function _reallyPublishAdminMenuItems($parent)
{
$db = FOFPlatform::getInstance()->getDbo();
$option = $parent->get('element');
$query = $db->getQuery(true)
->update('#__menu AS m')
->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id')
->set($db->qn('published') . ' = ' . $db->q(1))
->where('m.parent_id = 1')
->where('m.client_id = 1')
->where('m.menutype = ' . $db->quote('main'))
->where('e.type = ' . $db->quote('component'))
->where('e.element = ' . $db->quote($option));
$db->setQuery($query);
try
{
$db->execute();
}
catch (Exception $e)
{
// If it fails, it fails. Who cares.
}
}
/**
* Tells Joomla! to rebuild its menu structure to make triple-sure that the Components menu items really do exist
* in the correct place and can really be rendered.
*/
private function _rebuildMenu()
{
/** @var JTableMenu $table */
$table = JTable::getInstance('menu');
$db = FOFPlatform::getInstance()->getDbo();
// We need to rebuild the menu based on its root item. By default this is the menu item with ID=1. However, some
// crappy upgrade scripts enjoy screwing it up. Hey, ho, the workaround way I go.
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('id') . ' = ' . $db->q(1));
$rootItemId = $db->setQuery($query)->loadResult();
if (is_null($rootItemId))
{
// Guess what? The Problem has happened. Let's find the root node by title.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('title') . ' = ' . $db->q('Menu_Item_Root'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// For crying out loud, did that idiot changed the title too?! Let's find it by alias.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('alias') . ' = ' . $db->q('root'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// Dude. Dude! Duuuuuuude! The alias is screwed up, too?! Find it by component ID.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->where($db->qn('component_id') . ' = ' . $db->q('0'));
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// Your site is more of a "shite" than a "site". Let's try with minimum lft value.
$rootItemId = null;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__menu'))
->order($db->qn('lft') . ' ASC');
$rootItemId = $db->setQuery($query, 0, 1)->loadResult();
}
if (is_null($rootItemId))
{
// I quit. Your site is broken.
return false;
}
$table->rebuild($rootItemId);
}
/**
* Adds or updates a post-installation message (PIM) definition for Joomla! 3.2 or later. You can use this in your
* post-installation script using this code:
*
* The $options array contains the following mandatory keys:
*
* extension_id The numeric ID of the extension this message is for (see the #__extensions table)
*
* type One of message, link or action. Their meaning is:
* message Informative message. The user can dismiss it.
* link The action button links to a URL. The URL is defined in the action parameter.
* action A PHP action takes place when the action button is clicked. You need to specify the
* action_file (RAD path to the PHP file) and action (PHP function name) keys. See
* below for more information.
*
* title_key The JText language key for the title of this PIM
* Example: COM_FOOBAR_POSTINSTALL_MESSAGEONE_TITLE
*
* description_key The JText language key for the main body (description) of this PIM
* Example: COM_FOOBAR_POSTINSTALL_MESSAGEONE_DESCRIPTION
*
* action_key The JText language key for the action button. Ignored and not required when type=message
* Example: COM_FOOBAR_POSTINSTALL_MESSAGEONE_ACTION
*
* language_extension The extension name which holds the language keys used above. For example, com_foobar,
* mod_something, plg_system_whatever, tpl_mytemplate
*
* language_client_id Should we load the front-end (0) or back-end (1) language keys?
*
* version_introduced Which was the version of your extension where this message appeared for the first time?
* Example: 3.2.1
*
* enabled Must be 1 for this message to be enabled. If you omit it, it defaults to 1.
*
* condition_file The RAD path to a PHP file containing a PHP function which determines whether this message
* should be shown to the user. @see FOFTemplateUtils::parsePath() for RAD path format. Joomla!
* will include this file before calling the condition_method.
* Example: admin://components/com_foobar/helpers/postinstall.php
*
* condition_method The name of a PHP function which will be used to determine whether to show this message to
* the user. This must be a simple PHP user function (not a class method, static method etc)
* which returns true to show the message and false to hide it. This function is defined in the
* condition_file.
* Example: com_foobar_postinstall_messageone_condition
*
* When type=message no additional keys are required.
*
* When type=link the following additional keys are required:
*
* action The URL which will open when the user clicks on the PIM's action button
* Example: index.php?option=com_foobar&view=tools&task=installSampleData
*
* Then type=action the following additional keys are required:
*
* action_file The RAD path to a PHP file containing a PHP function which performs the action of this PIM.
*
* @see FOFTemplateUtils::parsePath() for RAD path format. Joomla! will include this file
* before calling the function defined in the action key below.
* Example: admin://components/com_foobar/helpers/postinstall.php
*
* action The name of a PHP function which will be used to run the action of this PIM. This must be a
* simple PHP user function (not a class method, static method etc) which returns no result.
* Example: com_foobar_postinstall_messageone_action
*
* @param array $options See description
*
* @return void
*
* @throws Exception
*/
protected function addPostInstallationMessage(array $options)
{
// Make sure there are options set
if (!is_array($options))
{
throw new Exception('Post-installation message definitions must be of type array', 500);
}
// Initialise array keys
$defaultOptions = array(
'extension_id' => '',
'type' => '',
'title_key' => '',
'description_key' => '',
'action_key' => '',
'language_extension' => '',
'language_client_id' => '',
'action_file' => '',
'action' => '',
'condition_file' => '',
'condition_method' => '',
'version_introduced' => '',
'enabled' => '1',
);
$options = array_merge($defaultOptions, $options);
// Array normalisation. Removes array keys not belonging to a definition.
$defaultKeys = array_keys($defaultOptions);
$allKeys = array_keys($options);
$extraKeys = array_diff($allKeys, $defaultKeys);
if (!empty($extraKeys))
{
foreach ($extraKeys as $key)
{
unset($options[$key]);
}
}
// Normalisation of integer values
$options['extension_id'] = (int)$options['extension_id'];
$options['language_client_id'] = (int)$options['language_client_id'];
$options['enabled'] = (int)$options['enabled'];
// Normalisation of 0/1 values
foreach (array('language_client_id', 'enabled') as $key)
{
$options[$key] = $options[$key] ? 1 : 0;
}
// Make sure there's an extension_id
if (!(int)$options['extension_id'])
{
throw new Exception('Post-installation message definitions need an extension_id', 500);
}
// Make sure there's a valid type
if (!in_array($options['type'], array('message', 'link', 'action')))
{
throw new Exception('Post-installation message definitions need to declare a type of message, link or action', 500);
}
// Make sure there's a title key
if (empty($options['title_key']))
{
throw new Exception('Post-installation message definitions need a title key', 500);
}
// Make sure there's a description key
if (empty($options['description_key']))
{
throw new Exception('Post-installation message definitions need a description key', 500);
}
// If the type is anything other than message you need an action key
if (($options['type'] != 'message') && empty($options['action_key']))
{
throw new Exception('Post-installation message definitions need an action key when they are of type "' . $options['type'] . '"', 500);
}
// You must specify the language extension
if (empty($options['language_extension']))
{
throw new Exception('Post-installation message definitions need to specify which extension contains their language keys', 500);
}
// The action file and method are only required for the "action" type
if ($options['type'] == 'action')
{
if (empty($options['action_file']))
{
throw new Exception('Post-installation message definitions need an action file when they are of type "action"', 500);
}
$file_path = FOFTemplateUtils::parsePath($options['action_file'], true);
if (!@is_file($file_path))
{
throw new Exception('The action file ' . $options['action_file'] . ' of your post-installation message definition does not exist', 500);
}
if (empty($options['action']))
{
throw new Exception('Post-installation message definitions need an action (function name) when they are of type "action"', 500);
}
}
if ($options['type'] == 'link')
{
if (empty($options['link']))
{
throw new Exception('Post-installation message definitions need an action (URL) when they are of type "link"', 500);
}
}
// The condition file and method are only required when the type is not "message"
if ($options['type'] != 'message')
{
if (empty($options['condition_file']))
{
throw new Exception('Post-installation message definitions need a condition file when they are of type "' . $options['type'] . '"', 500);
}
$file_path = FOFTemplateUtils::parsePath($options['condition_file'], true);
if (!@is_file($file_path))
{
throw new Exception('The condition file ' . $options['condition_file'] . ' of your post-installation message definition does not exist', 500);
}
if (empty($options['condition_method']))
{
throw new Exception('Post-installation message definitions need a condition method (function name) when they are of type "' . $options['type'] . '"', 500);
}
}
// Check if the definition exists
$tableName = '#__postinstall_messages';
$db = FOFPlatform::getInstance()->getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn($tableName))
->where($db->qn('extension_id') . ' = ' . $db->q($options['extension_id']))
->where($db->qn('type') . ' = ' . $db->q($options['type']))
->where($db->qn('title_key') . ' = ' . $db->q($options['title_key']));
$existingRow = $db->setQuery($query)->loadAssoc();
// Is the existing definition the same as the one we're trying to save (ignore the enabled flag)?
if (!empty($existingRow))
{
$same = true;
foreach ($options as $k => $v)
{
if ($k == 'enabled')
{
continue;
}
if ($existingRow[$k] != $v)
{
$same = false;
break;
}
}
// Trying to add the same row as the existing one; quit
if ($same)
{
return;
}
// Otherwise it's not the same row. Remove the old row before insert a new one.
$query = $db->getQuery(true)
->delete($db->qn($tableName))
->where($db->q('extension_id') . ' = ' . $db->q($options['extension_id']))
->where($db->q('type') . ' = ' . $db->q($options['type']))
->where($db->q('title_key') . ' = ' . $db->q($options['title_key']));
$db->setQuery($query)->execute();
}
// Insert the new row
$options = (object)$options;
$db->insertObject($tableName, $options);
}
/**
* Applies the post-installation messages for Joomla! 3.2 or later
*
* @return void
*/
protected function _applyPostInstallationMessages()
{
// Make sure it's Joomla! 3.2.0 or later
if (!version_compare(JVERSION, '3.2.0', 'ge'))
{
return;
}
// Make sure there are post-installation messages
if (empty($this->postInstallationMessages))
{
return;
}
// Get the extension ID for our component
$db = FOFPlatform::getInstance()->getDbo();
$query = $db->getQuery(true);
$query->select('extension_id')
->from('#__extensions')
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('element') . ' = ' . $db->q($this->componentName));
$db->setQuery($query);
try
{
$ids = $db->loadColumn();
}
catch (Exception $exc)
{
return;
}
if (empty($ids))
{
return;
}
$extension_id = array_shift($ids);
foreach ($this->postInstallationMessages as $message)
{
$message['extension_id'] = $extension_id;
$this->addPostInstallationMessage($message);
}
}
protected function uninstallPostInstallationMessages()
{
// Make sure it's Joomla! 3.2.0 or later
if (!version_compare(JVERSION, '3.2.0', 'ge'))
{
return;
}
// Make sure there are post-installation messages
if (empty($this->postInstallationMessages))
{
return;
}
// Get the extension ID for our component
$db = FOFPlatform::getInstance()->getDbo();
$query = $db->getQuery(true);
$query->select('extension_id')
->from('#__extensions')
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('element') . ' = ' . $db->q($this->componentName));
$db->setQuery($query);
try
{
$ids = $db->loadColumn();
}
catch (Exception $exc)
{
return;
}
if (empty($ids))
{
return;
}
$extension_id = array_shift($ids);
$query = $db->getQuery(true)
->delete($db->qn('#__postinstall_messages'))
->where($db->qn('extension_id') . ' = ' . $db->q($extension_id));
try
{
$db->setQuery($query)->execute();
}
catch (Exception $e)
{
return;
}
}
}
PK ! T�U�c
c
config/helper.phpnu &1i� <?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('FOF_INCLUDED') or die;
/**
* A utility class to help you fetch component parameters without going through JComponentHelper
*/
class FOFUtilsConfigHelper
{
/**
* Caches the component parameters without going through JComponentHelper. This is necessary since JComponentHelper
* cannot be reset or updated once you update parameters in the database.
*
* @var array
*/
private static $componentParams = array();
/**
* Loads the component's configuration parameters so they can be accessed by getComponentConfigurationValue
*
* @param string $component The component for loading the parameters
* @param bool $force Should I force-reload the configuration information?
*/
public final static function loadComponentConfig($component, $force = false)
{
if (isset(self::$componentParams[$component]) && !is_null(self::$componentParams[$component]) && !$force)
{
return;
}
$db = FOFPlatform::getInstance()->getDbo();
$sql = $db->getQuery(true)
->select($db->qn('params'))
->from($db->qn('#__extensions'))
->where($db->qn('type') . ' = ' . $db->q('component'))
->where($db->qn('element') . " = " . $db->q($component));
$db->setQuery($sql);
$config_ini = $db->loadResult();
// OK, Joomla! 1.6 stores values JSON-encoded so, what do I do? Right!
$config_ini = trim($config_ini);
if ((substr($config_ini, 0, 1) == '{') && substr($config_ini, -1) == '}')
{
$config_ini = json_decode($config_ini, true);
}
else
{
$config_ini = FOFUtilsIniParser::parse_ini_file($config_ini, false, true);
}
if (is_null($config_ini) || empty($config_ini))
{
$config_ini = array();
}
self::$componentParams[$component] = $config_ini;
}
/**
* Retrieves the value of a component configuration parameter without going through JComponentHelper
*
* @param string $component The component for loading the parameter value
* @param string $key The key to retrieve
* @param mixed $default The default value to use in case the key is missing
*
* @return mixed
*/
public final static function getComponentConfigurationValue($component, $key, $default = null)
{
self::loadComponentConfig($component, false);
if (array_key_exists($key, self::$componentParams[$component]))
{
return self::$componentParams[$component][$key];
}
else
{
return $default;
}
}
} PK ! �L�-�1 �1 array/array.phpnu &1i� <?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('FOF_INCLUDED') or die;
/**
* A utility class to handle array manipulation.
*
* Based on the JArrayHelper class as found in Joomla! 3.2.0
*/
abstract class FOFUtilsArray
{
/**
* Option to perform case-sensitive sorts.
*
* @var mixed Boolean or array of booleans.
*/
protected static $sortCase;
/**
* Option to set the sort direction.
*
* @var mixed Integer or array of integers.
*/
protected static $sortDirection;
/**
* Option to set the object key to sort on.
*
* @var string
*/
protected static $sortKey;
/**
* Option to perform a language aware sort.
*
* @var mixed Boolean or array of booleans.
*/
protected static $sortLocale;
/**
* Function to convert array to integer values
*
* @param array &$array The source array to convert
* @param mixed $default A default value (int|array) to assign if $array is not an array
*
* @return void
*/
public static function toInteger(&$array, $default = null)
{
if (is_array($array))
{
foreach ($array as $i => $v)
{
$array[$i] = (int) $v;
}
}
else
{
if ($default === null)
{
$array = array();
}
elseif (is_array($default))
{
self::toInteger($default, null);
$array = $default;
}
else
{
$array = array((int) $default);
}
}
}
/**
* Utility function to map an array to a stdClass object.
*
* @param array &$array The array to map.
* @param string $class Name of the class to create
*
* @return object The object mapped from the given array
*/
public static function toObject(&$array, $class = 'stdClass')
{
$obj = null;
if (is_array($array))
{
$obj = new $class;
foreach ($array as $k => $v)
{
if (is_array($v))
{
$obj->$k = self::toObject($v, $class);
}
else
{
$obj->$k = $v;
}
}
}
return $obj;
}
/**
* Utility function to map an array to a string.
*
* @param array $array The array to map.
* @param string $inner_glue The glue (optional, defaults to '=') between the key and the value.
* @param string $outer_glue The glue (optional, defaults to ' ') between array elements.
* @param boolean $keepOuterKey True if final key should be kept.
*
* @return string The string mapped from the given array
*/
public static function toString($array = null, $inner_glue = '=', $outer_glue = ' ', $keepOuterKey = false)
{
$output = array();
if (is_array($array))
{
foreach ($array as $key => $item)
{
if (is_array($item))
{
if ($keepOuterKey)
{
$output[] = $key;
}
// This is value is an array, go and do it again!
$output[] = self::toString($item, $inner_glue, $outer_glue, $keepOuterKey);
}
else
{
$output[] = $key . $inner_glue . '"' . $item . '"';
}
}
}
return implode($outer_glue, $output);
}
/**
* Utility function to map an object to an array
*
* @param object $p_obj The source object
* @param boolean $recurse True to recurse through multi-level objects
* @param string $regex An optional regular expression to match on field names
*
* @return array The array mapped from the given object
*/
public static function fromObject($p_obj, $recurse = true, $regex = null)
{
if (is_object($p_obj))
{
return self::_fromObject($p_obj, $recurse, $regex);
}
else
{
return null;
}
}
/**
* Utility function to map an object or array to an array
*
* @param mixed $item The source object or array
* @param boolean $recurse True to recurse through multi-level objects
* @param string $regex An optional regular expression to match on field names
*
* @return array The array mapped from the given object
*/
protected static function _fromObject($item, $recurse, $regex)
{
if (is_object($item))
{
$result = array();
foreach (get_object_vars($item) as $k => $v)
{
if (!$regex || preg_match($regex, $k))
{
if ($recurse)
{
$result[$k] = self::_fromObject($v, $recurse, $regex);
}
else
{
$result[$k] = $v;
}
}
}
}
elseif (is_array($item))
{
$result = array();
foreach ($item as $k => $v)
{
$result[$k] = self::_fromObject($v, $recurse, $regex);
}
}
else
{
$result = $item;
}
return $result;
}
/**
* Extracts a column from an array of arrays or objects
*
* @param array &$array The source array
* @param string $index The index of the column or name of object property
*
* @return array Column of values from the source array
*/
public static function getColumn(&$array, $index)
{
$result = array();
if (is_array($array))
{
foreach ($array as &$item)
{
if (is_array($item) && isset($item[$index]))
{
$result[] = $item[$index];
}
elseif (is_object($item) && isset($item->$index))
{
$result[] = $item->$index;
}
// Else ignore the entry
}
}
return $result;
}
/**
* Utility function to return a value from a named array or a specified default
*
* @param array &$array A named array
* @param string $name The key to search for
* @param mixed $default The default value to give if no key found
* @param string $type Return type for the variable (INT, FLOAT, STRING, WORD, BOOLEAN, ARRAY)
*
* @return mixed The value from the source array
*/
public static function getValue(&$array, $name, $default = null, $type = '')
{
$result = null;
if (isset($array[$name]))
{
$result = $array[$name];
}
// Handle the default case
if (is_null($result))
{
$result = $default;
}
// Handle the type constraint
switch (strtoupper($type))
{
case 'INT':
case 'INTEGER':
// Only use the first integer value
@preg_match('/-?[0-9]+/', $result, $matches);
$result = @(int) $matches[0];
break;
case 'FLOAT':
case 'DOUBLE':
// Only use the first floating point value
@preg_match('/-?[0-9]+(\.[0-9]+)?/', $result, $matches);
$result = @(float) $matches[0];
break;
case 'BOOL':
case 'BOOLEAN':
$result = (bool) $result;
break;
case 'ARRAY':
if (!is_array($result))
{
$result = array($result);
}
break;
case 'STRING':
$result = (string) $result;
break;
case 'WORD':
$result = (string) preg_replace('#\W#', '', $result);
break;
case 'NONE':
default:
// No casting necessary
break;
}
return $result;
}
/**
* Takes an associative array of arrays and inverts the array keys to values using the array values as keys.
*
* Example:
* $input = array(
* 'New' => array('1000', '1500', '1750'),
* 'Used' => array('3000', '4000', '5000', '6000')
* );
* $output = FOFUtilsArray::invert($input);
*
* Output would be equal to:
* $output = array(
* '1000' => 'New',
* '1500' => 'New',
* '1750' => 'New',
* '3000' => 'Used',
* '4000' => 'Used',
* '5000' => 'Used',
* '6000' => 'Used'
* );
*
* @param array $array The source array.
*
* @return array The inverted array.
*/
public static function invert($array)
{
$return = array();
foreach ($array as $base => $values)
{
if (!is_array($values))
{
continue;
}
foreach ($values as $key)
{
// If the key isn't scalar then ignore it.
if (is_scalar($key))
{
$return[$key] = $base;
}
}
}
return $return;
}
/**
* Method to determine if an array is an associative array.
*
* @param array $array An array to test.
*
* @return boolean True if the array is an associative array.
*/
public static function isAssociative($array)
{
if (is_array($array))
{
foreach (array_keys($array) as $k => $v)
{
if ($k !== $v)
{
return true;
}
}
}
return false;
}
/**
* Pivots an array to create a reverse lookup of an array of scalars, arrays or objects.
*
* @param array $source The source array.
* @param string $key Where the elements of the source array are objects or arrays, the key to pivot on.
*
* @return array An array of arrays pivoted either on the value of the keys, or an individual key of an object or array.
*/
public static function pivot($source, $key = null)
{
$result = array();
$counter = array();
foreach ($source as $index => $value)
{
// Determine the name of the pivot key, and its value.
if (is_array($value))
{
// If the key does not exist, ignore it.
if (!isset($value[$key]))
{
continue;
}
$resultKey = $value[$key];
$resultValue = &$source[$index];
}
elseif (is_object($value))
{
// If the key does not exist, ignore it.
if (!isset($value->$key))
{
continue;
}
$resultKey = $value->$key;
$resultValue = &$source[$index];
}
else
{
// Just a scalar value.
$resultKey = $value;
$resultValue = $index;
}
// The counter tracks how many times a key has been used.
if (empty($counter[$resultKey]))
{
// The first time around we just assign the value to the key.
$result[$resultKey] = $resultValue;
$counter[$resultKey] = 1;
}
elseif ($counter[$resultKey] == 1)
{
// If there is a second time, we convert the value into an array.
$result[$resultKey] = array(
$result[$resultKey],
$resultValue,
);
$counter[$resultKey]++;
}
else
{
// After the second time, no need to track any more. Just append to the existing array.
$result[$resultKey][] = $resultValue;
}
}
unset($counter);
return $result;
}
/**
* Utility function to sort an array of objects on a given field
*
* @param array &$a An array of objects
* @param mixed $k The key (string) or a array of key to sort on
* @param mixed $direction Direction (integer) or an array of direction to sort in [1 = Ascending] [-1 = Descending]
* @param mixed $caseSensitive Boolean or array of booleans to let sort occur case sensitive or insensitive
* @param mixed $locale Boolean or array of booleans to let sort occur using the locale language or not
*
* @return array The sorted array of objects
*/
public static function sortObjects(&$a, $k, $direction = 1, $caseSensitive = true, $locale = false)
{
if (!is_array($locale) || !is_array($locale[0]))
{
$locale = array($locale);
}
self::$sortCase = (array) $caseSensitive;
self::$sortDirection = (array) $direction;
self::$sortKey = (array) $k;
self::$sortLocale = $locale;
usort($a, array(__CLASS__, '_sortObjects'));
self::$sortCase = null;
self::$sortDirection = null;
self::$sortKey = null;
self::$sortLocale = null;
return $a;
}
/**
* Callback function for sorting an array of objects on a key
*
* @param array &$a An array of objects
* @param array &$b An array of objects
*
* @return integer Comparison status
*
* @see FOFUtilsArray::sortObjects()
*/
protected static function _sortObjects(&$a, &$b)
{
$key = self::$sortKey;
for ($i = 0, $count = count($key); $i < $count; $i++)
{
if (isset(self::$sortDirection[$i]))
{
$direction = self::$sortDirection[$i];
}
if (isset(self::$sortCase[$i]))
{
$caseSensitive = self::$sortCase[$i];
}
if (isset(self::$sortLocale[$i]))
{
$locale = self::$sortLocale[$i];
}
$va = $a->{$key[$i]};
$vb = $b->{$key[$i]};
if ((is_bool($va) || is_numeric($va)) && (is_bool($vb) || is_numeric($vb)))
{
$cmp = $va - $vb;
}
elseif ($caseSensitive)
{
$cmp = JString::strcmp($va, $vb, $locale);
}
else
{
$cmp = JString::strcasecmp($va, $vb, $locale);
}
if ($cmp > 0)
{
return $direction;
}
if ($cmp < 0)
{
return -$direction;
}
}
return 0;
}
/**
* Multidimensional array safe unique test
*
* @param array $myArray The array to make unique.
*
* @return array
*
* @see http://php.net/manual/en/function.array-unique.php
*/
public static function arrayUnique($myArray)
{
if (!is_array($myArray))
{
return $myArray;
}
foreach ($myArray as &$myvalue)
{
$myvalue = serialize($myvalue);
}
$myArray = array_unique($myArray);
foreach ($myArray as &$myvalue)
{
$myvalue = unserialize($myvalue);
}
return $myArray;
}
}
PK ! u�5�c c object/object.phpnu &1i� <?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('FOF_INCLUDED') or die;
/**
* Temporary class for backwards compatibility. You should not be using this
* in your code. It is currently present to handle the validation error stack
* for FOFTable::check() and will be removed in an upcoming version.
*
* This class is based on JObject as found in Joomla! 3.2.1
*
* @deprecated 2.1
* @codeCoverageIgnore
*/
class FOFUtilsObject
{
/**
* An array of error messages or Exception objects.
*
* @var array
*/
protected $_errors = array();
/**
* Class constructor, overridden in descendant classes.
*
* @param mixed $properties Either and associative array or another
* object to set the initial properties of the object.
*/
public function __construct($properties = null)
{
if ($properties !== null)
{
$this->setProperties($properties);
}
}
/**
* Magic method to convert the object to a string gracefully.
*
* @return string The classname.
*/
public function __toString()
{
return get_class($this);
}
/**
* Sets a default value if not alreay assigned
*
* @param string $property The name of the property.
* @param mixed $default The default value.
*
* @return mixed
*/
public function def($property, $default = null)
{
$value = $this->get($property, $default);
return $this->set($property, $value);
}
/**
* Returns a property of the object or the default value if the property is not set.
*
* @param string $property The name of the property.
* @param mixed $default The default value.
*
* @return mixed The value of the property.
*/
public function get($property, $default = null)
{
if (isset($this->$property))
{
return $this->$property;
}
return $default;
}
/**
* Returns an associative array of object properties.
*
* @param boolean $public If true, returns only the public properties.
*
* @return array
*/
public function getProperties($public = true)
{
$vars = get_object_vars($this);
if ($public)
{
foreach ($vars as $key => $value)
{
if ('_' == substr($key, 0, 1))
{
unset($vars[$key]);
}
}
}
return $vars;
}
/**
* Get the most recent error message.
*
* @param integer $i Option error index.
* @param boolean $toString Indicates if JError objects should return their error message.
*
* @return string Error message
*/
public function getError($i = null, $toString = true)
{
// Find the error
if ($i === null)
{
// Default, return the last message
$error = end($this->_errors);
}
elseif (!array_key_exists($i, $this->_errors))
{
// If $i has been specified but does not exist, return false
return false;
}
else
{
$error = $this->_errors[$i];
}
// Check if only the string is requested
if ($error instanceof Exception && $toString)
{
return (string) $error;
}
return $error;
}
/**
* Return all errors, if any.
*
* @return array Array of error messages or JErrors.
*/
public function getErrors()
{
return $this->_errors;
}
/**
* Modifies a property of the object, creating it if it does not already exist.
*
* @param string $property The name of the property.
* @param mixed $value The value of the property to set.
*
* @return mixed Previous value of the property.
*/
public function set($property, $value = null)
{
$previous = isset($this->$property) ? $this->$property : null;
$this->$property = $value;
return $previous;
}
/**
* Set the object properties based on a named array/hash.
*
* @param mixed $properties Either an associative array or another object.
*
* @return boolean
*/
public function setProperties($properties)
{
if (is_array($properties) || is_object($properties))
{
foreach ((array) $properties as $k => $v)
{
// Use the set function which might be overridden.
$this->set($k, $v);
}
return true;
}
return false;
}
/**
* Add an error message.
*
* @param string $error Error message.
*
* @return void
*/
public function setError($error)
{
array_push($this->_errors, $error);
}
}
PK ! �~�* * observable/dispatcher.phpnu &1i� <?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('FOF_INCLUDED') or die;
/**
* Class to handle dispatching of events.
*
* This is the Observable part of the Observer design pattern
* for the event architecture.
*
* This class is based on JEventDispatcher as found in Joomla! 3.2.0
*/
class FOFUtilsObservableDispatcher extends FOFUtilsObject
{
/**
* An array of Observer objects to notify
*
* @var array
*/
protected $_observers = array();
/**
* The state of the observable object
*
* @var mixed
*/
protected $_state = null;
/**
* A multi dimensional array of [function][] = key for observers
*
* @var array
*/
protected $_methods = array();
/**
* Stores the singleton instance of the dispatcher.
*
* @var FOFUtilsObservableDispatcher
*/
protected static $instance = null;
/**
* Returns the global Event Dispatcher object, only creating it
* if it doesn't already exist.
*
* @return FOFUtilsObservableDispatcher The EventDispatcher object.
*/
public static function getInstance()
{
if (self::$instance === null)
{
self::$instance = new static;
}
return self::$instance;
}
/**
* Get the state of the FOFUtilsObservableDispatcher object
*
* @return mixed The state of the object.
*/
public function getState()
{
return $this->_state;
}
/**
* Registers an event handler to the event dispatcher
*
* @param string $event Name of the event to register handler for
* @param string $handler Name of the event handler
*
* @return void
*
* @throws InvalidArgumentException
*/
public function register($event, $handler)
{
// Are we dealing with a class or callback type handler?
if (is_callable($handler))
{
// Ok, function type event handler... let's attach it.
$method = array('event' => $event, 'handler' => $handler);
$this->attach($method);
}
elseif (class_exists($handler))
{
// Ok, class type event handler... let's instantiate and attach it.
$this->attach(new $handler($this));
}
else
{
throw new InvalidArgumentException('Invalid event handler.');
}
}
/**
* Triggers an event by dispatching arguments to all observers that handle
* the event and returning their return values.
*
* @param string $event The event to trigger.
* @param array $args An array of arguments.
*
* @return array An array of results from each function call.
*/
public function trigger($event, $args = array())
{
$result = array();
/*
* If no arguments were passed, we still need to pass an empty array to
* the call_user_func_array function.
*/
$args = (array) $args;
$event = strtolower($event);
// Check if any plugins are attached to the event.
if (!isset($this->_methods[$event]) || empty($this->_methods[$event]))
{
// No Plugins Associated To Event!
return $result;
}
// Loop through all plugins having a method matching our event
foreach ($this->_methods[$event] as $key)
{
// Check if the plugin is present.
if (!isset($this->_observers[$key]))
{
continue;
}
// Fire the event for an object based observer.
if (is_object($this->_observers[$key]))
{
$args['event'] = $event;
$value = $this->_observers[$key]->update($args);
}
// Fire the event for a function based observer.
elseif (is_array($this->_observers[$key]))
{
$value = call_user_func_array($this->_observers[$key]['handler'], $args);
}
if (isset($value))
{
$result[] = $value;
}
}
return $result;
}
/**
* Attach an observer object
*
* @param object $observer An observer object to attach
*
* @return void
*/
public function attach($observer)
{
if (is_array($observer))
{
if (!isset($observer['handler']) || !isset($observer['event']) || !is_callable($observer['handler']))
{
return;
}
// Make sure we haven't already attached this array as an observer
foreach ($this->_observers as $check)
{
if (is_array($check) && $check['event'] == $observer['event'] && $check['handler'] == $observer['handler'])
{
return;
}
}
$this->_observers[] = $observer;
end($this->_observers);
$methods = array($observer['event']);
}
else
{
if (!($observer instanceof FOFUtilsObservableEvent))
{
return;
}
// Make sure we haven't already attached this object as an observer
$class = get_class($observer);
foreach ($this->_observers as $check)
{
if ($check instanceof $class)
{
return;
}
}
$this->_observers[] = $observer;
// Required in PHP 7 since foreach() doesn't advance the internal array counter, see http://php.net/manual/en/migration70.incompatible.php
end($this->_observers);
$methods = array();
foreach(get_class_methods($observer) as $obs_method)
{
// Magic methods are not allowed
if(strpos('__', $obs_method) === 0)
{
continue;
}
$methods[] = $obs_method;
}
//$methods = get_class_methods($observer);
}
$key = key($this->_observers);
foreach ($methods as $method)
{
$method = strtolower($method);
if (!isset($this->_methods[$method]))
{
$this->_methods[$method] = array();
}
$this->_methods[$method][] = $key;
}
}
/**
* Detach an observer object
*
* @param object $observer An observer object to detach.
*
* @return boolean True if the observer object was detached.
*/
public function detach($observer)
{
$retval = false;
$key = array_search($observer, $this->_observers);
if ($key !== false)
{
unset($this->_observers[$key]);
$retval = true;
foreach ($this->_methods as &$method)
{
$k = array_search($key, $method);
if ($k !== false)
{
unset($method[$k]);
}
}
}
return $retval;
}
}
PK ! t�>�� � observable/event.phpnu &1i� <?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('FOF_INCLUDED') or die;
/**
* Defines an observable event.
*
* This class is based on JEvent as found in Joomla! 3.2.0
*/
abstract class FOFUtilsObservableEvent extends FOFUtilsObject
{
/**
* Event object to observe.
*
* @var object
*/
protected $_subject = null;
/**
* Constructor
*
* @param object &$subject The object to observe.
*/
public function __construct(&$subject)
{
// Register the observer ($this) so we can be notified
$subject->attach($this);
// Set the subject to observe
$this->_subject = &$subject;
}
/**
* Method to trigger events.
* The method first generates the even from the argument array. Then it unsets the argument
* since the argument has no bearing on the event handler.
* If the method exists it is called and returns its return value. If it does not exist it
* returns null.
*
* @param array &$args Arguments
*
* @return mixed Routine return value
*/
public function update(&$args)
{
// First let's get the event from the argument array. Next we will unset the
// event argument as it has no bearing on the method to handle the event.
$event = $args['event'];
unset($args['event']);
/*
* If the method to handle an event exists, call it and return its return
* value. If it does not exist, return null.
*/
if (method_exists($this, $event))
{
return call_user_func_array(array($this, $event), $args);
}
else
{
return null;
}
}
}
PK ! �
b/5
5
update/extension.phpnu &1i� <?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;
/**
* A helper class to read and parse "extension" update XML files over the web
*/
class FOFUtilsUpdateExtension
{
/**
* Reads an "extension" XML update source and returns all listed update entries.
*
* If you have a "collection" XML update source you should do something like this:
* $collection = new FOFUtilsUpdateCollection();
* $extensionUpdateURL = $collection->getExtensionUpdateSource($url, 'component', 'com_foobar', JVERSION);
* $extension = new FOFUtilsUpdateExtension();
* $updates = $extension->getUpdatesFromExtension($extensionUpdateURL);
*
* @param string $url The extension XML update source URL to read from
*
* @return array An array of update entries
*/
public function getUpdatesFromExtension($url)
{
// Initialise
$ret = array();
// Get and parse the XML source
$downloader = new FOFDownload();
$xmlSource = $downloader->getFromURL($url);
try
{
$xml = new SimpleXMLElement($xmlSource, LIBXML_NONET);
}
catch(Exception $e)
{
return $ret;
}
// Sanity check
if (($xml->getName() != 'updates'))
{
unset($xml);
return $ret;
}
// Let's populate the list of updates
/** @var SimpleXMLElement $update */
foreach ($xml->children() as $update)
{
// Sanity check
if ($update->getName() != 'update')
{
continue;
}
$entry = array(
'infourl' => array('title' => '', 'url' => ''),
'downloads' => array(),
'tags' => array(),
'targetplatform' => array(),
);
$properties = get_object_vars($update);
foreach ($properties as $nodeName => $nodeContent)
{
switch ($nodeName)
{
default:
$entry[$nodeName] = $nodeContent;
break;
case 'infourl':
case 'downloads':
case 'tags':
case 'targetplatform':
break;
}
}
$infourlNode = $update->xpath('infourl');
$entry['infourl']['title'] = (string)$infourlNode[0]['title'];
$entry['infourl']['url'] = (string)$infourlNode[0];
$downloadNodes = $update->xpath('downloads/downloadurl');
foreach ($downloadNodes as $downloadNode)
{
$entry['downloads'][] = array(
'type' => (string)$downloadNode['type'],
'format' => (string)$downloadNode['format'],
'url' => (string)$downloadNode,
);
}
$tagNodes = $update->xpath('tags/tag');
foreach ($tagNodes as $tagNode)
{
$entry['tags'][] = (string)$tagNode;
}
/** @var SimpleXMLElement $targetPlatformNode */
$targetPlatformNode = $update->xpath('targetplatform');
$entry['targetplatform']['name'] = (string)$targetPlatformNode[0]['name'];
$entry['targetplatform']['version'] = (string)$targetPlatformNode[0]['version'];
$client = $targetPlatformNode[0]->xpath('client');
$entry['targetplatform']['client'] = (is_array($client) && count($client)) ? (string)$client[0] : '';
$folder = $targetPlatformNode[0]->xpath('folder');
$entry['targetplatform']['folder'] = is_array($folder) && count($folder) ? (string)$folder[0] : '';
$ret[] = $entry;
}
unset($xml);
return $ret;
}
}PK ! =�ή�'