Closed (fixed)
Project:
Drupal core
Version:
8.0.x-dev
Component:
rest.module
Priority:
Normal
Category:
Task
Assigned:
Issue tags:
Reporter:
Created:
3 Jun 2013 at 20:12 UTC
Updated:
29 Jul 2014 at 22:28 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
chrisjlee commentedGuess i'll give this a try.
Comment #2
ddrozdik commentedThis task means to replace deprecated function in whole module, not only in the file with extension *.module.
Also need to replace in all plugins and tests in this module.
Comment #3
chrisjlee commented@DmitryDrozdik: Ok thanks. Just trying to do a small change and get it green so i get a feel for the API change.
Also @DmitryDrozdik does #1957154: Replace calls to drupal_container()->get('module_handler') service with Drupal::moduleHandler() have to be committed first before this issue in order for tests to get passed?
Comment #4
chrisjlee commentedComment #5
ddrozdik commentedwe can prepare our changes before that task, or after, does not matter.
Comment #6
chrisjlee commented#1: 2011122-deprecate-drupal_service-in-rest-1.patch queued for re-testing.
Comment #8
Crell commentedThe patch referenced from #3 is in, so this can move forward.
Why do we need the conditional? If this module is enabled, that service should be there...
This should be Drupal::service('plugin.manager.rest')
Comment #9
kgoel commentedComment #11
hussainwebThe test failed because of line 13 in rest.module.
Of course, one thought is to use Drupal::getContainer() instead of Drupal::service() (which is invalid). However, the documentation says that this should be avoided.
The next approach I can think of is to remove the call to has() completely, something like this:
I am not sure about the approach, though. Any better ideas?
Comment #12
hussainwebHere is the patch with the fix suggested in #11.
Comment #14
kgoel commentedComment #16
kgoel commented#14: rest-2011122-14.patch queued for re-testing.
Comment #18
hussainwebIt appears that the error is here:
Drupal::service() expects a parameter. I am not sure how to support this particular case. Any ideas?
Comment #19
Crell commentedIf you actually need the container itself, you call \Drupal::getContainer()->getParameter().
That said... Plugins can now have values injected with a create() method so we really really should inject the format list properly rather than calling \Drupal.
Comment #20
hussainweb@Crell: I think that means adding a parameter to the constructor, right? I am not very sure if this counts as an API change. If it is an API change, then is it necessary to put it past the API freeze?
Comment #21
hussainwebI am trying out the change from #20.
Comment #22
kgoel commentedAdd the following in rest/lib/Drupal/rest/Plugin/ResourceBase.php
public static function create(ContainerInterface $container) {
return new static($container->getParameter('serializer.formats'));
}
Comment #23
hussainwebI don't think it is the matter of overriding the create() method. It seems that PluginBase::create() method already takes care of passing the container. Besides, passing in the
serializer.formatslist might just break the contract (the constructor should probably expect aContainerInterface).I think it is a matter of saving the container in the constructor and using the saved container instead of calling
\Drupal::getContainer(). Am I on the right track here?Comment #24
hussainwebOk, I found something. I am rewriting the patch based on Change Record: Plugins can receive injected dependencies from the container.
Comment #25
hussainwebComment #26
hussainwebHere goes nothing... I am still not sure if this counts as an API change. If it does, and if its too late for that, I think patch in #21 still applies and passes all tests.
Comment #28
hussainwebI guess I must define somewhere that these plugins will now need ContainerInterface parameter too. The change record didn't mention anything about it and I thought it would be picked up.
Any tips?
Comment #29
Crell commentedWe absolutely do not save the container here. We only need to save the formats property. The constructor is not something that would ever be accessed outside of a unit test (at least we don't support doing so), so it's not an API change to inject it properly.
Comment #30
hussainwebThanks @Crell,
Can you tell me if my approach in #26 was at least in the right direction? I am looking into the code to see how to work with it. I guess that instead of saving the ContainerInterface, I will just save the formats list, but the problem is that I am being passed NULL for $container. How should I proceed?
Comment #31
hussainwebCame up with this after analysis. I hope it works.
Comment #33
hussainwebWow, that was embarrassing. I changed the class but didn't update the namespace imports. Fixing it now...
Comment #35
hussainwebThere was some progress, so I made the change with injecting serializer.formats instead of the container. Let's see how this goes.
Comment #36
klausiLooking at the Views plugin inheritance tree I can see that it leads back to ContainerFactoryPluginBase, so we can implement a create() method here as well that pulls the content negotiation from the container?
Comment #37
hussainwebMade changes as per #36. I was torn between using
$container::Request();and$container->Request();. I just resorted to using$container->get('request')in thecreate()method. Lets see what happens.Comment #39
hussainwebIt looks like this should fix the problem. The test result says that the function definition for RestExport::create() is not compatible with ContainerFactoryPluginInterface::create(), but it is. I think it is only the missing reference, though I was expecting a different error in that case.
Comment #40
klausiExcellent!
Comment #41
alexpottI think that we should be changing ResourcePluginManager to use DefaultPluginManager.
Comment #42
hussainwebHere goes nothing. I used examples from other modules. I hope it works.
Comment #44
hussainwebI think this should fix it.
Comment #46
hussainwebI see the problem, really silly of me. I am still unsure about one part of the change, but I think it should work.
This is in rest.services.yml and is necessary because we are passing a @cache.rest to our plugin manager. I see the same usage in block.services.yml and field.services.yml.
The earlier error (in #44) was due to swapped arguments. I just fixed that in this patch and the block above.
Comment #47
klausiField formatter info? Why? And are the decorators above still needed?
class properties should use lowerCamel naming, see https://drupal.org/node/608152#naming
Comment #48
hussainwebI am not too sure about the additional decorators. These were the only decorators not present in DefaultPluginManager::__construct() and I thought I should not change that here.
About the other two calls: I didn't pay attention when copying them from FormatterPluginManager. I don't know if they are necessary, although it looks like they are. I have changed them appropriately.
I have also changed the class property name as mentioned in #47.
Comment #49
hussainwebFixing more bugs...
Comment #51
klausiand lowerCmale here too, please :-)
Comment #52
hussainwebI don't know why I am making mistakes like this. I put all the
usestatements in another file and resubmitted the patch. Silly me.And I changed the property name to camel case as indicated in #51. I hope there are no others. :)
Comment #54
hussainwebWell, 5 errors is certainly better than 400+ errors. It seems that the
Drupal\Core\Plugin\ContainerFactoryPluginBasehas been removed recently. I will try searching for it and replace it appropriately.Comment #55
hussainwebFound it.
Drupal\Core\Plugin\ContainerFactoryPluginBasehas been removed in #2033447: Remove obsolete ContainerFactoryPluginBase and I am bringing the changes in here.Comment #57
hussainwebHmmm... looks like
Drupal\Core\Plugin\ContainerFactoryPluginBasedid more than just the one abstract method. I have to recreate that method in ResourceBase, I think.Comment #58
hussainwebI am putting back
extends PluginBaseonResourceBaseas that class defines the properties and the methods and looks like the appropriate match here. That was the eventual class implementation in hierarchy when usingContainerFactoryPluginBasetoo, so with that latter becoming an interface now, we can revert toPluginBase.This is a lot more patches than I thought. :-)
Comment #59
hussainwebComment #60
hussainwebAnd we're back to green, gentlemen. Finally!
Please look at the approach when reviewing. The last patch before #58 to pass was #39. We changed the ResourcePluginManager to use DefaultPluginManager as per #41 and a few property names were changed from #47 and #51. As part of the changes, we found that ContainerFactoryPluginBase has since been removed since the patch in #39 (from #2033447: Remove obsolete ContainerFactoryPluginBase). I implemented the new method as per the change record: Allow plugins to have services injected.
Comment #61
klausiSo now REST plugins need to have a create() method, otherwise there will be PHP fatal errors if a plugin only implements the ResourceInterface? That means the Resource Interface itself must extend from ContainerFactoryPluginInterface.
So the AlterDecorator is not needed anymore. And for alterInfo() we should pass 'rest_resource'.
Same for the CacheDecorator, that is also not needed anymore, because DefaultPluginManager has built-in caching.
Comment #62
klausiPlease copy the ResourcePluginManager stuff from #2047593: Inject dependencies into EntityDerivative derivative class, looks good there.
Comment #63
hussainwebThanks @klausi, I am traveling until Wednesday. I will resume working on this then.
Comment #64
hussainwebIt looks like it needs a reroll. So, I am not attempting any major changes as suggested in #62 yet. I am just rerolling and putting in suggestions from #61 for now. If it turns green, I will look at #2047593: Inject dependencies into EntityDerivative derivative class and work the changes.
The reroll were from conflicts in #2043379: Allow plugins to be discovered in any directory and #1972116: Add REST test coverage for nodes. The second issue was fairly straight-forward as it was only a one line change. The first was a little tricky but ultimately, I see I had to change this line:
parent::__construct('rest/resource', $namespaces);to this:parent::__construct('Plugin/rest/resource', $namespaces);incore/modules/rest/lib/Drupal/rest/Plugin/Type/ResourcePluginManager.php.Comment #65
klausiThis looks good to me now for replacing drupal_container(), injecting other dependencies should be handled in #2047593: Inject dependencies into EntityDerivative derivative class.
Comment #66
alexpottCommitted 5031030 and pushed to 8.x. Thanks!
Fixed code indentation during commit...