+ {%- set title_div_opened = true -%}
+ {%- else -%}
+ {%- if subtitle_div_opened == true -%}
+
+ {%- set title_div_opened = false -%}
+ {%- endif -%}
+
+ {%- endif -%}
+ {%- else -%}
+ {%- if subtitle_div_opened == false -%}
+
+ {%- set subtitle_div_opened = true -%}
+ {%- else -%}
+
+ {%- endif -%}
+ {%- endif -%}
+ {{ 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(cFData, customField) == false) -%}
+ {%- if title is not empty -%}
+ {%- if title_div_opened == false -%}
+
+ {%- set title_div_opened = true -%}
+ {%- else -%}
+ {%- if subtitle_div_opened == true -%}
+
+ {%- set title_div_opened = false -%}
+ {%- endif -%}
+
+ {%- endif -%}
+ {{ chill_custom_field_widget(cFData, title) }}
+ {%- set title = null -%}
+ {%- endif -%}
+ {%- if subtitle is not empty -%}
+ {%- if subtitle_div_opened == false -%}
+
+ {%- set subtitle_div_opened = true -%}
+ {%- else -%}
+
+ {%- endif -%}
+ {{ chill_custom_field_widget(cFData, subtitle) }}
+ {%- set subtitle = null -%}
+ {%- endif -%}
+
{{ chill_custom_field_label(customField) }}
+ {{ chill_custom_field_widget(cFData , customField) }}
+ {%- set something_has_been_printed = true -%}
+ {%- endif -%}
+ {%- endif -%}
+{% endfor %}
+{%- if subtitle_div_opened == true -%}
+
+{%- endif -%}
+{%- if title_div_opened == true -%}
+
+{%- endif -%}
+{% if something_has_been_printed == false %}
+
{{ 'Empty data'|trans }}
+
{{ 'No data to show' | trans }}
+{% endif %}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsGroup/render_for_test.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsGroup/render_for_test.html.twig
new file mode 100644
index 000000000..a3c5ff8fe
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsGroup/render_for_test.html.twig
@@ -0,0 +1,7 @@
+
+ {{ customFieldsGroup.name(app.request.locale) }}
+ {% for customField in customFieldsGroup.customFields %}
+ - {{ chill_custom_field_label(customField) }}
+ - {{ chill_custom_field_widget(fields, customField) }}
+ {% endfor %}
+
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsGroup/show.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsGroup/show.html.twig
new file mode 100644
index 000000000..d2f9d4e33
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsGroup/show.html.twig
@@ -0,0 +1,116 @@
+{#
+ * 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 title %}{{ 'CustomFieldsGroup details'|trans }}{% endblock %}
+
+{% block admin_content %}
+ {{ 'CustomFieldsGroup details'|trans }}
+
+
+
+
+ {{ 'Name'|trans }} |
+ {{ entity.getName|localize_translatable_string }} |
+
+
+ {{ '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 -%}
+
+
+
+
+
+ {{ 'Fields associated with this group'|trans }}
+
+ {%- if entity.customFields|length > 0 -%}
+
+
+
+ {{ 'ordering'|trans|capitalize }} |
+ {{ 'label_field'|trans|capitalize }} |
+ {{ 'type'|trans|capitalize }} |
+ {{ 'active'|trans|capitalize }} |
+ |
+
+
+
+ {%- for field in entity.customFields -%}
+
+ {{ field.ordering }} |
+ {{ field.name|localize_translatable_string }} |
+ {{ field.type|trans }} |
+
+ {%- if field.active -%}
+
+ {%- else -%}
+
+ {%- endif -%}
+ |
+
+ {{ 'edit'|trans|capitalize }}
+ |
+
+ {%- endfor -%}
+
+
+ {{ form_start(create_field_form) }}
+
+ {{ form_widget(create_field_form.type) }}
+
+ {{ form_widget(create_field_form.submit, { 'attr': { 'class': 'sc-button bt-create' }, 'label': 'Add a new field' } ) }}
+ {{ form_end(create_field_form) }}
+ {%- else -%}
+
+ {{ 'Any field is currently associated with this group'|trans }}
+
+ {{ form_start(create_field_form) }}
+
+ {{ form_widget(create_field_form.type) }}
+
+ {{ form_widget(create_field_form.submit, { 'attr': { 'class': 'sc-button bt-create' }, 'label': 'Create a new field' } ) }}
+ {{ form_end(create_field_form) }}
+ {%- endif -%}
+{% endblock %}
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice.csv.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice.csv.twig
new file mode 100644
index 000000000..1538fd437
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice.csv.twig
@@ -0,0 +1,13 @@
+{% if selected|length > 0 %}
+{%- for choice in choices -%}
+ {% if choice['slug'] in selected %}
+ {%- if choice['slug'] is not same as('_other') -%}
+ {{ choice['name']|localize_translatable_string|csv_cell }}
+ {%- else -%}
+ {{ choice['name']|csv_cell }}
+ {%- endif -%}
+ {% endif %}
+{%- endfor -%}
+{% else %}
+ {{ 'None'|trans }}
+{% endif %}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice.html.twig
new file mode 100644
index 000000000..02f6ab13b
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice.html.twig
@@ -0,0 +1,29 @@
+{% if selected|length > 0 %}
+
+ {%- 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
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice_long.csv.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice_long.csv.twig
new file mode 100644
index 000000000..ec7084776
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice_long.csv.twig
@@ -0,0 +1 @@
+{% if values|length == 1 %}{{ values[0].text|localize_translatable_string|default("")|csv_cell }}{% elseif values|length ==0 %}{{ 'emtpy'|csv_cell }}{% else %}{{ 'pas de rendu multiple'|csv_cell }}{% endif %}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice_long.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/choice_long.html.twig
new file mode 100644
index 000000000..6849f1d0c
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/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/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/date.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/date.html.twig
new file mode 100644
index 000000000..87d7f5567
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/date.html.twig
@@ -0,0 +1 @@
+{% if value is not empty %}{{ value|localizeddate(format, 'none')}}{% endif %}
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/number.csv.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/number.csv.twig
new file mode 100644
index 000000000..e48f2f878
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/number.csv.twig
@@ -0,0 +1 @@
+{% if number is not empty %}{{ number|number_format(scale)|csv_cell }}{% endif %}
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/number.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/number.html.twig
new file mode 100644
index 000000000..894d34fae
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/number.html.twig
@@ -0,0 +1 @@
+{% if number is not empty %}{{ number|number_format(scale) }} {{ post|default('') }}{% endif %}
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/text.csv.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/text.csv.twig
new file mode 100644
index 000000000..03b805bbb
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/text.csv.twig
@@ -0,0 +1 @@
+{% if text is not empty %}{{ text|csv_cell}}{% else %}{{ 'None'|trans }}{% endif %}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/text.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/text.html.twig
new file mode 100644
index 000000000..6b977f123
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/text.html.twig
@@ -0,0 +1 @@
+{% if text is not empty %}{{ text|nl2br }}{% else %}{{ 'None'|trans }}{% endif %}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/title.html.twig b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/title.html.twig
new file mode 100644
index 000000000..59973725c
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/CustomFieldsRendering/title.html.twig
@@ -0,0 +1,5 @@
+{% if type == "title"%}
+ {{ title | localize_translatable_string }}
+{% else %}
+ {{ title | localize_translatable_string }}
+{% endif %}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Resources/views/Form/fields.html.twig b/src/Bundle/ChillCustomFields/Resources/views/Form/fields.html.twig
new file mode 100644
index 000000000..1fc722d77
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Resources/views/Form/fields.html.twig
@@ -0,0 +1,111 @@
+{#
+ * 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 .
+#}
+
+{# CustomFields Title #}
+{% block custom_field_title_widget %}
+
+ {{ form.vars.attr.title }}
+
+{% endblock custom_field_title_widget %}
+
+{# 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) }}
+{% endblock cf_choices_list_widget %}
+
+{# CFChoice : render the different elements in a choice list #}
+{% block cf_choices_row %}
+ {{ 'Choices'|trans }}
+
+
+
+
+ {# we use javascrit to add an additional element. All functions are personnalized with the id ( = form.vars.id) #}
+
+{% endblock cf_choices_row %}
+
+{# 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 %}
+
+{# extend the number 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 %}
+
+{# The choice_with_other_widget widget is defined in the main bundle #}
+
diff --git a/src/Bundle/ChillCustomFields/Service/CustomFieldProvider.php b/src/Bundle/ChillCustomFields/Service/CustomFieldProvider.php
new file mode 100644
index 000000000..d2871560e
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Service/CustomFieldProvider.php
@@ -0,0 +1,103 @@
+,
+ *
+ * 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\Service;
+
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Receive all the services tagged with 'chill.custom_field'.
+ *
+ * The services tagged with 'chill.custom_field' are services used to declare
+ * a new custom field type. The tag must contain a 'type' variable (that must
+ * be unique), this type is used to identify this custom field in the form
+ * declration
+ *
+ * For example (in services.yml) :
+ * services:
+ * chill.icp2.type:
+ * tags:
+ * - { name: 'chill.custom_field', type: 'ICPC2' }
+ *
+ * @author Julien Fastré
+ */
+class CustomFieldProvider implements ContainerAwareInterface
+{
+ /** @var array $servicesByType The services indexes by the type */
+ private $servicesByType = array();
+
+ /** @var Container $container The container */
+ private $container;
+
+ /**
+ * Add a new custom field to the provider
+ *
+ * @param type $serviceName The name of the service (declared in service.yml)
+ * @param type $type The type of the service (that is used in the form to
+ * add this type)
+ */
+ public function addCustomField($serviceName, $type)
+ {
+ $this->servicesByType[$type] = $serviceName;
+ }
+
+ /**
+ * Get a custom field stored in the provider. The custom field is identified
+ * by its type.
+ *
+ * @param string $type The type of the wanted service
+ * @return CustomFieldInterface
+ */
+ public function getCustomFieldByType($type)
+ {
+ if (isset($this->servicesByType[$type])) {
+ return $this->servicesByType[$type];
+ } else {
+ throw new \LogicException('the custom field with type '.$type.' '
+ . 'is not found');
+ }
+ }
+
+ /*
+ * (non-PHPdoc)
+ * @see \Symfony\Component\DependencyInjection\ContainerAwareInterface::setContainer()
+ */
+ public function setContainer(ContainerInterface $container = null)
+ {
+ if ($container === null) {
+ throw new \LogicException('container should not be null');
+ }
+
+ $this->container = $container;
+ }
+
+ /**
+ * Get all the custom fields known by the provider
+ *
+ * @return array Array of the known custom fields indexed by the type.
+ */
+ public function getAllFields()
+ {
+ return $this->servicesByType;
+ }
+}
diff --git a/src/Bundle/ChillCustomFields/Service/CustomFieldsHelper.php b/src/Bundle/ChillCustomFields/Service/CustomFieldsHelper.php
new file mode 100644
index 000000000..f5bc2cc2e
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Service/CustomFieldsHelper.php
@@ -0,0 +1,90 @@
+,
+ *
+ * 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\Service;
+
+use Doctrine\ORM\EntityManagerInterface;
+use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
+use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+
+/**
+ * Helpers for manipulating custom fields.
+ *
+ * Herlpers for getting a certain custom field, for getting the raw value
+ * of a custom field and for rendering the value of a custom field.
+ *
+ * @author Julien Fastré
+ *
+ */
+class CustomFieldsHelper
+{
+ /** @var EntityManagerInterface $em The entity manager */
+ private $em;
+
+ /** @var CustomFieldProvider $provider Provider of all the declared custom
+ * fields */
+ private $provider;
+
+ /**
+ * Constructor
+ *
+ * @param EntityManagerInterface $em The entity manager
+ * @param CustomFieldProvider $provider The customfield provider that
+ * contains all the declared custom fields
+ */
+ public function __construct(EntityManagerInterface $em,
+ CustomFieldProvider $provider)
+ {
+ $this->em = $em;
+ $this->provider = $provider;
+ }
+
+ public function isEmptyValue(array $fields, CustomField $customField)
+ {
+ $slug = $customField->getSlug();
+ $rawValue = (isset($fields[$slug])) ? $fields[$slug] : null;
+ $customFieldType = $this->provider->getCustomFieldByType($customField->getType());
+
+ $deserializedValue = $customFieldType->deserialize($rawValue, $customField);
+
+ return $customFieldType->isEmptyValue($deserializedValue, $customField);
+ }
+
+ /**
+ * Render the value of a custom field
+ *
+ * @param array $fields the **raw** array, as stored in the db
+ * @param CustomField $customField the customField entity
+ * @param string $documentType The type of document in which the rendered value is displayed ('html' or 'csv').
+ * @throws CustomFieldsHelperException if slug is missing
+ * @return The representation of the value the customField.
+ */
+ public function renderCustomField(array $fields, CustomField $customField, $documentType='html')
+ {
+ $slug = $customField->getSlug();
+ $rawValue = (isset($fields[$slug])) ? $fields[$slug] : null;
+ $customFieldType = $this->provider->getCustomFieldByType($customField->getType());
+
+ return $customFieldType->render($rawValue, $customField, $documentType);
+ }
+}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Service/CustomFieldsHelperException.php b/src/Bundle/ChillCustomFields/Service/CustomFieldsHelperException.php
new file mode 100644
index 000000000..497c96720
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Service/CustomFieldsHelperException.php
@@ -0,0 +1,36 @@
+,
+ *
+ * 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\Service;
+
+class CustomFieldsHelperException extends \Exception
+{
+ public static function customFieldsGroupNotFound($entity)
+ {
+ return new CustomFieldsHelperException("The customFieldsGroups associated with $entity are not found");
+ }
+
+ public static function slugIsMissing()
+ {
+ return new CustomFieldsHelperException("The slug is missing");
+ }
+}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Templating/Twig/CustomFieldRenderingTwig.php b/src/Bundle/ChillCustomFields/Templating/Twig/CustomFieldRenderingTwig.php
new file mode 100644
index 000000000..a43d7dc26
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Templating/Twig/CustomFieldRenderingTwig.php
@@ -0,0 +1,133 @@
+,
+ *
+ * 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\Templating\Twig;
+
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\DependencyInjection\Container;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+
+/**
+ * Add the following Twig Extension :
+ * * chill_custom_field_widget : to render the value of the custom field,
+ * * chill_custom_field_label : to render the label of the custom field,
+ *
+ * @author Julien Fastré
+ */
+class CustomFieldRenderingTwig extends \Twig_Extension implements ContainerAwareInterface
+{
+
+ /** @var Container $container The container */
+ private $container;
+
+ /** @var array $defaultParams The default parameters */
+ private $defaultParams = array(
+ 'label_layout' => 'ChillCustomFieldsBundle:CustomField:render_label.html.twig'
+ );
+
+ /*
+ * (non-PHPdoc)
+ * @see \Symfony\Component\DependencyInjection\ContainerAwareInterface::setContainer()
+ */
+ public function setContainer(ContainerInterface $container = null)
+ {
+ $this->container = $container;
+ }
+
+ /*
+ * (non-PHPdoc)
+ * @see Twig_Extension::getFunctions()
+ */
+ public function getFunctions()
+ {
+ return [
+ new \Twig_SimpleFunction('chill_custom_field_widget', array(
+ $this,
+ 'renderWidget'
+ ), array(
+ 'is_safe' => array(
+ 'html'
+ )
+ )),
+ new \Twig_SimpleFunction('chill_custom_field_label', array(
+ $this,
+ 'renderLabel'
+ ), array(
+ 'is_safe' => array(
+ 'html'
+ )
+ )),
+ new \Twig_SimpleFunction('chill_custom_field_is_empty', array(
+ $this,
+ 'isEmptyValue'
+ ))
+ ];
+ }
+
+
+ public function isEmptyValue($fields, CustomField $customField)
+ {
+ return $this->container->get('chill.custom_field.helper')
+ ->isEmptyValue($fields, $customField);
+ }
+
+ /* (non-PHPdoc)
+ * @see Twig_ExtensionInterface::getName()
+ */
+ public function getName()
+ {
+ return 'chill_custom_fields_rendering';
+ }
+
+ /**
+ * Twig Extension that is used to render the label of a custom field.
+ *
+ * @param CustomField $customField Either a customField OR a customizable_entity OR the FQDN of the entity
+ * @param array $params The parameters for rendering. Currently, 'label_layout' allow to choose a different label. Default is 'ChillCustomFieldsBundle:CustomField:render_label.html.twig'
+ * @return string HTML representation of the custom field label.
+ */
+ public function renderLabel(CustomField $customField, array $params = array())
+ {
+ $resolvedParams = array_merge($this->defaultParams, $params);
+
+ return $this->container->get('templating')
+ ->render($resolvedParams['label_layout'], array('customField' => $customField));
+ }
+
+ /**
+ * Twig extension that is used to render the value of a custom field.
+ *
+ * The presentation of the value is influenced by the document type.
+ *
+ * @param array $fields The array raw, as stored in the db
+ * @param CustomField $customField Either a customField OR a customizable_entity OR the FQDN of the entity
+ * @param string $documentType The type of the document (csv, html)
+ * @param string $slug The slug of the custom field ONLY necessary if the first argument is NOT a CustomField instance
+ * @return string HTML representation of the custom field value, as described in the CustomFieldInterface. Is HTML safe
+ */
+ public function renderWidget(array $fields, CustomField $customField, $documentType='html')
+ {
+ return $this->container->get('chill.custom_field.helper')
+ ->renderCustomField($fields, $customField, $documentType);
+ }
+}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Templating/Twig/CustomFieldsGroupRenderingTwig.php b/src/Bundle/ChillCustomFields/Templating/Twig/CustomFieldsGroupRenderingTwig.php
new file mode 100644
index 000000000..a6b9305c0
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Templating/Twig/CustomFieldsGroupRenderingTwig.php
@@ -0,0 +1,119 @@
+,
+ *
+ * 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\Templating\Twig;
+
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\DependencyInjection\Container;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+
+/**
+ * Add the following Twig Extension :
+ * * chill_custom_fields_group_widget : to render the value of a custom field
+ * * group
+ *
+ * @author Julien Fastré
+ * @author Marc Ducobu
+ */
+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',
+ '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()
+ */
+ public function setContainer(ContainerInterface $container = null)
+ {
+ $this->container = $container;
+ }
+
+ /*
+ * (non-PHPdoc)
+ * @see Twig_Extension::getFunctions()
+ */
+ public function getFunctions()
+ {
+ return [
+ new \Twig_SimpleFunction('chill_custom_fields_group_widget', array(
+ $this,
+ 'renderWidget'
+ ), array(
+ 'is_safe' => array(
+ 'html'
+ )
+ )),
+ ];
+ }
+
+ /* (non-PHPdoc)
+ * @see Twig_ExtensionInterface::getName()
+ */
+ public function getName()
+ {
+ return 'chill_custom_fields_group_rendering';
+ }
+
+ /**
+ * Twig extension that is used to render the value of a custom field group.
+ *
+ * The presentation of the value is influenced by the document type.
+ *
+ * @param array $fields The array raw, as stored in the db
+ * @param CustomFieldsGroud $customFielsGroup The custom field group
+ * @param string $documentType The type of the document (csv, html)
+ * @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
+ */
+ public function renderWidget(array $fields, $customFielsGroup, $documentType='html', array $params = array())
+ {
+ $resolvedParams = array_merge($this->defaultParams, $params);
+
+ return $this->container->get('templating')
+ ->render($resolvedParams['layout'], array(
+ 'cFGroup' => $customFielsGroup,
+ 'cFData' => $fields,
+ 'show_empty' => $resolvedParams['show_empty']));
+ }
+}
\ No newline at end of file
diff --git a/src/Bundle/ChillCustomFields/Tests/Config/ConfigCustomizablesEntitiesTest.php b/src/Bundle/ChillCustomFields/Tests/Config/ConfigCustomizablesEntitiesTest.php
new file mode 100644
index 000000000..df66ab56c
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Config/ConfigCustomizablesEntitiesTest.php
@@ -0,0 +1,70 @@
+
+ *
+ * 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\Config;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+
+/**
+ * Test the option Customizables_entities
+ *
+ * @author Julien Fastré
+ */
+class ConfigCustomizablesEntitiesTest extends KernelTestCase
+{
+ /**
+ * Test that the config does work if the option
+ * chill_custom_fields.customizables_entities IS NOT present
+ *
+ * In this case, parameter 'chill_custom_fields.customizables_entities'
+ * should be an empty array in container
+ */
+ public function testNotPresentInConfig()
+ {
+ self::bootKernel(array('environment' => 'test'));
+ $customizableEntities = static::$kernel->getContainer()
+ ->getParameter('chill_custom_fields.customizables_entities');
+
+ $this->assertInternalType('array', $customizableEntities);
+ $this->assertCount(1, $customizableEntities);
+ }
+
+ /**
+ * Test that the 'chill_custom_fields.customizables_entities' is filled
+ * correctly with a minimal configuration.
+ *
+ * @internal use a custom config environment
+ */
+ public function testNotEmptyConfig()
+ {
+ self::bootKernel(array('environment' => 'test_customizable_entities_test_not_empty_config'));
+ $customizableEntities = static::$kernel->getContainer()
+ ->getParameter('chill_custom_fields.customizables_entities');
+
+ $this->assertInternalType('array', $customizableEntities);
+ $this->assertCount(2, $customizableEntities);
+
+ foreach($customizableEntities as $key => $config) {
+ $this->assertInternalType('array', $config);
+ $this->assertArrayHasKey('name', $config);
+ $this->assertArrayHasKey('class', $config);
+ }
+ }
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/Controller/CustomFieldControllerTest_TODO.php b/src/Bundle/ChillCustomFields/Tests/Controller/CustomFieldControllerTest_TODO.php
new file mode 100644
index 000000000..c41de20e0
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Controller/CustomFieldControllerTest_TODO.php
@@ -0,0 +1,55 @@
+request('GET', '/customfield/');
+ $this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /customfield/");
+ $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_customfield[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_customfield[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/src/Bundle/ChillCustomFields/Tests/Controller/CustomFieldsGroupControllerTest.php b/src/Bundle/ChillCustomFields/Tests/Controller/CustomFieldsGroupControllerTest.php
new file mode 100644
index 000000000..8822aec15
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Controller/CustomFieldsGroupControllerTest.php
@@ -0,0 +1,74 @@
+ '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/');
+ $links = $crawler->selectLink('Modifier');
+
+ $this->assertGreaterThan(0, $links->count(),
+ "We can't find a 'Modifier' link on the index page");
+ $crawler = $client->click($links->last()->link());
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $form = $crawler->selectButton('Mettre à jour')->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/src/Bundle/ChillCustomFields/Tests/CustomFieldTestHelper.php b/src/Bundle/ChillCustomFields/Tests/CustomFieldTestHelper.php
new file mode 100644
index 000000000..3d4c58fe0
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/CustomFieldTestHelper.php
@@ -0,0 +1,86 @@
+
+ *
+ * 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 Symfony\Component\HttpKernel\KernelInterface;
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Give useful method to prepare tests regarding custom fields
+ *
+ * @author Julien Fastré
+ */
+trait CustomFieldTestHelper
+{
+
+ /**
+ * Prepare a crawler containing the rendering of a customField
+ *
+ * @internal This method will mock a customFieldGroup containing $field, and
+ * rendering the customfield, using Type\CustomFieldType, to a simple form row
+ *
+ * @param CustomField $field
+ * @param KernelTestCase $testCase
+ * @param KernelInterface $kernel
+ * @param type $locale
+ * @return Crawler
+ */
+ public function getCrawlerForField(CustomField $field, $locale = 'en')
+ {
+ $kernel = static::$kernel;
+
+ //check a kernel is accessible
+ $customFieldsGroup = $this->createMock('Chill\CustomFieldsBundle\Entity\CustomFieldsGroup');
+ $customFieldsGroup->expects($this->once())
+ ->method('getActiveCustomFields')
+ ->will($this->returnValue(array($field)));
+
+ $request = $this->createMock('Symfony\Component\HttpFoundation\Request');
+ $request->expects($this->any())
+ ->method('getLocale')
+ ->will($this->returnValue($locale));
+
+ $kernel->getContainer()->get('request_stack')->push($request);
+
+ $builder = $kernel->getContainer()->get('form.factory')->createBuilder();
+ $form = $builder->add('tested', 'custom_field',
+ array('group' => $customFieldsGroup))
+ ->getForm();
+
+ $kernel->getContainer()->get('twig.loader')
+ ->addPath($kernel->getContainer()->getParameter('kernel.root_dir').
+ '/Resources/views/', $namespace = 'test');
+
+ $content = $kernel
+ ->getContainer()->get('templating')
+ ->render('@test/CustomField/simple_form_render.html.twig', array(
+ 'form' => $form->createView(),
+ 'inputKeys' => array('tested')
+ ));
+
+ $crawler = new Crawler();
+ $crawler->addHtmlContent($content);
+
+ return $crawler;
+ }
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsChoiceTest.php b/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsChoiceTest.php
new file mode 100644
index 000000000..28351711c
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsChoiceTest.php
@@ -0,0 +1,468 @@
+
+ *
+ * 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);
+
+ $deserialized = $this->cfChoice->deserialize(array(null), $customField);
+ $this->assertSame(null, $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize(array('_other' => null, '_choices' => null), $customField);
+ $this->assertSame(null, $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize(array('_other' => null, '_choices' => ''), $customField);
+ $this->assertSame('', $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize(array(null), $customField);
+ $this->assertSame(null, $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);
+
+ $deserialized = $this->cfChoice->deserialize(array('_other' => null, '_choices' => null), $customField);
+ $this->assertSame(array('_other' => '', '_choices' => null), $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize(array('_other' => null, '_choices' => ''), $customField);
+ $this->assertSame(array('_other' => '', '_choices' => ''), $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize(array(null), $customField);
+ $this->assertSame(array('_other' => '', '_choices' => null), $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);
+
+ $deserialized = $this->cfChoice->deserialize(array('_other' => null, '_choices' => null), $customField);
+ $this->assertSame(array('_other' => '', '_choices' => array(null)), $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize(array('_other' => null, '_choices' => ''), $customField);
+ $this->assertSame(array('_other' => '', '_choices' => array('')), $deserialized);
+
+ $deserialized = $this->cfChoice->deserialize(array(null), $customField);
+ $this->assertSame(array('_other' => '', '_choices' => array(null)), $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);
+
+ // from multiple
+ $data = array(null);
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+ $this->assertSame(array(null), $deserialized);
+
+ $data = array('_other' => null, '_choices' => array(null));
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+ $this->assertSame(array(null), $deserialized);
+
+ //from single
+ $data = array('_other' => null, '_choices' => null);
+ $deserialized = $this->cfChoice->deserialize($data, $customField);
+ $this->assertSame(array(null), $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
+ //
+ ////////////////////////////////////////
+
+ /**
+ * test the not empty with the not-empty data provider
+ *
+ * @param mixed $data
+ * @dataProvider serializedRepresentationDataProvider
+ */
+ public function testIsEmptyValueNotEmpty($data)
+ {
+ $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);
+ }
+
+ /**
+ *
+ * @dataProvider emptyDataProvider
+ * @param mixed $data deserialized data
+ */
+ public function testIsEmptyValueEmpty($data)
+ {
+ $customField = $this->generateCustomField(array(
+ CustomFieldChoice::ALLOW_OTHER => false,
+ CustomFieldChoice::MULTIPLE => true
+ ));
+
+ $isEmpty = $this->cfChoice->isEmptyValue($data, $customField);
+
+ $this->assertTrue($isEmpty);
+ }
+
+ /**
+ * provide empty data in different possible representations.
+ * Those data are supposed to be deserialized.
+ *
+ * @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())
+ ),
+ // 6
+ array(
+ // empty
+ array('_other' => null, '_choices' => null)
+ ),
+ // 7
+ array(
+ // empty
+ array(null)
+ )
+ );
+ }
+
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsNumberTest.php b/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsNumberTest.php
new file mode 100644
index 000000000..a206be5c7
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsNumberTest.php
@@ -0,0 +1,191 @@
+
+ *
+ * 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;
+use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
+use Chill\CustomFieldsBundle\Form\CustomFieldsGroupType;
+
+/**
+ * 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()));
+ }
+
+ 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(\Chill\CustomFieldsBundle\Form\Type\CustomFieldType::class, 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(\Chill\CustomFieldsBundle\Form\Type\CustomFieldType::class, array(), array(
+ 'group' => $cfGroup
+ ))
+ ->getForm();
+
+ $this->assertTrue($form['default']->isRequired(),
+ "The field should be required");
+ }
+
+
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsTextTest.php b/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsTextTest.php
new file mode 100644
index 000000000..ad031e4a1
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/CustomFields/CustomFieldsTextTest.php
@@ -0,0 +1,106 @@
+.
+ */
+
+namespace Chill\CustomFieldsBundle\Tests;
+
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+use Chill\CustomFieldsBundle\CustomFields\CustomFieldText;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\DomCrawler\Crawler;
+use Chill\CustomFieldsBundle\Tests\CustomFieldTestHelper;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+class CustomFieldsTextTest extends WebTestCase
+{
+ /**
+ *
+ * @var \Chill\CustomFieldsBundle\Service\CustomFieldProvider
+ */
+ private $customFieldProvider;
+
+ use CustomFieldTestHelper;
+
+ public function setUp()
+ {
+ static::bootKernel();
+ $this->customFieldProvider = static::$kernel->getContainer()
+ ->get('chill.custom_field.provider');
+ }
+
+ public function testCustomFieldsTextExists()
+ {
+ $customField = $this->customFieldProvider->getCustomFieldByType('text');
+
+ $this->assertInstanceOf('Chill\CustomFieldsBundle\CustomFields\CustomFieldInterface',
+ $customField);
+ $this->assertInstanceOf('Chill\CustomFieldsBundle\CustomFields\CustomFieldText',
+ $customField);
+ }
+
+ public function testPublicFormRenderingLengthLessThan256()
+ {
+ $customField = new CustomField();
+ $customField->setType('text')
+ ->setOptions(array(CustomFieldText::MAX_LENGTH => 255))
+ ->setSlug('slug')
+ ->setOrdering(10)
+ ->setActive(true)
+ ->setName(array('en' => 'my label'));
+
+ $crawler = $this->getCrawlerForField($customField);
+
+ $this->assertCount(1, $crawler->filter("input[type=text]"));
+ $this->assertCount(1, $crawler->filter("label:contains('my label')"));
+ }
+
+ public function testPublicFormRenderingLengthMoreThan25()
+ {
+ $customField = new CustomField();
+ $customField->setType('text')
+ ->setOptions(array(CustomFieldText::MAX_LENGTH => 256))
+ ->setSlug('slug')
+ ->setOrdering(10)
+ ->setActive(true)
+ ->setName(array('en' => 'my label'));
+
+ $crawler = $this->getCrawlerForField($customField);
+
+ $this->assertCount(1, $crawler->filter("textarea"));
+ $this->assertCount(1, $crawler->filter("label:contains('my label')"));
+ }
+
+ public function testFormTextNew()
+ {
+ $client = static::createClient();
+
+ $crawler = $client->request('GET', '/fr/admin/customfield/new?type=text');
+
+ $this->assertTrue($client->getResponse()->isSuccessful());
+
+ $form = $crawler->selectButton('custom_field_choice_submit')->form();
+ $this->assertTrue($form->has('custom_field_choice[options][maxLength]'));
+ }
+
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/Form/Extension/PostTextIntegerExtensionTest.php b/src/Bundle/ChillCustomFields/Tests/Form/Extension/PostTextIntegerExtensionTest.php
new file mode 100644
index 000000000..5f395abe5
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Form/Extension/PostTextIntegerExtensionTest.php
@@ -0,0 +1,59 @@
+
+ *
+ * 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\Form\Extension;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use Symfony\Component\Form\Extension\Core\Type\IntegerType;
+
+/**
+ * Test the post-text extension
+ *
+ * @author Julien Fastré
+ */
+class PostTextIntegerExtensionTest extends KernelTestCase
+{
+ /**
+ *
+ * @var \Symfony\Component\Form\FormBuilderInterface
+ */
+ private $formBuilder;
+
+ public function setUp()
+ {
+ self::bootKernel();
+
+ $container = self::$kernel->getContainer();
+
+ $this->formBuilder = $container->get('form.factory')
+ ->createBuilder('form', null);
+ }
+
+ public function testCreateView()
+ {
+ $form = $this->formBuilder->add('test', IntegerType::class, array(
+ 'post_text' => 'my text'
+ ))->getForm();
+
+ $view = $form->createView();
+
+ $this->assertEquals('my text', $view['test']->vars['post_text']);
+ }
+
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/Form/Extension/PostTextNumberExtensionTest.php b/src/Bundle/ChillCustomFields/Tests/Form/Extension/PostTextNumberExtensionTest.php
new file mode 100644
index 000000000..86098ac21
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Form/Extension/PostTextNumberExtensionTest.php
@@ -0,0 +1,59 @@
+
+ *
+ * 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\Form\Extension;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use Symfony\Component\Form\Extension\Core\Type\NumberType;
+
+/**
+ * Test the post-text extension
+ *
+ * @author Julien Fastré
+ */
+class PostTextNumberExtensionTest extends KernelTestCase
+{
+ /**
+ *
+ * @var \Symfony\Component\Form\FormBuilderInterface
+ */
+ private $formBuilder;
+
+ public function setUp()
+ {
+ self::bootKernel();
+
+ $container = self::$kernel->getContainer();
+
+ $this->formBuilder = $container->get('form.factory')
+ ->createBuilder('form', null);
+ }
+
+ public function testCreateView()
+ {
+ $form = $this->formBuilder->add('test', NumberType::class, array(
+ 'post_text' => 'my text'
+ ))->getForm();
+
+ $view = $form->createView();
+
+ $this->assertEquals('my text', $view['test']->vars['post_text']);
+ }
+
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/Routing/RoutingLoaderTest.php b/src/Bundle/ChillCustomFields/Tests/Routing/RoutingLoaderTest.php
new file mode 100644
index 000000000..290cce37b
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Routing/RoutingLoaderTest.php
@@ -0,0 +1,45 @@
+
+ *
+ * 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\WebTestCase;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Test that routes are correctly loaded
+ *
+ * @author Julien Fastré
+ */
+class RoutingLoaderTest extends WebTestCase
+{
+ public function testRoutesAreLoaded()
+ {
+ $client = static::createClient();
+
+ $client->request('GET','/fr/admin/customfield/');
+
+ $this->assertEquals(
+ Response::HTTP_OK,
+ $client->getResponse()->getStatusCode()
+ );
+
+ }
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/Service/CustomFieldsHelperTest.php b/src/Bundle/ChillCustomFields/Tests/Service/CustomFieldsHelperTest.php
new file mode 100644
index 000000000..fc7276cf7
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Service/CustomFieldsHelperTest.php
@@ -0,0 +1,92 @@
+
+ *
+ * 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\Service;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use Chill\CustomFieldsBundle\Service\CustomFieldsHelper;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+
+/**
+ * Tests for custom fields helper
+ *
+ * @author Julien Fastré
+ * @author Champs Libres
+ */
+class CustomFieldsHelperTest extends KernelTestCase
+{
+ /**
+ *
+ * @var CustomFieldsHelper
+ */
+ private $cfHelper;
+
+ /**
+ *
+ * @var CustomField
+ */
+ private $randomCFText;
+
+ public function setUp()
+ {
+ self::bootKernel();
+
+ $container = self::$kernel->getContainer();
+
+ $this->cfHelper = $container->get('chill.custom_field.helper');
+
+ $this->randomCFText = (new CustomField())
+ ->setSlug('my-slug')
+ ->setActive(true)
+ ->setName(array('fr' => 'my cf'))
+ ->setOptions(array('maxLength' => 1000))
+ ->setType('text')
+ ;
+ }
+
+ public function testRenderCustomField()
+ {
+ $data = array(
+ $this->randomCFText->getSlug() => 'Sample text'
+ );
+
+ $text = $this->cfHelper->renderCustomField($data, $this->randomCFText);
+
+ $this->assertContains('Sample text', $text);
+ }
+
+ public function testIsEmptyValue()
+ {
+ // not empty value
+ $data = array(
+ $this->randomCFText->getSlug() => 'Sample text'
+ );
+
+ $this->assertFalse($this->cfHelper->isEmptyValue($data, $this->randomCFText));
+
+ //empty value
+ $data = array(
+ $this->randomCFText->getSlug() => ''
+ );
+
+ $this->assertTrue($this->cfHelper->isEmptyValue($data, $this->randomCFText));
+ }
+
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/Templating/Twig/CustomFieldRenderingTwigTest.php b/src/Bundle/ChillCustomFields/Tests/Templating/Twig/CustomFieldRenderingTwigTest.php
new file mode 100644
index 000000000..2f6f51df7
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Templating/Twig/CustomFieldRenderingTwigTest.php
@@ -0,0 +1,128 @@
+
+ *
+ * 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");
+ }
+
+ public function testIsEmpty()
+ {
+ $cf = $this->getSimpleCustomFieldText();
+
+ // value is not empty
+ $fields = array(
+ 'test' => "My tailor is rich"
+ );
+
+ $result = $this->cfRendering->isEmptyValue($fields, $cf);
+
+ $this->assertFalse($result);
+
+ // value is empty
+ $fields = array(
+ 'text' => ''
+ );
+
+ $result = $this->cfRendering->isEmptyValue($fields, $cf);
+
+ $this->assertTrue($result);
+ }
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/Templating/Twig/CustomFieldsGroupRenderingTwigTest.php b/src/Bundle/ChillCustomFields/Tests/Templating/Twig/CustomFieldsGroupRenderingTwigTest.php
new file mode 100644
index 000000000..d1cbe0209
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/Templating/Twig/CustomFieldsGroupRenderingTwigTest.php
@@ -0,0 +1,130 @@
+
+ *
+ * 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\CustomFieldsGroupRenderingTwig;
+use Chill\CustomFieldsBundle\Entity\CustomField;
+use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
+use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
+
+/**
+ * Test the rendering of a custom fields group through
+ * the `chill_custom_fields_group_widget`
+ *
+ * @author Julien Fastré
+ * @author Champs Libres
+ */
+class CustomFieldsGroupRenderingTwigTest extends KernelTestCase
+{
+ /**
+ *
+ * @var CustomFieldsGroupRenderingTwig
+ */
+ private $cfRendering;
+
+ /**
+ *
+ * @var CustomFieldProvider
+ */
+ private $cfProvider;
+
+ public function setUp()
+ {
+ self::bootKernel();
+ $this->cfRendering = self::$kernel->getContainer()
+ ->get('chill.custom_field.twig.custom_fields_group_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($slug, $name)
+ {
+ return (new CustomField())
+ ->setSlug($slug)
+ ->setName(array('fr' => $name))
+ ->setType('text')
+ ->setOrdering(10)
+ ->setOptions(array("maxLength" => 255))
+ ->setActive(true)
+ ;
+ }
+
+ /**
+ *
+ * @return CustomFieldsGroup
+ */
+ private function getCustomFieldsGroup()
+ {
+ return (new CustomFieldsGroup())
+ ->setEntity('\Dummy')
+ ->setName(array("fr" => "A cf group"))
+ ->addCustomField($this->getSimpleCustomFieldText("horses", "Do you like horses ?."))
+ ->addCustomField($this->getSimpleCustomFieldText("sure", "Are you sure ?"))
+ ;
+ }
+
+ public function testRenderingWidget()
+ {
+ $cfGroup = $this->getCustomFieldsGroup();
+
+ $text = $this->cfRendering->renderWidget(array(
+ 'horses' => 'I like horses',
+ 'sure' => 'Yes !'
+ ), $cfGroup);
+
+ $this->assertContains('Do you like horses', $text);
+ $this->assertContains('I like horses', $text);
+ $this->assertContains('Are you sure', $text);
+ $this->assertContains('Yes', $text);
+ }
+
+ public function testRenderingWidgetDoNotShowEmpty()
+ {
+ $cfGroup = $this->getCustomFieldsGroup();
+ $cfGroup->addCustomField($this->getSimpleCustomFieldText('empty', 'Do not answer'));
+
+ $text = $this->cfRendering->renderWidget(array(
+ 'horses' => 'I like horses',
+ 'sure' => 'Yes !'
+ ), $cfGroup, 'html', array('show_empty' => false));
+
+ $this->assertContains('Do you like horses', $text);
+ $this->assertContains('I like horses', $text);
+ $this->assertContains('Are you sure', $text);
+ $this->assertContains('Yes', $text);
+ $this->assertNotContains('Do not answer', $text);
+ }
+}
diff --git a/src/Bundle/ChillCustomFields/Tests/bootstrap.php b/src/Bundle/ChillCustomFields/Tests/bootstrap.php
new file mode 100644
index 000000000..9211155e5
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/Tests/bootstrap.php
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+ ./Tests
+
+
+
+
+ ./
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillCustomFields/run-server.sh b/src/Bundle/ChillCustomFields/run-server.sh
new file mode 100755
index 000000000..e12b22a86
--- /dev/null
+++ b/src/Bundle/ChillCustomFields/run-server.sh
@@ -0,0 +1 @@
+php Tests/Fixtures/App/app/console.php server:run --docroot=Tests/Fixtures/App/web/