params->get('loginLogoFile')) : ?>
-
 . $loginLogoFile; ?>)
+

diff --git a/build/build.php b/build/build.php
index a055194760b6d..b6173d794adf1 100644
--- a/build/build.php
+++ b/build/build.php
@@ -156,7 +156,6 @@ function usage($command)
'.php_cs',
'.travis.yml',
'README.md',
- 'SECURITY.md',
'appveyor-phpunit.xml',
'build',
'build.xml',
diff --git a/build/phpcs/Joomla/Sniffs/Commenting/FileCommentSniff.php b/build/phpcs/Joomla/Sniffs/Commenting/FileCommentSniff.php
index cb861a808f560..deb848329facd 100644
--- a/build/phpcs/Joomla/Sniffs/Commenting/FileCommentSniff.php
+++ b/build/phpcs/Joomla/Sniffs/Commenting/FileCommentSniff.php
@@ -593,9 +593,9 @@ protected function processPackage($errorPos)
$newContent = str_replace(' ', '_', $content);
$nameBits = explode('_', $newContent);
$firstBit = array_shift($nameBits);
- $newName = strtoupper($firstBit{0}).substr($firstBit, 1).'_';
+ $newName = strtoupper($firstBit[0]).substr($firstBit, 1).'_';
foreach ($nameBits as $bit) {
- $newName .= strtoupper($bit{0}).substr($bit, 1).'_';
+ $newName .= strtoupper($bit[0]).substr($bit, 1).'_';
}
$error = 'Package name "%s" is not valid; consider "%s" instead';
@@ -632,9 +632,9 @@ protected function processSubpackage($errorPos)
// $newContent = str_replace(' ', '_', $content);
// $nameBits = explode('_', $newContent);
// $firstBit = array_shift($nameBits);
-// $newName = strtoupper($firstBit{0}).substr($firstBit, 1).'_';
+// $newName = strtoupper($firstBit[0]).substr($firstBit, 1).'_';
// foreach ($nameBits as $bit) {
-// $newName .= strtoupper($bit{0}).substr($bit, 1).'_';
+// $newName .= strtoupper($bit[0]).substr($bit, 1).'_';
// }
//
// $error = 'Subpackage name "%s" is not valid; consider "%s" instead';
diff --git a/build/phpcs/Joomla/Sniffs/Commenting/SingleCommentSniff.php b/build/phpcs/Joomla/Sniffs/Commenting/SingleCommentSniff.php
index b64c9f5fd5c23..5f701b1dba37d 100644
--- a/build/phpcs/Joomla/Sniffs/Commenting/SingleCommentSniff.php
+++ b/build/phpcs/Joomla/Sniffs/Commenting/SingleCommentSniff.php
@@ -51,7 +51,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
* The exception to this is if the preceding line consists of a single open bracket.
*/
- if (isset($comment{2}) && $comment{2} != ' ')
+ if (isset($comment[2]) && $comment[2] != ' ')
{
$phpcsFile->addError('Please put a space between the // and the start of comment text; found "%s"'
, $stackPtr, 'NoSpace', array($comment));
@@ -65,7 +65,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
* The term is code and is case sensitive.(@todo)
*/
- if (isset($comment{3}) && $comment{3} != strtoupper($comment{3}))
+ if (isset($comment[3]) && $comment[3] != strtoupper($comment[3]))
{
// Comment does not start with an upper case letter
diff --git a/build/travis/phpenv/apcu-7.4.ini b/build/travis/phpenv/apcu-7.4.ini
new file mode 100644
index 0000000000000..019901d1ba62c
--- /dev/null
+++ b/build/travis/phpenv/apcu-7.4.ini
@@ -0,0 +1,2 @@
+apc.enabled=true
+apc.enable_cli=true
diff --git a/cli/finder_indexer.php b/cli/finder_indexer.php
index 5c1ed6b19121f..3f061f4099c02 100644
--- a/cli/finder_indexer.php
+++ b/cli/finder_indexer.php
@@ -12,10 +12,30 @@
* This is a command-line script to help with management of Smart Search.
*
* Called with no arguments: php finder_indexer.php
- * Performs an incremental update of the index.
+ * Performs an incremental update of the index using dynamic pausing.
*
- * Called with --purge: php finder_indexer.php --purge
+ * IMPORTANT NOTE: since Joomla version 3.9.12 the default behavior of this script has changed.
+ * If called with no arguments, the `--pause` argument is silently applied, in order to avoid the possibility of
+ * stressing the server too much and making a site (or multiple sites, if on a shared environment) unresponsive.
+ * If a pause is unwanted, just apply `--pause=0` to the command
+ *
+ * Called with --purge php finder_indexer.php --purge
* Purges and rebuilds the index (search filters are preserved).
+ *
+ * Called with --pause `php finder_indexer.php --pause`
+ * or --pause=x or `php finder_indexer.php --pause=x` where x = seconds.
+ * or --pause=division or `php finder_indexer.php --pause=division` The default divisor is 5.
+ * If another divisor is required, it can be set with --divisor=y, where
+ * y is the integer divisor
+ *
+ * This will pause for x seconds between batches,
+ * in order to give the server some time to catch up
+ * if --pause is called without an assignment, it defaults to dynamic pausing
+ * using the division method with a divisor of 5
+ * (eg. 1 second pause for every 5 seconds of batch processing time)
+ *
+ * Called with --minproctime=x Will set the minimum processing time of batches for a pause to occur. Defaults to 1
+ *
*/
// We are a valid entry point.
@@ -91,6 +111,37 @@ class FinderCli extends JApplicationCli
*/
private $filters = array();
+ /**
+ * Pausing type or defined pause time in seconds.
+ * One pausing type is implemented: 'division' for dynamic calculation of pauses
+ *
+ * Defaults to 'division'
+ *
+ * @var string|integer
+ * @since 3.9.12
+ */
+ private $pause = 'division';
+
+ /**
+ * The divisor of the division: batch-processing time / divisor.
+ * This is used together with --pause=division in order to pause dynamically
+ * in relation to the processing time
+ * Defaults to 5
+ *
+ * @var integer
+ * @since 3.9.12
+ */
+ private $divisor = 5;
+
+ /**
+ * Minimum processing time in seconds, in order to apply a pause
+ * Defaults to 1
+ *
+ * @var integer
+ * @since 3.9.12
+ */
+ private $minimumBatchProcessingTime = 1;
+
/**
* Entry point for Smart Search CLI script
*
@@ -114,6 +165,20 @@ public function doExecute()
$_SERVER['HTTP_HOST'] = 'domain.com';
JFactory::getApplication('site');
+ $this->minimumBatchProcessingTime = $this->input->getInt('minproctime', 1);
+
+ // Pause between batches to let the server catch a breath. The default, if not set by the user, is set in the class property `pause`
+ $pauseArg = $this->input->get('pause', $this->pause, 'raw');
+
+ if ($pauseArg === 'division')
+ {
+ $this->divisor = $this->input->getInt('divisor', $this->divisor);
+ }
+ else
+ {
+ $this->pause = (int) $pauseArg;
+ }
+
// Purge before indexing if --purge on the command line.
if ($this->input->getString('purge', false))
{
@@ -207,7 +272,43 @@ private function index()
JEventDispatcher::getInstance()->trigger('onBuildIndex');
// Batch reporting.
- $this->out(JText::sprintf('FINDER_CLI_BATCH_COMPLETE', $i + 1, round(microtime(true) - $this->qtime, 3)), true);
+ $this->out(JText::sprintf('FINDER_CLI_BATCH_COMPLETE', $i + 1, $processingTime = round(microtime(true) - $this->qtime, 3)), true);
+
+ if ($this->pause !== 0)
+ {
+ // Pausing Section
+ $skip = !($processingTime >= $this->minimumBatchProcessingTime);
+ $pause = 0;
+
+ if ($this->pause === 'division' && $this->divisor > 0)
+ {
+ if (!$skip)
+ {
+ $pause = round($processingTime / $this->divisor);
+ }
+ else
+ {
+ $pause = 1;
+ }
+ }
+ elseif ($this->pause > 0)
+ {
+ $pause = $this->pause;
+ }
+
+ if ($pause > 0 && !$skip)
+ {
+ $this->out(JText::sprintf('FINDER_CLI_BATCH_PAUSING', $pause), true);
+ sleep($pause);
+ $this->out(JText::_('FINDER_CLI_BATCH_CONTINUING'));
+ }
+
+ if ($skip)
+ {
+ $this->out(JText::sprintf('FINDER_CLI_SKIPPING_PAUSE_LOW_BATCH_PROCESSING_TIME', $processingTime, $this->minimumBatchProcessingTime), true);
+ }
+ // End of Pausing Section
+ }
}
}
catch (Exception $e)
@@ -331,7 +432,7 @@ private function getFilters()
$this->out(JText::_('FINDER_CLI_SAVE_FILTERS'));
// Get the taxonomy ids used by the filters.
- $db = JFactory::getDbo();
+ $db = JFactory::getDbo();
$query = $db->getQuery(true);
$query
->select('filter_id, title, data')
diff --git a/components/com_banners/models/banner.php b/components/com_banners/models/banner.php
index e0f6b501eec6c..8de828096d8e2 100644
--- a/components/com_banners/models/banner.php
+++ b/components/com_banners/models/banner.php
@@ -78,7 +78,7 @@ public function click()
if ($trackClicks > 0)
{
- $trackDate = JFactory::getDate()->format('Y-m-d H');
+ $trackDate = JFactory::getDate()->toSql();
$query->clear()
->select($db->quoteName('count'))
diff --git a/components/com_banners/models/banners.php b/components/com_banners/models/banners.php
index 7b978f5738da8..8a1fdebab411d 100644
--- a/components/com_banners/models/banners.php
+++ b/components/com_banners/models/banners.php
@@ -222,7 +222,7 @@ public function getItems()
*/
public function impress()
{
- $trackDate = JFactory::getDate()->format('Y-m-d H');
+ $trackDate = JFactory::getDate()->toSql();
$items = $this->getItems();
$db = $this->getDbo();
$query = $db->getQuery(true);
diff --git a/components/com_config/controller/display.php b/components/com_config/controller/display.php
index edf2b9be6457f..074595058a750 100644
--- a/components/com_config/controller/display.php
+++ b/components/com_config/controller/display.php
@@ -78,6 +78,15 @@ public function execute()
$model = new $modelClass;
$component = $model->getState()->get('component.option');
+ // Make sure com_joomlaupdate and com_privacy can only be accessed by SuperUser
+ if (in_array(strtolower($component), array('com_joomlaupdate', 'com_privacy'))
+ && !JFactory::getUser()->authorise('core.admin'))
+ {
+ $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error');
+
+ return;
+ }
+
// Access check.
if (!JFactory::getUser()->authorise('core.admin', $component)
&& !JFactory::getUser()->authorise('core.options', $component))
diff --git a/components/com_config/model/cms.php b/components/com_config/model/cms.php
index 45cf6d1d354a4..0ab22f82b8772 100644
--- a/components/com_config/model/cms.php
+++ b/components/com_config/model/cms.php
@@ -256,32 +256,25 @@ protected function populateState()
*/
protected function canDelete($record)
{
- if (!empty($record->id))
+ if (empty($record->id) || $record->published != -2)
{
- if ($record->published != -2)
- {
- return false;
- }
-
- $user = JFactory::getUser();
-
- return $user->authorise('core.delete', $this->option);
+ return false;
}
- }
- /**
- * Method to test whether a record can have its state changed.
- *
- * @param object $record A record object.
- *
- * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component.
- *
- * @since 3.2
- */
- protected function canEditState($record)
- {
- $user = JFactory::getUser();
+ return JFactory::getUser()->authorise('core.delete', $this->option);
+ }
- return $user->authorise('core.edit.state', $this->option);
+ /**
+ * Method to test whether a record can have its state changed.
+ *
+ * @param object $record A record object.
+ *
+ * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component.
+ *
+ * @since 3.2
+ */
+ protected function canEditState($record)
+ {
+ return JFactory::getUser()->authorise('core.edit.state', $this->option);
}
}
diff --git a/components/com_config/model/form.php b/components/com_config/model/form.php
index fa3f1f157b304..3886ae858357e 100644
--- a/components/com_config/model/form.php
+++ b/components/com_config/model/form.php
@@ -153,6 +153,8 @@ protected function loadForm($name, $source = null, $options = array(), $clear =
// Get the form.
// Register the paths for the form -- failing here
$paths = new SplPriorityQueue;
+ $paths->insert(JPATH_COMPONENT_ADMINISTRATOR . '/model/form', 'normal');
+ $paths->insert(JPATH_COMPONENT_ADMINISTRATOR . '/model/field', 'normal');
$paths->insert(JPATH_COMPONENT . '/model/form', 'normal');
$paths->insert(JPATH_COMPONENT . '/model/field', 'normal');
$paths->insert(JPATH_COMPONENT . '/model/rule', 'normal');
@@ -165,6 +167,8 @@ protected function loadForm($name, $source = null, $options = array(), $clear =
// Solution until JForm supports splqueue
JForm::addFormPath(JPATH_COMPONENT . '/models/forms');
JForm::addFieldPath(JPATH_COMPONENT . '/models/fields');
+ JForm::addFormPath(JPATH_COMPONENT_ADMINISTRATOR . '/model/form');
+ JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR . '/model/field');
JForm::addFormPath(JPATH_COMPONENT . '/model/form');
JForm::addFieldPath(JPATH_COMPONENT . '/model/field');
diff --git a/components/com_contact/controllers/contact.php b/components/com_contact/controllers/contact.php
index 82180e6233f0b..d822a986c4830 100644
--- a/components/com_contact/controllers/contact.php
+++ b/components/com_contact/controllers/contact.php
@@ -46,7 +46,6 @@ public function submit()
$app = JFactory::getApplication();
$model = $this->getModel('contact');
- $params = JComponentHelper::getParams('com_contact');
$stub = $this->input->getString('id');
$id = (int) $stub;
@@ -84,7 +83,7 @@ public function submit()
}
// Check for a valid session cookie
- if ($params->get('validate_session', 0))
+ if ($contact->params->get('validate_session', 0))
{
if (JFactory::getSession()->getState() !== 'active')
{
@@ -154,9 +153,9 @@ public function submit()
// Send the email
$sent = false;
- if (!$params->get('custom_reply'))
+ if (!$contact->params->get('custom_reply'))
{
- $sent = $this->_sendEmail($data, $contact, $params->get('show_email_copy', 0));
+ $sent = $this->_sendEmail($data, $contact, $contact->params->get('show_email_copy', 0));
}
// Set the success message if it was a success
diff --git a/components/com_contact/views/category/tmpl/default.xml b/components/com_contact/views/category/tmpl/default.xml
index 450513a6b6577..e3a53fa7a2059 100644
--- a/components/com_contact/views/category/tmpl/default.xml
+++ b/components/com_contact/views/category/tmpl/default.xml
@@ -327,6 +327,17 @@