Quantcast
Viewing all 294483 articles
Browse latest View live

Date field doesn't allow attributes

My custom form date field is set up as follows:

$form['right']['validfrom'] = array(
      '#type' => 'date',
      '#title' => $this->t('Start date'),
      '#description' => $this->t('The beginning date.'),
      '#attributes' => array('class' => array('lala')),
    );

And the error thrown is the following:

Notice: Undefined index: type in Drupal\Core\Render\Element\Date::processDate() (line 63 of /var/www/website/public_html/core/lib/Drupal/Core/Render/Element/Date.php)
#0 /var/www/website/public_html/core/includes/bootstrap.inc(548): _drupal_error_handler_real(8, 'Undefined index...', '/var/www/website...', 63, Array)
#1 /var/www/website/public_html/core/lib/Drupal/Core/Render/Element/Date.php(63): _drupal_error_handler(8, 'Undefined index...', '/var/www/website...', 63, Array)
#2 [internal function]: Drupal\Core\Render\Element\Date::processDate(Array, Object(Drupal\Core\Form\FormState), Array)
#3 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(981): call_user_func_array(Array, Array)
#4 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(1044): Drupal\Core\Form\FormBuilder->doBuildForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#5 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(1044): Drupal\Core\Form\FormBuilder->doBuildForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#6 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(557): Drupal\Core\Form\FormBuilder->doBuildForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#7 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(314): Drupal\Core\Form\FormBuilder->processForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#8 /var/www/website/public_html/core/lib/Drupal/Core/Controller/FormController.php(74): Drupal\Core\Form\FormBuilder->buildForm('vehicle_main_fo...', Object(Drupal\Core\Form\FormState))
#9 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#10 /var/www/website/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#11 /var/www/website/public_html/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#12 /var/www/website/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#13 /var/www/website/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#14 [internal function]: Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#15 /var/www/website/public_html/vendor/symfony/http-kernel/HttpKernel.php(144): call_user_func_array(Object(Closure), Array)
#16 /var/www/website/public_html/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#17 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/website/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /var/www/website/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /var/www/website/public_html/modules/devel/webprofiler/src/StackMiddleware/WebprofilerMiddleware.php(38): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\webprofiler\StackMiddleware\WebprofilerMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /var/www/website/public_html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /var/www/website/public_html/core/lib/Drupal/Core/DrupalKernel.php(652): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /var/www/website/public_html/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#27 {main}.

I've tested that this happens with whatever attribute you try to set and works perfectly when no attribute set.

EDIT adding more debugging info:

The code in /core/lib/Drupal/Core/Render/Element/Date for the relevant parts is:

class Date extends FormElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#theme' => 'input__date',
      '#process' => [[$class, 'processDate']],
      '#pre_render' => [[$class, 'preRenderDate']],
      '#theme_wrappers' => ['form_element'],
      '#attributes' => ['type' => 'date'],
      '#date_date_format' => 'Y-m-d',
    ];
  }

  /**
   * Processes a date form element.
   *
   * @param array $element
   *   The form element to process. Properties used:
   *   - #attributes: An associative array containing:
   *     - type: The type of date field rendered.
   *   - #date_date_format: The date format used in PHP formats.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form structure.
   *
   * @return array
   *   The processed element.
   */
  public static function processDate(&$element, FormStateInterface $form_state, &$complete_form) {
    // Attach JS support for the date field, if we can determine which date
    // format should be used.
    if ($element['#attributes']['type'] == 'date'&& !empty($element['#date_date_format'])) {
      $element['#attached']['library'][] = 'core/drupal.date';
      $element['#attributes']['data-drupal-date-format'] = [$element['#date_date_format']];
    }
    return $element;
  }

The sequence the code is processed is:

  1. Creation of field in custom form code
  2. Date::getInfo()
  3. Date::processDate()
  4. Date::preRenderDate - not relevant here

So now if I dpm($element) in Date::processDate()

when there's no attributes set in my field the element seems to have the attributes returned from Date::getInfo() :

Image may be NSFW.
Clik here to view.
attributes from getInfo

