bjori / mongo-php-transistor

A trait to save and load your objects in MongoDB
BSD 2-Clause "Simplified" License
28 stars 3 forks source link

Cannot load the trait #5

Closed gquemener closed 8 years ago

gquemener commented 8 years ago

Hello,

I've been struggling for the past hour trying to use the trait provided by your library...

Here's my document:

<?php

namespace App\Document;

use App\Model;
use MongoDB\Transistor;
use MongoDB\BSON\Persistable;

class Card extends Model\Card implements Persistable
{
    use MongoDB\Transistor;
    protected $_id;
}

And here's the error I don't know how to fix: "Attempted to load trait "Transistor" from namespace "App\Document\MongoDB".Did you forget a "use" statement for "MongoDB\Transistor"?"

I've tried adding a \ before the trait name (use \MongoDB\Transistor) but then I get the following error: "Attempted to load trait "Transistor" from namespace "MongoDB".Did you forget a "use" statement for "MongoDB\Transistor"?"

I'm suspecting an autoloading problem, but I can't find where it is. Here's my composer.json in case of it can help:

{
    "name": "symfony/framework-standard-edition",
    "license": "MIT",
    "type": "project",
    "description": "The \"Symfony Standard Edition\" distribution",
    "autoload": {
        "psr-4": { "": "src/" },
        "classmap": [ "app/AppKernel.php", "app/AppCache.php" ]
    },
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.0.*",
        "symfony/monolog-bundle": "^2.8",
        "sensio/distribution-bundle": "^5.0",
        "sensio/framework-extra-bundle": "^3.0.2",
        "incenteev/composer-parameter-handler": "^2.0",
        "mongodb/mongodb": "^1.0.0",
        "mongodb/transistor": "dev-master@dev"
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0",
        "symfony/phpunit-bridge": "^2.7",
        "phpspec/phpspec": "^2.4"
    },
    "scripts": {
        "post-install-cmd": [
            "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
        ],
        "post-update-cmd": [
            "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
        ]
    },
    "extra": {
        "symfony-app-dir": "app",
        "symfony-bin-dir": "bin",
        "symfony-var-dir": "var",
        "symfony-web-dir": "web",
        "symfony-tests-dir": "tests",
        "symfony-assets-install": "relative",
        "incenteev-parameters": {
            "file": "app/config/parameters.yml"
        },
        "branch-alias": {
            "dev-master": "3.0-dev"
        }
    }
}
renanbr commented 8 years ago

this is not my project, but I think you should try with use Transistor; because its full name was already define at the top of the file

Never mind, my bad :-) I use composer dump-autoload -o, so I didn't get this problem

@bjori was receptive to PRs

bjori commented 8 years ago

I've honestly no idea. Not a composer user actually. I can't even get that composer.json you pasted to do anything meaningful. It either fails with

Script Incenteev\ParameterHandler\ScriptHandler::buildParameters handling the post-install-cmd event terminated with an exception

or

Could not scan for classes inside "app/AppKernel.php" which does not appear to be a file nor a folder

One thing I notice is that the mongo-php-library doesn't have "src/MongoDB" folder, only "src/". Meaning the "MongoDB\Client" class is in "src/Client.php" -- while the transistor interface is "src/MongoDB/Transistor.php"

renanbr commented 8 years ago

@gquemener, you are right, the problem is the "autoload" entry in the composer.json file.

It's related to the what you @bjori noticed.

I saw some alternatives to fix it. I'm sharing my experiment with you all.

Run composer create-project mongodb/transistor:dev-master /tmp/autoload-fix

If you run the file below, you'll get the error…

<?php
require '/tmp/autoload-fix/vendor/autoload.php';
class Tmp { use MongoDB\Transistor; }
new Tmp;

Then change the autoload entry into /tmp/autoload-fix/composer.json to one the of these values:

"autoload": {
    "psr-4": {
        "": "src/"
    }
}

or

"autoload": {
    "psr-4": {
        "MongoDB\\": "src/MongoDB/"
    }
}

or

"autoload": {
    "classmap": ["src/MongoDB/Transistor.php"]
}

or

"autoload": {
    "psr-0": {
        "MongoDB\\": "src/"
    }
}

Then run:

composer dump-autoload -d /tmp/autoload-fix

If you run the php file again, the error disappears :pray: I hope

https://getcomposer.org/doc/04-schema.md#autoload

jmikola commented 8 years ago

@bjori: Confirming that "psr-4": { "MongoDB\\": "src/" } should resolve this, as @renanbr suggested. We have the same in the PHP library. Your current composer.json autoload definition has "src\/", but you probably shouldn't be escaping that forward slash.

Additionally, you should be able to remove the MongoDB/ directory from the src/ path in the repository.

bjori commented 8 years ago

Thanks @renanbr and @jmikola !

@gquemener I've move the Transistor.php file into more conventional location so your standard composer autoloaders should work fine now.

Thanks for the report! :D

gquemener commented 8 years ago

:+1: Great news!

I'll give it a try when I got time this week (I hope).

Cheers