예제 #1
0
 /**
  * Get access path to element which works with PropertyAccessor.
  *
  * @param string $elementId expects string in format used in form id field. (uniqueIdentifier_model_sub_model or uniqueIdentifier_model_1_sub_model etc.)
  * @param mixed  $entity
  *
  * @return string
  *
  * @throws \Exception
  */
 public function getElementAccessPath($elementId, $entity)
 {
     $propertyAccessor = $this->pool->getPropertyAccessor();
     $idWithoutIdentifier = preg_replace('/^[^_]*_/', '', $elementId);
     $initialPath = preg_replace('#(_(\\d+)_)#', '[$2]_', $idWithoutIdentifier);
     $parts = explode('_', $initialPath);
     $totalPath = '';
     $currentPath = '';
     foreach ($parts as $part) {
         $currentPath .= empty($currentPath) ? $part : '_' . $part;
         $separator = empty($totalPath) ? '' : '.';
         if ($this->pathExists($propertyAccessor, $entity, $totalPath . $separator . $currentPath)) {
             $totalPath .= $separator . $currentPath;
             $currentPath = '';
         }
     }
     if (!empty($currentPath)) {
         throw new \Exception(sprintf('Could not get element id from %s Failing part: %s', $elementId, $currentPath));
     }
     return $totalPath;
 }
예제 #2
0
 /**
  * Get access path to element which works with PropertyAccessor.
  *
  * @param string $elementId expects string in format used in form id field. (uniqueIdentifier_model_sub_model or uniqueIdentifier_model_1_sub_model etc.)
  * @param mixed  $entity
  *
  * @return string
  *
  * @throws \Exception
  */
 public function getElementAccessPath($elementId, $entity)
 {
     $propertyAccessor = $this->pool->getPropertyAccessor();
     $idWithoutUniqueIdentifier = implode('_', explode('_', substr($elementId, strpos($elementId, '_') + 1)));
     //array access of id converted to format which PropertyAccessor understands
     $initialPath = preg_replace('#(_(\\d+)_)#', '[$2]', $idWithoutUniqueIdentifier);
     $parts = preg_split('#\\[\\d+\\]#', $initialPath);
     $partReturnValue = $returnValue = '';
     $currentEntity = $entity;
     foreach ($parts as $key => $value) {
         $subParts = explode('_', $value);
         $id = '';
         $dot = '';
         foreach ($subParts as $subValue) {
             $id .= $id ? '_' . $subValue : $subValue;
             if ($this->pathExists($propertyAccessor, $currentEntity, $partReturnValue . $dot . $id)) {
                 $partReturnValue .= $dot . $id;
                 $dot = '.';
                 $id = '';
             } else {
                 $dot = '';
             }
         }
         if ($dot !== '.') {
             throw new \Exception(sprintf('Could not get element id from %s Failing part: %s', $elementId, $subValue));
         }
         //check if array access was in this location originally
         preg_match("#{$value}\\[(\\d+)#", $initialPath, $matches);
         if (isset($matches[1])) {
             $partReturnValue .= '[' . $matches[1] . ']';
         }
         $returnValue .= $returnValue ? '.' . $partReturnValue : $partReturnValue;
         $partReturnValue = '';
         if (isset($parts[$key + 1])) {
             $currentEntity = $propertyAccessor->getValue($entity, $returnValue);
         }
     }
     return $returnValue;
 }
 /**
  * @throws \RunTimeException
  *
  * @param mixed                     $element
  * @param FieldDescriptionInterface $fieldDescription
  *
  * @return mixed
  */
 public function renderRelationElement($element, FieldDescriptionInterface $fieldDescription)
 {
     if (!is_object($element)) {
         return $element;
     }
     $propertyPath = $fieldDescription->getOption('associated_property');
     if (null === $propertyPath) {
         // For BC kept associated_tostring option behavior
         $method = $fieldDescription->getOption('associated_tostring');
         if ($method) {
             @trigger_error('Option "associated_tostring" is deprecated since version 2.3. Use "associated_property" instead.', E_USER_DEPRECATED);
         } else {
             $method = '__toString';
         }
         if (!method_exists($element, $method)) {
             throw new \RuntimeException(sprintf('You must define an `associated_property` option or ' . 'create a `%s::__toString` method to the field option %s from service %s is ', get_class($element), $fieldDescription->getName(), $fieldDescription->getAdmin()->getCode()));
         }
         return call_user_func(array($element, $method));
     }
     if (is_callable($propertyPath)) {
         return $propertyPath($element);
     }
     return $this->pool->getPropertyAccessor()->getValue($element, $propertyPath);
 }
 /**
  * @param Request $request
  *
  * @return Response
  */
 public function setObjectFieldValueAction(Request $request)
 {
     $field = $request->get('field');
     $code = $request->get('code');
     $objectId = $request->get('objectId');
     $value = $request->get('value');
     $context = $request->get('context');
     $admin = $this->pool->getInstance($code);
     $admin->setRequest($request);
     // alter should be done by using a post method
     if (!$request->isXmlHttpRequest()) {
         return new JsonResponse(array('status' => 'KO', 'message' => 'Expected a XmlHttpRequest request header'));
     }
     if ($request->getMethod() != 'POST') {
         return new JsonResponse(array('status' => 'KO', 'message' => 'Expected a POST Request'));
     }
     $rootObject = $object = $admin->getObject($objectId);
     if (!$object) {
         return new JsonResponse(array('status' => 'KO', 'message' => 'Object does not exist'));
     }
     // check user permission
     if (false === $admin->isGranted('EDIT', $object)) {
         return new JsonResponse(array('status' => 'KO', 'message' => 'Invalid permissions'));
     }
     if ($context == 'list') {
         $fieldDescription = $admin->getListFieldDescription($field);
     } else {
         return new JsonResponse(array('status' => 'KO', 'message' => 'Invalid context'));
     }
     if (!$fieldDescription) {
         return new JsonResponse(array('status' => 'KO', 'message' => 'The field does not exist'));
     }
     if (!$fieldDescription->getOption('editable')) {
         return new JsonResponse(array('status' => 'KO', 'message' => 'The field cannot be edit, editable option must be set to true'));
     }
     $propertyPath = new PropertyPath($field);
     // If property path has more than 1 element, take the last object in order to validate it
     if ($propertyPath->getLength() > 1) {
         $object = $this->pool->getPropertyAccessor()->getValue($object, $propertyPath->getParent());
         $elements = $propertyPath->getElements();
         $field = end($elements);
         $propertyPath = new PropertyPath($field);
     }
     // Handle date type has setter expect a DateTime object
     if ('' !== $value && $fieldDescription->getType() == 'date') {
         $value = new \DateTime($value);
     }
     $this->pool->getPropertyAccessor()->setValue($object, $propertyPath, '' !== $value ? $value : null);
     $violations = $this->validator->validate($object);
     if (count($violations)) {
         $messages = array();
         foreach ($violations as $violation) {
             $messages[] = $violation->getMessage();
         }
         return new JsonResponse(array('status' => 'KO', 'message' => implode("\n", $messages)));
     }
     $admin->update($object);
     // render the widget
     // todo : fix this, the twig environment variable is not set inside the extension ...
     $extension = $this->twig->getExtension('sonata_admin');
     $extension->initRuntime($this->twig);
     $content = $extension->renderListElement($rootObject, $fieldDescription);
     return new JsonResponse(array('status' => 'OK', 'content' => $content));
 }