But when I set attributes from my own field declaration they seem to override the attributes all together:

Image may be NSFW.
Clik here to view.
Attributes from field declaration

All my other fields work fine with attributes just the date seems to be going crazy.


Document that Database/Connection::escapeLike() does not work when used with Database/Connection::query() and Database/Connection::queryRange()

Document that you cannot use the method \Drupal\Core\Database\Connection::escapeLike() in the query builder methods \Drupal\Core\Database\Connection::query() and \Drupal\Core\Database\Connection::queryRange().
You can only use the method \Drupal\Core\Database\Connection::escapeLike() in the query builder \Drupal\Core\Database\Connection::select().

Codespell report for Drupal 8.8.0

The FOSS server fossies.org offers a new feature "Source code misspelling reports":

https://fossies.org/features.html#codespell

Although such reports are normally only generated on request, as Fossies administrator I have just created (for testing purposes) an analysis for the current Drupal release 8.8.0:

https://fossies.org/linux/www/drupal/codespell.html

That version-independent URL should redirect always to the last report (if available), so currently to

https://fossies.org/linux/www/drupal-8.8.0.tar.gz/codespell.html

The result is surprisingly very good (Fossies internal rank "A") so I assume that there are similar checks were already done in the past.

Although some obviously wrong matches (false positives) are already filtered (ignored) please inform me if you find more of them so that I can force a new improved check if applicable.

Just for information there are also two supplemental pages

https://fossies.org/linux/www/drupal/codespell_conf.html

showing some used "codespell" configurations and

https://fossies.org/linux/www/drupal/codespell_fps.html

showing all resulting obvious "False Positives".

Especially I would point to the spelling "defintion" (instead of "definition"?) at lines 37 and 38 of the file "EntityTypeTest.php" browsable for e.g. via

https://fossies.org/linux/www/drupal-8.8.0.tar.gz/drupal-8.8.0/core/test...

but I'm not a PHP-expert so that may be the desired name.

[Drupal 9] Update autloader-suffix in composer.json

Currently it is still set to "Drupal8".

PhpUnit make test results more developer friendly

One thing I am always missing when running tests through command line is finding HTML output file by URL of HTTP request logged in it. I propose adding a meaningful label above each reference on HTML output file (see attached screenshots).

Create classy directory with README, in the templates directory for all themes subtheming Classy

Problem/Motivation

As detailed in #3050389: Remove dependency to Classy from core themes, Classy will be moved to contrib before Drupal 9 and we have to remove dependencies on Classy from all core themes.

Part of this process is creating theme-specific copies of any templates that were previously inherited from Classy. There should be an easy way to distinguish these used-to-be-Classy templates from ones created specifically for a theme.

Proposed resolution

In the templates directory for every core theme subtheming Classy, add a classy directory with a README explaining that:
- It is for templates copied from Classy,
- If a template in this directory is altered it should be moved outside the classy directory as it's now theme-specific.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

AdminNegotiator::determineActiveTheme() does not adhere to the interface

Problem/Motivation

\Drupal\Core\Theme\ThemeNegotiator::determineActiveTheme() only checks for NULL so \Drupal\user\Theme\AdminNegotiator::determineActiveTheme() should return NULL when the admin theme is empty — i.e. the admin theme should be the default theme ie. should fallback to \Drupal\Core\Theme\DefaultNegotiator

Proposed resolution

Detect empty string and return NULL instead.

Atm you can also get "0" as a value but that's being taken care of in #2587119: Form sets system.theme:admin to '0' breaking Quick Edit and making no sense

Remaining tasks

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

N/A

Path alias filter by system path

Problem/Motivation

Currently core's Path modules allows to filter url aliases only by alias itself. It is often required to filter by system path, instead of alias.

The only solution I use is to query database directly, which is very inconvenient.

Proposed resolution

Add a filter for system path.

Remaining tasks

User interface changes

New filter

API changes

N/A

Data model changes

N/a


Experimental modules should not have warnings after being installed

Problem/Motivation

