namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Sylius\Component\Resource\Model\ResourceInterface;
use Vankosoft\ApplicationBundle\Model\Interfaces\TaxonInterface;
/**
* @ORM\Table(name="VSORG_ProjectCategories")
* @ORM\Entity
*/
class ProjectCategory implements ResourceInterface
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var TaxonInterface
*
* @ORM\OneToOne(targetEntity="App\Entity\Application\Taxon", cascade={"all"}, orphanRemoval=true)
* @ORM\JoinColumn(name="taxon_id", referencedColumnName="id", nullable=false)
*/
private $taxon;
/**
* @var ProjectCategory
*
* @ORM\ManyToOne(targetEntity="App\Entity\ProjectCategory", inversedBy="children", cascade={"all"})
*/
private $parent;
/**
* @var Collection|ProjectCategory[]
*
* @ORM\OneToMany(targetEntity="App\Entity\ProjectCategory", mappedBy="parent")
*/
private $children;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Project", mappedBy="category", orphanRemoval=true)
* @ORM\OrderBy({"position" = "ASC"})
*/
private $projects;
public function __construct()
{
$this->children = new ArrayCollection();
$this->projects = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* {@inheritdoc}
*/
public function getParent(): ?ProjectCategory
{
return $this->parent;
}
/**
* {@inheritdoc}
*/
public function setParent( ?ProjectCategory $parent ): self
{
$this->parent = $parent;
return $this;
}
public function getChildren() : Collection
{
//return $this->children;
return $this->taxon->getChildren();
}
/**
* @return Collection|Project[]
*/
public function getProjects(): Collection
{
return $this->projects;
}
public function addProject( Project $project ): self
{
if ( ! $this->projects->contains( $project ) ) {
$this->projects[] = $project;
$project->addCategory( $this );
}
return $this;
}
public function removeProject( Project $project ): self
{
if ( ! $this->projects->contains( $project ) ) {
$this->projects->removeElement( $project );
$project->removeCategory( $this );
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getTaxon(): ?TaxonInterface
{
return $this->taxon;
}
/**
* {@inheritdoc}
*/
public function setTaxon( ?TaxonInterface $taxon ): self
{
$this->taxon = $taxon;
return $this;
}
public function getName()
{
return $this->taxon ? $this->taxon->getName() : '';
}
public function setName( string $name ): self
{
if ( ! $this->taxon ) {
// Create new taxon into the controller and set the properties passed from form
return $this;
}
$this->taxon->setName( $name );
return $this;
}
public function __toString()
{
return $this->taxon ? $this->taxon->getName() : '';
}
}
Create a Category Form
namespace App\Form;
use Vankosoft\ApplicationBundle\Form\AbstractForm;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Vankosoft\ApplicationBundle\Component\I18N;
use App\Entity\ProjectCategory;
class ProjectCategoryForm extends AbstractForm
{
public function buildForm( FormBuilderInterface $builder, array $options )
{
parent::buildForm( $builder, $options );
$builder
->add( 'currentLocale', ChoiceType::class, [
'choices' => \array_flip( I18N::LanguagesAvailable() ),
'mapped' => false,
'label' => 'vankosoft_org.form.locale',
'translation_domain' => 'VankoSoftOrg',
])
->add( 'name', TextType::class, [
'label' => 'vankosoft_org.form.name',
'translation_domain' => 'VankoSoftOrg',
])
;
}
public function configureOptions( OptionsResolver $resolver ): void
{
parent::configureOptions( $resolver );
$resolver->setDefaults([
'data_class' => ProjectCategory::class
]);
}
}
Create a Category CRUD Controller
namespace App\Controller\AdminPanel;
use Symfony\Component\HttpFoundation\Request;
use Vankosoft\ApplicationBundle\Controller\AbstractCrudController;
use Vankosoft\ApplicationBundle\Controller\TaxonomyHelperTrait;
use App\Entity\Application\Taxon;
class ProjectsCategoryController extends AbstractCrudController
{
use TaxonomyHelperTrait;
protected function prepareEntity( &$entity, &$form, Request $request )
{
$translatableLocale = $form['currentLocale']->getData();
$categoryName = $form['name']->getData();
$parentGroup = null;
$entity->setName( $categoryName );
if ( $entity->getTaxon() ) {
$entityTaxon = $entity->getTaxon();
if ( ! in_array( $translatableLocale, $entityTaxon->getExistingTranslations() ) ) {
$taxonTranslation = $this->createTranslation( $entityTaxon, $translatableLocale, $categoryName );
$entityTaxon->addTranslation( $taxonTranslation );
}
$entityTaxon->setCurrentLocale( $translatableLocale );
$entityTaxon->setName( $categoryName );
$entityTaxon->setCode( $this->get( 'vs_application.slug_generator' )->generate( $categoryName ) );
if ( $parentGroup ) {
$entityTaxon->setParent( $parentGroup->getTaxon() );
}
} else {
$taxonomy = $this->get( 'vs_application.repository.taxonomy' )->findByCode(
$this->getParameter( 'vs_org.project-categories.taxonomy_code' )
);
$entityTaxon = $this->createTaxon(
$categoryName,
$translatableLocale,
$parentGroup ? $parentGroup->getTaxon() : null,
$taxonomy->getId()
);
}
$entity->setTaxon( $entityTaxon );
$entity->setParent( $parentGroup );
$this->getDoctrine()->getManager()->persist( $entityTaxon );
}
protected function customData( Request $request, $entity = NULL ): array
{
$taxonomy = $this->get( 'vs_application.repository.taxonomy' )->findByCode(
$this->getParameter( 'vs_org.project-categories.taxonomy_code' )
);
$translations = $this->classInfo['action'] == 'indexAction' ? $this->getTranslations() : [];
return [
'taxonomyId' => $taxonomy->getId(),
'translations' => $translations,
];
}
private function createTranslation( $taxon, $locale, $name )
{
$translation = $taxon->createNewTranslation();
$translation->setLocale( $locale );
$translation->setName( $name );
$translation->setSlug( $this->get( 'vs_application.slug_generator' )->generate( $name ) );
return $translation;
}
private function getTranslations()
{
$locales = $this->get( 'vs_application.repository.locale' )->findAll();
$translations = [];
foreach ( $this->resources->getCurrentPageResults() as $category ) {
foreach( $locales as $locale ) {
$category->getTaxon()->getTranslation( $locale->getCode() );
}
$translations[$category->getId()] = $category->getTaxon()->getExistingTranslations();
}
//echo "<pre>"; var_dump($translations); die;
return $translations;
}
}
Make Resource Configurations
Add a Sylius Resource in sylius_resource.yaml
sylius_resource:
resources:
---
vsorg.projects_categories:
driver: doctrine/orm
classes:
model: App\Entity\ProjectCategory
interface: Sylius\Component\Resource\Model\ResourceInterface
controller: App\Controller\AdminPanel\ProjectsCategoryController
repository: Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository
form: App\Form\ProjectCategoryForm
Add a Sylius Resource Route
vsorg_projects_categories:
resource: |
alias: vsorg.projects_categories
except: ['show']
path: /projects/categories
templates: "admin-panel/pages/ProjectsCategories"
type: sylius.resource