🇮🇩 GMT+7
Account created on 29 February 2008, over 17 years ago
#

Merge Requests

More

Recent comments

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Have we already decided to use import map? Another option with the new installation method is using UMD build, which shouldn't be blocked by anything

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I do more benchmarking with https://www.php.net/manual/en/class.ds-set.php extension with add() method, and it is the most performant with the same behaviour as array_unique(array_merge())

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I did some benchmarks with this

use Drupal\Core\Cache\Cache;

final class CacheMergeTagsBench {

  private const int RANGE = 100;

  public function benchCore(): void {
    $tags = [];
    foreach (range(1, self::RANGE) as $i) {
      $tags = Cache::mergeTags($tags, [(string) $i, (string) $i]);
    }
  }

  public function benchArrayPushUniqueInLoop(): void {
    $tags = [];
    foreach (range(1, self::RANGE) as $i) {
      foreach ([(string) $i, (string) $i] as $tag) {
        $tags[] = $tag;
      }
      $tags = array_values(array_unique($tags));
    }
  }

  public function benchArrayMergeUniqueOutsideLoop(): void {
    $tags = [];
    foreach (range(1, self::RANGE) as $i) {
      $tags = array_merge($tags, [(string) $i, (string) $i]);
    }
    $tags = array_values(array_unique($tags));
  }

  public function benchArrayPushUniqueOutsideLoop(): void {
    $tags = [];
    foreach (range(1, self::RANGE) as $i) {
      foreach ([(string) $i, (string) $i] as $tag) {
        $tags[] = $tag;
      }
    }
    $tags = array_values(array_unique($tags));
  }

}

Here are the results:

RANGE = 100

CacheMergeTagsBench
===================

Average iteration times by variant

232.2μs   │ █
203.1μs   │ █
174.1μs   │ █
145.1μs   │ █
116.1μs   │ █ █
87.1μs    │ █ █
58.0μs    │ █ █ █
29.0μs    │ █ █ █ ▇
          └─────────
            1 2 3 4

[█ <current>]

1: benchCore            2: benchArrayPushUniqu᠁ 3: benchArrayMergeUniq᠁ 4: benchArrayPushUniqu᠁


<current>
+-------------------------------------+---------+-----------+---------+-----------+
| subject                             | memory  | mode      | rstdev  | stdev     |
+-------------------------------------+---------+-----------+---------+-----------+
| benchCore ()                        | 8.648mb | 232.153μs | ±81.02% | 312.908μs |
| benchArrayPushUniqueInLoop ()       | 8.649mb | 115.196μs | ±3.33%  | 3.899μs   |
| benchArrayMergeUniqueOutsideLoop () | 8.649mb | 57.742μs  | ±6.06%  | 3.611μs   |
| benchArrayPushUniqueOutsideLoop ()  | 8.649mb | 24.448μs  | ±7.30%  | 1.855μs   |
+-------------------------------------+---------+-----------+---------+-----------+

RANGE = 1_000

CacheMergeTagsBench
===================

Average iteration times by variant

8.7ms     │ █
7.6ms     │ █ ▃
6.5ms     │ █ █
5.4ms     │ █ █
4.3ms     │ █ █
3.2ms     │ █ █ █
2.2ms     │ █ █ █
1.1ms     │ █ █ █ ▂
          └─────────
            1 2 3 4

[█ <current>]

1: benchCore            2: benchArrayPushUniqu᠁ 3: benchArrayMergeUniq᠁ 4: benchArrayPushUniqu᠁


<current>
+-------------------------------------+---------+-----------+--------+-----------+
| subject                             | memory  | mode      | rstdev | stdev     |
+-------------------------------------+---------+-----------+--------+-----------+
| benchCore ()                        | 8.648mb | 8.665ms   | ±2.87% | 251.757μs |
| benchArrayPushUniqueInLoop ()       | 8.649mb | 6.787ms   | ±0.78% | 52.716μs  |
| benchArrayMergeUniqueOutsideLoop () | 8.649mb | 3.171ms   | ±1.35% | 42.865μs  |
| benchArrayPushUniqueOutsideLoop ()  | 8.649mb | 176.902μs | ±2.94% | 5.238μs   |
+-------------------------------------+---------+-----------+--------+-----------+

RANGE = 10_000

CacheMergeTagsBench
===================

Average iteration times by variant

803.8ms   │ █
703.3ms   │ █ ▃
602.8ms   │ █ █
502.4ms   │ █ █
401.9ms   │ █ █ ▂
301.4ms   │ █ █ █
200.9ms   │ █ █ █
100.5ms   │ █ █ █ ▁
          └─────────
            1 2 3 4

[█ <current>]

