summaryrefslogtreecommitdiffstatshomepage
path: root/core/lib
diff options
context:
space:
mode:
Diffstat (limited to 'core/lib')
-rw-r--r--core/lib/Drupal.php2
-rw-r--r--core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php13
-rw-r--r--core/lib/Drupal/Core/Cache/CacheTagsPurgeInterface.php24
-rw-r--r--core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php18
-rw-r--r--core/lib/Drupal/Core/Mailer/Transport/SendmailCommandValidationTransportFactory.php52
-rw-r--r--core/lib/Drupal/Core/Mailer/TransportServiceFactory.php44
-rw-r--r--core/lib/Drupal/Core/Mailer/TransportServiceFactoryInterface.php28
-rw-r--r--core/lib/Drupal/Core/Mailer/TransportServiceFactoryTrait.php42
-rw-r--r--core/lib/Drupal/Core/Recipe/ConsoleInputCollector.php13
-rw-r--r--core/lib/Drupal/Core/Session/SessionManager.php11
-rw-r--r--core/lib/Drupal/Core/Template/Loader/ComponentLoader.php7
-rw-r--r--core/lib/Drupal/Core/Theme/Component/ComponentValidator.php4
12 files changed, 243 insertions, 15 deletions
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 63514b60eff8..9b6dc8765017 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -76,7 +76,7 @@ class Drupal {
/**
* The current system version.
*/
- const VERSION = '11.2-dev';
+ const VERSION = '11.3-dev';
/**
* Core API compatibility.
diff --git a/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php b/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php
index 6c02649d2705..dad8bc10a21e 100644
--- a/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php
+++ b/core/lib/Drupal/Core/Cache/CacheTagsInvalidator.php
@@ -7,7 +7,7 @@ use Drupal\Component\Assertion\Inspector;
/**
* Passes cache tag events to classes that wish to respond to them.
*/
-class CacheTagsInvalidator implements CacheTagsInvalidatorInterface {
+class CacheTagsInvalidator implements CacheTagsInvalidatorInterface, CacheTagsPurgeInterface {
/**
* Holds an array of cache tags invalidators.
@@ -54,6 +54,17 @@ class CacheTagsInvalidator implements CacheTagsInvalidatorInterface {
}
/**
+ * {@inheritdoc}
+ */
+ public function purge(): void {
+ foreach ($this->invalidators as $invalidator) {
+ if ($invalidator instanceof CacheTagsPurgeInterface) {
+ $invalidator->purge();
+ }
+ }
+ }
+
+ /**
* Adds a cache tags invalidator.
*
* @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $invalidator
diff --git a/core/lib/Drupal/Core/Cache/CacheTagsPurgeInterface.php b/core/lib/Drupal/Core/Cache/CacheTagsPurgeInterface.php
new file mode 100644
index 000000000000..24c110372d12
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheTagsPurgeInterface.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Cache;
+
+/**
+ * Provides purging of cache tag invalidations.
+ *
+ * Backends that persistently store cache tag invalidations can use this
+ * interface to implement purging of cache tag invalidations. By default, cache
+ * tag purging will only be called during drupal_flush_all_caches(), after all
+ * other caches have been cleared.
+ *
+ * @ingroup cache
+ */
+interface CacheTagsPurgeInterface {
+
+ /**
+ * Purge cache tag invalidations.
+ */
+ public function purge(): void;
+
+}
diff --git a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php
index cb88c69495a7..9602bc8ba5d5 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php
@@ -8,7 +8,7 @@ use Drupal\Core\Database\DatabaseException;
/**
* Cache tags invalidations checksum implementation that uses the database.
*/
-class DatabaseCacheTagsChecksum implements CacheTagsChecksumInterface, CacheTagsInvalidatorInterface, CacheTagsChecksumPreloadInterface {
+class DatabaseCacheTagsChecksum implements CacheTagsChecksumInterface, CacheTagsInvalidatorInterface, CacheTagsChecksumPreloadInterface, CacheTagsPurgeInterface {
use CacheTagsChecksumTrait;
@@ -70,6 +70,22 @@ class DatabaseCacheTagsChecksum implements CacheTagsChecksumInterface, CacheTags
}
/**
+ * {@inheritdoc}
+ */
+ public function purge(): void {
+ try {
+ $this->connection->truncate('cachetags')->execute();
+ }
+ catch (\Throwable $e) {
+ // If the table does not exist yet, there is nothing to purge.
+ if (!$this->ensureTableExists()) {
+ throw $e;
+ }
+ }
+ $this->reset();
+ }
+
+ /**
* Check if the cache tags table exists and create it if not.
*/
protected function ensureTableExists() {
diff --git a/core/lib/Drupal/Core/Mailer/Transport/SendmailCommandValidationTransportFactory.php b/core/lib/Drupal/Core/Mailer/Transport/SendmailCommandValidationTransportFactory.php
new file mode 100644
index 000000000000..84dfb64c7b28
--- /dev/null
+++ b/core/lib/Drupal/Core/Mailer/Transport/SendmailCommandValidationTransportFactory.php
@@ -0,0 +1,52 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Mailer\Transport;
+
+use Drupal\Core\Site\Settings;
+use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
+use Symfony\Component\Mailer\Transport\Dsn;
+use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
+use Symfony\Component\Mailer\Transport\TransportInterface;
+
+/**
+ * Command validation decorator for sendmail transport factory.
+ */
+class SendmailCommandValidationTransportFactory implements TransportFactoryInterface {
+
+ /**
+ * Construct command validation decorator for sendmail transport factory.
+ *
+ * @param \Symfony\Component\Mailer\Transport\TransportFactoryInterface $inner
+ * The decorated sendmail transport factory.
+ */
+ public function __construct(
+ #[AutowireDecorated]
+ protected TransportFactoryInterface $inner,
+ ) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function create(Dsn $dsn): TransportInterface {
+ $command = $dsn->getOption('command');
+ if (!empty($command)) {
+ $commands = Settings::get('mailer_sendmail_commands', []);
+ if (!in_array($command, $commands, TRUE)) {
+ throw new \RuntimeException("Unsafe sendmail command {$command}");
+ }
+ }
+
+ return $this->inner->create($dsn);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports(Dsn $dsn): bool {
+ return $this->inner->supports($dsn);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Mailer/TransportServiceFactory.php b/core/lib/Drupal/Core/Mailer/TransportServiceFactory.php
new file mode 100644
index 000000000000..8950d44e3648
--- /dev/null
+++ b/core/lib/Drupal/Core/Mailer/TransportServiceFactory.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Mailer;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
+use Symfony\Component\Mailer\Transport\Dsn;
+use Symfony\Component\Mailer\Transport\TransportInterface;
+
+/**
+ * The default mailer transport service factory.
+ */
+class TransportServiceFactory implements TransportServiceFactoryInterface {
+
+ use TransportServiceFactoryTrait;
+
+ /**
+ * Constructs a new transport service factory.
+ *
+ * @param Iterable<TransportFactoryInterface> $factories
+ * A list of transport factories.
+ * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
+ * The config factory service.
+ */
+ public function __construct(
+ #[AutowireIterator(tag: 'mailer.transport_factory')]
+ iterable $factories,
+ protected ConfigFactoryInterface $configFactory,
+ ) {
+ $this->factories = $factories;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createTransport(): TransportInterface {
+ $dsn = $this->configFactory->get('system.mail')->get('mailer_dsn');
+ $dsnObject = new Dsn(...$dsn);
+ return $this->fromDsnObject($dsnObject);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Mailer/TransportServiceFactoryInterface.php b/core/lib/Drupal/Core/Mailer/TransportServiceFactoryInterface.php
new file mode 100644
index 000000000000..8a2b5368db05
--- /dev/null
+++ b/core/lib/Drupal/Core/Mailer/TransportServiceFactoryInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Mailer;
+
+use Symfony\Component\Mailer\Transport\TransportInterface;
+
+/**
+ * An interface defining mailer transport service factory implementations.
+ *
+ * The transport service factory is responsible to create a transport instance
+ * according to the site configuration. The default service factory looks up the
+ * `mailer_dsn` key from the `system.mail` config and returns an appropriate
+ * transport implementation.
+ *
+ * Contrib and custom code may choose to replace or decorate the transport
+ * service factory in order to provide a mailer transport instance which
+ * requires more complex setup.
+ */
+interface TransportServiceFactoryInterface {
+
+ /**
+ * Creates and returns a configured mailer transport class.
+ */
+ public function createTransport(): TransportInterface;
+
+}
diff --git a/core/lib/Drupal/Core/Mailer/TransportServiceFactoryTrait.php b/core/lib/Drupal/Core/Mailer/TransportServiceFactoryTrait.php
new file mode 100644
index 000000000000..c4aa2c736a4e
--- /dev/null
+++ b/core/lib/Drupal/Core/Mailer/TransportServiceFactoryTrait.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Core\Mailer;
+
+use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
+use Symfony\Component\Mailer\Transport\Dsn;
+use Symfony\Component\Mailer\Transport\TransportInterface;
+
+/**
+ * A trait containing helper methods for transport service construction.
+ */
+trait TransportServiceFactoryTrait {
+
+ /**
+ * A list of transport factories.
+ *
+ * @var Iterable<TransportFactoryInterface>
+ */
+ protected iterable $factories;
+
+ /**
+ * Constructs a transport instance given a DSN object.
+ *
+ * @param \Symfony\Component\Mailer\Transport\Dsn $dsn
+ * The mailer DSN object.
+ *
+ * @throws \Symfony\Component\Mailer\Exception\IncompleteDsnException
+ * @throws \Symfony\Component\Mailer\Exception\UnsupportedSchemeException
+ */
+ protected function fromDsnObject(Dsn $dsn): TransportInterface {
+ foreach ($this->factories as $factory) {
+ if ($factory->supports($dsn)) {
+ return $factory->create($dsn);
+ }
+ }
+
+ throw new UnsupportedSchemeException($dsn);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Recipe/ConsoleInputCollector.php b/core/lib/Drupal/Core/Recipe/ConsoleInputCollector.php
index f1db3a342af1..9feb9bed8da7 100644
--- a/core/lib/Drupal/Core/Recipe/ConsoleInputCollector.php
+++ b/core/lib/Drupal/Core/Recipe/ConsoleInputCollector.php
@@ -93,11 +93,14 @@ final class ConsoleInputCollector implements InputCollectorInterface {
$method = $settings['method'];
$arguments = $settings['arguments'] ?? [];
- // Most of the input-collecting methods of StyleInterface have a `default`
- // parameter.
- $arguments += [
- 'default' => $default_value,
- ];
+ if ($method !== 'askHidden') {
+ // Most of the input-collecting methods of StyleInterface have a `default`
+ // parameter.
+ $arguments += [
+ 'default' => $default_value,
+ ];
+ }
+
// We don't support using Symfony Console's inline validation; instead,
// input definitions should define constraints.
unset($arguments['validator']);
diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php
index 0170626181c0..6927ba2ebbec 100644
--- a/core/lib/Drupal/Core/Session/SessionManager.php
+++ b/core/lib/Drupal/Core/Session/SessionManager.php
@@ -6,6 +6,7 @@ use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
/**
@@ -162,6 +163,16 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
parent::save();
}
+ $allowedKeys = array_map(
+ fn (SessionBagInterface $bag) => $bag->getStorageKey(),
+ $this->bags
+ );
+ $allowedKeys[] = $this->getMetadataBag()->getStorageKey();
+ $deprecatedKeys = array_diff(array_keys($_SESSION), $allowedKeys);
+ if (count($deprecatedKeys) > 0) {
+ @trigger_error(sprintf('Storing values directly in $_SESSION is deprecated in drupal:11.2.0 and will become unsupported in drupal:12.0.0. Use $request->getSession()->set() instead. Affected keys: %s. See https://www.drupal.org/node/3518527', implode(", ", $deprecatedKeys)), E_USER_DEPRECATED);
+ }
+
$this->startedLazy = FALSE;
}
diff --git a/core/lib/Drupal/Core/Template/Loader/ComponentLoader.php b/core/lib/Drupal/Core/Template/Loader/ComponentLoader.php
index d141d202ecb0..e3669f8f1450 100644
--- a/core/lib/Drupal/Core/Template/Loader/ComponentLoader.php
+++ b/core/lib/Drupal/Core/Template/Loader/ComponentLoader.php
@@ -122,13 +122,8 @@ class ComponentLoader implements LoaderInterface {
catch (ComponentNotFoundException) {
throw new LoaderError('Unable to find component');
}
- // If any of the templates, or the component definition, are fresh. Then the
- // component is fresh.
$metadata_path = $component->getPluginDefinition()[YamlDirectoryDiscovery::FILE_KEY];
- if ($file_is_fresh($metadata_path)) {
- return TRUE;
- }
- return $file_is_fresh($component->getTemplatePath());
+ return $file_is_fresh($component->getTemplatePath()) && $file_is_fresh($metadata_path);
}
}
diff --git a/core/lib/Drupal/Core/Theme/Component/ComponentValidator.php b/core/lib/Drupal/Core/Theme/Component/ComponentValidator.php
index 246f143d4e25..ff102b5170a9 100644
--- a/core/lib/Drupal/Core/Theme/Component/ComponentValidator.php
+++ b/core/lib/Drupal/Core/Theme/Component/ComponentValidator.php
@@ -199,7 +199,9 @@ class ComponentValidator {
$errors = array_filter(
$this->validator->getErrors(),
function (array $error) use ($context): bool {
- if (($error['constraint'] ?? '') !== 'type') {
+ // Support 5.0 ($error['constraint']) and 6.0
+ // ($error['constraint']['name']) at the same time.
+ if (($error['constraint']['name'] ?? $error['constraint'] ?? '') !== 'type') {
return TRUE;
}
return !Element::isRenderArray($context[$error['property']] ?? NULL);