29
0
mirror of https://github.com/joomla/joomla-cms.git synced 2024-06-26 07:13:21 +00:00

Merge branch '4.3-dev' into 4.4-dev

This commit is contained in:
Allon Moritz 2023-09-01 10:39:10 +02:00
commit 4db71ec44e
No known key found for this signature in database
GPG Key ID: 6486E0BC67E6DDF4
20 changed files with 175 additions and 35 deletions

View File

@ -31,7 +31,9 @@ class Dispatcher extends ComponentDispatcher
*/
protected function checkAccess()
{
$extension = $this->getApplication()->getInput()->getCmd('extension');
$extension = empty($this->getApplication()->getInput()->getCmd('extension'))
? ''
: $this->getApplication()->getInput()->getCmd('extension');
$parts = explode('.', $extension);

View File

@ -633,7 +633,7 @@ abstract class Adapter extends CMSPlugin
*
* @param integer $id The plugin ID
*
* @return string The plugin type
* @return string|null The plugin type
*
* @since 2.5
*/
@ -643,6 +643,7 @@ abstract class Adapter extends CMSPlugin
$query = $this->db->getQuery(true)
->select($this->db->quoteName('element'))
->from($this->db->quoteName('#__extensions'))
->where($this->db->quoteName('folder') . ' = ' . $this->db->quote('finder'))
->where($this->db->quoteName('extension_id') . ' = ' . (int) $id);
$this->db->setQuery($query);
@ -877,6 +878,8 @@ abstract class Adapter extends CMSPlugin
foreach ($items as $item) {
$this->remove($item);
}
// Stop processing plugins
break;
}
}
}

View File

