Symfony- Error ocurred when I try to make an entity - php

When I use: php bin/console make:entity to create a new db entity, I get the following error:
In DoctrineHelper.php line 180:
Class "Doctrine\Persistence\Mapping\Driver\AnnotationDriver" does not exist
This is my composer.json:
{
"type": "project",
"license": "proprietary",
"require": {
"php": ">=7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"doctrine/annotations": "^1.13",
"doctrine/dbal": "^3.3",
"doctrine/doctrine-bundle": "^2.6",
"doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/orm": "^2.12",
"sensio/framework-extra-bundle": "^6.2",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/flex": "^1.3.1",
"symfony/form": "4.4.*",
"symfony/framework-bundle": "4.4.*",
"symfony/options-resolver": "4.4.*",
"symfony/property-access": "4.4.*",
"symfony/proxy-manager-bridge": "4.4.*",
"symfony/twig-bundle": "4.4.*",
"symfony/yaml": "4.4.*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/twig": "^2.12|^3.0"
},
"require-dev": {
"symfony/maker-bundle": "*",
"symfony/web-server-bundle": "4.4.*"
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"symfony/flex": true
},
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"#auto-scripts"
],
"post-update-cmd": [
"#auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "4.4.*"
}
}
}
This is my DoctrineHelper.php:
<?php
/*
* This file is part of the Symfony MakerBundle package.
*
* (c) Fabien Potencier <fabien#symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\MakerBundle\Doctrine;
use Doctrine\Common\Persistence\ManagerRegistry as LegacyManagerRegistry;
use Doctrine\Common\Persistence\Mapping\ClassMetadata as LegacyClassMetadata;
use Doctrine\Common\Persistence\Mapping\MappingException as LegacyPersistenceMappingException;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\ORM\Mapping\MappingException as ORMMappingException;
use Doctrine\ORM\Mapping\NamingStrategy;
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\Driver\AnnotationDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException;
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
use Symfony\Bundle\MakerBundle\Util\PhpCompatUtil;
/**
* #author Fabien Potencier <fabien#symfony.com>
* #author Ryan Weaver <ryan#knpuniversity.com>
* #author Sadicov Vladimir <sadikoff#gmail.com>
*
* #internal
*/
final class DoctrineHelper
{
/**
* #var string
*/
private $entityNamespace;
private $phpCompatUtil;
/**
* #var ManagerRegistry
*/
private $registry;
/**
* #var array|null
*/
private $mappingDriversByPrefix;
private $attributeMappingSupport;
/**
* #var ManagerRegistry|LegacyManagerRegistry
*/
public function __construct(string $entityNamespace, PhpCompatUtil $phpCompatUtil, $registry = null, bool $attributeMappingSupport = false, array $annotatedPrefixes = null)
{
$this->entityNamespace = trim($entityNamespace, '\\');
$this->phpCompatUtil = $phpCompatUtil;
$this->registry = $registry;
$this->attributeMappingSupport = $attributeMappingSupport;
$this->mappingDriversByPrefix = $annotatedPrefixes;
}
/**
* #return LegacyManagerRegistry|ManagerRegistry
*/
public function getRegistry()
{
// this should never happen: we will have checked for the
// DoctrineBundle dependency before calling this
if (null === $this->registry) {
throw new \Exception('Somehow the doctrine service is missing. Is DoctrineBundle installed?');
}
return $this->registry;
}
private function isDoctrineInstalled(): bool
{
return null !== $this->registry;
}
public function getEntityNamespace(): string
{
return $this->entityNamespace;
}
public function doesClassUseDriver(string $className, string $driverClass): bool
{
try {
/** #var EntityManagerInterface $em */
$em = $this->getRegistry()->getManagerForClass($className);
} catch (\ReflectionException $exception) {
// this exception will be thrown by the registry if the class isn't created yet.
// an example case is the "make:entity" command, which needs to know which driver is used for the class to determine
// if the class should be generated with attributes or annotations. If this exception is thrown, we will check based on the
// namespaces for the given $className and compare it with the doctrine configuration to get the correct MappingDriver.
return $this->isInstanceOf($this->getMappingDriverForNamespace($className), $driverClass);
}
if (null === $em) {
throw new \InvalidArgumentException(sprintf('Cannot find the entity manager for class "%s"', $className));
}
if (null === $this->mappingDriversByPrefix) {
// doctrine-bundle <= 2.2
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
if (!$this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
return $this->isInstanceOf($metadataDriver, $driverClass);
}
foreach ($metadataDriver->getDrivers() as $namespace => $driver) {
if (0 === strpos($className, $namespace)) {
return $this->isInstanceOf($driver, $driverClass);
}
}
return $this->isInstanceOf($metadataDriver->getDefaultDriver(), $driverClass);
}
$managerName = array_search($em, $this->getRegistry()->getManagers(), true);
foreach ($this->mappingDriversByPrefix[$managerName] as [$prefix, $prefixDriver]) {
if (0 === strpos($className, $prefix)) {
return $this->isInstanceOf($prefixDriver, $driverClass);
}
}
return false;
}
public function isClassAnnotated(string $className): bool
{
return $this->doesClassUseDriver($className, AnnotationDriver::class);
}
public function doesClassUsesAttributes(string $className): bool
{
return $this->doesClassUseDriver($className, AttributeDriver::class);
}
public function isDoctrineSupportingAttributes(): bool
{
return $this->isDoctrineInstalled() && $this->attributeMappingSupport && $this->phpCompatUtil->canUseAttributes();
}
public function getEntitiesForAutocomplete(): array
{
$entities = [];
if ($this->isDoctrineInstalled()) {
$allMetadata = $this->getMetadata();
foreach (array_keys($allMetadata) as $classname) {
$entityClassDetails = new ClassNameDetails($classname, $this->entityNamespace);
$entities[] = $entityClassDetails->getRelativeName();
}
}
sort($entities);
return $entities;
}
/**
* #return array|ClassMetadata|LegacyClassMetadata
*/
public function getMetadata(string $classOrNamespace = null, bool $disconnected = false)
{
$classNames = (new \ReflectionClass(AnnotationDriver::class))->getProperty('classNames');
$classNames->setAccessible(true);
// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
foreach ($this->mappingDriversByPrefix ?? [] as $managerName => $prefixes) {
foreach ($prefixes as [$prefix, $annotationDriver]) {
if (null !== $annotationDriver) {
$classNames->setValue($annotationDriver, null);
}
}
}
$metadata = [];
/** #var EntityManagerInterface $em */
foreach ($this->getRegistry()->getManagers() as $em) {
$cmf = $em->getMetadataFactory();
if ($disconnected) {
try {
$loaded = $cmf->getAllMetadata();
} catch (ORMMappingException $e) {
$loaded = $this->isInstanceOf($cmf, AbstractClassMetadataFactory::class) ? $cmf->getLoadedMetadata() : [];
} catch (LegacyPersistenceMappingException $e) {
$loaded = $this->isInstanceOf($cmf, AbstractClassMetadataFactory::class) ? $cmf->getLoadedMetadata() : [];
} catch (PersistenceMappingException $e) {
$loaded = $this->isInstanceOf($cmf, AbstractClassMetadataFactory::class) ? $cmf->getLoadedMetadata() : [];
}
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
foreach ($loaded as $m) {
$cmf->setMetadataFor($m->getName(), $m);
}
if (null === $this->mappingDriversByPrefix) {
// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
if ($this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
foreach ($metadataDriver->getDrivers() as $driver) {
if ($this->isInstanceOf($driver, AnnotationDriver::class)) {
$classNames->setValue($driver, null);
}
}
}
}
}
foreach ($cmf->getAllMetadata() as $m) {
if (null === $classOrNamespace) {
$metadata[$m->getName()] = $m;
} else {
if ($m->getName() === $classOrNamespace) {
return $m;
}
if (0 === strpos($m->getName(), $classOrNamespace)) {
$metadata[$m->getName()] = $m;
}
}
}
}
return $metadata;
}
public function createDoctrineDetails(string $entityClassName): ?EntityDetails
{
$metadata = $this->getMetadata($entityClassName);
if ($this->isInstanceOf($metadata, ClassMetadata::class)) {
return new EntityDetails($metadata);
}
return null;
}
public function isClassAMappedEntity(string $className): bool
{
if (!$this->isDoctrineInstalled()) {
return false;
}
return (bool) $this->getMetadata($className);
}
private function isInstanceOf($object, string $class): bool
{
if (!\is_object($object)) {
return false;
}
$legacyClass = str_replace('Doctrine\\Persistence\\', 'Doctrine\\Common\\Persistence\\', $class);
return $object instanceof $class || $object instanceof $legacyClass;
}
public function getPotentialTableName(string $className): string
{
$entityManager = $this->getRegistry()->getManager();
if (!$entityManager instanceof EntityManagerInterface) {
throw new \RuntimeException('ObjectManager is not an EntityManagerInterface.');
}
/** #var NamingStrategy $namingStrategy */
$namingStrategy = $entityManager->getConfiguration()->getNamingStrategy();
return $namingStrategy->classToTableName($className);
}
public function isKeyword(string $name): bool
{
/** #var Connection $connection */
$connection = $this->getRegistry()->getConnection();
return $connection->getDatabasePlatform()->getReservedKeywordsList()->isKeyword($name);
}
/**
* this method tries to find the correct MappingDriver for the given namespace/class
* To determine which MappingDriver belongs to the class we check the prefixes configured in Doctrine and use the
* prefix that has the closest match to the given $namespace.
*
* this helper function is needed to create entities with the configuration of doctrine if they are not yet been registered
* in the ManagerRegistry
*/
private function getMappingDriverForNamespace(string $namespace): ?MappingDriver
{
$lowestCharacterDiff = null;
$foundDriver = null;
foreach ($this->mappingDriversByPrefix ?? [] as $mappings) {
foreach ($mappings as [$prefix, $driver]) {
$diff = substr_compare($namespace, $prefix, 0);
if ($diff >= 0 && (null === $lowestCharacterDiff || $diff < $lowestCharacterDiff)) {
$lowestCharacterDiff = $diff;
$foundDriver = $driver;
}
}
}
return $foundDriver;
}
}
Line 180 is:
$classNames = (new \ReflectionClass(AnnotationDriver::class))->getProperty('classNames');
What could be the problem? I tried a lot of things but I'am not capable of solve it

