yiisoft / yii-core

Yii Framework 3.0 core
https://www.yiiframework.com/
433 stars 75 forks source link

Incorrect controllerPath resolving #113

Closed Insolita closed 5 years ago

Insolita commented 5 years ago

It is duplication of https://github.com/yiisoft/yii-console/issues/16

What steps will reproduce the problem?

1, Folder structure

- App
   -- Commands
       --- HelloController.php
- config
    -- common.php
    -- console.php
    -- params.php
...
- vendor
- composer.json

2, composer.json

 { 
...
 "extra": {
        "branch-alias": {
            "dev-master": "3.0.x-dev"
        },
        "config-plugin": {
            "params": ["config/params.php"],
            "common": ["config/common.php"],
            "console": [
                "$common",
                "config/console.php"
            ]
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "App",
            "Lib\\": "Lib"
        }
    },
}
...
  1. config parts

console.php

return [
    'app' => [
        'controllerNamespace' => 'App\Commands', // (Also trying with App\Commands::class)
    ],
];

common.php

return [
   'app' => [
        'basePath' => dirname(__DIR__) . '/App',
    ],
   ....
]

When i run /vendor/bin/yii hello/index - all correct, it works

When i run /vendor/bin/yii help - gotcha error

Error: Invalid path alias: @/App/Commands

Also if i add in my HelloController@actionIndex print app->controllerPath, error also reproduced

public function actionIndex(): int
    {
        $this->stdout('Hello, Yii3'.PHP_EOL, Console::FG_PURPLE); //It`s normal
        // With this line  error reproduced
        $this->stdout($this->app->controllerPath.PHP_EOL, Console::FG_PURPLE);

        return ExitCode::OK;
    }

What is the expected result?

alias should be '@App/Commands'

What do you get instead?

Error: Invalid path alias: @/App/Commands

Additional info

Q A
Yii version 3.0.? -latest dev-master
PHP version 7.3
Operating system ArchLinux

Solution

It can be fixed in

https://github.com/yiisoft/yii-core/blob/e7dd2905e25976a3109a2d4b831694968f63cea6/src/base/Module.php#L271

by adding trim for leading slash in controllerNamespace

public function getControllerPath()
    {
        $path = ltrim(str_replace('\\', '/', $this->controllerNamespace),'/');
        return $this->app->getAlias('@' .$path);
    }

Or some deeper in findAlias https://github.com/yiisoft/yii-core/blob/master/src/base/Aliases.php#L172 aliases

machour commented 5 years ago

@Insolita I just tried with a setup similar to yours without problems. Are you still running into this issue?

Insolita commented 5 years ago

when i change composer depends on, all ok

  "yiisoft/yii-base-cli": "^3.0",
  "yiisoft/yii-base-api": "^3.0",

in previous it was "^3.0@dev"; now it has another fail

machour commented 5 years ago

Can you upload the failing project in a repository? It would make it easier to reproduce the problem.

Insolita commented 5 years ago

@machour it was absolutely clean, with composer.json

{
    "name": "yii3/app",
    "description": "Yii3 test app",
    "type": "project",
    "require": {
        "yiisoft/yii-base-cli": "^3.0@dev",
        "yiisoft/yii-base-api": "^3.0@dev",
        "abraham/twitteroauth": "^0.9.2"
    },
    "license": "MIT",
    "authors": [
        {
            "name": "insolita",
            "email": "xxx@dev.ru"
        }
    ],
    "minimum-stability": "dev",
    "extra": {
        "branch-alias": {
            "dev-master": "3.0.x-dev"
        },
        "config-plugin": {
            "params": ["config/params.php"],
            "common": ["config/common.php"],
            "console": [
                "$common",
                "config/console.php"
            ]
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "App",
            "Lib\\": "Lib"
        }
    },
    "autoload-dev": {
        "psr-4": {"App\\tests\\": "tests"}
    },
    "config": {
        "process-timeout": 1800
    }
}

and common config is

<?php
return [
    'app' => [
        'basePath' => dirname(__DIR__) . '/App',
        'aliases'=>array_merge($aliases, [
            '@Lib'=>dirname(__DIR__) . '/Lib',
        ]),
        'language'=>'ru',
        /*
        'controllerMap' => [
            'fixture' => [ // Fixture generation command line.
                '__class' => 'yii\faker\FixtureController',
            ],
        ],
        */
    ],
    'logger' => [
        '__construct()' => [
            'targets' => [
                [
                    '__class' => yii\log\FileTarget::class,
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
    ],
    'cache' => [
        '__class' => yii\cache\Cache::class,
        'handler' => [
            '__class' => yii\cache\FileCache::class,
            'keyPrefix' => $params['app.id'],
        ],
    ],
    'db' => array_filter([
        '__class' => yii\db\Connection::class,
        'dsn' => $params['db.dsn'],
        'username' => $params['db.username'],
        'password' => $params['db.password'],
        'enableSchemaCache' => defined('YII_ENV') && YII_ENV !== 'dev',
    ]),
];

And one console HelloController decribed in first topic. I wanted to look yii3 with minimal abilities only, without concrete tasks

samdark commented 5 years ago

Not an issue anymore since console implementation is now different.