Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Updated: Comment 0
Problem/Motivation
At the moment a lot of services call the $view_entity->getExecutable()
which is just a wrapper function around the static function Views::executableFactory()->get($this);
.
The proper way to use the factory would be to inject it instead.
Proposed resolution
Inject the view executable factory where possible.
Remaining tasks
User interface changes
API changes
Beta phase evaluation
Issue category | Task since we are refactoring the code to follow best practices. |
---|---|
Issue priority | Normal because we are replacing code that works with code that is the current best practice. |
Prioritized changes | The main goal of this issue is refactor code to follow best practices. |
Disruption | None |
Comment | File | Size | Author |
---|---|---|---|
#37 | inject_the_view-2102293-37.patch | 58.61 KB | geertvd |
#37 | interdiff.txt | 1.92 KB | geertvd |
#18 | interdiff.txt | 5.19 KB | geertvd |
#12 | interdiff-10-12.txt | 50.37 KB | zaporylie |
#10 | 2102293-10.patch | 3.43 KB | alexandre.todorov |
Comments
Comment #1
dawehner.
Comment #2
bnjmnmI experimented with this replacement in a few places -
In views_ui\Form\Ajax\AddItem the replacement was fine but in views_ui/admin.inc functionality was disrupted to the point that the 'add' button in a view would not function.
My thought was to add the following code to each occurrence of $view->getExecutable(), to see if executable factory can safely be used instead.
I'd like to get verification from a more experienced contributor that determining an object match is sufficient evidence that ->getExecutable can be replaced by executable factory.
If this looks like it will work, I'll apply this test to each occurrence, change to executable factory when the objects match, and create a patch.
Comment #3
a.hover CreditAttribution: a.hover commentedComment #4
YesCT CreditAttribution: YesCT commented@a.hover Did you have any questions?
Comment #5
a.hover CreditAttribution: a.hover commentedComment #6
saltednutIt looks like the ::getExecutable method still exists in
core/modules/views/lib/Drupal/views/Entity/view.php
but it is not being called anywhere in the system.Is this issue still relevant?
If we are not using the global, perhaps it should be removed altogether, lest someone accidentally start using it again?
Comment #7
zaporylieI found some usages of getExecutable() with phpStorm "Find Usages" function. Will try to replace it with
Views::executableFactory()->get($view);
and publish a patch.Comment #8
zaporyliePlease, check this patch and say if it is going in the right direction.
Comment #10
alexandre.todorov CreditAttribution: alexandre.todorov commentedHI,
I just rerolled #8 patch witch didn't apply on latest 8.0.x. Without doing any changes, I ran tests witch have previously failed (Drupal\views\Tests\Handler\HandlerTest, Drupal\views_ui\Tests\DisplayCRUDTest) and finally those tests pass.
Drupal Dev Days Mentor Sprint - Montpellier (France) 2015
Comment #11
zaporylieThanks for moving this issue forward. It wasn't finished though so I'm moving it back to "Needs work" but that's great it's green now. Do you want to finish my work or should I take care of it?
Also, I've added drupaldevdays tag since you are working on it here.
Comment #12
zaporylieOk, I think I went through all occurrences of getExecutable(). Let's try patch it against testbot.
Comment #14
tim.plunkettThis just switches to using a static method call, which is a wrapper around \Drupal::service('views.executable')
As the issue title says, we should be injecting the factory instead.
Comment #15
geertvd CreditAttribution: geertvd commentedLet's see what the testbot says
Comment #16
geertvd CreditAttribution: geertvd commentedComment #18
geertvd CreditAttribution: geertvd commentedComment #20
geertvd CreditAttribution: geertvd commentedComment #21
geertvd CreditAttribution: geertvd at XIO commentedComment #23
geertvd CreditAttribution: geertvd at XIO commentedComment #24
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedOverall this looks very good. All injections seem to be done properly, so most remarks below are minor really.
This needs a beta evaluation, so tagging accordingly.
The factory always returns an instance of ViewExecutable, so the second check is unneeded.
Same.
Can we add an explanatory paragraph under the @return here?
These newline are redundant.
Is this the right place to define the factory? Shouldn't that be moved to a superclass? Not sure though, we might want to check with a maintainer.
"a"
"plugin id"
"plugin id"
Why is this needed, since it wasn't there before? (I found this 8 times, so it will have some use, but I don't get it)
"plugin id"
It's a mocked view executable "factory".
Same.
And again.
All lines around this comment change, so I'd fix the comment as well.
Comment #25
dawehnerIts great that people work on those issues. Thank you!!!
Comment #26
geertvd CreditAttribution: geertvd at XIO commentedI'm thinking this was not necessary before since this was already being called in
View::calculateDependencies()
when a new view object was constructed.setOption()
therePerhaps dawehner should verify 5 and 9 since I'm not sure about those.
Comment #27
dawehner+1
If we have both bits, I really think we don't need it. Have you tried to remove the additional calls, does something break?
Comment #28
geertvd CreditAttribution: geertvd at XIO commentedWhen I remove the
$executable->initDisplay()
there I get a white screen with the following error:Same kind of error is thrown whenever I try to call something on
$executable->displayHandlers
without adding the$executable->initDisplay()
line first.Comment #29
geertvd CreditAttribution: geertvd at XIO commentedWell at least I should be using the
$executable
variable there.Comment #30
geertvd CreditAttribution: geertvd at XIO commentedOk then I can actually remove that line since the display is initialised in
setDisplay()
Comment #31
geertvd CreditAttribution: geertvd at XIO commentedI just checked every addition of the the
$executable->initDisplay()
line.Looks like the above was the only one that could be removed though, in the other occasions we call a method on
$executable->displayHandlers
or$executable->display_handler
without calling$executable->setDisplay()
before that.Comment #32
dawehnerThank you! Note: We should still add a beta evaluation as well as maybe improve the issue summary in general a bit.
Comment #33
geertvd CreditAttribution: geertvd at XIO commentedThanks for reviewing, added the beta evaluation.
Comment #34
geertvd CreditAttribution: geertvd at XIO commentedImproved the IS a bit.
Comment #35
geertvd CreditAttribution: geertvd at XIO commentedComment #36
Anonymous (not verified) CreditAttribution: Anonymous at XIO commented@geertvd: Thanks for your work on this and investigating the uncertainties!
@dawehner: Thanks for your input!
This issue is both normal priority and a task because we refactor to follow best practices. See priorities and categories. I tweaked the beta evaluation to reflect that.
The issue summary itself looks good now.
I looked over the patch again, and I missed some things the first time reviewing. These are minor, but will need to be addressed before the patch goes in.
This newline should be removed.
RowPluginBase
The $executable_factory that was added, needs an @param definition in the docblock.
Comment #37
geertvd CreditAttribution: geertvd at XIO commentedThanks for the feedback
Comment #38
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedOk, thanks for addressing that!
Comment #39
alexpottThis is a lot of disruption for:
How likely is it that this will break existing Drupal 8 sites?
Comment #40
aspilicious CreditAttribution: aspilicious commentedWell in order to keep DS working in D8 I had to update the views integration 12 times since january. (last time this week) This change will brake it *again*.
So I don't think it's ok, while being in beta, to randomly change constructor arguments if they don't fix any real problem.
Comment #41
dawehnerSo you basically want to treat constructor arguments like an API now? I try to understand your particular point here ...
Comment #42
aspilicious CreditAttribution: aspilicious commentedWell, it's a grey line.
For example, let's compare these two cases:
(1) For some reason we add new constructor argument to 'DefaultPluginManager' and by doing that we would break every contrib module that deals with custom plugin managers.
(2) We commit this patch and we would potentially break contrib modules that extends one of the affected classes.
From a technical perspective (1) and (2) are the same.
(1) will never be allowed at this stage unless it fixes a critical/major bug
(2) possibly will be allowed because the affected code out of core will be very limited at the moment.
To be honest, I personally don't care because I don't have any working D8 sites at the moment. But *if* people are using it (and apparently according to the statistics, they do), they have no clue which version of the module they need to use to make everything work for them.
Comment #43
dawehnerMy personal opinion is that subclassing and especially the constructor side of things is not directly part of an public API.
No question, we should try to avoid changes, especially after the release, but at least for me, it should not be a reason to do things in a wrong way.
For core I would like to see some kind of @api tag for some base classes, so we promise to not change things there, see http://symfony.com/doc/current/contributing/code/bc.html
for a similar promise.
Comment #44
jp.stacey CreditAttribution: jp.stacey at Magnetic Phield commentedThis issue was reverted to Needs Review in comment #39, based on needing to discuss how much disruption it's likely to cause (really a Needs Work?)
At any rate, I'm going to remove the novice tag, because I don't think it's reviewable by a novice in its current state.
Comment #45
jp.stacey CreditAttribution: jp.stacey at Magnetic Phield commentedComment #47
joachim CreditAttribution: joachim as a volunteer commentedI think that replacing the $view variable with the executable is bad code style because it makes it really hard to read or debug the code, or inherit methods.
It's a problem with the existing code, so I'd be ok with this being done in a follow-up.
Comment #48
Mile23Adding parent #2729597: [meta] Replace \Drupal with injected services where appropriate in core because views executable is a service. All of those code paths eventually reach Views::executableFactory() which is just a wrapper for \Drupal::service('views.executable').
One reason to do IoC and inject the service is that we're calling a bunch of functions that all wrap wrappers. Except for the very last one, of course. So let's just call the last one, once.
Comment #61
dimitriskr CreditAttribution: dimitriskr commented