Back in #2657178: Warn about experimental modules on their help pages there was an issue to add warnings in three places once an experimental module is installed.

  • During install
  • On the modules page
  • in the site status

However, this commit has introduced a serious flaw in the UX for experimental modules on a drupal site. In general...

  • Warnings must be actionable
  • The site should not question the decisions of a site builder once a decision should be made
  • The site should inform the site builder the implications of installing an experimental module and provide documentation on where to find the status of the experimental module.

This has real consequences for 1st tier drupal shops, which run into issues when using otherwise best practices for drupal development. Not all experimental modules are equal, and the decision to use an experimental module, once installed, should not be questioned by the site. The lightning distribution is currently using layout discovery, which should be encouraged over the deprecated and unsupported layout plugin module.

Also note, there was no UX review of the previous issue, and it was hastily committed within 2 days. It should have not been committed without proper UX review and community feedback.

Proposed resolution

  1. Remove the warning from the status page.
  2. Remove the warning from the modules page.
  3. Add a better install notification/confirmation when installing an experimental module via the UI. This has basic support, but a handbook link or link to the status of experimental modules would be helpful.
  4. Encourage drush to add a confirmation before installing an experimental module, using the same url to reference users to the status of experimental modules. Filed https://github.com/drush-ops/drush/issues/2770

Remaining tasks

Create a patch to revert the warning from post install actions. Follow up with additional patch to make the confirmation page better when installing experimental modules.

User interface changes

Experimental modules should display a warning message only on the module confirmation install page.

API changes

N/A

Data model changes

N/A

Allow trailing slash to be added for home page

Some SEO experts expect trailing slash on all the urls, including home page. Currently this is possible for all the urls but home page.

Offending code is in Drupal\Core\Routing\UrlGenerator::generateFromRoute():

if (!empty($options['prefix'])) {
      $path = ltrim($path, '/');
      $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
      $path = '/' . str_replace('%2F', '/', rawurlencode($prefix)) . $path;
    }

Suggested solution

By default $path contains empty string for home page but we can change it to forward slash using OutboundPathProcessor. Respect this and do not remove slash if it is the only thing in $path

Missing url prefix on language neutral content

What are the steps required to reproduce the bug?

  • Install a new Drupal instance
  • Add an additional language (e.g. italian)
  • Use URL negotiation and configure path prefixes (e.g. /en for english and /it for italian)
  • Enable the language selector for content type
  • Create new node using "not specified" as language
  • Go to /it/admin/content

What behavior were you expecting?

The main link to the entity inside the content table should link to /it/node/1 (the current user interface language based on the url /it/admin/content).

What happened instead?

The main link to the entity inside the content table links to /node/1, which changes the site language (based on language path prefix) back to english.


I added a simple patch, but I'm not sure about consequences outside the described use-case.
The $entity->toURL() method adds the entities current language as an URL option to the link generator. The provided patch applies the current language as a prefix base if the nodes language is "not specified".

Error: Call to a member function getLabel() after enabling layout_builder

Existing drupal 8 site (upgraded from 8.2.x to 8.3, 8.4, 8.5). Current version 8.5.5 . If I enable layout_builder, then:

