composer и PSR-4 autoload с указанием массива. Не работает :( UPD: вроде разобрались

Предварительное обсуждение найденных ошибок перед отправкой их авторам фреймворка, а также внесение новых предложений.
Ответить
Аватара пользователя
GeX
Сообщения: 52
Зарегистрирован: 2013.01.22, 09:10

composer и PSR-4 autoload с указанием массива. Не работает :( UPD: вроде разобрались

Сообщение GeX »

Не знаю описывалась ли эта проблема или нет, возможно и да, если да - ткните носом, однако...

Решил сделать в экстеншене в autoload конструкцию наподобии

Код: Выделить всё

"autoload": {
        "psr-4": {
            "g\\": ["test/", "libraries/"],
            "gecon\\": ""
        }
}
Как это описано в https://getcomposer.org/doc/04-schema.md#psr-4

Сделал, запустил, а оно мне рожает ошибку:

Код: Выделить всё

[ErrorException]
  substr() expects parameter 1 to be string, array given
Включаю вербозу:

Код: Выделить всё

Exception trace:
 () at phar:///usr/local/bin/composer/src/Composer/Util/Filesystem.php:392
 Composer\Util\ErrorHandler::handle() at n/a:n/a
 substr() at phar:///usr/local/bin/composer/src/Composer/Util/Filesystem.php:392
 Composer\Util\Filesystem->isAbsolutePath() at /server/webroot/xp/orion-pax-2-admin/application/vendor/yiisoft/yii2-composer/Installer.php:125
 yii\composer\Installer->generateDefaultAlias() at /server/webroot/xp/orion-pax-2-admin/application/vendor/yiisoft/yii2-composer/Installer.php:85
 yii\composer\Installer->addPackage() at /server/webroot/xp/orion-pax-2-admin/application/vendor/yiisoft/yii2-composer/Installer.php:42
 yii\composer\Installer->install() at phar:///usr/local/bin/composer/src/Composer/Installer/InstallationManager.php:152
 Composer\Installer\InstallationManager->install() at phar:///usr/local/bin/composer/src/Composer/Installer/InstallationManager.php:139
 Composer\Installer\InstallationManager->execute() at phar:///usr/local/bin/composer/src/Composer/Installer.php:572
 Composer\Installer->doInstall() at phar:///usr/local/bin/composer/src/Composer/Installer.php:222
 Composer\Installer->run() at phar:///usr/local/bin/composer/src/Composer/Command/UpdateCommand.php:130
 Composer\Command\UpdateCommand->execute() at phar:///usr/local/bin/composer/vendor/symfony/console/Symfony/Component/Console/Command/Command.php:252
 Symfony\Component\Console\Command\Command->run() at phar:///usr/local/bin/composer/vendor/symfony/console/Symfony/Component/Console/Application.php:874
 Symfony\Component\Console\Application->doRunCommand() at phar:///usr/local/bin/composer/vendor/symfony/console/Symfony/Component/Console/Application.php:195
 Symfony\Component\Console\Application->doRun() at phar:///usr/local/bin/composer/src/Composer/Console/Application.php:146
 Composer\Console\Application->doRun() at phar:///usr/local/bin/composer/vendor/symfony/console/Symfony/Component/Console/Application.php:126
 Symfony\Component\Console\Application->run() at phar:///usr/local/bin/composer/src/Composer/Console/Application.php:83
 Composer\Console\Application->run() at phar:///usr/local/bin/composer/bin/composer:43
 require() at /usr/local/bin/composer:24
Причина ошибки найдена:

Код: Выделить всё

Composer\Util\Filesystem->isAbsolutePath() at /server/webroot/xp/orion-pax-2-admin/application/vendor/yiisoft/yii2-composer/Installer.php:125
Поправляю код, делаю костыль if(is_array($path)) { и дальше обработка $path как массива по аналогии с тем кодом что был:

Код: Выделить всё

            foreach ($autoload['psr-4'] as $name => $path) {
                if(is_array($path)) {
                    foreach($path as $pathSingle) {
                        $name = str_replace('\\', '/', trim($name, '\\'));
                        if (!$fs->isAbsolutePath($pathSingle)) {
                            $pathSingle = $this->vendorDir . '/' . $package->getPrettyName() . '/' . $pathSingle;
                        }
                        $pathSingle = $fs->normalizePath($pathSingle);
                        if (strpos($pathSingle . '/', $vendorDir . '/') === 0) {
                            $aliases["@$name"] = '<vendor-dir>' . substr($pathSingle, strlen($vendorDir));
                        } else {
                            $aliases["@$name"] = $pathSingle;
                        }
                    }
                } else {
                    $name = str_replace('\\', '/', trim($name, '\\'));
                    if (!$fs->isAbsolutePath($path)) {
                        $path = $this->vendorDir . '/' . $package->getPrettyName() . '/' . $path;
                    }
                    $path = $fs->normalizePath($path);
                    if (strpos($path . '/', $vendorDir . '/') === 0) {
                        $aliases["@$name"] = '<vendor-dir>' . substr($path, strlen($vendorDir));
                    } else {
                        $aliases["@$name"] = $path;
                    }
                }
            }
Ошибка пропадает, но не работает. Делаю:

Код: Выделить всё

print_r($aliases);
return $aliases;
И получаю:

Код: Выделить всё

Array
(
    [@g] => <vendor-dir>/gex/yii2-gecon/libraries
    [@gecon] => <vendor-dir>/gex/yii2-gecon
)
Я так понимаю дальше это всё дело идёт в генератор алиасов и, насколько я понимаю, Yii не умеет так чтобы одному алиасу соответствовало несколько путей, я правильно понимаю? То есть выходит что конструкцию вида:

Код: Выделить всё

{
    "autoload": {
        "psr-4": { "Monolog\\": ["src/", "lib/"] }
    }
}
как это описано в мануале Composer сделать попросту невозможно. Правильно ли я понимаю и есть ли способ это исправить?
Последний раз редактировалось GeX 2015.01.13, 00:42, всего редактировалось 1 раз.
lynicidn
Сообщения: 2222
Зарегистрирован: 2014.05.24, 15:12

Re: composer и PSR-4 autoload с указанием массива. Не работает :(

Сообщение lynicidn »

даже ваш костыль не решает проблемы, т.к. ваш алиас все равно зависит от окружения
Аватара пользователя
GeX
Сообщения: 52
Зарегистрирован: 2013.01.22, 09:10

Re: composer и PSR-4 autoload с указанием массива. Не работает :(

Сообщение GeX »

Основной вопрос - умеет ли Yii несколько путей на одном алиасе? Если да - можно править дальше, если нет - просто констатировать невозможность и не парить себе мозг. Я полагаю что не умеет :( Или таки умеет?
lynicidn
Сообщения: 2222
Зарегистрирован: 2014.05.24, 15:12

Re: composer и PSR-4 autoload с указанием массива. Не работает :(

Сообщение lynicidn »

как вы себе это представляете?
Аватара пользователя
GeX
Сообщения: 52
Зарегистрирован: 2013.01.22, 09:10

Re: composer и PSR-4 autoload с указанием массива. Не работает :(

Сообщение GeX »

'@alias' => ['path/to/folder1', 'path/to/folder2'] ... как-то так... но выходит что это невозможно - у Yii::setAlias второй параметр только строка, массив не поддерживается :(

UPD: Хехе, не работает только если тип yii-extension. Если поставить тип library всё работает. Интересно девки пляшут :) Ну мне пока Library и надо, будет надо что-то другое - будем разбираться :) Кто-то может объяснить разницу между yii-extension и library? Ну или ткнуть носом в мануал. Чего не может либа что может расширение?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: composer и PSR-4 autoload с указанием массива. Не работает :(

Сообщение zelenin »

GeX писал(а):'@alias' => ['path/to/folder1', 'path/to/folder2'] ... как-то так... но выходит что это невозможно - у Yii::setAlias второй параметр только строка, массив не поддерживается :(

UPD: Хехе, не работает только если тип yii-extension. Если поставить тип library всё работает. Интересно девки пляшут :) Ну мне пока Library и надо, будет надо что-то другое - будем разбираться :) Кто-то может объяснить разницу между yii-extension и library? Ну или ткнуть носом в мануал. Чего не может либа что может расширение?
для этого типа специально создан yii2-composer, который например yii-extension добавляет в extensions.php.
Ответить