diff --git a/administrator/config.xml b/administrator/config.xml
index a1a729c..ad4b697 100644
--- a/administrator/config.xml
+++ b/administrator/config.xml
@@ -15,39 +15,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/script.php b/script.php
new file mode 100644
index 0000000..2491598
--- /dev/null
+++ b/script.php
@@ -0,0 +1,1005 @@
+
+ * @copyright 2020 webmaster@ramblers-webs.org.uk
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+define('MODIFIED', 1);
+define('NOT_MODIFIED', 2);
+
+defined('_JEXEC') or die;
+
+use \Joomla\CMS\Factory;
+use \Joomla\CMS\Language\Text;
+
+/**
+ * Updates the database structure of the component
+ *
+ * @version Release: 0.2b
+ * @author Component Creator
+ * @since 0.1b
+ */
+class com_rw_accountsInstallerScript
+{
+ /**
+ * Method called before install/update the component. Note: This method won't be called during uninstall process.
+ *
+ * @param string $type Type of process [install | update]
+ * @param mixed $parent Object who called this method
+ *
+ * @return boolean True if the process should continue, false otherwise
+ * @throws Exception
+ */
+ public function preflight($type, $parent)
+ {
+ $jversion = new JVersion;
+
+ // Installing component manifest file version
+ $manifest = $parent->get("manifest");
+ $release = (string) $manifest['version'];
+
+ // Abort if the component wasn't build for the current Joomla version
+ if (!$jversion->isCompatible($release))
+ {
+ Factory::getApplication()->enqueueMessage(
+ Text::_('This component is not compatible with installed Joomla version'),
+ 'error'
+ );
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Method to install the component
+ *
+ * @param mixed $parent Object who called this method.
+ *
+ * @return void
+ *
+ * @since 0.2b
+ */
+ public function install($parent)
+ {
+ $this->installDb($parent);
+ $this->installPlugins($parent);
+ $this->installModules($parent);
+ }
+
+ /**
+ * Method to update the DB of the component
+ *
+ * @param mixed $parent Object who started the upgrading process
+ *
+ * @return void
+ *
+ * @since 0.2b
+ * @throws Exception
+ */
+ private function installDb($parent)
+ {
+ $installation_folder = $parent->getParent()->getPath('source');
+
+ $app = Factory::getApplication();
+
+ if (function_exists('simplexml_load_file') && file_exists($installation_folder . '/installer/structure.xml'))
+ {
+ $component_data = simplexml_load_file($installation_folder . '/installer/structure.xml');
+
+ // Check if there are tables to import.
+ foreach ($component_data->children() as $table)
+ {
+ $this->processTable($app, $table);
+ }
+ }
+ else
+ {
+ if (!function_exists('simplexml_load_file'))
+ {
+ $app->enqueueMessage(Text::_('This script needs \'simplexml_load_file\' to update the component'));
+ }
+ else
+ {
+ $app->enqueueMessage(Text::_('Structure file was not found.'));
+ }
+ }
+ }
+
+ /**
+ * Process a table
+ *
+ * @param JApplicationCms $app Application object
+ * @param SimpleXMLElement $table Table to process
+ *
+ * @return void
+ *
+ * @since 0.2b
+ */
+ private function processTable($app, $table)
+ {
+ $db = Factory::getDbo();
+
+ $table_added = false;
+
+ if (isset($table['action']))
+ {
+ switch ($table['action'])
+ {
+ case 'add':
+
+ // Check if the table exists before create the statement
+ if (!$this->existsTable($table['table_name']))
+ {
+ $create_statement = $this->generateCreateTableStatement($table);
+ $db->setQuery($create_statement);
+
+ try
+ {
+ $db->execute();
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'Table `%s` has been successfully created',
+ (string) $table['table_name']
+ )
+ );
+ $table_added = true;
+ } catch (Exception $ex)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error creating the table `%s`. Error: %s',
+ (string) $table['table_name'],
+ $ex->getMessage()
+ ), 'error'
+ );
+ }
+ }
+ break;
+ case 'change':
+
+ // Check if the table exists first to avoid errors.
+ if ($this->existsTable($table['old_name']) && !$this->existsTable($table['new_name']))
+ {
+ try
+ {
+ $db->renameTable($table['old_name'], $table['new_name']);
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'Table `%s` was successfully renamed to `%s`',
+ $table['old_name'],
+ $table['new_name']
+ )
+ );
+ } catch (Exception $ex)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error renaming the table `%s`. Error: %s',
+ $table['old_name'],
+ $ex->getMessage()
+ ), 'error'
+ );
+ }
+ }
+ else
+ {
+ if (!$this->existsTable($table['table_name']))
+ {
+ // If the table does not exists, let's create it.
+ $create_statement = $this->generateCreateTableStatement($table);
+ $db->setQuery($create_statement);
+
+ try
+ {
+ $db->execute();
+ $app->enqueueMessage(
+ Text::sprintf('Table `%s` has been successfully created', $table['table_name'])
+ );
+ $table_added = true;
+ } catch (Exception $ex)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error creating the table `%s`. Error: %s',
+ $table['table_name'],
+ $ex->getMessage()
+ ), 'error'
+ );
+ }
+ }
+ }
+ break;
+ case 'remove':
+
+ try
+ {
+ // We make sure that the table will be removed only if it exists specifying ifExists argument as true.
+ $db->dropTable((string) $table['table_name'], true);
+ $app->enqueueMessage(
+ Text::sprintf('Table `%s` was successfully deleted', $table['table_name'])
+ );
+ } catch (Exception $ex)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error deleting Table `%s`. Error: %s',
+ $table['table_name'], $ex->getMessage()
+ ), 'error'
+ );
+ }
+
+ break;
+ }
+ }
+
+ // If the table wasn't added before, let's process the fields of the table
+ if (!$table_added)
+ {
+ if ($this->existsTable($table['table_name']))
+ {
+ $this->executeFieldsUpdating($app, $table);
+ }
+ }
+ }
+
+ /**
+ * Checks if a certain exists on the current database
+ *
+ * @param string $table_name Name of the table
+ *
+ * @return boolean True if it exists, false if it does not.
+ */
+ private function existsTable($table_name)
+ {
+ $db = Factory::getDbo();
+
+ $table_name = str_replace('#__', $db->getPrefix(), (string) $table_name);
+
+ return in_array($table_name, $db->getTableList());
+ }
+
+ /**
+ * Generates a 'CREATE TABLE' statement for the tables passed by argument.
+ *
+ * @param SimpleXMLElement $table Table of the database
+ *
+ * @return string 'CREATE TABLE' statement
+ */
+ private function generateCreateTableStatement($table)
+ {
+ $create_table_statement = '';
+
+ if (isset($table->field))
+ {
+ $fields = $table->children();
+
+ $fields_definitions = array();
+ $indexes = array();
+
+ $db = Factory::getDbo();
+
+ foreach ($fields as $field)
+ {
+ $field_definition = $this->generateColumnDeclaration($field);
+
+ if ($field_definition !== false)
+ {
+ $fields_definitions[] = $field_definition;
+ }
+
+ if ($field['index'] == 'index')
+ {
+ $indexes[] = $field['field_name'];
+ }
+ }
+
+ foreach ($indexes as $index)
+ {
+ $fields_definitions[] = Text::sprintf(
+ 'INDEX %s (%s ASC)',
+ $db->quoteName((string) $index), $index
+ );
+ }
+
+ // Avoid duplicate PK definition
+ if (strpos(implode(',', $fields_definitions), 'PRIMARY KEY') === false)
+ {
+ $fields_definitions[] = 'PRIMARY KEY (`id`)';
+ }
+
+ $create_table_statement = Text::sprintf(
+ 'CREATE TABLE IF NOT EXISTS %s (%s)',
+ $table['table_name'],
+ implode(',', $fields_definitions)
+ );
+
+ if(isset($table['storage_engine']) && !empty($table['storage_engine']))
+ {
+ $create_table_statement .= " ENGINE=" . $table['storage_engine'];
+ }
+ if(isset($table['collation']))
+ {
+ $create_table_statement .= " DEFAULT COLLATE=" . $table['collation'];
+ }
+ }
+
+ return $create_table_statement;
+ }
+
+ /**
+ * Generate a column declaration
+ *
+ * @param SimpleXMLElement $field Field data
+ *
+ * @return string Column declaration
+ */
+ private function generateColumnDeclaration($field)
+ {
+ $db = Factory::getDbo();
+ $col_name = $db->quoteName((string) $field['field_name']);
+ $data_type = $this->getFieldType($field);
+
+ if ($data_type !== false)
+ {
+ $default_value = (isset($field['default'])) ? 'DEFAULT ' . $field['default'] : '';
+
+ $other_data = '';
+
+ if (isset($field['is_autoincrement']) && $field['is_autoincrement'] == 1)
+ {
+ $other_data .= ' AUTO_INCREMENT PRIMARY KEY';
+ }
+
+ $comment_value = (isset($field['description'])) ? 'COMMENT ' . $db->quote((string) $field['description']) : '';
+
+ return Text::sprintf(
+ '%s %s NOT NULL %s %s %s', $col_name, $data_type,
+ $default_value, $other_data, $comment_value
+ );
+ }
+
+ return false;
+ }
+
+ /**
+ * Generates SQL field type of a field.
+ *
+ * @param SimpleXMLElement $field Field information
+ *
+ * @return mixed SQL string data type, false on failure.
+ */
+ private function getFieldType($field)
+ {
+ $data_type = (string) $field['field_type'];
+
+ if (isset($field['field_length']) && ($this->allowsLengthField($data_type) || $data_type == 'ENUM'))
+ {
+ $data_type .= '(' . (string) $field['field_length'] . ')';
+ }
+
+ return (!empty($data_type)) ? $data_type : false;
+ }
+
+ /**
+ * Check if a SQL type allows length values.
+ *
+ * @param string $field_type SQL type
+ *
+ * @return boolean True if it allows length values, false if it does not.
+ */
+ private function allowsLengthField($field_type)
+ {
+ $allow_length = array(
+ 'INT',
+ 'VARCHAR',
+ 'CHAR',
+ 'TINYINT',
+ 'SMALLINT',
+ 'MEDIUMINT',
+ 'INTEGER',
+ 'BIGINT',
+ 'FLOAT',
+ 'DOUBLE',
+ 'DECIMAL',
+ 'NUMERIC'
+ );
+
+ return (in_array((string) $field_type, $allow_length));
+ }
+
+ /**
+ * Updates all the fields related to a table.
+ *
+ * @param JApplicationCms $app Application Object
+ * @param SimpleXMLElement $table Table information.
+ *
+ * @return void
+ */
+ private function executeFieldsUpdating($app, $table)
+ {
+ if (isset($table->field))
+ {
+ foreach ($table->children() as $field)
+ {
+ $table_name = (string) $table['table_name'];
+
+ $this->processField($app, $table_name, $field);
+ }
+ }
+ }
+
+ /**
+ * Process a certain field.
+ *
+ * @param JApplicationCms $app Application object
+ * @param string $table_name The name of the table that contains the field.
+ * @param SimpleXMLElement $field Field Information.
+ *
+ * @return void
+ */
+ private function processField($app, $table_name, $field)
+ {
+ $db = Factory::getDbo();
+
+ if (isset($field['action']))
+ {
+ switch ($field['action'])
+ {
+ case 'add':
+ $result = $this->addField($table_name, $field);
+
+ if ($result === MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf('Field `%s` has been successfully added', $field['field_name'])
+ );
+ }
+ else
+ {
+ if ($result !== NOT_MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error adding the field `%s`. Error: %s',
+ $field['field_name'], $result
+ ), 'error'
+ );
+ }
+ }
+ break;
+ case 'change':
+
+ if (isset($field['old_name']) && isset($field['new_name']))
+ {
+ if ($this->existsField($table_name, $field['old_name']) && !$this->existsField($table_name, $field['new_name']))
+ {
+ $renaming_statement = Text::sprintf(
+ 'ALTER TABLE %s CHANGE %s %s %s',
+ $table_name, $db->quoteName($field['old_name']->__toString()),
+ $db->quoteName($field['new_name']->__toString()),
+ $this->getFieldType($field)
+ );
+ $db->setQuery($renaming_statement);
+
+ try
+ {
+ $db->execute();
+ $app->enqueueMessage(
+ Text::sprintf('Field `%s` has been successfully modified', $field['old_name'])
+ );
+ } catch (Exception $ex)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error modifying the field `%s`. Error: %s',
+ $field['field_name'],
+ $ex->getMessage()
+ ), 'error'
+ );
+ }
+ }
+ else
+ {
+ $result = $this->addField($table_name, $field);
+
+ if ($result === MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf('Field `%s` has been successfully modified', $field['field_name'])
+ );
+ }
+ else
+ {
+ if ($result !== NOT_MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error modifying the field `%s`. Error: %s',
+ $field['field_name'], $result
+ ), 'error'
+ );
+ }
+ }
+ }
+ }
+ else
+ {
+ $result = $this->addField($table_name, $field);
+
+ if ($result === MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf('Field `%s` has been successfully added', $field['field_name'])
+ );
+ }
+ else
+ {
+ if ($result !== NOT_MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error adding the field `%s`. Error: %s',
+ $field['field_name'], $result
+ ), 'error'
+ );
+ }
+ }
+ }
+
+ break;
+ case 'remove':
+
+ // Check if the field exists first to prevent issue removing the field
+ if ($this->existsField($table_name, $field['field_name']))
+ {
+ $drop_statement = Text::sprintf(
+ 'ALTER TABLE %s DROP COLUMN %s',
+ $table_name, $field['field_name']
+ );
+ $db->setQuery($drop_statement);
+
+ try
+ {
+ $db->execute();
+ $app->enqueueMessage(
+ Text::sprintf('Field `%s` has been successfully deleted', $field['field_name'])
+ );
+ } catch (Exception $ex)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error deleting the field `%s`. Error: %s',
+ $field['field_name'],
+ $ex->getMessage()
+ ), 'error'
+ );
+ }
+ }
+
+ break;
+ }
+ }
+ else
+ {
+ $result = $this->addField($table_name, $field);
+
+ if ($result === MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf('Field `%s` has been successfully added', $field['field_name'])
+ );
+ }
+ else
+ {
+ if ($result !== NOT_MODIFIED)
+ {
+ $app->enqueueMessage(
+ Text::sprintf(
+ 'There was an error adding the field `%s`. Error: %s',
+ $field['field_name'], $result
+ ), 'error'
+ );
+ }
+ }
+ }
+ }
+
+ /**
+ * Add a field if it does not exists or modify it if it does.
+ *
+ * @param string $table_name Table name
+ * @param SimpleXMLElement $field Field Information
+ *
+ * @return mixed Constant on success(self::$MODIFIED | self::$NOT_MODIFIED), error message if an error occurred
+ */
+ private function addField($table_name, $field)
+ {
+ $db = Factory::getDbo();
+
+ $query_generated = false;
+
+ // Check if the field exists first to prevent issues adding the field
+ if ($this->existsField($table_name, $field['field_name']))
+ {
+ if ($this->needsToUpdate($table_name, $field))
+ {
+ $change_statement = $this->generateChangeFieldStatement($table_name, $field);
+ $db->setQuery($change_statement);
+ $query_generated = true;
+ }
+ }
+ else
+ {
+ $add_statement = $this->generateAddFieldStatement($table_name, $field);
+ $db->setQuery($add_statement);
+ $query_generated = true;
+ }
+
+ if ($query_generated)
+ {
+ try
+ {
+ $db->execute();
+
+ return MODIFIED;
+ } catch (Exception $ex)
+ {
+ return $ex->getMessage();
+ }
+ }
+
+ return NOT_MODIFIED;
+ }
+
+ /**
+ * Checks if a field exists on a table
+ *
+ * @param string $table_name Table name
+ * @param string $field_name Field name
+ *
+ * @return boolean True if exists, false if it do
+ */
+ private function existsField($table_name, $field_name)
+ {
+ $db = Factory::getDbo();
+
+ return in_array((string) $field_name, array_keys($db->getTableColumns($table_name)));
+ }
+
+ /**
+ * Check if a field needs to be updated.
+ *
+ * @param string $table_name Table name
+ * @param SimpleXMLElement $field Field information
+ *
+ * @return boolean True if the field has to be updated, false otherwise
+ */
+ private function needsToUpdate($table_name, $field)
+ {
+ $db = Factory::getDbo();
+
+ $query = Text::sprintf(
+ 'SHOW FULL COLUMNS FROM `%s` WHERE Field LIKE %s', $table_name, $db->quote((string) $field['field_name'])
+ );
+ $db->setQuery($query);
+
+ $field_info = $db->loadObject();
+
+ if (strripos($field_info->Type, $this->getFieldType($field)) === false)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Generates an change column statement
+ *
+ * @param string $table_name Table name
+ * @param SimpleXMLElement $field Field Information
+ *
+ * @return string Change column statement
+ */
+ private function generateChangeFieldStatement($table_name, $field)
+ {
+ $column_declaration = $this->generateColumnDeclaration($field);
+
+ return Text::sprintf('ALTER TABLE %s MODIFY %s', $table_name, $column_declaration);
+ }
+
+ /**
+ * Generates an add column statement
+ *
+ * @param string $table_name Table name
+ * @param SimpleXMLElement $field Field Information
+ *
+ * @return string Add column statement
+ */
+ private function generateAddFieldStatement($table_name, $field)
+ {
+ $column_declaration = $this->generateColumnDeclaration($field);
+
+ return Text::sprintf('ALTER TABLE %s ADD %s', $table_name, $column_declaration);
+ }
+
+ /**
+ * Installs plugins for this component
+ *
+ * @param mixed $parent Object who called the install/update method
+ *
+ * @return void
+ */
+ private function installPlugins($parent)
+ {
+ $installation_folder = $parent->getParent()->getPath('source');
+ $app = Factory::getApplication();
+
+ /* @var $plugins SimpleXMLElement */
+ $plugins = $parent->get("manifest")->plugins;
+
+ if (count($plugins->children()))
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ foreach ($plugins->children() as $plugin)
+ {
+ $pluginName = (string) $plugin['plugin'];
+ $pluginGroup = (string) $plugin['group'];
+ $path = $installation_folder . '/plugins/' . $pluginGroup . '/' . $pluginName;
+ $installer = new JInstaller;
+
+ if (!$this->isAlreadyInstalled('plugin', $pluginName, $pluginGroup))
+ {
+ $result = $installer->install($path);
+ }
+ else
+ {
+ $result = $installer->update($path);
+ }
+
+ if ($result)
+ {
+ $app->enqueueMessage('Plugin ' . $pluginName . ' was installed successfully');
+ }
+ else
+ {
+ $app->enqueueMessage('There was an issue installing the plugin ' . $pluginName,
+ 'error');
+ }
+
+ $query
+ ->clear()
+ ->update('#__extensions')
+ ->set('enabled = 1')
+ ->where(
+ array(
+ 'type LIKE ' . $db->quote('plugin'),
+ 'element LIKE ' . $db->quote($pluginName),
+ 'folder LIKE ' . $db->quote($pluginGroup)
+ )
+ );
+ $db->setQuery($query);
+ $db->execute();
+ }
+ }
+ }
+
+ /**
+ * Check if an extension is already installed in the system
+ *
+ * @param string $type Extension type
+ * @param string $name Extension name
+ * @param mixed $folder Extension folder(for plugins)
+ *
+ * @return boolean
+ */
+ private function isAlreadyInstalled($type, $name, $folder = null)
+ {
+ $result = false;
+
+ switch ($type)
+ {
+ case 'plugin':
+ $result = file_exists(JPATH_PLUGINS . '/' . $folder . '/' . $name);
+ break;
+ case 'module':
+ $result = file_exists(JPATH_SITE . '/modules/' . $name);
+ break;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Installs plugins for this component
+ *
+ * @param mixed $parent Object who called the install/update method
+ *
+ * @return void
+ */
+ private function installModules($parent)
+ {
+ $installation_folder = $parent->getParent()->getPath('source');
+ $app = Factory::getApplication();
+
+ if (!empty($parent->get("manifest")->modules))
+ {
+ $modules = $parent->get("manifest")->modules;
+
+ if (count($modules->children()))
+ {
+ foreach ($modules->children() as $module)
+ {
+ $moduleName = (string) $module['module'];
+ $path = $installation_folder . '/modules/' . $moduleName;
+ $installer = new JInstaller;
+
+ if (!$this->isAlreadyInstalled('module', $moduleName))
+ {
+ $result = $installer->install($path);
+ }
+ else
+ {
+ $result = $installer->update($path);
+ }
+
+ if ($result)
+ {
+ $app->enqueueMessage('Module ' . $moduleName . ' was installed successfully');
+ }
+ else
+ {
+ $app->enqueueMessage('There was an issue installing the module ' . $moduleName,
+ 'error');
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Method to update the component
+ *
+ * @param mixed $parent Object who called this method.
+ *
+ * @return void
+ */
+ public function update($parent)
+ {
+ $this->installDb($parent);
+ $this->installPlugins($parent);
+ $this->installModules($parent);
+ }
+
+ /**
+ * Method to uninstall the component
+ *
+ * @param mixed $parent Object who called this method.
+ *
+ * @return void
+ */
+ public function uninstall($parent)
+ {
+ $this->uninstallPlugins($parent);
+ $this->uninstallModules($parent);
+ }
+
+ /**
+ * Uninstalls plugins
+ *
+ * @param mixed $parent Object who called the uninstall method
+ *
+ * @return void
+ */
+ private function uninstallPlugins($parent)
+ {
+ $app = Factory::getApplication();
+ $plugins = $parent->get("manifest")->plugins;
+
+ if (count($plugins->children()))
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ foreach ($plugins->children() as $plugin)
+ {
+ $pluginName = (string) $plugin['plugin'];
+ $pluginGroup = (string) $plugin['group'];
+ $query
+ ->clear()
+ ->select('extension_id')
+ ->from('#__extensions')
+ ->where(
+ array(
+ 'type LIKE ' . $db->quote('plugin'),
+ 'element LIKE ' . $db->quote($pluginName),
+ 'folder LIKE ' . $db->quote($pluginGroup)
+ )
+ );
+ $db->setQuery($query);
+ $extension = $db->loadResult();
+
+ if (!empty($extension))
+ {
+ $installer = new JInstaller;
+ $result = $installer->uninstall('plugin', $extension);
+
+ if ($result)
+ {
+ $app->enqueueMessage('Plugin ' . $pluginName . ' was uninstalled successfully');
+ }
+ else
+ {
+ $app->enqueueMessage('There was an issue uninstalling the plugin ' . $pluginName,
+ 'error');
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Uninstalls plugins
+ *
+ * @param mixed $parent Object who called the uninstall method
+ *
+ * @return void
+ */
+ private function uninstallModules($parent)
+ {
+ $app = Factory::getApplication();
+
+ if (!empty($parent->get("manifest")->modules))
+ {
+ $modules = $parent->get("manifest")->modules;
+
+ if (count($modules->children()))
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ foreach ($modules->children() as $plugin)
+ {
+ $moduleName = (string) $plugin['module'];
+ $query
+ ->clear()
+ ->select('extension_id')
+ ->from('#__extensions')
+ ->where(
+ array(
+ 'type LIKE ' . $db->quote('module'),
+ 'element LIKE ' . $db->quote($moduleName)
+ )
+ );
+ $db->setQuery($query);
+ $extension = $db->loadResult();
+
+ if (!empty($extension))
+ {
+ $installer = new JInstaller;
+ $result = $installer->uninstall('module', $extension);
+
+ if ($result)
+ {
+ $app->enqueueMessage('Module ' . $moduleName . ' was uninstalled successfully');
+ }
+ else
+ {
+ $app->enqueueMessage('There was an issue uninstalling the module ' . $moduleName,
+ 'error');
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/site/models/domains.php b/site/models/domains.php
index 5e2c800..4ebedfc 100644
--- a/site/models/domains.php
+++ b/site/models/domains.php
@@ -76,29 +76,11 @@ public function __construct($config = array())
*/
protected function populateState($ordering = null, $direction = null)
{
- $app = Factory::getApplication();
-
+ $app = JFactory::getApplication();
$list = $app->getUserState($this->context . '.list');
$ordering = isset($list['filter_order']) ? $list['filter_order'] : null;
$direction = isset($list['filter_order_Dir']) ? $list['filter_order_Dir'] : null;
- if(empty($ordering)){
- $ordering = $app->getUserStateFromRequest($this->context . '.filter_order', 'filter_order', $app->get('filter_order'));
- if (!in_array($ordering, $this->filter_fields))
- {
- $ordering = 'areaname';
- }
- $this->setState('list.ordering', $ordering);
- }
- if(empty($direction))
- {
- $direction = $app->getUserStateFromRequest($this->context . '.filter_order_Dir', 'filter_order_Dir', $app->get('filter_order_Dir'));
- if (!in_array(strtoupper($direction), array('ASC', 'DESC', '')))
- {
- $direction = 'ASC';
- }
- $this->setState('list.direction', $direction);
- }
$list['limit'] = $app->getUserStateFromRequest($this->context . '.list.limit', 'limit', $app->get('list_limit'), 'uint');
$list['start'] = $app->input->getInt('start', 0);
@@ -111,13 +93,11 @@ protected function populateState($ordering = null, $direction = null)
// List state information.
- parent::populateState($ordering, $direction);
+ parent::populateState('areaname', 'ASC');
$context = $this->getUserStateFromRequest($this->context.'.filter.search', 'filter_search');
$this->setState('filter.search', $context);
-
-
// Split context into component and optional section
$parts = FieldsHelper::extract($context);
@@ -164,10 +144,6 @@ protected function getListQuery()
{
$query->where('a.state = 1');
}
- else
- {
- $query->where('(a.state IN (0, 1))');
- }
// Filter by search in title
$search = $this->getState('filter.search');
@@ -186,8 +162,6 @@ protected function getListQuery()
}
-
-
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'areaname');
$orderDirn = $this->state->get('list.direction', 'ASC');
diff --git a/site/models/fields/foreignkey.php b/site/models/fields/foreignkey.php
index 5cd72d0..bf9a1b0 100644
--- a/site/models/fields/foreignkey.php
+++ b/site/models/fields/foreignkey.php
@@ -12,7 +12,6 @@
use Joomla\CMS\Factory;
use \Joomla\CMS\HTML\HTMLHelper;
-use \Joomla\CMS\Language\Text;
jimport('joomla.form.formfield');
@@ -136,7 +135,7 @@ protected function getInput()
// Iterate through all the results
foreach ($results as $result)
{
- $options[] = HTMLHelper::_('select.option', $result->{$this->key_field}, Text::_($result->{$this->value_field}));
+ $options[] = HTMLHelper::_('select.option', $result->{$this->key_field}, $result->{$this->value_field});
}
$value = $this->value;
diff --git a/site/router.php b/site/router.php
index fd670e8..accd54b 100644
--- a/site/router.php
+++ b/site/router.php
@@ -10,49 +10,98 @@
// No direct access
defined('_JEXEC') or die;
-use Joomla\CMS\Component\Router\RouterViewConfiguration;
-use Joomla\CMS\Component\Router\RouterView;
-use Joomla\CMS\Component\Router\Rules\StandardRules;
-use Joomla\CMS\Component\Router\Rules\NomenuRules;
-use Joomla\CMS\Component\Router\Rules\MenuRules;
-use \Joomla\CMS\Factory;
+JLoader::registerPrefix('Rw_accounts', JPATH_SITE . '/components/com_rw_accounts/');
/**
* Class Rw_accountsRouter
*
+ * @since 3.3
*/
-class Rw_accountsRouter extends RouterView
+class Rw_accountsRouter extends \Joomla\CMS\Component\Router\RouterBase
{
- private $noIDs;
- public function __construct($app = null, $menu = null)
+ /**
+ * Build method for URLs
+ * This method is meant to transform the query parameters into a more human
+ * readable form. It is only executed when SEF mode is switched on.
+ *
+ * @param array &$query An array of URL arguments
+ *
+ * @return array The URL arguments to use to assemble the subsequent URL.
+ *
+ * @since 3.3
+ */
+ public function build(&$query)
{
- $params = Factory::getApplication()->getParams('com_rw_accounts');
- $this->noIDs = (bool) $params->get('sef_ids');
-
-
- $domains = new RouterViewConfiguration('domains');
- $this->registerView($domains);
-
+ $segments = array();
+ $view = null;
- parent::__construct($app, $menu);
-
- $this->attachRule(new MenuRules($this));
+ if (isset($query['task']))
+ {
+ $taskParts = explode('.', $query['task']);
+ $segments[] = implode('/', $taskParts);
+ $view = $taskParts[0];
+ unset($query['task']);
+ }
- if ($params->get('sef_advanced', 0))
+ if (isset($query['view']))
{
- $this->attachRule(new StandardRules($this));
- $this->attachRule(new NomenuRules($this));
+ $segments[] = $query['view'];
+ $view = $query['view'];
+
+ unset($query['view']);
}
- else
+
+ if (isset($query['id']))
{
- JLoader::register('Rw_accountsRulesLegacy', __DIR__ . '/helpers/legacyrouter.php');
- JLoader::register('Rw_accountsHelpersRw_accounts', __DIR__ . '/helpers/rw_accounts.php');
- $this->attachRule(new Rw_accountsRulesLegacy($this));
+ if ($view !== null)
+ {
+ $segments[] = $query['id'];
+ }
+ else
+ {
+ $segments[] = $query['id'];
+ }
+
+ unset($query['id']);
}
+
+ return $segments;
}
+ /**
+ * Parse method for URLs
+ * This method is meant to transform the human readable URL back into
+ * query parameters. It is only executed when SEF mode is switched on.
+ *
+ * @param array &$segments The segments of the URL to parse.
+ *
+ * @return array The URL attributes to be used by the application.
+ *
+ * @since 3.3
+ */
+ public function parse(&$segments)
+ {
+ $vars = array();
+
+ // View is always the first element of the array
+ $vars['view'] = array_shift($segments);
+ $model = Rw_accountsHelpersRw_accounts::getModel($vars['view']);
+
+ while (!empty($segments))
+ {
+ $segment = array_pop($segments);
-
+ // If it's the ID, let's put on the request
+ if (is_numeric($segment))
+ {
+ $vars['id'] = $segment;
+ }
+ else
+ {
+ $vars['task'] = $vars['view'] . '.' . $segment;
+ }
+ }
-
+ return $vars;
+ }
}
diff --git a/site/views/domains/tmpl/default.xml b/site/views/domains/tmpl/default.xml
index 7f0309c..4fc39b2 100644
--- a/site/views/domains/tmpl/default.xml
+++ b/site/views/domains/tmpl/default.xml
@@ -5,5 +5,4 @@
-