1: benchCore            2: benchArrayPushUniqu᠁ 3: benchArrayMergeUniq᠁ 4: benchArrayPushUniqu᠁


<current>
+-------------------------------------+---------+-----------+---------+-----------+
| subject                             | memory  | mode      | rstdev  | stdev     |
+-------------------------------------+---------+-----------+---------+-----------+
| benchCore ()                        | 8.648mb | 803.765ms | ±19.56% | 174.104ms |
| benchArrayPushUniqueInLoop ()       | 8.649mb | 630.155ms | ±0.17%  | 1.100ms   |
| benchArrayMergeUniqueOutsideLoop () | 8.649mb | 322.530ms | ±20.93% | 75.267ms  |
| benchArrayPushUniqueOutsideLoop ()  | 8.649mb | 1.899ms   | ±5.04%  | 98.035μs  |
+-------------------------------------+---------+-----------+---------+-----------+

RANGE = 20_000

CacheMergeTagsBench
===================

Average iteration times by variant

3.3s      │ █
2.9s      │ █ ▃
2.5s      │ █ █
2.0s      │ █ █
1.6s      │ █ █ ▂
1.2s      │ █ █ █
817.6ms   │ █ █ █
408.8ms   │ █ █ █ ▁
          └─────────
            1 2 3 4

[█ <current>]

1: benchCore            2: benchArrayPushUniqu᠁ 3: benchArrayMergeUniq᠁ 4: benchArrayPushUniqu᠁


<current>
+-------------------------------------+---------+---------+---------+-----------+
| subject                             | memory  | mode    | rstdev  | stdev     |
+-------------------------------------+---------+---------+---------+-----------+
| benchCore ()                        | 8.648mb | 3.270s  | ±7.65%  | 264.635ms |
| benchArrayPushUniqueInLoop ()       | 8.649mb | 2.558s  | ±7.49%  | 198.958ms |
| benchArrayMergeUniqueOutsideLoop () | 8.649mb | 1.318s  | ±10.64% | 147.986ms |
| benchArrayPushUniqueOutsideLoop ()  | 8.649mb | 3.752ms | ±2.05%  | 76.243μs  |
+-------------------------------------+---------+---------+---------+-----------+

Calling both array_merge and array_unique in a loop is a significant performance hit. Array merge can be replaced with $tags[] = $tag without any side effects, as we don't care about the array keys.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I do wonder if we should strip the data-entity-metadata attribute on page output, this can expose information that wouldn't have been exposed before when linking to a page, most importantly the author. As an anonymous user I see this in the markup:

Since this already requires a filter plugin, it is probably worth removing that attribute in the filter.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I've changed the actionsView to toolbarView.

I also removed previewButton.setTemplate as I'm not sure if it is still required. Instead, I bind the preview button href and label property to the entity metadata.

There are failed tests, which I think are related to the UI changes, but I don't have the bandwidth to look at them at the moment.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

frankenphp server won't start properly on https://www.drupal.org/project/drupal/issues/3437187 📌 Add Caddyfile configuration Active .

running frankenphp php-server -a -d gives

Error: flag needs an argument: 'd' in -d

we should get rid of -d or pass something like localhost.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

looking at the failed test

cURL error 7: Failed to connect to localhost port 80 after 0 ms: Couldn't connect to server

this seems like the frankenphp server not started properly.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I made a new MR based on 3.x branch as I can't change the base branch on the existing MR

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos created an issue.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

This is no longer needed, HEAD is already green and there are no code sniffer issues.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I wouldn't say hook implementations can replace event dispatcher altogether.

I can add a listener to the event dispatcher dynamically on runtime.

$anon = new class {
  public function userCancel(): void {
  }
};
$eventDispatcher->addListener(UserCancelEvent::class, [$anon, 'userCancel']);

When the event is dispatched, the anonymous class's method is called. However, the same thing does not work with hook implementations.

$eventDispatcher->addListener('drupal_hook.user_cancel', [$anon, 'userCancel']);

I'm not sure if this is a bug or if this is intended, but at the very least there is a feature missing if we want to replace event dispatcher.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I tried adding duplicate components in test, but can’t reproduce the crash.
Q: do we have any plugin manager/discovery that throws exception when there are duplicate plugins?

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I have a try at this. I move the responsibility to check the requirements to the component source plugin.

There is not much change in MR; it only moves some code and adds new methods for the component source plugins.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I can start with decorating the BlockManager.

Is storing the reasons in the component source definition make sense?

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I can start with decorating the BlockManager.

Does storing the reasons in the component source definition make sense?

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

When disabling a block component, it will get into \Drupal\experience_builder\Plugin\ComponentPluginManager::REASONS_STATE_KEY already.

