-{%- for choice in choices -%}
- {% if choice['slug'] in selected %}{%- set is_selected = true -%}{%- else -%}{%- set is_selected = false -%}{%- endif -%}
- {%- if is_selected -%}
-
- {%- if is_selected -%}
-
- {%- else -%}
-
- {%- endif -%}
- {%- if choice['slug'] is not same as('_other') -%}
- {{ choice['name']|localize_translatable_string }}
- {%- else -%}
- {{ choice['name'] }}
- {%- endif -%}
-
- {%- endif -%}
-{%- endfor -%}
-
+
+ {%- for choice in choices -%}
+ {% if choice['slug'] in selected %}
+ {%- set is_selected = true -%}
+ {%- else -%}
+ {%- set is_selected = false -%}
+ {%- endif -%}
+
+ {%- if is_selected -%}
+
+ {%- if is_selected -%}
+
+ {%- else -%}
+
+ {%- endif -%}
+
+ {%- if choice['slug'] is not same as('_other') -%}
+ {{ choice['name']|localize_translatable_string }}
+ {%- else -%}
+ {{ choice['name'] }}
+ {%- endif -%}
+
+ {%- endif -%}
+ {%- endfor -%}
+
{% else %}
{{ 'None'|trans }}
{% endif %}
\ No newline at end of file
From f068ac288fe2307b004060637f3a0d231dab334f Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Thu, 22 Oct 2015 15:09:43 +0200
Subject: [PATCH 06/54] Debug JS - close refs #626
---
Resources/views/Form/fields.html.twig | 78 ++++++++++-----------------
1 file changed, 27 insertions(+), 51 deletions(-)
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig
index a097bc78f..76ec0cb5c 100644
--- a/Resources/views/Form/fields.html.twig
+++ b/Resources/views/Form/fields.html.twig
@@ -35,61 +35,37 @@
{# render the possibility to add different elements in a choice list #}
{% block cf_choices_widget %}
-{{ form(form) }}
+ {{ form(form) }}
+
+ {# we use javascrit to add an additional element. All functions are personnalized with the id ( = form.vars.id) #}
+
+ jQuery(document).ready(initializeCFChoiceOptionsChoices('{{ form.vars.id }}'));
+
{% endblock cf_choices_widget %}
From d21595d306901a7f1f06f4206816c8bb9455615b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 26 Oct 2015 22:01:23 +0100
Subject: [PATCH 07/54] add gitlab-ci to project
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Squashed commit of the following:
commit 7baa7bddc3a1613816c691e454841baa885a5095
Author: Julien Fastré
Date: Mon Oct 26 21:13:47 2015 +0100
fix auth and database url
commit c47ad68586749e19fce125da9820d0fd0b2bf575
Author: Julien Fastré
Date: Mon Oct 26 20:59:33 2015 +0100
add gitlab-ci
---
.gitignore | 2 ++
.gitlab-ci.yml | 17 +++++++++++++++++
.../App/app/config/parameters.gitlab-ci.yml | 7 +++++++
3 files changed, 26 insertions(+)
create mode 100644 .gitlab-ci.yml
create mode 100644 Tests/Fixtures/App/app/config/parameters.gitlab-ci.yml
diff --git a/.gitignore b/.gitignore
index 90d5ec78f..08abe3eac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,5 @@ bin/*
/tmp/*
src/Chill/CustomFieldsBundle/vendor/*
bootstrap.php.cache
+#the file created by composer to store creds
+auth.json
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000..9f2233cb5
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,17 @@
+services:
+ - chill/database:latest
+
+before_script:
+ - composer config github-oauth.github.com $GITHUB_TOKEN
+ - composer install --no-interaction
+ - cp Tests/Fixtures/App/app/config/parameters.gitlab-ci.yml Tests/Fixtures/App/app/config/parameters.yml
+ - ./console.sh --env=test cache:warmup
+ - ./console.sh doctrine:migrations:migrate --env=test --no-interaction
+ - ./console.sh doctrine:fixtures:load --env=test --no-interaction
+
+test:php-5.6:
+ stage: test
+ script: phpunit --testdox
+test:php-7:
+ stage: test
+ script: phpunit --testdox
diff --git a/Tests/Fixtures/App/app/config/parameters.gitlab-ci.yml b/Tests/Fixtures/App/app/config/parameters.gitlab-ci.yml
new file mode 100644
index 000000000..9e3b75daf
--- /dev/null
+++ b/Tests/Fixtures/App/app/config/parameters.gitlab-ci.yml
@@ -0,0 +1,7 @@
+parameters:
+ database_host: chill__database
+ database_port: 5432
+ database_name: postgres
+ database_user: postgres
+ database_password: postgres
+ locale: fr
From e2c1a9bb9f51a39ad037819b2f4c88e54780a1ab Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Fri, 30 Oct 2015 10:36:27 +0100
Subject: [PATCH 08/54] Adding customfileds config in the Admin section menu
---
Controller/AdminController.php | 37 +++++++++++++++++++
Resources/config/routing/customfield.yml | 16 ++++++--
.../routing/customfieldsdefaultgroup.yml | 2 +-
.../config/routing/customfieldsgroup.yml | 2 +-
Resources/views/Admin/layout.html.twig | 31 ++++++++++++++++
Resources/views/Admin/menu.html.twig | 20 ++++++++++
Resources/views/CustomField/edit.html.twig | 2 +-
Resources/views/CustomField/index.html.twig | 2 +-
Resources/views/CustomField/new.html.twig | 2 +-
Resources/views/CustomField/show.html.twig | 2 +-
.../CustomFieldsDefaultGroup/list.html.twig | 2 +-
.../views/CustomFieldsGroup/edit.html.twig | 2 +-
.../views/CustomFieldsGroup/index.html.twig | 2 +-
.../views/CustomFieldsGroup/new.html.twig | 2 +-
.../views/CustomFieldsGroup/show.html.twig | 2 +-
15 files changed, 112 insertions(+), 14 deletions(-)
create mode 100644 Controller/AdminController.php
create mode 100644 Resources/views/Admin/layout.html.twig
create mode 100644 Resources/views/Admin/menu.html.twig
diff --git a/Controller/AdminController.php b/Controller/AdminController.php
new file mode 100644
index 000000000..b538d9092
--- /dev/null
+++ b/Controller/AdminController.php
@@ -0,0 +1,37 @@
+
+ *
+ * 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\CustomFieldsBundle\Controller;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+
+/**
+ * Controller for the custom fields configuration section (in
+ * the admin)
+ *
+ */
+class AdminController extends Controller
+{
+ public function indexAction()
+ {
+ return $this->render('ChillCustomFieldsBundle:Admin:layout.html.twig');
+ }
+}
\ No newline at end of file
diff --git a/Resources/config/routing/customfield.yml b/Resources/config/routing/customfield.yml
index eb92fdc96..0f8e7b8d3 100644
--- a/Resources/config/routing/customfield.yml
+++ b/Resources/config/routing/customfield.yml
@@ -1,11 +1,21 @@
-customfield:
+customfield_section:
path: /{_locale}/admin/customfield/
+ defaults: { _controller: "ChillCustomFieldsBundle:Admin:index" }
+ options:
+ menus:
+ admin_section:
+ order: 1000
+ label: "Custom fields configuration"
+ icons: ['asterisk']
+
+customfield:
+ path: /{_locale}/admin/customfield/list
defaults: { _controller: "ChillCustomFieldsBundle:CustomField:index" }
options:
menus:
- admin:
+ admin_custom_fields:
order: 1000
- label: "CustomFields"
+ label: "CustomFields List"
customfield_show:
path: /{_locale}/admin/customfield/{id}/show
diff --git a/Resources/config/routing/customfieldsdefaultgroup.yml b/Resources/config/routing/customfieldsdefaultgroup.yml
index d16434e8d..9919337af 100644
--- a/Resources/config/routing/customfieldsdefaultgroup.yml
+++ b/Resources/config/routing/customfieldsdefaultgroup.yml
@@ -3,7 +3,7 @@ customfieldsdefaultgroup:
defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsDefaultGroup:list" }
options:
menus:
- admin:
+ admin_custom_fields:
order: 1000
label: "CustomFields Default Groups : List"
diff --git a/Resources/config/routing/customfieldsgroup.yml b/Resources/config/routing/customfieldsgroup.yml
index c8a992856..f34e0169b 100644
--- a/Resources/config/routing/customfieldsgroup.yml
+++ b/Resources/config/routing/customfieldsgroup.yml
@@ -3,7 +3,7 @@ customfieldsgroup:
defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsGroup:index" }
options:
menus:
- admin:
+ admin_custom_fields:
order: 1010
label: "CustomFields Groups"
diff --git a/Resources/views/Admin/layout.html.twig b/Resources/views/Admin/layout.html.twig
new file mode 100644
index 000000000..27c0c61ac
--- /dev/null
+++ b/Resources/views/Admin/layout.html.twig
@@ -0,0 +1,31 @@
+{#
+ * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
+ /
+ *
+ * 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 .
+#}
+
+{% extends "ChillMainBundle::Admin/layoutWithVerticalMenu.html.twig" %}
+
+{% block vertical_menu_content %}
+ {{ chill_menu('admin_custom_fields', {
+ 'layout': 'ChillCustomFieldsBundle::Admin/menu.html.twig',
+ }) }}
+{% endblock %}
+
+{% block layout_wvm_content %}
+ {% block admin_content %}
+
{{ 'CustomFields configuration' |trans }}
+ {% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/Resources/views/Admin/menu.html.twig b/Resources/views/Admin/menu.html.twig
new file mode 100644
index 000000000..aeefd1013
--- /dev/null
+++ b/Resources/views/Admin/menu.html.twig
@@ -0,0 +1,20 @@
+{#
+ * Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
+ /
+ *
+ * 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 .
+#}
+
+{% extends "ChillMainBundle::Menu/verticalMenu.html.twig" %}
+{% block v_menu_title %}{{ 'Custom fields configuration menu'|trans }}{% endblock %}
\ No newline at end of file
diff --git a/Resources/views/CustomField/edit.html.twig b/Resources/views/CustomField/edit.html.twig
index 47f98ee92..bcc2e5d88 100644
--- a/Resources/views/CustomField/edit.html.twig
+++ b/Resources/views/CustomField/edit.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomField edit
diff --git a/Resources/views/CustomField/index.html.twig b/Resources/views/CustomField/index.html.twig
index 1802c3a9c..36c5f1243 100644
--- a/Resources/views/CustomField/index.html.twig
+++ b/Resources/views/CustomField/index.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomField list
diff --git a/Resources/views/CustomField/new.html.twig b/Resources/views/CustomField/new.html.twig
index 771abbd10..a94f16b3b 100644
--- a/Resources/views/CustomField/new.html.twig
+++ b/Resources/views/CustomField/new.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomField creation
diff --git a/Resources/views/CustomField/show.html.twig b/Resources/views/CustomField/show.html.twig
index 451a544db..69a4d9e25 100644
--- a/Resources/views/CustomField/show.html.twig
+++ b/Resources/views/CustomField/show.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomField
diff --git a/Resources/views/CustomFieldsDefaultGroup/list.html.twig b/Resources/views/CustomFieldsDefaultGroup/list.html.twig
index 560aedc8d..036bc04d5 100644
--- a/Resources/views/CustomFieldsDefaultGroup/list.html.twig
+++ b/Resources/views/CustomFieldsDefaultGroup/list.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomFieldsDefaultGroup list
diff --git a/Resources/views/CustomFieldsGroup/edit.html.twig b/Resources/views/CustomFieldsGroup/edit.html.twig
index 57f86745e..3197f9d90 100644
--- a/Resources/views/CustomFieldsGroup/edit.html.twig
+++ b/Resources/views/CustomFieldsGroup/edit.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomFieldsGroup edit
diff --git a/Resources/views/CustomFieldsGroup/index.html.twig b/Resources/views/CustomFieldsGroup/index.html.twig
index bea9b6409..4f751490d 100644
--- a/Resources/views/CustomFieldsGroup/index.html.twig
+++ b/Resources/views/CustomFieldsGroup/index.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomFieldsGroup list
diff --git a/Resources/views/CustomFieldsGroup/new.html.twig b/Resources/views/CustomFieldsGroup/new.html.twig
index b83aec347..19ab309f6 100644
--- a/Resources/views/CustomFieldsGroup/new.html.twig
+++ b/Resources/views/CustomFieldsGroup/new.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomFieldsGroup creation
diff --git a/Resources/views/CustomFieldsGroup/show.html.twig b/Resources/views/CustomFieldsGroup/show.html.twig
index 5fd8681bb..84a0141d2 100644
--- a/Resources/views/CustomFieldsGroup/show.html.twig
+++ b/Resources/views/CustomFieldsGroup/show.html.twig
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
#}
-{% extends "ChillMainBundle::Admin/layout.html.twig" %}
+{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
CustomFieldsGroup
From 6ad8d412440dc2d31ad23b2813e3f3a384a2a994 Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Fri, 30 Oct 2015 10:40:26 +0100
Subject: [PATCH 09/54] Adding composer.lock in gitignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index 08abe3eac..52d2b6ff7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
.gitignore~
*~
composer.phar
+composer.lock
/nbproject/private/
parameters.yml
app/config/parameters.yml
From 1ebfe7749b86e2f600366484d94d23709bb3d0df Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Fri, 30 Oct 2015 10:41:32 +0100
Subject: [PATCH 10/54] Removing .travis.yml file
---
.travis.yml | 27 ---------------------------
1 file changed, 27 deletions(-)
delete mode 100644 .travis.yml
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 104cafa19..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-language: php
-php:
-- 5.5
-- 5.6
-- hhvm-nightly
-matrix:
- allow_failures:
- - php: hhvm-nightly
-addons:
- postgresql: '9.3'
-sudo: false
-install:
- - composer config -g github-oauth.github.com $GITHUB_COMPOSER_AUTH
- - composer install --dev
- - cp Tests/Fixtures/App/app/config/parameters.travis.yml Tests/Fixtures/App/app/config/parameters.yml
-before_script:
- - psql -c 'create database test0;' -U postgres
- - "./console.sh --env=test cache:warmup"
- - "./console.sh doctrine:migrations:migrate --no-interaction"
- - "./console.sh doctrine:fixtures:load --no-interaction --env=test"
-script: phpunit --coverage-text
-notifications:
- email:
- - info@champs-libres.coop
-env:
- global:
- secure: MoVsISTKaeamuFNoylDv/nM6NBXBtCoH5tuGwX3RHpRK/zRXh421RgO8z/GTHxGt63r04EfYrsCXXng8fN4ZVA2Bjb9chGAozYZJOSwZ9Vmfjycu3k0v/+hikAj33DT+CEdVk4fggEZh5dcVbaJDRgaUZkwMLUtyCqeiv+J5X68=
From e4aadc891cc53ee9312f3be3ff75cf055fb283d2 Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Fri, 30 Oct 2015 10:42:45 +0100
Subject: [PATCH 11/54] Removing travis build image
---
README.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/README.md b/README.md
index fa6aeb184..cde8c8590 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
CustomFields
============
-[](http://travis-ci.org/#!/Chill-project/CustomFields)
-
Add custom fields to entities
This bundle is part of the Chill project.
From 5e211b3f0688debf203efb2a8e136c7432904af7 Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Fri, 30 Oct 2015 15:56:43 +0100
Subject: [PATCH 12/54] Adding ref to the dov
---
README.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index cde8c8590..08a2f468c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,9 @@
CustomFields
============
-Add custom fields to entities
+The bundle for adding custom fields to Chill. This bundle is part of the Chill project.
-This bundle is part of the Chill project.
+Documentation & installation
+============================
+
+Read documentation here : http://chill.readthedocs.org
From 7cf270cee425392b7e2f9188825ef68fa2b29ca8 Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Fri, 30 Oct 2015 15:57:27 +0100
Subject: [PATCH 13/54] Removing travis config file
---
Tests/Fixtures/App/app/config/parameters.travis.yml | 7 -------
1 file changed, 7 deletions(-)
delete mode 100644 Tests/Fixtures/App/app/config/parameters.travis.yml
diff --git a/Tests/Fixtures/App/app/config/parameters.travis.yml b/Tests/Fixtures/App/app/config/parameters.travis.yml
deleted file mode 100644
index 28d5cd26c..000000000
--- a/Tests/Fixtures/App/app/config/parameters.travis.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-parameters:
- database_host: 127.0.0.1
- database_port: 5432
- database_name: test0
- database_user: postgres
- database_password: postgres
- locale: fr
\ No newline at end of file
From 9d65ca5088404c6cab9f78303e2466cd9b62d33b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Sat, 31 Oct 2015 17:55:10 +0100
Subject: [PATCH 14/54] layout of index page for customfieldsgroup
- add a "default" column (according to chill-project/custom-fields#3 )
- translation
---
Controller/CustomFieldsGroupController.php | 58 ++++++++++++++++++-
.../config/routing/customfieldsgroup.yml | 4 ++
Resources/translations/messages.fr.yml | 11 ++++
.../views/CustomFieldsGroup/index.html.twig | 30 ++++++----
4 files changed, 89 insertions(+), 14 deletions(-)
diff --git a/Controller/CustomFieldsGroupController.php b/Controller/CustomFieldsGroupController.php
index 9897da5f4..0be440be4 100644
--- a/Controller/CustomFieldsGroupController.php
+++ b/Controller/CustomFieldsGroupController.php
@@ -4,7 +4,7 @@ namespace Chill\CustomFieldsBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-
+use Doctrine\ORM\Query;
use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
/**
@@ -22,12 +22,64 @@ class CustomFieldsGroupController extends Controller
{
$em = $this->getDoctrine()->getManager();
- $entities = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->findAll();
+ $cfGroups = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->findAll();
+ $defaultGroups = $this->getDefaultGroupsId();
+
+ $makeDefaultFormViews = array();
+ foreach ($cfGroups as $group) {
+ if (!in_array($group->getId(), $defaultGroups)){
+ $makeDefaultFormViews[$group->getId()] = $this->createMakeDefaultForm($group)->createView();
+ }
+ }
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:index.html.twig', array(
- 'entities' => $entities,
+ 'entities' => $cfGroups,
+ 'default_groups' => $defaultGroups,
+ 'make_default_forms' => $makeDefaultFormViews
));
}
+
+ /**
+ * Get an array of CustomFieldsGroupId which are marked as default
+ * for their entity
+ *
+ * @return int[]
+ */
+ private function getDefaultGroupsId()
+ {
+ $em = $this->getDoctrine()->getManager();
+
+ $customFieldsGroupIds = $em->createQuery('SELECT g.id FROM '
+ . 'ChillCustomFieldsBundle:CustomFieldsDefaultGroup d '
+ . 'JOIN d.customFieldsGroup g')
+ ->getResult(Query::HYDRATE_SCALAR);
+
+ $result = array();
+ foreach ($customFieldsGroupIds as $row) {
+ $result[] = $row['id'];
+ }
+
+ return $result;
+ }
+
+ /**
+ * create a form to make the group default
+ *
+ * @param CustomFieldsGroup $group
+ * @return \Symfony\Component\Form\Form
+ */
+ private function createMakeDefaultForm(CustomFieldsGroup $group)
+ {
+ return $this->createFormBuilder($group, array(
+ 'method' => 'POST',
+ 'action' => $this->generateUrl('customfieldsgroup_makedefault')
+ ))
+ ->add('id', 'hidden')
+ ->add('submit', 'submit', array('label' => 'Make default'))
+ ->getForm();
+ }
+
+
/**
* Creates a new CustomFieldsGroup entity.
*
diff --git a/Resources/config/routing/customfieldsgroup.yml b/Resources/config/routing/customfieldsgroup.yml
index f34e0169b..446a15aa3 100644
--- a/Resources/config/routing/customfieldsgroup.yml
+++ b/Resources/config/routing/customfieldsgroup.yml
@@ -10,6 +10,10 @@ customfieldsgroup:
customfieldsgroup_show:
path: /{_locale}/admin/customfieldsgroup/{id}/show
defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsGroup:show" }
+
+customfieldsgroup_makedefault:
+ path: /{_locale}/admin/customfieldsgroup/make_default
+ defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsGroup:makeDefault" }
customfieldsgroup_new:
path: /{_locale}/admin/customfieldsgroup/new
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 78b57984c..ad8407fbc 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -1,3 +1,14 @@
'Not available in your language': 'Traduction pas disponible dans votre langue'
'Other value': 'Autre valeur'
'None': 'Pas spécifié'
+
+Custom fields configuration: Configuration des champs personnalisés
+CustomFieldsGroup list: Groupes de champs personnalisés
+Entity: Entité
+"Is default ?": "Par défaut ?"
+"Some module select default groups for some usage. Example: the default person group is shown under person page.": "Certains modules sélectionnent en priorité les formulaires par défaut. Exemple: le formulaire par défaut pour une personne est affiché sur la page principale pour la personne"
+Make default: Assigner comme formulaire par défaut
+Create a new group: Créer un nouveau groupe
+
+CustomFields List: Liste des champs personnalisés
+CustomFields Groups: Groupe de champs personnalisés
diff --git a/Resources/views/CustomFieldsGroup/index.html.twig b/Resources/views/CustomFieldsGroup/index.html.twig
index 4f751490d..787c65436 100644
--- a/Resources/views/CustomFieldsGroup/index.html.twig
+++ b/Resources/views/CustomFieldsGroup/index.html.twig
@@ -17,30 +17,38 @@
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
{% block admin_content %}
-
From bb1e690bec518816d35cac9af79e2ca0f285cd56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Thu, 5 Nov 2015 22:41:54 +0100
Subject: [PATCH 15/54] fix "create" page with translation and layout
---
Resources/translations/messages.fr.yml | 1 +
.../views/CustomFieldsGroup/index.html.twig | 12 +++++-------
.../views/CustomFieldsGroup/new.html.twig | 19 ++++++++++---------
3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index ad8407fbc..2a7873d98 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -4,6 +4,7 @@
Custom fields configuration: Configuration des champs personnalisés
CustomFieldsGroup list: Groupes de champs personnalisés
+CustomFieldsGroup creation: Nouveau groupe de champs personnalisés
Entity: Entité
"Is default ?": "Par défaut ?"
"Some module select default groups for some usage. Example: the default person group is shown under person page.": "Certains modules sélectionnent en priorité les formulaires par défaut. Exemple: le formulaire par défaut pour une personne est affiché sur la page principale pour la personne"
diff --git a/Resources/views/CustomFieldsGroup/index.html.twig b/Resources/views/CustomFieldsGroup/index.html.twig
index 787c65436..697f9e874 100644
--- a/Resources/views/CustomFieldsGroup/index.html.twig
+++ b/Resources/views/CustomFieldsGroup/index.html.twig
@@ -57,11 +57,9 @@
{% endblock %}
From 41c47df0c363daad2a4562894fe869ac01b848ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Sat, 7 Nov 2015 09:56:28 +0100
Subject: [PATCH 20/54] remove delete action and form
---
Controller/CustomFieldsGroupController.php | 47 +---------------------
1 file changed, 2 insertions(+), 45 deletions(-)
diff --git a/Controller/CustomFieldsGroupController.php b/Controller/CustomFieldsGroupController.php
index 9e0794d73..211d7494a 100644
--- a/Controller/CustomFieldsGroupController.php
+++ b/Controller/CustomFieldsGroupController.php
@@ -175,12 +175,10 @@ class CustomFieldsGroupController extends Controller
}
$editForm = $this->createEditForm($entity);
- $deleteForm = $this->createDeleteForm($id);
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
- 'delete_form' => $deleteForm->createView(),
));
}
@@ -246,7 +244,6 @@ class CustomFieldsGroupController extends Controller
throw $this->createNotFoundException('Unable to find CustomFieldsGroup entity.');
}
- $deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
@@ -259,49 +256,9 @@ class CustomFieldsGroupController extends Controller
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
- 'delete_form' => $deleteForm->createView(),
));
}
- /**
- * Deletes a CustomFieldsGroup entity.
- *
- */
- public function deleteAction(Request $request, $id)
- {
- $form = $this->createDeleteForm($id);
- $form->handleRequest($request);
-
- if ($form->isValid()) {
- $em = $this->getDoctrine()->getManager();
- $entity = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->find($id);
-
- if (!$entity) {
- throw $this->createNotFoundException('Unable to find CustomFieldsGroup entity.');
- }
-
- $em->remove($entity);
- $em->flush();
- }
-
- return $this->redirect($this->generateUrl('customfieldsgroup'));
- }
-
- /**
- * Creates a form to delete a CustomFieldsGroup entity by id.
- *
- * @param mixed $id The entity id
- *
- * @return \Symfony\Component\Form\Form The form
- */
- private function createDeleteForm($id)
- {
- return $this->createFormBuilder()
- ->setAction($this->generateUrl('customfieldsgroup_delete', array('id' => $id)))
- ->setMethod('DELETE')
- ->add('submit', 'submit', array('label' => 'Delete'))
- ->getForm()
- ;
- }
+
/**
* This function render the customFieldsGroup as a form.
@@ -341,7 +298,7 @@ class CustomFieldsGroupController extends Controller
}
var_dump($form->getData());
- var_dump(json_encode($form->getData()));
+ var_dump(json_enccode($form->getData()));
}
From 0dcf2c33f07d921bddda318720008b068fefcbe1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Sun, 8 Nov 2015 17:59:43 +0100
Subject: [PATCH 21/54] create custom fields default group from new layout
---
.../CustomFieldsDefaultGroupController.php | 33 -------------
Controller/CustomFieldsGroupController.php | 48 ++++++++++++++++++-
Resources/translations/messages.fr.yml | 2 +-
3 files changed, 47 insertions(+), 36 deletions(-)
diff --git a/Controller/CustomFieldsDefaultGroupController.php b/Controller/CustomFieldsDefaultGroupController.php
index 860d3c554..b7ce2dad1 100644
--- a/Controller/CustomFieldsDefaultGroupController.php
+++ b/Controller/CustomFieldsDefaultGroupController.php
@@ -41,37 +41,4 @@ class CustomFieldsDefaultGroupController extends Controller
'form' => $form->createView()
));
}
-
- /**
- * Set the CustomField Group with id $cFGroupId as default
- */
- public function setAGroupAsDefaultAction(Request $request)
- {
- $cFGroupId = $request->query->get('cFGroup');
-
- $em = $this->getDoctrine()->getManager();
-
- $cFGroup = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->findOneById($cFGroupId);
-
- if(!$cFGroup) {
- throw new Exception("No CF GROUP with ID".$cFGroupId, 1);
- }
-
- $cFDefaultGroup = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsDefaultGroup')
- ->findOneByEntity($cFGroup->getEntity());
-
- if($cFDefaultGroup) {
- $em->remove($cFDefaultGroup);
- $em->flush();
- }
-
- $newCFDefaultGroup = new CustomFieldsDefaultGroup();
- $newCFDefaultGroup->setCustomFieldsGroup($cFGroup);
- $newCFDefaultGroup->setEntity($cFGroup->getEntity());
-
- $em->persist($newCFDefaultGroup);
- $em->flush();
-
- return $this->redirect($this->generateUrl('customfieldsdefaultgroup'));
- }
}
\ No newline at end of file
diff --git a/Controller/CustomFieldsGroupController.php b/Controller/CustomFieldsGroupController.php
index 211d7494a..3c7e0f3ef 100644
--- a/Controller/CustomFieldsGroupController.php
+++ b/Controller/CustomFieldsGroupController.php
@@ -8,6 +8,7 @@ use Doctrine\ORM\Query;
use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
use Chill\CustomFieldsBundle\Entity\CustomField;
use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldsGroupToIdTransformer;
+use Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup;
/**
* CustomFieldsGroup controller.
@@ -70,7 +71,7 @@ class CustomFieldsGroupController extends Controller
* @param CustomFieldsGroup $group
* @return \Symfony\Component\Form\Form
*/
- private function createMakeDefaultForm(CustomFieldsGroup $group)
+ private function createMakeDefaultForm(CustomFieldsGroup $group = null)
{
return $this->createFormBuilder($group, array(
'method' => 'POST',
@@ -256,9 +257,52 @@ class CustomFieldsGroupController extends Controller
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
- ));
+
+ ));
}
+ /**
+ * Set the CustomField Group with id $cFGroupId as default
+ */
+ public function makeDefaultAction(Request $request)
+ {
+
+ $form = $this->createMakeDefaultForm(null);
+ $form->handleRequest($request);
+
+ $cFGroupId = $form->get('id')->getData();
+
+ $em = $this->getDoctrine()->getManager();
+
+ $cFGroup = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->findOneById($cFGroupId);
+
+ if(!$cFGroup) {
+ throw $this
+ ->createNotFoundException("customFieldsGroup not found with "
+ . "id $cFGroupId");
+ }
+
+ $cFDefaultGroup = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsDefaultGroup')
+ ->findOneByEntity($cFGroup->getEntity());
+
+ if($cFDefaultGroup) {
+ $em->remove($cFDefaultGroup);
+ $em->flush(); /*this is necessary, if not doctrine
+ * will not remove old entity before adding a new one,
+ * and this leads to violation constraint of unique entity
+ * in postgresql
+ */
+ }
+
+ $newCFDefaultGroup = new CustomFieldsDefaultGroup();
+ $newCFDefaultGroup->setCustomFieldsGroup($cFGroup);
+ $newCFDefaultGroup->setEntity($cFGroup->getEntity());
+
+ $em->persist($newCFDefaultGroup);
+ $em->flush();
+
+ return $this->redirect($this->generateUrl('customfieldsgroup'));
+ }
/**
* This function render the customFieldsGroup as a form.
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 4968ebb67..2eb85c380 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -8,7 +8,7 @@ CustomFieldsGroup creation: Nouveau groupe de champs personnalisés
Entity: Entité
"Is default ?": "Par défaut ?"
"Some module select default groups for some usage. Example: the default person group is shown under person page.": "Certains modules sélectionnent en priorité les formulaires par défaut. Exemple: le formulaire par défaut pour une personne est affiché sur la page principale pour la personne"
-Make default: Assigner comme formulaire par défaut
+Make default: Rendre groupe par défaut
Create a new group: Créer un nouveau groupe
CustomFieldsGroup details: Détail du groupe de champs personnalisés
Fields associated with this group: Champs associés à ce groupe
From 3e23c1f1562e6f65eb691d540d65478676b6d540 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Sun, 8 Nov 2015 18:47:16 +0100
Subject: [PATCH 22/54] show options in show view
---
Controller/CustomFieldsGroupController.php | 26 ++++++++++++++++++-
Resources/translations/messages.fr.yml | 1 +
.../views/CustomFieldsGroup/show.html.twig | 18 ++++++++++++-
3 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/Controller/CustomFieldsGroupController.php b/Controller/CustomFieldsGroupController.php
index 3c7e0f3ef..f31edd4df 100644
--- a/Controller/CustomFieldsGroupController.php
+++ b/Controller/CustomFieldsGroupController.php
@@ -154,12 +154,36 @@ class CustomFieldsGroupController extends Controller
if (!$entity) {
throw $this->createNotFoundException('Unable to find CustomFieldsGroup entity.');
}
+
+ $options = $this->getOptionsAvailable($entity->getEntity());
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:show.html.twig', array(
'entity' => $entity,
- 'create_field_form' => $this->createCreateFieldForm($entity)->createView()
+ 'create_field_form' => $this->createCreateFieldForm($entity)->createView(),
+ 'options' => $options
));
}
+
+ /**
+ * Return an array of available key option for custom fields group
+ * on the given entity
+ *
+ * @param string $entity the entity to filter
+ */
+ private function getOptionsAvailable($entity)
+ {
+ $options = $this->getParameter('chill_custom_fields.'
+ . 'customizables_entities');
+
+ foreach($options as $key => $definition) {
+ if ($definition['class'] == $entity) {
+ foreach ($definition['options'] as $key => $value) {
+ yield $key;
+ }
+ }
+ }
+ // [$entity->getEntity()];
+ }
/**
* Displays a form to edit an existing CustomFieldsGroup entity.
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 2eb85c380..ab8cd4877 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -18,6 +18,7 @@ Add a new field: Ajouter un champ personnalisé
ordering: ordre
label_field: label du champ
active: actif
+No value defined for this option: Pas de valeur pour cette option
CustomFieldsGroup edit: Edition d'un groupe de champs personnalisé
diff --git a/Resources/views/CustomFieldsGroup/show.html.twig b/Resources/views/CustomFieldsGroup/show.html.twig
index bdbe2bad5..d2f9d4e33 100644
--- a/Resources/views/CustomFieldsGroup/show.html.twig
+++ b/Resources/views/CustomFieldsGroup/show.html.twig
@@ -16,7 +16,7 @@
#}
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
-{% block title%}{{ 'CustomFieldsGroup details'|trans }}{% endblock %}
+{% block title %}{{ 'CustomFieldsGroup details'|trans }}{% endblock %}
{% block admin_content %}
{{ 'CustomFieldsGroup details'|trans }}
@@ -31,6 +31,22 @@
{{ 'Entity'|trans }}
{{ entity.entity|trans }}
+ {%- for key in options -%}
+
+
{{ key ~ '_label'|trans }}
+
+ {%- if entity.options[key] is not defined -%}
+ {{ 'No value defined for this option'|trans }}
+ {%- elseif entity.options[key] is iterable -%}
+ {{ entity.options[key]|join(', ') }}
+ {% else %}
+ {{ entity.options[key] }}
+ {%- endif -%}
+
+
+ {%- else -%}
+
+ {%- endfor -%}
From 421f54e194406fa43a937d1a804eb2ba843637de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Sun, 8 Nov 2015 18:52:05 +0100
Subject: [PATCH 23/54] remove code for custom fields default group CRUD
The CRUD of default groups is handled now by the custom fields index page. The CRUD is not necessary.
---
.../CustomFieldsDefaultGroupController.php | 44 ------------------
Resources/config/routing.yml | 4 --
.../routing/customfieldsdefaultgroup.yml | 12 -----
.../CustomFieldsDefaultGroup/list.html.twig | 46 -------------------
4 files changed, 106 deletions(-)
delete mode 100644 Controller/CustomFieldsDefaultGroupController.php
delete mode 100644 Resources/config/routing/customfieldsdefaultgroup.yml
delete mode 100644 Resources/views/CustomFieldsDefaultGroup/list.html.twig
diff --git a/Controller/CustomFieldsDefaultGroupController.php b/Controller/CustomFieldsDefaultGroupController.php
deleted file mode 100644
index b7ce2dad1..000000000
--- a/Controller/CustomFieldsDefaultGroupController.php
+++ /dev/null
@@ -1,44 +0,0 @@
-getDoctrine()->getManager();
-
- $defaultGroups = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsDefaultGroup')->findAll();
-
- $form = $this->get('form.factory')
- ->createNamedBuilder(null, 'form', null, array(
- 'method' => 'GET',
- 'action' => $this->generateUrl('customfieldsdefaultgroup_set'),
- 'csrf_protection' => false
- ))
- ->add('cFGroup', 'entity', array(
- 'class' => 'ChillCustomFieldsBundle:CustomFieldsGroup',
- 'property' => 'name[fr]'
- ))
- ->getForm();
-
- return $this->render('ChillCustomFieldsBundle:CustomFieldsDefaultGroup:list.html.twig', array(
- 'defaultGroups' => $defaultGroups,
- 'form' => $form->createView()
- ));
- }
-}
\ No newline at end of file
diff --git a/Resources/config/routing.yml b/Resources/config/routing.yml
index 42718a48c..a6b554e69 100644
--- a/Resources/config/routing.yml
+++ b/Resources/config/routing.yml
@@ -5,7 +5,3 @@ chill_customfields_customfieldsgroup:
chill_customfields_customfield:
resource: "@ChillCustomFieldsBundle/Resources/config/routing/customfield.yml"
prefix: /
-
-chill_customfields_customfieldsdefaultgroup:
- resource: "@ChillCustomFieldsBundle/Resources/config/routing/customfieldsdefaultgroup.yml"
- prefix: /
\ No newline at end of file
diff --git a/Resources/config/routing/customfieldsdefaultgroup.yml b/Resources/config/routing/customfieldsdefaultgroup.yml
deleted file mode 100644
index 9919337af..000000000
--- a/Resources/config/routing/customfieldsdefaultgroup.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-customfieldsdefaultgroup:
- path: /{_locale}/admin/customfieldsdefaultgroup/
- defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsDefaultGroup:list" }
- options:
- menus:
- admin_custom_fields:
- order: 1000
- label: "CustomFields Default Groups : List"
-
-customfieldsdefaultgroup_set:
- path: /{_locale}/admin/customfieldsdefaultgroup/set/group/as/default/
- defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsDefaultGroup:setAGroupAsDefault" }
\ No newline at end of file
diff --git a/Resources/views/CustomFieldsDefaultGroup/list.html.twig b/Resources/views/CustomFieldsDefaultGroup/list.html.twig
deleted file mode 100644
index 036bc04d5..000000000
--- a/Resources/views/CustomFieldsDefaultGroup/list.html.twig
+++ /dev/null
@@ -1,46 +0,0 @@
-{#
- * Copyright (C) 2014, Champs Libres Cooperative SCRLFS,
- *
- * 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 .
-#}
-{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
-
-{% block admin_content %}
-
CustomFieldsDefaultGroup list
-
-
-
-
-
Entity
-
CustomFieldGroup
-
-
-
- {% for defaultGroup in defaultGroups %}
-
-
{{ defaultGroup.entity }}
-
{{ defaultGroup.customFieldsGroup.name['fr'] }}
-
- {% endfor %}
-
-
-
- {{ form_start(form) }}
- {{ form_row(form.cFGroup) }}
-
-
- {{ form_end(form) }}
-{% endblock %}
From cbcc722c0d9a9c5e66cf088728de511d908b048d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Sun, 8 Nov 2015 21:18:03 +0100
Subject: [PATCH 24/54] remove the field "customFieldsGroup" on custom field
creation
The customFieldsGroup field is hidden when creating a new customFields.
The customFieldsGroup is retrieved from the url (`customFieldsGroup` value in the URL).
This should ease the task for administrator and be consistent with the UI which group customFields into customFieldsGroup.
---
Controller/CustomFieldController.php | 19 ++++++++++---
Form/CustomFieldType.php | 40 +++++++++++++++++++++-------
Resources/config/services.yml | 1 +
3 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/Controller/CustomFieldController.php b/Controller/CustomFieldController.php
index f9958d70d..df23c6e40 100644
--- a/Controller/CustomFieldController.php
+++ b/Controller/CustomFieldController.php
@@ -4,7 +4,7 @@ namespace Chill\CustomFieldsBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-
+use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldsGroupToIdTransformer;
use Chill\CustomFieldsBundle\Entity\CustomField;
/**
@@ -85,9 +85,10 @@ class CustomFieldController extends Controller
'action' => $this->generateUrl('customfield_create',
array('type' => $type)),
'method' => 'POST',
- 'type' => $type
+ 'type' => $type,
+ 'group_widget' => ($entity->getCustomFieldsGroup()) ? 'hidden' :'entity'
));
-
+
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
@@ -100,6 +101,18 @@ class CustomFieldController extends Controller
public function newAction(Request $request)
{
$entity = new CustomField();
+
+ //add the custom field group if defined in URL
+ $cfGroupId = $request->query->get('customFieldsGroup', null);
+ $cfGroup = $this->getDoctrine()->getManager()
+ ->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')
+ ->find($cfGroupId);
+ if (!$cfGroup) {
+ throw $this->createNotFoundException('CustomFieldsGroup with id '
+ . $cfGroupId.' is not found !');
+ }
+ $entity->setCustomFieldsGroup($cfGroup);
+
$form = $this->createCreateForm($entity, $request->query->get('type'));
return $this->render('ChillCustomFieldsBundle:CustomField:new.html.twig', array(
diff --git a/Form/CustomFieldType.php b/Form/CustomFieldType.php
index 77d8366c1..7130b8e60 100644
--- a/Form/CustomFieldType.php
+++ b/Form/CustomFieldType.php
@@ -6,9 +6,11 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
-use Chill\CustomFieldsBundle\Entity\CustomField;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
+use Doctrine\Common\Persistence\ObjectManager;
+use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldsGroupToIdTransformer;
+
class CustomFieldType extends AbstractType
{
@@ -20,10 +22,17 @@ class CustomFieldType extends AbstractType
private $culture = 'fr';
+ /**
+ * @var ObjectManager
+ */
+ private $om;
- public function __construct(CustomFieldProvider $compiler)
+
+ public function __construct(CustomFieldProvider $compiler,
+ ObjectManager $om)
{
$this->customFieldProvider = $compiler;
+ $this->om = $om;
}
/**
* @param FormBuilderInterface $builder
@@ -40,11 +49,22 @@ class CustomFieldType extends AbstractType
$builder
->add('name', 'translatable_string')
- ->add('active', 'checkbox', array('required' => false))
- ->add('customFieldsGroup', 'entity', array(
+ ->add('active', 'checkbox', array('required' => false));
+
+ if ($options['group_widget'] === 'entity') {
+ $builder->add('customFieldsGroup', 'entity', array(
'class' => 'ChillCustomFieldsBundle:CustomFieldsGroup',
'property' => 'name['.$this->culture.']'
- ))
+ ));
+ } elseif ($options['group_widget'] === 'hidden') {
+ $builder->add('customFieldsGroup', 'hidden');
+ $builder->get('customFieldsGroup')
+ ->addViewTransformer(new CustomFieldsGroupToIdTransformer($this->om));
+ } else {
+ throw new \LogicException('The value of group_widget is not handled');
+ }
+
+ $builder
->add('ordering', 'number')
->add('type', 'hidden', array('data' => $options['type']))
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event)
@@ -80,10 +100,12 @@ class CustomFieldType extends AbstractType
'data_class' => 'Chill\CustomFieldsBundle\Entity\CustomField'
));
- $resolver->setRequired(array('type'))
- ->addAllowedValues(array('type' =>
- array_keys($this->customFieldProvider->getAllFields())
- ));
+ $resolver->setRequired(array('type', 'group_widget'))
+ ->addAllowedValues(array(
+ 'type' => array_keys($this->customFieldProvider->getAllFields()),
+ 'group_widget' => array('hidden', 'entity')
+ ))
+ ->setDefault('group_widget', 'entity');
}
/**
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index af7b05b91..1f073c09b 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -11,6 +11,7 @@ services:
class: Chill\CustomFieldsBundle\Form\CustomFieldType
arguments:
- "@chill.custom_field.provider"
+ - "@doctrine.orm.entity_manager"
tags:
- { name: 'form.type', alias: 'custom_field_choice' }
From b96076022f64107be331ef4bd1414b993251d31b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 25 Nov 2015 08:45:17 +0100
Subject: [PATCH 25/54] [wip] layout of custom field edition
[ci skip]
---
Controller/CustomFieldController.php | 2 +-
CustomFields/CustomFieldChoice.php | 6 +++--
Resources/translations/messages.fr.yml | 23 +++++++++++++++++-
Resources/views/CustomField/edit.html.twig | 28 +++++++++++++++++-----
Resources/views/Form/fields.html.twig | 17 +++++++++----
5 files changed, 62 insertions(+), 14 deletions(-)
diff --git a/Controller/CustomFieldController.php b/Controller/CustomFieldController.php
index df23c6e40..98b8b1c96 100644
--- a/Controller/CustomFieldController.php
+++ b/Controller/CustomFieldController.php
@@ -159,7 +159,7 @@ class CustomFieldController extends Controller
$editForm = $this->createEditForm($entity, $entity->getType());
$deleteForm = $this->createDeleteForm($id);
-
+
return $this->render('ChillCustomFieldsBundle:CustomField:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php
index a20eb4814..304b33ef3 100644
--- a/CustomFields/CustomFieldChoice.php
+++ b/CustomFields/CustomFieldChoice.php
@@ -136,7 +136,8 @@ class CustomFieldChoice implements CustomFieldInterface
'choices' => array(
1 => 'Multiple',
0 => 'Unique'),
- 'empty_data' => 0
+ 'empty_data' => 0,
+ 'label' => 'Multiplicity'
))
->add(self::EXPANDED, 'choice', array(
'expanded' => true,
@@ -144,7 +145,8 @@ class CustomFieldChoice implements CustomFieldInterface
'choices' => array(
1 => 'Expanded',
0 => 'Non expanded'),
- 'empty_data' => 0
+ 'empty_data' => 0,
+ 'label' => 'Choice display'
))
->add(self::ALLOW_OTHER, 'choice', array(
'label' => 'Allow other',
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index ab8cd4877..d9cf635fd 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -2,7 +2,7 @@
'Other value': 'Autre valeur'
'None': 'Pas spécifié'
-
+#customfieldsgroup administration
CustomFieldsGroup list: Groupes de champs personnalisés
CustomFieldsGroup creation: Nouveau groupe de champs personnalisés
Entity: Entité
@@ -26,3 +26,24 @@ CustomFieldsGroup edit: Edition d'un groupe de champs personnalisé
Custom fields configuration: Champs personnalisés
CustomFields List: Liste des champs personnalisés
CustomFields Groups: Groupe de champs personnalisés
+
+#customfield administration
+CustomField edit: Modification d'un champ personnalisé
+General informations: Informations générales
+Options: Options
+Custom fields group: Groupe de champ personnalisé
+Ordering: Ordre d'apparition
+Back to the group: Retour au groupe de champs personnalisé
+
+#custom field choice
+Multiplicity: Multiplicité
+Multiple: Multiple
+Unique: Un seul choix possible
+Choice display: Affichage des choix
+Expanded: Choix étendus (boutons radio)
+Non expanded: Choix rassemblés
+Allow other: Autoriser une autre valeur
+No: Non
+Yes: Oui
+Other value label (empty if use by default): Label du champ "autre valeur"
+Choices: Choix
diff --git a/Resources/views/CustomField/edit.html.twig b/Resources/views/CustomField/edit.html.twig
index bcc2e5d88..9b32ab809 100644
--- a/Resources/views/CustomField/edit.html.twig
+++ b/Resources/views/CustomField/edit.html.twig
@@ -16,17 +16,33 @@
#}
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
-{% block admin_content %}
-
CustomField edit
+{% block title %}{{ 'CustomField edit'|trans }}{% endblock title %}
- {{ form(edit_form) }}
+{% block admin_content %}
+
{{ 'CustomField edit'|trans }}
+
+
{{ 'General informations'|trans }}
+ {{ form_start(edit_form) }}
+ {{ form_row(edit_form.name) }}
+ {{ form_row(edit_form.active) }}
+ {% if edit_form.customFieldsGroup is defined %}
+ {{ form_row(edit_form.customFieldsGroup) }}
+ {% endif %}
+ {{ form_row(edit_form.ordering) }}
+ {% if edit_form.options is not empty %}
+
{% endblock %}
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig
index 76ec0cb5c..3a23a5adf 100644
--- a/Resources/views/Form/fields.html.twig
+++ b/Resources/views/Form/fields.html.twig
@@ -32,10 +32,19 @@
{% endblock cf_choices_list_widget %}
-{# render the possibility to add different elements in a choice list #}
-{% block cf_choices_widget %}
+{# CFChoice : render the different elements in a choice list #}
+{% block cf_choices_row %}
+
{{ 'Choices'|trans }}
- {{ form(form) }}
+
+ {% for choice in form %}
+
+ {{ form_row(choice.name) }}
+
+ {% endfor %}
+
+
+
{# we use javascrit to add an additional element. All functions are personnalized with the id ( = form.vars.id) #}
-{% endblock cf_choices_widget %}
+{% endblock cf_choices_row %}
{% block choice_with_other_widget %}
From f24a088a0d26f2b1d9f94e659e6e397cd2abe230 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 25 Nov 2015 21:26:30 +0100
Subject: [PATCH 26/54] [wip] re-introduce 'add element' functionality
---
Resources/views/Form/fields.html.twig | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig
index 3a23a5adf..8f611e6de 100644
--- a/Resources/views/Form/fields.html.twig
+++ b/Resources/views/Form/fields.html.twig
@@ -35,15 +35,20 @@
{# CFChoice : render the different elements in a choice list #}
{% block cf_choices_row %}
{# we use javascrit to add an additional element. All functions are personnalized with the id ( = form.vars.id) #}
From bf99b68a2a1ffdde68faac63ba80208d25009fd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 27 Nov 2015 13:37:07 +0100
Subject: [PATCH 27/54] Improve rendering of options and fields
---
CustomFields/CustomFieldText.php | 8 +++++-
CustomFields/CustomFieldTitle.php | 11 +++++---
Resources/translations/messages.fr.yml | 21 +++++++++++++++
Resources/views/CustomField/edit.html.twig | 2 +-
Resources/views/CustomField/new.html.twig | 31 +++++++++++++++++-----
Resources/views/Form/fields.html.twig | 8 +++---
6 files changed, 65 insertions(+), 16 deletions(-)
diff --git a/CustomFields/CustomFieldText.php b/CustomFields/CustomFieldText.php
index 08e4ab58f..a11705707 100644
--- a/CustomFields/CustomFieldText.php
+++ b/CustomFields/CustomFieldText.php
@@ -122,7 +122,13 @@ class CustomFieldText implements CustomFieldInterface
return $builder
->add(self::MAX_LENGTH, 'integer', array('empty_data' => 256))
->add(self::MULTIPLE_CF_INLINE, 'choice', array(
- 'choices' => array('1' => 'True', '0' => 'False')))
+ 'choices' => array(
+ '1' => 'Multiple boxes on the line',
+ '0' => 'One box on the line'
+ ),
+ 'label' => 'Box appearance',
+ 'expanded' => True
+ ))
;
}
}
diff --git a/CustomFields/CustomFieldTitle.php b/CustomFields/CustomFieldTitle.php
index 78b6f08d6..6c15543eb 100644
--- a/CustomFields/CustomFieldTitle.php
+++ b/CustomFields/CustomFieldTitle.php
@@ -96,10 +96,13 @@ class CustomFieldTitle implements CustomFieldInterface
public function buildOptionsForm(FormBuilderInterface $builder)
{
return $builder->add(self::TYPE, 'choice',
- array('choices' => array(
- self::TYPE_TITLE => self::TYPE_TITLE,
- self::TYPE_SUBTITLE => self::TYPE_SUBTITLE
- ))
+ array(
+ 'choices' => array(
+ self::TYPE_TITLE => 'Main title',
+ self::TYPE_SUBTITLE => 'Subtitle'
+ ),
+ 'label' => 'Title level'
+ )
);
}
}
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index d9cf635fd..469f4f2a9 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -20,6 +20,7 @@ label_field: label du champ
active: actif
No value defined for this option: Pas de valeur pour cette option
CustomFieldsGroup edit: Edition d'un groupe de champs personnalisé
+type: type
#menu entries
@@ -29,11 +30,19 @@ CustomFields Groups: Groupe de champs personnalisés
#customfield administration
CustomField edit: Modification d'un champ personnalisé
+CustomField creation: Nouveau champ personnalisé
General informations: Informations générales
Options: Options
Custom fields group: Groupe de champ personnalisé
Ordering: Ordre d'apparition
Back to the group: Retour au groupe de champs personnalisé
+Slug: Identifiant textuel
+
+#custom field name
+choice: choix
+title: titre
+text: texte
+text field: champ texte
#custom field choice
Multiplicity: Multiplicité
@@ -47,3 +56,15 @@ No: Non
Yes: Oui
Other value label (empty if use by default): Label du champ "autre valeur"
Choices: Choix
+Add an element: Ajouter un élément
+
+#custom field text
+Max length: Longueur maximum
+Box appearance: Apparence du champ
+Multiple boxes on the line: Plusieurs champs sur la ligne
+One box on the line: Un seul champ sur la ligne
+
+#custom field title
+Title level: Niveau de titre
+Main title: Titre principal
+Subtitle: Sous-titre
diff --git a/Resources/views/CustomField/edit.html.twig b/Resources/views/CustomField/edit.html.twig
index 9b32ab809..08fbed2ce 100644
--- a/Resources/views/CustomField/edit.html.twig
+++ b/Resources/views/CustomField/edit.html.twig
@@ -40,7 +40,7 @@
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig
index 8f611e6de..04febae3c 100644
--- a/Resources/views/Form/fields.html.twig
+++ b/Resources/views/Form/fields.html.twig
@@ -35,17 +35,17 @@
{# CFChoice : render the different elements in a choice list #}
{% block cf_choices_row %}
- {% endblock %}
From 46173231d2d9c66ebad345e039984739d6dbac74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 27 Nov 2015 14:18:19 +0100
Subject: [PATCH 30/54] adding flash messages for customfield
---
Controller/CustomFieldController.php | 17 +++++++++++++++--
Resources/translations/messages.fr.yml | 3 +++
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/Controller/CustomFieldController.php b/Controller/CustomFieldController.php
index 204652612..8342ea765 100644
--- a/Controller/CustomFieldController.php
+++ b/Controller/CustomFieldController.php
@@ -27,9 +27,16 @@ class CustomFieldController extends Controller
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
+
+ $this->addFlash('success', $this->get('translator')
+ ->trans('The custom field has been created'));
- return $this->redirect($this->generateUrl('customfield_show', array('id' => $entity->getId())));
- }
+ return $this->redirect($this->generateUrl('customfieldsgroup_show',
+ array('id' => $entity->getCustomFieldsGroup()->getId())));
+ }
+
+ $this->addFlash('error', $this->get('translator')
+ ->trans("The custom field form contains errors"));
return $this->render('ChillCustomFieldsBundle:CustomField:new.html.twig', array(
'entity' => $entity,
@@ -166,9 +173,15 @@ class CustomFieldController extends Controller
if ($editForm->isValid()) {
$em->flush();
+
+ $this->addFlash('success', $this->get('translator')
+ ->trans("The custom field has been updated"));
return $this->redirect($this->generateUrl('customfield_edit', array('id' => $id)));
}
+
+ $this->addFlash('error', $this->get('translator')
+ ->trans("The custom field form contains errors"));
return $this->render('ChillCustomFieldsBundle:CustomField:edit.html.twig', array(
'entity' => $entity,
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 469f4f2a9..38e037506 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -37,6 +37,9 @@ Custom fields group: Groupe de champ personnalisé
Ordering: Ordre d'apparition
Back to the group: Retour au groupe de champs personnalisé
Slug: Identifiant textuel
+The custom field has been created: Le champ personnalisé est créé
+The custom field form contains errors: Le formulaire contient des erreurs
+The custom field has been updated: Le champ personnalisé a été mis à jour
#custom field name
choice: choix
From 2401270754746b631a370c1a2a523e433e25b5d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 27 Nov 2015 14:26:46 +0100
Subject: [PATCH 31/54] add flash message for custom fields group
---
Controller/CustomFieldsGroupController.php | 15 +++++++++++++++
Resources/translations/messages.fr.yml | 4 ++++
2 files changed, 19 insertions(+)
diff --git a/Controller/CustomFieldsGroupController.php b/Controller/CustomFieldsGroupController.php
index f31edd4df..46b95fd5a 100644
--- a/Controller/CustomFieldsGroupController.php
+++ b/Controller/CustomFieldsGroupController.php
@@ -97,9 +97,15 @@ class CustomFieldsGroupController extends Controller
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
+
+ $this->addFlash('success', $this->get('translator')
+ ->trans("The custom fields group has been created"));
return $this->redirect($this->generateUrl('customfieldsgroup_show', array('id' => $entity->getId())));
}
+
+ $this->addFlash('error', $this->get('translator')
+ ->trans("The custom fields group form contains errors"));
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:new.html.twig', array(
'entity' => $entity,
@@ -274,9 +280,15 @@ class CustomFieldsGroupController extends Controller
if ($editForm->isValid()) {
$em->flush();
+
+ $this->addFlash('success', $this->get('translator')
+ ->trans("The custom fields group has been updated"));
return $this->redirect($this->generateUrl('customfieldsgroup_edit', array('id' => $id)));
}
+
+ $this->addFlash('error', $this->get('translator')
+ ->trans("The custom fields group form contains errors"));
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:edit.html.twig', array(
'entity' => $entity,
@@ -324,6 +336,9 @@ class CustomFieldsGroupController extends Controller
$em->persist($newCFDefaultGroup);
$em->flush();
+
+ $this->addFlash('success', $this->get('translator')
+ ->trans("The default custom fields group has been changed"));
return $this->redirect($this->generateUrl('customfieldsgroup'));
}
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 38e037506..77c13fd1c 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -21,6 +21,10 @@ active: actif
No value defined for this option: Pas de valeur pour cette option
CustomFieldsGroup edit: Edition d'un groupe de champs personnalisé
type: type
+The custom fields group has been created: Le groupe de champs personnalisés a été créé
+The custom fields group has been updated: Le groupe de champs personnalisés a été mis à jour
+The custom fields group form contains errors: Le formulaire contient des erreurs
+The default custom fields group has been changed: Le groupe par défaut a été changé
#menu entries
From c9ca7c1e1bcab73787229c05eb8beb8400340de9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 30 Nov 2015 21:31:58 +0100
Subject: [PATCH 32/54] fix creation of custom field without cfgroup id
---
.gitignore | 2 ++
Controller/CustomFieldController.php | 17 ++++++++++-------
Resources/views/CustomField/new.html.twig | 6 ++++++
Tests/CustomFields/CustomFieldsTextTest.php | 1 +
4 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/.gitignore b/.gitignore
index 52d2b6ff7..b11589291 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,5 @@ src/Chill/CustomFieldsBundle/vendor/*
bootstrap.php.cache
#the file created by composer to store creds
auth.json
+Tests/Fixtures/App/app/config/parameters.yml
+
diff --git a/Controller/CustomFieldController.php b/Controller/CustomFieldController.php
index 8342ea765..46b013f82 100644
--- a/Controller/CustomFieldController.php
+++ b/Controller/CustomFieldController.php
@@ -76,14 +76,17 @@ class CustomFieldController extends Controller
//add the custom field group if defined in URL
$cfGroupId = $request->query->get('customFieldsGroup', null);
- $cfGroup = $this->getDoctrine()->getManager()
- ->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')
- ->find($cfGroupId);
- if (!$cfGroup) {
- throw $this->createNotFoundException('CustomFieldsGroup with id '
- . $cfGroupId.' is not found !');
+
+ if ($cfGroupId !== null) {
+ $cfGroup = $this->getDoctrine()->getManager()
+ ->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')
+ ->find($cfGroupId);
+ if (!$cfGroup) {
+ throw $this->createNotFoundException('CustomFieldsGroup with id '
+ . $cfGroupId.' is not found !');
+ }
+ $entity->setCustomFieldsGroup($cfGroup);
}
- $entity->setCustomFieldsGroup($cfGroup);
$form = $this->createCreateForm($entity, $request->query->get('type'));
diff --git a/Resources/views/CustomField/new.html.twig b/Resources/views/CustomField/new.html.twig
index 556c464ec..783cbb1d6 100644
--- a/Resources/views/CustomField/new.html.twig
+++ b/Resources/views/CustomField/new.html.twig
@@ -41,9 +41,15 @@
{% endblock %}
diff --git a/Tests/CustomFields/CustomFieldsTextTest.php b/Tests/CustomFields/CustomFieldsTextTest.php
index 205dc7dfe..00130df80 100644
--- a/Tests/CustomFields/CustomFieldsTextTest.php
+++ b/Tests/CustomFields/CustomFieldsTextTest.php
@@ -100,4 +100,5 @@ class CustomFieldsTextTest extends WebTestCase
$form = $crawler->selectButton('custom_field_choice_submit')->form();
$this->assertTrue($form->has('custom_field_choice[options][maxLength]'));
}
+
}
From 9b5544beaf0cfeef90710855875d548dba836227 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 30 Nov 2015 22:10:04 +0100
Subject: [PATCH 33/54] create test for custom fields group complete scenario
a deps is added on the bundle "person" in order to make test working.
---
.../CustomFieldsGroupControllerTest.php | 67 +++++++++++++++++++
.../CustomFieldsGroupControllerTest_TODO.php | 55 ---------------
Tests/Fixtures/App/app/AppKernel.php | 3 +-
composer.json | 10 ++-
4 files changed, 76 insertions(+), 59 deletions(-)
create mode 100644 Tests/Controller/CustomFieldsGroupControllerTest.php
delete mode 100644 Tests/Controller/CustomFieldsGroupControllerTest_TODO.php
diff --git a/Tests/Controller/CustomFieldsGroupControllerTest.php b/Tests/Controller/CustomFieldsGroupControllerTest.php
new file mode 100644
index 000000000..920e02986
--- /dev/null
+++ b/Tests/Controller/CustomFieldsGroupControllerTest.php
@@ -0,0 +1,67 @@
+ 'test_customizable_entities_test_not_empty_config'));
+ // Create a new client to browse the application
+ $client = static::createClient(array(), array(
+ 'PHP_AUTH_USER' => 'admin',
+ 'PHP_AUTH_PW' => 'olala',
+ ));
+
+ //create the entity
+ $this->createCustomFieldsGroup($client);
+
+ // Edit the entity
+ $this->editCustomFieldsGroup($client);
+ }
+
+ private function createCustomFieldsGroup(Client &$client)
+ {
+ // Create a new entry in the database
+ $crawler = $client->request('GET', '/fr/admin/customfieldsgroup/');
+ $this->assertEquals(200, $client->getResponse()->getStatusCode(),
+ "Unexpected HTTP status code for GET /customfieldsgroup/");
+
+ $crawler = $client->click($crawler->selectLink('Créer un nouveau groupe')->link());
+
+ // Fill in the form and submit it
+ $form = $crawler->selectButton('Créer')->form(array(
+ 'custom_fields_group[name][fr]' => 'Test',
+ 'custom_fields_group[entity]' => 'Chill\PersonBundle\Entity\Person'
+ ));
+
+ $crawler = $client->submit($form);
+
+ $crawler = $client->followRedirect();
+
+ // Check data in the show view
+ $this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(),
+ 'Missing element td:contains("Test")');
+ }
+
+ private function editCustomFieldsGroup(Client $client)
+ {
+ $crawler = $client->request('GET', '/fr/admin/customfieldsgroup/');
+ $crawler = $client->click($crawler->selectLink('modifier')->link());
+ fwrite(STDOUT, $crawler->text());
+ $form = $crawler->selectButton('Update')->form(array(
+ 'custom_fields_group[name][fr]' => 'Foo',
+ ));
+
+ $client->submit($form);
+ $crawler = $client->followRedirect();
+
+ // Check the element contains an attribute with value equals "Foo"
+ $this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(),
+ 'Missing element [value="Foo"]');
+ }
+}
diff --git a/Tests/Controller/CustomFieldsGroupControllerTest_TODO.php b/Tests/Controller/CustomFieldsGroupControllerTest_TODO.php
deleted file mode 100644
index afa7bad25..000000000
--- a/Tests/Controller/CustomFieldsGroupControllerTest_TODO.php
+++ /dev/null
@@ -1,55 +0,0 @@
-request('GET', '/customfieldsgroup/');
- $this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /customfieldsgroup/");
- $crawler = $client->click($crawler->selectLink('Create a new entry')->link());
-
- // Fill in the form and submit it
- $form = $crawler->selectButton('Create')->form(array(
- 'cl_customfieldsbundle_customfieldsgroup[field_name]' => 'Test',
- // ... other fields to fill
- ));
-
- $client->submit($form);
- $crawler = $client->followRedirect();
-
- // Check data in the show view
- $this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(), 'Missing element td:contains("Test")');
-
- // Edit the entity
- $crawler = $client->click($crawler->selectLink('Edit')->link());
-
- $form = $crawler->selectButton('Update')->form(array(
- 'cl_customfieldsbundle_customfieldsgroup[field_name]' => 'Foo',
- // ... other fields to fill
- ));
-
- $client->submit($form);
- $crawler = $client->followRedirect();
-
- // Check the element contains an attribute with value equals "Foo"
- $this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
-
- // Delete the entity
- $client->submit($crawler->selectButton('Delete')->form());
- $crawler = $client->followRedirect();
-
- // Check the entity has been delete on the list
- $this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
- }
-
- */
-}
diff --git a/Tests/Fixtures/App/app/AppKernel.php b/Tests/Fixtures/App/app/AppKernel.php
index 59ec46bfa..d2e57ab94 100644
--- a/Tests/Fixtures/App/app/AppKernel.php
+++ b/Tests/Fixtures/App/app/AppKernel.php
@@ -17,7 +17,8 @@ class AppKernel extends Kernel
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new \Chill\MainBundle\ChillMainBundle,
new \Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
- new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle()
+ new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
+ new Chill\PersonBundle\ChillPersonBundle(),
#add here all the required bundle (some bundle are not required)
);
}
diff --git a/composer.json b/composer.json
index af1c0c6b4..32c01e7f5 100644
--- a/composer.json
+++ b/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": "~5.5",
- "symfony/symfony": "~2.7",
+ "symfony/symfony": "2.7.*",
"doctrine/orm": "~2.4",
"doctrine/dbal" : "~2.5",
"doctrine/common": "~2.4",
@@ -34,7 +34,8 @@
"chill-project/main": "dev-master"
},
"require-dev": {
- "doctrine/doctrine-fixtures-bundle": "~2.2@dev"
+ "doctrine/doctrine-fixtures-bundle": "~2.2@dev",
+ "chill-project/person": "dev-master@dev"
},
"scripts": {
"post-install-cmd": [
@@ -54,6 +55,9 @@
},
"extra": {
"symfony-app-dir": "Tests/Fixtures/App/app",
- "app-migrations-dir": "Tests/Fixtures/App/app/DoctrineMigrations"
+ "app-migrations-dir": "Tests/Fixtures/App/app/DoctrineMigrations",
+ "branch-alias": {
+ "dev-master": "fix_admin_interface-dev"
+ }
}
}
From 4c328d0aae42524943c35dd6b3d4532e532c69f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 30 Nov 2015 22:12:59 +0100
Subject: [PATCH 34/54] remove dump informations
---
Tests/Controller/CustomFieldsGroupControllerTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Tests/Controller/CustomFieldsGroupControllerTest.php b/Tests/Controller/CustomFieldsGroupControllerTest.php
index 920e02986..b6bc3bbee 100644
--- a/Tests/Controller/CustomFieldsGroupControllerTest.php
+++ b/Tests/Controller/CustomFieldsGroupControllerTest.php
@@ -52,7 +52,7 @@ class CustomFieldsGroupControllerTest extends WebTestCase
{
$crawler = $client->request('GET', '/fr/admin/customfieldsgroup/');
$crawler = $client->click($crawler->selectLink('modifier')->link());
- fwrite(STDOUT, $crawler->text());
+
$form = $crawler->selectButton('Update')->form(array(
'custom_fields_group[name][fr]' => 'Foo',
));
From 97475ca3b6c0f6be2c9db29c391045b2fae20eb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 30 Nov 2015 22:13:59 +0100
Subject: [PATCH 35/54] fix test for config according to new dev deps
---
Tests/Config/ConfigCustomizablesEntitiesTest.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Tests/Config/ConfigCustomizablesEntitiesTest.php b/Tests/Config/ConfigCustomizablesEntitiesTest.php
index deb9585e2..df66ab56c 100644
--- a/Tests/Config/ConfigCustomizablesEntitiesTest.php
+++ b/Tests/Config/ConfigCustomizablesEntitiesTest.php
@@ -43,7 +43,7 @@ class ConfigCustomizablesEntitiesTest extends KernelTestCase
->getParameter('chill_custom_fields.customizables_entities');
$this->assertInternalType('array', $customizableEntities);
- $this->assertCount(0, $customizableEntities);
+ $this->assertCount(1, $customizableEntities);
}
/**
@@ -59,7 +59,7 @@ class ConfigCustomizablesEntitiesTest extends KernelTestCase
->getParameter('chill_custom_fields.customizables_entities');
$this->assertInternalType('array', $customizableEntities);
- $this->assertCount(1, $customizableEntities);
+ $this->assertCount(2, $customizableEntities);
foreach($customizableEntities as $key => $config) {
$this->assertInternalType('array', $config);
From f18b384a0694435b4179cb59d70ddc70a1e8508f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 30 Nov 2015 22:33:15 +0100
Subject: [PATCH 36/54] remove 'empty_data' which cause conflict with
transformer
this blocked the possibility to uncheck the 'active' field on the
choice.
---
Form/Type/ChoicesListType.php | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Form/Type/ChoicesListType.php b/Form/Type/ChoicesListType.php
index 7cd3c4c3d..120559920 100644
--- a/Form/Type/ChoicesListType.php
+++ b/Form/Type/ChoicesListType.php
@@ -25,8 +25,7 @@ class ChoicesListType extends AbstractType
$builder->add('name', 'translatable_string')
->add('active', 'checkbox', array(
- 'required' => false,
- 'empty_data' => true
+ 'required' => false
))
->add('slug', 'hidden', array(
From c4d2c5e6913120923e528357b0808f85b236cea1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Mon, 30 Nov 2015 22:39:30 +0100
Subject: [PATCH 37/54] fix composer.json
---
composer.json | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/composer.json b/composer.json
index 32c01e7f5..0e0224354 100644
--- a/composer.json
+++ b/composer.json
@@ -55,9 +55,6 @@
},
"extra": {
"symfony-app-dir": "Tests/Fixtures/App/app",
- "app-migrations-dir": "Tests/Fixtures/App/app/DoctrineMigrations",
- "branch-alias": {
- "dev-master": "fix_admin_interface-dev"
- }
+ "app-migrations-dir": "Tests/Fixtures/App/app/DoctrineMigrations"
}
-}
+}
\ No newline at end of file
From 57fbd54a9c98560b7ac6c23eb60a2a21a2e0c6ee Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Tue, 8 Dec 2015 11:41:34 +0100
Subject: [PATCH 38/54] Removing the choice_with_other_widget that is alreay
defined in the main bundle
---
Resources/views/Form/fields.html.twig | 24 +++++-------------------
1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig
index 04febae3c..f696dc057 100644
--- a/Resources/views/Form/fields.html.twig
+++ b/Resources/views/Form/fields.html.twig
@@ -25,11 +25,9 @@
{# CustomFields Choice #}
{# render an alement in a choice list #}
{% block cf_choices_list_widget %}
-
-{{ form_row(form.name) }}
-{{ form_row(form.active) }}
-{{ form_row(form.slug) }}
-
+ {{ form_row(form.name) }}
+ {{ form_row(form.active) }}
+ {{ form_row(form.slug) }}
{% endblock cf_choices_list_widget %}
{# CFChoice : render the different elements in a choice list #}
@@ -80,18 +78,6 @@
jQuery(document).ready(initializeCFChoiceOptionsChoices('{{ form.vars.id }}'));
+{% endblock cf_choices_row %}
-{% endblock cf_choices_row %}
-
-{% block choice_with_other_widget %}
-
-{%- for child in form.children._choices %}
-{{- form_widget(child) -}}
-{{- form_label(child) -}}
-{%- if child.vars.value == '_other' -%}
-{{- form_widget(form.children._other) -}}
-{%- endif -%}
-{% endfor -%}
-
-
-{% endblock choice_with_other_widget %}
\ No newline at end of file
+{# The choice_with_other_widget widget is defined in the main bundle #}
\ No newline at end of file
From ebfb24a3ebaf323cdbfb094a0879fe9ee06f8677 Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Tue, 8 Dec 2015 11:42:05 +0100
Subject: [PATCH 39/54] Refactoring CustomFields/CustomFieldChoice.php :
removing useless linereturn
---
CustomFields/CustomFieldChoice.php | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php
index 304b33ef3..9bad639d6 100644
--- a/CustomFields/CustomFieldChoice.php
+++ b/CustomFields/CustomFieldChoice.php
@@ -20,14 +20,14 @@
namespace Chill\CustomFieldsBundle\CustomFields;
+use Chill\CustomFieldsBundle\Form\Type\ChoicesListType;
+use Chill\CustomFieldsBundle\Form\Type\ChoicesType;
+use Chill\CustomFieldsBundle\Form\Type\ChoiceWithOtherType;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\CustomFieldsBundle\Entity\CustomField;
-use Chill\CustomFieldsBundle\Form\Type\ChoicesType;
use Symfony\Component\HttpFoundation\RequestStack;
-use Chill\CustomFieldsBundle\Form\Type\ChoicesListType;
use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldDataTransformer;
-use Chill\CustomFieldsBundle\Form\Type\ChoiceWithOtherType;
use Symfony\Bridge\Twig\TwigEngine;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Component\Translation\Translator;
@@ -122,9 +122,7 @@ class CustomFieldChoice implements CustomFieldInterface
$builder->create($customField->getSlug(), 'choice', $options)
->addModelTransformer(new CustomFieldDataTransformer($this, $customField))
);
-
}
-
}
public function buildOptionsForm(FormBuilderInterface $builder)
From 373edab629595e6f5edcf4f2bf111fe1be2174d8 Mon Sep 17 00:00:00 2001
From: Marc Ducobu
Date: Tue, 8 Dec 2015 11:42:38 +0100
Subject: [PATCH 40/54] CustomFields/CustomFieldInterface.php : Improving the
doc
---
CustomFields/CustomFieldInterface.php | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/CustomFields/CustomFieldInterface.php b/CustomFields/CustomFieldInterface.php
index 149e5500b..994172e41 100644
--- a/CustomFields/CustomFieldInterface.php
+++ b/CustomFields/CustomFieldInterface.php
@@ -13,7 +13,9 @@ interface CustomFieldInterface
{
/**
- *
+ * Return a form type to edit the custom field. This form is shown to the
+ * user.
+ *
* @param \Chill\CustomFieldsBundle\CustomField\FormBuilderInterface $builder
* @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField
* @return \Symfony\Component\Form\FormTypeInterface the form type
@@ -21,7 +23,7 @@ interface CustomFieldInterface
public function buildForm(FormBuilderInterface $builder, CustomField $customField);
/**
- * transform the value into a format that can be stored in DB
+ * Transform the value into a format that can be stored in DB
*
* @param mixed $value
* @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField
@@ -38,6 +40,7 @@ interface CustomFieldInterface
public function deserialize($serialized, CustomField $customField);
/**
+ * Return a repsentation of the value of the CustomField.
*
* @param mixed $value the raw value, **not deserialized** (= as stored in the db)
* @param \Chill\CustomFieldsBundle\CustomField\CustomField $customField
@@ -48,7 +51,7 @@ interface CustomFieldInterface
public function getName();
/**
- * return a formType which allow to edit option for the custom type.
+ * Return a formType which allow to edit option for the custom type.
* This FormType is shown in admin
*
* @param \Chill\CustomFieldsBundle\CustomField\FormBuilderInterface $builder
From 4f2b605efc3f867f1b075c830f64df24a08aee96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 8 Dec 2015 19:45:04 +0100
Subject: [PATCH 41/54] add a number field
The field has three option :
- lesser or equal than. If null, this option is ignored ;
- greather or equal than. If null, this options is ignored ;
- precision : the number of decimal after the number ;
- text after the field : a text to show after the field.
The field is rendered as an HTML integer input if precision = 0, or a
symfony number field if precision > 0.
ref chill-project/Chill-CustomFields#11
---
CustomFields/CustomFieldNumber.php | 181 ++++++++++++++++++
Form/CustomFieldType.php | 1 +
Form/Extension/PostTextExtension.php | 53 +++++
Form/Extension/PostTextIntegerExtension.php | 37 ++++
Form/Extension/PostTextNumberExtension.php | 34 ++++
Resources/config/services.yml | 18 ++
Resources/translations/messages.fr.yml | 6 +
.../CustomFieldsRendering/number.html.twig | 1 +
Resources/views/Form/fields.html.twig | 26 ++-
Tests/CustomFields/CustomFieldsNumberTest.php | 143 ++++++++++++++
Tests/Fixtures/App/app/config/config.yml | 2 +-
composer.json | 2 +-
12 files changed, 501 insertions(+), 3 deletions(-)
create mode 100644 CustomFields/CustomFieldNumber.php
create mode 100644 Form/Extension/PostTextExtension.php
create mode 100644 Form/Extension/PostTextIntegerExtension.php
create mode 100644 Form/Extension/PostTextNumberExtension.php
create mode 100644 Resources/views/CustomFieldsRendering/number.html.twig
create mode 100644 Tests/CustomFields/CustomFieldsNumberTest.php
diff --git a/CustomFields/CustomFieldNumber.php b/CustomFields/CustomFieldNumber.php
new file mode 100644
index 000000000..d880f8a17
--- /dev/null
+++ b/CustomFields/CustomFieldNumber.php
@@ -0,0 +1,181 @@
+,
+ *
+ * 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\CustomFieldsBundle\CustomFields;
+
+use Chill\CustomFieldsBundle\CustomFields\CustomFieldInterface;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
+use Symfony\Component\Validator\Constraints\LessThanOrEqual;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Bundle\TwigBundle\TwigEngine;
+use Chill\MainBundle\Templating\TranslatableStringHelper;
+
+/**
+ * Create a custom field number.
+ *
+ * This number may have a min and max value, and a precision.
+ *
+ * @author Julien Fastré
+ * @author Marc Ducobu
+ */
+class CustomFieldNumber implements CustomFieldInterface
+{
+ /**
+ * key for the minimal value of the field
+ */
+ const MIN = 'min';
+ const MAX = 'max';
+ const SCALE = 'scale';
+ const POST_TEXT = 'post_text';
+
+ /**
+ *
+ * @var TwigEngine
+ */
+ private $templating = NULL;
+
+ /**
+ *
+ * @var TranslatableStringHelper
+ */
+ private $translatableStringHelper = NULL;
+
+ public function __construct(TwigEngine $templating, TranslatableStringHelper $translatableStringHelper)
+ {
+ $this->templating = $templating;
+ $this->translatableStringHelper = $translatableStringHelper;
+ }
+
+ public function buildForm(FormBuilderInterface $builder, CustomField $customField)
+ {
+ $options = $customField->getOptions();
+
+ //select the type depending to the SCALE
+ $type = ($options[self::SCALE] === 0 or $options[self::SCALE] === NULL)?
+ 'integer' : 'number';
+
+ $fieldOptions = $this->prepareFieldOptions($customField, $type);
+
+ $builder->add($customField->getSlug(), $type, $fieldOptions);
+ }
+
+ /**
+ * prepare the options'form field
+ *
+ * @param CustomField $customField
+ * @param string $type
+ * @return mixed[]
+ */
+ private function prepareFieldOptions(CustomField $customField, $type)
+ {
+ $options = $customField->getOptions();
+
+ /**
+ * @var mixed[] the formField options
+ */
+ $fieldOptions = array();
+
+ // add required
+ $fieldOptions['required'] = False;
+
+ //add label
+ $fieldOptions['label'] = $this->translatableStringHelper->localize($customField->getName());
+
+ // add constraints if required
+ if ($options[self::MIN] !== NULL) {
+ $fieldOptions['constraints'][] = new GreaterThanOrEqual(array('value' => $options[self::MIN]));
+ }
+ if ($options[self::MAX] !== NULL) {
+ $fieldOptions['constraints'][] = new LessThanOrEqual(array('value' => $options[self::MAX]));
+ }
+
+ // add precision to options if required
+ if ($type === 'number') {
+ $fieldOptions['scale'] = $options[self::SCALE];
+ }
+
+ if (!empty($options[self::POST_TEXT])) {
+ $fieldOptions['post_text'] = $options[self::POST_TEXT];
+ }
+
+ return $fieldOptions;
+ }
+
+ public function buildOptionsForm(FormBuilderInterface $builder)
+ {
+ return $builder
+ ->add(self::MIN, 'number', array(
+ 'scale' => 2,
+ 'label' => 'Greater or equal than',
+ 'required' => false
+ ))
+ ->add(self::MAX, 'number', array(
+ 'scale' => 2,
+ 'label' => 'Lesser or equal than',
+ 'required' => false
+ ))
+ ->add(self::SCALE, 'integer', array(
+ 'scale' => 0,
+ 'label' => 'Precision',
+ 'constraints' => array(
+ new GreaterThanOrEqual(array('value' => 0))
+ )
+ ))
+ ->add(self::POST_TEXT, 'text', array(
+ 'label' => 'Text after the field'
+ ))
+ ;
+
+ }
+
+ public function deserialize($serialized, CustomField $customField)
+ {
+ return $serialized;
+ }
+
+ public function getName()
+ {
+ return 'Number';
+ }
+
+ public function render($value, CustomField $customField, $documentType = 'html')
+ {
+ $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:number.'
+ .$documentType.'.twig';
+ $options = $customField->getOptions();
+
+ return $this->templating
+ ->render($template, array(
+ 'number' => $value,
+ 'scale' => $options[self::SCALE],
+ 'post' => $options[self::POST_TEXT]
+ ));
+ }
+
+ public function serialize($value, CustomField $customField)
+ {
+ return $value;
+ }
+
+}
diff --git a/Form/CustomFieldType.php b/Form/CustomFieldType.php
index 7130b8e60..9638cefca 100644
--- a/Form/CustomFieldType.php
+++ b/Form/CustomFieldType.php
@@ -87,6 +87,7 @@ class CustomFieldType extends AbstractType
->buildOptionsForm(
$builder
->create('options', null, array('compound' => true))
+ ->setRequired(false)
)
);
}
diff --git a/Form/Extension/PostTextExtension.php b/Form/Extension/PostTextExtension.php
new file mode 100644
index 000000000..24cf4e4f4
--- /dev/null
+++ b/Form/Extension/PostTextExtension.php
@@ -0,0 +1,53 @@
+
+ *
+ * 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\CustomFieldsBundle\Form\Extension;
+
+use Symfony\Component\Form\AbstractTypeExtension;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Form\FormView;
+use Symfony\Component\Form\FormInterface;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+
+/**
+ * This extension create the possibility to add some text
+ * after the input.
+ *
+ * This can be used to print the units of the field, or some text.
+ *
+ * This class must be extended by Extension class specifics to each input.
+ *
+ * @author Julien Fastré
+ */
+abstract class PostTextExtension extends AbstractTypeExtension
+{
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefined(array('post_text'));
+ }
+
+ public function buildView(FormView $view, FormInterface $form, array $options)
+ {
+ if (array_key_exists('post_text', $options)) {
+ //set the post text variable to the view
+ $view->vars['post_text'] = $options['post_text'];
+ }
+ }
+
+}
diff --git a/Form/Extension/PostTextIntegerExtension.php b/Form/Extension/PostTextIntegerExtension.php
new file mode 100644
index 000000000..1829501b8
--- /dev/null
+++ b/Form/Extension/PostTextIntegerExtension.php
@@ -0,0 +1,37 @@
+
+ *
+ * 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\CustomFieldsBundle\Form\Extension;
+
+use Symfony\Component\Form\Extension\Core\Type\IntegerType;
+
+/**
+ * This class add the PostTextExtension to integer fields
+ *
+ * @author Julien Fastré
+ */
+class PostTextIntegerExtension extends PostTextExtension
+{
+ public function getExtendedType()
+ {
+ // return IntegerType::class; !! only for symfony 2.8
+ return 'integer';
+ }
+
+}
diff --git a/Form/Extension/PostTextNumberExtension.php b/Form/Extension/PostTextNumberExtension.php
new file mode 100644
index 000000000..5cbaeca34
--- /dev/null
+++ b/Form/Extension/PostTextNumberExtension.php
@@ -0,0 +1,34 @@
+
+ *
+ * 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\CustomFieldsBundle\Form\Extension;
+
+/**
+ * This class add the PostTextExtension to number fields
+ *
+ * @author Julien Fastré
+ */
+class PostTextNumberExtension extends PostTextExtension
+{
+ public function getExtendedType()
+ {
+ return 'number';
+ }
+
+}
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index 1f073c09b..4641910b2 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -39,6 +39,24 @@ services:
- "@chill.main.helper.translatable_string"
tags:
- { name: 'chill.custom_field', type: 'text' }
+
+ chill.custom_field.number:
+ class: Chill\CustomFieldsBundle\CustomFields\CustomFieldNumber
+ arguments:
+ - "@templating"
+ - "@chill.main.helper.translatable_string"
+ tags:
+ - { name: 'chill.custom_field', type: 'number' }
+
+ chill.form_extension.post_text_integer:
+ class: Chill\CustomFieldsBundle\Form\Extension\PostTextIntegerExtension
+ tags:
+ - { name: form.type_extension, alias: 'integer' }
+
+ chill.form_extension.post_text_number:
+ class: Chill\CustomFieldsBundle\Form\Extension\PostTextNumberExtension
+ tags:
+ - { name: form.type_extension, alias: 'number' }
chill.custom_field.choice:
class: Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 77c13fd1c..2f4f55746 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -75,3 +75,9 @@ One box on the line: Un seul champ sur la ligne
Title level: Niveau de titre
Main title: Titre principal
Subtitle: Sous-titre
+
+#custom field number
+Greater or equal than: Plus grand ou égal à
+Lesser or equal than: Plus petit ou égal à
+Precision: Précision
+Text after the field: Texte après le champ
diff --git a/Resources/views/CustomFieldsRendering/number.html.twig b/Resources/views/CustomFieldsRendering/number.html.twig
new file mode 100644
index 000000000..894d34fae
--- /dev/null
+++ b/Resources/views/CustomFieldsRendering/number.html.twig
@@ -0,0 +1 @@
+{% if number is not empty %}{{ number|number_format(scale) }} {{ post|default('') }}{% endif %}
diff --git a/Resources/views/Form/fields.html.twig b/Resources/views/Form/fields.html.twig
index 04febae3c..b3d35ec94 100644
--- a/Resources/views/Form/fields.html.twig
+++ b/Resources/views/Form/fields.html.twig
@@ -94,4 +94,28 @@
{% endfor -%}
-{% endblock choice_with_other_widget %}
\ No newline at end of file
+{% endblock choice_with_other_widget %}
+
+{# extend the integer type to add post_text extension #}
+{% block integer_widget %}
+{%- if post_text is defined and post_text is not empty-%}
+
+{%- endif -%}
+{{ block('form_widget') }}
+{%- if post_text is defined and post_text is not empty-%}
+{{ post_text }}
+
+{%- endif -%}
+{% endblock %}
+
+{# extend the number type to add post_text extension #}
+{% block number_widget %}
+{%- if post_text is defined and post_text is not empty-%}
+
+{%- endif -%}
+{{ block('form_widget') }}
+{%- if post_text is defined and post_text is not empty-%}
+{{ post_text }}
+
+{%- endif -%}
+{% endblock %}
diff --git a/Tests/CustomFields/CustomFieldsNumberTest.php b/Tests/CustomFields/CustomFieldsNumberTest.php
new file mode 100644
index 000000000..466e03ab4
--- /dev/null
+++ b/Tests/CustomFields/CustomFieldsNumberTest.php
@@ -0,0 +1,143 @@
+
+ *
+ * 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\CustomFieldsBundle\Tests;
+
+use Chill\CustomFieldsBundle\CustomFields\CustomFieldNumber;
+use Symfony\Component\Form\FormBuilderInterface;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+
+/**
+ * Test CustomFieldsNumber
+ *
+ * @author Julien Fastré
+ */
+class CustomFieldsNumberTest extends \Symfony\Bundle\FrameworkBundle\Test\WebTestCase
+{
+ /**
+ *
+ * @var CustomFieldNumber
+ */
+ private $customFieldNumber;
+
+ /**
+ *
+ * @var FormBuilderInterface
+ */
+ private $formBuilder;
+
+ public function setUp()
+ {
+ self::bootKernel();
+
+ $this->customFieldNumber = self::$kernel->getContainer()
+ ->get('chill.custom_field.number');
+
+ $this->formBuilder = self::$kernel->getContainer()
+ ->get('form.factory')
+ ->createBuilder('form', null, array(
+ 'csrf_protection' => false,
+ 'csrf_field_name' => '_token'
+ ));
+
+ $request = new \Symfony\Component\HttpFoundation\Request();
+ $request->setLocale('fr');
+
+ self::$kernel->getContainer()
+ ->get('request_stack')
+ ->push($request);
+ }
+
+ /**
+ *
+ * @param mixed[] $options
+ * @return CustomField
+ */
+ private function createCustomFieldNumber($options)
+ {
+ return (new CustomField())
+ ->setType('number')
+ ->setActive(true)
+ ->setOrdering(10)
+ ->setSlug('default')
+ ->setName(array('fr' => 'default'))
+ ->setOptions($options);
+ }
+
+ public function testCreateValidForm()
+ {
+ $cf = $this->createCustomFieldNumber(array(
+ 'min' => null,
+ 'max' => null,
+ 'scale' => null,
+ 'post_text' => null
+ ));
+
+ $this->customFieldNumber->buildForm($this->formBuilder, $cf);
+
+ $form = $this->formBuilder->getForm();
+
+ $form->submit(array('default' => 10));
+
+ $this->assertTrue($form->isSynchronized());
+ $this->assertEquals(10, $form['default']->getData());
+ }
+
+ public function testCreateInvalidFormValueGreaterThanMaximum()
+ {
+ $cf = $this->createCustomFieldNumber(array(
+ 'min' => null,
+ 'max' => 10,
+ 'scale' => null,
+ 'post_text' => null
+ ));
+
+ $this->customFieldNumber->buildForm($this->formBuilder, $cf);
+
+ $form = $this->formBuilder->getForm();
+
+ $form->submit(array('default' => 100));
+
+ $this->assertTrue($form->isSynchronized());
+ $this->assertFalse($form->isValid());
+ $this->assertEquals(1, count($form['default']->getErrors()));
+ }
+
+ public function testCreateInvalidFormValueLowerThanMinimum()
+ {
+ $cf = $this->createCustomFieldNumber(array(
+ 'min' => 1000,
+ 'max' => null,
+ 'scale' => null,
+ 'post_text' => null
+ ));
+
+ $this->customFieldNumber->buildForm($this->formBuilder, $cf);
+
+ $form = $this->formBuilder->getForm();
+
+ $form->submit(array('default' => 100));
+
+ $this->assertTrue($form->isSynchronized());
+ $this->assertFalse($form->isValid());
+ $this->assertEquals(1, count($form['default']->getErrors()));
+ }
+
+
+}
diff --git a/Tests/Fixtures/App/app/config/config.yml b/Tests/Fixtures/App/app/config/config.yml
index 9fdeaf68d..48bd7abed 100644
--- a/Tests/Fixtures/App/app/config/config.yml
+++ b/Tests/Fixtures/App/app/config/config.yml
@@ -66,7 +66,7 @@ security:
anonymous: ~
form_login:
csrf_parameter: _csrf_token
- intention: authenticate
+ csrf_token_id: authenticate
csrf_provider: form.csrf_provider
logout: ~
access_control:
diff --git a/composer.json b/composer.json
index 32c01e7f5..b32bfc99e 100644
--- a/composer.json
+++ b/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": "~5.5",
- "symfony/symfony": "2.7.*",
+ "symfony/symfony": "~2.7",
"doctrine/orm": "~2.4",
"doctrine/dbal" : "~2.5",
"doctrine/common": "~2.4",
From 3230659a4ba77b394928aff3209cd08d4d1fc0bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Thu, 10 Dec 2015 17:16:59 +0100
Subject: [PATCH 42/54] add a required field to custom fields type
ref Chill-project/Chill-CustomFields#17
---
CustomFields/CustomFieldChoice.php | 2 +-
Entity/CustomField.php | 34 +++++++++++++
Form/CustomFieldType.php | 5 ++
Form/Type/CustomFieldType.php | 2 +
Resources/config/doctrine/CustomField.orm.yml | 2 +
.../migrations/Version20151210155904.php | 35 ++++++++++++++
Resources/translations/messages.fr.yml | 3 ++
Resources/views/CustomField/edit.html.twig | 1 +
Resources/views/CustomField/new.html.twig | 1 +
.../CustomFieldsGroupControllerTest.php | 5 +-
Tests/CustomFields/CustomFieldsNumberTest.php | 48 +++++++++++++++++++
11 files changed, 136 insertions(+), 2 deletions(-)
create mode 100644 Resources/migrations/Version20151210155904.php
diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php
index 9bad639d6..6f23b6339 100644
--- a/CustomFields/CustomFieldChoice.php
+++ b/CustomFields/CustomFieldChoice.php
@@ -94,7 +94,7 @@ class CustomFieldChoice implements CustomFieldInterface
$options = array(
'multiple' => $customFieldOptions[self::MULTIPLE],
'choices' => $choices,
- 'required' => false,
+ 'required' => $customField->isRequired(),
'label' => $this->translatableStringHelper->localize($customField->getName()));
//if allow_other = true
diff --git a/Entity/CustomField.php b/Entity/CustomField.php
index 2b45b498c..fe1a3bc89 100644
--- a/Entity/CustomField.php
+++ b/Entity/CustomField.php
@@ -60,6 +60,12 @@ class CustomField
*/
private $ordering;
+ /**
+ *
+ * @var bolean
+ */
+ private $required = FALSE;
+
const ONE_TO_ONE = 1;
const ONE_TO_MANY = 2;
@@ -246,6 +252,34 @@ class CustomField
$this->slug = $slug;
return $this;
}
+
+ /**
+ * alias for isRequired
+ *
+ * @return boolean
+ */
+ public function getRequired()
+ {
+ return $this->isRequired();
+ }
+
+ /**
+ * return true if the field required
+ *
+ * @return boolean
+ */
+ public function isRequired()
+ {
+ return $this->required;
+ }
+
+ public function setRequired($required)
+ {
+ $this->required = $required;
+ return $this;
+ }
+
+
}
diff --git a/Form/CustomFieldType.php b/Form/CustomFieldType.php
index 9638cefca..1d3594718 100644
--- a/Form/CustomFieldType.php
+++ b/Form/CustomFieldType.php
@@ -66,6 +66,11 @@ class CustomFieldType extends AbstractType
$builder
->add('ordering', 'number')
+ ->add('required', 'checkbox', array(
+ 'required' => false,
+ //'expanded' => TRUE,
+ 'label' => 'Required field'
+ ))
->add('type', 'hidden', array('data' => $options['type']))
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event)
{
diff --git a/Form/Type/CustomFieldType.php b/Form/Type/CustomFieldType.php
index 8a202e369..5e6ad0379 100644
--- a/Form/Type/CustomFieldType.php
+++ b/Form/Type/CustomFieldType.php
@@ -20,6 +20,7 @@ use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldDataTransformer;
use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
use Symfony\Component\OptionsResolver\OptionsResolver;
+use Chill\CustomFieldsBundle\CustomFields\CustomFieldTitle;
class CustomFieldType extends AbstractType
{
@@ -50,6 +51,7 @@ class CustomFieldType extends AbstractType
$this->customFieldCompiler
->getCustomFieldByType($cf->getType())
->buildForm($builder, $cf);
+ $builder->get($cf->getSlug())->setRequired($cf->isRequired());
}
}
diff --git a/Resources/config/doctrine/CustomField.orm.yml b/Resources/config/doctrine/CustomField.orm.yml
index 595e96db5..5e6651158 100644
--- a/Resources/config/doctrine/CustomField.orm.yml
+++ b/Resources/config/doctrine/CustomField.orm.yml
@@ -22,6 +22,8 @@ Chill\CustomFieldsBundle\Entity\CustomField:
type: float
options:
type: json_array
+ required:
+ type: boolean
lifecycleCallbacks: { }
manyToOne:
customFieldGroup:
diff --git a/Resources/migrations/Version20151210155904.php b/Resources/migrations/Version20151210155904.php
new file mode 100644
index 000000000..f3d9eadf3
--- /dev/null
+++ b/Resources/migrations/Version20151210155904.php
@@ -0,0 +1,35 @@
+abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE customfield ADD required BOOLEAN DEFAULT FALSE');
+ }
+
+ /**
+ * @param Schema $schema
+ */
+ public function down(Schema $schema)
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE CustomField DROP required');
+
+ }
+}
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 2f4f55746..0c5965eb8 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -39,6 +39,9 @@ General informations: Informations générales
Options: Options
Custom fields group: Groupe de champ personnalisé
Ordering: Ordre d'apparition
+Required field: Champs requis
+An answer is required: Une réponse est requise
+Any answer is required: Aucune réponse n'est requise
Back to the group: Retour au groupe de champs personnalisé
Slug: Identifiant textuel
The custom field has been created: Le champ personnalisé est créé
diff --git a/Resources/views/CustomField/edit.html.twig b/Resources/views/CustomField/edit.html.twig
index 08fbed2ce..019a02d95 100644
--- a/Resources/views/CustomField/edit.html.twig
+++ b/Resources/views/CustomField/edit.html.twig
@@ -29,6 +29,7 @@
{{ form_row(edit_form.customFieldsGroup) }}
{% endif %}
{{ form_row(edit_form.ordering) }}
+ {{ form_row(edit_form.required) }}
{% if edit_form.options is not empty %}
{{ 'Options'|trans }}
{% for option in edit_form.options %}
diff --git a/Resources/views/CustomField/new.html.twig b/Resources/views/CustomField/new.html.twig
index 783cbb1d6..d06ee0cc3 100644
--- a/Resources/views/CustomField/new.html.twig
+++ b/Resources/views/CustomField/new.html.twig
@@ -30,6 +30,7 @@
{{ form_row(form.customFieldsGroup) }}
{% endif %}
{{ form_row(form.ordering) }}
+ {{ form_row(form.required) }}
{% if form.options is not empty %}
{{ 'Options'|trans }}
{% for option in form.options %}
diff --git a/Tests/Controller/CustomFieldsGroupControllerTest.php b/Tests/Controller/CustomFieldsGroupControllerTest.php
index b6bc3bbee..420c4bf4c 100644
--- a/Tests/Controller/CustomFieldsGroupControllerTest.php
+++ b/Tests/Controller/CustomFieldsGroupControllerTest.php
@@ -51,7 +51,10 @@ class CustomFieldsGroupControllerTest extends WebTestCase
private function editCustomFieldsGroup(Client $client)
{
$crawler = $client->request('GET', '/fr/admin/customfieldsgroup/');
- $crawler = $client->click($crawler->selectLink('modifier')->link());
+ $links = $crawler->selectLink('modifier');
+ $crawler = $client->click($links->last()->link());
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
$form = $crawler->selectButton('Update')->form(array(
'custom_fields_group[name][fr]' => 'Foo',
diff --git a/Tests/CustomFields/CustomFieldsNumberTest.php b/Tests/CustomFields/CustomFieldsNumberTest.php
index 466e03ab4..fb4d44a26 100644
--- a/Tests/CustomFields/CustomFieldsNumberTest.php
+++ b/Tests/CustomFields/CustomFieldsNumberTest.php
@@ -22,6 +22,8 @@ namespace Chill\CustomFieldsBundle\Tests;
use Chill\CustomFieldsBundle\CustomFields\CustomFieldNumber;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\CustomFieldsBundle\Entity\CustomField;
+use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
+use Chill\CustomFieldsBundle\Form\CustomFieldsGroupType;
/**
* Test CustomFieldsNumber
@@ -139,5 +141,51 @@ class CustomFieldsNumberTest extends \Symfony\Bundle\FrameworkBundle\Test\WebTes
$this->assertEquals(1, count($form['default']->getErrors()));
}
+ public function testRequiredFieldIsFalse()
+ {
+ $cf = $this->createCustomFieldNumber(array(
+ 'min' => 1000,
+ 'max' => null,
+ 'scale' => null,
+ 'post_text' => null
+ ));
+ $cf->setRequired(false);
+
+ $cfGroup = (new \Chill\CustomFieldsBundle\Entity\CustomFieldsGroup())
+ ->addCustomField($cf);
+
+ $form = static::$kernel->getContainer()->get('form.factory')
+ ->createBuilder('custom_field', array(), array(
+ 'group' => $cfGroup
+ ))
+ ->getForm();
+
+ $this->assertFalse($form['default']->isRequired(),
+ "The field should not be required");
+ }
+
+ public function testRequiredFieldIsTrue()
+ {
+ $cf = $this->createCustomFieldNumber(array(
+ 'min' => 1000,
+ 'max' => null,
+ 'scale' => null,
+ 'post_text' => null
+ ));
+ $cf->setRequired(true);
+
+ $cfGroup = (new \Chill\CustomFieldsBundle\Entity\CustomFieldsGroup())
+ ->addCustomField($cf);
+
+ $form = static::$kernel->getContainer()->get('form.factory')
+ ->createBuilder('custom_field', array(), array(
+ 'group' => $cfGroup
+ ))
+ ->getForm();
+
+ $this->assertTrue($form['default']->isRequired(),
+ "The field should be required");
+ }
+
}
From 4f13ec69597f525547b7a5fb3f6ffaa9e4fd76d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 11 Dec 2015 10:50:39 +0100
Subject: [PATCH 43/54] add a custom field long choice basic
The `custom field long choice` aim to provide a way to deal with choices
with a big possibilities.
The `custom field long choice` allow :
- to persist different options in the database ;
- each option has a key, a text (translatable string), and eventually a
parent, and an internal_key
- every key can be activate or not. If the parent is inactivated, all
childs are inactivated
- the internal key have two purposes :
- link to an external csv file, with their own key ;
- add a special class to results, to allow custom layout.
Currently, the field exists, but some elements are missing :
- a script for CSV import
- possibility to select multiple items
- edition of options
- handle of option without parents
- tests are missing
---
CustomFields/CustomFieldLongChoice.php | 156 ++++++++++++++++
DataFixtures/ORM/LoadOption.php | 172 ++++++++++++++++++
Entity/CustomFieldLongChoice/Option.php | 153 ++++++++++++++++
.../OptionRepository.php | 77 ++++++++
.../CustomFieldLongChoice.Option.orm.yml | 33 ++++
Resources/config/services.yml | 18 +-
.../migrations/Version20151210205610.php | 47 +++++
Resources/translations/messages.fr.yml | 3 +
.../choice_long.html.twig | 11 ++
composer.json | 5 +-
10 files changed, 672 insertions(+), 3 deletions(-)
create mode 100644 CustomFields/CustomFieldLongChoice.php
create mode 100644 DataFixtures/ORM/LoadOption.php
create mode 100644 Entity/CustomFieldLongChoice/Option.php
create mode 100644 EntityRepository/CustomFieldLongChoice/OptionRepository.php
create mode 100644 Resources/config/doctrine/CustomFieldLongChoice.Option.orm.yml
create mode 100644 Resources/migrations/Version20151210205610.php
create mode 100644 Resources/views/CustomFieldsRendering/choice_long.html.twig
diff --git a/CustomFields/CustomFieldLongChoice.php b/CustomFields/CustomFieldLongChoice.php
new file mode 100644
index 000000000..a66de9dc2
--- /dev/null
+++ b/CustomFields/CustomFieldLongChoice.php
@@ -0,0 +1,156 @@
+
+ *
+ * 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\CustomFieldsBundle\CustomFields;
+
+use Chill\CustomFieldsBundle\CustomFields\CustomFieldInterface;
+use Symfony\Component\Form\FormBuilderInterface;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+use Chill\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice\OptionRepository;
+use Chill\MainBundle\Templating\TranslatableStringHelper;
+use Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option;
+use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldDataTransformer;
+use Symfony\Bridge\Twig\TwigEngine;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+class CustomFieldLongChoice implements CustomFieldInterface
+{
+ /**
+ *
+ * @var OptionRepository
+ */
+ private $optionRepository;
+
+ /**
+ *
+ * @var TranslatableStringHelper
+ */
+ private $translatableStringHelper;
+
+ /**
+ * @var TwigEngine
+ */
+ private $templating;
+
+ const KEY = 'key';
+
+ public function __construct(OptionRepository $optionRepository,
+ TranslatableStringHelper $translatableStringHelper,
+ TwigEngine $twigEngine)
+ {
+ $this->optionRepository = $optionRepository;
+ $this->translatableStringHelper = $translatableStringHelper;
+ $this->templating = $twigEngine;
+ }
+
+ public function buildForm(FormBuilderInterface $builder, CustomField $customField)
+ {
+ $options = $customField->getOptions();
+ $entries = $this->optionRepository->findFilteredByKey($options[self::KEY],
+ false, true);
+ //create a local copy of translatable string helper
+ $translatableStringHelper = $this->translatableStringHelper;
+ $builder->add($customField->getSlug(), 'select2_choice', array(
+ 'choices' => $entries,
+ 'choice_label' => function(Option $option) use ($translatableStringHelper) {
+ return $translatableStringHelper->localize($option->getText());
+ },
+ 'choice_value' => function ($key) use ($entries) {
+ if ($key === NULL) {
+ return null;
+ }
+ return $key->getId();
+ },
+ 'choices_as_values' => true,
+ 'multiple' => false,
+ 'expanded' => false,
+ 'group_by' => function(Option $option) use ($translatableStringHelper) {
+ if ($option->hasParent()) {
+ return $translatableStringHelper->localize($option->getParent()->getText());
+ } else {
+ return $translatableStringHelper->localize($option->getText());
+ }
+ },
+ 'label' => $translatableStringHelper->localize($customField->getName())
+ ));
+ $builder->get($customField->getSlug())
+ ->addModelTransformer(new CustomFieldDataTransformer($this, $customField));
+
+ }
+
+ public function buildOptionsForm(FormBuilderInterface $builder)
+ {
+ //create a selector between different keys
+ $keys = $this->optionRepository->getKeys();
+ $choices = array();
+ foreach ($keys as $key) {
+ $choices[$key] = $key;
+ }
+
+ return $builder->add(self::KEY, 'choice', array(
+ 'choices' => $choices,
+ 'label' => 'Options key'
+ ));
+
+ }
+
+ public function deserialize($serialized, \Chill\CustomFieldsBundle\Entity\CustomField $customField)
+ {
+ if ($serialized === NULL) {
+ return NULL;
+ }
+
+
+ return $this->optionRepository->find($serialized);
+ }
+
+ public function getName()
+ {
+ return 'Long Choice';
+ }
+
+ public function render($value, \Chill\CustomFieldsBundle\Entity\CustomField $customField, $documentType = 'html')
+ {
+ $option = $this->deserialize($value, $customField);
+ $template = 'ChillCustomFieldsBundle:CustomFieldsRendering:choice_long.'
+ .$documentType.'.twig';
+
+ return $this->templating
+ ->render($template, array(
+ 'values' => array($option)
+ ));
+ }
+
+ public function serialize($value, \Chill\CustomFieldsBundle\Entity\CustomField $customField)
+ {
+ if (!$value instanceof Option) {
+ throw new \LogicException('the value should be an instance of '
+ . 'Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option, '
+ . is_object($value) ? get_class($value) : gettype($value).' given');
+ }
+
+ // we place the id in array, to allow in the future multiple select
+ return $value->getId();
+ }
+
+}
diff --git a/DataFixtures/ORM/LoadOption.php b/DataFixtures/ORM/LoadOption.php
new file mode 100644
index 000000000..9dd9a5aaf
--- /dev/null
+++ b/DataFixtures/ORM/LoadOption.php
@@ -0,0 +1,172 @@
+
+ *
+ * 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\CustomFieldsBundle\DataFixtures\ORM;
+
+use Doctrine\Common\DataFixtures\AbstractFixture;
+use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
+use Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option;
+
+/**
+ * Load some Options
+ *
+ *
+ * @author Julien Fastré
+ */
+class LoadOption extends AbstractFixture implements OrderedFixtureInterface
+{
+ /**
+ *
+ * @var \Faker\Generator
+ */
+ public $fakerFr;
+
+ /**
+ *
+ * @var \Faker\Generator
+ */
+ public $fakerEn;
+
+ /**
+ *
+ * @var \Faker\Generator
+ */
+ public $fakerNl;
+
+ public function __construct()
+ {
+ $this->fakerFr = \Faker\Factory::create('fr_FR');
+ $this->fakerEn = \Faker\Factory::create('en_EN');
+ $this->fakerNl = \Faker\Factory::create('nl_NL');
+ }
+
+ public function getOrder()
+ {
+ return 1000;
+ }
+
+ public function load(\Doctrine\Common\Persistence\ObjectManager $manager)
+ {
+ echo "Loading Options \n";
+ // load companies
+ $this->loadingCompanies($manager);
+ $this->loadingWords($manager);
+
+
+ $manager->flush();
+
+ }
+
+ private function loadingWords(\Doctrine\Common\Persistence\ObjectManager $manager)
+ {
+ echo "Loading some words...\n";
+
+ $parents = array(
+ array(
+ 'fr' => 'Categorie 1',
+ 'nl' => 'Categorie 1',
+ 'en' => 'Category 1'
+ ),
+ array(
+ 'fr' => 'Categorie 2',
+ 'nl' => 'Categorie 2',
+ 'en' => 'Category 2'
+ )
+ );
+
+ foreach ($parents as $text) {
+ $parent = (new Option())
+ ->setText($text)
+ ->setKey('word')
+ ;
+ $manager->persist($parent);
+ //Load children
+ $expected_nb_children = rand(10, 50);
+ for ($i=0; $i < $expected_nb_children; $i++) {
+ $manager->persist($this->createChildOption($parent, array(
+ 'fr' => $this->fakerFr->word,
+ 'nl' => $this->fakerNl->word,
+ 'en' => $this->fakerEn->word
+ )));
+ }
+ }
+ }
+
+ private function loadingCompanies(\Doctrine\Common\Persistence\ObjectManager $manager)
+ {
+ echo "Loading companies \n";
+ $companiesParents = array(
+ array(
+ 'fr' => 'Grandes Entreprises',
+ 'nl' => 'Grotes Bedrijven',
+ 'en' => 'Big Companies'
+ ),
+ array(
+ 'fr' => 'Moyennes Entreprises',
+ 'nl' => 'Middelbare Bedrijven',
+ 'en' => 'Middle Companies'
+ ),
+ array(
+ 'fr' => 'Petites Entreprises',
+ 'nl' => 'Kleine Bedrijven',
+ 'en' => 'Little Companies'
+ )
+ );
+
+
+ foreach ($companiesParents as $text) {
+ $parent = (new Option())
+ ->setText($text)
+ ->setKey('company')
+ ;
+ $manager->persist($parent);
+ //Load children
+ $expected_nb_children = rand(10, 50);
+ for ($i=0; $i < $expected_nb_children; $i++) {
+ $companyName = $this->fakerFr->company;
+ $manager->persist($this->createChildOption($parent, array(
+ 'fr' => $companyName,
+ 'nl' => $companyName,
+ 'en' => $companyName
+ )));
+ }
+ }
+ }
+
+ private $counter = 0;
+
+ /**
+ *
+ * @param Option $parent
+ * @param array $text
+ * @return Option
+ */
+ private function createChildOption(Option $parent, array $text)
+ {
+ $this->counter ++;
+
+ return (new Option())
+ ->setText($text)
+ ->setParent($parent)
+ ->setActive(true)
+ ->setInternalKey($parent->getKey().'-'.$this->counter);
+ ;
+ }
+
+}
diff --git a/Entity/CustomFieldLongChoice/Option.php b/Entity/CustomFieldLongChoice/Option.php
new file mode 100644
index 000000000..9037ee117
--- /dev/null
+++ b/Entity/CustomFieldLongChoice/Option.php
@@ -0,0 +1,153 @@
+
+ *
+ * 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\CustomFieldsBundle\Entity\CustomFieldLongChoice;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+class Option
+{
+ /**
+ *
+ * @var int
+ */
+ private $id;
+
+ /**
+ *
+ * @var string
+ */
+ private $key;
+
+ /**
+ * a json representation of text (multilingual)
+ *
+ * @var array
+ */
+ private $text;
+
+ /**
+ *
+ * @var \Doctrine\Common\Collections\Collection
+ */
+ private $children;
+
+ /**
+ *
+ * @var Option
+ */
+ private $parent;
+
+ /**
+ *
+ * @var string
+ */
+ private $internalKey = '';
+
+ /**
+ *
+ * @var boolean
+ */
+ private $active = true;
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ public function getText()
+ {
+ return $this->text;
+ }
+
+ public function getChildren()
+ {
+ return $this->children;
+ }
+
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ public function setKey($key)
+ {
+ $this->key = $key;
+ return $this;
+ }
+
+ public function setText(array $text)
+ {
+ $this->text = $text;
+ return $this;
+ }
+
+ public function setParent(Option $parent = null)
+ {
+ $this->parent = $parent;
+ $this->key = $parent->getKey();
+ return $this;
+ }
+
+ /**
+ *
+ * @return boolean
+ */
+ public function hasParent()
+ {
+ return $this->parent === NULL ? false : true;
+ }
+
+ public function getInternalKey()
+ {
+ return $this->internalKey;
+ }
+
+ public function isActive()
+ {
+ return $this->active;
+ }
+
+ public function getActive()
+ {
+ return $this->isActive();
+ }
+
+ public function setInternalKey($internal_key)
+ {
+ $this->internalKey = $internal_key;
+ return $this;
+ }
+
+ public function setActive($active)
+ {
+ $this->active = $active;
+ return $this;
+ }
+
+
+}
diff --git a/EntityRepository/CustomFieldLongChoice/OptionRepository.php b/EntityRepository/CustomFieldLongChoice/OptionRepository.php
new file mode 100644
index 000000000..58f8ee302
--- /dev/null
+++ b/EntityRepository/CustomFieldLongChoice/OptionRepository.php
@@ -0,0 +1,77 @@
+
+ *
+ * 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\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice;
+
+use Doctrine\ORM\EntityRepository;
+use Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+class OptionRepository extends EntityRepository
+{
+ /**
+ *
+ * @param string $key
+ * @return Option[]
+ */
+ public function findFilteredByKey($key, $includeParents = true, $active = true)
+ {
+ $qb = $this->createQueryBuilder('option');
+ $qb->where('option.key = :key');
+
+ if ($active === true){
+ $qb->andWhere('option.active = true');
+ }
+
+ if ($includeParents === false) {
+ $qb->andWhere('option.parent IS NOT NULL');
+
+ if ($active === TRUE) {
+ $qb->join('option.parent', 'p');
+ $qb->andWhere('p.active = true');
+ }
+ }
+
+ $qb->setParameter('key', $key);
+
+ return $qb->getQuery()->getResult();
+ }
+
+ /**
+ *
+ * @return string[]
+ */
+ public function getKeys()
+ {
+ $keys = $this->createQueryBuilder('option')
+ ->select('option.key')
+ ->distinct()
+ ->getQuery()
+ ->getScalarResult();
+
+ return array_map(function($r) {
+ return $r['key'];
+ }, $keys);
+ }
+
+}
diff --git a/Resources/config/doctrine/CustomFieldLongChoice.Option.orm.yml b/Resources/config/doctrine/CustomFieldLongChoice.Option.orm.yml
new file mode 100644
index 000000000..3d0b8fbdc
--- /dev/null
+++ b/Resources/config/doctrine/CustomFieldLongChoice.Option.orm.yml
@@ -0,0 +1,33 @@
+Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option:
+ type: entity
+ table: custom_field_long_choice_options
+ repositoryClass: Chill\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice\OptionRepository
+ id:
+ id:
+ type: integer
+ id: true
+ generator:
+ strategy: AUTO
+ fields:
+ key:
+ type: string
+ length: 15
+ text:
+ type: json_array
+ internalKey:
+ type: string
+ length: 50
+ column: internal_key
+ active:
+ type: boolean
+ default: true
+ oneToMany:
+ children:
+ targetEntity: Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option
+ mappedBy: parent
+ manyToOne:
+ parent:
+ targetEntity: Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option
+ inversedBy: children
+ nullable: true
+
\ No newline at end of file
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index 4641910b2..e2c971c75 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -107,4 +107,20 @@ services:
calls:
- [setContainer, ["@service_container"]]
tags:
- - { name: twig.extension }
\ No newline at end of file
+ - { name: twig.extension }
+
+ chill.custom_field.custom_field_long_choice:
+ class: Chill\CustomFieldsBundle\CustomFields\CustomFieldLongChoice
+ arguments:
+ - "@chill.custom_field.custom_field_long_choice_option_repository"
+ - "@chill.main.helper.translatable_string"
+ - "@templating"
+ tags:
+ - { name: 'chill.custom_field', type: 'long_choice' }
+
+ chill.custom_field.custom_field_long_choice_option_repository:
+ class: Chill\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice\OptionRepository
+ factory: ["@doctrine", getRepository]
+ arguments:
+ - "Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option"
+
\ No newline at end of file
diff --git a/Resources/migrations/Version20151210205610.php b/Resources/migrations/Version20151210205610.php
new file mode 100644
index 000000000..01cb61728
--- /dev/null
+++ b/Resources/migrations/Version20151210205610.php
@@ -0,0 +1,47 @@
+abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('CREATE SEQUENCE custom_field_long_choice_options_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
+ $this->addSql('CREATE TABLE custom_field_long_choice_options (id INT NOT NULL, '
+ . 'parent_id INT DEFAULT NULL, '
+ . 'key VARCHAR(15) NOT NULL, '
+ . 'text jsonb NOT NULL, '
+ . 'active boolean NOT NULL,'
+ . 'internal_key VARCHAR(50) NOT NULL DEFAULT \'\', '
+ . 'PRIMARY KEY(id))');
+ $this->addSql('CREATE INDEX IDX_14BBB8E0727ACA70 ON custom_field_long_choice_options (parent_id)');
+ $this->addSql('ALTER TABLE custom_field_long_choice_options ADD CONSTRAINT cf_long_choice_self_referencing '
+ . 'FOREIGN KEY (parent_id) REFERENCES custom_field_long_choice_options (id) '
+ . 'NOT DEFERRABLE INITIALLY IMMEDIATE');
+
+ }
+
+ /**
+ * @param Schema $schema
+ */
+ public function down(Schema $schema)
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
+
+ $this->addSql('ALTER TABLE custom_field_long_choice_options DROP CONSTRAINT cf_long_choice_self_referencing');
+ $this->addSql('DROP SEQUENCE custom_field_long_choice_options_id_seq CASCADE');
+ $this->addSql('DROP TABLE custom_field_long_choice_options');
+ }
+}
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index 0c5965eb8..f77f08028 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -84,3 +84,6 @@ Greater or equal than: Plus grand ou égal à
Lesser or equal than: Plus petit ou égal à
Precision: Précision
Text after the field: Texte après le champ
+
+#custom field long choice
+Options key: Clé des options
diff --git a/Resources/views/CustomFieldsRendering/choice_long.html.twig b/Resources/views/CustomFieldsRendering/choice_long.html.twig
new file mode 100644
index 000000000..6849f1d0c
--- /dev/null
+++ b/Resources/views/CustomFieldsRendering/choice_long.html.twig
@@ -0,0 +1,11 @@
+{% if values|length > 0 %}
+
+ {%- for value in values -%}
+
+ {{ value.text|localize_translatable_string }}
+
+ {%- endfor -%}
+
+{% else %}
+
{{ 'None'|trans }}
+{% endif %}
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 68f716242..9c1240b5a 100644
--- a/composer.json
+++ b/composer.json
@@ -34,8 +34,9 @@
"chill-project/main": "dev-master"
},
"require-dev": {
- "doctrine/doctrine-fixtures-bundle": "~2.2@dev",
- "chill-project/person": "dev-master@dev"
+ "chill-project/person": "dev-master@dev",
+ "fzaninotto/faker": "~1",
+ "doctrine/doctrine-fixtures-bundle": "~2.2"
},
"scripts": {
"post-install-cmd": [
From 9ca2be78eb7e27df4643b41333d6380c4b7e3887 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 15 Dec 2015 10:06:05 +0100
Subject: [PATCH 44/54] use localize translatable string function to render
label widget
---
Resources/views/CustomField/render_label.html.twig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resources/views/CustomField/render_label.html.twig b/Resources/views/CustomField/render_label.html.twig
index bf4b186fc..05bc19cc3 100644
--- a/Resources/views/CustomField/render_label.html.twig
+++ b/Resources/views/CustomField/render_label.html.twig
@@ -1 +1 @@
-{{ customField.name(app.request.locale) }}
\ No newline at end of file
+{{ customField.name|localize_translatable_string }}
\ No newline at end of file
From fe73a64e9d19d5bab09164331ed61cbc5c53a51c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Tue, 15 Dec 2015 11:11:36 +0100
Subject: [PATCH 45/54] Add possibility to hide empty value in customfield
group view rendering
A new parameter is defined :
```
chill_custom_fields:
show_empty_values_in_views = true|false
```
A new method is added to CustomFieldInterface: `isEmptyValue`. To ease
the dev of new classes, an AbstractCustomField class is created, which
implements the most commons function (currently, only isEmptyValue).
A new Twig Filter is added: `chill_custom_field_is_empty`
The twig filter `chill_custom_fields_group_widget` has a new possibility
in array option : `show_empty`. Default to
chill_custom_fields.show_empty_values_in_view. May be forced by
true/false.
---
CustomFields/AbstractCustomField.php | 37 ++++++++++++++++++
CustomFields/CustomFieldChoice.php | 7 +++-
CustomFields/CustomFieldInterface.php | 8 ++++
CustomFields/CustomFieldLongChoice.php | 2 +-
CustomFields/CustomFieldNumber.php | 2 +-
CustomFields/CustomFieldText.php | 2 +-
CustomFields/CustomFieldTitle.php | 7 +++-
.../ChillCustomFieldsExtension.php | 2 +
DependencyInjection/Configuration.php | 38 +++++++++++--------
Resources/config/services.yml | 2 +
.../views/CustomFieldsGroup/render.html.twig | 4 +-
Service/CustomFieldsHelper.php | 18 +++++++--
Templating/Twig/CustomFieldRenderingTwig.php | 11 ++++++
.../Twig/CustomFieldsGroupRenderingTwig.php | 18 +++++++--
14 files changed, 131 insertions(+), 27 deletions(-)
create mode 100644 CustomFields/AbstractCustomField.php
diff --git a/CustomFields/AbstractCustomField.php b/CustomFields/AbstractCustomField.php
new file mode 100644
index 000000000..ddd019176
--- /dev/null
+++ b/CustomFields/AbstractCustomField.php
@@ -0,0 +1,37 @@
+
+ *
+ * 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\CustomFieldsBundle\CustomFields;
+
+use Chill\CustomFieldsBundle\CustomFields\CustomFieldInterface;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+abstract class AbstractCustomField implements CustomFieldInterface
+{
+ public function isEmptyValue($value, CustomField $customField)
+ {
+ return (empty($value) and $value !== FALSE);
+ }
+
+}
diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php
index 6f23b6339..8b0d0f647 100644
--- a/CustomFields/CustomFieldChoice.php
+++ b/CustomFields/CustomFieldChoice.php
@@ -38,7 +38,7 @@ use Symfony\Component\Translation\Translator;
* @author Julien Fastré
* @author Marc Ducobu
*/
-class CustomFieldChoice implements CustomFieldInterface
+class CustomFieldChoice extends AbstractCustomField
{
const ALLOW_OTHER = 'other';
const OTHER_VALUE_LABEL = 'otherValueLabel';
@@ -174,6 +174,11 @@ class CustomFieldChoice implements CustomFieldInterface
{
return 'Choices';
}
+
+ public function isEmptyValue($value, CustomField $customField)
+ {
+ return $value['_choices'] === NULL;
+ }
/**
*
diff --git a/CustomFields/CustomFieldInterface.php b/CustomFields/CustomFieldInterface.php
index 994172e41..ce341142d 100644
--- a/CustomFields/CustomFieldInterface.php
+++ b/CustomFields/CustomFieldInterface.php
@@ -58,4 +58,12 @@ interface CustomFieldInterface
* @return \Symfony\Component\Form\FormTypeInterface|null the form type
*/
public function buildOptionsForm(FormBuilderInterface $builder);
+
+ /**
+ * Return if the value can be considered as empty
+ *
+ * @param mixed $value the value passed throug the deserialize function
+ * @param CustomField $customField
+ */
+ public function isEmptyValue($value, CustomField $customField);
}
diff --git a/CustomFields/CustomFieldLongChoice.php b/CustomFields/CustomFieldLongChoice.php
index a66de9dc2..58285d132 100644
--- a/CustomFields/CustomFieldLongChoice.php
+++ b/CustomFields/CustomFieldLongChoice.php
@@ -33,7 +33,7 @@ use Symfony\Bridge\Twig\TwigEngine;
*
* @author Julien Fastré
*/
-class CustomFieldLongChoice implements CustomFieldInterface
+class CustomFieldLongChoice extends AbstractCustomField
{
/**
*
diff --git a/CustomFields/CustomFieldNumber.php b/CustomFields/CustomFieldNumber.php
index d880f8a17..b87dfe685 100644
--- a/CustomFields/CustomFieldNumber.php
+++ b/CustomFields/CustomFieldNumber.php
@@ -39,7 +39,7 @@ use Chill\MainBundle\Templating\TranslatableStringHelper;
* @author Julien Fastré
* @author Marc Ducobu
*/
-class CustomFieldNumber implements CustomFieldInterface
+class CustomFieldNumber extends AbstractCustomField
{
/**
* key for the minimal value of the field
diff --git a/CustomFields/CustomFieldText.php b/CustomFields/CustomFieldText.php
index a11705707..c2189bb88 100644
--- a/CustomFields/CustomFieldText.php
+++ b/CustomFields/CustomFieldText.php
@@ -33,7 +33,7 @@ use Chill\MainBundle\Templating\TranslatableStringHelper;
* @author Julien Fastré
* @author Marc Ducobu
*/
-class CustomFieldText implements CustomFieldInterface
+class CustomFieldText extends AbstractCustomField
{
private $requestStack;
diff --git a/CustomFields/CustomFieldTitle.php b/CustomFields/CustomFieldTitle.php
index 6c15543eb..23f9f5e2b 100644
--- a/CustomFields/CustomFieldTitle.php
+++ b/CustomFields/CustomFieldTitle.php
@@ -28,7 +28,7 @@ use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Bundle\TwigBundle\TwigEngine;
use Chill\MainBundle\Templating\TranslatableStringHelper;
-class CustomFieldTitle implements CustomFieldInterface
+class CustomFieldTitle extends AbstractCustomField
{
const TYPE = 'type';
const TYPE_TITLE = 'title';
@@ -92,6 +92,11 @@ class CustomFieldTitle implements CustomFieldInterface
{
return 'title';
}
+
+ public function isEmptyValue($value, CustomField $customField)
+ {
+ return false;
+ }
public function buildOptionsForm(FormBuilderInterface $builder)
{
diff --git a/DependencyInjection/ChillCustomFieldsExtension.php b/DependencyInjection/ChillCustomFieldsExtension.php
index 3aaab5933..05c4108e4 100644
--- a/DependencyInjection/ChillCustomFieldsExtension.php
+++ b/DependencyInjection/ChillCustomFieldsExtension.php
@@ -33,6 +33,8 @@ class ChillCustomFieldsExtension extends Extension implements PrependExtensionIn
$container->setParameter('chill_custom_fields.customizables_entities',
$config['customizables_entities']);
+ $container->setParameter('chill_custom_fields.show_empty_values',
+ $config['show_empty_values_in_views']);
}
/* (non-PHPdoc)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 232a1a9a2..84c2147bb 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -35,27 +35,35 @@ class Configuration implements ConfigurationInterface
->defaultValue(array())
->prototype('array')
->children()
- ->scalarNode('class')->isRequired()->info($classInfo)->end()
- ->scalarNode('name') ->isRequired()->info($nameInfo) ->end()
+ ->scalarNode('class')->isRequired()->info($classInfo)
+ ->end()
+ ->scalarNode('name') ->isRequired()->info($nameInfo)
+ ->end()
->arrayNode('options')
- ->info($optionsInfo)
- ->defaultValue(array())
- ->useAttributeAsKey('key')
- ->prototype('array')
- ->children()
- ->scalarNode('form_type')
- ->isRequired()
- ->info($optionsFormType)
- ->end()
- ->variableNode('form_options')
- ->info($optionsFormOptionsInfos)
- ->defaultValue(array())
- ->end()
+ ->info($optionsInfo)
+ ->defaultValue(array())
+ ->useAttributeAsKey('key')
+ ->prototype('array')
+ ->children()
+ ->scalarNode('form_type')
+ ->isRequired()
+ ->info($optionsFormType)
->end()
+ ->variableNode('form_options')
+ ->info($optionsFormOptionsInfos)
+ ->defaultValue(array())
+ ->end()
+ ->end()
->end()
->end()
->end()
->end()
+ ->end()
+ ->booleanNode('show_empty_values_in_views')
+ ->info('Show the empty value for custom fields in the views, timeline, ...')
+ ->defaultValue(true)
+ ->end()
+ ->end()
;
return $treeBuilder;
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index e2c971c75..1e03b8bf2 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -106,6 +106,8 @@ services:
class: Chill\CustomFieldsBundle\Templating\Twig\CustomFieldsGroupRenderingTwig
calls:
- [setContainer, ["@service_container"]]
+ arguments:
+ - "%chill_custom_fields.show_empty_values%"
tags:
- { name: twig.extension }
diff --git a/Resources/views/CustomFieldsGroup/render.html.twig b/Resources/views/CustomFieldsGroup/render.html.twig
index a63183233..e325432a0 100644
--- a/Resources/views/CustomFieldsGroup/render.html.twig
+++ b/Resources/views/CustomFieldsGroup/render.html.twig
@@ -2,7 +2,9 @@
{% if customField.type == 'title' %}
{{ chill_custom_field_widget(cFData , customField) }}
{% else %}
+ {%- if show_empty == true or (chill_custom_field_is_empty(customField, cFData) == false) -%}
- {% endif %}
+ {%- endif -%}
+ {%- endif -%}
{% endfor %}
\ No newline at end of file
diff --git a/Service/CustomFieldsHelper.php b/Service/CustomFieldsHelper.php
index 477c190ad..07c8c4f04 100644
--- a/Service/CustomFieldsHelper.php
+++ b/Service/CustomFieldsHelper.php
@@ -137,6 +137,17 @@ class CustomFieldsHelper
: null;
}
+ public function isEmptyValue(array $fields, $classOrCustomField, $slug = null)
+ {
+ $customField = ($classOrCustomField instanceof CustomField) ? $classOrCustomField : $this->getCustomField($classOrCustomField, $slug);
+ $slug = $customField->getSlug();
+ $rawValue = (isset($fields[$slug])) ? $fields[$slug] : null;
+
+ $customFieldType = $this->provider->getCustomFieldByType($customField->getType());
+
+ return $customFieldType->isEmptyValue($rawValue, $customField);
+ }
+
/**
* Render the value of a custom field
*
@@ -144,16 +155,17 @@ class CustomFieldsHelper
* @param CustomField|object|string $classOrCustomField the object OR the get_class($object) string OR The CustomField
* @param string $documentType The type of document in which the rendered value is displayed ('html' or 'csv').
* @param string $slug The slug of the custom field to render.
+ * @param boolean $showIfEmpty If the widget must be rendered if the value is empty. An empty value is all values described as http://php.net/manual/fr/function.empty.php, except `FALSE`
* @throws CustomFieldsHelperException if slug is missing
* @return The representation of the value the customField.
*/
- public function renderCustomField(array $fields, $classOrCustomField, $documentType='html', $slug = null)
+ public function renderCustomField(array $fields, $classOrCustomField, $documentType='html', $slug = null, $showIfEmpty = true)
{
$customField = ($classOrCustomField instanceof CustomField) ? $classOrCustomField : $this->getCustomField($classOrCustomField, $slug);
$slug = $customField->getSlug();
$rawValue = (isset($fields[$slug])) ? $fields[$slug] : null;
+ $customFieldType = $this->provider->getCustomFieldByType($customField->getType());
- return $this->provider->getCustomFieldByType($customField->getType())
- ->render($rawValue, $customField, $documentType);
+ return $customFieldType->render($rawValue, $customField, $documentType);
}
}
\ No newline at end of file
diff --git a/Templating/Twig/CustomFieldRenderingTwig.php b/Templating/Twig/CustomFieldRenderingTwig.php
index be155abe3..8561d26f8 100644
--- a/Templating/Twig/CustomFieldRenderingTwig.php
+++ b/Templating/Twig/CustomFieldRenderingTwig.php
@@ -76,10 +76,21 @@ class CustomFieldRenderingTwig extends \Twig_Extension implements ContainerAware
'is_safe' => array(
'html'
)
+ )),
+ new \Twig_SimpleFunction('chill_custom_field_is_empty', array(
+ $this,
+ 'isEmptyValue'
))
];
}
+
+ public function isEmptyValue($customFieldorClass, $fields, $slug = null)
+ {
+ return $this->container->get('chill.custom_field.helper')
+ ->isEmptyValue($fields, $customFieldorClass);
+ }
+
/* (non-PHPdoc)
* @see Twig_ExtensionInterface::getName()
*/
diff --git a/Templating/Twig/CustomFieldsGroupRenderingTwig.php b/Templating/Twig/CustomFieldsGroupRenderingTwig.php
index af6dbb585..a6b9305c0 100644
--- a/Templating/Twig/CustomFieldsGroupRenderingTwig.php
+++ b/Templating/Twig/CustomFieldsGroupRenderingTwig.php
@@ -37,15 +37,25 @@ use Chill\CustomFieldsBundle\Entity\CustomField;
*/
class CustomFieldsGroupRenderingTwig extends \Twig_Extension implements ContainerAwareInterface
{
-
+
/** @var Container $container The container */
private $container;
/** @var array $defaultParams The default parameters */
private $defaultParams = array(
- 'layout' => 'ChillCustomFieldsBundle:CustomFieldsGroup:render.html.twig'
+ 'layout' => 'ChillCustomFieldsBundle:CustomFieldsGroup:render.html.twig',
+ 'show_empty' => True
);
+ /**
+ *
+ * @param boolean $showEmptyValues whether the empty values must be rendered
+ */
+ public function __construct($showEmptyValues)
+ {
+ $this->defaultParams['show_empty'] = $showEmptyValues;
+ }
+
/*
* (non-PHPdoc)
* @see \Symfony\Component\DependencyInjection\ContainerAwareInterface::setContainer()
@@ -92,6 +102,7 @@ class CustomFieldsGroupRenderingTwig extends \Twig_Extension implements Containe
* @param array $params The parameters for rendering :
* - layout : allow to choose a different layout by default :
* ChillCustomFieldsBundle:CustomFieldsGroup:render.html.twig
+ * - show_empty : force show empty field
* @return string HTML representation of the custom field group value, as described in
* the CustomFieldInterface. Is HTML safe
*/
@@ -102,6 +113,7 @@ class CustomFieldsGroupRenderingTwig extends \Twig_Extension implements Containe
return $this->container->get('templating')
->render($resolvedParams['layout'], array(
'cFGroup' => $customFielsGroup,
- 'cFData' => $fields));
+ 'cFData' => $fields,
+ 'show_empty' => $resolvedParams['show_empty']));
}
}
\ No newline at end of file
From 0a1898e9a78882a29ce7d4b9a5fa60bc0609252c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 16 Dec 2015 20:25:40 +0100
Subject: [PATCH 46/54] take into account the different type of choices in
empty value
---
CustomFields/CustomFieldChoice.php | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php
index 8b0d0f647..a34968db3 100644
--- a/CustomFields/CustomFieldChoice.php
+++ b/CustomFields/CustomFieldChoice.php
@@ -177,7 +177,35 @@ class CustomFieldChoice extends AbstractCustomField
public function isEmptyValue($value, CustomField $customField)
{
- return $value['_choices'] === NULL;
+ if ($value === NULL) {
+ return true;
+ }
+
+ // if only one choice...
+ if (is_string($value)) {
+ return empty($value);
+ }
+
+ // if multiple choice OR multiple/single choice with other
+ if (is_array($value))
+ {
+ // if allow other
+ if (isset($value['_choices'])) {
+ if ($value['_choices'] === NULL) {
+ return true;
+ }
+ if (is_string($value['_choices'])) {
+ return empty($value);
+ }
+ if (is_array($value['_choices'])){
+ return count($value['_choices']) > 0;
+ }
+ } else { // we do not have 'allow other'
+ return count($value) > .0;
+ }
+ }
+
+ throw \LogicException("This case is not expected.");
}
/**
From 9c622bc852664c2f039d50e85d28f9068d2ffb24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Thu, 17 Dec 2015 07:41:16 +0100
Subject: [PATCH 47/54] improve cfgroup rendering to show title only if
necessary
If the value `chill_custom_fields.show_empty_values_in_views` is false,
the title is shown only if a field has been filled "below" the title.
---
Resources/translations/messages.fr.yml | 4 ++
.../views/CustomFieldsGroup/render.html.twig | 39 +++++++++++++++++--
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml
index f77f08028..bf29b6e7b 100644
--- a/Resources/translations/messages.fr.yml
+++ b/Resources/translations/messages.fr.yml
@@ -2,6 +2,10 @@
'Other value': 'Autre valeur'
'None': 'Pas spécifié'
+#customfieldsgroup rendering
+Empty data: Données vides
+No data to show: Pas de valeurs à afficher
+
#customfieldsgroup administration
CustomFieldsGroup list: Groupes de champs personnalisés
CustomFieldsGroup creation: Nouveau groupe de champs personnalisés
diff --git a/Resources/views/CustomFieldsGroup/render.html.twig b/Resources/views/CustomFieldsGroup/render.html.twig
index e325432a0..fb293cf92 100644
--- a/Resources/views/CustomFieldsGroup/render.html.twig
+++ b/Resources/views/CustomFieldsGroup/render.html.twig
@@ -1,10 +1,43 @@
+{#- a customField element will be stored in title variable -#}
+{%- set title = null -%}
+{#- a customField element will be stored in subtitle variable -#}
+{%- set subtitle = null -%}
+{%- set type = constant('Chill\\CustomFieldsBundle\\CustomFields\\CustomFieldTitle::TYPE') -%}
+{%- set type_subtitle = constant('Chill\\CustomFieldsBundle\\CustomFields\\CustomFieldTitle::TYPE_SUBTITLE') -%}
+{%- set type_title = constant('Chill\\CustomFieldsBundle\\CustomFields\\CustomFieldTitle::TYPE_TITLE') -%}
+{# a variable to store that "something has been printed #}
+{%- set something_has_been_printed = false -%}
{% for customField in cFGroup.activeCustomFields %}
{% if customField.type == 'title' %}
+ {%- if show_empty == true %}
{{ chill_custom_field_widget(cFData , customField) }}
+ {%- else -%}
+ {# we keep the customfield in memory, and print it only if 'something' has been filled after the title #}
+ {%- if customField.options[type] == type_title -%}
+ {%- set title = customField -%}
+ {# we have to reset the title hierarchy if we misused titles hierarchy #}
+ {%- set subtitle = null -%}
+ {%- elseif customField.options[type] == type_subtitle -%}
+ {%- set subtitle = customField -%}
+ {%- endif -%}
+ {%- endif -%}
{% else %}
{%- if show_empty == true or (chill_custom_field_is_empty(customField, cFData) == false) -%}
-
+ {%- if title is not empty -%}
+ {{ chill_custom_field_widget(cFData, title) }}
+ {%- set title = null -%}
+ {%- endif -%}
+ {%- if subtitle is not empty -%}
+ {{ chill_custom_field_widget(cFData, subtitle) }}
+ {%- set subtitle = null -%}
+ {%- endif -%}
+
From 24f9db6ae74cf66be9b0e5bee373ccb836fe2eb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Thu, 17 Dec 2015 23:50:24 +0100
Subject: [PATCH 51/54] fix bug in changing custom field option
bug description :
> if you change the options of a custom field choice (i.e. from a
> multiple to a single, removing or adding allow_other), the data
> representation change and do not match with the expected
> representation of the form.
This commit fix this bug by switching the data representation to the
current options.
---
CustomFields/CustomFieldChoice.php | 88 +++++
Tests/CustomFields/CustomFieldsChoiceTest.php | 365 ++++++++++++++++++
2 files changed, 453 insertions(+)
create mode 100644 Tests/CustomFields/CustomFieldsChoiceTest.php
diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php
index a34968db3..bc8c89d78 100644
--- a/CustomFields/CustomFieldChoice.php
+++ b/CustomFields/CustomFieldChoice.php
@@ -167,8 +167,96 @@ class CustomFieldChoice extends AbstractCustomField
public function deserialize($serialized, CustomField $customField)
{
+ // we always have to adapt to what the current data should be
+ $options = $customField->getOptions();
+
+ if ($options[self::MULTIPLE]) {
+ return $this->deserializeToMultiple($serialized, $options[self::ALLOW_OTHER]);
+ } else {
+ return $this->deserializeToUnique($serialized, $options[self::ALLOW_OTHER]);
+ }
return $serialized;
}
+
+ private function deserializeToUnique($serialized, $allowOther)
+ {
+ $value = $this->guessValue($serialized);
+
+ // set in a single value. We must have a single string
+ $fixedValue = is_array($value) ?
+ // check if the array has an element, if not replace by empty string
+ count($value) > 0 ? end($value) : ''
+ :
+ $value;
+
+ if ($allowOther) {
+ return $this->deserializeWithAllowOther($serialized, $fixedValue);
+ } else {
+ return $fixedValue;
+ }
+ }
+
+ /**
+ * deserialized the data from the database to a multiple
+ * field
+ *
+ * @param mixed $serialized
+ * @param boolean $allowOther
+ */
+ private function deserializeToMultiple($serialized, $allowOther)
+ {
+ $value = $this->guessValue($serialized);
+
+ // set in an array : we want a multiple
+ $fixedValue = is_array($value) ? $value : array($value);
+
+ if ($allowOther) {
+ return $this->deserializeWithAllowOther($serialized, $fixedValue);
+ } else {
+ return $fixedValue;
+ }
+ }
+
+ private function deserializeWithAllowOther($serialized, $value)
+ {
+ $existingOther = isset($serialized['_other']) ? $serialized['_other'] : '';
+
+ return array(
+ '_other' => $existingOther,
+ '_choices' => $value
+ );
+ }
+
+ /**
+ * Guess the value from the representation of it.
+ *
+ * If the value had an 'allow_other' = true option, the returned value
+ * **is not** the content of the _other field, but the `_other` string.
+ *
+ * @param array|string $value
+ * @return mixed
+ * @throws \LogicException if the case is not covered by this
+ */
+ private function guessValue($value)
+ {
+ if ($value === NULL) {
+ return NULL;
+ }
+
+ if (!is_array($value)) {
+ return $value;
+ } else {
+ // we have a field with "allow other"
+ if (isset($value['_choices'])) {
+ return $value['_choices'];
+ } else {
+ // we have a field with "multiple"
+ return $value;
+ }
+ }
+
+ throw \LogicException("This case is not expected.");
+ }
public function getName()
{
diff --git a/Tests/CustomFields/CustomFieldsChoiceTest.php b/Tests/CustomFields/CustomFieldsChoiceTest.php
new file mode 100644
index 000000000..f01a283ee
--- /dev/null
+++ b/Tests/CustomFields/CustomFieldsChoiceTest.php
@@ -0,0 +1,365 @@
+
+ *
+ * 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\CustomFieldsBundle\Tests;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+use Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice;
+
+/**
+ * This class cover the test of CustomFieldChoice.
+ *
+ * Function currently covered:
+ *
+ * - deserialize
+ *
+ * @author Julien Fastré
+ */
+class CustomFieldsChoiceTest extends KernelTestCase
+{
+
+ /**
+ *
+ * @var \Chill\CustomFieldsBundle\Service\CustomFieldProvider
+ */
+ private $cfProvider;
+
+ /**
+ *
+ * @var \Chill\CustomFieldsBundle\CustomFields\CustomFieldChoice
+ */
+ private $cfChoice;
+
+ public function setUp()
+ {
+ static::bootKernel();
+
+ $this->cfProvider = static::$kernel->getContainer()
+ ->get('chill.custom_field.provider');
+ $this->cfChoice = $this->cfProvider->getCustomFieldByType('choice');
+ }
+
+ public function tearDown()
+ {
+ parent::tearDown();
+ }
+
+ /**
+ *
+ * @param array $options
+ * @return CustomField
+ */
+ private function generateCustomField($options)
+ {
+ return (new CustomField())
+ ->setActive(true)
+ ->setSlug('slug')
+ ->setOptions($options)
+ ->setType('choice')
+ ;
+ }
+
+ /////////////////////////////////////////
+ //
+ // test function deserialize
+ //
+ ////////////////////////////////////////
+
+ /**
+ * Test if the representation of the data is deserialized to a single text.
+ *
+ * If the value is in _other, the _other value should not be returned.
+ *
+ * @param type $data
+ * @dataProvider serializedRepresentationDataProvider
+ */
+ public function testDeserializeSingleChoiceWithoutOther($data)
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => false,
+ CustomFieldChoice::MULTIPLE => false
+ ));
+
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame('my-value', $deserialized);
+ }
+
+
+ public function testDeserializeSingleChoiceWithoutOtherDataIsNull()
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => false,
+ CustomFieldChoice::MULTIPLE => false
+ ));
+
+ $deserialized = $this->cfChoice->deserialize(null, $customField);
+
+ $this->assertSame(null, $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize('', $customField);
+
+ $this->assertSame('', $deserialized);
+ }
+
+ /**
+ * Test if the representation of the data is deserialized to a single text
+ * with an "allow_other" field.
+ *
+ * If the value is in _other, the _other value should be in the _other field.
+ *
+ * @param type $data
+ * @dataProvider serializedRepresentationDataProvider
+ */
+ public function testDeserializeSingleChoiceWithOther($data)
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => true,
+ CustomFieldChoice::MULTIPLE => false
+ ));
+
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => '', '_choices' => 'my-value'), $deserialized);
+ }
+
+ /**
+ * Other cases :
+ *
+ * - Test if the selected value is '_other
+ * - Test with null data
+ *
+ * @param type $data
+ */
+ public function testDeserializeSingleChoiceWithOtherOtherCases()
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => true,
+ CustomFieldChoice::MULTIPLE => false
+ ));
+
+ // from a single to a single
+ $data = array('_other' => 'something', '_choices' => '_other');
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => '_other'), $deserialized);
+
+
+ // from a multiple to a single
+ $data = array('_other' => 'something', '_choices' => array('some', '_other'));
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => '_other'), $deserialized);
+
+ //test with null data
+ //from a single to a single :
+ $data = array('_other' => 'something', '_choices' => null);
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => null), $deserialized);
+
+ $data = array('_other' => 'something', '_choices' => '');
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => ''), $deserialized);
+
+ // from a multiple to a signle
+ $data = array('_other' => 'something', '_choices' => array());
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => ''), $deserialized);
+
+ $data = array('_other' => 'something', '_choices' => array(''));
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => ''), $deserialized);
+
+ }
+
+ /**
+ * Test if the representation of the data is deserialized to an array text
+ * with an "allow_other" field.
+ *
+ * This test does not covers the case when the selected value is `_other`
+ *
+ * @param type $data
+ * @dataProvider serializedRepresentationDataProvider
+ */
+ public function testDeserializeMultipleChoiceWithOther($data)
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => true,
+ CustomFieldChoice::MULTIPLE => true
+ ));
+
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => '', '_choices' => array('my-value')),
+ $deserialized);
+ }
+
+ /**
+ * Test if the representation of the data is deserialized to an array text
+ * with an "allow_other" field.
+ *
+ * This test covers :
+ * - the case when the selected value is `_other`
+ * - result is null
+ *
+ * @param type $data
+ */
+ public function testDeserializeMultipleChoiceWithOtherOtherCases()
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => true,
+ CustomFieldChoice::MULTIPLE => true
+ ));
+
+ // selected value is _other
+ // from single to multiple
+ $data = array('_other' => 'something', '_choices' => '_other');
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => array('_other')),
+ $deserialized);
+
+ // from multiple to multiple
+ $data = array('_other' => 'something', '_choices' => array('_other', 'something'));
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => 'something', '_choices' => array('_other', 'something')),
+ $deserialized);
+
+ // test with null value
+ // from single to multiple
+ $data = array('_other' => '', '_choices' => '');
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => '', '_choices' => array('')),
+ $deserialized);
+
+ // from multiple to multiple
+ $data = array('_other' => '', '_choices' => array());
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('_other' => '', '_choices' => array()),
+ $deserialized);
+ }
+
+ /**
+ * Test if the representation of the data is deserialized to an array text
+ * **without** an "allow_other" field.
+ *
+ *
+ * @param type $data
+ * @dataProvider serializedRepresentationDataProvider
+ */
+ public function testDeserializeMultipleChoiceWithoutOther($data)
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => false,
+ CustomFieldChoice::MULTIPLE => true
+ ));
+
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('my-value'), $deserialized);
+ }
+
+ /**
+ * Test if the representation of the data is deserialized to an array text
+ * **without** an "allow_other" field.
+ *
+ * Covered cases :
+ * - NULL values
+ *
+ *
+ * @param type $data
+ */
+ public function testDeserializeMultipleChoiceWithoutOtherOtherCases()
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => false,
+ CustomFieldChoice::MULTIPLE => true
+ ));
+
+ // from single to multiple
+ $data = 'my-value';
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('my-value'), $deserialized);
+
+ // from multiple to multiple
+ $data = array('my-value');
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+
+ $this->assertSame(array('my-value'), $deserialized);
+ }
+
+ public function serializedRepresentationDataProvider()
+ {
+ return array(
+ array(
+ // multiple => false, allow_other => false
+ 'my-value'
+ ),
+ array(
+ // multiple => true, allow_ther => false
+ array('my-value')
+ ),
+ array(
+ // multiple => false, allow_other => true, current value not in other
+ array('_other' => '', '_choices' => 'my-value')
+ ),
+ array(
+ // multiple => true, allow_other => true, current value not in other
+ array('_other' => '', '_choices'=> array('my-value'))
+ ),
+ );
+ }
+
+
+
+ /////////////////////////////////////////
+ //
+ // test function isEmptyValue
+ //
+ ////////////////////////////////////////
+
+ /**
+ *
+ * @param mixed $data
+ * @dataProvider serializedRepresentationDataProvider
+ */
+ public function testIsEmptyValueNotEmpty($data)
+ {
+ $this->markTestSkipped("We have to improve the isEmptyFunction");
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => false,
+ CustomFieldChoice::MULTIPLE => true
+ ));
+
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+ $isEmpty = $this->cfChoice->isEmptyValue($deserialized, $customField);
+
+ $this->assertFalse($isEmpty);
+ }
+
+}
From 573697d8c7d3eb09bb4fe39f7cde2fe5ef5efac0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Fri, 18 Dec 2015 00:22:09 +0100
Subject: [PATCH 52/54] improve function isEmptyValue + tests
---
CustomFields/CustomFieldChoice.php | 18 ++---
Tests/CustomFields/CustomFieldsChoiceTest.php | 65 +++++++++++++++++--
2 files changed, 66 insertions(+), 17 deletions(-)
diff --git a/CustomFields/CustomFieldChoice.php b/CustomFields/CustomFieldChoice.php
index bc8c89d78..782f5ab17 100644
--- a/CustomFields/CustomFieldChoice.php
+++ b/CustomFields/CustomFieldChoice.php
@@ -269,11 +269,6 @@ class CustomFieldChoice extends AbstractCustomField
return true;
}
- // if only one choice...
- if (is_string($value)) {
- return empty($value);
- }
-
// if multiple choice OR multiple/single choice with other
if (is_array($value))
{
@@ -282,17 +277,14 @@ class CustomFieldChoice extends AbstractCustomField
if ($value['_choices'] === NULL) {
return true;
}
- if (is_string($value['_choices'])) {
- return empty($value);
- }
- if (is_array($value['_choices'])){
- return count($value['_choices']) > 0;
- }
+ return empty($value['_choices']);
} else { // we do not have 'allow other'
- return count($value) > .0;
+ return empty($value);
}
+ } else {
+ return empty($value);
}
-
+
throw \LogicException("This case is not expected.");
}
diff --git a/Tests/CustomFields/CustomFieldsChoiceTest.php b/Tests/CustomFields/CustomFieldsChoiceTest.php
index f01a283ee..6fbc0b67e 100644
--- a/Tests/CustomFields/CustomFieldsChoiceTest.php
+++ b/Tests/CustomFields/CustomFieldsChoiceTest.php
@@ -344,22 +344,79 @@ class CustomFieldsChoiceTest extends KernelTestCase
////////////////////////////////////////
/**
+ * test the not empty with the not-empty data provider
*
* @param mixed $data
* @dataProvider serializedRepresentationDataProvider
*/
public function testIsEmptyValueNotEmpty($data)
{
- $this->markTestSkipped("We have to improve the isEmptyFunction");
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => false,
+ CustomFieldChoice::MULTIPLE => true
+ ));
+
+ $isEmpty = $this->cfChoice->isEmptyValue($data, $customField);
+
+ $this->assertFalse($isEmpty);
+ }
+
+ /**
+ *
+ * @dataProvider emptyDataProvider
+ * @param mixed $data
+ */
+ public function testIsEmptyValueEmpty($data)
+ {
$customField = $this->generateCustomField(array(
CustomFieldChoice::ALLOW_OTHER => false,
CustomFieldChoice::MULTIPLE => true
));
- $deserialized = $this->cfChoice->deserialize($data, $customField);
- $isEmpty = $this->cfChoice->isEmptyValue($deserialized, $customField);
+ $isEmpty = $this->cfChoice->isEmptyValue($data, $customField);
- $this->assertFalse($isEmpty);
+ $this->assertTrue($isEmpty);
+ }
+
+ /**
+ * provide empty data in different possible reprsentation
+ *
+ * @return array
+ */
+ public function emptyDataProvider()
+ {
+ return array(
+ // 0
+ array(
+ // signle
+ ''
+ ),
+ // 1
+ array(
+ // single
+ null
+ ),
+ // 2
+ array(
+ // signle with allow other
+ array('_other' => 'something', '_choices' => '')
+ ),
+ // 3
+ array(
+ // multiple
+ array()
+ ),
+ // 4
+ array(
+ // multiple with allow other
+ array('_other' => 'something', '_choices' => array())
+ ),
+ // 5
+ array(
+ // multiple with allow other
+ array('_other' => '', '_choices' => array())
+ ),
+ );
}
}
From 3e5a90c36c5719b010b2ebde585e7d58d06090b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 23 Dec 2015 23:46:15 +0100
Subject: [PATCH 53/54] escaping argument
---
Resources/config/services.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index 1e03b8bf2..9af084616 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -124,5 +124,5 @@ services:
class: Chill\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice\OptionRepository
factory: ["@doctrine", getRepository]
arguments:
- - "Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option"
+ - "Chill\\CustomFieldsBundle\\Entity\\CustomFieldLongChoice\\Option"
\ No newline at end of file
From 09a69765b98836bbfccfaf2695164fda55fa8b84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Julien=20Fastr=C3=A9?=
Date: Wed, 23 Dec 2015 23:46:44 +0100
Subject: [PATCH 54/54] adding test for customFieldRendering function
---
.../Twig/CustomFieldRenderingTwigTest.php | 105 ++++++++++++++++++
1 file changed, 105 insertions(+)
create mode 100644 Tests/Templating/Twig/CustomFieldRenderingTwigTest.php
diff --git a/Tests/Templating/Twig/CustomFieldRenderingTwigTest.php b/Tests/Templating/Twig/CustomFieldRenderingTwigTest.php
new file mode 100644
index 000000000..7f4923349
--- /dev/null
+++ b/Tests/Templating/Twig/CustomFieldRenderingTwigTest.php
@@ -0,0 +1,105 @@
+
+ *
+ * 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\CustomFields\Tests\Templating\Twig;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use Chill\CustomFieldsBundle\Templating\Twig\CustomFieldRenderingTwig;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
+
+/**
+ * Test the rendering of twig function which renders custom fields
+ *
+ * @author Julien Fastré
+ * @author Champs Libres
+ */
+class CustomFieldRenderingTwigTest extends KernelTestCase
+{
+ /**
+ *
+ * @var CustomFieldRenderingTwig
+ */
+ private $cfRendering;
+
+ /**
+ *
+ * @var CustomFieldProvider
+ */
+ private $cfProvider;
+
+ public function setUp()
+ {
+ self::bootKernel();
+ $this->cfRendering = self::$kernel->getContainer()
+ ->get('chill.custom_field.twig.custom_fields_rendering')
+ ;
+
+ $this->cfProvider = self::$kernel->getContainer()
+ ->get('chill.custom_field.provider');
+
+ // set locale to fr
+ $prophet = new \Prophecy\Prophet;
+ $request = $prophet->prophesize();
+ $request->willExtend('Symfony\Component\HttpFoundation\Request');
+ $request->getLocale()->willReturn('fr');
+ self::$kernel->getContainer()->get('request_stack')
+ ->push($request->reveal());
+ }
+
+ /**
+ *
+ * @return CustomField
+ */
+ private function getSimpleCustomFieldText()
+ {
+ return (new CustomField())
+ ->setSlug('test')
+ ->setName(array('fr' => 'Test'))
+ ->setType('text')
+ ->setOrdering(10)
+ ->setOptions(array("maxLength" => 255))
+ ->setActive(true)
+ ;
+ }
+
+ public function testLabelRendering()
+ {
+ $cf = $this->getSimpleCustomFieldText();
+
+ $text = $this->cfRendering->renderLabel($cf);
+
+ $this->assertContains('Test', $text,
+ "The rendering text should contains the 'test' text");
+ }
+
+ public function testWidgetRendering()
+ {
+ $cf = $this->getSimpleCustomFieldText();
+ $fields = array(
+ 'test' => "My tailor is rich"
+ );
+
+ $text = $this->cfRendering->renderWidget($fields, $cf);
+
+ $this->assertContains('My tailor is rich', $text,
+ "The rendering text should contains the 'test' text");
+ }
+}