Я испытываю проблему, пытаясь вписать свои сущности в комплект администратора Sonata. У меня есть что-то вроде 5 сущностей, которые точно перечислены и просматриваются в комплекте, но я не могу редактировать или создавать новую запись.
Когда я пытаюсь редактировать или создавать, я получаю ReflectionException
ошибка:
Класс не существует
Я попытался решить эту проблему, чтобы работать с пространствами имен (перемещая контроллер в том же пространстве имен, что и файлы администратора, или около того) или настроить контроллер администратора, чтобы рассказать ему о моих сущностях («-> add (‘Individual’, ‘entity’, array (‘class’ => ‘Platform \ ProjectBundle \ Entity \ Individual’)) «вместо -> add (‘индивидуальный’)).
Моя сущность называется Biosample. Вот файл Entity:
<?php
namespace Platform\ProjectBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="biosample")
*/
class Biosample
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Individual", inversedBy="samples")
* @ORM\JoinColumn(name="individual_id", referencedColumnName="id")
*/
protected $individual;
/**
* @ORM\Column(type="string", length=100)
*/
protected $organ;
/**
* @ORM\Column(type="string", length=100)
*/
protected $sample_name;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $organ_location;
/**
* @ORM\Column(type="string")
*/
protected $tissue_type;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $tissue_subtype;
/**
* @ORM\Column(type="datetimetz")
*/
protected $sampling_date;
/**
* @ORM\Column(type="decimal", scale=3, nullable=true)
*/
protected $cellularity;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $conservation;
/**
* @ORM\Column(type="text", nullable=true)
*/
protected $description;
/**
* @ORM\ManyToMany(targetEntity="Project", mappedBy="biosamples")
*/
protected $projects;
public function __construct()
{
$this->projects = new ArrayCollection();
}
public function __toString()
{
return $this->sample_name;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set organ
*
* @param string $organ
* @return Biosample
*/
public function setOrgan($organ)
{
$this->organ = $organ;
return $this;
}
/**
* Get organ
*
* @return string
*/
public function getOrgan()
{
return $this->organ;
}
/**
* Set organ_location
*
* @param string $organLocation
* @return Biosample
*/
public function setOrganLocation($organLocation)
{
$this->organ_location = $organLocation;
return $this;
}
/**
* Get organ_location
*
* @return string
*/
public function getOrganLocation()
{
return $this->organ_location;
}
/**
* Set tissue_type
*
* @param string $tissueType
* @return Biosample
*/
public function setTissueType($tissueType)
{
$this->tissue_type = $tissueType;
return $this;
}
/**
* Get tissue_type
*
* @return string
*/
public function getTissueType()
{
return $this->tissue_type;
}
/**
* Set tissue_subtype
*
* @param string $tissueSubtype
* @return Biosample
*/
public function setTissueSubtype($tissueSubtype)
{
$this->tissue_subtype = $tissueSubtype;
return $this;
}
/**
* Get tissue_subtype
*
* @return string
*/
public function getTissueSubtype()
{
return $this->tissue_subtype;
}
/**
* Set sampling_date
*
* @param \DateTime $samplingDate
* @return Biosample
*/
public function setSamplingDate($samplingDate)
{
$this->sampling_date = $samplingDate;
return $this;
}
/**
* Get sampling_date
*
* @return \DateTime
*/
public function getSamplingDate()
{
return $this->sampling_date;
}
/**
* Set cellularity
*
* @param string $cellularity
* @return Biosample
*/
public function setCellularity($cellularity)
{
$this->cellularity = $cellularity;
return $this;
}
/**
* Get cellularity
*
* @return string
*/
public function getCellularity()
{
return $this->cellularity;
}
/**
* Set conservation
*
* @param string $conservation
* @return Biosample
*/
public function setConservation($conservation)
{
$this->conservation = $conservation;
return $this;
}
/**
* Get conservation
*
* @return string
*/
public function getConservation()
{
return $this->conservation;
}
/**
* Set description
*
* @param string $description
* @return Biosample
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set individual
*
* @param \Platform\ProjectBundle\Entity\Individual $individual
* @return Biosample
*/
public function setIndividual(\Platform\ProjectBundle\Entity\Individual $individual = null)
{
$this->individual = $individual;
return $this;
}
/**
* Get individual
*
* @return \Platform\ProjectBundle\Entity\Individual
*/
public function getIndividual()
{
return $this->individual;
}
/**
* Add projects
*
* @param \Platform\ProjectBundle\Entity\Project $projects
* @return Biosample
*/
public function addProject(\Platform\ProjectBundle\Entity\Project $projects)
{
$this->projects[] = $projects;
return $this;
}
/**
* Remove projects
*
* @param \Platform\ProjectBundle\Entity\Project $projects
*/
public function removeProject(\Platform\ProjectBundle\Entity\Project $projects)
{
$this->projects->removeElement($projects);
}
/**
* Get projects
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProjects()
{
return $this->projects;
}
/**
* Set sample_name
*
* @param string $sampleName
* @return Biosample
*/
public function setSampleName($sampleName)
{
$this->sample_name = $sampleName;
return $this;
}
/**
* Get sample_name
*
* @return string
*/
public function getSampleName()
{
return $this->sample_name;
}
}`
Вот мой BiosampleAdmin.php:
<?php
namespace Platform\ProjectBundle\Controller\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Knp\Menu\ItemInterface as MenuItemInterface;
use Platform\ProjectBundle\Entity\Biosample;
class BiosampleAdmin extends Admin
{
/**
* @param \Sonata\AdminBundle\Show\ShowMapper $showMapper
*
* @return void
*/
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('id')
->add('sample_name')
->add('individual', 'entity', array('class' => 'Platform\ProjectBundle\Entity\Individual'))
->add('organ')
->add('organ_location')
->add('tissue_type')
->add('tissue_subtype')
->add('sampling_date')
->add('cellularity')
->add('conservation')
->add('projects', 'entity', array('class' => 'Platform\ProjectBundle\Entity\Project'))
->add('description')
;
}/**
* @param \Sonata\AdminBundle\Form\FormMapper $formMapper
*
* @return void
*/
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('sample_name')
->add('individual')
->add('organ')
->add('organ_location')
->add('tissue_type')
->add('tissue_subtype')
->end()
->with('Miscelaneous')
->add('sampling_date')
->add('cellularity')
->add('conservation')
->end()
->with('Projects')
->add('projects')
->end()
->with('Description')
->add('description', 'sonata_type_model', array('multiple' => false))
->end()
;
}
/**
* @param \Sonata\AdminBundle\Datagrid\ListMapper $listMapper
*
* @return void
*/
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->add('sample_name')
->add('individual')
->add('projects')
->add('organ')
->add('tissue')
->add('_action', 'actions', array(
'actions' => array(
'show' => array(),
'edit' => array(),
'delete' => array(),
)
))
;
}/**
* @param \Sonata\AdminBundle\Datagrid\DatagridMapper $datagridMapper
*
* @return void
*/
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('sample_name')
->add('individual')
->add('projects')
;
}
}
Вот административный контроллер:
<?php
namespace Platform\ProjectBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Platform\ProjectBundle\Entity\Biosample;
class BiosampleAdminController extends Controller
{
}
И если вам это нужно, вот мой composer.json:
{
"name": "symfony/framework-standard-edition",
"license": "MIT",
"type": "project",
"description": "The \"Symfony Standard Edition\" distribution",
"autoload": {
"psr-0": { "": "src/", "SymfonyStandard": "app/" }
},
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.6.*",
"doctrine/orm": "~2.2,>=2.2.3,<2.5",
"doctrine/dbal": "<2.5",
"doctrine/doctrine-bundle": "~1.2",
"twig/extensions": "~1.0",
"symfony/assetic-bundle": "~2.3",
"symfony/swiftmailer-bundle": "~2.3",
"symfony/monolog-bundle": "~2.4",
"sensio/distribution-bundle": "~3.0,>=3.0.12",
"sensio/framework-extra-bundle": "~3.0,>=3.0.2",
"jms/security-extra-bundle": "~1.2",
"ircmaxell/password-compat": "~1.0.3",
"stof/doctrine-extensions-bundle": "~1.1@dev",
"friendsofsymfony/user-bundle": "~1.3",
"incenteev/composer-parameter-handler": "~2.0",
"nervo/yuicompressor": "2.4.8",
"sonata-project/admin-bundle": "~2.3",
"sonata-project/doctrine-orm-admin-bundle": "~2.3",
"sonata-project/easy-extends-bundle": "~2.1",
"sonata-project/user-bundle": "~2.2",
"knplabs/knp-menu-bundle": "~1.1",
"mopa/bootstrap-bundle": "~2",
"twbs/bootstrap-sass": "~3.3.0",
"knplabs/knp-paginator-bundle": "dev-master",
"knplabs/knp-menu": "~1.1",
"craue/formflow-bundle": "~2.0"},
"require-dev": {
"sensio/generator-bundle": "~2.3"},
"scripts": {
"post-root-package-install": [
"SymfonyStandard\\Composer::hookRootPackageInstall"],
"post-install-cmd": [
"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::removeSymfonyStandardFiles"],
"post-update-cmd": [
"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::removeSymfonyStandardFiles"]
},
"config": {
"bin-dir": "bin"},
"extra": {
"symfony-app-dir": "app",
"symfony-web-dir": "web",
"symfony-assets-install": "relative",
"incenteev-parameters": {
"file": "app/config/parameters.yml"},
"branch-alias": {
"dev-master": "2.6-dev"}
}
}
Наконец, вот мое объявление сервиса и мой файл config.yml:
Service.yml:
services:
platform.project.admin.biosample:
class: Platform\ProjectBundle\Controller\Admin\BiosampleAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: Project Manager, label: Biosample }
arguments: [null, Platform\ProjectBundle\Entity\Biosample, PlatformProjectBundle:BiosampleAdmin]
config.yml:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
framework:
#esi: ~
translator: { fallbacks: ["%locale%"] }
secret: "%secret%"router:
resource: "%kernel.root_dir%/config/routing.yml"strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"trusted_hosts: ~
trusted_proxies: ~
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"strict_variables: "%kernel.debug%"
# Assetic Configuration
assetic:
debug: "%kernel.debug%"use_controller: false
bundles: [ ]
#java: /usr/bin/java
filters:
cssrewrite: ~
#closure:
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"#yui_css:
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_driver%"host: "%database_host%"port: "%database_port%"dbname: "%database_name%"user: "%database_user%"password: "%database_password%"charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
# path: "%database_path%"types:
json: Sonata\Doctrine\Types\JsonType
orm:
auto_generate_proxy_classes: "%kernel.debug%"auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"host: "%mailer_host%"username: "%mailer_user%"password: "%mailer_password%"spool: { type: memory }fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: secured
user_class: Application\Sonata\UserBundle\Entity\User
group:
group_class: Application\Sonata\UserBundle\Entity\Group
group_manager: sonata.user.orm.group_manager
service:
user_manager: sonata.user.orm.user_managersonata_doctrine_orm_admin:
entity_manager: ~
sonata_block:
default_contexts: [cms]
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
sonata.user.block.menu: ~
sonata.user.block.account: ~
sonata.block.service.text: ~sonata_user:
security_acl: true
manager_type: orm
mopa_bootstrap:
form: ~
И последнее, но не менее важное: трассировка полного стека.
[1] ReflectionException: Class does not exist
at n/a
in /var/www/Project/app/cache/dev/classes.php line 6756
at ReflectionClass->__construct('')
in /var/www/Project/app/cache/dev/classes.php line 6756
at Doctrine\Common\Persistence\AbstractManagerRegistry->getManagerForClass(null)
in /var/www/Project/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php line 220
at Sonata\DoctrineORMAdminBundle\Model\ModelManager->getEntityManager(null)
in /var/www/Project/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php line 54
at Sonata\DoctrineORMAdminBundle\Model\ModelManager->getMetadata(null)
in /var/www/Project/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php line 317
at Sonata\DoctrineORMAdminBundle\Model\ModelManager->getIdentifierFieldNames(null)
in /var/www/Project/app/cache/dev/classes.php line 12663
at Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList->__construct(object(ModelManager), null, null, null, null)
in /var/www/Project/app/cache/dev/classes.php line 13690
at Sonata\AdminBundle\Form\Type\ModelType->Sonata\AdminBundle\Form\Type\{closure}(object(OptionsResolver), object(SimpleChoiceList))
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/OptionsResolver.php line 836
at Symfony\Component\OptionsResolver\OptionsResolver->offsetGet('choice_list')
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/OptionsResolver/OptionsResolver.php line 769
at Symfony\Component\OptionsResolver\OptionsResolver->resolve(array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormType.php line 109
at Symfony\Component\Form\ResolvedFormType->createBuilder(object(FormFactory), 'description', array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php line 82
at Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->createBuilder(object(FormFactory), 'description', array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormFactory.php line 87
at Symfony\Component\Form\FormFactory->createNamedBuilder('description', 'sonata_type_model', null, array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php line 106
at Symfony\Component\Form\FormBuilder->create('description', 'sonata_type_model', array('sonata_field_description' => object(FieldDescription), 'class' => null, 'model_manager' => object(ModelManager), 'multiple' => false, 'label_render' => false, 'label' => 'Description'))
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php line 268
at Symfony\Component\Form\FormBuilder->resolveChildren()
in /var/www/Project/vendor/symfony/symfony/src/Symfony/Component/Form/FormBuilder.php line 216
at Symfony\Component\Form\FormBuilder->getForm()
in /var/www/Project/app/cache/dev/classes.php line 9671
at Sonata\AdminBundle\Admin\Admin->buildForm()
in /var/www/Project/app/cache/dev/classes.php line 9930
at Sonata\AdminBundle\Admin\Admin->getForm()
in /var/www/Project/vendor/sonata-project/admin-bundle/Controller/CRUDController.php line 353
at Sonata\AdminBundle\Controller\CRUDController->editAction('1')
in line
at call_user_func_array(array(object(CRUDController), 'editAction'), array('1'))
in /var/www/Project/app/bootstrap.php.cache line 3022
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
in /var/www/Project/app/bootstrap.php.cache line 2984
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
in /var/www/Project/app/bootstrap.php.cache line 3133
at Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel->handle(object(Request), '1', true)
in /var/www/Project/app/bootstrap.php.cache line 2377
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
in /var/www/Project/web/app_dev.php line 28
Ну, причиной этой ошибки была плохая копия / вставка из учебника.
В классе администратора функция configureFormFields содержала плохо описанное поле «Описание».
->with('Description')
->add('description', 'sonata_type_model', array('multiple' => false))
->end()
Я должен был заменить это:
->with('Description')
->add('description')
->end()
Я обнаружил, что автоматическая генерация скелета класса администратора является функцией Sonata Admin Bundle.
Чтобы автоматически сгенерировать, выполните:
php app / console соната: admin: сгенерировать
Затем введите полный путь к вашей сущности, в этом примере:
Платформа \ ProjectBundle \ Entity \ биопробы
Пакет администратора проанализирует вашу сущность и:
Я думаю, что это должен быть предпочтительный метод, когда вы начинаете с комплекта администратора сонаты.
У меня была та же проблема, и по причине, которую я игнорирую, не в прошлом проекте, где я сделал то же самое …
После часа поиска я понимаю, что моя таблица ‘fos_user_user_group’ не была создана, если отображение не создано. Поэтому мое решение состояло в том, чтобы просто переопределить свойство groups моего объекта-пользователя для определения Doctrine ORM Mapping:
/**
* The User can have many groups.
* @ORM\ManyToMany(targetEntity="Group")
* @ORM\JoinTable(name="fos_user_user_group",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
protected $groups;
После этого doctrine: schema: update —force и проблема была решена;)
Если вы сделали это, как я, и создали сначала базу данных, затем через консоль yml-файлы и из этого классы, тогда ваши аннотации бесполезны.
Соната использует yml, а не аннотации. Они существуют и, кажется, работают, но они просто не работают. Чтобы сделать сообщение «Класс не существует», проверьте, что говорят ваши определения yml. Мне нужно было добавить отношения и классы сущностей там.
Если это действительно причина ваших ошибок, вы можете активировать аннотации, удалив или переместив шаблоны yml или xml в другое место (.. \ Resources \ config \ doctrine).