This is the snippet that does this in \Drupal\experience_builder\Controller\ComponentStatusController::performOperation:

$reasons = $this->state->get(ComponentPluginManager::REASONS_STATE_KEY);
if ($op === 'disable') {
  $component->disable()->save();
  $reasons[$component->getComponentPluginId()] = 'Manually disabled';
}
...
$this->state->set(ComponentPluginManager::REASONS_STATE_KEY, $reasons);

But, this state will be rebuilt each time component plugin definitions are rebuilt, which only accounts for SDC source. Perhaps each component source can define its own state key for where to store its reasons, and then use \Drupal\Core\State\StateInterface::getMultiple for each component source in \Drupal\experience_builder\Controller\ComponentStatusController

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

lets wait for 📌 Revert case sensitive use-statement sniff Active , and no need to change the phpcs config

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Postponing as this possibly due to custom code or other contrib modules. The view mode isn't meant to be null, core itself have 'full' for default value.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

left some comments in the MR

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos changed the visibility of the branch 2.7.x to hidden.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I had an attempt at this. Components inserted via the sidebar will then be selected, although the component setting panel will be opened before the component is fully rendered.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Oops sorry, accidentally changed status

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Apologize for coming late, I had some time looking at this.

When I disable a block component via /admin/structure/component, I can't enable it back again with an error message

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "local_tasks_block" plugin does not exist.

.

Is this something to worry about? Or should this be a follow-up issue?

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7
/**
 * This hook is NOT invoked for the 'user_cancel_delete' account cancellation
 * method. To react to that method, implement hook_ENTITY_TYPE_predelete() or
 * hook_ENTITY_TYPE_delete() for user entities instead.
 */

This can be achieved by subscribing to:

  • \Drupal\core_event_dispatcher\EntityHookEvents::ENTITY_PRE_DELETE
  • \Drupal\core_event_dispatcher\EntityHookEvents::ENTITY_DELETE
🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I just added a test case to validate the bug

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

This is a valid, both \Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent::getArguments and \Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent::setArguments won't work.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I updated tests for 10.3 per #3459926-14: Update CKEditor 5 to 42.0.0 . I have pushed the changes but can't reopen the MR, should I create a new MR?

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos changed the visibility of the branch 3477799-bump-ckeditor5-10.3.x to hidden.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos changed the visibility of the branch 3477799-bump-ckeditor5-10.3.x to active.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

It's a best practice to inject the interface instead, as implementation can change.

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler;

Injecting interface means you can swap implementation without changing the code.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I still think this is a duplicate as it is the same issue. Can you provide more detail if this is not a duplicate?

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos created an issue.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos created an issue.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos created an issue.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Tests on D11 are still blocked on webform dependency, we need to figure out what to do with it.

One option is to remove webform from dev dependency and skip the webform tests, unless we can separate dependency for D10 and D11.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

el7cosmos made their first commit to this issue’s fork.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Most plugins already have a common interface. An interface for each plugin seems too verbose for most and probably ends up being an empty interface.

From what I understand, the concern was raised because there is no way yet to deprecate a plugin and this is an issue for FQCN as plugin ID, not as alias. Alias definition will still have the same plugin ID (eg Entity type with alias Node::class will still have a definition with ID node). Plugin ID will still end up in configurations, alias will always used in code and never in configurations. When a plugin class is deprecated this won't be a problem as long as the class is tagged as @deprecated.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I just removed additional test

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I don't think the related issue is a parent of this, the discussion is more about the plugin ID itself. But in this, we keep the plugin ID as it is, and introduce an alias, which is new, and we can set a new convention around it without worrying about backward compatibility.

As for the FQCN, using FQCN as a method/function argument doesn't necessarily mean we are requesting an instance of that class. If we take a look at this:

\Drupal::entityTypeManager()->getStorage(\Drupal\node\Entity\Node::class);

We don't want an instance of that class, we want something else.

Using FQCN as an argument means better IDE support which will then improve DX.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

I make an attempt for aliases in 💬 Allow plugin definition to be aliased Active

That at least works for something like this:

\Drupal::entityTypeManager()->getStorage(\Drupal\node\Entity\Node::class);
\Drupal::entityTypeManager()->getDefinition(\Drupal\node\Entity\Node::class);
🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Adding aliases directly to the definitions causes problem with various plugin manager as they need some properties of the definitions when processing it. Changing the IS for a different approach.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

If we want this by default, do we need to update the existing field config?

It may also make more sense to have "Show all items"/"Show all widgets" instead.

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Thanks, Debdeep for the work.

Can we have a logo that represents events instead?

Production build 0.71.5 2024