Symfony 4 without top level namespace - symfony

I want to migrate a Silex project to Symfony 4. I'm working on the skeleton first so I executed:
composer create-project symfony/skeleton myProject
and then required the bundles with composer require bundle for each one.
One of them needs some configuration to be installed, so I added a file config/packages/custom_bundle.yaml with such configuration.
custom_bundle.yaml needs a custom user provider service which I copied from the Silex project to the same namespace (Security) with the same name (UserProvider.php) so I created a service at config/services.yaml:
security.users_provider:
class: Security\UserProvider
Then I tried to require the bundle again and I get this error:
The autoloader expected class "App\Security\UserProvider" to be defined in file "/vagrant/myProject/vendor/composer/../../src/Security/UserProvider.php".
The file was found but the class was not in it, the class name or namespace probably has a typo in /vagrant/myProject/config/services.yaml (which is loaded in resource "/vagrant/myProject/config/services.yaml").
Of course, I have to tell composer to load classes from non-top-level-namespace so I replaced:
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
in composer.json with:
"autoload": {
"psr-4": {
"": "src/"
}
},
But now I get this error because the Kernel.php namespace is App:
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "Kernel" from namespace "App".
I have the entire Silex project without top-level-namespace, so adding App or whatever as top-level-namespace would mean renaming the whole project classes.
By other hand, removing the App namespace of Kernel.php would mean using this class as global, which might won't be a good idea.
Any workaround to avoid rewriting all classes namespaces?
PS: I also tried with:
"autoload": {
"psr-4": {
"App\\": "src/",
"": "src/",
}
},
but same happens.
Edit:
The problem was the default definition of services:
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
As I don't have the App namespace I've had to comment it by now. Later I'll have to add any services to be auto-defined with their namespaces. E.g.
Service\:
resource: '../src/Service/*'
So it works with commenting the default App services definition and adding:
"autoload": {
"psr-4": {
"App\\": "src/",
"Secutiry\\": "src/Secutiry/",
}
},
and any other namespaces to composer.json. Thanks #Cerad for the tips.
Edit2:
Even works with:
"autoload": {
"psr-4": {
"App\\": "src/",
"": "src/"
}
},

Related

Doctrine annotations are not loaded during execution of Behat context

