29
0
mirror of https://github.com/joomla/joomla-cms.git synced 2024-06-17 09:35:35 +00:00

Merge branch '4.2-dev' into upmerge-2022-10-16

# Conflicts:
#	administrator/components/com_tags/src/Table/TagTable.php
#	administrator/language/en-GB/com_tags.ini
This commit is contained in:
Olivier Buisard 2022-10-16 16:37:00 -04:00
commit b55890c87c
36 changed files with 598 additions and 362 deletions

View File

@ -119,8 +119,13 @@ class ContactTable extends Table implements VersionableTableInterface, TaggableT
$table = Table::getInstance('ContactTable', __NAMESPACE__ . '\\', array('dbo' => $this->getDbo()));
if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) {
// Is the existing contact trashed?
$this->setError(Text::_('COM_CONTACT_ERROR_UNIQUE_ALIAS'));
if ($table->published === -2) {
$this->setError(Text::_('COM_CONTACT_ERROR_UNIQUE_ALIAS_TRASHED'));
}
return false;
}

View File

@ -157,7 +157,7 @@ class FilterTable extends Table
$table = new static($this->getDbo());
if ($table->load(array('alias' => $this->alias)) && ($table->filter_id != $this->filter_id || $this->filter_id == 0)) {
$this->setError(Text::_('JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS'));
$this->setError(Text::_('COM_FINDER_FILTER_ERROR_UNIQUE_ALIAS'));
return false;
}

View File

