diff --git a/administrator/language/en-GB/en-GB.lib_joomla.ini b/administrator/language/en-GB/en-GB.lib_joomla.ini index b7929aa2d9d93..14b271b6cb0ea 100644 --- a/administrator/language/en-GB/en-GB.lib_joomla.ini +++ b/administrator/language/en-GB/en-GB.lib_joomla.ini @@ -539,11 +539,13 @@ JLIB_INSTALLER_ERROR_CREATE_DIRECTORY="JInstaller: :Install: Failed to create fo JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED="Failed to create folder [%s]" JLIB_INSTALLER_ERROR_DEPRECATED_FORMAT="Deprecated install format (client="_QQ_"both"_QQ_"), use package installer in future." JLIB_INSTALLER_ERROR_DISCOVER_INSTALL_UNSUPPORTED="A %s extension can not be installed using the discover method. Please install this extension from Extension Manager: Install." +JLIB_INSTALLER_ERROR_DOWNGRADE="Sorry! You cannot downgrade from version %s to %s" JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT="Error connecting to the server: %s" JLIB_INSTALLER_ERROR_FAIL_COPY_FILE="JInstaller: :Install: Failed to copy file %1$s to %2$s" JLIB_INSTALLER_ERROR_FAIL_COPY_FOLDER="JInstaller: :Install: Failed to copy folder %1$s to %2$s" JLIB_INSTALLER_ERROR_FAILED_READING_NETWORK_RESOURCES="Failed reading network resource: %s" JLIB_INSTALLER_ERROR_FILE_EXISTS="JInstaller: :Install: File already exists %s" +JLIB_INSTALLER_ERROR_FILE_FOLDER="Error on deleting file or folder %s" JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_MANIFEST="Files Uninstall: Invalid manifest file." JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Files Uninstall: Manifest file invalid or not found." JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_ENTRY="Files Uninstall: Could not load extension entry." @@ -602,7 +604,10 @@ JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DIRECTORY="Template Uninstall: Folde JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_ID_EMPTY="Template Uninstall: Template ID is empty, can't uninstall files." JLIB_INSTALLER_ERROR_TPL_UNINSTALL_WARNCORETEMPLATE="Template Uninstall: Trying to uninstall a core template: %s" JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE="Unknown Client Type [%s]" +JLIB_INSTALLER_FILE_ERROR_MOVE="Error on moving file %s" JLIB_INSTALLER_INSTALL="Install" +JLIB_INSTALLER_MINIMUM_JOOMLA="You don't have the minimum Joomla version requirement of J%s" +JLIB_INSTALLER_MINIMUM_PHP="Your server doesn't meet the minimum PHP version requirement of %s" JLIB_INSTALLER_NOTICE_LANG_RESET_USERS="Language set to Default for %d users." JLIB_INSTALLER_NOTICE_LANG_RESET_USERS_1="Language set to Default for %d user." JLIB_INSTALLER_UNINSTALL="Uninstall" diff --git a/language/en-GB/en-GB.lib_joomla.ini b/language/en-GB/en-GB.lib_joomla.ini index b7929aa2d9d93..14b271b6cb0ea 100644 --- a/language/en-GB/en-GB.lib_joomla.ini +++ b/language/en-GB/en-GB.lib_joomla.ini @@ -539,11 +539,13 @@ JLIB_INSTALLER_ERROR_CREATE_DIRECTORY="JInstaller: :Install: Failed to create fo JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED="Failed to create folder [%s]" JLIB_INSTALLER_ERROR_DEPRECATED_FORMAT="Deprecated install format (client="_QQ_"both"_QQ_"), use package installer in future." JLIB_INSTALLER_ERROR_DISCOVER_INSTALL_UNSUPPORTED="A %s extension can not be installed using the discover method. Please install this extension from Extension Manager: Install." +JLIB_INSTALLER_ERROR_DOWNGRADE="Sorry! You cannot downgrade from version %s to %s" JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT="Error connecting to the server: %s" JLIB_INSTALLER_ERROR_FAIL_COPY_FILE="JInstaller: :Install: Failed to copy file %1$s to %2$s" JLIB_INSTALLER_ERROR_FAIL_COPY_FOLDER="JInstaller: :Install: Failed to copy folder %1$s to %2$s" JLIB_INSTALLER_ERROR_FAILED_READING_NETWORK_RESOURCES="Failed reading network resource: %s" JLIB_INSTALLER_ERROR_FILE_EXISTS="JInstaller: :Install: File already exists %s" +JLIB_INSTALLER_ERROR_FILE_FOLDER="Error on deleting file or folder %s" JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_MANIFEST="Files Uninstall: Invalid manifest file." JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Files Uninstall: Manifest file invalid or not found." JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_ENTRY="Files Uninstall: Could not load extension entry." @@ -602,7 +604,10 @@ JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DIRECTORY="Template Uninstall: Folde JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_ID_EMPTY="Template Uninstall: Template ID is empty, can't uninstall files." JLIB_INSTALLER_ERROR_TPL_UNINSTALL_WARNCORETEMPLATE="Template Uninstall: Trying to uninstall a core template: %s" JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE="Unknown Client Type [%s]" +JLIB_INSTALLER_FILE_ERROR_MOVE="Error on moving file %s" JLIB_INSTALLER_INSTALL="Install" +JLIB_INSTALLER_MINIMUM_JOOMLA="You don't have the minimum Joomla version requirement of J%s" +JLIB_INSTALLER_MINIMUM_PHP="Your server doesn't meet the minimum PHP version requirement of %s" JLIB_INSTALLER_NOTICE_LANG_RESET_USERS="Language set to Default for %d users." JLIB_INSTALLER_NOTICE_LANG_RESET_USERS_1="Language set to Default for %d user." JLIB_INSTALLER_UNINSTALL="Uninstall" diff --git a/libraries/cms/installer/script.php b/libraries/cms/installer/script.php new file mode 100644 index 0000000000000..d6126635641f8 --- /dev/null +++ b/libraries/cms/installer/script.php @@ -0,0 +1,353 @@ +minimumPhp) && !version_compare(PHP_VERSION, $this->minimumPhp, '>')) + { + JLog::add(JText::sprintf('JLIB_INSTALLER_MINIMUM_PHP', $this->minimumPhp), JLog::WARNING, 'jerror'); + } + + // Check for the minimum Joomla version before continuing + if (!empty($this->minimumJoomla) && !version_compare(JVERSION, $this->minimumJoomla, '>')) + { + JLog::add(JText::sprintf('JLIB_INSTALLER_MINIMUM_JOOMLA', $this->minimumJoomla), JLog::WARNING, 'jerror'); + } + + // Extension manifest file version + $this->release = $parent->get("manifest")->version; + $extensionType = substr($this->extension, 0, 3); + + // Modules parameters are located in the module table - else in the extension table + if ($extensionType === 'mod') + { + $this->paramTable = '#__modules'; + } + else + { + $this->paramTable = '#__extensions'; + } + + // Abort if the extension being installed is not newer than the currently installed version + if (strtolower($type) == 'update' && !$this->allowDowngrades) + { + $manifest = $this->getItemArray('manifest_cache', '#__extensions', 'element', JFactory::getDbo()->quote($this->extension)); + $oldRelease = $manifest['version']; + + if (version_compare($this->release, $oldRelease, '<')) + { + JFactory::getApplication()->enqueueMessage(JText::sprintf('JLIB_INSTALLER_INCORRECT_SEQUENCE', $oldRelease, $this->release), 'error'); + + return false; + } + } + + return true; + } + + /** + * Gets each instance of a module in the #__modules table + * + * @param boolean $isModule True if the extension is a module as this can have multiple instances + * + * @return array An array of ID's of the extension + * + * @since 3.6 + */ + public function getInstances($isModule) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Select the item(s) and retrieve the id + $query->select($db->quoteName('id')); + + if ($isModule) + { + $query->from($db->quoteName('#__modules')) + ->where($db->quoteName('module') . ' = ' . $db->quote($this->extension)); + } + else + { + $query->from($db->quoteName('#__extensions')) + ->where($db->quoteName('element') . ' = ' . $db->quote($this->extension)); + } + + // Set the query and obtain an array of id's + return $db->setQuery($query)->loadColumn(); + } + + /** + * Gets parameter value in the extensions row of the extension table + * + * @param string $name The name of the parameter to be retrieved + * @param integer $id The id of the item in the Param Table + * + * @return string The parameter desired + * + * @since 3.6 + */ + public function getParam($name, $id = 0) + { + if (!is_int($id) || $id == 0) + { + // Return false if there is no item given + return false; + } + + $params = $this->getItemArray('params', $this->paramTable, 'id', $id); + + return $params[$name]; + } + + /** + * Sets parameter values in the extensions row of the extension table. Note that the + * this must be called separately for deleting and editing. Note if edit is called as a + * type then if the param doesn't exist it will be created + * + * @param array $param_array The array of parameters to be added/edited/removed + * @param string $type The type of change to be made to the param (edit/remove) + * @param integer $id The id of the item in the relevant table + * + * @return boolean True on success + * + * @since 3.6 + */ + public function setParams($param_array = null, $type = 'edit', $id = 0) + { + if (!is_int($id) || $id == 0) + { + // Return false if there is no valid item given + return false; + } + + $params = $this->getItemArray('params', $this->paramTable, 'id', $id); + + if ($param_array) + { + foreach ($param_array as $name => $value) + { + if ($type == 'edit') + { + // Add or edit the new variable(s) to the existing params + if (is_array($value)) + { + // Convert an array into a json encoded string + $params[(string) $name] = array_values($value); + } + else + { + $params[(string) $name] = (string) $value; + } + } + elseif ($type == 'remove') + { + // Unset the parameter from the array + unset($params[(string) $name]); + } + } + } + + // Store the combined new and existing values back as a JSON string + $paramsString = json_encode($params); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName($this->paramTable)) + ->set('params = ' . $db->quote($paramsString)) + ->where('id = ' . $id); + + // Update table + $db->setQuery($query)->execute(); + + return true; + } + + /** + * Builds a standard select query to produce better DRY code in this script. + * This should produce a single unique cell which is json encoded - it will then + * return an associated array with this data in. + * + * @param string $element The element to get from the query + * @param string $table The table to search for the data in + * @param string $column The column of the database to search from + * @param mixed $identifier The integer id or the already quoted string + * + * @return array Associated array containing data from the cell + * + * @since 3.6 + */ + public function getItemArray($element, $table, $column, $identifier) + { + // Get the DB and query objects + $db = JFactory::getDbo(); + + // Build the query + $query = $db->getQuery(true) + ->select($db->quoteName($element)) + ->from($db->quoteName($table)) + ->where($db->quoteName($column) . ' = ' . $identifier); + $db->setQuery($query); + + // Load the single cell and json_decode data + return json_decode($db->loadResult(), true); + } + + /** + * Remove the files and folders in the given array from + * + * @return void + * + * @since 3.6 + */ + public function removeFiles() + { + if (!empty($this->deleteFiles)) + { + foreach ($this->deleteFiles as $file) + { + if (file_exists(JPATH_ROOT . $file) && !JFile::delete(JPATH_ROOT . $file)) + { + echo JText::sprintf('JLIB_INSTALLER_ERROR_FILE_FOLDER', $file) . '
'; + } + } + } + + if (!empty($this->deleteFolders)) + { + foreach ($this->deleteFolders as $folder) + { + if (JFolder::exists(JPATH_ROOT . $folder) && !JFolder::delete(JPATH_ROOT . $folder)) + { + echo JText::sprintf('JLIB_INSTALLER_ERROR_FILE_FOLDER', $folder) . '
'; + } + } + } + } + + /** + * Moves the CLI scripts into the CLI folder in the CMS + * + * @return void + * + * @since 3.6 + */ + public function moveCliFiles() + { + if (!empty($this->cliScriptFiles)) + { + foreach ($this->cliScriptFiles as $file) + { + $name = basename($file); + + if (file_exists(JPATH_ROOT . $file) && !JFile::move(JPATH_ROOT . $file, JPATH_ROOT . '/cli/' . $name)) + { + echo JText::sprintf('JLIB_INSTALLER_FILE_ERROR_MOVE', $name); + } + } + } + } +}