I use Symfony 2.8 and Behat 3.3. I have standard FeatureContext class in project_root/features/bootstrap directory. Before scenario execution I want purge DB like that:
/**
* #BeforeScenario
*/
public function beforeScenario()
{
// use Doctrine\Common\DataFixtures\Purger\ORMPurger
$purger = new ORMPurger($this->em);
$purger->purge();
}
But when I execute test I receive error:
The annotation "#Doctrine\ORM\Mapping\Entity" in class XXX does not
exist, or could not be auto-loaded.
My behat.yml is:
default:
suites:
default:
contexts:
- FeatureContext:
em: '#doctrine.orm.entity_manager'
extensions:
Behat\Symfony2Extension:
kernel:
bootstrap: "vendor/autoload.php"
env: "test"
debug: "true"
composer.json autoload section:
"autoload": {
"psr-4": {
"": "src/"
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
}
If remove line bootstrap: "vendor/autoload.php" from behat.yml, everything will work as needed.

Host Symfony2 bundle on GitHub and install it with Composer

Background
I have created a Symfony2 application hosted on GitHub. Now I want to make it a bundle instead of an application, in order to use it with Composer.
What I've tried
I have created a new repository on GitHub named AsyncTweetsBundle, I think my vendor name should be AlexisLefebvre and the bundle name AsyncTweetsBundle. But I don't understand how to configure the composer.jsonfile, here is the current content of the file:
{
"name" : "alexislefebvre/async-tweets-bundle",
"type" : "symfony-bundle",
"description" : "PHP Twitter reader for asynchronous reading",
"keywords" : ["twitter", "reader", "bundle"],
"homepage": "http://asynctweets.alexislefebvre.com/",
"license" : "MIT",
"authors" : [{
"name" : "Alexis Lefebvre",
"homepage": "http://alexislefebvre.com/",
"role": "Developer"
}],
"require" : {
"php": ">=5.3.2",
"abraham/twitteroauth": "0.5.0"
},
"autoload" : {
"psr-0" : {
"AlexisLefebvre\\Bundle\\AsyncTweetsBundle" : ""
}
},
"target-dir": "AlexisLefebvre/Bundle/AsyncTweetsBundle",
"extra": {
"branch-alias": {
"dev-master": "0.1-dev"
}
}
}
And here is the base class of the bundle AlexisLefebvreAsyncTweetsBundle :
<?php
namespace AlexisLefebvre\Bundle\AlexisLefebvreAsyncTweetsBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AlexisLefebvreAsyncTweetsBundle extends Bundle
{
}
I have submitted this package on Packagist: alexislefebvre/async-tweets-bundle.
So I created a Symfony2 installation and added this dependency:
composer create-project \
symfony/framework-standard-edition symfony2_AsyncTweetBundle --prefer-dist
cd symfony2_AsyncTweetBundle/
composer require alexislefebvre/async-tweets-bundle
The bundle is installed in vendor/alexislefebvre/async-tweets-bundle/AlexisLefebvre/Bundle/AsyncTweetsBundle/AlexisLefebvreAsyncTweetsBundle.php but I can't use it.
Problems
The bundle is installed in vendor/alexislefebvre/async-tweets-bundle/AlexisLefebvre/Bundle/AsyncTweetsBundle/AlexisLefebvreAsyncTweetsBundle.php. Is it correct?
I added new AlexisLefebvre\Bundle\AlexisLefebvreAsyncTweetsBundle() in app/AppKernel.php but if I run a command, eg. php app/console cache:clear --env=dev, it throws an error:
PHP Fatal error: Class 'AlexisLefebvre\Bundle\AlexisLefebvreAsyncTweetsBundle' not found in .../symfony2_AsyncTweetBundle/app/AppKernel.php on line 20
What is the correct name for the bundle? Is the namespace AlexisLefebvre mandatory in the bundle's class name? Should I use AlexisLefebvre or AlexisLefebvre\Bundle as the base namespace? What is the correct value of "target-dir". I didn't find any explanation of the links between the different parts of the composer.json file: "name", "autoload" : {"psr-0" : {}} and "target-dir".
I tried with "autoload" : {"psr-4" : {...}} (psr-0 is deprecated for new projets) and it was even worse, the bundle didn't installed at all.
Looking at your packagist repository and your github repository. It seems that the repository point by your package has no files. So, first try merging your files at these two locations.
Then, if you want to change your vendor name/namespace change namespace for every file for uniformity and for you already know how to create your own package.
Still you can look at Creating your very own Composer Package
in case of confusion.
Here is a working example for a PersonBundle under the Cerad namespace.
{
"name": "cerad/person-bundle",
"type": "symfony-bundle",
"description": "Symfony Cerad Person Bundle",
"keywords": ["cerad","zayso"],
"homepage": "http://github.com/cerad/PersonBundle",
"license": "MIT",
"authors": [
{
"name": "",
"email": "",
"homepage": "http://zayso.org",
"role": "Developer"
}
],
"require": {
"php": ">=5.3.3"
},
"minimum-stability": "dev",
"autoload": {
"psr-0": { "Cerad\\Bundle\\PersonBundle\\": "" }
},
"target-dir": "Cerad/Bundle/PersonBundle"
}
The code gets installed under
vendor\cerad\person-bundle\Cerad\Bundle\PersonBundle
I have a CeradPersonBundle.php file
with a namespace of Cerad\Bundle\PersonBundle;
All the path and options are confusing. I worked my way through it by having composer first load directly from github instead of packagist. Easier to make changes to composer.json that way.
The solution was to use psr-4 in composer.json:
{
"name" : "alexislefebvre/async-tweets-bundle",
"type" : "symfony-bundle",
"description" : "PHP Twitter reader for asynchronous reading",
"keywords" : ["twitter", "reader", "bundle"],
[...]
"autoload" : {
"psr-4" : {
"AlexisLefebvre\\Bundle\\AsyncTweetsBundle\\" : ""
}
}
}
And here is the base bundle class:
<?php
namespace AlexisLefebvre\Bundle\AsyncTweetsBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AsyncTweetsBundle extends Bundle
{
}
I was able to load the bundle in Symfony2 by adding this to app/AppKernel.php:
new AlexisLefebvre\Bundle\AsyncTweetsBundle\AsyncTweetsBundle(),

Cannot load custom bundle in Sylius?

I want to create my own bundles in Sylius. I created in the directory src and named App like that
src
Sylius
.......
App
Bundle
ShopBundle
AppShopBundle.php
In this file, I wrote very simple:
namespace App\Bundle\ShopBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppShopBundle extends Bundle
{
}
And I registered this bundle in AppKernel.php
$bundles = array(
new App\Bundle\ShopBundle\AppShopBundle()
);
But when I run the site, I have an exception. I don't understand the problem here, anyone can help me ?
ClassNotFoundException in AppKernel.php line 28:
Attempted to load class "AppShopBundle" from namespace "App\Bundle\ShopBundle".
Did you forget a "use" statement for "App\Bundle\ShopBundle\AppShopBundle"?
You should edit composer.json file to autoload your new bundle
"autoload": {
"psr-0": { "": "src/" }
}
Then run composer dump-autoload in terminal
Tuan's approach worked for me. In my case my composer.json autoload equals:
"autoload": {
"psr-0": { "Sylius\\": "src/", "App\\": "src/" }
},
and then you'll want to clear cache after running 'composer dump-autoload'
php app/console cache:clear --env=dev
While Tuan's answer will work, it uses psr-0. Adding an updated answer for psr-4 support.
Change your composer.json's autoload configuration to load the whole source directory like so:
"autoload": {
"psr-4": {
"": "src/"
}
}

Symfony external library - Payone

Has anybody ever used Symfony in conjunction with payone(payone.de)?
I got the SDK and it has the folders js, locale and php.
My problem: I don't really know how to include/use them in my project(inexperienced in Symfony) because I don't know where I should place it and how to include it. I read about the auto loader but since the SDK doesn't follow the standards needed(concerning folder structure) I guess it's not the way to go.
You can autoload all classes with the psr-0 too if the classes are following the PEAR-style non-namespaced convention.
To manage the vendor download via composer, you can define a package in your composer.json directly.
{
"repositories": [
{
"type": "package",
"package": {
"name": "payone/php-sdk",
"version": "1.0.0",
"dist": {
"url": "http://github.com/PAYONE/PHP-SDK/archive/master.zip",
"type": "zip"
},
"autoload": {
"psr-0": { "Payone_": "php/" }
}
}
}
],
"require": {
"payone/php-sdk": "1.0.*"
}
}
Note: This repository type has a few limitations and should be avoided whenever possible:
Composer will not update the package unless you change the version field.

Symfony2 using third party vendors inside a bundle

I am creating a CpanelBundle which will integrate the Cpanel xmlapi into Symfony.
I will use the class provided by CpanelInc here: https://github.com/CpanelInc/xmlapi-php.
I want to make this bundle usable across projects and also open source.
The Symfony documentation says you should not put third party libraries into your bundles. The Cpanel class also don't have a namespace and its not on composer.
I could and should put the Cpanel class in vendor folder but how can I add it to autoload and to my bundle composer.json so when I release my bundle the user will also get it?
Hello you can load this file using composer. Please see composer autoload documentation
Your composer.json can looks like:
{
"name": "my/bundle",
"autoload": {
"psr-0": {"": "src"}
},
"require": {
"php": ">=5.3.2",
"symfony/framework-bundle": ">=2.1,<2.3-dev",
"CpanelInc/xmlapi-php": "*"
},
"repositories": [
{
"type": "package",
"package": {
"name": "CpanelInc/xmlapi-php",
"version": "master-dev",
"dist": {
"url": "http://github.com/CpanelInc/xmlapi-php/zipball/master",
"type": "zip"
},
"source": {
"url": "git://github.com/CpanelInc/xmlapi-php.git",
"type": "git",
"reference": "master"
},
"autoload": {
"files" : ['xmlapi.php']
}
}
}
]
}
Will be even better when you just create composer.json and add it for CpanelInc/xmlapi-php and do PR :)

Resources