Symfony validator custom error message

If you need to customize your validator error messages, you can use the setMessage() function.
On your Form class (ex: /lib/form/doctrine/DemandeForm.class.php)

//sfValidatorInteger
$this->validatorSchema['produit_ean']->setMessage('invalid', 'ean should be integer');
$this->validatorSchema['produit_ean']->setMessage('min', 'ean must be at least %min%');
$this->validatorSchema['produit_ean']->setMessage('max', 'ean must be at least %max%');

//sfValidatorDate
$this->validatorSchema['date']->setMessage('bad_format', 'Format must be dd/mm/YYYY');
$this->validatorSchema['date']->setMessage('max', 'Date should be after than 01/01/2013');
$this->validatorSchema['date']->setMessage('min', 'Date should be before than 01/02/2013');

//required
$this->validatorSchema['date']->setMessage('required', 'Date is mandatory');

Symfony 1.x propel-insert-sql [propel-sql-exec] SQLSTATE[42000]: Syntax error or access violation: 1064

You are using a old version of symfony 1.x on a new version of mysql and when you try to insert the model on your database you get this error :

[propel-sql-exec] SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘Type=InnoDB’ at line 6

The problem come from this query

CREATE TABLE `pret_externe_type`
 (
 `id_pret_externe_type` BIGINT(20)  NOT NULL AUTO_INCREMENT,
 `libelle` VARCHAR(100)  NOT NULL,
 PRIMARY KEY (`id_pret_externe_type`)
 )Type=InnoDB

Mysql do not use “Type=” option anymore, you have to replace it by “Engine=”

CREATE TABLE `pret_externe_type`
 (
 `id_pret_externe_type` BIGINT(20)  NOT NULL AUTO_INCREMENT,
 `libelle` VARCHAR(100)  NOT NULL,
 PRIMARY KEY (`id_pret_externe_type`)
 )Engine=InnoDB

To fix it the code, on symfony 1.2 go on this file /lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php and change the line 156
from

 $script .= "Type=$mysqlTableType";

to

 $script .= "Engine=$mysqlTableType";

On symfony 1.4, you have to change this file : lib/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php
Always on ligne 156

After code change, rebuild your SQL model and insert it to your databases

php symfony propel-build-sql
php symfony propel-insert-sql

Warning: ob_start(): function ” not found or invalid function name Symfony

If you are installing a symfony 1.x project on a PHP 5.4.1 (or later) version, you may encounter this warning message :
Warning: ob_start(): function ” not found or invalid function name in /var/www/lib/config/sfApplicationConfiguration.class.php on line 157 Notice: ob_start(): failed to create buffer in /var/www/lib/config/sfApplicationConfiguration.class.php on line 157

To fix it, go on your /lib/config/sfApplicationConfiguration.class.php file and change this

// compress output
    if (!self::$coreLoaded)
    {
      ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : '');
    }

to this

// compress output
    if (!self::$coreLoaded)
    {
      ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : null);
    }

sfWidgetFormDateJQueryUI date format

You want to use the sfWidgetFormDateJQueryUI widget but you cannot configure it to display the date in your culture ?

I had the same problem, and there is what I did to fix it.

I start to override the sfWidgetFormDateJQueryUI class to add a “format_date” option. Add a new class here lib/widget/adinWindgetFormDateJQueryUI.class.php and override the configure fonction to add the format_date option.

 protected function configure($options = array(), $attributes = array())
  {
    $this->addOption('format_date', null);
    parent::configure($options, $attributes);
  }

In the render function, format the value

   if($this->getOption('format_date') != null){
        $dateFormat = new sfDateFormat();
        $value = $dateFormat->format($value, $this->getOption('format_date'));
    }

(The complete class source is at the end of this post.)

In your formClass, configure the widget :

class DemandeForm extends BaseDemandeForm
{
    public function configure()
    {
       $this->widgetSchema['date_creation'] = new adinWidgetFormDateJQueryUI(
                array("change_month" => true, 
                      "change_year" => true, 
                      "culture" => 'fr', 
                      "show_button_panel" => true, 
                      "format_date" => 'dd/MM/y' //define here format
                      )
                 );

        $this->validatorSchema['date_creation'] = new sfValidatorDate(   
                array("date_format" => '~(?P<day>\d{2})/(?P<month>\d{2})/(?P<year>\d{4})~' , //regex,
                      "date_output" => "Y-m-d",  //format the value after validation to send to BDD
                      "required" => true
                      )
                 );
    }
}

Here the complete adinWidgetFormDateJQueryUI source code

<?php
class adinWidgetFormDateJQueryUI extends sfWidgetFormDateJQueryUI
{
 protected function configure($options = array(), $attributes = array())
  {
    $this->addOption('format_date', null);
    parent::configure($options, $attributes);
  }

