Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions administrator/language/en-GB/lib_joomla.ini
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,11 @@ JLIB_HTML_BATCH_MOVE="Move"
JLIB_HTML_BATCH_MOVE_QUESTION="Action to Perform"
JLIB_HTML_BATCH_NO_CATEGORY="- Don't copy or move -"
JLIB_HTML_BATCH_NOCHANGE="- Keep original Access Levels -"
JLIB_HTML_BATCH_TAG_LABEL="Add Tag"
JLIB_HTML_BATCH_TAG_NOCHANGE="- Keep original Tags -"
JLIB_HTML_BATCH_TAG_ADD="Add"
JLIB_HTML_BATCH_TAG_ADDREMOVE_QUESTION="Action to Perform"
JLIB_HTML_BATCH_TAG_MENU_LABEL="Add or remove a Tag"
JLIB_HTML_BATCH_TAG_NO_CHANGE="- Don't add or remove Tags -"
JLIB_HTML_BATCH_TAG_REMOVE="Remove"
JLIB_HTML_BATCH_USER_LABEL="Set User."
JLIB_HTML_BATCH_USER_NOCHANGE="- Keep original User -"
JLIB_HTML_BATCH_USER_NOUSER="No User."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/

(() => {
const onSelect = () => {
const batchTag = document.getElementById('batch-tag-id');
const batchTagAddRemove = document.getElementById('batch-tag-addremove');
let batchSelector;

const onChange = () => {
if (!batchSelector.value
|| (batchSelector.value && parseInt(batchSelector.value, 10) === 0)) {
batchTagAddRemove.classList.add('hidden');
} else {
batchTagAddRemove.classList.remove('hidden');
}
};

if (batchTag) {
batchSelector = batchTag;
}

if (batchTagAddRemove) {
batchTagAddRemove.classList.add('hidden');
}

if (batchTagAddRemove) {
batchSelector.addEventListener('change', onChange);
}

// Cleanup
document.removeEventListener('DOMContentLoaded', onSelect, true);
};

// Document loaded
document.addEventListener('DOMContentLoaded', onSelect, true);

// Joomla updated
document.addEventListener('joomla:updated', onSelect, true);
})();
8 changes: 8 additions & 0 deletions build/media_source/system/joomla.asset.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,14 @@
"defer": true
}
},
{
"name": "joomla.batch-tag-addremove",
"type": "script",
"uri": "layouts/joomla/html/batch/batch-tag-addremove.min.js",
"attributes": {
"defer": true
}
},
{
"name": "webcomponent.field-fancy-select-legacy",
"type": "script",
Expand Down
33 changes: 27 additions & 6 deletions layouts/joomla/html/batch/tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,35 @@

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;

// Create the add/remove tag options.
$options = [
HTMLHelper::_('select.option', 'a', Text::_('JLIB_HTML_BATCH_TAG_ADD')),
HTMLHelper::_('select.option', 'r', Text::_('JLIB_HTML_BATCH_TAG_REMOVE'))
];

/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->useScript('joomla.batch-tag-addremove');

?>
<label id="batch-tag-lbl" for="batch-tag-id">
<?php echo Text::_('JLIB_HTML_BATCH_TAG_LABEL'); ?>
<label id="batch-tag-choose-action-lbl" for="batch-tag-id">
<?php echo Text::_('JLIB_HTML_BATCH_TAG_MENU_LABEL'); ?>
</label>
<select name="batch[tag]" class="form-select" id="batch-tag-id">
<option value=""><?php echo Text::_('JLIB_HTML_BATCH_TAG_NOCHANGE'); ?></option>
<?php echo HTMLHelper::_('select.options', HTMLHelper::_('tag.tags', ['filter.published' => [1]]), 'value', 'text'); ?>
</select>
<div id="batch-tag-choose-action" class="control-group">
<select name="batch[tag]" class="form-select" id="batch-tag-id">
<option value=""><?php echo Text::_('JLIB_HTML_BATCH_TAG_NO_CHANGE'); ?></option>
<?php echo HTMLHelper::_('select.options', HTMLHelper::_('tag.tags', ['filter.published' => [1]]), 'value', 'text'); ?>
</select>
</div>
<div id="batch-tag-addremove" class="control-group radio">
<fieldset id="batch-tag-addremove-id">
<legend>
<?php echo Text::_('JLIB_HTML_BATCH_TAG_ADDREMOVE_QUESTION'); ?>
</legend>
<?php echo HTMLHelper::_('select.radiolist', $options, 'batch[tag_addremove]', '', 'value', 'text', 'a'); ?>
</fieldset>
</div>
9 changes: 7 additions & 2 deletions libraries/src/Helper/TagsHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -817,12 +817,13 @@ public static function getTypes($arrayType = 'objectList', $selectTypes = null,
* @param TableInterface $table Table being processed
* @param array $newTags Array of new tags
* @param boolean $replace Flag indicating if all existing tags should be replaced
* @param boolean $remove Flag indicating if the tags in $newTags should be removed
*
* @return boolean
*
* @since 3.1
*/
public function postStoreProcess(TableInterface $table, $newTags = [], $replace = true)
public function postStoreProcess(TableInterface $table, $newTags = [], $replace = true, $remove = false)
{
if (!empty($table->newTags) && empty($newTags)) {
$newTags = $table->newTags;
Expand Down Expand Up @@ -856,7 +857,11 @@ public function postStoreProcess(TableInterface $table, $newTags = [], $replace
$ucmId = $ucmContentTable->core_content_id;

// Store the tag data if the article data was saved and run related methods.
$result = $result && $this->tagItem($ucmId, $table, $newTags, $replace);
if ($remove) {
$result = $result && $this->unTagItem($ucmId, $table, $newTags);
} else {
$result = $result && $this->tagItem($ucmId, $table, $newTags, $replace);
}
}
}

Expand Down
22 changes: 16 additions & 6 deletions libraries/src/MVC/Model/AdminModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,16 @@ public function batch($commands, $pks, $contexts)

foreach ($this->batch_commands as $identifier => $command) {
if (!empty($commands[$identifier])) {
if (!$this->$command($commands[$identifier], $pks, $contexts)) {
return false;
if ($command === 'batchTag') {
$removeTags = ArrayHelper::getValue($commands, 'tag_addremove', 'a') === 'r';

if (!$this->batchTag($commands[$identifier], $pks, $contexts, $removeTags)) {
return false;
}
} else {
if (!$this->$command($commands[$identifier], $pks, $contexts)) {
return false;
}
}

$done = true;
Expand Down Expand Up @@ -677,15 +685,16 @@ protected function batchMove($value, $pks, $contexts)
/**
* Batch tag a list of item.
*
* @param integer $value The value of the new tag.
* @param array $pks An array of row IDs.
* @param array $contexts An array of item contexts.
* @param integer $value The value of the new tag.
* @param array $pks An array of row IDs.
* @param array $contexts An array of item contexts.
* @param boolean $removeTags Flag indicating whether the tags in $value have to be removed.
*
* @return boolean True if successful, false otherwise and internal error is set.
*
* @since 3.1
*/
protected function batchTag($value, $pks, $contexts)
protected function batchTag($value, $pks, $contexts, $removeTags = false)
{
// Initialize re-usable member properties, and re-usable local variables
$this->initBatch();
Expand All @@ -702,6 +711,7 @@ protected function batchTag($value, $pks, $contexts)
'subject' => $this->table,
'newTags' => $tags,
'replaceTags' => false,
'removeTags' => $removeTags,
]
);

Expand Down
3 changes: 2 additions & 1 deletion plugins/behaviour/taggable/src/Extension/Taggable.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ public function onTableSetNewTags(SetNewTagsEvent $event)
$table = $event['subject'];
$newTags = $event['newTags'];
$replaceTags = $event['replaceTags'];
$removeTags = $event['removeTags'];

// If the tags table doesn't implement the interface bail
if (!($table instanceof TaggableTableInterface)) {
Expand All @@ -248,7 +249,7 @@ public function onTableSetNewTags(SetNewTagsEvent $event)
$tagsHelper = $table->getTagsHelper();
$tagsHelper->typeAlias = $table->getTypeAlias();

if (!$tagsHelper->postStoreProcess($table, $newTags, $replaceTags)) {
if (!$tagsHelper->postStoreProcess($table, $newTags, $replaceTags, $removeTags)) {
throw new RuntimeException($table->getError());
}
}
Expand Down