* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace Chill\MainBundle\DependencyInjection; use Chill\MainBundle\Controller\UserController; use Chill\MainBundle\Doctrine\DQL\STContains; use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Form\UserJobType; use Chill\MainBundle\Form\UserType; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface; use Chill\MainBundle\DependencyInjection\Configuration; use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey; use Chill\MainBundle\Doctrine\DQL\Unaccent; use Chill\MainBundle\Doctrine\DQL\JsonAggregate; use Chill\MainBundle\Doctrine\DQL\JsonbExistsInArray; use Chill\MainBundle\Doctrine\DQL\Similarity; use Chill\MainBundle\Doctrine\DQL\OverlapsI; use Chill\MainBundle\Doctrine\DQL\Replace; use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator; use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType; use Chill\MainBundle\Doctrine\Type\PointType; use Symfony\Component\HttpFoundation\Request; /** * Class ChillMainExtension * This class load config for chillMainExtension. * * @package Chill\MainBundle\DependencyInjection */ class ChillMainExtension extends Extension implements PrependExtensionInterface, Widget\HasWidgetFactoriesExtensionInterface { /** * widget factory * * @var WidgetFactoryInterface[] */ protected $widgetFactories = array(); /** * @param WidgetFactoryInterface $factory */ public function addWidgetFactory(WidgetFactoryInterface $factory) { $this->widgetFactories[] = $factory; } /** * @return WidgetFactoryInterface[] */ public function getWidgetFactories() { return $this->widgetFactories; } /** * {@inheritDoc} * @param array $configs * @param ContainerBuilder $container * @throws \Exception */ public function load(array $configs, ContainerBuilder $container) { // configuration for main bundle $configuration = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($configuration, $configs); $container->setParameter('chill_main.installation_name', $config['installation_name']); $container->setParameter('chill_main.available_languages', $config['available_languages']); $container->setParameter('chill_main.routing.resources', $config['routing']['resources']); $container->setParameter('chill_main.pagination.item_per_page', $config['pagination']['item_per_page']); $container->setParameter('chill_main.notifications', $config['notifications']); $container->setParameter('chill_main.redis', $config['redis']); $container->setParameter('chill_main.phone_helper', $config['phone_helper'] ?? []); // add the key 'widget' without the key 'enable' $container->setParameter('chill_main.widgets', isset($config['widgets']['homepage']) ? array('homepage' => $config['widgets']['homepage']): array() ); $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); $loader->load('services.yaml'); $loader->load('services/doctrine.yaml'); $loader->load('services/logger.yaml'); $loader->load('services/pagination.yaml'); $loader->load('services/export.yaml'); $loader->load('services/form.yaml'); $loader->load('services/validator.yaml'); $loader->load('services/widget.yaml'); $loader->load('services/controller.yaml'); $loader->load('services/routing.yaml'); $loader->load('services/fixtures.yaml'); $loader->load('services/menu.yaml'); $loader->load('services/security.yaml'); $loader->load('services/notification.yaml'); $loader->load('services/redis.yaml'); $loader->load('services/command.yaml'); $loader->load('services/phonenumber.yaml'); $loader->load('services/cache.yaml'); $loader->load('services/templating.yaml'); $loader->load('services/timeline.yaml'); $loader->load('services/search.yaml'); $loader->load('services/serializer.yaml'); $this->configureCruds($container, $config['cruds'], $config['apis'], $loader); } /** * @param array $config * @param ContainerBuilder $container * @return \Chill\MainBundle\DependencyInjection\Configuration|null|object|\Symfony\Component\Config\Definition\ConfigurationInterface */ public function getConfiguration(array $config, ContainerBuilder $container) { return new Configuration($this->widgetFactories, $container); } /** * @param ContainerBuilder $container */ public function prepend(ContainerBuilder $container) { //add installation_name and date_format to globals $chillMainConfig = $container->getExtensionConfig($this->getAlias()); $config = $this->processConfiguration($this ->getConfiguration($chillMainConfig, $container), $chillMainConfig); $twigConfig = array( 'globals' => array( 'installation' => array( 'name' => $config['installation_name']), 'available_languages' => $config['available_languages'] ), 'form_themes' => array('@ChillMain/Form/fields.html.twig') ); $container->prependExtensionConfig('twig', $twigConfig); //add DQL function to ORM (default entity_manager) $container ->prependExtensionConfig( 'doctrine', [ 'orm' => [ 'dql' => [ 'string_functions' => [ 'unaccent' => Unaccent::class, 'GET_JSON_FIELD_BY_KEY' => GetJsonFieldByKey::class, 'AGGREGATE' => JsonAggregate::class, 'REPLACE' => Replace::class, ], 'numeric_functions' => [ 'JSONB_EXISTS_IN_ARRAY' => JsonbExistsInArray::class, 'SIMILARITY' => Similarity::class, 'OVERLAPSI' => OverlapsI::class, 'STRICT_WORD_SIMILARITY_OPS' => StrictWordSimilarityOPS::class, 'ST_CONTAINS' => STContains::class, ], ], 'hydrators' => [ 'chill_flat_hierarchy_list' => FlatHierarchyEntityHydrator::class, ], ], ], ); //add dbal types (default entity_manager) $container ->prependExtensionConfig( 'doctrine', [ 'dbal' => [ // ignore views: 'schema_filter' => '~^(?!view_)~', // This is mandatory since we are using postgis as database. 'mapping_types' => [ 'geometry' => 'string', ], 'types' => [ 'dateinterval' => [ 'class' => NativeDateIntervalType::class ], 'point' => [ 'class' => PointType::class ] ] ] ] ); //add current route to chill main $container->prependExtensionConfig('chill_main', array( 'routing' => array( 'resources' => array( '@ChillMainBundle/config/routes.yaml' ) ) )); //add a channel to log app events $container->prependExtensionConfig('monolog', array( 'channels' => array('chill') )); //add crud api $this->prependCruds($container); } /** * Load parameter for configuration and set parameters for api */ protected function configureCruds( ContainerBuilder $container, array $crudConfig, array $apiConfig, Loader\YamlFileLoader $loader ): void { if (count($crudConfig) === 0) { return; } $loader->load('services/crud.yaml'); $container->setParameter('chill_main_crud_route_loader_config', $crudConfig); $container->setParameter('chill_main_api_route_loader_config', $apiConfig); // Note: the controller are loaded inside compiler pass } /** * @param ContainerBuilder $container */ protected function prependCruds(ContainerBuilder $container) { $container->prependExtensionConfig('chill_main', [ 'cruds' => [ [ 'class' => UserJob::class, 'name' => 'admin_user_job', 'base_path' => '/admin/main/user-job', 'base_role' => 'ROLE_ADMIN', 'form_class' => UserJobType::class, 'actions' => [ 'index' => [ 'role' => 'ROLE_ADMIN', 'template' => '@ChillMain/UserJob/index.html.twig', ], 'new' => [ 'role' => 'ROLE_ADMIN' ], 'edit' => [ 'role' => 'ROLE_ADMIN' ] ], ], [ 'class' => User::class, 'controller' => UserController::class, 'name' => 'admin_user', 'base_path' => '/admin/main/user2', 'base_role' => 'ROLE_ADMIN', 'form_class' => UserType::class, 'actions' => [ 'index' => [ 'role' => 'ROLE_ADMIN', 'template' => '@ChillMain/User/index.html.twig' ], 'new' => [ 'role' => 'ROLE_ADMIN', ], 'edit' => [ 'role' => 'ROLE_ADMIN', ] ] ] ], 'apis' => [ [ 'class' => \Chill\MainBundle\Entity\Address::class, 'name' => 'address', 'base_path' => '/api/1.0/main/address', 'base_role' => 'ROLE_USER', 'actions' => [ '_index' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ], ], '_entity' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_POST => true, Request::METHOD_HEAD => true, Request::METHOD_PATCH => true ] ], ] ], [ 'controller' => \Chill\MainBundle\Controller\AddressReferenceAPIController::class, 'class' => \Chill\MainBundle\Entity\AddressReference::class, 'name' => 'address_reference', 'base_path' => '/api/1.0/main/address-reference', 'base_role' => 'ROLE_USER', 'actions' => [ '_index' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ], ], '_entity' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ] ], ] ], [ 'controller' => \Chill\MainBundle\Controller\PostalCodeAPIController::class, 'class' => \Chill\MainBundle\Entity\PostalCode::class, 'name' => 'postal_code', 'base_path' => '/api/1.0/main/postal-code', 'base_role' => 'ROLE_USER', 'actions' => [ '_index' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ], ], '_entity' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true, Request::METHOD_POST => true, ] ], ] ], [ 'class' => \Chill\MainBundle\Entity\Country::class, 'name' => 'country', 'base_path' => '/api/1.0/main/country', 'base_role' => 'ROLE_USER', 'actions' => [ '_index' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ], ], '_entity' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ] ], ] ], [ 'class' => \Chill\MainBundle\Entity\User::class, 'controller' => \Chill\MainBundle\Controller\UserApiController::class, 'name' => 'user', 'base_path' => '/api/1.0/main/user', 'base_role' => 'ROLE_USER', 'actions' => [ '_index' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ], ], '_entity' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true, ] ], ] ], [ 'class' => \Chill\MainBundle\Entity\Scope::class, 'name' => 'scope', 'base_path' => '/api/1.0/main/scope', 'base_role' => 'ROLE_USER', 'actions' => [ '_index' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true ], ], '_entity' => [ 'methods' => [ Request::METHOD_GET => true, Request::METHOD_HEAD => true, ] ], ] ], ] ]); } }