Error: Call to a member function getLabel() on null in Drupal\layout_builder\Plugin\Derivative\FieldBlockDeriver->getDerivativeDefinitions() (line 111 of /home/agwophqf/public_html/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php) #0 /home/agwophqf/public_html/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php(101): Drupal\layout_builder\Plugin\Derivative\FieldBlockDeriver->getDerivativeDefinitions(Array) #1 /home/agwophqf/public_html/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php(87): Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDerivatives(Array) #2 /home/agwophqf/public_html/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php(284): Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDefinitions() #3 /home/agwophqf/public_html/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php(175): Drupal\Core\Plugin\DefaultPluginManager->findDefinitions() #4 /home/agwophqf/public_html/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryCachedTrait.php(22): Drupal\Core\Plugin\DefaultPluginManager->getDefinitions() #5 /home/agwophqf/public_html/core/lib/Drupal/Core/Plugin/Factory/ContainerFactory.php(16): Drupal\Core\Plugin\DefaultPluginManager->getDefinition('system_main_blo...') #6 /home/agwophqf/public_html/core/lib/Drupal/Component/Plugin/PluginManagerBase.php(76): Drupal\Core\Plugin\Factory\ContainerFactory->createInstance('system_main_blo...', Array) #7 /home/agwophqf/public_html/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php(62): Drupal\Component\Plugin\PluginManagerBase->createInstance('system_main_blo...', Array) #8 /home/agwophqf/public_html/core/modules/block/src/BlockPluginCollection.php(57): Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->initializePlugin('system_main_blo...') #9 /home/agwophqf/public_html/core/lib/Drupal/Component/Plugin/LazyPluginCollection.php(80): Drupal\block\BlockPluginCollection->initializePlugin('system_main_blo...') #10 /home/agwophqf/public_html/core/modules/block/src/BlockPluginCollection.php(45): Drupal\Component\Plugin\LazyPluginCollection->get('system_main_blo...') #11 /home/agwophqf/public_html/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php(83): Drupal\block\BlockPluginCollection->get('system_main_blo...') #12 /home/agwophqf/public_html/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php(99): Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->setConfiguration(Array) #13 /home/agwophqf/public_html/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php(55): Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->addInstanceId('system_main_blo...', Array) #14 /home/agwophqf/public_html/core/modules/block/src/BlockPluginCollection.php(34): Drupal\Core\Plugin\DefaultSingleLazyPluginCollection->__construct(Object(Drupal\Core\Block\BlockManager), 'system_main_blo...', Array) #15 /home/agwophqf/public_html/core/modules/block/src/Entity/Block.php(149): Drupal\block\BlockPluginCollection->__construct(Object(Drupal\Core\Block\BlockManager), 'system_main_blo...', Array, 'bone_content') #16 /home/agwophqf/public_html/core/modules/block/src/Entity/Block.php(138): Drupal\block\Entity\Block->getPluginCollection() #17 /home/agwophqf/public_html/core/modules/block/src/BlockAccessControlHandler.php(113): Drupal\block\Entity\Block->getPlugin() #18 /home/agwophqf/public_html/core/lib/Drupal/Core/Entity/EntityAccessControlHandler.php(105): Drupal\block\BlockAccessControlHandler->checkAccess(Object(Drupal\block\Entity\Block), 'view', Object(Drupal\Core\Session\AccountProxy)) #19 /home/agwophqf/public_html/core/lib/Drupal/Core/Entity/Entity.php(366): Drupal\Core\Entity\EntityAccessControlHandler->access(Object(Drupal\block\Entity\Block), 'view', Object(Drupal\Core\Session\AccountProxy), true) #20 /home/agwophqf/public_html/core/modules/block/src/BlockRepository.php(56): Drupal\Core\Entity\Entity->access('view', NULL, true) #21 /home/agwophqf/public_html/core/modules/block/src/Plugin/DisplayVariant/BlockPageVariant.php(137): Drupal\block\BlockRepository->getVisibleBlocksPerRegion(Array) #22 /home/agwophqf/public_html/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(259): Drupal\block\Plugin\DisplayVariant\BlockPageVariant->build() #23 /home/agwophqf/public_html/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(117): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #24 /home/agwophqf/public_html/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #25 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #26 /home/agwophqf/public_html/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #27 /home/agwophqf/public_html/vendor/symfony/http-kernel/HttpKernel.php(156): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent)) #28 /home/agwophqf/public_html/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #29 /home/agwophqf/public_html/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #30 /home/agwophqf/public_html/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #31 /home/agwophqf/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #32 /home/agwophqf/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #33 /home/agwophqf/public_html/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #34 /home/agwophqf/public_html/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #35 /home/agwophqf/public_html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #36 /home/agwophqf/public_html/core/lib/Drupal/Core/DrupalKernel.php(666): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #37 /home/agwophqf/public_html/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #38 {main}.

loadUnchanged() should check the id

