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:
commit
4db71ec44e
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) . ')')
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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])) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = [];
|
||||
|
|
Loading…
Reference in New Issue
Block a user