Problem/Motivation

When some devel/profiling modules like webprofiler are enabled I get the following warning:

Warning: uasort(): Array was modified by the user comparison function in Drupal\token\Token->getInfo() (line 56 of modules/contrib/token/src/Token.php).

Proposed resolution

Use SortArray::stableUasort(() instead of uasort().

Remaining tasks

This can not be added before the issue '#2466097: uasort() does NOT preserve sort order, but core assumes so (Element::children, css sort, ...)' is solved

CommentFileSizeAuthor
#10 interdiff_9-10.txt1.61 KBAnonymous (not verified)
#10 token-separate_sort-2671060-10.patch2.31 KBAnonymous (not verified)
#9 token-separate_sort-2671060-9.patch1.97 KBAnonymous (not verified)
#2 token-use_stable_uasort-2671060-1-D8-do-not-test.patch1.88 KBweri
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

weri created an issue. See original summary.

weri’s picture

Status: Active » Needs review
FileSize
1.88 KB
3eidoz’s picture

same error here in D8.0.3 then D8.0.4

Warning: uasort(): Array was modified by the user comparison function in Drupal\token\Token->getInfo() (line 56 of modules/token/src/Token.php).
Drupal\token\Token->getInfo()
Drupal\metatag\MetatagToken->coreReplace('[current-page:title] | [site:name]', Array, Array)
Drupal\metatag\MetatagToken->contribReplace('[current-page:title] | [site:name]', Array, Array)
Drupal\metatag\MetatagToken->tokenReplace('[current-page:title] | [site:name]', Array)
Drupal\metatag\MetatagManager->generateElements(Array, NULL)
metatag_get_tags_from_route()
metatag_page_attachments(Array)
Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\debug_bar\DebugBarMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1)
Stack\StackedHttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)

Jose Reyero’s picture

The solution for this bug would be IMO just not ordering tokens here.

The issue is explained here which, well, may be a duplicate (I've just moved it from Metatag module), https://www.drupal.org/node/2670942#comment-11353379

Berdir’s picture

Status: Needs review » Postponed

Token info is cached per language and not everything is interface text, some token labels are based on configuration for example. So I think this is the right place for sorting them.

Making it clear that this is postponed on the mentioned core issue.

RavindraSingh’s picture

Same issue, any workaround ?

Warning: uasort(): Array was modified by the user comparison function in Drupal\token\Token->getInfo() (line 51 of modules/contrib/token/src/Token.php).
Drupal\token\Token->getInfo() (Line: 249)
token_get_token_problems() (Line: 16)
token_requirements('runtime')
call_user_func_array('token_requirements', Array) (Line: 402)
Drupal\Core\Extension\ModuleHandler->invokeAll('requirements', Array) (Line: 112)
Drupal\system\SystemManager->listRequirements() (Line: 48)
Drupal\system\Controller\SystemInfoController->status()
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
call_user_func_array(Object, Array) (Line: 139)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 62)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 38)
Drupal\webprofiler\StackMiddleware\WebprofilerMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 628)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
RavindraSingh’s picture

Status: Postponed » Needs work
Berdir’s picture

#2797547: Cached sorted tokens in Token::getInfo fixed the ones in Token::getInfo(), we can convert the other one in a similar way and don't have to wait on the core issue, which likely will never land given that array_multisort() is the better solution.

Anonymous’s picture

With array_multisort numeric keys will be re-indexed. Hence, we can not use keys of sorted $children to $elements when we've sparse array.
Or do you propose to split the "#items" and then merged it with sorted $children?

Also, may be to make the sort out of the token_element_children()?

Anonymous’s picture

FileSize
2.31 KB
1.61 KB

Also, we can change the $elements only when changed the order of items. And return $keys from sort function for clarity.

+++ b/token.module
@@ -676,13 +676,13 @@ function token_element_children(&$elements, $sort = FALSE) {
-    sort_token_element_children($elements, $keys);
+    $keys = sort_token_element_children($elements, $keys);

@@ -699,18 +699,21 @@ function sort_token_element_children(&$elements, $keys)
   // Sort the children if necessary.
   if ($sortable) {
     asort($weights);
-    $keys = array_keys($weights);
+    $new_keys = array_keys($weights);
+    if($new_keys != $keys) {
+      $keys = $new_keys;
+      #and rerange $elements
+      ....
+  return $keys;
Berdir’s picture

Status: Needs work » Closed (duplicate)