diff --git a/src/Blast/Component/UIBuilder/Builder/AbstractBuilder.php b/src/Blast/Component/UIBuilder/Builder/AbstractBuilder.php new file mode 100644 index 00000000..6e54fe56 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/AbstractBuilder.php @@ -0,0 +1,120 @@ +parent = $parent; + $this->abstractFactory = $abstractFactory; + $this->name = $name; + } + + public function getOptions() + { + return $this->options; + } + + /** + * @return AbstractFactoryInterface + */ + public function getAbstractFactory() + { + return $this->abstractFactory; + } + + /** + * @return BuilderInterface + */ + public function getParent() + { + return $this->parent; + } + + /** + * @return ModelInterface + */ + public function getParentModel() + { + return $this->getParent()->getModel(); + } + + protected function findChildModelByName(string $name) + { + return $this->getModel()->findChildByName($name); + } + + /** + * @return UiModelInterface + */ + public function getModel(): UiModelInterface + { + if (null === $this->model) { + $this->model = $this->build(); + } + + return $this->model; + } + + public function setModel(UiModelInterface $model) + { + $this->model = $model; + } + + protected function addInParentModel() + { + $this->getParentModel()->addChild($this->getModel()); + } + + /** + * @return BuilderInterface + */ + public function end() + { + if (null !== $this->parent) { + $this->addInParentModel(); + + return $this->getParent(); + } else { + return $this; + } + } + + abstract protected function build(); +} diff --git a/src/Blast/Component/UIBuilder/Builder/BaseBuilder.php b/src/Blast/Component/UIBuilder/Builder/BaseBuilder.php new file mode 100644 index 00000000..9ec74efe --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/BaseBuilder.php @@ -0,0 +1,55 @@ +options['css.classes'] = $classes; + + return $this; + } + + public function containerCss(string $classes) + { + $this->options['container_css.classes'] = $classes; + + return $this; + } + + public function template(string $template) + { + $this->options['template'] = $template; + + return $this; + } + + public function useBuilder(self $builder) + { + $this->model = $builder->getModel(); + $this->options = $builder->getOptions(); + $this->model->setName($this->name); + + return $this; + } + + public function override(string $childName) + { + $childModel = $this->getModel()->findChildByName($childName, true); + if (null === $childModel) { + throw new \InvalidArgumentException('child named "' . $childName . '" does not exist'); + } + $builderClass = BuilderClassMap::getBuilderClassFromModel($childModel); + + return (new BuilderOverride($this, $builderClass, $childModel))->getBuilder(); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/BuilderClassMap.php b/src/Blast/Component/UIBuilder/Builder/BuilderClassMap.php new file mode 100644 index 00000000..81112ec3 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/BuilderClassMap.php @@ -0,0 +1,24 @@ +getShortName(); + $builderClass = __NAMESPACE__ . '\\' . $modelClass . 'Builder'; + + return $builderClass; + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/BuilderInterface.php b/src/Blast/Component/UIBuilder/Builder/BuilderInterface.php new file mode 100644 index 00000000..d9a381f3 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/BuilderInterface.php @@ -0,0 +1,20 @@ +builder = new $builderClass(null, $rootBuilder->getAbstractFactory(), $model->getName()); + $this->builder->setModel($model); + $this->model = $model; + } + + public function getName(): string + { + return $this->model->getName(); + } + + public function getBuilder(): BuilderInterface + { + return $this->builder; + } + + public function getModel(): UiModelInterface + { + return $this; + } + + public function addChild($child) + { + $this->model->mergeWith($child); + } + + public function end() + { + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/CollectionAwareTrait.php b/src/Blast/Component/UIBuilder/Builder/CollectionAwareTrait.php new file mode 100644 index 00000000..0c99c0a1 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/CollectionAwareTrait.php @@ -0,0 +1,19 @@ +getAbstractFactory(), $name); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/CollectionBuilder.php b/src/Blast/Component/UIBuilder/Builder/CollectionBuilder.php new file mode 100644 index 00000000..a9c7861a --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/CollectionBuilder.php @@ -0,0 +1,35 @@ +options['type'] = $type; + + return $this; + } + + public function valueAccessor($valueAccessor) + { + $this->options['valueAccessor'] = $valueAccessor; + + return $this; + } + + public function build() + { + return $this->getAbstractFactory()->createCollection($this->name, $this->options); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/FieldAwareTrait.php b/src/Blast/Component/UIBuilder/Builder/FieldAwareTrait.php new file mode 100644 index 00000000..d852d16f --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/FieldAwareTrait.php @@ -0,0 +1,24 @@ +getAbstractFactory(), $name); + } + + public function inputField($name) + { + return new InputFieldBuilder($this, $this->getAbstractFactory(), $name); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/FieldBuilder.php b/src/Blast/Component/UIBuilder/Builder/FieldBuilder.php new file mode 100644 index 00000000..f4fc28bc --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/FieldBuilder.php @@ -0,0 +1,54 @@ +options['label'] = $label; + + return $this; + } + + public function labelIcon(string $icon) + { + $this->options['labelIcon'] = $icon; + + return $this; + } + + public function type($type) + { + $this->options['type'] = $type; + + return $this; + } + + public function valueAccessor($valueAccessor) + { + $this->options['valueAccessor'] = $valueAccessor; + + return $this; + } + + public function valueTemplate($valueTemplate) + { + $this->options['valueTemplate'] = $valueTemplate; + + return $this; + } + + protected function build() + { + return $this->getAbstractFactory()->createField($this->name, $this->options); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/FieldGroupAwareTrait.php b/src/Blast/Component/UIBuilder/Builder/FieldGroupAwareTrait.php new file mode 100644 index 00000000..5db97225 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/FieldGroupAwareTrait.php @@ -0,0 +1,19 @@ +getAbstractFactory(), $name); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/FieldGroupBuilder.php b/src/Blast/Component/UIBuilder/Builder/FieldGroupBuilder.php new file mode 100644 index 00000000..e226dcac --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/FieldGroupBuilder.php @@ -0,0 +1,22 @@ +getAbstractFactory()->createFieldGroup($this->name, $this->options); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/FormAwareTrait.php b/src/Blast/Component/UIBuilder/Builder/FormAwareTrait.php new file mode 100644 index 00000000..d2f3bbcc --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/FormAwareTrait.php @@ -0,0 +1,19 @@ +getAbstractFactory(), $name); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/FormBuilder.php b/src/Blast/Component/UIBuilder/Builder/FormBuilder.php new file mode 100644 index 00000000..383157d4 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/FormBuilder.php @@ -0,0 +1,24 @@ +getAbstractFactory()->createForm($this->name, $this->options); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/GroupAwareTrait.php b/src/Blast/Component/UIBuilder/Builder/GroupAwareTrait.php new file mode 100644 index 00000000..382140cc --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/GroupAwareTrait.php @@ -0,0 +1,19 @@ +getAbstractFactory(), $name); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/GroupBuilder.php b/src/Blast/Component/UIBuilder/Builder/GroupBuilder.php new file mode 100644 index 00000000..7349bdb5 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/GroupBuilder.php @@ -0,0 +1,32 @@ +options['label'] = $label; + + return $this; + } + + public function build() + { + return $this->getAbstractFactory()->createGroup($this->name, $this->options); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/InputFieldBuilder.php b/src/Blast/Component/UIBuilder/Builder/InputFieldBuilder.php new file mode 100644 index 00000000..4cc45b93 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/InputFieldBuilder.php @@ -0,0 +1,33 @@ +options['required'] = $bool; + + return $this; + } + + public function placeholder($placeholder) + { + $this->options['placeholder'] = $placeholder; + + return $this; + } + + protected function build() + { + return $this->getAbstractFactory()->createInputField($this->name, $this->options); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/TabBuilder.php b/src/Blast/Component/UIBuilder/Builder/TabBuilder.php new file mode 100644 index 00000000..b9db8dbb --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/TabBuilder.php @@ -0,0 +1,44 @@ +options['label'] = $label; + + return $this; + } + + public function contentCss(string $classes) + { + $this->options['contentCss.classes'] = $classes; + + return $this; + } + + protected function build() + { + return $this->getAbstractFactory()->createTab($this->name, $this->options); + } + + protected function addInParentModel() + { + $this->getParentModel()->addTab($this->getModel()); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/TabContainerAwareTrait.php b/src/Blast/Component/UIBuilder/Builder/TabContainerAwareTrait.php new file mode 100644 index 00000000..a5367eb9 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/TabContainerAwareTrait.php @@ -0,0 +1,19 @@ +getAbstractFactory(), $name); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/TabContainerBuilder.php b/src/Blast/Component/UIBuilder/Builder/TabContainerBuilder.php new file mode 100644 index 00000000..800dffb5 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/TabContainerBuilder.php @@ -0,0 +1,36 @@ +getAbstractFactory(), $name); + } + + protected function build() + { + return $this->getAbstractFactory()->createTabContainer($this->name, $this->options); + } + + public function end() + { + $this->getParentModel()->addChild($this->getModel()); + + return parent::end(); + } +} diff --git a/src/Blast/Component/UIBuilder/Builder/UIBuilder.php b/src/Blast/Component/UIBuilder/Builder/UIBuilder.php new file mode 100644 index 00000000..a509c22b --- /dev/null +++ b/src/Blast/Component/UIBuilder/Builder/UIBuilder.php @@ -0,0 +1,31 @@ +getAbstractFactory()->createView($this->name, $this->options); + } +} diff --git a/src/Blast/Component/UIBuilder/Factory/AbstractFactoryInterface.php b/src/Blast/Component/UIBuilder/Factory/AbstractFactoryInterface.php new file mode 100644 index 00000000..b6a9843d --- /dev/null +++ b/src/Blast/Component/UIBuilder/Factory/AbstractFactoryInterface.php @@ -0,0 +1,16 @@ +valueAccessor; + } + + public function setValueAccessor(string $valueAccessor) + { + $this->valueAccessor = $valueAccessor; + } + + public function valueFrom($data) + { + if (null === $this->valueAccessor) { + return $data; + } + + return PropertyAccess::createPropertyAccessor()->getValue($data, $this->valueAccessor); + } + + public function addChild(UiModelInterface $child) + { + parent::addChild(new CollectionItem($child)); + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderCollection($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/CollectionItem.php b/src/Blast/Component/UIBuilder/Model/CollectionItem.php new file mode 100644 index 00000000..b5350152 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/CollectionItem.php @@ -0,0 +1,37 @@ +field = $field; + parent::__construct($field->getName() . '.item', []); + } + + public function getField() + { + return $this->field; + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderCollectionItem($this, $data); + } + + public function findChildByName(string $name, bool $deep = false): ?UiModelInterface + { + return ($this->field->getName() == $name) ? $this->field : null; + } +} diff --git a/src/Blast/Component/UIBuilder/Model/CssConfig.php b/src/Blast/Component/UIBuilder/Model/CssConfig.php new file mode 100644 index 00000000..c92ffd1d --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/CssConfig.php @@ -0,0 +1,32 @@ +id; + } + + public function getClasses() + { + return $this->classes; + } + + public function setClasses($classes) + { + $this->classes = $classes; + } +} diff --git a/src/Blast/Component/UIBuilder/Model/Field.php b/src/Blast/Component/UIBuilder/Model/Field.php new file mode 100644 index 00000000..c1148257 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/Field.php @@ -0,0 +1,93 @@ +value = new FieldValue(); + parent::__construct($name, $options); + } + + public function getLabel() + { + return $this->label; + } + + public function setLabel($label) + { + $this->label = $label; + } + + public function getLabelIcon() + { + return $this->labelIcon; + } + + public function setLabelIcon($labelIcon) + { + $this->labelIcon = $labelIcon; + } + + public function getType() + { + return $this->value->getType(); + } + + public function setType($type) + { + $this->value->setType($type); + } + + public function getValue() + { + return $this->value; + } + + public function setValue(FieldValue $value) + { + $this->value = $value; + } + + public function getValueAccessor() + { + return $this->value->getDataAccessor(); + } + + public function setValueAccessor(string $valueAccessor) + { + $this->value->setDataAccessor($valueAccessor); + } + + public function getValueTemplate() + { + return $this->value->getValueTemplate(); + } + + public function setValueTemplate(string $valueTemplate) + { + $this->value->setValueTemplate($valueTemplate); + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderField($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/FieldGroup.php b/src/Blast/Component/UIBuilder/Model/FieldGroup.php new file mode 100644 index 00000000..fbf6c948 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/FieldGroup.php @@ -0,0 +1,24 @@ +renderFieldGroup($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/FieldGroupItem.php b/src/Blast/Component/UIBuilder/Model/FieldGroupItem.php new file mode 100644 index 00000000..9de6834a --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/FieldGroupItem.php @@ -0,0 +1,37 @@ +field = $field; + parent::__construct($field->getName() . '.item', []); + } + + public function getField() + { + return $this->field; + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderFieldGroupItem($this, $data); + } + + public function findChildByName(string $name, bool $deep = false): ?UiModelInterface + { + return ($this->field->getName() == $name) ? $this->field : null; + } +} diff --git a/src/Blast/Component/UIBuilder/Model/FieldValue.php b/src/Blast/Component/UIBuilder/Model/FieldValue.php new file mode 100644 index 00000000..5cc42c10 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/FieldValue.php @@ -0,0 +1,80 @@ +getType(); + } + + public function getTemplate(): ?string + { + return $this->template; + } + + public function setTemplate(string $template) + { + $this->template = $template; + } + + public function getType() + { + return $this->type; + } + + public function setType($type) + { + $this->type = $type; + } + + public function getDataAccessor() + { + return $this->dataAccessor; + } + + public function setDataAccessor(string $dataAccessor) + { + $this->dataAccessor = $dataAccessor; + } + + public function getValueTemplate() + { + return $this->valueTemplate; + } + + public function setValueTemplate(string $valueTemplate) + { + $this->valueTemplate = $valueTemplate; + } + + public function valueFrom($data) + { + if (null === $this->dataAccessor) { + return $data; + } + + return PropertyAccess::createPropertyAccessor()->getValue($data, $this->dataAccessor); + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderFieldValue($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/Form.php b/src/Blast/Component/UIBuilder/Model/Form.php new file mode 100644 index 00000000..24b7a13b --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/Form.php @@ -0,0 +1,19 @@ +renderForm($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/Group.php b/src/Blast/Component/UIBuilder/Model/Group.php new file mode 100644 index 00000000..37077979 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/Group.php @@ -0,0 +1,31 @@ +label; + } + + public function setLabel(string $label) + { + $this->label = $label; + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderGroup($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/InputField.php b/src/Blast/Component/UIBuilder/Model/InputField.php new file mode 100644 index 00000000..88324d49 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/InputField.php @@ -0,0 +1,38 @@ +rows; + } + + public function getFormView($formFactory, $data) + { + $builder = $formFactory->createNamedBuilder($this->getName(), $this->getType(), $this->getValue()->valueFrom($data)); + + return $builder->getForm()->createView(); + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderInputField($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/Tab.php b/src/Blast/Component/UIBuilder/Model/Tab.php new file mode 100644 index 00000000..32bec38d --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/Tab.php @@ -0,0 +1,66 @@ +contentCss = new CssConfig(); + parent::__construct($name, $options); + } + + public function getLabel() + { + return $this->label; + } + + public function setLabel(string $label) + { + $this->label = $label; + } + + public function getIcon() + { + return $this->icon; + } + + public function getContentCss() + { + return $this->contentCss; + } + + public function getDescription() + { + return 'drgr drg drg drg drg drgdrgdr gdr gdrgdrg drg drg drg'; //$this->description; + } + + public function getOrder() + { + return $this->order; + } + + public function setOrder(int $order) + { + $this->order = $order; + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderTab($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/TabContainer.php b/src/Blast/Component/UIBuilder/Model/TabContainer.php new file mode 100644 index 00000000..6d417bcf --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/TabContainer.php @@ -0,0 +1,34 @@ +children; + } + + public function addTab(Tab $tab) + { + $this->children[$tab->getName()] = $tab; + } + + public function addChild(UiModelInterface $child) + { + throw new \LogicException(__METHOD__ . ' is not allowed, use addTab() instead.'); + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderTabContainer($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Model/UiContainer.php b/src/Blast/Component/UIBuilder/Model/UiContainer.php new file mode 100644 index 00000000..cf43b5e5 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/UiContainer.php @@ -0,0 +1,45 @@ +children; + } + + public function addChild(UiModelInterface $child) + { + $this->children[$child->getName()] = $child; + } + + public function findChildByName(string $name, bool $deep = false): ?UiModelInterface + { + if (array_key_exists($name, $this->children)) { + return $this->children[$name]; + } + if (!$deep) { + return null; + } + foreach ($this->children as $child) { + print_r("\n" . $child->getName()); + $result = $child->findChildByName($name, $deep); + if (null !== $result) { + return $result; + } + } + + return null; + } +} diff --git a/src/Blast/Component/UIBuilder/Model/UiModel.php b/src/Blast/Component/UIBuilder/Model/UiModel.php new file mode 100644 index 00000000..17990919 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/UiModel.php @@ -0,0 +1,87 @@ +name = $name; + $this->css = new CssConfig(); + $this->containerCss = new CssConfig(); + $this->configure($options); + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name) + { + $this->name = $name; + } + + public function getCss() + { + return $this->css; + } + + public function getContainerCss() + { + return $this->containerCss; + } + + public function getTemplate(): ?string + { + return $this->template; + } + + public function setTemplate(string $template) + { + $this->template = $template; + } + + public function mergeWith(self $model) + { + $properties = get_object_vars($this); + foreach ($properties as $prop => $value) { + if (is_array($this->$prop)) { + $this->$prop = array_merge($this->$prop, $model->$prop); + } else { + $this->$prop = $model->$prop; + } + } + } + + protected function configure(array $options = []) + { + $accessor = PropertyAccess::createPropertyAccessor(); + foreach ($options as $prop =>$value) { + if ($accessor->isWritable($this, $prop)) { + $accessor->setValue($this, $prop, $value); + } + } + } + + public function findChildByName(string $name, bool $deep = false): ?UiModelInterface + { + return null; + } +} diff --git a/src/Blast/Component/UIBuilder/Model/UiModelInterface.php b/src/Blast/Component/UIBuilder/Model/UiModelInterface.php new file mode 100644 index 00000000..a0878098 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Model/UiModelInterface.php @@ -0,0 +1,18 @@ +title; + } + + public function setTitle(string $title) + { + return $this->title; + } + + public function renderUsing($renderer, $data) + { + return $renderer->renderView($this, $data); + } +} diff --git a/src/Blast/Component/UIBuilder/Tests/Resources/Examples/example1.yml b/src/Blast/Component/UIBuilder/Tests/Resources/Examples/example1.yml new file mode 100644 index 00000000..466ad0e1 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Tests/Resources/Examples/example1.yml @@ -0,0 +1,36 @@ +blast_view_builder: + + view.contact: + class: My\Contact + tabs: + tab.info: + import: view.contact.info + + tab.organizations: + template: "@MyBundle:Contact/Organizations.html.twig" + data: + path: .organizations + + tab.emails: + label: "Emails" + + groups: + group.emails: + type: grid + + data: + class: My\Email + repository: + method: findEmailsByContact + arguments: + - & #parent reference (the contact object) + + fields: + exp: + type: string + dests: + type: simple_list + object: + type: string + sent: + type: boolean diff --git a/src/Blast/Component/UIBuilder/Tests/Resources/autoload.php.dist b/src/Blast/Component/UIBuilder/Tests/Resources/autoload.php.dist new file mode 100644 index 00000000..09db48d4 --- /dev/null +++ b/src/Blast/Component/UIBuilder/Tests/Resources/autoload.php.dist @@ -0,0 +1,27 @@ +markTestSkipped('disabled'); + } + + public function notestBuilder() + { + $view = new UIBuilder(new BaseAbstractFactory()); + $view + ->form('category') + ->tabContainer() + ->tab('general') + ->group('') + + ->field('name') + ->required() + ->endField() + + ->field('treeParent') + ->type(NestedTreeableType::class) + ->model(Category::class) + ->required(false) + ->placeholder('') + ->endField() + + ->endGroup() + ->endTab() + ->endTabContainer() + ->endForm(); + } + + public function notestBuilder2() + { + $view = new UIBuilder(new BaseAbstractFactory()); + $view + + ->tab('general') + ->template('@MyBundle:Contact/Info.html.twig') + ->end() + + ->tab('organizations') + ->import('view.organizations') + ->end() + + ->tab('coordonnées') + + ->group('adresses') + ->css(['col-md-6']) + ->template('@MyBundle:Address/CardView.html.twig') + ->data() + ->type('collection') + ->model('My\Address') + ->path('addresses') + ->end() + ->end() + + ->group('téléphones') + ->css(['col-md-6']) + ->template('@MyBundle:Phone/CardView.html.twig') + ->data() + ->type('collection') + ->model('My\Phone') + ->repository() + ->method('findPhonesByContact') + ->arguments(['&']) + ->end() + ->end() + ->end() + + ->end() + + ->end(); + } + + public function testBuilder() + { + $view = new UIBuilder(new BaseAbstractFactory(), 'my.view'); + $view->tabContainer('my.tab_container') + ->tab('my.tab') + ->group('my.group.1') + ->form('my.form') + ->inputField('my.field') + ->label('my.field.label') + ->type('integer') + ->required() + ->end() + ->end() + ->end() + ->group('my.group.2') + ->useBuilder($this->createGroupBuilder()) + ->end() + ->end() + ->end(); + + $view + ->override('my.form') + ->override('my.field') + ->label('my.field2.label') + ->type('string') + ->end() + ->end(); + + print_r($view->getModel()); + } + + public function createGroupBuilder() + { + $group = new GroupBuilder(null, new BaseAbstractFactory(), 'dummy.group'); + $group + ->field('my.other.field') + ->end(); + + return $group; + } +} diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/after_success_test.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/after_success_test.sh new file mode 100755 index 00000000..87158518 --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/after_success_test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +set -ev + +coveralls -v diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/before_install_test.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/before_install_test.sh new file mode 100755 index 00000000..ab3303f9 --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/before_install_test.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +set -ev + +# check syntax +find . -name '*.php' -exec php -l {} \; + +# Ugly hack +echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + +composer self-update --stable + +composer global require --no-interaction cedx/coveralls +composer global require --no-interaction phpunit/phpunit + + diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_docs.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_docs.sh new file mode 100755 index 00000000..9e618c4e --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_docs.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -ev + +RELEVANT_FILES=$(git diff --name-only HEAD upstream/${TRAVIS_BRANCH} -- '*.rst') + +if [[ -z ${RELEVANT_FILES} ]]; then echo -n 'KO'; exit 0; fi; diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_lint.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_lint.sh new file mode 100755 index 00000000..ab9ad2cb --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_lint.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -ev + +RELEVANT_FILES=$(git diff --name-only HEAD upstream/${TRAVIS_BRANCH} -- '*.json' '*.yml' '*.xml' '*.xliff') + +if [[ -z ${RELEVANT_FILES} ]]; then echo -n 'KO'; exit 0; fi; \ No newline at end of file diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_test.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_test.sh new file mode 100755 index 00000000..bf4fe2a9 --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/check_relevant_test.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -ev + +RELEVANT_FILES=$(git diff --name-only HEAD upstream/${TRAVIS_BRANCH} -- '*.php' '*.yml' '*.xml' '*.twig' '*.js' '*.css' '*.json') + +if [[ -z ${RELEVANT_FILES} ]]; then echo -n 'KO'; exit 0; fi; \ No newline at end of file diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/create_travis_database_test.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/create_travis_database_test.sh new file mode 100755 index 00000000..6416e256 --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/create_travis_database_test.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env sh +set -ev + +# Database creation + +### +### mysql +### + +# (mysql service is started by default by travis for each build instance +# (mysql travis user is created by travis for each build instance +# mysql -u travis -e 'CREATE DATABASE travis;' -v + +### +### postgresql +### + +# needed in .travis.yml +#services: +# - postgresql +# or here : sudo /etc/init.d/postgresql start + +# (we try to create a travis user) +# psql -c 'CREATE USER travis;' -U postgres +# psql -c 'ALTER ROLE travis WITH CREATEDB;' -U postgres + +psql -c 'CREATE DATABASE travis;' -U postgres +psql -c 'ALTER DATABASE travis OWNER TO travis' -U postgres + + +#psql -U postgres -c "CREATE EXTENSION 'uuid-ossp';" + +### +### +### diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/install_docs.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/install_docs.sh new file mode 100755 index 00000000..362f6449 --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/install_docs.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +set -ev + +pip install -r Resources/doc/requirements.txt --user diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/install_lint.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/install_lint.sh new file mode 100755 index 00000000..0580be4e --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/install_lint.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh +set -ev + +composer global require sllh/composer-lint:@stable --prefer-dist --no-interaction + +#gem install yaml-lint \ No newline at end of file diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/install_test.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/install_test.sh new file mode 100755 index 00000000..901c0f9a --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/install_test.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env sh +set -ev + +mkdir --parents "${HOME}/bin" + +composer install --no-interaction --prefer-dist + +# composer update --prefer-dist --no-interaction --prefer-stable + + + diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/run_docs.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/run_docs.sh new file mode 100755 index 00000000..31fae91f --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/run_docs.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +cd Resources/doc +sphinx-build -b html -d _build/doctrees . _build/html diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/run_lint.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/run_lint.sh new file mode 100755 index 00000000..732ea402 --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/run_lint.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +composer validate diff --git a/src/Blast/Component/UIBuilder/bin/ci-scripts/run_test.sh b/src/Blast/Component/UIBuilder/bin/ci-scripts/run_test.sh new file mode 100755 index 00000000..4ff9fe5b --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/ci-scripts/run_test.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +phpunit -v -c phpunit.xml.dist --coverage-clover build/logs/clover.xml diff --git a/src/Blast/Component/UIBuilder/bin/git-script/pre-commit.sh b/src/Blast/Component/UIBuilder/bin/git-script/pre-commit.sh new file mode 100755 index 00000000..bd7dd2b0 --- /dev/null +++ b/src/Blast/Component/UIBuilder/bin/git-script/pre-commit.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# install ln -s ../../bin/git-script/pre-commit.sh .git/hooks/pre-commit + +echo "php-cs-fixer pre commit hook start" + +PHP_CS_FIXER=$(which php-cs-fixer) +HAS_PHP_CS_FIXER=false + +if [ -x "$PHP_CS_FIXER" ]; then + HAS_PHP_CS_FIXER=true +fi + +if $HAS_PHP_CS_FIXER; then + git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | while read line; do + $PHP_CS_FIXER fix "$line"; + git add "$line"; + done +else + echo "" + echo "Please install php-cs-fixer" + echo "" +fi + +echo "php-cs-fixer pre commit hook finish" diff --git a/src/Blast/Component/UIBuilder/doc/specs.rst b/src/Blast/Component/UIBuilder/doc/specs.rst new file mode 100644 index 00000000..1c8ce744 --- /dev/null +++ b/src/Blast/Component/UIBuilder/doc/specs.rst @@ -0,0 +1,32 @@ +Type Of Fields +============== + +Form +---- + +SELECT box with add button + +input text + +input text with autocomplete + +input text with action button (e.g generate, verify, ...) [label|icon|help] + +dialog form + +list inline form with add button + +View +---- + +card + +Features +======== + +- gestion des droits d'affichage +- gestion de class css custom +- gestion des type de field (lecture / écriture) +- gestion de template custom +- gestion des templates utilisés pour le rendu des Ui (theme ?) +-> builder overriding diff --git a/src/Blast/Component/UIBuilder/phpunit.xml.dist b/src/Blast/Component/UIBuilder/phpunit.xml.dist new file mode 100644 index 00000000..48a4ff20 --- /dev/null +++ b/src/Blast/Component/UIBuilder/phpunit.xml.dist @@ -0,0 +1,51 @@ + + + + + + + + ./Tests/Unit + ./src/*/Component/*/Tests/Unit + + + ./tests/Functional + + + + + + + ./src/ + + ./Tests/ + ./DataFixtures/ + ./Resources/ + ./vendor/ + ./coverage/ + ./src/*/Component/*/bin/ + ./src/*/Component/*/etc/ + ./src/*/Component/*/Tests/ + ./src/*/Component/*/DataFixtures/ + ./src/*/Component/*/vendor/ + ./src/*/Component/*/coverage/ + + + + + + + + + +