/** * {@inheritdoc} */ public function generateMenuUrl(AdminInterface $admin, $name, array $parameters = array(), $absolute = UrlGeneratorInterface::ABSOLUTE_PATH) { // if the admin is a child we automatically append the parent's id if ($admin->isChild() && $admin->hasRequest() && $admin->getRequest()->attributes->has($admin->getParent()->getIdParameter())) { // twig template does not accept variable hash key ... so cannot use admin.idparameter ... // switch value if (isset($parameters['id'])) { $parameters[$admin->getIdParameter()] = $parameters['id']; unset($parameters['id']); } $parameters[$admin->getParent()->getIdParameter()] = $admin->getRequest()->attributes->get($admin->getParent()->getIdParameter()); } // if the admin is linked to a parent FieldDescription (ie, embedded widget) if ($admin->hasParentFieldDescription()) { // merge link parameter if any provided by the parent field $parameters = array_merge($parameters, $admin->getParentFieldDescription()->getOption('link_parameters', array())); $parameters['uniqid'] = $admin->getUniqid(); $parameters['code'] = $admin->getCode(); $parameters['pcode'] = $admin->getParentFieldDescription()->getAdmin()->getCode(); $parameters['puniqid'] = $admin->getParentFieldDescription()->getAdmin()->getUniqid(); } if ($name == 'update' || substr($name, -7) == '|update') { $parameters['uniqid'] = $admin->getUniqid(); $parameters['code'] = $admin->getCode(); } // allows to define persistent parameters if ($admin->hasRequest()) { $parameters = array_merge($admin->getPersistentParameters(), $parameters); } $code = $this->getCode($admin, $name); if (!array_key_exists($code, $this->caches)) { throw new \RuntimeException(sprintf('unable to find the route `%s`', $code)); } return array('route' => $this->caches[$code], 'routeParameters' => $parameters, 'routeAbsolute' => $absolute); }
/** * Return current translatable locale * ie: the locale used to load object translations != current request locale. * * @return string */ public function getTranslatableLocale(AdminInterface $admin) { if ($this->translatableLocale == null) { if ($admin->getRequest()) { $this->translatableLocale = $admin->getRequest()->get(self::TRANSLATABLE_LOCALE_PARAMETER); } if ($this->translatableLocale == null) { $this->translatableLocale = $this->getDefaultTranslationLocale($admin); } } return $this->translatableLocale; }
/** * @param AdminInterface $admin * @param object $subject * @param string $elementId * @return array */ public function appendFormFieldElement(AdminInterface $admin, $subject, $elementId) { // retrieve the subject $formBuilder = $admin->getFormBuilder(); $form = $formBuilder->getForm(); $form->setData($subject); $form->submit($admin->getRequest()); // get the field element $childFormBuilder = $this->getChildFormBuilder($formBuilder, $elementId); // retrieve the FieldDescription $fieldDescription = $admin->getFormFieldDescription($childFormBuilder->getName()); try { $value = $fieldDescription->getValue($form->getData()); } catch (NoValueException $e) { $value = null; } // retrieve the posted data $data = $admin->getRequest()->get($formBuilder->getName()); if (!isset($data[$childFormBuilder->getName()])) { $data[$childFormBuilder->getName()] = array(); } $objectCount = count($value); $postCount = count($data[$childFormBuilder->getName()]); $fields = array_keys($fieldDescription->getAssociationAdmin()->getFormFieldDescriptions()); // for now, not sure how to do that $value = array(); foreach ($fields as $name) { $value[$name] = ''; } // add new elements to the subject while ($objectCount <= $postCount) { // append a new instance into the object $this->addNewInstance($form->getData(), $fieldDescription); $objectCount++; } $subject->orderLayoutBlocks(); $finalForm = $admin->getFormBuilder()->getForm(); $finalForm->setData($subject); // bind the data $finalForm->setData($form->getData()); return array($fieldDescription, $finalForm); }
/** * Sanity check and default locale to request locale. * * {@inheritdoc} */ public function alterNewInstance(AdminInterface $admin, $object) { if (!$object instanceof TranslatableInterface) { throw new \InvalidArgumentException('Expected TranslatableInterface, got ' . get_class($object)); } if ($admin->hasRequest()) { $currentLocale = $admin->getRequest()->getLocale(); if (in_array($currentLocale, $this->locales)) { $object->setLocale($currentLocale); } } }
/** * {@inheritdoc} */ public function preUpdate(AdminInterface $admin, $object) { if (!$admin->hasRequest() || !($data = $admin->getRequest()->get($admin->getUniqid()))) { return; } if (!isset($data[$this->fieldName])) { return; } $modelManager = $admin->getModelManager(); if (!$modelManager instanceof LockInterface) { return; } $modelManager->lock($object, $data[$this->fieldName]); }
/** * @throws \RuntimeException * @param \Sonata\AdminBundle\Admin\AdminInterface $admin * @param $name * @param array $parameter * @param bool $absolute * @return string */ public function generateUrl(AdminInterface $admin, $name, array $parameters = array(), $absolute = false) { if (!$admin->isChild()) { if (strpos($name, '.')) { $name = $admin->getCode() . '|' . $name; } else { $name = $admin->getCode() . '.' . $name; } } else { if ($admin->isChild()) { $name = $admin->getBaseCodeRoute() . '.' . $name; // twig template does not accept variable hash key ... so cannot use admin.idparameter ... // switch value if (isset($parameters['id'])) { $parameters[$admin->getIdParameter()] = $parameters['id']; unset($parameters['id']); } $parameters[$admin->getParent()->getIdParameter()] = $admin->getRequest()->get($admin->getParent()->getIdParameter()); } } // if the admin is linked to a parent FieldDescription (ie, embedded widget) if ($admin->hasParentFieldDescription()) { // merge link parameter if any provided by the parent field $parameters = array_merge($parameters, $admin->getParentFieldDescription()->getOption('link_parameters', array())); $parameters['uniqid'] = $admin->getUniqid(); $parameters['code'] = $admin->getCode(); $parameters['pcode'] = $admin->getParentFieldDescription()->getAdmin()->getCode(); $parameters['puniqid'] = $admin->getParentFieldDescription()->getAdmin()->getUniqid(); } if ($name == 'update' || substr($name, -7) == '|update') { $parameters['uniqid'] = $admin->getUniqid(); $parameters['code'] = $admin->getCode(); } // allows to define persistent parameters if ($admin->hasRequest()) { $parameters = array_merge($admin->getPersistentParameters(), $parameters); } $route = $admin->getRoute($name); if (!$route) { throw new \RuntimeException(sprintf('unable to find the route `%s`', $name)); } return $this->router->generate($route->getDefault('_sonata_name'), $parameters, $absolute); }
/** * Set a default parent if defined in the request * * {@inheritDoc} */ public function alterNewInstance(AdminInterface $admin, $object) { if (!$admin->hasRequest() || !($parentId = $admin->getRequest()->get('parent'))) { return; } $parent = $admin->getModelManager()->find(null, $parentId); if (!$parent) { return; } switch ($object) { case $object instanceof HierarchyInterface: $object->setParentDocument($parent); break; case $object instanceof ChildInterface: $object->setParentObject($parent); break; default: throw new \InvalidArgumentException(sprintf('Class %s is not supported', get_class($object))); } }
/** * Note: * This code is ugly, but there is no better way of doing it. * For now the append form element action used to add a new row works * only for direct FieldDescription (not nested one) * * @throws \RuntimeException * * @param \Sonata\AdminBundle\Admin\AdminInterface $admin * @param object $subject * @param string $elementId * * @return array */ public function appendFormFieldElement(AdminInterface $admin, $subject, $elementId) { // retrieve the subject $formBuilder = $admin->getFormBuilder(); $form = $formBuilder->getForm(); $form->setData($subject); $form->handleRequest($admin->getRequest()); $elementId = preg_replace('#.(\\d+)#', '[$1]', implode('.', $this->generateElementId($formBuilder, substr($elementId, strpos($elementId, '_') + 1)))); // append a new instance into the object $this->addNewInstance($admin, $elementId); // return new form with empty row $finalForm = $admin->getFormBuilder()->getForm(); $finalForm->setData($subject); $finalForm->setData($form->getData()); return $finalForm; }
/** * Note: * This code is ugly, but there is no better way of doing it. * For now the append form element action used to add a new row works * only for direct FieldDescription (not nested one). * * @throws \RuntimeException * * @param AdminInterface $admin * @param object $subject * @param string $elementId * * @return array */ public function appendFormFieldElement(AdminInterface $admin, $subject, $elementId) { // retrieve the subject $formBuilder = $admin->getFormBuilder(); $form = $formBuilder->getForm(); $form->setData($subject); $form->handleRequest($admin->getRequest()); // get the field element $childFormBuilder = $this->getChildFormBuilder($formBuilder, $elementId); //Child form not found (probably nested one) //if childFormBuilder was not found resulted in fatal error getName() method call on non object if (!$childFormBuilder) { $propertyAccessor = $this->pool->getPropertyAccessor(); $entity = $admin->getSubject(); $path = $this->getElementAccessPath($elementId, $entity); $collection = $propertyAccessor->getValue($entity, $path); if ($collection instanceof \Doctrine\ORM\PersistentCollection || $collection instanceof \Doctrine\ODM\MongoDB\PersistentCollection) { //since doctrine 2.4 $entityClassName = $collection->getTypeClass()->getName(); } elseif ($collection instanceof \Doctrine\Common\Collections\Collection) { $entityClassName = $this->getEntityClassName($admin, explode('.', preg_replace('#\\[\\d*?\\]#', '', $path))); } else { throw new \Exception('unknown collection class'); } $collection->add(new $entityClassName()); $propertyAccessor->setValue($entity, $path, $collection); $fieldDescription = null; } else { // retrieve the FieldDescription $fieldDescription = $admin->getFormFieldDescription($childFormBuilder->getName()); try { $value = $fieldDescription->getValue($form->getData()); } catch (NoValueException $e) { $value = null; } // retrieve the posted data $data = $admin->getRequest()->get($formBuilder->getName()); if (!isset($data[$childFormBuilder->getName()])) { $data[$childFormBuilder->getName()] = array(); } $objectCount = count($value); $postCount = count($data[$childFormBuilder->getName()]); $fields = array_keys($fieldDescription->getAssociationAdmin()->getFormFieldDescriptions()); // for now, not sure how to do that $value = array(); foreach ($fields as $name) { $value[$name] = ''; } // add new elements to the subject while ($objectCount < $postCount) { // append a new instance into the object $this->addNewInstance($form->getData(), $fieldDescription); ++$objectCount; } $this->addNewInstance($form->getData(), $fieldDescription); } $finalForm = $admin->getFormBuilder()->getForm(); $finalForm->setData($subject); // bind the data $finalForm->setData($form->getData()); return array($fieldDescription, $finalForm); }
/** * Returns true if this datagrid builder can process these values. */ public function isSmart(AdminInterface $admin, array $values = array()) { // first : validate if elastica is asked in the configuration for this action $fullCurrentAction = $admin->getRequest()->attributes->get('_controller'); $currentAction = explode('::', $fullCurrentAction); // remove Action from 'listAction' $currentAction = substr($currentAction[1], 0, -strlen('Action')); // in case of batch|export action, no need to elasticsearch if (!in_array($currentAction, $this->finderProvider->getActionsByAdmin($admin))) { return false; } // Get mapped field names $finderId = $this->finderProvider->getFinderIdByAdmin($admin); // Assume that finder id is composed like this 'fos_elastica.finder.<index name>.<type name> list($indexName, $typeName) = array_slice(explode('.', $finderId), 2); $typeConfiguration = $this->configManager->getTypeConfiguration($indexName, $typeName); $mapping = $typeConfiguration->getMapping(); $mappedFieldNames = array_keys($mapping['properties']); // Compare to the fields on wich the search apply $smart = true; foreach ($values as $key => $value) { if (!is_array($value) || !isset($value['value'])) { // This is not a filter field continue; } if (!$value['value']) { // No value set on the filter field continue; } if (!in_array($key, $mappedFieldNames)) { /* * We are in the case where a field is used as filter * without being mapped in elastic search. * An ugly case would be to have a custom field used in the filter * without mapping in the model, we need to control that */ $ret = $admin->getModelManager()->getParentMetadataForProperty($admin->getClass(), $key, $admin->getModelManager()); list($metadata, $propertyName, $parentAssociationMappings) = $ret; //Case if a filter is used in the filter but not linked to the ModelManager ("mapped" = false ) case if (!$metadata->hasField($key)) { break; } // This filter field is not mapped in elasticsearch // so we cannot use elasticsearch $smart = false; break; } } return $smart; }