phphtmltextareasilverstripeformatted-text

Silverstripe 3.3 - How can I save HTML formatted text into database from frontend form?


I'd like to allow users on my site to submit plain text comments. When I present these comments on my site, I'd like them to be shown as HTML (ie: in a <p> tag and new lines as <br>).

How can I present the plain text as HTML in Silverstripe 3.3?

I have a Dataobject with

private static $db = array (
        'MyText' => 'HTMLText',
);

and a form:

public function MyForm() {
      $myForm = Form::create(
          $this,
          __FUNCTION__,
          FieldList::create(
              HtmlEditorField::create('MyText')
          ),
          FieldList::create(
              FormAction::create('submit','Submit')
          )
      );
      return $myForm;
}

When my submit function is like this

public function submit($data, $form) {
      $myDataobject = new MyDataobject();
      $form->saveInto($myDataobject);
      $myDataobject->write();

      $form->sessionMessage('Message saved.','good');
      return $this->redirectBack();
}

Currently it saves the text as a plain text string without any HTML.


Solution

  • OK - from your comment it appears your example code isn't what you're actually doing and you're using a TextareaField instead of an HTMLEditorField.

    This is fine, so you have a couple of choices:

    1. Add the HTML before writing the form submission:

      public function submit($data, $form) { $myDataobject = new MyDataobject(); $form->saveInto($myDataobject); $myDataobject->MyText = sprintf('

      %s

      ', nl2br(Convert::raw2xml($data['MyText']))); $myDataobject->write();

        $form->sessionMessage('Message saved.','good');
        return $this->redirectBack();
      

      }

    Please note the use of Convert::raw2html - without this, you'll likely be vulnerable to a malicious user who submits HTML to perform an HTML injection attack.

    1. Add a setter on the Model:

      class MyDataobject extends DataObject {

      ...

      public function setMyText($value) {
          return $this->setField('MyText', sprintf('<p>%s</p>', nl2br(Convert::raw2xml($value)));
      }
      

      }

    This approach will likely be quite fragile as any time the value is set, it'll be encoded which could be when you're deliberately setting HTML.

    Recommended solution: #1