<?php
namespace App\Crud\Controller;
use App\Crud\Crud;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Pagerfanta\Pagerfanta;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use App\Crud\FormFilter\crudFilterType;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
//use Symfony\Component\Form\Extension\Core\Type\ChoiceType
use App\Crud\ParseConfig\ParseConfig;
use Symfony\Contracts\Translation\TranslatorInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
* crudController controller.
*/
class crudPlainController extends AbstractController
{
//CONSTANTES RELACIONADAS CON LAS PLANTILLAS POR DEFECTO EN CASO DE QUE NO SE
//ESPECIFIQUE NINGUNA
const defaultTwigIndexName = '@crud\crud\index.html.twig';
const defaultTwigInlineIndexName = '@crud\crud\index_inline.html.twig';
const defaultTwigNewName = '@crud\crud\new.html.twig';
const defaultModalTwigNewName = '@crud\crud\formulario_new_modal.html.twig';
const defaultTwigEditName = '@crud\crud\edit.html.twig';
const defaultTwigShowName = '@crud\crud\show.html.twig';
const defaultModalTwigEditName = '@crud\crud\formulario_edit_modal.html.twig';
const defaultModalTwigShowName = '@crud\crud\show_data.html.twig';
const defaultTwigExcelName = '@crud\crud\excel.html.twig';
//COSNTANTE QUE INDICA LA CANTIDAD DE COLUMNAS QUE TENDRÁ EL FORMULARIO DE
//FILTRADO EN CASO DE QUE NO SE ESPECIFIQUE NINGÚN OTRO
const defaultFilterColumns = 2;
//REQUEST OBJECT
protected $request;
protected $inline = false;
protected $ajax = false;
//PROPIEDADES RELACIONADAS CON LA IDENTIFICACION DE LA ENTIDAD A LA QUE SE
//LE HACE CRUD
protected $rol; //rol pasado en la ruta
protected $routeClassName; //Identificador de la clase en el mapa
protected $className; //Nombre real de la clase
protected $fabricante; //Fabricante de la clase
protected $bundle; //Bundle donde reside la clase
protected $entityFolder; //Folder donde reside el fichero que define la clase
protected $classFullName; //Calculado. Nombre completo de la clase: <Fabricante/Bundle/Folder/Clase>
protected $bundleName; //Calculado. Nombre del bundle: <FabricanteBundle>
//PROPIEDADES RELACIONADAS CON LAS PLANTILLAS QUE SE USARÁN PARA MOSTRAR LAS
//DISTINTAS OPERACIONES
protected $twigIndexName;
protected $twigNewName;
protected $twigShowName;
protected $twigEditName;
protected $heightModalForm;
protected $widthModalForm;
protected $heightModalShow;
protected $widthModalShow;
protected $indexInnerView;
protected $twigExcelName;
//PROPIEDADES RELACIONADAS CON LA OPERACION INDEX.
//
//Layout de la tabla
protected $columnAction;
protected $search;
protected $tableInfo;
protected $scrollY;
//BOTONES QUE SE MOSTRARÁN O NO.
protected $showInIndex;
protected $newInIndex;
protected $editInIndex;
protected $deleteInIndex;
protected $buttons; //Imágenes que se usarán para cada botón.
//
//FILTRADO
protected $showFilter;
protected $filterColumns;
protected $showColumns;
protected $filterData;
protected $formularioFiltro;
//
//PAGINADO
protected $paginator;
protected $showPaginator;
protected $maxPerPage = 10;
//PROPIEDADES RELACIONADAS CON LAS OPERACIONES NEW Y EDIT.
protected $showIdInForm;
protected $formulario;
protected $formColumns;
//OTRAS PROPIEDADES ÚTILES Y COMUNES A TODAS LAS OPERACIONES
protected $em;
protected $translator;
protected $translatorBase;
protected $booleans;
protected $paramsRequest;
protected $entities;
protected $oldEntity;
protected $logger;
protected $widthLabel;
protected $modal;
protected $mailer;
protected $session;
protected $dateFields = [];
protected $allowedRol = null;
protected $allowedINDEX = null;
protected $allowedCREATE = null;
protected $allowedUPDATE = null;
protected $allowedDELETE = null;
protected $allowedSHOW = null;
protected $accion;
protected function setDateToBeginMonth($fecha)
{
$year = $fecha->format('Y');
$month = $fecha->format('m');
$fecha->setDate($year, $month, 1);
$fecha->setTime(0,0,0);
return $fecha;
}
/*
* MÉTODOS DE LA CLASE
*/
public function __construct(TranslatorInterface $translator, LoggerInterface $logger, MailerInterface $mailer, RequestStack $requestStack, EntityManagerInterface $entityManager)
{
$this->translator = $translator;
$this->logger = $logger;
$this->mailer = $mailer;
$this->session = $requestStack->getSession();
$this->request = $requestStack->getCurrentRequest();
$this->em = $entityManager;
}
/*
* MÉTODOS COMUNES A UNA O VARIAS ACCIONES
*/
protected function comunCheckConstrains($entity)
{
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$paramsForFunctionInEntity['accion'] = $this->accion;
$paramsForFunctionInEntity['bundle_class'] = $this->bundleName . ':' . $this->className;
$paramsForFunctionInEntity['entity'] = $entity;
return $this->comunCheckNullableConstrains($entity)
&&
$this->comunCheckUniqueConstrains($entity)
&&
$this->checkNonUniqueConstrains($entity);
}
protected function comunCheckUniqueConstrains($entity)
{
$className = $this->classFullName;
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$constraints = $className::getUniqueConstraints($paramsForFunctionInEntity);
$existe = false;
if (isset($constraints['singles']))
foreach ($constraints['singles'] as $campo)
{
$search = array();
$value=$entity->getFieldValue($campo['nombre']);
if ($campo['association'])
if ($value)
$value=$value->getId();
else
continue;
$search[$campo['nombre']]=$value;
$otraEntidad = $this->em->getRepository($this->bundleName . '\\Entity\\' . $this->className)->findOneBy($search);
$existe = ($this->accion=='CREATE' && $otraEntidad)
||
( $otraEntidad && $entity->getId() != $otraEntidad->getId() );
if ($existe)
{
$this->session->getFlashBag()->set('danger',
$this->translator->trans(
'error.unique.single',
array('%className%' => strtoupper($this->translator->trans($this->routeClassName.'.singular',array(),'crud')),
'%fieldname%' => strtoupper($this->translator->trans($this->routeClassName.'.fields.'.$campo['nombre'],array(),'crud'))),
'crud'));
return false;
}
}
if (isset($constraints['composite']))
foreach ($constraints['composite'] as $nombre=>$columns)
{
$search = array();
$camposStr = '';
foreach ($columns as $campo)
{
if ($camposStr == '')
$camposStr .= $this->translator->trans($this->routeClassName.'.fields.'.$campo['nombre'],array(),'crud');
else
$camposStr .= ', '.$this->translator->trans($this->routeClassName.'.fields.'.$campo['nombre'],array(),'crud');
$value=$entity->getFieldValue($campo['nombre']);
if ($campo['association'] and $value)
$value=$value->getId();
if ($value)
$search[$campo['nombre']]=$value;
}
if (count($search)>1)
{
$otraEntidad = $this->em->getRepository($this->bundleName . '\\Entity\\' . $this->className)->findOneBy($search);
$existe = ($this->accion=='CREATE' && $otraEntidad)
||
( $otraEntidad && $entity->getId() != $otraEntidad->getId() );
if ($existe)
{
$this->session->getFlashBag()->set('danger',
$this->translator->trans(
'error.unique.composite',
array('%className%' => strtoupper($this->translator->trans($this->routeClassName.'.singular',array(),'crud')),
'%fieldname%' => strtoupper($camposStr)),
'crud'));
return false;
}
}
}
return true;
}
protected function getNullableConstraints($entity)
{
//Singles Unique Constraints
$nullableFields = array();
$properties = $this->em->getClassMetadata($this->classFullName)->fieldMappings;
$association = $this->em->getClassMetadata($this->classFullName)->associationMappings;
$formulario = $this->getFormulario($entity);
foreach ($formulario as $field=>$prop)
{
if ( isset($properties[$field]) && isset($properties[$field]['nullable']) && !$properties[$field]['nullable'])
{
$nullableFields[$field]=$field;
}
if ( isset($association[$field]) &&
( (isset($association[$field]['joinColumns'][0]['nullable']) && !$association[$field]['joinColumns'][0]['nullable']) || (isset($association[$field]['joinTable']['joinColumns'][0]['nullable']) && !$association[$field]['joinTable']['joinColumns'][0]['nullable'])))
{
$nullableFields[$field]=$field;
}
}
return $nullableFields;
}
protected function comunCheckNullableConstrains($entity)
{
$constraints = $this->getNullableConstraints($entity);
if (count($constraints)>0)
foreach ($constraints as $key=>$campo)
{
$valor = $entity->getFieldValue($campo);
if ($valor===null || $valor==='' || ($valor instanceof \Doctrine\Common\Collections\ArrayCollection && $valor->count()== 0))
{
$this->session->getFlashBag()->set('danger',
$this->translator->trans(
'error.nullable',
array('%fieldname%' => strtoupper($this->translator->trans($this->routeClassName.'.fields.'.$campo,array(),'crud'))),
'crud'));
return false;
}
}
return true;
}
protected function checkNonUniqueConstrains($entity)
{
$formulario= $this->getFormulario($entity);
foreach ($formulario as $campo)
{
if ($valor = $entity->getFieldValue($campo['nombre']))
{
if ($campo['type']=='integer' || $campo['type']=='smallint')
{
if (!is_numeric($valor) || !is_integer($valor*1))
{
$this->session->getFlashBag()->set('danger',
$this->translator->trans(
'error.integer',
array('%fieldname%' => strtoupper($this->translator->trans($this->translatorBase.'.fields.'.$campo['nombre'],array(),'crud'))),
'crud'));
return false;
}
}
else
if ($campo['type']=='float')
{
if (!is_numeric($valor) || !is_float($valor*1))
{
$this->session->getFlashBag()->set('danger',
$this->translator->trans(
'error.float',
array('%fieldname%' => strtoupper($this->translator->trans($this->translatorBase.'.fields.'.$campo['nombre'],array(),'crud'))),
'crud'));
return false;
}
}
}
}
return true;
}
protected function comunParamsForForm($entity=null)
{
$params = $this->comunParamsForFunctionsInEntity();
$params['accion'] = $this->accion;
$params['showIdInForm'] = $this->showIdInForm;
$params['entity'] = $entity;
return $params;
}
private function buildForm(&$params)
{
$builder = $this->createFormBuilder($params['entity'], array('allow_extra_fields'=>true));
$formulario = $this->getFormulario($params['entity']);
foreach ($formulario as $item)
{
$tipo = null;
$atributos = null;
if (isset($item['atributos']))
{
if (isset($item['atributos']['attr']['data-url']))
{
$item['atributos']['attr']['data-url'] = $params['url'];
}
//en caso de que la entidad tenga una relacion ManyToOne con otra y este atributo se llene a partir de haber seleccionado
//el valor del parent previamente, por lo que el valor de dicho padre no debe ser modificable y no se muestra
if (isset($item['atributos']['attr']['isparent']) and isset($params['paramsRequest']['idParent']))
{
$idParent = $params['paramsRequest']['idParent'];
//creando una query que devuelve una lista con solo la entity que tenga el valor del parent seleccionado
$item['atributos']['query_builder'] = function (EntityRepository $er) use ($idParent) {
return $er->createQueryBuilder('e')
->where('e.id = :id')
->setParameter('id', $idParent);
};
//eliminando que ponga el placeholder para que seleccione automaticamente el unico valor que hay en la lista devuelta por la query anterior
$item['atributos']['empty_value'] = false;
}
//para el caso de que exista una query_builder como atributo y ademas sea necesario reemplazar algun valor de esa query
//y dicho valor debe venir dentro del array de $params
if(isset($item['atributos']['attr']['query_builder']))
{
foreach ($item['atributos']['attr']['query_builder']['replace'] as $key){
$item['atributos']['attr']['query_builder']['params'] = str_replace($key, $params[$key], $item['atributos']['attr']['query_builder']['params']);
}
$item['atributos']['query_builder'] = $params['em']->getRepository($item['atributos']['attr']['query_builder']['entity'])->{$item['atributos']['attr']['query_builder']['funcion']}($item['atributos']['attr']['query_builder']['params']);
unset($item['atributos']['attr']['query_builder']);
}
$atributos = $item['atributos'];
}
if (isset($item['tipo']))
$tipo = $item['tipo'];
$nombre = $item['nombre'];
switch ($tipo)
{
/* case 'time':
$tipo = TimeType::class;
break;*/
case 'collection':
$tipo = CollectionType::class;
break;
case 'date':
$tipo = DateType::class;
$atributos['html5'] = false;
// $builder->add($nombre, $tipo, $atributos);
// $builder->get($nombre)->addViewTransformer(new DateTimeToStringTransformer(null, null, 'd-m-Y'));
// $builder->add($builder->create($nombre,$tipo,$atributos)->addViewTransformer(new DateTimeToStringTransformer()));
break;
case 'geometria':
$tipo = "Symfony\Component\Form\Extension\Core\Type\HiddenType";
// $builder->add($nombre, $tipo, $atributos);
break;
case 'biplane_enum':
if (isset($atributos['attr']['class']))
{
$class = str_replace('spinbox-input', '', $atributos['attr']['class']);
if ($class)
{
$atributos['attr']['class'] = $class;
}
else
{
unset($atributos['attr']['class']);
}
}
break;
case 'subcriber':
$builder->addEventSubscriber(new $item['atributos']['class_subcriber']($params['em'], $params['translator']));
break;
case 'Symfony\Component\Form\Extension\Core\Type\FileType':
$params['file'][$nombre] = $atributos['attr']['class'];
break;
}
if ($tipo != 'subcriber')
{
if ($atributos && isset($atributos['attr']['class']))
$atributos['attr']['class'].=' form-control';
else
$atributos['attr']['class']='form-control';
if (strpos($atributos['attr']['class'],'chosen-select')!==false)
{
$atributos['attr']['class'].=' chosen-pending';
}
$builder->add($nombre, $tipo, $atributos);
}
}
return $builder->getForm();
}
protected function comunParamsForFunctionsInEntity()
{
$params = array(
'em' => $this->em,
'rol' => $this->rol,
'routeClassName' => $this->routeClassName,
'user' => $this->getUser(),
'className' => $this->classFullName,
'session' => $this->session,
'translator' => $this->translator,
'translatorBase' => $this->translatorBase,
'filterData' => $this->filterData,
'paramsRequest' => $this->paramsRequest,
'viewWidth' => $this->session->get('view_width'),
'logger' => $this->logger,
);
unset($params['paramsRequest']['filterData']);
return $params;
}
protected function comunPersist($entity, $flush=true)
{
if (!$this->em)
$this->em = $this->getDoctrine()->getManager();
try
{
$isNew = $entity->getId()==null;
$this->em->persist($entity);
if($flush)
{
$this->em->flush();
if (!$this->ajax)
{
$texto = $isNew ? 'persist.success.create' : 'persist.success.update';
$this->session->getFlashBag()->set(
'info',
$this->translator->trans($texto, array(), 'crud')
);
}
}
return true;
}
catch (\Exception $exc)
{
if (!$this->ajax)
{
$texto = $isNew ? 'persist.fail.create' : 'persist.fail.update';
$this->session->getFlashBag()->set(
'danger',
$this->translator->trans($texto, array(), 'crud').' ( '.$exc->getMessage().' )'
);
}
$this->logger->error($exc->getTraceAsString());
return false;
}
}
protected function comunRemove($entity, $flush=true)
{
if (!$this->em)
$this->em = $this->getDoctrine()->getManager();
try {
$this->em->remove($entity);
if($flush){
$this->em->flush();
if (!$this->ajax)
{
$this->session->getFlashBag()->set('info', $this->translator
->trans('persist.success.delete', array(), 'crud'));
}
}
return true;
} catch (\Exception $exc) {
if (!$this->ajax)
{
$msg = $exc->getMessage();
if (strpos($msg,'Foreign')===false)
{
$this->session->getFlashBag()->set(
'danger',
$this->translator->trans('persist.fail.delete', array(), 'crud')
);
}
else
{
$this->session->getFlashBag()->set(
'danger',
$this->translator->trans('persist.fail.delete_foreign', array(), 'crud')
);
}
}
$this->logger->error($msg);
return false;
}
}
protected function setClassMap($routeClassName)
{
$parseConfig = new ParseConfig();
$config = $parseConfig->parse($this->container);
$this->booleans = $config['crudBooleans'];
$this->buttons = $config['crudButtons'];
$config = $config['crudMapping'];
$this->inline = false;
$inline = strrpos($routeClassName, '_inline');
if ($inline !== false)
{
$routeClassName = substr($routeClassName, 0, $inline);
$this->inline = true;
}
// $config = $this->container->getParameter('crudmapping');
if (isset($config[$routeClassName]))
{
$this->routeClassName = $routeClassName;
$properties = $config[$routeClassName];
if (isset($properties['allowedRol']))
{
$this->allowedRol = $properties['allowedRol'];
}
if (isset($properties['allowedINDEX']))
{
$this->allowedINDEX = $properties['allowedINDEX'];
}
if (isset($properties['allowedCREATE']))
{
$this->allowedCREATE = $properties['allowedCREATE'];
}
if (isset($properties['allowedUPDATE']))
{
$this->allowedUPDATE = $properties['allowedUPDATE'];
}
if (isset($properties['allowedDELETE']))
{
$this->allowedDELETE = $properties['allowedDELETE'];
}
if (isset($properties['allowedSHOW']))
{
$this->allowedSHOW = $properties['allowedSHOW'];
}
if (!$this->inline)
{
$this->translatorBase = $properties['translatorBase'];
if (isset($properties['className']))
{
$this->className = $properties['className'];
}
if (isset($properties['fabricante']))
{
$this->fabricante = $properties['fabricante'];
}
if (isset($properties['bundle']))
{
$this->bundle = $properties['bundle'];
}
if (isset($properties['bundlename']))
{
$this->bundleName = $properties['bundlename'];
}
if (isset($properties['entityfolder']))
{
$this->entityFolder = $properties['entityfolder'];
}
if (isset($properties['classfullname']))
{
$this->classFullName = $properties['classfullname'];
}
$this->modal = $properties['modal'];
$this->widthModalForm = $properties['widthModalForm'];
$this->heightModalForm = $properties['heightModalForm'];
$this->widthModalShow = $properties['widthModalShow'];
$this->heightModalShow = $properties['heightModalShow'];
if (isset($properties['indexInnerView']))
$this->indexInnerView = $properties['indexInnerView'];
if (isset($properties['twigIndexName']))
$this->twigIndexName = $properties['twigIndexName'];
else
if (!$this->twigIndexName)
$this->twigIndexName = self::defaultTwigIndexName;
if (isset($properties['twigNewName']))
{
$this->twigNewName = $properties['twigNewName'];
}
else
if (!$this->twigNewName || $this->twigNewName==self::defaultTwigNewName)
{
if ($this->modal)
{
$this->twigNewName = self::defaultModalTwigNewName;
}
else
{
$this->twigNewName = self::defaultTwigNewName;
}
}
if (isset($properties['twigEditName']))
$this->twigEditName = $properties['twigEditName'];
else
if (!$this->twigEditName || $this->twigEditName==self::defaultTwigEditName)
{
if ($this->modal)
$this->twigEditName = self::defaultModalTwigEditName;
else
$this->twigEditName = self::defaultTwigEditName;
}
if (isset($properties['twigShowName']))
$this->twigShowName = $properties['twigShowName'];
else
if (!$this->twigShowName || $this->twigShowName==self::defaultTwigShowName)
{
if ($this->modal)
$this->twigShowName = self::defaultModalTwigShowName;
else
$this->twigShowName = self::defaultTwigShowName;
}
if (isset($properties['twigexcelname']))
$this->twigExcelName = $properties['twigexcelname'];
else
if (!$this->twigExcelName || $this->twigExcelName==self::defaultTwigExcelName)
{
if ($this->modal)
$this->twigExcelName = self::defaultTwigExcelName;
else
$this->twigExcelName = self::defaultTwigExcelName;
}
$this->filterColumns = $properties['filterColumns'];
if (!isset($this->showColumns))
$this->showColumns = $properties['showColumns'];
if (!isset($this->formColumns))
$this->formColumns = $properties['formColumns'];
if (isset($properties['showIdInForm']))
$this->showIdInForm = $properties['showIdInForm'];
else
if (!isset($this->showIdInForm))
$this->showIdInForm = false;
if (isset($properties['showInIndex']))
$this->showInIndex = $properties['showInIndex'];
else
if (!isset($this->showInIndex))
$this->showInIndex = false;
if (isset($properties['newInIndex']))
$this->newInIndex = $properties['newInIndex'];
else
if (!isset($this->newInIndex))
$this->newInIndex = true;
if (isset($properties['deleteInIndex']))
$this->deleteInIndex = $properties['deleteInIndex'];
else
if (!isset($this->deleteInIndex))
$this->deleteInIndex = true;
if (isset($properties['editInIndex']))
$this->editInIndex = $properties['editInIndex'];
else
if (!isset($this->editInIndex))
$this->editInIndex = true;
if (isset($properties['showFilter']))
$this->showFilter = $properties['showFilter'];
else
if (!isset($this->showFilter))
$this->showFilter = true;
if (isset($properties['showPaginator']))
$this->showPaginator = $properties['showPaginator'];
else
if (!isset($this->showPaginator))
$this->showPaginator = true;
if (isset($properties['columnAction']))
$this->columnAction = $properties['columnAction'];
else
if (!isset($this->columnAction))
$this->columnAction = true;
if (isset($properties['search']))
$this->search = $properties['search'];
else
if (!isset($this->search))
$this->search = true;
if (isset($properties['tableInfo']))
$this->tableInfo = $properties['tableInfo'];
else
if (!isset($this->tableInfo))
$this->tableInfo = true;
if (isset($properties['scrollY']))
$this->scrollY = $properties['scrollY'];
else
if (!isset($this->scrollY))
$this->scrollY = null;
if (isset($properties['widthLabel']))
$this->widthLabel = $properties['widthLabel'];
else
if (!isset($this->widthLabel))
$this->widthLabel = '20%';
}
else
{
$this->twigIndexName = self::defaultTwigInlineIndexName;
}
}
else
{
throw new \RuntimeException(
$this->translator->trans(
'error.class_not_defined', array('%className%' => $this->routeClassName), 'crud'
)
);
}
return $config;
}
protected function comunSetFileFields($params, $form, $entity, $uploadDir = "uploads", $hashKey = '')
{
$deleteFiles = array();
if (isset($params['file']))
{
$oldfile=$this->request->get('oldfile');
foreach ($params['file'] as $fieldName=>$class)
{
if ($oldfile && isset($oldfile[$fieldName]) && $oldfile[$fieldName]=='deleted')
{
$deleteFiles[] = $fieldName;
}
$file = $form->get($fieldName);
$viewData = $file->getViewData();
if ($viewData instanceof \Symfony\Component\HttpFoundation\File\UploadedFile)
{
$fileName = $this->comunUpload($viewData, $uploadDir, $hashKey);
if ($fileName)
{
$adjunto = new $class();
$adjunto->setArchivo($viewData->getClientOriginalName());
$adjunto->setRuta($uploadDir);
$adjunto->setArchivoHash($fileName);
$adjunto->setSize(filesize($uploadDir.'/'.$fileName));
$this->em->persist($adjunto);
$this->em->flush();
$setMethod = 'set'.ucfirst($fieldName);
$entity->$setMethod($adjunto);
}
}
else
{
if ($oldfile && isset($oldfile[$fieldName]) && $oldfile[$fieldName]=='deleted')
{
$setMethod = 'set'.ucfirst($fieldName);
$entity->$setMethod(null);
}
}
}
}
return $deleteFiles;
}
protected function setParamsRequest()
{
$this->paramsRequest = array();
$keys = $this->request->query->keys();
foreach ($keys as $index=>$key)
{
$this->paramsRequest[$key]=$this->request->get($key);
}
$keys = $this->request->attributes->keys();
foreach ($keys as $index=>$key)
{
if (strpos($key,'_')!==0 && $key!='id' && $key!='routeClassName' && $key!='filterdata')
{
$this->paramsRequest[$key]=$this->request->get($key);
}
}
$keys = $this->request->request->keys();
foreach ($keys as $index=>$key)
{
if ($key!='crud_type')
{
$this->paramsRequest[$key]=$this->request->get($key);
}
}
}
protected function setFilterData($routeClassName)
{
$this->filterData = $this->request->get('filterData');
if (!$this->filterData)
$this->filterData=$this->session->get($routeClassName);
if (!$this->filterData)
$this->filterData=array();
}
protected function setInitialValues($rol, $routeClassName)
{
$this->rol = $rol;
$this->ajax = $this->request->get('_xml_http_request')==='true';
$this->setUtilProperties();
$this->setFilterData($routeClassName);
$this->setParamsRequest();
$this->setClassMap($routeClassName);
}
protected function setUtilProperties()
{
}
protected function comunUpload($file, $uploadDir, $hashKey)
{
if ($file){
$extension = pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
if (!$extension) {
// no se puede deducir la extensión
$extension = 'bin';
}
$fileName = $hashKey . rand(1, 99999999) . '.' . $extension;
rtrim($uploadDir,"/");
$file->move($uploadDir,$fileName);
return $fileName;
}else{
return null;
}
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN INDEX
*/
public function indexAction($rol, $routeClassName)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion = 'INDEX';
if (!$this->allowActionExecution())
{
return $this->render('@crud\\accesDenied.html.twig');
}
if (!$this->inline)
{
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$paramsForFunctionInEntity['showIdInForm'] = $this->showIdInForm;
$this->indexPrepareFilterForm($paramsForFunctionInEntity);
$paramsForFunctionInEntity['filterForm']= $this->formularioFiltro;
$this->entities = $this->indexLoadEntities($paramsForFunctionInEntity);
$this->session->set($routeClassName,$this->filterData);
//$this->paginator = $this->indexCreatePaginator($this->entities);
$this->paginator = null;
}
$params = $this->indexParamsForTwig($this->em);
if (isset($this->paramsRequest['view']))
return $this->render($this->paramsRequest['view'], $params);
else
return $this->render($this->twigIndexName, $params);
}
protected function getFormFilter()
{
$formulario = array();
$R = new \ReflectionClass($this->classFullName);
$fields = $R->getProperties(\ReflectionProperty::IS_PRIVATE);
$properties = $this->em->getClassMetadata($this->classFullName)->fieldMappings;
$association = $this->em->getClassMetadata($this->classFullName)->associationMappings;
foreach ($fields as $field)
{
$fieldname = $field->name;
$label = $this->translator->trans($this->routeClassName.'.fields.'.$fieldname, array(), 'crud');
if ($label == $this->routeClassName.'.fields.'.$fieldname)
{
$label = $this->translator->trans($this->translatorBase.'.fields.'.$fieldname, array(), 'crud');
}
if (isset($properties[$field->name]))
{
$prop = $properties[$fieldname];
if (isset($prop['id']) && $prop['id'] && (!isset($this->showIdInForm) || !$this->showIdInForm))
{
continue;
}
$formulario[$fieldname]=array('nombre' =>$fieldname,
'tipo' => null,
'type' => $prop['type'],
'atributos'=> array('label' => $label,
'required' => false,
'attr'=>array('style'=>'width: 100%')));
if ($prop['type']=='integer' || $prop['type']=='smallint')
{
$this->getFormFilterInteger($fieldname, $prop, $formulario);
}
if ($prop['type']=='boolean')
{
$this->getFormFilterBoolean($fieldname, $prop, $formulario);
}
if ($prop['type']=='datetime')
{
$this->getFormFilterDateTime($fieldname, $prop, $formulario);
}
}
if (isset($association[$field->name]))
{
$prop = $association[$fieldname];
if ((isset($prop['id']) && $prop['id'] && !$this->showIdInForm)
||
$this->isAdjunto($prop['targetEntity']))
continue;
$this->getFormFilterAssociation($fieldname, $prop, $formulario);
}
}
return $formulario;
}
protected function getFormFilterInteger($fieldname, $prop, &$formulario)
{
$formulario[$fieldname]['atributos']['attr']['class'] = 'spinbox-input';
$formulario[$fieldname]['atributos']['attr']['full_width'] = true;
}
protected function getFormFilterBoolean($fieldname, $prop, &$formulario)
{
$formulario[$fieldname]['tipo'] = 'Symfony\Component\Form\Extension\Core\Type\ChoiceType';
$formulario[$fieldname]['atributos']['choices']=array_flip(array('true'=>$this->translator->trans('choice_value.yes', array(), 'crud'),
'false'=>$this->translator->trans('choice_value.no', array(), 'crud')));
$formulario[$fieldname]['atributos']['placeholder'] = $this->translator->trans('choice_value.empty_value',array(),'crud');
$formulario[$fieldname]['atributos']['empty_data'] = null;
}
protected function getFormFilterDateTime($fieldname, $prop, &$formulario)
{
$label = $formulario[$fieldname]['atributos']['label'];
$formulario[$fieldname.'_WWdesdeWW']=array(
'nombre' => $fieldname.'_WWdesdeWW',
'tipo' => null,//'text',
'type' => $prop['type'],
'atributos' => array(
'label' => $label.
' '.
$this->translator->trans('range_values.since', array(), 'crud').':',
'required' => false,
'attr' => array(
'style'=>'width: 100%'
)
)
);
$formulario[$fieldname.'_WWhastaWW']=array(
'nombre' =>$fieldname.'_WWhastaWW',
'tipo' => null,//'text',
'type' => $prop['type'],
'atributos' => array(
'label' => $label.
' '.
$this->translator->trans('range_values.to', array(), 'crud').':',
'required' => false,
'attr' => array(
'style'=>'width: 100%'
)
)
);
if (isset($prop['columnDefinition']) && $prop['columnDefinition']=='fecha')
{
$formulario[$fieldname.'_WWdesdeWW']['tipo'] = 'date';
$formulario[$fieldname.'_WWdesdeWW']['atributos']['attr']['class']='campo_fecha date-picker';
$formulario[$fieldname.'_WWdesdeWW']['atributos']['attr']['data-date-format']="dd-mm-yyyy";
$formulario[$fieldname.'_WWhastaWW']['tipo'] = 'date';
$formulario[$fieldname.'_WWhastaWW']['atributos']['attr']['class']='campo_fecha date-picker';
$formulario[$fieldname.'_WWhastaWW']['atributos']['attr']['data-date-format']="dd-mm-yyyy";
}
unset($formulario[$fieldname]);
}
protected function getFormFilterAssociation($fieldname, $prop, &$formulario)
{
$label = $this->translator->trans($this->routeClassName.'.fields.'.$fieldname, array(), 'crud');
if ($label == $this->routeClassName.'.fields.'.$fieldname)
{
$label = $this->translator->trans($this->translatorBase.'.fields.'.$fieldname, array(), 'crud');
}
$formulario[$fieldname]=array(
'nombre' => $fieldname,
'tipo' => EntityType::class,
'type' => 'association',
'association' => $prop['type'],
'atributos' => array(
'label' => $label,
'required' => false,
'class' => $prop['targetEntity'],
'placeholder' => $this->translator->trans('choice_value.empty_value', array(), 'crud'),
'empty_data' => null,
'multiple' => true,
'attr' => array(
'class' =>'chosen-select',
'style' =>'width: 100%',
'data-placeholder' => $this->translator->trans('choice_value.empty_value', array(), 'crud')
)
)
);
}
protected function isAdjunto($aClassName)
{
$r = new \ReflectionClass($aClassName);
return $r->isSubclassOf('App\Crud\Entity\crudAdjunto');
}
private function indexShowFields()
{
$showFields = array();
$translator = $this->translator;
$className = $this->classFullName;
$R = new \ReflectionClass($className);
$fields = $R->getProperties(\ReflectionProperty::IS_PRIVATE);
$properties = $this->em->getClassMetadata($className)->fieldMappings;
$association = $this->em->getClassMetadata($className)->associationMappings;
foreach ($fields as $field)
{
$fieldname = $field->name;
$label = $translator->trans($this->routeClassName.'.fields.'.$fieldname, array(), 'crud');
if ($label == $this->routeClassName.'.fields.'.$fieldname)
{
$label = $translator->trans($this->translatorBase.'.fields.'.$fieldname, array(), 'crud');
}
if (isset($properties[$field->name]))
{
$prop = $properties[$fieldname];
if (isset($prop['id']) && $prop['id'] && !$this->showIdInForm)
continue;
$showFields[$fieldname]=array('nombre' => $fieldname,
'type' => $prop['type'],
'label' => $label);
if (isset($prop['columnDefinition']))
{
$showFields[$fieldname]['type'] = $prop['columnDefinition'];
}
}
if (isset($association[$field->name]))
{
$prop = $association[$fieldname];
if ((isset($prop['id']) && $prop['id'] && !$params['showIdInForm'])
||
(isset($prop['type']) && ($prop['type']==8 || $prop['type']==4)))
continue;
$showFields[$fieldname]=array(
'nombre' => $fieldname,
'label' => $label
);
if($this->isAdjunto($prop['targetEntity']))
{
$showFields[$fieldname]['type'] = 'attach';
}
}
}
return $showFields;
}
protected function showGetFields($entity=null)
{
$showFields = $this->indexShowFields();
return $showFields;
}
protected function indexGetFields()
{
$indexFields = $this->indexShowFields();
return $indexFields;
}
protected function excelGetFields()
{
$excelFields = $this->indexGetFields();
return $excelFields;
}
protected function indexParamsForTwig()
{
$params = array();
$params['routeClassName'] = $this->routeClassName;
$params['contenedor'] = $this->routeClassName;
$params['imageWidth'] = '70px';
foreach ($this->paramsRequest as $key=>$value)
{
if ($key!='filterData')
{
$params[$key]=$value;
}
}
$params['now'] = new \DateTime();
if ($this->indexInnerView)
$params['index_view'] = $this->indexInnerView;
else
if (!$this->modal)
$params['index_view'] = '@crud\crud\index_inner.html.twig';
else
$params['index_view'] = '@crud\crud\index_inner_modal.html.twig';
$params['inline'] = $this->inline;
if (!$this->inline)
{
$className = $this->classFullName;
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$paramsForFunctionInEntity['showIdInForm'] = $this->showIdInForm;
$params['indexFields'] = $this->indexGetFields();
$params['rol'] = $this->rol;
$params['className'] = $this->classFullName;
$params['formFilter'] = $this->formFilter->createView();
$params['filterActive'] = $this->filterActive;
$params['filterColumns'] = $this->filterColumns;
$params['showInIndex'] = $this->showInIndex;
$params['newInIndex'] = $this->newInIndex;
$params['editInIndex'] = $this->editInIndex;
$params['deleteInIndex'] = $this->deleteInIndex;
$params['filterData'] = $this->filterData;
$params['showFilter'] = $this->showFilter;
$params['showPaginator'] = $this->showPaginator;
$params['columnAction'] = $this->columnAction;
$params['search'] = $this->search;
$params['tableInfo'] = $this->tableInfo;
$params['scrollY'] = $this->scrollY;
$params['booleans'] = $this->booleans;
$params['buttons'] = $this->buttons;
$params['entities'] = $this->paginator ? $this->paginator->getCurrentPageResults() : ($this->entities instanceof \Doctrine\ORM\QueryBuilder ? $this->entities->getQuery()->getResult() : $this->entities);
$params['paginator'] = $this->paginator;
$params['paramsRequest'] = $this->paramsRequest;
$params['heightModalForm'] = $this->heightModalForm;
$params['widthModalForm'] = $this->widthModalForm;
$params['heightModalShow'] = $this->heightModalShow;
$params['widthModalShow'] = $this->widthModalShow;
$params['widthLabel'] = $this->widthLabel;
$paramsForFunctionInEntity['entities'] = $params['entities'];
$paramsEntity = $className::getParamsForIndexTwig($paramsForFunctionInEntity);
$params = array_merge($params, $paramsEntity);
}
return $params;
}
protected function indexCreatePaginator($entities)
{
if ($this->showPaginator)
{
$adapter = new DoctrineORMAdapter($entities);
$pagerfanta = new Pagerfanta($adapter);
$pagerfanta->setMaxPerPage($this->maxPerPage);
if (!$page = $this->request->get('page'))
{
$page = 1;
}
try
{
$pagerfanta->setCurrentPage($page);
}
catch (NotValidCurrentPageException $e)
{
throw new NotFoundHttpException();
}
return $pagerfanta;
}
else
return null;
}
protected function indexLoadEntities($params)
{
$params['logger'] = $this->logger;
$query = $this->em->getRepository($this->bundleName.'\\Entity\\'.$this->className)->loadResults($params, $this->filterData);
return $query->getQuery()->getResult();
}
protected function indexCleanFilterData()
{
foreach ($this->filterData as $key=>$valor)
{
if ((is_array($valor) && empty($valor)) ||
(($valor instanceof \Doctrine\Common\Collections\ArrayCollection) && $valor->count()==0) ||
$valor=='')
{
unset($this->filterData[$key]);
}
}
}
public function indexPrepareFilterForm($params)
{
$this->indexCleanFilterData();
if ($this->request->getMethod()=="POST")
{
$this->filterData=array();
//Tomar los datos del request
if ($this->request->get('form'))
{
$this->filterData = $this->request->get('form');
}
$this->indexCleanFilterData();
}
// $classFullName = $this->classFullName;
// $classFullName::setFiltros($params, $this->filterData);
$this->setFiltros();
$this->formFilter = $this->indexBuildFilterForm($this->filterData, $params);
$this->filterActive = false; //Para poner abierto o cerrado el panel de filtros
foreach ($this->filterData as $value)
{
if (!empty($value))
{
$this->filterActive = true;
break;
}
}
}
protected function allowActionExecution($entity=null)
{
if ($this->allowedRol)
{
return $this->isAllowed($this->allowedRol);
}
else
{
$var = 'allowed'.$this->accion;
if ($this->$var)
{
return $this->isAllowed($this->$var);
}
else
{
return false;
}
}
}
private function isAllowed($rule)
{
if (is_array($rule))
{
return in_array($this->rol, $rule);
}
else
{
return $rule=='all' || $rule == $this->rol;
}
}
protected function setFiltros()
{
}
private function indexBuildFilterForm($data, $params)
{
$builder = $this->createFormBuilder($data, array(
'csrf_protection' => false,
'validation_groups' => array('filtering'),
));
$this->formularioFiltro = $this->getFormFilter();
foreach ($this->formularioFiltro as $item)
{
$tipo = null;
$atributos = array('mapped'=>false);
if (isset($item['tipo']))
$tipo = $item['tipo'];
if (isset($item['atributos']))
$atributos = array_merge ($atributos, $item['atributos']);
$nombre = $item['nombre'];
if ($data && isset($data[$nombre]) && $data[$nombre]!='null' && $data[$nombre]!='not null')
{
if (isset($item['type']) && $item['type']=='association' && $data[$nombre] != '')
{
if (isset($atributos['multiple']) && $atributos['multiple']==true)
{
if ($data[$nombre] instanceof \Doctrine\Common\Collections\ArrayCollection)
{
$data[$nombre] = $data[$nombre]->toArray();
}
if (!is_array($data[$nombre]))
$data[$nombre]=array($data[$nombre]);
$atributos['data'] = new \Doctrine\Common\Collections\ArrayCollection();
foreach ($data[$nombre] as $key=>$option)
{
if ($option instanceof \Crud\Entity\crudEntity)
$entidad = $option;
else
$entidad = $this->em->getRepository($atributos['class'])->find($option);
$entidad = $this->em->merge($entidad);
$atributos['data'][]=$entidad;
}
}
else
{
$entidad = $this->em->getRepository($atributos['class'])->find($data[$nombre]);
$atributos['data']=$entidad;
}
}
else
if ($tipo=='Biplane\EnumBundle\Form\Type\EnumType' && isset($atributos['enum_class']) && $data[$nombre] != '' )
{
if (is_array($data[$nombre]))
{
foreach ($data[$nombre] as $valor)
{
$enum = $this->getEnumFilterData($atributos['enum_class'], $valor);
$atributos['data'][] = $enum;
}
}
else
{
$enum = $this->getEnumFilterData($atributos['enum_class'], $data[$nombre]);
$atributos['data']=$enum;
}
}
else
if (($tipo=='entity' || $tipo==EntityType::class) && isset($atributos['class']) && $data[$nombre] != '' )
{
if (isset($atributos['multiple']) && $atributos['multiple']==true)
{
$collecion = new \Doctrine\Common\Collections\ArrayCollection();
if (!is_array($data[$nombre]))
$data[$nombre]=array($data[$nombre]);
foreach ($data[$nombre] as $option)
{
$entidad = $this->em->getRepository($atributos['class'])->find($option);
$collecion[]=$entidad;
}
$atributos['data']=$collecion;
}
else
{
$entidad = $this->em->getRepository($atributos['class'])->find($data[$nombre]);
$atributos['data']=$entidad;
}
}
else
{
$atributos['data']=$data[$nombre];
}
}
if ($tipo=="date")
{
$tipo=null;//"text";
$builder->add($nombre,$tipo,$atributos);
if (isset($data[$nombre]))
{
$atributos['data']=$data[$nombre];
}
//$builder->get($nombre)->addViewTransformer(new DateTimeToStringTransformer(null,null,'d-m-Y'));
}
else
if ($tipo=="Biplane\EnumBundle\Form\Type\EnumType")
{
if (isset($atributos['attr']['class']))
{
$class = str_replace('spinbox-input', '', $atributos['attr']['class']);
if ($class)
$atributos['attr']['class']=$class;
else
unset($atributos['attr']['class']);
}
/* if (isset($atributos['enum_class']))
{
$atributos['choices'] = $atributos['enum_class']::getReadables();
unset($atributos['enum_class']);
}*/
$builder->add($nombre,'Biplane\EnumBundle\Form\Type\EnumType',$atributos);
}
else
{
$builder->add($nombre,$tipo,$atributos);
}
}
return $builder->getForm();
}
private function getEnumFilterData($enumClass, $valor)
{
try
{
$enum = $enumClass::create($valor);
}
catch (\Exception $exc)
{
if (is_numeric($valor))
$enum = $enumClass::create((int)$valor);
}
return $enum;
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN NEW
*/
public function newAction($rol, $routeClassName)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion = 'CREATE';
if (!$this->allowActionExecution())
{
return $this->render('@crud\\accesDenied.html.twig');
}
$entity = $this->createEntity();
$this->setValuesBeforeForm($entity);
$params = $this->comunParamsForForm($entity);
$this->formulario = $this->buildForm($params);
$paramsForTwigNew = $this->newParamsForTwig($entity);
return $this->render($this->twigNewName, $paramsForTwigNew);
}
protected function newParamsForTwig($entity)
{
$params= array(
'rol' => $this->rol,
'routeClassName' => $this->routeClassName,
'contenedor' => $this->routeClassName,
'entity' => $entity,
'form' => $this->formulario->createView(),
'filterData' => $this->filterData,
'paramsRequest' => $this->paramsRequest,
'widthLabel' => $this->widthLabel,
'formColumns' => $this->formColumns,
'accion' => $this->accion,
'notShow' => array('_token'=>'1'),
);
foreach ($this->paramsRequest as $key=>$value)
{
if ($key!='filterData' && $key!='form')
{
$params[$key]=$value;
}
}
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$paramsEntity = $entity->newParamsForTwig($paramsForFunctionInEntity);
return array_merge($params, $paramsEntity);
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN CREATE
*/
public function backToListAction($rol, $routeClassName, $id)
{
$this->setInitialValues($rol, $routeClassName);
$aClassName = $this->classFullName;
if ($id == -1) $id=null;
$ruta = $aClassName::backToList($routeClassName, $this->em, $id, $this->filterData );
$ruta['params']['rol'] = $rol;
return $this->redirect($this->generateUrl($ruta['ruta'], $ruta['params']));
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN CREATE
*/
public function createAction($rol, $routeClassName)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion = 'CREATE';
if (!$this->allowActionExecution())
{
return $this->render('@crud\\accesDenied.html.twig');
}
$entity = $this->createEntity();
// $this->setValuesBeforeForm('CREATE', $entity);
$params = $this->comunParamsForForm($entity);
$this->formulario = $this->buildForm($params);
$this->formulario->handleRequest($this->request);
if ($this->formulario->isSubmitted() && $this->formulario->isValid())
{
$this->setValuesAfterForm($entity);
$this->comunSetFileFields($params, $this->formulario, $entity);
if ($this->comunCheckConstrains($entity))
{
$this->beforeSave($entity);
if($this->comunPersist($entity))
{
$this->afterSave($entity);
return $this->createRedirectOnSuccess($entity);
}
}
}
else
$this->comunSetFormularioErrors();
return $this->createRedirectOnFail($entity);
}
protected function createRedirectOnFail($entity)
{
if ($this->ajax)
{
$error = $this->session->getFlashBag()->get('danger');
if (count($error)>0)
$error = $error[0];
else
$error="Error";
$data= array('ok'=>false,'error'=>$error);
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
else
{
$paramsForTwigNew = $this->newParamsForTwig($entity);
return $this->render($this->twigNewName, $paramsForTwigNew);
}
}
protected function afterSave($entity)
{
$params = $this->comunParamsForFunctionsInEntity();
$params['request'] = $this->request;
$params['entity'] = $entity;
$params['accion'] = $this->accion;
if ($this->accion=='UPDATE')
$params['oldEntity'] = $this->oldEntity;
$entity->afterSave($params);
}
protected function beforeSave($entity)
{
$params = $this->comunParamsForFunctionsInEntity();
$params['request'] = $this->request;
$params['entity'] = $entity;
$params['accion'] = $this->accion;
if ($this->accion=='UPDATE')
$params['oldEntity'] = $this->oldEntity;
$entity->beforeSave($params);
}
protected function createEntity()
{
$entityFullName = $this->classFullName;
return new $entityFullName();
}
protected function createRedirectOnSuccess($entity)
{
if ($this->ajax)
{
$data= array('ok'=>true,'id'=>$entity->getId(),'txt'=>$entity->__toString());
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
else
{
$ruta = $entity->createRedirectOnSuccess($this->em, $this->request, $this->routeClassName, $this->rol );
return $this->redirect($this->generateUrl($ruta['ruta'], $ruta['params']));
}
}
protected function setValuesAfterForm($entity)
{
}
protected function setValuesBeforeForm($entity)
{
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN SHOW
*/
public function showAction($rol, $id, $routeClassName, $tab=-1)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion = 'SHOW';
$entity = $this->em->getRepository($this->bundleName.'\\Entity\\'.$this->className)->find($id);
if (!$entity)
throw new \RuntimeException($this->translator->trans(
'error.instance_not_found',
array('%className%' => $this->routeClassName.'/'.$this->className,
'%id%' => $id),
'crud'));
if (!$this->allowActionExecution('SHOW', $entity))
{
return $this->render('@crud\\accesDenied.html.twig');
}
$paramsForTwigShow = $this->showCreateParamsForTwig($entity);
$paramsForTwigShow['tab']=$tab;
return $this->render($this->twigShowName, $paramsForTwigShow);
}
protected function showCreateParamsForTwig($entity)
{
$className = $this->classFullName;
$page = $this->request->get('page');
$params= array(
'routeClassName' => $this->routeClassName,
'rol' => $this->rol,
//'readableSingularClassName' => $this->readableSingularClassName,
'entity' => $entity,
'booleans' => $this->booleans,
'paramsRequest' => $this->paramsRequest,
'widthLabel' => $this->widthLabel,
'showColumns' => $this->showColumns,
'editInIndex' => $this->editInIndex,
'deleteInIndex' => $this->deleteInIndex,
);
foreach ($this->paramsRequest as $key=>$value)
if ($key!='filterData')
$params[$key]=$value;
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$paramsForFunctionInEntity['entity'] = $entity;
$paramsForFunctionInEntity['showIdInForm'] = $this->showIdInForm;
$params['showFields'] = $this->showGetFields($entity);
$paramsEntity = $entity->getParamsForShowTwig($this->comunParamsForFunctionsInEntity());
return array_merge($params, $paramsEntity);
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN EDIT
*/
public function editAction($rol, $id, $routeClassName)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion = 'UPDATE';
$entity = $this->em->getRepository($this->bundleName.'\\Entity\\'.$this->className)->find($id);
if (!$entity)
throw new \RuntimeException($this->translator->trans(
'error.instance_not_found',
array('%className%' => $this->routeClassName.'/'.$this->className,
'%id%' => $id),
'crud'));
if (!$this->allowActionExecution($entity))
{
return $this->render('@crud\\accesDenied.html.twig');
}
$this->setValuesBeforeForm($entity);
$params = $this->comunParamsForForm($entity);
$this->formulario = $this->buildForm($params);
$paramsForTwigEdit = $this->editParamsForTwig($entity);
return $this->render($this->twigEditName, $paramsForTwigEdit);
}
protected function editParamsForTwig($entity)
{
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$paramsEntity = $entity->editParamsForTwig($paramsForFunctionInEntity);
$params= array(
'rol' => $this->rol,
'routeClassName' => $this->routeClassName,
'contenedor' => $this->routeClassName,
'entity' => $entity,
'form' => $this->formulario->createView(),
'filterData' => $this->filterData,
'paramsRequest' => $this->paramsRequest,
'widthLabel' => $this->widthLabel,
'formColumns' => $this->formColumns,
'accion' => $this->accion,
'editInIndex' => $this->editInIndex,
'deleteInIndex' => $this->deleteInIndex,
'notShow' => array('_token'=>'1'),
);
foreach ($this->paramsRequest as $key=>$value)
if ($key!='filterData')
$params[$key]=$value;
return array_merge($params, $paramsEntity);
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN UPDATE
*/
public function updateAction($rol, $id, $routeClassName)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion = 'UPDATE';
$entity = $this->em->getRepository($this->bundleName.'\\Entity\\'.$this->className)->find($id);
if (!$entity)
throw new \RuntimeException($this->translator->trans(
'error.instance_not_found',
array('%className%' => $this->routeClassName.'/'.$this->className,
'%id%' => $id),
'crud'));
if (!$this->allowActionExecution($entity))
{
return $this->render('@crud\\accesDenied.html.twig');
}
$this->oldEntity = clone $entity;
$params = $this->comunParamsForForm($entity);
$this->formulario = $this->buildForm($params);
$this->formulario->handleRequest($this->request);
if ($this->formulario->isSubmitted() && $this->formulario->isValid())
{
$this->setValuesAfterForm($entity);
$deleteFiles = $this->comunSetFileFields($params, $this->formulario, $entity);
if ($this->comunCheckConstrains($entity))
{
$this->beforeSave($entity);
if($this->comunPersist($entity))
{
$this->deleteFiles($entity, $deleteFiles);
$this->afterSave($entity);
return $this->updateRedirectOnSuccess($entity);
}
}
}
else
{
$this->comunSetFormularioErrors();
}
return $this->updateRedirectOnFail($entity);
}
protected function updateRedirectOnFail($entity)
{
if ($this->ajax)
{
$error = $this->session->getFlashBag()->get('danger');
if (count($error)>0)
$error = $error[0];
else
$error="Error";
$data= array('ok'=>false,'error'=>$error);
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
else
{
$paramsForTwigEdit = $this->editParamsForTwig($entity);
return $this->render($this->twigEditName, $paramsForTwigEdit);
}
}
protected function comunSetFormularioErrors()
{
$childs = $this->formulario->getIterator();
$childs = $childs->getIterator();
$error = '';
$childs->next();
while ($error=='' && $child = $childs->current())
{
$errors = $child->getErrors();
if (count($errors)>0)
{
$fieldName = $this->translator
->trans($this->routeClassName.'.fields.'.$child->getName(), array(), 'crud');
$errorMessage = $errors[0]->getMessage();
$fieldValue = $errors[0]->getMessageParameters();
$fieldValue = $fieldValue['{{ value }}'];
$this->session->getFlashBag()
->set('danger', $fieldName.': '.$errorMessage.' "'.$fieldValue.'"');
$error = 'error';
}
$childs->next();
}
}
protected function deleteFiles($entity, $deleteFiles)
{
foreach ($deleteFiles as $fieldName)
{
//borrar aqui el adjunto anterior
$getMethod = 'get'.ucfirst($fieldName);
$adjunto = $this->oldEntity->$getMethod();
$filename = $adjunto->getRuta().'/'.$adjunto->getArchivoHash();
try
{
$this->em->remove($adjunto);
$this->em->flush();
unlink($filename);
}
catch (\Exception $exc) {}
}
}
protected function updateRedirectOnSuccess($entity)
{
if ($this->ajax)
{
$data= array('ok'=>true,'id'=>$entity->getId());
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
else
{
$ruta = $entity->updateRedirectOnSuccess($this->em, $this->request, $this->routeClassName, $this->rol );
return $this->redirect($this->generateUrl($ruta['ruta'], $ruta['params']));
}
}
/*
* MÉTODOS ASOCIADOS A LA ACCIÓN DELETE
*/
public function deleteAction($rol, $id, $routeClassName)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion='DELETE';
$entity = $this->em->getRepository($this->bundleName.'\\Entity\\'.$this->className)->find($id);
if (!$entity)
throw new \RuntimeException($this->translator->trans(
'error.instance_not_found',
array('%className%' => $this->routeClassName.'/'.$this->className,
'%id%' => $id),
'crud'));
if (!$this->allowActionExecution($entity))
{
return $this->render('@crud\\accesDenied.html.twig');
}
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
if($entity->checkNonReferentialIntegrityConstrains($paramsForFunctionInEntity))
{
$this->beforeDelete($entity, $paramsForFunctionInEntity);
if($this->comunRemove($entity))
{
$this->afterDelete($entity, $paramsForFunctionInEntity);
return $this->deleteRedirectOnSuccess($entity);
}
else{
return $this->deleteRedirectOnFail($entity);
}
}
else {
return $this->deleteRedirectOnFail($entity);
}
}
protected function afterDelete($entity, $params = null)
{
}
protected function beforeDelete($entity, $params)
{
$entity->beforeDelete($params);
}
protected function deleteRedirectOnSuccess($entity)
{
if ($this->ajax)
{
$data= array('ok'=>true,'id'=>$entity->getId(),'txt'=>$entity->__toString());
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
else
{
$ruta = $entity->deleteRedirectOnSuccess($this->em, $this->request, $this->routeClassName, $this->rol );
return $this->redirect($this->generateUrl($ruta['ruta'], $ruta['params']));
}
}
protected function deleteRedirectOnFail($entity)
{
if ($this->ajax)
{
$error = $this->session->getFlashBag()->get('danger');
if (count($error)>0)
$error = $error[0];
else
$error="Error";
$data= array('ok'=>false,'error'=>$error);
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
else
{
$ruta = $entity->deleteRedirectOnFail($this->em, $this->request, $this->routeClassName, $this->rol );
return $this->redirect($this->generateUrl($ruta['ruta'], $ruta['params']));
}
}
public function paginatorAction($rol, $routeClassName, $page)
{
$this->setInitialValues($rol, $routeClassName);
$aClassName = $this->classFullName;
$ruta = $aClassName::paginator($routeClassName, $page, $this->filterData );
return $this->redirect($this->generateUrl($ruta['ruta'], $ruta['params']));
}
public function getNestedAction($bundleName, $className, $fieldName, $value, $sel=-1)
{
$em = $this ->em;
if ($value==-1)
$childs = $em->getRepository($bundleName.'\\Entity\\'.$className)->findAll();
else
{
$childs = $em->getRepository($bundleName.'\\Entity\\'.$className)->createQueryBuilder('p')
->leftJoin('p.'.$fieldName,$fieldName)
->where($fieldName.'.id='.$value)
->getQuery()->getResult();
}
return $this->render('@crud\Common\comboreloaded.html.twig', array("entities"=>$childs, 'value'=>$sel));
}
public function getDependientesAction($className, $fieldName, $value, $sel=-1)
{
$className = str_replace('()','\\',$className);
$em = $this ->em;
if ($value==-1)
$childs = $em->getRepository($className)->findAll();
else
{
$childs = $em->getRepository($className)->createQueryBuilder('p')
->leftJoin('p.'.$fieldName,$fieldName)
->where($fieldName.'.id='.$value)
->getQuery()->getResult();
}
return $this->render('@crud\Common\comboreloaded.html.twig', array("entities"=>$childs, 'value'=>$sel));
}
public function getAllItemsAction($routeClassName, $sel=-1)
{
$this->setInitialValues($routeClassName);
$items = $this->em->getRepository($this->bundleName.'\\Entity\\'.$this->className)->findAll();
return $this->render('@crud\Common\comboreloaded.html.twig', array("entities"=>$items, 'value'=>$sel));
}
protected function excelCreateParamsForTwig()
{
$params = $this->indexParamsForTwig();
$params['indexFields'] = $this->excelGetFields();
return $params;
}
public function excelAction($rol, $routeClassName)
{
$this->setInitialValues($rol, $routeClassName);
$this->accion='INDEX';
if (!$this->allowActionExecution())
{
return $this->render('@crud\\accesDenied.html.twig');
}
$paramsForFunctionInEntity = $this->comunParamsForFunctionsInEntity();
$paramsForFunctionInEntity['showIdInForm'] = $this->showIdInForm;
$this->indexPrepareFilterForm($paramsForFunctionInEntity);
$paramsForFunctionInEntity['filterForm']= $this->formularioFiltro;
$this->entities = $this->indexLoadEntities($paramsForFunctionInEntity);
$spreadSheet = $this->generateSpreadSheet();
$contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
$xlsxWriter = new Xlsx($spreadSheet);
$fileName = str_replace(' ','',$this->translator->trans($this->translatorBase.'.plural', [], 'crud')).'.xlsx';
$response = new StreamedResponse();
$response->headers->set('Content-Type', $contentType);
$response->headers->set('Content-Disposition', 'attachment;filename="'.$fileName.'"');
$response->setPrivate();
$response->headers->addCacheControlDirective('no-cache', true);
$response->headers->addCacheControlDirective('must-revalidate', true);
$response->setCallback(function() use ($xlsxWriter) {
$xlsxWriter->save('php://output');
});
return $response;
}
protected function getExcelValue($entity, $field)
{
if (is_object($entity))
{
return $entity->getFieldValue($field['nombre']);
}
else
{
return $entity[$field['nombre']];
}
}
protected function generateSpreadSheet()
{
// $fields = $this->excelGetFields();
$params = $this->excelCreateParamsForTwig();
$fields = $params['indexFields'];
$spreadSheet = new Spreadsheet();
$sheet = $spreadSheet->getActiveSheet();
$sheet->setCellValue('A1', $this->translator->trans($this->translatorBase.'.plural', [], 'crud'))->mergeCells('A1:D1');
$sheet->getStyle('A1')->getFont()->setBold(true);
$sheet->getStyle('A1')->getFont()->setSize(16);
$col = 'A';
foreach ($fields as $field)
{
$sheet->setCellValue($col.'3', $field['label']);
$sheet->getStyle($col.'3')->getFont()->setBold(true);
$sheet->getStyle($col.'3')->getFont()->setSize(12);
$col++;
}
$row = 4;
foreach ($this->entities as $entity)
{
$col = 'A';
foreach ($fields as $field)
{
$value = $this->getExcelValue($entity, $field);
if (is_object($value))
{
if ($value instanceof \DateTime)
{
$value = $value->format('Y/m/d');
}
else
{
$value = $value->__toString();
}
}
$sheet->setCellValue($col.$row, $value);
$col++;
}
$row++;
}
return $spreadSheet;
}
protected function getParameter(string $name): array|bool|string|int|float|\UnitEnum|null
{
if (isset($_ENV[$name]))
{
$value = $_ENV[$name];
}
else
{
$value = parent::getParameter($name);
if (!$value)
{
throw new \Exception('Parameter '.$name.' is not defined');
}
}
return $value;
}
protected function getFormulario($entity)
{
$formulario = array();
$R = new \ReflectionClass($this->classFullName);
$fields = $R->getProperties(\ReflectionProperty::IS_PRIVATE);
$properties = $this->em->getClassMetadata($this->classFullName)->fieldMappings;
$association = $this->em->getClassMetadata($this->classFullName)->associationMappings;
foreach ($fields as $field)
{
$fieldname = $field->name;
$label = $this->translator->trans($this->routeClassName.'.fields.'.$fieldname, array(), 'crud');
if ($label == $this->routeClassName.'.fields.'.$fieldname)
{
$label = $this->translator->trans($this->translatorBase.'.fields.'.$fieldname, array(), 'crud');
}
if (isset($properties[$field->name]))
{
$prop = $properties[$fieldname];
if (isset($prop['id']) && $prop['id'] && (!isset($this->showIdInForm) || !$this->showIdInForm))
{
continue;
}
$formulario[$fieldname]=array(
'nombre' =>$fieldname,
'tipo' =>null,
'type' =>$prop['type'],
'atributos'=>array(
'label' => $label,
'required' => !$prop['nullable'],
'attr'=>array(
'style'=>'width: 100%'
)
)
);
$tip = $this->translator->trans($this->translatorBase.'.tips.'.$fieldname, array(), 'crud');
if ($tip != $this->translatorBase.'.tips.'.$fieldname)
{
$formulario[$fieldname]['atributos']['attr']['tip']=$tip;
}
if ($prop['type']=='boolean')
{
$formulario[$fieldname]['atributos']['attr']['class'] = 'ace ace-switch ace-switch-5';
}
if ($prop['type']=='text')
{
$formulario[$fieldname]['atributos']['attr']['rows'] = '2';
}
if ($prop['type']=='integer' || $prop['type']=='smallint')
{
$formulario[$fieldname]['atributos']['attr']['class'] = 'spinbox-input';
$formulario[$fieldname]['atributos']['attr']['full_width'] = true;
$formulario[$fieldname]['tipo'] = 'Symfony\Component\Form\Extension\Core\Type\IntegerType';
}
if ($prop['type']=='float')
{
if (isset($prop['columnDefinition']) && $prop['columnDefinition']=='dolar')
{
$formulario[$fieldname]['tipo'] = 'number';
$formulario[$fieldname]['atributos']['attr']['class']='dolar form-control-currency';
$formulario[$fieldname]['atributos']['attr']['min']="0";
$formulario[$fieldname]['atributos']['attr']['step']="0.01";
$formulario[$fieldname]['atributos']['attr']['data-number-to-fixed']="2";
$formulario[$fieldname]['atributos']['attr']['data-number-step-factor']="100";
$formulario[$fieldname]['atributos']['attr']['style'].="; text-align: right";
}
}
/* if ($prop['type']=='time')
{
$formulario[$fieldname]['tipo'] = 'time';
}*/
if ($prop['type']=='datetime')
{
if (isset($prop['columnDefinition']) && $prop['columnDefinition']=='fecha')
{
$formulario[$fieldname]['tipo'] = 'date';
$formulario[$fieldname]['atributos']['widget'] = 'single_text';
$formulario[$fieldname]['atributos']['format'] = 'dd-MM-yyyy';
$formulario[$fieldname]['atributos']['attr']['class']='campo_fecha date-picker';
$formulario[$fieldname]['atributos']['attr']['data-date-format']="dd-mm-yyyy";
//$formulario[$fieldname]['atributos']['attr']['data-uk-datepicker']="{format:'DD-MM-YYYY', pos: 'bottom'}";
}
if (isset($prop['columnDefinition']) && $prop['columnDefinition']=='fechaHora')
{
$formulario[$fieldname]['tipo'] = 'date';
$formulario[$fieldname]['atributos']['attr']['class']='campo_hora_fecha date-picker';
$formulario[$fieldname]['atributos']['attr']['data-date-format']="dd-mm-yyyy";
//$formulario[$fieldname]['atributos']['attr']['data-uk-datepicker']="{format:'DD-MM-YYYY', pos: 'bottom'}";
}
}
if (isset($prop['columnDefinition']))
{
switch ($prop['columnDefinition'])
{
case 'geometria_punto':
$formulario[$fieldname]['tipo'] = 'geometria';
$formulario[$fieldname]['atributos']['attr']['class']='geometria_punto';
break;
case 'geometria_poligono':
$formulario[$fieldname]['tipo'] = 'geometria';
$formulario[$fieldname]['atributos']['attr']['class']='geometria_poligono';
break;
case 'email':
$formulario[$fieldname]['tipo'] = 'Symfony\Component\Form\Extension\Core\Type\EmailType';
break;
}
}
}
if (isset($association[$field->name]))
{
$prop = $association[$fieldname];
if ((isset($prop['id']) && $prop['id'] && !$this->showIdInForm)
|| (!$prop['isOwningSide'] && !$entity->getNotOwningSideInForm($field->name)))
{
continue;
}
$formulario[$fieldname]=array(
'nombre' =>$fieldname,
'tipo' =>null,
'type' =>'association',
'atributos'=>array(
'label' => $label,
'required' => (isset($prop['joinColumns'][0]['nullable']) && !$prop['joinColumns'][0]['nullable']) || (isset($prop['joinTable']['joinColumns'][0]['nullable']) && !$prop['joinTable']['joinColumns'][0]['nullable']),
'placeholder' => $this->translator->trans('choice_value.empty_value', array(), 'crud'),
'empty_data' => null,
'attr' => array(
'class'=>'chosen-select',
'style'=>'width: 100%',
'data-placeholder'=>$this->translator->trans('choice_value.empty_value',array(),'crud')
)
)
);
if (isset($prop['joinColumns'][0]['columnDefinition']))
{
if (strpos($prop['joinColumns'][0]['columnDefinition'],'relation/')===0)
{
$formulario[$fieldname]['atributos']['attr']['relation']=str_replace('relation/','',$prop['joinColumns'][0]['columnDefinition']);
}
if (strpos($prop['joinColumns'][0]['columnDefinition'],'dependiente{')===0)
{
$dependiente = str_replace('dependiente{','',$prop['joinColumns'][0]['columnDefinition']);
$dependiente = str_replace('}','',$dependiente);
$dependiente = explode(',', $dependiente);
if (count($dependiente)==3)
{
$dependiente[1] = str_replace('\\','()',$dependiente[1]);
$formulario[$fieldname]['atributos']['attr']['dependiente_parent']=$dependiente[0];
$formulario[$fieldname]['atributos']['attr']['dependiente_class']=$dependiente[1];
$formulario[$fieldname]['atributos']['attr']['dependiente_field']=$dependiente[2];
}
else
{
throw new \RuntimeException('Crud - The column definition for property "'.$fieldname.'" is not correct.');
}
}
}
$tip = $this->translator->trans($this->translatorBase.'.tips.'.$fieldname, array(), 'crud');
if ($tip != $this->translatorBase.'.tips.'.$fieldname)
{
$formulario[$fieldname]['atributos']['attr']['tip']=$tip;
}
if($prop['type']==8) //Many to many association
{
$formulario[$fieldname]['atributos']['attr']['class'] = 'chosen-select form-control';
}
else
if($prop['type']==4) //One to Many (not owning side)
{
$formulario[$fieldname]['tipo'] = 'collection';
$formulario[$fieldname]['atributos']['entry_type'] = $prop['targetEntity'];
$formulario[$fieldname]['atributos']['entry_options'] = ['label' => false];
$formulario[$fieldname]['atributos']['allow_add'] = true;
$formulario[$fieldname]['atributos']['attr']['containerclass'] = 'full-row';
unset($formulario[$fieldname]['atributos']['placeholder']);
}
else
{
if(isset($prop['joinColumns'][0]['columnDefinition']) && $prop['joinColumns'][0]['columnDefinition']=='chosen')
{
$formulario[$fieldname]['atributos']['attr']['class'] = 'chosen-select form-control';
}
}
if($this->isAdjunto($prop['targetEntity']))
{
$formulario[$fieldname]['tipo'] = 'Symfony\Component\Form\Extension\Core\Type\FileType';
unset($formulario[$fieldname]['atributos']['placeholder']);
unset($formulario[$fieldname]['atributos']['empty_data']);
$formulario[$fieldname]['atributos']['mapped'] = false;
$formulario[$fieldname]['atributos']['attr']['class'] = $prop['targetEntity'];
unset($formulario[$fieldname]['atributos']['attr']['style']);
unset($formulario[$fieldname]['atributos']['attr']['data-placeholder']);
if (isset($prop['joinColumns'][0]['columnDefinition']))
{
$formulario[$fieldname]['atributos']['attr']['accept'] = $prop['joinColumns'][0]['columnDefinition'];
}
}
}
}
return $formulario;
}
public function quickUpdateAction()
{
$ret= array('ok'=>true);
try
{
$data = $this->request->get('quick');
$entity = $this->em->getRepository('App\\Entity\\'.$data['class'])->find($data['id']);
if ($entity)
{
if ($data['association'])
{
$valor = $this->em->getRepository('App\\Entity\\'.$data['association'])->find($data['valor']);
}
else
{
$valor = $data['valor'];
}
$setFunction = 'set'.ucfirst($data['field']);
$entity->$setFunction($valor);
$this->em->persist($entity);
$this->em->flush();
}
else
{
$ret['ok'] = false;
$ret['msg'] = 'No se encontro a un '.$data['class'].' con el identificador envíado';
}
}
catch(\Exception $exc)
{
$ret['ok'] = false;
$ret['msg'] = $exc->getMessage();
}
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($ret));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
public function quickDeleteAction($className, $id)
{
try
{
$habilidad = $this->em->getRepository('App\\Entity\\'.$className)->find($id);
$this->em->remove($habilidad);
$this->em->flush();
$ret = ['ok'=>true];
}
catch (\Exception $exc)
{
$ret = ['ok'=>false, 'msg'=>$exc->getMessage()];
}
$data = new \Symfony\Component\HttpFoundation\Response(json_encode($ret));
$data->headers->set('Content-Type', 'application/json');
return $data;
}
}