Roots Discourse

Composer autoload not working for classes in theme folder

Hello guys,

I am on bedrock, I tried to implement the ps4 namespacing for autoloading classes in a theme subfolder, like my-theme/includes with all my classes inside. I placed the ps4 directions in the main composer.json under src/. I also tried to create a theme specific composer, without success.

What am I ignoring?

Thanks in advance.

Can you show us your actual code please?

1 Like

Which one? In composer.json?

composer.json, file paths, the namespacing in the classes you’re trying to load, etc

1 Like

So here it is src/composer.json:

{
  "name": "roots/bedrock",
  "type": "project",
  "license": "MIT",
  "description": "WordPress boilerplate with modern development tools, easier configuration, and an improved folder structure",
  "homepage": "https://roots.io/bedrock/",
  "authors": [
    {
      "name": "Scott Walkinshaw",
      "email": "scott.walkinshaw@gmail.com",
      "homepage": "https://github.com/swalkinshaw"
    },
    {
      "name": "Ben Word",
      "email": "ben@benword.com",
      "homepage": "https://github.com/retlehs"
    }
  ],
  "keywords": [
    "bedrock", "composer", "roots", "wordpress", "wp", "wp-config"
  ],
  "support": {
    "issues": "https://github.com/roots/bedrock/issues",
    "forum": "https://discourse.roots.io/category/bedrock"
  },
  "repositories": [
    {
      "type": "composer",
      "url": "https://wpackagist.org",
      "only": ["wpackagist-plugin/*", "wpackagist-theme/*"]
    }
  ],
  "require": {
    "php": ">=7.1",
    "composer/installers": "^1.8",
    "vlucas/phpdotenv": "^4.1.8",
    "oscarotero/env": "^2.1",
    "roots/bedrock-autoloader": "^1.0",
    "roots/wordpress": "^5.8.0",
    "roots/wp-config": "1.0.0",
    "roots/wp-password-bcrypt": "1.0.0",
    "wpackagist-plugin/duplicate-page": "^4.4",
    "wpackagist-plugin/wordpress-importer": "^0.7.0"
  },
  "require-dev": {
    "squizlabs/php_codesniffer": "^3.5.6",
    "roave/security-advisories": "dev-master"
  },
  "config": {
    "optimize-autoloader": true,
    "preferred-install": "dist"
  },
  "minimum-stability": "dev",
  "prefer-stable": true,
  "extra": {
    "installer-paths": {
      "web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"],
      "web/app/plugins/{$name}/": ["type:wordpress-plugin"],
      "web/app/themes/{$name}/": ["type:wordpress-theme"]
    },
    "wordpress-install-dir": "web/wp"
  },
  "scripts": {
    "post-root-package-install": [
      "php -r \"copy('.env.example', '.env');\""
    ],
    "test": [
      "phpcs"
    ]
  },
"autoload": {
    "psr-4": {
      "App\\mytheme\\includes\\": "app/themes/mytheme/includes",
      "App\\mytheme\\includes\\utils\\": "app/themes/mytheme/includes/utils",
      "App\\mytheme\\includes\\types\\": "app/themes/mytheme/includes/types",
      "App\\mytheme\\includes\\controllers\\": "app/themes/mytheme/includes/controllers"
    }
  }
}

I think the first should be enough, but I tried also sub folders.
In each of my classes the namespace looks like this:

namespace App\mytheme\includes\utils;

// example for src/app/themes/mytheme/includes/utils/Array_Utils.php
class Array_Utils
{...}
"autoload": {
    "psr-4": {
      "App\\mytheme\\includes\\": "app/themes/mytheme/includes",
      "App\\mytheme\\includes\\utils\\": "app/themes/mytheme/includes/utils",
      "App\\mytheme\\includes\\types\\": "app/themes/mytheme/includes/types",
      "App\\mytheme\\includes\\controllers\\": "app/themes/mytheme/includes/controllers"
    }
  }

These paths are incorrect. Look at the other paths defined here, i.e.:

    "installer-paths": {
      "web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"],

You’ve also made it more complex than necessary. The following should work:

"autoload": {
    "psr-4": {
      "App\\mytheme\\includes\\": "web/app/themes/mytheme/includes"
    }
  }

Also keep in mind that composer needs to generate autoload maps in order for changes to autoloading to work, so always run composer dump-autoload after you make changes to autoloading.

Finally, why are you loading theme files at the bedrock level? A Sage theme can autoload files with its own composer.json. If you want whatever is in these files at a higher level than the theme, then that feels like it should be a plugin or composer package, not some weird deep dependency on a theme.

1 Like

Aaaaa ah! Great help! Jeez it’s time for the weekend, for me…

About the rest, I didn’t consider to move to Sage yet since it’s just an old react app which I want to serve with WP APIs, quick and dirty. But you are right, I’ll implement the composer at theme level.

Thank you for now.

2 Likes