setEntityLabelInPlural($this->getEntityLabelInPlural()) ->setEntityLabelInSingular($this->getEntityLabelInSingular()) ->setSearchFields(['name', 'description']) ->setDefaultSort(['createdAt' => 'DESC']) ->setFormThemes([ '@EasyAdmin/crud/form_theme.html.twig', 'easy_admin/crud/form_theme.html.twig', ]) ->setFormOptions([ 'validation_groups' => [AbstractProductFormType::class], ]) ; } public function configureFilters(Filters $filters): Filters { return $filters ->add(UuidFilter::new('id')) ->add(EnumFilter::new('status', ProductStatusType::class)) ->add(EnumFilter::new('visibility', ProductVisibilityType::class)) ->add('category') ->add('owner') ->add('name') ->add('description') ; } public function configureActions(Actions $actions): Actions { $onBreak = Action::new('onBreak', 'action.onBreak') ->linkToCrudAction('changeStatus') ->displayIf(static function (Product $product) { return $product->isActive(); }); $activate = Action::new('activate', 'action.activate') ->linkToCrudAction('changeStatus') ->displayIf(static function (Product $product) { return $product->isPaused(); }); $availability = Action::new('availability', 'action.availability') ->linkToCrudAction('linkToProductAvailabilityPage'); $exportAction = Action::new('export') ->linkToUrl(function () { /** @var AdminContext $context */ $context = $this->getContext(); return $this->adminUrlGenerator->setAll($context->getRequest()->query->all()) ->setEntityId(null) ->setAction('export') ->generateUrl(); }) ->addCssClass('btn btn-success') ->setIcon('fa fa-download') ->createAsGlobalAction() ; return $actions ->add(Crud::PAGE_INDEX, Action::DETAIL) ->add(Crud::PAGE_EDIT, Action::DETAIL) ->add(Crud::PAGE_EDIT, Action::INDEX) ->add(Crud::PAGE_INDEX, $onBreak) ->add(Crud::PAGE_INDEX, $activate) ->add(Crud::PAGE_DETAIL, $availability) ->add(Crud::PAGE_INDEX, $exportAction); } private function redirectToObjectCrudPage(): RedirectResponse { $this->adminUrlGenerator->setController(ObjectCrudController::class)->setAction('index')->removeReferrer()->setEntityId(null); return $this->redirect($this->adminUrlGenerator->generateUrl()); } public function linkToProductAvailabilityPage(): Response { return $this->render('/admin/product/availability_product.html.twig'); } public function changeStatus(AdminContext $context): Response { /** @var Product $product */ $product = $context->getEntity()->getInstance(); if ($product->isPaused()) { $product->setStatus(ProductStatus::ACTIVE); } else { $product->setStatus(ProductStatus::PAUSED); } $this->productRepository->save($product, true); return $this->redirectToObjectCrudPage(); } /** * For now, we export exactly what we see in the list to avoid security problems. */ public function export(AdminContext $context): Response { $fields = FieldCollection::new($this->configureFields(Crud::PAGE_INDEX)); /** @var CrudDto $crud Crud is defined here */ $crud = $context->getCrud(); $filters = $this->filterFactory->create($crud->getFiltersConfig(), $fields, $context->getEntity()); /** @var SearchDto $search */ $search = $context->getSearch(); $queryBuilder = $this->createIndexQueryBuilder($search, $context->getEntity(), $fields, $filters); $fileName = $this->slugger->slug($this->translator->trans($this->getEntityLabelInPlural(), [], DashboardController::DOMAIN)); return $this->csvExporter->createResponseFromQueryBuilder($queryBuilder, $fields, $fileName.'.csv'); } public static function getEntityFqcn(): string { return Product::class; } public function createEntity(string $entityFqcn): Product { /** @var Product $product */ $product = new $entityFqcn(); $product->setType($this->getProductType()); return $product; } /** * Only display a given product type. */ public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder { $qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); $alias = $qb->getRootAliases()[0] ?? null; $qb->andWhere($alias.'.type = :type') ->setParameter('type', $this->getProductType()); return $qb; } /** * Return all possible product fields. * * @return array */ public function getFields(string $pageName): array { $idField = IdField::new('id') ->setLabel('id') ->hideOnForm(); $typeField = ChoiceField::new('type') ->setFormType(EnumType::class) ->setFormTypeOption('class', ProductType::class) ->setChoices(ProductType::getAsArray()); $statusField = ChoiceField::new('status') ->setFormType(EnumType::class) ->setFormTypeOption('class', ProductStatus::class) ->setChoices(ProductStatus::getAsArray()); $visibilityField = ChoiceField::new('visibility') ->setFormType(EnumType::class) ->setFormTypeOption('class', ProductVisibility::class) ->setChoices(ProductVisibility::getAsArray()); $groupsField = AssociationField::new('groups')->onlyOnForms(); $groupsFieldList = CollectionField::new('groups')->hideOnForm(); $ownerField = AssociationField::new('owner') ->setFormTypeOption('attr', [ 'data-controller' => 'admin-parentgroup', 'data-admin-parentgroup-target' => 'ownerField', ]) ->addWebpackEncoreEntries('admin'); $categoryField = AssociationField::new('category') ->setQueryBuilder(function (QueryBuilder $queryBuilder) { return $this->categoryRepository->addTypeFilter($queryBuilder, $this->getProductType()); }) ; $nameField = TextField::new('name'); $descriptionField = TextareaField::new('description'); // objects $ageField = TextField::new('age'); $depositField = MoneyField::new('deposit') ->setCurrencyPropertyPath('currency') ->setStoredAsCents() ->setNumDecimals(0) ; $currencyField = CurrencyField::new('currency'); // services $durationField = TextField::new('duration'); $createdAt = DateTimeField::new('createdAt'); $updatedAt = DateTimeField::new('updatedAt'); $imageField = ImageField::new('images') ->setBasePath($this->productBasePath) // correctly set the formatted value available in the template ->setUploadDir('public'.$this->productBasePath) ->setUploadedFileNamePattern('[uuid].[extension]') ->setFormTypeOption('upload_new', $this->easyAdminHelper->getUploadNewCallback($this->productStorage)) ->setFormTypeOption('upload_delete', $this->easyAdminHelper->getUploadDeleteCallback($this->productStorage)) ->setFormTypeOption('required', false) ->setFormTypeOption('multiple', true) ->setFormTypeOption('constraints', $this->mediaManager->getImageArrayConstraints()) ->setTemplatePath('easy_admin/field/flysystem_images.html.twig') ->setCustomOption('first_image_only', true) ->setHelp($this->mediaManager->getHelpMessage()) ->setSortable(false) ; $addressField = TextField::new('address'); if ($pageName === Crud::PAGE_DETAIL) { /** @var Product $product */ $product = $this->getContext()?->getEntity()->getInstance(); $addressField = TextField::new('address')->setValue($product->getOwner()->getAddress()?->getDisplayName()); } $preferredLoanDuration = TextField::new('preferredLoanDuration'); return compact( 'idField', 'typeField', 'statusField', 'visibilityField', 'groupsField', 'groupsFieldList', 'ownerField', 'categoryField', 'nameField', 'descriptionField', 'ageField', 'durationField', 'depositField', 'currencyField', 'createdAt', 'updatedAt', 'imageField', 'addressField', 'preferredLoanDuration', ); } }