symfony advent calendar day nine: local improvements
====================================================
Previously on symfony
---------------------
During [day eight](8.txt), we added AJAX interactions to askeet without pain. The application is now quite usable, but could use a lot of little improvements. Rich text should be allowed in the questions `body`, and primary keys should not appear in the URIs. All that is not difficult to put in place with symfony: today will be a good occasion to practice what you already learned, and to check that you know how to manipulate all the layers of the MVC architecture.
Allow rich text formatting on questions and answers
---------------------------------------------------
### Markdown
The question and answer bodies only accept plain text for now. To allow basic formatting - bold, italic, hyperlinks, images, etc. - we will use an external library rather than reinvent the wheel.
If you have taken a look at the symfony documentation in text format, you probably know that we are big [Markdown](http://daringfireball.net/projects/markdown/) fans. Markdown is a text-to-HTML conversion tool, and a syntax for text formatting. The great advantage of Markdown over, for instance, Wiki or forum syntax, is that a plain text markdown file is still very readable:
Test Markdown text
------------------
This is a **very simple** example of [Markdown][1].
The best thing about markdown is its _auto-escape_ feature for code chunks:
link to symfony
>The `<` and `>` are properly escaped as `<` and `>`,
>and are not interpreted by any browser
[1]: http://daringfireball.net/projects/markdown/ "Markdown"
This Markdown renders as follow:
>Test Markdown text
>------------------
>
>This is a **very simple** example of [Markdown](http://daringfireball.net/projects/markdown/).
>The best thing about markdown is its _auto-escape_ feature for code chunks:
>
> link to symfony
>
>>The `<` and `>` are properly escaped as `<` and `>`,
>>and are not interpreted by any browser
### Markdown library
Although originally written in [Perl](http://www.perl.com/), Markdown is available as a PHP library at [PHP Markdown](http://www.michelf.com/projects/php-markdown/). That's the one we will use. Download the `markdown.php` file and put it in the `lib` folder of the askeet project (`askeet/lib/`). That's all: It is now available to all the classes of the askeet applications, provided that you require it first:
[php]
require_once('markdown.php');
We could call the Markdown converter each time we display the body of a message, but that would require too high a load on our servers. We'd rather convert the text body to an HTML body when the question is created, and store the HTML version of the body in the `Question` table. You are probably getting used to this, so the model extension won't be a surprise.
### Extend the model
First, add a colomn to the `Question` table in the `schema.xml`:
[php]
Then, regenerate the model and update the database:
$ symfony propel-build-model
$ symfony propel-build-sql
$ symfony propel-insert-sql
### Override the `setBody` method
When the `->setBody()` method of the `Question` class is called, the `html_body` column must also be updated with the Markdown conversion of the text body. Open the `askeet/lib/model/Question.php` model file, and create:
[php]
public function setBody($v)
{
parent::setBody($v);
require_once('markdown.php');
// strip all HTML tags
$v = htmlentities($v, ENT_QUOTES, 'UTF-8');
$this->setHtmlBody(markdown($v));
}
Applying the `htmlentities()` function before setting the HTML body protects askeet from cross-site-scripting (XSS) attacks since all `