├── .gitignore ├── .travis.yml ├── Admin ├── AbstractElement.php ├── CRUD │ ├── BatchElement.php │ ├── CRUDElement.php │ ├── Context │ │ ├── BatchElementContext.php │ │ ├── CRUDFormElementContext.php │ │ ├── CRUDListElementContext.php │ │ ├── DeleteElementContext.php │ │ ├── FormElementContext.php │ │ ├── ListElementContext.php │ │ └── Request │ │ │ ├── BatchFormSubmitHandler.php │ │ │ ├── BatchFormValidRequestHandler.php │ │ │ ├── DataGridBindDataHandler.php │ │ │ ├── DataGridSetDataHandler.php │ │ │ ├── DataSourceBindParametersHandler.php │ │ │ ├── DeleteRequestHandler.php │ │ │ ├── FormSubmitHandler.php │ │ │ └── FormValidRequestHandler.php │ ├── DataIndexerElement.php │ ├── DeleteElement.php │ ├── DependentBatchElement.php │ ├── DependentCRUDElement.php │ ├── DependentDeleteElement.php │ ├── DependentFormElement.php │ ├── DependentListElement.php │ ├── FormElement.php │ ├── GenericBatchElement.php │ ├── GenericCRUDElement.php │ ├── GenericDeleteElement.php │ ├── GenericFormElement.php │ ├── GenericListElement.php │ └── ListElement.php ├── Context │ ├── ContextAbstract.php │ ├── ContextInterface.php │ ├── ContextManager.php │ └── Request │ │ ├── AbstractFormSubmitHandler.php │ │ ├── AbstractFormValidRequestHandler.php │ │ ├── AbstractHandler.php │ │ └── HandlerInterface.php ├── DependentElement.php ├── DependentElementImpl.php ├── Display │ ├── Context │ │ ├── DisplayContext.php │ │ └── Request │ │ │ └── Handler.php │ ├── DependentDisplayElement.php │ ├── Element.php │ └── GenericDisplayElement.php ├── Element.php ├── LocaleProviderAware.php ├── Manager.php ├── Manager │ ├── DependentElementsVisitor.php │ ├── ElementCollectionVisitor.php │ └── Visitor.php ├── ManagerInterface.php ├── RedirectableElement.php ├── RequestStackAware.php └── ResourceRepository │ ├── Context │ ├── Request │ │ ├── FormSubmitHandler.php │ │ └── FormValidRequestHandler.php │ └── ResourceRepositoryContext.php │ ├── Element.php │ ├── GenericResourceElement.php │ └── ResourceFormBuilder.php ├── Behat ├── Context │ ├── AbstractContext.php │ ├── AdminContext.php │ ├── DataContext.php │ ├── DisplayContext.php │ ├── FiltersContext.php │ ├── FormContext.php │ ├── ListContext.php │ ├── MessageContext.php │ ├── NavigationContext.php │ └── ResourceContext.php ├── Element │ ├── Display.php │ ├── Filters.php │ ├── ListElement.php │ ├── ListResultsElement.php │ ├── Messages.php │ └── Pagination.php └── Page │ ├── AdminPanel.php │ ├── CategoryList.php │ ├── CategoryNewsCreate.php │ ├── CategoryNewsEdit.php │ ├── CategoryNewsList.php │ ├── CustomNewsCreate.php │ ├── CustomNewsEdit.php │ ├── CustomNewsList.php │ ├── CustomSubscribersList.php │ ├── DTOForm.php │ ├── DefaultPage.php │ ├── HomePageEdit.php │ ├── NewsCreate.php │ ├── NewsDisplay.php │ ├── NewsEdit.php │ ├── NewsList.php │ ├── Page.php │ ├── PersonAddForm.php │ ├── PersonEditForm.php │ ├── PersonList.php │ ├── SubscriberEdit.php │ ├── SubscriberForm.php │ └── SubscribersList.php ├── CHANGELOG-1.1.md ├── CHANGELOG-2.1.md ├── CHANGELOG-3.0.md ├── CHANGELOG-3.1.md ├── Controller ├── AdminController.php ├── BatchController.php ├── ControllerAbstract.php ├── DataIndexerElementFinder.php ├── DisplayController.php ├── FormController.php ├── ListController.php ├── PositionableController.php ├── ReorderTreeController.php └── ResourceController.php ├── DataGrid └── Extension │ └── Admin │ └── ColumnTypeExtension │ ├── BatchActionExtension.php │ └── ElementActionExtension.php ├── DependencyInjection ├── Compiler │ ├── FlashMessagesPass.php │ ├── ResourceRepositoryPass.php │ └── TwigGlobalsPass.php ├── Configuration.php └── FSIAdminExtension.php ├── Display ├── Display.php ├── Property.php ├── Property │ ├── Formatter │ │ ├── Boolean.php │ │ ├── Callback.php │ │ ├── Collection.php │ │ ├── DateTime.php │ │ └── EmptyValue.php │ └── ValueFormatter.php ├── PropertyAccessDisplay.php └── SimpleDisplay.php ├── Doctrine └── Admin │ ├── BatchElement.php │ ├── CRUDElement.php │ ├── DataIndexerElementImpl.php │ ├── DeleteElement.php │ ├── DependentBatchElement.php │ ├── DependentCRUDElement.php │ ├── DependentDeleteElement.php │ ├── DependentDisplayElement.php │ ├── DependentFormElement.php │ ├── DependentListElement.php │ ├── DisplayElement.php │ ├── Element.php │ ├── ElementImpl.php │ ├── FormElement.php │ ├── ListElement.php │ └── ResourceElement.php ├── Event ├── AdminContextPreCreateEvent.php ├── AdminEvent.php ├── BatchEvent.php ├── BatchObjectPostApplyEvent.php ├── BatchObjectPreApplyEvent.php ├── BatchObjectsPostApplyEvent.php ├── BatchObjectsPreApplyEvent.php ├── BatchRequestPostSubmitEvent.php ├── BatchRequestPreSubmitEvent.php ├── DisplayEvent.php ├── DisplayResponsePreRenderEvent.php ├── FormDataPostSaveEvent.php ├── FormDataPreSaveEvent.php ├── FormEvent.php ├── FormRequestPostSubmitEvent.php ├── FormRequestPreSubmitEvent.php ├── FormResponsePreRenderEvent.php ├── ListDataGridPostSetDataEvent.php ├── ListDataGridPostSubmitRequestEvent.php ├── ListDataGridPreSetDataEvent.php ├── ListDataGridPreSubmitRequestEvent.php ├── ListDataSourcePostBindEvent.php ├── ListDataSourcePreBindEvent.php ├── ListEvent.php ├── ListResponsePreRenderEvent.php ├── MenuEvent.php ├── MenuMainEvent.php ├── MenuToolsEvent.php ├── MovedDownTreeEvent.php ├── MovedUpTreeEvent.php ├── PositionableEvent.php ├── PositionablePostMoveEvent.php └── PositionablePreMoveEvent.php ├── EventSubscriber ├── CleanUpMenuSubscriber.php ├── LocaleMenuSubscriber.php ├── LocaleSubscriber.php ├── MainMenuSubscriber.php ├── MessagesSubscriber.php ├── TranslationLocaleMenuSubscriber.php └── TranslationLocaleSubscriber.php ├── Exception ├── ContextBuilderException.php ├── ContextException.php ├── ContextExceptionInterface.php ├── ExceptionInterface.php ├── InvalidArgumentException.php ├── MissingOptionException.php ├── RequestHandlerException.php └── RuntimeException.php ├── FSiAdminBundle.php ├── Factory ├── ProductionLine.php ├── Worker.php └── Worker │ ├── DoctrineWorker.php │ ├── FormWorker.php │ ├── ListWorker.php │ ├── LocaleProviderWorker.php │ └── RequestStackWorker.php ├── Form └── CollectionTypeExtension.php ├── LICENSE.md ├── Menu ├── Builder │ ├── Builder.php │ ├── Exception │ │ └── InvalidYamlStructureException.php │ └── MenuBuilder.php ├── Item │ ├── ElementItem.php │ ├── Item.php │ └── RoutableItem.php └── KnpMenu │ ├── ElementVoter.php │ ├── ItemAttributesDecorator.php │ ├── ItemDecorator.php │ ├── ItemElementsDecorator.php │ ├── ItemLabelDecorator.php │ ├── ItemRouteDecorator.php │ └── MenuBuilder.php ├── Message ├── FlashMessages.php ├── RequestStackFlashMessages.php └── SessionFlashMessages.php ├── Model └── PositionableInterface.php ├── README.md ├── Request └── Parameters.php ├── ResourceRepository ├── Form │ └── ResourceTypeExtension.php └── TranslatableMapBuilder.php ├── Resources ├── config │ ├── resource_repository_translatable.xml │ ├── routing │ │ └── admin.yaml │ └── services.xml ├── doc │ ├── admin_dependent_elements.md │ ├── admin_element.md │ ├── admin_element_batch.md │ ├── admin_element_crud.md │ ├── admin_element_display.md │ ├── admin_element_form.md │ ├── admin_element_list.md │ ├── admin_element_resource.md │ ├── admin_panel_translation.md │ ├── admin_positionable.md │ ├── admin_tree.md │ ├── configuration.md │ ├── contexts.md │ ├── embedding_element.md │ ├── events.md │ ├── home_page.md │ ├── how_to_create_edit_link_at_list.md │ ├── index.md │ ├── installation.md │ └── menu.md ├── public │ ├── css │ │ └── bootstrap.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ └── js │ │ ├── bootstrap.min.js │ │ ├── collection.js │ │ ├── jquery-1.11.2.min.js │ │ └── require.js ├── translations │ ├── FSiAdminBundle.en.yml │ └── FSiAdminBundle.pl.yml └── views │ ├── Admin │ ├── index.html.twig │ ├── main_menu_theme.html.twig │ └── tools_menu_theme.html.twig │ ├── CRUD │ ├── datagrid.html.twig │ ├── datagrid_edit_form.html.twig │ ├── datasource.html.twig │ └── list.html.twig │ ├── Display │ └── display.html.twig │ ├── Form │ ├── form.html.twig │ └── form_theme.html.twig │ ├── List │ └── list.html.twig │ ├── Resource │ └── resource.html.twig │ ├── base.html.twig │ └── flash_messages.html.twig ├── Translatable ├── DataGrid │ └── Extension │ │ └── DefaultLocaleExtension.php ├── EventSubscriber │ └── RequestContextLocaleListener.php ├── Form │ ├── DefaultTranslation.php │ ├── Extension │ │ └── TranslatableExtension.php │ ├── Extractor │ │ ├── FormDataClassExtractor.php │ │ └── FormDataExtractor.php │ ├── FormTranslatableData.php │ ├── PropertyTranslatableData.php │ ├── TranslatableFormDataExtractor.php │ └── TranslatablePropertyBuilder.php └── Menu │ └── Voter │ └── TranslatableElementVoter.php ├── Twig ├── MessageTwigExtension.php └── TranslatableExtension.php ├── UPGRADE-1.1.md ├── UPGRADE-2.1.md ├── UPGRADE-3.0.md ├── behat.yml ├── composer.json ├── docker-compose.yml ├── features ├── admin_panel_main_page.feature ├── change_admin_panel_language.feature ├── crud │ ├── crud_list.feature │ ├── crud_list_create.feature │ ├── crud_list_custom_templates.feature │ ├── crud_list_delete.feature │ ├── crud_list_edit.feature │ ├── crud_list_edit_at_list.feature │ ├── crud_list_filtering.feature │ ├── crud_list_pagination.feature │ ├── crud_list_sorting.feature │ └── crud_results_per_page.feature ├── delete │ └── list_delete.feature ├── dependent_crud │ ├── dependent_crud_list.feature │ ├── dependent_crud_list_create.feature │ ├── dependent_crud_list_delete.feature │ ├── dependent_crud_list_edit.feature │ ├── dependent_crud_list_edit_at_list.feature │ ├── dependent_crud_list_filtering.feature │ ├── dependent_crud_list_pagination.feature │ ├── dependent_crud_list_sorting.feature │ └── dependent_crud_results_per_page.feature ├── display.feature ├── fixtures │ └── project │ │ ├── .gitignore │ │ ├── bin │ │ └── console │ │ ├── config │ │ ├── admin_menu.yaml │ │ ├── config.yaml │ │ ├── doctrine │ │ │ ├── Category.orm.xml │ │ │ ├── News.orm.xml │ │ │ ├── Node.orm.xml │ │ │ ├── Person.orm.xml │ │ │ ├── Resource.orm.xml │ │ │ ├── Subscriber.orm.xml │ │ │ ├── Tag.orm.xml │ │ │ └── TagElement.orm.xml │ │ ├── framework_44.yaml │ │ ├── framework_54.yaml │ │ ├── resource_map.yaml │ │ └── routing.yaml │ │ ├── src │ │ ├── AppKernel.php │ │ └── FixturesBundle │ │ │ ├── Admin │ │ │ ├── AboutUsPage.php │ │ │ ├── Category.php │ │ │ ├── CategoryNews.php │ │ │ ├── CategoryNewsDisplay.php │ │ │ ├── CustomNews.php │ │ │ ├── CustomSubscriber.php │ │ │ ├── DTOFormElement.php │ │ │ ├── DisplayNews.php │ │ │ ├── News.php │ │ │ ├── Node.php │ │ │ ├── Person.php │ │ │ ├── Structure │ │ │ │ └── HomePage.php │ │ │ ├── Subscriber.php │ │ │ ├── SubscriberDelete.php │ │ │ └── SubscriberForm.php │ │ │ ├── CustomAdmin │ │ │ └── Contact.php │ │ │ ├── DTO │ │ │ └── Model.php │ │ │ ├── DataGrid │ │ │ └── NewsDataGridBuilder.php │ │ │ ├── DataSource │ │ │ └── NewsDataSourceBuilder.php │ │ │ ├── DependencyInjection │ │ │ └── FSiFixturesExtension.php │ │ │ ├── Entity │ │ │ ├── Category.php │ │ │ ├── News.php │ │ │ ├── Node.php │ │ │ ├── Person.php │ │ │ ├── Resource.php │ │ │ ├── Subscriber.php │ │ │ ├── Tag.php │ │ │ └── TagElement.php │ │ │ ├── FSiFixturesBundle.php │ │ │ ├── Form │ │ │ ├── NewsType.php │ │ │ ├── TagElementType.php │ │ │ └── TagType.php │ │ │ └── Resources │ │ │ ├── config │ │ │ └── services.xml │ │ │ └── views │ │ │ └── Admin │ │ │ ├── custom_form.html.twig │ │ │ ├── custom_list.html.twig │ │ │ ├── subscriber_custom_list.html.twig │ │ │ └── subscriber_list.html.twig │ │ ├── translations │ │ └── messages.en.yml │ │ └── web │ │ ├── .htaccess │ │ ├── app_test.php │ │ └── files │ │ └── .gitkeep ├── form │ ├── collections.feature │ ├── form.feature │ └── nested_collections.feature ├── list │ ├── list.feature │ ├── list_custom_templates.feature │ ├── list_filtering.feature │ ├── list_pagination.feature │ ├── list_sorting.feature │ └── results_per_page.feature └── resource.feature ├── phpcs.xml ├── phpstan.neon └── spec ├── FSi └── Bundle │ └── AdminBundle │ ├── Admin │ ├── CRUD │ │ ├── Context │ │ │ ├── BatchElementContextSpec.php │ │ │ ├── DeleteElementContextSpec.php │ │ │ ├── FormElementContextSpec.php │ │ │ ├── ListElementContextSpec.php │ │ │ └── Request │ │ │ │ ├── BatchFormSubmitHandlerSpec.php │ │ │ │ ├── BatchFormValidRequestHandlerSpec.php │ │ │ │ ├── DataGridBindDataHandlerSpec.php │ │ │ │ ├── DataGridSetDataHandlerSpec.php │ │ │ │ ├── DataSourceBindParametersHandlerSpec.php │ │ │ │ ├── DeleteRequestHandlerSpec.php │ │ │ │ ├── FormSubmitHandlerSpec.php │ │ │ │ └── FormValidRequestHandlerSpec.php │ │ ├── DependentBatchElementSpec.php │ │ ├── DependentCRUDElementSpec.php │ │ ├── DependentFormElementSpec.php │ │ ├── DependentListElementSpec.php │ │ ├── GenericBatchElementSpec.php │ │ ├── GenericCRUDElementSpec.php │ │ ├── GenericFormElementSpec.php │ │ └── GenericListElementSpec.php │ ├── Context │ │ └── ContextManagerSpec.php │ ├── Display │ │ └── Context │ │ │ └── DisplayContextSpec.php │ ├── Manager │ │ └── ElementCollectionVisitorSpec.php │ ├── ManagerSpec.php │ └── ResourceRepository │ │ ├── Context │ │ ├── Request │ │ │ ├── FormSubmitHandlerSpec.php │ │ │ └── FormValidRequestHandlerSpec.php │ │ └── ResourceRepositoryContextSpec.php │ │ └── ResourceFormBuilderSpec.php │ ├── Controller │ ├── AdminControllerSpec.php │ ├── BatchControllerSpec.php │ ├── DisplayControllerSpec.php │ ├── FormControllerSpec.php │ ├── ListControllerSpec.php │ ├── PositionableControllerSpec.php │ ├── ReorderTreeControllerSpec.php │ └── ResourceControllerSpec.php │ ├── DataGrid │ └── Extension │ │ └── Admin │ │ └── ColumnTypeExtension │ │ ├── BatchActionExtensionSpec.php │ │ └── ElementActionExtensionSpec.php │ ├── DependencyInjection │ └── Compiler │ │ ├── ResourceRepositoryPassSpec.php │ │ └── TwigGlobalsPassSpec.php │ ├── Display │ ├── Property │ │ └── Formatter │ │ │ ├── BooleanSpec.php │ │ │ ├── CallbackSpec.php │ │ │ ├── CollectionSpec.php │ │ │ ├── DateTimeSpec.php │ │ │ └── EmptyValueSpec.php │ ├── PropertyAccessDisplaySpec.php │ └── SimpleDisplaySpec.php │ ├── Doctrine │ └── Admin │ │ ├── BatchElementSpec.php │ │ ├── CRUDElementSpec.php │ │ ├── DeleteElementSpec.php │ │ ├── DependentBatchElementSpec.php │ │ ├── DependentCRUDElementSpec.php │ │ ├── DependentDeleteElementSpec.php │ │ ├── DependentFormElementSpec.php │ │ ├── DependentListElementSpec.php │ │ ├── FormElementSpec.php │ │ ├── ListElementSpec.php │ │ └── ResourceElementSpec.php │ ├── EventSubscriber │ ├── CleanUpMenuSubscriberSpec.php │ ├── LocaleMenuSubscriberSpec.php │ ├── LocaleSubscriberSpec.php │ ├── MainMenuSubscriberSpec.php │ ├── MessagesSubscriberSpec.php │ ├── admin_menu.yml │ └── invalid_admin_menu.yml │ ├── FSiAdminBundleSpec.php │ ├── Factory │ ├── ProductionLineSpec.php │ └── Worker │ │ ├── DoctrineWorkerSpec.php │ │ ├── FormWorkerSpec.php │ │ ├── ListWorkerSpec.php │ │ ├── LocaleProviderWorkerSpec.php │ │ └── RequestStackWorkerSpec.php │ └── Menu │ ├── Builder │ └── MenuBuilderSpec.php │ ├── Item │ ├── ElementItemSpec.php │ └── ItemSpec.php │ └── KnpMenu │ ├── ElementVoterSpec.php │ └── MenuBuilderSpec.php └── fixtures ├── Admin ├── CRUDElement.php ├── CustomClass.php ├── DoctrineElement.php ├── RequestStackAwareElement.php └── SimpleAdminElement.php ├── CustomAdmin └── SimpleAdminElement.php ├── Doctrine ├── MyBatchElement.php ├── MyCrudElement.php ├── MyDeleteElement.php ├── MyDependentBatchElement.php ├── MyDependentCrudElement.php ├── MyDependentDeleteElement.php ├── MyDependentFormElement.php ├── MyDependentListElement.php ├── MyFormElement.php └── MyListElement.php ├── Entity └── Resource.php ├── MyBatch.php ├── MyBundle.php ├── MyCRUD.php ├── MyDependentBatch.php ├── MyDependentCRUD.php ├── MyDependentForm.php ├── MyDependentList.php ├── MyForm.php ├── MyList.php ├── MyResource.php └── MyResourceElement.php /.gitignore: -------------------------------------------------------------------------------- 1 | /features/fixtures/project/var 2 | /vendor 3 | composer.lock 4 | .phpcs-cache 5 | -------------------------------------------------------------------------------- /Admin/CRUD/BatchElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\LocaleProviderAware; 15 | use FSi\Bundle\AdminBundle\Admin\RedirectableElement; 16 | 17 | /** 18 | * @template T of array|object 19 | * @template-extends DataIndexerElement 20 | */ 21 | interface BatchElement extends DataIndexerElement, LocaleProviderAware, RedirectableElement 22 | { 23 | /** 24 | * @param T $data 25 | */ 26 | public function apply($data): void; 27 | } 28 | -------------------------------------------------------------------------------- /Admin/CRUD/CRUDElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | /** 15 | * @template T of array|object 16 | * @template TSaveDTO of array|object 17 | * @template-default TSaveDTO=T 18 | * @template-extends DeleteElement 19 | * @template-extends FormElement 20 | * @template-extends ListElement 21 | */ 22 | interface CRUDElement extends ListElement, FormElement, DeleteElement 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /Admin/CRUD/Context/CRUDFormElementContext.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD\Context; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\CRUDElement; 15 | use FSi\Bundle\AdminBundle\Admin\Element; 16 | 17 | class CRUDFormElementContext extends FormElementContext 18 | { 19 | protected function supportsElement(Element $element): bool 20 | { 21 | return $element instanceof CRUDElement; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Admin/CRUD/Context/CRUDListElementContext.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD\Context; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\CRUDElement; 15 | use FSi\Bundle\AdminBundle\Admin\Element; 16 | 17 | class CRUDListElementContext extends ListElementContext 18 | { 19 | protected function supportsElement(Element $element): bool 20 | { 21 | return $element instanceof CRUDElement; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Admin/CRUD/Context/DeleteElementContext.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD\Context; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\DeleteElement; 15 | use FSi\Bundle\AdminBundle\Admin\Element; 16 | 17 | class DeleteElementContext extends BatchElementContext 18 | { 19 | public static function getPriority(): int 20 | { 21 | return 10; 22 | } 23 | 24 | protected function supportsElement(Element $element): bool 25 | { 26 | return $element instanceof DeleteElement; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Admin/CRUD/Context/Request/BatchFormSubmitHandler.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD\Context\Request; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Context\Request\AbstractFormSubmitHandler; 15 | use FSi\Bundle\AdminBundle\Event\BatchRequestPostSubmitEvent; 16 | use FSi\Bundle\AdminBundle\Event\BatchRequestPreSubmitEvent; 17 | use FSi\Bundle\AdminBundle\Event\FormEvent; 18 | 19 | class BatchFormSubmitHandler extends AbstractFormSubmitHandler 20 | { 21 | protected function getPreSubmitEvent(FormEvent $event): FormEvent 22 | { 23 | return BatchRequestPreSubmitEvent::fromOtherEvent($event); 24 | } 25 | 26 | protected function getPostSubmitEvent(FormEvent $event): FormEvent 27 | { 28 | return BatchRequestPostSubmitEvent::fromOtherEvent($event); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Admin/CRUD/Context/Request/FormSubmitHandler.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD\Context\Request; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Context\Request\AbstractFormSubmitHandler; 15 | use FSi\Bundle\AdminBundle\Event\FormEvent; 16 | use FSi\Bundle\AdminBundle\Event\FormRequestPostSubmitEvent; 17 | use FSi\Bundle\AdminBundle\Event\FormRequestPreSubmitEvent; 18 | 19 | class FormSubmitHandler extends AbstractFormSubmitHandler 20 | { 21 | protected function getPreSubmitEvent(FormEvent $event): FormEvent 22 | { 23 | return FormRequestPreSubmitEvent::fromOtherEvent($event); 24 | } 25 | 26 | protected function getPostSubmitEvent(FormEvent $event): FormEvent 27 | { 28 | return FormRequestPostSubmitEvent::fromOtherEvent($event); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Admin/CRUD/DataIndexerElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use FSi\Component\DataIndexer\DataIndexerInterface; 16 | 17 | /** 18 | * @template T of array|object 19 | */ 20 | interface DataIndexerElement extends Element 21 | { 22 | /** 23 | * @return DataIndexerInterface 24 | */ 25 | public function getDataIndexer(): DataIndexerInterface; 26 | } 27 | -------------------------------------------------------------------------------- /Admin/CRUD/DeleteElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | /** 15 | * @template T of array|object 16 | * @template-extends BatchElement 17 | */ 18 | interface DeleteElement extends BatchElement 19 | { 20 | /** 21 | * @param T $data 22 | */ 23 | public function delete($data): void; 24 | } 25 | -------------------------------------------------------------------------------- /Admin/CRUD/DependentBatchElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of array|object 19 | * @template TParent of array|object 20 | * @template-extends GenericBatchElement 21 | * @template-implements DependentElement 22 | */ 23 | abstract class DependentBatchElement extends GenericBatchElement implements DependentElement 24 | { 25 | /** @use DependentElementImpl */ 26 | use DependentElementImpl; 27 | 28 | public function getRouteParameters(): array 29 | { 30 | return array_merge( 31 | parent::getRouteParameters(), 32 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Admin/CRUD/DependentCRUDElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of array|object 19 | * @template TSaveDTO of array|object 20 | * @template TParent of array|object 21 | * @template-default TSaveDTO=T 22 | * @template-extends GenericCRUDElement 23 | * @template-implements DependentElement 24 | */ 25 | abstract class DependentCRUDElement extends GenericCRUDElement implements DependentElement 26 | { 27 | /** @use DependentElementImpl */ 28 | use DependentElementImpl; 29 | 30 | public function getRouteParameters(): array 31 | { 32 | return array_merge( 33 | parent::getRouteParameters(), 34 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Admin/CRUD/DependentDeleteElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of array|object 19 | * @template TParent of array|object 20 | * @template-extends GenericDeleteElement 21 | * @template-implements DependentElement 22 | */ 23 | abstract class DependentDeleteElement extends GenericDeleteElement implements DependentElement 24 | { 25 | /** @use DependentElementImpl */ 26 | use DependentElementImpl; 27 | 28 | public function getRouteParameters(): array 29 | { 30 | return array_merge( 31 | parent::getRouteParameters(), 32 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Admin/CRUD/DependentFormElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of array|object 19 | * @template TSaveDTO of array|object 20 | * @template TParent of array|object 21 | * @template-default TSaveDTO=T 22 | * @template-extends GenericFormElement 23 | * @template-implements DependentElement 24 | */ 25 | abstract class DependentFormElement extends GenericFormElement implements DependentElement 26 | { 27 | /** @use DependentElementImpl */ 28 | use DependentElementImpl; 29 | 30 | public function getRouteParameters(): array 31 | { 32 | return array_merge( 33 | parent::getRouteParameters(), 34 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Admin/CRUD/DependentListElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of array|object 19 | * @template TParent of array|object 20 | * @template-extends GenericListElement 21 | * @template-implements DependentElement 22 | */ 23 | abstract class DependentListElement extends GenericListElement implements DependentElement 24 | { 25 | /** @use DependentElementImpl */ 26 | use DependentElementImpl; 27 | 28 | public function getRouteParameters(): array 29 | { 30 | return array_merge( 31 | parent::getRouteParameters(), 32 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Admin/CRUD/GenericDeleteElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use phpDocumentor\Reflection\DocBlock\Tags\Generic; 15 | 16 | /** 17 | * @template T of array|object 18 | * @template-extends GenericBatchElement 19 | * @template-implements DeleteElement 20 | */ 21 | abstract class GenericDeleteElement extends GenericBatchElement implements DeleteElement 22 | { 23 | public function apply($object): void 24 | { 25 | $this->delete($object); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Admin/CRUD/ListElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\CRUD; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\LocaleProviderAware; 15 | use FSi\Component\DataGrid\DataGridFactoryInterface; 16 | use FSi\Component\DataGrid\DataGridInterface; 17 | use FSi\Component\DataSource\DataSourceFactoryInterface; 18 | use FSi\Component\DataSource\DataSourceInterface; 19 | 20 | /** 21 | * @template T of array|object 22 | * @template-extends DataIndexerElement 23 | */ 24 | interface ListElement extends DataIndexerElement, LocaleProviderAware 25 | { 26 | public function createDataGrid(): DataGridInterface; 27 | 28 | public function setDataGridFactory(DataGridFactoryInterface $factory): void; 29 | 30 | /** 31 | * @return DataSourceInterface 32 | */ 33 | public function createDataSource(): DataSourceInterface; 34 | 35 | public function setDataSourceFactory(DataSourceFactoryInterface $factory): void; 36 | 37 | public function saveDataGrid(): void; 38 | } 39 | -------------------------------------------------------------------------------- /Admin/Context/ContextInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Context; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | 18 | interface ContextInterface 19 | { 20 | public static function getPriority(): int; 21 | 22 | public function supports(string $route, Element $element): bool; 23 | 24 | public function setElement(Element $element): void; 25 | 26 | public function handleRequest(Request $request): ?Response; 27 | 28 | public function getTemplateName(): ?string; 29 | 30 | /** 31 | * @return array 32 | */ 33 | public function getData(): array; 34 | } 35 | -------------------------------------------------------------------------------- /Admin/Context/ContextManager.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Context; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | 16 | class ContextManager 17 | { 18 | /** 19 | * @var array 20 | */ 21 | protected array $contexts; 22 | 23 | /** 24 | * @param iterable $contexts 25 | */ 26 | public function __construct(iterable $contexts) 27 | { 28 | $this->contexts = []; 29 | 30 | foreach ($contexts as $context) { 31 | $this->addContext($context); 32 | } 33 | } 34 | 35 | public function addContext(ContextInterface $builder): void 36 | { 37 | $this->contexts[] = $builder; 38 | } 39 | 40 | public function createContext(string $route, Element $element): ?ContextInterface 41 | { 42 | foreach ($this->contexts as $context) { 43 | if ($context->supports($route, $element)) { 44 | $context->setElement($element); 45 | return $context; 46 | } 47 | } 48 | 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Admin/Context/Request/AbstractHandler.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Context\Request; 13 | 14 | use Psr\EventDispatcher\EventDispatcherInterface; 15 | 16 | abstract class AbstractHandler implements HandlerInterface 17 | { 18 | protected EventDispatcherInterface $eventDispatcher; 19 | 20 | public function __construct(EventDispatcherInterface $eventDispatcher) 21 | { 22 | $this->eventDispatcher = $eventDispatcher; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Admin/Context/Request/HandlerInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Context\Request; 13 | 14 | use FSi\Bundle\AdminBundle\Event\AdminEvent; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | 18 | interface HandlerInterface 19 | { 20 | public function handleRequest(AdminEvent $event, Request $request): ?Response; 21 | } 22 | -------------------------------------------------------------------------------- /Admin/DependentElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\DataIndexerElement; 15 | 16 | /** 17 | * @template TParent of array|object 18 | */ 19 | interface DependentElement extends Element, RequestStackAware 20 | { 21 | public const PARENT_REQUEST_PARAMETER = 'parent'; 22 | 23 | /** 24 | * ID of parent element 25 | */ 26 | public function getParentId(): string; 27 | 28 | /** 29 | * @param DataIndexerElement $element 30 | */ 31 | public function setParentElement(DataIndexerElement $element): void; 32 | 33 | /** 34 | * @return TParent|null 35 | */ 36 | public function getParentObject(); 37 | } 38 | -------------------------------------------------------------------------------- /Admin/Display/Context/Request/Handler.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Display\Context\Request; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Context\Request\AbstractHandler; 15 | use FSi\Bundle\AdminBundle\Event\AdminEvent; 16 | use FSi\Bundle\AdminBundle\Event\DisplayEvent; 17 | use FSi\Bundle\AdminBundle\Event\DisplayResponsePreRenderEvent; 18 | use FSi\Bundle\AdminBundle\Exception\RequestHandlerException; 19 | use Symfony\Component\HttpFoundation\Request; 20 | use Symfony\Component\HttpFoundation\Response; 21 | 22 | class Handler extends AbstractHandler 23 | { 24 | public function handleRequest(AdminEvent $event, Request $request): ?Response 25 | { 26 | if (false === $event instanceof DisplayEvent) { 27 | throw new RequestHandlerException(sprintf('%s requires DisplayEvent', get_class($this))); 28 | } 29 | 30 | $responsePreRenderEvent = DisplayResponsePreRenderEvent::fromOtherEvent($event); 31 | $this->eventDispatcher->dispatch($responsePreRenderEvent); 32 | 33 | return $responsePreRenderEvent->getResponse(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Admin/Display/DependentDisplayElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Display; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template TParent of array|object 19 | * @template-extends GenericDisplayElement 20 | * @template-implements DependentElement 21 | */ 22 | abstract class DependentDisplayElement extends GenericDisplayElement implements DependentElement 23 | { 24 | /** @use DependentElementImpl */ 25 | use DependentElementImpl; 26 | 27 | public function getRouteParameters(): array 28 | { 29 | return array_merge( 30 | parent::getRouteParameters(), 31 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Admin/Display/Element.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Display; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\DataIndexerElement; 15 | use FSi\Bundle\AdminBundle\Admin\LocaleProviderAware; 16 | use FSi\Bundle\AdminBundle\Display\Display; 17 | 18 | /** 19 | * @template T of array|object 20 | * @template-extends DataIndexerElement 21 | */ 22 | interface Element extends DataIndexerElement, LocaleProviderAware 23 | { 24 | /** 25 | * @param T $data 26 | * @return Display 27 | */ 28 | public function createDisplay($data): Display; 29 | } 30 | -------------------------------------------------------------------------------- /Admin/Element.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin; 13 | 14 | use Symfony\Component\OptionsResolver\OptionsResolver; 15 | 16 | interface Element 17 | { 18 | public function getId(): string; 19 | 20 | public function getRoute(): string; 21 | 22 | /** 23 | * @return array 24 | */ 25 | public function getRouteParameters(): array; 26 | 27 | public function configureOptions(OptionsResolver $resolver): void; 28 | 29 | /** 30 | * @param string $name 31 | * @return mixed 32 | */ 33 | public function getOption(string $name); 34 | 35 | /** 36 | * @return array 37 | */ 38 | public function getOptions(): array; 39 | 40 | public function hasOption(string $name): bool; 41 | } 42 | -------------------------------------------------------------------------------- /Admin/LocaleProviderAware.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin; 13 | 14 | use FSi\Component\Translatable\LocaleProvider; 15 | 16 | interface LocaleProviderAware 17 | { 18 | public function setLocaleProvider(LocaleProvider $localeProvider): void; 19 | } 20 | -------------------------------------------------------------------------------- /Admin/Manager/DependentElementsVisitor.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Manager; 13 | 14 | use Assert\Assertion; 15 | use FSi\Bundle\AdminBundle\Admin\CRUD\DataIndexerElement; 16 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 17 | use FSi\Bundle\AdminBundle\Admin\ManagerInterface; 18 | 19 | class DependentElementsVisitor implements Visitor 20 | { 21 | public static function getPriority(): int 22 | { 23 | return 0; 24 | } 25 | 26 | public function visitManager(ManagerInterface $manager): void 27 | { 28 | foreach ($manager->getElements() as $element) { 29 | if (false === $element instanceof DependentElement) { 30 | continue; 31 | } 32 | 33 | /** @var DataIndexerElement|object> $parentElement */ 34 | $parentElement = $manager->getElement($element->getParentId()); 35 | Assertion::isInstanceOf($parentElement, DataIndexerElement::class); 36 | 37 | $element->setParentElement($parentElement); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Admin/Manager/Visitor.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\Manager; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\ManagerInterface; 15 | 16 | interface Visitor 17 | { 18 | public static function getPriority(): int; 19 | public function visitManager(ManagerInterface $manager): void; 20 | } 21 | -------------------------------------------------------------------------------- /Admin/ManagerInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Manager\Visitor; 15 | 16 | interface ManagerInterface 17 | { 18 | public function addElement(Element $element): void; 19 | 20 | public function hasElement(string $id): bool; 21 | 22 | public function getElement(string $id): Element; 23 | 24 | public function removeElement(string $id): void; 25 | 26 | /** 27 | * @return array 28 | */ 29 | public function getElements(): array; 30 | } 31 | -------------------------------------------------------------------------------- /Admin/RedirectableElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin; 13 | 14 | interface RedirectableElement extends Element 15 | { 16 | public function getSuccessRoute(): string; 17 | 18 | /** 19 | * @return array 20 | */ 21 | public function getSuccessRouteParameters(): array; 22 | } 23 | -------------------------------------------------------------------------------- /Admin/RequestStackAware.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin; 13 | 14 | use Symfony\Component\HttpFoundation\RequestStack; 15 | 16 | interface RequestStackAware 17 | { 18 | public function setRequestStack(RequestStack $requestStack): void; 19 | } 20 | -------------------------------------------------------------------------------- /Admin/ResourceRepository/Context/Request/FormSubmitHandler.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\ResourceRepository\Context\Request; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Context\Request\AbstractFormSubmitHandler; 15 | use FSi\Bundle\AdminBundle\Event\FormEvent; 16 | use FSi\Bundle\AdminBundle\Event\FormRequestPostSubmitEvent; 17 | use FSi\Bundle\AdminBundle\Event\FormRequestPreSubmitEvent; 18 | 19 | class FormSubmitHandler extends AbstractFormSubmitHandler 20 | { 21 | protected function getPreSubmitEvent(FormEvent $event): FormEvent 22 | { 23 | return FormRequestPreSubmitEvent::fromOtherEvent($event); 24 | } 25 | 26 | protected function getPostSubmitEvent(FormEvent $event): FormEvent 27 | { 28 | return FormRequestPostSubmitEvent::fromOtherEvent($event); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Admin/ResourceRepository/Element.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Admin\ResourceRepository; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\LocaleProviderAware; 15 | use FSi\Bundle\AdminBundle\Admin\RedirectableElement; 16 | use FSi\Bundle\ResourceRepositoryBundle\Model\ResourceValue; 17 | use FSi\Bundle\ResourceRepositoryBundle\Model\ResourceValueRepository; 18 | 19 | interface Element extends LocaleProviderAware, RedirectableElement 20 | { 21 | public function getKey(): string; 22 | 23 | /** 24 | * @return array 25 | */ 26 | public function getResourceFormOptions(): array; 27 | 28 | public function save(ResourceValue $resource): void; 29 | 30 | public function getResourceValueRepository(): ResourceValueRepository; 31 | } 32 | -------------------------------------------------------------------------------- /Behat/Context/DisplayContext.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Context; 13 | 14 | use Behat\Gherkin\Node\TableNode; 15 | use FSi\Bundle\AdminBundle\Behat\Element\Display; 16 | 17 | class DisplayContext extends AbstractContext 18 | { 19 | /** 20 | * @Given /^I should see display with following fields$/ 21 | */ 22 | public function iShouldSeeDisplayWithFollowingFields(TableNode $table): void 23 | { 24 | $display = $this->getElement(Display::class); 25 | foreach ($table->getHash() as $row) { 26 | expect($display->hasFieldWithName($row['Field name']))->toBe(true); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Behat/Element/Display.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Element; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Element\Element; 15 | 16 | class Display extends Element 17 | { 18 | public function hasFieldWithName($fieldName): bool 19 | { 20 | $selector = sprintf('table.table.table-bordered tr td:first-child:contains("%s")', $fieldName); 21 | 22 | return $this->getDocument()->find('css', $selector) !== null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Behat/Element/ListResultsElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Element; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Element\Element; 15 | 16 | class ListResultsElement extends Element 17 | { 18 | public function setElementsPerPage(int $elementsCount): void 19 | { 20 | $this->getDocument()->find('css', 'div#list-results ul[role="menu"]')->clickLink((string) $elementsCount); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Behat/Element/Messages.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Element; 13 | 14 | use Exception; 15 | use FriendsOfBehat\PageObjectExtension\Element\Element; 16 | 17 | class Messages extends Element 18 | { 19 | public function getMessageText(string $type): string 20 | { 21 | $alerts = $this->getElement('messages')->findAll('css', sprintf('.alert-%s', $type)); 22 | if (count($alerts) < 1) { 23 | throw new Exception(sprintf("Unable to find any alert with type '%s'", $type)); 24 | } 25 | 26 | return implode("\n", array_map(static function ($alert) { 27 | return $alert->getText(); 28 | }, $alerts)); 29 | } 30 | 31 | protected function getDefinedElements(): array 32 | { 33 | return [ 34 | 'messages' => '#messages', 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Behat/Element/Pagination.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Element; 13 | 14 | use Behat\Mink\Element\NodeElement; 15 | use FriendsOfBehat\PageObjectExtension\Element\Element; 16 | 17 | class Pagination extends Element 18 | { 19 | public function hasLink(string $selector): bool 20 | { 21 | return $this->getPagination()->hasLink($selector); 22 | } 23 | 24 | public function clickLink(string $selector): void 25 | { 26 | $this->getPagination()->clickLink($selector); 27 | } 28 | 29 | public function isDisabled(string $selector): bool 30 | { 31 | return $this->getPagination()->findLink($selector)->getParent()->hasClass('disabled'); 32 | } 33 | 34 | public function isCurrentPage(string $selector): bool 35 | { 36 | return $this->getPagination()->findLink($selector)->getParent()->hasClass('active'); 37 | } 38 | 39 | private function getPagination(): NodeElement 40 | { 41 | return $this->getDocument()->find('css', 'ul.pagination'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Behat/Page/CategoryList.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CategoryList extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("List of elements")')) { 23 | throw new UnexpectedPageException( 24 | "{$this->getUrl($urlParameters)} page is missing \"List of elements\" header" 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/list/category'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/CategoryNewsCreate.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CategoryNewsCreate extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("New element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf("%s page is missing \"New element\" header", $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . "/admin/en/form/category_news?parent={$urlParameters['parent_id']}"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/CategoryNewsEdit.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CategoryNewsEdit extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("Edit element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf("%s page is missing \"Edit element\" header", $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') 32 | . "/admin/en/form/category_news/{$urlParameters['id']}?parent={$urlParameters['parent_id']}"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Behat/Page/CategoryNewsList.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CategoryNewsList extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("List of elements")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "List of elements" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/list/category_news' 32 | . (($urlParameters['parent_id'] ?? null) ? "?parent={$urlParameters['parent_id']}" : ''); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Behat/Page/CustomNewsCreate.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CustomNewsCreate extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', 'h1#page-header:contains("Custom form")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Custom form" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/form/custom_news'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/CustomNewsEdit.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CustomNewsEdit extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', 'h1#page-header:contains("Custom form")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Custom form" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . "/admin/en/form/custom_news/{$urlParameters['id']}"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/CustomNewsList.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CustomNewsList extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', 'h1#page-header:contains("Custom list")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Custom list" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/list/custom_news'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/CustomSubscribersList.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class CustomSubscribersList extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', 'h1#page-header:contains("Custom subscribers list")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Custom subscribers list" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/list/custom_subscriber'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/DTOForm.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class DTOForm extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("New element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "New element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/form/dto_form'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/DefaultPage.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | class DefaultPage extends Page 15 | { 16 | protected function getUrl(array $urlParameters = []): string 17 | { 18 | return $this->getParameter('base_url') . '/'; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Behat/Page/HomePageEdit.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class HomePageEdit extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("Edit resources")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Resource edit" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/resource/home_page'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/NewsCreate.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class NewsCreate extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("New element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "New element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/form/news'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/NewsDisplay.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class NewsDisplay extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("Display element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Display element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . "/admin/en/display/news/{$urlParameters['id']}"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/NewsEdit.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class NewsEdit extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("Edit element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "New element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . "/admin/en/form/news/{$urlParameters['id']}"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/NewsList.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class NewsList extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("List of elements")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "List of elements" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/list/news'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/PersonAddForm.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class PersonAddForm extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("New element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "New element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/form/person'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/PersonEditForm.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class PersonEditForm extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("Edit element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Edit element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . "/admin/en/form/person/{$urlParameters['id']}"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/PersonList.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class PersonList extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("List of elements")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "List of elements" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/list/person'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/SubscriberEdit.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class SubscriberEdit extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("Edit element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "Edit element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . "/admin/en/form/subscriber_form/{$urlParameters['id']}"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/SubscriberForm.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class SubscriberForm extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("New element")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "New element" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/form/subscriber_form'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Behat/Page/SubscribersList.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Behat\Page; 13 | 14 | use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; 15 | 16 | class SubscribersList extends Page 17 | { 18 | public function verify(array $urlParameters = []): void 19 | { 20 | parent::verify($urlParameters); 21 | 22 | if (false === $this->getDocument()->has('css', '#page-header:contains("List of elements")')) { 23 | throw new UnexpectedPageException( 24 | sprintf('%s page is missing "List of elements" header', $this->getUrl($urlParameters)) 25 | ); 26 | } 27 | } 28 | 29 | protected function getUrl(array $urlParameters = []): string 30 | { 31 | return $this->getParameter('base_url') . '/admin/en/list/subscriber'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CHANGELOG-3.1.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for 3.1 2 | 3 | This document covers the extent of changes done during the transition from 4 | branch 3.0 to 3.1. 5 | 6 | ## Dropped support for Symfony 2.x and FSi packages 1.x 7 | 8 | Supporting the entire range of versions from Symfony 2 to 4 became unmanagable for 9 | Composer due to enormous number of available tags. -------------------------------------------------------------------------------- /Controller/BatchController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Controller; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\BatchElement; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 18 | 19 | use function get_class; 20 | use function sprintf; 21 | 22 | class BatchController extends ControllerAbstract 23 | { 24 | public function batchAction(string $element, Request $request): Response 25 | { 26 | $elementObject = $this->getElement($element); 27 | if (false === $elementObject instanceof BatchElement) { 28 | throw new NotFoundHttpException(sprintf( 29 | 'Admin element with id "%s" should be of class "%s", but it is "%s".', 30 | $element, 31 | BatchElement::class, 32 | get_class($elementObject) 33 | )); 34 | } 35 | 36 | return $this->handleRequest($elementObject, $request, 'fsi_admin_batch'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Controller/DisplayController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Controller; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Display\Element; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 18 | 19 | use function get_class; 20 | use function sprintf; 21 | 22 | class DisplayController extends ControllerAbstract 23 | { 24 | public function displayAction(string $element, Request $request): Response 25 | { 26 | $elementObject = $this->getElement($element); 27 | if (false === $elementObject instanceof Element) { 28 | throw new NotFoundHttpException(sprintf( 29 | 'Admin element with id "%s" should be of class "%s", but it is "%s".', 30 | $element, 31 | Element::class, 32 | get_class($elementObject) 33 | )); 34 | } 35 | 36 | return $this->handleRequest($elementObject, $request, 'fsi_admin_display'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Controller/FormController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Controller; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\FormElement; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 18 | 19 | use function get_class; 20 | use function sprintf; 21 | 22 | class FormController extends ControllerAbstract 23 | { 24 | public function formAction(string $element, Request $request): Response 25 | { 26 | $elementObject = $this->getElement($element); 27 | if (false === $elementObject instanceof FormElement) { 28 | throw new NotFoundHttpException(sprintf( 29 | 'Admin element with id "%s" should be of class "%s", but it is "%s".', 30 | $element, 31 | FormElement::class, 32 | get_class($elementObject) 33 | )); 34 | } 35 | 36 | return $this->handleRequest($elementObject, $request, 'fsi_admin_form'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Controller/ListController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Controller; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\ListElement; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 18 | 19 | use function get_class; 20 | use function sprintf; 21 | 22 | class ListController extends ControllerAbstract 23 | { 24 | public function listAction(string $element, Request $request): Response 25 | { 26 | $elementObject = $this->getElement($element); 27 | if (false === $elementObject instanceof ListElement) { 28 | throw new NotFoundHttpException(sprintf( 29 | 'Admin element with id "%s" should be of class "%s", but it is "%s".', 30 | $element, 31 | ListElement::class, 32 | get_class($elementObject) 33 | )); 34 | } 35 | 36 | return $this->handleRequest($elementObject, $request, 'fsi_admin_list'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Controller/ResourceController.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Controller; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\ResourceRepository\Element; 15 | use Symfony\Component\HttpFoundation\Request; 16 | use Symfony\Component\HttpFoundation\Response; 17 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 18 | 19 | use function get_class; 20 | use function sprintf; 21 | 22 | class ResourceController extends ControllerAbstract 23 | { 24 | public function resourceAction(string $element, Request $request): Response 25 | { 26 | $elementObject = $this->getElement($element); 27 | if (false === $elementObject instanceof Element) { 28 | throw new NotFoundHttpException(sprintf( 29 | 'Admin element with id "%s" should be of class "%s", but it is "%s".', 30 | $element, 31 | Element::class, 32 | get_class($elementObject) 33 | )); 34 | } 35 | 36 | return $this->handleRequest($elementObject, $request, 'fsi_admin_resource'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Display/Display.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Display; 13 | 14 | use FSi\Bundle\AdminBundle\Display\Property\ValueFormatter; 15 | 16 | interface Display 17 | { 18 | /** 19 | * @param mixed $value 20 | * @param string|null $label 21 | * @param array $valueFormatters 22 | */ 23 | public function add($value, ?string $label = null, array $valueFormatters = []): self; 24 | 25 | /** 26 | * @return array 27 | */ 28 | public function getData(): array; 29 | } 30 | -------------------------------------------------------------------------------- /Display/Property/Formatter/Boolean.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use FSi\Bundle\AdminBundle\Display\Property\ValueFormatter; 15 | 16 | class Boolean implements ValueFormatter 17 | { 18 | private string $true; 19 | 20 | private string $false; 21 | 22 | public function __construct(string $true, string $false) 23 | { 24 | $this->true = $true; 25 | $this->false = $false; 26 | } 27 | 28 | /** 29 | * @param mixed $value 30 | * @return mixed|string 31 | */ 32 | public function format($value) 33 | { 34 | if (empty($value) && false === is_bool($value)) { 35 | return $value; 36 | } 37 | 38 | return $value ? $this->true : $this->false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Display/Property/Formatter/Callback.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use FSi\Bundle\AdminBundle\Display\Property\ValueFormatter; 15 | 16 | class Callback implements ValueFormatter 17 | { 18 | /** 19 | * @var callable 20 | */ 21 | private $callable; 22 | 23 | public function __construct(callable $callable) 24 | { 25 | $this->callable = $callable; 26 | } 27 | 28 | /** 29 | * @param mixed $value 30 | * @return mixed 31 | */ 32 | public function format($value) 33 | { 34 | if (empty($value)) { 35 | return $value; 36 | } 37 | 38 | $callable = $this->callable; 39 | 40 | return $callable($value); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Display/Property/Formatter/DateTime.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use DateTimeInterface; 15 | use FSi\Bundle\AdminBundle\Display\Property\ValueFormatter; 16 | 17 | class DateTime implements ValueFormatter 18 | { 19 | private string $format; 20 | 21 | public function __construct(string $format = 'Y-m-d H:i:s') 22 | { 23 | $this->format = $format; 24 | } 25 | 26 | /** 27 | * @param mixed $value 28 | * @return mixed|string 29 | */ 30 | public function format($value) 31 | { 32 | if (empty($value) || false === $value instanceof DateTimeInterface) { 33 | return $value; 34 | } 35 | 36 | return $value->format($this->format); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Display/Property/Formatter/EmptyValue.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use FSi\Bundle\AdminBundle\Display\Property\ValueFormatter; 15 | 16 | class EmptyValue implements ValueFormatter 17 | { 18 | private string $emptyValue; 19 | 20 | public function __construct(string $emptyValue = '-') 21 | { 22 | $this->emptyValue = $emptyValue; 23 | } 24 | 25 | /** 26 | * @param mixed $value 27 | * @return mixed 28 | */ 29 | public function format($value) 30 | { 31 | if (empty($value)) { 32 | return $this->emptyValue; 33 | } 34 | 35 | return $value; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Display/Property/ValueFormatter.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Display\Property; 13 | 14 | interface ValueFormatter 15 | { 16 | /** 17 | * @param mixed $value 18 | * @return mixed 19 | */ 20 | public function format($value); 21 | } 22 | -------------------------------------------------------------------------------- /Display/SimpleDisplay.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Display; 13 | 14 | class SimpleDisplay implements Display 15 | { 16 | /** 17 | * @var array 18 | */ 19 | private array $data = []; 20 | 21 | /** 22 | * {@inheritdoc} 23 | */ 24 | public function add($value, ?string $label = null, array $valueFormatters = []): Display 25 | { 26 | $this->data[] = new Property($value, $label, $valueFormatters); 27 | 28 | return $this; 29 | } 30 | 31 | public function getData(): array 32 | { 33 | return $this->data; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Doctrine/Admin/BatchElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\GenericBatchElement; 15 | 16 | /** 17 | * @template T of object 18 | * @template-extends GenericBatchElement 19 | * @template-implements Element 20 | */ 21 | abstract class BatchElement extends GenericBatchElement implements Element 22 | { 23 | /** @use DataIndexerElementImpl */ 24 | use DataIndexerElementImpl; 25 | } 26 | -------------------------------------------------------------------------------- /Doctrine/Admin/CRUDElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\GenericCRUDElement; 15 | 16 | /** 17 | * @template T of object 18 | * @template TSaveDTO of object 19 | * @template-default TSaveDTO=T 20 | * @template-extends GenericCRUDElement 21 | * @template-implements Element 22 | */ 23 | abstract class CRUDElement extends GenericCRUDElement implements Element 24 | { 25 | /** @use DataIndexerElementImpl */ 26 | use DataIndexerElementImpl; 27 | 28 | public function save($object): void 29 | { 30 | $this->getObjectManager()->persist($object); 31 | $this->getObjectManager()->flush(); 32 | } 33 | 34 | public function saveDataGrid(): void 35 | { 36 | $this->getObjectManager()->flush(); 37 | } 38 | 39 | public function delete($object): void 40 | { 41 | $this->getObjectManager()->remove($object); 42 | $this->getObjectManager()->flush(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Doctrine/Admin/DataIndexerElementImpl.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Component\DataIndexer\DataIndexerInterface; 15 | use FSi\Component\DataIndexer\DoctrineDataIndexer; 16 | 17 | /** 18 | * @template T of object 19 | */ 20 | trait DataIndexerElementImpl 21 | { 22 | /** @use ElementImpl */ 23 | use ElementImpl; 24 | 25 | public function getDataIndexer(): DataIndexerInterface 26 | { 27 | /** @var class-string $className */ 28 | $className = $this->getRepository()->getClassName(); 29 | return new DoctrineDataIndexer($this->registry, $className); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Doctrine/Admin/DeleteElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\GenericDeleteElement; 15 | 16 | /** 17 | * @template T of object 18 | * @template-extends GenericDeleteElement 19 | * @template-implements Element 20 | */ 21 | abstract class DeleteElement extends GenericDeleteElement implements Element 22 | { 23 | /** @use DataIndexerElementImpl */ 24 | use DataIndexerElementImpl; 25 | 26 | public function delete($object): void 27 | { 28 | $this->getObjectManager()->remove($object); 29 | $this->getObjectManager()->flush(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Doctrine/Admin/DependentBatchElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of object 19 | * @template TParent of object 20 | * @template-extends BatchElement 21 | * @template-implements DependentElement 22 | */ 23 | abstract class DependentBatchElement extends BatchElement implements DependentElement 24 | { 25 | /** @use DependentElementImpl */ 26 | use DependentElementImpl; 27 | 28 | public function getRouteParameters(): array 29 | { 30 | return array_merge( 31 | parent::getRouteParameters(), 32 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Doctrine/Admin/DependentCRUDElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of object 19 | * @template TSaveDTO of object 20 | * @template TParent of object 21 | * @template-default TSaveDTO=T 22 | * @template-extends CRUDElement 23 | * @template-implements DependentElement 24 | */ 25 | abstract class DependentCRUDElement extends CRUDElement implements DependentElement 26 | { 27 | /** @use DependentElementImpl */ 28 | use DependentElementImpl; 29 | 30 | public function getRouteParameters(): array 31 | { 32 | return array_merge( 33 | parent::getRouteParameters(), 34 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Doctrine/Admin/DependentDeleteElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of object 19 | * @template TParent of object 20 | * @template-extends DeleteElement 21 | * @template-implements DependentElement 22 | */ 23 | abstract class DependentDeleteElement extends DeleteElement implements DependentElement 24 | { 25 | /** @use DependentElementImpl */ 26 | use DependentElementImpl; 27 | 28 | public function getRouteParameters(): array 29 | { 30 | return array_merge( 31 | parent::getRouteParameters(), 32 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Doctrine/Admin/DependentDisplayElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of object 19 | * @template TParent of object 20 | * @template-extends DisplayElement 21 | * @template-implements DependentElement 22 | */ 23 | abstract class DependentDisplayElement extends DisplayElement implements DependentElement 24 | { 25 | /** @use DependentElementImpl */ 26 | use DependentElementImpl; 27 | 28 | public function getRouteParameters(): array 29 | { 30 | return array_merge( 31 | parent::getRouteParameters(), 32 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Doctrine/Admin/DependentFormElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of object 19 | * @template TSaveDTO of object 20 | * @template TParent of object 21 | * @template-default TSaveDTO=T 22 | * @template-extends FormElement 23 | * @template-implements DependentElement 24 | */ 25 | abstract class DependentFormElement extends FormElement implements DependentElement 26 | { 27 | /** @use DependentElementImpl */ 28 | use DependentElementImpl; 29 | 30 | public function getRouteParameters(): array 31 | { 32 | return array_merge( 33 | parent::getRouteParameters(), 34 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Doctrine/Admin/DependentListElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\DependentElement; 15 | use FSi\Bundle\AdminBundle\Admin\DependentElementImpl; 16 | 17 | /** 18 | * @template T of object 19 | * @template TParent of object 20 | * @template-extends ListElement 21 | * @template-implements DependentElement 22 | */ 23 | abstract class DependentListElement extends ListElement implements DependentElement 24 | { 25 | /** @use DependentElementImpl */ 26 | use DependentElementImpl; 27 | 28 | public function getRouteParameters(): array 29 | { 30 | return array_merge( 31 | parent::getRouteParameters(), 32 | [DependentElement::PARENT_REQUEST_PARAMETER => $this->getParentObjectId()] 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Doctrine/Admin/DisplayElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Display\GenericDisplayElement; 15 | 16 | /** 17 | * @template T of object 18 | * @template-extends GenericDisplayElement 19 | * @template-implements Element 20 | */ 21 | abstract class DisplayElement extends GenericDisplayElement implements Element 22 | { 23 | /** @use DataIndexerElementImpl */ 24 | use DataIndexerElementImpl; 25 | } 26 | -------------------------------------------------------------------------------- /Doctrine/Admin/Element.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use Doctrine\Persistence\ManagerRegistry; 15 | use Doctrine\Persistence\ObjectManager; 16 | use Doctrine\Persistence\ObjectRepository; 17 | 18 | /** 19 | * @template T of object 20 | */ 21 | interface Element 22 | { 23 | /** 24 | * @return class-string 25 | */ 26 | public function getClassName(): string; 27 | 28 | public function getObjectManager(): ObjectManager; 29 | 30 | /** 31 | * @return ObjectRepository 32 | */ 33 | public function getRepository(): ObjectRepository; 34 | 35 | public function setManagerRegistry(ManagerRegistry $registry): void; 36 | } 37 | -------------------------------------------------------------------------------- /Doctrine/Admin/FormElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\GenericFormElement; 15 | 16 | /** 17 | * @template T of object 18 | * @template TSaveDTO of object 19 | * @template-default TSaveDTO=T 20 | * @template-extends GenericFormElement 21 | * @template-implements Element 22 | */ 23 | abstract class FormElement extends GenericFormElement implements Element 24 | { 25 | /** @use DataIndexerElementImpl */ 26 | use DataIndexerElementImpl; 27 | 28 | public function save($object): void 29 | { 30 | $this->getObjectManager()->persist($object); 31 | $this->getObjectManager()->flush(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Doctrine/Admin/ListElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Doctrine\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\GenericListElement; 15 | 16 | /** 17 | * @template T of object 18 | * @template-extends GenericListElement 19 | * @template-implements Element 20 | */ 21 | abstract class ListElement extends GenericListElement implements Element 22 | { 23 | /** @use DataIndexerElementImpl */ 24 | use DataIndexerElementImpl; 25 | 26 | public function saveDataGrid(): void 27 | { 28 | $this->getObjectManager()->flush(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Event/AdminContextPreCreateEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class AdminContextPreCreateEvent extends AdminEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/BatchObjectPostApplyEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class BatchObjectPostApplyEvent extends BatchEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/BatchObjectPreApplyEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | class BatchObjectPreApplyEvent extends BatchEvent 15 | { 16 | private bool $skip = false; 17 | 18 | public function shouldSkip(): bool 19 | { 20 | return $this->skip; 21 | } 22 | 23 | public function skip(bool $skip = true): void 24 | { 25 | $this->skip = $skip; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Event/BatchObjectsPostApplyEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class BatchObjectsPostApplyEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/BatchObjectsPreApplyEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class BatchObjectsPreApplyEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/BatchRequestPostSubmitEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class BatchRequestPostSubmitEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/BatchRequestPreSubmitEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class BatchRequestPreSubmitEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/DisplayResponsePreRenderEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class DisplayResponsePreRenderEvent extends DisplayEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/FormDataPostSaveEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class FormDataPostSaveEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/FormDataPreSaveEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class FormDataPreSaveEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/FormRequestPostSubmitEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class FormRequestPostSubmitEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/FormRequestPreSubmitEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class FormRequestPreSubmitEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/FormResponsePreRenderEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class FormResponsePreRenderEvent extends FormEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/ListDataGridPostSetDataEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class ListDataGridPostSetDataEvent extends ListEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/ListDataGridPostSubmitRequestEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class ListDataGridPostSubmitRequestEvent extends ListEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/ListDataGridPreSetDataEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class ListDataGridPreSetDataEvent extends ListEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/ListDataGridPreSubmitRequestEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class ListDataGridPreSubmitRequestEvent extends ListEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/ListDataSourcePostBindEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class ListDataSourcePostBindEvent extends ListEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/ListDataSourcePreBindEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class ListDataSourcePreBindEvent extends ListEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/ListResponsePreRenderEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class ListResponsePreRenderEvent extends ListEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/MenuEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | use FSi\Bundle\AdminBundle\Menu\Item\Item; 15 | use Symfony\Contracts\EventDispatcher\Event; 16 | 17 | abstract class MenuEvent extends Event 18 | { 19 | private Item $menu; 20 | 21 | public function __construct(Item $menu) 22 | { 23 | $this->menu = $menu; 24 | } 25 | 26 | public function getMenu(): Item 27 | { 28 | return $this->menu; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Event/MenuMainEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class MenuMainEvent extends MenuEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/MenuToolsEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class MenuToolsEvent extends MenuEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/MovedDownTreeEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use Symfony\Component\HttpFoundation\Request; 16 | 17 | final class MovedDownTreeEvent extends AdminEvent 18 | { 19 | private object $entity; 20 | 21 | public function __construct(Element $element, Request $request, object $entity) 22 | { 23 | parent::__construct($element, $request); 24 | $this->entity = $entity; 25 | } 26 | 27 | public function getEntity(): object 28 | { 29 | return $this->entity; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Event/MovedUpTreeEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use Symfony\Component\HttpFoundation\Request; 16 | 17 | final class MovedUpTreeEvent extends AdminEvent 18 | { 19 | private object $entity; 20 | 21 | public function __construct(Element $element, Request $request, object $entity) 22 | { 23 | parent::__construct($element, $request); 24 | $this->entity = $entity; 25 | } 26 | 27 | public function getEntity(): object 28 | { 29 | return $this->entity; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Event/PositionableEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use FSi\Bundle\AdminBundle\Model\PositionableInterface; 16 | use Symfony\Component\HttpFoundation\Request; 17 | use Symfony\Contracts\EventDispatcher\Event; 18 | 19 | abstract class PositionableEvent extends Event 20 | { 21 | private Request $request; 22 | 23 | private Element $element; 24 | 25 | private PositionableInterface $object; 26 | 27 | public function __construct(Request $request, Element $element, PositionableInterface $object) 28 | { 29 | $this->request = $request; 30 | $this->element = $element; 31 | $this->object = $object; 32 | } 33 | 34 | public function getRequest(): Request 35 | { 36 | return $this->request; 37 | } 38 | 39 | public function getElement(): Element 40 | { 41 | return $this->element; 42 | } 43 | 44 | public function getObject(): PositionableInterface 45 | { 46 | return $this->object; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Event/PositionablePostMoveEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class PositionablePostMoveEvent extends PositionableEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Event/PositionablePreMoveEvent.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Event; 13 | 14 | final class PositionablePreMoveEvent extends PositionableEvent 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Exception/ContextBuilderException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | class ContextBuilderException extends \RuntimeException implements ContextExceptionInterface 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Exception/ContextException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | class ContextException extends RuntimeException implements ContextExceptionInterface 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Exception/ContextExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | interface ContextExceptionInterface extends ExceptionInterface 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Exception/ExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | interface ExceptionInterface 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface 15 | { 16 | /** 17 | * @param class-string $contextClass 18 | * @param class-string $expectedClass 19 | * @param class-string $givenClass 20 | * @return self 21 | */ 22 | public static function create(string $contextClass, string $expectedClass, string $givenClass): self 23 | { 24 | return new self(sprintf("%s requires %s but instance of %s given", $contextClass, $expectedClass, $givenClass)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Exception/MissingOptionException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | class MissingOptionException extends \InvalidArgumentException implements ExceptionInterface 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Exception/RequestHandlerException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | class RequestHandlerException extends RuntimeException 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Exception/RuntimeException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Exception; 13 | 14 | class RuntimeException extends \RuntimeException implements ExceptionInterface 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /Factory/ProductionLine.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected array $workers; 15 | 16 | /** 17 | * @param iterable $workers 18 | */ 19 | public function __construct(iterable $workers) 20 | { 21 | $this->workers = []; 22 | 23 | foreach ($workers as $worker) { 24 | $this->addWorker($worker); 25 | } 26 | } 27 | 28 | public function addWorker(Worker $worker): void 29 | { 30 | $this->workers[] = $worker; 31 | } 32 | 33 | public function count(): int 34 | { 35 | return count($this->workers); 36 | } 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function getWorkers(): array 42 | { 43 | return $this->workers; 44 | } 45 | 46 | public function workOn(Element $element): void 47 | { 48 | foreach ($this->workers as $worker) { 49 | $worker->mount($element); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Factory/Worker.php: -------------------------------------------------------------------------------- 1 | managerRegistry = $managerRegistry; 19 | } 20 | 21 | public function mount(Element $element): void 22 | { 23 | if (true === $element instanceof DoctrineElement) { 24 | $element->setManagerRegistry($this->managerRegistry); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Factory/Worker/FormWorker.php: -------------------------------------------------------------------------------- 1 | formFactory = $formFactory; 19 | } 20 | 21 | public function mount(Element $element): void 22 | { 23 | if (true === $element instanceof FormElement) { 24 | $element->setFormFactory($this->formFactory); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Factory/Worker/ListWorker.php: -------------------------------------------------------------------------------- 1 | dataSourceFactory = $dataSourceFactory; 24 | $this->dataGridFactory = $dataGridFactory; 25 | } 26 | 27 | public function mount(Element $element): void 28 | { 29 | if (true === $element instanceof ListElement) { 30 | $element->setDataSourceFactory($this->dataSourceFactory); 31 | $element->setDataGridFactory($this->dataGridFactory); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Factory/Worker/LocaleProviderWorker.php: -------------------------------------------------------------------------------- 1 | localeProvider = $localeProvider; 19 | } 20 | 21 | public function mount(Element $element): void 22 | { 23 | if (true === $element instanceof LocaleProviderAware) { 24 | $element->setLocaleProvider($this->localeProvider); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Factory/Worker/RequestStackWorker.php: -------------------------------------------------------------------------------- 1 | requestStack = $requestStack; 19 | } 20 | 21 | public function mount(Element $element): void 22 | { 23 | if (true === $element instanceof RequestStackAware) { 24 | $element->setRequestStack($this->requestStack); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Form/CollectionTypeExtension.php: -------------------------------------------------------------------------------- 1 | > 17 | */ 18 | public static function getExtendedTypes(): iterable 19 | { 20 | return [CollectionType::class]; 21 | } 22 | 23 | /** 24 | * @param FormView $view 25 | * @param FormInterface $form 26 | * @param array $options 27 | */ 28 | public function buildView(FormView $view, FormInterface $form, array $options): void 29 | { 30 | $view->vars['attr']['data-allow-add'] = (int) $options['allow_add']; 31 | $view->vars['attr']['data-allow-delete'] = (int) $options['allow_delete']; 32 | $view->vars['attr']['data-prototype-name'] = $options['prototype_name']; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 FSi Sp. z o.o. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Menu/Builder/Builder.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Menu\Builder; 13 | 14 | use FSi\Bundle\AdminBundle\Menu\Item\Item; 15 | 16 | interface Builder 17 | { 18 | public function buildMenu(): Item; 19 | } 20 | -------------------------------------------------------------------------------- /Menu/Builder/Exception/InvalidYamlStructureException.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Menu\Builder\Exception; 13 | 14 | use Exception; 15 | 16 | class InvalidYamlStructureException extends Exception 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /Menu/Builder/MenuBuilder.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Menu\Builder; 13 | 14 | use FSi\Bundle\AdminBundle\Event\MenuEvent; 15 | use FSi\Bundle\AdminBundle\Menu\Item\Item; 16 | use Psr\EventDispatcher\EventDispatcherInterface; 17 | 18 | class MenuBuilder implements Builder 19 | { 20 | private EventDispatcherInterface $eventDispatcher; 21 | private string $eventName; 22 | 23 | /** 24 | * @param class-string $eventName 25 | */ 26 | public function __construct(EventDispatcherInterface $eventDispatcher, string $eventName) 27 | { 28 | $this->eventName = $eventName; 29 | $this->eventDispatcher = $eventDispatcher; 30 | } 31 | 32 | public function buildMenu(): Item 33 | { 34 | $menu = new Item(); 35 | 36 | $this->eventDispatcher->dispatch(new $this->eventName($menu)); 37 | 38 | return $menu; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Menu/Item/RoutableItem.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Menu\Item; 13 | 14 | class RoutableItem extends Item 15 | { 16 | private string $route; 17 | /** 18 | * @var array 19 | */ 20 | private array $routeParameters; 21 | 22 | /** 23 | * @param array $routeParameters 24 | */ 25 | public function __construct(string $name, string $route, array $routeParameters = []) 26 | { 27 | parent::__construct($name); 28 | 29 | $this->route = $route; 30 | $this->routeParameters = $routeParameters; 31 | } 32 | 33 | public function getRoute(): string 34 | { 35 | return $this->route; 36 | } 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function getRouteParameters(): array 42 | { 43 | return $this->routeParameters; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Menu/KnpMenu/ItemAttributesDecorator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Menu\KnpMenu; 13 | 14 | use FSi\Bundle\AdminBundle\Menu\Item\Item as AdminMenuItem; 15 | use Knp\Menu\ItemInterface as KnpMenuItem; 16 | 17 | class ItemAttributesDecorator implements ItemDecorator 18 | { 19 | public function decorate(KnpMenuItem $knpMenuItem, AdminMenuItem $adminMenuItem): void 20 | { 21 | $knpMenuItem->setUri('#'); 22 | 23 | if (true === $adminMenuItem->hasOption('attr')) { 24 | $knpMenuItem->setAttributes($adminMenuItem->getOption('attr')); 25 | } 26 | 27 | if (true === $adminMenuItem->hasChildren()) { 28 | $knpMenuItem->setAttribute('dropdown', true); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Menu/KnpMenu/ItemDecorator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Menu\KnpMenu; 13 | 14 | use FSi\Bundle\AdminBundle\Menu\Item\Item as AdminMenuItem; 15 | use Knp\Menu\ItemInterface as KnpMenuItem; 16 | 17 | interface ItemDecorator 18 | { 19 | public function decorate(KnpMenuItem $knpMenuItem, AdminMenuItem $adminMenuItem): void; 20 | } 21 | -------------------------------------------------------------------------------- /Menu/KnpMenu/ItemLabelDecorator.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Menu\KnpMenu; 13 | 14 | use FSi\Bundle\AdminBundle\Menu\Item\Item as AdminMenuItem; 15 | use Knp\Menu\ItemInterface as KnpMenuItem; 16 | 17 | class ItemLabelDecorator implements ItemDecorator 18 | { 19 | public function decorate(KnpMenuItem $knpMenuItem, AdminMenuItem $adminMenuItem): void 20 | { 21 | if (null !== $adminMenuItem->getLabel()) { 22 | $knpMenuItem->setLabel($adminMenuItem->getLabel()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Model/PositionableInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Model; 13 | 14 | interface PositionableInterface 15 | { 16 | public function increasePosition(): void; 17 | public function decreasePosition(): void; 18 | } 19 | -------------------------------------------------------------------------------- /Request/Parameters.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Request; 13 | 14 | final class Parameters 15 | { 16 | public const ELEMENT = 'element'; 17 | public const TRANSLATABLE_LOCALE = 'translatableLocale'; 18 | } 19 | -------------------------------------------------------------------------------- /Resources/config/resource_repository_translatable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | %fsi_resource_repository.resource.map_path% 14 | %fsi_resource_repository.resource.types% 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Resources/doc/admin_panel_translation.md: -------------------------------------------------------------------------------- 1 | ## Admin panel translation 2 | 3 | Currently the bundle is available in two languages: 4 | - english (en), 5 | - polish (pl), 6 | 7 | but you can easily add another language by creating a proper translation file. 8 | 9 | To enable the language switcher in the main menu, you need to add following lines 10 | to the ``config/config.yaml`` file: 11 | 12 | ```yaml 13 | # config/config.yaml 14 | 15 | fsi_admin: 16 | display_language_switch: true 17 | ``` 18 | 19 | [Back to index](index.md) 20 | -------------------------------------------------------------------------------- /Resources/doc/configuration.md: -------------------------------------------------------------------------------- 1 | # FSiAdminBundle configuration 2 | 3 | Below is reference for configuration of all bundle parameters, with default values: 4 | 5 | ```yaml 6 | # config/config.yaml 7 | 8 | fsi_admin: 9 | default_locale: %locale% 10 | # used for interface translation 11 | locales: 12 | - %locale% 13 | # used for integration with fsi/translatable 14 | translatable_locales: 15 | - %locale% 16 | menu_config_path: %kernel.project_dir%/config/admin_menu.yaml 17 | templates: 18 | base: @FSiAdmin/base.html.twig 19 | index_page: @FSiAdmin/Admin/index.html.twig 20 | list: @FSiAdmin/List/list.html.twig 21 | form: @FSiAdmin/Form/form.html.twig 22 | crud_list: @FSiAdmin/CRUD/list.html.twig 23 | # by default the value of `templates.form` option is copied here, 24 | # but you can overwrite it 25 | crud_form: @FSiAdmin/Form/form.html.twig 26 | resource: @FSiAdmin/Resource/resource.html.twig 27 | display: @FSiAdmin/Display/display.html.twig 28 | datagrid_theme: @FSiAdmin/CRUD/datagrid.html.twig 29 | datasource_theme: @FSiAdmin/CRUD/datasource.html.twig 30 | form_theme: @FSiAdmin/Form/form_div_layout.html.twig 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /Resources/doc/home_page.md: -------------------------------------------------------------------------------- 1 | # Home page 2 | 3 | By default the admin panel home page (index page) is just a blank page with 4 | navigation bar, but you can customize it to fit your needs. 5 | 6 | ## Override the template file 7 | 8 | If you don't need any extra logic, you can just override the home page template 9 | file with your own. 10 | 11 | ```yaml 12 | #config/fsi_admin.yaml 13 | 14 | fsi_admin: 15 | templates: 16 | index_page: '@YourAdmin/Admin/index.html.twig' 17 | ``` 18 | 19 | It is a good idea to have your custom template file extend the FSi Admin Bundle base template file. 20 | 21 | ```twig 22 | # YourAdminBundle/Resources/views/Admin/index.html.twig 23 | 24 | {% extends admin_templates_base %} 25 | 26 | {% block content %} 27 | {# Your content goes here... #} 28 | {% endblock %} 29 | ``` 30 | 31 | ## Override the route 32 | 33 | If you want to have your own controller with custom logic, you can override the 34 | home page route (just like any other route in Symfony). 35 | 36 | ```yaml 37 | # config/routes.yaml 38 | 39 | fsi_admin: 40 | path: / 41 | controller: YourAdminBundle\Controller\IndexController 42 | ``` 43 | 44 | [Back to index](index.md) 45 | -------------------------------------------------------------------------------- /Resources/doc/index.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | - [Installation](installation.md) 4 | - [Create your first admin element](admin_element.md) 5 | - [Embedding Element](embedding_element.md) 6 | - [Events](events.md) 7 | - [Home page](home_page.md) 8 | - [Menu](menu.md) 9 | - [Bundle Configuration](configuration.md) 10 | - [Admin Panel Translation](admin_panel_translation.md) 11 | - [Contexts and context manager](contexts.md) 12 | -------------------------------------------------------------------------------- /Resources/doc/installation.md: -------------------------------------------------------------------------------- 1 | # Installation in 4 simple steps 2 | 3 | ## 1. Add FSiAdminBundle to your project 4 | 5 | Add the following line to your `composer.json` and run update: 6 | 7 | ```json 8 | "require": { 9 | "fsi/admin-bundle": "^4.0@dev" 10 | } 11 | ``` 12 | 13 | ## 2. Register required bundles 14 | 15 | Update your `AppKernel.php` file with the following bundles: 16 | 17 | ```php 18 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /Resources/views/Admin/tools_menu_theme.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@FSiAdmin/Admin/main_menu_theme.html.twig' %} 2 | 3 | {% block root %} 4 | {% set listAttributes = { class: 'nav navbar-nav navbar-right' } %} 5 | {{ block('list') -}} 6 | {% endblock %} 7 | 8 | {% block label item.label|trans({}, 'FSiAdminBundle') %} 9 | -------------------------------------------------------------------------------- /Resources/views/CRUD/datagrid_edit_form.html.twig: -------------------------------------------------------------------------------- 1 | {% extends admin_templates_form_theme %} 2 | 3 | {% block form_label_class %} 4 | {{ form.parent | length > 1 ? 'col-sm-12' : 'sr-only' }} 5 | {% endblock form_label_class %} 6 | 7 | {% block form_group_class %} 8 | col-sm-12 9 | {% endblock form_group_class %} 10 | 11 | {% block row_row %} 12 | {{ form_widget(form) }} 13 | {% endblock row_row %} 14 | 15 | {% block collection_widget %} 16 |
17 | {%- if form.parent is empty -%} 18 | {{ form_errors(form) }} 19 | {%- endif -%} 20 | {% set collection = form %} 21 | {% for form in collection %} 22 | {{ block('collection_item') }} 23 | {% endfor %} 24 | {{- form_rest(form) -}} 25 |
26 | {% endblock %} 27 | 28 | {% block collection_item %} 29 |
30 |
31 | {{ form_widget(form) }} 32 | {{ form_errors(form) }} 33 |
34 |
35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /Resources/views/CRUD/list.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@FSiAdmin/List/list.html.twig' %} 2 | 3 | {% block top_buttons %} 4 | {% if element.option('allow_add') == true %} 5 | 6 | 7 | {{ 'crud.list.button.create'|trans({}, 'FSiAdminBundle') }} 8 | 9 | {% endif %} 10 | {% endblock top_buttons %} 11 | 12 | {% block bottom_buttons %} 13 | {% block buttons %} 14 | {% if element.option('allow_add') == true %} 15 | 16 | 17 | {{ 'crud.list.button.create'|trans({}, 'FSiAdminBundle') }} 18 | 19 | {% endif %} 20 | {% endblock buttons %} 21 | {% endblock bottom_buttons %} 22 | -------------------------------------------------------------------------------- /Resources/views/Resource/resource.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@FSiAdmin/Form/form.html.twig' %} 2 | 3 | {% block themes %} 4 | {% form_theme form admin_templates_form_theme %} 5 | {% endblock themes %} 6 | 7 | {% block header 'resource.title'|trans({}, 'FSiAdminBundle') %} 8 | -------------------------------------------------------------------------------- /Resources/views/flash_messages.html.twig: -------------------------------------------------------------------------------- 1 |
2 | {%- set typeClass = {success: 'success', warning: 'warning', error: 'danger', info: 'info'} -%} 3 | {% for type, typeMessages in fsi_admin_messages() %} 4 | {% for message in typeMessages %} 5 |
6 | {{ (message.text)|trans(message.params, message.domain) }} 7 |
8 | {% endfor %} 9 | {% endfor %} 10 |
11 | -------------------------------------------------------------------------------- /Translatable/Form/Extractor/FormDataExtractor.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Translatable\Form\Extractor; 13 | 14 | use FSi\Bundle\AdminBundle\Translatable\Form\FormTranslatableData; 15 | use Symfony\Component\Form\FormInterface; 16 | 17 | interface FormDataExtractor 18 | { 19 | /** 20 | * @param FormInterface $form 21 | */ 22 | public function extract(FormInterface $form): ?FormTranslatableData; 23 | } 24 | -------------------------------------------------------------------------------- /Translatable/Form/FormTranslatableData.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Translatable\Form; 13 | 14 | use RuntimeException; 15 | 16 | final class FormTranslatableData 17 | { 18 | private bool $translatable; 19 | private ?object $data; 20 | 21 | public function __construct(bool $translatable, ?object $data) 22 | { 23 | if (false === $translatable && null !== $data) { 24 | throw new RuntimeException('Cannot pass data for non translatable form property.'); 25 | } 26 | 27 | $this->translatable = $translatable; 28 | $this->data = $data; 29 | } 30 | 31 | public function isTranslatable(): bool 32 | { 33 | return $this->translatable; 34 | } 35 | 36 | public function getData(): ?object 37 | { 38 | return $this->data; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Translatable/Form/PropertyTranslatableData.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Translatable\Form; 13 | 14 | final class PropertyTranslatableData 15 | { 16 | private bool $translatable; 17 | private ?DefaultTranslation $defaultTranslation; 18 | 19 | public function __construct(bool $translatable, ?DefaultTranslation $defaultTranslation) 20 | { 21 | $this->translatable = $translatable; 22 | $this->defaultTranslation = $defaultTranslation; 23 | } 24 | 25 | public function isTranslatable(): bool 26 | { 27 | return $this->translatable; 28 | } 29 | 30 | public function getDefaultTranslation(): ?DefaultTranslation 31 | { 32 | return $this->defaultTranslation; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Twig/MessageTwigExtension.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Twig; 13 | 14 | use FSi\Bundle\AdminBundle\Message\FlashMessages; 15 | use Twig\Extension\AbstractExtension; 16 | use Twig\TwigFunction; 17 | 18 | class MessageTwigExtension extends AbstractExtension 19 | { 20 | private FlashMessages $flashMessages; 21 | 22 | public function __construct(FlashMessages $flashMessages) 23 | { 24 | $this->flashMessages = $flashMessages; 25 | } 26 | 27 | public function getFunctions(): array 28 | { 29 | return [ 30 | new TwigFunction('fsi_admin_messages', fn(): array => $this->flashMessages->all()), 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Twig/TranslatableExtension.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\Twig; 13 | 14 | use FSi\Bundle\AdminBundle\Message\FlashMessages; 15 | use FSi\Component\Translatable\LocaleProvider; 16 | use Twig\Extension\AbstractExtension; 17 | use Twig\TwigFunction; 18 | 19 | class TranslatableExtension extends AbstractExtension 20 | { 21 | private LocaleProvider $localeProvider; 22 | 23 | public function __construct(LocaleProvider $localeProvider) 24 | { 25 | $this->localeProvider = $localeProvider; 26 | } 27 | 28 | public function getFunctions(): array 29 | { 30 | return [ 31 | new TwigFunction('translatable_locale', [$this, 'getTranslatableLocale']), 32 | ]; 33 | } 34 | 35 | public function getTranslatableLocale(): string 36 | { 37 | return $this->localeProvider->getLocale(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3' 3 | 4 | services: 5 | web: 6 | image: fsiopenpl/docker-php-apache:alpine-8.1 7 | container_name: admin-bundle-web 8 | ports: 9 | - 80:80 10 | - 443:443 11 | environment: 12 | PHP_IDE_CONFIG: 'serverName=localhost' 13 | DOCROOT: /var/www/application/features/fixtures/project/web 14 | XDEBUG_CONFIG: 'idekey=PHPSTORM discover_client_host=false client_host=host.docker.internal' 15 | XDEBUG_MODE: debug 16 | HOST_UID: 1000 17 | HOST_GID: 1000 18 | volumes: 19 | - .:/var/www/application 20 | - ~/.composer:/var/www/.composer 21 | extra_hosts: 22 | - "host.docker.internal:host-gateway" 23 | selenium: 24 | image: selenium/standalone-firefox:2.53.1 25 | container_name: admin-bundle-selenium 26 | -------------------------------------------------------------------------------- /features/admin_panel_main_page.feature: -------------------------------------------------------------------------------- 1 | Feature: Admin panel main page 2 | In order to generate admin panel for Symfony2 project 3 | As a developer 4 | I need to install FSiAdminBundle and configure few admin elements 5 | 6 | Scenario: Admin panel top bar appearance 7 | Given the following admin elements were registered 8 | | Id | Class | 9 | | category | FSi\FixturesBundle\Admin\Category | 10 | | news | FSi\FixturesBundle\Admin\News | 11 | | subscriber | FSi\FixturesBundle\Admin\Subscriber | 12 | | about_us_page | FSi\FixturesBundle\Admin\AboutUsPage | 13 | And translations are enabled in application 14 | And I am on the "Admin panel" page 15 | Then I should see "Admin" title at top bar 16 | And menu with following elements should be visible at the top of the page 17 | | Element name | Element group | 18 | | Categories | | 19 | | News | | 20 | | Subscribers | | 21 | | Tree | | 22 | | About us page | Site structure | 23 | | Home page | Site structure | 24 | -------------------------------------------------------------------------------- /features/change_admin_panel_language.feature: -------------------------------------------------------------------------------- 1 | Feature: Change admin panel language 2 | In order to change language of admin panel 3 | As a administrator 4 | I need to choose language from list in top navigation bar 5 | 6 | Scenario: Change panel language 7 | Given I am on the "Admin panel" page 8 | Then I should see language dropdown button in navigation bar with text "Language (English)" 9 | And language dropdown button should have following links 10 | | Link | 11 | | English | 12 | | Polish | 13 | When I click "Polish" link from language dropdown button 14 | Then I should see language dropdown button with text "Język (polski)" 15 | And language dropdown button should have following links 16 | | Link | 17 | | angielski | 18 | | polski | 19 | -------------------------------------------------------------------------------- /features/crud/crud_list.feature: -------------------------------------------------------------------------------- 1 | Feature: List of elements 2 | In order to generate list of elements in admin panel 3 | As a developer 4 | I need to install FSiAdminBundle and configure datagrid for news admin element 5 | 6 | 7 | Scenario: Accessing news list from admin panel main page 8 | Given the following admin elements were registered 9 | | Id | Class | 10 | | news | FSi\FixturesBundle\Admin\News | 11 | And translations are enabled in application 12 | And I am on the "Admin panel" page 13 | When I follow "News" url from top bar 14 | Then I should see list with following columns 15 | | Column name | 16 | | Batch | 17 | | Title | 18 | | Date | 19 | | Created at | 20 | | Visible | 21 | | Creator email | 22 | And I should see "News list" page header "List of elements" 23 | -------------------------------------------------------------------------------- /features/crud/crud_list_custom_templates.feature: -------------------------------------------------------------------------------- 1 | Feature: Overwriting default CRUD element templates 2 | In order to modify default CRUD element templates 3 | As a developer 4 | I need to install FSiAdminBundle and configure admin element 5 | 6 | Scenario: Services configuration 7 | Given the following admin elements were registered 8 | | Id | Class | 9 | | custom_news | FSi\FixturesBundle\Admin\CustomNews | 10 | And "custom_news" element have following options defined 11 | | Option | Value | 12 | | template_list | @FSiFixtures/Admin/custom_list.html.twig | 13 | | template_form | @FSiFixtures/Admin/custom_form.html.twig | 14 | 15 | 16 | 17 | Scenario: Display custom list view 18 | And I am on the "Custom news list" page 19 | Then page "Custom news list" should display OK status 20 | 21 | 22 | Scenario: Display custom edit view 23 | Given there is a "news" with "id" 1 present in the database 24 | And I am on the "Custom news edit" page with id 1 25 | Then page "Custom news edit" should display OK status 26 | -------------------------------------------------------------------------------- /features/crud/crud_results_per_page.feature: -------------------------------------------------------------------------------- 1 | Feature: Changing results per page at list page 2 | In order to generate list of elements in admin panel 3 | As a developer 4 | I need to install FSiAdminBundle and configure datagrid and datasource for news admin element 5 | 6 | Background: 7 | Given "news" element datasource max results is set 10 8 | 9 | 10 | Scenario: Display list with elements count equal to datasource max results 11 | Given the following admin elements were registered 12 | | Id | Class | 13 | | news | FSi\FixturesBundle\Admin\News | 14 | And there are 20 "news" 15 | And I am on the "News list" page 16 | Then there should be 10 elements at list 17 | 18 | 19 | Scenario: Change elements per page 20 | Given there are 20 "news" 21 | And I am on the "News list" page 22 | Then there should be 10 elements at list 23 | When I change elements per page to 5 24 | Then there should be 5 elements at list 25 | When I change elements per page to 50 26 | Then there should be 20 elements at list 27 | -------------------------------------------------------------------------------- /features/dependent_crud/dependent_crud_list.feature: -------------------------------------------------------------------------------- 1 | Feature: List of dependent elements 2 | In order to generate list of dependent elements in admin panel 3 | As a developer 4 | I need to install FSiAdminBundle and configure parent admin element and child admin element 5 | 6 | 7 | Scenario: Accessing news list from admin panel main page 8 | Given the following admin elements were registered 9 | | Id | Class | Parent | 10 | | category_news | FSi\FixturesBundle\Admin\CategoryNews | category | 11 | | category | FSi\FixturesBundle\Admin\Category | | 12 | And translations are enabled in application 13 | And there are 2 "categories" 14 | And I am on the "Admin panel" page 15 | When I follow "Categories" url from top bar 16 | And I clicked "news" in "Actions" column in first row 17 | Then I should be on the "Category news list" page 18 | And "Categories" link in the top bar should be highlighted 19 | And I should see list with following columns 20 | | Column name | 21 | | Batch | 22 | | Title | 23 | And I should see "Category news list" page header "List of elements" 24 | -------------------------------------------------------------------------------- /features/display.feature: -------------------------------------------------------------------------------- 1 | Feature: View object 2 | In order to view object's details 3 | As a developer 4 | I need to install FSiAdminBundle and configure display admin element 5 | 6 | 7 | Scenario: Accessing display object page 8 | Given the following admin elements were registered 9 | | Id | Class | 10 | | news | FSi\FixturesBundle\Admin\News | 11 | | news_display | FSi\FixturesBundle\Admin\DisplayNews | 12 | And there is 1 "news" 13 | And translations are enabled in application 14 | And I am on the "News list" page 15 | When I press "Display" link in actions column of first element at list 16 | Then I should see "News display" page header "Display element" 17 | And I should see display with following fields 18 | | Field name | 19 | | Identity | 20 | | Title | 21 | | Date | 22 | | Created at | 23 | | Creator email | 24 | -------------------------------------------------------------------------------- /features/fixtures/project/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/data.sqlite 2 | /bin/cache 3 | /bin/logs 4 | /web/bundles 5 | /web/uploaded/* 6 | -------------------------------------------------------------------------------- /features/fixtures/project/bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(new ArgvInput()); 19 | -------------------------------------------------------------------------------- /features/fixtures/project/config/admin_menu.yaml: -------------------------------------------------------------------------------- 1 | menu: 2 | - { id: category, name: admin.category.name } 3 | - { id: news, name: admin.news.name } 4 | - { id: subscriber, name : admin.subscriber.name } 5 | - { id: node, name: admin.node.name } 6 | - admin.menu.structure: 7 | - { id: home_page, name: admin.home_page.name } 8 | - { id: about_us_page, name: admin.about_us_page.name } 9 | -------------------------------------------------------------------------------- /features/fixtures/project/config/doctrine/Category.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /features/fixtures/project/config/doctrine/Person.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /features/fixtures/project/config/doctrine/Resource.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /features/fixtures/project/config/doctrine/Subscriber.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /features/fixtures/project/config/doctrine/TagElement.orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /features/fixtures/project/config/framework_44.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | framework: 3 | session: 4 | storage_id: session.storage.filesystem 5 | -------------------------------------------------------------------------------- /features/fixtures/project/config/framework_54.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | framework: 3 | session: 4 | storage_factory_id: session.storage.factory.mock_file 5 | -------------------------------------------------------------------------------- /features/fixtures/project/config/resource_map.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | type: group 3 | homepage: 4 | type: group 5 | content: 6 | type: text 7 | form_options: 8 | label: admin.home_page.form.content 9 | header: 10 | type: text 11 | form_options: 12 | required: true 13 | label: admin.home_page.form.header 14 | -------------------------------------------------------------------------------- /features/fixtures/project/config/routing.yaml: -------------------------------------------------------------------------------- 1 | admin: 2 | resource: "@FSiAdminBundle/Resources/config/routing/admin.yaml" 3 | prefix: /admin 4 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Admin/AboutUsPage.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class AboutUsPage extends ResourceElement 14 | { 15 | public function getId(): string 16 | { 17 | return 'about_us_page'; 18 | } 19 | 20 | public function getKey(): string 21 | { 22 | return 'resources.about_us'; 23 | } 24 | 25 | public function getClassName(): string 26 | { 27 | return Entity\Resource::class; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Admin/CustomSubscriber.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class CustomSubscriber extends ListElement 18 | { 19 | public function getId(): string 20 | { 21 | return 'custom_subscriber'; 22 | } 23 | 24 | public function getClassName(): string 25 | { 26 | return Entity\Subscriber::class; 27 | } 28 | 29 | protected function initDataGrid(DataGridFactoryInterface $factory): DataGridInterface 30 | { 31 | return $factory->createDataGrid(Subscriber::ID); 32 | } 33 | 34 | protected function initDataSource(DataSourceFactoryInterface $factory): DataSourceInterface 35 | { 36 | return $factory->createDataSource( 37 | 'doctrine-orm', 38 | ['entity' => $this->getClassName()], 39 | Subscriber::ID 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Admin/Structure/HomePage.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class HomePage extends ResourceElement 14 | { 15 | public function getId(): string 16 | { 17 | return 'home_page'; 18 | } 19 | 20 | public function getKey(): string 21 | { 22 | return 'resources.homepage'; 23 | } 24 | 25 | public function getClassName(): string 26 | { 27 | return Entity\Resource::class; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Admin/SubscriberDelete.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\FixturesBundle\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\DeleteElement; 15 | use FSi\FixturesBundle\Entity; 16 | 17 | /** 18 | * @template-extends DeleteElement 19 | */ 20 | class SubscriberDelete extends DeleteElement 21 | { 22 | public function getClassName(): string 23 | { 24 | return Entity\Subscriber::class; 25 | } 26 | 27 | public function getId(): string 28 | { 29 | return 'subscriber_delete'; 30 | } 31 | 32 | public function getSuccessRoute(): string 33 | { 34 | return 'fsi_admin_list'; 35 | } 36 | 37 | public function getSuccessRouteParameters(): array 38 | { 39 | return ['element' => 'subscriber']; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/CustomAdmin/Contact.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | class Contact extends ResourceElement 14 | { 15 | public function getClassName(): string 16 | { 17 | return Entity\Resource::class; 18 | } 19 | 20 | public function getId(): string 21 | { 22 | return 'contact'; 23 | } 24 | 25 | public function getKey(): string 26 | { 27 | return 'contact'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/DTO/Model.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\FixturesBundle\DTO; 13 | 14 | use Symfony\Component\Validator\Constraints as Assert; 15 | 16 | class Model 17 | { 18 | /** 19 | * @Assert\Email 20 | * @Assert\NotBlank 21 | */ 22 | private ?string $email = null; 23 | 24 | public function getEmail(): ?string 25 | { 26 | return $this->email; 27 | } 28 | 29 | public function setEmail(?string $email): void 30 | { 31 | $this->email = $email; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/DependencyInjection/FSiFixturesExtension.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\FixturesBundle\DependencyInjection; 13 | 14 | use Symfony\Component\Config\FileLocator; 15 | use Symfony\Component\DependencyInjection\ContainerBuilder; 16 | use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; 17 | use Symfony\Component\HttpKernel\DependencyInjection\Extension; 18 | 19 | class FSiFixturesExtension extends Extension 20 | { 21 | /** 22 | * @param array $configs 23 | */ 24 | public function load(array $configs, ContainerBuilder $container): void 25 | { 26 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); 27 | $loader->load('services.xml'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Entity/Category.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\FixturesBundle\Entity; 13 | 14 | use Doctrine\ORM\Mapping as ORM; 15 | 16 | class Category 17 | { 18 | private ?int $id = null; 19 | 20 | private ?string $title = null; 21 | 22 | public function getId(): ?int 23 | { 24 | return $this->id; 25 | } 26 | 27 | public function setTitle(?string $title): void 28 | { 29 | $this->title = $title; 30 | } 31 | 32 | public function getTitle(): ?string 33 | { 34 | return $this->title; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Entity/Person.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\FixturesBundle\Entity; 13 | 14 | class Person 15 | { 16 | private ?int $id = null; 17 | private ?string $email = null; 18 | 19 | public function getId(): ?int 20 | { 21 | return $this->id; 22 | } 23 | 24 | public function setEmail(?string $email): void 25 | { 26 | $this->email = $email; 27 | } 28 | 29 | public function getEmail(): ?string 30 | { 31 | return $this->email; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Entity/Resource.php: -------------------------------------------------------------------------------- 1 | id; 19 | } 20 | 21 | public function setCreatedAt(?DateTimeInterface $createdAt): void 22 | { 23 | $this->createdAt = $createdAt; 24 | } 25 | 26 | public function getCreatedAt(): ?DateTimeInterface 27 | { 28 | return $this->createdAt; 29 | } 30 | 31 | public function setEmail(?string $email): void 32 | { 33 | $this->email = $email; 34 | } 35 | 36 | public function getEmail(): ?string 37 | { 38 | return $this->email; 39 | } 40 | 41 | public function setActive(bool $active): void 42 | { 43 | $this->active = $active; 44 | } 45 | 46 | public function isActive(): bool 47 | { 48 | return $this->active; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Entity/TagElement.php: -------------------------------------------------------------------------------- 1 | id; 16 | } 17 | 18 | public function getName(): ?string 19 | { 20 | return $this->name; 21 | } 22 | 23 | public function setName(?string $name): void 24 | { 25 | $this->name = $name; 26 | } 27 | 28 | public function getTag(): ?Tag 29 | { 30 | return $this->tag; 31 | } 32 | 33 | public function setTag(?Tag $tag): void 34 | { 35 | $this->tag = $tag; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/FSiFixturesBundle.php: -------------------------------------------------------------------------------- 1 | $builder 18 | * @param array $options 19 | */ 20 | public function buildForm(FormBuilderInterface $builder, array $options): void 21 | { 22 | $builder->add('name', TextType::class, ['constraints' => [new NotBlank()]]); 23 | } 24 | 25 | public function configureOptions(OptionsResolver $resolver): void 26 | { 27 | $resolver->setDefault('data_class', TagElement::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Resources/views/Admin/custom_form.html.twig: -------------------------------------------------------------------------------- 1 |

Custom form

2 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Resources/views/Admin/custom_list.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@FSiAdmin/CRUD/list.html.twig' %} 2 | 3 | {% block themes %} 4 | {{ parent() }} 5 | {% datagrid_theme datagrid_view admin_templates_datagrid_theme %} 6 | {% endblock themes %} 7 | 8 | {% block content %} 9 |

Custom list

10 | {% endblock content %} 11 | -------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Resources/views/Admin/subscriber_custom_list.html.twig: -------------------------------------------------------------------------------- 1 |

Custom subscribers list

-------------------------------------------------------------------------------- /features/fixtures/project/src/FixturesBundle/Resources/views/Admin/subscriber_list.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@FSiAdmin/List/list.html.twig' %} 2 | {% trans_default_domain 'FSiAdminBundle' %} 3 | 4 | {% block bottom_buttons %} 5 | {{ 'crud.list.button.create'|trans }} 6 | {% endblock bottom_buttons %} 7 | 8 | {% block top_buttons %} 9 | {{ 'crud.list.button.create'|trans }} 10 | {% endblock top_buttons %} 11 | -------------------------------------------------------------------------------- /features/fixtures/project/translations/messages.en.yml: -------------------------------------------------------------------------------- 1 | admin: 2 | menu: 3 | structure: Site structure 4 | category: 5 | name: Categories 6 | list: 7 | title: Title 8 | actions: Actions 9 | news: 10 | name: News 11 | list: 12 | title: Title 13 | date: Date 14 | created_at: Created at 15 | created_at_from: Created at from 16 | created_at_to: Created at to 17 | visible: Visible 18 | photo: Photo 19 | creator_email: Creator email 20 | tags: Tags 21 | tag_elements: Elements 22 | non_editable_tags: Non-editable tags 23 | removable_comments: Removable-only comments 24 | actions: Actions 25 | node: 26 | name: Tree 27 | list: 28 | title: Title 29 | actions: Actions 30 | child_nodes: Child nodes 31 | subscriber: 32 | name: Subscribers 33 | list: 34 | email: Email 35 | created_at: Created at 36 | created_at_from: Created at from 37 | created_at_to: Created at to 38 | active: Active 39 | actions: Actions 40 | home_page: 41 | name: Home page 42 | form: 43 | header: Header 44 | content: Content 45 | about_us_page: 46 | name: About us page 47 | email: Email 48 | -------------------------------------------------------------------------------- /features/fixtures/project/web/app_test.php: -------------------------------------------------------------------------------- 1 | handle($request); 16 | $response->send(); 17 | $kernel->terminate($request, $response); 18 | -------------------------------------------------------------------------------- /features/fixtures/project/web/files/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsi-open/admin-bundle/f82faea38c1f8bc95758db4635bbc7ea571aa281/features/fixtures/project/web/files/.gitkeep -------------------------------------------------------------------------------- /features/list/list.feature: -------------------------------------------------------------------------------- 1 | Feature: List of elements 2 | In order to generate list of elements in admin panel 3 | As a developer 4 | I need to install FSiAdminBundle and configure datagrid for newsletter subscribers admin element 5 | 6 | Scenario: Accessing newsletter subscribers list from admin panel main page 7 | Given the following admin elements were registered 8 | | Id | Class | 9 | | subscriber | FSi\FixturesBundle\Admin\Subscriber | 10 | And translations are enabled in application 11 | And I am on the "Admin panel" page 12 | When I follow "Subscribers" url from top bar 13 | Then I should see list with following columns 14 | | Column name | 15 | | Email | 16 | | Active | 17 | | Created at | 18 | And I should see "Subscribers list" page header "List of elements" 19 | 20 | Scenario: Accessing tree-like list 21 | Given I am on the "Admin panel" page 22 | And I follow "Tree" url from top bar 23 | Then I should see list with following columns 24 | | Column name | 25 | | Title | 26 | | Actions | 27 | -------------------------------------------------------------------------------- /features/list/list_custom_templates.feature: -------------------------------------------------------------------------------- 1 | Feature: Overwriting default list element templates 2 | In order to modify default list element templates 3 | As a developer 4 | I need to install FSiAdminBundle and configure newsletter subscribers admin element 5 | 6 | Scenario: Services configuration 7 | Given the following admin elements were registered 8 | | Id | Class | 9 | | custom_subscriber | FSi\FixturesBundle\Admin\CustomSubscriber | 10 | And "custom_subscriber" element have following options defined 11 | | Option | Value | 12 | | template_list | @FSiFixtures/Admin/subscriber_custom_list.html.twig | 13 | 14 | 15 | 16 | Scenario: Display custom list view 17 | And I am on the "Custom subscribers list" page 18 | Then page "Custom subscribers list" should display OK status 19 | -------------------------------------------------------------------------------- /features/list/results_per_page.feature: -------------------------------------------------------------------------------- 1 | Feature: Changing results per page at list page 2 | In order to generate list of subscribers in admin panel 3 | As a developer 4 | I need to install FSiAdminBundle and configure datagrid and datasource for newsletter subscribers admin element 5 | 6 | Background: 7 | Given "subscriber" element datasource max results is set 10 8 | 9 | Scenario: Display list with elements count equal to datasource max results 10 | Given the following admin elements were registered 11 | | Id | Class | 12 | | subscriber | FSi\FixturesBundle\Admin\Subscriber | 13 | And there are 20 "subscribers" 14 | And I am on the "Subscribers list" page 15 | Then there should be 10 elements at list 16 | 17 | Scenario: Change elements per page 18 | Given there are 20 "subscribers" 19 | And I am on the "Subscribers list" page 20 | Then there should be 10 elements at list 21 | When I change elements per page to 5 22 | Then there should be 5 elements at list 23 | When I change elements per page to 50 24 | Then there should be 20 elements at list 25 | -------------------------------------------------------------------------------- /features/resource.feature: -------------------------------------------------------------------------------- 1 | Feature: Editing page resources 2 | In order to allow editing application resources 3 | As a developer 4 | I need to install FSiAdminBundle and configure resource admin element 5 | 6 | Scenario: Accessing resource edit page 7 | And I am on the "Admin panel" page 8 | And translations are enabled in application 9 | When I follow "Home page" menu element 10 | Then I should see "Home page edit" page header "Edit resources" 11 | 12 | Scenario: Display form build from resource map 13 | Given there are following resources added to resource map 14 | | Key | Type | 15 | | resources.homepage.content | text | 16 | | resources.homepage.header | text | 17 | And I am on the "Home page edit" page 18 | Then I should see form with following fields 19 | | Field name | 20 | | Content | 21 | | Header | 22 | 23 | Scenario: Redirect after successful save 24 | Given there are following resources added to resource map 25 | | Key | 26 | | resources.homepage.content | 27 | And I am on the "Home page edit" page 28 | And I fill form "Content" field with "Resource test content" 29 | When I press form "Save" button 30 | And I should see form "Content" field with value "Resource test content" 31 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | . 7 | Resources 8 | features/fixtures/project/var 9 | features/fixtures/project/web 10 | spec 11 | vendor 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Admin/Manager/ElementCollectionVisitorSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Admin\Manager; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use FSi\Bundle\AdminBundle\Admin\ManagerInterface; 16 | use FSi\Bundle\AdminBundle\Factory\ProductionLine; 17 | use PhpSpec\ObjectBehavior; 18 | 19 | class ElementCollectionVisitorSpec extends ObjectBehavior 20 | { 21 | public function let(Element $adminElement, ProductionLine $productionLine): void 22 | { 23 | $this->beConstructedWith([$adminElement], $productionLine); 24 | } 25 | 26 | public function it_visits_manager_and_add_into_it_elements( 27 | ManagerInterface $manager, 28 | ProductionLine $productionLine, 29 | Element $adminElement 30 | ): void { 31 | $productionLine->workOn($adminElement)->shouldBeCalled(); 32 | $manager->addElement($adminElement)->shouldBeCalled(); 33 | 34 | $this->visitManager($manager); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Admin/ManagerSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use FSi\Bundle\AdminBundle\Admin\Manager\Visitor; 16 | use PhpSpec\ObjectBehavior; 17 | 18 | class ManagerSpec extends ObjectBehavior 19 | { 20 | public function let(Visitor $visitor): void 21 | { 22 | $this->beConstructedWith([$visitor]); 23 | } 24 | 25 | public function it_removes_element_by_id(Element $element): void 26 | { 27 | $element->getId()->willReturn('foo'); 28 | $this->addElement($element); 29 | 30 | $this->hasElement('foo')->shouldReturn(true); 31 | $this->removeElement('foo'); 32 | $this->hasElement('foo')->shouldReturn(false); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Display/Property/Formatter/BooleanSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use PhpSpec\ObjectBehavior; 15 | use Prophecy\Argument; 16 | 17 | class BooleanSpec extends ObjectBehavior 18 | { 19 | public function let(): void 20 | { 21 | $this->beConstructedWith('yes', 'no'); 22 | } 23 | 24 | public function it_ignore_empty_values(): void 25 | { 26 | $this->format(0)->shouldReturn(0); 27 | $this->format(null)->shouldReturn(null); 28 | $this->format([])->shouldReturn([]); 29 | } 30 | 31 | public function it_decorate_value(): void 32 | { 33 | $this->format(true)->shouldReturn('yes'); 34 | $this->format(false)->shouldReturn('no'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Display/Property/Formatter/CallbackSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use PhpSpec\ObjectBehavior; 15 | use Prophecy\Argument; 16 | 17 | class CallbackSpec extends ObjectBehavior 18 | { 19 | public function let(): void 20 | { 21 | $this->beConstructedWith( 22 | function ($value) { 23 | return $value . '+'; 24 | } 25 | ); 26 | } 27 | 28 | public function it_ignore_empty_values(): void 29 | { 30 | $this->format(0)->shouldReturn(0); 31 | $this->format(null)->shouldReturn(null); 32 | $this->format([])->shouldReturn([]); 33 | } 34 | 35 | public function it_form_value_using_callback_funciton(): void 36 | { 37 | $value = 'value'; 38 | $this->format($value)->shouldReturn('value+'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Display/Property/Formatter/DateTimeSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use PhpSpec\ObjectBehavior; 15 | 16 | class DateTimeSpec extends ObjectBehavior 17 | { 18 | public function let(): void 19 | { 20 | $this->beConstructedWith('Y:m:d H:i:s'); 21 | } 22 | 23 | public function it_ignore_empty_values_and_values_that_are_not_datetime(): void 24 | { 25 | $this->format(0)->shouldReturn(0); 26 | $this->format(null)->shouldReturn(null); 27 | $this->format([])->shouldReturn([]); 28 | $this->format('not_datetime')->shouldReturn('not_datetime'); 29 | } 30 | 31 | public function it_decorate_value(): void 32 | { 33 | $datetime = new \DateTime(); 34 | $this->format($datetime)->shouldReturn($datetime->format('Y:m:d H:i:s')); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Display/Property/Formatter/EmptyValueSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Display\Property\Formatter; 13 | 14 | use PhpSpec\ObjectBehavior; 15 | 16 | class EmptyValueSpec extends ObjectBehavior 17 | { 18 | public function let(): void 19 | { 20 | $this->beConstructedWith('-'); 21 | } 22 | 23 | public function it_format_empty_values(): void 24 | { 25 | $this->format(0)->shouldReturn('-'); 26 | $this->format(null)->shouldReturn('-'); 27 | $this->format([])->shouldReturn('-'); 28 | } 29 | 30 | public function it_ignore_not_empty_value(): void 31 | { 32 | $datetime = new \DateTime(); 33 | $this->format($datetime)->shouldReturn($datetime); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Display/SimpleDisplaySpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Display; 13 | 14 | use PhpSpec\ObjectBehavior; 15 | 16 | class SimpleDisplaySpec extends ObjectBehavior 17 | { 18 | public function it_creates_data_for_object(): void 19 | { 20 | $this->add('Piotr', 'First Name'); 21 | $this->add(['ROLE_ADMIN', 'ROLE_USER'], 'Roles'); 22 | 23 | $this->getData()->shouldHaveProperty('Piotr', 'First Name'); 24 | } 25 | 26 | public function getMatchers(): array 27 | { 28 | return [ 29 | 'haveProperty' => function ($subject, $value, $label) { 30 | /* @var $property Property */ 31 | foreach ($subject as $property) { 32 | if ($property->getLabel() === $label && $property->getValue() === $value) { 33 | return true; 34 | } 35 | } 36 | }, 37 | ]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/EventSubscriber/admin_menu.yml: -------------------------------------------------------------------------------- 1 | menu: 2 | - {id : news, name: "News"} 3 | - article 4 | - {route: fsi_admin, name: "Home"} 5 | - {route: custom_route, name: "Something custom", route_parameters: {foo: 'bar'}} 6 | - admin.menu.structure: 7 | - home_page 8 | - {id: contact, name: "Contact"} 9 | - {id: offer, name: "Offer", elements: [category, product]} 10 | - {id: non_existing, name: "Whatever"} 11 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/EventSubscriber/invalid_admin_menu.yml: -------------------------------------------------------------------------------- 1 | - {id : news, name: "News"} 2 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Factory/ProductionLineSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Factory; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use FSi\Bundle\AdminBundle\Factory\Worker; 16 | use PhpSpec\ObjectBehavior; 17 | 18 | class ProductionLineSpec extends ObjectBehavior 19 | { 20 | public function it_is_created_with_workers(Worker $workerFoo, Worker $workerBar): void 21 | { 22 | $this->beConstructedWith([$workerFoo, $workerBar]); 23 | $this->count()->shouldReturn(2); 24 | $this->getWorkers()->shouldReturn([$workerFoo, $workerBar]); 25 | } 26 | 27 | public function it_work_on_element_with_workers( 28 | Worker $workerFoo, 29 | Worker $workerBar, 30 | Element $element 31 | ): void { 32 | $this->beConstructedWith([$workerFoo, $workerBar]); 33 | $workerBar->mount($element)->shouldBeCalled(); 34 | $workerFoo->mount($element)->shouldBeCalled(); 35 | 36 | $this->workOn($element); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Factory/Worker/DoctrineWorkerSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Factory\Worker; 13 | 14 | use Doctrine\Persistence\ManagerRegistry; 15 | use FSi\Bundle\AdminBundle\Doctrine\Admin\CRUDElement; 16 | use PhpSpec\ObjectBehavior; 17 | 18 | class DoctrineWorkerSpec extends ObjectBehavior 19 | { 20 | public function let(ManagerRegistry $managerRegistry): void 21 | { 22 | $this->beConstructedWith($managerRegistry); 23 | } 24 | 25 | public function it_mount_datagrid_factory_to_elements_that_are_doctrine_elements( 26 | CRUDElement $element, 27 | ManagerRegistry $managerRegistry 28 | ): void { 29 | $element->setManagerRegistry($managerRegistry)->shouldBeCalled(); 30 | 31 | $this->mount($element); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Factory/Worker/FormWorkerSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Factory\Worker; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\CRUD\GenericCRUDElement; 15 | use PhpSpec\ObjectBehavior; 16 | use Symfony\Component\Form\FormFactoryInterface; 17 | 18 | class FormWorkerSpec extends ObjectBehavior 19 | { 20 | public function let(FormFactoryInterface $formFactory): void 21 | { 22 | $this->beConstructedWith($formFactory); 23 | } 24 | 25 | public function it_mount_form_factory_to_elements_that_are_form_aware( 26 | GenericCRUDElement $element, 27 | FormFactoryInterface $formFactory 28 | ): void { 29 | $element->setFormFactory($formFactory)->shouldBeCalled(); 30 | 31 | $this->mount($element); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Factory/Worker/RequestStackWorkerSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Factory\Worker; 13 | 14 | use FSi\Bundle\AdminBundle\spec\fixtures\Admin\RequestStackAwareElement; 15 | use PhpSpec\ObjectBehavior; 16 | use Symfony\Component\HttpFoundation\RequestStack; 17 | 18 | class RequestStackWorkerSpec extends ObjectBehavior 19 | { 20 | public function let(RequestStack $requestStack): void 21 | { 22 | $this->beConstructedWith($requestStack); 23 | } 24 | 25 | public function it_mount_request_stack_to_elements_that_are_request_stack_aware( 26 | RequestStackAwareElement $element, 27 | RequestStack $requestStack 28 | ): void { 29 | $element->setRequestStack($requestStack)->shouldBeCalled(); 30 | 31 | $this->mount($element); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Menu/Builder/MenuBuilderSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Menu\Builder; 13 | 14 | use FSi\Bundle\AdminBundle\Event\MenuToolsEvent; 15 | use FSi\Bundle\AdminBundle\Menu\Item\Item; 16 | use PhpSpec\ObjectBehavior; 17 | use Prophecy\Argument; 18 | use Psr\EventDispatcher\EventDispatcherInterface; 19 | 20 | class MenuBuilderSpec extends ObjectBehavior 21 | { 22 | public function let(EventDispatcherInterface $dispatcher): void 23 | { 24 | $this->beConstructedWith($dispatcher, MenuToolsEvent::class); 25 | } 26 | 27 | public function it_should_emit_proper_event(EventDispatcherInterface $dispatcher): void 28 | { 29 | $dispatcher->dispatch(Argument::type(MenuToolsEvent::class))->shouldBeCalled(); 30 | 31 | $this->buildMenu()->shouldReturnAnInstanceOf(Item::class); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Menu/Item/ElementItemSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Menu\Item; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\Element; 15 | use PhpSpec\ObjectBehavior; 16 | 17 | class ElementItemSpec extends ObjectBehavior 18 | { 19 | public function let(Element $element): void 20 | { 21 | $element->getRoute()->willReturn('route'); 22 | $element->getRouteParameters()->willReturn([]); 23 | $this->beConstructedWith('some name', $element); 24 | } 25 | 26 | public function it_has_default_options(): void 27 | { 28 | $this->getRoute()->shouldBe('route'); 29 | $this->getRouteParameters()->shouldBe([]); 30 | $this->getOptions()->shouldReturn(['attr' => ['id' => null, 'class' => null], 'elements' => []]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spec/FSi/Bundle/AdminBundle/Menu/Item/ItemSpec.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace spec\FSi\Bundle\AdminBundle\Menu\Item; 13 | 14 | use PhpSpec\ObjectBehavior; 15 | 16 | class ItemSpec extends ObjectBehavior 17 | { 18 | public function it_has_default_options(): void 19 | { 20 | $this->getOptions()->shouldReturn(['attr' => ['id' => null, 'class' => null]]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spec/fixtures/Admin/CustomClass.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Admin; 13 | 14 | use Doctrine\Persistence\ManagerRegistry; 15 | 16 | class DoctrineElement extends SimpleAdminElement 17 | { 18 | /** 19 | * @var ManagerRegistry 20 | */ 21 | private $registry; 22 | 23 | public function setManagerRegistry(ManagerRegistry $registry): void 24 | { 25 | $this->registry = $registry; 26 | } 27 | 28 | public function isDoctrineAware(): bool 29 | { 30 | return isset($this->registry); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spec/fixtures/Admin/RequestStackAwareElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\RequestStackAware; 15 | use Symfony\Component\HttpFoundation\RequestStack; 16 | 17 | class RequestStackAwareElement extends SimpleAdminElement implements RequestStackAware 18 | { 19 | /** 20 | * @var RequestStack 21 | */ 22 | private $requestStack; 23 | 24 | public function setRequestStack(RequestStack $requestStack): void 25 | { 26 | $this->requestStack = $requestStack; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spec/fixtures/Admin/SimpleAdminElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Admin; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\AbstractElement; 15 | use FSi\Bundle\AdminBundle\Annotation as Admin; 16 | use Symfony\Component\OptionsResolver\OptionsResolver; 17 | 18 | /** 19 | * @Admin\Element 20 | */ 21 | class SimpleAdminElement extends AbstractElement 22 | { 23 | public function getId(): string 24 | { 25 | return 'simple_admin_element'; 26 | } 27 | 28 | public function getRoute(): string 29 | { 30 | } 31 | 32 | public function configureOptions(OptionsResolver $resolver): void 33 | { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/fixtures/CustomAdmin/SimpleAdminElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\CustomAdmin; 13 | 14 | use FSi\Bundle\AdminBundle\spec\fixtures\Admin\SimpleAdminElement as BaseElement; 15 | 16 | class SimpleAdminElement extends BaseElement 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyBatchElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\BatchElement; 15 | 16 | class MyBatchElement extends BatchElement 17 | { 18 | public function getClassName(): string 19 | { 20 | return 'FSiDemoBundle:Entity'; 21 | } 22 | 23 | public function getId(): string 24 | { 25 | return 'my_entity_batch'; 26 | } 27 | 28 | public function apply($object): void 29 | { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyDeleteElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\DeleteElement; 15 | 16 | class MyDeleteElement extends DeleteElement 17 | { 18 | public function getClassName(): string 19 | { 20 | return 'FSiDemoBundle:Entity'; 21 | } 22 | 23 | public function getId(): string 24 | { 25 | return 'my_entity_batch'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyDependentBatchElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\DependentBatchElement; 15 | 16 | class MyDependentBatchElement extends DependentBatchElement 17 | { 18 | public function getClassName(): string 19 | { 20 | return 'FSiDemoBundle:Entity'; 21 | } 22 | 23 | public function getId(): string 24 | { 25 | return 'my_entity_batch'; 26 | } 27 | 28 | public function getParentId(): string 29 | { 30 | return 'my_parent_entity'; 31 | } 32 | 33 | public function apply($object): void 34 | { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyDependentDeleteElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\DependentDeleteElement; 15 | 16 | class MyDependentDeleteElement extends DependentDeleteElement 17 | { 18 | public function getClassName(): string 19 | { 20 | return 'FSiDemoBundle:Entity'; 21 | } 22 | 23 | public function getId(): string 24 | { 25 | return 'my_entity_delete'; 26 | } 27 | 28 | public function getParentId(): string 29 | { 30 | return 'my_parent_entity'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyDependentFormElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\DependentFormElement; 15 | use Symfony\Component\Form\FormFactoryInterface; 16 | use Symfony\Component\Form\FormInterface; 17 | 18 | class MyDependentFormElement extends DependentFormElement 19 | { 20 | public function getClassName(): string 21 | { 22 | return 'FSiDemoBundle:Entity'; 23 | } 24 | 25 | public function getId(): string 26 | { 27 | return 'my_entity_form'; 28 | } 29 | 30 | public function getParentId(): string 31 | { 32 | return 'my_parent_entity'; 33 | } 34 | 35 | protected function initForm(FormFactoryInterface $factory, $data = null): FormInterface 36 | { 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyDependentListElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\DependentListElement; 15 | use FSi\Component\DataGrid\DataGridFactoryInterface; 16 | use FSi\Component\DataGrid\DataGridInterface; 17 | use FSi\Component\DataSource\DataSourceFactoryInterface; 18 | use FSi\Component\DataSource\DataSourceInterface; 19 | 20 | class MyDependentListElement extends DependentListElement 21 | { 22 | public function getClassName(): string 23 | { 24 | return 'FSiDemoBundle:Entity'; 25 | } 26 | 27 | public function getId(): string 28 | { 29 | return 'my_entity'; 30 | } 31 | 32 | public function getParentId(): string 33 | { 34 | return 'my_parent_entity'; 35 | } 36 | 37 | protected function initDataGrid(DataGridFactoryInterface $factory): DataGridInterface 38 | { 39 | } 40 | 41 | protected function initDataSource(DataSourceFactoryInterface $factory): DataSourceInterface 42 | { 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyFormElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\FormElement; 15 | use Symfony\Component\Form\FormFactoryInterface; 16 | use Symfony\Component\Form\FormInterface; 17 | 18 | class MyFormElement extends FormElement 19 | { 20 | public function getClassName(): string 21 | { 22 | return 'FSiDemoBundle:Entity'; 23 | } 24 | 25 | public function getId(): string 26 | { 27 | return 'my_entity_form'; 28 | } 29 | 30 | protected function initForm(FormFactoryInterface $factory, $data = null): FormInterface 31 | { 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/fixtures/Doctrine/MyListElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Doctrine; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\ListElement; 15 | use FSi\Component\DataGrid\DataGridFactoryInterface; 16 | use FSi\Component\DataGrid\DataGridInterface; 17 | use FSi\Component\DataSource\DataSourceFactoryInterface; 18 | use FSi\Component\DataSource\DataSourceInterface; 19 | 20 | class MyListElement extends ListElement 21 | { 22 | public function getClassName(): string 23 | { 24 | return 'FSiDemoBundle:Entity'; 25 | } 26 | 27 | public function getId(): string 28 | { 29 | return 'my_entity'; 30 | } 31 | 32 | protected function initDataGrid(DataGridFactoryInterface $factory): DataGridInterface 33 | { 34 | } 35 | 36 | protected function initDataSource(DataSourceFactoryInterface $factory): DataSourceInterface 37 | { 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spec/fixtures/Entity/Resource.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures\Entity; 13 | 14 | use FSi\Bundle\ResourceRepositoryBundle\Model\Resource as BaseResource; 15 | 16 | class Resource extends BaseResource 17 | { 18 | } 19 | -------------------------------------------------------------------------------- /spec/fixtures/MyBatch.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures; 13 | 14 | use FSi\Bundle\AdminBundle\Admin\ResourceRepository\GenericResourceElement; 15 | use FSi\Bundle\ResourceRepositoryBundle\Model\ResourceValue; 16 | use FSi\Bundle\ResourceRepositoryBundle\Model\ResourceValueRepository; 17 | 18 | class MyResource extends GenericResourceElement 19 | { 20 | public function getKey(): string 21 | { 22 | return 'resources.main_page'; 23 | } 24 | 25 | public function getId(): string 26 | { 27 | return 'main_page'; 28 | } 29 | 30 | public function getResourceValueRepository(): ResourceValueRepository 31 | { 32 | } 33 | 34 | public function save(ResourceValue $resource): void 35 | { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /spec/fixtures/MyResourceElement.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | declare(strict_types=1); 11 | 12 | namespace FSi\Bundle\AdminBundle\spec\fixtures; 13 | 14 | use FSi\Bundle\AdminBundle\Doctrine\Admin\ResourceElement; 15 | 16 | class MyResourceElement extends ResourceElement 17 | { 18 | public function getId(): string 19 | { 20 | return 'main_page'; 21 | } 22 | 23 | public function getKey(): string 24 | { 25 | return 'resources.main_page'; 26 | } 27 | 28 | public function getClassName(): string 29 | { 30 | return 'FSi\Bundle\DemoBundle\Entity\Resource'; 31 | } 32 | } 33 | --------------------------------------------------------------------------------