@ -553,7 +553,7 @@ class Query
$query->clear()
->select('t1.id, t1.title, t2.title AS branch')
->from($db->quoteName('#__finder_taxonomy') . ' AS t1')
->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id')
->leftJoin($db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.lft < t1.lft AND t1.rgt < t2.rgt AND t2.level = 1')
->where('t1.state = 1')
->where('t1.access IN (' . $groups . ')')
->where('t1.id IN (' . implode(',', $filters) . ')')
@ -617,7 +617,7 @@ class Query
*/
$query->select('t1.id, t1.title, t2.title AS branch')
->from($db->quoteName('#__finder_taxonomy') . ' AS t1')
->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id')
->leftJoin($db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.lft < t1.lft AND t1.rgt < t2.rgt AND t2.level = 1')
->where('t1.state = 1')
->where('t1.access IN (' . $groups . ')')
->where('t1.id IN (' . implode(',', $filters) . ')')

View File

@ -479,7 +479,7 @@ class TemplateController extends BaseController
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_TYPE'), 'error');
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
$this->setRedirect(Route::_($url, false));
} elseif (!preg_match('/^(?!\.)(?!.*\.$)(?!.*\.\.)[a-zA-Z0-9_.]+$/', $name)) {
} elseif (!preg_match('/^(?!\.)(?!.*\.$)(?!.*\.\.)[a-zA-Z0-9_.-]+$/', $name)) {
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error');
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
$this->setRedirect(Route::_($url, false));
@ -672,7 +672,7 @@ class TemplateController extends BaseController
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_RENAME_ASSET_FILE'), 'warning');
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
$this->setRedirect(Route::_($url, false));
} elseif (!preg_match('/^(?!\.)(?!.*\.$)(?!.*\.\.)[a-zA-Z0-9_.]+$/', $newName)) {
} elseif (!preg_match('/^(?!\.)(?!.*\.$)(?!.*\.\.)[a-zA-Z0-9_.-]+$/', $newName)) {
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error');
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
$this->setRedirect(Route::_($url, false));

View File

@ -395,9 +395,12 @@ class StyleModel extends AdminModel
$formFile = Path::clean($client->path . '/templates/' . $template . '/templateDetails.xml');
// Load the core and/or local language file(s).
// Default to using parent template language constants
$lang->load('tpl_' . $data->parent, $client->path)
|| $lang->load('tpl_' . $data->parent, $client->path . '/templates/' . $data->parent);
// Apply any, optional, overrides for child template language constants
$lang->load('tpl_' . $template, $client->path)
|| (!empty($data->parent) && $lang->load('tpl_' . $data->parent, $client->path))
|| (!empty($data->parent) && $lang->load('tpl_' . $data->parent, $client->path . '/templates/' . $data->parent))
|| $lang->load('tpl_' . $template, $client->path . '/templates/' . $template);
if (file_exists($formFile)) {

View File

@ -296,7 +296,9 @@
if (window.innerHeight < containerTmp.getBoundingClientRect().bottom + 20) {
containerTmp.style.marginTop = - (containerTmp.getBoundingClientRect().height + this.inputField.getBoundingClientRect().height) + "px";
}
} else {
containerTmp.style.marginTop = 'initial';
}
this.processCalendar();
};

View File

@ -302,7 +302,7 @@ class JoomlaFieldMedia extends HTMLElement {
let type;
this.buttonClearEl.style.display = '';
this.previewElement.innerHTML = '';
const ext = getExtension(value);
const ext = getExtension(value).toLowerCase();
if (supportedExtensions.images.includes(ext)) type = 'images';
if (supportedExtensions.audios.includes(ext)) type = 'audios';

View File

@ -143,8 +143,11 @@
iframeDocument = this.contentDocument;
// Validate the child form and update parent form.
if (iframeDocument.getElementById(idFieldId) && iframeDocument.getElementById(idFieldId).value != '0')
{
if (
iframeDocument.getElementById(idFieldId)
&& iframeDocument.getElementById(idFieldId).value != '0'
&& [].slice.call(iframeDocument.querySelectorAll('joomla-alert[type="danger"]')).length == 0
) {
window.processModalParent(fieldPrefix, iframeDocument.getElementById(idFieldId).value, iframeDocument.getElementById(titleFieldId).value);
// If Save & Close (save task), submit the edit close action (so we don't have checked out items).

View File

@ -21,6 +21,7 @@
flex-direction: column;
justify-content: center;
padding: .8rem;
line-height: normal;
color: var(--white);
background: var(--alert-accent-color, var(--template-bg-dark));
align-content: center;

View File

@ -171,12 +171,23 @@ class ContactController extends FormController
// Validation succeeded, continue with custom handlers
$results = $this->app->triggerEvent('onValidateContact', [&$contact, &$data]);
$passValidation = true;
foreach ($results as $result) {
if ($result instanceof \Exception) {
return false;
$passValidation = false;
$app->enqueueMessage($result->getMessage(), 'error');
}
}
if (!$passValidation) {
$app->setUserState('com_contact.contact.data', $data);
$this->setRedirect(Route::_('index.php?option=com_contact&view=contact&id=' . $id . '&catid=' . $contact->catid, false));
return false;
}
// Passed Validation: Process the contact plugins to integrate with other applications
$this->app->triggerEvent('onSubmitContact', [&$contact, &$data]);

View File

@ -35,8 +35,8 @@ class TagsController extends BaseController
// Receive request data
$filters = [
'like' => trim($this->input->get('like', null, 'string')),
'title' => trim($this->input->get('title', null, 'string')),
'like' => trim($this->input->get('like', '', 'string')),
'title' => trim($this->input->get('title', '', 'string')),
'flanguage' => $this->input->get('flanguage', null, 'word'),
'published' => $this->input->get('published', 1, 'int'),
'parent_id' => $this->input->get('parent_id', 0, 'int'),

View File

@ -395,7 +395,7 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`,
-- Templates
INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`, `ordering`, `state`) VALUES
(0, 'atum', 'template', 'atum', '', 1, 1, 1, 0, 1, '', '', '', 0, 0),
(0, 'cassiopeia', 'template', 'cassiopeia', '', 0, 1, 1, 0, 1, '', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}', '', 0, 0);
(0, 'cassiopeia', 'template', 'cassiopeia', '', 0, 1, 1, 0, 1, '', '{"brand":"1","logoFile":"","siteTitle":"","siteDescription":"","useFontScheme":"0","colorName":"colors_standard","fluidContainer":"0","stickyHeader":0,"backTop":0}', '', 0, 0);
-- Files Extensions
INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`, `ordering`, `state`) VALUES

View File

@ -401,7 +401,7 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder",
-- Templates
INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES
(0, 'atum', 'template', 'atum', '', 1, 1, 1, 0, 1, '', '', '', 0, 0),
(0, 'cassiopeia', 'template', 'cassiopeia', '', 0, 1, 1, 0, 1, '', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}', '', 0, 0);
(0, 'cassiopeia', 'template', 'cassiopeia', '', 0, 1, 1, 0, 1, '', '{"brand":"1","logoFile":"","siteTitle":"","siteDescription":"","useFontScheme":"0","colorName":"colors_standard","fluidContainer":"0","stickyHeader":0,"backTop":0}', '', 0, 0);
-- Files Extensions
INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES

View File

@ -583,4 +583,52 @@ class ConsoleApplication extends Application implements DispatcherAwareInterface
]
);
}
/**
* Gets a user state.
*
* @param string $key The path of the state.
* @param mixed $default Optional default value, returned if the internal value is null.
*
* @return mixed The user state or null.
*
* @since __DEPLOY_VERSION__
*/
public function getUserState($key, $default = null)
{
$registry = $this->getSession()->get('registry');
if ($registry !== null) {
return $registry->get($key, $default);
}
return $default;
}
/**
* Gets the value of a user state variable.
*
* @param string $key The key of the user state variable.
* @param string $request The name of the variable passed in a request.
* @param string $default The default value for the variable if not found. Optional.
* @param string $type Filter for the variable, for valid values see {@link InputFilter::clean()}. Optional.
*
* @return mixed The request user state.
*
* @since __DEPLOY_VERSION__
*/
public function getUserStateFromRequest($key, $request, $default = null, $type = 'none')
{
$cur_state = $this->getUserState($key, $default);
$new_state = $this->input->get($request, null, $type);
if ($new_state === null) {
return $cur_state;
}
// Save the new value only if it was set in this request.
$this->setUserState($key, $new_state);
return $new_state;
}
}

View File

@ -10,11 +10,12 @@
namespace Joomla\CMS\Console;
use Joomla\Application\Cli\CliInput;
use Joomla\CMS\Extension\ExtensionHelper;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Installer\InstallerHelper;
use Joomla\Console\Command\AbstractCommand;
use Joomla\Database\DatabaseInterface;
use Joomla\Filesystem\File;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@ -165,6 +166,19 @@ class UpdateCoreCommand extends AbstractCommand
return self::ERR_CHECKS_FAILED;
}
$this->progressBar->advance();
$this->progressBar->setMessage('Check Database Table Structure...');
$errors = $this->checkSchema();
if ($errors > 0) {
$this->ioStyle->error('Database Table Structure not Up to Date');
$this->progressBar->finish();
$this->ioStyle->info('There were ' . $errors . ' errors');
return self::ERR_CHECKS_FAILED;
}
$this->progressBar->advance();
$this->progressBar->setMessage('Starting Joomla! update ...');
@ -386,4 +400,32 @@ class UpdateCoreCommand extends AbstractCommand
{
Folder::copy($file, $dir, '', true);
}
/**
* Check Database Table Structure
*
* @return integer the number of errors
*
* @since __DEPLOY_VERSION__
*/
public function checkSchema(): int
{
$app = $this->getApplication();
$app->getLanguage()->load('com_installer', JPATH_ADMINISTRATOR);
$coreExtensionInfo = ExtensionHelper::getExtensionRecord('joomla', 'file');
$dbmodel = $app->bootComponent('com_installer')->getMVCFactory($app)->createModel('Database', 'Administrator');
// Ensure we only get information for core
$dbmodel->setState('filter.extension_id', $coreExtensionInfo->extension_id);
// We're filtering by a single extension which must always exist - so can safely access this through element 0 of the array
$changeInformation = $dbmodel->getItems()[0];
foreach ($changeInformation['errorsMessage'] as $msg) {
$this->ioStyle->info($msg);
}
return $changeInformation['errorsCount'];
}
}

View File

@ -640,6 +640,10 @@ class Document
*/
public function addStyleDeclaration($content, $type = 'text/css')
{
if ($content === null) {
return $this;
}
$type = strtolower($type);
if (empty($this->_style[$type])) {

View File

@ -1019,7 +1019,20 @@ abstract class FormField implements DatabaseAwareInterface
? ((string) $this->form->getXml()->config->inlinehelp['button'] == 'show' ?: false)
: false;
if ($this->showon) {
// Check if the field has showon in nested option
$hasOptionShowOn = false;
if (!empty((array) $this->element->xpath('option'))) {
foreach ($this->element->xpath('option') as $option) {
if ((string) $option['showon']) {
$hasOptionShowOn = true;
break;
}
}
}
if ($this->showon || $hasOptionShowOn) {
$options['rel'] = ' data-showon=\'' .
json_encode(FormHelper::parseShowOnConditions($this->showon, $this->formControl, $this->group)) . '\'';
$options['showonEnabled'] = true;
@ -1252,17 +1265,12 @@ abstract class FormField implements DatabaseAwareInterface
*/
protected function getLayoutData()
{
// Label preprocess
$label = !empty($this->element['label']) ? (string) $this->element['label'] : null;
$label = $label && $this->translateLabel ? Text::_($label) : $label;
// Description preprocess
$label = !empty($this->element['label']) ? (string) $this->element['label'] : null;
$label = $label && $this->translateLabel ? Text::_($label) : $label;
$description = !empty($this->description) ? $this->description : null;
$description = !empty($description) && $this->translateDescription ? Text::_($description) : $description;
$alt = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname);
return [
$alt = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname);
$options = [
'autocomplete' => $this->autocomplete,
'autofocus' => $this->autofocus,
'class' => $this->class,
@ -1292,6 +1300,8 @@ abstract class FormField implements DatabaseAwareInterface
'dataAttributes' => $this->dataAttributes,
'parentclass' => $this->parentclass,
];
return $options;
}
/**

View File

@ -232,7 +232,7 @@ class Mail extends PHPMailer implements MailerInterface
*/
public function setSubject($subject)
{
$this->Subject = MailHelper::cleanLine($subject);
$this->Subject = MailHelper::cleanSubject($subject);
return $this;
}

View File

@ -43,11 +43,6 @@ final class LoadModule extends CMSPlugin
*/
public function onContentPrepare($context, &$article, &$params, $page = 0)
{
// Don't run this plugin when the content is being indexed
if ($context === 'com_finder.indexer') {
return;
}
// Only execute if $article is an object and has a text property
if (!is_object($article) || !property_exists($article, 'text') || is_null($article->text)) {
return;
@ -69,6 +64,23 @@ final class LoadModule extends CMSPlugin
// Expression to search for(id)
$regexmodid = '/{loadmoduleid\s([1-9][0-9]*)}/i';
// Remove macros and don't run this plugin when the content is being indexed
if ($context === 'com_finder.indexer') {
if (str_contains($article->text, 'loadposition')) {
$article->text = preg_replace($regex, '', $article->text);
}
if (str_contains($article->text, 'loadmoduleid')) {
$article->text = preg_replace($regexmodid, '', $article->text);
}
if (str_contains($article->text, 'loadmodule')) {
$article->text = preg_replace($regexmod, '', $article->text);
}
return;
}
if (str_contains($article->text, '{loadposition ')) {
// Find all instances of plugin and put in $matches for loadposition
// $matches[0] is full pattern match, $matches[1] is the position

View File

@ -26,7 +26,6 @@ use Joomla\CMS\Uri\Uri;
*/
$uri = clone Uri::getInstance();
$uri->setVar('hitcount', '0');
// Create option list for voting select box
$options = [];