fpdf add page number

Here an easy way to add page number at the end of a fpdf document

In your fpdf class, before calling addpage(), call the AliasNbPages() fonction

$this->AliasNbPages();

then create a footer() fonction to override the default empty footer

function Footer()
{
        $this->SetY(-10);
        $this->SetFont('Arial', '', 8);
        $this->Cell(0,10,'Page '.$this->PageNo().'/{nb}', 0, 0, 'C');
        $this->SetY(-10);
        $this->Cell(0,10,"date d'impression: ".date('d/m/Y'), 0, 0, 'R');
}

The complete class : file pdfListeDemandes.class.php

<?php

class pdfListeDemandes extends FPDF
{
   function init()
   {
                $this->AliasNbPages();
                ...
   }
   function writeListe()
   {
         $this->init();
         ...
   }

   function Footer()
   {
        $this->SetY(-10);
        $this->SetFont('Arial', '', 8);
        $this->Cell(0,10,'Page '.$this->PageNo().'/{nb}', 0, 0, 'C');
        $this->SetY(-10);
        $this->Cell(0,10,"date d'impression: ".date('d/m/Y'), 0, 0, 'R');
   }

}

And the code to call your class

$pdf = new pdfListeDemandes();
$pdf->writeListe();
$pdf->output('Liste_demande.pdf', 'D');
exit;

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.

Increment ID identiques sur plusieurs commandes dans Magento 1.3

Découverte de la journée … un bug dans la version 1.3 de Magento lors de forte charge de mysql…. des commandes apparaissent avec des increment id identiques

La méthode fetchNewIncrementId de la classe Furet_Eav_Model_Entity_Type qui au final permet de récupérer le nouvel increment id, génère un SELECT et un UPDATE

SELECT `eav_entity_store`.* FROM `eav_entity_store` WHERE (entity_type_id='11') AND (store_id='1')
START TRANSACTION
UPDATE `eav_entity_store` SET `entity_store_id` = '2', `entity_type_id` = '11', `store_id` = '1', `increment_prefix` = '1', `increment_last_id` = '100132298' WHERE (entity_store_id='2')
commit

On s’imagine facilement ce qu’il peut se passer si beaucoup de clients tapent à la porte du site…

Client 1 => SELECT `eav_entity_store`.* FROM `eav_entity_store` WHERE (entity_type_id='11') AND (store_id='1')

Client 2 => SELECT `eav_entity_store`.* FROM `eav_entity_store` WHERE (entity_type_id='11') AND (store_id='1')

Client 1 => START TRANSACTION
Client 1 => UPDATE `eav_entity_store` SET `entity_store_id` = '2', `entity_type_id` = '11', `store_id` = '1', `increment_prefix` = '1', `increment_last_id` = '100132298' WHERE (entity_store_id='2')
Client 1 => commit

Client 2 => START TRANSACTION
Client 2 => UPDATE `eav_entity_store` SET `entity_store_id` = '2', `entity_type_id` = '11', `store_id` = '1', `increment_prefix` = '1', `increment_last_id` = '100132298' WHERE (entity_store_id='2')
Client 2 => commit

et voilà .. 2 commandes avec le même increment id

Ce bug est corrigé dans la version 1.7 en intégrant le SELECT dans la transaction et surtout en lui ajoutant le verrou de lecture “for update”

La méthode en question (Mage_Eav_Model_Mysql4_Entity_Store)

public function loadByEntityStore(Mage_Core_Model_Abstract $object, $entityTypeId, $storeId)
{
$read = $this->_getWriteAdapter();

$select = $read->select()-&gt;from($this-&gt;getMainTable())
->forUpdate(true)
->where('entity_type_id=?', $entityTypeId)
->where('store_id=?', $storeId);
$data = $read-&gt;fetchRow($select);

if (!$data) {
return false;
}

$object->setData($data);

$this->_afterLoad($object);

return true;
}

La solution pour corriger la 1.3 (même si il vaudrait mieux penser à passer à une version supérieure) :

  • Nouveau Module
  • Surchage de Mage_Eav_Model_Entity_Type->fetchNewIncrementId() pour ajouter le select dans la transaction
  • Surcharge de Mage_Eav_Model_Mysql4_Entity_Store->loadByEntityStore() pour ajouter le lock “for update”

Et voilà le rsultat

START TRANSACTION
SELECT `eav_entity_store`.* FROM `eav_entity_store` WHERE (entity_type_id='11') AND (store_id='1') FOR UPDATE
UPDATE `eav_entity_store` SET `entity_store_id` = '2', `entity_type_id` = '11', `store_id` = '1', `increment_prefix` = '1', `increment_last_id` = '100132304' WHERE (entity_store_id='2')
commit

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 )

Symfony 1.4 multi fields validator

In your form class (lib/form/doctrine/classForm.class.php)

  $this->validatorSchema->setPostValidator(
      new sfValidatorMultiFields(
        array('field1', 'field2', 'field3'),
        array('labels' => array('name1', 'name2', 'name3')),
        array('global_invalid' => 'Multi fields error')));

save this class in a lib folder, for exemple apps/frontend/lib/sfValidatorMultiFields.class.php

<?
class sfValidatorMultiFields extends sfValidatorSchema
{
 
  public function __construct(array $fields, $options = array(), $messages = array())
  {
    $this->addOption('fields', $fields);

    $this->addMessage('invalid', 'Error with this field');
    $this->addMessage('global_invalid', 'Multi fields error');

    parent::__construct(null, $options, $messages);
  }

  protected function doClean($values)
  {
    $valid = false;
    foreach ($this->getOption('fields') as $field) {
	//put here your validation code
        // ex: $values[$field] ....
    }
    //another example, at least one field in not empty
    if($values['field1'] != '' || $values['field2'] != '' || $values['field3'] != '')
    {
        $valid = true;
    }

    if ($valid)
    {
      $errorSchema = new sfValidatorErrorSchema($this);

        // The global error
        $errorSchema->addError(new sfValidatorError($this, 'global_invalid', array()));
      }

      // Fields error
      $error = new sfValidatorError($this, 'invalid', array()));

      // Add the error for each defined fields
      foreach ($this->getOption('fields') as $field)
      {
        $errorSchema->addError($error, $field);
      }

      throw $errorSchema;
    }

    return $values;
  }
}
?>

The keys points are :
– use $this->validatorSchema->setPostValidator() in your form class
– all fields are now available from the $values array ($values[‘field1′], $values[‘field2′] …)

Magento – display more than one image on page list

If you need to pull out more than one image per product in page list (list.phtml), the code below will help you.

<?php
  //get more images for product
  $product = Mage::getModel('catalog/product')->load($_product->getId());
  foreach ($product->getMediaGalleryImages() as $image) {
     echo "<img src='" . $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail', $image->getFile())->resize(50) . "' />";
  }
?>

Remove index.php from URL .htaccess

How to remove index.php from URL using .htaccess file ?
That is this easy :

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[^/]*/index\.php [NC]
RewriteRule ^index\.php(.+) $1 [R=301,L]
</IfModule>

Maybe you are using a magento website and you need to keep index.php for the backoffice.
Then add this condition to the .htaccess file

RewriteCond %{REQUEST_URI} !^[^/]*/index\.php/admin.*

and don’t forget to enable rewrite module

a2enmod rewrite

Redirect domain, add www

If you want to redirect your website’s visitors to your www domain name, add this in your apache virtualhost configuration

RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain.com$
RewriteRule ^/(.*)$ http://www.domain.com/$1 [R=301,L]

and don’t forget to enable rewrite module

a2enmod rewrite