Problem/Motivation

After the completion of the new Extension system API's in #2208429: Extension System, Part III: ExtensionList, ModuleExtensionList and ProfileExtensionList and #2659940: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList, drupal_get_path() has been replaced with the theme, module and profile extension listing services. This issue will deprecate the usage of drupal_get_path() and drupal_get_filename() in core and replace with the relevant extension listing service calls (Module|Profile|Theme)ExtensionList::getPath() and (Module|Profile|Theme)ExtensionList::getPathname() respectively.

Proposed resolution

Replace all dynamic uses drupal_get_path() with (Module|Profile|Theme)ExtensionList::getPath().
Replace all dynamic uses drupal_get_filename() with (Module|Profile|Theme)ExtensionList::getPathname().

Remaining tasks

Reviews
Commit

User interface changes

None

API changes

drupal_get_path() and drupal_get_filename() are deprecated.

\Drupal\Core\Extension\Exception\UnknownExtensionException is now thrown if the extension is not found.
\Drupal\Core\Extension\Exception\UnknownExtensionTypeException is now thrown if the extension type is not found.

The class \Drupal\ckeditor\CKEditorPluginBase gets two new public methods: getModuleList() and getModulePath($module_name). The first method returns the module list service (\Drupal::service('extension.list.module')). The second method the module path for the given module name (\Drupal::service('extension.list.module')->getPath($module_name)).

CommentFileSizeAuthor
#302 2347783-302-interdiff.txt6.2 KBberdir
#302 2347783-302.patch177.45 KBberdir
#298 2347783-298.patch181.29 KBandypost
#298 interdiff.txt658 bytesandypost
#297 2347783-297.patch181.34 KBandypost
#297 interdiff.txt5.49 KBandypost
#296 2347783-296.patch181.52 KBandypost
#296 interdiff.txt8.41 KBandypost
#294 2347783-293.patch179.35 KBdhirendra.mishra
#294 interdiff_291-293.txt3.09 KBdhirendra.mishra
#293 interdiff_291-293.txt3.09 KBdhirendra.mishra
#291 2347783-291.patch180.84 KBdhirendra.mishra
#291 interdiff_287-291.txt4.59 KBdhirendra.mishra
#287 2347783-287.patch178.9 KBandypost
#287 interdiff.txt607 bytesandypost
#286 2347783-286.patch178.9 KBandypost
#286 interdiff.txt6.89 KBandypost
#283 2347783-283-interdiff.txt2.04 KBberdir
#283 2347783-283.patch180.2 KBberdir
#280 2347783-280-interdiff.txt1.31 KBberdir
#280 2347783-280.patch179.06 KBberdir
#279 2347783-276-interdiff.txt18.65 KBberdir
#279 2347783-276.patch178.75 KBberdir
#271 interdiff_268_271.txt3.04 KBspokje
#271 2347783-271.patch174.58 KBspokje
#270 2347783-270.patch174.57 KBspokje
#270 interdiff_268_270.txt3.04 KBspokje
#268 2347783-268.patch171.2 KBpaulocs
#268 interdiff-262-268.txt10.01 KBpaulocs
#262 2347783-261.patch178.33 KBspokje
#262 interdiff_260_261.txt676 bytesspokje
#260 2347783-260-interdiff.txt752 byteskim.pepper
#260 2347783-260.patch178.33 KBkim.pepper
#258 2347783-258.patch172.07 KBkim.pepper
#254 2347783-254.patch172.07 KBalexpott
#254 252-254-interdiff.txt2.78 KBalexpott
#252 2347783-252-interdiff.txt16.78 KBkim.pepper
#252 2347783-252.patch171.96 KBkim.pepper
#250 2347783-250-interdiff.txt2.17 KBkim.pepper
#250 2347783-250.patch172.33 KBkim.pepper
#249 2347783-249-interdiff.txt6.84 KBkim.pepper
#249 2347783-249.patch172.65 KBkim.pepper
#246 2347783-246.patch169.41 KBkim.pepper
#242 interdiff_240_242.txt7.93 KBanmolgoyal74
#242 2347783-242.patch166.9 KBanmolgoyal74
#240 interdiff_243_240.txt51.63 KBkapilv
#240 2347783-240.patch160.01 KBkapilv
#234 2347783-234-interdiff.txt3.41 KBkim.pepper
#234 2347783-234.patch167.36 KBkim.pepper
#232 2347783-232-interdiff.txt2.26 KBkim.pepper
#232 2347783-232.patch165.47 KBkim.pepper
#227 2347783-227-interdiff.txt812 byteskim.pepper
#227 2347783-227.patch164.99 KBkim.pepper
#225 2347783-225-interdiff.txt9.59 KBkim.pepper
#225 2347783-225.patch164.19 KBkim.pepper
#218 2347783-218-interdiff.txt38.42 KBkim.pepper
#218 2347783-218.patch165.22 KBkim.pepper
#217 Screen Shot 2020-05-23 at 14.14.30.png126.63 KBshaktik
#212 Screen Shot 2020-05-21 at 21.07.12.png148.99 KBshaktik
#208 interdiff-2347783-202-205.txt8.63 KBmrinalini9
#205 2347783-205.patch171.8 KBaleevas
#204 interdiff.2347783.202-204.txt15.65 KBaleevas
#204 2347783-204.patch170.52 KBaleevas
#202 interdiff_190-202.txt1.67 KBsaurabh-2k17
#202 interdiff_200-202.txt993 bytessaurabh-2k17
#202 deprecated_path_and_filename-2347783-202.patch171.36 KBsaurabh-2k17
#200 interdiff_190-200.txt720 bytessaurabh-2k17
#200 deprecated_path_and_filename-2347783-200.patch170.2 KBsaurabh-2k17
#198 interdiff_190-198.txt4.93 KBsaurabh-2k17
#198 deprecated_path_and_filename-2347783-198.patch165.45 KBsaurabh-2k17
#192 2347783-182-190.interdiff.txt18.26 KBkim.pepper
#190 interdiff.2347783.186-190.txt1.75 KBaleevas
#190 2347783-190.patch169.5 KBaleevas
#189 Screen Shot 2020-05-15 at 4.56.50 PM.png453 KBdeepak goyal
#186 interdiff.2347783.182-186.txt48.45 KBaleevas
#186 2347783-186.patch168.22 KBaleevas
#182 2347783-182-interdiff.txt9.16 KBkim.pepper
#182 2347783-182.patch169.58 KBkim.pepper
#180 interdiff.2347783.179-180.txt10.03 KBaleevas
#180 2347783-180.patch169.45 KBaleevas
#178 2347783-178-interdiff.txt3.28 KBkim.pepper
#178 2347783-178.patch161 KBkim.pepper
#176 2347783-176.patch157.74 KBkim.pepper
#174 2347783-174-interdiff.txt948 byteskim.pepper
#174 2347783-174.patch161.68 KBkim.pepper
#172 2347783-172-interdiff.txt4.1 KBkim.pepper
#172 2347783-172.patch161.07 KBkim.pepper
#170 2347783-170.patch156.97 KBkim.pepper
#164 2347783-164.patch157.08 KBalexpott
#164 161-164-interdiff.txt1.81 KBalexpott
#161 2347783-161.patch156.97 KBwim leers
#161 interdiff.txt4.32 KBwim leers
#160 2347783-160-interdiff.txt7.7 KBkim.pepper
#160 2347783-160.patch156.97 KBkim.pepper
#154 2347783-154-interdiff.txt3.7 KBkim.pepper
#154 2347783-154.patch157.1 KBkim.pepper
#152 2347783-152-interdiff.txt473 byteskim.pepper
#152 2347783-152.patch160.79 KBkim.pepper
#151 2347783-151-interdiff.txt4.77 KBkim.pepper
#151 2347783-151.patch161.25 KBkim.pepper
#148 2347783-148.patch159.94 KBandypost
#148 interdiff.txt3.04 KBandypost
#145 2347783-145.patch160.45 KBandypost
#145 interdiff.txt816 bytesandypost
#143 2347783-142-interdiff.txt1.24 KBkim.pepper
#143 2347783-142.patch164.11 KBkim.pepper
#140 2347783-140-interdiff.txt1.96 KBkim.pepper
#140 2347783-140.patch163.23 KBkim.pepper
#138 2347783-138-interdiff.txt3.79 KBkim.pepper
#138 2347783-138.patch163.95 KBkim.pepper
#136 2347783-135-interdiff.txt24.1 KBkim.pepper
#136 2347783-135.patch167.73 KBkim.pepper
#130 2347783-130-interdiff.txt2.43 KBkim.pepper
#130 2347783-130.patch168.27 KBkim.pepper
#122 2347783-122-interdiff.txt1.6 KBkim.pepper
#122 2347783-122.patch167.84 KBkim.pepper
#116 2347783-116-interdiff.txt10.2 KBkim.pepper
#116 2347783-116.patch167.85 KBkim.pepper
#114 2347783-114-interdiff.txt5.52 KBkim.pepper
#114 2347783-114.patch169.03 KBkim.pepper
#110 2347783-110-interdiff.txt1.44 KBkim.pepper
#110 2347783-110.patch169.65 KBkim.pepper
#109 2347783-109-interdiff.txt18.65 KBkim.pepper
#109 2347783-109.patch169.66 KBkim.pepper
#104 2347783-104-interdiff.txt4.7 KBkim.pepper
#104 2347783-104.patch167.14 KBkim.pepper
#103 2347783-103-interdiff.txt14.86 KBkim.pepper
#103 2347783-103.patch167.07 KBkim.pepper
#101 2347783-101-interdiff.txt18.51 KBkim.pepper
#101 2347783-101.patch158.59 KBkim.pepper
#97 2347783-97-interdiff.txt28.25 KBkim.pepper
#97 2347783-97.patch155.22 KBkim.pepper
#94 2347783-94-interdiff.txt971 byteskim.pepper
#94 2347783-94.patch134.74 KBkim.pepper
#92 2347783-92.patch134.77 KBkim.pepper
#90 2347783-90.patch133.98 KBsubson
#89 2347783-89.patch133.04 KBkim.pepper
#89 2347783-89-interdiff.txt1.12 KBkim.pepper
#87 2347783-87.patch132.91 KBkim.pepper
#87 2347783-87-interdiff.txt597 byteskim.pepper
#85 2347783-85.patch132.48 KBkim.pepper
#85 2347783-85-interdiff.txt10.07 KBkim.pepper
#83 interdiff-2347783-81-83.txt1.66 KBnaveenvalecha
#83 2347783-83.patch128.17 KBnaveenvalecha
#81 interdiff.txt696 bytesrodrigoaguilera
#81 2347783-81.patch128.17 KBrodrigoaguilera
#79 interdiff.txt1.41 KBrodrigoaguilera
#79 2347783-79.patch128.14 KBrodrigoaguilera
#78 interdiff-72-76.txt12.3 KBrodrigoaguilera
#76 2347783-76.patch128.45 KBrodrigoaguilera
#74 2347783-74.patch126.65 KBrodrigoaguilera
#72 2347783-72.patch130.56 KBrodrigoaguilera
#70 2347783-70.patch129.67 KBizus
#69 2347783-89.patch129.67 KBizus
#67 interdiff.txt1.83 KBalmaudoh
#67 2347783-67.patch129.76 KBalmaudoh
#64 2347783-64.patch129.85 KBalmaudoh
#64 interdiff.txt812 bytesalmaudoh
#60 2347783-60.patch129.03 KBalmaudoh
#60 interdiff.txt22.35 KBalmaudoh
#57 2347783-drupal_get_path-57.patch111.84 KBgumanist
#57 interdiff.txt1.45 KBgumanist
#54 2347783-drupal_get_path-54.patch111.68 KBgumanist
#54 interdiff-52-54.txt1.37 KBgumanist
#52 2347783-drupal_get_path-52.patch111.53 KBgumanist
#52 interdiff.txt1.1 KBgumanist
#51 2347783-drupal_get_path-50.patch111.42 KBandypost
#48 47-48-changes.txt8.71 KBalmaudoh
#47 2347783-47.patch110.65 KBandypost
#47 interdiff.txt24.75 KBandypost
#44 interdiff.txt3.76 KBgumanist
#44 2347783-43.patch92.29 KBgumanist
#42 interdiff.txt5.7 KBgumanist
#42 2347783-42.patch88.38 KBgumanist
#38 2347783-38.patch87.86 KBgumanist
#30 2347783-30.patch92.07 KBalmaudoh
#30 interdiff.txt938 bytesalmaudoh
#28 2347783-28.patch92.07 KBalmaudoh
#28 interdiff.txt649 bytesalmaudoh
#26 2347783-26.patch92.32 KBalmaudoh
#26 interdiff.txt760 bytesalmaudoh
#24 2347783-24.patch92.61 KBalmaudoh
#24 interdiff.txt100.91 KBalmaudoh
#22 2347783-22.patch90.76 KBharsha012
#19 extension_system-deprecate-2347783-D8.patch916 bytesioana apetri

Issue fork drupal-2347783

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

almaudoh’s picture

Title: Remove drupal_get_path() as public facing API and replace with module_load_include() for including PHP code » Remove drupal_get_path() as public facing API and replace with module_load_include() for including PHP files
tim.plunkett’s picture

drupal_get_path() is used for much more than PHP files.
Mostly for CSS and JS.

almaudoh’s picture

Status: Active » Postponed

@tim.plunkett, this is kinda jumping ahead of #1308152-182: Add stream wrappers to access .json files in extensions. Marking postponed on that one.

midynamics’s picture

I would agree with almoudoh. Its best to remove drupal_get_path()and replace with module_load_include

Crell’s picture

With most code now in classed objects, do we even need module_load_include() anymore? I don't think it has a purpose. (If you have enough procedural code to bother breaking into multiple files then most of it should be in classes anyway.)

tim.plunkett’s picture

Thats a nice thought, but it's post-beta and there are 53 usages of module_load_include in HEAD.

almaudoh’s picture

Related issue #697946: Properly deprecate module_load_include() and move it into \Drupal::moduleHandler() service where module_load_include() is replaced with include_once(), file_exists() and drupal_get_path(). So are we going round in loops...

fietserwin’s picture

If we don't want to go around in loops with #697946: Properly deprecate module_load_include() and move it into \Drupal::moduleHandler() service, we might change the goal of this issue into striving to replace the other usages of drupal_get_path():

- js files: about 23 usages: replace with module://...?
- css files: about 37 usages: replace with module://...?
- info.yml: 2 usages (and 1 in a comment): replace with $this->moduleHandler()->getModule($moduleName)->getName()
- other .yml: 2 usages: replace with module://...?
- xml files: 4 usages: replace with module://...?
- php files not to be included but to be executed via an HTTP request in tests: 8 usages: can be replaced with module://

In total there are about 181 usages. It seems that many can be replaced with module:// (or theme:// or profile:// or the not yet existing library://) as their usage is in adding css/js resources to a page, and many are in test situations. However, to which degree, do we want to make our tests depend on other functionality like module:// where a small error in the module stream wrapper may lead to 1000's of test failures?

For not test situations: how is the order of loading? I saw some usages of drupal_get_path in the module handler, so that obviously can't be replaced with module://. But how early are the stream wrappers loaded, currently and after turning them into services?

almaudoh’s picture

Already raised #2350553: Replace uses of drupal_get_path() for CSS and JS files with module:// theme:// and profile://streamwrappers to replace usages for CSS and JS files which more or less everyone agrees on. So this issue can be rescoped to discuss (and implement) the other use cases.

almaudoh’s picture

Title: Remove drupal_get_path() as public facing API and replace with module_load_include() for including PHP files » [PP-2] Remove drupal_get_path() as public facing API for including files
Version: 8.0.x-dev » 8.1.x-dev
Issue summary: View changes
Related issues: +#2208429: Extension System, Part III: ExtensionList, ModuleExtensionList and ProfileExtensionList, +#2351919: Replace uses of drupal_get_path() with __DIR__ where possible

There's now a better direction, with a more streamlined extension system for (profiles, module, theme, theme_engines, etc.), drupal_get_path() will be easily replaced by ExtensionList::getPath($extension_name)

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jibran’s picture

Title: [PP-2] Remove drupal_get_path() as public facing API for including files » [PP-1] Remove drupal_get_path() as public facing API for including files
almaudoh’s picture

Title: [PP-1] Remove drupal_get_path() as public facing API for including files » Deprecate drupal_get_path() and replace with ExtensionList::getPath()
Component: file system » extension system
Status: Postponed » Active

Rescoping this issue to deprecate drupal_get_path() and replace with ExtensionList::getPath(). The second issue this was postponed on has been fixed for D8 and is just awaiting backport to D7.

ioana apetri’s picture

Status: Active » Needs review
StatusFileSize
new916 bytes

I created a change record and I deprecate the drupal_get_path() function.
Please review.
Thanks:).

almaudoh’s picture

You should actually remove the uses of drupal_get_path() in the code base as well and replace with \Drupal::service('extension.list.module')->getPath($module_name);

harsha012’s picture

Status: Needs work » Needs review
StatusFileSize
new90.76 KB

fixed as per #21

almaudoh’s picture

Status: Needs work » Needs review
StatusFileSize
new100.91 KB
new92.61 KB

So this is not a simple matter of find and replace. drupal_get_path() is used in so many places in core that it would be difficult to inject the service classes into all the places where it is used. So this patch does the following:

1. Creates a new trait called ExtensionPathsTrait that provides wrappers around drupal_get_path() for modules and profiles. So using this trait in classes allows the classes to call $this->getModulePath() or $this->getProfilePath() instead of having to inject the dependencies directly. This pattern is used in core in other places e.g. with StringTranslationTrait

2. A method ::getModulePath($module_name) is also added to KernelTestBase, BrowserTestBase and WebTestBase since so many tests use drupal_get_path() and it's easier DX to just have a helper method.

3. Injection is done in a few places where there's no BC impact.

4. __DIR__ is used in places where there is a fixed relative path the script file and the other file being referenced (e.g. files in the same module)

5. The rest just directly call the service using \Drupal::service($service_name)->getPath()

6. Changes made to drupal_get_path('theme', ...) were reverted pending when #2659940: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList is committed.

almaudoh’s picture

Status: Needs work » Needs review
StatusFileSize
new760 bytes
new92.32 KB

Removed the @trigger_error from drupal_get_filename(), since that still has uses in many parts of the codebase.

almaudoh’s picture

Status: Needs work » Needs review
StatusFileSize
new649 bytes
new92.07 KB

Also removed the @trigger_error from drupal_get_path(), since we didn't remove all its uses. Just to allow testbot confirm that the changes are sane.

almaudoh’s picture

Status: Needs work » Needs review
StatusFileSize
new938 bytes
new92.07 KB

Made a little blunder there yesterday. Fixed now. Let's see how it goes.

almaudoh’s picture

Title: Deprecate drupal_get_path() and replace with ExtensionList::getPath() » [PP 1] Deprecate drupal_get_path() and replace with ExtensionList::getPath()
Status: Needs work » Postponed
Related issues: +#2659940: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andypost’s picture

Title: [PP 1] Deprecate drupal_get_path() and replace with ExtensionList::getPath() » Deprecate drupal_get_path() and replace with ExtensionList::getPath()
Status: Postponed » Needs work
andypost’s picture

Issue tags: +@deprecated, +Kill includes
almaudoh’s picture