@ -17,107 +17,129 @@
@on-focused="focused"
@keyup.up="openLastActions()"
@keyup.down="openActions()"
@keyup.end="openLastActions()"
@keyup.home="openActions()"
@keydown.up.prevent
@keydown.down.prevent
@keydown.home.prevent
@keydown.end.prevent
/>
<div
v-if="showActions"
ref="actionList"
class="media-browser-actions-list"
role="toolbar"
aria-orientation="vertical"
:aria-label="sprintf('COM_MEDIA_ACTIONS_TOOLBAR_LABEL',(this.$parent.$props.item.name))"
>
<ul>
<li>
<media-browser-action-item-preview
v-if="previewable"
ref="actionPreview"
:on-focused="focused"
:main-action="openPreview"
:closing-action="hideActions"
@keyup.up="$refs.actionDelete.$el.focus()"
@keyup.down="$refs.actionDelete.$el.previousElementSibling.focus()"
@keyup.esc="hideActions"
/>
</li>
<li>
<media-browser-action-item-download
v-if="downloadable"
ref="actionDownload"
:on-focused="focused"
:main-action="download"
:closing-action="hideActions"
@keyup.up="$refs.actionPreview.$el.focus()"
@keyup.down="$refs.actionPreview.$el.previousElementSibling.focus()"
@keyup.esc="hideActions"
/>
</li>
<li>
<media-browser-action-item-rename
v-if="canEdit"
ref="actionRename"
:on-focused="focused"
:main-action="openRenameModal"
:closing-action="hideActions"
@keyup.up="
downloadable
? $refs.actionDownload.$el.focus()
: $refs.actionDownload.$el.previousElementSibling.focus()
"
@keyup.down="
canEdit
? $refs.actionEdit.$el.focus()
: shareable
? $refs.actionShare.$el.focus()
: $refs.actionShare.$el.previousElementSibling.focus()
"
@keyup.esc="hideActions"
/>
</li>
<li>
<media-browser-action-item-edit
v-if="canEdit && canOpenEditView"
ref="actionEdit"
:on-focused="focused"
:main-action="editItem"
:closing-action="hideActions"
@keyup.up="$refs.actionRename.$el.focus()"
@keyup.down="$refs.actionRename.$el.previousElementSibling.focus()"
@keyup.esc="hideActions"
/>
</li>
<li>
<media-browser-action-item-share
v-if="shareable"
ref="actionShare"
:on-focused="focused"
:main-action="openShareUrlModal"
:closing-action="hideActions"
@keyup.up="
canEdit
? $refs.actionEdit.$el.focus()
: $refs.actionEdit.$el.previousElementSibling.focus()
"
@keyup.down="$refs.actionDelete.$el.focus()"
@keyup.esc="hideActions"
/>
</li>
<li>
<media-browser-action-item-delete
v-if="canDelete"
ref="actionDelete"
:on-focused="focused"
:main-action="openConfirmDeleteModal"
:hide-actions="hideActions"
@keyup.up="
shareable
? $refs.actionShare.$el.focus()
: $refs.actionShare.$el.previousElementSibling.focus()
"
@keyup.down="
previewable
? $refs.actionPreview.$el.focus()
: $refs.actionPreview.$el.previousElementSibling.focus()
"
@keyup.esc="hideActions"
/>
</li>
</ul>
<span
aria-hidden="true"
class="media-browser-actions-item-name"
>
<strong>{{ this.$parent.$props.item.name }}</strong>
</span>
<media-browser-action-item-preview
v-if="previewable"
ref="actionPreview"
:on-focused="focused"
:main-action="openPreview"
:closing-action="hideActions"
@keydown.up.prevent
@keydown.down.prevent
@keyup.up="focusPrev"
@keyup.down="focusNext"
@keyup.end="focusLast"
@keyup.home="focusFirst"
@keydown.home.prevent
@keydown.end.prevent
@keyup.esc="hideActions"
@keydown.tab="hideActions"
/>
<media-browser-action-item-download
v-if="downloadable"
ref="actionDownload"
:on-focused="focused"
:main-action="download"
:closing-action="hideActions"
@keydown.up.prevent
@keydown.down.prevent
@keyup.up="focusPrev"
@keyup.down="focusNext"
@keyup.esc="hideActions"
@keydown.tab="hideActions"
@keyup.end="focusLast"
@keyup.home="focusFirst"
@keydown.home.prevent
@keydown.end.prevent
/>
<media-browser-action-item-rename
v-if="canEdit"
ref="actionRename"
:on-focused="focused"
:main-action="openRenameModal"
:closing-action="hideActions"
@keydown.up.prevent
@keydown.down.prevent
@keyup.up="focusPrev"
@keyup.down="focusNext"
@keyup.esc="hideActions"
@keydown.tab="hideActions"
@keyup.end="focusLast"
@keyup.home="focusFirst"
@keydown.home.prevent
@keydown.end.prevent
/>
<media-browser-action-item-edit
v-if="canEdit && canOpenEditView"
ref="actionEdit"
:on-focused="focused"
:main-action="editItem"
:closing-action="hideActions"
@keydown.up.prevent
@keydown.down.prevent
@keyup.up="focusPrev"
@keyup.down="focusNext"
@keyup.esc="hideActions"
@keydown.tab="hideActions"
@keyup.end="focusLast"
@keyup.home="focusFirst"
@keydown.home.prevent
@keydown.end.prevent
/>
<media-browser-action-item-share
v-if="shareable"
ref="actionShare"
:on-focused="focused"
:main-action="openShareUrlModal"
:closing-action="hideActions"
@keydown.up.prevent
@keydown.down.prevent
@keyup.up="focusPrev"
@keyup.down="focusNext"
@keyup.esc="hideActions"
@keydown.tab="hideActions"
@keyup.end="focusLast"
@keyup.home="focusFirst"
@keydown.home.prevent
@keydown.end.prevent
/>
<media-browser-action-item-delete
v-if="canDelete"
ref="actionDelete"
:on-focused="focused"
:main-action="openConfirmDeleteModal"
:hide-actions="hideActions"
@keydown.up.prevent
@keydown.down.prevent
@keyup.up="focusPrev"
@keyup.down="focusNext"
@keyup.esc="hideActions"
@keydown.tab="hideActions"
@keyup.end="focusLast"
@keyup.home="focusFirst"
@keydown.home.prevent
@keydown.end.prevent
/>
</div>
</div>
</template>
@ -170,6 +192,7 @@ export default {
/* Hide actions dropdown */
hideActions() {
this.showActions = false;
this.$parent.$parent.$data.actionsActive = false;
},
/* Preview an item */
openPreview() {
@ -200,19 +223,89 @@ export default {
/* Open actions dropdown */
openActions() {
this.showActions = true;
this.$parent.$parent.$data.actionsActive = true;
const buttons = [...this.$el.parentElement.querySelectorAll('.media-browser-actions-list button')];
if (buttons.length) {
buttons.forEach((button, i) => {
if (i === (0)) {
button.tabIndex = 0;
} else {
button.tabIndex = -1;
}
});
buttons[0].focus();
}
},
/* Open actions dropdown and focus on last element */
openLastActions() {
this.showActions = true;
this.$parent.$parent.$data.actionsActive = true;
const buttons = [...this.$el.parentElement.querySelectorAll('.media-browser-actions-list button')];
if (buttons.length) {
buttons.forEach((button, i) => {
if (i === (buttons.length)) {
button.tabIndex = 0;
} else {
button.tabIndex = -1;
}
});
this.$nextTick(() => buttons[buttons.length - 1].focus());
}
},
/* Focus on the next item or go to the beginning again */
focusNext(event) {
const active = event.target;
const buttons = [...active.parentElement.querySelectorAll('button')];
const lastchild = buttons[buttons.length - 1];
active.tabIndex = -1;
if (active === lastchild) {
buttons[0].focus();
buttons[0].tabIndex = 0;
} else {
active.nextElementSibling.focus();
active.nextElementSibling.tabIndex = 0;
}
},
/* Focus on the previous item or go to the end again */
focusPrev(event) {
const active = event.target;
const buttons = [...active.parentElement.querySelectorAll('button')];
const firstchild = buttons[0];
active.tabIndex = -1;
if (active === firstchild) {
buttons[buttons.length - 1].focus();
buttons[buttons.length - 1].tabIndex = 0;
} else {
active.previousElementSibling.focus();
active.previousElementSibling.tabIndex = 0;
}
},
/* Focus on the first item */
focusFirst(event) {
const active = event.target;
const buttons = [...active.parentElement.querySelectorAll('button')];
buttons[0].focus();
buttons.forEach((button, i) => {
if (i === 0) {
button.tabIndex = 0;
} else {
button.tabIndex = -1;
}
});
},
/* Focus on the last item */
focusLast(event) {
const active = event.target;
const buttons = [...active.parentElement.querySelectorAll('button')];
buttons[buttons.length - 1].focus();
buttons.forEach((button, i) => {
if (i === (buttons.length)) {
button.tabIndex = 0;
} else {
button.tabIndex = -1;
}
});
},
editItem() {
this.edit();
},

View File

@ -2,19 +2,20 @@
<button
type="button"
class="action-delete"
:aria-label="translate('COM_MEDIA_ACTION_DELETE')"
:title="translate('COM_MEDIA_ACTION_DELETE')"
@keyup.enter="openConfirmDeleteModal()"
@keyup.space="openConfirmDeleteModal()"
@focus="focused(true)"
@blur="focused(false)"
@keyup.esc="hideActions()"
@click.stop="openConfirmDeleteModal()"
>
<span
class="image-browser-action icon-trash"
aria-hidden="true"
@click.stop="openConfirmDeleteModal()"
/>
<span class="action-text">
{{ translate('COM_MEDIA_ACTION_DELETE') }}
</span>
</button>
</template>

View File

@ -2,10 +2,9 @@
<button
type="button"
class="action-download"
:aria-label="translate('COM_MEDIA_ACTION_DOWNLOAD')"
:title="translate('COM_MEDIA_ACTION_DOWNLOAD')"
@keyup.enter="download()"
@keyup.space="download()"
@click.stop="download()"
@focus="focused(true)"
@blur="focused(false)"
@keyup.esc="hideActions()"
@ -13,8 +12,10 @@
<span
class="image-browser-action icon-download"
aria-hidden="true"
@click.stop="download()"
/>
<span class="action-text">
{{ translate('COM_MEDIA_ACTION_DOWNLOAD') }}
</span>
</button>
</template>

View File

@ -2,10 +2,9 @@
<button
type="button"
class="action-edit"
:aria-label="translate('COM_MEDIA_ACTION_EDIT')"
:title="translate('COM_MEDIA_ACTION_EDIT')"
@keyup.enter="editItem()"
@keyup.space="editItem()"
@click.stop="editItem()"
@focus="focused(true)"
@blur="focused(false)"
@keyup.esc="hideActions()"
@ -13,8 +12,10 @@
<span
class="image-browser-action icon-pencil-alt"
aria-hidden="true"
@click.stop="editItem()"
/>
<span class="action-text">
{{ translate('COM_MEDIA_ACTION_EDIT') }}
</span>
</button>
</template>

View File

@ -2,8 +2,7 @@
<button
type="button"
class="action-preview"
:aria-label="translate('COM_MEDIA_ACTION_PREVIEW')"
:title="translate('COM_MEDIA_ACTION_PREVIEW')"
@click.stop="openPreview()"
@keyup.enter="openPreview()"
@keyup.space="openPreview()"
@focus="focused(true)"
@ -13,8 +12,10 @@
<span
class="image-browser-action icon-search-plus"
aria-hidden="true"
@click.stop="openPreview()"
/>
<span class="action-text">
{{ translate('COM_MEDIA_ACTION_PREVIEW') }}
</span>
</button>
</template>

View File

@ -3,8 +3,7 @@
ref="actionRenameButton"
type="button"
class="action-rename"
:aria-label="translate('COM_MEDIA_ACTION_RENAME')"
:title="translate('COM_MEDIA_ACTION_RENAME')"
@click.stop="openRenameModal()"
@keyup.enter="openRenameModal()"
@keyup.space="openRenameModal()"
@focus="focused(true)"
@ -12,10 +11,12 @@
@keyup.esc="hideActions()"
>
<span
class="image-browser-action icon-text-width"
class="image-browser-action fa fa-i-cursor"
aria-hidden="true"
@click.stop="openRenameModal()"
/>
<span class="action-text">
{{ translate('COM_MEDIA_ACTION_RENAME') }}
</span>
</button>
</template>

View File

@ -2,8 +2,7 @@
<button
type="button"
class="action-url"
:aria-label="translate('COM_MEDIA_ACTION_SHARE')"
:title="translate('COM_MEDIA_ACTION_SHARE')"
@click.stop="openShareUrlModal()"
@keyup.enter="openShareUrlModal()"
@keyup.space="openShareUrlModal()"
@focus="focused(true)"
@ -13,8 +12,10 @@
<span
class="image-browser-action icon-link"
aria-hidden="true"
@click.stop="openShareUrlModal()"
/>
<span class="action-text">
{{ translate('COM_MEDIA_ACTION_SHARE') }}
</span>
</button>
</template>

View File

@ -2,9 +2,8 @@
<button
type="button"
class="action-toggle"
tabindex="0"
:aria-label="translate('COM_MEDIA_OPEN_ITEM_ACTIONS')"
:title="translate('COM_MEDIA_OPEN_ITEM_ACTIONS')"
:aria-label="sprintf('COM_MEDIA_MANAGE_ITEM', (this.$parent.$props.item.name))"
:title="sprintf('COM_MEDIA_MANAGE_ITEM', (this.$parent.$props.item.name))"
@keyup.enter="openActions()"
@focus="focused(true)"
@blur="focused(false)"

View File

@ -13,6 +13,7 @@ export default {
data() {
return {
hoverActive: false,
actionsActive: false,
};
},
methods: {
@ -87,6 +88,14 @@ export default {
return this.hoverActive;
},
/**
* Whether or not the item is currently active (on hover or via tab)
* @returns {boolean}
*/
hasActions() {
return this.actionsActive;
},
/**
* Turns on the hover class
*/
@ -177,6 +186,7 @@ export default {
'media-browser-item': true,
selected: this.isSelected(),
active: this.isHoverActive(),
actions: this.hasActions(),
},
onClick: this.handleClick,
onMouseover: this.mouseover,

View File

@ -10,6 +10,7 @@ defined('_JEXEC') or die;
use Joomla\CMS\Language\Text;
Text::script('COM_MEDIA_ACTIONS_TOOLBAR_LABEL', true);
Text::script('COM_MEDIA_ACTION_DELETE', true);
Text::script('COM_MEDIA_ACTION_DOWNLOAD', true);
Text::script('COM_MEDIA_ACTION_EDIT', true);
@ -37,6 +38,7 @@ Text::script('COM_MEDIA_FILE_EXISTS_AND_OVERRIDE', true);
Text::script('COM_MEDIA_FOLDER', true);
Text::script('COM_MEDIA_FOLDER_NAME', true);
Text::script('COM_MEDIA_INCREASE_GRID', true);
Text::script('COM_MEDIA_MANAGE_ITEM', true);
Text::script('COM_MEDIA_MEDIA_DATE_CREATED', true);
Text::script('COM_MEDIA_MEDIA_DATE_MODIFIED', true);
Text::script('COM_MEDIA_MEDIA_DIMENSION', true);

View File

@ -173,8 +173,13 @@ class NewsfeedTable extends Table implements VersionableTableInterface, Taggable
$table = Table::getInstance('NewsfeedTable', __NAMESPACE__ . '\\', array('dbo' => $this->_db));
if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) {
// Is the existing newsfeed trashed?
$this->setError(Text::_('COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS'));
if ($table->published === -2) {
$this->setError(Text::_('COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS_TRASHED'));
}
return false;
}

View File

@ -190,12 +190,15 @@ class TagTable extends Nested implements VersionableTableInterface
// Verify that the alias is unique
$table = new static($this->getDbo());
if (
$table->load(array('alias' => $this->alias, 'parent_id' => (int) $this->parent_id))
&& ($table->id != $this->id || $this->id == 0)
) {
if ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) {
// Is the existing tag trashed?
$this->setError(Text::_('COM_TAGS_ERROR_UNIQUE_ALIAS'));
if ($table->published === -2) {
$this->setError(Text::_('COM_TAGS_ERROR_UNIQUE_ALIAS_TRASHED'));
}
return false;
}

View File

@ -115,7 +115,7 @@ if ($this->type == 'font') {
<?php echo HTMLHelper::_('form.token'); ?>
<p><?php echo Text::_('COM_TEMPLATES_HOME_TEXT'); ?></p>
<p>
<a href="https://docs.joomla.org/Special:MyLanguage/J3.x:How_to_use_the_Template_Manager" target="_blank" rel="noopener" class="btn btn-primary btn-lg">
<a href="https://docs.joomla.org/Special:MyLanguage/J4.x:Template_Overrides" target="_blank" rel="noopener" class="btn btn-primary btn-lg">
<?php echo Text::_('COM_TEMPLATES_HOME_BUTTON'); ?>
</a>
</p>

View File

@ -20,136 +20,140 @@ $listDirn = $this->escape($this->state->get('list.direction'));
$loginActions = [];
$actions = [];
// Split the actions table
foreach ($this->actions as $action) :
$name = $action[0];
if (in_array($name, ['core.login.site', 'core.login.admin', 'core.login.offline', 'core.login.api', 'core.admin'])) :
$loginActions[] = $action;
else :
$actions[] = $action;
endif;
endforeach;
?>
<form action="<?php echo Route::_('index.php?option=com_users&view=debuguser&user_id=' . (int) $this->state->get('user_id')); ?>" method="post" name="adminForm" id="adminForm">
<div id="j-main-container" class="j-main-container">
<?php echo LayoutHelper::render('joomla.searchtools.default', array('view' => $this)); ?>
<div class="d-flex flex-wrap">
<?php foreach ($loginActions as $action) :
$name = $action[0];
$check = $this->items[0]->checks[$name];
if ($check === true) :
$class = 'text-success icon-check';
$button = 'btn-success';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_ALLOW');
elseif ($check === false) :
$class = 'text-danger icon-times';
$button = 'btn-danger';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_DENY');
elseif ($check === null) :
$class = 'text-danger icon-minus-circle';
$button = 'btn-warning';
$text = Text::_('COM_USERS_DEBUG_IMPLICIT_DENY');
else :
$class = '';
$button = '';
$text = '';
endif;
?>
<div class="d-inline p-2">
<?php echo Text::_($action[1]); ?>
<span class="<?php echo $class; ?>" aria-hidden="true"></span>
<span class="visually-hidden"><?php echo Text::_($text); ?></span>
<?php if (empty($this->items)) : ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php endforeach; ?>
</div>
<table class="table">
<caption class="visually-hidden">
<?php echo Text::_('COM_USERS_DEBUG_USER_TABLE_CAPTION'); ?>,
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
</caption>
<thead>
<tr>
<th scope="col">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_USERS_HEADING_ASSET_TITLE', 'a.title', $listDirn, $listOrder); ?>
</th>
<th scope="col">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_USERS_HEADING_ASSET_NAME', 'a.name', $listDirn, $listOrder); ?>
</th>
<?php foreach ($actions as $key => $action) : ?>
<th scope="col" class="w-6 text-center">
<?php echo Text::_($action[1]); ?>
</th>
<?php endforeach; ?>
<th scope="col" class="w-6">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_USERS_HEADING_LFT', 'a.lft', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-3">
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $item) :?>
<tr class="row0" scope="row">
<td>
<?php echo $this->escape(Text::_($item->title)); ?>
</td>
<td>
<?php echo LayoutHelper::render('joomla.html.treeprefix', array('level' => $item->level + 1)) . $this->escape($item->name); ?>
</td>
<?php foreach ($actions as $action) : ?>
<?php
$name = $action[0];
$check = $item->checks[$name];
if ($check === true) :
$class = 'text-success icon-check';
$button = 'btn-success';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_ALLOW');
elseif ($check === false) :
$class = 'text-danger icon-times';
$button = 'btn-danger';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_DENY');
elseif ($check === null) :
$class = 'text-danger icon-minus-circle';
$button = 'btn-warning';
$text = Text::_('COM_USERS_DEBUG_IMPLICIT_DENY');
else :
$class = '';
$button = '';
$text = '';
endif;
?>
<td class="text-center">
<span class="<?php echo $class; ?>" aria-hidden="true"></span>
<span class="visually-hidden"> <?php echo $text; ?></span>
</td>
<?php endforeach; ?>
<td>
<?php echo (int) $item->lft; ?>
- <?php echo (int) $item->rgt; ?>
</td>
<td>
<?php echo (int) $item->id; ?>
</td>
</tr>
<?php else : ?>
<?php
// Split the actions table
foreach ($this->actions as $action) :
$name = $action[0];
if (in_array($name, ['core.login.site', 'core.login.admin', 'core.login.offline', 'core.login.api', 'core.admin'])) :
$loginActions[] = $action;
else :
$actions[] = $action;
endif;
endforeach;
?>
<div class="d-flex flex-wrap">
<?php foreach ($loginActions as $action) :
$name = $action[0];
$check = $this->items[0]->checks[$name];
if ($check === true) :
$class = 'text-success icon-check';
$button = 'btn-success';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_ALLOW');
elseif ($check === false) :
$class = 'text-danger icon-times';
$button = 'btn-danger';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_DENY');
elseif ($check === null) :
$class = 'text-danger icon-minus-circle';
$button = 'btn-warning';
$text = Text::_('COM_USERS_DEBUG_IMPLICIT_DENY');
endif;
?>
<div class="d-inline p-2">
<?php echo Text::_($action[1]); ?>
<span class="<?php echo $class; ?>" aria-hidden="true"></span>
<span class="visually-hidden"><?php echo Text::_($text); ?></span>
</div>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="legend">
<span class="text-danger icon-minus-circle" aria-hidden="true"></span>&nbsp;<?php echo Text::_('COM_USERS_DEBUG_IMPLICIT_DENY'); ?>&nbsp;
<span class="text-success icon-check" aria-hidden="true"></span>&nbsp;<?php echo Text::_('COM_USERS_DEBUG_EXPLICIT_ALLOW'); ?>&nbsp;
<span class="text-danger icon-times" aria-hidden="true">&nbsp;</span><?php echo Text::_('COM_USERS_DEBUG_EXPLICIT_DENY'); ?>
</div>
<table class="table">
<caption class="visually-hidden">
<?php echo Text::_('COM_USERS_DEBUG_USER_TABLE_CAPTION'); ?>,
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
</caption>
<thead>
<tr>
<th scope="col">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_USERS_HEADING_ASSET_TITLE', 'a.title', $listDirn, $listOrder); ?>
</th>
<th scope="col">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_USERS_HEADING_ASSET_NAME', 'a.name', $listDirn, $listOrder); ?>
</th>
<?php foreach ($actions as $key => $action) : ?>
<th scope="col" class="w-6 text-center">
<?php echo Text::_($action[1]); ?>
</th>
<?php endforeach; ?>
<th scope="col" class="w-6">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_USERS_HEADING_LFT', 'a.lft', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-3">
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $item) :?>
<tr class="row0" scope="row">
<td>
<?php echo $this->escape(Text::_($item->title)); ?>
</td>
<td>
<?php echo LayoutHelper::render('joomla.html.treeprefix', array('level' => $item->level + 1)) . $this->escape($item->name); ?>
</td>
<?php foreach ($actions as $action) : ?>
<?php
$name = $action[0];
$check = $item->checks[$name];
if ($check === true) :
$class = 'text-success icon-check';
$button = 'btn-success';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_ALLOW');
elseif ($check === false) :
$class = 'text-danger icon-times';
$button = 'btn-danger';
$text = Text::_('COM_USERS_DEBUG_EXPLICIT_DENY');
elseif ($check === null) :
$class = 'text-danger icon-minus-circle';
$button = 'btn-warning';
$text = Text::_('COM_USERS_DEBUG_IMPLICIT_DENY');
else :
$class = '';
$button = '';
$text = '';
endif;
?>
<td class="text-center">
<span class="<?php echo $class; ?>" aria-hidden="true"></span>
<span class="visually-hidden"> <?php echo $text; ?></span>
</td>
<?php endforeach; ?>
<td>
<?php echo (int) $item->lft; ?>
- <?php echo (int) $item->rgt; ?>
</td>
<td>
<?php echo (int) $item->id; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php // load the pagination. ?>
<?php echo $this->pagination->getListFooter(); ?>
<div class="legend">
<span class="text-danger icon-minus-circle" aria-hidden="true"></span>&nbsp;<?php echo Text::_('COM_USERS_DEBUG_IMPLICIT_DENY'); ?>&nbsp;
<span class="text-success icon-check" aria-hidden="true"></span>&nbsp;<?php echo Text::_('COM_USERS_DEBUG_EXPLICIT_ALLOW'); ?>&nbsp;
<span class="text-danger icon-times" aria-hidden="true">&nbsp;</span><?php echo Text::_('COM_USERS_DEBUG_EXPLICIT_DENY'); ?>
</div>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?php echo HTMLHelper::_('form.token'); ?>
<?php // load the pagination. ?>
<?php echo $this->pagination->getListFooter(); ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?php echo HTMLHelper::_('form.token'); ?>
<?php endif; ?>
</div>
</form>

View File

@ -20,7 +20,8 @@ COM_CONTACT_EMPTYSTATE_BUTTON_ADD="Add your first contact"
COM_CONTACT_EMPTYSTATE_CONTENT="Contacts can be as simple as a contact form or as complex as a staff directory. You can use this component to create and manage your contacts."
COM_CONTACT_EMPTYSTATE_TITLE="No Contacts have been created yet."
COM_CONTACT_ERROR_ALL_LANGUAGE_ASSOCIATED="A contact item set to All languages can't be associated. Associations have not been set."
COM_CONTACT_ERROR_UNIQUE_ALIAS="Another Contact from this category has the same alias (remember it may be a trashed item)."
COM_CONTACT_ERROR_UNIQUE_ALIAS="Another Contact in this category has the same alias."
COM_CONTACT_ERROR_UNIQUE_ALIAS_TRASHED="A trashed Contact in this category has the same alias."
COM_CONTACT_FIELD_ARTICLES_DISPLAY_NUM_LABEL="# Articles to List"
COM_CONTACT_FIELD_ARTICLES_SHOW_LABEL="User Articles"
COM_CONTACT_FIELD_CAPTCHA_LABEL="Allow Captcha on Contact"

View File

@ -44,6 +44,8 @@ COM_CONTENT_ERROR_CANNOT_ARCHIVE="One or more of the selected articles can't be
COM_CONTENT_ERROR_CANNOT_PUBLISH="One or more of the selected articles can't be set to published."
COM_CONTENT_ERROR_CANNOT_TRASH="One or more of the selected articles can't be set to trashed."
COM_CONTENT_ERROR_CANNOT_UNPUBLISH="One or more of the selected articles can't be set to unpublished."
COM_CONTENT_ERROR_UNIQUE_ALIAS="Another Article in this category has the same alias."
COM_CONTENT_ERROR_UNIQUE_ALIAS_TRASHED="A trashed Article in this category has the same alias."
COM_CONTENT_ERROR_UPDATE_STAGE="You cannot execute this transition and update the stage."
COM_CONTENT_FEATURED_ARTICLES="Featured Articles"
COM_CONTENT_FEATURED_CATEGORIES_LABEL="Select Categories"

View File

@ -75,6 +75,7 @@ COM_FINDER_FIELDSET_SEARCH_OPTIONS_LABEL="Smart Search"
COM_FINDER_FILTER_BRANCH_LABEL="Search by %s"
COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE="Smart Search: Edit Filter"
COM_FINDER_FILTER_END_DATE_LABEL="End Date"
COM_FINDER_FILTER_ERROR_UNIQUE_ALIAS="Another Filter has the same alias."
COM_FINDER_FILTER_FIELDSET_PARAMS="Filter Timeline"
COM_FINDER_FILTER_FORM_TITLE_EDIT="Edit Filter"
COM_FINDER_FILTER_FORM_TITLE_NEW="New Filter"

View File

@ -4,12 +4,13 @@
; Note : All ini files need to be saved as UTF-8
COM_MEDIA="Media"
COM_MEDIA_ACTION_DELETE="Delete item"
COM_MEDIA_ACTION_DOWNLOAD="Download item"
COM_MEDIA_ACTION_EDIT="Edit item"
COM_MEDIA_ACTION_PREVIEW="Preview item"
COM_MEDIA_ACTION_RENAME="Rename item"
COM_MEDIA_ACTION_SHARE="Get a shareable link"
COM_MEDIA_ACTIONS_TOOLBAR_LABEL="Item: %s"
COM_MEDIA_ACTION_DELETE="Delete"
COM_MEDIA_ACTION_DOWNLOAD="Download"
COM_MEDIA_ACTION_EDIT="Edit"
COM_MEDIA_ACTION_PREVIEW="Preview"
COM_MEDIA_ACTION_RENAME="Rename"
COM_MEDIA_ACTION_SHARE="Get Link"
COM_MEDIA_BREADCRUMB_LABEL="Breadcrumb"
COM_MEDIA_BROWSER_TABLE_CAPTION="Contents of Directory %s"
COM_MEDIA_CONFIGURATION="Media: Options"
@ -69,6 +70,7 @@ COM_MEDIA_FOLDER="Folder"
COM_MEDIA_FOLDERS="Media Folders"
COM_MEDIA_FOLDER_NAME="Folder Name"
COM_MEDIA_INCREASE_GRID="Increase grid size"
COM_MEDIA_MANAGE_ITEM="Manage item: %s"
COM_MEDIA_MEDIA_DATE_CREATED="Date Created"
COM_MEDIA_MEDIA_DATE_MODIFIED="Date Modified"
COM_MEDIA_MEDIA_DIMENSION="Dimensions"
@ -78,6 +80,8 @@ COM_MEDIA_MEDIA_NAME="Name"
COM_MEDIA_MEDIA_SIZE="Size"
COM_MEDIA_MEDIA_TYPE="Type"
COM_MEDIA_NAME="Name"
; The string COM_MEDIA_OPEN_ITEM_ACTIONS is deprecated and no longer in use as of __DEPLOY_VERSION__
; Please use the string COM_MEDIA_MANAGE_ITEM (with the file name) instead.
COM_MEDIA_OPEN_ITEM_ACTIONS="Open item actions"
COM_MEDIA_PLEASE_SELECT_ITEM="Please select item."
COM_MEDIA_RENAME="Rename"

View File

@ -17,7 +17,8 @@ COM_NEWSFEEDS_EMPTYSTATE_BUTTON_ADD="Add your first news feed"
COM_NEWSFEEDS_EMPTYSTATE_CONTENT="Adding News Feeds to your sites is a way of integrating content from other web sites."
COM_NEWSFEEDS_EMPTYSTATE_TITLE="No News Feeds have been created yet."
COM_NEWSFEEDS_ERROR_ALL_LANGUAGE_ASSOCIATED="A news feed item set to All languages can't be associated. Associations have not been set."
COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS="Another News feed from this category has the same alias (remember it may be a trashed item)."
COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS="Another News feed from this category has the same alias."
COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS_TRASHED="A trashed News feed in this category has the same alias."
COM_NEWSFEEDS_FIELD_CACHETIME_LABEL="Cache Time"
COM_NEWSFEEDS_FIELD_CHARACTER_COUNT_DESC="0 will show all the text."
COM_NEWSFEEDS_FIELD_CHARACTER_COUNT_LABEL="Characters Count"

View File

@ -37,7 +37,8 @@ COM_TAGS_COUNT_UNPUBLISHED_ITEMS="Unpublished items"
COM_TAGS_EMPTYSTATE_BUTTON_ADD="Add your first tag"
COM_TAGS_EMPTYSTATE_CONTENT="Tags in Joomla! provide a flexible way of organizing content. The same tag can be applied to many different content items across content types."
COM_TAGS_EMPTYSTATE_TITLE="No Tags have been created yet."
COM_TAGS_ERROR_UNIQUE_ALIAS="Another Tag with the same parent tag has the same alias (remember it may be a trashed item)."
COM_TAGS_ERROR_UNIQUE_ALIAS="Another Tag has the same alias."
COM_TAGS_ERROR_UNIQUE_ALIAS_TRASHED="A trashed Tag has the same alias."
COM_TAGS_EXCLUDE="Exclude"
COM_TAGS_FIELD_CONTENT_TYPE_LABEL="Content types"
COM_TAGS_FIELD_FULL_LABEL="Full Image"
@ -98,7 +99,7 @@ COM_TAGS_N_ITEMS_UNPUBLISHED_1="Tag unpublished."
COM_TAGS_N_QUICKICON="Tags"
COM_TAGS_N_QUICKICON_0="Tags"
COM_TAGS_N_QUICKICON_1="Tag"
COM_TAGS_N_QUICKICON_SRONLY="Tags: %d tags are published."
COM_TAGS_N_QUICKICON_SRONLY="Tags: %s tags are published."
COM_TAGS_N_QUICKICON_SRONLY_0="Tags: No tag is published."
COM_TAGS_N_QUICKICON_SRONLY_1="Tags: One tag is published."
COM_TAGS_NONE="None"

View File

@ -111,7 +111,8 @@ JLIB_DATABASE_ERROR_ADAPTER_MYSQLI="The MySQL adapter 'mysqli' is not available.
JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS="Another article from this category has the same alias (remember it may be a trashed item)."
JLIB_DATABASE_ERROR_BIND_FAILED_INVALID_SOURCE_ARGUMENT="%s: :bind failed. Invalid source argument."
JLIB_DATABASE_ERROR_CATEGORY_REQUIRED="Category is required."
JLIB_DATABASE_ERROR_CATEGORY_UNIQUE_ALIAS="Another category with the same parent category has the same alias (remember it may be a trashed item)."
JLIB_DATABASE_ERROR_CATEGORY_UNIQUE_ALIAS="Another category with the same parent category has the same alias."
JLIB_DATABASE_ERROR_CATEGORY_UNIQUE_ALIAS_TRASHED="A trashed category with the same parent category has the same alias."
JLIB_DATABASE_ERROR_CHECK_FAILED="%s: :check Failed - %s"
JLIB_DATABASE_ERROR_CHECKIN_FAILED="%s: :check-in failed - %s"
JLIB_DATABASE_ERROR_CHECKOUT_FAILED="%s: :check-out failed - %s"
@ -149,8 +150,9 @@ JLIB_DATABASE_ERROR_MENU_HOME_NOT_COMPONENT="The home menu item must be a compon
JLIB_DATABASE_ERROR_MENU_HOME_NOT_UNIQUE_IN_MENU="A menu should have only one Default home."
JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_COMPONENT="A first level menu item alias can't be 'component'."
JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_FOLDER="A first level menu item alias can't be '%s' because '%s' is a sub-folder of your Joomla installation folder."
JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS="The alias <strong>%1$s</strong> is already being used by <strong>%2$s</strong> menu item in the <strong>%3$s</strong> menu (remember it may be a trashed item)."
JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS="The alias <a href=\"%4$s\" class=\"alert-link\"><strong>%1$s</strong></a> is already being used by the <strong>%2$s</strong> menu item in the <strong>%3$s</strong> menu."
JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS_ROOT="Another menu item has the same alias in Root (remember it may be a trashed item). Root is the top level parent."
JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS_TRASHED="The alias <a href=\"%4$s\" class=\"alert-link\"><strong>%1$s</strong></a> is already being used by the trashed <strong>%2$s</strong> menu item in the <strong>%3$s</strong> menu."
JLIB_DATABASE_ERROR_MENU_UNPUBLISH_DEFAULT_HOME="Can't unpublish default home."
JLIB_DATABASE_ERROR_MENUTYPE="Some menu items or some menu modules related to this menutype are checked out by another user or the default menu item is in this menu."
JLIB_DATABASE_ERROR_MENUTYPE_CHECKOUT="The user checking out does not match the user who checked out this menu and/or its linked menu module."

View File

@ -44,10 +44,10 @@ $grid-item-icon-color-hover: rgba(0,0,0,.8);
$grid-item-icon-bg-color-hover: #fff;
$grid-item-icon-warning-icon-bg: #d9534f;
$grid-item-no-preview-bg: #f5f5f5;
$grid-item-width-sm: 12.5%;
$grid-item-width-md: 16.666%;
$grid-item-width-lg: 25%;
$grid-item-width-xl: 50%;
$grid-item-width-sm: 13%;
$grid-item-width-md: 18%;
$grid-item-width-lg: 26%;
$grid-item-width-xl: 40%;
// Media Browser Table
$table-item-height: 30px;

View File

@ -8,32 +8,30 @@
// Grid View
.media-browser-grid {
padding: $grid-outside-padding 0 $grid-outside-padding $grid-outside-padding;
padding: $grid-outside-padding;
}
.media-browser-items {
display: flex;
flex-wrap: wrap;
display: grid;
gap: $grid-gutter-width;
&.media-browser-items-sm {
grid-template-columns: repeat(auto-fill, minmax($grid-item-width-sm, 1fr));
}
&.media-browser-items-md {
grid-template-columns: repeat(auto-fill, minmax($grid-item-width-md, 1fr));
}
&.media-browser-items-lg {
grid-template-columns: repeat(auto-fill, minmax($grid-item-width-lg, 1fr));
}
&.media-browser-items-xl {
grid-template-columns: repeat(auto-fill, minmax($grid-item-width-xl, 1fr));
}
}
.media-browser-item {
position: relative;
margin-right: $grid-gutter-width;
margin-bottom: $grid-gutter-width;
cursor: pointer;
user-select: none;
.media-browser-items-sm & {
width: calc(#{$grid-item-width-sm} - #{$grid-gutter-width});
}
.media-browser-items-md & {
width: calc(#{$grid-item-width-md} - #{$grid-gutter-width});
}
.media-browser-items-lg & {
width: calc(#{$grid-item-width-lg} - #{$grid-gutter-width});
}
.media-browser-items-xl & {
width: calc(#{$grid-item-width-xl} - #{$grid-gutter-width});
}
}
.media-browser-item-preview {
@ -125,27 +123,48 @@
}
}
&.active {
top: 0;
z-index: 1;
width: max-content;
min-width: 100%;
background-color: var(--template-bg-dark-3);
border: 1px solid hsl(var(--hue), 35%, 95%);
border-radius: .25rem;
box-shadow: 0 2px 10px -8px var(--template-bg-dark-50);
> button {
display: none;
}
}
ul {
padding: 0;
margin: 0;
list-style: none;
column-gap: 5px;
columns: 2;
@media (max-width: 576px) {
.actions & {
height: 100%;
overflow: visible;
.media-browser-actions-list {
position: absolute;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: var(--template-bg-dark-3);
}
}
}
}
}
.media-browser-actions-list {
display: flex;
flex-direction: column;
margin-top: 2px;
.media-browser-actions-item-name {
padding: 2px;
margin-block-end: 3px;
}
button, a {
position: relative;
top: 0;
padding: 0;
margin-bottom: 3px;
padding: 2px;
margin-block-end: 3px;
visibility: hidden;
background-color: transparent;
border: 0;
@ -154,20 +173,18 @@
transition-delay: 0s;
.media-browser-actions.active & {
top: 0;
display: flex;
align-items: center;
width: 100%;
visibility: visible;
opacity: 1;
transition-duration: .2s;
&:first-of-type {
transition-delay: .1s;
}
&:nth-of-type(2) {
transition-delay: .15s;
}
&:nth-of-type(3) {
transition-delay: .2s;
}
&:nth-of-type(4) {
transition-delay: .25s;
&:hover, &:focus {
background-color: var(--template-bg-dark-10);
&.action-delete {
color: $grid-item-icon-color;
background-color: $grid-item-icon-warning-icon-bg;
}
}
}
}
@ -176,13 +193,14 @@
.image-browser-action {
width: calc(#{$grid-item-icon-size} * 1.55);
height: calc(#{$grid-item-icon-size} * 1.55);
margin-right: 4px;
margin-left: 4px;
margin-inline: 4px;
color: $grid-item-icon-color;
text-align: center;
cursor: pointer;
background-color: $grid-item-icon-bg-color;
border-radius: $grid-item-border-radius;
flex-shrink: 0;
transition-duration: .2s;
.action-delete & {
background-color: $grid-item-icon-warning-icon-bg;
}
@ -190,11 +208,18 @@
font-size: $grid-item-icon-size;
line-height: calc(#{$grid-item-icon-size} * 1.55);
}
&:hover {
&:hover, &:focus,
button:hover &,
button:focus & {
color: $grid-item-icon-color-hover;
background-color: $grid-item-icon-bg-color-hover;
}
}
.action-text {
flex-shrink: 0;
text-align: start;
padding-inline: 5px;
}
.image-background {
background-color: #fff;
@ -205,8 +230,8 @@
.image-cropped {
aspect-ratio: 1/1;
max-width: 100%;
height: auto;
width: 100%;
height: 100%;
object-fit: contain;
border-radius: $grid-item-border-radius;
}

View File

@ -3,21 +3,31 @@
/* eslint-disable no-undef */
tinymce.PluginManager.add('jdragndrop', function (editor) {
var responseData; // Reset the drop area border
tinyMCE.DOM.bind(document, 'dragleave', function (e) {
// Reset the drop area border
var dragleaveCallback = function (e) {
if (!e.dataTransfer.types.includes('Files')) return;
e.stopPropagation();
e.preventDefault();
editor.contentAreaContainer.style.borderWidth = '1px 0 0';
editor.contentAreaContainer.style.borderWidth = '0';
return false;
}); // Fix for Chrome
}
tinyMCE.DOM.bind(document, 'dragleave', dragleaveCallback);
// Remove listener when editor are removed
editor.on('remove', function () {
tinyMCE.DOM.unbind(document, 'dragleave', dragleaveCallback);
});
// Fix for Chrome
editor.on('dragenter', function (e) {
if (!e.dataTransfer.types.includes('Files')) return;
e.stopPropagation();
return false;
}); // Notify user when file is over the drop area
});
// Notify user when file is over the drop area
editor.on('dragover', function (e) {
if (!e.dataTransfer.types.includes('Files')) return;
e.preventDefault();
editor.contentAreaContainer.style.borderStyle = 'dashed';
editor.contentAreaContainer.style.borderWidth = '5px';
@ -46,7 +56,7 @@
}
if (response.data && response.data.path) {
responseData = response.data;
var responseData = response.data;
var urlPath; // For local adapters use relative paths
var _Joomla$getOptions = Joomla.getOptions('system.paths'),
@ -119,47 +129,39 @@
function readFile(file) {
// Create a new file reader instance
var reader = new FileReader(); // Add the on load callback
var reader = new FileReader();
// Add the on load callback
reader.onload = function (progressEvent) {
var result = progressEvent.target.result;
var splitIndex = result.indexOf('base64') + 7;
var content = result.slice(splitIndex, result.length); // Upload the file
var content = result.slice(splitIndex, result.length);
// Upload the file
uploadFile(file.name, content);
};
reader.readAsDataURL(file);
} // Listeners for drag and drop
if (typeof FormData !== 'undefined') {
// Logic for the dropped file
editor.on('drop', function (e) {
e.preventDefault(); // We override only for files
if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
var files = [].slice.call(e.dataTransfer.files);
files.forEach(function (file) {
// Only images allowed
if (file.name.toLowerCase().match(/\.(jpg|jpeg|png|gif)$/)) {
// Upload the file(s)
readFile(file);
}
});
}
editor.contentAreaContainer.style.borderWidth = '1px 0 0';
});
} else {
Joomla.renderMessages({
error: [Joomla.Text._('PLG_TINY_ERR_UNSUPPORTEDBROWSER')]
});
editor.on('drop', function (e) {
e.preventDefault();
return false;
});
}
});
// Logic for the dropped file
editor.on('drop', function (e) {
if (!e.dataTransfer.types.includes('Files')) return;
e.preventDefault();
// Read and upload files
if (e.dataTransfer.files.length > 0) {
var files = [].slice.call(e.dataTransfer.files);
files.forEach(function (file) {
// Only images allowed
if (file.name.toLowerCase().match(/\.(jpg|jpeg|png|gif|webp)$/)) {
// Upload the file(s)
readFile(file);
}
});
}
editor.contentAreaContainer.style.borderWidth = '0';
});
});
}());

View File

@ -54,19 +54,17 @@ if (container) {
// Element is moved down
if (dragIndex < dropIndex) {
rows[dropIndex].setAttribute('value', rows[dropIndex - 1].value);
rows[dropIndex].value = rows[dropIndex - 1].value;
for (i = dragIndex; i < dropIndex; i += 1) {
if (direction === 'asc') {
rows[i].setAttribute('value', parseInt(rows[i].value, 10) - 1);
rows[i].value = parseInt(rows[i].value, 10) - 1;
} else {
rows[i].setAttribute('value', parseInt(rows[i].value, 10) + 1);
rows[i].value = parseInt(rows[i].value, 10) + 1;
}
}
} else {
// Element is moved up
rows[dropIndex].setAttribute('value', rows[dropIndex + 1].value);
rows[dropIndex].value = rows[dropIndex + 1].value;
for (i = dropIndex + 1; i <= dragIndex; i += 1) {

View File

@ -10,6 +10,11 @@
border-color: $focuscolor;
box-shadow: $focusshadow;
}
&::placeholder {
font-size: .8rem;
font-style: italic;
}
}
.control-group {

View File

@ -4,12 +4,13 @@
; Note : All ini files need to be saved as UTF-8
COM_MEDIA="Media"
COM_MEDIA_ACTION_DELETE="Delete item"
COM_MEDIA_ACTION_DOWNLOAD="Download item"
COM_MEDIA_ACTION_EDIT="Edit item"
COM_MEDIA_ACTION_PREVIEW="Preview item"
COM_MEDIA_ACTION_RENAME="Rename item"
COM_MEDIA_ACTION_SHARE="Get a shareable link"
COM_MEDIA_ACTIONS_TOOLBAR_LABEL="Item: %s"
COM_MEDIA_ACTION_DELETE="Delete"
COM_MEDIA_ACTION_DOWNLOAD="Download"
COM_MEDIA_ACTION_EDIT="Edit"
COM_MEDIA_ACTION_PREVIEW="Preview"
COM_MEDIA_ACTION_RENAME="Rename"
COM_MEDIA_ACTION_SHARE="Get Link"
COM_MEDIA_ALIGN="Image Float"
COM_MEDIA_ALIGN_DESC="This will apply the classes 'float-start', 'pull-center' or 'float-end' to the '<figure>' or '<img>' element."
COM_MEDIA_BREADCRUMB_LABEL="Breadcrumb"
@ -78,6 +79,7 @@ COM_MEDIA_IMAGE_URL="Image URL"
COM_MEDIA_INCREASE_GRID="Increase grid size"
COM_MEDIA_INSERT="Insert"
COM_MEDIA_INSERT_IMAGE="Insert Image"
COM_MEDIA_MANAGE_ITEM="Manage item: %s"
COM_MEDIA_MAXIMUM_SIZE="Maximum Size"
COM_MEDIA_MEDIA="Media"
COM_MEDIA_MEDIA_DATE_CREATED="Date created"
@ -91,6 +93,8 @@ COM_MEDIA_MEDIA_TYPE="Type"
COM_MEDIA_NAME="Image Name"
COM_MEDIA_NO_IMAGES_FOUND="No Images Found"
COM_MEDIA_NOT_SET="Not Set"
; The string COM_MEDIA_OPEN_ITEM_ACTIONS is deprecated and no longer in use as of __DEPLOY_VERSION__
; Please use the string COM_MEDIA_MANAGE_ITEM (with the file name) instead.
COM_MEDIA_OPEN_ITEM_ACTIONS="Open item actions"
COM_MEDIA_OVERALL_PROGRESS="Overall Progress"
COM_MEDIA_PIXEL_DIMENSIONS="Pixel Dimensions (w x h)"

View File

@ -228,7 +228,7 @@ class JNamespacePsr4Map
}
// Load the manifest file
$xml = simplexml_load_file($file);
$xml = simplexml_load_file($file, 'SimpleXMLElement', LIBXML_NOERROR);
// When invalid, ignore
if (!$xml) {

View File

@ -542,7 +542,7 @@ class HtmlDocument extends Document implements CacheControllerFactoryAwareInterf
]
)
);
$cbuffer = $cache->get('cbuffer_' . $type);
$cbuffer = $cache->get('cbuffer_' . $type) ?: [];
if (isset($cbuffer[$hash])) {
return Cache::getWorkarounds($cbuffer[$hash], array('mergehead' => 1));

View File

@ -150,7 +150,13 @@ abstract class FormModel extends BaseDatabaseModel implements FormFactoryAwareIn
return true;
}
$user = $this->getCurrentUser();
$user = $this->getCurrentUser();
// When the user is a guest, don't do a checkout
if (!$user->id) {
return false;
}
$checkedOutField = $table->getColumnAlias('checked_out');
// Check if this is the user having previously checked out the row.

View File

@ -257,8 +257,13 @@ class Category extends Nested implements VersionableTableInterface, TaggableTabl
$table->load(array('alias' => $this->alias, 'parent_id' => (int) $this->parent_id, 'extension' => $this->extension))
&& ($table->id != $this->id || $this->id == 0)
) {
// Is the existing category trashed?
$this->setError(Text::_('JLIB_DATABASE_ERROR_CATEGORY_UNIQUE_ALIAS'));
if ($table->published === -2) {
$this->setError(Text::_('JLIB_DATABASE_ERROR_CATEGORY_UNIQUE_ALIAS_TRASHED'));
}
return false;
}

View File

@ -346,7 +346,12 @@ class Content extends Table implements VersionableTableInterface, TaggableTableI
$table = Table::getInstance('Content', 'JTable', array('dbo' => $this->getDbo()));
if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) {
$this->setError(Text::_('JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS'));
// Is the existing article trashed?
$this->setError(Text::_('COM_CONTENT_ERROR_UNIQUE_ALIAS'));
if ($table->published === -2) {
$this->setError(Text::_('COM_CONTENT_ERROR_UNIQUE_ALIAS_TRASHED'));
}
return false;
}

View File

@ -14,6 +14,7 @@ use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Database\DatabaseDriver;
use Joomla\Database\ParameterType;
use Joomla\Registry\Registry;
@ -241,7 +242,14 @@ class Menu extends Nested
if ($error) {
$menuTypeTable = Table::getInstance('MenuType', 'JTable', array('dbo' => $db));
$menuTypeTable->load(array('menutype' => $table->menutype));
$this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS', $this->alias, $table->title, $menuTypeTable->title));
$url = Route::_('index.php?option=com_menus&task=item.edit&id=' . (int) $table->id);
// Is the existing menu item trashed?
$this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS', $this->alias, $table->title, $menuTypeTable->title, $url));
if ($table->published === -2) {
$this->setError(Text::sprintf('JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS_TRASHED', $this->alias, $table->title, $menuTypeTable->title, $url));
}
return false;
}

View File

@ -244,7 +244,7 @@ class FormModelTest extends UnitTestCase
*
* @since 4.2.0
*/
public function testSucessfullCheckout()
public function testSuccessfulCheckout()
{
$table = $this->createStub(Table::class);
$table->checked_out = 0;
@ -263,7 +263,11 @@ class FormModelTest extends UnitTestCase
return null;
}
};
$model->setCurrentUser(new User());
// Must be a valid user
$user = new User();
$user->id = 1;
$model->setCurrentUser($user);
$this->assertTrue($model->checkout(1));
}
@ -275,7 +279,7 @@ class FormModelTest extends UnitTestCase
*
* @since 4.2.0
*/
public function testSucessfullCheckoutWithEmptyRecord()
public function testSuccessfulCheckoutWithEmptyRecord()
{
$model = new class (['dbo' => $this->createStub(DatabaseInterface::class)], $this->createStub(MVCFactoryInterface::class)) extends FormModel
{
@ -307,6 +311,41 @@ class FormModelTest extends UnitTestCase
$mvcFactory = $this->createStub(MVCFactoryInterface::class);
$mvcFactory->method('createTable')->willReturn($table);
$model = new class (['dbo' => $this->createStub(DatabaseInterface::class)], $mvcFactory) extends FormModel
{
public function getForm($data = array(), $loadData = true)
{
return null;
}
};
// Must be a valid user
$user = new User();
$user->id = 1;
$model->setCurrentUser($user);
$this->assertFalse($model->checkout(1));
}
/**
* @testdox can't checkout a record when the current user is a guest
*
* @return void
*
* @since 4.2.0
*/
public function testFailedCheckoutAsGuest()
{
$table = $this->createStub(Table::class);
$table->checked_out = 0;
$table->method('load')->willReturn(true);
$table->method('hasField')->willReturn(true);
$table->method('checkIn')->willReturn(false);
$table->method('getColumnAlias')->willReturn('checked_out');
$mvcFactory = $this->createStub(MVCFactoryInterface::class);
$mvcFactory->method('createTable')->willReturn($table);
$model = new class (['dbo' => $this->createStub(DatabaseInterface::class)], $mvcFactory) extends FormModel
{
public function getForm($data = array(), $loadData = true)