Use Composer $COMPOSER_VENDOR_DIR in autoload filepath - symfony

I am using Symfony for a Dockerized app. I need to move my composer vendors directory, so I did set the environnement variable $COMPOSER_VENDOR_DIR to /root/app-vendors.
The vendors are correctly located to this directory, but it causes troubles with the Symfony VarDump component. By default in Symfony 2, it is loaded from composer like this:
"autoload-dev": {
"files": [
"vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
}
In my case, this path becomes wrong. I'd like to do something like this:
"autoload-dev": {
"files": [
"{$COMPOSER_VENDOR_DIR}/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
},
But I don't see anything in the composer documentation about using env variables in a composer.json filepath.
I want to move the vendors in dev mode, but I want them to be in the default location if $COMPOSER_VENDOR_DIR is not set ; so I cannot put absolute filepath in autoload-dev section like this:
"autoload-dev": {
"files": [
"/root/app-vendors/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
},

A simple solution after a few days of step back:
Create this file on app/dump.php
<?php
$vendorsDir = getenv('COMPOSER_VENDOR_DIR')
?: __DIR__.'/../vendor';
require "$vendorsDir/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php";
Then autoload this file instead of the Symfony one
"autoload-dev": {
"files": [
"app/dump.php"
]
},
Note:
COMPOSER_VENDOR_DIR default is "vendor", see https://getcomposer.org/doc/03-cli.md#composer-vendor-dir

Related

Symfony 3.4 : generate bundle : ClassNotFoundException: Attempted to load class "MyVendorFOSUserBundle" from namespace "MyVendorFOSUserBundle"

Hello every body I'm doing inheritance from FOSUserBundle to override some controllers, but At first step when I was creating a simple bundle I found an issue:
bin/console genrate:bundle
Are you planning on sharing this bundle across multiple applications? [no]:
Bundle name: MyVendorFOSUserBundle
Target Directory [src/]: src/MyVendor/
Configuration format (annotation, yml, xml, php) [annotation]:
Bundle generation
> Generating a sample bundle skeleton into app/../src/MyVendor/MyVendorFOSUserBundle
created ./app/../src/MyVendor/MyVendorFOSUserBundle/
created ./app/../src/MyVendor/MyVendorFOSUserBundle/MyVendorFOSUserBundle.php
created ./app/../src/MyVendor/MyVendorFOSUserBundle/Controller/
created ./app/../src/MyVendor/MyVendorFOSUserBundle/Controller/DefaultController.php
created ./app/../tests/MyVendorFOSUserBundle/Controller/
created ./app/../tests/MyVendorFOSUserBundle/Controller/DefaultControllerTest.php
created ./app/../src/MyVendor/MyVendorFOSUserBundle/Resources/views/Default/
created ./app/../src/MyVendor/MyVendorFOSUserBundle/Resources/views/Default/index.html.twig
created ./app/../src/MyVendor/MyVendorFOSUserBundle/Resources/config/
created ./app/../src/MyVendor/MyVendorFOSUserBundle/Resources/config/services.yml
> Checking that the bundle is autoloaded
FAILED
> Enabling the bundle inside app/AppKernel.php
updated ./app/AppKernel.php
OK
> Importing the bundle's routes from the app/config/routing.yml file
updated ./app/config/routing.yml
OK
> Importing the bundle's services.yml from the app/config/config.yml file
updated ./app/config/config.yml
OK
The command was not able to configure everything automatically.
You'll need to make the following changes manually.
- Edit the composer.json file and register the bundle
namespace in the "autoload" section:
At first solution I tried to modify composer.json :*
"autoload": {
"psr-4": {
"": "src/" //modif
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
Does someone have any idea about that
Open composer.json file.
Change this:
"autoload": { "psr-4": { "AppBundle\\": "src/AppBundle" },
to:
"autoload": { "psr-4": { "": "src/" },
Run this command: composer dumpautoload Now composer will generate new autoload.php file
Run command: php bin/console server:run everything works file.
Finally, I found the solution:
"autoload": {
"psr-4": {
"AppBundle\\": "src/AppBundle",
"MyVendorFOSUserBundle\\": "src/MyVendor/MyVendorFOSUserBundle" //Line added
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
Don't forget to run:
composer dumpautoload

Symfony Generate new Bundle Failed to auto update autoload

I use Symfony Version 2.8. I get the following error when generating a new bundle.
I generate a new bundle using this command:
php bin/console generate:bundle --namespace=FrontBundle --no-interaction
Then the console show me this results
Bundle generation
Generating a sample bundle skeleton into C:\xampp\htdocs\TRC\app/../src/FrontBundle
created .\app/../src/FrontBundle/
created .\app/../src/FrontBundle/FrontBundle.php
created .\app/../src/FrontBundle/Controller/
created .\app/../src/FrontBundle/Controller/DefaultController.php
created .\app/../tests/FrontBundle/Controller/
created .\app/../tests/FrontBundle/Controller/DefaultControllerTest.php
created .\app/../src/FrontBundle/Resources/views/Default/
created .\app/../src/FrontBundle/Resources/views/Default/index.html.twig
created .\app/../src/FrontBundle/Resources/config/
created .\app/../src/FrontBundle/Resources/config/services.yml
Checking that the bundle is autoloaded
FAILED
Enabling the bundle inside C:\xampp\htdocs\TRC\app\AppKernel.php
updated .\app\AppKernel.php
OK
Importing the bundle's routes from the C:\xampp\htdocs\TRC\app\config\routing.yml file
updated .\app/config/routing.yml
OK
Importing the bundle's services.yml from the C:\xampp\htdocs\TRC\app\config\config.yml file
updated .\app/config/config.yml
OK
The command was not able to configure everything automatically.
You'll need to make the following changes manually.
Edit the composer.json file and register the bundle
namespace in the "autoload" section:
Process finished with exit code 0 at 17:19:48.
Execution time: 719 ms.
Then I add a line to Composer.Json in autoload section:
#...
"autoload": {
"psr-4": {
"AppBundle\\": "src/AppBundle",
"FrontBundle\\": "src/FrontBundle"
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
"autoload-dev": {
"files": [
"vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
},
#.........
Finally, I use again the console to dump-autoload and when I refresh the page I get the same error.
I have tried to clear cache and force browser to refresh.
"psr-4": {
"AppBundle\\": "src/AppBundle",
"FrontBundle\\": "src/FrontBundle"
},
Or better:
"psr-4": {
"": "src/"
}

Do I need to append every generated bundle to composer.json manually?

I've started to learn Symfony and I am following some tutorials where there is nothing about this:
When I create a new project with symfony installer and run composer install and then php app/console server:start I can open that project in my browser.
BUT! When I create a new bundle with command php app/console generate:bundle I get this error message:
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "BlogBundle" from namespace "BlogBundle".
Did you forget a "use" statement for another namespace? in /home/user/Symfony/myapp/app/AppKernel.php:19
And then I need to go to my composer.json file and append my new generated bundle after AppBundle like this
{
"name": "user/myapp",
"license": "proprietary",
"type": "project",
"autoload": {
"psr-4": {
"AppBundle\\": "src/AppBundle",
"BlogBundle\\": "src/BlogBundle" // <-- this is the new appended one
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
..........
And then when I try to start the server again it works and it shows Hello world in my browser.
So the question is do I have to do this every time (append new generated bundle in composer.json file)?
Yes. This is the reason, why you usually have an namespace above that. Some abbreviation of your name or company for example. This way you only add that namespace for the src folder and all bundles are "found" automatically.
Example:
{
...
"autoload": {
"psr-4": {
"Acme\\": "src"
},
}
...
}
Now of course your bundles need to use that namespace, eg.:
namespace Acme\BlogBundle;
class BlogBundle {
}

use PHPExcel with composer and Symfony2.2

I found this on SO: How to use PHPExcel correctly with Symfony 2
This works, but I want to use it with composer.
The first part I already solved: to load PHPExcel for a special tag (the last stable release)
I don't find out how to fetch a tag with this syntax:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/umpirsky/SyliusAssortmentBundle"
}
]
So I use the Package notation:
I found out, the reference should be the tag name on github.
And the version cannot be the same value (PHPExcel_1.7.8). Seems that alphabetical characters are not allowed, so it's only the version as a number (1.7.8)
"repositories": [{
"type": "package",
"package": {
"name": "PHPOffice/PHPExcel",
"version": "1.7.8",
"source": {
"url": "https://github.com/PHPOffice/PHPExcel.git",
"type": "git",
"reference": "PHPExcel_1.7.8"
}
}
}]
The next step I didn't solve. I tried out every combination for the autoloading: psr-0, classmap, different paths, relative to project/vendor/phpexcel, update composer everytime, but nothing worked.
It only works, if I put this line
$loader->add('PHPExcel', __DIR__.'/../vendor/PHPOffice/PHPExcel/Classes');
into the app/autoload.php. I found out, that the first string (PHPExcel) can also be an empty string: ''.
Is there a differnece if I use PHPExcel or ''?
So my primary question is, how can I avoid to write this line into the autoload.php, put the equivalent commands into my project's composer.json?
Regarding your primary question, the problem is that once the package is installed, if you update the definition and add autoload stuff, then running composer update will not change anything. Composer still has the old package that was already installed in its "cache", so it uses that to generate the autoload and that fails.
To resolve this you should remove the vendor/PHPOffice/PHPExcel directly and run composer update, which will reinstall it with the latest information from your composer.json, including autoload, etc. You should specify autoloading as such:
"repositories": [{
"type": "package",
"package": {
"name": "PHPOffice/PHPExcel",
"version": "1.8.0",
"source": {
"url": "https://github.com/PHPOffice/PHPExcel.git",
"type": "git",
"reference": "1.8.0"
},
"autoload": {
"psr-0": {
"PHPExcel": "Classes/"
}
}
}
}],
"require": {
"PHPOffice/PHPExcel": "1.8.*",
...
Regarding the secondary question and '' vs 'PHPExcel': '' just says that any namespace can be found in this directory. That means the autoloader will always scan this directory to find classes, which is convenient but slower than mapping namespaces to directories explicitly. So both work, but the more specific form is preferred, especially in packages you publish publicly.

Wrap PHPWord on bundle

I just want to use PHPWord for Symfony 2. But Im new on Symfony 2.
I paste PHPWord source into my util folder bundle but there is an error loading autoloader class from PHPWord...
Question is simple, How can I "wrap" code (in this case PHPWord) in to bundle? or someway I can use it.
Any solution?
Thanks for answering, that gives me some light. Altough, This doen't work for me.
I download composer.phar and I edit my composer.json as you say: adding in my require region "phpword/phpword": "0.6.2" and creating new repository phpword...
Doesn't work, I run "php composer.phar" command but It doesn't download anything...
Any tutorial or tip to make this work?
Thank you
composer require phpoffice/phpword dev-master did the work for me.
It should download and place install PhpOffice\PHPWord under the vendor folder in your Symfony2 installation (besides modifying your composer.json automatically).
In the controller you are about to use PhpWord:
use PhpOffice\PhpWord\PhpWord;
And inside the action, you can create a new instance as follows:
$doc = new PhpWord();
You shouldn't be copying the source code yourself. Use composer to install PHPWord.
Since PHPWord doesn't use composer (yet), you'll need to define a repository in your composer.json:
{
"require": {
"phpword/phpword": "0.6.2"
},
"repositories": [
{
"type": "package",
"package": {
"name": "phpword/phpword",
"version": "0.6.2",
"dist": {
"url": "http://download-codeplex.sec.s-msft.com/Download/Release?ProjectName=phpword&DownloadId=138035&FileTime=129545976016270000&Build=19692",
"type": "zip"
},
"autoload": {
"classmap": ["."]
}
}
}
]
}
Than you'll be able to use PHPWord in your Symfony project (any PHP project in fact):
$word = new PHPWord();
$writer = new PHPWord_Writer_Word2007($word);
$writer->save('test.doc');
Update: I just realized the URL to download changes with time. It'd be better to replace it with something that doesn't change (if possible, otherwise host it somewhere yourself).
As the URL changes, you can use the github repository if you've no problem with the dev version :
{
"require": {
"phpword/phpword": "dev"
},
"repositories": [
{
"type": "package",
"package": {
"name": "phpword/phpword",
"version": "dev",
"dist": {
"url": "https://github.com/PHPOffice/PHPWord/archive/develop.zip",
"type": "zip"
},
"autoload": {
"classmap": ["."]
}
}
}
]
}
You can use this simple bundle as wrapper for PhpWord:
https://packagist.org/packages/ggggino/wordbundle

Resources