diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-06-03.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-06-03.sql
new file mode 100644
index 0000000000000..2166de7eb35be
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-06-03.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `#__extensions` ADD COLUMN `changelogurl` text AFTER `element`;
+ALTER TABLE `#__updates` ADD COLUMN `changelogurl` text AFTER `infourl`;
diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-06-03.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-06-03.sql
new file mode 100644
index 0000000000000..018cb0b5b749a
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-06-03.sql
@@ -0,0 +1,2 @@
+ALTER TABLE "#__extensions" ADD COLUMN "changelogurl" text;
+ALTER TABLE "#__updates" ADD COLUMN "changelogurl" text;
diff --git a/administrator/components/com_installer/Controller/ManageController.php b/administrator/components/com_installer/Controller/ManageController.php
index 3bdd126053cd0..2fdb1e74241a9 100644
--- a/administrator/components/com_installer/Controller/ManageController.php
+++ b/administrator/components/com_installer/Controller/ManageController.php
@@ -11,11 +11,14 @@
defined('_JEXEC') or die;
+use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
+use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
+use Joomla\Component\Installer\Administrator\Model\ManageModel;
use Joomla\Utilities\ArrayHelper;
/**
@@ -49,6 +52,8 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu
*
* @return void
*
+ * @throws \Exception
+ *
* @since 1.6
*/
public function publish()
@@ -67,7 +72,7 @@ public function publish()
}
else
{
- /* @var \Joomla\Component\Installer\Administrator\Model\ManageModel $model */
+ /** @var ManageModel $model */
$model = $this->getModel('manage');
// Change the state of the records.
@@ -98,6 +103,8 @@ public function publish()
*
* @return void
*
+ * @throws \Exception
+ *
* @since 1.5
*/
public function remove()
@@ -105,7 +112,7 @@ public function remove()
// Check for request forgeries.
Session::checkToken() or jexit(Text::_('JINVALID_TOKEN'));
- /* @var \Joomla\Component\Installer\Administrator\Model\ManageModel $model */
+ /** @var ManageModel $model */
$model = $this->getModel('manage');
$eid = $this->input->get('cid', array(), 'array');
@@ -128,7 +135,7 @@ public function refresh()
// Check for request forgeries.
Session::checkToken() or jexit(Text::_('JINVALID_TOKEN'));
- /* @var \Joomla\Component\Installer\Administrator\Model\ManageModel $model */
+ /** @var ManageModel $model */
$model = $this->getModel('manage');
$uid = $this->input->get('cid', array(), 'array');
@@ -136,4 +143,29 @@ public function refresh()
$model->refresh($uid);
$this->setRedirect(Route::_('index.php?option=com_installer&view=manage', false));
}
+
+ /**
+ * Load the changelog for a given extension.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function loadChangelog()
+ {
+ /** @var ManageModel $model */
+ $model = $this->getModel('manage');
+
+ $eid = $this->input->get('eid', 0, 'int');
+ $source = $this->input->get('source', 'manage', 'string');
+
+ if (!$eid)
+ {
+ return;
+ }
+
+ $output = $model->loadChangelog($eid, $source);
+
+ echo (new JsonResponse($output));
+ }
}
diff --git a/administrator/components/com_installer/Model/ManageModel.php b/administrator/components/com_installer/Model/ManageModel.php
index 411e9fe215601..25e32ddce3f09 100644
--- a/administrator/components/com_installer/Model/ManageModel.php
+++ b/administrator/components/com_installer/Model/ManageModel.php
@@ -11,11 +11,14 @@
defined('_JEXEC') or die;
+use Joomla\CMS\Changelog\Changelog;
use Joomla\CMS\Extension\ExtensionHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Installer\Installer;
use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\FileLayout;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
+use Joomla\CMS\Table\Extension;
use Joomla\Component\Templates\Administrator\Table\StyleTable;
use Joomla\Database\DatabaseQuery;
@@ -64,6 +67,8 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu
*
* @return void
*
+ * @throws \Exception
+ *
* @since 1.6
*/
protected function populateState($ordering = 'name', $direction = 'asc')
@@ -94,6 +99,8 @@ protected function populateState($ordering = 'name', $direction = 'asc')
*
* @return boolean True on success
*
+ * @throws \Exception
+ *
* @since 1.5
*/
public function publish(&$eid = array(), $value = 1)
@@ -117,7 +124,7 @@ public function publish(&$eid = array(), $value = 1)
}
// Get a table object for the extension type
- $table = new \Joomla\CMS\Table\Extension($this->getDbo());
+ $table = new Extension($this->getDbo());
// Enable the extension in the table and store it in the database
foreach ($eid as $i => $id)
@@ -182,7 +189,7 @@ public function refresh($eid)
// Get an installer object for the extension type
$installer = Installer::getInstance();
- $result = 0;
+ $result = 0;
// Uninstall the chosen extensions
foreach ($eid as $id)
@@ -200,6 +207,8 @@ public function refresh($eid)
*
* @return boolean True on success
*
+ * @throws \Exception
+ *
* @since 1.5
*/
public function remove($eid = array())
@@ -222,10 +231,10 @@ public function remove($eid = array())
// Get an installer object for the extension type
$installer = Installer::getInstance();
- $row = new \Joomla\CMS\Table\Extension($this->getDbo());
+ $row = new \Joomla\CMS\Table\Extension($this->getDbo());
// Uninstall the chosen extensions
- $msgs = array();
+ $msgs = array();
$result = false;
foreach ($eid as $id)
@@ -235,7 +244,7 @@ public function remove($eid = array())
$result = false;
$langstring = 'COM_INSTALLER_TYPE_TYPE_' . strtoupper($row->type);
- $rowtype = Text::_($langstring);
+ $rowtype = Text::_($langstring);
if (strpos($rowtype, $langstring) !== false)
{
@@ -376,4 +385,79 @@ protected function getListQuery()
return $query;
}
+
+ /**
+ * Load the changelog details for a given extension.
+ *
+ * @param integer $eid The extension ID
+ * @param string $source The view the changelog is for, this is used to determine which version number to show
+ *
+ * @return string The output to show in the modal.
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function loadChangelog($eid, $source)
+ {
+ // Get the changelog URL
+ $db = $this->getDbo();
+ $query = $db->getQuery(true)
+ ->select(
+ $db->quoteName(
+ array(
+ 'extensions.element',
+ 'extensions.type',
+ 'extensions.changelogurl',
+ 'extensions.manifest_cache',
+ 'extensions.client_id'
+ )
+ )
+ )
+ ->select($db->quoteName('updates.version', 'updateVersion'))
+ ->from($db->quoteName('#__extensions', 'extensions'))
+ ->leftJoin(
+ $db->quoteName('#__updates', 'updates')
+ . ' ON ' . $db->quoteName('updates.extension_id') . ' = ' . $db->quoteName('extensions.extension_id')
+ )
+ ->where($db->quoteName('extensions.extension_id') . ' = ' . (int) $eid);
+ $db->setQuery($query);
+
+ $extensions = $db->loadObjectList();
+ $this->translate($extensions);
+ $extension = array_shift($extensions);
+
+ if (!$extension->changelogurl)
+ {
+ return '';
+ }
+
+ $changelog = new Changelog;
+ $changelog->setVersion($source === 'manage' ? $extension->version : $extension->updateVersion);
+ $changelog->loadFromXml($extension->changelogurl);
+
+ // Read all the entries
+ $entries = array(
+ 'security' => array(),
+ 'fix' => array(),
+ 'addition' => array(),
+ 'change' => array(),
+ 'remove' => array(),
+ 'language' => array(),
+ 'note' => array()
+ );
+
+ array_walk(
+ $entries,
+ function (&$value, $name) use ($changelog) {
+ if ($field = $changelog->get($name))
+ {
+ $value = $changelog->get($name)->data;
+ }
+ }
+ );
+
+ $layout = new FileLayout('joomla.installer.changelog');
+ $output = $layout->render($entries);
+
+ return $output;
+ }
}
diff --git a/administrator/components/com_installer/tmpl/manage/default.php b/administrator/components/com_installer/tmpl/manage/default.php
index b31e99688a9db..a510f977ae020 100644
--- a/administrator/components/com_installer/tmpl/manage/default.php
+++ b/administrator/components/com_installer/tmpl/manage/default.php
@@ -104,14 +104,34 @@
type_translated; ?>
- version != '' ? $item->version : ' '; ?>
+ version !== '') : ?>
+ changelogurl !== null) : ?>
+
+ version?>
+
+ Text::sprintf('COM_INSTALLER_CHANGELOG_TITLE', $item->name, $item->version),
+ ),
+ ''
+ );
+ ?>
+
+ version; ?>
+
+
|
- creationDate != '' ? $item->creationDate : ' '; ?>
+ creationDate) && $item->creationDate !== '' ? $item->creationDate : ' '; ?>
|
- author != '' ? $item->author : ' '; ?>
+ author) && $item->author !== '' ? $item->author : ' '; ?>
|
diff --git a/administrator/components/com_installer/tmpl/update/default.php b/administrator/components/com_installer/tmpl/update/default.php
index 80ca2014605d3..cd4ca6ddf9966 100644
--- a/administrator/components/com_installer/tmpl/update/default.php
+++ b/administrator/components/com_installer/tmpl/update/default.php
@@ -27,14 +27,13 @@
showMessage) : ?>
loadTemplate('message'); ?>
-
ftp) : ?>
loadTemplate('ftp'); ?>
$this)); ?>
items)) : ?>
-
+
@@ -43,9 +42,9 @@
-
+ |
-
+ |
|
@@ -61,8 +60,11 @@
|
-
-
+ |
+
+ |
+
+
|
@@ -102,6 +104,28 @@
|
version; ?>
|
+
+ changelogurl !== null) : ?>
+
+
+
+ Text::sprintf('COM_INSTALLER_CHANGELOG_TITLE', $item->name, $item->version),
+ ),
+ ''
+ );
+ ?>
+
+
+
+
+
+
+ |
folder_translated; ?>
|
diff --git a/administrator/language/en-GB/en-GB.com_installer.ini b/administrator/language/en-GB/en-GB.com_installer.ini
index 985575ca48742..acc8a7d45e494 100644
--- a/administrator/language/en-GB/en-GB.com_installer.ini
+++ b/administrator/language/en-GB/en-GB.com_installer.ini
@@ -6,6 +6,15 @@
COM_INSTALLER="Installer"
COM_INSTALLER_AUTHOR_INFORMATION="Author Information"
COM_INSTALLER_CACHETIMEOUT_LABEL="Updates Caching (in hours)"
+COM_INSTALLER_CHANGELOG="Changelog"
+COM_INSTALLER_CHANGELOG_ADDITION="New Features"
+COM_INSTALLER_CHANGELOG_CHANGE="Changes"
+COM_INSTALLER_CHANGELOG_FIX="Bug Fixes"
+COM_INSTALLER_CHANGELOG_LANGUAGE="Language"
+COM_INSTALLER_CHANGELOG_NOTE="Notes"
+COM_INSTALLER_CHANGELOG_REMOVE="Removed Features"
+COM_INSTALLER_CHANGELOG_SECURITY="Security Fixes"
+COM_INSTALLER_CHANGELOG_TITLE="Changelog - %s - %s"
COM_INSTALLER_CONFIGURATION="Installer: Options"
COM_INSTALLER_CONFIRM_UNINSTALL="Are you sure you want to uninstall? Confirming will permanently delete the selected item(s)!"
COM_INSTALLER_CURRENT_VERSION="Installed"
diff --git a/administrator/templates/atum/scss/blocks/_modals.scss b/administrator/templates/atum/scss/blocks/_modals.scss
index c3328431fc862..9477f1fb382b3 100644
--- a/administrator/templates/atum/scss/blocks/_modals.scss
+++ b/administrator/templates/atum/scss/blocks/_modals.scss
@@ -43,3 +43,59 @@
.contentpane {
padding: 15px;
}
+
+// Changelog
+.changelog {
+ text-align: left !important;
+
+ &__item {
+ display: flex;
+ border-bottom: 1px solid $table-border-color;
+
+ @include media-breakpoint-down(sm) {
+ flex-direction: column;
+ }
+ }
+
+ &__tag {
+ flex: 1 0 180px;
+ max-width: 180px;
+ padding: 10px 15px;
+ background: darken($gray-100, 2.5%);
+ border-right: 1px solid $table-border-color;
+ text-align: right;
+
+ .badge {
+ border-radius: .2rem;
+
+ &.badge-jlanguage {
+ background-color: $white;
+ }
+ }
+
+ @include media-breakpoint-down(sm) {
+ flex: 1 0 auto;
+ max-width: 100%;
+ text-align: left;
+ border-right: 0;
+ border-bottom: 1px solid $table-border-color;
+ }
+ }
+
+ &__list {
+ padding: 10px 15px;
+
+ ul {
+ padding-left: 15px;
+ margin-bottom: 0;
+ }
+
+ li {
+ margin-bottom: .15rem;
+
+ &:last-of-type{
+ margin-bottom: 0;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/build/media_source/system/js/core.es6.js b/build/media_source/system/js/core.es6.js
index d9c41c72d0093..0c344a80745f6 100644
--- a/build/media_source/system/js/core.es6.js
+++ b/build/media_source/system/js/core.es6.js
@@ -914,6 +914,25 @@ window.Joomla.Modal = window.Joomla.Modal || {
return xhr;
};
+ /**
+ * Load the changelog data
+ *
+ * @param extensionId The extension ID to load the changelog for
+ * @param view The view the changelog is for,
+ * this is used to determine which version number to show
+ *
+ * @since 4.0.0
+ */
+ Joomla.loadChangelog = (extensionId, view) => {
+ Joomla.request({
+ url: `index.php?option=com_installer&task=manage.loadChangelog&eid=${extensionId}&source=${view}&format=json`,
+ onSuccess: (response) => {
+ const result = JSON.parse(response);
+ document.querySelectorAll('#changelogModal .modal-body')[0].innerHTML = result.data;
+ },
+ });
+ };
+
/**
* Loads any needed polyfill for web components and async load any web components
*
diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql
index 218a95e99cd6e..85bc46ceba93e 100644
--- a/installation/sql/mysql/joomla.sql
+++ b/installation/sql/mysql/joomla.sql
@@ -491,6 +491,7 @@ CREATE TABLE IF NOT EXISTS `#__extensions` (
`name` varchar(100) NOT NULL,
`type` varchar(20) NOT NULL,
`element` varchar(100) NOT NULL,
+ `changelogurl` text,
`folder` varchar(100) NOT NULL,
`client_id` tinyint(3) NOT NULL,
`enabled` tinyint(3) NOT NULL DEFAULT 0,
@@ -1833,6 +1834,7 @@ CREATE TABLE IF NOT EXISTS `#__updates` (
`data` text NOT NULL,
`detailsurl` text NOT NULL,
`infourl` text NOT NULL,
+ `changelogurl` text,
`extra_query` varchar(1000) DEFAULT '',
PRIMARY KEY (`update_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci COMMENT='Available Updates';
diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql
index dada3344af91e..d0ab155e77ce4 100644
--- a/installation/sql/postgresql/joomla.sql
+++ b/installation/sql/postgresql/joomla.sql
@@ -503,6 +503,7 @@ CREATE TABLE IF NOT EXISTS "#__extensions" (
"name" varchar(100) NOT NULL,
"type" varchar(20) NOT NULL,
"element" varchar(100) NOT NULL,
+ "changelogurl" text,
"folder" varchar(100) NOT NULL,
"client_id" smallint NOT NULL,
"enabled" smallint DEFAULT 0 NOT NULL,
@@ -1830,6 +1831,7 @@ CREATE TABLE IF NOT EXISTS "#__updates" (
"data" text NOT NULL,
"detailsurl" text NOT NULL,
"infourl" text NOT NULL,
+ "changelogurl" text,
"extra_query" varchar(1000) DEFAULT '',
PRIMARY KEY ("update_id")
);
diff --git a/layouts/joomla/installer/changelog.php b/layouts/joomla/installer/changelog.php
new file mode 100644
index 0000000000000..67de92f2f152a
--- /dev/null
+++ b/layouts/joomla/installer/changelog.php
@@ -0,0 +1,64 @@
+
+
+ ` element
+ *
+ * @var string
+ * @since __DEPLOY_VERSION__
+ */
+ protected $element;
+
+ /**
+ * Update manifest `` element
+ *
+ * @var string
+ * @since __DEPLOY_VERSION__
+ */
+ protected $type;
+
+ /**
+ * Update manifest `` element
+ *
+ * @var string
+ * @since __DEPLOY_VERSION__
+ */
+ protected $version;
+
+ /**
+ * Update manifest `` element
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $security = array();
+
+ /**
+ * Update manifest `` element
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $fix = array();
+
+ /**
+ * Update manifest `` element
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $language = array();
+
+ /**
+ * Update manifest `` element
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $addition = array();
+
+ /**
+ * Update manifest `` elements
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $change = array();
+
+ /**
+ * Update manifest `` element
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $remove = array();
+
+ /**
+ * Update manifest `` element
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $note = array();
+
+ /**
+ * List of node items
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ private $items = array();
+
+ /**
+ * Resource handle for the XML Parser
+ *
+ * @var resource
+ * @since __DEPLOY_VERSION__
+ */
+ protected $xmlParser;
+
+ /**
+ * Element call stack
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
+ */
+ protected $stack = array('base');
+
+ /**
+ * Object containing the current update data
+ *
+ * @var \stdClass
+ * @since __DEPLOY_VERSION__
+ */
+ protected $currentChangelog;
+
+ /**
+ * The version to match the changelog
+ *
+ * @var string
+ * @since __DEPLOY_VERSION__
+ */
+ private $matchVersion = '';
+
+ /**
+ * Object containing the latest changelog data
+ *
+ * @var \stdClass
+ * @since __DEPLOY_VERSION__
+ */
+ protected $latest;
+
+ /**
+ * Gets the reference to the current direct parent
+ *
+ * @return object
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function getStackLocation()
+ {
+ return implode('->', $this->stack);
+ }
+
+ /**
+ * Get the last position in stack count
+ *
+ * @return string
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function getLastTag()
+ {
+ return $this->stack[count($this->stack) - 1];
+ }
+
+ /**
+ * Set the version to match.
+ *
+ * @param string $version The version to match
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION_
+ */
+ public function setVersion(string $version)
+ {
+ $this->matchVersion = $version;
+ }
+
+ /**
+ * XML Start Element callback
+ *
+ * @param object $parser Parser object
+ * @param string $name Name of the tag found
+ * @param array $attrs Attributes of the tag
+ *
+ * @return void
+ *
+ * @note This is public because it is called externally
+ * @since 1.7.0
+ */
+ public function startElement($parser, $name, $attrs = array())
+ {
+ $this->stack[] = $name;
+ $tag = $this->getStackLocation();
+
+ // Reset the data
+ if (isset($this->$tag))
+ {
+ $this->$tag->data = '';
+ }
+
+ switch ($name)
+ {
+ default:
+ $name = strtolower($name);
+
+ if (!isset($this->currentChangelog->$name))
+ {
+ $this->currentChangelog->$name = new \stdClass;
+ }
+
+ $this->currentChangelog->$name->data = '';
+
+ foreach ($attrs as $key => $data)
+ {
+ $key = strtolower($key);
+ $this->currentChangelog->$name->$key = $data;
+ }
+ break;
+ }
+ }
+
+ /**
+ * Callback for closing the element
+ *
+ * @param object $parser Parser object
+ * @param string $name Name of element that was closed
+ *
+ * @return void
+ *
+ * @note This is public because it is called externally
+ * @since 1.7.0
+ */
+ public function endElement($parser, $name)
+ {
+ array_pop($this->stack);
+
+ switch ($name)
+ {
+ case 'SECURITY':
+ case 'FIX':
+ case 'LANGUAGE':
+ case 'ADDITION':
+ case 'CHANGE':
+ case 'REMOVE':
+ case 'NOTE':
+ $name = strtolower($name);
+ $this->currentChangelog->$name->data = $this->items;
+ $this->items = array();
+ break;
+ case 'CHANGELOG':
+ if (version_compare($this->currentChangelog->version->data, $this->matchVersion, '==') === true)
+ {
+ $this->latest = $this->currentChangelog;
+ }
+
+ // No version match, empty it
+ $this->currentChangelog = new \stdClass;
+ break;
+ case 'CHANGELOGS':
+ // If the latest item is set then we transfer it to where we want to
+ if (isset($this->latest))
+ {
+ foreach (get_object_vars($this->latest) as $key => $val)
+ {
+ $this->$key = $val;
+ }
+
+ unset($this->latest);
+ unset($this->currentChangelog);
+ }
+ elseif (isset($this->currentChangelog))
+ {
+ // The update might be for an older version of j!
+ unset($this->currentChangelog);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Character Parser Function
+ *
+ * @param object $parser Parser object.
+ * @param object $data The data.
+ *
+ * @return void
+ *
+ * @note This is public because its called externally.
+ * @since 1.7.0
+ */
+ public function characterData($parser, $data)
+ {
+ $tag = $this->getLastTag();
+
+ switch ($tag)
+ {
+ case 'ITEM':
+ $this->items[] = $data;
+ break;
+ case 'SECURITY':
+ case 'FIX':
+ case 'LANGUAGE':
+ case 'ADDITION':
+ case 'CHANGE':
+ case 'REMOVE':
+ case 'NOTE':
+ break;
+ default:
+ // Throw the data for this item together
+ $tag = strtolower($tag);
+
+ if (isset($this->currentChangelog->$tag))
+ {
+ $this->currentChangelog->$tag->data .= $data;
+ }
+ break;
+ }
+ }
+
+ /**
+ * Loads an XML file from a URL.
+ *
+ * @param string $url The URL.
+ *
+ * @return boolean True on success
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function loadFromXml($url)
+ {
+ $version = new Version;
+ $httpOption = new Registry;
+ $httpOption->set('userAgent', $version->getUserAgent('Joomla', true, false));
+
+ try
+ {
+ $http = HttpFactory::getHttp($httpOption);
+ $response = $http->get($url);
+ }
+ catch (RuntimeException $e)
+ {
+ $response = null;
+ }
+
+ if ($response === null || $response->code !== 200)
+ {
+ // TODO: Add a 'mark bad' setting here somehow
+ Log::add(Text::sprintf('JLIB_UPDATER_ERROR_EXTENSION_OPEN_URL', $url), Log::WARNING, 'jerror');
+
+ return false;
+ }
+
+ $this->currentChangelog = new \stdClass;
+
+ $this->xmlParser = xml_parser_create('');
+ xml_set_object($this->xmlParser, $this);
+ xml_set_element_handler($this->xmlParser, 'startElement', 'endElement');
+ xml_set_character_data_handler($this->xmlParser, 'characterData');
+
+ if (!xml_parse($this->xmlParser, $response->body))
+ {
+ Log::add(
+ sprintf(
+ 'XML error: %s at line %d', xml_error_string(xml_get_error_code($this->xmlParser)),
+ xml_get_current_line_number($this->xmlParser)
+ ),
+ Log::WARNING, 'updater'
+ );
+
+ return false;
+ }
+
+ xml_parser_free($this->xmlParser);
+
+ return true;
+ }
+}
diff --git a/libraries/src/Installer/Adapter/ComponentAdapter.php b/libraries/src/Installer/Adapter/ComponentAdapter.php
index c5dbdd4c52600..bcdb25ffe4d9b 100644
--- a/libraries/src/Installer/Adapter/ComponentAdapter.php
+++ b/libraries/src/Installer/Adapter/ComponentAdapter.php
@@ -903,9 +903,10 @@ protected function storeExtension($deleteExisting = false)
}
// Add or update an entry to the extension table
- $this->extension->name = $this->name;
- $this->extension->type = 'component';
- $this->extension->element = $this->element;
+ $this->extension->name = $this->name;
+ $this->extension->type = 'component';
+ $this->extension->element = $this->element;
+ $this->extension->changelogurl = $this->changelogurl;
// If we are told to delete existing extension entries then do so.
if ($deleteExisting)
@@ -1037,10 +1038,10 @@ protected function _buildAdminMenus($component_id = null)
{
// Lets find the extension id
$query->clear()
- ->select('e.extension_id')
- ->from('#__extensions AS e')
- ->where('e.type = ' . $db->quote('component'))
- ->where('e.element = ' . $db->quote($option));
+ ->select($db->quoteName('e.extension_id'))
+ ->from($db->quoteName('#__extensions', 'e'))
+ ->where($db->quoteName('e.type') . ' = ' . $db->quote('component'))
+ ->where($db->quoteName('e.element') . ' = ' . $db->quote($option));
$db->setQuery($query);
$component_id = $db->loadResult();
@@ -1067,37 +1068,37 @@ protected function _buildAdminMenus($component_id = null)
if ($menuElement)
{
// I have a menu element, use this information
- $data['menutype'] = 'main';
- $data['client_id'] = 1;
- $data['title'] = (string) trim($menuElement);
- $data['alias'] = (string) $menuElement;
- $data['link'] = 'index.php?option=' . $option;
- $data['type'] = 'component';
- $data['published'] = 1;
- $data['parent_id'] = 1;
+ $data['menutype'] = 'main';
+ $data['client_id'] = 1;
+ $data['title'] = (string) trim($menuElement);
+ $data['alias'] = (string) $menuElement;
+ $data['link'] = 'index.php?option=' . $option;
+ $data['type'] = 'component';
+ $data['published'] = 1;
+ $data['parent_id'] = 1;
$data['component_id'] = $component_id;
- $data['img'] = ((string) $menuElement->attributes()->img) ?: 'class:component';
- $data['home'] = 0;
- $data['path'] = '';
- $data['params'] = '';
+ $data['img'] = ((string) $menuElement->attributes()->img) ?: 'class:component';
+ $data['home'] = 0;
+ $data['path'] = '';
+ $data['params'] = '';
}
else
{
// No menu element was specified, Let's make a generic menu item
- $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'] = 1;
- $data['parent_id'] = 1;
+ $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'] = 1;
+ $data['parent_id'] = 1;
$data['component_id'] = $component_id;
- $data['img'] = 'class:component';
- $data['home'] = 0;
- $data['path'] = '';
- $data['params'] = '';
+ $data['img'] = 'class:component';
+ $data['home'] = 0;
+ $data['path'] = '';
+ $data['params'] = '';
}
// Try to create the menu item in the database
@@ -1120,17 +1121,17 @@ protected function _buildAdminMenus($component_id = null)
foreach ($this->getManifest()->administration->submenu->menu as $child)
{
- $data = array();
- $data['menutype'] = 'main';
- $data['client_id'] = 1;
- $data['title'] = (string) trim($child);
- $data['alias'] = (string) $child;
- $data['type'] = 'component';
- $data['published'] = 1;
- $data['parent_id'] = $parent_id;
+ $data = array();
+ $data['menutype'] = 'main';
+ $data['client_id'] = 1;
+ $data['title'] = (string) trim($child);
+ $data['alias'] = (string) $child;
+ $data['type'] = 'component';
+ $data['published'] = 1;
+ $data['parent_id'] = $parent_id;
$data['component_id'] = $component_id;
- $data['img'] = ((string) $child->attributes()->img) ?: 'class:component';
- $data['home'] = 0;
+ $data['img'] = ((string) $child->attributes()->img) ?: 'class:component';
+ $data['home'] = 0;
// Set the sub menu link
if ((string) $child->attributes()->link)
@@ -1171,7 +1172,7 @@ protected function _buildAdminMenus($component_id = null)
$request[] = 'sub=' . $child->attributes()->sub;
}
- $qstring = count($request) ? '&' . implode('&', $request) : '';
+ $qstring = count($request) ? '&' . implode('&', $request) : '';
$data['link'] = 'index.php?option=' . $option . $qstring;
}
@@ -1199,6 +1200,8 @@ protected function _buildAdminMenus($component_id = null)
*
* @return boolean True if successful.
*
+ * @throws \Exception
+ *
* @since 3.1
*/
protected function _removeAdminMenus($id)
@@ -1210,8 +1213,8 @@ protected function _removeAdminMenus($id)
// Get the ids of the menu items
$query = $db->getQuery(true)
- ->select('id')
- ->from('#__menu')
+ ->select($db->quoteName('id'))
+ ->from($db->quoteName('#__menu'))
->where($db->quoteName('client_id') . ' = 1')
->where($db->quoteName('menutype') . ' = ' . $db->quote('main'))
->where($db->quoteName('component_id') . ' = :id')
@@ -1219,8 +1222,7 @@ protected function _removeAdminMenus($id)
$db->setQuery($query);
- $ids = $db->loadColumn();
-
+ $ids = $db->loadColumn();
$result = true;
// Check for error
@@ -1277,12 +1279,12 @@ protected function _updateMenus($component_id, $clientId = null)
// Update all menu items which contain 'index.php?option=com_extension' or 'index.php?option=com_extension&...'
// to use the new component id.
$query = $db->getQuery(true)
- ->update('#__menu')
- ->set('component_id = ' . $db->quote($component_id))
- ->where('type = ' . $db->quote('component'))
+ ->update($db->quoteName('#__menu'))
+ ->set($db->quoteName('component_id') . ' = ' . $db->quote($component_id))
+ ->where($db->quoteName('type') . ' = ' . $db->quote('component'))
->where('('
- . 'link LIKE ' . $db->quote('index.php?option=' . $option) . ' OR '
- . 'link LIKE ' . $db->quote($db->escape('index.php?option=' . $option . '&') . '%', false)
+ . $db->quoteName('link') . ' LIKE ' . $db->quote('index.php?option=' . $option) . ' OR '
+ . $db->quoteName('link') . ' LIKE ' . $db->quote($db->escape('index.php?option=' . $option . '&') . '%', false)
. ')');
if (isset($clientId))
@@ -1312,6 +1314,8 @@ protected function _updateMenus($component_id, $clientId = null)
*
* @return boolean True on success
*
+ * @throws \Exception
+ *
* @since 3.1
*/
protected function _rollback_menu($step)
@@ -1328,8 +1332,8 @@ protected function _rollback_menu($step)
*/
public function discover()
{
- $results = array();
- $site_components = Folder::folders(JPATH_SITE . '/components');
+ $results = array();
+ $site_components = Folder::folders(JPATH_SITE . '/components');
$admin_components = Folder::folders(JPATH_ADMINISTRATOR . '/components');
$api_components = Folder::folders(JPATH_API . '/components');
@@ -1407,15 +1411,16 @@ public function discover()
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally
- $client = ApplicationHelper::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';
+ $client = ApplicationHelper::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 = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
+ $manifest_details = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
- $this->parent->extension->name = $manifest_details['name'];
+ $this->parent->extension->name = $manifest_details['name'];
+ $this->parent->extension->namespace = $manifest_details['namespace'];
try
{
@@ -1436,6 +1441,10 @@ public function refreshManifestCache()
* @param integer $parentId The parent menu item ID
*
* @return boolean|integer Menu item ID on success, false on failure
+ *
+ * @throws \Exception
+ *
+ * @since 3.1
*/
protected function _createAdminMenuItem(array &$data, $parentId)
{
diff --git a/libraries/src/Installer/Adapter/FileAdapter.php b/libraries/src/Installer/Adapter/FileAdapter.php
index e44e2f6c3b302..d079ef300667e 100644
--- a/libraries/src/Installer/Adapter/FileAdapter.php
+++ b/libraries/src/Installer/Adapter/FileAdapter.php
@@ -410,9 +410,10 @@ protected function storeExtension()
else
{
// Add an entry to the extension table with a whole heap of defaults
- $this->extension->name = $this->name;
- $this->extension->type = 'file';
- $this->extension->element = $this->element;
+ $this->extension->name = $this->name;
+ $this->extension->type = 'file';
+ $this->extension->element = $this->element;
+ $this->extension->changelogurl = $this->changelogurl;
// There is no folder for files so leave it blank
$this->extension->folder = '';
diff --git a/libraries/src/Installer/Adapter/LanguageAdapter.php b/libraries/src/Installer/Adapter/LanguageAdapter.php
index 54de5d32dc7f9..11a19dd2db60c 100644
--- a/libraries/src/Installer/Adapter/LanguageAdapter.php
+++ b/libraries/src/Installer/Adapter/LanguageAdapter.php
@@ -486,6 +486,7 @@ protected function _install($cname, $basePath, $clientId, &$element)
$row->set('name', $this->name);
$row->set('type', 'language');
$row->set('element', $this->tag);
+ $row->set('changelogurl', (string) $this->getManifest()->changelogurl);
// There is no folder for languages
$row->set('folder', '');
@@ -765,6 +766,7 @@ public function update()
$row->set('type', 'language');
$row->set('element', $this->tag);
$row->set('manifest_cache', $this->parent->generateManifestCache());
+ $row->set('changelogurl', (string) $this->getManifest()->changelogurl);
// Clean installed languages cache.
Factory::getCache()->clean('com_languages');
@@ -790,8 +792,8 @@ public function update()
*/
public function discover()
{
- $results = array();
- $site_languages = Folder::folders(JPATH_SITE . '/language');
+ $results = array();
+ $site_languages = Folder::folders(JPATH_SITE . '/language');
$admin_languages = Folder::folders(JPATH_ADMINISTRATOR . '/language');
foreach ($site_languages as $language)
@@ -844,18 +846,18 @@ public function discover()
public function discover_install()
{
// Need to find to find where the XML file is since we don't store this normally
- $client = ApplicationHelper::getClientInfo($this->parent->extension->client_id);
- $short_element = $this->parent->extension->element;
- $manifestPath = $client->path . '/language/' . $short_element . '/' . $short_element . '.xml';
+ $client = ApplicationHelper::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 = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
+ $manifest_details = Installer::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->state = 0;
+ $this->parent->extension->name = $manifest_details['name'];
+ $this->parent->extension->enabled = 1;
// @todo remove code: $this->parent->extension->params = $this->parent->getParams();
try
@@ -885,23 +887,21 @@ public function discover_install()
*/
public function refreshManifestCache()
{
- $client = ApplicationHelper::getClientInfo($this->parent->extension->client_id);
- $manifestPath = $client->path . '/language/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml';
+ $client = ApplicationHelper::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 = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
+ $manifest_details = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
- $this->parent->extension->name = $manifest_details['name'];
+ $this->parent->extension->name = $manifest_details['name'];
if ($this->parent->extension->store())
{
return true;
}
- else
- {
- Log::add(Text::_('JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE'), Log::WARNING, 'jerror');
- return false;
- }
+ Log::add(Text::_('JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE'), Log::WARNING, 'jerror');
+
+ return false;
}
}
diff --git a/libraries/src/Installer/Adapter/LibraryAdapter.php b/libraries/src/Installer/Adapter/LibraryAdapter.php
index d3a8a062bfa9d..c07240644e705 100644
--- a/libraries/src/Installer/Adapter/LibraryAdapter.php
+++ b/libraries/src/Installer/Adapter/LibraryAdapter.php
@@ -94,10 +94,10 @@ protected function finaliseInstall()
// Clobber any possible pending updates
/** @var Update $update */
$update = Table::getInstance('update');
- $uid = $update->find(
+ $uid = $update->find(
array(
'element' => $this->element,
- 'type' => $this->type,
+ 'type' => $this->type,
)
);
@@ -109,8 +109,8 @@ protected function finaliseInstall()
// Lastly, we will copy the manifest file to its appropriate place.
if ($this->route !== 'discover_install')
{
- $manifest = array();
- $manifest['src'] = $this->parent->getPath('manifest');
+ $manifest = array();
+ $manifest['src'] = $this->parent->getPath('manifest');
$manifest['dest'] = JPATH_MANIFESTS . '/libraries/' . $this->element . '.xml';
$destFolder = dirname($manifest['dest']);
@@ -130,7 +130,7 @@ protected function finaliseInstall()
// If there is a manifest script, let's copy it.
if ($this->manifest_script)
{
- $path['src'] = $this->parent->getPath('source') . '/' . $this->manifest_script;
+ $path['src'] = $this->parent->getPath('source') . '/' . $this->manifest_script;
$path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->manifest_script;
if ($this->parent->isOverwrite() || !file_exists($path['dest']))
@@ -228,9 +228,9 @@ public function loadLanguage($path = null)
$this->parent->setPath('source', JPATH_PLATFORM . '/' . $this->getElement());
}
- $extension = 'lib_' . str_replace('/', '_', $this->getElement());
+ $extension = 'lib_' . str_replace('/', '_', $this->getElement());
$librarypath = (string) $this->getManifest()->libraryname;
- $source = $path ?: JPATH_PLATFORM . '/' . $librarypath;
+ $source = $path ?: JPATH_PLATFORM . '/' . $librarypath;
$this->doLoadLanguage($extension, $source, JPATH_SITE);
}
@@ -257,7 +257,7 @@ protected function parseOptionalTags()
*/
public function prepareDiscoverInstall()
{
- $manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->extension->element . '.xml';
+ $manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$this->setManifest($this->parent->getManifest());
@@ -388,10 +388,10 @@ protected function storeExtension()
$manifest_details = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->extension->manifest_cache = json_encode($manifest_details);
- $this->extension->state = 0;
- $this->extension->name = $manifest_details['name'];
- $this->extension->enabled = 1;
- $this->extension->params = $this->parent->getParams();
+ $this->extension->state = 0;
+ $this->extension->name = $manifest_details['name'];
+ $this->extension->enabled = 1;
+ $this->extension->params = $this->parent->getParams();
if (!$this->extension->store())
{
@@ -402,9 +402,10 @@ protected function storeExtension()
return;
}
- $this->extension->name = $this->name;
- $this->extension->type = 'library';
- $this->extension->element = $this->element;
+ $this->extension->name = $this->name;
+ $this->extension->type = 'library';
+ $this->extension->element = $this->element;
+ $this->extension->changelogurl = $this->changelogurl;
// There is no folder for libraries
$this->extension->folder = '';
@@ -460,8 +461,8 @@ public function update()
*/
// Set the extensions name
- $name = (string) $this->getManifest()->name;
- $name = InputFilter::getInstance()->clean($name, 'string');
+ $name = (string) $this->getManifest()->name;
+ $name = InputFilter::getInstance()->clean($name, 'string');
$element = str_replace('.xml', '', basename($this->parent->getPath('manifest')));
$this->name = $name;
@@ -469,8 +470,8 @@ public function update()
// We don't want to compromise this instance!
$installer = new Installer;
- $db = $this->parent->getDbo();
- $query = $db->getQuery(true)
+ $db = $this->parent->getDbo();
+ $query = $db->getQuery(true)
->select($db->quoteName('extension_id'))
->from($db->quoteName('#__extensions'))
->where($db->quoteName('type') . ' = ' . $db->quote('library'))
@@ -487,7 +488,7 @@ public function update()
// Clear the cached data
$this->currentExtensionId = null;
- $this->extension = Table::getInstance('Extension', 'JTable', array('dbo' => $this->db));
+ $this->extension = Table::getInstance('Extension', 'JTable', array('dbo' => $this->db));
}
// Now create the new files
@@ -515,7 +516,7 @@ public function discover()
foreach ($iterator as $file => $pattern)
{
- $element = str_replace(array($mainFolder . DIRECTORY_SEPARATOR, '.xml'), '', $file);
+ $element = str_replace(array($mainFolder . DIRECTORY_SEPARATOR, '.xml'), '', $file);
$manifestCache = Installer::parseXMLInstallFile($file);
$extension = Table::getInstance('extension');
@@ -543,13 +544,13 @@ public function discover()
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';
+ $manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->parent->extension->element . '.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
- $manifest_details = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
+ $manifest_details = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
- $this->parent->extension->name = $manifest_details['name'];
+ $this->parent->extension->name = $manifest_details['name'];
try
{
diff --git a/libraries/src/Installer/Adapter/ModuleAdapter.php b/libraries/src/Installer/Adapter/ModuleAdapter.php
index eb38d4a123224..925522b534abc 100644
--- a/libraries/src/Installer/Adapter/ModuleAdapter.php
+++ b/libraries/src/Installer/Adapter/ModuleAdapter.php
@@ -619,10 +619,11 @@ protected function storeExtension()
}
else
{
- $this->extension->name = $this->name;
- $this->extension->type = 'module';
- $this->extension->element = $this->element;
- $this->extension->namespace = (string) $this->manifest->namespace;
+ $this->extension->name = $this->name;
+ $this->extension->type = 'module';
+ $this->extension->element = $this->element;
+ $this->extension->namespace = (string) $this->manifest->namespace;
+ $this->extension->changelogurl = $this->changelogurl;
// There is no folder for modules
$this->extension->folder = '';
diff --git a/libraries/src/Installer/Adapter/PackageAdapter.php b/libraries/src/Installer/Adapter/PackageAdapter.php
index 54efab19324fb..f10fadf7f5b7a 100644
--- a/libraries/src/Installer/Adapter/PackageAdapter.php
+++ b/libraries/src/Installer/Adapter/PackageAdapter.php
@@ -556,9 +556,10 @@ protected function storeExtension()
}
else
{
- $this->extension->name = $this->name;
- $this->extension->type = 'package';
- $this->extension->element = $this->element;
+ $this->extension->name = $this->name;
+ $this->extension->type = 'package';
+ $this->extension->element = $this->element;
+ $this->extension->changelogurl = $this->changelogurl;
// There is no folder for packages
$this->extension->folder = '';
diff --git a/libraries/src/Installer/Adapter/PluginAdapter.php b/libraries/src/Installer/Adapter/PluginAdapter.php
index a21d0b11400f9..91f11f21a0768 100644
--- a/libraries/src/Installer/Adapter/PluginAdapter.php
+++ b/libraries/src/Installer/Adapter/PluginAdapter.php
@@ -443,10 +443,10 @@ protected function storeExtension()
$manifest_details = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->extension->manifest_cache = json_encode($manifest_details);
- $this->extension->state = 0;
- $this->extension->name = $manifest_details['name'];
- $this->extension->enabled = 'editors' === $this->extension->folder ? 1 : 0;
- $this->extension->params = $this->parent->getParams();
+ $this->extension->state = 0;
+ $this->extension->name = $manifest_details['name'];
+ $this->extension->enabled = 'editors' === $this->extension->folder ? 1 : 0;
+ $this->extension->params = $this->parent->getParams();
if (!$this->extension->store())
{
@@ -482,16 +482,17 @@ protected function storeExtension()
else
{
// Store in the extensions table (1.6)
- $this->extension->name = $this->name;
- $this->extension->type = 'plugin';
- $this->extension->ordering = 0;
- $this->extension->element = $this->element;
- $this->extension->folder = $this->group;
- $this->extension->enabled = 0;
- $this->extension->protected = 0;
- $this->extension->access = 1;
- $this->extension->client_id = 0;
- $this->extension->params = $this->parent->getParams();
+ $this->extension->name = $this->name;
+ $this->extension->type = 'plugin';
+ $this->extension->ordering = 0;
+ $this->extension->element = $this->element;
+ $this->extension->folder = $this->group;
+ $this->extension->enabled = 0;
+ $this->extension->protected = 0;
+ $this->extension->access = 1;
+ $this->extension->client_id = 0;
+ $this->extension->params = $this->parent->getParams();
+ $this->extension->changelogurl = $this->changelogurl;
// Update the manifest cache for the entry
$this->extension->manifest_cache = $this->parent->generateManifestCache();
diff --git a/libraries/src/Installer/Adapter/TemplateAdapter.php b/libraries/src/Installer/Adapter/TemplateAdapter.php
index f08d09377f9f4..ae7cf74c2a00c 100644
--- a/libraries/src/Installer/Adapter/TemplateAdapter.php
+++ b/libraries/src/Installer/Adapter/TemplateAdapter.php
@@ -343,8 +343,8 @@ protected function parseQueries()
*/
public function prepareDiscoverInstall()
{
- $client = ApplicationHelper::getClientInfo($this->extension->client_id);
- $manifestPath = $client->path . '/templates/' . $this->extension->element . '/templateDetails.xml';
+ $client = ApplicationHelper::getClientInfo($this->extension->client_id);
+ $manifestPath = $client->path . '/templates/' . $this->extension->element . '/templateDetails.xml';
$this->parent->manifest = $this->parent->isManifest($manifestPath);
$this->parent->setPath('manifest', $manifestPath);
$this->setManifest($this->parent->getManifest());
@@ -398,13 +398,13 @@ protected function setupInstallPaths()
throw new \RuntimeException(Text::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_UNKNOWN_CLIENT', $cname));
}
- $basePath = $client->path;
+ $basePath = $client->path;
$this->clientId = $client->id;
}
else
{
// No client attribute was found so we assume the site as the client
- $basePath = JPATH_SITE;
+ $basePath = JPATH_SITE;
$this->clientId = 0;
}
@@ -537,12 +537,13 @@ protected function storeExtension()
$this->extension->element = $this->element;
// There is no folder for templates
- $this->extension->folder = '';
- $this->extension->enabled = 1;
- $this->extension->protected = 0;
- $this->extension->access = 1;
- $this->extension->client_id = $this->clientId;
- $this->extension->params = $this->parent->getParams();
+ $this->extension->folder = '';
+ $this->extension->enabled = 1;
+ $this->extension->protected = 0;
+ $this->extension->access = 1;
+ $this->extension->client_id = $this->clientId;
+ $this->extension->params = $this->parent->getParams();
+ $this->extension->changelogurl = $this->changelogurl;
}
// Name might change in an update
@@ -551,6 +552,8 @@ protected function storeExtension()
// Update the manifest cache for the entry
$this->extension->manifest_cache = $this->parent->generateManifestCache();
+ $this->extension->changelogurl = $this->changelogurl;
+
if (!$this->extension->store())
{
// Install failed, roll back changes
@@ -571,10 +574,10 @@ protected function storeExtension()
*/
public function discover()
{
- $results = array();
- $site_list = Folder::folders(JPATH_SITE . '/templates');
+ $results = array();
+ $site_list = Folder::folders(JPATH_SITE . '/templates');
$admin_list = Folder::folders(JPATH_ADMINISTRATOR . '/templates');
- $site_info = ApplicationHelper::getClientInfo('site', true);
+ $site_info = ApplicationHelper::getClientInfo('site', true);
$admin_info = ApplicationHelper::getClientInfo('administrator', true);
foreach ($site_list as $template)
@@ -588,7 +591,7 @@ public function discover()
}
$manifest_details = Installer::parseXMLInstallFile(JPATH_SITE . "/templates/$template/templateDetails.xml");
- $extension = Table::getInstance('extension');
+ $extension = Table::getInstance('extension');
$extension->set('type', 'template');
$extension->set('client_id', $site_info->id);
$extension->set('element', $template);
@@ -612,7 +615,7 @@ public function discover()
}
$manifest_details = Installer::parseXMLInstallFile(JPATH_ADMINISTRATOR . "/templates/$template/templateDetails.xml");
- $extension = Table::getInstance('extension');
+ $extension = Table::getInstance('extension');
$extension->set('type', 'template');
$extension->set('client_id', $admin_info->id);
$extension->set('element', $template);
@@ -638,14 +641,14 @@ public function discover()
public function refreshManifestCache()
{
// Need to find to find where the XML file is since we don't store this normally.
- $client = ApplicationHelper::getClientInfo($this->parent->extension->client_id);
- $manifestPath = $client->path . '/templates/' . $this->parent->extension->element . '/templateDetails.xml';
+ $client = ApplicationHelper::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 = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
+ $manifest_details = Installer::parseXMLInstallFile($this->parent->getPath('manifest'));
$this->parent->extension->manifest_cache = json_encode($manifest_details);
- $this->parent->extension->name = $manifest_details['name'];
+ $this->parent->extension->name = $manifest_details['name'];
try
{
diff --git a/libraries/src/Installer/InstallerAdapter.php b/libraries/src/Installer/InstallerAdapter.php
index f71bb19a57dbb..ecd6725677254 100644
--- a/libraries/src/Installer/InstallerAdapter.php
+++ b/libraries/src/Installer/InstallerAdapter.php
@@ -28,6 +28,14 @@
*/
abstract class InstallerAdapter
{
+ /**
+ * Changelog URL of extensions
+ *
+ * @var string
+ * @since __DEPLOY_VERSION__
+ * */
+ protected $changelogurl = null;
+
/**
* ID for the currently installed extension if present
*
@@ -666,20 +674,18 @@ protected function getScriptClassName()
public function install()
{
// Get the extension's description
- $description = (string) $this->getManifest()->description;
+ $description = (string) $this->getManifest()->description;
+ $this->parent->message = '';
if ($description)
{
$this->parent->message = Text::_($description);
}
- else
- {
- $this->parent->message = '';
- }
// Set the extension's name and element
- $this->name = $this->getName();
- $this->element = $this->getElement();
+ $this->name = $this->getName();
+ $this->element = $this->getElement();
+ $this->changelogurl = (string) $this->getManifest()->changelogurl;
/*
* ---------------------------------------------------------------------------------------------
diff --git a/libraries/src/Updater/UpdateAdapter.php b/libraries/src/Updater/UpdateAdapter.php
index eabb0c1ec6f23..bd88338d7714c 100644
--- a/libraries/src/Updater/UpdateAdapter.php
+++ b/libraries/src/Updater/UpdateAdapter.php
@@ -56,7 +56,7 @@ abstract class UpdateAdapter extends \JAdapterInstance
* @var array
* @since 3.0.0
*/
- protected $updatecols = array('NAME', 'ELEMENT', 'TYPE', 'FOLDER', 'CLIENT', 'VERSION', 'DESCRIPTION', 'INFOURL', 'EXTRA_QUERY');
+ protected $updatecols = array('NAME', 'ELEMENT', 'TYPE', 'FOLDER', 'CLIENT', 'VERSION', 'DESCRIPTION', 'INFOURL', 'CHANGELOGURL', 'EXTRA_QUERY');
/**
* Should we try appending a .xml extension to the update site's URL?
|