This work for me.
Composer.json - change:
and
composer.lock- delete
"doctrine/orm": "^2.12",
to:
"doctrine/orm": "^2.11",
add (to prevent 2.12 being installed):
"conflict": {
"symfony/symfony": "*",
"doctrine/orm": "2.12.0"
},

Just a composer update works for me.
If not, try install "symfony/maker-bundle": "1.33.*"
then run composer update

Related

SqlServerParser.php does not comply with psr-4 autoloading standard in Crestapps

Trying to require CrestApps in a newly created Laravel project, gives me the following msg:
Class CrestApps\CodeGenerator\DatabaseParser\SqlServerParser located in C:/xampp/htdocs/cn/vendor/crestapps/laravel-code-generator/src\DatabaseParsers\SqlServerParser.php does not comply with psr-4 autoloading standard. Skipping.
Composer ver 2.0.7
CrestApps ver 2.4
Laravel installer 4.1.1
Composer.json file:
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"require": {
"php": "^7.3|^8.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.12",
"laravel/tinker": "^2.5"
},
"require-dev": {
"crestapps/laravel-code-generator": "^2.4",
"facade/ignition": "^2.5",
"fakerphp/faker": "^1.9.1",
"mockery/mockery": "^1.4.2",
"nunomaduro/collision": "^5.0",
"phpunit/phpunit": "^9.3.3"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover --ansi"
],
"post-root-package-install": [
"#php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"#php artisan key:generate --ansi"
]
}
}
SqlServerParser.php file:
<?php
namespace CrestApps\CodeGenerator\DatabaseParser;
use App;
use CrestApps\CodeGenerator\Models\Field;
use CrestApps\CodeGenerator\Models\FieldOptimizer;
use CrestApps\CodeGenerator\Support\DatabaseParser\ParserBase;
use DB;
use Exception;
class SqlServerParser extends ParserBase
{
/**
* The table name.
*
* #var array
*/
protected $tableName;
/**
* The databasename
*
* #var array
*/
protected $databaseName;
/**
* The locale value
*
* #var array
*/
protected $locale;
/**
* The final fields.
*
* #var array
*/
protected $fields;
/**
* Creates a new field instance.
*
* #param string $tableName
* #param string $databaseName
*
* #return void
*/
public function __construct($tableName, $databaseName)
{
$this->tableName = $tableName;
$this->databaseName = $databaseName;
$this->locale = App::getLocale();
}
/**
* Gets the final fields.
*
* #return array
*/
public function getFields()
{
if (is_null($this->fields)) {
$columns = $this->getColumn();
if (empty($columns)) {
throw new Exception('The table ' . $this->tableName . ' was not found in the ' . $this->databaseName . ' database.');
}
$this->fields = $this->transfer($columns);
}
return $this->fields;
}
/**
* Gets column meta info from the information schema.
*
* #return array
*/
protected function getColumn()
{
return DB::select(
'SELECT
c.COLUMN_NAME
,c.COLUMN_DEFAULT
,c.IS_NULLABLE
,c.DATA_TYPE
,c.CHARACTER_MAXIMUM_LENGTH
,pk.CONSTRAINT_TYPE AS EXTRA
FROM INFORMATION_SCHEMA.COLUMNS AS c
LEFT JOIN (
SELECT ku.TABLE_CATALOG,ku.TABLE_SCHEMA,ku.TABLE_NAME,ku.COLUMN_NAME, tc.CONSTRAINT_TYPE
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS ku ON tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME
) AS pk ON c.TABLE_CATALOG = pk.TABLE_CATALOG
AND c.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.COLUMN_NAME = pk.COLUMN_NAME
WHERE c.TABLE_NAME = ? AND c.TABLE_CATALOG = ? ',
[$this->tableName, $this->databaseName]
);
}
/**
* Gets array of field after transfering each column meta into field.
*
* #param array $columns
*
* #return array
*/
protected function transfer(array $columns)
{
$fields = [];
foreach ($columns as $column) {
$field = new Field($column->COLUMN_NAME);
$this->setIsNullable($field, $column->IS_NULLABLE)
->setMaxLength($field, $column->CHARACTER_MAXIMUM_LENGTH)
->setDefault($field, $column->COLUMN_DEFAULT)
->setDataType($field, $column->DATA_TYPE)
->setKey($field, $column->COLUMN_KEY, $column->EXTRA)
->setLabel($field, $column->COLUMN_NAME)
->setHtmlType($field, $column->DATA_TYPE);
$optimizer = new FieldOptimizer($field);
$fields[] = $optimizer->optimize()->getField();
}
return $fields;
}
/**
* Set the unsiged flag for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $type
*
* #return $this
*/
protected function setUnsigned(Field &$field, $type)
{
if (strpos($type, 'unsigned') !== false) {
$field->isUnsigned = true;
$field->validationRules[] = sprintf('min:%s', 0);
}
return $this;
}
/**
* Set the html type for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $type
*
* #return $this
*/
protected function setHtmlType(Field &$field, $type)
{
$map = $this->getMap();
if (array_key_exists($type, $map)) {
$field->htmlType = $map[$type];
}
return $this;
}
/**
* Set the data type for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $type
*
* #return $this
*/
protected function setDataType(Field &$field, $type)
{
$map = $this->dataTypeMap();
if (array_key_exists($type, $map)) {
$field->dataType = $map[$type];
}
return $this;
}
/**
* Set the nullable for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $nullable
*
* #return $this
*/
protected function setIsNullable(Field &$field, $nullable)
{
$field->isNullable = (strtoupper($nullable) == 'YES');
return $this;
}
/**
* Set the max length for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $length
*
* #return $this
*/
protected function setMaxLength(Field &$field, $length)
{
if (($value = intval($length)) > 0) {
$field->validationRules[] = sprintf('max:%s', $value);
$field->methodParams[] = $value;
}
return $this;
}
/**
* Set the default value for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $default
*
* #return $this
*/
protected function setDefault(Field &$field, $default)
{
if (!empty($default)) {
$field->dataValue = $default;
}
return $this;
}
/**
* Set the labels for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $name
*
* #return $this
*/
protected function setLabel(Field &$field, $name)
{
$field->addLabel($this->getLabelName($name), $this->tableName, true, $this->locale);
return $this;
}
/**
* Set the keys for a given field.
*
* #param CrestApps\CodeGenerator\Models\Field $field
* #param string $key
* #param string $extra
*
* #return $this
*/
protected function setKey(Field &$field, $key, $extra)
{
$key = strtoupper($key);
if ($key == 'PRIMARY KEY') {
$field->isPrimary = true;
}
if ($key == 'MUL') {
$field->isIndex = true;
}
if ($key == 'UNI') {
$field->isUnique = true;
}
if (strtolower($extra) == 'auto_increment') {
$field->isAutoIncrement = true;
}
return $this;
}
/**
* Gets a labe field's label from a given name.
*
* #return string
*/
protected function getLabelName($name)
{
return trim(ucwords(str_replace(['-', '_'], ' ', $name)));
}
/**
* Gets the eloquent method to html
*
* #return array
*/
protected function getMap()
{
return config('codegenerator.eloquent_type_to_html_type');
}
/**
* Gets the eloquent type to method collection
*
* #return array
*/
public function dataTypeMap()
{
return config('codegenerator.eloquent_type_to_method');
}
}
As per Composer version 2 changes regarding psr-4 autoloading standards, file SqlServerParser.php file had to be changed as follows:
line:
namespace CrestApps\CodeGenerator\DatabaseParser;
to be changed to:
namespace crestapps\laravelCodeGenerator\src\DatabaseParser;
Issue solved. Command "composer require crestapps/laravel-code-generator --dev" does not give any errors anymore, generating optimized autoload files successfully.

