0
votes

I have a problem overriding the editAction of Sonata Admin on Symfony 4. My problem is that I have this interface for editing posts as you can see is these two images:

Everytime The admin change the content formatter it get changed and the changes get saved in mysql

but when you try to edit the post again the admin get always 'text' selected by default

I want to make the default selected option the one saved in MySQL. For example if the admin changes it to rawhtml, the next time when he want to edit this post he should find the rawhtml selected by default (not text like in the image).

This is Sonata editAction method :

public function editAction($id = null)
{
    $request = $this->getRequest();
    // the key used to lookup the template
    $templateKey = 'edit';

    $id = $request->get($this->admin->getIdParameter());
    $existingObject = $this->admin->getObject($id);

    if (!$existingObject) {
        throw $this->createNotFoundException(sprintf('unable to find the object with id: %s', $id));
    }

    $this->checkParentChildAssociation($request, $existingObject);

    $this->admin->checkAccess('edit', $existingObject);

    $preResponse = $this->preEdit($request, $existingObject);
    if (null !== $preResponse) {
        return $preResponse;
    }

    $this->admin->setSubject($existingObject);
    $objectId = $this->admin->getNormalizedIdentifier($existingObject);

    /** @var $form Form */
    $form = $this->admin->getForm();
    $form->setData($existingObject);
    $form->handleRequest($request);
    if ($form->isSubmitted()) {
        $isFormValid = $form->isValid();

        // persist if the form was valid and if in preview mode the preview was approved
        if ($isFormValid && (!$this->isInPreviewMode() || $this->isPreviewApproved())) {
            $submittedObject = $form->getData();
            $this->admin->setSubject($submittedObject);

            try {
                $existingObject = $this->admin->update($submittedObject);

                if ($this->isXmlHttpRequest()) {
                    return $this->renderJson([
                        'result' => 'ok',
                        'objectId' => $objectId,
                        'objectName' => $this->escapeHtml($this->admin->toString($existingObject)),
                    ], 200, []);
                }

                $this->addFlash(
                    'sonata_flash_success',
                    $this->trans(
                        'flash_edit_success',
                        ['%name%' => $this->escapeHtml($this->admin->toString($existingObject))],
                        'SonataAdminBundle'
                    )
                );

                // redirect to edit mode
                return $this->redirectTo($existingObject);
            } catch (ModelManagerException $e) {
                $this->handleModelManagerException($e);

                $isFormValid = false;
            } catch (LockException $e) {
                $this->addFlash('sonata_flash_error', $this->trans('flash_lock_error', [
                    '%name%' => $this->escapeHtml($this->admin->toString($existingObject)),
                    '%link_start%' => '<a href="'.$this->admin->generateObjectUrl('edit', $existingObject).'">',
                    '%link_end%' => '</a>',
                ], 'SonataAdminBundle'));
            }
        }

        // show an error message if the form failed validation
        if (!$isFormValid) {
            if (!$this->isXmlHttpRequest()) {
                $this->addFlash(
                    'sonata_flash_error',
                    $this->trans(
                        'flash_edit_error',
                        ['%name%' => $this->escapeHtml($this->admin->toString($existingObject))],
                        'SonataAdminBundle'
                    )
                );
            }
        } elseif ($this->isPreviewRequested()) {
            // enable the preview template if the form was valid and preview was requested
            $templateKey = 'preview';
            $this->admin->getShow();
        }
    }

    $formView = $form->createView();
    // set the theme for the current Admin Form
    $this->setFormTheme($formView, $this->admin->getFormTheme());

    // NEXT_MAJOR: Remove this line and use commented line below it instead
    $template = $this->admin->getTemplate($templateKey);
    // $template = $this->templateRegistry->getTemplate($templateKey);

    return $this->renderWithExtraParams($template, [
        'action' => 'edit',
        'form' => $formView,
        'object' => $existingObject,
        'objectId' => $objectId,
    ], null);
}

Here is my configureFormFields method for PostAdmin:

        $isHorizontal = 'horizontal' == $this->getConfigurationPool()->getOption('form_type');
    $formMapper
        ->with('group_post', [
            'class' => 'col-md-8',
        ])
        ->add('author', ModelListType::class)
        ->add('title')
        ->add('abstract', TextareaType::class, [
            'attr' => ['rows' => 5],
        ])
        ->add('content', FormatterType::class, [
            'event_dispatcher' => $formMapper->getFormBuilder()->getEventDispatcher(),
            'format_field' => 'contentFormatter',
            'source_field' => 'rawContent',
            'source_field_options' => [
                'horizontal_input_wrapper_class' => $isHorizontal ? 'col-lg-12' : '',
                'attr' => ['class' => $isHorizontal ? 'span10 col-sm-10 col-md-10' : '', 'rows' => 20],
            ],
            'ckeditor_context' => 'news',
            'target_field' => 'content',
            'listener' => true,
        ])
        ->end()
        ->with('group_status', [
            'class' => 'col-md-4',
        ])
        ->add('enabled', CheckboxType::class, ['required' => false])
        ->add('image', ModelListType::class, ['required' => false], [
            'link_parameters' => [
                'context' => 'news',
                'hide_context' => true,
            ],
        ])

        ->add('publicationDateStart', DateTimePickerType::class, [
            'dp_side_by_side' => true,
        ])
        ->add('commentsCloseAt', DateTimePickerType::class, [
            'dp_side_by_side' => true,
            'required' => false,
        ])
        ->add('commentsEnabled', CheckboxType::class, [
            'required' => false,
        ])
        ->add('commentsDefaultStatus', CommentStatusType::class, [
            'expanded' => true,
        ])
        ->end()

        ->with('group_classification', [
            'class' => 'col-md-4',
        ])
        ->add('tags', ModelAutocompleteType::class, [
            'property' => 'name',
            'multiple' => 'true',
            'required' => false,
        ])
        ->add('collection', ModelListType::class, [
            'required' => false,
        ])->end();
    $options = $formMapper->get('content')->get('contentFormatter')->getOptions();
    $options = array_merge($options,array('choices'=>array('markdown'=>'markdown','text'=>'text','rawhtml'=>'rawhtml','richhtml'=>'richhtml')));
    $rawcontent = $formMapper->get('content')->get('rawContent');
    $formMapper->get('content')->remove('contentFormatter')->remove('rawContent')->add('contentFormatter',ChoiceType::class,$options)->add($rawcontent);

it Still does not take the default selected value. Is there anyway to force it to take the real value from mysql as 'data' ? I can't find where I should edit the form to take the default selected value from the object. Please if you can help me with this I will be very glad. I'm not familiar with Sonata bundle and managing forms.

1
You never use the $options variable ... and where is the form field representing the contentFomatter property of your entity?Jim Panse

1 Answers

0
votes

I think there is no need to modify the editAction or the controller at all.

I want to make the default selected option the one saved in MySQL.

This is a classic use case for saving values back from the form to the model and display it when editing the next time.

Instead you should modify your admin class

I don't know your model but for example in your admins configureFormFields method:

$formMapper->add('contentFormatter', 'choice', ['choices' => ['Text' => 'text', 'Raw HTML' => 'rawHtml']]);

So the choices are in the format Display Value => Value from the entity.

So if your value from your entity returns 'rawHtml' the form will select "Raw HTML". If this doen't work, there is something misconfigured in your admin. Double check what value returns from your entity object.