4
votes

I have the following setup: php 5.4, symfony 1.4.17, and firefox, ie, chrome.

I have built a simple news module.

  • table: TbNews
  • columns:
    • id as primary key
    • scontent as a text field for saving the news content. It will have html content inside, saved with CKeditor and its working perfectly.

If I use fetchOne() (in template), the html is interpreted before writting the content.

If I use symfony pager (in action, then template) the html is NOT interpreted and I see the HTML tags in the output with the content. You can see the examples below which shows exactly what Im talking about.

I have read in other topics that for security reasons symfony output escaper automatically converts HTML into "text", and we must use getRawValue on the data to get the original HTML chars.

I have some questions:

  1. why symfony output escaper is working with symfony pager, and its not working if we use fetchOne()?
  2. how should I use getRawValue() in my example below with the symfony pager, interpreting the HTML and then showing only the content?
  3. Is getRawValue() the best option to get only the content written?

Example code:

//1. fetchOne() outputs content interpreting html before.
//index/templates/indexSuccess.php
//-------------------------------
$q = Doctrine_Query::create()->from('TbNews e')->where('e.id = ?', '1');
$new = $q->fetchOne(); // <p>testcontent</p>\r\n
echo $new['scontent']; 
// output:  testcontent  --- OK, output is not escaped because we are jumping symfony output escaper since we are doing it directly in the action.


//2. Get all news with symfony pager, html tags are not interpreted, html tags are shown.
//index/actions/actions.class.php
//-------------------------------
$app_max_news_in_homepage = 4;
$this->pager = new sfDoctrinePager('TbNews', $app_max_news_in_homepage);
$this->pager->setQuery(Doctrine::getTable('TbNews')->createQuery('a'));
$this->pager->setPage($request->getParameter('page', 1));
$this->pager->init();

//index/templates/indexSuccess.php 
//--------------------------------
foreach ($pager->getResults() as $new)
{
  echo $new['scontent']; // &lt;p&gt;testcontent&lt;/p&gt;\r\n
}

//output:  <p>testcontent</p>  --- OK, since output is escaped by symfony output escaper since we get data at the action and show it in the template.
1

1 Answers

4
votes

Your first test is wrong.

When you test with fetchOne(), you are inside an action. So the content you retrieve from your database and the one you displayed (with echo) isn't escaped because it's not send to the template.

When you perform your second test, you retrieve the content from the action and display the result inside the template. In this case, the content is escaped by sfOutputEscaper. If you make the first test and then try to display the content in your template, you'll see that the html is escaped.

// in actions
$this->new = $q->fetchOne();

// in template
echo $new['scontent'];

// result-> &lt;p&gt;testcontent&lt;/p&gt;\r\n

If you have activated escaping_strategy & escaping_method inside your apps/[app_name]/config/settings.yml, every thing that will be given to the template will be escaped.

When I want to display a html content which has been escaped, I usually use the unescape method from the sfOutputEscaper. In your case:

foreach ($pager->getResults() as $new)
{
  echo sfOutputEscaper::unescape($new['scontent']);
}

another option (said by Michal Trojanowski):

foreach ($pager->getResults()->getRawValue() as $new)
{
  echo $new['scontent'];
}