Symfony 4.4 Error on FOSUserBundle : UserManager

I had a bug with symfony, I had to reinstall my vendor folder and since then I have a bug that I cannot fix.
Argument 3 passed to FOS\UserBundle\Doctrine\UserManager::__construct() must be an instance of Doctrine\Common\Persistence\ObjectManager, instance of Doctrine\ORM\EntityManager given, called in C:\wamp64\www\brouwers\var\cache\dev\ContainerMmxuCtr\srcApp_KernelDevDebugContainer.php on line 1664
Error on my browser
I have try to add : "doctrine/common":"^2.13" on my composer.json
The bug is still here ...
I don't know how to fix this.
Someone can help me ?
My composer.json
{
"type": "project",
"license": "proprietary",
"require": {
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"friendsofsymfony/user-bundle": "^2.1",
"a2lix/translation-form-bundle": "^3.0",
"excelwebzone/recaptcha-bundle": "^1.5",
"doctrine/common":"^2.13",
"karser/karser-recaptcha3-bundle": "^0.1.8",
"knplabs/doctrine-behaviors": "^2.0",
"knplabs/knp-paginator-bundle": "^5.2",
"sensio/framework-extra-bundle": "^5.1",
"stof/doctrine-extensions-bundle": "^1.4",
"symfony/apache-pack": "^1.0",
"symfony/asset": "4.4.*",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/expression-language": "4.4.*",
"symfony/flex": "^1.3.1",
"symfony/form": "4.4.*",
"symfony/framework-bundle": "4.4.*",
"symfony/http-client": "4.4.*",
"symfony/intl": "4.4.*",
"symfony/mailer": "4.4.*",
"symfony/monolog-bundle": "^3.1",
"symfony/orm-pack": "*",
"symfony/process": "4.4.*",
"symfony/security-bundle": "4.4.*",
"symfony/serializer-pack": "*",
"symfony/swiftmailer-bundle": "^3.4",
"symfony/translation": "4.4.*",
"symfony/twig-pack": "*",
"symfony/validator": "4.4.*",
"symfony/web-link": "4.4.*",
"symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "4.4.*",
"twig/extensions": "^1.5",
"twig/extra-bundle": "^3.0",
"twig/twig": "^2.0"
},
"require-dev": {
"symfony/debug-pack": "*",
"symfony/maker-bundle": "^1.0",
"symfony/profiler-pack": "*",
"symfony/test-pack": "*"
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"#auto-scripts"
],
"post-update-cmd": [
"#auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "4.4.*"
}
}
}
Entity User :
<?php
// src/Entity/User.php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Assert\File(maxSize="2048k")
* #Assert\Image(mimeTypesMessage="Please upload a valid image.")
*/
protected $profilePictureFile;
// for temporary storage
private $tempProfilePicturePath;
/**
* #ORM\Column(type="string", length=255, nullable=true)
*/
protected $profilePicturePath;
public function __construct()
{
parent::__construct();
// your own logic
$this->roles = array('ROLE_ADMIN');
$this->enabled = true;
}
public function getId(): ?int
{
return $this->id;
}
/**
* Asks whether the user is granted a particular role
*
* #return boolean
*/
public function isGranted($role)
{
return in_array($role, $this->getRoles());
}
/**
* Sets the file used for profile picture uploads
*
* #param UploadedFile $file
* #return object
*/
public function setProfilePictureFile(UploadedFile $file = null) {
// set the value of the holder
$this->profilePictureFile = $file;
// check if we have an old image path
if (isset($this->profilePicturePath)) {
// store the old name to delete after the update
$this->tempProfilePicturePath = $this->profilePicturePath;
$this->profilePicturePath = null;
} else {
$this->profilePicturePath = 'initial';
}
return $this;
}
/**
* Get the file used for profile picture uploads
*
* #return UploadedFile
*/
public function getProfilePictureFile() {
return $this->profilePictureFile;
}
/**
* Set profilePicturePath
*
* #param string $profilePicturePath
* #return User
*/
public function setProfilePicturePath($profilePicturePath)
{
$this->profilePicturePath = $profilePicturePath;
return $this;
}
/**
* Get profilePicturePath
*
* #return string
*/
public function getProfilePicturePath()
{
return $this->profilePicturePath;
}
/**
* Get the absolute path of the profilePicturePath
*/
public function getProfilePictureAbsolutePath() {
return null === $this->profilePicturePath
? null
: $this->getUploadRootDir().'/'.$this->profilePicturePath;
}
/**
* Get root directory for file uploads
*
* #return string
*/
protected function getUploadRootDir($type='profilePicture') {
// the absolute directory path where uploaded
// documents should be saved
return __DIR__.'/../../public/images/'.$this->getUploadDir($type);
}
/**
* Specifies where in the /web directory profile pic uploads are stored
*
* #return string
*/
protected function getUploadDir($type='profilePicture') {
// the type param is to change these methods at a later date for more file uploads
// get rid of the __DIR__ so it doesn't screw up
// when displaying uploaded doc/image in the view.
return 'profilePicture';
}
/**
* Get the web path for the user
*
* #return string
*/
public function getWebProfilePicturePath() {
return '/'.$this->getUploadDir().'/'.$this->getProfilePicturePath();
}
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function preUploadProfilePicture() {
if (null !== $this->getProfilePictureFile()) {
// a file was uploaded
// generate a unique filename
$filename = md5(random_bytes(10));
$this->setProfilePicturePath($filename.'.'.$this->getProfilePictureFile()->guessExtension());
}
}
/**
* #ORM\PostPersist()
* #ORM\PostUpdate()
*
* Upload the profile picture
*
* #return mixed
*/
public function uploadProfilePicture() {
// check there is a profile pic to upload
if ($this->getProfilePictureFile() === null) {
return;
}
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->getProfilePictureFile()->move($this->getUploadRootDir(), $this->getProfilePicturePath());
// check if we have an old image
if (isset($this->tempProfilePicturePath) && file_exists($this->getUploadRootDir().'/'.$this->tempProfilePicturePath)) {
// delete the old image
unlink($this->getUploadRootDir().'/'.$this->tempProfilePicturePath);
// clear the temp image path
$this->tempProfilePicturePath = null;
}
$this->profilePictureFile = null;
}
/**
* #ORM\PostRemove()
*/
public function removeProfilePictureFile()
{
if ($file = $this->getProfilePictureAbsolutePath() && file_exists($this->getProfilePictureAbsolutePath())) {
unlink($file);
}
}
}
fos_user.yaml
fos_user:
db_driver: orm # other valid values are 'mongodb' and 'couchdb'
firewall_name: main
user_class: App\Entity\User
from_email:
address: "bastien#no.com"
sender_name: "bastien#no.com"
Tks a lot
The FOSUserBundle hasn't had a contribution since the 5th January as of today. We dropped it in our company, because it caused a lot of trouble with Symfony 4, since it isn't compatible with it as it seems.
The documentation from Symfony covers everything you need to know and do, so I'd start there and implement the authentication myself. Symfony 4 has pretty much everything built in what you need.
Here's a link to the official documentation: https://symfony.com/doc/4.4/security/form_login_setup.html
The other way would to search for forks of the bundle that are compatible with Symfony 4 and use the fork or create one yourself.

