From 3a0b5e97f88d7bc067e04646382a626c16e49d28 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Tue, 22 May 2018 02:07:56 +0800 Subject: [PATCH 01/15] Create a small modal test --- .../com_content/tmpl/article/edit.php | 4 +++ .../tmpl/article/edit_autoassociations.php | 12 +++++++ layouts/joomla/edit/autoassociations.php | 32 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 administrator/components/com_content/tmpl/article/edit_autoassociations.php create mode 100644 layouts/joomla/edit/autoassociations.php diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index 79d11bb141..d478f4ffbe 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -99,6 +99,10 @@ loadTemplate('associations'); ?> + + Test + + loadTemplate('autoassociations'); ?> diff --git a/administrator/components/com_content/tmpl/article/edit_autoassociations.php b/administrator/components/com_content/tmpl/article/edit_autoassociations.php new file mode 100644 index 0000000000..e97013a4b3 --- /dev/null +++ b/administrator/components/com_content/tmpl/article/edit_autoassociations.php @@ -0,0 +1,12 @@ + $modalTitle, + 'url' => $url, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '', + ) +); From 28e6656b9062ce2f5ba8c80994f8fcda625e10c2 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Wed, 23 May 2018 02:16:43 +0800 Subject: [PATCH 02/15] New auto-association modal for articles --- .../Model/AutoassociationsModel.php | 44 +++++++++ .../View/Autoassociations/HtmlView.php | 97 +++++++++++++++++++ .../tmpl/autoassociations/default.php | 66 +++++++++++++ layouts/joomla/edit/autoassociations.php | 3 +- 4 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 administrator/components/com_content/Model/AutoassociationsModel.php create mode 100644 administrator/components/com_content/View/Autoassociations/HtmlView.php create mode 100644 administrator/components/com_content/tmpl/autoassociations/default.php diff --git a/administrator/components/com_content/Model/AutoassociationsModel.php b/administrator/components/com_content/Model/AutoassociationsModel.php new file mode 100644 index 0000000000..66c7a8a6a8 --- /dev/null +++ b/administrator/components/com_content/Model/AutoassociationsModel.php @@ -0,0 +1,44 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select required fields from the languages table. + $query->select('l.lang_id, l.lang_code') + ->from($db->quoteName('#__languages') . ' AS l'); + + // Join over the articles. + $query->select('c.id, c.title, c.language') + ->join('LEFT', $db->quoteName('#__content') . 'AS c ON c.language = l.lang_code'); + + return $query; + } +} \ No newline at end of file diff --git a/administrator/components/com_content/View/Autoassociations/HtmlView.php b/administrator/components/com_content/View/Autoassociations/HtmlView.php new file mode 100644 index 0000000000..86a12d26fa --- /dev/null +++ b/administrator/components/com_content/View/Autoassociations/HtmlView.php @@ -0,0 +1,97 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + // In article associations modal we need to remove language filter if forcing a language. + // We also need to change the category filter to show show categories with All or the forced language. + if ($forcedLanguage = \JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) + { + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. + $languageXml = new \SimpleXMLElement(''); + $this->filterForm->setField($languageXml, 'filter', true); + + // Also, unset the active language filter so the search tools is not open by default with this filter. + unset($this->activeFilters['language']); + + // One last changes needed is to change the category filter to just show categories with All language or with the forced language. + $this->filterForm->setFieldAttribute('category_id', 'language', '*,' . $forcedLanguage, 'filter'); + } + + return parent::display($tpl); + } +} \ No newline at end of file diff --git a/administrator/components/com_content/tmpl/autoassociations/default.php b/administrator/components/com_content/tmpl/autoassociations/default.php new file mode 100644 index 0000000000..c9c4c9aada --- /dev/null +++ b/administrator/components/com_content/tmpl/autoassociations/default.php @@ -0,0 +1,66 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +?> +
+
+
+
+ + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + +
+ + + + + +
+ pagination->getListFooter(); ?> +
+ lang_id); ?> + + escape($item->lang_code); ?> + + escape($item->title); ?> +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/layouts/joomla/edit/autoassociations.php b/layouts/joomla/edit/autoassociations.php index 197aa70ef9..8cb2fc8cc8 100644 --- a/layouts/joomla/edit/autoassociations.php +++ b/layouts/joomla/edit/autoassociations.php @@ -12,8 +12,7 @@ $modalId = 'Article_auto_associations'; $modalTitle = 'Multilingual Associations'; -$url = 'index.php?option=com_content&view=articles&layout=modal&tmpl=component&' . \JSession::getFormToken() . '=1' - . '&function=jSelectArticle_jform_associations_auto'; +$url = 'index.php?option=com_content&view=autoassociations&layout=default&tmpl=component&' . \JSession::getFormToken() . '=1'; echo \JHtml::_( From 085a6404af2aeb1ff3a938636fef74d0ad6860aa Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Fri, 25 May 2018 02:28:47 +0800 Subject: [PATCH 03/15] Build skeleton of auto-associations in com_associations --- .../com_associations/Model/AutoModel.php | 175 ++++++++++++++++ .../com_associations/View/Auto/HtmlView.php | 186 ++++++++++++++++++ .../com_associations/forms/filter_auto.xml | 103 ++++++++++ .../com_associations/tmpl/auto/modal.php | 101 ++++++++++ .../Model/AutoassociationsModel.php | 44 ----- .../View/Autoassociations/HtmlView.php | 97 --------- .../com_content/tmpl/article/edit.php | 2 +- ...dit_autoassociations.php => edit_auto.php} | 2 +- .../tmpl/autoassociations/default.php | 66 ------- .../edit/{autoassociations.php => auto.php} | 6 +- 10 files changed, 570 insertions(+), 212 deletions(-) create mode 100644 administrator/components/com_associations/Model/AutoModel.php create mode 100644 administrator/components/com_associations/View/Auto/HtmlView.php create mode 100644 administrator/components/com_associations/forms/filter_auto.xml create mode 100644 administrator/components/com_associations/tmpl/auto/modal.php delete mode 100644 administrator/components/com_content/Model/AutoassociationsModel.php delete mode 100644 administrator/components/com_content/View/Autoassociations/HtmlView.php rename administrator/components/com_content/tmpl/article/{edit_autoassociations.php => edit_auto.php} (80%) delete mode 100644 administrator/components/com_content/tmpl/autoassociations/default.php rename layouts/joomla/edit/{autoassociations.php => auto.php} (76%) diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoModel.php new file mode 100644 index 0000000000..5b324991e9 --- /dev/null +++ b/administrator/components/com_associations/Model/AutoModel.php @@ -0,0 +1,175 @@ +input->get('forcedLanguage', '', 'cmd'); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + // Adjust the context to support forced languages. + if ($forcedLanguage) + { + $this->context .= '.' . $forcedLanguage; + } + + $this->setState('itemtype', $this->getUserStateFromRequest($this->context . '.itemtype', 'itemtype', '', 'string')); + $this->setState('language', $this->getUserStateFromRequest($this->context . '.language', 'language', '', 'string')); + $this->setState('referenceId', $this->getUserStateFromRequest($this->context . '.id', 'id', 0, 'int')); + + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + $this->setState( + 'filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'cmd') + ); + $this->setState('filter.menutype', $this->getUserStateFromRequest($this->context . '.filter.menutype', 'filter_menutype', '', 'string')); + $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'string')); + $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since __DEPLOY_VERSION__ + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('itemtype'); + $id .= ':' . $this->getState('forcedLanguage'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.category_id'); + $id .= ':' . $this->getState('filter.menutype'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.level'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return DatabaseQuery|boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function getListQuery() + { + $type = null; + + list($extensionName, $typeName) = explode('.', $this->state->get('itemtype'), 2); + + $extension = AssociationsHelper::getSupportedExtension($extensionName); + $types = $extension->get('types'); + + if (array_key_exists($typeName, $types)) + { + $type = $types[$typeName]; + } + + if (is_null($type)) + { + return false; + } + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Main query + $query->select($db->quoteName('l.lang_id', 'lang_id')) + ->select($db->quoteName('l.lang_code', 'language')) + ->select($db->quoteName('l.published', 'published')) + ->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) + ->from($db->quoteName('#__languages', 'l')); + + // @TODO Use db query to find associations, and set category_title. + + return $query; + } +} diff --git a/administrator/components/com_associations/View/Auto/HtmlView.php b/administrator/components/com_associations/View/Auto/HtmlView.php new file mode 100644 index 0000000000..e9e0e6b2de --- /dev/null +++ b/administrator/components/com_associations/View/Auto/HtmlView.php @@ -0,0 +1,186 @@ +state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + if (!Associations::isEnabled()) + { + $link = \JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . AssociationsHelper::getLanguagefilterPluginId()); + \JFactory::getApplication()->enqueueMessage(\JText::sprintf('COM_ASSOCIATIONS_ERROR_NO_ASSOC', $link), 'warning'); + } + else + { + $type = null; + + list($extensionName, $typeName) = explode('.', $this->state->get('itemtype'), 2); + + $extension = AssociationsHelper::getSupportedExtension($extensionName); + + $types = $extension->get('types'); + + if (array_key_exists($typeName, $types)) + { + $type = $types[$typeName]; + } + + $this->itemType = $type; + + if (is_null($type)) + { + \JFactory::getApplication()->enqueueMessage(\JText::_('COM_ASSOCIATIONS_ERROR_NO_TYPE'), 'warning'); + } + else + { + $this->extensionName = $extensionName; + $this->typeName = $typeName; + $this->typeSupports = array(); + $this->typeFields = array(); + + $details = $type->get('details'); + + if (array_key_exists('support', $details)) + { + $support = $details['support']; + $this->typeSupports = $support; + } + + if (array_key_exists('fields', $details)) + { + $fields = $details['fields']; + $this->typeFields = $fields; + } + + // Dynamic filter form. + // This selectors doesn't have to activate the filter bar. + unset($this->activeFilters['itemtype']); + unset($this->activeFilters['language']); + + // Remove filters options depending on selected type. + if (empty($support['state'])) + { + unset($this->activeFilters['state']); + $this->filterForm->removeField('state', 'filter'); + } + if (empty($support['category'])) + { + unset($this->activeFilters['category_id']); + $this->filterForm->removeField('category_id', 'filter'); + } + if ($extensionName !== 'com_menus') + { + unset($this->activeFilters['menutype']); + $this->filterForm->removeField('menutype', 'filter'); + } + if (empty($support['level'])) + { + unset($this->activeFilters['level']); + $this->filterForm->removeField('level', 'filter'); + } + if (empty($support['acl'])) + { + unset($this->activeFilters['access']); + $this->filterForm->removeField('access', 'filter'); + } + + // Add extension attribute to category filter. + if (empty($support['catid'])) + { + $this->filterForm->setFieldAttribute('category_id', 'extension', $extensionName, 'filter'); + } + + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + + // @TODO move these into model + $referenceId = $this->state->get('referenceId'); + $associations = AssociationsHelper::getAssociationList($extensionName, $typeName, $referenceId); + + foreach ($this->items as $item) + { + if (isset($associations[$item->language])) + { + $item->association = $associations[$item->language]; + } + } + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \Exception(implode("\n", $errors), 500); + } + + parent::display($tpl); + } + } +} diff --git a/administrator/components/com_associations/forms/filter_auto.xml b/administrator/components/com_associations/forms/filter_auto.xml new file mode 100644 index 0000000000..63f10e0327 --- /dev/null +++ b/administrator/components/com_associations/forms/filter_auto.xml @@ -0,0 +1,103 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_associations/tmpl/auto/modal.php b/administrator/components/com_associations/tmpl/auto/modal.php new file mode 100644 index 0000000000..0042f58534 --- /dev/null +++ b/administrator/components/com_associations/tmpl/auto/modal.php @@ -0,0 +1,101 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canManageCheckin = JFactory::getUser()->authorise('core.manage', 'com_checkin'); +$colSpan = 4; + +// @TODO add scripts +//JHtml::_('script', 'com_associations/admin-auto-modal.min.js', false, true); +?> +
+
+
+
+ $this)); ?> + + + + + + + + typeFields['menutype'])) : ?> + + + + + + + + + + + items as $i => $item) :?> + + + + + + typeFields['menutype'])) : ?> + + + + + +
+ + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ lang_id); ?> + + published, $i, 'languages.', true); ?> + + escape($item->language); ?> + + association)) : ?> + association['title']; ?> + typeFields['alias'])) : ?> + + escape($item->association['alias'])); ?> + + + typeFields['catid'])) : ?> +
+ escape($item->association['catid']); ?> +
+ + +
+ escape($item->menutype_title); ?> +
+ + + +
+
+
+
diff --git a/administrator/components/com_content/Model/AutoassociationsModel.php b/administrator/components/com_content/Model/AutoassociationsModel.php deleted file mode 100644 index 66c7a8a6a8..0000000000 --- a/administrator/components/com_content/Model/AutoassociationsModel.php +++ /dev/null @@ -1,44 +0,0 @@ -getDbo(); - $query = $db->getQuery(true); - - // Select required fields from the languages table. - $query->select('l.lang_id, l.lang_code') - ->from($db->quoteName('#__languages') . ' AS l'); - - // Join over the articles. - $query->select('c.id, c.title, c.language') - ->join('LEFT', $db->quoteName('#__content') . 'AS c ON c.language = l.lang_code'); - - return $query; - } -} \ No newline at end of file diff --git a/administrator/components/com_content/View/Autoassociations/HtmlView.php b/administrator/components/com_content/View/Autoassociations/HtmlView.php deleted file mode 100644 index 86a12d26fa..0000000000 --- a/administrator/components/com_content/View/Autoassociations/HtmlView.php +++ /dev/null @@ -1,97 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - - // In article associations modal we need to remove language filter if forcing a language. - // We also need to change the category filter to show show categories with All or the forced language. - if ($forcedLanguage = \JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) - { - // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. - $languageXml = new \SimpleXMLElement(''); - $this->filterForm->setField($languageXml, 'filter', true); - - // Also, unset the active language filter so the search tools is not open by default with this filter. - unset($this->activeFilters['language']); - - // One last changes needed is to change the category filter to just show categories with All language or with the forced language. - $this->filterForm->setFieldAttribute('category_id', 'language', '*,' . $forcedLanguage, 'filter'); - } - - return parent::display($tpl); - } -} \ No newline at end of file diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index d478f4ffbe..a53ad24e8e 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -102,7 +102,7 @@ Test - loadTemplate('autoassociations'); ?> + loadTemplate('auto'); ?> diff --git a/administrator/components/com_content/tmpl/article/edit_autoassociations.php b/administrator/components/com_content/tmpl/article/edit_auto.php similarity index 80% rename from administrator/components/com_content/tmpl/article/edit_autoassociations.php rename to administrator/components/com_content/tmpl/article/edit_auto.php index e97013a4b3..09471790f5 100644 --- a/administrator/components/com_content/tmpl/article/edit_autoassociations.php +++ b/administrator/components/com_content/tmpl/article/edit_auto.php @@ -9,4 +9,4 @@ defined('_JEXEC') or die; -echo JLayoutHelper::render('joomla.edit.autoassociations', $this); \ No newline at end of file +echo JLayoutHelper::render('joomla.edit.auto', $this); \ No newline at end of file diff --git a/administrator/components/com_content/tmpl/autoassociations/default.php b/administrator/components/com_content/tmpl/autoassociations/default.php deleted file mode 100644 index c9c4c9aada..0000000000 --- a/administrator/components/com_content/tmpl/autoassociations/default.php +++ /dev/null @@ -1,66 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); - -?> -
-
-
-
- - - - - - - - - - - - - - - items as $i => $item) : ?> - - - - - - - -
- - - - - -
- pagination->getListFooter(); ?> -
- lang_id); ?> - - escape($item->lang_code); ?> - - escape($item->title); ?> -
- - - - -
-
-
-
\ No newline at end of file diff --git a/layouts/joomla/edit/autoassociations.php b/layouts/joomla/edit/auto.php similarity index 76% rename from layouts/joomla/edit/autoassociations.php rename to layouts/joomla/edit/auto.php index 8cb2fc8cc8..e0e818d373 100644 --- a/layouts/joomla/edit/autoassociations.php +++ b/layouts/joomla/edit/auto.php @@ -10,17 +10,17 @@ defined('JPATH_BASE') or die; +$itemId = $displayData->get('Item')->id; $modalId = 'Article_auto_associations'; $modalTitle = 'Multilingual Associations'; -$url = 'index.php?option=com_content&view=autoassociations&layout=default&tmpl=component&' . \JSession::getFormToken() . '=1'; - +$modalUrl = 'index.php?option=com_associations&view=auto&layout=modal&tmpl=component&itemtype=com_content.article&id=' . $itemId; echo \JHtml::_( 'bootstrap.renderModal', 'ModalSelect' . $modalId, array( 'title' => $modalTitle, - 'url' => $url, + 'url' => $modalUrl, 'height' => '400px', 'width' => '800px', 'bodyHeight' => 70, From b2f6904c37bd095c62c3fffee4f0a0c23a6d2757 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Sun, 27 May 2018 20:22:25 +0800 Subject: [PATCH 04/15] Use sql in model to find associations, categories, alias and menutype --- .../com_associations/Model/AutoModel.php | 88 +++++++++++++++++-- .../com_associations/View/Auto/HtmlView.php | 12 --- .../com_associations/tmpl/auto/modal.php | 51 ++++++----- 3 files changed, 107 insertions(+), 44 deletions(-) diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoModel.php index 5b324991e9..b0bef475d9 100644 --- a/administrator/components/com_associations/Model/AutoModel.php +++ b/administrator/components/com_associations/Model/AutoModel.php @@ -86,7 +86,6 @@ protected function populateState($ordering = 'ordering', $direction = 'asc') } $this->setState('itemtype', $this->getUserStateFromRequest($this->context . '.itemtype', 'itemtype', '', 'string')); - $this->setState('language', $this->getUserStateFromRequest($this->context . '.language', 'language', '', 'string')); $this->setState('referenceId', $this->getUserStateFromRequest($this->context . '.id', 'id', 0, 'int')); $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); @@ -143,8 +142,8 @@ protected function getListQuery() list($extensionName, $typeName) = explode('.', $this->state->get('itemtype'), 2); - $extension = AssociationsHelper::getSupportedExtension($extensionName); - $types = $extension->get('types'); + $extension = AssociationsHelper::getSupportedExtension($extensionName); + $types = $extension->get('types'); if (array_key_exists($typeName, $types)) { @@ -160,15 +159,92 @@ protected function getListQuery() $db = $this->getDbo(); $query = $db->getQuery(true); - // Main query + $details = $type->get('details'); + + if (!array_key_exists('support', $details)) + { + return false; + } + + $support = $details['support']; + + if (!array_key_exists('fields', $details)) + { + return false; + } + + $fields = $details['fields']; + + $tablename = $details['tables']['a']; + $referenceId = $this->state->get('referenceId'); + $context = $extensionName . '.item'; + $pk = explode('.', $fields['id'])[1]; + $titleField = explode('.', $fields['title'])[1]; + $langField = explode('.', $fields['language'])[1]; + + if ($typeName === 'category') + { + $context = 'com_categories.item'; + } + + $categoriesExtraSql = (($tablename === '#__categories') ? ' AND c2.extension = ' . $db->quote($extensionName) : ''); + + $query->select($db->quoteName('c2.' . $pk, 'item_id')) + ->select($db->quoteName('c2.' . $titleField, 'item_title')) + ->from($db->quoteName($tablename, 'c')) + ->join('INNER', $db->quoteName('#__associations', 'a') . ' ON a.id = c.' . $db->quoteName($pk) . ' AND a.context=' . $db->quote($context)) + ->join('INNER', $db->quoteName('#__associations', 'a2') . ' ON a.key = a2.key') + ->join('INNER', $db->quoteName($tablename, 'c2') . ' ON a2.id = c2.' . $db->quoteName($pk) . $categoriesExtraSql); + $query->select($db->quoteName('l.lang_id', 'lang_id')) ->select($db->quoteName('l.lang_code', 'language')) ->select($db->quoteName('l.published', 'published')) ->select($db->quoteName('l.title', 'language_title')) ->select($db->quoteName('l.image', 'language_image')) - ->from($db->quoteName('#__languages', 'l')); + ->join( + 'RIGHT', $db->quoteName('#__languages', 'l') . ' ON c2.' + . $db->quoteName($langField) . ' = l.lang_code' + ); + + // Use alias field ? + if (!empty($fields['alias'])) + { + $aliasField = explode('.', $fields['alias'])[1]; + + $query->select($db->quoteName('c2.' . $aliasField, 'alias')); + } + + // Use catid field ? + if (!empty($fields['catid'])) + { + $catField = explode('.', $fields['catid'])[1]; + + $query->join('LEFT', $db->quoteName('#__categories', 'ca') + . ' ON ' . $db->quoteName('c2.' . $catField) . ' = ca.id AND ca.extension = ' . $db->quote($extensionName) + ) + ->select($db->quoteName('ca.alias', 'category')); + } - // @TODO Use db query to find associations, and set category_title. + // If component item type supports menu type, select the menu type also. + if (!empty($fields['menutype'])) + { + $menutypeField = explode('.', $fields['menutype'])[1]; + + $query->select($db->quoteName('mt.title', 'menutype_title')) + ->join( + 'LEFT', $db->quoteName('#__menu_types', 'mt') . ' ON ' . $db->quoteName('mt.menutype') + . ' = ' . $db->quoteName('c2.' . $menutypeField) + ); + } + + $query->where('(c.' . $pk . ' = ' . (int) $referenceId . ' OR c.' . $pk . ' IS NULL) AND (c.' + . $langField . ' != l.lang_code OR c.' . $langField . ' IS NULL)' + ); + + if ($tablename === '#__categories') + { + $query->where('c.extension = ' . $db->quote($extensionName)); + } return $query; } diff --git a/administrator/components/com_associations/View/Auto/HtmlView.php b/administrator/components/com_associations/View/Auto/HtmlView.php index e9e0e6b2de..c4a27b7b88 100644 --- a/administrator/components/com_associations/View/Auto/HtmlView.php +++ b/administrator/components/com_associations/View/Auto/HtmlView.php @@ -160,18 +160,6 @@ public function display($tpl = null) $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); - - // @TODO move these into model - $referenceId = $this->state->get('referenceId'); - $associations = AssociationsHelper::getAssociationList($extensionName, $typeName, $referenceId); - - foreach ($this->items as $item) - { - if (isset($associations[$item->language])) - { - $item->association = $associations[$item->language]; - } - } } // Check for errors. diff --git a/administrator/components/com_associations/tmpl/auto/modal.php b/administrator/components/com_associations/tmpl/auto/modal.php index 0042f58534..01b871155d 100644 --- a/administrator/components/com_associations/tmpl/auto/modal.php +++ b/administrator/components/com_associations/tmpl/auto/modal.php @@ -18,7 +18,6 @@ $colSpan = 4; // @TODO add scripts -//JHtml::_('script', 'com_associations/admin-auto-modal.min.js', false, true); ?>
@@ -27,27 +26,27 @@ $this)); ?> - - - - - + + + + + typeFields['menutype'])) : ?> + - typeFields['menutype'])) : ?> - - - + + @@ -69,16 +68,16 @@ escape($item->language); ?>
- - - - - - - +
+ + + + + + + + + - -
- association)) : ?> - association['title']; ?> - typeFields['alias'])) : ?> + item_title)) : ?> + item_title; ?> + typeFields['alias'])) : ?> - escape($item->association['alias'])); ?> + escape($item->alias)); ?> typeFields['catid'])) : ?>
- escape($item->association['catid']); ?> + escape($item->category); ?>
From 5510ac3baea3b98c15207f1b63522e829d204f84 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Tue, 29 May 2018 16:59:32 +0800 Subject: [PATCH 05/15] Use function to remove field in filter form. --- .../com_associations/View/Auto/HtmlView.php | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/administrator/components/com_associations/View/Auto/HtmlView.php b/administrator/components/com_associations/View/Auto/HtmlView.php index c4a27b7b88..f3502e17f1 100644 --- a/administrator/components/com_associations/View/Auto/HtmlView.php +++ b/administrator/components/com_associations/View/Auto/HtmlView.php @@ -128,28 +128,19 @@ public function display($tpl = null) // Remove filters options depending on selected type. if (empty($support['state'])) { - unset($this->activeFilters['state']); - $this->filterForm->removeField('state', 'filter'); + $this->removeFilterField('state'); } if (empty($support['category'])) { - unset($this->activeFilters['category_id']); - $this->filterForm->removeField('category_id', 'filter'); + $this->removeFilterField('category_id'); } if ($extensionName !== 'com_menus') { - unset($this->activeFilters['menutype']); - $this->filterForm->removeField('menutype', 'filter'); - } - if (empty($support['level'])) - { - unset($this->activeFilters['level']); - $this->filterForm->removeField('level', 'filter'); + $this->removeFilterField('menutype'); } if (empty($support['acl'])) { - unset($this->activeFilters['access']); - $this->filterForm->removeField('access', 'filter'); + $this->removeFilterField('access'); } // Add extension attribute to category filter. @@ -171,4 +162,17 @@ public function display($tpl = null) parent::display($tpl); } } + + /** + * @param string $fieldname The field name to be removed in the filter form. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function removeFilterField($fieldname) + { + unset($this->activeFilters[$fieldname]); + $this->filterForm->removeField($fieldname, 'filter'); + } } From 948e4f5e827bf24d21f84d56ee77d89560fafcc7 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Sun, 3 Jun 2018 02:17:04 +0800 Subject: [PATCH 06/15] Create associations of current article by selected languages --- .../com_associations/Model/AutoModel.php | 6 +- .../com_associations/forms/filter_auto.xml | 10 - .../Controller/ArticleController.php | 30 +++ .../com_content/Model/ArticleModel.php | 177 ++++++++++++++++++ .../src/MVC/Controller/FormController.php | 38 ++++ 5 files changed, 248 insertions(+), 13 deletions(-) diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoModel.php index b0bef475d9..306acae41e 100644 --- a/administrator/components/com_associations/Model/AutoModel.php +++ b/administrator/components/com_associations/Model/AutoModel.php @@ -203,7 +203,7 @@ protected function getListQuery() ->select($db->quoteName('l.image', 'language_image')) ->join( 'RIGHT', $db->quoteName('#__languages', 'l') . ' ON c2.' - . $db->quoteName($langField) . ' = l.lang_code' + . $db->quoteName($langField) . ' = ' . $db->quoteName('l.lang_code') ); // Use alias field ? @@ -238,12 +238,12 @@ protected function getListQuery() } $query->where('(c.' . $pk . ' = ' . (int) $referenceId . ' OR c.' . $pk . ' IS NULL) AND (c.' - . $langField . ' != l.lang_code OR c.' . $langField . ' IS NULL)' + . $langField . ' != ' . $db->quoteName('l.lang_code') . ' OR c.' . $langField . ' IS NULL)' ); if ($tablename === '#__categories') { - $query->where('c.extension = ' . $db->quote($extensionName)); + $query->where($db->quoteName('c.extension') . ' = ' . $db->quote($extensionName)); } return $query; diff --git a/administrator/components/com_associations/forms/filter_auto.xml b/administrator/components/com_associations/forms/filter_auto.xml index 63f10e0327..f806a52e47 100644 --- a/administrator/components/com_associations/forms/filter_auto.xml +++ b/administrator/components/com_associations/forms/filter_auto.xml @@ -62,16 +62,6 @@ - - - diff --git a/administrator/components/com_content/Controller/ArticleController.php b/administrator/components/com_content/Controller/ArticleController.php index 578e30f0f2..ef82b6a36e 100644 --- a/administrator/components/com_content/Controller/ArticleController.php +++ b/administrator/components/com_content/Controller/ArticleController.php @@ -121,6 +121,36 @@ protected function allowEdit($data = array(), $key = 'id') return false; } + /** + * Method to automatically create associated articles. + * + * @param BaseDatabaseModel $model The model of the component being processed. + * + * @return boolean True is successful, false otherwise and internal error is set. + * + * @since __DEPLOY_VERSION__ + */ + public function autocreate($model = null) + { + \JSession::checkToken() or jexit(\JText::_('JINVALID_TOKEN')); + + if (!Associations::isEnabled()) + { + // @TODO Add Error Messages + $this->setMessage(Text::_('')); + + return false; + } + + // Set the model + $model = $this->getModel('Article', 'Administrator', array()); + + // Preset the redirect + $this->setRedirect(\JRoute::_('index.php?option=com_content&view=articles' . $this->getRedirectToListAppend(), false)); + + return parent::autocreate($model); + } + /** * Method to run batch operations. * diff --git a/administrator/components/com_content/Model/ArticleModel.php b/administrator/components/com_content/Model/ArticleModel.php index 4d986f15c5..8638b477a6 100644 --- a/administrator/components/com_content/Model/ArticleModel.php +++ b/administrator/components/com_content/Model/ArticleModel.php @@ -14,6 +14,7 @@ use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; use Joomla\CMS\MVC\Model\AdminModel; +use Joomla\Component\Associations\Administrator\Helper\AssociationsHelper; /** * Item Model for an Article. @@ -46,6 +47,182 @@ class ArticleModel extends AdminModel */ protected $associationsContext = 'com_content.item'; + /** + * Method to automatically create associations of an item in chosen languages. + * + * @param int $itemId Id of current item. + * @param array $cid An array of language ids. + * + * @return boolean Return true on success, false on failure. + * + * @since __DEPLOY_VERSION__ + */ + public function autocreate($itemId, $cid) + { + // Sanitize ids. + $cid = array_unique($cid); + $cid = ArrayHelper::toInteger($cid); + + // Remove any values of zero. + if (array_search(0, $cid, true)) + { + unset($cid[array_search(0, $cid, true)]); + } + + if (empty($cid)) + { + $this->setError(\JText::_('JGLOBAL_NO_ITEM_SELECTED')); + + return false; + } + + // Get associations + $associations = AssociationsHelper::getAssociationList('com_content', 'article', $itemId); + + // Get current user + if (empty($this->user)) + { + $this->user = \JFactory::getUser(); + } + + // Get content table + if (empty($this->table)) + { + $this->table = $this->getTable(); + } + + // Get language table + $languageTable = $this->getTable('Language', 'Joomla\CMS\Table'); + + while (!empty($cid)) + { + // Pop the first ID off the stack + $pk = array_shift($cid); + + $this->table->reset(); + $languageTable->reset(); + + if (!$languageTable->load($pk) || !$this->table->load($itemId)) + { + if ($error = $languageTable->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + elseif ($error = $this->table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_ROW_NOT_FOUND' + // Not fatal error + $this->setError(\JText::sprintf('', $pk)); + continue; + } + } + + // Get current language + $lang_code = $languageTable->lang_code; + + // If the article doesn't have associations in current language + if (!isset($associations[$lang_code])) + { + // Alter the title & alias + $this->table->title .= ' [' . $lang_code . ']'; + $this->table->alias .= ' [' . $lang_code . ']'; + + // Alter the language + $this->table->language = $lang_code; + + // Reset the ID, hits, state. + $this->table->id = $this->table->hits = $this->table->state = 0; + + // @TODO Change category? + + // Get the featured state + $featured = $this->table->featured; + + // Check the row. + if (!$this->table->check()) + { + $this->setError($this->table->getError()); + + return false; + } + + // Store the row. + if (!$this->table->store()) + { + $this->setError($this->table->getError()); + + return false; + } + + // Get the new item ID + $newId = $this->table->get('id'); + + // Check if the article was featured and update the #__content_frontpage table + if ($featured == 1) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->insert($db->quoteName('#__content_frontpage')) + ->values($newId . ', 0'); + $db->setQuery($query); + $db->execute(); + } + } + } + + // Get associations key for edited item + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('key')) + ->from($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote('com_content.item')) + ->where($db->quoteName('id') . ' = ' . (int) $itemId); + $db->setQuery($query); + $oldKey = $db->loadResult(); + + // Deleting old associations for the associated items + $query = $db->getQuery(true) + ->delete($db->quoteName('#__associations')) + ->where('(' . $db->quoteName('context') . ' = ' . $db->quote('.item') . ') AND (' + . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')' + ); + + $db->setQuery($query); + $db->execute(); + + // Add new associations + if (count($associations) > 1) + { + // Adding new association for these items + $key = md5(json_encode($associations)); + $query = $db->getQuery(true) + ->insert('#__associations'); + + foreach ($associations as $data) + { + $query->values(((int) $data['id']) . ',' . $db->quote('com_content.item') . ',' . $db->quote($key)); + } + + $db->setQuery($query); + $db->execute(); + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + /** * Batch copy items to a new category or current. * diff --git a/libraries/src/MVC/Controller/FormController.php b/libraries/src/MVC/Controller/FormController.php index 747c828277..055a25a1d3 100644 --- a/libraries/src/MVC/Controller/FormController.php +++ b/libraries/src/MVC/Controller/FormController.php @@ -241,6 +241,44 @@ protected function allowSave($data, $key = 'id') } } + /** + * Method to automatically create associated articles. + * + * @param BaseDatabaseModel $model The model of the component being processed. + * + * @return boolean True is successful, false otherwise and internal error is set. + * + * @since __DEPLOY_VERSION__ + */ + public function autocreate($model) + { + $cid = $this->input->post->get('cid', array(), 'array'); + $itemId = $this->input->post->get('id', array(), 'INT'); + + if (!Associations::isEnabled()) + { + // @TODO Add Error Messages + $this->setMessage(Text::_('')); + + return false; + } + + if ($model->autocreate($itemId, $cid)) + { + // @TODO Add 'JLIB_APPLICATION_SUCCESS_AUTO_ASSOCIATIONS' + $this->setMessage(Text::_('')); + + return true; + } + else + { + // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_FAILED' + $this->setMessage(Text::_('')); + + return false; + } + } + /** * Method to run batch operations. * From 92199a762935109d3ed7cc8e96b3372d88854117 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Wed, 6 Jun 2018 00:19:12 +0800 Subject: [PATCH 07/15] Update query statements in getListQuery() --- .../com_associations/Model/AutoModel.php | 139 +++++++++++------- 1 file changed, 82 insertions(+), 57 deletions(-) diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoModel.php index 306acae41e..406a4ddc6c 100644 --- a/administrator/components/com_associations/Model/AutoModel.php +++ b/administrator/components/com_associations/Model/AutoModel.php @@ -175,75 +175,100 @@ protected function getListQuery() $fields = $details['fields']; - $tablename = $details['tables']['a']; - $referenceId = $this->state->get('referenceId'); - $context = $extensionName . '.item'; - $pk = explode('.', $fields['id'])[1]; - $titleField = explode('.', $fields['title'])[1]; - $langField = explode('.', $fields['language'])[1]; + $tablename = $details['tables']['a']; + $referenceId = $this->state->get('referenceId'); + $context = $extensionName . '.item'; + $pk = explode('.', $fields['id'])[1]; + $titleField = explode('.', $fields['title'])[1]; + $langField = explode('.', $fields['language'])[1]; + $associations = AssociationsHelper::getAssociationList($extensionName, $typeName, $referenceId); if ($typeName === 'category') { $context = 'com_categories.item'; } - $categoriesExtraSql = (($tablename === '#__categories') ? ' AND c2.extension = ' . $db->quote($extensionName) : ''); - - $query->select($db->quoteName('c2.' . $pk, 'item_id')) - ->select($db->quoteName('c2.' . $titleField, 'item_title')) - ->from($db->quoteName($tablename, 'c')) - ->join('INNER', $db->quoteName('#__associations', 'a') . ' ON a.id = c.' . $db->quoteName($pk) . ' AND a.context=' . $db->quote($context)) - ->join('INNER', $db->quoteName('#__associations', 'a2') . ' ON a.key = a2.key') - ->join('INNER', $db->quoteName($tablename, 'c2') . ' ON a2.id = c2.' . $db->quoteName($pk) . $categoriesExtraSql); - - $query->select($db->quoteName('l.lang_id', 'lang_id')) - ->select($db->quoteName('l.lang_code', 'language')) - ->select($db->quoteName('l.published', 'published')) - ->select($db->quoteName('l.title', 'language_title')) - ->select($db->quoteName('l.image', 'language_image')) - ->join( - 'RIGHT', $db->quoteName('#__languages', 'l') . ' ON c2.' - . $db->quoteName($langField) . ' = ' . $db->quoteName('l.lang_code') - ); - - // Use alias field ? - if (!empty($fields['alias'])) - { - $aliasField = explode('.', $fields['alias'])[1]; - - $query->select($db->quoteName('c2.' . $aliasField, 'alias')); - } - - // Use catid field ? - if (!empty($fields['catid'])) + if (!empty($associations)) { - $catField = explode('.', $fields['catid'])[1]; - - $query->join('LEFT', $db->quoteName('#__categories', 'ca') - . ' ON ' . $db->quoteName('c2.' . $catField) . ' = ca.id AND ca.extension = ' . $db->quote($extensionName) - ) - ->select($db->quoteName('ca.alias', 'category')); - } - - // If component item type supports menu type, select the menu type also. - if (!empty($fields['menutype'])) - { - $menutypeField = explode('.', $fields['menutype'])[1]; - - $query->select($db->quoteName('mt.title', 'menutype_title')) + $categoriesExtraSql = (($tablename === '#__categories') ? ' AND c2.extension = ' . $db->quote($extensionName) : ''); + + $query->select($db->quoteName('c2.' . $pk, 'item_id')) + ->select($db->quoteName('c2.' . $titleField, 'item_title')) + ->from($db->quoteName($tablename, 'c')) + ->join('INNER', $db->quoteName('#__associations', 'a') . ' ON a.id = c.' . $db->quoteName($pk) + . ' AND a.context=' . $db->quote($context) + ) + ->join('INNER', $db->quoteName('#__associations', 'a2') . ' ON a.key = a2.key') + ->join('INNER', $db->quoteName($tablename, 'c2') . ' ON a2.id = c2.' . $db->quoteName($pk) . $categoriesExtraSql); + + $query->select($db->quoteName('l.lang_id', 'lang_id')) + ->select($db->quoteName('l.lang_code', 'language')) + ->select($db->quoteName('l.published', 'published')) + ->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) ->join( - 'LEFT', $db->quoteName('#__menu_types', 'mt') . ' ON ' . $db->quoteName('mt.menutype') - . ' = ' . $db->quoteName('c2.' . $menutypeField) + 'RIGHT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('c2.' . $langField) + . ' = ' . $db->quoteName('l.lang_code') ); - } - $query->where('(c.' . $pk . ' = ' . (int) $referenceId . ' OR c.' . $pk . ' IS NULL) AND (c.' - . $langField . ' != ' . $db->quoteName('l.lang_code') . ' OR c.' . $langField . ' IS NULL)' - ); + // Use alias field ? + if (!empty($fields['alias'])) + { + $aliasField = explode('.', $fields['alias'])[1]; + + $query->select($db->quoteName('c2.' . $aliasField, 'alias')); + } + + // Use catid field ? + if (!empty($fields['catid'])) + { + $catField = explode('.', $fields['catid'])[1]; + + $query->join('LEFT', $db->quoteName('#__categories', 'ca') + . ' ON ' . $db->quoteName('c2.' . $catField) . ' = ca.id AND ca.extension = ' . $db->quote($extensionName) + ) + ->select($db->quoteName('ca.alias', 'category')); + } + + // If component item type supports menu type, select the menu type also. + if (!empty($fields['menutype'])) + { + $menutypeField = explode('.', $fields['menutype'])[1]; + + $query->select($db->quoteName('mt.title', 'menutype_title')) + ->join( + 'LEFT', $db->quoteName('#__menu_types', 'mt') . ' ON ' . $db->quoteName('mt.menutype') + . ' = ' . $db->quoteName('c2.' . $menutypeField) + ); + } + + $query->where('(c.' . $pk . ' = ' . (int) $referenceId . ' OR c.' . $pk . ' IS NULL) AND (c.' + . $langField . ' != l.lang_code OR c.' . $langField . ' IS NULL)' + ); - if ($tablename === '#__categories') + if ($tablename === '#__categories') + { + $query->where($db->quoteName('c.extension') . ' = ' . $db->quote($extensionName)); + } + } + else { - $query->where($db->quoteName('c.extension') . ' = ' . $db->quote($extensionName)); + $tmpQuery = $db->getQuery(true); + + $tmpQuery->select($db->quoteName('c.' . $langField)) + ->from($db->quoteName($tablename, 'c')) + ->where($db->quoteName('c.' . $pk) . ' = ' . (int) $referenceId); + + $db->setQuery($tmpQuery); + $ignored = $db->loadResult(); + + $query->select($db->quoteName('l.lang_id', 'lang_id')) + ->select($db->quoteName('l.lang_code', 'language')) + ->select($db->quoteName('l.published', 'published')) + ->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) + ->from($db->quoteName('#__languages', 'l')) + ->where($db->quoteName('l.lang_code') . ' != ' . $db->quote($ignored)); } return $query; From 0bff96db4f169738cc359ff6f5d35491dd2379ca Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Wed, 6 Jun 2018 16:57:58 +0800 Subject: [PATCH 08/15] Create associations by selected languages --- .../Controller/AutoController.php | 53 +++++ .../com_associations/Model/AutoModel.php | 192 ++++++++++++++++++ .../com_associations/tmpl/auto/modal.php | 156 +++++++------- .../Controller/ArticleController.php | 30 --- .../com_content/Model/ArticleModel.php | 177 ---------------- .../src/MVC/Controller/FormController.php | 2 +- 6 files changed, 329 insertions(+), 281 deletions(-) create mode 100644 administrator/components/com_associations/Controller/AutoController.php diff --git a/administrator/components/com_associations/Controller/AutoController.php b/administrator/components/com_associations/Controller/AutoController.php new file mode 100644 index 0000000000..ee84b81f1e --- /dev/null +++ b/administrator/components/com_associations/Controller/AutoController.php @@ -0,0 +1,53 @@ +setMessage(Text::_('')); + + return false; + } + + // Set the model + $model = $this->getModel('Auto', 'Administrator', array()); + + // Preset the redirect + $this->setRedirect(\JRoute::_('index.php?option=com_content&view=articles' . $this->getRedirectToListAppend(), false)); + + return parent::autocreate($model); + } +} \ No newline at end of file diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoModel.php index 406a4ddc6c..8bfc03e523 100644 --- a/administrator/components/com_associations/Model/AutoModel.php +++ b/administrator/components/com_associations/Model/AutoModel.php @@ -14,6 +14,8 @@ use Joomla\CMS\MVC\Model\ListModel; use Joomla\Database\DatabaseQuery; use Joomla\Component\Associations\Administrator\Helper\AssociationsHelper; +use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Table\Table; /** * Methods supporting a list of article records. @@ -55,6 +57,196 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu parent::__construct($config, $factory); } + /** + * Method to automatically create associations of an item in chosen languages. + * + * @param int $itemId Id of current item. + * @param array $cid An array of language ids. + * + * @return boolean Return true on success, false on failure. + * + * @since __DEPLOY_VERSION__ + */ + public function autocreate($itemId, $cid) + { + // Sanitize ids. + $cid = array_unique($cid); + $cid = ArrayHelper::toInteger($cid); + + // Remove any values of zero. + if (array_search(0, $cid, true)) + { + unset($cid[array_search(0, $cid, true)]); + } + + if (empty($cid)) + { + $this->setError(\JText::_('JGLOBAL_NO_ITEM_SELECTED')); + + return false; + } + + // Get associations + $associations = AssociationsHelper::getAssociationList('com_content', 'article', $itemId); + + // Get current user + if (empty($this->user)) + { + $this->user = \JFactory::getUser(); + } + + // Get content table + $contentTable = Table::getInstance('Content', 'Joomla\\CMS\\Table\\'); + + // Get language table + $languageTable = Table::getInstance('Language', 'Joomla\\CMS\\Table\\'); + + while (!empty($cid)) + { + // Pop the first ID off the stack + $pk = array_shift($cid); + + $contentTable->reset(); + $languageTable->reset(); + + if (!$languageTable->load($pk) || !$contentTable->load($itemId)) + { + if ($error = $languageTable->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + elseif ($error = $contentTable->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_ROW_NOT_FOUND' + // Not fatal error + $this->setError(\JText::sprintf('', $pk)); + continue; + } + } + + // Get current language + $langCode = $languageTable->lang_code; + + if (!isset($itemLang)) + { + $itemLang = $contentTable->language; + } + + // If the article doesn't have associations in current language + if (!isset($associations[$langCode])) + { + // Alter the title & alias + $contentTable->title .= ' [' . $langCode . ']'; + $contentTable->alias .= ' [' . $langCode . ']'; + + // Alter the language + $contentTable->language = $langCode; + + // Reset the ID, hits, state. + $contentTable->id = $contentTable->hits = $contentTable->state = 0; + + // @TODO Change category? + + // Get the featured state + $featured = $contentTable->featured; + + // Check the row. + if (!$contentTable->check()) + { + $this->setError($contentTable->getError()); + + return false; + } + + // Store the row. + if (!$contentTable->store()) + { + $this->setError($contentTable->getError()); + + return false; + } + + // Get the new item ID + $newId = $contentTable->getId(); + + // Check if the article was featured and update the #__content_frontpage table + if ($featured == 1) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->insert($db->quoteName('#__content_frontpage')) + ->values($newId . ', 0'); + $db->setQuery($query); + $db->execute(); + } + + // Add new item to associations + $associations[$langCode] = (int) $contentTable->getId(); + } + else + { + $associations[$langCode] = (int) $associations[$langCode]['id']; + } + } + + // Get associations key for edited item + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('key')) + ->from($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote('com_content.item')) + ->where($db->quoteName('id') . ' = ' . (int) $itemId); + $db->setQuery($query); + $oldKey = $db->loadResult(); + + // Deleting old associations for the associated items + $query = $db->getQuery(true) + ->delete($db->quoteName('#__associations')) + ->where('(' . $db->quoteName('context') . ' = ' . $db->quote('.item') . ') AND (' + . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')' + ); + + $db->setQuery($query); + $db->execute(); + + if ($itemLang !== '*') + { + $associations[$itemLang] = (int) $itemId; + } + + // Add new associations + if (count($associations) > 1) + { + // Adding new association for these items + $key = md5(json_encode($associations)); + $query = $db->getQuery(true) + ->insert('#__associations'); + + foreach ($associations as $id) + { + $query->values(((int) $id) . ',' . $db->quote('com_content.item') . ',' . $db->quote($key)); + } + + $db->setQuery($query); + $db->execute(); + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + /** * Method to auto-populate the model state. * diff --git a/administrator/components/com_associations/tmpl/auto/modal.php b/administrator/components/com_associations/tmpl/auto/modal.php index 01b871155d..e48b57c909 100644 --- a/administrator/components/com_associations/tmpl/auto/modal.php +++ b/administrator/components/com_associations/tmpl/auto/modal.php @@ -19,82 +19,92 @@ // @TODO add scripts ?> - -
-
-
- $this)); ?> - - - - - - - - typeFields['menutype'])) : ?> - + + + + + + + items as $i => $item) :?> + + + + + + typeFields['menutype'])) : ?> + + + + + +
- - - - - - - - - + + + + +
+ +
+
+
+ $this)); ?> + + + + + + + - - - - - - - - - - items as $i => $item) :?> - - - - - typeFields['menutype'])) : ?> - + - - -
+ + + + + + +
- pagination->getListFooter(); ?> -
- lang_id); ?> - - published, $i, 'languages.', true); ?> - - escape($item->language); ?> - - item_title)) : ?> - item_title; ?> - typeFields['alias'])) : ?> - - escape($item->alias)); ?> - - - typeFields['catid'])) : ?> -
- escape($item->category); ?> -
- - -
- escape($item->menutype_title); ?> - + +
- - - +
+ pagination->getListFooter(); ?> +
+ lang_id); ?> + + published, $i, 'languages.', true); ?> + + escape($item->language); ?> + + item_title)) : ?> + item_title; ?> + typeFields['alias'])) : ?> + + escape($item->alias)); ?> + + + typeFields['catid'])) : ?> +
+ escape($item->category); ?> +
+ + +
+ escape($item->menutype_title); ?> +
+ + + + + +
- - + + \ No newline at end of file diff --git a/administrator/components/com_content/Controller/ArticleController.php b/administrator/components/com_content/Controller/ArticleController.php index ef82b6a36e..578e30f0f2 100644 --- a/administrator/components/com_content/Controller/ArticleController.php +++ b/administrator/components/com_content/Controller/ArticleController.php @@ -121,36 +121,6 @@ protected function allowEdit($data = array(), $key = 'id') return false; } - /** - * Method to automatically create associated articles. - * - * @param BaseDatabaseModel $model The model of the component being processed. - * - * @return boolean True is successful, false otherwise and internal error is set. - * - * @since __DEPLOY_VERSION__ - */ - public function autocreate($model = null) - { - \JSession::checkToken() or jexit(\JText::_('JINVALID_TOKEN')); - - if (!Associations::isEnabled()) - { - // @TODO Add Error Messages - $this->setMessage(Text::_('')); - - return false; - } - - // Set the model - $model = $this->getModel('Article', 'Administrator', array()); - - // Preset the redirect - $this->setRedirect(\JRoute::_('index.php?option=com_content&view=articles' . $this->getRedirectToListAppend(), false)); - - return parent::autocreate($model); - } - /** * Method to run batch operations. * diff --git a/administrator/components/com_content/Model/ArticleModel.php b/administrator/components/com_content/Model/ArticleModel.php index 8638b477a6..4d986f15c5 100644 --- a/administrator/components/com_content/Model/ArticleModel.php +++ b/administrator/components/com_content/Model/ArticleModel.php @@ -14,7 +14,6 @@ use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; use Joomla\CMS\MVC\Model\AdminModel; -use Joomla\Component\Associations\Administrator\Helper\AssociationsHelper; /** * Item Model for an Article. @@ -47,182 +46,6 @@ class ArticleModel extends AdminModel */ protected $associationsContext = 'com_content.item'; - /** - * Method to automatically create associations of an item in chosen languages. - * - * @param int $itemId Id of current item. - * @param array $cid An array of language ids. - * - * @return boolean Return true on success, false on failure. - * - * @since __DEPLOY_VERSION__ - */ - public function autocreate($itemId, $cid) - { - // Sanitize ids. - $cid = array_unique($cid); - $cid = ArrayHelper::toInteger($cid); - - // Remove any values of zero. - if (array_search(0, $cid, true)) - { - unset($cid[array_search(0, $cid, true)]); - } - - if (empty($cid)) - { - $this->setError(\JText::_('JGLOBAL_NO_ITEM_SELECTED')); - - return false; - } - - // Get associations - $associations = AssociationsHelper::getAssociationList('com_content', 'article', $itemId); - - // Get current user - if (empty($this->user)) - { - $this->user = \JFactory::getUser(); - } - - // Get content table - if (empty($this->table)) - { - $this->table = $this->getTable(); - } - - // Get language table - $languageTable = $this->getTable('Language', 'Joomla\CMS\Table'); - - while (!empty($cid)) - { - // Pop the first ID off the stack - $pk = array_shift($cid); - - $this->table->reset(); - $languageTable->reset(); - - if (!$languageTable->load($pk) || !$this->table->load($itemId)) - { - if ($error = $languageTable->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - elseif ($error = $this->table->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - else - { - // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_ROW_NOT_FOUND' - // Not fatal error - $this->setError(\JText::sprintf('', $pk)); - continue; - } - } - - // Get current language - $lang_code = $languageTable->lang_code; - - // If the article doesn't have associations in current language - if (!isset($associations[$lang_code])) - { - // Alter the title & alias - $this->table->title .= ' [' . $lang_code . ']'; - $this->table->alias .= ' [' . $lang_code . ']'; - - // Alter the language - $this->table->language = $lang_code; - - // Reset the ID, hits, state. - $this->table->id = $this->table->hits = $this->table->state = 0; - - // @TODO Change category? - - // Get the featured state - $featured = $this->table->featured; - - // Check the row. - if (!$this->table->check()) - { - $this->setError($this->table->getError()); - - return false; - } - - // Store the row. - if (!$this->table->store()) - { - $this->setError($this->table->getError()); - - return false; - } - - // Get the new item ID - $newId = $this->table->get('id'); - - // Check if the article was featured and update the #__content_frontpage table - if ($featured == 1) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->insert($db->quoteName('#__content_frontpage')) - ->values($newId . ', 0'); - $db->setQuery($query); - $db->execute(); - } - } - } - - // Get associations key for edited item - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('key')) - ->from($db->quoteName('#__associations')) - ->where($db->quoteName('context') . ' = ' . $db->quote('com_content.item')) - ->where($db->quoteName('id') . ' = ' . (int) $itemId); - $db->setQuery($query); - $oldKey = $db->loadResult(); - - // Deleting old associations for the associated items - $query = $db->getQuery(true) - ->delete($db->quoteName('#__associations')) - ->where('(' . $db->quoteName('context') . ' = ' . $db->quote('.item') . ') AND (' - . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')' - ); - - $db->setQuery($query); - $db->execute(); - - // Add new associations - if (count($associations) > 1) - { - // Adding new association for these items - $key = md5(json_encode($associations)); - $query = $db->getQuery(true) - ->insert('#__associations'); - - foreach ($associations as $data) - { - $query->values(((int) $data['id']) . ',' . $db->quote('com_content.item') . ',' . $db->quote($key)); - } - - $db->setQuery($query); - $db->execute(); - } - - // Clean the cache - $this->cleanCache(); - - return true; - } - /** * Batch copy items to a new category or current. * diff --git a/libraries/src/MVC/Controller/FormController.php b/libraries/src/MVC/Controller/FormController.php index 055a25a1d3..bd4677a8b2 100644 --- a/libraries/src/MVC/Controller/FormController.php +++ b/libraries/src/MVC/Controller/FormController.php @@ -253,7 +253,7 @@ protected function allowSave($data, $key = 'id') public function autocreate($model) { $cid = $this->input->post->get('cid', array(), 'array'); - $itemId = $this->input->post->get('id', array(), 'INT'); + $itemId = $this->input->post->get('id', array(), 'int'); if (!Associations::isEnabled()) { From 3cc0d2a3ad2a1ae3d29df1be94a42f38f61a72b9 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Mon, 11 Jun 2018 00:16:07 +0800 Subject: [PATCH 09/15] Improve sql statements in AutoModel --- .../com_associations/Model/AutoModel.php | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoModel.php index 8bfc03e523..f1629cf618 100644 --- a/administrator/components/com_associations/Model/AutoModel.php +++ b/administrator/components/com_associations/Model/AutoModel.php @@ -310,7 +310,6 @@ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('itemtype'); - $id .= ':' . $this->getState('forcedLanguage'); $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.category_id'); @@ -380,6 +379,15 @@ protected function getListQuery() $context = 'com_categories.item'; } + $tmpQuery = $db->getQuery(true); + + $tmpQuery->select($db->quoteName('c.' . $langField)) + ->from($db->quoteName($tablename, 'c')) + ->where($db->quoteName('c.' . $pk) . ' = ' . (int) $referenceId); + + $db->setQuery($tmpQuery); + $ignored = $db->loadResult(); + if (!empty($associations)) { $categoriesExtraSql = (($tablename === '#__categories') ? ' AND c2.extension = ' . $db->quote($extensionName) : ''); @@ -387,11 +395,13 @@ protected function getListQuery() $query->select($db->quoteName('c2.' . $pk, 'item_id')) ->select($db->quoteName('c2.' . $titleField, 'item_title')) ->from($db->quoteName($tablename, 'c')) - ->join('INNER', $db->quoteName('#__associations', 'a') . ' ON a.id = c.' . $db->quoteName($pk) - . ' AND a.context=' . $db->quote($context) + ->join('INNER', $db->quoteName('#__associations', 'a') . ' ON (a.id = c.' . $db->quoteName($pk) + . ' AND a.context =' . $db->quote($context) . ' AND c.' . $db->quoteName($pk) . ' = ' . (int) $referenceId . ')' ) ->join('INNER', $db->quoteName('#__associations', 'a2') . ' ON a.key = a2.key') - ->join('INNER', $db->quoteName($tablename, 'c2') . ' ON a2.id = c2.' . $db->quoteName($pk) . $categoriesExtraSql); + ->join('INNER', $db->quoteName($tablename, 'c2') . ' ON (a2.id = c2.' . $db->quoteName($pk) . ' AND c2.' . $db->quoteName($pk) + . ' != ' . $db->quote($referenceId) . $categoriesExtraSql . ')' + ); $query->select($db->quoteName('l.lang_id', 'lang_id')) ->select($db->quoteName('l.lang_code', 'language')) @@ -399,9 +409,10 @@ protected function getListQuery() ->select($db->quoteName('l.title', 'language_title')) ->select($db->quoteName('l.image', 'language_image')) ->join( - 'RIGHT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('c2.' . $langField) - . ' = ' . $db->quoteName('l.lang_code') - ); + 'RIGHT', $db->quoteName('#__languages', 'l') . ' ON (' . $db->quoteName('c2.' . $langField) + . ' = ' . $db->quoteName('l.lang_code') . ' AND c.' . $db->quoteName($langField) . ' != l.lang_code)' + ) + ->where('l.lang_code != ' . $db->quote($ignored)); // Use alias field ? if (!empty($fields['alias'])) @@ -434,10 +445,6 @@ protected function getListQuery() ); } - $query->where('(c.' . $pk . ' = ' . (int) $referenceId . ' OR c.' . $pk . ' IS NULL) AND (c.' - . $langField . ' != l.lang_code OR c.' . $langField . ' IS NULL)' - ); - if ($tablename === '#__categories') { $query->where($db->quoteName('c.extension') . ' = ' . $db->quote($extensionName)); @@ -445,15 +452,6 @@ protected function getListQuery() } else { - $tmpQuery = $db->getQuery(true); - - $tmpQuery->select($db->quoteName('c.' . $langField)) - ->from($db->quoteName($tablename, 'c')) - ->where($db->quoteName('c.' . $pk) . ' = ' . (int) $referenceId); - - $db->setQuery($tmpQuery); - $ignored = $db->loadResult(); - $query->select($db->quoteName('l.lang_id', 'lang_id')) ->select($db->quoteName('l.lang_code', 'language')) ->select($db->quoteName('l.published', 'published')) From f98a560a206c24e902427e35be7fa7bbf937ce74 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Tue, 12 Jun 2018 20:15:14 +0800 Subject: [PATCH 10/15] Pop up modal when clicking save buttons in com_article. --- .../com_content/tmpl/article/edit.php | 3 ++ .../com_content/js/admin-article-edit.es6.js | 29 +++++++++++++++++++ media/com_content/js/admin-article-edit.js | 23 +++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 media/com_content/js/admin-article-edit.es6.js create mode 100644 media/com_content/js/admin-article-edit.js diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index 2911b65954..fcde465183 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -10,12 +10,15 @@ defined('_JEXEC') or die; use Joomla\Registry\Registry; +use Joomla\CMS\HTML\HTMLHelper; JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); JHtml::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); JHtml::_('behavior.tabstate'); +HTMLHelper::_('script', 'com_content/admin-article-edit.js', ['relative' => true, 'version' => 'auto']); + $this->configFieldsets = array('editorConfig'); $this->hiddenFieldsets = array('basic-limited'); $this->ignore_fieldsets = array('jmetadata', 'item_associations'); diff --git a/media/com_content/js/admin-article-edit.es6.js b/media/com_content/js/admin-article-edit.es6.js new file mode 100644 index 0000000000..4eed0c2d98 --- /dev/null +++ b/media/com_content/js/admin-article-edit.es6.js @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +import jQuery from 'jquery'; + +(() => { + 'use strict'; + + // Get save buttons + const saveButtons = ['save-group-children-apply', 'save-group-children-save', 'save-group-children-save-new', 'save-group-children-save-copy']; + + document.addEventListener('DOMContentLoaded', () => { + saveButtons.forEach((buttonId) => { + const button = document.getElementById(buttonId); + const task = button.onclick; + button.removeAttribute('onclick'); + button.addEventListener('click', (e) => { + e.preventDefault(); + const assocModal = jQuery('#associationAddAssociations'); + assocModal.modal('show'); + assocModal.on('hidden.bs.modal', () => { + task(); + }); + }); + }); + }); +})(); diff --git a/media/com_content/js/admin-article-edit.js b/media/com_content/js/admin-article-edit.js new file mode 100644 index 0000000000..1fb257c9a8 --- /dev/null +++ b/media/com_content/js/admin-article-edit.js @@ -0,0 +1,23 @@ +(function() { + 'use strict'; + + // Get save buttons + var saveButtons = ['save-group-children-apply', 'save-group-children-save', 'save-group-children-save-new', 'save-group-children-save-copy']; + + document.addEventListener('DOMContentLoaded', function () { + saveButtons.forEach(function(buttonId) { + var button = document.getElementById(buttonId); + var task = button.onclick; + button.removeAttribute('onclick'); + button.addEventListener('click', function(e) { + // e.preventDefault(); + var assocModal = document.getElementById('associationAddAssociations'); + $('#associationAddAssociations').modal('show'); + + $('#associationAddAssociations').on('hidden.bs.modal', function(e) { + task(); + }); + }); + }); + }); +})(); \ No newline at end of file From 815e62827b9e3dec215bbbac9d0f1fc0a27dda35 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Sun, 17 Jun 2018 01:45:36 +0800 Subject: [PATCH 11/15] Popup modal when clicking save. Add new field for remembering. --- .../Controller/AutoController.php | 53 ----- .../com_associations/Model/AutoModel.php | 192 ----------------- .../com_associations/tmpl/auto/modal.php | 16 +- .../Controller/ArticleController.php | 35 +++ .../com_content/Model/ArticleModel.php | 203 ++++++++++++++++++ .../components/com_content/config.xml | 18 ++ .../components/com_content/forms/article.xml | 12 ++ .../com_content/tmpl/article/edit.php | 6 +- .../language/en-GB/en-GB.com_content.ini | 5 + layouts/joomla/edit/auto.php | 21 +- .../src/MVC/Controller/FormController.php | 38 ---- media/com_associations/js/admin-auto-modal.js | 30 +++ media/com_content/js/admin-article-edit.js | 38 +++- 13 files changed, 358 insertions(+), 309 deletions(-) delete mode 100644 administrator/components/com_associations/Controller/AutoController.php create mode 100644 media/com_associations/js/admin-auto-modal.js diff --git a/administrator/components/com_associations/Controller/AutoController.php b/administrator/components/com_associations/Controller/AutoController.php deleted file mode 100644 index ee84b81f1e..0000000000 --- a/administrator/components/com_associations/Controller/AutoController.php +++ /dev/null @@ -1,53 +0,0 @@ -setMessage(Text::_('')); - - return false; - } - - // Set the model - $model = $this->getModel('Auto', 'Administrator', array()); - - // Preset the redirect - $this->setRedirect(\JRoute::_('index.php?option=com_content&view=articles' . $this->getRedirectToListAppend(), false)); - - return parent::autocreate($model); - } -} \ No newline at end of file diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoModel.php index f1629cf618..270b381455 100644 --- a/administrator/components/com_associations/Model/AutoModel.php +++ b/administrator/components/com_associations/Model/AutoModel.php @@ -14,8 +14,6 @@ use Joomla\CMS\MVC\Model\ListModel; use Joomla\Database\DatabaseQuery; use Joomla\Component\Associations\Administrator\Helper\AssociationsHelper; -use Joomla\Utilities\ArrayHelper; -use Joomla\CMS\Table\Table; /** * Methods supporting a list of article records. @@ -57,196 +55,6 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu parent::__construct($config, $factory); } - /** - * Method to automatically create associations of an item in chosen languages. - * - * @param int $itemId Id of current item. - * @param array $cid An array of language ids. - * - * @return boolean Return true on success, false on failure. - * - * @since __DEPLOY_VERSION__ - */ - public function autocreate($itemId, $cid) - { - // Sanitize ids. - $cid = array_unique($cid); - $cid = ArrayHelper::toInteger($cid); - - // Remove any values of zero. - if (array_search(0, $cid, true)) - { - unset($cid[array_search(0, $cid, true)]); - } - - if (empty($cid)) - { - $this->setError(\JText::_('JGLOBAL_NO_ITEM_SELECTED')); - - return false; - } - - // Get associations - $associations = AssociationsHelper::getAssociationList('com_content', 'article', $itemId); - - // Get current user - if (empty($this->user)) - { - $this->user = \JFactory::getUser(); - } - - // Get content table - $contentTable = Table::getInstance('Content', 'Joomla\\CMS\\Table\\'); - - // Get language table - $languageTable = Table::getInstance('Language', 'Joomla\\CMS\\Table\\'); - - while (!empty($cid)) - { - // Pop the first ID off the stack - $pk = array_shift($cid); - - $contentTable->reset(); - $languageTable->reset(); - - if (!$languageTable->load($pk) || !$contentTable->load($itemId)) - { - if ($error = $languageTable->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - elseif ($error = $contentTable->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - else - { - // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_ROW_NOT_FOUND' - // Not fatal error - $this->setError(\JText::sprintf('', $pk)); - continue; - } - } - - // Get current language - $langCode = $languageTable->lang_code; - - if (!isset($itemLang)) - { - $itemLang = $contentTable->language; - } - - // If the article doesn't have associations in current language - if (!isset($associations[$langCode])) - { - // Alter the title & alias - $contentTable->title .= ' [' . $langCode . ']'; - $contentTable->alias .= ' [' . $langCode . ']'; - - // Alter the language - $contentTable->language = $langCode; - - // Reset the ID, hits, state. - $contentTable->id = $contentTable->hits = $contentTable->state = 0; - - // @TODO Change category? - - // Get the featured state - $featured = $contentTable->featured; - - // Check the row. - if (!$contentTable->check()) - { - $this->setError($contentTable->getError()); - - return false; - } - - // Store the row. - if (!$contentTable->store()) - { - $this->setError($contentTable->getError()); - - return false; - } - - // Get the new item ID - $newId = $contentTable->getId(); - - // Check if the article was featured and update the #__content_frontpage table - if ($featured == 1) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->insert($db->quoteName('#__content_frontpage')) - ->values($newId . ', 0'); - $db->setQuery($query); - $db->execute(); - } - - // Add new item to associations - $associations[$langCode] = (int) $contentTable->getId(); - } - else - { - $associations[$langCode] = (int) $associations[$langCode]['id']; - } - } - - // Get associations key for edited item - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('key')) - ->from($db->quoteName('#__associations')) - ->where($db->quoteName('context') . ' = ' . $db->quote('com_content.item')) - ->where($db->quoteName('id') . ' = ' . (int) $itemId); - $db->setQuery($query); - $oldKey = $db->loadResult(); - - // Deleting old associations for the associated items - $query = $db->getQuery(true) - ->delete($db->quoteName('#__associations')) - ->where('(' . $db->quoteName('context') . ' = ' . $db->quote('.item') . ') AND (' - . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')' - ); - - $db->setQuery($query); - $db->execute(); - - if ($itemLang !== '*') - { - $associations[$itemLang] = (int) $itemId; - } - - // Add new associations - if (count($associations) > 1) - { - // Adding new association for these items - $key = md5(json_encode($associations)); - $query = $db->getQuery(true) - ->insert('#__associations'); - - foreach ($associations as $id) - { - $query->values(((int) $id) . ',' . $db->quote('com_content.item') . ',' . $db->quote($key)); - } - - $db->setQuery($query); - $db->execute(); - } - - // Clean the cache - $this->cleanCache(); - - return true; - } - /** * Method to auto-populate the model state. * diff --git a/administrator/components/com_associations/tmpl/auto/modal.php b/administrator/components/com_associations/tmpl/auto/modal.php index e48b57c909..f8824ead32 100644 --- a/administrator/components/com_associations/tmpl/auto/modal.php +++ b/administrator/components/com_associations/tmpl/auto/modal.php @@ -6,24 +6,22 @@ * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ +use Joomla\CMS\HTML\HTMLHelper; defined('_JEXEC') or die; -JHtml::_('jquery.framework'); -JHtml::_('behavior.multiselect'); +HTMLHelper::_('jquery.framework'); +HTMLHelper::_('behavior.multiselect'); +HTMLHelper::_('script', 'com_associations/admin-auto-modal.js', array('version' => 'auto', 'relative' => true)); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $canManageCheckin = JFactory::getUser()->authorise('core.manage', 'com_checkin'); $colSpan = 4; -// @TODO add scripts ?> - - - + +
@@ -98,8 +96,6 @@
- - diff --git a/administrator/components/com_content/Controller/ArticleController.php b/administrator/components/com_content/Controller/ArticleController.php index 578e30f0f2..acc7634a19 100644 --- a/administrator/components/com_content/Controller/ArticleController.php +++ b/administrator/components/com_content/Controller/ArticleController.php @@ -14,6 +14,9 @@ use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\Utilities\ArrayHelper; use Joomla\CMS\MVC\Controller\FormController; +use Joomla\CMS\Language\Associations; +use Joomla\CMS\Language\Text; +use Joomla\CMS\MVC\Model\BaseDatabaseModel; /** * The article controller @@ -143,4 +146,36 @@ public function batch($model = null) return parent::batch($model); } + + /** + * Function that allows child controller access to model data + * after the data has been saved. + * + * @param BaseDatabaseModel $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 1.6 + */ + protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) + { + $itemId = $validData['id']; + $assocLanguages = $this->input->post->get('assocLanguages', '', 'str'); + $langIds = explode(':', $assocLanguages); + + if (Associations::isEnabled()) + { + if ($model->autocreate($itemId, $langIds)) + { + // @TODO Add 'JLIB_APPLICATION_SUCCESS_AUTO_ASSOCIATIONS' + $this->setMessage(Text::_('')); + } + else + { + // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_FAILED' + $this->setMessage(Text::_('')); + } + } + } } diff --git a/administrator/components/com_content/Model/ArticleModel.php b/administrator/components/com_content/Model/ArticleModel.php index 4d986f15c5..8ca2fd2b33 100644 --- a/administrator/components/com_content/Model/ArticleModel.php +++ b/administrator/components/com_content/Model/ArticleModel.php @@ -14,6 +14,9 @@ use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; use Joomla\CMS\MVC\Model\AdminModel; +use Joomla\Component\Associations\Administrator\Helper\AssociationsHelper; +use Joomla\CMS\Table\Table; +use Joomla\CMS\Language\Text; /** * Item Model for an Article. @@ -46,6 +49,206 @@ class ArticleModel extends AdminModel */ protected $associationsContext = 'com_content.item'; + /** + * Method to automatically create associations of an item in chosen languages. + * + * @param int $itemId Id of current item. + * @param array $cid An array of language ids. + * + * @return boolean Return true on success, false on failure. + * + * @since __DEPLOY_VERSION__ + */ + public function autoCreate($itemId, $cid) + { + // Sanitize ids. + $cid = array_unique($cid); + $cid = ArrayHelper::toInteger($cid); + + // Remove any values of zero. + if (array_search(0, $cid, true)) + { + unset($cid[array_search(0, $cid, true)]); + } + + if (empty($cid)) + { + $this->setError(Text::_('JGLOBAL_NO_ITEM_SELECTED')); + + return false; + } + + // Get associations + $associations = AssociationsHelper::getAssociationList('com_content', 'article', $itemId); + + // Get current user + if (empty($this->user)) + { + $this->user = \JFactory::getUser(); + } + + // Get content table + $contentTable = $this->getTable(); + + // Get language table + $languageTable = Table::getInstance('Language', 'Joomla\\CMS\\Table\\'); + + // Set a flag to find whether associations are changed + $assocChanged = false; + + while (!empty($cid)) + { + // Pop the first ID off the stack + $pk = array_shift($cid); + + $contentTable->reset(); + $languageTable->reset(); + + if (!$languageTable->load($pk) || !$contentTable->load($itemId)) + { + if ($error = $languageTable->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + elseif ($error = $contentTable->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_ROW_NOT_FOUND' + // Not fatal error + $this->setError(\JText::sprintf('', $pk)); + continue; + } + } + + // Get current language + $langCode = $languageTable->lang_code; + + if (!isset($itemLang)) + { + $itemLang = $contentTable->language; + } + + // If the article doesn't have associations in current language + if (!isset($associations[$langCode])) + { + // Alter the title & alias + $contentTable->title .= ' [' . $langCode . ']'; + $contentTable->alias .= ' [' . $langCode . ']'; + + // Alter the language + $contentTable->language = $langCode; + + // Reset the ID, hits, state. + $contentTable->id = $contentTable->hits = 0; + + // @TODO set state by "Automatic State" field + $contentTable->state = 1; + + // @TODO Change category? + + // Get the featured state + $featured = $contentTable->featured; + + // Check the row. + if (!$contentTable->check()) + { + $this->setError($contentTable->getError()); + + return false; + } + + // Store the row. + if (!$contentTable->store()) + { + $this->setError($contentTable->getError()); + + return false; + } + + // Get the new item ID + $newId = $contentTable->getId(); + + // Check if the article was featured and update the #__content_frontpage table + if ($featured == 1) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->insert($db->quoteName('#__content_frontpage')) + ->values($newId . ', 0'); + $db->setQuery($query); + $db->execute(); + } + + // Add new item to associations + $associations[$langCode] = (int) $contentTable->getId(); + $assocChanged = true; + } + else + { + $associations[$langCode] = (int) $associations[$langCode]['id']; + } + } + + if ($assocChanged) + { + // Get associations key for edited item + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('key')) + ->from($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote('com_content.item')) + ->where($db->quoteName('id') . ' = ' . (int) $itemId); + $db->setQuery($query); + $oldKey = $db->loadResult(); + + // Deleting old associations for the associated items + $query = $db->getQuery(true) + ->delete($db->quoteName('#__associations')) + ->where('(' . $db->quoteName('context') . ' = ' . $db->quote('com_content.item') . ') AND (' + . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')' + ); + + $db->setQuery($query); + $db->execute(); + + if ($itemLang !== '*') + { + $associations[$itemLang] = (int) $itemId; + } + + // Add new associations + if (count($associations) > 1) + { + // Adding new association for these items + $key = md5(json_encode($associations)); + $query = $db->getQuery(true) + ->insert('#__associations'); + + foreach ($associations as $id) + { + $query->values(((int) $id) . ',' . $db->quote('com_content.item') . ',' . $db->quote($key)); + } + + $db->setQuery($query); + $db->execute(); + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + /** * Batch copy items to a new category or current. * diff --git a/administrator/components/com_content/config.xml b/administrator/components/com_content/config.xml index 60283278e0..8af524eef9 100644 --- a/administrator/components/com_content/config.xml +++ b/administrator/components/com_content/config.xml @@ -1078,4 +1078,22 @@ section="component" /> + +
+ + + + +
diff --git a/administrator/components/com_content/forms/article.xml b/administrator/components/com_content/forms/article.xml index c15e96f726..4b6c70efe9 100644 --- a/administrator/components/com_content/forms/article.xml +++ b/administrator/components/com_content/forms/article.xml @@ -934,6 +934,18 @@ + + + + + + get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; ?> - @@ -102,9 +101,7 @@ loadTemplate('associations'); ?> - - Test - + form->renderField('remember'); ?> loadTemplate('auto'); ?> @@ -128,6 +125,7 @@ +
diff --git a/administrator/language/en-GB/en-GB.com_content.ini b/administrator/language/en-GB/en-GB.com_content.ini index 64c5a7b094..71d56918e9 100644 --- a/administrator/language/en-GB/en-GB.com_content.ini +++ b/administrator/language/en-GB/en-GB.com_content.ini @@ -8,11 +8,13 @@ COM_CONTENT_ARTICLE_CONTENT="Content" COM_CONTENT_ARTICLES_TITLE="Articles" COM_CONTENT_ATTRIBS_ARTICLE_SETTINGS_LABEL="Options" COM_CONTENT_ATTRIBS_FIELDSET_LABEL="Options" +COM_CONTENT_AUTOMATIC_ASSOCIATIONS_LABEL="Automatic Associations" COM_CONTENT_BATCH_OPTIONS="Batch process the selected articles" COM_CONTENT_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved articles. Otherwise, all actions are applied to the selected articles." COM_CONTENT_CHANGE_ARTICLE="Select or Change article" COM_CONTENT_CHANGE_ARTICLE_BUTTON="Select/Change" COM_CONTENT_CONFIG_ARTICLE_SETTINGS_DESC="These settings apply for article layouts unless they are changed for a specific menu item." +COM_CONTENT_CONFIG_AUTOMATIC_ASSOCIATIONS_DESC="These settings apply for Automatic Associations Options, unless they are changed for specific settings." COM_CONTENT_CONFIG_BLOG_SETTINGS_DESC="These settings apply for blog or featured layouts unless they are changed for a specific menu item." COM_CONTENT_CONFIG_BLOG_SETTINGS_LABEL="Blog/Featured Layouts" COM_CONTENT_CONFIG_CATEGORIES_SETTINGS_DESC="These settings apply for Articles Categories Options, unless they are changed by the individual category or menu settings." @@ -57,6 +59,8 @@ COM_CONTENT_FIELD_OPTION_BELOW="Below" COM_CONTENT_FIELD_OPTION_SPLIT="Split" COM_CONTENT_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" COM_CONTENT_FIELD_PUBLISH_UP_LABEL="Start Publishing" +COM_CONTENT_FIELD_REMEMBER_LABEL="Remember Decision" +COM_CONTENT_FIELD_REMEMBER_DESC="Remember user's decision on association languages" COM_CONTENT_FIELD_SELECT_ARTICLE_LABEL="Select Article" COM_CONTENT_FIELD_SHOW_CAT_TAGS_LABEL="Tags" COM_CONTENT_FIELD_SHOW_TAGS_LABEL="Tags" @@ -127,6 +131,7 @@ COM_CONTENT_PUBLISH_DOWN_ASC="Finish Publishing ascending" COM_CONTENT_PUBLISH_DOWN_DESC="Finish Publishing descending" COM_CONTENT_PUBLISH_UP_ASC="Start Publishing ascending" COM_CONTENT_PUBLISH_UP_DESC="Start Publishing descending" +COM_CONTENT_REMEMBER_LABEL="Remember User's Decision" COM_CONTENT_RIGHT="Right" COM_CONTENT_SAVE_SUCCESS="Article saved." COM_CONTENT_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the article to customise the alias." diff --git a/layouts/joomla/edit/auto.php b/layouts/joomla/edit/auto.php index e0e818d373..54158dd976 100644 --- a/layouts/joomla/edit/auto.php +++ b/layouts/joomla/edit/auto.php @@ -7,17 +7,22 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ - defined('JPATH_BASE') or die; + $itemId = $displayData->get('Item')->id; -$modalId = 'Article_auto_associations'; +$modalId = 'associationAddAssociations'; $modalTitle = 'Multilingual Associations'; -$modalUrl = 'index.php?option=com_associations&view=auto&layout=modal&tmpl=component&itemtype=com_content.article&id=' . $itemId; +$modalUrl = 'index.php?option=com_associations&view=auto&layout=modal&tmpl=component&itemtype=com_content.article'; + +if (!is_null($itemId)) +{ + $modalUrl .= '&id=' . $itemId; +} echo \JHtml::_( 'bootstrap.renderModal', - 'ModalSelect' . $modalId, + $modalId, array( 'title' => $modalTitle, 'url' => $modalUrl, @@ -25,7 +30,11 @@ 'width' => '800px', 'bodyHeight' => 70, 'modalWidth' => 80, - 'footer' => '', + 'footer' => '' + . '', ) ); diff --git a/libraries/src/MVC/Controller/FormController.php b/libraries/src/MVC/Controller/FormController.php index bd4677a8b2..747c828277 100644 --- a/libraries/src/MVC/Controller/FormController.php +++ b/libraries/src/MVC/Controller/FormController.php @@ -241,44 +241,6 @@ protected function allowSave($data, $key = 'id') } } - /** - * Method to automatically create associated articles. - * - * @param BaseDatabaseModel $model The model of the component being processed. - * - * @return boolean True is successful, false otherwise and internal error is set. - * - * @since __DEPLOY_VERSION__ - */ - public function autocreate($model) - { - $cid = $this->input->post->get('cid', array(), 'array'); - $itemId = $this->input->post->get('id', array(), 'int'); - - if (!Associations::isEnabled()) - { - // @TODO Add Error Messages - $this->setMessage(Text::_('')); - - return false; - } - - if ($model->autocreate($itemId, $cid)) - { - // @TODO Add 'JLIB_APPLICATION_SUCCESS_AUTO_ASSOCIATIONS' - $this->setMessage(Text::_('')); - - return true; - } - else - { - // @TODO Add 'JLIB_APPLICATION_ERROR_AUTO_ASSOCIATIONS_FAILED' - $this->setMessage(Text::_('')); - - return false; - } - } - /** * Method to run batch operations. * diff --git a/media/com_associations/js/admin-auto-modal.js b/media/com_associations/js/admin-auto-modal.js new file mode 100644 index 0000000000..a2d24fab78 --- /dev/null +++ b/media/com_associations/js/admin-auto-modal.js @@ -0,0 +1,30 @@ +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +(function() { + "use strict"; + + Joomla.gatherCheckedBoxes = function() { + var checkedBoxes = document.querySelectorAll("td.row-selected input[type='checkbox']"); + var values = []; + + checkedBoxes.forEach(function(box) { + values.push(box.value); + }); + + var functionName = 'fillAssocLanguagesField'; + + window.parent[functionName](values); + window.parent['closeModal'](); + }; + + document.addEventListener('DOMContentLoaded', function() { + var applyBtn = document.getElementById('applyBtn'); + applyBtn.addEventListener('click', function(e) { + e.preventDefault(); + Joomla.gatherCheckedBoxes(); + }) + }); +})(); \ No newline at end of file diff --git a/media/com_content/js/admin-article-edit.js b/media/com_content/js/admin-article-edit.js index 1fb257c9a8..eb8f310d2d 100644 --- a/media/com_content/js/admin-article-edit.js +++ b/media/com_content/js/admin-article-edit.js @@ -1,23 +1,49 @@ +/** + * PLEASE DO NOT MODIFY THIS FILE. WORK ON THE ES6 VERSION. + * OTHERWISE YOUR CHANGES WILL BE REPLACED ON THE NEXT BUILD. + **/ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ (function() { 'use strict'; // Get save buttons - var saveButtons = ['save-group-children-apply', 'save-group-children-save', 'save-group-children-save-new', 'save-group-children-save-copy']; + var saveButtons = ['save-group-children-apply', 'save-group-children-save', 'save-group-children-save-new']; document.addEventListener('DOMContentLoaded', function () { saveButtons.forEach(function(buttonId) { var button = document.getElementById(buttonId); var task = button.onclick; + var assocModal = $('#associationAddAssociations'); + button.removeAttribute('onclick'); button.addEventListener('click', function(e) { - // e.preventDefault(); - var assocModal = document.getElementById('associationAddAssociations'); - $('#associationAddAssociations').modal('show'); - - $('#associationAddAssociations').on('hidden.bs.modal', function(e) { + e.preventDefault(); + assocModal.modal('show'); + assocModal.on('hidden.bs.modal', function() { task(); }); }); }); }); + + window.fillAssocLanguagesField = function(languageIds) { + var assocLanguages = document.querySelector("input[name='assocLanguages']"); + + languageIds.forEach(function(languageId, index) { + if (index === 0) { + assocLanguages.value = languageId; + } else { + assocLanguages.value += ':' + languageId; + } + }); + }; + + window.closeModal = function() { + var assocModal = $('#associationAddAssociations'); + assocModal.modal('hide'); + } })(); \ No newline at end of file From 23e5fcbd6fe3d3f3bba3313702bf3059401811f8 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Thu, 5 Jul 2018 04:02:19 +0800 Subject: [PATCH 12/15] Complete strategy of popup modal --- media/com_content/js/admin-article-edit.js | 77 ++++++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/media/com_content/js/admin-article-edit.js b/media/com_content/js/admin-article-edit.js index eb8f310d2d..38eb9bb9e2 100644 --- a/media/com_content/js/admin-article-edit.js +++ b/media/com_content/js/admin-article-edit.js @@ -11,24 +11,75 @@ 'use strict'; // Get save buttons - var saveButtons = ['save-group-children-apply', 'save-group-children-save', 'save-group-children-save-new']; + var saveButtons = ['save-group-children-apply', 'save-group-children-save', 'save-group-children-save-new', 'save-group-children-save-copy']; document.addEventListener('DOMContentLoaded', function () { - saveButtons.forEach(function(buttonId) { + var associationsEditOptions = Joomla.getOptions('system.associations.edit'), formControl = associationsEditOptions.formControl || 'jform', + formControlLanguage = document.getElementById(formControl + '_language'); + var selectedLanguage = formControlLanguage.value; + var modal = document.getElementById('associationAddAssociations'); + + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + if (selectedLanguage !== '*') { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } + + if (formControlLanguage) { + formControlLanguage.addEventListener('change', function(event) { + selectedLanguage = event.target.value; + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + + if (selectedLanguage === '*') { + saveButtons.forEach(function(buttonId) { + var button = document.getElementById(buttonId); + if (button) { + if (!button.onclick) { + button.setAttribute('onclick', button.getAttribute('buttonTask')); + } + } + }); + } else { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } + }); + } + }); + + window.overrideSaveButtons = function(buttons, language) { + var assocModal = $('#associationAddAssociations'); + var modal = document.getElementById('associationAddAssociations'); + var url, substitution; + url = substitution = modal.getAttribute('data-url'); + if (url.search(/&itemLanguage/) !== -1) { + substitution = substitution.replace(/(&itemLanguage=)[\w\-]+$/g, "$1" + language); + } else { + substitution += ('&itemLanguage=' + language); + } + + modal.setAttribute('data-url', substitution); + + var ifram = modal.getAttribute('data-iframe'); + url = url.replace(/&/g, '&'); + substitution = substitution.replace(/&/g, '&'); + modal.setAttribute('data-iframe', ifram.replace(url, substitution)); + + buttons.forEach(function(buttonId) { var button = document.getElementById(buttonId); - var task = button.onclick; - var assocModal = $('#associationAddAssociations'); - - button.removeAttribute('onclick'); - button.addEventListener('click', function(e) { - e.preventDefault(); - assocModal.modal('show'); - assocModal.on('hidden.bs.modal', function() { - task(); + if (button) { + if (button.onclick) { + button.setAttribute('buttonTask', button.onclick); + button.removeAttribute('onclick'); + } + button.addEventListener('click', function() { + assocModal.modal('show'); + assocModal.on('hidden.bs.modal', function() { + var buttonTask = new Function(button.getAttribute('buttonTask') + 'onclick();'); + buttonTask(); + }); }); - }); + } }); - }); + }; window.fillAssocLanguagesField = function(languageIds) { var assocLanguages = document.querySelector("input[name='assocLanguages']"); From 193a278f1c4c5330961cbb64c317dca8b16501b0 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Fri, 6 Jul 2018 13:40:19 +0800 Subject: [PATCH 13/15] Offer an option to remember user's decision --- .../Helper/AssociationsHelper.php | 27 +++++ .../com_associations/tmpl/auto/modal.php | 2 +- .../Controller/ArticleController.php | 5 +- .../com_content/Model/ArticleModel.php | 8 +- .../com_content/tmpl/article/edit.php | 8 +- layouts/joomla/edit/auto.php | 5 +- media/com_associations/js/admin-auto-modal.js | 14 ++- .../com_content/js/admin-article-edit.es6.js | 104 +++++++++++++++--- media/com_content/js/admin-article-edit.js | 14 ++- 9 files changed, 154 insertions(+), 33 deletions(-) diff --git a/administrator/components/com_associations/Helper/AssociationsHelper.php b/administrator/components/com_associations/Helper/AssociationsHelper.php index 1543b90218..3ecb0e170a 100644 --- a/administrator/components/com_associations/Helper/AssociationsHelper.php +++ b/administrator/components/com_associations/Helper/AssociationsHelper.php @@ -12,6 +12,7 @@ use Joomla\CMS\Association\AssociationExtensionInterface; use Joomla\CMS\Association\AssociationServiceInterface; +use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Helper\ContentHelper; use Joomla\CMS\Layout\LayoutHelper; @@ -695,4 +696,30 @@ public static function getLanguagefilterPluginId() return $result; } + + /** + * Store user's decision on associated languages. + * + * @param array $langIds Language ids. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public static function storeDecision($langIds) + { + $decision = implode(':', $langIds); + $params = ComponentHelper::getComponent('com_associations')->getParams(); + $params->set('decision', $decision); + + // Save params in DB + $db = \JFactory::getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__extensions')) + ->set($db->quoteName('params') . ' = ' . $db->quote($params->toString())) + ->where($db->quoteName('name') . ' = ' . $db->quote('com_associations')); + $db->setQuery($query); + + $db->execute(); + } } diff --git a/administrator/components/com_associations/tmpl/auto/modal.php b/administrator/components/com_associations/tmpl/auto/modal.php index f8824ead32..9d87eb989d 100644 --- a/administrator/components/com_associations/tmpl/auto/modal.php +++ b/administrator/components/com_associations/tmpl/auto/modal.php @@ -12,7 +12,7 @@ HTMLHelper::_('jquery.framework'); HTMLHelper::_('behavior.multiselect'); -HTMLHelper::_('script', 'com_associations/admin-auto-modal.js', array('version' => 'auto', 'relative' => true)); +HTMLHelper::_('script', 'com_associations/admin-auto-modal.js', array('relative' => true)); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); diff --git a/administrator/components/com_content/Controller/ArticleController.php b/administrator/components/com_content/Controller/ArticleController.php index acc7634a19..a37156e796 100644 --- a/administrator/components/com_content/Controller/ArticleController.php +++ b/administrator/components/com_content/Controller/ArticleController.php @@ -161,12 +161,13 @@ public function batch($model = null) protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) { $itemId = $validData['id']; - $assocLanguages = $this->input->post->get('assocLanguages', '', 'str'); + $assocLanguages = $this->input->post->get('assocLanguages', '', 'string'); + $decision = (bool) $this->input->post->get('decision', '', 'string'); $langIds = explode(':', $assocLanguages); if (Associations::isEnabled()) { - if ($model->autocreate($itemId, $langIds)) + if ($model->autocreate($itemId, $langIds, $decision)) { // @TODO Add 'JLIB_APPLICATION_SUCCESS_AUTO_ASSOCIATIONS' $this->setMessage(Text::_('')); diff --git a/administrator/components/com_content/Model/ArticleModel.php b/administrator/components/com_content/Model/ArticleModel.php index 8ca2fd2b33..99eefe462a 100644 --- a/administrator/components/com_content/Model/ArticleModel.php +++ b/administrator/components/com_content/Model/ArticleModel.php @@ -59,7 +59,7 @@ class ArticleModel extends AdminModel * * @since __DEPLOY_VERSION__ */ - public function autoCreate($itemId, $cid) + public function autoCreate($itemId, $cid, $remember) { // Sanitize ids. $cid = array_unique($cid); @@ -78,6 +78,12 @@ public function autoCreate($itemId, $cid) return false; } + // Store user's decision + if ($remember) + { + AssociationsHelper::storeDecision($cid); + } + // Get associations $associations = AssociationsHelper::getAssociationList('com_content', 'article', $itemId); diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index 4db87c1793..5a43d63ad2 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -101,8 +101,6 @@ loadTemplate('associations'); ?> - form->renderField('remember'); ?> - loadTemplate('auto'); ?> @@ -116,16 +114,20 @@ canDo->get('core.admin')) : ?> - form->getInput('rules'); ?> + form->getInput('rules'); ?> + loadTemplate('auto'); ?> + + + diff --git a/layouts/joomla/edit/auto.php b/layouts/joomla/edit/auto.php index 54158dd976..9ff52f67d1 100644 --- a/layouts/joomla/edit/auto.php +++ b/layouts/joomla/edit/auto.php @@ -33,8 +33,11 @@ 'footer' => '' + . '' . '', + . 'Create', ) ); diff --git a/media/com_associations/js/admin-auto-modal.js b/media/com_associations/js/admin-auto-modal.js index a2d24fab78..524c271023 100644 --- a/media/com_associations/js/admin-auto-modal.js +++ b/media/com_associations/js/admin-auto-modal.js @@ -6,7 +6,7 @@ (function() { "use strict"; - Joomla.gatherCheckedBoxes = function() { + Joomla.gatherCheckedBoxes = function(remember) { var checkedBoxes = document.querySelectorAll("td.row-selected input[type='checkbox']"); var values = []; @@ -14,17 +14,21 @@ values.push(box.value); }); - var functionName = 'fillAssocLanguagesField'; - - window.parent[functionName](values); + window.parent['fillFields'](values, remember); window.parent['closeModal'](); }; document.addEventListener('DOMContentLoaded', function() { var applyBtn = document.getElementById('applyBtn'); + var rememberBtn = document.getElementById('rememberBtn'); + applyBtn.addEventListener('click', function(e) { e.preventDefault(); - Joomla.gatherCheckedBoxes(); + Joomla.gatherCheckedBoxes(false); + }); + rememberBtn.addEventListener('click', function(e) { + e.preventDefault(); + Joomla.gatherCheckedBoxes(true); }) }); })(); \ No newline at end of file diff --git a/media/com_content/js/admin-article-edit.es6.js b/media/com_content/js/admin-article-edit.es6.js index 4eed0c2d98..81491d332f 100644 --- a/media/com_content/js/admin-article-edit.es6.js +++ b/media/com_content/js/admin-article-edit.es6.js @@ -5,25 +5,99 @@ import jQuery from 'jquery'; -(() => { - 'use strict'; - +((() => { // Get save buttons const saveButtons = ['save-group-children-apply', 'save-group-children-save', 'save-group-children-save-new', 'save-group-children-save-copy']; document.addEventListener('DOMContentLoaded', () => { - saveButtons.forEach((buttonId) => { + const associationsEditOptions = Joomla.getOptions('system.associations.edit'); + const formControl = associationsEditOptions.formControl || 'jform'; + const formControlLanguage = document.getElementById(`${formControl}_language`); + let selectedLanguage = formControlLanguage.value; + + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + if (selectedLanguage !== '*') { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } + + if (formControlLanguage) { + formControlLanguage.addEventListener('change', (event) => { + selectedLanguage = event.target.value; + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + + if (selectedLanguage === '*') { + saveButtons.forEach((buttonId) => { + const button = document.getElementById(buttonId); + if (button) { + if (!button.onclick) { + button.setAttribute('onclick', button.getAttribute('buttonTask')); + } + } + }); + } else { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } + }); + } + }); + + window.overrideSaveButtons = (buttons, language) => { + const assocModal = jQuery('#associationAddAssociations'); + const modal = document.getElementById('associationAddAssociations'); + let url; + let substitution; + url = modal.getAttribute('data-url'); + substitution = url; + if (url.search(/&itemLanguage/) !== -1) { + substitution = substitution.replace(/(&itemLanguage=)[-\w]+$/g, `$1${language}`); + } else { + substitution += (`&itemLanguage=${language}`); + } + + modal.setAttribute('data-url', substitution); + + const ifram = modal.getAttribute('data-iframe'); + url = url.replace(/&/g, '&'); + substitution = substitution.replace(/&/g, '&'); + modal.setAttribute('data-iframe', ifram.replace(url, substitution)); + + buttons.forEach((buttonId) => { const button = document.getElementById(buttonId); - const task = button.onclick; - button.removeAttribute('onclick'); - button.addEventListener('click', (e) => { - e.preventDefault(); - const assocModal = jQuery('#associationAddAssociations'); - assocModal.modal('show'); - assocModal.on('hidden.bs.modal', () => { - task(); + if (button) { + if (button.onclick) { + button.setAttribute('buttonTask', button.onclick); + button.removeAttribute('onclick'); + } + button.addEventListener('click', () => { + assocModal.modal('show'); + assocModal.on('hidden.bs.modal', () => { + const buttonTask = new Function(`${button.getAttribute('buttonTask')}onclick();`); + buttonTask(); + }); }); - }); + } }); - }); -})(); + }; + + window.fillFields = (languageIds, remember) => { + const assocLanguages = document.querySelector("input[name='assocLanguages']"); + const decision = document.querySelector("input[name='decision']"); + languageIds.forEach((languageId, index) => { + if (index === 0) { + assocLanguages.value = languageId; + } else { + assocLanguages.value += `:${languageId}`; + } + }); + if (remember) { + decision.value = 'true'; + } else { + decision.value = ''; + } + }; + + window.closeModal = () => { + const assocModal = jQuery('#associationAddAssociations'); + assocModal.modal('hide'); + }; +}))(); diff --git a/media/com_content/js/admin-article-edit.js b/media/com_content/js/admin-article-edit.js index 38eb9bb9e2..eb50af72cb 100644 --- a/media/com_content/js/admin-article-edit.js +++ b/media/com_content/js/admin-article-edit.js @@ -17,7 +17,6 @@ var associationsEditOptions = Joomla.getOptions('system.associations.edit'), formControl = associationsEditOptions.formControl || 'jform', formControlLanguage = document.getElementById(formControl + '_language'); var selectedLanguage = formControlLanguage.value; - var modal = document.getElementById('associationAddAssociations'); document.querySelector("input[name='itemLanguage']").value = selectedLanguage; if (selectedLanguage !== '*') { @@ -51,7 +50,7 @@ var url, substitution; url = substitution = modal.getAttribute('data-url'); if (url.search(/&itemLanguage/) !== -1) { - substitution = substitution.replace(/(&itemLanguage=)[\w\-]+$/g, "$1" + language); + substitution = substitution.replace(/(&itemLanguage=)[-\w]+$/g, "$1" + language); } else { substitution += ('&itemLanguage=' + language); } @@ -81,9 +80,9 @@ }); }; - window.fillAssocLanguagesField = function(languageIds) { + window.fillFields = function(languageIds, remember) { var assocLanguages = document.querySelector("input[name='assocLanguages']"); - + var decision = document.querySelector("input[name='decision']"); languageIds.forEach(function(languageId, index) { if (index === 0) { assocLanguages.value = languageId; @@ -91,10 +90,15 @@ assocLanguages.value += ':' + languageId; } }); + if (remember) { + decision.value = 'true'; + } else { + decision.value = ''; + } }; window.closeModal = function() { var assocModal = $('#associationAddAssociations'); assocModal.modal('hide'); - } + }; })(); \ No newline at end of file From 37dfe7f798616cce14e396308c2cad326ca932a7 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Sun, 8 Jul 2018 06:40:20 +0800 Subject: [PATCH 14/15] Store and use user's decision --- .../Helper/AssociationsHelper.php | 7 +- .../components/com_associations/config.xml | 23 ++ .../Controller/ArticleController.php | 5 +- .../com_content/Model/ArticleModel.php | 27 +- .../com_content/View/Article/HtmlView.php | 13 + .../components/com_content/config.xml | 18 -- .../components/com_content/forms/article.xml | 305 +++++++++--------- .../com_content/tmpl/article/edit.php | 3 +- .../language/en-GB/en-GB.com_associations.ini | 4 + .../language/en-GB/en-GB.com_content.ini | 2 - .../com_content/js/admin-article-edit.es6.js | 57 ++-- media/com_content/js/admin-article-edit.js | 57 ++-- 12 files changed, 281 insertions(+), 240 deletions(-) diff --git a/administrator/components/com_associations/Helper/AssociationsHelper.php b/administrator/components/com_associations/Helper/AssociationsHelper.php index 3ecb0e170a..4ebcd4b72b 100644 --- a/administrator/components/com_associations/Helper/AssociationsHelper.php +++ b/administrator/components/com_associations/Helper/AssociationsHelper.php @@ -700,17 +700,18 @@ public static function getLanguagefilterPluginId() /** * Store user's decision on associated languages. * - * @param array $langIds Language ids. + * @param array $decision Language ids. * * @return void * * @since __DEPLOY_VERSION__ */ - public static function storeDecision($langIds) + public static function storeDecision($decision) { - $decision = implode(':', $langIds); + $decision = implode(':', $decision); $params = ComponentHelper::getComponent('com_associations')->getParams(); $params->set('decision', $decision); + $params->set('remember', '1'); // Save params in DB $db = \JFactory::getDbo(); diff --git a/administrator/components/com_associations/config.xml b/administrator/components/com_associations/config.xml index 1074b48ec7..a7ce2218a2 100644 --- a/administrator/components/com_associations/config.xml +++ b/administrator/components/com_associations/config.xml @@ -14,4 +14,27 @@ section="component" /> + +
+ + + + + + +
diff --git a/administrator/components/com_content/Controller/ArticleController.php b/administrator/components/com_content/Controller/ArticleController.php index a37156e796..4284ac250f 100644 --- a/administrator/components/com_content/Controller/ArticleController.php +++ b/administrator/components/com_content/Controller/ArticleController.php @@ -162,12 +162,13 @@ protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) { $itemId = $validData['id']; $assocLanguages = $this->input->post->get('assocLanguages', '', 'string'); - $decision = (bool) $this->input->post->get('decision', '', 'string'); + $remember = $this->input->post->get('remember', '0', 'cmd'); + $decision = explode(':', $this->input->post->get('decision', '', 'string')); $langIds = explode(':', $assocLanguages); if (Associations::isEnabled()) { - if ($model->autocreate($itemId, $langIds, $decision)) + if ($model->autocreate($itemId, $langIds, $remember, $decision)) { // @TODO Add 'JLIB_APPLICATION_SUCCESS_AUTO_ASSOCIATIONS' $this->setMessage(Text::_('')); diff --git a/administrator/components/com_content/Model/ArticleModel.php b/administrator/components/com_content/Model/ArticleModel.php index 99eefe462a..6733595961 100644 --- a/administrator/components/com_content/Model/ArticleModel.php +++ b/administrator/components/com_content/Model/ArticleModel.php @@ -52,25 +52,38 @@ class ArticleModel extends AdminModel /** * Method to automatically create associations of an item in chosen languages. * - * @param int $itemId Id of current item. - * @param array $cid An array of language ids. + * @param int $itemId Id of current item. + * @param array $cid An array of language ids. + * @param string $remember Whether to remember user's decision. + * @param array $decision User's decision on associated languages. * * @return boolean Return true on success, false on failure. * * @since __DEPLOY_VERSION__ */ - public function autoCreate($itemId, $cid, $remember) + public function autoCreate($itemId, $cid, $remember, $decision) { // Sanitize ids. $cid = array_unique($cid); $cid = ArrayHelper::toInteger($cid); // Remove any values of zero. - if (array_search(0, $cid, true)) + if (array_search(0, $cid, true) !== false) { unset($cid[array_search(0, $cid, true)]); } + // Store user's decision + if ($remember == '1' && !empty($cid)) + { + AssociationsHelper::storeDecision($cid); + } + elseif ($remember == '1' && !empty($decision)) + { + AssociationsHelper::storeDecision($decision); + $cid = $decision; + } + if (empty($cid)) { $this->setError(Text::_('JGLOBAL_NO_ITEM_SELECTED')); @@ -78,12 +91,6 @@ public function autoCreate($itemId, $cid, $remember) return false; } - // Store user's decision - if ($remember) - { - AssociationsHelper::storeDecision($cid); - } - // Get associations $associations = AssociationsHelper::getAssociationList('com_content', 'article', $itemId); diff --git a/administrator/components/com_content/View/Article/HtmlView.php b/administrator/components/com_content/View/Article/HtmlView.php index 29982c70b0..78bf5b7417 100644 --- a/administrator/components/com_content/View/Article/HtmlView.php +++ b/administrator/components/com_content/View/Article/HtmlView.php @@ -11,6 +11,7 @@ defined('_JEXEC') or die; +use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; @@ -78,6 +79,18 @@ public function display($tpl = null) $this->state = $this->get('State'); $this->canDo = \JHelperContent::getActions('com_content', 'article', $this->item->id); + $params = ComponentHelper::getComponent('com_associations')->getParams(); + $this->set('remember', $params->get('remember', '0', 'cmd')); + + if ($this->get('remember') == '1') + { + $this->set('decision', $params->get('decision')); + } + else + { + $this->set('decision', ''); + } + // Check for errors. if (count($errors = $this->get('Errors'))) { diff --git a/administrator/components/com_content/config.xml b/administrator/components/com_content/config.xml index 8af524eef9..60283278e0 100644 --- a/administrator/components/com_content/config.xml +++ b/administrator/components/com_content/config.xml @@ -1078,22 +1078,4 @@ section="component" /> - -
- - - - -
diff --git a/administrator/components/com_content/forms/article.xml b/administrator/components/com_content/forms/article.xml index 4b6c70efe9..b8f25c2b20 100644 --- a/administrator/components/com_content/forms/article.xml +++ b/administrator/components/com_content/forms/article.xml @@ -1,61 +1,61 @@
- - - - - - - @@ -64,7 +64,7 @@ - - - - - - - - - - - - - - - - JYES - @@ -249,12 +249,12 @@
- @@ -278,7 +278,7 @@ - JHIDE - - -
@@ -586,7 +586,7 @@ label="JGLOBAL_LINKED_TITLES_LABEL" /> - - -
- @@ -724,7 +724,7 @@ type="media" label="COM_CONTENT_FIELD_INTRO_LABEL" /> - + COM_CONTENT_LEFT - - - COM_CONTENT_NONE - - - - - - JGLOBAL_NOINDEX_NOFOLLOW - - -
- - - - - - - diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index 5a43d63ad2..eb689e54b6 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -127,7 +127,8 @@ - + +
diff --git a/administrator/language/en-GB/en-GB.com_associations.ini b/administrator/language/en-GB/en-GB.com_associations.ini index 8cf38050cf..d1cdddd1a0 100644 --- a/administrator/language/en-GB/en-GB.com_associations.ini +++ b/administrator/language/en-GB/en-GB.com_associations.ini @@ -6,6 +6,8 @@ COM_ASSOCIATIONS="Multilingual Associations" COM_ASSOCIATIONS_ADD_NEW_ASSOCIATION="Add new association" COM_ASSOCIATIONS_ASSOCIATED_ITEM="Target" +COM_ASSOCIATIONS_AUTOMATIC_ASSOCIATIONS_LABEL="Automatic Associations" +COM_ASSOCIATIONS_CONFIG_AUTOMATIC_ASSOCIATIONS_DESC="These settings apply for Automatic Associations Options, unless they are changed for specific settings." COM_ASSOCIATIONS_CHANGE_TARGET="Change Target" COM_ASSOCIATIONS_COMPONENT_NOT_SUPPORTED="The extension %s does not support multilingual associations." COM_ASSOCIATIONS_CONFIGURATION="Multilingual Associations: Options" @@ -18,6 +20,8 @@ COM_ASSOCIATIONS_EDIT_ASSOCIATION="Edit association" COM_ASSOCIATIONS_EDIT_HIDE_REFERENCE="Hide Reference" COM_ASSOCIATIONS_EDIT_SHOW_REFERENCE="Show Reference" COM_ASSOCIATIONS_ERROR_NO_ASSOC="The Multilingual Associations component can't be used if the site is not set as multilingual and/or Associations is not enabled in the Language Filter plugin." +COM_ASSOCIATIONS_FIELD_REMEMBER_LABEL="Remember User's Decision" +COM_ASSOCIATIONS_FIELD_REMEMBER_DESC="Remember User's Decision on associated languages." COM_ASSOCIATIONS_FILTER_SEARCH_DESC="Search an item by its title" COM_ASSOCIATIONS_FILTER_SEARCH_LABEL="Search item" COM_ASSOCIATIONS_FILTER_SELECT_ITEM_TYPE="- Select Item Type -" diff --git a/administrator/language/en-GB/en-GB.com_content.ini b/administrator/language/en-GB/en-GB.com_content.ini index 71d56918e9..fa01f397c0 100644 --- a/administrator/language/en-GB/en-GB.com_content.ini +++ b/administrator/language/en-GB/en-GB.com_content.ini @@ -59,8 +59,6 @@ COM_CONTENT_FIELD_OPTION_BELOW="Below" COM_CONTENT_FIELD_OPTION_SPLIT="Split" COM_CONTENT_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" COM_CONTENT_FIELD_PUBLISH_UP_LABEL="Start Publishing" -COM_CONTENT_FIELD_REMEMBER_LABEL="Remember Decision" -COM_CONTENT_FIELD_REMEMBER_DESC="Remember user's decision on association languages" COM_CONTENT_FIELD_SELECT_ARTICLE_LABEL="Select Article" COM_CONTENT_FIELD_SHOW_CAT_TAGS_LABEL="Tags" COM_CONTENT_FIELD_SHOW_TAGS_LABEL="Tags" diff --git a/media/com_content/js/admin-article-edit.es6.js b/media/com_content/js/admin-article-edit.es6.js index 81491d332f..c894e24310 100644 --- a/media/com_content/js/admin-article-edit.es6.js +++ b/media/com_content/js/admin-article-edit.es6.js @@ -14,30 +14,33 @@ import jQuery from 'jquery'; const formControl = associationsEditOptions.formControl || 'jform'; const formControlLanguage = document.getElementById(`${formControl}_language`); let selectedLanguage = formControlLanguage.value; + const remember = document.querySelector("input[name='remember']"); - document.querySelector("input[name='itemLanguage']").value = selectedLanguage; - if (selectedLanguage !== '*') { - window.overrideSaveButtons(saveButtons, selectedLanguage); - } + if (remember.value === '0') { + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + if (selectedLanguage !== '*') { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } - if (formControlLanguage) { - formControlLanguage.addEventListener('change', (event) => { - selectedLanguage = event.target.value; - document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + if (formControlLanguage) { + formControlLanguage.addEventListener('change', (event) => { + selectedLanguage = event.target.value; + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; - if (selectedLanguage === '*') { - saveButtons.forEach((buttonId) => { - const button = document.getElementById(buttonId); - if (button) { - if (!button.onclick) { - button.setAttribute('onclick', button.getAttribute('buttonTask')); + if (selectedLanguage === '*') { + saveButtons.forEach((buttonId) => { + const button = document.getElementById(buttonId); + if (button) { + if (!button.onclick) { + button.setAttribute('onclick', button.getAttribute('buttonTask')); + } } - } - }); - } else { - window.overrideSaveButtons(saveButtons, selectedLanguage); - } - }); + }); + } else { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } + }); + } } }); @@ -79,20 +82,28 @@ import jQuery from 'jquery'; }); }; - window.fillFields = (languageIds, remember) => { + window.fillFields = (languageIds, rememberDecision) => { const assocLanguages = document.querySelector("input[name='assocLanguages']"); + const remember = document.querySelector("input[name='remember']"); const decision = document.querySelector("input[name='decision']"); languageIds.forEach((languageId, index) => { if (index === 0) { assocLanguages.value = languageId; + if (rememberDecision) { + decision.value = languageId; + } } else { assocLanguages.value += `:${languageId}`; + if (rememberDecision) { + decision.value += `:${languageId}`; + } } }); - if (remember) { - decision.value = 'true'; + if (rememberDecision) { + remember.value = '1'; } else { decision.value = ''; + remember.value = '0'; } }; diff --git a/media/com_content/js/admin-article-edit.js b/media/com_content/js/admin-article-edit.js index eb50af72cb..976f4dc7d3 100644 --- a/media/com_content/js/admin-article-edit.js +++ b/media/com_content/js/admin-article-edit.js @@ -17,30 +17,33 @@ var associationsEditOptions = Joomla.getOptions('system.associations.edit'), formControl = associationsEditOptions.formControl || 'jform', formControlLanguage = document.getElementById(formControl + '_language'); var selectedLanguage = formControlLanguage.value; + var remember = document.querySelector("input[name='remember']"); - document.querySelector("input[name='itemLanguage']").value = selectedLanguage; - if (selectedLanguage !== '*') { - window.overrideSaveButtons(saveButtons, selectedLanguage); - } + if (remember.value === '0') { + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + if (selectedLanguage !== '*') { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } - if (formControlLanguage) { - formControlLanguage.addEventListener('change', function(event) { - selectedLanguage = event.target.value; - document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + if (formControlLanguage) { + formControlLanguage.addEventListener('change', function(event) { + selectedLanguage = event.target.value; + document.querySelector("input[name='itemLanguage']").value = selectedLanguage; - if (selectedLanguage === '*') { - saveButtons.forEach(function(buttonId) { - var button = document.getElementById(buttonId); - if (button) { - if (!button.onclick) { - button.setAttribute('onclick', button.getAttribute('buttonTask')); + if (selectedLanguage === '*') { + saveButtons.forEach(function(buttonId) { + var button = document.getElementById(buttonId); + if (button) { + if (!button.onclick) { + button.setAttribute('onclick', button.getAttribute('buttonTask')); + } } - } - }); - } else { - window.overrideSaveButtons(saveButtons, selectedLanguage); - } - }); + }); + } else { + window.overrideSaveButtons(saveButtons, selectedLanguage); + } + }); + } } }); @@ -80,20 +83,28 @@ }); }; - window.fillFields = function(languageIds, remember) { + window.fillFields = function(languageIds, rememberDecision) { var assocLanguages = document.querySelector("input[name='assocLanguages']"); + var remember = document.querySelector("input[name='remember']"); var decision = document.querySelector("input[name='decision']"); languageIds.forEach(function(languageId, index) { if (index === 0) { assocLanguages.value = languageId; + if (rememberDecision) { + decision.value = languageId; + } } else { assocLanguages.value += ':' + languageId; + if (rememberDecision) { + decision.value += ':' + languageId; + } } }); - if (remember) { - decision.value = 'true'; + if (rememberDecision) { + remember.value = '1'; } else { decision.value = ''; + remember.value = '0'; } }; From 4c7562003865b9f655aeb27c3ad1eb19bc3f56d9 Mon Sep 17 00:00:00 2001 From: GraySmog <18949832421@163.com> Date: Tue, 10 Jul 2018 04:38:19 +0800 Subject: [PATCH 15/15] Fix bugs --- .../{AutoModel.php => AutoassocModel.php} | 2 +- .../View/{Auto => Autoassoc}/HtmlView.php | 2 +- .../{filter_auto.xml => filter_autoassoc.xml} | 0 .../tmpl/{auto => autoassoc}/modal.php | 2 +- .../Controller/ArticleController.php | 10 ++-- .../com_content/Model/ArticleModel.php | 51 +++++++++++++------ .../com_content/tmpl/article/edit.php | 2 +- .../{edit_auto.php => edit_autoassoc.php} | 2 +- .../joomla/edit/{auto.php => autoassoc.php} | 2 +- libraries/src/Language/LanguageHelper.php | 31 +++++++++++ ...auto-modal.js => admin-autoassoc-modal.js} | 2 +- media/com_content/js/admin-article-edit.js | 9 ++-- 12 files changed, 86 insertions(+), 29 deletions(-) rename administrator/components/com_associations/Model/{AutoModel.php => AutoassocModel.php} (99%) rename administrator/components/com_associations/View/{Auto => Autoassoc}/HtmlView.php (98%) rename administrator/components/com_associations/forms/{filter_auto.xml => filter_autoassoc.xml} (100%) rename administrator/components/com_associations/tmpl/{auto => autoassoc}/modal.php (97%) rename administrator/components/com_content/tmpl/article/{edit_auto.php => edit_autoassoc.php} (82%) rename layouts/joomla/edit/{auto.php => autoassoc.php} (90%) rename media/com_associations/js/{admin-auto-modal.js => admin-autoassoc-modal.js} (99%) diff --git a/administrator/components/com_associations/Model/AutoModel.php b/administrator/components/com_associations/Model/AutoassocModel.php similarity index 99% rename from administrator/components/com_associations/Model/AutoModel.php rename to administrator/components/com_associations/Model/AutoassocModel.php index 270b381455..40907d3f6d 100644 --- a/administrator/components/com_associations/Model/AutoModel.php +++ b/administrator/components/com_associations/Model/AutoassocModel.php @@ -20,7 +20,7 @@ * * @since __DEPLOY_VERSION__ */ -class AutoModel extends ListModel +class AutoassocModel extends ListModel { /** * Override parent constructor. diff --git a/administrator/components/com_associations/View/Auto/HtmlView.php b/administrator/components/com_associations/View/Autoassoc/HtmlView.php similarity index 98% rename from administrator/components/com_associations/View/Auto/HtmlView.php rename to administrator/components/com_associations/View/Autoassoc/HtmlView.php index f3502e17f1..ceea5ad1a2 100644 --- a/administrator/components/com_associations/View/Auto/HtmlView.php +++ b/administrator/components/com_associations/View/Autoassoc/HtmlView.php @@ -6,7 +6,7 @@ * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\Component\Associations\Administrator\View\Auto; +namespace Joomla\Component\Associations\Administrator\View\Autoassoc; defined('_JEXEC') or die; diff --git a/administrator/components/com_associations/forms/filter_auto.xml b/administrator/components/com_associations/forms/filter_autoassoc.xml similarity index 100% rename from administrator/components/com_associations/forms/filter_auto.xml rename to administrator/components/com_associations/forms/filter_autoassoc.xml diff --git a/administrator/components/com_associations/tmpl/auto/modal.php b/administrator/components/com_associations/tmpl/autoassoc/modal.php similarity index 97% rename from administrator/components/com_associations/tmpl/auto/modal.php rename to administrator/components/com_associations/tmpl/autoassoc/modal.php index 9d87eb989d..89a5b4a907 100644 --- a/administrator/components/com_associations/tmpl/auto/modal.php +++ b/administrator/components/com_associations/tmpl/autoassoc/modal.php @@ -12,7 +12,7 @@ HTMLHelper::_('jquery.framework'); HTMLHelper::_('behavior.multiselect'); -HTMLHelper::_('script', 'com_associations/admin-auto-modal.js', array('relative' => true)); +HTMLHelper::_('script', 'com_associations/admin-autoassoc-modal.js', array('relative' => true)); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); diff --git a/administrator/components/com_content/Controller/ArticleController.php b/administrator/components/com_content/Controller/ArticleController.php index 4284ac250f..e3243001f6 100644 --- a/administrator/components/com_content/Controller/ArticleController.php +++ b/administrator/components/com_content/Controller/ArticleController.php @@ -11,6 +11,7 @@ defined('_JEXEC') or die; +use Joomla\CMS\Language\LanguageHelper; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\Utilities\ArrayHelper; use Joomla\CMS\MVC\Controller\FormController; @@ -161,14 +162,17 @@ public function batch($model = null) protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) { $itemId = $validData['id']; + $itemLanguage = $this->input->post->get('itemLanguage', '*', 'string'); $assocLanguages = $this->input->post->get('assocLanguages', '', 'string'); - $remember = $this->input->post->get('remember', '0', 'cmd'); + $remember = ($this->input->post->get('remember', '0', 'cmd') === '1' ? true : false); $decision = explode(':', $this->input->post->get('decision', '', 'string')); $langIds = explode(':', $assocLanguages); - if (Associations::isEnabled()) + if (Associations::isEnabled() && $itemLanguage !== '*') { - if ($model->autocreate($itemId, $langIds, $remember, $decision)) + $itemLangId = LanguageHelper::getLanguageId($itemLanguage); + + if ($model->autocreate($itemId, $itemLangId, $langIds, $remember, $decision)) { // @TODO Add 'JLIB_APPLICATION_SUCCESS_AUTO_ASSOCIATIONS' $this->setMessage(Text::_('')); diff --git a/administrator/components/com_content/Model/ArticleModel.php b/administrator/components/com_content/Model/ArticleModel.php index 6733595961..e938b3ffc9 100644 --- a/administrator/components/com_content/Model/ArticleModel.php +++ b/administrator/components/com_content/Model/ArticleModel.php @@ -52,39 +52,58 @@ class ArticleModel extends AdminModel /** * Method to automatically create associations of an item in chosen languages. * - * @param int $itemId Id of current item. - * @param array $cid An array of language ids. - * @param string $remember Whether to remember user's decision. - * @param array $decision User's decision on associated languages. + * @param int $itemId Id of current item. + * @param int $itemLangId Language Id of current item. + * @param array $langIds An array of language ids. + * @param bool $remember Whether to remember user's decision. + * @param array $decision User's decision on associated languages. * * @return boolean Return true on success, false on failure. * * @since __DEPLOY_VERSION__ */ - public function autoCreate($itemId, $cid, $remember, $decision) + public function autoCreate($itemId, $itemLangId, $langIds, $remember, $decision) { // Sanitize ids. - $cid = array_unique($cid); - $cid = ArrayHelper::toInteger($cid); + $langIds = array_unique($langIds); + $langIds = ArrayHelper::toInteger($langIds); + $decision = ArrayHelper::toInteger($decision); // Remove any values of zero. - if (array_search(0, $cid, true) !== false) + if (array_search(0, $langIds, true) !== false) { - unset($cid[array_search(0, $cid, true)]); + unset($langIds[array_search(0, $langIds, true)]); } // Store user's decision - if ($remember == '1' && !empty($cid)) + if ($remember && !empty($langIds)) { - AssociationsHelper::storeDecision($cid); + $decision = $langIds; + + if (array_search($itemLangId, $decision, true) === false) + { + $decision[] = $itemLangId; + } + + AssociationsHelper::storeDecision($decision); } - elseif ($remember == '1' && !empty($decision)) + elseif ($remember && !empty($decision)) { + $langIds = $decision; + + if (array_search($itemLangId, $decision, true) === false) + { + $decision[] = $itemLangId; + } + else + { + unset($langIds[array_search($itemLangId, $decision, true)]); + } + AssociationsHelper::storeDecision($decision); - $cid = $decision; } - if (empty($cid)) + if (empty($langIds)) { $this->setError(Text::_('JGLOBAL_NO_ITEM_SELECTED')); @@ -109,10 +128,10 @@ public function autoCreate($itemId, $cid, $remember, $decision) // Set a flag to find whether associations are changed $assocChanged = false; - while (!empty($cid)) + while (!empty($langIds)) { // Pop the first ID off the stack - $pk = array_shift($cid); + $pk = array_shift($langIds); $contentTable->reset(); $languageTable->reset(); diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index eb689e54b6..8c7d44f50e 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -120,7 +120,7 @@ - loadTemplate('auto'); ?> + loadTemplate('autoassoc'); ?> diff --git a/administrator/components/com_content/tmpl/article/edit_auto.php b/administrator/components/com_content/tmpl/article/edit_autoassoc.php similarity index 82% rename from administrator/components/com_content/tmpl/article/edit_auto.php rename to administrator/components/com_content/tmpl/article/edit_autoassoc.php index 09471790f5..46cdec3ed1 100644 --- a/administrator/components/com_content/tmpl/article/edit_auto.php +++ b/administrator/components/com_content/tmpl/article/edit_autoassoc.php @@ -9,4 +9,4 @@ defined('_JEXEC') or die; -echo JLayoutHelper::render('joomla.edit.auto', $this); \ No newline at end of file +echo JLayoutHelper::render('joomla.edit.autoassoc', $this); \ No newline at end of file diff --git a/layouts/joomla/edit/auto.php b/layouts/joomla/edit/autoassoc.php similarity index 90% rename from layouts/joomla/edit/auto.php rename to layouts/joomla/edit/autoassoc.php index 9ff52f67d1..eeb7930d00 100644 --- a/layouts/joomla/edit/auto.php +++ b/layouts/joomla/edit/autoassoc.php @@ -13,7 +13,7 @@ $itemId = $displayData->get('Item')->id; $modalId = 'associationAddAssociations'; $modalTitle = 'Multilingual Associations'; -$modalUrl = 'index.php?option=com_associations&view=auto&layout=modal&tmpl=component&itemtype=com_content.article'; +$modalUrl = 'index.php?option=com_associations&view=autoassoc&layout=modal&tmpl=component&itemtype=com_content.article'; if (!is_null($itemId)) { diff --git a/libraries/src/Language/LanguageHelper.php b/libraries/src/Language/LanguageHelper.php index b6c720dc57..5689ed8fd1 100644 --- a/libraries/src/Language/LanguageHelper.php +++ b/libraries/src/Language/LanguageHelper.php @@ -10,6 +10,7 @@ defined('JPATH_PLATFORM') or die; +use Joomla\CMS\Factory; use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; @@ -609,4 +610,34 @@ public static function parseXMLLanguageFile($path) return $metadata; } + + /** + * Get id of a language. + * + * @param string $langCode Language code. + * + * @return mixed Language id, or false when language code doesn't exists. + * + * @since __DEPLOY_VERSION__ + */ + public static function getLanguageId($langCode) + { + if (self::exists($langCode)) + { + $db = Factory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->quoteName('lang_id')) + ->from($db->quoteName('#__languages')) + ->where($db->quoteName('lang_code') . ' = ' . $db->quote($langCode)); + + $langId = $db->setQuery($query)->loadResult(); + + return $langId; + } + else + { + return false; + } + } } diff --git a/media/com_associations/js/admin-auto-modal.js b/media/com_associations/js/admin-autoassoc-modal.js similarity index 99% rename from media/com_associations/js/admin-auto-modal.js rename to media/com_associations/js/admin-autoassoc-modal.js index 524c271023..9da84322d7 100644 --- a/media/com_associations/js/admin-auto-modal.js +++ b/media/com_associations/js/admin-autoassoc-modal.js @@ -31,4 +31,4 @@ Joomla.gatherCheckedBoxes(true); }) }); -})(); \ No newline at end of file +})(); diff --git a/media/com_content/js/admin-article-edit.js b/media/com_content/js/admin-article-edit.js index 976f4dc7d3..58e790bff3 100644 --- a/media/com_content/js/admin-article-edit.js +++ b/media/com_content/js/admin-article-edit.js @@ -17,10 +17,12 @@ var associationsEditOptions = Joomla.getOptions('system.associations.edit'), formControl = associationsEditOptions.formControl || 'jform', formControlLanguage = document.getElementById(formControl + '_language'); var selectedLanguage = formControlLanguage.value; + var itemLanguage = document.querySelector("input[name='itemLanguage']"); var remember = document.querySelector("input[name='remember']"); + itemLanguage.value = selectedLanguage; + if (remember.value === '0') { - document.querySelector("input[name='itemLanguage']").value = selectedLanguage; if (selectedLanguage !== '*') { window.overrideSaveButtons(saveButtons, selectedLanguage); } @@ -28,7 +30,7 @@ if (formControlLanguage) { formControlLanguage.addEventListener('change', function(event) { selectedLanguage = event.target.value; - document.querySelector("input[name='itemLanguage']").value = selectedLanguage; + itemLanguage.value = selectedLanguage; if (selectedLanguage === '*') { saveButtons.forEach(function(buttonId) { @@ -51,7 +53,8 @@ var assocModal = $('#associationAddAssociations'); var modal = document.getElementById('associationAddAssociations'); var url, substitution; - url = substitution = modal.getAttribute('data-url'); + url = modal.getAttribute('data-url'); + substitution = url; if (url.search(/&itemLanguage/) !== -1) { substitution = substitution.replace(/(&itemLanguage=)[-\w]+$/g, "$1" + language); } else {