Issue tags: +Needs reroll
wim leers’s picture

🥳

gumanist’s picture

Status: Needs work » Needs review
StatusFileSize
new87.86 KB
andypost’s picture

Issue tags: -Needs reroll
berdir’s picture

  1. +++ b/core/lib/Drupal/Core/Theme/Registry.php
    @@ -820,7 +830,7 @@ public function getPrefixGroupedUserFunctions($prefixes = []) {
     
       /**
    -   * Wraps drupal_get_path().
    +   * Wraps ExtensionList::getPath().
        *
    

    We only needed to wrap the function because it was a function, to make unit tests happy. Now that it no longer is, we can just call $this->moduleList->getPath() directly.

    Not sure if we should keep the protected function getPath(), we might need to, to be extra careful with subclasses.

  2. +++ b/core/lib/Drupal/Core/Theme/Registry.php
    @@ -828,7 +838,10 @@ public function getPrefixGroupedUserFunctions($prefixes = []) {
        */
       protected function getPath($module) {
    -    return drupal_get_path('module', $module);
    +    if ($this->moduleList === NULL) {
    +      $this->moduleList = \Drupal::service('extension.list.module');
    +    }
    +    return $this->moduleList->getPath($module);
       }
    

    the common approach is to do the fallback directly in the constructor, possibly with a @trigger_error() if it's missing.

  3. +++ b/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php
    @@ -65,7 +65,7 @@ protected function setUp() {
       /**
        * Returns the module name and the module directory for the plugin.
        *
    -   * Function drupal_get_path() cannot be used here, because it is not available
    +   * ExtensionList::getPath() cannot be used here, because it is not available
        * in Drupal PHPUnit tests.
        *
    

    Same here, the the description doesn't make sense anymore

gumanist’s picture

Status: Needs work » Needs review
StatusFileSize
new88.38 KB
new5.7 KB

Thanks @Berdir

gumanist’s picture

Status: Needs work » Needs review
StatusFileSize
new92.29 KB
new3.76 KB

Missed trait

almaudoh’s picture

  1. +++ b/core/lib/Drupal/Core/Updater/Theme.php
    @@ -25,8 +25,8 @@ class Theme extends Updater implements UpdaterInterface {
    +    if ($this->isInstalled() && ($relative_path = \Drupal::service('extension.list.theme')->getPath('theme', $this->name))) {
    

    Should be return (bool) \Drupal::service('extension.list.theme')->getPath($this->name);

  2. +++ b/core/lib/Drupal/Core/Updater/Theme.php
    @@ -71,7 +71,7 @@ public static function canUpdateDirectory($directory) {
    +    return (bool) \Drupal::service('extension.list.theme')->getPath('theme', $project_name);
    

    Same here

  3. +++ b/core/modules/color/color.module
    @@ -143,7 +143,7 @@ function color_get_info($theme) {
    +  $path = \Drupal::service('extension.list.theme')->getPath('theme', $theme);
    

    Same here

  4. +++ b/core/modules/color/color.module
    @@ -400,7 +400,7 @@ function color_scheme_form_submit($form, FormStateInterface $form_state) {
    +    $source = \Drupal::service('extension.list.theme')->getPath('theme', $theme) . '/' . $info['base_image'];
    
    @@ -445,7 +445,7 @@ function color_scheme_form_submit($form, FormStateInterface $form_state) {
    +  $paths['source'] = \Drupal::service('extension.list.theme')->getPath('theme', $theme) . '/';
    

    Same here too

  5. +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaDisplayTest.php
    @@ -24,7 +24,7 @@ protected function setUp() {
    +    $extension_path = \Drupal::service('extension.list.module')->getPath('profile', 'standard');
    

    Should be $extension_path = \Drupal::service('extension.list.profile')->getPath('standard');

andypost’s picture

StatusFileSize
new24.75 KB
new110.65 KB

Fix #46 and few other places
I think deprecation of drupal_get_filename() needs separate issue because this patch is already big enough

Remaining usage (todo)
- module_load_include()
- \Drupal\Core\Config\ConfigInstaller::drupalGetPath()
- \Drupal\Core\Config\ConfigManager::uninstall()

almaudoh’s picture

StatusFileSize
new8.71 KB

I was actually working on a patch, but you beat me to it. So here's a diff off what additional stuff I did, in case you're still working on it.

andypost’s picture

@almaudoh Thanks for fixes, meanwhile would be great to check #697946: Properly deprecate module_load_include() and move it into \Drupal::moduleHandler() service
ATM I'm workin on followup for drupal_get_filename() cos it needs separate CR and will help to simplify the patch a bit

andypost’s picture

StatusFileSize
new111.42 KB

Let's see how many fails with #48 interdiff

gumanist’s picture

StatusFileSize
new1.1 KB
new111.53 KB

Updated files getPath instead of __DIR__

gumanist’s picture

Status: Needs work » Needs review

oups, status...

gumanist’s picture

StatusFileSize
new1.37 KB
new111.68 KB

Removed __DIR__ for other places in locale module

gumanist’s picture

StatusFileSize
new1.45 KB
new111.84 KB

Replaced with services for batches in update and node modules

gumanist’s picture

Status: Needs work » Needs review

status

almaudoh’s picture

Status: Needs work » Needs review
StatusFileSize
new22.35 KB
new129.03 KB

Made some fixes to the tests that are failing. The patch is now huge and would need to be split into three or more pieces.

I suggest:
1. Direct replacements in tests without any dependency injection
2. Replacement in classes or other services which require dependency injection
3. Replacement in functions which don't require dependency injection.

andypost’s picture

I find strange that __DIR__ replaced with service call, it reverts #2351919: Replace uses of drupal_get_path() with __DIR__ where possible

almaudoh’s picture

I find strange that __DIR__ replaced with service call, it reverts #2351919: Replace uses of drupal_get_path() with __DIR__ where possible

Not really, the __DIR__ uses replaced in recent patches were actually introduced in this issues' original patch #24.4, not in #2351919: Replace uses of drupal_get_path() with __DIR__ where possible. In these cases __DIR__ cannot be used because what is needed is a relative path (e.g. core/modules/statistics) while __DIR__ will return an absolute path (e.g. /var/www/html/core/modules/statistics), and calculating the relative path is more expensive than just pulling it from the ModuleExtensionList service. This may be why these particular cases were not changed by the #2351919 patch

almaudoh’s picture

Status: Needs work » Needs review
Related issues: +#2808063: LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist
StatusFileSize
new812 bytes
new129.85 KB

Finally found time to fix the AjaxTest. A similar fix was tried in #2808063: LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist

almaudoh’s picture

Issue summary: View changes
andypost’s picture

Nice summary! Meanwhile ci shows 4 coding standards messages

almaudoh’s picture

StatusFileSize
new129.76 KB
new1.83 KB

Fixed coding standard nits.

izus’s picture

Status: Needs work » Needs review
StatusFileSize
new129.67 KB

Hi,
rerolled #67 to trigger again tests
hope it'll be green this time

izus’s picture

StatusFileSize
new129.67 KB

corrected the increment error in the file name

andypost’s picture

+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -18,6 +19,8 @@
+  use ExtensionListingTrait;

@@ -254,7 +257,7 @@ protected function getComponentFolder(Extension $extension) {
-    return drupal_get_path('core', 'core') . '/' . $this->getCollectionDirectory();
+    return $this->getCorePath() . '/' . $this->getCollectionDirectory();

+++ b/core/modules/ckeditor/src/CKEditorPluginBase.php
@@ -30,6 +31,8 @@
+  use ExtensionListingTrait;

+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
@@ -22,7 +22,7 @@ class DrupalImage extends CKEditorPluginBase implements CKEditorPluginConfigurab
+    return $this->getModulePath('ckeditor') . '/js/plugins/drupalimage/plugin.js';

@@ -51,7 +51,7 @@ public function getButtons() {
+        'image' => $this->getModulePath('ckeditor') . '/js/plugins/drupalimage/icons/drupalimage.png',

+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
@@ -46,7 +49,7 @@ public function getLibraries(Editor $editor) {
+    return $this->getModulePath('ckeditor') . '/js/plugins/drupalimagecaption/plugin.js';

@@ -70,7 +73,7 @@ public function getConfig(Editor $editor) {
+      $this->getModulePath('ckeditor') . '/css/plugins/drupalimagecaption/ckeditor.drupalimagecaption.css',

+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalLink.php
@@ -20,7 +20,7 @@ class DrupalLink extends CKEditorPluginBase {
+    return $this->getModulePath('ckeditor') . '/js/plugins/drupallink/plugin.js';

@@ -46,7 +46,7 @@ public function getConfig(Editor $editor) {
+    $path = $this->getModulePath('ckeditor') . '/js/plugins/drupallink';

+++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/Language.php
@@ -128,7 +128,7 @@ public function settingsForm(array $form, FormStateInterface $form_state, Editor
+      $this->getModulePath('ckeditor') . '/css/plugins/language/ckeditor.language.css',

+++ b/core/modules/ckeditor/tests/modules/src/Form/AjaxCssForm.php
@@ -14,6 +15,8 @@
+  use ExtensionListingTrait;

@@ -81,7 +84,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
+    $url = $this->getModulePath('ckeditor_test') . '/css/test.css';

+++ b/core/modules/update/src/Form/UpdateManagerUpdate.php
@@ -16,6 +17,8 @@
+  use ExtensionListingTrait;

@@ -336,7 +339,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
+      'file' => $this->getModulePath('update') . '/update.manager.inc',

This looks the all of usage of the trait, so I think no reason to implement the trait.
Instead, helpers like ones added to testBase classes makes sense

rodrigoaguilera’s picture

StatusFileSize
new130.56 KB

This patch needed a reroll for a conflict in
core/modules/system/src/Form/ThemeSettingsForm.php

I want to try to address #71 after the reroll

rodrigoaguilera’s picture

Status: Needs work » Needs review
StatusFileSize
new126.65 KB

oops. missing comma

rodrigoaguilera’s picture

Status: Needs work » Needs review
StatusFileSize
new128.45 KB

The patch in #74 was missing the new Trait.

In the patch attached I remove that trait with methods in the CkeditorPluginBase. I also fix the code style issue reported by the CI.

I don't know what is happening with the CI...

rodrigoaguilera’s picture

Status: Needs work » Needs review
StatusFileSize
new12.3 KB

Forgot the interdiff

rodrigoaguilera’s picture

StatusFileSize
new128.14 KB
new1.41 KB

Ok, It was not a good decision to make DrupalImageCaption extend CKEditorPluginBase. Reverting that.

rodrigoaguilera’s picture

Status: Needs work » Needs review
StatusFileSize
new128.17 KB
new696 bytes

I forgot one getModulePath

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

naveenvalecha’s picture

StatusFileSize
new128.17 KB
new1.66 KB

Here's the updated patch for 8.8.x with the updated deprecated message.

kim.pepper’s picture

Status: Needs review » Needs work

Looking great!

Just a few nitpicks...

  1. +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
    @@ -235,13 +235,13 @@ public function setProfileDirectoriesFromSettings() {
    +        $this->profileDirectories[] = \Drupal::service('extension.list.profile')->getPath($testing_profile);
    

    Can we create a local variable and typehint?

  2. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -509,7 +509,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
    +    $service_yaml_file = \Drupal::service('extension.list.module')->getPath($module) . "/$module.services.yml";
    

    Can we inject this?

  3. +++ b/core/lib/Drupal/Core/Theme/Registry.php
    @@ -177,6 +194,11 @@ public function __construct($root, CacheBackendInterface $cache, LockBackendInte
    +      @trigger_error('The extension.list.module service is a required parameter to the Registry constructor in Drupal 9.0.0.', E_USER_DEPRECATED);
    

    Can we use the *almost* standard format? https://www.drupal.org/project/coding_standards/issues/3024461

  4. +++ b/core/modules/system/tests/modules/common_test/src/Controller/CommonTestController.php
    @@ -67,9 +67,9 @@ public function jsAndCssQuerystring() {
    +          \Drupal::service('extension.list.module')->getPath('node') . '/css/node.admin.css' => [],
    ...
    +          '/' . \Drupal::service('extension.list.module')->getPath('node') . '/node-fake.css?arg1=value1&arg2=value2' => [],
    

    Can we create a local variable then do assert($var instanceof ModuleExtensionList)?

  5. +++ b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
    @@ -111,7 +113,8 @@ public function testSuggestionPreprocessFunctions() {
    +    $extension_list = \Drupal::service('extension.list.module');
    

    assert($extension_list instanceof ModuleExtensionList)

  6. +++ b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
    @@ -199,7 +203,8 @@ public function testThemeTemplatesRegisteredByModules() {
    +    $extension_list = \Drupal::service('extension.list.module');
    

    Ditto

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new10.07 KB
new132.48 KB

Fixes for my own feedback in #84 :-)

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new597 bytes
new132.91 KB

Updates services yaml.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new1.12 KB
new133.04 KB

Fix deprecation message.

subson’s picture

StatusFileSize
new133.98 KB

rerolling the patch against 8.8.x, am not able to take the interdiff between 89 and 90 as the earlier patch was not applying cleanly.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new134.77 KB

Here's another attempt at a reroll.

I also updated some of the deprecation messages to the standard format, and added a trigger_error where it was missing.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new134.74 KB
new971 bytes

Fixes deprecation test.

andypost’s picture

Looks great!
As I see it missing legacy tests for this functions but adds legacy test for constructor which looks not much useful
Also base test classes using duplicated methods - not sure it fits to trait but this is code duplication

  1. +++ b/core/includes/bootstrap.inc
    @@ -255,6 +255,18 @@ function config_get_config_directory($type) {
    + * @deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0.
    + *   Instead, you should use \Drupal\Core\Extension\ExtensionList::getPathname().
    + *   Where it is not possible to inject the service, you can use the
    + *   \Drupal::service('extension.list.module')->getPathName()
    + *   \Drupal::service('extension.list.profile')->getPathName()
    + *   \Drupal::service('extension.list.theme')->getPathName()
    + *   as appropriate.
    + *
    + * @see https://www.drupal.org/node/2940438
    + *
    + * @see \Drupal\Core\Extension\ExtensionList::getPathname()
      */
     function drupal_get_filename($type, $name, $filename = NULL) {
    

    Maybe this function also should trigger error (depending on $type pointing to valid service)?

  2. +++ b/core/includes/bootstrap.inc
    @@ -304,8 +316,14 @@ function drupal_get_filename($type, $name, $filename = NULL) {
     function drupal_get_path($type, $name) {
    +  @trigger_error('drupal_get_path() is deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Extension\ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438');
    

    otoh it will trigger twice if both functions will use it

  3. +++ b/core/modules/simpletest/src/WebTestBase.php
    @@ -2079,4 +2079,20 @@ protected function setHttpResponseDebugCacheabilityHeaders($value = TRUE) {
    +  protected function getModulePath($module_name) {
    +    return $this->container->get('extension.list.module')->getPath($module_name);
    

    other tests also add getThemePath (trait?)

  4. +++ b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
    @@ -255,4 +264,16 @@ public function testThemeTemplatesRegisteredByModules() {
    +   * @group legacy
    +   * @expectedDeprecation Calling Registry::__construct() without the $module_list argument is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2940438
    +   */
    +  public function testDeprecatedConstructor() {
    +    $theme_handler = \Drupal::service('theme_handler');
    +    $registry_theme = new Registry($this->root, \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme');
    +    $this->assertNotNull($registry_theme);
    

    Not sure it needed

  5. +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
    @@ -1107,4 +1107,36 @@ public static function assertEquals($expected, $actual, $message = '', $delta =
    +  protected function getModulePath($module_name) {
    +    return $this->container->get('extension.list.module')->getPath($module_name);
    ...
    +  protected function getThemePath($theme_name) {
    +    return $this->container->get('extension.list.theme')->getPath($theme_name);
    
    +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -743,4 +743,36 @@ protected function translatePostValues(array $values) {
    +  protected function getModulePath($module_name) {
    +    return $this->container->get('extension.list.module')->getPath($module_name);
    ...
    +  protected function getThemePath($theme_name) {
    +    return $this->container->get('extension.list.theme')->getPath($theme_name);
    

    Could be a trait

andypost’s picture

Status: Needs review » Needs work

NW for message

+++ b/core/includes/bootstrap.inc
@@ -255,6 +255,18 @@ function config_get_config_directory($type) {
+ * @deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0.

@@ -304,8 +316,14 @@ function drupal_get_filename($type, $name, $filename = NULL) {
+ * @deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0.
...
+  @trigger_error('drupal_get_path() is deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Extension\ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438');

The message should use new format `drupal:8.8.0` and so on according to https://www.drupal.org/core/deprecation#how-function

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new155.22 KB
new28.25 KB

#95:

  1. Added the trigger_error()
  2. Triggering 2 deprecations seems ok to me
  3. Added a getThemePath()
  4. Removed
  5. Do we really need a trait for this? 🤔

#96 updated deprecation format.

I added the deprecation and realised there were quite a lot of usages that were still in core. I've made an attempt to replace them all, however, not sure what is going to break now.

kim.pepper’s picture

+++ b/core/lib/Drupal/Core/Config/ConfigManager.php
@@ -238,7 +268,18 @@ public function uninstall($type, $name) {
+    switch ($type) {
+      case 'module':
+        $schema_dir = $this->moduleExtensionList->getPathname($name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY;
+        break;
+
+      case 'theme':
+        $schema_dir = $this->themeExtensionList->getPathname($name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY;
+        break;
+
+      default:
+        $schema_dir = NULL;
+    }

This makes me think we haven't got the api right yet!

berdir’s picture

Went through the patch a bit, not a full review...

  1. +++ b/core/includes/bootstrap.inc
    @@ -255,8 +255,21 @@ function config_get_config_directory($type) {
    + * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, you
    + *   should use \Drupal\Core\Extension\ExtensionList::getPathname().
    + *   Where it is not possible to inject the service, you can use the
    + *   \Drupal::service('extension.list.module')->getPathName()
    + *   \Drupal::service('extension.list.profile')->getPathName()
    + *   \Drupal::service('extension.list.theme')->getPathName()
    + *   as appropriate.
    

    I think we can still improve this a bit.

    You also need to know the corresponding service name if you do inject it, so maybe it should be something like "Use ExtensionList::getPathname() from the respective service (extension.list.module, extension.list.profile, extension.list.theme)" or so

  2. +++ b/core/includes/install.core.inc
    @@ -471,10 +476,9 @@ function install_begin_request($class_loader, &$install_state) {
       // Before having installed the system module and being able to do a module
    -  // rebuild, prime the drupal_get_filename() static cache with the system
    +  // rebuild, prime the module list static cache with the system
       // module's location.
    -  // @todo Remove as part of https://www.drupal.org/node/2186491
    -  drupal_get_filename('module', 'system', 'core/modules/system/system.info.yml');
    +  $module_list->setPathname('system', 'core/modules/system/system.info.yml');
     
    

    doesn't feel like we've really resolved this @todo and the one for user below. We apparently still special-case system and user, I think that @todo doesn't mean to just replace it with the equivalent method/service but completely remove it. I'd just keep the @todo for now?

  3. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -91,11 +121,12 @@ public function buildByExtension($extension) {
           if ($this->moduleHandler->moduleExists($extension)) {
             $extension_type = 'module';
    +        $path = $this->moduleList->getPath($extension);
           }
           else {
             $extension_type = 'theme';
    +        $path = $this->themeList->getPath($extension);
           }
    -      $path = $this->drupalGetPath($extension_type, $extension);
    

    apparently we still need $extension_type below, once..

  4. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -400,13 +431,6 @@ protected function applyLibrariesOverride($libraries, $extension) {
    -  /**
    -   * Wraps drupal_get_path().
    -   */
    -  protected function drupalGetPath($type, $name) {
    -    return drupal_get_path($type, $name);
    -  }
    -
    

    we've kept such methods before in similar cases and deprecated them as well. kinda overkill, but might be the safer option?

  5. +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
    @@ -667,7 +667,7 @@ protected function getDefaultConfigDirectory($type, $name) {
       /**
    -   * Wrapper for drupal_get_path().
    +   * Wrapper for ExtensionList::getPath().
        *
        * @param $type
    

    looks like this updates the docs but not the actual implementation? Possibly another one we want to deprecate and use an injected service?

  6. +++ b/core/lib/Drupal/Core/Config/ConfigManager.php
    @@ -238,7 +268,18 @@ public function uninstall($type, $name) {
     
    -    $schema_dir = drupal_get_path($type, $name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY;
    +    switch ($type) {
    +      case 'module':
    +        $schema_dir = $this->moduleExtensionList->getPathname($name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY;
    +        break;
    +
    +      case 'theme':
    +        $schema_dir = $this->themeExtensionList->getPathname($name) . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY;
    +        break;
    +
    +      default:
    +        $schema_dir = NULL;
    +    }
    

    can there be anything else?

    I mean we could do something like this, but not sure if that's really better:

    $schema_dir = $this->{$type . 'ExtensionList'}->getPathname().

    That's basically what drupal_get_path/filename does too with "\Drupal::service("extension.list.$type")", so that would fail hard if called with something non-existing as well.

  7. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -461,7 +475,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
           // Clear the static cache of the "extension.list.module" service to pick
           // up the new module, since it merges the installation status of modules
           // into its statically cached list.
    -      \Drupal::service('extension.list.module')->reset();
    +      $this->moduleExtensionList->reset();
     
           // Clear plugin manager caches.
           \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
    

    there might be a reason we didn't inject that yet, module installer is really funky as it does container rebuilds.

  8. +++ b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
    @@ -74,13 +82,16 @@ class CKEditor extends EditorBase implements ContainerFactoryPluginInterface {
         $this->languageManager = $language_manager;
         $this->renderer = $renderer;
    +    $this->moduleList = $module_list;
       }
    

    missing the deprecation thingy.

  9. +++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
    @@ -28,6 +29,8 @@ public function register(ContainerBuilder $container) {
       /**
        * Tests that drupal_get_filename() works when the file is not in database.
    +   *
    +   * @expectedDeprecation drupal_get_filename() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathName() instead. See https://www.drupal.org/node/2940438
        */
       public function testDrupalGetFilename() {
    

    Having a dejavu, but I think this test isn't just a legacy test, that still needs to work now for our installer? so maybe instead rename and use the extension list?

  10. +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -512,3 +509,7 @@ protected function getPath($module) {
     }
    +
    +if (!defined('DRUPAL_MINIMUM_PHP')) {
    +  define('DRUPAL_MINIMUM_PHP', '5.5.9');
    +}
    

    looks like a merge leftover... this was removed.

joachim’s picture

> there might be a reason we didn't inject that yet, module installer is really funky as it does container rebuilds.

Sounds like we should open a side issue to add a comment about that there, so it doesn't get accidentally 'fixed' in future.

kim.pepper’s picture

StatusFileSize
new158.59 KB
new18.51 KB

Thanks @Berdir

  1. Fixed
  2. Fixed
  3. Yes? I left as is.
  4. Fixed
  5. Fixed
  6. I was thinking factory? So you could do something like ExtensionListFactory::getExtensionList($type)
  7. Reverted those changes.
  8. Fixed
  9. Changed the name and switched to using the ExtensionLists. I also cleaned up the missing extension test, as it was doing something funky with state??
  10. Fixed. Although we needed to require_once bootstrap in order to get the DRUPAL_MINIMUM_PHP constant.
kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new167.07 KB
new14.86 KB

Re: #101.6 here's what I was thinking for an extension list factory. I think it makes things a lot cleaner.

kim.pepper’s picture

StatusFileSize
new167.14 KB
new4.7 KB

Hmm. Need to special-case some logic for core in ConfigInstaller.

berdir’s picture

  1. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -431,6 +431,19 @@ protected function applyLibrariesOverride($libraries, $extension) {
    +  protected function drupalGetPath($type, $name) {
    +    @trigger_error('drupalGetPath() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    maybe include the classname for those methods?

  2. +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -81,6 +81,7 @@ class RegistryTest extends UnitTestCase {
       protected function setUp() {
         parent::setUp();
    +    require_once $this->root . '/core/includes/bootstrap.inc';
     
    

    hm, I know we don't do that in unit tests because it pollutes all tests. If we need it then I assume we have to re-add the constant, just with the right value.

    Why do we need it now though?

  1. +++ b/core/lib/Drupal/Core/Extension/ExtensionListFactory.php
    @@ -0,0 +1,66 @@
    +
    +/**
    + * Factory for getting extension lists by type.
    + */
    +class ExtensionListFactory {
    

    Maybe, but not sure if factory is the right term here? It doesn't actually create them, just allows you to access them through a single dependency?

    Can't really think of a good name right now, ExtensionListRepository also doesn't seem that great?

  2. +++ b/core/tests/Drupal/KernelTests/Core/Extension/ExtensionListFactoryTest.php
    @@ -0,0 +1,37 @@
    +    $factory = $this->container->get('extension.list.factory');
    +    $this->assertNotNull($factory);
    

    maybe use an assertInstanceOf for these?

+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -108,7 +108,12 @@ public function __construct(ConfigFactoryInterface $config_factory, StorageInter
   public function installDefaultConfig($type, $name) {
-    $extension_path = $this->extensionListFactory->get($type)->getPathname($name);
+    if ($type === 'core') {
+      $extension_path = 'core';
+    }
+    else {
+      $extension_path = $this->extensionListFactory->get($type)->getPathname($name);

I suppose that's exactly why we have the core logic in drupal_get_filename() :)

kim.pepper’s picture

Status: Needs review » Needs work

Maybe, but not sure if factory is the right term here? It doesn't actually create them, just allows you to access them through a single dependency?

Can't really think of a good name right now, ExtensionListRepository also doesn't seem that great?

We could:

  1. Rename it to ExtensionPathResolver - always liked 'resolver' ;-)
  2. Have a getPathname() (getPath()?) method
  3. Encapsulate the 'core' special-case handling
  4. internally look up the right extension list, and call getPathname() on it
berdir’s picture

Status: Needs work » Needs review

That sounds interesting, I guess most cases that need to call the same method on these services dynamically is the path stuff?

andypost’s picture

Last weekend I used to dig Advanced help module and filed #3077074: [Meta] Change mentions from module to extension
Module using module & theme handlers to look for read.me(+ bit more) in active extensions
Then a lot of UI/render require to
- get path to use "finder"
- render extension name - that's where it using proxy ModuleHandler::getName()

kim.pepper’s picture

StatusFileSize
new169.66 KB
new18.65 KB

Here's an attempt at the idea suggested in #106.

kim.pepper’s picture

StatusFileSize
new169.65 KB
new1.44 KB

Fixed incorrect replacement of getPathname() instead of getPath().

joachim’s picture

Not a full review, but I spotted this:

+++ b/core/includes/install.core.inc
@@ -471,10 +476,9 @@ function install_begin_request($class_loader, &$install_state) {
-  // @todo Remove as part of https://www.drupal.org/node/2186491

This @todo shouldn't be getting removed.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new169.03 KB
new5.52 KB

Found another place that can use ExtensionPathResolver.

Re #113: restores todo

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new167.85 KB
new10.2 KB

Fix LibraryDiscoveryParserTest fails.

kim.pepper’s picture

I'm scratching my head over these fails...

1) Drupal\FunctionalTests\Installer\InstallerExistingConfigNoSystemSiteTest::testConfigSync
Exception: Notice: Undefined index: theme
Drupal\Core\Config\ConfigImporter->createExtensionChangelist()() (Line: 435)
voleger’s picture

In BrowserTestBaseUserAgentTest I comparing the values that provaided before and after changes. So
drupal_get_path('module', 'system') returns path to the directory, but $this->container->get('extension.list.module')->getPathname('system') returns path to the info file.
See the results:

core/modules/system
core/modules/system/system.info.yml
voleger’s picture

So the main problem is in that test getPathname method call have to be replaced with getPath method call

voleger’s picture

+++ b/core/includes/install.core.inc
@@ -454,12 +454,17 @@ function install_begin_request($class_loader, &$install_state) {
+  /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
+  $module_list = \Drupal::service('extension.list.module');
+  /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_list */
+  $profile_list = \Drupal::service('extension.list.module');

Also, I'm not sure that $profile_list have to be an instance of the extension.list.module service.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new167.84 KB
new1.6 KB

Thanks @voleger 🎉 They are definitely bugs, however I don't think that will fix the fails.

kim.pepper’s picture

From @Berdir slack:

random guess on ..., could it also be due to depency injection?

config importer installs modules, and then the injected service doesn't know about the thing thing that it just installed

kim.pepper’s picture

I think I need a picture to get my head around that! 🤯

voleger’s picture

At least we fix the UA related test.
There is more issue related to changes introduced by the patch:

+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -79,21 +87,28 @@ class ConfigInstaller implements ConfigInstallerInterface {
-    $extension_path = $this->drupalGetPath($type, $name);
+    $extension_path = $this->extensionPathResolver->getDir($type, $name);

There is an incorrect method call introduced in the ConfigInstaller. getInfoPath method call has to be used instead of getDir method call.

kim.pepper’s picture

There is an incorrect method call introduced in the ConfigInstaller. getInfoPath method call has to be used instead of getDir method call.

I don't think that's true? Looking at how $extension_path is used on the next line indicates it should be a directory.

if (is_dir($extension_path . '/' . InstallStorage::CONFIG_SCHEMA_DIRECTORY) || $type == 'theme') {
      $this->typedConfig->clearCachedDefinitions();
}
voleger’s picture

I debugging the code in the context of the InstallerBase tests, so I'm also confused about that. But the return values of the replaced code is different so that looks incorrect.
Also

  1. +++ b/core/includes/bootstrap.inc
    @@ -255,8 +255,18 @@ function config_get_config_directory($type) {
    + * @see \Drupal\Core\Extension\ExtensionList::getPathnØame()
    

    Typo here

  2. +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
    @@ -663,7 +678,7 @@ protected function getProfileStorages($installing_name = '') {
    +    return $this->extensionPathResolver->getDir($type, $name) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
    

    Checked the return values of the replaced code so in the context of the InstallerBase test here we can get the next values:
    $this->drupalGetPath($type, $name) returns core
    $this->extensionPathResolver->getDir($type, $name) returns .
    But if we replace code with $this->extensionPathResolver->getInfoPath($type, $name) that will returns core

voleger’s picture

I have an assumption that at some phase we set the dirname path to the extension path property instead of the filename of the info file of that extension. Can be that a reason why we can get the correct value from getFilename method instead of getDir method?

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new168.27 KB
new2.43 KB

Checked the return values of the replaced code so in the context of the InstallerBase test here we can get the next values:
$this->drupalGetPath($type, $name) returns core
$this->extensionPathResolver->getDir($type, $name) returns .
But if we replace code with $this->extensionPathResolver->getInfoPath($type, $name) that will returns core

Aha! That was the problem. I tried to remove that code in the ExtensionPathResolver, but it's required for the 'core' type.

voleger’s picture

Oh, that makes sense. And also fixes the installer related tests.
+1 for rtbc

andypost’s picture

+1 to rtbc but I think @Berdir should set it

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/core.services.yml
    @@ -512,20 +512,32 @@ services:
    +  extension.path.resolver:
    +    class: Drupal\Core\Extension\ExtensionPathResolver
    +    tags:
    +      - { name: service_collector, tag: extension_list, call: addExtensionList }
    

    I like the path resolver, but I'm not 100% sure that we should use an extensible pattern to inject its depenndencies, that implies an extensibility that doesn't actually exist? There is no use case for contrib to add another etension list?

  2. +++ b/core/includes/install.core.inc
    @@ -454,12 +454,17 @@ function install_begin_request($class_loader, &$install_state) {
       // Prime drupal_get_filename()'s static cache.
       foreach ($install_state['profiles'] as $name => $profile) {
    -    drupal_get_filename('profile', $name, $profile->getPathname());
    -    // drupal_get_filename() is called both with 'module' and 'profile', see
    +    // Profile path is set in both module and profile lists. See
         // \Drupal\Core\Config\ConfigInstaller::getProfileStorages for example.
    -    drupal_get_filename('module', $name, $profile->getPathname());
    +    $profile_list->setPathname($name, $profile->getPathname());
    +    $module_list->setPathname($name, $profile->getPathname());
       }
    

    I guess it's off-topic to fix that here, although we're actually specifically changing ConfigInstaller::getProfileStorages() here.

  3. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,92 @@
    +  public function getInfoPath($type, $name) {
    ...
    +   */
    +  public function getDir($type, $name) {
    +    return dirname($this->getInfoPath($type, $name));
    

    Why different method names here than on the extension lists? I agree that getPath() vs getPathname() is a bit confusing, but IIRC, that was discussed and explicitly decided to be consistent with https://www.php.net/manual/de/splfileinfo.getpathname.php and https://www.php.net/manual/de/splfileinfo.getpath.php.

    The class name is also ExtensionPathResolver.

    Also, we don't shorten things like that, so should be getDirectory() if we stick with that.

  4. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,92 @@
    +    // Type 'core' only exists to simplify application-level logic; it always
    +    // maps to the /core directory, whereas $name is ignored. It is only
    +    // requested via ::getDir(). /core/core.info.yml does not exist, but is
    +    // required since ::getDir() returns the dirname() of the returned pathname.
    +    if ($type === 'core') {
    +      return 'core/core.info.yml';
    +    }
    

    If it's only called through getDir() then why not implement it there?

  5. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -80,7 +88,14 @@ protected function setUp() {
         $this->streamWrapperManager = $this->createMock(StreamWrapperManagerInterface::class);
    -    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->streamWrapperManager);
    +    $this->extensionPathResolver = $this->prophesize(ExtensionPathResolver::class);
    +    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser(
    

    I'm a bit confused about our two mocking libraries in core to be honest.. other places use createMock(), this uses prophecy, it's not about consistency either as the call above is createMock() ;)

  6. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -620,3 +641,6 @@ public function setFileValidUri($source, $valid) {
     }
    +if (!defined('DRUPAL_MINIMUM_PHP')) {
    +  define('DRUPAL_MINIMUM_PHP', '5.5.9');
    

    still confused by this, as mentioned should at least use the same php version?

  7. +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -1,12 +1,8 @@
    -/**
    - * @file
    - * Contains \Drupal\Tests\Core\Theme\RegistryTest.
    - */
    -
    

    not really in scope ;)

  8. +++ b/core/modules/simpletest/src/WebTestBase.php
    @@ -2079,4 +2079,36 @@ protected function setHttpResponseDebugCacheabilityHeaders($value = TRUE) {
    +   *   The drupal-root relative path to the module directory.
    +   *
    +   * @throws \Drupal\Core\Extension\Exception\UnknownExtensionException
    +   *   If the module does not exist.
    +   */
    +  protected function getModulePath($module_name) {
    +    return $this->container->get('extension.list.module')->getPath($module_name);
    +  }
    +
    +  /**
    +   * Gets the path for the specified theme.
    

    we certainly don't need these methods on WebTestBsae and I'm also not sure if we should if others need it. Maybe it should be getExtensionPath($type, $name) and use the extension path resolver?

    kernel tests have 18 calls to their getModulePath() (and just 2 for getThemePath()), most of them for hardcoded method names that often violate https://www.drupal.org/node/3034299, for example all the ckeditor calls.

    And most that aren't their own module is for simpletest files, so something that we need to move out of there anyway.

    browser tests do have a bit more calls, and whlie most are also a hardcoded module, most need to relative path for checking http requests/html content, so __DIR__ doesn't work there. Maybe we could just keep a getExtensionPath() method there?

    Just thinking about loud, happy to hear counter-arguments on most of these (not WebTestBase, though :))

berdir’s picture

On #133.6, I did run the test without that line with run-tests.sh and phpunit directly and it's not needed?

andypost’s picture

There is no use case for contrib to add another etension list?

I suppose it is, at least db drivers screams about it

Why extension system should be not extensible?

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new167.73 KB
new24.1 KB

Thanks for the review @Berdir!

  1. Fixed. I removed the service collector, and added a constructor.
  2. Left this one alone.
  3. Fixed. Renamed to getPathname() and getPath() as this was previously agreed to.
  4. Fixed. Moved to getPath()
  5. Fixed. Changed to createMock()
  6. Fixed. Removed.
  7. Reverted. However, since we've touched this file, it will fail code sniffer.
  8. I removed getThemePath() as it wasn't used. I also replaced a few usages in \Drupal\aggregator\Tests\AggregatorTestBase although that is deprecated anyway.
berdir’s picture

> Why extension system should be not extensible?

Because it's not? ExtensionPathResolver has a hardcoded list of allowed types and validates against that.

+++ b/core/modules/aggregator/src/Tests/AggregatorTestBase.php
@@ -339,7 +339,7 @@ public function getEmptyOpml() {
    */
   public function getRSS091Sample() {
-    return $GLOBALS['base_url'] . '/' . $this->getModulePath('aggregator') . '/tests/modules/aggregator_test/aggregator_test_rss091.xml';
+    return __DIR__ . '../../tests/modules/aggregator_test/aggregator_test_rss091.xml';
   }

yeah, these are exactly problematic examples. This isn't about a local path, it's about a URL that is then requested in the test.

WebTestBase is fully deprecated and we shouldn't have any calls to WebTestBase::getModulePath() in this patch anyway?

kim.pepper’s picture

StatusFileSize
new163.95 KB
new3.79 KB

I've reverted changes to WebTestBase and sub-classes, removing getModulePath()

voleger’s picture

Found that #105.2 still without answer why we need this change.

+++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php
@@ -53,7 +53,7 @@ public function testDrupalSettingsCachingRegression() {
-    $fake_library = 'fakeLibrary/fakeLibrary';
+    $fake_library = 'ajax_test/fakeLibrary';

Also wondering why we need this change also. Does that mean influence on the library definitions?

kim.pepper’s picture

StatusFileSize
new163.23 KB
new1.96 KB

Thanks @voleger.

  1. I've removed bootstrap and are now defining DRUPAL_MINIMUM_PHP in the test setup.
  2. 🤷‍♂️ no idea. I've reverted.
voleger’s picture

#140.1 now it is better. Instead of including the whole bootstrap file just defining the required constant. And that is great, let's keep it for the issue related to moving those constant into namespaced class. See #2908079: Move some of the bootstrap.inc PHP-related constants to \Drupal and deprecate the old versions.

#140.2 Does that mean that change introduced in the patch has influence on the caching?

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new164.11 KB
new1.24 KB

Not sure.

I also re-removed the file docblock as this is now failing code sniffer as we've touched this file.

andypost’s picture

Issue tags: +Needs reroll
andypost’s picture

Issue tags: -Needs reroll
StatusFileSize
new816 bytes
new160.45 KB

Reroll and one more fix

voleger’s picture

Set retest against the latest changes in core. If green +1 for RTBC

voleger’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Needs reroll

andypost’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new3.04 KB
new159.94 KB

Reroll + few fixes, also found few new mentions in comments

berdir’s picture

Status: Needs review » Reviewed & tested by the community

I think this looks good, I did several reviews and I really like the ExtensionPathResolver service that we added here, it allows us to keep a similar/simple API to get the path of any type of extension and made many of the replacements much easier as we previously needed to inject 3 different services to get the same result.

If #2908079: Move some of the bootstrap.inc PHP-related constants to \Drupal and deprecate the old versions lands first (and it is also RTBC), then we can drop the constant definition here.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. Thanks for working on this
  2. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,94 @@
    +   * @var array
    

    @var \Drupal\Core\Extension\ExtensionList[]

  3. +++ b/core/lib/Drupal/Core/Theme/Registry.php
    @@ -148,6 +149,20 @@ class Registry implements DestructableInterface {
    +  /**
    +   * The theme initialization.
    +   *
    +   * @var \Drupal\Core\Theme\ThemeInitializationInterface
    +   */
    +  protected $themeInitialization;
    
    +++ b/core/modules/system/src/Form/ThemeSettingsForm.php
    @@ -2,20 +2,21 @@
    +use Drupal\Core\Config\ConfigFactoryInterface;
    +use Drupal\Core\Extension\ModuleHandlerInterface;
    +use Drupal\Core\Extension\ThemeExtensionList;
     use Drupal\Core\Extension\ThemeHandlerInterface;
     use Drupal\Core\File\Exception\FileException;
     use Drupal\Core\File\FileSystemInterface;
    +use Drupal\Core\Form\ConfigFormBase;
     use Drupal\Core\Form\FormStateInterface;
     use Drupal\Core\Render\Element;
     use Drupal\Core\StreamWrapper\PublicStream;
     use Drupal\Core\StreamWrapper\StreamWrapperManager;
    +use Drupal\Core\Theme\ThemeManagerInterface;
     use Symfony\Component\DependencyInjection\ContainerInterface;
     use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
     use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    -use Drupal\Core\Config\ConfigFactoryInterface;
    -use Drupal\Core\Extension\ModuleHandlerInterface;
    -use Drupal\Core\Form\ConfigFormBase;
    -use Drupal\Core\Theme\ThemeManagerInterface;
    
    +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -1,12 +1,8 @@
    -/**
    - * @file
    - * Contains \Drupal\Tests\Core\Theme\RegistryTest.
    - */
    -
    

    This is a large change and some of this is not related or necessary for the change. Makes reviewing harder.

  4. +++ b/core/lib/Drupal/Core/Theme/Registry.php
    @@ -819,16 +841,4 @@ public function getPrefixGroupedUserFunctions($prefixes = []) {
    -  /**
    -   * Wraps drupal_get_path().
    -   *
    -   * @param string $module
    -   *   The name of the item for which the path is requested.
    -   *
    -   * @return string
    -   */
    -  protected function getPath($module) {
    -    return drupal_get_path('module', $module);
    -  }
    

    This should be deprecated - no?

  5. +++ b/core/modules/action/action.install
    @@ -0,0 +1,13 @@
    +<?php
    +
    +/**
    + * @file
    + * Install, update and uninstall functions for the action module.
    + */
    +
    +/**
    + * Removes the action.settings configuration.
    + */
    +function action_update_8001() {
    +  \Drupal::configFactory()->getEditable('action.settings')->delete();
    +}
    

    Not sure this should be here.

  6. +++ b/core/modules/update/src/Form/UpdateManagerUpdate.php
    @@ -38,10 +46,13 @@ class UpdateManagerUpdate extends FormBase {
    +   * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
    +   *   The module list service.
        */
    -  public function __construct(ModuleHandlerInterface $module_handler, StateInterface $state) {
    +  public function __construct(ModuleHandlerInterface $module_handler, StateInterface $state, ModuleExtensionList $module_list) {
         $this->moduleHandler = $module_handler;
         $this->state = $state;
    +    $this->moduleList = $module_list;
       }
     
    

    Don't we need to dance the deprecation dance here?

  7. +++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/BootstrapDeprecationTest.php
    @@ -0,0 +1,35 @@
    +    $this->assertNotEmpty(drupal_get_filename('module', 'system'));
    ...
    +    $this->assertNotEmpty(drupal_get_path('module', 'system'));
    

    Can we not assert against the return value. Won't this be core/modules/system

  8. +++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionListTest.php
    @@ -0,0 +1,106 @@
    + * Tests that drupal_get_filename() works correctly.
    

    This isn't testing drupal_get_filename()

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new161.25 KB
new4.77 KB

Needed a re-roll after #2940189: Deprecate system_get_info().

Re #150

  1. You're welcome!
  2. Fixed
  3. I reverted this and created a follow up #3086397: Registry does not declare a themeInitialization property. I realise this is a pain, but as we're modifying the list of imports, its a good opportunity to clean it up and sort it alphabetically. Happy to revert and file a follow up.
  4. Fixed. Made it deprecated.
  5. Not sure where this should go?
  6. Did the deprecation dance 💃
  7. Fixed
  8. Fixed
kim.pepper’s picture

StatusFileSize
new160.79 KB
new473 bytes

Re: #150.5 I think this was accidentally included in a bad reroll. Removed.

alexpott’s picture

+++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionListTest.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Bootstrap;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Extension\Exception\UnknownExtensionException;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests for ExtensionList and sub-classes.
+ *
+ * @group Bootstrap
+ */
+class ExtensionListTest extends KernelTestBase {
...
+  /**
+   * Tests that drupal_get_filename() works when the file is not in database.
+   */
+  public function testDrupalGetFilename() {
...
+  /**
+   * Tests missing extensions.
+   */
+  public function testMissingExtensions() {

Discussed with @berdir. The first test is no longer testing anything without a database. And we already have good unit test coverage of both ExtensionList and ExtensionDiscovery.

The second test is also covered by the existing unit test coverage.

Therefore let's not add this test here but still completely remove GetFilenameTest.

kim.pepper’s picture

StatusFileSize
new157.1 KB
new3.7 KB

Therefore let's not add this test here but still completely remove GetFilenameTest.

I took this to mean remove the entire test class.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

berdir’s picture

Version: 8.9.x-dev » 8.8.x-dev
Status: Needs review » Reviewed & tested by the community

Yes, exactly that. I always feel bad when I RTBC something and miss things like #150.5 and some of the others, hopefully this one will be better :)

kim.pepper’s picture

Title: Deprecate drupal_get_path() and replace with ExtensionList::getPath() » Deprecate drupal_get_path() and drupal_get_filename() and replace with ExtensionList::getPath() and ExtensionList::getPathname()

Updated the title and CR to mention we are also deprecating drupal_get_filename().

kim.pepper’s picture

Ubernit: found an extra character in getPathnØame() in this comment.

+++ b/core/includes/bootstrap.inc
@@ -256,8 +256,18 @@ function config_get_config_directory($type) {
+ * @see \Drupal\Core\Extension\ExtensionList::getPathnØame()
larowlan’s picture

Status: Reviewed & tested by the community » Needs review

This is great work here folks, and really highlights some hidden dependencies we were masking with procedural code. Below is a few actual things that might need fixing, and a lot of random ramblings about the coupling.

  1. +++ b/core/includes/bootstrap.inc
    @@ -256,8 +256,18 @@ function config_get_config_directory($type) {
    + * @see \Drupal\Core\Extension\ExtensionList::getPathnØame()
    

    stray character here that can be fixed on commit

  2. +++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
    @@ -104,10 +104,12 @@ protected function getAllFolders() {
    +          /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list */
    +          $profile_extension_list = \Drupal::service('extension.list.profile');
    +          $profile_extension_list->setPathname($this->installProfile, $profile_list[$this->installProfile]->getPathname());
    

    ick, circular dependency? realise it was already there, but just hidden

  3. +++ b/core/lib/Drupal/Core/Config/InstallStorage.php
    @@ -162,7 +162,9 @@ protected function getAllFolders() {
    +          /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list */
    +          $profile_extension_list = \Drupal::service('extension.list.profile');
    +          $profile_extension_list->setPathname($profile, $profile_list[$profile]->getPathname());
    

    and here too 😿

  4. +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
    @@ -229,7 +229,7 @@ public function scan($type, $include_tests = NULL) {
       public function setProfileDirectoriesFromSettings() {
    ...
         if ($profile = \Drupal::installProfile()) {
    -      $this->profileDirectories[] = drupal_get_path('profile', $profile);
    +      $this->profileDirectories[] = \Drupal::service('extension.list.profile')->getPath($profile);
    

    It would be good to get a follow up to try and untangle this a bit (and the above).

    install storage calls scan on profiles, which calls setProfileDirectoriesFromSettings which gets the profile directories, but then install storage calls set profile? its super-coupled and the static access on both of them indicates something is out right?

    Something where we can map out a plan of how we fix this interdependency

  5. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -531,7 +531,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
    -    $service_yaml_file = drupal_get_path('module', $module) . "/$module.services.yml";
    +    $service_yaml_file = \Drupal::service('extension.list.module')->getPath($module) . "/$module.services.yml";
    

    wow this really highlights all the places we were kidding ourselves about having modern code 😂

    the module installer and the extension list are tightly coupled aren't they (sorry, nothing useful in my review so far, I might be getting delirious)

  6. +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    @@ -46,7 +46,7 @@ public function getLibraries(Editor $editor) {
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor') . '/js/plugins/drupalimagecaption/plugin.js';
    
    @@ -70,7 +70,7 @@ public function getConfig(Editor $editor) {
    +      \Drupal::service('extension.list.module')->getPath('ckeditor') . '/css/plugins/drupalimagecaption/ckeditor.drupalimagecaption.css',
    

    any reason these don't use ->getModulePath like the ones above and below?

  7. +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
    @@ -1108,4 +1108,36 @@ public static function assertEquals($expected, $actual, $message = '', $delta =
    +  protected function getModulePath($module_name) {
    ...
    +  protected function getThemePath($theme_name) {
    
    +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -753,4 +753,36 @@ protected function translatePostValues(array $values) {
    +  protected function getModulePath($module_name) {
    ...
    +  protected function getThemePath($theme_name) {
    

    could these be in a trait so a) we can share the code with these two base classes but b) DTT can also use it?

kim.pepper’s picture

StatusFileSize
new156.97 KB
new7.7 KB

Re: #159

1. Fixed

I left 2-5 for @Berdir to respond to.

6. Created follow up #3087327: [PP-1] DrupalImageCaption should extend CKEditorPluginBase.
7. Moved to a trait.

Also fixed method name in deprecation message.

wim leers’s picture

StatusFileSize
new4.32 KB
new156.97 KB

Epic work!

  1. +++ b/core/modules/ckeditor/src/CKEditorPluginBase.php
    @@ -30,6 +30,44 @@
     abstract class CKEditorPluginBase extends PluginBase implements CKEditorPluginInterface, CKEditorPluginButtonsInterface {
     
    +  /**
    +   * The module list service.
    +   *
    +   * @var \Drupal\Core\Extension\ModuleExtensionList
    +   */
    +  protected $moduleList;
    +
    +  /**
    

    🤔 Shouldn't this get a constructor with an optional argument, with the optionality being deprecated in 9.0.0?

    ✅ Hm … upon further investigation, it looks like we almost never do this in plugin base classes.

  2. +++ b/core/modules/ckeditor/src/CKEditorPluginBase.php
    @@ -30,6 +30,44 @@
    +   * Gets the drupal-root relative installation directory of a module.
    

    🤓 Übernit: "drupal" → "Drupal"

  3. +++ b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
    @@ -74,13 +82,20 @@ class CKEditor extends EditorBase implements ContainerFactoryPluginInterface {
    +      @trigger_error('Calling CKEditor::__construct() without the $module_list argument is deprecated in drupal:8.0.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    🤓 "8.0.0" → "8.8.0"

  4. +++ b/core/tests/Drupal/KernelTests/Core/Extension/ExtensionPathResolverTest.php
    @@ -0,0 +1,64 @@
    + * Tests the extension list factory.
    

    🤓 "list factory" → "path resolver". Nope, \Drupal\Core\Extension\ExtensionPathResolver is documented as Factory for getting extension lists by type. so leaving unchanged. Oddly named though.

  5. +++ b/core/tests/Drupal/KernelTests/Core/Extension/ExtensionPathResolverTest.php
    @@ -0,0 +1,64 @@
    +   * @covers ::getPathname
    ...
    +  public function testGetPath() {
    ...
    +   * @covers ::getPath
    ...
    +  public function testGetDir() {
    

    🤓 Mismatches.

  6. +++ b/core/tests/Drupal/KernelTests/Core/Extension/ExtensionPathResolverTest.php
    @@ -0,0 +1,64 @@
    +    $path_resolver->getPathname('foo', 'bar');
    ...
    +    $path_resolver->getPathname('foo', 'bar');
    

    👎 The first one is correct, the second one should be calling ::getPath().

  7. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -565,18 +628,8 @@ public function providerTestCssAssert() {
    -  protected function drupalGetPath($type, $name) {
    
    +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -486,22 +495,12 @@ public function providerTestPostProcessExtension() {
    -class TestRegistry extends Registry {
    -
    -  protected function getPath($module) {
    -    if ($module == 'theme_test') {
    -      return 'core/modules/system/tests/modules/theme_test';
    -    }
    -  }
    -
    -}
    

    🥳

  8. +++ b/core/tests/Drupal/Tests/ExtensionListTestTrait.php
    @@ -0,0 +1,42 @@
    +   *   The drupal-root relative path to the module directory.
    ...
    +   *   The drupal-root relative path to the theme directory.
    

    🤓 "drupal" → "Drupal"

Fixed all those nits, and back to RTBC ah no, I can't, @Berdir still needs to respond to point 2–5. Darn!

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs followup

Just stumbled upon this in Drupal Slack!

kimb0:coffee:  5 hours ago
there’s a couple of easy fixes in https://www.drupal.org/project/drupal/issues/2347783#comment-13295779

kimb0:coffee:  5 hours ago
wondering whether you had a response to some of those? Happy to try and tackle some myself

kimb0:coffee:  5 hours ago
e.g. 6. and 7.

berdir  5 hours ago
will check, short meeting right now

kimb0:coffee:  5 hours ago
no worries

berdir  5 hours ago
looks like 6 was sorted out, fine with making a trait for 7, it's not that much code but why not

berdir  5 hours ago
and for 2-5, probably won't be easy, but no objection to creating a follow-up to try and make more sense of that. I think @larowlan is just asking for that?

kimb0:coffee:  5 hours ago
thanks!

larowlan:pnx:  4 hours ago
yeah 2-5 can’t be solved here

berdir  1 hour ago
@wimleers (he/him) ^, I replied here. But I guess the follow-up doesn't exist yet

larowlan:pnx:  1 hour ago
Yeah those are random musings of someone who's spent too long looking at dreditor diffs this week :joy:

wimleers (he/him)  1 hour ago
ah yeah I didn’t realize that, I didn’t dig deeper into them :slightly_smiling_face:

wimleers (he/him)  1 hour ago
so @berdir, @larowlan: I can then actually RTBC, right?

berdir  1 hour ago
yes, I'll try to create a follow-up asap, although I'm not quite sure yet what to name it :wink:

The only reason I did not RTBC #161 is points 2–5 in #159. But those cannot be fixed here. @Berdir will file a follow-up.

So: tagging + RTBC'ing :)

berdir’s picture

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new1.81 KB
new157.08 KB

The behaviour for when you use type 'core' does not seem to be the same.

>>> drupal_get_path('core', '');
PHP Deprecated:  drupal_get_path() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use /Drupal/Core/Extension/ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438 in /Users/alex/dev/sites/drupal8alt.dev/core/includes/bootstrap.inc on line 325
PHP Deprecated:  drupal_get_filename() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use /Drupal/Core/Extension/ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438 in /Users/alex/dev/sites/drupal8alt.dev/core/includes/bootstrap.inc on line 270
=> "core"
>>> drupal_get_filename('core', '');
PHP Deprecated:  drupal_get_filename() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use /Drupal/Core/Extension/ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438 in /Users/alex/dev/sites/drupal8alt.dev/core/includes/bootstrap.inc on line 270
=> "core/core.info.yml"
>>> \Drupal::service('extension.path.resolver')->getPath('core', '');
=> "core"
>>> \Drupal::service('extension.path.resolver')->getPathname('core', '');
PHP Notice:  Undefined index: core in /Users/alex/dev/sites/drupal8alt.dev/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php on line 58

What's interesting about this is that we have code like

  public function __construct($root, $type, $pathname, $filename = NULL) {
    // @see \Drupal\Core\Theme\ThemeInitialization::getActiveThemeByName()
    assert($pathname === 'core/core.info.yml' || ($pathname[0] !== '/' && file_exists($root . '/' . $pathname)), sprintf('The file specified by the given app root, relative path and file name (%s) do not exist.', $root . '/' . $pathname));

in core/lib/Drupal/Core/Extension/Extension.php

and

$active_theme = $this->getActiveTheme(new Extension($this->root, 'theme', 'core/core.info.yml'));

core/lib/Drupal/Core/Theme/ThemeInitialization.php

I think we need to do

  public function getPathname($type, $name) {
    $this->validateType($type);
    if ($type === 'core') {
      return 'core/core.info.yml';
    }
    return $this->extensionLists[$type]->getPathname($name);
  }

in \Drupal\Core\Extension\ExtensionPathResolver::getPathname() and remove the early return from \Drupal\Core\Extension\ExtensionPathResolver::getPath

This results in

Psy Shell v0.9.9 (PHP 7.2.22 — cli) by Justin Hileman
>>> \Drupal::service('extension.path.resolver')->getPathname('core', '');
=> "core/core.info.yml"
>>> \Drupal::service('extension.path.resolver')->getPath('core', '');
=> "core"
>>>

which matches drupal_get_path() and drupal_get_filename() behaviour.

kim.pepper’s picture

Status: Needs review » Reviewed & tested by the community

Good catch!

kim.pepper’s picture

I guess this is now drupal 9.1.x 😭

voleger’s picture

Yes, small chances to be replaced before 9.0.0. Here the discussion #3088246: [policy, no patch] How to handle Drupal 8.9.x deprecations

wim leers’s picture

Priority: Normal » Major

I think this is actually at committer discretion. This is one of the few remaining procedural APIs. Core committers could decide that if this is important enough, that it ships with 8.8.0-alpha2.

Also, given that this allows us to do actual unit testing instead of faking it, bumping this to Major.

alexpott’s picture

Version: 8.8.x-dev » 9.0.x-dev
Status: Reviewed & tested by the community » Needs work

We need a reroll here also we've missed the D8.8 ship so I think that means we need to target Drupal 9 now - which will be 9.1 - or we might consider this important enough to do in 8.9 but only deprecate for Drupal 10 - this is a release manager decision.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new156.97 KB

Re-roll of #164.

I left the deprecation messages at 8.8.0 until we get some direction on the version this should target.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new161.07 KB
new4.1 KB

Replaced a couple of uses of deprecated drupal_get_path() and drupal_get_filename() introduced in the last 3 months.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new161.68 KB
new948 bytes

Replaced use of $this->libraryDiscoveryParser->setPaths() in LibraryDiscoveryParserTest which was removed in earlier patches.

kim.pepper’s picture

Tagging for #169

kim.pepper’s picture

Version: 9.0.x-dev » 9.1.x-dev
StatusFileSize
new157.74 KB

Re-roll against 9.1.x

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new161 KB
new3.28 KB

Removes a couple of uses of deprecated drupal_get_path that have been added.

aleevas’s picture

Status: Needs work » Needs review
StatusFileSize
new169.45 KB
new10.03 KB

Tried to fix failed tests

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new169.58 KB
new9.16 KB

Sorry. Didn't see what #180 was trying to do from that interdiff.

This patch is based off #178 and tries to fix the remaining test fails.

daffie’s picture

Status: Needs review » Needs work
  1. When I do a code search for "drupal_get_path(", I still find it in placed where it needs to be removed. Like: "core/lib/Drupal/Core/Batch/BatchBuilder.php".
  2. When I do a code search for "drupal_get_filename(", I still find it in placed where it needs to be removed. Like: "core/includes/install.core.inc".
  3. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -428,8 +443,14 @@ protected function applyLibrariesOverride($libraries, $extension) {
    +   *
    +   * @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
    +   *   \Drupal\Core\Extension\ExtensionList::getPathname() instead.
    +   *
    +   * @see https://www.drupal.org/node/2940438
    ...
    +    @trigger_error('drupalGetPath() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    This patch is for 9.1. Deprecating in 8.8 is no longer possible. Multiple places.

  4. The CR needs updating for deprecation in 9.1 and I am missing examples for drupal_get_filename().
kapilv’s picture

@daffie is correct, I am working on this issue.

Thanks.

anybody’s picture

Issue summary: View changes
aleevas’s picture

Status: Needs work » Needs review
StatusFileSize
new168.22 KB
new48.45 KB

Hope I've resolved all issues that was listed in #183

I've also updated the CR

daffie’s picture

Status: Needs review » Needs work

The testbot returns the following error: "PHP Fatal error: Trait 'Drupal\Tests\ExtensionListTestTrait' not found in /var/www/html/core/tests/Drupal/KernelTests/KernelTestBase.php on line 76"

deepak goyal’s picture

Assigned: Unassigned » deepak goyal
deepak goyal’s picture

Assigned: deepak goyal » Unassigned
StatusFileSize
new453 KB

I have applied patch #186 and getting error so I am unassigned myself.

aleevas’s picture

Status: Needs work » Needs review
StatusFileSize
new169.5 KB
new1.75 KB

Sorry, In patch was a wrong path to file.
Trying to fix last failure.

daffie’s picture

Status: Needs review » Needs work
  1. I still found an occurrence of "drupal_get_path()" in core/lib/Drupal/Core/Theme/Registry.php
  2. I still found an occurrence of "drupal_get_filename()" in core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
  3. When I compare the patch from comment #190 and the one from comment #182, I am missing the following files: "core/tests/Drupal/KernelTests/Core/Bootstrap/BootstrapDeprecationTest.php" and "core/tests/Drupal/KernelTests/Core/Extension/ExtensionPathResolverTest.php"
  4. The remark from comment #183.3 is still open.
kim.pepper’s picture

StatusFileSize
new18.26 KB
  1. The occurrence is a comment on an also deprecated method that wraps drupal_get_path(). I think this ok.
  2. I'm sure why that comment is even here? We're not dealing with the extension system in this test. The link to #2186491: [meta] D8 Extension System: Discovery/Listing/Info seems irrelevant. Maybe we can just remove?
  3. Attached the interdiff from #182 to #190 so we can see if anything else has changed
  4. todo
shaktik’s picture

Assigned: Unassigned » shaktik
shaktik’s picture

Assigned: shaktik » Unassigned
daffie’s picture

@kim.pepper: Thank you for the interdiff. It makes reviewing the differences between the patches from comment #182 and #190 a lot easier.

For #192.1: Good point!

For #192.2: I think it is better to only change "drupal_get_filename()" and create a followup for removing the comment. It is a bit out of scope for this issue.

kim.pepper’s picture

+++ b/core/includes/bootstrap.inc
@@ -160,8 +160,9 @@ function drupal_get_filename($type, $name, $filename = NULL) {
+  // does not exist, but is required since ExtensionList::getPath()
+  // returns the dirname() of the returned pathname.

+++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
@@ -95,8 +95,9 @@ protected function getAllFolders() {
+          // static cache with the profile info file location
+          // so we can use ExtensionList::getPath() on the active

+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -151,16 +151,18 @@ protected function getAllFolders() {
+          // \Drupal\Core\Extension\ExtensionList::getPath()
+          // on the active profile during the module scan.

+++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
@@ -159,10 +159,10 @@ public function testUninstallProfileDependency() {
+    // as it is not the currently active profile
+    // and we don't yet have any cached way to retrieve its location.

@@ -201,10 +201,10 @@ public function testProfileAllDependencies() {
+    // as it is not the currently active profile
+    // and we don't yet have any cached way to retrieve its location.

+++ b/core/modules/system/tests/src/Kernel/Installer/InstallerDependenciesResolutionTest.php
@@ -21,9 +21,10 @@ class InstallerDependenciesResolutionTest extends KernelTestBase {
+    // with the location of the testing profile
+    // as it is not the currently active profile
+    // and we don't yet have any cached way to retrieve its location.

+++ b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
@@ -45,8 +45,9 @@ public function testInstallerTranslationFiles() {
+    // with the location of the testing profile
+    // as it is not the currently active profile and we don't

Text should wrap at 80 chars.

saurabh-2k17’s picture

Assigned: Unassigned » saurabh-2k17
saurabh-2k17’s picture

Assigned: saurabh-2k17 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new165.45 KB
new4.93 KB

Hi team,
1. @daffie, I have changed drupal_get_filename() as per your suggestion.
2. 183.3 - now the message is changed "drupalGetPath() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0" this is the current one.
3. @kim.pepper as per your suggestion i have not changed drupal_get_path() comment.

Thanks

saurabh-2k17’s picture

Assigned: Unassigned » saurabh-2k17
saurabh-2k17’s picture

StatusFileSize
new170.2 KB
new720 bytes

Sorry for the mess forgot to add newly generated files in the patch, here is the correct one.

saurabh-2k17’s picture

Assigned: saurabh-2k17 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new171.36 KB
new993 bytes
new1.67 KB

Hi,

Updated patch as last one failed. I have attached interdiff for better understanding.

Thanks

daffie’s picture

Status: Needs review » Needs work

@Saurabh_sgh: Thank you for adding the intediff_190-202.txt file.

  1. +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/NoMultilingualReviewPageTest.php
    @@ -12,6 +13,8 @@
    +  ¶
    

    Whitespace error.

  2. +++ b/core/tests/Drupal/KernelTests/Core/File/ScanDirectoryTest.php
    @@ -36,7 +36,7 @@ protected function setUp(): void {
    +    // location from \Drupal\Core\Extension\ExtensionList::getPathname() in a cached way.
    

    This comment goes over the 80 character limit.

  3. +++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
    @@ -95,11 +95,14 @@ protected function getAllFolders() {
    +          // Prime the \Drupal\Core\Extension\ExtensionList::getPathname
    +          // static cache with the profile info file location
    +          // so we can use ExtensionList::getPath() on the active
    +          // profile during the module scan.
    
    +++ b/core/lib/Drupal/Core/Config/InstallStorage.php
    @@ -151,18 +151,22 @@ protected function getAllFolders() {
    +          // \Drupal\Core\Extension\ExtensionList::getPath()
    +          // on the active profile during the module scan.
    
    +++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
    @@ -158,12 +159,14 @@ public function testUninstallProfileDependency() {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    +    // with the location of the testing_install_profile_dependencies profile
    +    // as it is not the currently active profile
    +    // and we don't yet have any cached way to retrieve its location.
    
    @@ -198,12 +201,14 @@ public function testProfileAllDependencies() {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    +    // with the location of the testing_install_profile_dependencies profile
    +    // as it is not the currently active profile
    +    // and we don't yet have any cached way to retrieve its location.
    
    +++ b/core/modules/system/tests/src/Kernel/Installer/InstallerDependenciesResolutionTest.php
    @@ -20,11 +21,14 @@ class InstallerDependenciesResolutionTest extends KernelTestBase {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    +    // with the location of the testing profile
    +    // as it is not the currently active profile
    +    // and we don't yet have any cached way to retrieve its location.
    
    +++ b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
    @@ -44,11 +45,14 @@ public function testInstallerTranslationFiles() {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    +    // with the location of the testing profile
    +    // as it is not the currently active profile and we don't
    

    These comments must wrap as close to 80 characters as possible without going over. See: https://www.drupal.org/docs/develop/standards/api-documentation-and-comm....

aleevas’s picture

Status: Needs work » Needs review
StatusFileSize
new170.52 KB
new15.65 KB

Was updated the latest patch accordingly previous warnings.

aleevas’s picture

StatusFileSize
new171.8 KB

Sorry for previous patch, was lost one file.
Next try

kim.pepper’s picture

@aleevas can you please post an interdiff as per https://www.drupal.org/documentation/git/interdiff#git

daffie’s picture

Status: Needs review » Needs work

Putting this back to needs work for the interdiff.txt file. The patch file is 170KB. I am not going to review the whole patch again, trying to figure out what has changed!

mrinalini9’s picture

Status: Needs work » Needs review
StatusFileSize
new8.63 KB

Please find the interdiff file here.

aleevas’s picture

Status: Needs review » Needs work

@mrinalini9 thank you for help.
@kim.pepper @daffie
sorry for that, I've just forgot to add interdiff to my last comment

daffie’s picture

Issue summary: View changes
Status: Needs work » Needs review
daffie’s picture

Status: Needs review » Reviewed & tested by the community

@mrinalini9: Thank you for the interdiff.txt file.

All occurrences of "drupal_get_filename()" and "drupal_get_path()" have been replaced on places where it should be replaced.
Both deprecated function have deprecation testing.
All code changes look good to me.
The IS and the CR are in order.
For me it is RTBC.

shaktik’s picture

StatusFileSize
new148.99 KB

Some more files require deprecation for drupal_get_path().

../core/includes/bootstrap.inc:
  213   * @see https://www.drupal.org/node/2940438
  214   */
  215: function drupal_get_path($type, $name) {
  216:   @trigger_error('drupal_get_path() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
  217    return dirname(drupal_get_filename($type, $name));
  218  }

../core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php:
  443  
  444    /**
  445:    * Wraps drupal_get_path().
  446     *
  447     * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use
  ...
  452    protected function drupalGetPath($type, $name) {
  453      @trigger_error('drupalGetPath() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
  454:     return drupal_get_path($type, $name);
  455    }
  456  

../core/lib/Drupal/Core/Config/ConfigInstaller.php:
  713  
  714    /**
  715:    * Wrapper for drupal_get_path().
  716     *
  717     * @param $type
  ...
  733    protected function drupalGetPath($type, $name) {
  734      @trigger_error('drupalGetPath() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
  735:     return drupal_get_path($type, $name);
  736    }
  737  

../core/lib/Drupal/Core/Theme/Registry.php:
  845  
  846    /**
  847:    * Wraps drupal_get_path().
  848     *
  849     * @param string $module

../core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php:
   26  
   27    /**
   28:    * @expectedDeprecation drupal_get_path() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438
   29     * @expectedDeprecation drupal_get_filename() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438
   30     */
   31    public function testDrupalGetPath() {
   32:     $this->assertEquals('core/modules/system', drupal_get_path('module', 'system'));
   33    }
   34  
dww’s picture

Assigned: Unassigned » dww
Status: Reviewed & tested by the community » Needs work

@shaktik:

A) Please don't post screenshots of your editor or CLI. That's not helpful.

B) Did you read the context of the "problems" found? They're all either deprecated wrapper functions or a deprecation test. ;) None of that needs "fixing".

Meanwhile, I started a thorough review on this. Found some stuff. I'll post the review in a bit, but wanted to alert folks that this isn't RTBC and that I'm working on finishing the review.

Thanks,
-Derek

dww’s picture

Assigned: dww » Unassigned

Sorry for the novel. :/ Long patches solicit long reviews...

  1. +++ b/core/includes/bootstrap.inc
    @@ -131,8 +131,8 @@
    - * Calling drupal_get_filename('module', 'foo') will give you one of
    - * the above, depending on where the module is located.
    + * Calling \Drupal\Core\Extension\ExtensionList::getPathname('module', 'foo')
    + * will give you one of the above, depending on where the module is located.
    

    Seems weird to change this comment. It's in the docblock for drupal_get_filename(). That's already marked deprecated. But I don't think we we want to try to introduce "the right way" to get this info like this.

  2. +++ b/core/includes/bootstrap.inc
    @@ -146,12 +146,23 @@
    + *   extension.list.theme).
    

    Looks like extension.list.theme_engine is also a thing. Dare we mention it here?

  3. +++ b/core/includes/bootstrap.inc
    @@ -146,12 +146,23 @@
    +  @trigger_error('drupal_get_filename() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    This @trigger_error doesn't match the @deprecated text above. Does that matter?

  4. +++ b/core/includes/bootstrap.inc
    @@ -146,12 +146,23 @@
    +  // \Drupal\Core\Extension\ExtensionList::getPath(). /core/core.info.yml
    +  // does not exist, but is required since ExtensionList::getPath()
    

    This is maybe out of scope, but if we're changing this comment anyway, the "getPath(). /core part looks like string concatenation, not the end of a sentence. ;) Can we say:

    "getPath(). The file /core/core.info.yml does not exist..." to break this up?

  5. +++ b/core/includes/bootstrap.inc
    @@ -195,8 +206,14 @@ function drupal_get_filename($type, $name, $filename = NULL) {
    + *   Instead, you should use \Drupal\Core\Extension\ExtensionList::getPath().
    + *
    + * @see https://www.drupal.org/node/2940438
    

    Above, we @see to the replacement, too. Can we do that here?

    @see \Drupal\Core\Extension\ExtensionList::getPath()

  6. +++ b/core/includes/bootstrap.inc
    @@ -195,8 +206,14 @@ function drupal_get_filename($type, $name, $filename = NULL) {
    +  @trigger_error('drupal_get_path() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    Again, the @trigger_error doesn't match @deprecated. Maybe it doesn't matter.

    The @trigger_error version: "Use \Drupal\Core... instead." seems better for both...

  7. +++ b/core/includes/install.core.inc
    @@ -474,10 +479,10 @@ function install_begin_request($class_loader, &$install_state) {
    -  // rebuild, prime the drupal_get_filename() static cache with the system
    +  // rebuild, prime the module list static cache with the system
       // module's location.
    

    "module's" ahouls wrap to the previous line now.

  8. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -428,8 +443,14 @@ protected function applyLibrariesOverride($libraries, $extension) {
    +   * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use
    +   *   \Drupal\Core\Extension\ExtensionList::getPathname() instead.
    +   *
    +   * @see https://www.drupal.org/node/2940438
    

    Again can/should we @see the replacement, too?

  9. +++ b/core/lib/Drupal/Core/Batch/BatchBuilder.php
    @@ -203,7 +203,8 @@ public function setErrorMessage($message) {
        * The path should be relative to base_path(), and thus should be built using
    -   * drupal_get_path(). Defaults to {module_name}.module.
    +   * should use \Drupal\Core\Extension\ExtensionList::getPath().
    +   * Defaults to {module_name}.module.
    

    A) "and thus should be built using should use \Drupal..." doesn't parse. s/should use// on the new line.

    B) "Defaults to" at least can wrap to the previous line. Maybe more once you remove "should use".

  10. +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
    @@ -80,21 +88,28 @@ class ConfigInstaller implements ConfigInstallerInterface {
    +      @trigger_error('Calling ConfigInstaller::__construct() without the $extension_path_resolver argument is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    Wrong versions here.

  11. +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
    @@ -709,8 +724,14 @@ protected function getDefaultConfigDirectory($type, $name) {
    +   * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use
    +   *   \Drupal\Core\Extension\ExtensionList::getPathname() instead.
    +   *
    +   * @see https://www.drupal.org/node/2940438
    

    @see the replacement?

  12. +++ b/core/lib/Drupal/Core/Config/ConfigManager.php
    @@ -94,8 +102,10 @@ class ConfigManager implements ConfigManagerInterface {
    +   * @param \Drupal\Core\Extension\ExtensionPathResolver|null $extension_path_resolver
    

    I don't think we want |null here. Never seen that for other optional args anywhere in core.

  13. +++ b/core/lib/Drupal/Core/Config/ConfigManager.php
    @@ -103,6 +113,11 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Con
    +      @trigger_error('Calling ConfigManager::__construct without the $extension_path_resolver argument is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    Wrong versions.

  14. +++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
    @@ -95,11 +95,14 @@ protected function getAllFolders() {
    +          // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static
    

    getPathname() with parens...

  15. +++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
    @@ -95,11 +95,14 @@ protected function getAllFolders() {
    +          $profile_extension_list = \Drupal::service('extension.list.profile');
    

    Haven't fully investigated, but can we not use proper DI for this service in this class? \Drupal::service() inside a class is generally frowned upon.

  16. +++ b/core/lib/Drupal/Core/Config/InstallStorage.php
    @@ -151,18 +151,22 @@ protected function getAllFolders() {
    +      // \Drupal\Core\Extension\ExtensionList::getPath()
           // yet because the system module may not yet be enabled during install.
    

    The "yet because..." line can now wrap onto the previous.

  17. +++ b/core/lib/Drupal/Core/Config/InstallStorage.php
    @@ -151,18 +151,22 @@ protected function getAllFolders() {
    -          // Prime the drupal_get_filename() static cache with the profile info
    -          // file location so we can use drupal_get_path() on the active profile
    -          // during the module scan.
    +          // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static
    +          // cache with the profile info file location so we can use
    +          // \Drupal\Core\Extension\ExtensionList::getPath() on the active
    +          // profile during the module scan.
               // @todo Remove as part of https://www.drupal.org/node/2186491
    -          drupal_get_filename('profile', $profile, $profile_list[$profile]->getPathname());
    +          /** @var \Drupal\Core\Extension\ProfileExtensionList $profile_extension_list */
    +          $profile_extension_list = \Drupal::service('extension.list.profile');
    +          $profile_extension_list->setPathname($profile, $profile_list[$profile]->getPathname());
    

    Nothing to fix, but... deja vu here. ;) Too bad we have the same comment and code block sprinkled in various spots in core. :/

  18. +++ b/core/lib/Drupal/Core/Config/InstallStorage.php
    @@ -254,7 +258,7 @@ protected function getComponentFolder(Extension $extension) {
       protected function getCoreFolder() {
    -    return drupal_get_path('core', 'core') . '/' . $this->getCollectionDirectory();
    +    return 'core/' . $this->getCollectionDirectory();
       }
    

    🤔 is returning 'core/' like this legit? Seems like a bit of a wonky API here. Would need to investigate more to see what's really happening, but on first glance, this seems like it would break for sites running in subdirectories (maybe?)...

  19. +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
    @@ -229,7 +229,7 @@ public function scan($type, $include_tests = NULL) {
    +      $this->profileDirectories[] = \Drupal::service('extension.list.profile')->getPath($profile);
    

    Can we not use proper DI here?

  20. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,94 @@
    +  /**
    +   * The list of valid extension list types.
    +   *
    +   * @var string[]
    +   */
    +  protected $validTypes = ['core', 'module', 'theme', 'theme_engine', 'profile'];
    ...
    +    $this->extensionLists['module'] = $module_extension_list;
    +    $this->extensionLists['profile'] = $profile_extension_list;
    +    $this->extensionLists['theme'] = $theme_extension_list;
    +    $this->extensionLists['theme_engine'] = $theme_engine_extension_list;
    ...
    +  public function getPathname($type, $name) {
    +    $this->validateType($type);
    ...
    +    if (!in_array($type, $this->validTypes, TRUE)) {
    +      throw new UnknownExtensionTypeException("$type is not a valid extension list type");
    +    }
    

    A) Wonder if we really want a separate array for validTypes at all. Maybe we just want:

    if ($type !== 'core' && !isset($this->extensionLists[$type]) {
      throw new ...
    }
    

    B) Looks like validateType() is only called from getPathname(). Do we need it at all? Maybe we can just test for !isset($this->extensionLists[$type]) directly in getPathname() and throw the exception there?

  21. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,94 @@
    +   * A associative array of ExtensionLists keyed by type.
    

    A) s/A/An/

    B) "ExtensionLists" is a bit weird. Maybe:

    "An associative array of ExtensionList objects keyed by type."
    ?

  22. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,94 @@
    +    return dirname($this->getPathname($type, $name));
    

    I'm having flashbacks to other core bugs where calling dirname() directly breaks in certain cases. We have a filesystem service that handles dirname() for us. Maybe we need to be using that service in this class?

  23. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -537,7 +537,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
    +    $service_yaml_file = \Drupal::service('extension.list.module')->getPath($module) . "/$module.services.yml";
    

    Real DI?

  24. +++ b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
    @@ -409,13 +409,13 @@ protected function installDefaultThemeFromClassProperty(ContainerInterface $cont
    +    $default_sync_path = $container->get('extension.list.profile')->getPath($profile) . '/config/sync';
    ...
    +    $default_install_path = $container->get('extension.list.profile')->getPath($profile) . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
    

    There the whole \Drupal:: vs. container in tests debate, which is still unresolved, but I think the emerging consensus is that \Drupal:: is better in tests. /shrug

  25. +++ b/core/lib/Drupal/Core/Theme/Registry.php
    @@ -174,8 +182,10 @@ class Registry implements DestructableInterface {
    +   * @param \Drupal\Core\Extension\ModuleExtensionList|null $module_list
    

    Don't need |null

  26. +++ b/core/lib/Drupal/Core/Theme/Registry.php
    @@ -184,6 +194,11 @@ public function __construct($root, CacheBackendInterface $cache, LockBackendInte
    +      @trigger_error('Calling Registry::__construct() without the $module_list argument is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    Wrong versions.

  27. +++ b/core/lib/Drupal/Core/Updater/Module.php
    @@ -13,21 +13,21 @@ class Module extends Updater implements UpdaterInterface {
    +    if ($this->isInstalled() && ($relative_path = \Drupal::service('extension.list.module')->getPath($this->name))) {
    

    Real DI?

  28. +++ b/core/lib/Drupal/Core/Updater/Module.php
    @@ -72,7 +72,7 @@ public static function canUpdateDirectory($directory) {
    +    return (bool) \Drupal::service('extension.list.module')->getPath($project_name);
    

    More DI.

  29. +++ b/core/lib/Drupal/Core/Updater/Theme.php
    @@ -13,7 +13,8 @@ class Theme extends Updater implements UpdaterInterface {
    +   * If the theme is already installed,
    +   * \Drupal::service('extension.list.module')->getPath() will return a valid
    

    Since this is about themes, we mean 'extension.list.theme' in this comment.

  30. +++ b/core/lib/Drupal/Core/Updater/Theme.php
    @@ -25,9 +26,10 @@ class Theme extends Updater implements UpdaterInterface {
    +    if ($this->isInstalled() && ($relative_path = \Drupal::service('extension.list.theme')->getPath($this->name))) {
    +      // The return value of
    +      // \Drupal::service('extension.list.module')->getPath() is always relative
    

    s/list.module/list.theme/ here, too.

  31. +++ b/core/lib/Drupal/Core/Updater/Theme.php
    @@ -71,7 +73,7 @@ public static function canUpdateDirectory($directory) {
    +    return (bool) \Drupal::service('extension.list.theme')->getPath($project_name);
    

    More DI. Maybe for this class, we want the general extension.path.resolver service, and use it for both modules and themes?

  32. +++ b/core/modules/ckeditor/ckeditor.api.php
    @@ -53,7 +53,7 @@ function hook_ckeditor_plugin_info_alter(array &$plugins) {
    diff --git a/core/modules/ckeditor/ckeditor.module b/core/modules/ckeditor/ckeditor.module
    
    diff --git a/core/modules/ckeditor/ckeditor.module b/core/modules/ckeditor/ckeditor.module
    index 62dd48932c..7068f2b33f 100644
    
    index 62dd48932c..7068f2b33f 100644
    --- a/core/modules/ckeditor/ckeditor.module
    
    --- a/core/modules/ckeditor/ckeditor.module
    +++ b/core/modules/ckeditor/ckeditor.module
    
    +++ b/core/modules/ckeditor/ckeditor.module
    +++ b/core/modules/ckeditor/ckeditor.module
    @@ -5,9 +5,9 @@
    
    @@ -5,9 +5,9 @@
      * Provides integration with the CKEditor WYSIWYG editor.
      */
     
    -use Drupal\Core\Url;
     use Drupal\Component\Utility\UrlHelper;
     use Drupal\Core\Routing\RouteMatchInterface;
    +use Drupal\Core\Url;
     use Drupal\editor\Entity\Editor;
    

    Out of scope. :/

  33. +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
    @@ -51,7 +51,7 @@ public function getButtons() {
    diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    
    diff --git a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    index 45b97e77bc..99cc1d6722 100644
    
    index 45b97e77bc..99cc1d6722 100644
    --- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    
    --- a/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    
    +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    @@ -3,10 +3,10 @@
    
    @@ -3,10 +3,10 @@
     namespace Drupal\ckeditor\Plugin\CKEditorPlugin;
     
     use Drupal\Core\Plugin\PluginBase;
    -use Drupal\editor\Entity\Editor;
    -use Drupal\ckeditor\CKEditorPluginInterface;
     use Drupal\ckeditor\CKEditorPluginContextualInterface;
     use Drupal\ckeditor\CKEditorPluginCssInterface;
    +use Drupal\ckeditor\CKEditorPluginInterface;
    +use Drupal\editor\Entity\Editor;
     
    

    Out of scope.

  34. +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    @@ -46,7 +46,7 @@ public function getLibraries(Editor $editor) {
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor') . '/js/plugins/drupalimagecaption/plugin.js';
    
    @@ -70,7 +70,7 @@ public function getConfig(Editor $editor) {
    +      \Drupal::service('extension.list.module')->getPath('ckeditor') . '/css/plugins/drupalimagecaption/ckeditor.drupalimagecaption.css',
    

    Why not $this->getModulePath()?

  35. +++ b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
    @@ -84,14 +92,21 @@ class CKEditor extends EditorBase implements ContainerFactoryPluginInterface {
    +      @trigger_error('Calling CKEditor::__construct() without the $module_list argument is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    Wrong versions.

  36. +++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/Llama.php
    @@ -51,7 +51,7 @@ public function isInternal() {
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/js/llama.js';
    
    +++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaButton.php
    @@ -29,7 +29,7 @@ public function getButtons() {
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/js/llama_button.js';
    
    +++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextual.php
    @@ -35,7 +35,7 @@ public function isEnabled(Editor $editor) {
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/js/llama_contextual.js';
    
    +++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaContextualAndButton.php
    @@ -50,7 +50,7 @@ public function getButtons() {
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/js/llama_contextual_and_button.js';
    
    +++ b/core/modules/ckeditor/tests/modules/src/Plugin/CKEditorPlugin/LlamaCss.php
    @@ -32,7 +32,7 @@ public function getButtons() {
    +      \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/css/llama.css',
    
    @@ -40,7 +40,7 @@ public function getCssFiles(Editor $editor) {
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor_test') . '/js/llama_css.js';
    

    Aren't these more children of CKEditorPluginBase? Why not $this->getModulePath() for these?

  37. +++ b/core/modules/color/color.module
    @@ -286,7 +286,7 @@ function template_preprocess_color_scheme_form(&$variables) {
    -  $preview_html_path = \Drupal::root() . '/' . (isset($info['preview_html']) ? drupal_get_path('theme', $theme) . '/' . $info['preview_html'] : drupal_get_path('module', 'color') . '/preview.html');
    +  $preview_html_path = \Drupal::root() . '/' . (isset($info['preview_html']) ? \Drupal::service('extension.list.theme')->getPath($theme) . '/' . $info['preview_html'] : \Drupal::service('extension.list.module')->getPath('color') . '/preview.html');
    

    Probably out of scope, but yowzah, that's a really long + complicated line. ;) Can we maybe break this up into multi-line format?

  38. +++ b/core/modules/media/tests/src/FunctionalJavascript/MediaDisplayTest.php
    @@ -29,7 +29,7 @@ protected function setUp(): void {
    +    $extension_path = \Drupal::service('extension.list.profile')->getPath('standard');
    
    +++ b/core/modules/media/tests/src/Traits/OEmbedTestTrait.php
    @@ -17,7 +17,7 @@ trait OEmbedTestTrait {
    +    return $this->container->get('extension.list.module')->getPath('media') . '/tests/fixtures/oembed';
    

    Let's not mix container->get() vs. \Drupal::service() in this patch. Let's have everything use \Drupal:: per previous comment...

  39. +++ b/core/modules/system/src/Form/ThemeSettingsForm.php
    @@ -2,20 +2,21 @@
    +use Drupal\Core\Config\ConfigFactoryInterface;
    +use Drupal\Core\Extension\ModuleHandlerInterface;
    +use Drupal\Core\Extension\ThemeExtensionList;
     use Drupal\Core\Extension\ThemeHandlerInterface;
     use Drupal\Core\File\Exception\FileException;
     use Drupal\Core\File\FileSystemInterface;
    +use Drupal\Core\Form\ConfigFormBase;
     use Drupal\Core\Form\FormStateInterface;
     use Drupal\Core\Render\Element;
     use Drupal\Core\StreamWrapper\PublicStream;
     use Drupal\Core\StreamWrapper\StreamWrapperManager;
    +use Drupal\Core\Theme\ThemeManagerInterface;
     use Symfony\Component\DependencyInjection\ContainerInterface;
     use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
     use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    -use Drupal\Core\Config\ConfigFactoryInterface;
    -use Drupal\Core\Extension\ModuleHandlerInterface;
    -use Drupal\Core\Form\ConfigFormBase;
    -use Drupal\Core\Theme\ThemeManagerInterface;
    

    Most of this is out of scope. I hate having to say so. I wish we let such cleanups happen naturally, but I know core committers are hyper aware of this, so I figure I should flag it so they don't have to. :/

  40. +++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
    @@ -158,12 +159,14 @@ public function testUninstallProfileDependency() {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    

    getPathname()

  41. +++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
    @@ -191,19 +194,20 @@ public function testUninstallProfileDependency() {
    -   * Tests that a profile can supply only real dependencies
    +   * Tests that a profile can supply only real dependencies.
    

    Probably out of scope.

  42. +++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
    @@ -191,19 +194,20 @@ public function testUninstallProfileDependency() {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    
    +++ b/core/modules/system/tests/src/Kernel/Installer/InstallerDependenciesResolutionTest.php
    @@ -20,11 +21,14 @@ class InstallerDependenciesResolutionTest extends KernelTestBase {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    

    getPathname()

    Since this is like the bazillontyith time this code block appears in the patch, can we put it somewhere shared? ;) Probably not, and probably out of scope (take that, @dww!), but maybe?

  43. +++ b/core/modules/update/src/Form/UpdateManagerUpdate.php
    @@ -41,10 +49,17 @@ class UpdateManagerUpdate extends FormBase {
    +      @trigger_error('Calling ' . __METHOD__ . '() without the $module_list argument is deprecated in drupal:8.8.0 and is required in drupal:9.0.0. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    A) Wrong versions.

    B) This comes up a lot in the patch. It'd be nice to be consistent about "Calling" or not, __METHOD__ or not, () or not, etc.

  44. +++ b/core/profiles/demo_umami/tests/src/Functional/DemoUmamiProfileTest.php
    @@ -52,10 +52,10 @@ public function testConfig() {
    +    $default_config_storage = new FileStorage($this->container->get('extension.list.profile')->getPath('demo_umami') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
    ...
    +    $default_config_storage = new FileStorage($this->container->get('extension.list.profile')->getPath('demo_umami') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY, InstallStorage::DEFAULT_COLLECTION);
    
    +++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseUserAgentTest.php
    @@ -28,7 +28,7 @@ class BrowserTestBaseUserAgentTest extends BrowserTestBase {
    +    $system_path = $this->buildUrl($this->container->get('extension.list.module')->getPath('system'));
    
    +++ b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php
    @@ -130,9 +130,10 @@ public function testCompileDIC() {
    +    $module_extension_list = $container->get('extension.list.module');
    

    More container vs. \Drupal:: inconsistency.

  45. +++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php
    @@ -58,7 +58,7 @@ public function testDrupalSettingsCachingRegression() {
    -    $fake_library = 'fakeLibrary/fakeLibrary';
    +    $fake_library = 'ajax_test/fakeLibrary';
    

    Out of scope.

  46. +++ b/core/tests/Drupal/KernelTests/Core/Installer/InstallerLanguageTest.php
    @@ -44,11 +45,13 @@ public function testInstallerTranslationFiles() {
    +    // Prime the \Drupal\Core\Extension\ExtensionList::getPathname static cache
    

    getPathname()

    $bazillontyith++ ;)

  47. +++ b/core/tests/Drupal/KernelTests/Core/Theme/RegistryTest.php
    @@ -2,6 +2,8 @@
    +use Drupal\Core\Extension\ExtensionList;
    
    @@ -234,7 +243,9 @@ public function testThemeTemplatesRegisteredByModules() {
    +    $extension_list = \Drupal::service('extension.list.module');
    +    assert($extension_list instanceof ExtensionList);
    

    Why do we care about ExtentionList itself? Previously we assert it's an instance of ModuleExtensionList. Not clear why this one is any different...

  48. +++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php
    @@ -131,7 +131,7 @@ public function testWhiteListChaining() {
    diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
    
    diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
    index b1ebad5e32..c34c99192f 100644
    
    index b1ebad5e32..c34c99192f 100644
    --- a/core/tests/Drupal/KernelTests/KernelTestBase.php
    
    --- a/core/tests/Drupal/KernelTests/KernelTestBase.php
    +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
    
    +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
    +++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
    @@ -18,6 +18,7 @@
    
    @@ -18,6 +18,7 @@
     use Drupal\Core\Test\TestDatabase;
     use Drupal\Tests\AssertHelperTrait;
     use Drupal\Tests\ConfigTestTrait;
    +use Drupal\Tests\ExtensionListTestTrait;
     use Drupal\Tests\RandomGeneratorTrait;
     use Drupal\Tests\TestRequirementsTrait;
     use Drupal\Tests\Traits\PHPUnit8Warnings;
    @@ -79,6 +80,7 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
    
    @@ -79,6 +80,7 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
       use AssertHelperTrait;
       use RandomGeneratorTrait;
       use ConfigTestTrait;
    +  use ExtensionListTestTrait;
       use TestRequirementsTrait;
       use PHPUnit8Warnings;
    

    👍 I was wondering where this happened. Lots of the tests above use the trait themselves, but now we've finally got it happening in the base class. We should remove the trait from children test classes if it's handled in the base. Sorry, I don't want to go back through the whole patch for this. But basically search for "use ExtensionListTestTrait" and remove it from any test classes since we should have it in the parent classes.

  49. +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -65,6 +65,7 @@ abstract class BrowserTestBase extends TestCase {
    +  use ExtensionListTestTrait;
    

    Don't we need use Drupal\Tests\ExtensionListTestTrait earlier in this file before we can use it?

  50. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -70,6 +71,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
    +   * @var \Drupal\Core\Extension\ExtensionPathResolver|\PHPUnit\Framework\MockObject\MockObject
    
    +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryLegacyTest.php
    @@ -64,6 +65,13 @@ class RegistryLegacyTest extends UnitTestCase {
    +   * @var \Drupal\Core\Extension\ModuleExtensionList|\PHPUnit\Framework\MockObject\MockObject
    
    +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -61,6 +62,13 @@ class RegistryTest extends UnitTestCase {
    +   * @var \Drupal\Core\Extension\ModuleExtensionList|\PHPUnit\Framework\MockObject\MockObject
    

    🤔 Is that the right format for these? I don't remember seeing this, but I'm probably wrong.

  51. +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryLegacyTest.php
    @@ -134,7 +147,17 @@ public function testGetLegacyThemeFunctionRegistryForModule() {
    @@ -147,3 +170,7 @@ protected function setupTheme() {
    
    @@ -147,3 +170,7 @@ protected function setupTheme() {
       }
     
     }
    +
    +if (!defined('DRUPAL_MINIMUM_PHP')) {
    +  define('DRUPAL_MINIMUM_PHP', '7.3.0');
    +}
    
    +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -473,7 +485,7 @@ public function providerTestPostProcessExtension() {
    @@ -497,3 +509,7 @@ protected function setupTheme() {
    
    @@ -497,3 +509,7 @@ protected function setupTheme() {
     function get_defined_functions() {
       return RegistryTest::$functions ?: \get_defined_functions();
     }
    +
    +if (!defined('DRUPAL_MINIMUM_PHP')) {
    +  define('DRUPAL_MINIMUM_PHP', '7.3.0');
    +}
    

    Out of scope? What's up with this?

  52. +++ b/core/tests/Drupal/Tests/ExtensionListTestTrait.php
    @@ -0,0 +1,42 @@
    +    return $this->container->get('extension.list.module')->getPath($module_name);
    ...
    +    return $this->container->get('extension.list.theme')->getPath($theme_name);
    
    +++ b/core/tests/Drupal/Tests/UpdatePathTestTrait.php
    @@ -88,8 +88,10 @@ protected function runUpdates($update_url = NULL) {
    +      $module_list = $this->container->get('extension.list.module');
    

    Container or \Drupal::?

Thanks/sorry!
-Derek

shaktik’s picture

Assigned: Unassigned » shaktik
shaktik’s picture

Assigned: shaktik » Unassigned
shaktik’s picture

StatusFileSize
new126.63 KB

Hi @dww,

I have applied patch #205 and getting below error, Please find the attached screenshot.

The website encountered an unexpected error. Please try again later.

Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "extension.path.resolver". in Drupal\Component\DependencyInjection\Container->get() (line 151 of core/lib/Drupal/Component/DependencyInjection/Container.php).
Drupal::service('extension.path.resolver') (Line: 92)
Drupal\Core\Asset\LibraryDiscoveryParser->__construct('/Applications/MAMP/htdocs/drupal', Object, Object, Object, Object) (Line: 257)
Drupal\Component\DependencyInjection\Container->createService(Array, 'library.discovery.parser') (Line: 171)
Drupal\Component\DependencyInjection\Container->get('library.discovery.parser', 1) (Line: 432)
Drupal\Component\DependencyInjection\Container->resolveServicesAndParameters(Array) (Line: 235)
Drupal\Component\DependencyInjection\Container->createService(Array, 'library.discovery.collector') (Line: 171)
Drupal\Component\DependencyInjection\Container->get('library.discovery.collector', 1) (Line: 432)
Drupal\Component\DependencyInjection\Container->resolveServicesAndParameters(Array) (Line: 235)
Drupal\Component\DependencyInjection\Container->createService(Array, 'library.discovery') (Line: 171)
Drupal\Component\DependencyInjection\Container->get('library.discovery', 1) (Line: 432)
Drupal\Component\DependencyInjection\Container->resolveServicesAndParameters(Array) (Line: 235)
Drupal\Component\DependencyInjection\Container->createService(Array, 'asset.resolver') (Line: 171)
Drupal\Component\DependencyInjection\Container->get('asset.resolver', 1) (Line: 432)
Drupal\Component\DependencyInjection\Container->resolveServicesAndParameters(Array) (Line: 235)
Drupal\Component\DependencyInjection\Container->createService(Array, 'ajax_response.attachments_processor') (Line: 171)
Drupal\Component\DependencyInjection\Container->get('ajax_response.attachments_processor', 1) (Line: 432)
Drupal\Component\DependencyInjection\Container->resolveServicesAndParameters(Array) (Line: 235)
Drupal\Component\DependencyInjection\Container->createService(Array, 'ajax_response.subscriber') (Line: 171)
Drupal\Component\DependencyInjection\Container->get('ajax_response.subscriber') (Line: 148)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->getListeners('kernel.request') (Line: 121)
Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy->getListeners('kernel.request') (Line: 71)
Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy->dispatch(Object, 'kernel.request') (Line: 134)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
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: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 705)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

#205 site broken

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new165.22 KB
new38.42 KB

Thanks for the exhaustive review @dww!

Overall comments:

  • In test cases where existing code is using $this->container->get() I have used the same for consistency. I think it's out of scope to covert everything to \Drupal::service() in this issue.
  • There are issues using dependency injection in a lot of these cases. I haven't got the full history of why. Happy to take another look after the rest of the issues are cleaned up

Here goes:

  1. Fixed
  2. Fixed
  3. Fixed
  4. Fixed
  5. Fixed
  6. Fixed
  7. Fixed
  8. Fixed
  9. Fixed
  10. Fixed
  11. Fixed
  12. Fixed
  13. Fixed
  14. Fixed
  15. DI: Left as is
  16. Fixed
  17. Left as is
  18. Not sure. Left as is.
  19. DI: Left as is
  20. Fixed
  21. Fixed
  22. We aren't dealing with streamwrappers here, so no need for our FileSystem dirname handling.
  23. DI: left as is
  24. $this->container() left as is
  25. Fixed
  26. Fixed
  27. DI: left as is
  28. DI: left as is
  29. Fixed
  30. Fixed
  31. DI: left as is. Not sure how the resolver would work in this case? I only see extension.list.theme in use?
  32. Reverted
  33. Reverted
  34. This class does not extend from CKEditorPluginBase so doesn't have that method. Follow up?
  35. Fixed
  36. These classes does not extend from CKEditorPluginBase so doesn't have that method. Follow up?
  37. Fixed
  38. $this->container() left as is
  39. Reverted
  40. Fixed
  41. Reverted
  42. Fixed. Follow up?
  43. Fixed
  44. $this->container() left as is
  45. Reverted
  46. Fixed
  47. Fixed
  48. Went through all test cases that extend classes that use the trait already and removed.
  49. Not sure what you mean?
  50. Yep. I've seen it used like that before.
  51. We aren't loading bootstrap.inc anymore so that constant isn't defined.
  52. $this->container() left as is
dww’s picture

Thanks for addressing all that! Don't have time to look at the interdiff, but sounds promising. :)

Re: Overall - container + DI: all sounds fine, we can do those in followups.

31: Yes, sorry. I guess I had missed this was Theme.php and doesn't care about modules at all. 😉
34: Oh wow. 😉 Sorry, didn't realize this doesn't extend CKEditorPluginBase. Whoops. follow-up++
42: Follow-up++
49: Sorry I wasn't clear. BrowserTestBase is now using the ExtensionListTestTrait trait but doesn't have a use statement about it. Guess they're in the same namespace so it finds it? Didn't notice that the first time, so probably this is fine.
50: 👍
51: 👍

Re: test fail: Looks like a random fail? Re-queuing.

There was 1 error:

1) Drupal\FunctionalJavascriptTests\Ajax\AjaxTest::testDrupalSettingsCachingRegression
RuntimeException: Unable to complete AJAX request.
kim.pepper’s picture

Did a quick scan and we already have followup for #3087327: [PP-1] DrupalImageCaption should extend CKEditorPluginBase I guess they all could extend CKEditorPluginBase?

kim.pepper’s picture

I wonder if the test fail was due to #214.45 and why??

kim.pepper’s picture

The ajax test change was introduced in #64 by @almaudoh, then removed, then re-added. I don't think we had an explanation for the change anywhere in the long history of this issue.

Finally found time to fix the AjaxTest. A similar fix was tried in #2808063: LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist

alexpott’s picture

  1. +++ b/core/core.services.yml
    @@ -522,7 +522,7 @@ services:
    -    arguments: ['%app.root%', '@module_handler', '@kernel']
    +    arguments: ['%app.root%', '@module_handler', '@kernel', '@extension.list.module']
    

    This injection is no longer used.

  2. +++ b/core/includes/bootstrap.inc
    @@ -153,12 +153,23 @@
    + * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use
    + *   \Drupal\Core\Extension\ExtensionList::getPathname() from the respective
    + *   service (extension.list.module, extension.list.profile,
    + *   extension.list.theme, extension.list.theme_engine) instead.
    ...
    +  @trigger_error('drupal_get_filename() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() from the respective service (extension.list.module, extension.list.profile, extension.list.theme, extension.list.theme_engine) instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    
    @@ -202,8 +213,15 @@ function drupal_get_filename($type, $name, $filename = NULL) {
    + * @deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use
    + *   \Drupal\Core\Extension\ExtensionList::getPath() instead.
    ...
    +  @trigger_error('drupal_get_path() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPath() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    How come we're not mentioning the new extension.path.resolver service?

  3. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,74 @@
    +   * @return string
    +   *   The extension path.
    +   */
    +  public function getPathname($type, $name) {
    ...
    +   *
    +   * @return string
    +   *   The extension info file path.
    +   */
    +  public function getPath($type, $name) {
    

    As this is new code let's use scalar typehints and return typehints.

  4. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,74 @@
    +    if ($type !== 'core' && !isset($this->extensionLists[$type])) {
    +      throw new UnknownExtensionTypeException(sprintf("Unknown extension type %s.", $type));
    +    }
    +    if ($type === 'core') {
    +      return 'core/core.info.yml';
    +    }
    

    This could be simplified by swapping things around. Eg:

        if ($type === 'core') {
          return 'core/core.info.yml';
        }
        if (!isset($this->extensionLists[$type])) {
          throw new UnknownExtensionTypeException(sprintf("Unknown extension type %s.", $type));
        }
    
  5. +++ b/core/modules/media/tests/src/Traits/OEmbedTestTrait.php
    @@ -17,7 +17,7 @@ trait OEmbedTestTrait {
    -    return drupal_get_path('module', 'media') . '/tests/fixtures/oembed';
    +    return $this->container->get('extension.list.module')->getPath('media') . '/tests/fixtures/oembed';
    

    This is used in functional tests - we should not be using $this->container there. It gets out of date.

  6. +++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseUserAgentTest.php
    @@ -28,7 +28,7 @@ class BrowserTestBaseUserAgentTest extends BrowserTestBase {
    -    $system_path = $this->buildUrl(drupal_get_path('module', 'system'));
    +    $system_path = $this->buildUrl($this->container->get('extension.list.module')->getPath('system'));
    

    BrowserTests should avoid $this->container

  7. +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryLegacyTest.php
    @@ -147,3 +170,7 @@ protected function setupTheme() {
    +if (!defined('DRUPAL_MINIMUM_PHP')) {
    +  define('DRUPAL_MINIMUM_PHP', '7.3.0');
    +}
    
    +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -497,3 +509,7 @@ protected function setupTheme() {
    +if (!defined('DRUPAL_MINIMUM_PHP')) {
    +  define('DRUPAL_MINIMUM_PHP', '7.3.0');
    +}
    

    This should no longer be necessary. It's been converted to \Drupal::MINIMUM_PHP

  8. +++ b/core/tests/Drupal/Tests/ExtensionListTestTrait.php
    @@ -0,0 +1,42 @@
    +  protected function getModulePath($module_name) {
    +    return $this->container->get('extension.list.module')->getPath($module_name);
    +  }
    ...
    +  protected function getThemePath($theme_name) {
    +    return $this->container->get('extension.list.theme')->getPath($theme_name);
    +  }
    

    So as mentioned before $this->container is tricky in browser tests because it gets out of date. I think we should use \Drupal::service() here. Plus we should now have scalar typehints and return typehints.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new164.19 KB
new9.59 KB

Thanks @alexpott.

Addresses feedback in #224. The AjaxTest fail is still a mystery.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new164.99 KB
new812 bytes

OK. Here's the fix for AjaxTest

-    $fake_library = 'fakeLibrary/fakeLibrary';
+    $fake_library = 'ajax_test/fakeLibrary';
dww’s picture

Re: #227: Ugh, it really was #214.45 🤦‍♂️ whoops! 😉 Sorry about that, and thanks for tracking it down.

https://www.drupal.org/node/2940438 could use some edits to mention extension.path.resolver, too.

Do we need a new title here, too?

Thanks!
-Derek

kim.pepper’s picture

I gave the change record a few teaks to emphasise Drupal\Core\Extension\ExtensionPathResolver

dww’s picture

Nice, thanks. Did a few more little formatting edits. Removing the tag.

alexpott’s picture

+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -105,7 +120,7 @@ public function buildByExtension($extension) {
-      $path = $this->drupalGetPath($extension_type, $extension);
+      $path = $this->extensionPathResolver->getPath($extension_type, $extension);

This is why the Ajax test needs changing... in drupal_get_filename() we catch InvalidArgumentException and covert it to a warning. The new code is not doing this. PHP will continue processing after the warning. I think we need to update the CR with this information. Also I think we need to have a good think about whether this change will break sites that were previously working even though they have missing module code. Also the API changes section of the issue summary doesn't cover this change. In some ways I think we might have to consider deprecating the warning behaviour and only make this part of the change in Drupal 10. Maybe one course of action would be to re-implement this warning functionality in the new extension path resolver service (and deprecate it for Drupal 10) and then use this service in any place where this might matter.

So review points:

  1. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,74 @@
    +   * @return string
    +   *   The extension path.
    +   */
    +  public function getPathname(string $type, string $name): string {
    ...
    +   * @return string
    +   *   The extension info file path.
    +   */
    +  public function getPath(string $type, string $name): string {
    

    Maybe we should document that this will thrown an exception when the extension is not found.

  2. +++ b/core/tests/Drupal/Tests/ExtensionListTestTrait.php
    @@ -0,0 +1,42 @@
    +  protected function getModulePath($module_name) {
    +    return \Drupal::service('extension.list.module')->getPath($module_name);
    +  }
    +
    ...
    +  protected function getThemePath($theme_name) {
    +    return \Drupal::service('extension.list.theme')->getPath($theme_name);
    +  }
    

    Can use scalar typehints and return typehints.

  3. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,74 @@
    +    if (!isset($this->extensionLists[$type])) {
    +      throw new UnknownExtensionTypeException(sprintf("Unknown extension type %s.", $type));
    +    }
    

    The exception is not documented with an @throws

kim.pepper’s picture

Issue summary: View changes
StatusFileSize
new165.47 KB
new2.26 KB

Addressed feedback in #231 I'm declaring these methods throw \Drupal\Core\Extension\Exception\UnknownExtensionException if the extension is not found, which I think is more accurate than \InvalidArgumentException

I've updated the API Changes section in the summary and the change record.

alexpott’s picture

Well there is a bit of #231 that's not addressed

In some ways I think we might have to consider deprecating the warning behaviour and only make this part of the change in Drupal 10. Maybe one course of action would be to re-implement this warning functionality in the new extension path resolver service (and deprecate it for Drupal 10) and then use this service in any place where this might matter.

This one is tricky. But I think we need to go through the code and see where this might cause an issue. We know it might in the assert resolver because of #214.45

kim.pepper’s picture

StatusFileSize
new167.36 KB
new3.41 KB

Adds a deprecation warning if extension type not found, and a legacy test to test the deprecation works.

alexpott’s picture

Status: Needs review » Needs work

@kim.pepper I don't think #234 addresses #233.

The issue is that the code is no longer behaving the same way for:

+++ b/core/core.services.yml
@@ -314,7 +314,7 @@ services:
+    arguments: ['@config.factory', '@config.storage', '@config.typed', '@config.manager', '@event_dispatcher', '%install_profile%', '@extension.path.resolver']

+++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php
@@ -58,7 +58,7 @@ public function testDrupalSettingsCachingRegression() {
-    $fake_library = 'fakeLibrary/fakeLibrary';
+    $fake_library = 'ajax_test/fakeLibrary';

In HEAD, I think this results in this code in drupal_get_filename()

  catch (\InvalidArgumentException $e) {
    // Catch the exception. This will result in triggering an error.
    // If the filename is still unknown, create a user-level error message.
    trigger_error(
      sprintf('The following %s is missing from the file system: %s', $type, $name),
      E_USER_WARNING
    );
  }

triggering.

The change in #234 is covering the following code in drupal_get_filename()

  catch (ServiceNotFoundException $e) {
    // Catch the exception. This will result in triggering an error.
    // If the service is unknown, create a user-level error message.
    trigger_error(
      sprintf('Unknown type specified: "%s". Must be one of: "core", "profile", "module", "theme", or "theme_engine".', $type),
      E_USER_WARNING
    );
  }

Thinking about this situation some more.

  • We might think it is okay that the new code behaves differently because existing code has to move to the new code to get the new throwing exceptions behaviour
  • But we're also changing things like the AssetResolver where things might be relying on the non-breaking warning behaviour.
  • If we remove the exceptions then we need to go back to triggering the same warnings.
  • The fact that no test was changed as a result of #234 means we're missing test coverage of throwing the exception.
  • One possible way out is to keep throwing exceptions but in areas where we think this might be risky - like the AssetResolver catch them and emit a warning instead.
kim.pepper’s picture

If we remove the exceptions then we need to go back to triggering the same warnings.

I (incorrectly) assumed triggering a deprecation would have the same effect.

The fact that no test was changed as a result of #234 means we're missing test coverage of throwing the exception.

I took out throwing an exception in #234 and triggered a deprecation warning?

One possible way out is to keep throwing exceptions but in areas where we think this might be risky - like the AssetResolver catch them and emit a warning instead.

I had a look through AssetResolver but couldn't workout where it calls ExtensionPathResolver in order to catch an exception in the right place. 🤔

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

andypost’s picture

Queued for 9.2, maybe apply for merge requests for this issue?

The patch is ~150kb - it needs rebase time to time

kapilv’s picture

Assigned: Unassigned » kapilv
kapilv’s picture

Assigned: kapilv » Unassigned
Status: Needs work » Needs review
StatusFileSize
new160.01 KB
new51.63 KB

Hear an updated patch.

daffie’s picture

Status: Needs review » Needs work

The patch fails the testbot.

anmolgoyal74’s picture

Status: Needs work » Needs review
StatusFileSize
new166.9 KB
new7.93 KB

In 240, new files were not added to the patch.
Added those and updated CS messages.

cyb_tachyon’s picture

Added #3179546: Tag ExtensionList services with extension.list

This will allow us to reduce the amount of repeated code in this patch.

kim.pepper’s picture

Re: #244 should be a follow up.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new169.41 KB

Wasn't sure what was going on in #242 so did a reroll of #234 replacing some new uses of drupal_get_path().

kim.pepper’s picture

Issue tags: +DrupalGov 2020
kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new172.65 KB
new6.84 KB

Fixes deprecation annotations.

kim.pepper’s picture

StatusFileSize
new172.33 KB
new2.17 KB

Rounding back to the issue raised by @alexpott in #235. I *think* this should restore the original behaviour.

andypost’s picture

Status: Needs review » Needs work

Deprecated in 9.2 please update now(

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new171.96 KB
new16.78 KB

Updated deprecation notices to 9.2. Let's hope we don't need to change it to 9.3!

Still puzzled by the AjaxTest fail. Could use some help with that.

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new2.78 KB
new172.07 KB

Here's a fix for the AjaxTest - #250 copied the wrong catch...

paulocs’s picture

We must also update the CR.
I'll do it.

paulocs’s picture

Status: Needs review » Reviewed & tested by the community

CR was updated.
Moving to RTBC as I did not find any place where drupal_get_path() and drupal_get_filename() are called.
Deprecation tests looks good.

mondrake’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll
kim.pepper’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new172.07 KB

Re-roll of #254

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new178.33 KB
new752 bytes

Replace usage in core/modules/migrate_drupal_ui/tests/src/Functional/d7/DoubleSlashTest.php

spokje’s picture

Status: Needs work » Needs review
StatusFileSize
new676 bytes
new178.33 KB

Replace usage in core/modules/migrate_drupal_ui/tests/src/Functional/d7/DoubleSlashTest.php

I think this is what you were after?

daffie’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -433,8 +448,15 @@ protected function applyLibrariesOverride($libraries, $extension) {
    +    @trigger_error('drupalGetPath() is deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    There is no deprecation message test for this deprecation.

  2. +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
    @@ -710,8 +725,15 @@ protected function getDefaultConfigDirectory($type, $name) {
    +    @trigger_error('drupalGetPath() is deprecated in drupal:9.2.0 and is removed from drupal:10.0.0. Use \Drupal\Core\Extension\ExtensionList::getPathname() instead. See https://www.drupal.org/node/2940438', E_USER_DEPRECATED);
    

    There is no deprecation message test for this deprecation.

  3. +++ b/core/includes/bootstrap.inc
    @@ -153,12 +153,21 @@
    + * @see https://www.drupal.org/node/2940438
    + *
    + * @see \Drupal\Core\Extension\ExtensionList::getPathname()
    

    Nitpick: This empty line can be removed.

  4. +++ b/core/lib/Drupal/Core/Extension/ExtensionPathResolver.php
    @@ -0,0 +1,88 @@
    +      trigger_error(sprintf('The following %s is missing from the file system: %s', $type, $name), E_USER_WARNING);
    

    Why trigger_error instead of @trigger_error like we do everywhere else.

  5. +++ b/core/lib/Drupal/Core/Render/theme.api.php
    @@ -1030,7 +1030,7 @@ function hook_library_info_alter(&$libraries, $extension) {
    +  unset($css[\Drupal::service('extension.list.module')->getPath('system') . '/defaults.css']);
    

    Can we do this on 2 lines for improved readability.

  6. +++ b/core/modules/ckeditor/src/CKEditorPluginBase.php
    @@ -30,6 +30,44 @@
    +    if ($this->moduleList === NULL) {
    

    In core we usually do if (!$this->moduleList) {

  7. +++ b/core/modules/user/src/Form/UserPasswordForm.php
    @@ -176,7 +176,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    -    $form_state->setRedirect('<front>');
    +    $form_state->setRedirect('user.page');
    

    This change does not belong in this patch. Out of scope.

  8. +++ b/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php
    @@ -117,79 +105,4 @@ public function testUserMailNotifyLangcodeDeprecation() {
    -  public function testUserRecoveryMailLanguage() {
    

    Why is this test removed?

  9. +++ b/core/modules/user/user.module
    @@ -775,7 +775,7 @@ function user_mail($key, &$message, $params) {
    -  $language = $language_manager->getLanguage($langcode);
    +  $language = $language_manager->getLanguage($params['account']->getPreferredLangcode());
    

    This change is out of scope for this issue.

  10. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -752,10 +828,12 @@ public function testEmptyLibraryFile() {
    -
    

    Nitpick: This empty does not need to be removed.

  11. +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -173,7 +185,7 @@ public function testGetRegistryForModule() {
    -  public function testPostProcessExtension($defined_functions, $hooks, $expected) {
    +  public function testPostProcessExtension(array $defined_functions, array $hooks, array $expected) {
    

    This change is out of scope for this issue.

  12. +++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
    @@ -497,3 +509,7 @@ protected function setupTheme() {
    +
    +if (!defined('DRUPAL_MINIMUM_PHP')) {
    +  define('DRUPAL_MINIMUM_PHP', '7.3.0');
    +}
    

    This change can be removed. See: #2908079: Move some of the bootstrap.inc PHP-related constants to \Drupal and deprecate the old versions

daffie’s picture

The CR was updated by @kim.pepper on 3 july.

paulocs’s picture

Assigned: Unassigned » paulocs

I'll work on it

paulocs’s picture

Assigned: paulocs » Unassigned

Sorry, I will have to unassigned the issue. Tomorrow morning I can work on it and add a patch for it.

paulocs’s picture

Assigned: Unassigned » paulocs

Now I'll work on it.

paulocs’s picture

Assigned: paulocs » Unassigned
Status: Needs work » Needs review
StatusFileSize
new10.01 KB
new171.2 KB

About 263.1 and 263.1, the patch removes the function drupalGetPath() as it is a protected function and it is not used any more in LibraryDiscoveryParser.php and in ConfigInstaller.php

I didn't addressed 263.4 because I'm not sure if it is on scope of that issue.

I did the rest of the changes suggested on comment #263.

Please review.

daffie’s picture

Status: Needs review » Needs work

For #263.4: I did a code search and we are using both in core. So, both are good.

Just 1 point left for me:

+++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
@@ -18,52 +18,20 @@ class GetFilenameTest extends KernelTestBase {
-  public function testDrupalGetFilename() {
-    // Retrieving the location of a module.
-    $this->assertIdentical(drupal_get_filename('module', 'system'), 'core/modules/system/system.info.yml');
-
-    // Retrieving the location of a theme.
-    \Drupal::service('theme_installer')->install(['stark']);
-    $this->assertIdentical(drupal_get_filename('theme', 'stark'), 'core/themes/stark/stark.info.yml');
-
-    // Retrieving the location of a theme engine.
-    $this->assertIdentical(drupal_get_filename('theme_engine', 'twig'), 'core/themes/engines/twig/twig.info.yml');
-
-    // Retrieving the location of a profile. Profiles are a special case with
-    // a fixed location and naming.
-    $this->assertIdentical(drupal_get_filename('profile', 'testing'), 'core/profiles/testing/testing.info.yml');
-
-    // Set a custom error handler so we can ignore the file not found error.
-    set_error_handler(function ($severity, $message, $file, $line) {
-      // Skip error handling if this is a "file not found" error.
-      if (strstr($message, 'is missing from the file system:')) {
-        \Drupal::state()->set('get_filename_test_triggered_error', $message);
-        return;
-      }
-      throw new \ErrorException($message, 0, $severity, $file, $line);
-    });
-    $this->assertNull(drupal_get_filename('module', 'there_is_a_module_for_that'), 'Searching for an item that does not exist returns NULL.');
-    $this->assertEquals('The following module is missing from the file system: there_is_a_module_for_that', \Drupal::state()->get('get_filename_test_triggered_error'));
-
-    $this->assertNull(drupal_get_filename('theme', 'there_is_a_theme_for_you'), 'Searching for an item that does not exist returns NULL.');
-    $this->assertEquals('The following theme is missing from the file system: there_is_a_theme_for_you', \Drupal::state()->get('get_filename_test_triggered_error'));
-
-    $this->assertNull(drupal_get_filename('profile', 'there_is_an_install_profile_for_you'), 'Searching for an item that does not exist returns NULL.');
-    $this->assertEquals('The following profile is missing from the file system: there_is_an_install_profile_for_you', \Drupal::state()->get('get_filename_test_triggered_error'));
-
-    // Restore the original error handler.
-    restore_error_handler();

Can we move these tests over to a new ExtensionPathResolverTest.

spokje’s picture

Status: Needs work » Needs review
StatusFileSize
new3.04 KB
new174.57 KB

Ignore, had an typo in a function name.

spokje’s picture

StatusFileSize
new174.58 KB
new3.04 KB

Can we move these tests over to a new ExtensionPathResolverTest.

#269

Would this do?

spokje’s picture

I've seem to have inherited a coding standards message

core/includes/bootstrap.inc 
line 162	Additional blank lines found at end of doc comment

I'm pretty sure this can be fixed on commit? Seems a bit of TestBotTime-waste to run a full core test on an empty doc comment line...

daffie’s picture

Issue summary: View changes

Updated the IS and the CR. with the API additions for the class \Drupal\ckeditor\CKEditorPluginBase.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

All code changes look good to me.
The patch does what IS says it should do.
The deprecations are mentioned in the CR.
The API additions are mentioned in the CR.
Both deprecations have testing for them.
All usages of the deprecated function have been removed with the exception of the deprecated functions themselfs and deprecation testing.

The protected methods \Drupal\Core\Asset\LibraryDiscoveryParser::drupalGetPath() and \Drupal\Core\Config\ConfigInstaller::drupalGetPath() have been removed.
When I do a code search on contrib modules for drupalGetPath(, then all the occurrences that I found have their own implementations for that method. See: http://grep.xnddx.ru/search?text=drupalGetPath%28&filename=

The protected method \Drupal\Core\Theme\Registry::getPath() has been deprecated. The method now triggers a deprecation message. The class has been tagged @internal and no deprecation message test has been added.

For me the patch is RTBC.

paulocs’s picture

Nice!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

So we removed ::drupalGetPath() because there is no testing. That's not right. We should leave the deprecations in as per #262. These one liner wrappers do not need testing an eyeball can see that these are fine. We don't know what is in custom and there is no reason to break it when we can issue a deprecation. We can remove private functions and these functions should have been created as private but they're not.

daffie’s picture

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new178.75 KB
new18.65 KB

Lots of conflicts with file_create_url()/batch builder and assert changes.

Also updated all deprecation messages. And restored 2 drupalGetPath() methods. One that is removed is in an inlined test class, I would say we can safely assume that to be internal and not needing to deprecate ;)

berdir’s picture

StatusFileSize
new179.06 KB
new1.31 KB

Fixed CS issues.

berdir’s picture

+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigCRUDTest.php
@@ -270,7 +269,6 @@ public function testDataTypes() {
     $name = 'config_test.types';
     $config = $this->config($name);
-    $original_content = file_get_contents(drupal_get_path('module', 'config_test') . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY . "/$name.yml");
 
     // Verify variable data types are intact.

Note on this:

$original_content is an unused variable, #3193163: Deprecate AssertLegacyTrait::verbose and remove its usage removed the verbose() call of it but did not remove the variable. So I just removed the line.

Status: Needs review » Needs work

The last submitted patch, 280: 2347783-280.patch, failed testing. View results

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new180.2 KB
new2.04 KB

Fixing those test fails.

andypost’s picture

Looks great except few unrelated changes

+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -506,7 +521,7 @@ public function checkConfigurationToInstall($type, $name) {
-    list($invalid_default_config, $missing_dependencies) = $this->findDefaultConfigWithUnmetDependencies($storage, $enabled_extensions, $profile_storages);
+    [$invalid_default_config, $missing_dependencies] = $this->findDefaultConfigWithUnmetDependencies($storage, $enabled_extensions, $profile_storages);

@@ -574,7 +589,7 @@ protected function findDefaultConfigWithUnmetDependencies(StorageInterface $stor
-      list($provider) = explode('.', $config_name, 2);
+      [$provider] = explode('.', $config_name, 2);

@@ -600,7 +615,7 @@ protected function validateDependencies($config_name, array $data, array $enable
-      list($provider) = explode('.', $config_name, 2);
+      [$provider] = explode('.', $config_name, 2);

out of scope

daffie’s picture

Status: Needs review » Needs work

Patch looks good. Just 2 nitpicks for me:

  1. +++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionPathResolverTest.php
    @@ -0,0 +1,64 @@
    +  public function testExtensionPathResolving() {
    ...
    +  public function testExtensionPathResolvingWithNonExistingModule() {
    ...
    +  public function testExtensionPathResolvingWithNonExistingTheme() {
    ...
    +  public function testExtensionPathResolvingWithNonExistingProfile() {
    ...
    +  public function testExtensionPathResolvingWithNonExistingThemeEngine() {
    

    These new test methods need a docblock.

  2. +++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionPathResolverTest.php
    @@ -0,0 +1,64 @@
    +    // Retrieving the location of a module.
    +    $this->assertSame('core/modules/system/system.info.yml', \Drupal::service('extension.list.module')
    +      ->getPathname('system'));
    

    This is a special case. Can we also add a test with a regular module.

andypost’s picture

Status: Needs work » Needs review
StatusFileSize
new6.89 KB
new178.9 KB

Fix for #284/285

andypost’s picture

StatusFileSize
new607 bytes
new178.9 KB

Fix CS

daffie’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs release manager review

All code changes are good enough for me.
The IS and the CR are in order.
There is enough testing.
For me it is RTBC.

Removing the release manager review tag, because this is not going into 8.9 anymore.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/ckeditor/src/CKEditorPluginBase.php
    @@ -30,6 +30,44 @@
    +  public function getModuleList() {
    ...
    +  public function getModulePath($module_name) {
    

    These methods really should not be on the public API of these plugins. Can they be protected instead of public?

  2. +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    @@ -46,7 +46,7 @@ public function getLibraries(Editor $editor) {
    -    return drupal_get_path('module', 'ckeditor') . '/js/plugins/drupalimagecaption/plugin.js';
    +    return \Drupal::service('extension.list.module')->getPath('ckeditor') . '/js/plugins/drupalimagecaption/plugin.js';
    
    @@ -70,7 +70,7 @@ public function getConfig(Editor $editor) {
    -      drupal_get_path('module', 'ckeditor') . '/css/plugins/drupalimagecaption/ckeditor.drupalimagecaption.css',
    +      \Drupal::service('extension.list.module')->getPath('ckeditor') . '/css/plugins/drupalimagecaption/ckeditor.drupalimagecaption.css',
    

    Is there a follow up to inject the service?

  3. +++ b/core/modules/datetime_range/tests/src/Kernel/Views/EntityTypeWithoutViewsDataTest.php
    @@ -34,7 +34,7 @@ class EntityTypeWithoutViewsDataTest extends KernelTestBase {
    -    $view_yaml = drupal_get_path('module', 'taxonomy') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY . '/views.view.taxonomy_term.yml';
    +    $view_yaml = \Drupal::service('extension.list.module')->getPath('taxonomy') . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY . '/views.view.taxonomy_term.yml';
    

    $this->getModulePath()

dhirendra.mishra’s picture

Assigned: Unassigned » dhirendra.mishra

Let me work on this.....

dhirendra.mishra’s picture

Assigned: dhirendra.mishra » Unassigned
Status: Needs work » Needs review
StatusFileSize
new4.59 KB
new180.84 KB

Please review my Files below

alexpott’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImageCaption.php
    @@ -21,4 +23,28 @@
    +  /**
    +   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
    +   *   The module extension list.
    +   */
    +  public function __construct(ModuleExtensionList $extension_list_module) {
    +    $this->moduleExtensionList = $extension_list_module;
    +  }
    +
    

    Adding a constructor can cause issues for anything extending it. Fortunately this is not happening in contrib - http://grep.xnddx.ru/search?text=DrupalImageCaption&filename=

  2. +++ b/core/modules/datetime_range/tests/src/Kernel/Views/EntityTypeWithoutViewsDataTest.php
    @@ -16,4 +18,28 @@
       /**
    +   * The module extension list.
    +   *
    +   * @var \Drupal\Core\Extension\ModuleExtensionList
    +   */
    +  protected $moduleExtensionList;
    +
    +  /**
    +   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
    +   *   The module extension list.
    +   */
    +  public function __construct(ModuleExtensionList $extension_list_module) {
    +    $this->moduleExtensionList = $extension_list_module;
    +  }
    +
    +  /**
    +   * {@inheritdoc}
    +   */
    +  public static function create(ContainerInterface $container) {
    +    return new static(
    +      $container->get('extension.list.module')
    +    );
    +  }
    

    This is not necessary - tests have a method getModulePath() that can be used here. It's added by a trait in this issue.

dhirendra.mishra’s picture

Status: Needs work » Needs review
StatusFileSize
new3.09 KB

Please find the updated one from #292 comment.

dhirendra.mishra’s picture

StatusFileSize
new3.09 KB
new179.35 KB

Pls ignore above one and find below files as per #292 comment

Status: Needs review » Needs work

The last submitted patch, 294: 2347783-293.patch, failed testing. View results

andypost’s picture

Status: Needs work » Needs review
StatusFileSize
new8.41 KB
new181.52 KB

Attempt to fix tests, the DrupalImageCaption plugin could use injection so it needs ContainerFactoryPluginInterface and I see no reason to add protected method there (this plugin is not inherited from CKEditorPluginBase - needs follow-up?)

Also added type-hints to the methods and updated ckeditor's test plugins

andypost’s picture

StatusFileSize
new5.49 KB
new181.34 KB

Fixed test plugins to use proper DI, people often copy code from tests so better to use clean approach

andypost’s picture

StatusFileSize
new658 bytes
new181.29 KB

Fix CS

daffie’s picture

Status: Needs review » Reviewed & tested by the community

The points of @alexpott have been addressed.
Back to RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/ckeditor/src/Plugin/CKEditorPlugin/DrupalImage.php
    @@ -22,7 +22,7 @@ class DrupalImage extends CKEditorPluginBase implements CKEditorPluginConfigurab
    -    return drupal_get_path('module', 'ckeditor') . '/js/plugins/drupalimage/plugin.js';
    +    return $this->getModulePath('ckeditor') . '/js/plugins/drupalimage/plugin.js';
       }
     
       /**
    @@ -51,7 +51,7 @@ public function getButtons() {
    
    @@ -51,7 +51,7 @@ public function getButtons() {
         return [
           'DrupalImage' => [
             'label' => $this->t('Image'),
    -        'image' => drupal_get_path('module', 'ckeditor') . '/js/plugins/drupalimage/icons/drupalimage.png',
    +        'image' => $this->getModulePath('ckeditor') . '/js/plugins/drupalimage/icons/drupalimage.png',
           ],
    

    These changes make me uneasy. It feels odd that all these plugins need a reference to the entire module extension list. I'm pondering if we should consider making the module paths available as container parameters. We already have the container.modules parameter. We could even only add the parameters that used so we don't have to add all module paths to the container.

  2. +++ b/core/modules/system/src/Form/ThemeSettingsForm.php
    @@ -102,7 +117,8 @@ public static function create(ContainerInterface $container) {
           $container->get('theme_handler'),
    
    @@ -307,7 +323,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme =
    -          $local_file = drupal_get_path('theme', $theme) . '/' . $default;
    +          $local_file = $this->themeList->getPath($theme) . '/' . $default;
    
    @@ -355,7 +371,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme =
    -        $theme_path = drupal_get_path('theme', $theme);
    +        $theme_path = $this->themeList->getPath($theme);
    

    We don't need the extension list theme here...

    We can do $this->themeHandler->getTheme($theme)->getPath().

    One less deprecation and less change.

  3. +++ b/core/modules/update/src/Form/UpdateManagerUpdate.php
    @@ -379,7 +395,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
    -      ->setFile(drupal_get_path('module', 'update') . '/update.manager.inc')
    +      ->setFile($this->moduleList->getPath('update') . '/update.manager.inc')
    

    Same here - this can be $this->moduleHandler->getModule('update')->getPath() and then we don't need the extension list.

berdir’s picture

1. Isn't this just making the existing dependencies explicit? Not quite sure how the container parameter thing would work exactly, would we define a parameter for every enabled module, then you'd inject %module_path.ckeditor% into your plugin? We've been discussing whether we need/want #1308152: Add stream wrappers to access .json files in extensions or not for 10 years now. That would be the alternative, then you can just write "module://ckeditor/js/plugins/drupalimage/icons/drupalimage.png". But postponing this on a 10 year old issue doesn't sound like fun.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new177.45 KB
new6.2 KB

1. Yeah, I'm not convinced that this would make things simpler. Yeah, it's quite a dependency to have, but from a performance standpoint, anything that even just invokes a hook or so is going to instantiate that anyway and the service _is_ based on the container.modules information. Accessing that directly would be quite awkward as we actually store the path to the .info.yml file, not the module directory, and you can't access something in an array directly, so you'd need to write it out: dirname($container->getParameter('container.modules'])['ckeditor']['pathname']).

And you would need to inject the whole modules array, I doubt that's any faster than injecting the service?

To allow for something like %module_list.ckeditor%, we'd need to duplicate that information in the container into a top-level parameter for every module.

Updated the two classes for 2 and 3.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

The point #300.1 has been answered by @Berdir in #301 and #302.

The points #300.2 and #300.3 from @alexpott have been fixed.

Back to RTBC.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

@Berdir what I'm suggesting is a compiler pass that would look for %module.path.ckeditor% and replace this with the correct string or set up the container param so it'll work. So we only get the necessary paths and then in order to use this service there's no cache get / state get... because it's just taking a string. In a future world maybe we could avoid caching the paths at all and rely on the container for having this info - and then only store this in state to prevent file system scans on cache clear. Given that the module list is already there this does not feel like a big stretch. However, I do think that we could punt this to a follow-up. Rather than try to achieve this here, created a follow-up #3223760: Get extension paths from container and not cache

Committed 1110b04 and pushed to 9.3.x. Thanks!

  • alexpott committed 1110b04 on 9.3.x
    Issue #2347783 by kim.pepper, andypost, almaudoh, gumanist, aleevas,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.