mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
Merge branch 'master' into add_gitlab_ci
Conflicts: .gitignore
This commit is contained in:
commit
1de944f838
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,6 +15,7 @@
|
||||
.gitignore~
|
||||
*~
|
||||
composer.phar
|
||||
composer.lock
|
||||
/nbproject/private/
|
||||
parameters.yml
|
||||
app/config/parameters.yml
|
||||
@ -27,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
|
||||
|
||||
|
27
.travis.yml
27
.travis.yml
@ -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=
|
37
Controller/AdminController.php
Normal file
37
Controller/AdminController.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
* Copyright (C) 2015 Champs Libres <info@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ namespace Chill\CustomFieldsBundle\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
use Chill\CustomFieldsBundle\Entity\CustomField;
|
||||
|
||||
/**
|
||||
@ -14,40 +13,6 @@ use Chill\CustomFieldsBundle\Entity\CustomField;
|
||||
class CustomFieldController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Lists all CustomField entities.
|
||||
*
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
$entities = $em->getRepository('ChillCustomFieldsBundle:CustomField')->findAll();
|
||||
|
||||
//prepare form for new custom type
|
||||
$fieldChoices = array();
|
||||
foreach ($this->get('chill.custom_field.provider')->getAllFields()
|
||||
as $key => $customType) {
|
||||
$fieldChoices[$key] = $customType->getName();
|
||||
}
|
||||
$form = $this->get('form.factory')
|
||||
->createNamedBuilder(null, 'form', null, array(
|
||||
'method' => 'GET',
|
||||
'action' => $this->generateUrl('customfield_new'),
|
||||
'csrf_protection' => false
|
||||
))
|
||||
->add('type', 'choice', array(
|
||||
'choices' => $fieldChoices
|
||||
))
|
||||
->getForm();
|
||||
|
||||
return $this->render('ChillCustomFieldsBundle:CustomField:index.html.twig', array(
|
||||
'entities' => $entities,
|
||||
'form' => $form->createView()
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new CustomField entity.
|
||||
*
|
||||
@ -62,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,
|
||||
@ -85,9 +57,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 +73,21 @@ 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$form = $this->createCreateForm($entity, $request->query->get('type'));
|
||||
|
||||
return $this->render('ChillCustomFieldsBundle:CustomField:new.html.twig', array(
|
||||
@ -111,6 +99,7 @@ class CustomFieldController extends Controller
|
||||
/**
|
||||
* Finds and displays a CustomField entity.
|
||||
*
|
||||
* @deprecated is not used since there is no link to show action
|
||||
*/
|
||||
public function showAction($id)
|
||||
{
|
||||
@ -122,12 +111,8 @@ class CustomFieldController extends Controller
|
||||
throw $this->createNotFoundException('Unable to find CustomField entity.');
|
||||
}
|
||||
|
||||
$deleteForm = $this->createDeleteForm($id);
|
||||
|
||||
return $this->render('ChillCustomFieldsBundle:CustomField:show.html.twig', array(
|
||||
'entity' => $entity,
|
||||
'delete_form' => $deleteForm->createView(),
|
||||
));
|
||||
'entity' => $entity, ));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,12 +130,10 @@ 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(),
|
||||
'delete_form' => $deleteForm->createView(),
|
||||
));
|
||||
}
|
||||
|
||||
@ -166,7 +149,8 @@ class CustomFieldController extends Controller
|
||||
$form = $this->createForm('custom_field_choice', $entity, array(
|
||||
'action' => $this->generateUrl('customfield_update', array('id' => $entity->getId())),
|
||||
'method' => 'PUT',
|
||||
'type' => $type
|
||||
'type' => $type,
|
||||
'group_widget' => 'hidden'
|
||||
));
|
||||
|
||||
$form->add('submit', 'submit', array('label' => 'Update'));
|
||||
@ -187,61 +171,24 @@ class CustomFieldController extends Controller
|
||||
throw $this->createNotFoundException('Unable to find CustomField entity.');
|
||||
}
|
||||
|
||||
$deleteForm = $this->createDeleteForm($id);
|
||||
$editForm = $this->createEditForm($entity, $entity->getType());
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
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,
|
||||
'edit_form' => $editForm->createView(),
|
||||
'delete_form' => $deleteForm->createView(),
|
||||
));
|
||||
}
|
||||
/**
|
||||
* Deletes a CustomField 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:CustomField')->find($id);
|
||||
|
||||
if (!$entity) {
|
||||
throw $this->createNotFoundException('Unable to find CustomField entity.');
|
||||
}
|
||||
|
||||
$em->remove($entity);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
return $this->redirect($this->generateUrl('customfield'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a form to delete a CustomField 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('customfield_delete', array('id' => $id)))
|
||||
->setMethod('DELETE')
|
||||
->add('submit', 'submit', array('label' => 'Delete'))
|
||||
->getForm()
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
use Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup;
|
||||
|
||||
/**
|
||||
* CustomFieldsDefaultGroup controller.
|
||||
*
|
||||
*/
|
||||
class CustomFieldsDefaultGroupController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Lists all CustomFieldsDefaultGroup entities.
|
||||
*
|
||||
*/
|
||||
public function listAction()
|
||||
{
|
||||
$em = $this->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()
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'));
|
||||
}
|
||||
}
|
@ -4,8 +4,11 @@ namespace Chill\CustomFieldsBundle\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
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.
|
||||
@ -22,12 +25,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 = null)
|
||||
{
|
||||
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.
|
||||
*
|
||||
@ -42,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,
|
||||
@ -99,14 +160,36 @@ class CustomFieldsGroupController extends Controller
|
||||
if (!$entity) {
|
||||
throw $this->createNotFoundException('Unable to find CustomFieldsGroup entity.');
|
||||
}
|
||||
|
||||
$deleteForm = $this->createDeleteForm($id);
|
||||
|
||||
$options = $this->getOptionsAvailable($entity->getEntity());
|
||||
|
||||
return $this->render('ChillCustomFieldsBundle:CustomFieldsGroup:show.html.twig', array(
|
||||
'entity' => $entity,
|
||||
'delete_form' => $deleteForm->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.
|
||||
@ -123,12 +206,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(),
|
||||
));
|
||||
}
|
||||
|
||||
@ -149,6 +230,37 @@ class CustomFieldsGroupController extends Controller
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
private function createCreateFieldForm(CustomFieldsGroup $customFieldsGroup)
|
||||
{
|
||||
|
||||
$fieldChoices = array();
|
||||
foreach ($this->get('chill.custom_field.provider')->getAllFields()
|
||||
as $key => $customType) {
|
||||
$fieldChoices[$key] = $customType->getName();
|
||||
}
|
||||
|
||||
$customfield = (new CustomField())
|
||||
->setCustomFieldsGroup($customFieldsGroup);
|
||||
|
||||
$builder = $this->get('form.factory')
|
||||
->createNamedBuilder(null, 'form', $customfield, array(
|
||||
'method' => 'GET',
|
||||
'action' => $this->generateUrl('customfield_new'),
|
||||
'csrf_protection' => false
|
||||
))
|
||||
->add('type', 'choice', array(
|
||||
'choices' => $fieldChoices
|
||||
))
|
||||
->add('customFieldsGroup', 'hidden')
|
||||
->add('submit', 'submit');
|
||||
$builder->get('customFieldsGroup')
|
||||
->addViewTransformer(new CustomFieldsGroupToIdTransformer(
|
||||
$this->getDoctrine()->getManager()));
|
||||
|
||||
return $builder->getForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits an existing CustomFieldsGroup entity.
|
||||
*
|
||||
@ -163,61 +275,72 @@ class CustomFieldsGroupController extends Controller
|
||||
throw $this->createNotFoundException('Unable to find CustomFieldsGroup entity.');
|
||||
}
|
||||
|
||||
$deleteForm = $this->createDeleteForm($id);
|
||||
$editForm = $this->createEditForm($entity);
|
||||
$editForm->handleRequest($request);
|
||||
|
||||
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,
|
||||
'edit_form' => $editForm->createView(),
|
||||
'delete_form' => $deleteForm->createView(),
|
||||
));
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a CustomFieldsGroup entity.
|
||||
*
|
||||
* Set the CustomField Group with id $cFGroupId as default
|
||||
*/
|
||||
public function deleteAction(Request $request, $id)
|
||||
public function makeDefaultAction(Request $request)
|
||||
{
|
||||
$form = $this->createDeleteForm($id);
|
||||
|
||||
$form = $this->createMakeDefaultForm(null);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isValid()) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$entity = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->find($id);
|
||||
$cFGroupId = $form->get('id')->getData();
|
||||
|
||||
if (!$entity) {
|
||||
throw $this->createNotFoundException('Unable to find CustomFieldsGroup entity.');
|
||||
}
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
$em->remove($entity);
|
||||
$em->flush();
|
||||
$cFGroup = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsGroup')->findOneById($cFGroupId);
|
||||
|
||||
if(!$cFGroup) {
|
||||
throw $this
|
||||
->createNotFoundException("customFieldsGroup not found with "
|
||||
. "id $cFGroupId");
|
||||
}
|
||||
|
||||
return $this->redirect($this->generateUrl('customfieldsgroup'));
|
||||
}
|
||||
$cFDefaultGroup = $em->getRepository('ChillCustomFieldsBundle:CustomFieldsDefaultGroup')
|
||||
->findOneByEntity($cFGroup->getEntity());
|
||||
|
||||
/**
|
||||
* 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()
|
||||
;
|
||||
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();
|
||||
|
||||
$this->addFlash('success', $this->get('translator')
|
||||
->trans("The default custom fields group has been changed"));
|
||||
|
||||
return $this->redirect($this->generateUrl('customfieldsgroup'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,7 +381,7 @@ class CustomFieldsGroupController extends Controller
|
||||
}
|
||||
|
||||
var_dump($form->getData());
|
||||
var_dump(json_encode($form->getData()));
|
||||
var_dump(json_enccode($form->getData()));
|
||||
}
|
||||
|
||||
|
||||
|
37
CustomFields/AbstractCustomField.php
Normal file
37
CustomFields/AbstractCustomField.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\CustomFieldsBundle\CustomFields;
|
||||
|
||||
use Chill\CustomFieldsBundle\CustomFields\CustomFieldInterface;
|
||||
use Chill\CustomFieldsBundle\Entity\CustomField;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
abstract class AbstractCustomField implements CustomFieldInterface
|
||||
{
|
||||
public function isEmptyValue($value, CustomField $customField)
|
||||
{
|
||||
return (empty($value) and $value !== FALSE);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
@ -38,45 +38,44 @@ use Symfony\Component\Translation\Translator;
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @author Marc Ducobu <marc@champs-libes.coop>
|
||||
*/
|
||||
class CustomFieldChoice implements CustomFieldInterface
|
||||
class CustomFieldChoice extends AbstractCustomField
|
||||
{
|
||||
const ALLOW_OTHER = 'other';
|
||||
const ALLOW_OTHER = 'other';
|
||||
const OTHER_VALUE_LABEL = 'otherValueLabel';
|
||||
const MULTIPLE = 'multiple';
|
||||
const EXPANDED = 'expanded';
|
||||
const CHOICES = 'choices';
|
||||
const MULTIPLE = 'multiple';
|
||||
const EXPANDED = 'expanded';
|
||||
const CHOICES = 'choices';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var RequestStack
|
||||
*/
|
||||
private $requestStack;
|
||||
|
||||
private $defaultLocales;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var TwigEngine
|
||||
*/
|
||||
private $templating;
|
||||
/**
|
||||
*
|
||||
* @var RequestStack
|
||||
*/
|
||||
private $requestStack;
|
||||
|
||||
private $defaultLocales;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var TwigEngine
|
||||
*/
|
||||
private $templating;
|
||||
|
||||
/**
|
||||
* @var TranslatableStringHelper Helper that find the string in current locale from an array of translation
|
||||
*/
|
||||
private $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
RequestStack $requestStack,
|
||||
Translator $translator,
|
||||
TwigEngine $templating,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
)
|
||||
{
|
||||
$this->requestStack = $requestStack;
|
||||
$this->defaultLocales = $translator->getFallbackLocales();
|
||||
$this->templating = $templating;
|
||||
public function __construct(
|
||||
RequestStack $requestStack,
|
||||
Translator $translator,
|
||||
TwigEngine $templating,
|
||||
TranslatableStringHelper $translatableStringHelper)
|
||||
{
|
||||
$this->requestStack = $requestStack;
|
||||
$this->defaultLocales = $translator->getFallbackLocales();
|
||||
$this->templating = $templating;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, CustomField $customField)
|
||||
{
|
||||
@ -93,11 +92,10 @@ class CustomFieldChoice implements CustomFieldInterface
|
||||
|
||||
//prepare $options
|
||||
$options = array(
|
||||
'multiple' => $customFieldOptions[self::MULTIPLE],
|
||||
'choices' => $choices,
|
||||
'required' => false,
|
||||
'label' => $this->translatableStringHelper->localize($customField->getName())
|
||||
);
|
||||
'multiple' => $customFieldOptions[self::MULTIPLE],
|
||||
'choices' => $choices,
|
||||
'required' => $customField->isRequired(),
|
||||
'label' => $this->translatableStringHelper->localize($customField->getName()));
|
||||
|
||||
//if allow_other = true
|
||||
if ($customFieldOptions[self::ALLOW_OTHER] == true) {
|
||||
@ -124,37 +122,35 @@ class CustomFieldChoice implements CustomFieldInterface
|
||||
$builder->create($customField->getSlug(), 'choice', $options)
|
||||
->addModelTransformer(new CustomFieldDataTransformer($this, $customField))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function buildOptionsForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add(self::MULTIPLE, 'choice', array(
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'choices' => array(
|
||||
1 => 'Multiple',
|
||||
0 => 'Unique'
|
||||
),
|
||||
'empty_data' => 0
|
||||
))
|
||||
$builder
|
||||
->add(self::MULTIPLE, 'choice', array(
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'choices' => array(
|
||||
1 => 'Multiple',
|
||||
0 => 'Unique'),
|
||||
'empty_data' => 0,
|
||||
'label' => 'Multiplicity'
|
||||
))
|
||||
->add(self::EXPANDED, 'choice', array(
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'choices' => array(
|
||||
1 => 'Expanded',
|
||||
0 => 'Non expanded'
|
||||
),
|
||||
'empty_data' => 0
|
||||
))
|
||||
0 => 'Non expanded'),
|
||||
'empty_data' => 0,
|
||||
'label' => 'Choice display'
|
||||
))
|
||||
->add(self::ALLOW_OTHER, 'choice', array(
|
||||
'label' => 'Allow other',
|
||||
'choices' => array(
|
||||
0 => 'No',
|
||||
1 => 'Yes'
|
||||
),
|
||||
1 => 'Yes'),
|
||||
'empty_data' => 0,
|
||||
'expanded' => true,
|
||||
'multiple' => false
|
||||
@ -164,21 +160,133 @@ class CustomFieldChoice implements CustomFieldInterface
|
||||
->add(self::CHOICES, new ChoicesType(), array(
|
||||
'type' => new ChoicesListType($this->defaultLocales),
|
||||
'allow_add' => true
|
||||
))
|
||||
;
|
||||
));
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return 'Choices';
|
||||
}
|
||||
|
||||
public function isEmptyValue($value, CustomField $customField)
|
||||
{
|
||||
if ($value === NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
return empty($value['_choices']);
|
||||
} else { // we do not have 'allow other'
|
||||
return empty($value);
|
||||
}
|
||||
} else {
|
||||
return empty($value);
|
||||
}
|
||||
|
||||
throw \LogicException("This case is not expected.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -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,11 +51,19 @@ 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
|
||||
* @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);
|
||||
}
|
||||
|
161
CustomFields/CustomFieldLongChoice.php
Normal file
161
CustomFields/CustomFieldLongChoice.php
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\CustomFieldsBundle\CustomFields;
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class CustomFieldLongChoice extends AbstractCustomField
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @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,
|
||||
'required' => $customField->isRequired(),
|
||||
'placeholder' => 'Choose a value',
|
||||
'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 field';
|
||||
}
|
||||
|
||||
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' => $option === NULL ? array() : array($option)
|
||||
));
|
||||
}
|
||||
|
||||
public function serialize($value, \Chill\CustomFieldsBundle\Entity\CustomField $customField)
|
||||
{
|
||||
if ($value === NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
181
CustomFields/CustomFieldNumber.php
Normal file
181
CustomFields/CustomFieldNumber.php
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
|
||||
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
* @author Marc Ducobu <marc@champs-libres.coop>
|
||||
*/
|
||||
class CustomFieldNumber extends AbstractCustomField
|
||||
{
|
||||
/**
|
||||
* 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 field';
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -33,7 +33,7 @@ use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @author Marc Ducobu <marc@champs-libres.coop>
|
||||
*/
|
||||
class CustomFieldText implements CustomFieldInterface
|
||||
class CustomFieldText extends AbstractCustomField
|
||||
{
|
||||
|
||||
private $requestStack;
|
||||
@ -114,7 +114,7 @@ class CustomFieldText implements CustomFieldInterface
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'text field';
|
||||
return 'Text field';
|
||||
}
|
||||
|
||||
public function buildOptionsForm(FormBuilderInterface $builder)
|
||||
@ -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
|
||||
))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -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';
|
||||
@ -90,16 +90,24 @@ class CustomFieldTitle implements CustomFieldInterface
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'title';
|
||||
return 'Title';
|
||||
}
|
||||
|
||||
public function isEmptyValue($value, CustomField $customField)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
172
DataFixtures/ORM/LoadOption.php
Normal file
172
DataFixtures/ORM/LoadOption.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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);
|
||||
;
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
153
Entity/CustomFieldLongChoice/Option.php
Normal file
153
Entity/CustomFieldLongChoice/Option.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
77
EntityRepository/CustomFieldLongChoice/OptionRepository.php
Normal file
77
EntityRepository/CustomFieldLongChoice/OptionRepository.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\CustomFieldsBundle\EntityRepository\CustomFieldLongChoice;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Chill\CustomFieldsBundle\Entity\CustomFieldLongChoice\Option;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -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,12 +49,28 @@ 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('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)
|
||||
{
|
||||
@ -62,14 +87,14 @@ class CustomFieldType extends AbstractType
|
||||
|
||||
|
||||
$builder->add(
|
||||
$this->customFieldProvider
|
||||
->getCustomFieldByType($options['type'])
|
||||
->buildOptionsForm(
|
||||
$builder
|
||||
->create('options', null, array('compound' => true))
|
||||
$this->customFieldProvider
|
||||
->getCustomFieldByType($options['type'])
|
||||
->buildOptionsForm(
|
||||
$builder
|
||||
->create('options', null, array('compound' => true))
|
||||
->setRequired(false)
|
||||
)
|
||||
);
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,10 +106,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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,14 @@ class CustomFieldsGroupToIdTransformer implements DataTransformerInterface
|
||||
if (null === $customFieldsGroup) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!$customFieldsGroup instanceof CustomFieldsGroup) {
|
||||
throw new TransformationFailedException(sprintf('Transformation failed: '
|
||||
. 'the expected type of the transforme function is an '
|
||||
. 'object of type Chill\CustomFieldsBundle\Entity\CustomFieldsGroup, '
|
||||
. '%s given (value : %s)', gettype($customFieldsGroup),
|
||||
$customFieldsGroup));
|
||||
}
|
||||
|
||||
return $customFieldsGroup->getId();
|
||||
}
|
||||
@ -49,6 +57,14 @@ class CustomFieldsGroupToIdTransformer implements DataTransformerInterface
|
||||
if (!$id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($id instanceof CustomFieldsGroup) {
|
||||
throw new TransformationFailedException(sprintf(
|
||||
'The transformation failed: the expected argument on '
|
||||
. 'reverseTransform is an object of type int,'
|
||||
. 'Chill\CustomFieldsBundle\Entity\CustomFieldsGroup, '
|
||||
. 'given', gettype($id)));
|
||||
}
|
||||
|
||||
$customFieldsGroup = $this->om
|
||||
->getRepository('ChillCustomFieldsBundle:customFieldsGroup')->find($id)
|
||||
|
53
Form/Extension/PostTextExtension.php
Normal file
53
Form/Extension/PostTextExtension.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
37
Form/Extension/PostTextIntegerExtension.php
Normal file
37
Form/Extension/PostTextIntegerExtension.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Form\Extension;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||
|
||||
/**
|
||||
* This class add the PostTextExtension to integer fields
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class PostTextIntegerExtension extends PostTextExtension
|
||||
{
|
||||
public function getExtendedType()
|
||||
{
|
||||
// return IntegerType::class; !! only for symfony 2.8
|
||||
return 'integer';
|
||||
}
|
||||
|
||||
}
|
34
Form/Extension/PostTextNumberExtension.php
Normal file
34
Form/Extension/PostTextNumberExtension.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Form\Extension;
|
||||
|
||||
/**
|
||||
* This class add the PostTextExtension to number fields
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class PostTextNumberExtension extends PostTextExtension
|
||||
{
|
||||
public function getExtendedType()
|
||||
{
|
||||
return 'number';
|
||||
}
|
||||
|
||||
}
|
@ -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(
|
||||
|
||||
@ -39,9 +38,9 @@ class ChoicesListType extends AbstractType
|
||||
|
||||
if (NULL === $formData['slug']) {
|
||||
$slug = $form['name'][$locales[0]]->getData();
|
||||
$slug= strtolower($slug);
|
||||
$slug= preg_replace('/[^a-zA-Z0-9 -]/','', $slug); // only take alphanumerical characters, but keep the spaces and dashes too...
|
||||
$slug= str_replace(' ','-', $slug); // replace spaces by dashes
|
||||
$slug = strtolower($slug);
|
||||
$slug = preg_replace('/[^a-zA-Z0-9 -]/','', $slug); // only take alphanumerical characters, but keep the spaces and dashes too...
|
||||
$slug = str_replace(' ','-', $slug); // replace spaces by dashes
|
||||
|
||||
$data['slug'] = $slug;
|
||||
$event->setData($data);
|
||||
|
@ -21,6 +21,4 @@ class ChoicesType extends AbstractType
|
||||
{
|
||||
return 'collection';
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
CustomFields
|
||||
============
|
||||
|
||||
[](http://travis-ci.org/#!/Chill-project/CustomFields)
|
||||
The bundle for adding custom fields to Chill. This bundle is part of the Chill project.
|
||||
|
||||
Add custom fields to entities
|
||||
Documentation & installation
|
||||
============================
|
||||
|
||||
This bundle is part of the Chill project.
|
||||
Read documentation here : http://chill.readthedocs.org
|
||||
|
@ -22,6 +22,8 @@ Chill\CustomFieldsBundle\Entity\CustomField:
|
||||
type: float
|
||||
options:
|
||||
type: json_array
|
||||
required:
|
||||
type: boolean
|
||||
lifecycleCallbacks: { }
|
||||
manyToOne:
|
||||
customFieldGroup:
|
||||
|
@ -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
|
||||
|
@ -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: /
|
@ -1,15 +1,12 @@
|
||||
customfield:
|
||||
customfield_section:
|
||||
path: /{_locale}/admin/customfield/
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:CustomField:index" }
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:Admin:index" }
|
||||
options:
|
||||
menus:
|
||||
admin:
|
||||
admin_section:
|
||||
order: 1000
|
||||
label: "CustomFields"
|
||||
|
||||
customfield_show:
|
||||
path: /{_locale}/admin/customfield/{id}/show
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:CustomField:show" }
|
||||
label: "Custom fields configuration"
|
||||
icons: ['asterisk']
|
||||
|
||||
customfield_new:
|
||||
path: /{_locale}/admin/customfield/new
|
||||
@ -28,8 +25,3 @@ customfield_update:
|
||||
path: /{_locale}/admin/customfield/{id}/update
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:CustomField:update" }
|
||||
requirements: { _method: post|put }
|
||||
|
||||
customfield_delete:
|
||||
path: /{_locale}/admin/customfield/{id}/delete
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:CustomField:delete" }
|
||||
requirements: { _method: post|delete }
|
||||
|
@ -1,12 +0,0 @@
|
||||
customfieldsdefaultgroup:
|
||||
path: /{_locale}/admin/customfieldsdefaultgroup/
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsDefaultGroup:list" }
|
||||
options:
|
||||
menus:
|
||||
admin:
|
||||
order: 1000
|
||||
label: "CustomFields Default Groups : List"
|
||||
|
||||
customfieldsdefaultgroup_set:
|
||||
path: /{_locale}/admin/customfieldsdefaultgroup/set/group/as/default/
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsDefaultGroup:setAGroupAsDefault" }
|
@ -3,13 +3,17 @@ customfieldsgroup:
|
||||
defaults: { _controller: "ChillCustomFieldsBundle:CustomFieldsGroup:index" }
|
||||
options:
|
||||
menus:
|
||||
admin:
|
||||
admin_custom_fields:
|
||||
order: 1010
|
||||
label: "CustomFields Groups"
|
||||
|
||||
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
|
||||
|
@ -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' }
|
||||
|
||||
@ -38,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
|
||||
@ -87,5 +106,23 @@ services:
|
||||
class: Chill\CustomFieldsBundle\Templating\Twig\CustomFieldsGroupRenderingTwig
|
||||
calls:
|
||||
- [setContainer, ["@service_container"]]
|
||||
arguments:
|
||||
- "%chill_custom_fields.show_empty_values%"
|
||||
tags:
|
||||
- { name: twig.extension }
|
||||
- { 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"
|
||||
|
35
Resources/migrations/Version20151210155904.php
Normal file
35
Resources/migrations/Version20151210155904.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Application\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
class Version20151210155904 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// this up() 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 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');
|
||||
|
||||
}
|
||||
}
|
47
Resources/migrations/Version20151210205610.php
Normal file
47
Resources/migrations/Version20151210205610.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Application\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
class Version20151210205610 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->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');
|
||||
}
|
||||
}
|
@ -1,3 +1,96 @@
|
||||
'Not available in your language': 'Traduction pas disponible dans votre langue'
|
||||
'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
|
||||
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: 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
|
||||
Any field is currently associated with this group: Aucun champ n'est associé à ce groupe actuellement
|
||||
Create a new field: Créer un champ personnalisé
|
||||
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é
|
||||
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
|
||||
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é
|
||||
CustomField creation: Nouveau champ personnalisé
|
||||
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éé
|
||||
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
|
||||
Title: Titre
|
||||
text: texte
|
||||
Text field: Champ texte
|
||||
|
||||
#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
|
||||
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
|
||||
|
||||
#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
|
||||
Number field: Champ nombre
|
||||
|
||||
#custom field long choice
|
||||
Options key: Clé des options
|
||||
Choose a value: Choisissez une valeur
|
||||
Long choice field: Champ à choix pré-enregistrés
|
||||
|
31
Resources/views/Admin/layout.html.twig
Normal file
31
Resources/views/Admin/layout.html.twig
Normal file
@ -0,0 +1,31 @@
|
||||
{#
|
||||
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
|
||||
<info@champs-libres.coop> / <http://www.champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
|
||||
{% 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 %}<!-- block personcontent empty -->
|
||||
<h1>{{ 'CustomFields configuration' |trans }}</h1>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
20
Resources/views/Admin/menu.html.twig
Normal file
20
Resources/views/Admin/menu.html.twig
Normal file
@ -0,0 +1,20 @@
|
||||
{#
|
||||
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
|
||||
<info@champs-libres.coop> / <http://www.champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
|
||||
{% extends "ChillMainBundle::Menu/verticalMenu.html.twig" %}
|
||||
{% block v_menu_title %}{{ 'Custom fields configuration menu'|trans }}{% endblock %}
|
@ -14,19 +14,36 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block title %}{{ 'CustomField edit'|trans }}{% endblock title %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomField edit</h1>
|
||||
<h1>{{ 'CustomField edit'|trans }}</h1>
|
||||
|
||||
{{ form(edit_form) }}
|
||||
<h2>{{ 'General informations'|trans }}</h2>
|
||||
{{ 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) }}
|
||||
{{ form_row(edit_form.required) }}
|
||||
{% if edit_form.options is not empty %}
|
||||
<h2>{{ 'Options'|trans }}</h2>
|
||||
{% for option in edit_form.options %}
|
||||
{{ form_row(option) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{{ form_row(edit_form.submit, {'attr': { 'class': 'sc-button btn-update' } } ) }}
|
||||
{{ form_end(edit_form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('customfield') }}">
|
||||
Back to the list
|
||||
<a href="{{ path('customfieldsgroup_show', { 'id': entity.customFieldsGroup.id }) }}" class="sc-button btn-reset">
|
||||
{{ 'Back to the group'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>{{ form(delete_form) }}</li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
@ -1,66 +0,0 @@
|
||||
{#
|
||||
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomField list</h1>
|
||||
|
||||
<table class="records_list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Label</th>
|
||||
<th>Type</th>
|
||||
<th>Active</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entity in entities %}
|
||||
<tr>
|
||||
<td><a href="{{ path('customfield_show', { 'id': entity.id }) }}">{{ entity.id }}</a></td>
|
||||
<td>{{ entity.name(app.request.locale) }}</td>
|
||||
<td>{{ entity.type }}</td>
|
||||
<td>{{ entity.active }}</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ path('customfield_show', { 'id': entity.id }) }}">show</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('customfield_edit', { 'id': entity.id }) }}">edit</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_row(form) }}
|
||||
<button type="submit">
|
||||
Create a new entry
|
||||
</button>
|
||||
|
||||
{{ form_end(form) }}
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock %}
|
@ -14,17 +14,43 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block title %}{{ 'CustomField creation'|trans }}{% endblock title %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomField creation</h1>
|
||||
<h1>{{ 'CustomField creation'|trans }}</h1>
|
||||
|
||||
{{ form(form) }}
|
||||
<ul class="record_actions">
|
||||
<h2>{{ 'General informations'|trans }}</h2>
|
||||
{{ form_start(form) }}
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.active) }}
|
||||
{{ form_row(form.slug) }}
|
||||
{% if form.customFieldsGroup is defined %}
|
||||
{{ form_row(form.customFieldsGroup) }}
|
||||
{% endif %}
|
||||
{{ form_row(form.ordering) }}
|
||||
{{ form_row(form.required) }}
|
||||
{% if form.options is not empty %}
|
||||
<h2>{{ 'Options'|trans }}</h2>
|
||||
{% for option in form.options %}
|
||||
{{ form_row(option) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{{ form_row(form.submit, {'attr': { 'class': 'sc-button btn-create' } } ) }}
|
||||
{{ form_end(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('customfield') }}">
|
||||
Back to the list
|
||||
{% if entity.customFieldsGroup is not null %}
|
||||
<a href="{{ path('customfieldsgroup_show', { 'id': entity.customFieldsGroup.id }) }}" class="sc-button btn-reset">
|
||||
{{ 'Back to the group'|trans }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ path('customfieldsgroup') }}" class="sc-button btn-reset">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
@ -1 +1 @@
|
||||
{{ customField.name(app.request.locale) }}
|
||||
{{ customField.name|localize_translatable_string }}
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomField</h1>
|
||||
|
@ -1,46 +0,0 @@
|
||||
{#
|
||||
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomFieldsDefaultGroup list</h1>
|
||||
|
||||
<table class="records_list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Entity</th>
|
||||
<th>CustomFieldGroup</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for defaultGroup in defaultGroups %}
|
||||
<tr>
|
||||
<td>{{ defaultGroup.entity }}</td>
|
||||
<td>{{ defaultGroup.customFieldsGroup.name['fr'] }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_row(form.cFGroup) }}
|
||||
|
||||
<button type="submit">
|
||||
set as Default
|
||||
</button>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
@ -14,19 +14,32 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block title %}{{ 'CustomFieldsGroup edit'|trans }}{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomFieldsGroup edit</h1>
|
||||
<h1>{{ 'CustomFieldsGroup edit'|trans }}</h1>
|
||||
|
||||
{{ form(edit_form) }}
|
||||
{{ form_start(edit_form) }}
|
||||
{{ form_row(edit_form.name) }}
|
||||
{{ form_row(edit_form.entity) }}
|
||||
{% if edit_form.options is defined %}
|
||||
{{ form_row(edit_form.options) }}
|
||||
{% endif %}
|
||||
{{ form_row(edit_form.submit, { 'attr': { 'class': 'sc-button bt-edit' } } ) }}
|
||||
{{ form_end(edit_form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup') }}">
|
||||
Back to the list
|
||||
<a href="{{ path('customfieldsgroup') }}" class="sc-button bt-cancel">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup_show', { 'id' : entity.id }) }}" class="sc-button bt-cancel">
|
||||
{{ 'show'|trans|capitalize }}
|
||||
</a>
|
||||
</li>
|
||||
<li>{{ form(delete_form) }}</li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
@ -14,33 +14,43 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block title %}{{ 'CustomFieldsGroup list'|trans }}{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomFieldsGroup list</h1>
|
||||
<h1>{{ 'CustomFieldsGroup list'|trans }}</h1>
|
||||
|
||||
<table class="records_list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Name</th>
|
||||
<th>Entity</th>
|
||||
<th>Actions</th>
|
||||
<th>{{ 'Name'|trans }}</th>
|
||||
<th>{{ 'Entity'|trans }}</th>
|
||||
<th>{{ 'Is default ?'|trans }} <i class="fa fa-info-circle" title="{{ 'Some module select default groups for some usage. Example: the default person group is shown under person page.'|trans|escape('html_attr') }}"></i></th>
|
||||
<th>{{ 'Actions'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entity in entities %}
|
||||
<tr>
|
||||
<td><a href="{{ path('customfieldsgroup_show', { 'id': entity.id }) }}">{{ entity.id }}</a></td>
|
||||
<td>{{ entity.name['fr'] }}</td>
|
||||
<td>{{ entity.entity }}</td>
|
||||
<td><a href="{{ path('customfieldsgroup_show', { 'id': entity.id }) }}">{{ entity.name|localize_translatable_string }}</a></td>
|
||||
<td>{{ entity.entity|trans }}</td>
|
||||
<td style="text-align: center;">
|
||||
{%- if entity.id in default_groups -%}
|
||||
<i class="fa fa-star"></i>
|
||||
{%- else -%}
|
||||
{{ form_start(make_default_forms[entity.id]) }}
|
||||
{{ form_widget(make_default_forms[entity.id].submit, { 'attr' : { 'class' : 'sc-button bt-action' } } ) }}
|
||||
{{ form_end(make_default_forms[entity.id]) }}
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup_show', { 'id': entity.id }) }}">show</a>
|
||||
<a href="{{ path('customfieldsgroup_show', { 'id': entity.id }) }}" class="sc-button">{{ 'show'|trans|capitalize }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup_edit', { 'id': entity.id }) }}">edit</a>
|
||||
<a href="{{ path('customfieldsgroup_edit', { 'id': entity.id }) }}" class="sc-button btn-edit">{{ 'edit'|trans|capitalize }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
@ -49,11 +59,9 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup_new') }}">
|
||||
Create a new entry
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<a href="{{ path('customfieldsgroup_new') }}" class="sc-button bt-create">
|
||||
{{ 'Create a new group'|trans }}
|
||||
</a>
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
@ -14,18 +14,19 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomFieldsGroup creation</h1>
|
||||
<h1>{{ 'CustomFieldsGroup creation'|trans }}</h1>
|
||||
|
||||
{{ form(form) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup') }}">
|
||||
Back to the list
|
||||
{{ form_start(form) }}
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.entity) }}
|
||||
<p>
|
||||
{{ form_widget(form.submit, { 'attr' : { 'class': 'sc-button bt-create' } } ) }}
|
||||
<a href="{{ path('customfieldsgroup') }}" class="sc-button bt-cancel">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
@ -1,8 +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 %}
|
||||
<dt>{{ chill_custom_field_label(customField) }}</dt>
|
||||
<dd>{{ chill_custom_field_widget(cFData , customField) }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{%- 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 -%}
|
||||
<dt class="custom_fields_group_rendering">{{ chill_custom_field_label(customField) }}</dt>
|
||||
<dd class="custom_fields_group_rendering">{{ chill_custom_field_widget(cFData , customField) }}</dd>
|
||||
{%- set something_has_been_printed = true -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
{% if something_has_been_printed == false %}
|
||||
<dt class="custom_field_no_data custom_fields_group_rendering">{{ 'Empty data'|trans }}</dt>
|
||||
<dd class="custom_field_no_data custom_fields_group_rendering">{{ 'No data to show' | trans }}</dd>
|
||||
{% endif %}
|
@ -14,39 +14,103 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
{% extends "ChillMainBundle::Admin/layout.html.twig" %}
|
||||
{% extends "ChillCustomFieldsBundle::Admin/layout.html.twig" %}
|
||||
|
||||
{% block title %}{{ 'CustomFieldsGroup details'|trans }}{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
<h1>CustomFieldsGroup</h1>
|
||||
<h1>{{ 'CustomFieldsGroup details'|trans }}</h1>
|
||||
|
||||
<table class="record_properties">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<td>{{ entity.id }}</td>
|
||||
<th>{{ 'Name'|trans }}</th>
|
||||
<td>{{ entity.getName|localize_translatable_string }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<td>{{ entity.getName(app.request.locale) }}</td>
|
||||
<th>{{ 'Entity'|trans }}</th>
|
||||
<td>{{ entity.entity|trans }}</td>
|
||||
</tr>
|
||||
{%- for key in options -%}
|
||||
<tr>
|
||||
<th>Entity</th>
|
||||
<td>{{ entity.entity }}</td>
|
||||
<th>{{ key ~ '_label'|trans }}</th>
|
||||
<td>
|
||||
{%- 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 -%}
|
||||
</td>
|
||||
</tr>
|
||||
{%- else -%}
|
||||
<!-- no option available for this entity -->
|
||||
{%- endfor -%}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup') }}">
|
||||
Back to the list
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup_edit', { 'id': entity.id }) }}">
|
||||
Edit
|
||||
</a>
|
||||
</li>
|
||||
<li>{{ form(delete_form) }}</li>
|
||||
</ul>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup') }}" class="sc-button bt-cancel">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('customfieldsgroup_edit', { 'id': entity.id }) }}" class="sc-button bt-edit">
|
||||
{{ 'Edit'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>{{ 'Fields associated with this group'|trans }}</h2>
|
||||
|
||||
{%- if entity.customFields|length > 0 -%}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'ordering'|trans|capitalize }}</th>
|
||||
<th>{{ 'label_field'|trans|capitalize }}</th>
|
||||
<th>{{ 'type'|trans|capitalize }}</th>
|
||||
<th>{{ 'active'|trans|capitalize }}</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%- for field in entity.customFields -%}
|
||||
<tr>
|
||||
<td>{{ field.ordering }}</td>
|
||||
<td>{{ field.name|localize_translatable_string }}</td>
|
||||
<td>{{ field.type|trans }}</td>
|
||||
<td style="text-align:center;">
|
||||
{%- if field.active -%}
|
||||
<i class="fa fa-check-square-o"></i>
|
||||
{%- else -%}
|
||||
<i class="fa fa-square-o"></i>
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td style="text-align:center">
|
||||
<a href="{{ path('customfield_edit', { 'id' : field.id }) }}" class="sc-button bt-edit">{{ 'edit'|trans|capitalize }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{%- endfor -%}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ form_start(create_field_form) }}
|
||||
<div class="grid-4">
|
||||
{{ form_widget(create_field_form.type) }}
|
||||
</div>
|
||||
{{ form_widget(create_field_form.submit, { 'attr': { 'class': 'sc-button bt-create' }, 'label': 'Add a new field' } ) }}
|
||||
{{ form_end(create_field_form) }}
|
||||
{%- else -%}
|
||||
<p>
|
||||
{{ 'Any field is currently associated with this group'|trans }}
|
||||
</p>
|
||||
{{ form_start(create_field_form) }}
|
||||
<div class="grid-4">
|
||||
{{ form_widget(create_field_form.type) }}
|
||||
</div>
|
||||
{{ form_widget(create_field_form.submit, { 'attr': { 'class': 'sc-button bt-create' }, 'label': 'Create a new field' } ) }}
|
||||
{{ form_end(create_field_form) }}
|
||||
{%- endif -%}
|
||||
{% endblock %}
|
||||
|
@ -1,23 +1,29 @@
|
||||
{% if selected|length > 0 %}
|
||||
<ul class="custom_fields choice">
|
||||
{%- for choice in choices -%}
|
||||
{% if choice['slug'] in selected %}{%- set is_selected = true -%}{%- else -%}{%- set is_selected = false -%}{%- endif -%}
|
||||
{%- if is_selected -%}
|
||||
<li class="{% if is_selected or expanded == 1 %} selected {% endif %}">
|
||||
{%- if is_selected -%}
|
||||
<i class="fa fa-check-square-o"></i>
|
||||
{%- else -%}
|
||||
<i class="fa fa-square-o"></i>
|
||||
{%- endif -%}
|
||||
{%- if choice['slug'] is not same as('_other') -%}
|
||||
{{ choice['name']|localize_translatable_string }}
|
||||
{%- else -%}
|
||||
{{ choice['name'] }}
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
<ul class="custom_fields choice">
|
||||
{%- for choice in choices -%}
|
||||
{% if choice['slug'] in selected %}
|
||||
{%- set is_selected = true -%}
|
||||
{%- else -%}
|
||||
{%- set is_selected = false -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- if is_selected -%}
|
||||
<li class="{% if is_selected or expanded == 1 %} selected {% endif %}">
|
||||
{%- if is_selected -%}
|
||||
<i class="fa fa-check-square-o"></i>
|
||||
{%- else -%}
|
||||
<i class="fa fa-square-o"></i>
|
||||
{%- endif -%}
|
||||
|
||||
{%- if choice['slug'] is not same as('_other') -%}
|
||||
{{ choice['name']|localize_translatable_string }}
|
||||
{%- else -%}
|
||||
{{ choice['name'] }}
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
{% else %}
|
||||
<div class="custom_fields_choice empty">{{ 'None'|trans }}</div>
|
||||
{% endif %}
|
11
Resources/views/CustomFieldsRendering/choice_long.html.twig
Normal file
11
Resources/views/CustomFieldsRendering/choice_long.html.twig
Normal file
@ -0,0 +1,11 @@
|
||||
{% if values|length > 0 %}
|
||||
<ul class="custom_fields long_choice {% if values|length == 1 %}unique{% endif %}">
|
||||
{%- for value in values -%}
|
||||
<li class="long_choice_item long_choice-key-{{ value.key }} long_choice-ikey-{{ value.internalKey }} long_choice-parent-ikey-{{ value.parent.internalKey }}">
|
||||
<i class="fa fa-check-square-o"></i> {{ value.text|localize_translatable_string }}
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
{% else %}
|
||||
<div class="custom_fields_choice long_choice empty">{{ 'None'|trans }}</div>
|
||||
{% endif %}
|
1
Resources/views/CustomFieldsRendering/number.html.twig
Normal file
1
Resources/views/CustomFieldsRendering/number.html.twig
Normal file
@ -0,0 +1 @@
|
||||
{% if number is not empty %}{{ number|number_format(scale) }} {{ post|default('') }}{% endif %}
|
@ -25,83 +25,60 @@
|
||||
{# 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 %}
|
||||
|
||||
{# 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 %}
|
||||
<h3>{{ 'Choices'|trans }}</h3>
|
||||
|
||||
<div id="{{ form.vars.id }}" data-prototype="{{- form_row(form.vars.prototype.children.name)
|
||||
~ form_row(form.vars.prototype.children.active)
|
||||
~ form_row(form.vars.prototype.children.slug) -}}">
|
||||
<table><tbody>
|
||||
{% for choice in form %}
|
||||
<tr><td>
|
||||
{{ form_row(choice.name) }}
|
||||
{{ form_row(choice.active) }}
|
||||
{{ form_row(choice.slug) }}
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</tbody></table>
|
||||
</div>
|
||||
|
||||
|
||||
{# we use javascrit to add an additional element. All functions are personnalized with the id ( = form.vars.id) #}
|
||||
<script type="text/javascript">
|
||||
function addElementInDiv(div_id) {
|
||||
var div = $('#' + div_id);
|
||||
var prototype = div.data('prototype');
|
||||
var index = div.data('index');
|
||||
var add_element_link = $('#' + div_id + '_add_element_link');
|
||||
var new_fields = prototype.replace(/__name__label__/g, index);
|
||||
var new_fields = prototype.replace(/__name__/g, index);
|
||||
|
||||
{{ form(form) }}
|
||||
div.data('index', index + 1);
|
||||
console.log(index);
|
||||
add_element_link.before(new_fields);
|
||||
}
|
||||
|
||||
<ul id="ul_{{ form.vars.id }}"></ul>
|
||||
{# we use javascrit to add an additional element. All functions are personnalized with the id ( = form.vars.id) #}
|
||||
<script type="text/javascript">
|
||||
var $collectionHolder_{{ form.vars.id }};
|
||||
function initializeCFChoiceOptionsChoices(div_id) {
|
||||
var add_element_link = $('<a id="' + div_id + '_add_element_link"" href="#" class="sc-button bt-submit">{{ 'Add an element'|trans }}</a>');
|
||||
var div = $('#' + div_id);
|
||||
div.append(add_element_link);
|
||||
div.data('index', div.find(':input').length / 5);
|
||||
|
||||
// setup an "add a tag" link
|
||||
var $addTagLink_{{ form.vars.id }} = $('<a href="#" class="add_tag_link">Add an element</a>');
|
||||
var $newLinkLi_{{ form.vars.id }} = $('<li></li>').append($addTagLink_{{ form.vars.id }});
|
||||
add_element_link.on('click', function (e) {
|
||||
e.preventDefault();
|
||||
addElementInDiv(div_id);
|
||||
});
|
||||
}
|
||||
|
||||
function initialize_{{ form.vars.id }}(ULelementId) {
|
||||
// Get the ul that holds the collection of tags
|
||||
$collectionHolder_{{ form.vars.id }} = $('#' + ULelementId);
|
||||
jQuery(document).ready(initializeCFChoiceOptionsChoices('{{ form.vars.id }}'));
|
||||
</script>
|
||||
{% endblock cf_choices_row %}
|
||||
|
||||
// add the "add a tag" anchor and li to the tags ul
|
||||
$collectionHolder_{{ form.vars.id }}.append($newLinkLi_{{ form.vars.id }});
|
||||
{# The choice_with_other_widget widget is defined in the main bundle #}
|
||||
|
||||
// count the current form inputs we have (e.g. 2), use that as the new
|
||||
// index when inserting a new item (e.g. 2)
|
||||
$collectionHolder_{{ form.vars.id }}.data('index', $collectionHolder_{{ form.vars.id }}.find(':input').length);
|
||||
|
||||
$addTagLink_{{ form.vars.id }}.on('click', function(e) {
|
||||
// prevent the link from creating a "#" on the URL
|
||||
e.preventDefault();
|
||||
|
||||
// add a new tag form (see next code block)
|
||||
addTagForm_{{ form.vars.id }}($collectionHolder_{{ form.vars.id }}, $newLinkLi_{{ form.vars.id }});
|
||||
});
|
||||
};
|
||||
|
||||
function addTagForm_{{ form.vars.id }}(collection, newLinkLi) {
|
||||
console.log($collectionHolder_{{ form.vars.id }});
|
||||
// Get the data-prototype explained earlier
|
||||
var prototype = $( '#' + '{{ form.vars.id }}').data('prototype');
|
||||
console.log(prototype);
|
||||
// get the new index
|
||||
var index = collection.data('index');
|
||||
|
||||
// Replace '__name__' in the prototype's HTML to
|
||||
// instead be a number based on how many items we have
|
||||
var newForm = prototype.replace(/__name__/g, index);
|
||||
|
||||
// increase the index with one for the next item
|
||||
collection.data('index', index + 1);
|
||||
|
||||
// Display the form in the page in an li, before the "Add a tag" link li
|
||||
var $newFormLi = $('<li></li>').append(newForm);
|
||||
newLinkLi.before($newFormLi);
|
||||
};
|
||||
|
||||
|
||||
jQuery(document).ready(initialize_{{ form.vars.id }}('ul_' + '{{ form.vars.id }}'));
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock cf_choices_widget %}
|
||||
|
||||
{% block choice_with_other_widget %}
|
||||
<div {{ block('widget_container_attributes') }}>
|
||||
{%- for child in form.children._choices %}
|
||||
{{- form_widget(child) -}}
|
||||
{{- form_label(child) -}}
|
||||
{%- if child.vars.value == '_other' -%}
|
||||
{{- form_widget(form.children._other) -}}
|
||||
{%- endif -%}
|
||||
{% endfor -%}
|
||||
</div>
|
||||
|
||||
{% endblock choice_with_other_widget %}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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()
|
||||
*/
|
||||
|
@ -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']));
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
70
Tests/Controller/CustomFieldsGroupControllerTest.php
Normal file
70
Tests/Controller/CustomFieldsGroupControllerTest.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\Client;
|
||||
|
||||
class CustomFieldsGroupControllerTest extends WebTestCase
|
||||
{
|
||||
|
||||
public function testCompleteScenario()
|
||||
{
|
||||
self::bootKernel(array('environment' => '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');
|
||||
$crawler = $client->click($links->last()->link());
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$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"]');
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CustomFieldsBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
class CustomFieldsGroupControllerTest extends WebTestCase
|
||||
{
|
||||
/*
|
||||
public function testCompleteScenario()
|
||||
{
|
||||
// Create a new client to browse the application
|
||||
$client = static::createClient();
|
||||
|
||||
// Create a new entry in the database
|
||||
$crawler = $client->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());
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
422
Tests/CustomFields/CustomFieldsChoiceTest.php
Normal file
422
Tests/CustomFields/CustomFieldsChoiceTest.php
Normal file
@ -0,0 +1,422 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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
|
||||
//
|
||||
////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 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
|
||||
));
|
||||
|
||||
$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
|
||||
));
|
||||
|
||||
$isEmpty = $this->cfChoice->isEmptyValue($data, $customField);
|
||||
|
||||
$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())
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
191
Tests/CustomFields/CustomFieldsNumberTest.php
Normal file
191
Tests/CustomFields/CustomFieldsNumberTest.php
Normal file
@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
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('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");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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]'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
105
Tests/Templating/Twig/CustomFieldRenderingTwigTest.php
Normal file
105
Tests/Templating/Twig/CustomFieldRenderingTwigTest.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
* Copyright (C) 2015 Champs Libres <info@champs-libres.coop>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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é <julien.fastre@champs-libres.coop>
|
||||
* @author Champs Libres <info@champs-libres.coop>
|
||||
*/
|
||||
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");
|
||||
}
|
||||
}
|
@ -34,7 +34,9 @@
|
||||
"chill-project/main": "dev-master"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-fixtures-bundle": "~2.2@dev"
|
||||
"chill-project/person": "dev-master@dev",
|
||||
"fzaninotto/faker": "~1",
|
||||
"doctrine/doctrine-fixtures-bundle": "~2.2"
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": [
|
||||
|
Loading…
x
Reference in New Issue
Block a user