ContentEntityStorageBase::loadUnchanged() implies that its argument is a valid entity id, but never checks it. Supplying, eg, NULL as an argument can lead to a number of side-effects, such as resetting static cache, calling preload hook for all entities etc, to say nothing about just time it takes. It should return NULL and exit instead.

Add allowfullscreen attribute for remote media rendered in Iframe

The properties of the upper iframe are missing the allowfullscreen = "" property. Therefore, full-screen mode will not work with remote videos.

Migrations fail due to missing dependency when dependency is clearly not missing.

Problem/Motivation

When running a migration via one or more drush commands, the dependencies between the migrations are not being recognized as successfully met, even if they have completed execution.

Processed 13725 items (13725 created, 0 updated, 0 failed, 0 ignored) - done with 'asset_files_migration'                                                              [status]
Migration uploaded_document_migration did not meet the requirements. Missing migrations asset_files_migration. requirements: asset_files_migration.                             [error]
Migration media_entity_migration did not meet the requirements. Missing migrations asset_files_migration. requirements: asset_files_migration.                                [error]

This was found in a system running Drupal 8.1.8 with Migrate Plus & Migrate Tools.

Proposed resolution

Solve for X.

Remaining tasks

Root cause, solution, test, victory.

User interface changes

None anticipated.

API changes

???

Data model changes

???

From Original Post

I did not receive any errors relating to memory limits like in this issue, https://www.drupal.org/node/2701121 although the problem seems very similar-- the dependency is clearly there but not recognized.


Database reserved keywords need to be quoted as per the ANSI standard

Problem/Motivation