FOSRestBundle integration with BazingaHateoasBundle but links are still missing from response

I'm trying to integrate FOSRestBundle with BazingaHateoasBundle but the links (that I expected to be automatically generated) are still missing from the response. What is wrong with my set-up?
Here are my configs:
composer.json [excerpt]:
"require": {
"php": "^7.1.3",
"friendsofsymfony/rest-bundle": "^2.5",
"jms/serializer-bundle": "^2.4",
"lexik/jwt-authentication-bundle": "^2.6",
"sensio/framework-extra-bundle": "^5.2",
"stof/doctrine-extensions-bundle": "^1.3",
"symfony/flex": "^1.1",
"symfony/framework-bundle": "4.2.*",
"willdurand/hateoas-bundle": "^1.4"
},
jms_serializer.yaml:
jms_serializer:
visitors:
xml:
format_output: '%kernel.debug%'
fos_rest.yaml:
fos_rest:
zone:
- { path: ^/api/* }
view:
view_response_listener: true
format_listener:
rules:
- { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json ] }
routing_loader:
default_format: json
body_listener:
array_normalizer: fos_rest.normalizer.camel_keys
serializer:
serialize_null: true
body_converter:
enabled: true
validate: true
And here are my classes:
PersonsController.php:
/**
* #Rest\Route("/persons")
*/
class PersonsController extends AbstractFOSRestController
{
/**
* #Rest\Get("")
* #return View
*/
public function getList()
{
$repository = $this->getDoctrine()->getRepository(Person::class);
$view = $this->view(
$repository->findAll()
);
$view->getContext()->setGroups(['default']);
return $view;
}
}
Person.php
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Hateoas\Configuration\Annotation as Hateoas;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity(repositoryClass="App\Repository\PersonRepository")
* #UniqueEntity("slug")
* #Serializer\ExclusionPolicy("all")
* #Hateoas\Relation("self", href = "expr('/api/persons/' ~ object.getSlug())")
*/
class Person
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
* #Serializer\Expose
* #Serializer\Groups({"default"})
*/
private $name;
/**
* #ORM\Column(type="string", length=255, unique=true)
* #Gedmo\Slug(fields={"name"})
* #Serializer\Expose
* #Serializer\Groups({"default"})
* #Serializer\XmlAttribute
*/
private $slug;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getSlug()
{
return $this->slug;
}
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
}
Testing:
GET http://localhost:8000/api/groups response:
[
{
"name": "person1",
"slug": "person1"
},
{
"name": "person2",
"slug": "person2"
}
]
Expected:
[
{
"name": "person1",
"slug": "person1",
"_links": {
"self": { "href": "http://example.com/api/persons/person1" }
}
},
{
"name": "person2",
"slug": "person2",
"_links": {
"self": { "href": "http://example.com/api/persons/person2" }
}
}
]
Researched:
https://github.com/willdurand/BazingaHateoasBundle/blob/master/Resources/doc/index.md#serializing-objects - doesn't show integration with the FOS bundle. It just constructs the Response manually.
https://github.com/willdurand/Hateoas/issues/238 - suggested removing serializedGroups, but I need groups to properly hide/expose fields to be displayed
Symfony and Wildurand/Hateoas Bundle - no links on JSON reposnse - the OP just manually constructed the response object, thus did not actually use the features of FOSRestBundle
https://symfony.com/doc/master/bundles/FOSRestBundle/1-setting_up_the_bundle.html#b-enable-a-serializer - Because the JMSSerializerBundle is the only serializer that I installed, I assume that it is the one used by the FOSRestBundle to automatically serialize the data. Thus I should not manually serialize the data and construct the response, contrary to the solutions I found.
I just needed to add the exclusion property to the Relation annotation, and specify the group where it should appear.
/**
* #ORM\Entity(repositoryClass="App\Repository\PersonRepository")
* #UniqueEntity("slug")
* #Serializer\ExclusionPolicy("all")
* #Hateoas\Relation(
* "self",
* href = "expr('/api/persons/' ~ object.getSlug())",
* exclusion = #Hateoas\Exclusion(groups={"default"})
* )
*/
class Person
{ ...

Symfony 3.3 Parse error: syntax error, unexpected ':', expecting ';' or '{' in c:\xampp\htdocs\myproject\path\to\AnnotationRegistry.php on line 50

I have downloaded and installed Symfony 3.3 and i work with php 7.2 . I started to follow a symfony tutorial, everything was fine but once I did the symfony update with the command "php ../composer.phar update" I had this error:
Parse error: error syntax, unexpected ':', expecting ';' or '{' in
C: \ wamp \ wamp64 \ www \ Symfony \ Vendor \ Doctrine \ Annotations \ lib \ Doctrine \ Common \ Annotations \ AnnotationRegistry.php
This is the content of composer.php :
{
"name": "cashexpress/symfony",
"license": "proprietary",
"type": "project",
"autoload": {
"psr-4": {
"": "src/"
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
},
"files": [
"vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
},
"require": {
"php": ">=5.5.9",
"doctrine/doctrine-bundle": "^1.6",
"doctrine/orm": "^2.5",
"incenteev/composer-parameter-handler": "^2.0",
"sensio/distribution-bundle": "^5.0.19",
"sensio/framework-extra-bundle": "^3.0.2",
"symfony/monolog-bundle": "^3.1.0",
"symfony/polyfill-apcu": "^1.0",
"symfony/swiftmailer-bundle": "^2.3.10",
"symfony/symfony": "3.3.*",
"twig/twig": "^1.0||^2.0",
"doctrine/doctrine-fixtures-bundle": "~2.3"
},
"require-dev": {
"sensio/generator-bundle": "^3.0",
"symfony/phpunit-bridge": "^3.0"
},
"scripts": {
"symfony-scripts": [
"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-install-cmd": [
"#symfony-scripts"
],
"post-update-cmd": [
"#symfony-scripts"
]
},
"config": {
"sort-packages": true
},
"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": null
} }
This is the content of AnnotationRegistry.php:
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Annotations;
final class AnnotationRegistry
{
/**
* A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
*
* Contains the namespace as key and an array of directories as value. If the value is NULL
* the include path is used for checking for the corresponding file.
*
* This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
*
* #var string[][]|string[]|null[]
*/
static private $autoloadNamespaces = [];
/**
* A map of autoloader callables.
*
* #var callable[]
*/
static private $loaders = [];
/**
* An array of classes which cannot be found
*
* #var null[] indexed by class name
*/
static private $failedToAutoload = [];
public static function reset() : void
{
self::$autoloadNamespaces = [];
self::$loaders = [];
self::$failedToAutoload = [];
}
/**
* Registers file.
*
* #deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use #example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerFile(string $file) : void
{
require_once $file;
}
/**
* Adds a namespace with one or many directories to look for files or null for the include path.
*
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
*
* #param string $namespace
* #param string|array|null $dirs
*
* #deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use #example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerAutoloadNamespace(string $namespace, $dirs = null) : void
{
self::$autoloadNamespaces[$namespace] = $dirs;
}
/**
* Registers multiple namespaces.
*
* Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
*
* #param string[][]|string[]|null[] $namespaces indexed by namespace name
*
* #deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use #example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerAutoloadNamespaces(array $namespaces) : void
{
self::$autoloadNamespaces = \array_merge(self::$autoloadNamespaces, $namespaces);
}
/**
* Registers an autoloading callable for annotations, much like spl_autoload_register().
*
* NOTE: These class loaders HAVE to be silent when a class was not found!
* IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
*
* #deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
* autoloading should be deferred to the globally registered autoloader by then. For now,
* use #example AnnotationRegistry::registerLoader('class_exists')
*/
public static function registerLoader(callable $callable) : void
{
// Reset our static cache now that we have a new loader to work with
self::$failedToAutoload = [];
self::$loaders[] = $callable;
}
/**
* Registers an autoloading callable for annotations, if it is not already registered
*
* #deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
*/
public static function registerUniqueLoader(callable $callable) : void
{
if ( ! in_array($callable, self::$loaders, true) ) {
self::registerLoader($callable);
}
}
/**
* Autoloads an annotation class silently.
*/
public static function loadAnnotationClass(string $class) : bool
{
if (\class_exists($class, false)) {
return true;
}
if (\array_key_exists($class, self::$failedToAutoload)) {
return false;
}
foreach (self::$autoloadNamespaces AS $namespace => $dirs) {
if (\strpos($class, $namespace) === 0) {
$file = \str_replace('\\', \DIRECTORY_SEPARATOR, $class) . '.php';
if ($dirs === null) {
if ($path = stream_resolve_include_path($file)) {
require $path;
return true;
}
} else {
foreach((array) $dirs AS $dir) {
if (is_file($dir . \DIRECTORY_SEPARATOR . $file)) {
require $dir . \DIRECTORY_SEPARATOR . $file;
return true;
}
}
}
}
}
foreach (self::$loaders AS $loader) {
if ($loader($class) === true) {
return true;
}
}
self::$failedToAutoload[$class] = null;
return false;
}
}
I saw the other solutions proposed on stackoverflow but I did not find an answer to this error
 I do not know what to do now. I'm only new to Symfony. Help is badly needed.
composer update doctrine/annotations results :
[1]: https://i.stack.imgur.com/uIyWa.jpg
composer show doctrine/annotations results :
[1]: https://i.stack.imgur.com/NfjRH.jpg
Ensure that you are using php version >= 7.1
Also specify you PHP version in composer.json:
"config": {
"platform": {
"php": "7.2"
}
}
after that, run
composer update doctrine/annotations
Looks to me like your PHP version isn't 7.2, ensure the PHP version in the command line is also PHP 7.2 by running php -v. The error you're getting looks as it fails on the return types.

Doctrine2: Warning: Illegal offset type in isset or empty

I've a ManyToMany relation in Listing entity:
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\ListingRepository")
* #ORM\Table(name="listings")
*/
class Listing extends MainEntity
{
/**
* #ORM\Id
* #ORM\Column(type="uuid")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\AttributeDescription", inversedBy="listings", cascade={"persist", "remove"})
* #JoinTable(name="listing_attriubute_descriptions",
* joinColumns={#JoinColumn(name="listing_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="attribute_description_id", referencedColumnName="id")}
* )
*/
public $attributeDescriptions;
public function __construct()
{
$this->id = Uuid::uuid4();
$this->attributeDescriptions = new ArrayCollection();
}
public function removeAttributeDescription(AttributeDescription $attributeDescription)
{
if(!$this->attributeDescriptions->contains($attributeDescription))
{
return;
}
$this->attributeDescriptions->remove($attributeDescription);
return $this;
}
}
Somewhere in the ListingService I'm trying to remove AttributeDescription from the Listing entity like this:
$listing->removeAttributeDescription($toRemoveAttributeDescription);
But got an error: Warning: Illegal offset type in isset or empty
Using xdebug I've landed to remove() method in ArrayCollection:
public function remove($key)
{
if ( ! isset($this->elements[$key]) && ! array_key_exists($key, $this->elements)) {
return null;
}
$removed = $this->elements[$key];
unset($this->elements[$key]);
return $removed;
}
And found out that the problem comes from isset($this->elements[$key]).
Here is the screenshot from xdebug:
As you can see the $key contains an AttributeDescription, and the $this->elements is an array of AttributeDescriptions.
I really don't get whether I'm doing something wrong or is this a doctrine bug?
I'm using:
Symfony 3.3.13 with php 7.1.1
Doctrine:
"doctrine/doctrine-bundle": "^1.6",
"doctrine/doctrine-cache-bundle": "^1.2",
"doctrine/doctrine-migrations-bundle": "^1.2",
"doctrine/orm": "^2.5"
The solution: I was using wrong method. Instead of remove() I should use removeElement()

Categories