  /**
   * @param  string $name        The element name
   * @param  string $value       The date displayed in this widget
   * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
   * @param  array  $errors      An array of errors for the field
   *
   * @return string An HTML tag string
   *
   * @see sfWidgetForm
   */
  public function render($name, $value = null, $attributes = array(), $errors = array())
  {
    $attributes = $this->getAttributes();

    $input = new sfWidgetFormInput(array(), $attributes);

   if($this->getOption('format_date') != null){
        $dateFormat = new sfDateFormat();
        $value = $dateFormat->format($value, $this->getOption('format_date'));
    }
    $html = $input->render($name, $value);

    $id = $input->generateId($name);
    $culture = $this->getOption('culture');
    $cm = $this->getOption("change_month") ? "true" : "false";
    $cy = $this->getOption("change_year") ? "true" : "false";
    $nom = $this->getOption("number_of_months");
    $sbp = $this->getOption("show_button_panel") ? "true" : "false";

    if ($culture!='en')
    {
    $html .= <<<EOHTML
<script type="text/javascript">
        $(function() {
    var params = $.datepicker.regional['$culture'];
    params.changeMonth = $cm;
    params.changeYear = $cy;
    params.numberOfMonths = $nom;
    params.showButtonPanel = $sbp;
    $("#$id").datepicker(params);
        });
</script>
EOHTML;
    }
    else
    {
    $html .= <<<EOHTML
<script type="text/javascript">
        $(function() {
    var params = {
    changeMonth : $cm,
    changeYear : $cy,
    numberOfMonths : $nom,
    showButtonPanel : $sbp };
    $("#$id").datepicker(params);
        });
</script>
EOHTML;
    }

    return $html;
  }
}

Don’t forget to run

php symfony cc

to clear your cache and enable this new class on prod environment.

Symfony The default context does not exist

You may have to use in your model class or somewhere else the “context instance” in your code but when this code is used by a task, a test or data fixture, you get a “The default contect does not exist” error.
To avoid that, you can use the sfContext::hasInstance() fonction. See below

class Demande extends BaseDemande
{
   public function save(Doctrine_Connection $con = null)
   {
       if(sfContext::hasInstance())
       {
          $id_service = sfContext::getInstance()->getUser()->getAttribute('id_service', false, 'sfMatchlib/user');        
          $this->setIdService($id_service);
        }
        parent::save($con);
    }
}

Symfony 1.4 format date doctrine object

To format a date from a doctrine object, you can use this code, quick and easy.

$demande->getDateTimeObject('date_creation')->format('d/m/Y');

Sometimes, this first solution return current date even if the doctrine record is null.
You then have to use this other solution

use_helper('Date');
format_date($demande->getDateCreation(), 'dd-MM-yyyy');

You can found format rules here

ckWebServicePlugin empty params

You are using Symfony and the ckWebServicePlugin but in your action method you can’t access params value ? They are desperately empty ?

This may due to a configuration issue, in your apps/config/filters.yml, it is important to put the soap_parameter before the cache and execution parameters

doesn’t work

# You can find more information about this file on the symfony website:
# http://www.symfony-project.org/reference/1_4/en/12-Filters

rendering: ~
security:  ~

# insert your own filters here

cache:     ~
execution: ~

soap_parameter:
  class: ckSoapParameterFilter
  param:
    condition: %APP_ENABLE_SOAP_PARAMETER%

works

# You can find more information about this file on the symfony website:
# http://www.symfony-project.org/reference/1_4/en/12-Filters

rendering: ~
security:  ~

# insert your own filters here
soap_parameter:
  class: ckSoapParameterFilter
  param:
    condition: %APP_ENABLE_SOAP_PARAMETER%

cache:     ~
execution: ~

It looks weird but it works for me.

Symfony 1.4 display an array in templates

You need to use an array in your template but this array is transform as an object by symfony.

in your actions/actions.class.php

public function executeChoix(sfWebRequest $request)
{
        $this->nom_jour = array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi' , 'Samedi');
}

in your template template/choixSuccess.php

<?php print_r($nom_jour); ?>

This is what you get :
sfOutputEscaperArrayDecorator Object ( [count:sfOutputEscaperArrayDecorator:private] => 7 [value:protected] => Array ( [0] => Dimanche [1] => Lundi [2] => Mardi [3] => Mercredi [4] => Jeudi [5] => Vendredi [6] => Samedi ) [escapingMethod:protected] => esc_specialchars )

To display a proper array, use

<?php print_r($sf_data->getRaw('nom_jour')); ?>

You get the classic print_r render :
Array ( [0] => Dimanche [1] => Lundi [2] => Mardi [3] => Mercredi [4] => Jeudi [5] => Vendredi [6] => Samedi )