AAAAPK Z?\) adapters/.htaccessnu W+A
Order allow,deny
Deny from all
PK Z?\V adapters/index.htmlnu W+A
PK Z?\;E E adapters/template.phpnu W+A parent->getPath('source');
if (!$source)
{
$this->parent
->setPath(
'source',
($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/templates/' . $this->parent->extension->element
);
}
$clientId = isset($this->parent->extension) ? $this->parent->extension->client_id : 0;
$this->manifest = $this->parent->getManifest();
$name = strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
$client = (string) $this->manifest->attributes()->client;
// Load administrator language if not set.
if (!$client)
{
$client = 'ADMINISTRATOR';
}
$extension = "tpl_$name";
$lang = JFactory::getLanguage();
$source = $path ? $path : ($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/templates/' . $name;
$lang->load($extension . '.sys', $source, null, false, true)
|| $lang->load($extension . '.sys', constant('JPATH_' . strtoupper($client)), null, false, true);
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 11.1
*/
public function install()
{
// Get a database connector object
$db = $this->parent->getDbo();
$lang = JFactory::getLanguage();
$xml = $this->parent->getManifest();
// Get the client application target
if ($cname = (string) $xml->attributes()->client)
{
// Attempt to map the client to a base path
$client = JApplicationHelper::getClientInfo($cname, true);
if ($client === false)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_UNKNOWN_CLIENT', $cname));
return false;
}
$basePath = $client->path;
$clientId = $client->id;
}
else
{
// No client attribute was found so we assume the site as the client
$cname = 'site';
$basePath = JPATH_SITE;
$clientId = 0;
}
// Set the extension's name
$name = JFilterInput::getInstance()->clean((string) $xml->name, 'cmd');
$element = strtolower(str_replace(" ", "_", $name));
$this->set('name', $name);
$this->set('element', $element);
// Check to see if a template by the same name is already installed.
$query = $db->getQuery(true);
$query->select($query->qn('extension_id'))->from($query->qn('#__extensions'));
$query->where($query->qn('type') . ' = ' . $query->q('template'));
$query->where($query->qn('element') . ' = ' . $query->q($element));
$db->setQuery($query);
try
{
$id = $db->loadResult();
}
catch (RuntimeException $e)
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK'), $e->getMessage());
return false;
}
// Legacy error handling switch based on the JError::$legacy switch.
// @deprecated 12.1
if (JError::$legacy && $db->getErrorNum())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
// Set the template root path
$this->parent->setPath('extension_root', $basePath . '/templates/' . $element);
// if it's on the fs...
if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->isOverwrite() || $this->parent->isUpgrade()))
{
$updateElement = $xml->update;
// Upgrade manually set or
// Update function available or
// Update tag detected
if ($this->parent->isUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update'))
|| $updateElement)
{
// Force this one
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
if ($id)
{
// if there is a matching extension mark this as an update; semantics really
$this->route = 'update';
}
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is not set
// If we didn't have overwrite set, find an update function or find an update tag so let's call it safe
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_TPL_INSTALL_ANOTHER_TEMPLATE_USING_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
/*
* If the template directory already exists, then we will assume that the template is already
* installed or another template is using that directory.
*/
if (file_exists($this->parent->getPath('extension_root')) && !$this->parent->isOverwrite())
{
JError::raiseWarning(
100,
JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ANOTHER_TEMPLATE_USING_DIRECTORY', $this->parent->getPath('extension_root'))
);
return false;
}
// If the template directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_root')))
{
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_FAILED_CREATE_DIRECTORY', $this->parent->getPath('extension_root')));
return false;
}
}
// If we created the template directory and will want to remove it if we have to roll back
// the installation, let's add it to the installation step stack
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
}
// Copy all the necessary files
if ($this->parent->parseFiles($xml->files, -1) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
if ($this->parent->parseFiles($xml->images, -1) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
if ($this->parent->parseFiles($xml->css, -1) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseMedia($xml->media);
$this->parent->parseLanguages($xml->languages, $clientId);
// Get the template description
$this->parent->set('message', JText::_((string) $xml->description));
// Lastly, we will copy the manifest file to its appropriate place.
if (!$this->parent->copyManifest(-1))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_TPL_INSTALL_COPY_SETUP'));
return false;
}
// Extension Registration
$row = JTable::getInstance('extension');
if ($this->route == 'update' && $id)
{
$row->load($id);
}
else
{
$row->type = 'template';
$row->element = $this->get('element');
// There is no folder for templates
$row->folder = '';
$row->enabled = 1;
$row->protected = 0;
$row->access = 1;
$row->client_id = $clientId;
$row->params = $this->parent->getParams();
$row->custom_data = ''; // custom data
}
$row->name = $this->get('name'); // name might change in an update
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
if ($this->route == 'install')
{
//insert record in #__template_styles
$query = $db->getQuery(true);
$query->insert($db->quoteName('#__template_styles'));
$debug = $lang->setDebug(false);
$columns = array($db->quoteName('template'),
$db->quoteName('client_id'),
$db->quoteName('home'),
$db->quoteName('title'),
$db->quoteName('params')
);
$query->columns($columns);
$query->values(
$db->Quote($row->element)
. ',' . $db->Quote($clientId)
. ',' . $db->Quote(0)
. ',' . $db->Quote(JText::sprintf('JLIB_INSTALLER_DEFAULT_STYLE', JText::_($this->get('name'))))
. ',' . $db->Quote($row->params)
);
$lang->setDebug($debug);
$db->setQuery($query);
// There is a chance this could fail but we don't care...
$db->execute();
}
return $row->get('extension_id');
}
/**
* Custom update method for components
*
* @return boolean True on success
*
* @since 11.1
*/
public function update()
{
return $this->install();
}
/**
* Custom uninstall method
*
* @param integer $id The extension ID
*
* @return boolean True on success
*
* @since 11.1
*/
public function uninstall($id)
{
// Initialise variables.
$retval = true;
// First order of business will be to load the template object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id) || !strlen($row->element))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_ERRORUNKOWNEXTENSION'));
return false;
}
// Is the template we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_WARNCORETEMPLATE', $row->name));
return false;
}
$name = $row->element;
$clientId = $row->client_id;
// For a template the id will be the template name which represents the subfolder of the templates folder that the template resides in.
if (!$name)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_ID_EMPTY'));
return false;
}
// Deny remove default template
$db = $this->parent->getDbo();
$query = 'SELECT COUNT(*) FROM #__template_styles' . ' WHERE home = 1 AND template = ' . $db->Quote($name);
$db->setQuery($query);
if ($db->loadResult() != 0)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DEFAULT'));
return false;
}
// Get the template root path
$client = JApplicationHelper::getClientInfo($clientId);
if (!$client)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_CLIENT'));
return false;
}
$this->parent->setPath('extension_root', $client->path . '/templates/' . strtolower($name));
$this->parent->setPath('source', $this->parent->getPath('extension_root'));
// We do findManifest to avoid problem when uninstalling a list of extensions: getManifest cache its manifest file
$this->parent->findManifest();
$manifest = $this->parent->getManifest();
if (!($manifest instanceof SimpleXMLElement))
{
// Kill the extension entry
$row->delete($row->extension_id);
unset($row);
// Make sure we delete the folders
JFolder::delete($this->parent->getPath('extension_root'));
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_NOTFOUND_MANIFEST'));
return false;
}
// Remove files
$this->parent->removeFiles($manifest->media);
$this->parent->removeFiles($manifest->languages, $clientId);
// Delete the template directory
if (JFolder::exists($this->parent->getPath('extension_root')))
{
$retval = JFolder::delete($this->parent->getPath('extension_root'));
}
else
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DIRECTORY'));
$retval = false;
}
// Set menu that assigned to the template back to default template
$query = 'UPDATE #__menu INNER JOIN #__template_styles' . ' ON #__template_styles.id = #__menu.template_style_id'
. ' SET #__menu.template_style_id = 0' . ' WHERE #__template_styles.template = ' . $db->Quote(strtolower($name))
. ' AND #__template_styles.client_id = ' . $db->Quote($clientId);
$db->setQuery($query);
$db->execute();
$query = 'DELETE FROM #__template_styles' . ' WHERE template = ' . $db->Quote($name) . ' AND client_id = ' . $db->Quote($clientId);
$db->setQuery($query);
$db->execute();
$row->delete($row->extension_id);
unset($row);
return $retval;
}
/**
* Discover existing but uninstalled templates
*
* @return array JExtensionTable list
*/
public function discover()
{
$results = array();
$site_list = JFolder::folders(JPATH_SITE . '/templates');
$admin_list = JFolder::folders(JPATH_ADMINISTRATOR . '/templates');
$site_info = JApplicationHelper::getClientInfo('site', true);
$admin_info = JApplicationHelper::getClientInfo('administrator', true);
foreach ($site_list as $template)
{
if ($template == 'system')
{
continue;
// Ignore special system template
}
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_SITE . "/templates/$template/templateDetails.xml");
$extension = JTable::getInstance('extension');
$extension->set('type', 'template');
$extension->set('client_id', $site_info->id);
$extension->set('element', $template);
$extension->set('name', $template);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
foreach ($admin_list as $template)
{
if ($template == 'system')
{
continue;
// Ignore special system template
}
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_ADMINISTRATOR . "/templates/$template/templateDetails.xml");
$extension = JTable::getInstance('extension');
$extension->set('type', 'template');
$extension->set('client_id', $admin_info->id);
$extension->set('element', $template);
$extension->set('name', $template);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
return $results;
}
/**
* Discover_install
* Perform an install for a discovered extension
*
* @return boolean
*
* @since 11.1
*/
public function discover_install()
{
// Templates are one of the easiest
// If its not in the extensions table we just add it
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$lang = JFactory::getLanguage();
$manifestPath = $client->path . '/templates/' . $this->parent->extension->element . '/templateDetails.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$description = (string) $this->parent->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
$data = new JObject;
foreach ($manifest_details as $key => $value)
{
$data->set($key, $value);
}
$this->parent->extension->params = $this->parent->getParams();
if ($this->parent->extension->store())
{
//insert record in #__template_styles
$db = $this->parent->getDbo();
$query = $db->getQuery(true);
$query->insert($db->quoteName('#__template_styles'));
$debug = $lang->setDebug(false);
$columns = array($db->quoteName('template'),
$db->quoteName('client_id'),
$db->quoteName('home'),
$db->quoteName('title'),
$db->quoteName('params')
);
$query->columns($columns);
$query->values(
$db->Quote($this->parent->extension->element)
. ',' . $db->Quote($this->parent->extension->client_id)
. ',' . $db->Quote(0)
. ',' . $db->Quote(JText::sprintf('JLIB_INSTALLER_DEFAULT_STYLE', $this->parent->extension->name))
. ',' . $db->Quote($this->parent->extension->params)
);
$lang->setDebug($debug);
$db->setQuery($query);
$db->execute();
return $this->parent->extension->get('extension_id');
}
else
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_TPL_DISCOVER_STORE_DETAILS'));
return false;
}
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure
*
* @since 11.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally.
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/templates/' . $this->parent->extension->element . '/templateDetails.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (JException $e)
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_TPL_REFRESH_MANIFEST_CACHE'));
return false;
}
}
}
PK Z?\Gb adapters/component.phpnu W+A parent->getPath('source');
if (!$source)
{
$this->parent
->setPath(
'source',
($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) .
'/components/' . $this->parent->extension->element
);
}
$this->manifest = $this->parent->getManifest();
$name = strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
if (substr($name, 0, 4) == "com_")
{
$extension = $name;
}
else
{
$extension = "com_$name";
}
$lang = JFactory::getLanguage();
$source = $path ? $path : ($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/components/' . $extension;
if ($this->manifest->administration->files)
{
$element = $this->manifest->administration->files;
}
elseif ($this->manifest->files)
{
$element = $this->manifest->files;
}
else
{
$element = null;
}
if ($element)
{
$folder = (string) $element->attributes()->folder;
if ($folder && file_exists("$path/$folder"))
{
$source = "$path/$folder";
}
}
$lang->load($extension . '.sys', $source, null, false, true)
|| $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, true);
}
/**
* Custom install method for components
*
* @return boolean True on success
*
* @since 11.1
*/
public function install()
{
// Get a database connector object
$db = $this->parent->getDbo();
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
// Manifest Document Setup Section
// Set the extension's name
$name = strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
if (substr($name, 0, 4) == "com_")
{
$element = $name;
}
else
{
$element = "com_$name";
}
$this->set('name', $name);
$this->set('element', $element);
// Get the component description
$this->parent->set('message', JText::_((string) $this->manifest->description));
// Set the installation target paths
$this->parent->setPath('extension_site', JPath::clean(JPATH_SITE . '/components/' . $this->get('element')));
$this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $this->get('element')));
// copy this as its used as a common base
$this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator'));
// Basic Checks Section
// Make sure that we have an admin element
if (!$this->manifest->administration)
{
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_COMP_INSTALL_ADMIN_ELEMENT'));
return false;
}
// Filesystem Processing Section
// If the component site or admin directory already exists, then we will assume that the component is already
// installed or another component is using that directory.
if (file_exists($this->parent->getPath('extension_site')) || file_exists($this->parent->getPath('extension_administrator')))
{
// Look for an update function or update tag
$updateElement = $this->manifest->update;
// Upgrade manually set or
// Update function available or
// Update tag detected
if ($this->parent->isUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update'))
|| $updateElement)
{
return $this->update(); // transfer control to the update function
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is set.
// We didn't have overwrite set, find an update function or find an update tag so lets call it safe
if (file_exists($this->parent->getPath('extension_site')))
{
// If the site exists say so.
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_COMP_INSTALL_DIR_SITE', $this->parent->getPath('extension_site')));
}
else
{
// If the admin exists say so
JError::raiseWarning(
1,
JText::sprintf('JLIB_INSTALLER_ERROR_COMP_INSTALL_DIR_ADMIN', $this->parent->getPath('extension_administrator'))
);
}
return false;
}
}
// Installer Trigger Loading
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $this->get('element') . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight('install', $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create msg object; first use here
$msg = ob_get_contents();
ob_end_clean();
// If the component directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_site')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_site')))
{
JError::raiseWarning(
1,
JText::sprintf('JLIB_INSTALLER_ERROR_COMP_INSTALL_FAILED_TO_CREATE_DIRECTORY_SITE', $this->parent->getPath('extension_site'))
);
return false;
}
}
// Since we created the component directory and will want to remove it if we have to roll back
// the installation, let's add it to the installation step stack
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
}
// If the component admin directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_administrator')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_administrator')))
{
JError::raiseWarning(
1,
JText::sprintf(
'JLIB_INSTALLER_ERROR_COMP_INSTALL_FAILED_TO_CREATE_DIRECTORY_ADMIN',
$this->parent->getPath('extension_administrator')
)
);
// Install failed, rollback any changes
$this->parent->abort();
return false;
}
}
/*
* Since we created the component admin directory and we will want to remove it if we have to roll
* back the installation, let's add it to the installation step stack
*/
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_administrator')));
}
// Copy site files
if ($this->manifest->files)
{
if ($this->parent->parseFiles($this->manifest->files) === false)
{
// Install failed, rollback any changes
$this->parent->abort();
return false;
}
}
// Copy admin files
if ($this->manifest->administration->files)
{
if ($this->parent->parseFiles($this->manifest->administration->files, 1) === false)
{
// Install failed, rollback any changes
$this->parent->abort();
return false;
}
}
// Parse optional tags
$this->parent->parseMedia($this->manifest->media);
$this->parent->parseLanguages($this->manifest->languages);
$this->parent->parseLanguages($this->manifest->administration->languages, 1);
// Deprecated install, remove after 1.6
// If there is an install file, lets copy it.
$installFile = (string) $this->manifest->installfile;
if ($installFile)
{
// Make sure it hasn't already been copied (this would be an error in the XML install file)
if (!file_exists($this->parent->getPath('extension_administrator') . '/' . $installFile) || $this->parent->isOverwrite())
{
$path['src'] = $this->parent->getPath('source') . '/' . $installFile;
$path['dest'] = $this->parent->getPath('extension_administrator') . '/' . $installFile;
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_PHP_INSTALL'));
return false;
}
}
$this->set('install_script', $installFile);
}
// Deprecated uninstall, remove after 1.6
// If there is an uninstall file, let's copy it.
$uninstallFile = (string) $this->manifest->uninstallfile;
if ($uninstallFile)
{
// Make sure it hasn't already been copied (this would be an error in the XML install file)
if (!file_exists($this->parent->getPath('extension_administrator') . '/' . $uninstallFile) || $this->parent->isOverwrite())
{
$path['src'] = $this->parent->getPath('source') . '/' . $uninstallFile;
$path['dest'] = $this->parent->getPath('extension_administrator') . '/' . $uninstallFile;
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_PHP_UNINSTALL'));
return false;
}
}
}
// If there is a manifest script, let's copy it.
if ($this->get('manifest_script'))
{
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_administrator') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']) || $this->parent->isOverwrite())
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_MANIFEST'));
return false;
}
}
}
/**
* ---------------------------------------------------------------------------------------------
* Database Processing Section
* ---------------------------------------------------------------------------------------------
*/
/*
* Let's run the install queries for the component
* If Joomla 1.5 compatible, with discreet sql files - execute appropriate
* file for utf-8 support or non-utf-8 support
*/
// Try for Joomla 1.5 type queries
// Second argument is the utf compatible version attribute
if (isset($this->manifest->install->sql))
{
$utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_SQL_ERROR', $db->stderr(true)));
return false;
}
}
/**
* ---------------------------------------------------------------------------------------------
* Custom Installation Script Section
* ---------------------------------------------------------------------------------------------
*/
/*
* If we have an install script, let's include it, execute the custom
* install method, and append the return value from the custom install
* method to the installation message.
*/
// Start legacy support
if ($this->get('install_script'))
{
if (is_file($this->parent->getPath('extension_administrator') . '/' . $this->get('install_script')) || $this->parent->isOverwrite())
{
$notdef = false;
$ranwell = false;
ob_start();
ob_implicit_flush(false);
require_once $this->parent->getPath('extension_administrator') . '/' . $this->get('install_script');
if (function_exists('com_install'))
{
if (com_install() === false)
{
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
}
}
// End legacy support
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'install'))
{
if ($this->parent->manifestClass->install($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
/**
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Add an entry to the extension table with a whole heap of defaults
$row = JTable::getInstance('extension');
$row->set('name', $this->get('name'));
$row->set('type', 'component');
$row->set('element', $this->get('element'));
$row->set('folder', ''); // There is no folder for components
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', 0);
$row->set('client_id', 1);
$row->set('params', $this->parent->getParams());
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
$eid = $db->insertid();
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $this->get('element'), 'type' => 'component', 'client_id' => '', 'folder' => ''));
if ($uid)
{
$update->delete($uid);
}
// We will copy the manifest file to its appropriate place.
if (!$this->parent->copyManifest())
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_COPY_SETUP'));
return false;
}
// Time to build the admin menus
if (!$this->_buildAdminMenus($row->extension_id))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ABORT_COMP_BUILDADMINMENUS_FAILED'));
//$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $db->stderr(true)));
//return false;
}
// Set the schema version to be the latest update version
if ($this->manifest->update)
{
$this->parent->setSchemaVersion($this->manifest->update->schemas, $eid);
}
// Register the component container just under root in the assets table.
$asset = JTable::getInstance('Asset');
$asset->name = $row->element;
$asset->parent_id = 1;
$asset->rules = '{}';
$asset->title = $row->name;
$asset->setLocation(1, 'last-child');
if (!$asset->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight('install', $this);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->extension_id;
}
/**
* Custom update method for components
*
* @return boolean True on success
*
* @since 11.1
*/
public function update()
{
// Get a database connector object
$db = $this->parent->getDbo();
// Set the overwrite setting
$this->parent->setOverwrite(true);
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
/**
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Set the extension's name
$name = strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
if (substr($name, 0, 4) == "com_")
{
$element = $name;
}
else
{
$element = "com_$name";
}
$this->set('name', $name);
$this->set('element', $element);
// Get the component description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Set the installation target paths
$this->parent->setPath('extension_site', JPath::clean(JPATH_SITE . '/components/' . $this->get('element')));
$this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $this->get('element')));
$this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // copy this as its used as a common base
/**
* Hunt for the original XML file
*/
$old_manifest = null;
// Create a new installer because findManifest sets stuff
// Look in the administrator first
$tmpInstaller = new JInstaller;
$tmpInstaller->setPath('source', $this->parent->getPath('extension_administrator'));
if (!$tmpInstaller->findManifest())
{
// Then the site
$tmpInstaller->setPath('source', $this->parent->getPath('extension_site'));
if ($tmpInstaller->findManifest())
{
$old_manifest = $tmpInstaller->getManifest();
}
}
else
{
$old_manifest = $tmpInstaller->getManifest();
}
// Should do this above perhaps?
if ($old_manifest)
{
$this->oldAdminFiles = $old_manifest->administration->files;
$this->oldFiles = $old_manifest->files;
}
else
{
$this->oldAdminFiles = null;
$this->oldFiles = null;
}
/**
* ---------------------------------------------------------------------------------------------
* Basic Checks Section
* ---------------------------------------------------------------------------------------------
*/
// Make sure that we have an admin element
if (!$this->manifest->administration)
{
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ABORT_COMP_UPDATE_ADMIN_ELEMENT'));
return false;
}
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight('update', $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create msg object; first use here
$msg = ob_get_contents();
ob_end_clean();
/**
* ---------------------------------------------------------------------------------------------
* Filesystem Processing Section
* ---------------------------------------------------------------------------------------------
*/
// If the component directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_site')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_site')))
{
JError::raiseWarning(
1,
JText::sprintf('JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_SITE', $this->parent->getPath('extension_site'))
);
return false;
}
}
/*
* Since we created the component directory and will want to remove it if we have to roll back
* the installation, lets add it to the installation step stack
*/
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
}
// If the component admin directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_administrator')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_administrator')))
{
JError::raiseWarning(
1,
JText::sprintf(
'JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_ADMIN',
$this->parent->getPath('extension_administrator')
)
);
// Install failed, rollback any changes
$this->parent->abort();
return false;
}
}
/*
* Since we created the component admin directory and we will want to remove it if we have to roll
* back the installation, let's add it to the installation step stack
*/
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_administrator')));
}
// Find files to copy
if ($this->manifest->files)
{
if ($this->parent->parseFiles($this->manifest->files, 0, $this->oldFiles) === false)
{
// Install failed, rollback any changes
$this->parent->abort();
return false;
}
}
if ($this->manifest->administration->files)
{
if ($this->parent->parseFiles($this->manifest->administration->files, 1, $this->oldAdminFiles) === false)
{
// Install failed, rollback any changes
$this->parent->abort();
return false;
}
}
// Parse optional tags
$this->parent->parseMedia($this->manifest->media);
$this->parent->parseLanguages($this->manifest->languages);
$this->parent->parseLanguages($this->manifest->administration->languages, 1);
// Deprecated install, remove after 1.6
// If there is an install file, lets copy it.
$installFile = (string) $this->manifest->installfile;
if ($installFile)
{
// Make sure it hasn't already been copied (this would be an error in the XML install file)
if (!file_exists($this->parent->getPath('extension_administrator') . '/' . $installFile) || $this->parent->isOverwrite())
{
$path['src'] = $this->parent->getPath('source') . '/' . $installFile;
$path['dest'] = $this->parent->getPath('extension_administrator') . '/' . $installFile;
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_UPDATE_PHP_INSTALL'));
return false;
}
}
$this->set('install_script', $installFile);
}
// Deprecated uninstall, remove after 1.6
// If there is an uninstall file, lets copy it.
$uninstallFile = (string) $this->manifest->uninstallfile;
if ($uninstallFile)
{
// Make sure it hasn't already been copied (this would be an error in the XML install file)
if (!file_exists($this->parent->getPath('extension_administrator') . '/' . $uninstallFile) || $this->parent->isOverwrite())
{
$path['src'] = $this->parent->getPath('source') . '/' . $uninstallFile;
$path['dest'] = $this->parent->getPath('extension_administrator') . '/' . $uninstallFile;
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_UPDATE_PHP_UNINSTALL'));
return false;
}
}
}
// If there is a manifest script, let's copy it.
if ($this->get('manifest_script'))
{
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_administrator') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']) || $this->parent->isOverwrite())
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_UPDATE_MANIFEST'));
return false;
}
}
}
/**
* ---------------------------------------------------------------------------------------------
* Database Processing Section
* ---------------------------------------------------------------------------------------------
*/
/*
* Let's run the update queries for the component
*/
$row = JTable::getInstance('extension');
$eid = $row->find(array('element' => strtolower($this->get('element')), 'type' => 'component'));
if ($this->manifest->update)
{
$result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $eid);
if ($result === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_UPDATE_SQL_ERROR', $db->stderr(true)));
return false;
}
}
// Time to build the admin menus
if (!$this->_buildAdminMenus($eid))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ABORT_COMP_BUILDADMINMENUS_FAILED'));
// $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $db->stderr(true)));
// Return false;
}
/**
* ---------------------------------------------------------------------------------------------
* Custom Installation Script Section
* ---------------------------------------------------------------------------------------------
*/
/*
* If we have an install script, let's include it, execute the custom
* install method, and append the return value from the custom install
* method to the installation message.
*/
// Start legacy support
if ($this->get('install_script'))
{
if (is_file($this->parent->getPath('extension_administrator') . '/' . $this->get('install_script')) || $this->parent->isOverwrite())
{
$notdef = false;
$ranwell = false;
ob_start();
ob_implicit_flush(false);
require_once $this->parent->getPath('extension_administrator') . '/' . $this->get('install_script');
if (function_exists('com_install'))
{
if (com_install() === false)
{
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
}
}
/*
* If we have an update script, let's include it, execute the custom
* update method, and append the return value from the custom update
* method to the installation message.
*/
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update'))
{
if ($this->parent->manifestClass->update($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
/**
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $this->get('element'), 'type' => 'component', 'client_id' => '', 'folder' => ''));
if ($uid)
{
$update->delete($uid);
}
// Update an entry to the extension table
if ($eid)
{
$row->load($eid);
}
else
{
// Set the defaults
// There is no folder for components
$row->folder = '';
$row->enabled = 1;
$row->protected = 0;
$row->access = 1;
$row->client_id = 1;
$row->params = $this->parent->getParams();
}
$row->name = $this->get('name');
$row->type = 'component';
$row->element = $this->get('element');
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_UPDATE_ROLLBACK', $db->stderr(true)));
return false;
}
// We will copy the manifest file to its appropriate place.
if (!$this->parent->copyManifest())
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_UPDATE_COPY_SETUP'));
return false;
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight('update', $this);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->extension_id;
}
/**
* Custom uninstall method for components
*
* @param integer $id The unique extension id of the component to uninstall
*
* @return mixed Return value for uninstall method in component uninstall file
*
* @since 11.1
*/
public function uninstall($id)
{
// Initialise variables.
$db = $this->parent->getDbo();
$row = null;
$retval = true;
// First order of business will be to load the component object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_ERRORUNKOWNEXTENSION'));
return false;
}
// Is the component we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_WARNCORECOMPONENT'));
return false;
}
// Get the admin and site paths for the component
$this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $row->element));
$this->parent->setPath('extension_site', JPath::clean(JPATH_SITE . '/components/' . $row->element));
$this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // copy this as its used as a common base
/**
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Find and load the XML install file for the component
$this->parent->setPath('source', $this->parent->getPath('extension_administrator'));
// Get the package manifest object
// We do findManifest to avoid problem when uninstalling a list of extension: getManifest cache its manifest file
$this->parent->findManifest();
$this->manifest = $this->parent->getManifest();
if (!$this->manifest)
{
// Make sure we delete the folders if no manifest exists
JFolder::delete($this->parent->getPath('extension_administrator'));
JFolder::delete($this->parent->getPath('extension_site'));
// Remove the menu
$this->_removeAdminMenus($row);
// Raise a warning
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_ERRORREMOVEMANUALLY'));
// Return
return false;
}
// Set the extensions name
$name = strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
if (substr($name, 0, 4) == "com_")
{
$element = $name;
}
else
{
$element = "com_$name";
}
$this->set('name', $name);
$this->set('element', $element);
// Attempt to load the admin language file; might have uninstall strings
$this->loadLanguage(JPATH_ADMINISTRATOR . '/components/' . $element);
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading and Uninstall
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$scriptFile = (string) $this->manifest->scriptfile;
if ($scriptFile)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $scriptFile;
if (is_file($manifestScriptFile))
{
// load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $row->element . 'InstallerScript';
if (class_exists($classname))
{
// create a new instance
$this->parent->manifestClass = new $classname($this);
// and set this so we can copy it later
$this->set('manifest_script', $scriptFile);
// Note: if we don't find the class, don't bother to copy the file
}
}
ob_start();
ob_implicit_flush(false);
// run uninstall if possible
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
$msg = ob_get_contents();
ob_end_clean();
/**
* ---------------------------------------------------------------------------------------------
* Custom Uninstallation Script Section; Legacy CMS 1.5 Support
* ---------------------------------------------------------------------------------------------
*/
// Now let's load the uninstall file if there is one and execute the uninstall function if it exists.
$uninstallFile = (string) $this->manifest->uninstallfile;
if ($uninstallFile)
{
// Element exists, does the file exist?
if (is_file($this->parent->getPath('extension_administrator') . '/' . $uninstallFile))
{
ob_start();
ob_implicit_flush(false);
require_once $this->parent->getPath('extension_administrator') . '/' . $uninstallFile;
if (function_exists('com_uninstall'))
{
if (com_uninstall() === false)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_CUSTOM'));
$retval = false;
}
}
// append this in case there was something else
$msg .= ob_get_contents();
ob_end_clean();
}
}
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
/**
* ---------------------------------------------------------------------------------------------
* Database Processing Section
* ---------------------------------------------------------------------------------------------
*/
/*
* Let's run the uninstall queries for the component
* If Joomla CMS 1.5 compatible, with discrete sql files - execute appropriate
* file for utf-8 support or non-utf support
*/
// Try for Joomla 1.5 type queries
// Second argument is the utf compatible version attribute
if (isset($this->manifest->uninstall->sql))
{
$utfresult = $this->parent->parseSQLFiles($this->manifest->uninstall->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_SQL_ERROR', $db->stderr(true)));
$retval = false;
}
}
$this->_removeAdminMenus($row);
/**
* ---------------------------------------------------------------------------------------------
* Filesystem Processing Section
* ---------------------------------------------------------------------------------------------
*/
// Let's remove those language files and media in the JROOT/images/ folder that are
// associated with the component we are uninstalling
$this->parent->removeFiles($this->manifest->media);
$this->parent->removeFiles($this->manifest->languages);
$this->parent->removeFiles($this->manifest->administration->languages, 1);
// Remove the schema version
$query = $db->getQuery(true);
$query->delete()->from('#__schemas')->where('extension_id = ' . $id);
$db->setQuery($query);
$db->execute();
// Remove the component container in the assets table.
$asset = JTable::getInstance('Asset');
if ($asset->loadByName($element))
{
$asset->delete();
}
// Remove categories for this component
$query = $db->getQuery(true);
$query->delete()->from('#__categories')->where('extension=' . $db->quote($element), 'OR')
->where('extension LIKE ' . $db->quote($element . '.%'));
$db->setQuery($query);
$db->execute();
// Check for errors.
if ($db->getErrorNum())
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_FAILED_DELETE_CATEGORIES'));
$this->setError($db->getErrorMsg());
$retval = false;
}
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $row->element, 'type' => 'component', 'client_id' => '', 'folder' => ''));
if ($uid)
{
$update->delete($uid);
}
// Now we need to delete the installation directories. This is the final step in uninstalling the component.
if (trim($row->element))
{
// Delete the component site directory
if (is_dir($this->parent->getPath('extension_site')))
{
if (!JFolder::delete($this->parent->getPath('extension_site')))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_FAILED_REMOVE_DIRECTORY_SITE'));
$retval = false;
}
}
// Delete the component admin directory
if (is_dir($this->parent->getPath('extension_administrator')))
{
if (!JFolder::delete($this->parent->getPath('extension_administrator')))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_COMP_UNINSTALL_FAILED_REMOVE_DIRECTORY_ADMIN'));
$retval = false;
}
}
// Now we will no longer need the extension object, so let's delete it and free up memory
$row->delete($row->extension_id);
unset($row);
return $retval;
}
else
{
// No component option defined... cannot delete what we don't know about
JError::raiseWarning(100, 'JLIB_INSTALLER_ERROR_COMP_UNINSTALL_NO_OPTION');
return false;
}
}
/**
* Method to build menu database entries for a component
*
* @return boolean True if successful
*
* @since 11.1
*/
protected function _buildAdminMenus()
{
// Initialise variables.
$db = $this->parent->getDbo();
$table = JTable::getInstance('menu');
$option = $this->get('element');
// If a component exists with this option in the table then we don't need to add menus
$query = $db->getQuery(true);
$query->select('m.id, e.extension_id');
$query->from('#__menu AS m');
$query->leftJoin('#__extensions AS e ON m.component_id = e.extension_id');
$query->where('m.parent_id = 1');
$query->where("m.client_id = 1");
$query->where('e.element = ' . $db->quote($option));
$db->setQuery($query);
$componentrow = $db->loadObject();
// Check if menu items exist
if ($componentrow)
{
// Don't do anything if overwrite has not been enabled
if (!$this->parent->isOverwrite())
{
return true;
}
// Remove existing menu items if overwrite has been enabled
if ($option)
{
$this->_removeAdminMenus($componentrow); // If something goes wrong, theres no way to rollback TODO: Search for better solution
}
$component_id = $componentrow->extension_id;
}
else
{
// Lets Find the extension id
$query->clear();
$query->select('e.extension_id');
$query->from('#__extensions AS e');
$query->where('e.element = ' . $db->quote($option));
$db->setQuery($query);
$component_id = $db->loadResult(); // TODO Find Some better way to discover the component_id
}
// Ok, now its time to handle the menus. Start with the component root menu, then handle submenus.
$menuElement = $this->manifest->administration->menu;
if ($menuElement)
{
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = (string) $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;
if (!$table->setLocation(1, 'last-child') || !$table->bind($data) || !$table->check() || !$table->store())
{
// The menu item already exists. Delete it and retry instead of throwing an error.
$query = $db->getQuery(true);
$query->select('id');
$query->from('#__menu');
$query->where('menutype = '.$db->quote('main'));
$query->where('client_id = 1');
$query->where('link = '.$db->quote('index.php?option='.$option));
$query->where('type = '.$db->quote('component'));
$query->where('parent_id = 1');
$query->where('home = 0');
$db->setQuery($query);
$menu_id = $db->loadResult();
if(!$menu_id) {
// Oops! Could not get the menu ID. Go back and rollback changes.
JError::raiseWarning(1, $table->getError());
return false;
} else {
// Remove the old menu item
$query = $db->getQuery(true);
$query->delete('#__menu');
$query->where('id = '.(int)$menu_id);
$db->setQuery($query);
$db->query();
// Retry creating the menu item
if (!$table->setLocation(1, 'last-child') || !$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.
*/
$this->parent->pushStep(array('type' => 'menu', 'id' => $component_id));
}
// 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;
if (!$table->setLocation(1, 'last-child') || !$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.
*/
$this->parent->pushStep(array('type' => 'menu', 'id' => $component_id));
}
$parent_id = $table->id;
/*
* Process SubMenus
*/
if (!$this->manifest->administration->submenu)
{
return true;
}
$parent_id = $table->id;
foreach ($this->manifest->administration->submenu->menu as $child)
{
$data = array();
$data['menutype'] = 'main';
$data['client_id'] = 1;
$data['title'] = (string) $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');
if (!$table->setLocation($parent_id, 'last-child') || !$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.
*/
$this->parent->pushStep(array('type' => 'menu', 'id' => $component_id));
}
return true;
}
/**
* Method to remove admin menu references to a component
*
* @param object &$row Component table object.
*
* @return boolean True if successful.
*
* @since 11.1
*/
protected function _removeAdminMenus(&$row)
{
// Initialise Variables
$db = $this->parent->getDbo();
$table = JTable::getInstance('menu');
$id = $row->extension_id;
// Get the ids of the menu items
$query = $db->getQuery(true);
$query->select('id');
$query->from('#__menu');
$query->where($query->qn('client_id') . ' = 1');
$query->where($query->qn('component_id') . ' = ' . (int) $id);
$db->setQuery($query);
$ids = $db->loadColumn();
// Check for error
if ($error = $db->getErrorMsg())
{
JError::raiseWarning('', JText::_('JLIB_INSTALLER_ERROR_COMP_REMOVING_ADMIN_MENUS_FAILED'));
if ($error && $error != 1)
{
JError::raiseWarning(100, $error);
}
return false;
}
elseif (!empty($ids))
{
// Iterate the items to delete each one.
foreach ($ids as $menuid)
{
if (!$table->delete((int) $menuid))
{
$this->setError($table->getError());
return false;
}
}
// Rebuild the whole tree
$table->rebuild();
}
return true;
}
/**
* Custom rollback method
* - Roll back the component menu item
*
* @param array $step Installation step to rollback.
*
* @return boolean True on success
*
* @since 11.1
*/
protected function _rollback_menu($step)
{
return $this->_removeAdminMenus((object) array('extension_id' => $step['id']));
}
/**
* Discover unregistered extensions.
*
* @return array A list of extensions.
*
* @since 11.1
*/
public function discover()
{
$results = array();
$site_components = JFolder::folders(JPATH_SITE . '/components');
$admin_components = JFolder::folders(JPATH_ADMINISTRATOR . '/components');
foreach ($site_components as $component)
{
if (file_exists(JPATH_SITE . '/components/' . $component . '/' . str_replace('com_', '', $component) . '.xml'))
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(
JPATH_SITE . '/components/' . $component . '/' . str_replace('com_', '', $component) . '.xml'
);
$extension = JTable::getInstance('extension');
$extension->set('type', 'component');
$extension->set('client_id', 0);
$extension->set('element', $component);
$extension->set('name', $component);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
}
foreach ($admin_components as $component)
{
if (file_exists(JPATH_ADMINISTRATOR . '/components/' . $component . '/' . str_replace('com_', '', $component) . '.xml'))
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(
JPATH_ADMINISTRATOR . '/components/' . $component . '/' . str_replace('com_', '', $component) . '.xml'
);
$extension = JTable::getInstance('extension');
$extension->set('type', 'component');
$extension->set('client_id', 1);
$extension->set('element', $component);
$extension->set('name', $component);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
}
return $results;
}
/**
* Install unregistered extensions that have been discovered.
*
* @return mixed
*
* @since 11.1
*/
public function discover_install()
{
// Need to find to find where the XML file is since we don't store this normally
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$short_element = str_replace('com_', '', $this->parent->extension->element);
$manifestPath = $client->path . '/components/' . $this->parent->extension->element . '/' . $short_element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$this->parent->setPath('source', $client->path . '/components/' . $this->parent->extension->element);
$this->parent->setPath('extension_root', $this->parent->getPath('source'));
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
$this->parent->extension->params = $this->parent->getParams();
try
{
$this->parent->extension->store();
}
catch (JException $e)
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_COMP_DISCOVER_STORE_DETAILS'));
return false;
}
// now we need to run any SQL it has, languages, media or menu stuff
// Get a database connector object
$db = $this->parent->getDbo();
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
/**
* ---------------------------------------------------------------------------------------------
* Manifest Document Setup Section
* ---------------------------------------------------------------------------------------------
*/
// Set the extensions name
$name = strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
if (substr($name, 0, 4) == "com_")
{
$element = $name;
}
else
{
$element = "com_$name";
}
$this->set('name', $name);
$this->set('element', $element);
// Get the component description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_((string) $description));
}
else
{
$this->parent->set('message', '');
}
// Set the installation target paths
$this->parent->setPath('extension_site', JPath::clean(JPATH_SITE . '/components/' . $this->get('element')));
$this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $this->get('element')));
$this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // copy this as its used as a common base
/**
* ---------------------------------------------------------------------------------------------
* Basic Checks Section
* ---------------------------------------------------------------------------------------------
*/
// Make sure that we have an admin element
if (!$this->manifest->administration)
{
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_COMP_INSTALL_ADMIN_ELEMENT'));
return false;
}
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// create a new instance
$this->parent->manifestClass = new $classname($this);
// and set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight('discover_install', $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg = ob_get_contents(); // create msg object; first use here
ob_end_clean();
// Normally we would copy files and create directories, lets skip to the optional files
// Note: need to dereference things!
// Parse optional tags
//$this->parent->parseMedia($this->manifest->media);
// We don't do language because 1.6 suggests moving to extension based languages
//$this->parent->parseLanguages($this->manifest->languages);
//$this->parent->parseLanguages($this->manifest->administration->languages, 1);
/**
* ---------------------------------------------------------------------------------------------
* Database Processing Section
* ---------------------------------------------------------------------------------------------
*/
/*
* Let's run the install queries for the component
* If Joomla 1.5 compatible, with discreet sql files - execute appropriate
* file for utf-8 support or non-utf-8 support
*/
// Try for Joomla 1.5 type queries
// second argument is the utf compatible version attribute
if (isset($this->manifest->install->sql))
{
$utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_SQL_ERROR', $db->stderr(true)));
return false;
}
}
// Time to build the admin menus
if (!$this->_buildAdminMenus($this->parent->extension->extension_id))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ABORT_COMP_BUILDADMINMENUS_FAILED'));
//$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $db->stderr(true)));
//return false;
}
/**
* ---------------------------------------------------------------------------------------------
* Custom Installation Script Section
* ---------------------------------------------------------------------------------------------
*/
/*
* If we have an install script, lets include it, execute the custom
* install method, and append the return value from the custom install
* method to the installation message.
*/
// start legacy support
if ($this->get('install_script'))
{
if (is_file($this->parent->getPath('extension_administrator') . '/' . $this->get('install_script')))
{
ob_start();
ob_implicit_flush(false);
require_once $this->parent->getPath('extension_administrator') . '/' . $this->get('install_script');
if (function_exists('com_install'))
{
if (com_install() === false)
{
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
}
}
// End legacy support
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'install'))
{
if ($this->parent->manifestClass->install($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
/**
* ---------------------------------------------------------------------------------------------
* Finalization and Cleanup Section
* ---------------------------------------------------------------------------------------------
*/
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $this->get('element'), 'type' => 'component', 'client_id' => '', 'folder' => ''));
if ($uid)
{
$update->delete($uid);
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight('discover_install', $this);
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $this->parent->extension->extension_id;
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure
*
* @since 11.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$short_element = str_replace('com_', '', $this->parent->extension->element);
$manifestPath = $client->path . '/components/' . $this->parent->extension->element . '/' . $short_element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (JException $e)
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_COMP_REFRESH_MANIFEST_CACHE'));
return false;
}
}
}
PK Z?\+(N N adapters/language.phpnu W+A parent->getPath('source');
if (!$source)
{
$this->parent
->setPath(
'source',
($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/language/' . $this->parent->extension->element
);
}
$this->manifest = $this->parent->getManifest();
$root = $this->manifest->document;
// Get the client application target
if ((string) $this->manifest->attributes()->client == 'both')
{
JError::raiseWarning(42, JText::_('JLIB_INSTALLER_ERROR_DEPRECATED_FORMAT'));
$element = $this->manifest->site->files;
if (!$this->_install('site', JPATH_SITE, 0, $element))
{
return false;
}
$element = $this->manifest->administration->files;
if (!$this->_install('administrator', JPATH_ADMINISTRATOR, 1, $element))
{
return false;
}
// This causes an issue because we have two eid's, *sigh* nasty hacks!
return true;
}
elseif ($cname = (string) $this->manifest->attributes()->client)
{
// Attempt to map the client to a base path
$client = JApplicationHelper::getClientInfo($cname, true);
if ($client === null)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname)));
return false;
}
$basePath = $client->path;
$clientId = $client->id;
$element = $this->manifest->files;
return $this->_install($cname, $basePath, $clientId, $element);
}
else
{
// No client attribute was found so we assume the site as the client
$cname = 'site';
$basePath = JPATH_SITE;
$clientId = 0;
$element = $this->manifest->files;
return $this->_install($cname, $basePath, $clientId, $element);
}
}
/**
* Install function that is designed to handle individual clients
*
* @param string $cname Cname @todo: not used
* @param string $basePath The base name.
* @param integer $clientId The client id.
* @param object &$element The XML element.
*
* @return boolean
*
* @since 11.1
*/
protected function _install($cname, $basePath, $clientId, &$element)
{
$this->manifest = $this->parent->getManifest();
// Get the language name
// Set the extensions name
$name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd');
$this->set('name', $name);
// Get the Language tag [ISO tag, eg. en-GB]
$tag = (string) $this->manifest->tag;
// Check if we found the tag - if we didn't, we may be trying to install from an older language package
if (!$tag)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG')));
return false;
}
$this->set('tag', $tag);
// Set the language installation path
$this->parent->setPath('extension_site', $basePath . '/language/' . $tag);
// Do we have a meta file in the file list? In other words... is this a core language pack?
if ($element && count($element->children()))
{
$files = $element->children();
foreach ($files as $file)
{
if ((string) $file->attributes()->file == 'meta')
{
$this->_core = true;
break;
}
}
}
// Either we are installing a core pack or a core pack must exist for the language we are installing.
if (!$this->_core)
{
if (!JFile::exists($this->parent->getPath('extension_site') . '/' . $this->get('tag') . '.xml'))
{
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_NO_CORE_LANGUAGE', $this->get('tag'))));
return false;
}
}
// If the language directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_site')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_site')))
{
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT',
JText::sprintf('JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED', $this->parent->getPath('extension_site'))
)
);
return false;
}
}
else
{
// Look for an update function or update tag
$updateElement = $this->manifest->update;
// Upgrade manually set or
// Update function available or
// Update tag detected
if ($this->parent->isUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update'))
|| $updateElement)
{
return $this->update(); // transfer control to the update function
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is set
// We didn't have overwrite set, find an update function or find an update tag so lets call it safe
if (file_exists($this->parent->getPath('extension_site')))
{
// If the site exists say so.
JError::raiseWarning(
1,
JText::sprintf(
'JLIB_INSTALLER_ABORT',
JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_site'))
)
);
}
else
{
// If the admin exists say so.
JError::raiseWarning(
1,
JText::sprintf(
'JLIB_INSTALLER_ABORT',
JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_administrator'))
)
);
}
return false;
}
}
/*
* If we created the language directory we will want to remove it if we
* have to roll back the installation, so let's add it to the installation
* step stack
*/
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
}
// Copy all the necessary files
if ($this->parent->parseFiles($element) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseMedia($this->manifest->media);
// Copy all the necessary font files to the common pdf_fonts directory
$this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts');
$overwrite = $this->parent->setOverwrite(true);
if ($this->parent->parseFiles($this->manifest->fonts) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
$this->parent->setOverwrite($overwrite);
// Get the language description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Add an entry to the extension table with a whole heap of defaults
$row = JTable::getInstance('extension');
$row->set('name', $this->get('name'));
$row->set('type', 'language');
$row->set('element', $this->get('tag'));
// There is no folder for languages
$row->set('folder', '');
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', 0);
$row->set('client_id', $clientId);
$row->set('params', $this->parent->getParams());
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError()));
return false;
}
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => '', 'folder' => ''));
if ($uid)
{
$update->delete($uid);
}
return $row->get('extension_id');
}
/**
* Custom update method
*
* @return boolean True on success, false on failure
*
* @since 11.1
*/
public function update()
{
$xml = $this->parent->getManifest();
$this->manifest = $xml;
$cname = $xml->attributes()->client;
// Attempt to map the client to a base path
$client = JApplicationHelper::getClientInfo($cname, true);
if ($client === null || (empty($cname) && $cname !== 0))
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname)));
return false;
}
$basePath = $client->path;
$clientId = $client->id;
// Get the language name
// Set the extensions name
$name = (string) $this->manifest->name;
$name = JFilterInput::getInstance()->clean($name, 'cmd');
$this->set('name', $name);
// Get the Language tag [ISO tag, eg. en-GB]
$tag = (string) $xml->tag;
// Check if we found the tag - if we didn't, we may be trying to install from an older language package
if (!$tag)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG')));
return false;
}
$this->set('tag', $tag);
$folder = $tag;
// Set the language installation path
$this->parent->setPath('extension_site', $basePath . '/language/' . $this->get('tag'));
// Do we have a meta file in the file list? In other words... is this a core language pack?
if (count($xml->files->children()))
{
foreach ($xml->files->children() as $file)
{
if ((string) $file->attributes()->file == 'meta')
{
$this->_core = true;
break;
}
}
}
// Either we are installing a core pack or a core pack must exist for the language we are installing.
if (!$this->_core)
{
if (!JFile::exists($this->parent->getPath('extension_site') . '/' . $this->get('tag') . '.xml'))
{
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_NO_CORE_LANGUAGE', $this->get('tag'))));
return false;
}
}
// Copy all the necessary files
if ($this->parent->parseFiles($xml->files) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseMedia($xml->media);
// Copy all the necessary font files to the common pdf_fonts directory
$this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts');
$overwrite = $this->parent->setOverwrite(true);
if ($this->parent->parseFiles($xml->fonts) === false)
{
// Install failed, rollback changes
$this->parent->abort();
return false;
}
$this->parent->setOverwrite($overwrite);
// Get the language description and set it as message
$this->parent->set('message', (string) $xml->description);
// Finalization and Cleanup Section
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => $clientId));
if ($uid)
{
$update->delete($uid);
}
// Update an entry to the extension table
$row = JTable::getInstance('extension');
$eid = $row->find(array('element' => strtolower($this->get('tag')), 'type' => 'language', 'client_id' => $clientId));
if ($eid)
{
$row->load($eid);
}
else
{
// set the defaults
$row->set('folder', ''); // There is no folder for language
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', 0);
$row->set('client_id', $clientId);
$row->set('params', $this->parent->getParams());
}
$row->set('name', $this->get('name'));
$row->set('type', 'language');
$row->set('element', $this->get('tag'));
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError()));
return false;
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight('update', $this);
}
$msg = ob_get_contents(); // append messages
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->get('extension_id');
}
/**
* Custom uninstall method
*
* @param string $eid The tag of the language to uninstall
*
* @return mixed Return value for uninstall method in component uninstall file
*
* @since 11.1
*/
public function uninstall($eid)
{
// Load up the extension details
$extension = JTable::getInstance('extension');
$extension->load($eid);
// Grab a copy of the client details
$client = JApplicationHelper::getClientInfo($extension->get('client_id'));
// Check the element isn't blank to prevent nuking the languages directory...just in case
$element = $extension->get('element');
if (empty($element))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_ELEMENT_EMPTY'));
return false;
}
// Check that the language is not protected, Normally en-GB.
$protected = $extension->get('protected');
if ($protected == 1)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PROTECTED'));
return false;
}
// Verify that it's not the default language for that client
$params = JComponentHelper::getParams('com_languages');
if ($params->get($client->name) == $element)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DEFAULT'));
return false;
}
// Construct the path from the client, the language and the extension element name
$path = $client->path . '/language/' . $element;
// Get the package manifest object and remove media
$this->parent->setPath('source', $path);
// We do findManifest to avoid problem when uninstalling a list of extension: getManifest cache its manifest file
$this->parent->findManifest();
$this->manifest = $this->parent->getManifest();
$this->parent->removeFiles($this->manifest->media);
// Check it exists
if (!JFolder::exists($path))
{
// If the folder doesn't exist lets just nuke the row as well and presume the user killed it for us
$extension->delete();
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PATH_EMPTY'));
return false;
}
if (!JFolder::delete($path))
{
// If deleting failed we'll leave the extension entry in tact just in case
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DIRECTORY'));
return false;
}
// Remove the extension table entry
$extension->delete();
// Setting the language of users which have this language as the default language
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->from('#__users');
$query->select('*');
$db->setQuery($query);
$users = $db->loadObjectList();
if ($client->name == 'administrator')
{
$param_name = 'admin_language';
}
else
{
$param_name = 'language';
}
$count = 0;
foreach ($users as $user)
{
$registry = new JRegistry;
$registry->loadString($user->params);
if ($registry->get($param_name) == $element)
{
$registry->set($param_name, '');
$query = $db->getQuery(true);
$query->update('#__users');
$query->set('params=' . $db->quote($registry));
$query->where('id=' . (int) $user->id);
$db->setQuery($query);
$db->execute();
$count = $count + 1;
}
}
if (!empty($count))
{
JError::raiseNotice(500, JText::plural('JLIB_INSTALLER_NOTICE_LANG_RESET_USERS', $count));
}
// All done!
return true;
}
/**
* Custom discover method
* Finds language files
*
* @return boolean True on success
*
* @since 11.1
*/
public function discover()
{
$results = array();
$site_languages = JFolder::folders(JPATH_SITE . '/language');
$admin_languages = JFolder::folders(JPATH_ADMINISTRATOR . '/language');
foreach ($site_languages as $language)
{
if (file_exists(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml'))
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml');
$extension = JTable::getInstance('extension');
$extension->set('type', 'language');
$extension->set('client_id', 0);
$extension->set('element', $language);
$extension->set('name', $language);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
}
foreach ($admin_languages as $language)
{
if (file_exists(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml'))
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml');
$extension = JTable::getInstance('extension');
$extension->set('type', 'language');
$extension->set('client_id', 1);
$extension->set('element', $language);
$extension->set('name', $language);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
}
return $results;
}
/**
* Custom discover install method
* Basically updates the manifest cache and leaves everything alone
*
* @return integer The extension id
*
* @since 11.1
*/
public function discover_install()
{
// Need to find to find where the XML file is since we don't store this normally
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$short_element = $this->parent->extension->element;
$manifestPath = $client->path . '/language/' . $short_element . '/' . $short_element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$this->parent->setPath('source', $client->path . '/language/' . $short_element);
$this->parent->setPath('extension_root', $this->parent->getPath('source'));
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
//$this->parent->extension->params = $this->parent->getParams();
try
{
$this->parent->extension->store();
}
catch (JException $e)
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_LANG_DISCOVER_STORE_DETAILS'));
return false;
}
return $this->parent->extension->get('extension_id');
}
/**
* Refreshes the extension table cache
*
* @return boolean result of operation, true if updated, false on failure
*
* @since 11.1
*/
public function refreshManifestCache()
{
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/language/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
if ($this->parent->extension->store())
{
return true;
}
else
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE'));
return false;
}
}
}
PK Z?\ښ/!e !e adapters/module.phpnu W+A parent->getPath('source');
if (!$source)
{
$this->parent
->setPath(
'source',
($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/modules/' . $this->parent->extension->element
);
}
$this->manifest = $this->parent->getManifest();
if ($this->manifest->files)
{
$element = $this->manifest->files;
$extension = '';
if (count($element->children()))
{
foreach ($element->children() as $file)
{
if ((string) $file->attributes()->module)
{
$extension = strtolower((string) $file->attributes()->module);
break;
}
}
}
if ($extension)
{
$lang = JFactory::getLanguage();
$source = $path ? $path : ($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/modules/' . $extension;
$folder = (string) $element->attributes()->folder;
if ($folder && file_exists("$path/$folder"))
{
$source = "$path/$folder";
}
$client = (string) $this->manifest->attributes()->client;
$lang->load($extension . '.sys', $source, null, false, true)
|| $lang->load($extension . '.sys', constant('JPATH_' . strtoupper($client)), null, false, true);
}
}
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 11.1
*/
public function install()
{
// Get a database connector object
$db = $this->parent->getDbo();
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
// Manifest Document Setup Section
// Set the extensions name
$name = (string) $this->manifest->name;
$name = JFilterInput::getInstance()->clean($name, 'string');
$this->set('name', $name);
// Get the component description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Target Application Section
// Get the target application
if ($cname = (string) $this->manifest->attributes()->client)
{
// Attempt to map the client to a base path
$client = JApplicationHelper::getClientInfo($cname, true);
if ($client === false)
{
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_MOD_UNKNOWN_CLIENT', JText::_('JLIB_INSTALLER_' . $this->route), $client->name));
return false;
}
$basePath = $client->path;
$clientId = $client->id;
}
else
{
// No client attribute was found so we assume the site as the client
$cname = 'site';
$basePath = JPATH_SITE;
$clientId = 0;
}
// Set the installation path
$element = '';
if (count($this->manifest->files->children()))
{
foreach ($this->manifest->files->children() as $file)
{
if ((string) $file->attributes()->module)
{
$element = (string) $file->attributes()->module;
$this->set('element', $element);
break;
}
}
}
if (!empty($element))
{
$this->parent->setPath('extension_root', $basePath . '/modules/' . $element);
}
else
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_MOD_INSTALL_NOFILE', JText::_('JLIB_INSTALLER_' . $this->route)));
return false;
}
// Check to see if a module by the same name is already installed
// If it is, then update the table because if the files aren't there
// we can assume that it was (badly) uninstalled
// If it isn't, add an entry to extensions
$query = $db->getQuery(true);
$query->select($query->qn('extension_id'))->from($query->qn('#__extensions'));
$query->where($query->qn('element') . ' = ' . $query->q($element))->where($query->qn('client_id') . ' = ' . (int) $clientId);
$db->setQuery($query);
try
{
$db->execute();
}
catch (JException $e)
{
// Install failed, roll back changes
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_MOD_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true)));
return false;
}
$id = $db->loadResult();
// If the module directory already exists, then we will assume that the
// module is already installed or another module is using that
// directory.
// Check that this is either an issue where its not overwriting or it is
// set to upgrade anyway
if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->isOverwrite() || $this->parent->isUpgrade()))
{
// Look for an update function or update tag
$updateElement = $this->manifest->update;
// Upgrade manually set or
// Update function available or
// Update tag detected
if ($this->parent->isUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update'))
|| $updateElement)
{
// Force this one
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
if ($id)
{
// If there is a matching extension mark this as an update; semantics really
$this->route = 'Update';
}
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is set
// We didn't have overwrite set, find an update function or find an update tag so lets call it safe
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_MOD_INSTALL_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
// Installer Trigger Loading
// If there is an manifest class file, let's load it; we'll copy it later (don't have destination yet)
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance.
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later.
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file.
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_MOD_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create msg object; first use here
$msg = ob_get_contents();
ob_end_clean();
// Filesystem Processing Section
// If the module directory does not exist, lets create it
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_root')))
{
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_MOD_INSTALL_CREATE_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
// Since we created the module directory and will want to remove it if
// we have to roll back the installation, let's add it to the
// installation step stack
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
}
// Copy all necessary files
if ($this->parent->parseFiles($this->manifest->files, -1) === false)
{
// Install failed, roll back changes
$this->parent->abort();
return false;
}
// If there is a manifest script, let's copy it.
if ($this->get('manifest_script'))
{
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']) || $this->parent->isOverwrite())
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_MOD_INSTALL_MANIFEST'));
return false;
}
}
}
// Parse optional tags
$this->parent->parseMedia($this->manifest->media, $clientId);
$this->parent->parseLanguages($this->manifest->languages, $clientId);
// Parse deprecated tags
$this->parent->parseFiles($this->manifest->images, -1);
// Database Processing Section
$row = JTable::getInstance('extension');
// Was there a module already installed with the same name?
if ($id)
{
// Load the entry and update the manifest_cache
$row->load($id);
$row->name = $this->get('name'); // update name
$row->manifest_cache = $this->parent->generateManifestCache(); // update manifest
if (!$row->store())
{
// Install failed, roll back changes
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_MOD_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true)));
return false;
}
}
else
{
$row->set('name', $this->get('name'));
$row->set('type', 'module');
$row->set('element', $this->get('element'));
$row->set('folder', ''); // There is no folder for modules
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', $clientId == 1 ? 2 : 0);
$row->set('client_id', $clientId);
$row->set('params', $this->parent->getParams());
$row->set('custom_data', ''); // custom data
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_MOD_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true)));
return false;
}
// Set the insert id
$row->extension_id = $db->insertid();
// Since we have created a module item, we add it to the installation step stack
// so that if we have to rollback the changes we can undo it.
$this->parent->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id));
// Create unpublished module in jos_modules
$name = preg_replace('#[\*?]#', '', JText::_($this->get('name')));
$module = JTable::getInstance('module');
$module->set('title', $name);
$module->set('module', $this->get('element'));
$module->set('access', '1');
$module->set('showtitle', '1');
$module->set('client_id', $clientId);
$module->set('language', '*');
$module->store();
}
// Let's run the queries for the module
// If Joomla 1.5 compatible, with discrete sql files, execute appropriate
// file for utf-8 support or non-utf-8 support
// Try for Joomla 1.5 type queries
// Second argument is the utf compatible version attribute
if (strtolower($this->route) == 'install')
{
$utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
$this->parent
->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_MOD_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
// Set the schema version to be the latest update version
if ($this->manifest->update)
{
$this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id);
}
}
elseif (strtolower($this->route) == 'update')
{
if ($this->manifest->update)
{
$result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id);
if ($result === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_MOD_UPDATE_SQL_ERROR', $db->stderr(true)));
return false;
}
}
}
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
{
if ($this->parent->manifestClass->{$this->route}($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_MOD_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
// Finalization and Cleanup Section
// Lastly, we will copy the manifest file to its appropriate place.
if (!$this->parent->copyManifest(-1))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_MOD_INSTALL_COPY_SETUP'));
return false;
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight($this->route, $this);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->get('extension_id');
}
/**
* Custom update method
*
* This is really a shell for the install system
*
* @return boolean True on success.
*
* @since 11.1
*/
public function update()
{
// Set the overwrite setting
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
// Set the route for the install
$this->route = 'Update';
// Go to install which handles updates properly
return $this->install();
}
/**
* Custom discover method
*
* @return array JExtension list of extensions available
*
* @since 11.1
*/
public function discover()
{
$results = array();
$site_list = JFolder::folders(JPATH_SITE . '/modules');
$admin_list = JFolder::folders(JPATH_ADMINISTRATOR . '/modules');
$site_info = JApplicationHelper::getClientInfo('site', true);
$admin_info = JApplicationHelper::getClientInfo('administrator', true);
foreach ($site_list as $module)
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_SITE . "/modules/$module/$module.xml");
$extension = JTable::getInstance('extension');
$extension->set('type', 'module');
$extension->set('client_id', $site_info->id);
$extension->set('element', $module);
$extension->set('name', $module);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = clone $extension;
}
foreach ($admin_list as $module)
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_ADMINISTRATOR . "/modules/$module/$module.xml");
$extension = JTable::getInstance('extension');
$extension->set('type', 'module');
$extension->set('client_id', $admin_info->id);
$extension->set('element', $module);
$extension->set('name', $module);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = clone $extension;
}
return $results;
}
/**
* Custom discover_install method
*
* @return mixed Extension ID on success, boolean false on failure
*
* @since 11.1
*/
public function discover_install()
{
// Modules are like templates, and are one of the easiest
// If its not in the extensions table we just add it
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/modules/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$description = (string) $this->parent->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
// TODO: Re-evaluate this; should we run installation triggers? postflight perhaps?
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
$this->parent->extension->params = $this->parent->getParams();
if ($this->parent->extension->store())
{
return $this->parent->extension->get('extension_id');
}
else
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_MOD_DISCOVER_STORE_DETAILS'));
return false;
}
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure.
*
* @since 11.1
*/
public function refreshManifestCache()
{
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/modules/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
if ($this->parent->extension->store())
{
return true;
}
else
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE'));
return false;
}
}
/**
* Custom uninstall method
*
* @param integer $id The id of the module to uninstall
*
* @return boolean True on success
*
* @since 11.1
*/
public function uninstall($id)
{
// Initialise variables.
$row = null;
$retval = true;
$db = $this->parent->getDbo();
// First order of business will be to load the module object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id) || !strlen($row->element))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_ERRORUNKOWNEXTENSION'));
return false;
}
// Is the module we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_WARNCOREMODULE', $row->name));
return false;
}
// Get the extension root path
$element = $row->element;
$client = JApplicationHelper::getClientInfo($row->client_id);
if ($client === false)
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_UNKNOWN_CLIENT', $row->client_id));
return false;
}
$this->parent->setPath('extension_root', $client->path . '/modules/' . $element);
$this->parent->setPath('source', $this->parent->getPath('extension_root'));
// Get the package manifest objecct
// We do findManifest to avoid problem when uninstalling a list of extensions: getManifest cache its manifest file.
$this->parent->findManifest();
$this->manifest = $this->parent->getManifest();
// Attempt to load the language file; might have uninstall strings
$this->loadLanguage(($row->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/modules/' . $element);
// If there is an manifest class file, let's load it
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('extension_root') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
ob_start();
ob_implicit_flush(false);
// Run uninstall if possible
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
$msg = ob_get_contents();
ob_end_clean();
if (!($this->manifest instanceof SimpleXMLElement))
{
// Make sure we delete the folders
JFolder::delete($this->parent->getPath('extension_root'));
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_INVALID_NOTFOUND_MANIFEST'));
return false;
}
/*
* Let's run the uninstall queries for the component
* If Joomla 1.5 compatible, with discreet sql files - execute appropriate
* file for utf-8 support or non-utf support
*/
// Try for Joomla 1.5 type queries
// Second argument is the utf compatible version attribute
$utfresult = $this->parent->parseSQLFiles($this->manifest->uninstall->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_SQL_ERROR', $db->stderr(true)));
$retval = false;
}
// Remove the schema version
$query = $db->getQuery(true);
$query->delete()->from('#__schemas')->where('extension_id = ' . $row->extension_id);
$db->setQuery($query);
$db->execute();
// Remove other files
$this->parent->removeFiles($this->manifest->media);
$this->parent->removeFiles($this->manifest->languages, $row->client_id);
// Let's delete all the module copies for the type we are uninstalling
$query = $db->getQuery(true);
$query->select($query->qn('id'))->from($query->qn('#__modules'));
$query->where($query->qn('module') . ' = ' . $query->q($row->element));
$query->where($query->qn('client_id') . ' = ' . (int) $row->client_id);
$db->setQuery($query);
try
{
$modules = $db->loadColumn();
}
catch (JException $e)
{
$modules = array();
}
// Do we have any module copies?
if (count($modules))
{
// Ensure the list is sane
JArrayHelper::toInteger($modules);
$modID = implode(',', $modules);
// Wipe out any items assigned to menus
$query = 'DELETE' . ' FROM #__modules_menu' . ' WHERE moduleid IN (' . $modID . ')';
$db->setQuery($query);
try
{
$db->execute();
}
catch (JException $e)
{
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_EXCEPTION', $db->stderr(true)));
$retval = false;
}
// Wipe out any instances in the modules table
$query = 'DELETE' . ' FROM #__modules' . ' WHERE id IN (' . $modID . ')';
$db->setQuery($query);
try
{
$db->execute();
}
catch (JException $e)
{
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_EXCEPTION', $db->stderr(true)));
$retval = false;
}
}
// Now we will no longer need the module object, so let's delete it and free up memory
$row->delete($row->extension_id);
$query = 'DELETE FROM #__modules WHERE module = ' . $db->Quote($row->element) . ' AND client_id = ' . $row->client_id;
$db->setQuery($query);
try
{
// Clean up any other ones that might exist as well
$db->execute();
}
catch (JException $e)
{
// Ignore the error...
}
unset($row);
// Remove the installation folder
if (!JFolder::delete($this->parent->getPath('extension_root')))
{
// JFolder should raise an error
$retval = false;
}
return $retval;
}
/**
* Custom rollback method
* - Roll back the menu item
*
* @param array $arg Installation step to rollback
*
* @return boolean True on success
*
* @since 11.1
*/
protected function _rollback_menu($arg)
{
// Get database connector object
$db = $this->parent->getDbo();
// Remove the entry from the #__modules_menu table
$query = 'DELETE' . ' FROM #__modules_menu' . ' WHERE moduleid=' . (int) $arg['id'];
$db->setQuery($query);
try
{
return $db->execute();
}
catch (JException $e)
{
return false;
}
}
/**
* Custom rollback method
* - Roll back the module item
*
* @param array $arg Installation step to rollback
*
* @return boolean True on success
*
* @since 11.1
*/
protected function _rollback_module($arg)
{
// Get database connector object
$db = $this->parent->getDbo();
// Remove the entry from the #__modules table
$query = 'DELETE' . ' FROM #__modules' . ' WHERE id=' . (int) $arg['id'];
$db->setQuery($query);
try
{
return $db->execute();
}
catch (JException $e)
{
return false;
}
}
}
PK Z?\"*;2 ;2 adapters/library.phpnu W+A parent->getPath('source');
if (!$source)
{
$this->parent->setPath('source', JPATH_PLATFORM . '/' . $this->parent->extension->element);
}
$this->manifest = $this->parent->getManifest();
$extension = 'lib_' . strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
$name = strtolower((string) $this->manifest->libraryname);
$lang = JFactory::getLanguage();
$source = $path ? $path : JPATH_PLATFORM . "/$name";
$lang->load($extension . '.sys', $source, null, false, true)
|| $lang->load($extension . '.sys', JPATH_SITE, null, false, true);
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 11.1
*/
public function install()
{
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
// Manifest Document Setup Section
// Set the extensions name
$name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'string');
$element = str_replace('.xml', '', basename($this->parent->getPath('manifest')));
$this->set('name', $name);
$this->set('element', $element);
$db = $this->parent->getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName('extension_id'));
$query->from($db->quoteName('#__extensions'));
$query->where($db->quoteName('type') . ' = ' . $db->quote('library'));
$query->where($db->quoteName('element') . ' = ' . $db->quote($element));
$db->setQuery($query);
$result = $db->loadResult();
if ($result)
{
// Already installed, can we upgrade?
if ($this->parent->isOverwrite() || $this->parent->isUpgrade())
{
// We can upgrade, so uninstall the old one
$installer = new JInstaller; // we don't want to compromise this instance!
$installer->uninstall('library', $result);
}
else
{
// Abort the install, no upgrade possible
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_ALREADY_INSTALLED'));
return false;
}
}
// Get the libraries description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Set the installation path
$group = (string) $this->manifest->libraryname;
if (!$group)
{
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_NOFILE'));
return false;
}
else
{
$this->parent->setPath('extension_root', JPATH_PLATFORM . '/' . implode(DIRECTORY_SEPARATOR, explode('/', $group)));
}
// Filesystem Processing Section
// If the plugin directory does not exist, let's create it
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_root')))
{
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_LIB_INSTALL_FAILED_TO_CREATE_DIRECTORY', $this->parent->getPath('extension_root'))
);
return false;
}
}
// If we created the plugin directory and will want to remove it if we
// have to roll back the installation, let's add it to the installation
// step stack
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
}
// Copy all necessary files
if ($this->parent->parseFiles($this->manifest->files, -1) === false)
{
// Install failed, roll back changes
$this->parent->abort();
return false;
}
// Parse optional tags
$this->parent->parseLanguages($this->manifest->languages);
$this->parent->parseMedia($this->manifest->media);
// Extension Registration
$row = JTable::getInstance('extension');
$row->name = $this->get('name');
$row->type = 'library';
$row->element = $this->get('element');
$row->folder = ''; // There is no folder for modules
$row->enabled = 1;
$row->protected = 0;
$row->access = 1;
$row->client_id = 0;
$row->params = $this->parent->getParams();
$row->custom_data = ''; // custom data
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_LIB_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
// Finalization and Cleanup Section
// Lastly, we will copy the manifest file to its appropriate place.
$manifest = array();
$manifest['src'] = $this->parent->getPath('manifest');
$manifest['dest'] = JPATH_MANIFESTS . '/libraries/' . basename($this->parent->getPath('manifest'));
if (!$this->parent->copyFiles(array($manifest), true))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_COPY_SETUP'));
return false;
}
return $row->get('extension_id');
}
/**
* Custom update method
*
* @return boolean True on success
*
* @since 11.1
*/
public function update()
{
// Since this is just files, an update removes old files
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
// Manifest Document Setup Section
// Set the extensions name
$name = (string) $this->manifest->name;
$name = JFilterInput::getInstance()->clean($name, 'string');
$element = str_replace('.xml', '', basename($this->parent->getPath('manifest')));
$this->set('name', $name);
$this->set('element', $element);
$installer = new JInstaller; // we don't want to compromise this instance!
$db = $this->parent->getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName('extension_id'));
$query->from($db->quoteName('#__extensions'));
$query->where($db->quoteName('type') . ' = ' . $db->quote('library'));
$query->where($db->quoteName('element') . ' = ' . $db->quote($element));
$db->setQuery($query);
$result = $db->loadResult();
if ($result)
{
// Already installed, which would make sense
$installer->uninstall('library', $result);
}
// Now create the new files
return $this->install();
}
/**
* Custom uninstall method
*
* @param string $id The id of the library to uninstall.
*
* @return boolean True on success
*
* @since 11.1
*/
public function uninstall($id)
{
// Initialise variables.
$retval = true;
// First order of business will be to load the module object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id) || !strlen($row->element))
{
JError::raiseWarning(100, JText::_('ERRORUNKOWNEXTENSION'));
return false;
}
// Is the library we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_WARNCORELIBRARY'));
return false;
}
$manifestFile = JPATH_MANIFESTS . '/libraries/' . $row->element . '.xml';
// Because libraries may not have their own folders we cannot use the standard method of finding an installation manifest
if (file_exists($manifestFile))
{
$manifest = new JLibraryManifest($manifestFile);
// Set the plugin root path
$this->parent->setPath('extension_root', JPATH_PLATFORM . '/' . $manifest->libraryname);
$xml = JFactory::getXML($manifestFile);
// If we cannot load the XML file return null
if (!$xml)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_LOAD_MANIFEST'));
return false;
}
// Check for a valid XML root tag.
// TODO: Remove backwards compatibility in a future version
// Should be 'extension', but for backward compatibility we will accept 'install'.
if ($xml->getName() != 'install' && $xml->getName() != 'extension')
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_MANIFEST'));
return false;
}
$this->parent->removeFiles($xml->files, -1);
JFile::delete($manifestFile);
}
else
{
// Remove this row entry since its invalid
$row->delete($row->extension_id);
unset($row);
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_NOTFOUND_MANIFEST'));
return false;
}
// TODO: Change this so it walked up the path backwards so we clobber multiple empties
// If the folder is empty, let's delete it
if (JFolder::exists($this->parent->getPath('extension_root')))
{
if (is_dir($this->parent->getPath('extension_root')))
{
$files = JFolder::files($this->parent->getPath('extension_root'));
if (!count($files))
{
JFolder::delete($this->parent->getPath('extension_root'));
}
}
}
$this->parent->removeFiles($xml->media);
$this->parent->removeFiles($xml->languages);
$row->delete($row->extension_id);
unset($row);
return $retval;
}
/**
* Custom discover method
*
* @return array JExtension list of extensions available
*
* @since 11.1
*/
public function discover()
{
$results = array();
$file_list = JFolder::files(JPATH_MANIFESTS . '/libraries', '\.xml$');
foreach ($file_list as $file)
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_MANIFESTS . '/libraries/' . $file);
$file = JFile::stripExt($file);
$extension = JTable::getInstance('extension');
$extension->set('type', 'library');
$extension->set('client_id', 0);
$extension->set('element', $file);
$extension->set('name', $file);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
return $results;
}
/**
* Custom discover_install method
*
* @return boolean True on success
*
* @since 11.1
*/
public function discover_install()
{
/* Libraries are a strange beast; they are actually references to files
* There are two parts to a library which are disjunct in their locations
* 1) The manifest file (stored in /JPATH_MANIFESTS/libraries)
* 2) The actual files (stored in /JPATH_PLATFORM/libraryname)
* Thus installation of a library is the process of dumping files
* in two different places. As such it is impossible to perform
* any operation beyond mere registration of a library under the presumption
* that the files exist in the appropriate location so that come uninstall
* time they can be adequately removed.
*/
$manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = 1;
$this->parent->extension->params = $this->parent->getParams();
if ($this->parent->extension->store())
{
return true;
}
else
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_LIB_DISCOVER_STORE_DETAILS'));
return false;
}
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure
*
* @since 11.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
$manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (JException $e)
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_LIB_REFRESH_MANIFEST_CACHE'));
return false;
}
}
}
PK Z?\aP4b 4b adapters/plugin.phpnu W+A parent->getPath('source');
if (!$source)
{
$this->parent->setPath('source', JPATH_PLUGINS . '/' . $this->parent->extension->folder . '/' . $this->parent->extension->element);
}
$this->manifest = $this->parent->getManifest();
$element = $this->manifest->files;
if ($element)
{
$group = strtolower((string) $this->manifest->attributes()->group);
$name = '';
if (count($element->children()))
{
foreach ($element->children() as $file)
{
if ((string) $file->attributes()->plugin)
{
$name = strtolower((string) $file->attributes()->plugin);
break;
}
}
}
if ($name)
{
$extension = "plg_${group}_${name}";
$lang = JFactory::getLanguage();
$source = $path ? $path : JPATH_PLUGINS . "/$group/$name";
$folder = (string) $element->attributes()->folder;
if ($folder && file_exists("$path/$folder"))
{
$source = "$path/$folder";
}
$lang->load($extension . '.sys', $source, null, false, true)
|| $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, true);
}
}
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 11.1
*/
public function install()
{
// Get a database connector object
$db = $this->parent->getDbo();
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
$xml = $this->manifest;
// Manifest Document Setup Section
// Set the extension name
$name = (string) $xml->name;
$name = JFilterInput::getInstance()->clean($name, 'string');
$this->set('name', $name);
// Get the component description
$description = (string) $xml->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
/*
* Backward Compatibility
* @todo Deprecate in future version
*/
$type = (string) $xml->attributes()->type;
// Set the installation path
if (count($xml->files->children()))
{
foreach ($xml->files->children() as $file)
{
if ((string) $file->attributes()->$type)
{
$element = (string) $file->attributes()->$type;
break;
}
}
}
$group = (string) $xml->attributes()->group;
if (!empty($element) && !empty($group))
{
$this->parent->setPath('extension_root', JPATH_PLUGINS . '/' . $group . '/' . $element);
}
else
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_NO_FILE', JText::_('JLIB_INSTALLER_' . $this->route)));
return false;
}
// Check if we should enable overwrite settings
// Check to see if a plugin by the same name is already installed.
$query = $db->getQuery(true);
$query->select($query->qn('extension_id'))->from($query->qn('#__extensions'));
$query->where($query->qn('folder') . ' = ' . $query->q($group));
$query->where($query->qn('element') . ' = ' . $query->q($element));
$db->setQuery($query);
try
{
$db->execute();
}
catch (JException $e)
{
// Install failed, roll back changes
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true)));
return false;
}
$id = $db->loadResult();
// If it's on the fs...
if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->isOverwrite() || $this->parent->isUpgrade()))
{
$updateElement = $xml->update;
// Upgrade manually set or
// Update function available or
// Update tag detected
if ($this->parent->isUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update'))
|| $updateElement)
{
// Force this one
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
if ($id)
{
// If there is a matching extension mark this as an update; semantics really
$this->route = 'update';
}
}
elseif (!$this->parent->isOverwrite())
{
// Overwrite is set
// We didn't have overwrite set, find an update function or find an update tag so lets call it safe
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PLG_INSTALL_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
// Installer Trigger Loading
// If there is an manifest class file, let's load it; we'll copy it later (don't have destination yet).
if ((string) $xml->scriptfile)
{
$manifestScript = (string) $xml->scriptfile;
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// If a dash is present in the group name, remove it
$groupClass = str_replace('-', '', $group);
// Set the class name
$classname = 'plg' . $groupClass . $element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg = ob_get_contents(); // create msg object; first use here
ob_end_clean();
// Filesystem Processing Section
// If the plugin directory does not exist, lets create it
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
if (!$created = JFolder::create($this->parent->getPath('extension_root')))
{
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PLG_INSTALL_CREATE_DIRECTORY', JText::_('JLIB_INSTALLER_' . $this->route),
$this->parent->getPath('extension_root')
)
);
return false;
}
}
// If we're updating at this point when there is always going to be an extension_root find the old XML files
if ($this->route == 'update')
{
// Hunt for the original XML file
$old_manifest = null;
$tmpInstaller = new JInstaller; // create a new installer because findManifest sets stuff; side effects!
// Look in the extension root
$tmpInstaller->setPath('source', $this->parent->getPath('extension_root'));
if ($tmpInstaller->findManifest())
{
$old_manifest = $tmpInstaller->getManifest();
$this->oldFiles = $old_manifest->files;
}
}
// If we created the plugin directory and will want to remove it if we
// have to roll back the installation, let's add it to the installation
// step stack
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
}
// Copy all necessary files
if ($this->parent->parseFiles($xml->files, -1, $this->oldFiles) === false)
{
// Install failed, roll back changes
$this->parent->abort();
return false;
}
// Parse optional tags -- media and language files for plugins go in admin app
$this->parent->parseMedia($xml->media, 1);
$this->parent->parseLanguages($xml->languages, 1);
// If there is a manifest script, lets copy it.
if ($this->get('manifest_script'))
{
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']))
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent
->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_MANIFEST', JText::_('JLIB_INSTALLER_' . $this->route)));
return false;
}
}
}
// Database Processing Section
$row = JTable::getInstance('extension');
// Was there a plugin with the same name already installed?
if ($id)
{
if (!$this->parent->isOverwrite())
{
// Install failed, roll back changes
$this->parent
->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PLG_INSTALL_ALLREADY_EXISTS', JText::_('JLIB_INSTALLER_' . $this->route),
$this->get('name')
)
);
return false;
}
$row->load($id);
$row->name = $this->get('name');
$row->manifest_cache = $this->parent->generateManifestCache();
$row->store(); // update the manifest cache and name
}
else
{
// Store in the extensions table (1.6)
$row->name = $this->get('name');
$row->type = 'plugin';
$row->ordering = 0;
$row->element = $element;
$row->folder = $group;
$row->enabled = 0;
$row->protected = 0;
$row->access = 1;
$row->client_id = 0;
$row->params = $this->parent->getParams();
// Custom data
$row->custom_data = '';
// System data
$row->system_data = '';
$row->manifest_cache = $this->parent->generateManifestCache();
// Editor plugins are published by default
if ($group == 'editors')
{
$row->enabled = 1;
}
if (!$row->store())
{
// Install failed, roll back changes
$this->parent
->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
// Since we have created a plugin item, we add it to the installation step stack
// so that if we have to rollback the changes we can undo it.
$this->parent->pushStep(array('type' => 'extension', 'id' => $row->extension_id));
$id = $row->extension_id;
}
// Let's run the queries for the module
// If Joomla 1.5 compatible, with discreet sql files - execute appropriate
// file for utf-8 support or non-utf-8 support
// Try for Joomla 1.5 type queries
// Second argument is the utf compatible version attribute
if (strtolower($this->route) == 'install')
{
$utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
$this->parent
->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
// Set the schema version to be the latest update version
if ($this->manifest->update)
{
$this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id);
}
}
elseif (strtolower($this->route) == 'update')
{
if ($this->manifest->update)
{
$result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id);
if ($result === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_UPDATE_SQL_ERROR', $db->stderr(true)));
return false;
}
}
}
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
{
if ($this->parent->manifestClass->{$this->route}($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
// Finalization and Cleanup Section
// Lastly, we will copy the manifest file to its appropriate place.
if (!$this->parent->copyManifest(-1))
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_COPY_SETUP', JText::_('JLIB_INSTALLER_' . $this->route)));
return false;
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight($this->route, $this);
}
// Append messages
$msg .= ob_get_contents();
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $id;
}
/**
* Custom update method
*
* @return boolean True on success
*
* @since 11.1
*/
public function update()
{
// Set the overwrite setting
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
// Set the route for the install
$this->route = 'update';
// Go to install which handles updates properly
return $this->install();
}
/**
* Custom uninstall method
*
* @param integer $id The id of the plugin to uninstall
*
* @return boolean True on success
*
* @since 11.1
*/
public function uninstall($id)
{
$this->route = 'uninstall';
// Initialise variables.
$row = null;
$retval = true;
$db = $this->parent->getDbo();
// First order of business will be to load the plugin object table from the database.
// This should give us the necessary information to proceed.
$row = JTable::getInstance('extension');
if (!$row->load((int) $id))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_ERRORUNKOWNEXTENSION'));
return false;
}
// Is the plugin we are trying to uninstall a core one?
// Because that is not a good idea...
if ($row->protected)
{
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_WARNCOREPLUGIN', $row->name));
return false;
}
// Get the plugin folder so we can properly build the plugin path
if (trim($row->folder) == '')
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_FOLDER_FIELD_EMPTY'));
return false;
}
// Set the plugin root path
if (is_dir(JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element))
{
// Use 1.6 plugins
$this->parent->setPath('extension_root', JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element);
}
else
{
// Use Legacy 1.5 plugins
$this->parent->setPath('extension_root', JPATH_PLUGINS . '/' . $row->folder);
}
// Because 1.5 plugins don't have their own folders we cannot use the standard method of finding an installation manifest
// Since 1.6 they do, however until we move to 1.7 and remove 1.6 legacy we still need to use this method.
// When we get there it'll be something like "$this->parent->findManifest();$manifest = $this->parent->getManifest();"
$manifestFile = $this->parent->getPath('extension_root') . '/' . $row->element . '.xml';
if (!file_exists($manifestFile))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_INVALID_NOTFOUND_MANIFEST'));
return false;
}
$xml = JFactory::getXML($manifestFile);
$this->manifest = $xml;
// If we cannot load the XML file return null
if (!$xml)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_LOAD_MANIFEST'));
return false;
}
/*
* Check for a valid XML root tag.
* @todo: Remove backwards compatibility in a future version
* Should be 'extension', but for backward compatibility we will accept 'install'.
*/
if ($xml->getName() != 'install' && $xml->getName() != 'extension')
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_INVALID_MANIFEST'));
return false;
}
// Attempt to load the language file; might have uninstall strings
$this->parent->setPath('source', JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element);
$this->loadLanguage(JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element);
// Installer Trigger Loading
// If there is an manifest class file, let's load it; we'll copy it later (don't have dest yet)
$manifestScript = (string) $xml->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// If a dash is present in the folder, remove it
$folderClass = str_replace('-', '', $row->folder);
// Set the class name
$classname = 'plg' . $folderClass . $row->element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
// Run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
// Create msg object; first use here
$msg = ob_get_contents();
ob_end_clean();
// Let's run the queries for the module
// If Joomla 1.5 compatible, with discreet sql files - execute appropriate
// file for utf-8 support or non-utf-8 support
// Try for Joomla 1.5 type queries
// Second argument is the utf compatible version attribute
$utfresult = $this->parent->parseSQLFiles($xml->{strtolower($this->route)}->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_UNINSTALL_SQL_ERROR', $db->stderr(true)));
return false;
}
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
// Append messages
$msg = ob_get_contents();
ob_end_clean();
// Remove the plugin files
$this->parent->removeFiles($xml->images, -1);
$this->parent->removeFiles($xml->files, -1);
JFile::delete($manifestFile);
// Remove all media and languages as well
$this->parent->removeFiles($xml->media);
$this->parent->removeFiles($xml->languages, 1);
// Remove the schema version
$query = $db->getQuery(true);
$query->delete()->from('#__schemas')->where('extension_id = ' . $row->extension_id);
$db->setQuery($query);
$db->execute();
// Now we will no longer need the plugin object, so let's delete it
$row->delete($row->extension_id);
unset($row);
// If the folder is empty, let's delete it
$files = JFolder::files($this->parent->getPath('extension_root'));
JFolder::delete($this->parent->getPath('extension_root'));
if ($msg)
{
$this->parent->set('extension_message', $msg);
}
return $retval;
}
/**
* Custom discover method
*
* @return array JExtension) list of extensions available
*
* @since 11.1
*/
public function discover()
{
$results = array();
$folder_list = JFolder::folders(JPATH_SITE . '/plugins');
foreach ($folder_list as $folder)
{
$file_list = JFolder::files(JPATH_SITE . '/plugins/' . $folder, '\.xml$');
foreach ($file_list as $file)
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_SITE . '/plugins/' . $folder . '/' . $file);
$file = JFile::stripExt($file);
// Ignore example plugins
if ($file == 'example')
{
continue;
}
$extension = JTable::getInstance('extension');
$extension->set('type', 'plugin');
$extension->set('client_id', 0);
$extension->set('element', $file);
$extension->set('folder', $folder);
$extension->set('name', $file);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
$folder_list = JFolder::folders(JPATH_SITE . '/plugins/' . $folder);
foreach ($folder_list as $plugin_folder)
{
$file_list = JFolder::files(JPATH_SITE . '/plugins/' . $folder . '/' . $plugin_folder, '\.xml$');
foreach ($file_list as $file)
{
$manifest_details = JApplicationHelper::parseXMLInstallFile(
JPATH_SITE . '/plugins/' . $folder . '/' . $plugin_folder . '/' . $file
);
$file = JFile::stripExt($file);
if ($file == 'example')
{
continue;
}
// ignore example plugins
$extension = JTable::getInstance('extension');
$extension->set('type', 'plugin');
$extension->set('client_id', 0);
$extension->set('element', $file);
$extension->set('folder', $folder);
$extension->set('name', $file);
$extension->set('state', -1);
$extension->set('manifest_cache', json_encode($manifest_details));
$results[] = $extension;
}
}
}
return $results;
}
/**
* Custom discover_install method.
*
* @return mixed
*
* @since 11.1
*/
public function discover_install()
{
// Plugins use the extensions table as their primary store
// Similar to modules and templates, rather easy
// If it's not in the extensions table we just add it
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
if (is_dir($client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element))
{
$manifestPath = $client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element . '/'
. $this->parent->extension->element . '.xml';
}
else
{
$manifestPath = $client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element . '.xml';
}
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$description = (string) $this->parent->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($manifestPath);
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->state = 0;
$this->parent->extension->name = $manifest_details['name'];
$this->parent->extension->enabled = ('editors' == $this->parent->extension->folder) ? 1 : 0;
$this->parent->extension->params = $this->parent->getParams();
if ($this->parent->extension->store())
{
return $this->parent->extension->get('extension_id');
}
else
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_PLG_DISCOVER_STORE_DETAILS'));
return false;
}
}
/**
* Refreshes the extension table cache.
*
* @return boolean Result of operation, true if updated, false on failure.
*
* @since 11.1
*/
public function refreshManifestCache()
{
// Plugins use the extensions table as their primary store
// Similar to modules and templates, rather easy
// If it's not in the extensions table we just add it
$client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
$manifestPath = $client->path . '/plugins/' . $this->parent->extension->folder . '/' . $this->parent->extension->element . '/'
. $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
if ($this->parent->extension->store())
{
return true;
}
else
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_PLG_REFRESH_MANIFEST_CACHE'));
return false;
}
}
}
PK Z?\UM UM adapters/file.phpnu W+A manifest = $this->parent->getManifest();
$extension = 'files_' . str_replace('files_', '', strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd')));
$lang = JFactory::getLanguage();
$source = $path;
$lang->load($extension . '.sys', $source, null, false, true)
|| $lang->load($extension . '.sys', JPATH_SITE, null, false, true);
}
/**
* Custom install method
*
* @return boolean True on success
*
* @since 11.1
*/
public function install()
{
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
// Manifest Document Setup Section
// Set the extension's name
$name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'string');
$this->set('name', $name);
// Set element
$manifestPath = JPath::clean($this->parent->getPath('manifest'));
$element = preg_replace('/\.xml/', '', basename($manifestPath));
$this->set('element', $element);
// Get the component description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
//Check if the extension by the same name is already installed
if ($this->extensionExistsInSystem($element))
{
// Package with same name already exists
if (!$this->parent->isOverwrite())
{
// we're not overwriting so abort
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_SAME_NAME'));
return false;
}
else
{
// swap to the update route
$this->route = 'update';
}
}
// Set the file root path
$this->parent->setPath('extension_root', JPATH_ROOT);
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// create a new instance
$this->parent->manifestClass = new $classname($this);
// and set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
// run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg = ob_get_contents(); // create msg object; first use here
ob_end_clean();
// Populate File and Folder List to copy
$this->populateFilesAndFolderList();
// Filesystem Processing Section
// Now that we have folder list, lets start creating them
foreach ($this->folderList as $folder)
{
if (!JFolder::exists($folder))
{
if (!$created = JFolder::create($folder))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $folder));
// If installation fails, rollback
$this->parent->abort();
return false;
}
// Since we created a directory and will want to remove it if we have to roll back.
// the installation due to some errors, let's add it to the installation step stack.
if ($created)
{
$this->parent->pushStep(array('type' => 'folder', 'path' => $folder));
}
}
}
// Now that we have file list, let's start copying them
$this->parent->copyFiles($this->fileList);
// Parse optional tags
$this->parent->parseLanguages($this->manifest->languages);
// Finalization and Cleanup Section
// Get a database connector object
$db = $this->parent->getDbo();
// Check to see if a module by the same name is already installed
// If it is, then update the table because if the files aren't there
// we can assume that it was (badly) uninstalled
// If it isn't, add an entry to extensions
$query = $db->getQuery(true);
$query->select($query->qn('extension_id'))
->from($query->qn('#__extensions'));
$query->where($query->qn('type') . ' = ' . $query->q('file'))
->where($query->qn('element') . ' = ' . $query->q($element));
$db->setQuery($query);
try
{
$db->execute();
}
catch (JException $e)
{
// Install failed, roll back changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
$id = $db->loadResult();
$row = JTable::getInstance('extension');
if ($id)
{
// Load the entry and update the manifest_cache
$row->load($id);
// Update name
$row->set('name', $this->get('name'));
// Update manifest
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
}
else
{
// Add an entry to the extension table with a whole heap of defaults
$row->set('name', $this->get('name'));
$row->set('type', 'file');
$row->set('element', $this->get('element'));
// There is no folder for files so leave it blank
$row->set('folder', '');
$row->set('enabled', 1);
$row->set('protected', 0);
$row->set('access', 0);
$row->set('client_id', 0);
$row->set('params', '');
$row->set('system_data', '');
$row->set('manifest_cache', $this->parent->generateManifestCache());
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK', $db->stderr(true)));
return false;
}
// Set the insert id
$row->set('extension_id', $db->insertid());
// Since we have created a module item, we add it to the installation step stack
// so that if we have to rollback the changes we can undo it.
$this->parent->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id));
}
/*
* Let's run the queries for the file
*/
// second argument is the utf compatible version attribute
if (strtolower($this->route) == 'install')
{
$utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
if ($utfresult === false)
{
// Install failed, rollback changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
);
return false;
}
// Set the schema version to be the latest update version
if ($this->manifest->update)
{
$this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id);
}
}
elseif (strtolower($this->route) == 'update')
{
if ($this->manifest->update)
{
$result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id);
if ($result === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_UPDATE_SQL_ERROR', $db->stderr(true)));
return false;
}
}
}
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
{
if ($this->parent->manifestClass->{$this->route}($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
// Lastly, we will copy the manifest file to its appropriate place.
$manifest = array();
$manifest['src'] = $this->parent->getPath('manifest');
$manifest['dest'] = JPATH_MANIFESTS . '/files/' . basename($this->parent->getPath('manifest'));
if (!$this->parent->copyFiles(array($manifest), true))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_COPY_SETUP'));
return false;
}
// Clobber any possible pending updates
$update = JTable::getInstance('update');
$uid = $update->find(
array('element' => $this->get('element'), 'type' => 'file', 'client_id' => '', 'folder' => '')
);
if ($uid)
{
$update->delete($uid);
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight($this->route, $this);
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->get('extension_id');
}
/**
* Custom update method
*
* @return boolean True on success
*
* @since 11.1
*/
public function update()
{
// Set the overwrite setting
$this->parent->setOverwrite(true);
$this->parent->setUpgrade(true);
$this->route = 'update';
// ...and adds new files
return $this->install();
}
/**
* Custom uninstall method
*
* @param string $id The id of the file to uninstall
*
* @return boolean True on success
*
* @since 11.1
*/
public function uninstall($id)
{
// Initialise variables.
$row = JTable::getInstance('extension');
if (!$row->load($id))
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_ENTRY'));
return false;
}
if ($row->protected)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_WARNCOREFILE'));
return false;
}
$retval = true;
$manifestFile = JPATH_MANIFESTS . '/files/' . $row->element . '.xml';
// Because files may not have their own folders we cannot use the standard method of finding an installation manifest
if (file_exists($manifestFile))
{
// Set the plugin root path
$this->parent->setPath('extension_root', JPATH_ROOT); // . '/files/' . $manifest->filename);
$xml = JFactory::getXML($manifestFile);
// If we cannot load the XML file return null
if (!$xml)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_MANIFEST'));
return false;
}
/*
* Check for a valid XML root tag.
*/
if ($xml->getName() != 'extension')
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_MANIFEST'));
return false;
}
$this->manifest = $xml;
// If there is an manifest class file, let's load it
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('extension_root') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $row->element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
ob_start();
ob_implicit_flush(false);
// Run uninstall if possible
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
$msg = ob_get_contents();
ob_end_clean();
/*
* Let's run the uninstall queries for the component
* If Joomla 1.5 compatible, with discreet sql files - execute appropriate
* file for utf-8 support or non-utf support
*/
// Try for Joomla 1.5 type queries
// Second argument is the utf compatible version attribute
$utfresult = $this->parent->parseSQLFiles($this->manifest->uninstall->sql);
$db = JFactory::getDbo();
if ($utfresult === false)
{
// Install failed, rollback changes
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_SQL_ERROR', $db->stderr(true)));
$retval = false;
}
// Remove the schema version
$query = $db->getQuery(true);
$query->delete()
->from('#__schemas')
->where('extension_id = ' . $row->extension_id);
$db->setQuery($query);
$db->execute();
// Set root folder names
$packagePath = $this->parent->getPath('source');
$jRootPath = JPath::clean(JPATH_ROOT);
// Loop through all elements and get list of files and folders
foreach ($xml->fileset->files as $eFiles)
{
$folder = (string) $eFiles->attributes()->folder;
$target = (string) $eFiles->attributes()->target;
// Create folder path
if (empty($target))
{
$targetFolder = JPATH_ROOT;
}
else
{
$targetFolder = JPATH_ROOT . '/' . $target;
}
$folderList = array();
// Check if all children exists
if (count($eFiles->children()) > 0)
{
// Loop through all filenames elements
foreach ($eFiles->children() as $eFileName)
{
if ($eFileName->getName() == 'folder')
{
$folderList[] = $targetFolder . '/' . $eFileName;
}
else
{
$fileName = $targetFolder . '/' . $eFileName;
JFile::delete($fileName);
}
}
}
// Delete any folders that don't have any content in them.
foreach ($folderList as $folder)
{
$files = JFolder::files($folder);
if (!count($files))
{
JFolder::delete($folder);
}
}
}
JFile::delete($manifestFile);
}
else
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_NOTFOUND_MANIFEST'));
// Delete the row because its broken
$row->delete();
return false;
}
$this->parent->removeFiles($xml->languages);
$row->delete();
return $retval;
}
/**
* Function used to check if extension is already installed
*
* @param string $extension The element name of the extension to install
*
* @return boolean True if extension exists
*
* @since 11.1
*/
protected function extensionExistsInSystem($extension = null)
{
// Get a database connector object
$db = $this->parent->getDBO();
$query = $db->getQuery(true);
$query->select($query->qn('extension_id'))
->from($query->qn('#__extensions'));
$query->where($query->qn('type') . ' = ' . $query->q('file'))
->where($query->qn('element') . ' = ' . $query->q($extension));
$db->setQuery($query);
try
{
$db->execute();
}
catch (JException $e)
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', $db->stderr(true)));
return false;
}
$id = $db->loadResult();
if (empty($id))
{
return false;
}
return true;
}
/**
* Function used to populate files and folder list
*
* @return boolean none
*
* @since 11.1
*/
protected function populateFilesAndFolderList()
{
// Initialise variable
$this->folderList = array();
$this->fileList = array();
// Get fileset
$eFileset = $this->manifest->fileset->files;
// Set root folder names
$packagePath = $this->parent->getPath('source');
$jRootPath = JPath::clean(JPATH_ROOT);
// Loop through all elements and get list of files and folders
foreach ($this->manifest->fileset->files as $eFiles)
{
// Check if the element is files element
$folder = (string) $eFiles->attributes()->folder;
$target = (string) $eFiles->attributes()->target;
//Split folder names into array to get folder names. This will
// help in creating folders
$arrList = preg_split("#/|\\/#", $target);
$folderName = $jRootPath;
foreach ($arrList as $dir)
{
if (empty($dir))
{
continue;
}
$folderName .= '/' . $dir;
// Check if folder exists, if not then add to the array for folder creation
if (!JFolder::exists($folderName))
{
array_push($this->folderList, $folderName);
}
}
// Create folder path
$sourceFolder = empty($folder) ? $packagePath : $packagePath . '/' . $folder;
$targetFolder = empty($target) ? $jRootPath : $jRootPath . '/' . $target;
// Check if source folder exists
if (!JFolder::exists($sourceFolder))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $sourceFolder));
// If installation fails, rollback
$this->parent->abort();
return false;
}
// Check if all children exists
if (count($eFiles->children()))
{
// Loop through all filenames elements
foreach ($eFiles->children() as $eFileName)
{
$path['src'] = $sourceFolder . '/' . $eFileName;
$path['dest'] = $targetFolder . '/' . $eFileName;
$path['type'] = 'file';
if ($eFileName->getName() == 'folder')
{
$folderName = $targetFolder . '/' . $eFileName;
array_push($this->folderList, $folderName);
$path['type'] = 'folder';
}
array_push($this->fileList, $path);
}
}
else
{
$files = JFolder::files($sourceFolder);
foreach ($files as $file)
{
$path['src'] = $sourceFolder . '/' . $file;
$path['dest'] = $targetFolder . '/' . $file;
array_push($this->fileList, $path);
}
}
}
}
/**
* Refreshes the extension table cache
*
* @return boolean result of operation, true if updated, false on failure
*
* @since 11.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
$manifestPath = JPATH_MANIFESTS . '/files/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (JException $e)
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_PACK_REFRESH_MANIFEST_CACHE'));
return false;
}
}
}
PK Z?\A"|; |; adapters/package.phpnu W+A manifest = $this->parent->getManifest();
$extension = 'pkg_' . strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->packagename, 'cmd'));
$lang = JFactory::getLanguage();
$source = $path;
$lang->load($extension . '.sys', $source, null, false, true)
|| $lang->load($extension . '.sys', JPATH_SITE, null, false, true);
}
/**
* Custom install method
*
* @return int The extension id
*
* @since 11.1
*/
public function install()
{
// Get the extension manifest object
$this->manifest = $this->parent->getManifest();
// Manifest Document Setup Section
// Set the extensions name
$filter = JFilterInput::getInstance();
$name = (string) $this->manifest->packagename;
$name = $filter->clean($name, 'cmd');
$this->set('name', $name);
$element = 'pkg_' . $filter->clean($this->manifest->packagename, 'cmd');
$this->set('element', $element);
// Get the component description
$description = (string) $this->manifest->description;
if ($description)
{
$this->parent->set('message', JText::_($description));
}
else
{
$this->parent->set('message', '');
}
// Set the installation path
$files = $this->manifest->files;
$group = (string) $this->manifest->packagename;
if (!empty($group))
{
$this->parent->setPath('extension_root', JPATH_MANIFESTS . '/packages/' . implode(DIRECTORY_SEPARATOR, explode('/', $group)));
}
else
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_PACK', JText::_('JLIB_INSTALLER_' . strtoupper($this->route))));
return false;
}
/**
* ---------------------------------------------------------------------------------------------
* Installer Trigger Loading
* ---------------------------------------------------------------------------------------------
*/
// If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
$this->scriptElement = $this->manifest->scriptfile;
$manifestScript = (string) $this->manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $element . 'InstallerScript';
if (class_exists($classname))
{
// create a new instance
$this->parent->manifestClass = new $classname($this);
// and set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
// run preflight if possible (since we know we're not an update)
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
{
if ($this->parent->manifestClass->preflight($this->route, $this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg = ob_get_contents(); // create msg object; first use here
ob_end_clean();
// Filesystem Processing Section
if ($folder = $files->attributes()->folder)
{
$source = $this->parent->getPath('source') . '/' . $folder;
}
else
{
$source = $this->parent->getPath('source');
}
// Install all necessary files
if (count($this->manifest->files->children()))
{
$i = 0;
foreach ($this->manifest->files->children() as $child)
{
$file = $source . '/' . $child;
if (is_dir($file))
{
// If it's actually a directory then fill it up
$package = array();
$package['dir'] = $file;
$package['type'] = JInstallerHelper::detectType($file);
}
else
{
// If it's an archive
$package = JInstallerHelper::unpack($file);
}
$tmpInstaller = new JInstaller;
$installResult = $tmpInstaller->install($package['dir']);
if (!$installResult)
{
$this->parent->abort(
JText::sprintf(
'JLIB_INSTALLER_ABORT_PACK_INSTALL_ERROR_EXTENSION', JText::_('JLIB_INSTALLER_' . strtoupper($this->route)),
basename($file)
)
);
return false;
}
else
{
$results[$i] = array(
'name' => $tmpInstaller->manifest->name,
'result' => $installResult
);
}
$i++;
}
}
else
{
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES', JText::_('JLIB_INSTALLER_' . strtoupper($this->route))));
return false;
}
// Parse optional tags
$this->parent->parseLanguages($this->manifest->languages);
// Extension Registration
$row = JTable::getInstance('extension');
$eid = $row->find(array('element' => strtolower($this->get('element')), 'type' => 'package'));
if ($eid)
{
$row->load($eid);
}
else
{
$row->name = $this->get('name');
$row->type = 'package';
$row->element = $this->get('element');
// There is no folder for modules
$row->folder = '';
$row->enabled = 1;
$row->protected = 0;
$row->access = 1;
$row->client_id = 0;
// custom data
$row->custom_data = '';
$row->params = $this->parent->getParams();
}
// Update the manifest cache for the entry
$row->manifest_cache = $this->parent->generateManifestCache();
if (!$row->store())
{
// Install failed, roll back changes
$this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_ROLLBACK', $row->getError()));
return false;
}
// Finalization and Cleanup Section
// Start Joomla! 1.6
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
{
if ($this->parent->manifestClass->{$this->route}($this) === false)
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
return false;
}
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
// Lastly, we will copy the manifest file to its appropriate place.
$manifest = array();
$manifest['src'] = $this->parent->getPath('manifest');
$manifest['dest'] = JPATH_MANIFESTS . '/packages/' . basename($this->parent->getPath('manifest'));
if (!$this->parent->copyFiles(array($manifest), true))
{
// Install failed, rollback changes
$this->parent->abort(
JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_COPY_SETUP', JText::_('JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES'))
);
return false;
}
// If there is a manifest script, let's copy it.
if ($this->get('manifest_script'))
{
// First, we have to create a folder for the script if one isn't present
$created = false;
if (!file_exists($this->parent->getPath('extension_root')))
{
JFolder::create($this->parent->getPath('extension_root'));
}
$path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
$path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->get('manifest_script');
if (!file_exists($path['dest']) || $this->parent->isOverwrite())
{
if (!$this->parent->copyFiles(array($path)))
{
// Install failed, rollback changes
$this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_MANIFEST'));
return false;
}
}
}
// And now we run the postflight
ob_start();
ob_implicit_flush(false);
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
{
$this->parent->manifestClass->postflight($this->route, $this, $results);
}
$msg .= ob_get_contents(); // append messages
ob_end_clean();
if ($msg != '')
{
$this->parent->set('extension_message', $msg);
}
return $row->extension_id;
}
/**
* Updates a package
*
* The only difference between an update and a full install
* is how we handle the database
*
* @return void
*
* @since 11.1
*/
public function update()
{
$this->route = 'update';
$this->install();
}
/**
* Custom uninstall method
*
* @param integer $id The id of the package to uninstall.
*
* @return boolean True on success
*
* @since 11.1
*/
public function uninstall($id)
{
// Initialise variables.
$row = null;
$retval = true;
$row = JTable::getInstance('extension');
$row->load($id);
if ($row->protected)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_WARNCOREPACK'));
return false;
}
$manifestFile = JPATH_MANIFESTS . '/packages/' . $row->get('element') . '.xml';
$manifest = new JPackageManifest($manifestFile);
// Set the package root path
$this->parent->setPath('extension_root', JPATH_MANIFESTS . '/packages/' . $manifest->packagename);
// Because packages may not have their own folders we cannot use the standard method of finding an installation manifest
if (!file_exists($manifestFile))
{
// TODO: Fail?
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_MISSINGMANIFEST'));
return false;
}
$xml = JFactory::getXML($manifestFile);
// If we cannot load the XML file return false
if (!$xml)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_LOAD_MANIFEST'));
return false;
}
/*
* Check for a valid XML root tag.
* @todo: Remove backwards compatibility in a future version
* Should be 'extension', but for backward compatibility we will accept 'install'.
*/
if ($xml->getName() != 'install' && $xml->getName() != 'extension')
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_INVALID_MANIFEST'));
return false;
}
// If there is an manifest class file, let's load it
$this->scriptElement = $manifest->scriptfile;
$manifestScript = (string) $manifest->scriptfile;
if ($manifestScript)
{
$manifestScriptFile = $this->parent->getPath('extension_root') . '/' . $manifestScript;
if (is_file($manifestScriptFile))
{
// Load the file
include_once $manifestScriptFile;
}
// Set the class name
$classname = $row->element . 'InstallerScript';
if (class_exists($classname))
{
// Create a new instance
$this->parent->manifestClass = new $classname($this);
// And set this so we can copy it later
$this->set('manifest_script', $manifestScript);
// Note: if we don't find the class, don't bother to copy the file
}
}
ob_start();
ob_implicit_flush(false);
// Run uninstall if possible
if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
{
$this->parent->manifestClass->uninstall($this);
}
$msg = ob_get_contents();
ob_end_clean();
$error = false;
foreach ($manifest->filelist as $extension)
{
$tmpInstaller = new JInstaller;
$id = $this->_getExtensionID($extension->type, $extension->id, $extension->client, $extension->group);
$client = JApplicationHelper::getClientInfo($extension->client, true);
if ($id)
{
if (!$tmpInstaller->uninstall($extension->type, $id, $client->id))
{
$error = true;
JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_NOT_PROPER', basename($extension->filename)));
}
}
else
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_UNKNOWN_EXTENSION'));
}
}
// Remove any language files
$this->parent->removeFiles($xml->languages);
// clean up manifest file after we're done if there were no errors
if (!$error)
{
JFile::delete($manifestFile);
$folder = $this->parent->getPath('extension_root');
if (JFolder::exists($folder))
{
JFolder::delete($folder);
}
$row->delete();
}
else
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PACK_UNINSTALL_MANIFEST_NOT_REMOVED'));
}
// Return the result up the line
return $retval;
}
/**
* Gets the extension id.
*
* @param string $type The extension type.
* @param string $id The name of the extension (the element field).
* @param integer $client The application id (0: Joomla CMS site; 1: Joomla CMS administrator).
* @param string $group The extension group (mainly for plugins).
*
* @return integer
*
* @since 11.1
*/
protected function _getExtensionID($type, $id, $client, $group)
{
$db = $this->parent->getDbo();
$result = $id;
$query = $db->getQuery(true);
$query->select('extension_id');
$query->from('#__extensions');
$query->where('type = ' . $db->Quote($type));
$query->where('element = ' . $db->Quote($id));
switch ($type)
{
case 'plugin':
// Plugins have a folder but not a client
$query->where('folder = ' . $db->Quote($group));
break;
case 'library':
case 'package':
case 'component':
// Components, packages and libraries don't have a folder or client.
// Included for completeness.
break;
case 'language':
case 'module':
case 'template':
// Languages, modules and templates have a client but not a folder
$client = JApplicationHelper::getClientInfo($client, true);
$query->where('client_id = ' . (int) $client->id);
break;
}
$db->setQuery($query);
$result = $db->loadResult();
// Note: For templates, libraries and packages their unique name is their key.
// This means they come out the same way they came in.
return $result;
}
/**
* Refreshes the extension table cache
*
* @return boolean Result of operation, true if updated, false on failure
*
* @since 11.1
*/
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
$manifestPath = JPATH_MANIFESTS . '/packages/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
$this->parent->extension->name = $manifest_details['name'];
try
{
return $this->parent->extension->store();
}
catch (JException $e)
{
JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_PACK_REFRESH_MANIFEST_CACHE'));
return false;
}
}
}
PK Z?\#0 0
helper.phpnu W+A getUserAgent('Installer'));
$http = JHttpFactory::getHttp();
// load installer plugins, and allow url and headers modification
$headers = array();
JPluginHelper::importPlugin('installer');
$dispatcher = JDispatcher::getInstance();
$results = $dispatcher->trigger('onInstallerBeforePackageDownload', array(&$url, &$headers));
try
{
$response = $http->get($url, $headers);
}
catch (Exception $exc)
{
$response = null;
}
if (is_null($response))
{
JError::raiseWarning(42, JText::_('JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT'));
return false;
}
if (302 == $response->code && isset($response->headers['Location']))
{
return self::downloadPackage($response->headers['Location']);
}
elseif (200 != $response->code)
{
if ($response->body === '')
{
$response->body = $php_errormsg;
}
JError::raiseWarning(42, JText::sprintf('JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT', $response->body));
return false;
}
// Parse the Content-Disposition header to get the file name
if (isset($response->headers['Content-Disposition'])
&& preg_match("/\s*filename\s?=\s?(.*)/", $response->headers['Content-Disposition'], $parts))
{
$target = trim(rtrim($parts[1], ";"), '"');
}
// Set the target path if not given
if (!$target)
{
$target = $config->get('tmp_path') . '/' . self::getFilenameFromURL($url);
}
else
{
$target = $config->get('tmp_path') . '/' . basename($target);
}
// Write buffer to file
JFile::write($target, $response->body);
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// bump the max execution time because not using built in php zip libs are slow
@set_time_limit(ini_get('max_execution_time'));
// Return the name of the downloaded package
return basename($target);
}
/**
* Unpacks a file and verifies it as a Joomla element package
* Supports .gz .tar .tar.gz and .zip
*
* @param string $p_filename The uploaded package filename or install directory
*
* @return array Two elements: extractdir and packagefile
*
* @since 11.1
*/
public static function unpack($p_filename)
{
// Path to the archive
$archivename = $p_filename;
// Temporary folder to extract the archive into
$tmpdir = uniqid('install_');
// Clean the paths to use for archive extraction
$extractdir = JPath::clean(dirname($p_filename) . '/' . $tmpdir);
$archivename = JPath::clean($archivename);
// Do the unpacking of the archive
$result = JArchive::extract($archivename, $extractdir);
if ($result === false)
{
return false;
}
/*
* Let's set the extraction directory and package file in the result array so we can
* cleanup everything properly later on.
*/
$retval['extractdir'] = $extractdir;
$retval['packagefile'] = $archivename;
/*
* Try to find the correct install directory. In case the package is inside a
* subdirectory detect this and set the install directory to the correct path.
*
* List all the items in the installation directory. If there is only one, and
* it is a folder, then we will set that folder to be the installation folder.
*/
$dirList = array_merge(JFolder::files($extractdir, ''), JFolder::folders($extractdir, ''));
if (count($dirList) == 1)
{
if (JFolder::exists($extractdir . '/' . $dirList[0]))
{
$extractdir = JPath::clean($extractdir . '/' . $dirList[0]);
}
}
/*
* We have found the install directory so lets set it and then move on
* to detecting the extension type.
*/
$retval['dir'] = $extractdir;
/*
* Get the extension type and return the directory/type array on success or
* false on fail.
*/
if ($retval['type'] = self::detectType($extractdir))
{
return $retval;
}
else
{
return false;
}
}
/**
* Method to detect the extension type from a package directory
*
* @param string $p_dir Path to package directory
*
* @return mixed Extension type string or boolean false on fail
*
* @since 11.1
*/
public static function detectType($p_dir)
{
// Search the install dir for an XML file
$files = JFolder::files($p_dir, '\.xml$', 1, true);
if (!count($files))
{
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE'));
return false;
}
foreach ($files as $file)
{
if (!$xml = JFactory::getXML($file))
{
continue;
}
if ($xml->getName() != 'install' && $xml->getName() != 'extension')
{
unset($xml);
continue;
}
$type = (string) $xml->attributes()->type;
// Free up memory
unset($xml);
return $type;
}
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_NOTFINDJOOMLAXMLSETUPFILE'));
// Free up memory.
unset($xml);
return false;
}
/**
* Gets a file name out of a url
*
* @param string $url URL to get name from
*
* @return mixed String filename or boolean false if failed
*
* @since 11.1
*/
public static function getFilenameFromURL($url)
{
if (is_string($url))
{
$parts = explode('/', $url);
return $parts[count($parts) - 1];
}
return false;
}
/**
* Clean up temporary uploaded package and unpacked extension
*
* @param string $package Path to the uploaded package file
* @param string $resultdir Path to the unpacked extension
*
* @return boolean True on success
*
* @since 11.1
*/
public static function cleanupInstall($package, $resultdir)
{
$config = JFactory::getConfig();
// Does the unpacked extension directory exist?
if (is_dir($resultdir))
{
JFolder::delete($resultdir);
}
// Is the package file a valid file?
if (is_file($package))
{
JFile::delete($package);
}
elseif (is_file(JPath::clean($config->get('tmp_path') . '/' . $package)))
{
// It might also be just a base filename
JFile::delete(JPath::clean($config->get('tmp_path') . '/' . $package));
}
}
/**
* Splits contents of a sql file into array of discreet queries.
* Queries need to be delimited with end of statement marker ';'
*
* @param string $sql The SQL statement.
*
* @return array Array of queries
*
* @since 11.1
*/
public static function splitSql($sql)
{
$db = JFactory::getDbo();
return $db->splitSql($sql);
}
}
PK Z?\V
index.htmlnu W+A
PK Z?\Am6 6
installer.phpnu W+A isOverwrite();
}
/**
* Get the allow overwrite switch
*
* @return boolean Allow overwrite switch
*
* @since 11.4
*/
public function isOverwrite()
{
return $this->_overwrite;
}
/**
* Set the allow overwrite switch
*
* @param boolean $state Overwrite switch state
*
* @return boolean True it state is set, false if it is not
*
* @since 11.1
*/
public function setOverwrite($state = false)
{
$tmp = $this->_overwrite;
if ($state)
{
$this->_overwrite = true;
}
else
{
$this->_overwrite = false;
}
return $tmp;
}
/**
* Get the redirect location
*
* @return string Redirect location (or null)
*
* @since 11.1
*/
public function getRedirectURL()
{
return $this->redirect_url;
}
/**
* Set the redirect location
*
* @param string $newurl New redirect location
*
* @return void
*
* @since 11.1
*/
public function setRedirectURL($newurl)
{
$this->redirect_url = $newurl;
}
/**
* Get the upgrade switch
*
* @return boolean
*
* @since 11.1
* @deprecated 12.1 Use JInstaller::isUpgrade()
*/
public function getUpgrade()
{
JLog::add('JInstaller::getUpgrade() is deprecated. Please use JInstaller::isUpgrade() instead', JLog::WARNING, 'deprecated');
return $this->isUpgrade();
}
/**
* Get the upgrade switch
*
* @return boolean
*
* @since 11.4
*/
public function isUpgrade()
{
return $this->_upgrade;
}
/**
* Set the upgrade switch
*
* @param boolean $state Upgrade switch state
*
* @return boolean True if upgrade, false otherwise
*
* @since 11.1
*/
public function setUpgrade($state = false)
{
$tmp = $this->_upgrade;
if ($state)
{
$this->_upgrade = true;
}
else
{
$this->_upgrade = false;
}
return $tmp;
}
/**
* Get the installation manifest object
*
* @return object Manifest object
*
* @since 11.1
*/
public function getManifest()
{
if (!is_object($this->manifest))
{
$this->findManifest();
}
return $this->manifest;
}
/**
* Get an installer path by name
*
* @param string $name Path name
* @param string $default Default value
*
* @return string Path
*
* @since 11.1
*/
public function getPath($name, $default = null)
{
return (!empty($this->_paths[$name])) ? $this->_paths[$name] : $default;
}
/**
* Sets an installer path by name
*
* @param string $name Path name
* @param string $value Path
*
* @return void
*
* @since 11.1
*/
public function setPath($name, $value)
{
$this->_paths[$name] = $value;
}
/**
* Pushes a step onto the installer stack for rolling back steps
*
* @param array $step Installer step
*
* @return void
*
* @since 11.1
*/
public function pushStep($step)
{
$this->_stepStack[] = $step;
}
/**
* Installation abort method
*
* @param string $msg Abort message from the installer
* @param string $type Package type if defined
*
* @return boolean True if successful
*
* @since 11.1
*/
public function abort($msg = null, $type = null)
{
// Initialise variables.
$retval = true;
$step = array_pop($this->_stepStack);
// Raise abort warning
if ($msg)
{
JError::raiseWarning(100, $msg);
}
while ($step != null)
{
switch ($step['type'])
{
case 'file':
// Remove the file
$stepval = JFile::delete($step['path']);
break;
case 'folder':
// Remove the folder
$stepval = JFolder::delete($step['path']);
break;
case 'query':
// Placeholder in case this is necessary in the future
// $stepval is always false because if this step was called it invariably failed
$stepval = false;
break;
case 'extension':
// Get database connector object
$db = $this->getDBO();
$query = $db->getQuery(true);
// Remove the entry from the #__extensions table
$query->delete($db->quoteName('#__extensions'));
$query->where($db->quoteName('extension_id') . ' = ' . (int) $step['id']);
$db->setQuery($query);
$stepval = $db->execute();
break;
default:
if ($type && is_object($this->_adapters[$type]))
{
// Build the name of the custom rollback method for the type
$method = '_rollback_' . $step['type'];
// Custom rollback method handler
if (method_exists($this->_adapters[$type], $method))
{
$stepval = $this->_adapters[$type]->$method($step);
}
}
else
{
$stepval = false; // set it to false
}
break;
}
// Only set the return value if it is false
if ($stepval === false)
{
$retval = false;
}
// Get the next step and continue
$step = array_pop($this->_stepStack);
}
$conf = JFactory::getConfig();
$debug = $conf->get('debug');
if ($debug)
{
JError::raiseError(500, JText::_('JLIB_INSTALLER_ABORT_DEBUG') . $msg);
}
return $retval;
}
// Adapter functions
/**
* Package installation method
*
* @param string $path Path to package source folder
*
* @return boolean True if successful
*
* @since 11.1
*/
public function install($path = null)
{
if ($path && JFolder::exists($path))
{
$this->setPath('source', $path);
}
else
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_NOINSTALLPATH'));
return false;
}
if (!$this->setupInstall())
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST'));
return false;
}
$type = (string) $this->manifest->attributes()->type;
if (is_object($this->_adapters[$type]))
{
// Add the languages from the package itself
if (method_exists($this->_adapters[$type], 'loadLanguage'))
{
$this->_adapters[$type]->loadLanguage($path);
}
// Fire the onExtensionBeforeInstall event.
JPluginHelper::importPlugin('extension');
$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger(
'onExtensionBeforeInstall',
array('method' => 'install', 'type' => $type, 'manifest' => $this->manifest, 'extension' => 0)
);
// Run the install
$result = $this->_adapters[$type]->install();
// Fire the onExtensionAfterInstall
$dispatcher->trigger(
'onExtensionAfterInstall',
array('installer' => clone $this, 'eid' => $result)
);
if ($result !== false)
{
return true;
}
else
{
return false;
}
}
return false;
}
/**
* Discovered package installation method
*
* @param integer $eid Extension ID
*
* @return boolean True if successful
*
* @since 11.1
*/
public function discover_install($eid = null)
{
if ($eid)
{
$this->extension = JTable::getInstance('extension');
if (!$this->extension->load($eid))
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_LOAD_DETAILS'));
return false;
}
if ($this->extension->state != -1)
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_ALREADYINSTALLED'));
return false;
}
// Lazy load the adapter
if (!isset($this->_adapters[$this->extension->type]) || !is_object($this->_adapters[$this->extension->type]))
{
if (!$this->setAdapter($this->extension->type))
{
return false;
}
}
if (is_object($this->_adapters[$this->extension->type]))
{
if (method_exists($this->_adapters[$this->extension->type], 'discover_install'))
{
// Add the languages from the package itself
if (method_exists($this->_adapters[$this->extension->type], 'loadLanguage'))
{
$this->_adapters[$this->extension->type]->loadLanguage();
}
// Fire the onExtensionBeforeInstall event.
JPluginHelper::importPlugin('extension');
$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger(
'onExtensionBeforeInstall',
array(
'method' => 'discover_install',
'type' => $this->extension->get('type'),
'manifest' => null,
'extension' => $this->extension->get('extension_id')
)
);
// Run the install
$result = $this->_adapters[$this->extension->type]->discover_install();
// Fire the onExtensionAfterInstall
$dispatcher->trigger(
'onExtensionAfterInstall',
array('installer' => clone $this, 'eid' => $result)
);
if ($result !== false)
{
return true;
}
else
{
return false;
}
}
else
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_METHODNOTSUPPORTED'));
return false;
}
}
return false;
}
else
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_EXTENSIONNOTVALID'));
return false;
}
}
/**
* Extension discover method
* Asks each adapter to find extensions
*
* @return array JExtension
*
* @since 11.1
*/
public function discover()
{
$this->loadAllAdapters();
$results = array();
foreach ($this->_adapters as $adapter)
{
// Joomla! 1.5 installation adapter legacy support
if (method_exists($adapter, 'discover'))
{
$tmp = $adapter->discover();
// if its an array and has entries
if (is_array($tmp) && count($tmp))
{
// merge it into the system
$results = array_merge($results, $tmp);
}
}
}
return $results;
}
/**
* Package update method
*
* @param string $path Path to package source folder
*
* @return boolean True if successful
*
* @since 11.1
*/
public function update($path = null)
{
if ($path && JFolder::exists($path))
{
$this->setPath('source', $path);
}
else
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_NOUPDATEPATH'));
return false;
}
if (!$this->setupInstall())
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST'));
return false;
}
$type = (string) $this->manifest->attributes()->type;
if (is_object($this->_adapters[$type]))
{
// Add the languages from the package itself
if (method_exists($this->_adapters[$type], 'loadLanguage'))
{
$this->_adapters[$type]->loadLanguage($path);
}
// Fire the onExtensionBeforeUpdate event.
JPluginHelper::importPlugin('extension');
$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger('onExtensionBeforeUpdate', array('type' => $type, 'manifest' => $this->manifest));
// Run the update
$result = $this->_adapters[$type]->update();
// Fire the onExtensionAfterUpdate
$dispatcher->trigger(
'onExtensionAfterUpdate',
array('installer' => clone $this, 'eid' => $result)
);
if ($result !== false)
{
return true;
}
else
{
return false;
}
}
return false;
}
/**
* Package uninstallation method
*
* @param string $type Package type
* @param mixed $identifier Package identifier for adapter
* @param integer $cid Application ID; deprecated in 1.6
*
* @return boolean True if successful
*
* @since 11.1
*/
public function uninstall($type, $identifier, $cid = 0)
{
if (!isset($this->_adapters[$type]) || !is_object($this->_adapters[$type]))
{
if (!$this->setAdapter($type))
{
// We failed to get the right adapter
return false;
}
}
if (is_object($this->_adapters[$type]))
{
// We don't load languages here, we get the extension adapter to work it out
// Fire the onExtensionBeforeUninstall event.
JPluginHelper::importPlugin('extension');
$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger('onExtensionBeforeUninstall', array('eid' => $identifier));
// Run the uninstall
$result = $this->_adapters[$type]->uninstall($identifier);
// Fire the onExtensionAfterInstall
$dispatcher->trigger(
'onExtensionAfterUninstall',
array('installer' => clone $this, 'eid' => $identifier, 'result' => $result)
);
return $result;
}
return false;
}
/**
* Refreshes the manifest cache stored in #__extensions
*
* @param integer $eid Extension ID
*
* @return mixed void on success, false on error @todo missing return value ?
*
* @since 11.1
*/
public function refreshManifestCache($eid)
{
if ($eid)
{
$this->extension = JTable::getInstance('extension');
if (!$this->extension->load($eid))
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_LOAD_DETAILS'));
return false;
}
if ($this->extension->state == -1)
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_REFRESH_MANIFEST_CACHE'));
return false;
}
// Lazy load the adapter
if (!isset($this->_adapters[$this->extension->type]) || !is_object($this->_adapters[$this->extension->type]))
{
if (!$this->setAdapter($this->extension->type))
{
return false;
}
}
if (is_object($this->_adapters[$this->extension->type]))
{
if (method_exists($this->_adapters[$this->extension->type], 'refreshManifestCache'))
{
$result = $this->_adapters[$this->extension->type]->refreshManifestCache();
if ($result !== false)
{
return true;
}
else
{
return false;
}
}
else
{
$this->abort(JText::sprintf('JLIB_INSTALLER_ABORT_METHODNOTSUPPORTED_TYPE', $this->extension->type));
return false;
}
}
return false;
}
else
{
$this->abort(JText::_('JLIB_INSTALLER_ABORT_REFRESH_MANIFEST_CACHE_VALID'));
return false;
}
}
// Utility functions
/**
* Prepare for installation: this method sets the installation directory, finds
* and checks the installation file and verifies the installation type.
*
* @return boolean True on success
*
* @since 11.1
*/
public function setupInstall()
{
// We need to find the installation manifest file
if (!$this->findManifest())
{
return false;
}
// Load the adapter(s) for the install manifest
$type = (string) $this->manifest->attributes()->type;
// Lazy load the adapter
if (!isset($this->_adapters[$type]) || !is_object($this->_adapters[$type]))
{
if (!$this->setAdapter($type))
{
return false;
}
}
return true;
}
/**
* Backward compatible method to parse through a queries element of the
* installation manifest file and take appropriate action.
*
* @param SimpleXMLElement $element The XML node to process
*
* @return mixed Number of queries processed or False on error
*
* @since 11.1
*/
public function parseQueries($element)
{
// Get the database connector object
$db = & $this->_db;
if (!$element || !count($element->children()))
{
// Either the tag does not exist or has no children therefore we return zero files processed.
return 0;
}
// Get the array of query nodes to process
$queries = $element->children();
if (count($queries) == 0)
{
// No queries to process
return 0;
}
// Process each query in the $queries array (children of $tagName).
foreach ($queries as $query)
{
$db->setQuery($query->data());
if (!$db->execute())
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_SQL_ERROR', $db->stderr(true)));
return false;
}
}
return (int) count($queries);
}
/**
* Method to extract the name of a discreet installation sql file from the installation manifest file.
*
* @param object $element The XML node to process
*
* @return mixed Number of queries processed or False on error
*
* @since 11.1
*/
public function parseSQLFiles($element)
{
if (!$element || !count($element->children()))
{
// The tag does not exist.
return 0;
}
// Initialise variables.
$queries = array();
$db = & $this->_db;
$dbDriver = strtolower($db->name);
if ($dbDriver == 'mysqli')
{
$dbDriver = 'mysql';
}
elseif($dbDriver == 'sqlsrv')
{
$dbDriver = 'sqlazure';
}
// Get the name of the sql file to process
$sqlfile = '';
foreach ($element->children() as $file)
{
$fCharset = (strtolower($file->attributes()->charset) == 'utf8') ? 'utf8' : '';
$fDriver = strtolower($file->attributes()->driver);
if ($fDriver == 'mysqli')
{
$fDriver = 'mysql';
}
elseif($fDriver == 'sqlsrv')
{
$fDriver = 'sqlazure';
}
if ($fCharset == 'utf8' && $fDriver == $dbDriver)
{
$sqlfile = $this->getPath('extension_root') . '/' . trim($file);
// Check that sql files exists before reading. Otherwise raise error for rollback
if (!file_exists($sqlfile))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_SQL_FILENOTFOUND', $sqlfile));
return false;
}
$buffer = file_get_contents($sqlfile);
// Graceful exit and rollback if read not successful
if ($buffer === false)
{
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_SQL_READBUFFER'));
return false;
}
// Create an array of queries from the sql file
$queries = JInstallerHelper::splitSql($buffer);
if (count($queries) == 0)
{
// No queries to process
return 0;
}
// Process each query in the $queries array (split out of sql file).
foreach ($queries as $query)
{
$query = trim($query);
if ($query != '' && $query{0} != '#')
{
$db->setQuery($query);
if (!$db->execute())
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_SQL_ERROR', $db->stderr(true)));
return false;
}
}
}
}
}
return (int) count($queries);
}
/**
* Set the schema version for an extension by looking at its latest update
*
* @param SimpleXMLElement $schema Schema Tag
* @param integer $eid Extension ID
*
* @return void
*
* @since 11.1
*/
public function setSchemaVersion($schema, $eid)
{
if ($eid && $schema)
{
$db = JFactory::getDBO();
$schemapaths = $schema->children();
if (!$schemapaths)
{
return;
}
if (count($schemapaths))
{
$dbDriver = strtolower($db->name);
if ($dbDriver == 'mysqli')
{
$dbDriver = 'mysql';
}
elseif ($dbDriver == 'sqlsrv')
{
$dbDriver = 'sqlazure';
}
$schemapath = '';
foreach ($schemapaths as $entry)
{
$attrs = $entry->attributes();
if ($attrs['type'] == $dbDriver)
{
$schemapath = $entry;
break;
}
}
if (strlen($schemapath))
{
$files = str_replace('.sql', '', JFolder::files($this->getPath('extension_root') . '/' . $schemapath, '\.sql$'));
usort($files, 'version_compare');
// Update the database
$query = $db->getQuery(true);
$query->delete()
->from('#__schemas')
->where('extension_id = ' . $eid);
$db->setQuery($query);
if ($db->execute())
{
$query->clear();
$query->insert($db->quoteName('#__schemas'));
$query->columns(array($db->quoteName('extension_id'), $db->quoteName('version_id')));
$query->values($eid . ', ' . $db->quote(end($files)));
$db->setQuery($query);
$db->execute();
}
}
}
}
}
/**
* Method to process the updates for an item
*
* @param SimpleXMLElement $schema The XML node to process
* @param integer $eid Extension Identifier
*
* @return boolean Result of the operations
*
* @since 11.1
*/
public function parseSchemaUpdates($schema, $eid)
{
$files = array();
$update_count = 0;
// Ensure we have an XML element and a valid extension id
if ($eid && $schema)
{
$db = JFactory::getDBO();
$schemapaths = $schema->children();
if (count($schemapaths))
{
$dbDriver = strtolower($db->name);
if ($dbDriver == 'mysqli')
{
$dbDriver = 'mysql';
}
elseif ($dbDriver == 'sqlsrv')
{
$dbDriver = 'sqlazure';
}
$schemapath = '';
foreach ($schemapaths as $entry)
{
$attrs = $entry->attributes();
if ($attrs['type'] == $dbDriver)
{
$schemapath = $entry;
break;
}
}
if (strlen($schemapath))
{
$files = str_replace('.sql', '', JFolder::files($this->getPath('extension_root') . '/' . $schemapath, '\.sql$'));
usort($files, 'version_compare');
if (!count($files))
{
return false;
}
$query = $db->getQuery(true);
$query->select('version_id')
->from('#__schemas')
->where('extension_id = ' . $eid);
$db->setQuery($query);
$version = $db->loadResult();
if ($version)
{
// We have a version!
foreach ($files as $file)
{
if (version_compare($file, $version) > 0)
{
$buffer = file_get_contents($this->getPath('extension_root') . '/' . $schemapath . '/' . $file . '.sql');
// Graceful exit and rollback if read not successful
if ($buffer === false)
{
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_SQL_READBUFFER'));
return false;
}
// Create an array of queries from the sql file
$queries = JInstallerHelper::splitSql($buffer);
if (count($queries) == 0)
{
// No queries to process
continue;
}
// Process each query in the $queries array (split out of sql file).
foreach ($queries as $query)
{
$query = trim($query);
if ($query != '' && $query{0} != '#')
{
$db->setQuery($query);
if (!$db->execute())
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_SQL_ERROR', $db->stderr(true)));
return false;
}
$update_count++;
}
}
}
}
}
// Update the database
$query = $db->getQuery(true);
$query->delete()
->from('#__schemas')
->where('extension_id = ' . $eid);
$db->setQuery($query);
if ($db->execute())
{
$query->clear();
$query->insert($db->quoteName('#__schemas'));
$query->columns(array($db->quoteName('extension_id'), $db->quoteName('version_id')));
$query->values($eid . ', ' . $db->quote(end($files)));
$db->setQuery($query);
$db->execute();
}
}
}
}
return $update_count;
}
/**
* Method to parse through a files element of the installation manifest and take appropriate
* action.
*
* @param SimpleXMLElement $element The XML node to process
* @param integer $cid Application ID of application to install to
* @param array $oldFiles List of old files (SimpleXMLElement's)
* @param array $oldMD5 List of old MD5 sums (indexed by filename with value as MD5)
*
* @return boolean True on success
*
* @since 11.1
*/
public function parseFiles($element, $cid = 0, $oldFiles = null, $oldMD5 = null)
{
// Get the array of file nodes to process; we checked whether this had children above.
if (!$element || !count($element->children()))
{
// Either the tag does not exist or has no children (hence no files to process) therefore we return zero files processed.
return 0;
}
// Initialise variables.
$copyfiles = array();
// Get the client info
$client = JApplicationHelper::getClientInfo($cid);
/*
* Here we set the folder we are going to remove the files from.
*/
if ($client)
{
$pathname = 'extension_' . $client->name;
$destination = $this->getPath($pathname);
}
else
{
$pathname = 'extension_root';
$destination = $this->getPath($pathname);
}
// Here we set the folder we are going to copy the files from.
// Does the element have a folder attribute?
//
// If so this indicates that the files are in a subdirectory of the source
// folder and we should append the folder attribute to the source path when
// copying files.
$folder = (string) $element->attributes()->folder;
if ($folder && file_exists($this->getPath('source') . '/' . $folder))
{
$source = $this->getPath('source') . '/' . $folder;
}
else
{
$source = $this->getPath('source');
}
// Work out what files have been deleted
if ($oldFiles && ($oldFiles instanceof SimpleXMLElement))
{
$oldEntries = $oldFiles->children();
if (count($oldEntries))
{
$deletions = $this->findDeletedFiles($oldEntries, $element->children());
foreach ($deletions['folders'] as $deleted_folder)
{
JFolder::delete($destination . '/' . $deleted_folder);
}
foreach ($deletions['files'] as $deleted_file)
{
JFile::delete($destination . '/' . $deleted_file);
}
}
}
// Copy the MD5SUMS file if it exists
if (file_exists($source . '/MD5SUMS'))
{
$path['src'] = $source . '/MD5SUMS';
$path['dest'] = $destination . '/MD5SUMS';
$path['type'] = 'file';
$copyfiles[] = $path;
}
// Process each file in the $files array (children of $tagName).
foreach ($element->children() as $file)
{
$path['src'] = $source . '/' . $file;
$path['dest'] = $destination . '/' . $file;
// Is this path a file or folder?
$path['type'] = ($file->getName() == 'folder') ? 'folder' : 'file';
// Before we can add a file to the copyfiles array we need to ensure
// that the folder we are copying our file to exits and if it doesn't,
// we need to create it.
if (basename($path['dest']) != $path['dest'])
{
$newdir = dirname($path['dest']);
if (!JFolder::create($newdir))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_CREATE_DIRECTORY', $newdir));
return false;
}
}
// Add the file to the copyfiles array
$copyfiles[] = $path;
}
return $this->copyFiles($copyfiles);
}
/**
* Method to parse through a languages element of the installation manifest and take appropriate
* action.
*
* @param SimpleXMLElement $element The XML node to process
* @param integer $cid Application ID of application to install to
*
* @return boolean True on success
*
* @since 11.1
*/
public function parseLanguages($element, $cid = 0)
{
// TODO: work out why the below line triggers 'node no longer exists' errors with files
if (!$element || !count($element->children()))
{
// Either the tag does not exist or has no children therefore we return zero files processed.
return 0;
}
// Initialise variables.
$copyfiles = array();
// Get the client info
$client = JApplicationHelper::getClientInfo($cid);
// Here we set the folder we are going to copy the files to.
// 'languages' Files are copied to JPATH_BASE/language/ folder
$destination = $client->path . '/language';
// Here we set the folder we are going to copy the files from.
// Does the element have a folder attribute?
// If so this indicates that the files are in a subdirectory of the source
// folder and we should append the folder attribute to the source path when
// copying files.
$folder = (string) $element->attributes()->folder;
if ($folder && file_exists($this->getPath('source') . '/' . $folder))
{
$source = $this->getPath('source') . '/' . $folder;
}
else
{
$source = $this->getPath('source');
}
// Process each file in the $files array (children of $tagName).
foreach ($element->children() as $file)
{
// Language files go in a subfolder based on the language code, ie.
// en-US.mycomponent.ini
// would go in the en-US subdirectory of the language folder.
// We will only install language files where a core language pack
// already exists.
if ((string) $file->attributes()->tag != '')
{
$path['src'] = $source . '/' . $file;
if ((string) $file->attributes()->client != '')
{
// Override the client
$langclient = JApplicationHelper::getClientInfo((string) $file->attributes()->client, true);
$path['dest'] = $langclient->path . '/language/' . $file->attributes()->tag . '/' . basename((string) $file);
}
else
{
// Use the default client
$path['dest'] = $destination . '/' . $file->attributes()->tag . '/' . basename((string) $file);
}
// If the language folder is not present, then the core pack hasn't been installed... ignore
if (!JFolder::exists(dirname($path['dest'])))
{
continue;
}
}
else
{
$path['src'] = $source . '/' . $file;
$path['dest'] = $destination . '/' . $file;
}
//
// Before we can add a file to the copyfiles array we need to ensure
// that the folder we are copying our file to exits and if it doesn't,
// we need to create it.
if (basename($path['dest']) != $path['dest'])
{
$newdir = dirname($path['dest']);
if (!JFolder::create($newdir))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_CREATE_DIRECTORY', $newdir));
return false;
}
}
// Add the file to the copyfiles array
$copyfiles[] = $path;
}
return $this->copyFiles($copyfiles);
}
/**
* Method to parse through a media element of the installation manifest and take appropriate
* action.
*
* @param SimpleXMLElement $element The XML node to process
* @param integer $cid Application ID of application to install to
*
* @return boolean True on success
*
* @since 11.1
*/
public function parseMedia($element, $cid = 0)
{
if (!$element || !count($element->children()))
{
// Either the tag does not exist or has no children therefore we return zero files processed.
return 0;
}
// Initialise variables.
$copyfiles = array();
// Get the client info
$client = JApplicationHelper::getClientInfo($cid);
// Here we set the folder we are going to copy the files to.
// Default 'media' Files are copied to the JPATH_BASE/media folder
$folder = ((string) $element->attributes()->destination) ? '/' . $element->attributes()->destination : null;
$destination = JPath::clean(JPATH_ROOT . '/media' . $folder);
// Here we set the folder we are going to copy the files from.
// Does the element have a folder attribute?
// If so this indicates that the files are in a subdirectory of the source
// folder and we should append the folder attribute to the source path when
// copying files.
$folder = (string) $element->attributes()->folder;
if ($folder && file_exists($this->getPath('source') . '/' . $folder))
{
$source = $this->getPath('source') . '/' . $folder;
}
else
{
$source = $this->getPath('source');
}
// Process each file in the $files array (children of $tagName).
foreach ($element->children() as $file)
{
$path['src'] = $source . '/' . $file;
$path['dest'] = $destination . '/' . $file;
// Is this path a file or folder?
$path['type'] = ($file->getName() == 'folder') ? 'folder' : 'file';
// Before we can add a file to the copyfiles array we need to ensure
// that the folder we are copying our file to exits and if it doesn't,
// we need to create it.
if (basename($path['dest']) != $path['dest'])
{
$newdir = dirname($path['dest']);
if (!JFolder::create($newdir))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_CREATE_DIRECTORY', $newdir));
return false;
}
}
// Add the file to the copyfiles array
$copyfiles[] = $path;
}
return $this->copyFiles($copyfiles);
}
/**
* Method to parse the parameters of an extension, build the INI
* string for its default parameters, and return the INI string.
*
* @return string INI string of parameter values
*
* @since 11.1
*/
public function getParams()
{
// Validate that we have a fieldset to use
if (!isset($this->manifest->config->fields->fieldset))
{
return '{}';
}
// Getting the fieldset tags
$fieldsets = $this->manifest->config->fields->fieldset;
// Creating the data collection variable:
$ini = array();
// Iterating through the fieldsets:
foreach ($fieldsets as $fieldset)
{
if (!count($fieldset->children()))
{
// Either the tag does not exist or has no children therefore we return zero files processed.
return null;
}
// Iterating through the fields and collecting the name/default values:
foreach ($fieldset as $field)
{
// Check against the null value since otherwise default values like "0"
// cause entire parameters to be skipped.
if (($name = $field->attributes()->name) === null)
{
continue;
}
if (($value = $field->attributes()->default) === null)
{
continue;
}
$ini[(string) $name] = (string) $value;
}
}
return json_encode($ini);
}
/**
* Copyfiles
*
* Copy files from source directory to the target directory
*
* @param array $files Array with filenames
* @param boolean $overwrite True if existing files can be replaced
*
* @return boolean True on success
*
* @since 11.1
*/
public function copyFiles($files, $overwrite = null)
{
// To allow for manual override on the overwriting flag, we check to see if
// the $overwrite flag was set and is a boolean value. If not, use the object
// allowOverwrite flag.
if (is_null($overwrite) || !is_bool($overwrite))
{
$overwrite = $this->_overwrite;
}
/*
* $files must be an array of filenames. Verify that it is an array with
* at least one file to copy.
*/
if (is_array($files) && count($files) > 0)
{
foreach ($files as $file)
{
// Get the source and destination paths
$filesource = JPath::clean($file['src']);
$filedest = JPath::clean($file['dest']);
$filetype = array_key_exists('type', $file) ? $file['type'] : 'file';
if (!file_exists($filesource))
{
/*
* The source file does not exist. Nothing to copy so set an error
* and return false.
*/
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_NO_FILE', $filesource));
return false;
}
elseif (($exists = file_exists($filedest)) && !$overwrite)
{
// It's okay if the manifest already exists
if ($this->getPath('manifest') == $filesource)
{
continue;
}
// The destination file already exists and the overwrite flag is false.
// Set an error and return false.
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_FILE_EXISTS', $filedest));
return false;
}
else
{
// Copy the folder or file to the new location.
if ($filetype == 'folder')
{
if (!(JFolder::copy($filesource, $filedest, null, $overwrite)))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_FAIL_COPY_FOLDER', $filesource, $filedest));
return false;
}
$step = array('type' => 'folder', 'path' => $filedest);
}
else
{
if (!(JFile::copy($filesource, $filedest, null)))
{
JError::raiseWarning(1, JText::sprintf('JLIB_INSTALLER_ERROR_FAIL_COPY_FILE', $filesource, $filedest));
return false;
}
$step = array('type' => 'file', 'path' => $filedest);
}
/*
* Since we copied a file/folder, we want to add it to the installation step stack so that
* in case we have to roll back the installation we can remove the files copied.
*/
if (!$exists)
{
$this->_stepStack[] = $step;
}
}
}
}
else
{
// The $files variable was either not an array or an empty array
return false;
}
return count($files);
}
/**
* Method to parse through a files element of the installation manifest and remove
* the files that were installed
*
* @param object $element The XML node to process
* @param integer $cid Application ID of application to remove from
*
* @return boolean True on success
*
* @since 11.1
*/
public function removeFiles($element, $cid = 0)
{
if (!$element || !count($element->children()))
{
// Either the tag does not exist or has no children therefore we return zero files processed.
return true;
}
// Initialise variables.
$removefiles = array();
$retval = true;
$debug = false;
if (isset($GLOBALS['installerdebug']) && $GLOBALS['installerdebug'])
{
$debug = true;
}
// Get the client info if we're using a specific client
if ($cid > -1)
{
$client = JApplicationHelper::getClientInfo($cid);
}
else
{
$client = null;
}
// Get the array of file nodes to process
$files = $element->children();
if (count($files) == 0)
{
// No files to process
return true;
}
$folder = '';
/*
* Here we set the folder we are going to remove the files from. There are a few
* special cases that need to be considered for certain reserved tags.
*/
switch ($element->getName())
{
case 'media':
if ((string) $element->attributes()->destination)
{
$folder = (string) $element->attributes()->destination;
}
else
{
$folder = '';
}
$source = $client->path . '/media/' . $folder;
break;
case 'languages':
$lang_client = (string) $element->attributes()->client;
if ($lang_client)
{
$client = JApplicationHelper::getClientInfo($lang_client, true);
$source = $client->path . '/language';
}
else
{
if ($client)
{
$source = $client->path . '/language';
}
else
{
$source = '';
}
}
break;
default:
if ($client)
{
$pathname = 'extension_' . $client->name;
$source = $this->getPath($pathname);
}
else
{
$pathname = 'extension_root';
$source = $this->getPath($pathname);
}
break;
}
// Process each file in the $files array (children of $tagName).
foreach ($files as $file)
{
// If the file is a language, we must handle it differently. Language files
// go in a subdirectory based on the language code, ie.
// en_US.mycomponent.ini
// would go in the en_US subdirectory of the languages directory.
if ($file->getName() == 'language' && (string) $file->attributes()->tag != '')
{
if ($source)
{
$path = $source . '/' . $file->attributes()->tag . '/' . basename((string) $file);
}
else
{
$target_client = JApplicationHelper::getClientInfo((string) $file->attributes()->client, true);
$path = $target_client->path . '/language/' . $file->attributes()->tag . '/' . basename((string) $file);
}
// If the language folder is not present, then the core pack hasn't been installed... ignore
if (!JFolder::exists(dirname($path)))
{
continue;
}
}
else
{
$path = $source . '/' . $file;
}
// Actually delete the files/folders
if (is_dir($path))
{
$val = JFolder::delete($path);
}
else
{
$val = JFile::delete($path);
}
if ($val === false)
{
JError::raiseWarning(43, 'Failed to delete ' . $path);
$retval = false;
}
}
if (!empty($folder))
{
$val = JFolder::delete($source);
}
return $retval;
}
/**
* Copies the installation manifest file to the extension folder in the given client
*
* @param integer $cid Where to copy the installfile [optional: defaults to 1 (admin)]
*
* @return boolean True on success, False on error
*
* @since 11.1
*/
public function copyManifest($cid = 1)
{
// Get the client info
$client = JApplicationHelper::getClientInfo($cid);
$path['src'] = $this->getPath('manifest');
if ($client)
{
$pathname = 'extension_' . $client->name;
$path['dest'] = $this->getPath($pathname) . '/' . basename($this->getPath('manifest'));
}
else
{
$pathname = 'extension_root';
$path['dest'] = $this->getPath($pathname) . '/' . basename($this->getPath('manifest'));
}
return $this->copyFiles(array($path), true);
}
/**
* Tries to find the package manifest file
*
* @return boolean True on success, False on error
*
* @since 1.0
*/
public function findManifest()
{
// Main folder manifests (higher priority)
$parentXmlfiles = JFolder::files($this->getPath('source'), '.xml$', false, true);
// Search for children manifests (lower priority)
$allXmlFiles = JFolder::files($this->getPath('source'), '.xml$', 1, true);
// Create an unique array of files
$xmlfiles = array_unique(array_merge($parentXmlfiles, $allXmlFiles));
// If at least one XML file exists
if (!empty($xmlfiles))
{
foreach ($xmlfiles as $file)
{
// Is it a valid Joomla installation manifest file?
$manifest = $this->isManifest($file);
if (!is_null($manifest))
{
// If the root method attribute is set to upgrade, allow file overwrite
if ((string) $manifest->attributes()->method == 'upgrade')
{
$this->_upgrade = true;
$this->_overwrite = true;
}
// If the overwrite option is set, allow file overwriting
if ((string) $manifest->attributes()->overwrite == 'true')
{
$this->_overwrite = true;
}
// Set the manifest object and path
$this->manifest = $manifest;
$this->setPath('manifest', $file);
// Set the installation source path to that of the manifest file
$this->setPath('source', dirname($file));
return true;
}
}
// None of the XML files found were valid install files
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_NOTFINDJOOMLAXMLSETUPFILE'));
return false;
}
else
{
// No XML files were found in the install folder
JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE'));
return false;
}
}
/**
* Is the XML file a valid Joomla installation manifest file.
*
* @param string $file An xmlfile path to check
*
* @return mixed A JXMLElement, or null if the file failed to parse
*
* @since 11.1
*/
public function isManifest($file)
{
// Initialise variables.
$xml = JFactory::getXML($file);
// If we cannot load the XML file return null
if (!$xml)
{
return null;
}
// Check for a valid XML root tag.
// @todo: Remove backwards compatibility in a future version
// Should be 'extension', but for backward compatibility we will accept 'extension' or 'install'.
// 1.5 uses 'install'
// 1.6 uses 'extension'
if ($xml->getName() != 'install' && $xml->getName() != 'extension')
{
return null;
}
// Valid manifest file return the object
return $xml;
}
/**
* Generates a manifest cache
*
* @return string serialised manifest data
*
* @since 11.1
*/
public function generateManifestCache()
{
return json_encode(JApplicationHelper::parseXMLInstallFile($this->getPath('manifest')));
}
/**
* Cleans up discovered extensions if they're being installed some other way
*
* @param string $type The type of extension (component, etc)
* @param string $element Unique element identifier (e.g. com_content)
* @param string $folder The folder of the extension (plugins; e.g. system)
* @param integer $client The client application (administrator or site)
*
* @return object Result of query
*
* @since 11.1
*/
public function cleanDiscoveredExtension($type, $element, $folder = '', $client = 0)
{
$dbo = JFactory::getDBO();
$query = $dbo->getQuery(true);
$query->delete($dbo->quoteName('#__extensions'));
$query->where('type = ' . $dbo->Quote($type));
$query->where('element = ' . $dbo->Quote($element));
$query->where('folder = ' . $dbo->Quote($folder));
$query->where('client_id = ' . intval($client));
$query->where('state = -1');
return $dbo->execute();
}
/**
* Compares two "files" entries to find deleted files/folders
*
* @param array $old_files An array of SimpleXMLElement objects that are the old files
* @param array $new_files An array of SimpleXMLElement objects that are the new files
*
* @return array An array with the delete files and folders in findDeletedFiles[files] and findDeletedFiles[folders] respectively
*
* @since 11.1
*/
public function findDeletedFiles($old_files, $new_files)
{
// The magic find deleted files function!
// The files that are new
$files = array();
// The folders that are new
$folders = array();
// The folders of the files that are new
$containers = array();
// A list of files to delete
$files_deleted = array();
// A list of folders to delete
$folders_deleted = array();
foreach ($new_files as $file)
{
switch ($file->getName())
{
case 'folder':
// Add any folders to the list
$folders[] = (string) $file; // add any folders to the list
break;
case 'file':
default:
// Add any files to the list
$files[] = (string) $file;
// Now handle the folder part of the file to ensure we get any containers
// Break up the parts of the directory
$container_parts = explode('/', dirname((string) $file));
// Make sure this is clean and empty
$container = '';
foreach ($container_parts as $part)
{
// Iterate through each part
// Add a slash if its not empty
if (!empty($container))
{
$container .= '/';
}
$container .= $part; // append the folder part
if (!in_array($container, $containers))
{
$containers[] = $container; // add the container if it doesn't already exist
}
}
break;
}
}
foreach ($old_files as $file)
{
switch ($file->getName())
{
case 'folder':
if (!in_array((string) $file, $folders))
{
// See whether the folder exists in the new list
if (!in_array((string) $file, $containers))
{
// Check if the folder exists as a container in the new list
// If it's not in the new list or a container then delete it
$folders_deleted[] = (string) $file;
}
}
break;
case 'file':
default:
if (!in_array((string) $file, $files))
{
// look if the file exists in the new list
if (!in_array(dirname((string) $file), $folders))
{
// look if the file is now potentially in a folder
$files_deleted[] = (string) $file; // not in a folder, doesn't exist, wipe it out!
}
}
break;
}
}
return array('files' => $files_deleted, 'folders' => $folders_deleted);
}
/**
* Loads an MD5SUMS file into an associative array
*
* @param string $filename Filename to load
*
* @return array Associative array with filenames as the index and the MD5 as the value
*
* @since 11.1
*/
public function loadMD5Sum($filename)
{
if (!file_exists($filename))
{
// Bail if the file doesn't exist
return false;
}
$data = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$retval = array();
foreach ($data as $row)
{
$results = explode(' ', $row); // split up the data
$results[1] = str_replace('./', '', $results[1]); // cull any potential prefix
$retval[$results[1]] = $results[0]; // throw into the array
}
return $retval;
}
/**
* Parse a XML install manifest file.
*
* XML Root tag should be 'install' except for languages which use meta file.
*
* @param string $path Full path to XML file.
*
* @return array XML metadata.
*
* @since 12.1
*/
public static function parseXMLInstallFile($path)
{
// Read the file to see if it's a valid component XML file
if (!$xml = JFactory::getXML($path))
{
return false;
}
// Check for a valid XML root tag.
// Should be 'install', but for backward compatibility we will accept 'extension'.
// Languages use 'metafile' instead
if ($xml->getName() != 'install' && $xml->getName() != 'extension' && $xml->getName() != 'metafile')
{
unset($xml);
return false;
}
$data = array();
$data['legacy'] = ($xml->getName() == 'mosinstall' || $xml->getName() == 'install');
$data['name'] = (string) $xml->name;
// Check if we're a language. If so use metafile.
$data['type'] = $xml->getName() == 'metafile' ? 'language' : (string) $xml->attributes()->type;
$data['creationDate'] = ((string) $xml->creationDate) ? (string) $xml->creationDate : JText::_('Unknown');
$data['author'] = ((string) $xml->author) ? (string) $xml->author : JText::_('Unknown');
$data['copyright'] = (string) $xml->copyright;
$data['authorEmail'] = (string) $xml->authorEmail;
$data['authorUrl'] = (string) $xml->authorUrl;
$data['version'] = (string) $xml->version;
$data['description'] = (string) $xml->description;
$data['group'] = (string) $xml->group;
return $data;
}
}
PK Z?\;pz z
extension.phpnu W+A type = (string) $element->attributes()->type;
$this->id = (string) $element->attributes()->id;
switch ($this->type)
{
case 'component':
// By default a component doesn't have anything
break;
case 'module':
case 'template':
case 'language':
$this->client = (string) $element->attributes()->client;
$tmp_client_id = JApplicationHelper::getClientInfo($this->client, 1);
if ($tmp_client_id == null)
{
JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_EXTENSION_INVALID_CLIENT_IDENTIFIER'));
}
else
{
$this->client_id = $tmp_client_id->id;
}
break;
case 'plugin':
$this->group = (string) $element->attributes()->group;
break;
default:
// Catch all
// Get and set client and group if we don't recognise the extension
if ($client = (string) $element->attributes()->client)
{
$this->client_id = JApplicationHelper::getClientInfo($this->client, 1);
$this->client_id = $this->client_id->id;
}
if ($group = (string) $element->attributes()->group)
{
$this->group = (string) $element->attributes()->group;
}
break;
}
$this->filename = (string) $element;
}
}
}
PK Z?\XM packagemanifest.phpnu W+A loadManifestFromXML($xmlpath);
}
}
/**
* Load a manifest from an XML file
*
* @param string $xmlfile Path to XML manifest file
*
* @return boolean Result of load
*
* @since 11.1
*/
public function loadManifestFromXML($xmlfile)
{
$this->manifest_file = JFile::stripExt(basename($xmlfile));
$xml = JFactory::getXML($xmlfile);
if (!$xml)
{
$this->_errors[] = JText::sprintf('JLIB_INSTALLER_ERROR_LOAD_XML', $xmlfile);
return false;
}
else
{
$this->name = (string) $xml->name;
$this->packagename = (string) $xml->packagename;
$this->update = (string) $xml->update;
$this->authorurl = (string) $xml->authorUrl;
$this->author = (string) $xml->author;
$this->authoremail = (string) $xml->authorEmail;
$this->description = (string) $xml->description;
$this->packager = (string) $xml->packager;
$this->packagerurl = (string) $xml->packagerurl;
$this->scriptfile = (string) $xml->scriptfile;
$this->version = (string) $xml->version;
if (isset($xml->files->file) && count($xml->files->file))
{
foreach ($xml->files->file as $file)
{
// NOTE: JExtension doesn't expect a string.
// DO NOT CAST $file
$this->filelist[] = new JExtension($file);
}
}
return true;
}
}
}
PK Z?\&W librarymanifest.phpnu W+A loadManifestFromXML($xmlpath);
}
}
/**
* Load a manifest from a file
*
* @param string $xmlfile Path to file to load
*
* @return boolean
*
* @since 11.1
*/
public function loadManifestFromXML($xmlfile)
{
$this->manifest_file = JFile::stripExt(basename($xmlfile));
$xml = JFactory::getXML($xmlfile);
if (!$xml)
{
$this->_errors[] = JText::sprintf('JLIB_INSTALLER_ERROR_LOAD_XML', $xmlfile);
return false;
}
else
{
$this->name = (string) $xml->name;
$this->libraryname = (string) $xml->libraryname;
$this->version = (string) $xml->version;
$this->description = (string) $xml->description;
$this->creationdate = (string) $xml->creationdate;
$this->author = (string) $xml->author;
$this->authoremail = (string) $xml->authorEmail;
$this->authorurl = (string) $xml->authorUrl;
$this->packager = (string) $xml->packager;
$this->packagerurl = (string) $xml->packagerurl;
$this->update = (string) $xml->update;
if (isset($xml->files) && isset($xml->files->file) && count($xml->files->file))
{
foreach ($xml->files->file as $file)
{
$this->filelist[] = (string) $file;
}
}
return true;
}
}
}
PK Z?\) .htaccessnu W+A
Order allow,deny
Deny from all
PK Z?\) adapters/.htaccessnu W+A PK Z?\V adapters/index.htmlnu W+A PK Z?\;E E # adapters/template.phpnu W+A PK Z?\Gb ~F adapters/component.phpnu W+A PK Z?\+(N N 3 adapters/language.phpnu W+A PK Z?\ښ/!e !e Ȃ adapters/module.phpnu W+A PK Z?\"*;2 ;2 , adapters/library.phpnu W+A PK Z?\aP4b 4b adapters/plugin.phpnu W+A PK Z?\UM UM "} adapters/file.phpnu W+A PK Z?\A"|; |; adapters/package.phpnu W+A PK Z?\#0 0
x helper.phpnu W+A PK Z?\V
# index.htmlnu W+A PK Z?\Am6 6
;$ installer.phpnu W+A PK Z?\;pz z
extension.phpnu W+A PK Z?\XM e packagemanifest.phpnu W+A PK Z?\&W ) librarymanifest.phpnu W+A PK Z?\) @ .htaccessnu W+A PK a