Closed (fixed)
Project:
Drupal core
Version:
11.x-dev
Component:
filter.module
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
20 Jul 2015 at 19:15 UTC
Updated:
17 Apr 2026 at 22:30 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
tim.plunkettComment #3
tim.plunkettRan
php core/scripts/generate-proxy-class.php '\Drupal\filter\FilterFormatRepository' "core/modules/filter/src"to fix thatComment #5
tim.plunkettYou've gotta be kidding me. Why the hell is that not valid!?
Comment #6
dawehnerIt is great to do those things, but I kinda doubt this will be able to land in 8.0.x
Define what means allowed
Any reason for gets vs. returns?
Did you considered mocking using prophecy? You should see the error messages created by prophecy, its from another universe
I would argue that entity type definitions are value objects and so don't need to be mocked, as they don't consists of logic for themselves
Comment #7
tim.plunkett1) Rewritten
2) Returns was c/p, changed all to Gets
3) Tried it out. Thanks for the pointers
4) Fair point!
Comment #8
dawehnerWhat about using ::class and get autocompletion?
Comment #9
tim.plunkettI broke some of the coverage with that.
Also I have no idea what #8 is suggesting. @dawehner, do you want to implement what you have in mind?
Comment #10
dawehnerSometimes along this lines ...
Comment #11
tim.plunkettOh cool, importing those really shows you how many things you depend on.
@dawehner++
Comment #12
mile23Really like the
Interface::classpattern. :-)I don't suppose there's an easy way to do a test-only patch here.
The patch in #11 still applies, but there's no
FilterFormatRepositoryInterfaceanymore.Comment #13
mile23Hey, you know what?
git diff --name-onlywon't tell you files *added* by the patch. :-)Comment #14
mile23My proxy-fu is no good, so I can't review that. Coding standards:
Needs a return comment.
Comment #22
claudiu.cristeaAdded CR. Rerolled, refreshed the code, added proper deprecations.
Comment #23
claudiu.cristeaAdding #1577902: [META] Remove all usages of drupal_static() & drupal_static_reset() as related because this remove usages of
drupal_static()anddrupal_static_reset().Comment #25
claudiu.cristeaReplaced all usages of deprecated functions.
Comment #27
claudiu.cristeaThe patch from #25 was wrong. Republishing.
Comment #29
claudiu.cristeaOuch, an accidental edit.
Comment #30
claudiu.cristea::getDefaultFormat() was not properly used.
Comment #32
claudiu.cristeaMore fixes.
Comment #35
claudiu.cristeaFixing coding standards.
Comment #37
claudiu.cristeaLast fix.
Comment #38
andypostwhy not just filter.format_repository?
Comment #39
claudiu.cristeaI would say, better
filter.format_repository. Because the service ID is always namespaced under the module’s name, which in this case isfilter.*EDIT: @andypost, initially I misread your comment. In fact we're on the same page.
Comment #40
claudiu.cristeaFixed #38. Improved the service.
Comment #42
claudiu.cristeaAdded deprecation test. Fixed unit test failure.
Comment #44
claudiu.cristeaCoding standards.
Comment #46
claudiu.cristeaNot related & wrong changes. Undo.
Increase version: 8.7.0 -> 8.8.0. Update also the CR.
Exceeds 80 chars.
For BC reasons
$format_repositoryshould be optional and should trigger deprecation error if not passed.Tests should use \Drupal::service(...) instead of $this->container->get(...).
Apart from the inline review, we should handle the case when a 3rd party code uses calls the cache reset directly
drupal_cache_reset('filter_formats').Comment #47
claudiu.cristeaFixed #46.
Comment #48
andypostbtw Entities are could be statically cached in storage handler and I'm sure better to relay on its caching instead of internal property
Also it needs __sleep() method to unset this properties on serialize
Comment #49
claudiu.cristeaNot sure I get this.
Comment #50
andypostI mean kind of it, we already using static cache for user roles, so caching of formats also makes sense
I see no reason to abuse cache with already cached config entities (only sorting of formats could be moved to storage handler)
Comment #52
andypostA bit of clean-up
Comment #54
claudiu.cristeaI see your point, but this is a performance regression compared to #47, as
::loadByProperties()is doing a real query against the DB on each::getAllFormats()call. So, it's not only sorting of formats that occurs every time.Comment #55
andypostJust checked
\Drupal\Core\Entity\EntityStorageBase::loadByProperties()and worried as well(Then I think we should always use
loadMultiple()& filter/sort in repository method but makes sense to test & I sure there should not be big diff in performanceComment #56
claudiu.cristeaYep, I fully agree. better than having another caching layer.
Given that there are only few text formats, usually fewer than 10 I don't know if it make sense to benchmark.
Use the standard deprecation messages.
We should not do this in constructor. I hit an edge case, see https://www.drupal.org/project/drupal/issues/2863986#comment-12899598. Let's revert this
I also noticed that some tests are doing a useless cache clearing.
The failing test still needs some investigation.
Comment #57
claudiu.cristeaSorry, the patch from #56 was wrong. Here's the correct version. The interdiff is correct.
Comment #61
ridhimaabrol24 commentedReroll for 9.1.x and trying to fix test cases.
Comment #62
ridhimaabrol24 commentedFixing PHP lint error in #61
Comment #64
ridhimaabrol24 commentedFixing test cases.
Comment #66
ridhimaabrol24 commentedFixing failed test cases. Also regarding #54, loadbyproperties() has been used in several repository methods in core.
Comment #69
berdirWe seem to be losing both static and persistent caching here.
I kinda get the persistent cache, but note that loadByProperties() is *not* cached and is pretty slow. We could add a lookup_keys for status to FilterFormat as well, that would help a bit, but it's still a database query. And that requires an upgrade path too. I don't think removing the caching here is a good idea.
I see that this was discussed before, but even a loadMultiple() is still an extra query. Every time. See \Drupal\Core\Config\Entity\ConfigEntityStorage::doLoadMultiple(). We cache the list of all config entities of a given type.
this on the other hand seems pointless. All actual changes to the filter formats already save them and imply invalidating the entity cache. And any change that does not change the format but e.g. changes user/role permissions, this is pointless.
the array map thing happens quite often, we could add a method for that.
interesting, where are we injecting it in the critical path but might not actually use it? The proxy actually adds overhead and it's only worth doing if we are saving calls. What you want to do instead IMHO is make sure that you don't do any extra work in the constructor, specifically instantiating the entity storage.
this seems like an old method that no longer exists like this, used quite a lot.
Comment #74
claudiu.cristeaComment #76
claudiu.cristeaRestarted by converting #66 into a MR. I didn't make any changes, just verbatim conversion to begin with
Comment #77
claudiu.cristeaComment #78
claudiu.cristeaThis is ready for review
Comment #80
claudiu.cristeaApplied @berdir's suggestion
Comment #81
berdirAnother review posted. I'm open to discuss this and get feedback from others about things like the deprecation version. And know that the service name would be a very tedious change to update due to uses and so on.
Comment #82
claudiu.cristeaAddressed the remarks. Back to "Needs review"
Comment #83
claudiu.cristeaUpdated IS & CR
Comment #84
berdirHopefully really the last review iteration...
Comment #85
claudiu.cristeaThank you. I've addressed the latest remarks.
Comment #86
claudiu.cristeaYes, I saw that before but finally I forgot to change.
Fixed latest change requests. Ready for review again
Comment #87
berdirThanks, I think this is ready.
IMHO the introduction of the repository service makes sense here, the methods are not trivial due to caching and so on. In regards to performance, I was wondering a bit, because I don't think any of these calls really are in the critical path, but I think it makes sense to essentially keep the level of caching that we have here for now, the we don't need to discuss that further. What's really neat is that the introduction of cache tags for that caches means that we can remove a lot of explicit cache invalidation and it makes it much easier to remove the caching if we consider it to no longer be necessary in the future.
As a follow-up, I'd like to explore to add a general persistent cache for loadMultiple() without ids for config entities, it's a fairly common thing for them and would likely allow us to remove the custom caching here for this. Possibly combined with the idea in #3551948: Document that EntityStorageInterface::loadMultiple may bypass caching, but likely cache first, refactoring and deprecations later. That certainly would allow us to drop this extra cache, because we essentially add a cache for the wildcard config query + the format config entity load, which is in fast chained config cache, which would be faster than this.
We did DI where we could with BC, most changes are in tests.
Comment #88
wim leersJust postponed #2917817 on this: would be better to land this first.
Comment #92
claudiu.cristeaSince RTBC, all commits were rerolls. MR !14343 is the one that counts
Comment #93
godotislateSome minor comments on the MR.
I think it'd also be useful to have unit(?) tests to confirm that the caching in getAllFormats() and getFormatsForAccount() works and is invalidated as expected.
Comment #94
godotislateLooks like the CR needs updating as well:
Comment #95
claudiu.cristeaUpdate the CR according to #94
Comment #96
claudiu.cristeaAddressed remarks except the testing of cache. I wonder if we still need that, in very rare cases we're doing that
Comment #97
nicxvan commentedA couple of minor comments, I'm not sure how strongly @godotislate feels about the unit tests.
Comment #98
godotislateIf there's existing coverage, even implicit, for the caching behavior, then I think the tests aren't that necessary.
Comment #99
claudiu.cristeaReady for a new review
Comment #100
berdir> Ok, there's a lot of back and forth with these versions, each reviewer has different POV. My head is exploding
I think we're consistently on 11.4 for 13 now, which seems fine. not sure if we'd need to bother with the BC for drupal_static_reset() until D13, it's such a super edge case, but it also doesn't hurt to keep it.
> If there's existing coverage, even implicit, for the caching behavior, then I think the tests aren't that necessary.
We definitely have test coverage for the persistent caching invalidation, otherwise plenty of tests would fail that add new formats and then use them.
getFormatsForAccount() might not be explicitly covered, but I'm not even sure we need that memory caching there. This isn't in the critical path, I had a look at how often it's called, it's 2-3 times when editing a node (multiplied by number of text fields with a format). The only thing this really caches is getting the memory-cached filters and the array_filter() with the access check, which also is cached.
But we kind of thought that we want to avoid the discussion and decision on whether or not we need it and just keep it. Fairly limited complexity I think.
On other side, I just realized that we have a bug in the caching logic, see MR review. So maybe we should have more explicit test coverage, but with my suggested refactoring, there won't be much left to test and the problem can't really happen anymore.
Comment #101
claudiu.cristeaStatus:
Ready for review
Comment #102
berdirThanks, yes, exactly like that. That is much easier.
I added a note to the CR that the reset calls are very likely not needed and can probably be removed.
I'll leave it to @godotislate to decide on whether or not the test coverage here is sufficient, I think it is ok now with the updated implementation. I'd rather open a follow-up to decide if we want to remove caching from getFormatsForAccount().
Comment #103
claudiu.cristeaStraight reroll after #3580662: Deprecate _filter_tips() has been merged
Comment #107
godotislateThanks to everyone for their incredible patience to get this one over the line!
There were two minor merge conflicts in filter.module and FilterThemeHooks.php when backporting to 11.x, but these just involved the use statements. I manually resolved the conflicts.
Committed d65f017 and pushed to main and committed f7f8afd and pushed to 11.x. Thanks!