Search code examples
phpwordpresscomposer-phpautoloadpsr-4

Need Help in autoloading classes with psr-4 standard


I have the following file structure

- esimowl-mobimatter
- - src
- - - Esimowl
- - - - Mobimatter
- - - - - Product.php
- - composer.json
- - esimowl-mobimatter.php

my composer.json file have the following content

{
    "name": "esimowl/mobimatter",
    "description": "An awesome plugin created by Esimowl",
    "type": "wordpress-plugin",
    "autoload": {
        "psr-4": {
            "Esimowl\\Mobimatter\\": "./src/" 
        }
    }
}

Please note i have tried "Esimowl\\Mobimatter\\": "src/" in my composer.json

When I run composer dumpautoload -o i got the following error

Class Esimowl\Mobimatter\Product located in ./src/Esimowl/Mobimatter/Product.php does not comply with psr-4 autoloading standard. Skipping.

What could Have I done wrong?

By the way Product.php just have the following content

<?php

namespace Esimowl\Mobimatter;

class Product {
    public function __construct() {
        if (is_admin()) {
            echo 'Tshi is admin';
        }
    }
}

and esimowl-mobimatter.php just have

<?php
/**
 * Plugin Name: Esimowl MobiMatter Integration
 * Plugin URI: https://jameshwartlopez.com
 * Description: Toolkit for integrating to Mobimatter api 
 * Version: 1.0.0
 * Author: Jameshwart
 * Author URI: https://jameshwartlopez.com
 * Text Domain: esimowl
 * Requires at least: 6.2
 * Requires PHP: 7.3
 *
 * @package Esimowl
 */

 defined('ABSPATH') || exit;

 define('ESIMOW_MOBIMATTER_PLUGIN_DIR', plugin_dir_path(__FILE__));
 
 require ESIMOW_MOBIMATTER_PLUGIN_DIR . 'vendor/autoload.php';

Solution

  • As per the documentation, the psr-4 value:

    [defines] a mapping from namespaces to paths, relative to the package root

    What this means is that the key is the base namespace, and the value the path where that namespace should be found; any sub-directories in that path define sub-packages of that namespace. So, the "canonical" namespace for your Product class would actually be:

    Esimowl\Mobimatter\Esimowl\Mobimatter\Product
    

    Now, obviously that's ridiculous, so you can change your configuration to match what you have on disk, changing the specification to one of:

    "Esimowl\\Mobimatter\\": "src/Esimowl/Mobimatter"
    
    "Esimowl\\": "src/Esimowl"
    

    or simply:

    "": "src"
    

    This last option is specifically called out in the same documentation as:

    a fallback directory where any namespace will be looked for

    Otherwise you can change the directory structure such that Product.php is located at:

    ./src/Product.php
    

    to match your original PSR-4 specification.