/** * @todo Implement testGetPath(). */ public function testGetPath() { $this->saveFactoryState(); $newDbo = $this->getMock('test'); JFactory::$database = &$newDbo; $this->object = JInstaller::getInstance(); $this->assertThat( $this->object->getPath('path1_getpath', 'default_value'), $this->equalTo('default_value'), 'getPath did not return the default value for an undefined path' ); $this->object->setPath('path2_getpath', JPATH_BASE.'/required_path'); $this->assertThat( $this->object->getPath('path2_getpath', 'default_value'), $this->equalTo(JPATH_BASE.'/required_path'), 'getPath did not return the previously set value for the path' ); $this->restoreFactoryState(); }
public function install() { foreach ($this->manifests as $i => $manifest) { $installer = new JInstaller(); $installer->setPath('source', $this->parent->getPath('source')); //This is essentially what method="upgrade" does $installer->_overwrite = true; $xml =& JFactory::getXMLParser('Simple'); $xml->loadFile($manifest); $installer->_manifest = $xml; $installer->setPath('manifest', $manifest); $root = $xml->document; $type = $root->attributes('type'); //Don't install if the type isn't defined if (!$type) { unset($this->manifests[$i]); continue; } // Lazy load the adapter if (!isset($installer->_adapters[$type]) || !is_object($installer->_adapters[$type])) { $installer->setAdapter($type); } $installer->_adapters[$type]->install(); $installer->install($this->parent->getPath('source')); } if (JFolder::exists($this->parent->getPath('source') . '/nooku')) { $this->manifests[] = $manifest = $this->parent->getPath('source') . '/nooku/manifest.xml'; $installer = new JInstaller(); $installer->setPath('source', $this->parent->getPath('source') . '/nooku'); //This is essentially what method="upgrade" does $installer->_overwrite = true; $xml =& JFactory::getXMLParser('Simple'); $xml->loadFile($manifest); $installer->_manifest = $xml; $installer->setPath('manifest', $manifest); $root = $xml->document; $type = $root->attributes('type'); // Lazy load the adapter if (!isset($installer->_adapters[$type]) || !is_object($installer->_adapters[$type])) { $installer->setAdapter($type); } $installer->_adapters[$type]->install(); $installer->install($this->parent->getPath('source')); } return $this; }
function getManifestObject($path) { $installer = new JInstaller(); $installer->setPath('source', $path); if (!$installer->setupInstall()) { return null; } $manifest =& $installer->getManifest(); return $manifest; }
/** * Test... * * @covers JInstaller::getPath * * @return void */ public function testGetPath() { $this->assertThat( $this->object->getPath('path1_getpath', 'default_value'), $this->equalTo('default_value'), 'getPath did not return the default value for an undefined path' ); $this->object->setPath('path2_getpath', JPATH_BASE . '/required_path'); $this->assertThat( $this->object->getPath('path2_getpath', 'default_value'), $this->equalTo(JPATH_BASE . '/required_path'), 'getPath did not return the previously set value for the path' ); }
/** * Custom install method * * @access public * @return boolean True on success * @since 1.5 */ 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 extensions 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 Compatability * @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 . DS . $group . DS . $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 = 'SELECT `extension_id`' . ' FROM `#__extensions`' . ' WHERE folder = ' . $db->Quote($group) . ' AND element = ' . $db->Quote($element); $db->setQuery($query); try { $db->Query(); } 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 its on the fs... if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->getOverwrite() || $this->parent->getUpgrade())) { $updateElement = $xml->update; // upgrade manually set // update function available // update tag detected if ($this->parent->getUpgrade() || $this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update') || is_a($updateElement, 'JXMLElement')) { // force these 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'; } } else { if (!$this->parent->getOverwrite()) { // overwrite is set // we didn't have overwrite set, find an udpate 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, lets load it; we'll copy it later (don't have dest yet) if ((string) $xml->scriptfile) { $manifestScript = (string) $xml->scriptfile; $manifestScriptFile = $this->parent->getPath('source') . DS . $manifestScript; if (is_file($manifestScriptFile)) { // load the file include_once $manifestScriptFile; } // Set the class name $classname = 'plg' . $group . $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, lets 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') . DS . $this->get('manifest_script'); $path['dest'] = $this->parent->getPath('extension_root') . DS . $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 already installed with the same name? if ($id) { if (!$this->parent->getOverwrite()) { // 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(); $row->custom_data = ''; // custom data $row->system_data = ''; // 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); } } else { if (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; } } $msg .= ob_get_contents(); // append messages 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); } $msg .= ob_get_contents(); // append messages ob_end_clean(); if ($msg != '') { $this->parent->set('extension_message', $msg); } return $id; }
/** * Custom update method for components * * @return boolean True on success * * @since 3.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'))); // Copy the admin path as it's used as a common base $this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // 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) { JLog::add(JText::_('JLIB_INSTALLER_ABORT_COMP_UPDATE_ADMIN_ELEMENT'), JLog::WARNING, 'jerror'); 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); } } // 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')))) { JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_SITE', $this->parent->getPath('extension_site')), JLog::WARNING, 'jerror'); 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')))) { JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_ADMIN', $this->parent->getPath('extension_administrator')), JLog::WARNING, 'jerror'); // 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); // 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)) { JLog::add(JText::_('JLIB_INSTALLER_ABORT_COMP_BUILDADMINMENUS_FAILED'), JLog::WARNING, 'jerror'); // $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 * update method, and append the return value from the custom update * method to the installation message. */ 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' => 1, '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; }
/** * Method to create the extension root path if necessary * * @return void * * @since 3.4 * @throws RuntimeException */ protected function createExtensionRoot() { // Run the common create code first parent::createExtensionRoot(); // 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') { // Create a new installer because findManifest sets stuff; side effects! $tmpInstaller = new JInstaller(); // 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; } } }
/** * Method to setup the update routine for the adapter * * @return void * * @since 3.4 */ protected function setupUpdates() { // Hunt for the original XML file $old_manifest = null; // Use a temporary instance due to side effects; start 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(); } if ($old_manifest) { $this->oldAdminFiles = $old_manifest->administration->files; $this->oldFiles = $old_manifest->files; } }
/** * Rebuild update sites tables. * * @return void * * @since 3.6 * * @throws Exception on ACL error */ public function rebuild() { if (!JFactory::getUser()->authorise('core.admin', 'com_installer')) { throw new Exception(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_NOT_PERMITTED'), 403); } $db = JFactory::getDbo(); $app = JFactory::getApplication(); // Check if Joomla Extension plugin is enabled. if (!JPluginHelper::isEnabled('extension', 'joomla')) { $query = $db->getQuery(true)->select($db->quoteName('extension_id'))->from($db->quoteName('#__extensions'))->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))->where($db->quoteName('element') . ' = ' . $db->quote('joomla'))->where($db->quoteName('folder') . ' = ' . $db->quote('extension')); $db->setQuery($query); $pluginId = (int) $db->loadResult(); $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . $pluginId); $app->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATESITES_REBUILD_EXTENSION_PLUGIN_NOT_ENABLED', $link), 'error'); return; } $clients = array(JPATH_SITE, JPATH_ADMINISTRATOR); $extensionGroupFolders = array('components', 'modules', 'plugins', 'templates', 'language', 'manifests'); $pathsToSearch = array(); // Identifies which folders to search for manifest files. foreach ($clients as $clientPath) { foreach ($extensionGroupFolders as $extensionGroupFolderName) { // Components, modules, plugins, templates, languages and manifest (files, libraries, etc) if ($extensionGroupFolderName != 'plugins') { foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) { array_push($pathsToSearch, $extensionFolderPath); } } else { foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $pluginGroupFolderPath) { foreach (glob($pluginGroupFolderPath . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) { array_push($pathsToSearch, $extensionFolderPath); } } } } } // Gets Joomla core update sites Ids. $joomlaUpdateSitesIds = implode(', ', $this->getJoomlaUpdateSitesIds(0)); // Delete from all tables (except joomla core update sites). $query = $db->getQuery(true)->delete($db->quoteName('#__update_sites'))->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); $db->setQuery($query); $db->execute(); $query = $db->getQuery(true)->delete($db->quoteName('#__update_sites_extensions'))->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); $db->setQuery($query); $db->execute(); $query = $db->getQuery(true)->delete($db->quoteName('#__updates'))->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); $db->setQuery($query); $db->execute(); $count = 0; // Gets Joomla core extension Ids. $joomlaCoreExtensionIds = implode(', ', $this->getJoomlaUpdateSitesIds(1)); // Search for updateservers in manifest files inside the folders to search. foreach ($pathsToSearch as $extensionFolderPath) { $tmpInstaller = new JInstaller(); $tmpInstaller->setPath('source', $extensionFolderPath); // Main folder manifests (higher priority) $parentXmlfiles = JFolder::files($tmpInstaller->getPath('source'), '.xml$', false, true); // Search for children manifests (lower priority) $allXmlFiles = JFolder::files($tmpInstaller->getPath('source'), '.xml$', 1, true); // Create an unique array of files ordered by priority $xmlfiles = array_unique(array_merge($parentXmlfiles, $allXmlFiles)); if (!empty($xmlfiles)) { foreach ($xmlfiles as $file) { // Is it a valid Joomla installation manifest file? $manifest = $tmpInstaller->isManifest($file); if (!is_null($manifest)) { // Search if the extension exists in the extensions table. Excluding joomla core extensions (id < 10000) and discovered extensions. $query = $db->getQuery(true)->select($db->quoteName('extension_id'))->from($db->quoteName('#__extensions'))->where($db->quoteName('name') . ' = ' . $db->quote($manifest->name))->where($db->quoteName('type') . ' = ' . $db->quote($manifest['type']))->where($db->quoteName('extension_id') . ' NOT IN (' . $joomlaCoreExtensionIds . ')')->where($db->quoteName('state') . ' != -1'); $db->setQuery($query); $eid = (int) $db->loadResult(); if ($eid && $manifest->updateservers) { // Set the manifest object and path $tmpInstaller->manifest = $manifest; $tmpInstaller->setPath('manifest', $file); // Load the extension plugin (if not loaded yet). JPluginHelper::importPlugin('extension', 'joomla'); // Fire the onExtensionAfterUpdate JFactory::getApplication()->triggerEvent('onExtensionAfterUpdate', array('installer' => $tmpInstaller, 'eid' => $eid)); $count++; } } } } } if ($count > 0) { $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_SUCCESS'), 'message'); } else { $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_MESSAGE'), 'message'); } }
/** * Custom update method for components * * @access public * @return boolean True on success * @since 1.5 */ 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 extensions name $name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'); $element = strtolower('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 . DS . "components" . DS . $this->get('element'))); $this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR . DS . "components" . DS . $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 */ $oldmanifest = null; $tmpInstaller = new JInstaller(); // create a new installer because findManifest sets stuff // look in the administrator first $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::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('The XML file did not contain an administration 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') . DS . $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')) { $this->parent->manifestClass->preflight('update', $this); } $msg = ob_get_contents(); // create msg object; first use here ob_end_clean(); /** * --------------------------------------------------------------------------------------------- * Filesystem Processing Section * --------------------------------------------------------------------------------------------- */ // If the component directory does not exist, lets 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::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('FAILED_TO_CREATE_DIRECTORY') . ': "' . $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, lets 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::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('FAILED_TO_CREATE_DIRECTORY') . ': "' . $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, lets 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') . DS . $installFile) || $this->parent->getOverwrite()) { $path['src'] = $this->parent->getPath('source') . DS . $installFile; $path['dest'] = $this->parent->getPath('extension_administrator') . DS . $installFile; if (!$this->parent->copyFiles(array($path))) { // Install failed, rollback changes $this->parent->abort(JText::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('Could_not_copy_PHP_install_file')); 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') . DS . $uninstallFile) || $this->parent->getOverwrite()) { $path['src'] = $this->parent->getPath('source') . DS . $uninstallFile; $path['dest'] = $this->parent->getPath('extension_administrator') . DS . $uninstallFile; if (!$this->parent->copyFiles(array($path))) { // Install failed, rollback changes $this->parent->abort(JText::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('Could_not_copy_PHP_uninstall_file')); return false; } } } // If there is a manifest script, lets copy it. if ($this->get('manifest_script')) { $path['src'] = $this->parent->getPath('source') . DS . $this->get('manifest_script'); $path['dest'] = $this->parent->getPath('extension_administrator') . DS . $this->get('manifest_script'); if (!file_exists($path['dest']) || $this->parent->getOverwrite()) { if (!$this->parent->copyFiles(array($path))) { // Install failed, rollback changes $this->parent->abort(JText::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('Could not copy PHP manifest file.')); 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 */ // second argument is the utf compatible version attribute $utfresult = $this->parent->parseSQLFiles($this->manifest->update->sql); if ($utfresult === false) { // Install failed, rollback changes $this->parent->abort(JText::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('SQLERRORORFILE') . " " . $db->stderr(true)); return false; } // Time to build the admin menus $this->_buildAdminMenus(); /** * --------------------------------------------------------------------------------------------- * Custom Installation Script Section * --------------------------------------------------------------------------------------------- */ /* * If we have an update script, lets 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')) { $this->parent->manifestClass->update($this); } $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); } // Update an entry to the extension table $row =& JTable::getInstance('extension'); $eid = $row->find(array('element' => strtolower($this->get('element')), 'type' => 'component')); if ($eid) { $row->load($eid); } else { // set the defaults $row->folder = ''; // There is no folder for components $row->enabled = 1; $row->protected = 0; $row->access = 1; $row->client_id = 0; $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::_('Component') . ' ' . JText::_('Update') . ': ' . $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::_('Component') . ' ' . JText::_('Update') . ': ' . JText::_('COULD_NOT_COPY_SETUP_FILE')); 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->extension_id; }
/** * Attempts to uninstall the specified extension * * @param array $pkg the paket package information * @return Boolean True if successful, false otherwise */ function uninstallExtension($package) { //Get an installer instance, always get a new one $installer = new JInstaller(); //attemp to load the manifest file $file = $this->findManifest($package); //check to see if the manifest was found if (isset($file)) { if (version_compare(JVERSION, '1.6.0', 'ge')) { // Joomla! 1.6+ code here $manifest = $installer->isManifest($file); } else { // Joomla! 1.5 code here $manifest = $installer->_isManifest($file); } if (!is_null($manifest)) { // If the root method attribute is set to upgrade, allow file overwrite $root = $manifest->document; if ($root->attributes('method') == 'upgrade') { $installer->_overwrite = true; } // Set the manifest object and path $installer->_manifest = $manifest; $installer->setPath('manifest', $file); // Set the installation source path to that of the manifest file $installer->setPath('source', dirname($file)); } } else { $this->setError(JText::_("Unable to locate manifest file")); return false; } //check if the extension is installed already and if so uninstall it //$manifestInformation = $this->paketItemToManifest($package); $manifestInformation = $package; $elementID = $this->checkIfInstalledAlready($manifestInformation); if ($elementID != 0) { $clientid = 0; if ($package['client'] == 'administrator') { $clientid = '1'; } //uninstall the extension using the joomla uninstaller if ($installer->uninstall($manifestInformation["type"], $elementID, $clientid)) { $this->setError(JText::_("ELEMENT UNINSTALLED")); return true; } } //$this->_addModifiedExtension($manifestInformation); //$this->_formatMessage("Uninstalled"); $this->setError(JText::_("ELEMENT NOT INSTALLED")); return false; }
public function preflight($type, $parent) { // Bugfix for "Can not build admin menus" if (in_array($type, array('install', 'discover_install'))) { $this->bugfixDBFunctionReturnedNoError(); } else { $this->bugfixCantBuildAdminMenus(); } $manifest = $parent->getParent()->getManifest(); // Prevent installation if requirements are not met. if (!$this->checkRequirements($manifest->version)) { return false; } // TODO: If we do not need to display the warning (but only after dropping J1.5 support) // if (version_compare($manifest->version, '2.0', '>')) return true; $adminpath = $parent->getParent()->getPath('extension_administrator'); $sitepath = $parent->getParent()->getPath('extension_site'); // If Kunena wasn't installed, there's nothing to do. if (!file_exists($adminpath)) { return true; } // Find the old manifest file. $tmpInstaller = new JInstaller(); $tmpInstaller->setPath('source', $adminpath); $obj_manifest = $tmpInstaller->findManifest() ? $tmpInstaller->getManifest() : null; $old_manifest = basename($tmpInstaller->getPath('manifest')); if ($obj_manifest) { $this->oldAdminFiles = $this->findFilesFromManifest($obj_manifest->administration->files) + array($old_manifest => $old_manifest); $this->oldAdminFiles += $this->findFilesFromManifest($manifest->administration->files); $this->oldFiles = $this->findFilesFromManifest($obj_manifest->files); $this->oldFiles += $this->findFilesFromManifest($manifest->files); } // Detect existing installation. if ($old_manifest && JFile::exists("{$adminpath}/admin.kunena.php")) { $contents = file_get_contents("{$adminpath}/admin.kunena.php"); if (!strstr($contents, '/* KUNENA FORUM INSTALLER */')) { // If we don't find Kunena 2.0 installer, backup existing files... $backuppath = "{$adminpath}/bak"; if (JFolder::exists($backuppath)) { JFolder::delete($backuppath); } $this->backup($adminpath, $backuppath, $this->oldAdminFiles); $backuppath = "{$sitepath}/bak"; if (JFolder::exists($backuppath)) { JFolder::delete($backuppath); } $this->backup($sitepath, $backuppath, $this->oldFiles); } } // Remove old manifest files, excluding the current one. $manifests = array('manifest.xml', 'kunena.j16.xml', 'kunena.j25.xml', 'kunena.xml'); foreach ($manifests as $filename) { if ($filename == $old_manifest) { continue; } if (JFile::exists("{$adminpath}/{$filename}")) { JFile::delete("{$adminpath}/{$filename}"); } } clearstatcache(); return true; }
/** * Attempts to uninstall the specified extension * * @param array $pkg the paket package information * @return Boolean True if successful, false otherwise */ function uninstallExtension($package) { //Get an installer instance, always get a new one $installer = new JInstaller(); //attemp to load the manifest file $file = $this->findManifest($package); //check to see if the manifest was found if (isset($file)) { // Is it a valid joomla installation manifest file? $manifest = $installer->_isManifest($file); if (!is_null($manifest)) { // If the root method attribute is set to upgrade, allow file overwrite $root = $manifest->document; if ($root->attributes('method') == 'upgrade') { $installer->_overwrite = true; } // Set the manifest object and path $installer->_manifest = $manifest; $installer->setPath('manifest', $file); // Set the installation source path to that of the manifest file $installer->setPath('source', dirname($file)); } } else { $this->setError(JText::_('COM_TIENDA_UNABLE_TO_LOCATE_MANIFEST_FILE')); return false; } //check if the extension is installed already and if so uninstall it //$manifestInformation = $this->paketItemToManifest($package); $manifestInformation = $package; $elementID = $this->checkIfInstalledAlready($manifestInformation); if (!empty($elementID)) { $clientid = 0; if ($package['client'] == 'administrator') { $clientid = '1'; } //uninstall the extension using the joomla uninstaller if ($installer->uninstall($manifestInformation["type"], $elementID, $clientid)) { $this->setError(JText::_('COM_TIENDA_ELEMENT_UNINSTALLED')); return true; } else { $this->setError(JText::_('COM_TIENDA_ELEMENT_UNINSTALL_FAILED') . " :: " . $installer->getError()); return false; } } $this->setError(JText::_('COM_TIENDA_ELEMENT_NOT_UNINSTALLED')); return false; }
public function preflight($type, $adapter) { if ($type !== 'update') { return true; } // "Fix" Joomla! bug $row = JTable::getInstance('extension'); $eid = $row->find(array('element' => strtolower($adapter->get('element')), 'type' => 'component')); $db = JFactory::getDbo(); $query = $db->getQuery(true); $query->select('version_id')->from('#__schemas')->where('extension_id = ' . $eid); $db->setQuery($query); if ($db->loadResult()) { return true; } // Get the previous version $old_manifest = null; // Create a new installer because findManifest sets stuff // Look in the administrator first $tmpInstaller = new JInstaller(); $tmpInstaller->setPath('source', JPATH_ADMINISTRATOR . '/components/com_slicomments'); if (!$tmpInstaller->findManifest()) { echo 'Could not find old manifest.'; return false; } $old_manifest = $tmpInstaller->getManifest(); $version = (string) $old_manifest->version; // Store $data = new stdClass(); $data->extension_id = $eid; $data->version_id = $version; $db->insertObject('#__schemas', $data); return true; }
public function getKSVersion() { $kmdestination = JPATH_ROOT . '/administrator/components/' . $this->ext_name_com; $tmpInstaller = new JInstaller(); $tmpInstaller->setPath('source', $kmdestination); $manifest = $tmpInstaller->getManifest(); $info = new stdClass(); $info->name = JText::_($manifest->name); $info->version = (string) $manifest->version; JFactory::getApplication()->close(json_encode($info)); }