Loading module/Application/src/Form/AbstractFieldset.php +2 −20 Original line number Diff line number Diff line Loading @@ -2,29 +2,11 @@ namespace Application\Form; use Application\Traits\FormFieldsetTrait; use Laminas\Form\Fieldset; use Laminas\InputFilter\InputFilterProviderInterface; abstract class AbstractFieldset extends Fieldset implements InputFilterProviderInterface { /** * Generates a url given the name of a route. * * @param string $name Name of the route * @param array $params Parameters for the link * @param array|Traversable $options Options for the route * @param bool $reuseMatchedParams Whether to reuse matched parameters * * @return string Url For the link href attribute * @see \Laminas\Mvc\Router\RouteInterface::assemble() * */ protected function getUrl($name = null, $params = [], $options = [], $reuseMatchedParams = false) { $url = \Application::$container->get('ViewHelperManager')->get('url'); /* @var $url \Laminas\View\Helper\Url */ return $url->__invoke($name, $params, $options, $reuseMatchedParams); } use FormFieldsetTrait; } No newline at end of file module/Application/src/Form/AbstractForm.php +2 −492 Original line number Diff line number Diff line Loading @@ -2,159 +2,17 @@ namespace Application\Form; use Application\Constants; use Application\Filter\FloatFromString; use Application\Hydrator\GenericHydrator; use Application\Interfaces\ParametreEntityInterface; use Application\Service\AbstractEntityService; use Application\Traits\TranslatorTrait; use Doctrine\ORM\EntityManager; use Laminas\Form\Element\Checkbox; use Laminas\Form\Element\Csrf; use Laminas\Form\Element\Number; use Laminas\Form\Element\Select; use Laminas\Form\Element\Text; use Application\Traits\FormFieldsetTrait; use Laminas\Form\Form; use Laminas\Http\Request; use Laminas\InputFilter\InputFilterProviderInterface; use Laminas\Mvc\Plugin\FlashMessenger\FlashMessenger; use Laminas\Stdlib\ArrayUtils; use UnicaenApp\Entity\HistoriqueAwareInterface; use UnicaenApp\Util; abstract class AbstractForm extends Form implements InputFilterProviderInterface { use TranslatorTrait; private ?FlashMessenger $controllerPluginFlashMessenger = null; private ?EntityManager $entityManager = null; protected array $spec = []; protected function getEntityManager(): EntityManager { if (!$this->entityManager) { $this->entityManager = \Application::$container->get(Constants::BDD); } return $this->entityManager; } private function getControllerPluginFlashMessenger(): FlashMessenger { if (!$this->controllerPluginFlashMessenger) { $this->controllerPluginFlashMessenger = \Application::$container->get('ControllerPluginManager')->get('flashMessenger'); } return $this->controllerPluginFlashMessenger; } /** * Generates a url given the name of a route. * * @param string $name Name of the route * @param array $params Parameters for the link * @param array|Traversable $options Options for the route * @param bool $reuseMatchedParams Whether to reuse matched parameters * * @return string For the link href attribute * @see \Laminas\Mvc\Router\RouteInterface::assemble() * */ protected function getUrl($name = null, $params = [], $options = [], $reuseMatchedParams = false): string { $url = \Application::$container->get('ViewHelperManager')->get('url'); /* @var $url \Laminas\View\Helper\Url */ return $url->__invoke($name, $params, $options, $reuseMatchedParams); } /** * @return string */ protected function getCurrentUrl() { return $this->getUrl(null, [], [], true); } public function spec(string|object|array $spec, array $ignore = []) { if (is_string($spec) && class_exists($spec)) { return $this->specFromClass($spec, $ignore); } if (is_object($spec)) { return $this->specFromObject($spec, $ignore); } if (is_array($spec)) { return $this->specFromArray($spec, $ignore); } throw new \Exception('La spécification fournie n\'est pas exploitable'); } public function specDump() { echo '<pre>'; foreach ($this->spec as $name => $spec) { echo '<h3>' . $name . '</h3>'; phpDump($spec); } echo '</pre>'; } public function build() { if (!$this->hasAttribute('action')) { $this->setAttribute('action', $this->getCurrentUrl()); } if (!$this->hydrator) { $hydratorElements = []; foreach ($this->spec as $name => $spec) { if (isset($spec['hydrator'])) { $hydratorElements[$name] = $spec['hydrator']; } } $hydrator = new GenericHydrator($this->getEntityManager(), $hydratorElements); $this->setHydrator($hydrator); } foreach ($this->spec as $elName => $elSpec) { if (isset($elSpec['input'])) { unset($elSpec['input']); } if (isset($elSpec['hydrator'])) { unset($elSpec['hydrator']); } if (!empty($elSpec)) { try { $this->add($elSpec); } catch (\Throwable $e) { throw new \Exception('L\'élément de formulaire "' . $elName . '" n\'a pas pu être généré depuis sa spécification', 0, $e); } } } $this->add(new Csrf('security')); } use FormFieldsetTrait; public function addSubmit(string $value = 'Enregistrer'): self Loading @@ -173,201 +31,6 @@ abstract class AbstractForm extends Form implements InputFilterProviderInterface public function setLabels(array $labels): self { foreach ($labels as $element => $label) { if ($this->has($element)) { $this->get($element)->setLabel($label); } } return $this; } /** * Permet de peupler facilement une liste d'options * Accepte pour $collection : * - Un tableau d'entités * - Une requête DQL * - Un tableau associatif ([value => label, ...]) * * $params sert à fournir d'éventuels paramètres si $collection est une requête DQL * * @param string $name * @param string|array $collection * @param $params * * @return $this * @throws \Exception */ public function setValueOptions(string $name, string|array $collection, $params = null): self { if (!$this->has($name)) { throw new \Exception('Elément ' . $name . ' non trouvé'); } $element = $this->get($name); if (!method_exists($element, 'setValueOptions')) { throw new \Exception('L\élément ' . $name . ' ne peut pas se voir associer de listes d\'options'); } if (is_string($collection)) { $query = $this->getEntityManager()->createQuery($collection); if (is_array($params)) { $query->setParameters($params); } $element->setValueOptions(Util::collectionAsOptions($query->getResult())); } if (is_array($collection)) { $element->setValueOptions(Util::collectionAsOptions($collection)); } return $this; } /** * Permet de peupler facilement une liste d'options à l'aide d'une requête SQL * la clé doit correspondre à la colonne VALUE et à défaut ID ou CODE ou SOURCE_CODE * la valeur doit correspondre à la colonne LABEL et à défaut LIBELLE ou LIBELLE_COURT * Si la clé est introuvable, alors la ligne est ignorée * * @param string $name * @param string $query * @param array $params * * @return $this * @throws \Doctrine\DBAL\Exception */ public function setValueOptionsSql(string $name, string $query, array $params = []): self { $res = $this->getEntityManager()->getConnection()->fetchAllAssociative($query, $params); $options = []; foreach ($res as $r) { $value = $r['VALUE'] ?? $r['ID'] ?? $r['CODE'] ?? $r['SOURCE_CODE'] ?? null; $label = $r['LABEL'] ?? $r['LIBELLE'] ?? $r['LIBELLE_COURT'] ?? null; if ($value && $label) { $options[$value] = $label; } } asort($options); return $this->setValueOptions($name, $options); } private function specFromClass(string $class, array $ignore): self { $elements = []; $rc = new \ReflectionClass($class); $methods = $rc->getMethods(); if ($rc->implementsInterface(HistoriqueAwareInterface::class)) { $ignore[] = 'histoCreation'; $ignore[] = 'histoCreateur'; $ignore[] = 'histoModification'; $ignore[] = 'histoModificateur'; $ignore[] = 'histoDestruction'; $ignore[] = 'histoDestructeur'; } if ($rc->implementsInterface(ParametreEntityInterface::class)) { $ignore[] = 'annee'; } foreach ($methods as $method) { $property = null; if (str_starts_with($method->name, 'get')) { $property = substr($method->name, 3); } elseif (str_starts_with($method->name, 'is')) { $property = substr($method->name, 2); } if ($property) { if (!$rc->hasMethod('set' . $property)) { $property = null; } } if ($property) { $elKey = lcfirst($property); if (!in_array($elKey, $ignore)) { $element = [ 'hydrator' => [ 'getter' => $method->name, 'setter' => 'set' . $property, ], ]; if ($method->hasReturnType()) { $rt = $method->getReturnType(); if ($rt instanceof \ReflectionNamedType) { $element['hydrator']['type'] = $rt->getName(); } elseif ($rt instanceof \ReflectionUnionType) { $element['hydrator']['type'] = $rt->getTypes()[0]->getName(); } } $elements[$elKey] = $element; } } } /* Si c'est une entité Doctrine, on récupère les infos du mapping */ try { $cmd = $this->getEntityManager()->getClassMetadata($class); } catch (\Exception $e) { $cmd = null; } if (!empty($elements) && !empty($cmd)) { foreach ($elements as $property => $element) { if ($cmd->hasField($property)) { $mapping = $cmd->getFieldMapping($property); $this->elementAddMapping($elements[$property], $mapping); } } } /* Ajout d'un élément caché pour l'ID */ if ($cmd && $cmd->hasField('id')) { $elements['id'] = ['type' => 'Hidden', 'name' => 'id']; } /* Construction des éléments de formulaires */ if (!empty($elements)) { foreach ($elements as $property => $element) { $this->makeElement($property, $elements[$property]); } } $this->specFromArray($elements, []); return $this; } private function specFromObject(object $object, array $ignore): self { return $this->specFromClass(get_class($object), $ignore); } private function specFromArray(array $spec, array $ignore): self { foreach ($spec as $k => $v) { if (in_array($k, $ignore)) { unset($spec[$k]); } } $this->spec = ArrayUtils::merge($this->spec, $spec); return $this; } /** * Exécute la sauvegarde d'un formulaire à partir des données Request * Loading Loading @@ -451,157 +114,4 @@ abstract class AbstractForm extends Form implements InputFilterProviderInterface return true; } public function readOnly(bool $readOnly = true) { /** @var $element \Laminas\Form\Element */ foreach ($this->getElements() as $element) { switch (get_class($element)) { case Number::class: case Text::class: $element->setAttribute('readonly', $readOnly); break; case Select::class: case Checkbox::class: $element->setAttribute('disabled', $readOnly); break; } } } public function getInputFilterSpecification() { $filters = []; foreach ($this->spec as $name => $elSpec) { if (isset($elSpec['input'])) { $filters[$name] = $elSpec['input']; } } return $filters; } private function elementAddMapping(array &$element, array $mapping) { /* Gestion du Required */ if (isset($mapping['nullable'])) { if (!isset($element['input'])) { $element['input'] = []; } $element['input']['required'] = !$mapping['nullable']; } /* Gestion des length */ if (($mapping['type'] ?? '') == 'string' && isset($mapping['length']) && $mapping['length']) { if (!isset($element['input'])) { $element['input'] = []; } if (!isset($element['input']['validators'])) { $element['input']['validators'] = []; } $element['input']['validators'][] = [ 'name' => 'StringLength', 'options' => ['max' => $mapping['length']], ]; } } protected function makeElement(string $property, array &$element) { $spec = []; switch ($element['hydrator']['type'] ?? '') { case 'string': $spec = [ 'type' => 'Text', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], ]; break; case 'bool': case 'boolean': $spec = [ 'type' => 'Checkbox', 'name' => $property, 'options' => [ 'label' => ucfirst($property), 'checked_value' => '1', 'unchecked_value' => '0', ], ]; break; case 'float': $spec = [ 'type' => 'Text', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], 'input' => [ 'filters' => [ ['name' => 'Laminas\Filter\StringTrim'], ['name' => FloatFromString::class], ], ], ]; break; case 'int': $spec = [ 'type' => 'Text', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], 'input' => [ 'filters' => [ ['name' => 'Laminas\Filter\StringTrim'], ], ], ]; break; case \DateTime::class: $spec = [ 'type' => 'DateTime', 'name' => $property, 'options' => [ 'label' => ucfirst($property), 'format' => Constants::DATE_FORMAT, 'label_options' => [ 'disable_html_escape' => true, ], ], 'attributes' => [ 'placeholder' => "jj/mm/aaaa", ], ]; break; } /* Si c'est une entité Doctrine, alors on présuppose qu'on a affaire à un Select */ try { $this->getEntityManager()->getClassMetadata($element['hydrator']['type'] ?? ''); $spec = [ 'type' => 'Select', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], ]; } catch (\Exception $e) { } if (!empty($spec)) { $element = ArrayUtils::merge($element, $spec); } } } No newline at end of file module/Application/src/Form/OffreFormation/ElementPedagogiqueRechercheFieldset.php +1 −4 Original line number Diff line number Diff line Loading @@ -5,8 +5,6 @@ namespace Application\Form\OffreFormation; use Application\Entity\Db\ElementPedagogique; use Application\Form\AbstractFieldset; use Application\Service\Traits\ContextServiceAwareTrait; use UnicaenApp\Service\EntityManagerAwareInterface; use UnicaenApp\Service\EntityManagerAwareTrait; use UnicaenApp\Traits\SessionContainerTrait; use Doctrine\ORM\QueryBuilder; use Application\Service\Traits\ElementPedagogiqueServiceAwareTrait; Loading @@ -17,9 +15,8 @@ use Laminas\Hydrator\HydratorInterface; * Description of ElementPedagogiqueRechercheFieldset * */ class ElementPedagogiqueRechercheFieldset extends AbstractFieldset implements EntityManagerAwareInterface class ElementPedagogiqueRechercheFieldset extends AbstractFieldset { use EntityManagerAwareTrait; use ContextServiceAwareTrait; use SessionContainerTrait; use ElementPedagogiqueServiceAwareTrait; Loading module/Application/src/Form/ServiceReferentiel/SaisieFieldset.php +1 −4 Original line number Diff line number Diff line Loading @@ -12,8 +12,6 @@ use Application\Service\Traits\FonctionReferentielServiceAwareTrait; use Application\Service\Traits\LocalContextServiceAwareTrait; use Application\Service\Traits\StructureServiceAwareTrait; use UnicaenApp\Form\Element\SearchAndSelect; use UnicaenApp\Service\EntityManagerAwareInterface; use UnicaenApp\Service\EntityManagerAwaretrait; use UnicaenApp\Util; use Laminas\Filter\PregReplace; use Laminas\Validator\Callback; Loading @@ -28,13 +26,12 @@ use Laminas\Hydrator\HydratorInterface; * * @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr> */ class SaisieFieldset extends AbstractFieldset implements EntityManagerAwareInterface class SaisieFieldset extends AbstractFieldset { use ContextServiceAwareTrait; use LocalContextServiceAwareTrait; use StructureServiceAwareTrait; use FonctionReferentielServiceAwareTrait; use EntityManagerAwareTrait; /** * @var Structure[] Loading module/Application/src/Form/TypeIntervention/TypeInterventionStructureSaisieForm.php +2 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Application\Form\TypeIntervention; use Application\Entity\Db\Traits\TypeInterventionStructureAwareTrait; use Application\Form\AbstractForm; use Application\Service\Traits\TypeInterventionServiceAwareTrait; use Application\Service\Traits\TypeInterventionStructureServiceAwareTrait; Loading @@ -19,7 +20,7 @@ use UnicaenApp\Util; */ class TypeInterventionStructureSaisieForm extends AbstractForm { use \Application\Entity\Db\Traits\TypeInterventionStructureAwareTrait; use TypeInterventionStructureAwareTrait; use StructureServiceAwareTrait; use ContextServiceAwareTrait; use AnneeServiceAwareTrait; Loading Loading
module/Application/src/Form/AbstractFieldset.php +2 −20 Original line number Diff line number Diff line Loading @@ -2,29 +2,11 @@ namespace Application\Form; use Application\Traits\FormFieldsetTrait; use Laminas\Form\Fieldset; use Laminas\InputFilter\InputFilterProviderInterface; abstract class AbstractFieldset extends Fieldset implements InputFilterProviderInterface { /** * Generates a url given the name of a route. * * @param string $name Name of the route * @param array $params Parameters for the link * @param array|Traversable $options Options for the route * @param bool $reuseMatchedParams Whether to reuse matched parameters * * @return string Url For the link href attribute * @see \Laminas\Mvc\Router\RouteInterface::assemble() * */ protected function getUrl($name = null, $params = [], $options = [], $reuseMatchedParams = false) { $url = \Application::$container->get('ViewHelperManager')->get('url'); /* @var $url \Laminas\View\Helper\Url */ return $url->__invoke($name, $params, $options, $reuseMatchedParams); } use FormFieldsetTrait; } No newline at end of file
module/Application/src/Form/AbstractForm.php +2 −492 Original line number Diff line number Diff line Loading @@ -2,159 +2,17 @@ namespace Application\Form; use Application\Constants; use Application\Filter\FloatFromString; use Application\Hydrator\GenericHydrator; use Application\Interfaces\ParametreEntityInterface; use Application\Service\AbstractEntityService; use Application\Traits\TranslatorTrait; use Doctrine\ORM\EntityManager; use Laminas\Form\Element\Checkbox; use Laminas\Form\Element\Csrf; use Laminas\Form\Element\Number; use Laminas\Form\Element\Select; use Laminas\Form\Element\Text; use Application\Traits\FormFieldsetTrait; use Laminas\Form\Form; use Laminas\Http\Request; use Laminas\InputFilter\InputFilterProviderInterface; use Laminas\Mvc\Plugin\FlashMessenger\FlashMessenger; use Laminas\Stdlib\ArrayUtils; use UnicaenApp\Entity\HistoriqueAwareInterface; use UnicaenApp\Util; abstract class AbstractForm extends Form implements InputFilterProviderInterface { use TranslatorTrait; private ?FlashMessenger $controllerPluginFlashMessenger = null; private ?EntityManager $entityManager = null; protected array $spec = []; protected function getEntityManager(): EntityManager { if (!$this->entityManager) { $this->entityManager = \Application::$container->get(Constants::BDD); } return $this->entityManager; } private function getControllerPluginFlashMessenger(): FlashMessenger { if (!$this->controllerPluginFlashMessenger) { $this->controllerPluginFlashMessenger = \Application::$container->get('ControllerPluginManager')->get('flashMessenger'); } return $this->controllerPluginFlashMessenger; } /** * Generates a url given the name of a route. * * @param string $name Name of the route * @param array $params Parameters for the link * @param array|Traversable $options Options for the route * @param bool $reuseMatchedParams Whether to reuse matched parameters * * @return string For the link href attribute * @see \Laminas\Mvc\Router\RouteInterface::assemble() * */ protected function getUrl($name = null, $params = [], $options = [], $reuseMatchedParams = false): string { $url = \Application::$container->get('ViewHelperManager')->get('url'); /* @var $url \Laminas\View\Helper\Url */ return $url->__invoke($name, $params, $options, $reuseMatchedParams); } /** * @return string */ protected function getCurrentUrl() { return $this->getUrl(null, [], [], true); } public function spec(string|object|array $spec, array $ignore = []) { if (is_string($spec) && class_exists($spec)) { return $this->specFromClass($spec, $ignore); } if (is_object($spec)) { return $this->specFromObject($spec, $ignore); } if (is_array($spec)) { return $this->specFromArray($spec, $ignore); } throw new \Exception('La spécification fournie n\'est pas exploitable'); } public function specDump() { echo '<pre>'; foreach ($this->spec as $name => $spec) { echo '<h3>' . $name . '</h3>'; phpDump($spec); } echo '</pre>'; } public function build() { if (!$this->hasAttribute('action')) { $this->setAttribute('action', $this->getCurrentUrl()); } if (!$this->hydrator) { $hydratorElements = []; foreach ($this->spec as $name => $spec) { if (isset($spec['hydrator'])) { $hydratorElements[$name] = $spec['hydrator']; } } $hydrator = new GenericHydrator($this->getEntityManager(), $hydratorElements); $this->setHydrator($hydrator); } foreach ($this->spec as $elName => $elSpec) { if (isset($elSpec['input'])) { unset($elSpec['input']); } if (isset($elSpec['hydrator'])) { unset($elSpec['hydrator']); } if (!empty($elSpec)) { try { $this->add($elSpec); } catch (\Throwable $e) { throw new \Exception('L\'élément de formulaire "' . $elName . '" n\'a pas pu être généré depuis sa spécification', 0, $e); } } } $this->add(new Csrf('security')); } use FormFieldsetTrait; public function addSubmit(string $value = 'Enregistrer'): self Loading @@ -173,201 +31,6 @@ abstract class AbstractForm extends Form implements InputFilterProviderInterface public function setLabels(array $labels): self { foreach ($labels as $element => $label) { if ($this->has($element)) { $this->get($element)->setLabel($label); } } return $this; } /** * Permet de peupler facilement une liste d'options * Accepte pour $collection : * - Un tableau d'entités * - Une requête DQL * - Un tableau associatif ([value => label, ...]) * * $params sert à fournir d'éventuels paramètres si $collection est une requête DQL * * @param string $name * @param string|array $collection * @param $params * * @return $this * @throws \Exception */ public function setValueOptions(string $name, string|array $collection, $params = null): self { if (!$this->has($name)) { throw new \Exception('Elément ' . $name . ' non trouvé'); } $element = $this->get($name); if (!method_exists($element, 'setValueOptions')) { throw new \Exception('L\élément ' . $name . ' ne peut pas se voir associer de listes d\'options'); } if (is_string($collection)) { $query = $this->getEntityManager()->createQuery($collection); if (is_array($params)) { $query->setParameters($params); } $element->setValueOptions(Util::collectionAsOptions($query->getResult())); } if (is_array($collection)) { $element->setValueOptions(Util::collectionAsOptions($collection)); } return $this; } /** * Permet de peupler facilement une liste d'options à l'aide d'une requête SQL * la clé doit correspondre à la colonne VALUE et à défaut ID ou CODE ou SOURCE_CODE * la valeur doit correspondre à la colonne LABEL et à défaut LIBELLE ou LIBELLE_COURT * Si la clé est introuvable, alors la ligne est ignorée * * @param string $name * @param string $query * @param array $params * * @return $this * @throws \Doctrine\DBAL\Exception */ public function setValueOptionsSql(string $name, string $query, array $params = []): self { $res = $this->getEntityManager()->getConnection()->fetchAllAssociative($query, $params); $options = []; foreach ($res as $r) { $value = $r['VALUE'] ?? $r['ID'] ?? $r['CODE'] ?? $r['SOURCE_CODE'] ?? null; $label = $r['LABEL'] ?? $r['LIBELLE'] ?? $r['LIBELLE_COURT'] ?? null; if ($value && $label) { $options[$value] = $label; } } asort($options); return $this->setValueOptions($name, $options); } private function specFromClass(string $class, array $ignore): self { $elements = []; $rc = new \ReflectionClass($class); $methods = $rc->getMethods(); if ($rc->implementsInterface(HistoriqueAwareInterface::class)) { $ignore[] = 'histoCreation'; $ignore[] = 'histoCreateur'; $ignore[] = 'histoModification'; $ignore[] = 'histoModificateur'; $ignore[] = 'histoDestruction'; $ignore[] = 'histoDestructeur'; } if ($rc->implementsInterface(ParametreEntityInterface::class)) { $ignore[] = 'annee'; } foreach ($methods as $method) { $property = null; if (str_starts_with($method->name, 'get')) { $property = substr($method->name, 3); } elseif (str_starts_with($method->name, 'is')) { $property = substr($method->name, 2); } if ($property) { if (!$rc->hasMethod('set' . $property)) { $property = null; } } if ($property) { $elKey = lcfirst($property); if (!in_array($elKey, $ignore)) { $element = [ 'hydrator' => [ 'getter' => $method->name, 'setter' => 'set' . $property, ], ]; if ($method->hasReturnType()) { $rt = $method->getReturnType(); if ($rt instanceof \ReflectionNamedType) { $element['hydrator']['type'] = $rt->getName(); } elseif ($rt instanceof \ReflectionUnionType) { $element['hydrator']['type'] = $rt->getTypes()[0]->getName(); } } $elements[$elKey] = $element; } } } /* Si c'est une entité Doctrine, on récupère les infos du mapping */ try { $cmd = $this->getEntityManager()->getClassMetadata($class); } catch (\Exception $e) { $cmd = null; } if (!empty($elements) && !empty($cmd)) { foreach ($elements as $property => $element) { if ($cmd->hasField($property)) { $mapping = $cmd->getFieldMapping($property); $this->elementAddMapping($elements[$property], $mapping); } } } /* Ajout d'un élément caché pour l'ID */ if ($cmd && $cmd->hasField('id')) { $elements['id'] = ['type' => 'Hidden', 'name' => 'id']; } /* Construction des éléments de formulaires */ if (!empty($elements)) { foreach ($elements as $property => $element) { $this->makeElement($property, $elements[$property]); } } $this->specFromArray($elements, []); return $this; } private function specFromObject(object $object, array $ignore): self { return $this->specFromClass(get_class($object), $ignore); } private function specFromArray(array $spec, array $ignore): self { foreach ($spec as $k => $v) { if (in_array($k, $ignore)) { unset($spec[$k]); } } $this->spec = ArrayUtils::merge($this->spec, $spec); return $this; } /** * Exécute la sauvegarde d'un formulaire à partir des données Request * Loading Loading @@ -451,157 +114,4 @@ abstract class AbstractForm extends Form implements InputFilterProviderInterface return true; } public function readOnly(bool $readOnly = true) { /** @var $element \Laminas\Form\Element */ foreach ($this->getElements() as $element) { switch (get_class($element)) { case Number::class: case Text::class: $element->setAttribute('readonly', $readOnly); break; case Select::class: case Checkbox::class: $element->setAttribute('disabled', $readOnly); break; } } } public function getInputFilterSpecification() { $filters = []; foreach ($this->spec as $name => $elSpec) { if (isset($elSpec['input'])) { $filters[$name] = $elSpec['input']; } } return $filters; } private function elementAddMapping(array &$element, array $mapping) { /* Gestion du Required */ if (isset($mapping['nullable'])) { if (!isset($element['input'])) { $element['input'] = []; } $element['input']['required'] = !$mapping['nullable']; } /* Gestion des length */ if (($mapping['type'] ?? '') == 'string' && isset($mapping['length']) && $mapping['length']) { if (!isset($element['input'])) { $element['input'] = []; } if (!isset($element['input']['validators'])) { $element['input']['validators'] = []; } $element['input']['validators'][] = [ 'name' => 'StringLength', 'options' => ['max' => $mapping['length']], ]; } } protected function makeElement(string $property, array &$element) { $spec = []; switch ($element['hydrator']['type'] ?? '') { case 'string': $spec = [ 'type' => 'Text', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], ]; break; case 'bool': case 'boolean': $spec = [ 'type' => 'Checkbox', 'name' => $property, 'options' => [ 'label' => ucfirst($property), 'checked_value' => '1', 'unchecked_value' => '0', ], ]; break; case 'float': $spec = [ 'type' => 'Text', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], 'input' => [ 'filters' => [ ['name' => 'Laminas\Filter\StringTrim'], ['name' => FloatFromString::class], ], ], ]; break; case 'int': $spec = [ 'type' => 'Text', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], 'input' => [ 'filters' => [ ['name' => 'Laminas\Filter\StringTrim'], ], ], ]; break; case \DateTime::class: $spec = [ 'type' => 'DateTime', 'name' => $property, 'options' => [ 'label' => ucfirst($property), 'format' => Constants::DATE_FORMAT, 'label_options' => [ 'disable_html_escape' => true, ], ], 'attributes' => [ 'placeholder' => "jj/mm/aaaa", ], ]; break; } /* Si c'est une entité Doctrine, alors on présuppose qu'on a affaire à un Select */ try { $this->getEntityManager()->getClassMetadata($element['hydrator']['type'] ?? ''); $spec = [ 'type' => 'Select', 'name' => $property, 'options' => [ 'label' => ucfirst($property), ], ]; } catch (\Exception $e) { } if (!empty($spec)) { $element = ArrayUtils::merge($element, $spec); } } } No newline at end of file
module/Application/src/Form/OffreFormation/ElementPedagogiqueRechercheFieldset.php +1 −4 Original line number Diff line number Diff line Loading @@ -5,8 +5,6 @@ namespace Application\Form\OffreFormation; use Application\Entity\Db\ElementPedagogique; use Application\Form\AbstractFieldset; use Application\Service\Traits\ContextServiceAwareTrait; use UnicaenApp\Service\EntityManagerAwareInterface; use UnicaenApp\Service\EntityManagerAwareTrait; use UnicaenApp\Traits\SessionContainerTrait; use Doctrine\ORM\QueryBuilder; use Application\Service\Traits\ElementPedagogiqueServiceAwareTrait; Loading @@ -17,9 +15,8 @@ use Laminas\Hydrator\HydratorInterface; * Description of ElementPedagogiqueRechercheFieldset * */ class ElementPedagogiqueRechercheFieldset extends AbstractFieldset implements EntityManagerAwareInterface class ElementPedagogiqueRechercheFieldset extends AbstractFieldset { use EntityManagerAwareTrait; use ContextServiceAwareTrait; use SessionContainerTrait; use ElementPedagogiqueServiceAwareTrait; Loading
module/Application/src/Form/ServiceReferentiel/SaisieFieldset.php +1 −4 Original line number Diff line number Diff line Loading @@ -12,8 +12,6 @@ use Application\Service\Traits\FonctionReferentielServiceAwareTrait; use Application\Service\Traits\LocalContextServiceAwareTrait; use Application\Service\Traits\StructureServiceAwareTrait; use UnicaenApp\Form\Element\SearchAndSelect; use UnicaenApp\Service\EntityManagerAwareInterface; use UnicaenApp\Service\EntityManagerAwaretrait; use UnicaenApp\Util; use Laminas\Filter\PregReplace; use Laminas\Validator\Callback; Loading @@ -28,13 +26,12 @@ use Laminas\Hydrator\HydratorInterface; * * @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr> */ class SaisieFieldset extends AbstractFieldset implements EntityManagerAwareInterface class SaisieFieldset extends AbstractFieldset { use ContextServiceAwareTrait; use LocalContextServiceAwareTrait; use StructureServiceAwareTrait; use FonctionReferentielServiceAwareTrait; use EntityManagerAwareTrait; /** * @var Structure[] Loading
module/Application/src/Form/TypeIntervention/TypeInterventionStructureSaisieForm.php +2 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Application\Form\TypeIntervention; use Application\Entity\Db\Traits\TypeInterventionStructureAwareTrait; use Application\Form\AbstractForm; use Application\Service\Traits\TypeInterventionServiceAwareTrait; use Application\Service\Traits\TypeInterventionStructureServiceAwareTrait; Loading @@ -19,7 +20,7 @@ use UnicaenApp\Util; */ class TypeInterventionStructureSaisieForm extends AbstractForm { use \Application\Entity\Db\Traits\TypeInterventionStructureAwareTrait; use TypeInterventionStructureAwareTrait; use StructureServiceAwareTrait; use ContextServiceAwareTrait; use AnneeServiceAwareTrait; Loading