Over many years Drupal has held off checking queries for reserved words in column names, table names and aliases because it was a design decision. The idea is that we just just should not use reserved words. However, time has made it clear that this position (as stated in the long discussions in #371: resolve ANSI SQL-92/99/2003 reserved words conflict in query statements) is not really tenable. Here are the problems:

  • The list of reserved words is different for different database drivers even those the support the various ANSI SQL standards. For example OFFSET is reserved in PostgreSQL but not in MySQL
  • Database drivers add new reserved keywords in new versions. MySQL has been doing this in every new version for example 5.7 and 8

Proposed resolution

  • Add a new syntax square bracket syntax to the query builder to know what identifiers (column names/ aliases) are. Leverage work in #371: resolve ANSI SQL-92/99/2003 reserved words conflict in query statements suggested using [COLUMN_NAME] to match {TABLE_NAME}. This supports db_query(), addExpression() and addWhere()
  • Automatically quote fields and aliases in escapeField() and escapeAlias().
  • All identifiers should be quoted. This helps us ensure that the database API is properly used when query building and will make edge-cases less likely.

Using [] to identify identifiers (field names / aliases)

There is precedence - this is the quote character in MSSQL.

The one consideration is that :variable[] is used to identify and expand array variables.

Discarded resolution(s)

We could deprecate SELECT, UPDATE, INSERT queries via \Drupal\Core\Database\Connection::query() since the methods like \Drupal\Core\Database\Connection::select() require fields to be specified. If we do that we have to worry about performance - see #1067802: Compare db_query() and db_select() performance. Also this does not work for columns added using ->addExpression() or ->addWhere(). Therefore this resolution has been discarded.

Remaining tasks

Fix the blockers:

File follow-ups:

  • add coder rule to try to check for missing []
  • Ensure core uses new square bracket syntax

User interface changes

None

API changes

At the moment \Drupal\Core\Database\Connection::escapeField() and \Drupal\Core\Database\Connection::escapeAlias() in their core implementations are re-entrant. And some core code relies on this. That said the docs hint that this should not be case. In the new implementation methods also now quote identifiers BUT because the code removes the quotes before adding them they still are re-entrant. The new implementations result in strings like users_data.uid becoming "users_data"."uid".

\Drupal\Core\Database\Query\ConditionInterface::condition()'s first argument $field must be a field and cannot be (ab)used to do ->condition('1 <> 1'). The way to do this is to use the new API added by #2986334: Add a way to enforce an empty result set for a database condition query

\Drupal\Core\Database\Connection::prepareQuery() now takes additionally takes a boolean that is derived from a query's $options['allow_square_brackets'] value that allows specific queries to use square brackets and to not them for identifier quotes. The default value for $options['allow_square_brackets'] is FALSE.

\Drupal\Core\Database\Connection::prefixTables now quotes tables so {node} becomes "node".

Data model changes

None

Release notes snippet

All identifiers (table names, database names, field names and aliases) are quoted in database queries. Column names or aliases should be wrapped in square brackets when using Connection::query(), db_query(), ConditionInterface::where() or SelectInterface::addExpression. Custom or contrib database drivers should read https://www.drupal.org/node/2986894 to see what changes are necessary.

ContentEntityStorageBase::loadRevision() should use the static and the persistent entity cache like ContentEntityStorageBase::load()

Problem/Motivation

#597236: Add entity caching to core added the entity cache to core, but unfortunately it did not consider enabling it when loading an entity by revision ID.
There are contrib modules such as Entity Reference Revisions, Paragraphs and core modules such as Content Moderation, which rely heavily on loading entity revisions.

A developer might build a system where she is using ContentEntityStorageBase::loadRevision() to load a default entity revision and by doing so one will currently not profit from the entity cache.

ContentEntityStorageBase::loadRevision() is neither using the static entity cache nor the persistent entity cache, which has as a consequence that the function is inconsistent with ContentEntityStorageBase::load(), as if you retrieve an entity multiple times in a single request with the latter one it will always return a reference to the same entity object, but if you retrieve it multiple times with the former one you will always get a new entity object and thus a completely different object reference.

The attached test demonstrates all the problems.

Proposed resolution

  1. Enable static entity caching for ContentEntityStorageBase::loadRevision() for all revisions.
  2. Enable persistent entity caching for ContentEntityStorageBase::loadRevision() for all revisions.
  3. Ensure that ContentEntityStorageBase::load() and ContentEntityStorageBase::loadRevision() return a reference to the same entity object, if loading the default entity revision.
  4. To ensure backwards compatibility $storage::resetCache() will be invalidating all cached revisions. Include an optimization to invalidate only the default revision when the entity has only revisionable fields.

Remaining tasks

Review.

User interface changes

none

API changes

  1. \Drupal\Core\Entity\RevisionableStorageInterface::loadRevisionUnchanged() to load an entity revision bypassing the static cache.
  2. \Drupal\Core\Entity\RevisionableStorageInterface::resetRevisionCache($revision_id) for reseting the static and persistent cache for specific revision IDs
  3. $storage->loadRevision($revision_id) === $storage->loadRevision($revision_id)now evaluates to TRUE
  4. $storage->load($id) === $storage->loadRevision($revision_id)now evaluates to TRUE if $revision_id references the current default revision

Data model changes

none

link with data-dialog-type="modal" doesn't work for external URL's

Im using drupal 8.7.8

I can open a url on my site in a dialog with:

<p><a class="use-ajax" data-dialog-options="{&quot;width&quot;:800}" data-dialog-type="modal" href="/node/add/article">Add article</a></p>

But I can't open cross domain (external) page in a dialog using exact same params - only changing href.

<p><a class="use-ajax" data-dialog-options="{&quot;width&quot;:800}" data-dialog-type="modal" href="https://crossdomain.co.uk">Open another website</a></p>

I cant see reason for this documented anywhere so assume its a bug?

How do I open an external link in a modal dialog? e.g. social network share pages etc. very common on other sites and blogs.

thanks

Add a new Drupal.theme JavaScript function for theming the the show/hide row weight toggle and its wrapper in draggable tables

Problem/Motivation

Drupal core's tabledrag.js uses a hard-coded markup for the tabledrag toggle height markup and its wrapper div that are not overridable by themes.

Proposed resolution

  1. Introduce new Drupal.theme callback for the toggle weight (visibility) button.
  2. Introduce new Drupal.theme callback for the toggle button wrapper.
  3. Refactor tabledrag.js and fully replace the toggle if it is changed. This is required for adding different icons for the 'show' and the 'hide' action.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Create a method of filtering one field by its relation to another field

Viewing all 294483 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>