must be compatible with that of Sonata\AdminBundle\Admin\AdminInterface::validate() error message

You are using sonata and want to validate some fields.
You innocently add the validate function to your Admin file

function validate(ErrorElement $errorElement, $object)
{
}

Then, you get this error :

Fatal error: Declaration of Adin\AdminBundle\Admin\AnnonceAdmin::validate() must be compatible with that of Sonata\AdminBundle\Admin\AdminInterface::validate() in /home/www/arlogis/src/Adin/AdminBundle/Admin/AnnonceAdmin.php on line 251 

You checked to AdminInterface file the declaration is the same.

To fix it, you need to use additionnal namespace :

use Sonata\AdminBundle\Validator\ErrorElement;
use Symfony\Component\Validator\ValidatorInterface;

Installing pear beta packages

You are trying to install a new pear package but get an error because pear is configured as stable and the package is beta ?

pear install Spreadsheet_Excel_Writer
Failed to download pear/Spreadsheet_Excel_Writer within preferred state "stable", latest release is version 0.9.3, stability "beta", use "channel://pear.php.net/Spreadsheet_Excel_Writer-0.9.3" to install
install failed

Here some tips to help you :
– force installation with -f

pear install -f Spreadsheet_Excel_Writer-0.9.3

– change pear preferences

pear config-set preferred_state beta
pear install Spreadsheet_Excel_Writer-0.9.3
pear config-set preferred_state stable

or do it directly within the same command

pear -d preferred_state=beta install Spreadsheet_Excel_Writer-0.9.3

– add the shorcut -beta at the end of the package name

pear install Spreadsheet_Excel_Writer-0.9.3-beta

Développement d’un module magento avec Git et Modman

Ca fait donc un moment que j’utilise Git dans mes développements quotidiens et jusqu’à présent j’utilisais le fichier .gitignore pour sortir l’ensemble des fichiers de magento de mon repo.

Ensuite il me suffisait d’ajouter les fichiers de mon modules en utilisant le paramètre de forçage ce qui me donnait des trucs du style :

git add -f app/code/community/MonNamespace/MonModule/

Ca fonctionne .. c’est pas optimal et il faut pas oublier d’inclure à la main l’ensemble des fichiers…
Aujourd’hui j’ai décidé d’essayer un outil qui à priori est fait pour faire ce type de développement j’ai nommé modman

En résumé c’est un gros bash qui va s’occuper pour nous :

  • de gérer les interactions avec votre repository git en le clonant dans son répertoire .modman
  • de faire les liens symboliques du repository placé dans .modman et notre instance de Magento

Etape 1 – Création d’un repository git qui va contenir le code de notre module

Donc la première chose à faire est de créer votre nouveau bare repository git avec par exemple le fichier de configuration modman à l’intérieur.

Sur le serveur contenant git

mkdir <monrepot>.git
cd !$
git --bare init

Puis en local chez vous vous préparer à faire votre premier commit

cd /tmp
mkdir temporaire
cd temporaire
git init
git remote add origin <monserveur>/<monrepot>.git
touch modman
git add modman
git commit -f "Initial commit"
git push origin master

et voilà .. fin de la première étape .. votre repo git qui va contenir le module est prêt

Etape 2 – Initialisation de modman et clone

Bon maintenant il vous faut une version toute fraichement installé de magento pour commencer .. je vais pas vous expliquer comment faire .. c’est assez bien décrit ici ou ici

Vous êtes donc désormais dans le DocumentRoot de votre magento et on va commencer par :

  • Initialiser modman
    modman init
  • Cloner notre dépôt git
    modman clone '<monserveur>/<monrepot>.git'

Arrivé ici vous devriez avoir votre repo cloné dans .modman/

Etape 3 – Le fichier de configuration de modman

Le fichier de configuration de modman est relativement simple en gros on a par ligne

 <cible> <source>

Du coup on va commencer avec une configuration basique pour un module à savoir

app/etc/modules/Namespace_Module.xml       app/etc/modules/Namespace_Module.xml
app/code/community/Namespace/Module/       app/code/community/Namespace/Module/

On peut lancer ensuite la commande modman, à la racine de votre documentroot, qui va créer les liens symboliques

modman update <monrepot>

Vous devriez voir apparaître dans les répertoires concernés les liens symboliques mappés sur le repot (dans .modman/xxxx)

Voilà .. pour finir il ne faut pas oublier d’activer la gestion de la prise en compte des liens symboliques dans magento. Ca se passe dans le backend et plus particulièrement dans le menu Système>Configuration>Développeur>Paramètres de gabarit

fpdf import pdf file

You are using fpdf to generate PDF file in php. You want to use an existing PDF file to import header and footer ? This is easy :

First, download FPDI lib here

and do that on your code :

require_once('fpdf.php'); 
require_once('fpdi.php'); 

$pdf = new FPDI();   // FPDI and not FPDF
$pdf->AliasNbPages();
$pdf->AddPage();
$pagecount = $pdf->setSourceFile(SF_ROOT_DIR.'/lib/fpdf/courrier.pdf');
$tplix = $pdf->importPage(1);
$pdf->useTemplate($tplix);
$pdf->Output('newdocument.pdf', 'D'); 

If you get this error

Warning: require_once(fpdf_tpl.php): failed to open stream:

you need to get the FPDF_TPL class too.

This only import file for the first page, if you want it on every page, override AddPage() function :

public function AddPage($orientation='', $size='', $keepmargins=false, $tocpage=false)
{
    parent::AddPage();
    $pagecount = $this->setSourceFile(SF_ROOT_DIR.'/lib/fpdf/courrier.pdf');                                                          
    $tplix = $this->importPage(1);
    $this->useTemplate($tplix);
}

Symfony2 twig add new function file_exists

An important function is missing on twig : file_exists.

I will show you here how to define a new function for twig.

On your namespace/bundle, add a Twig/Extension directory and create your class file :
/src/Adin/ArlogisBundle/Twig/Extension/FileExistsExtension.php

<?php

namespace Adin\ArlogisBundle\Twig\Extension;

class FileExistsExtension extends \twig_Extension
{
        /**
         *Return the function registered as twig extension
         *
         *@return array
         */
        public function getFunctions()
        {
                return array(
                        'file_exists' => new \Twig_Function_Function('file_exists'),
                        );
        }

        public function getName()
        {
                return 'adin_file_exists';
        }
}
?>

You then have to register your service, add a in your /Adin/ArlogisBundle/Ressources/config/services.xml file

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
       <service id="adin.twig.tripix_extension" class="Adin\ArlogisBundle\Twig\Extension\FileExistsExtension">
        <tag name="twig.extension" />
        </service>
    </services>
</container>

It’s ready, you can use it on your twig template

{% if file_exists('/var/www/image.jpg') %}
    File exists
{% else %}
    File not exists
{% endif %}

Be carefull, you need to specify the absolute path of the file. You can create a twig global variable root_path.
app/config/config.yml

# Twig Configuration
twig:
    globals:
        root_path: %kernel.root_dir%/../web

Then on twig template

{% if file_exists({{root_path}}'/var/www/image.jpg') %}
    File exists
{% else %}
    File not exists
{% endif %}

PHP sort array by sub value

Here my array structure :

Array
(
    [33] => Array
        (
            [id_site] => 33
            [datas] => Array
                (
                    [id] => 2965
                    [site_id] => 33
                    [operation_id] => 20
                    [positionnement] => 1
                )
            [statut] => Validé DM
            [sort] => 0119
        )
    [32] => Array
        (
            [id_site] => 32
            [datas] => Array
                (
                    [id] => 1929
                    [site_id] => 32
                    [operation_id] => 20
                    [positionnement] => 1
                 )
            [statut] => Validé DM
            [sort] => 0114
        )
    [34] => Array
        (
            [id_site] => 34
            [datas] => Array
                (
                    [id] => 2230
                    [site_id] => 34
                    [operation_id] => 20
                    [positionnement] => 1
                )
            [statut] => Validé DM
            [sort] => 0128
        )
)

How to sort by the [sort] value inside my array ?

I have to use the usort() function :

function sortByCustom($a, $b) {
    return strcmp($a['sort'], $b['sort']);
}
...
usort($array, 'sortByCustom');

Here the result :

Array
(
    [0] => Array
        (
            [id_site] => 32
            [datas] => Array
                (
                    [id] => 1929
                    [site_id] => 32
                    [operation_id] => 20
                    [positionnement] => 1
                 )
            [statut] => Validé DM
            [sort] => 0114
        )

    [1] => Array
        (
            [id_site] => 33
            [datas] => Array
                (
                    [id] => 2965
                    [site_id] => 33
                    [operation_id] => 20
                    [positionnement] => 1
                )
            [statut] => Validé DM
            [sort] => 0119
        )
    [2] => Array
        (
            [id_site] => 34
            [datas] => Array
                (
                    [id] => 2230
                    [site_id] => 34
                    [operation_id] => 20
                    [positionnement] => 1
                )
            [statut] => Validé DM
            [sort] => 0128
        )
)

If you want to maintain the index value association, use the uasort() function

uasort($array, 'sortByCustom');

Here the result :

Array
(
    [32] => Array
        (
            [id_site] => 32
            [datas] => Array
                (
                    [id] => 1929
                    [site_id] => 32
                    [operation_id] => 20
                    [positionnement] => 1
                 )
            [statut] => Validé DM
            [sort] => 0114
        )

    [33] => Array
        (
            [id_site] => 33
            [datas] => Array
                (
                    [id] => 2965
                    [site_id] => 33
                    [operation_id] => 20
                    [positionnement] => 1
                )
            [statut] => Validé DM
            [sort] => 0119
        )

    [34] => Array
        (
            [id_site] => 34
            [datas] => Array
                (
                    [id] => 2230
                    [site_id] => 34
                    [operation_id] => 20
                    [positionnement] => 1
                )
            [statut] => Validé DM
            [sort] => 0128
        )
)

If you use this in a class, you have to define the sort function outside the class

<?php
function sortByCustom($a, $b)
{
        return strcmp($a['sort'], $b['sort']);
}
class positionnemen {
...

for strict number comparaison, you can also use this function

  function sortByCustom($a, $b)
  {
      if($a['nbr'] > $b['nbr'])
      {
          return 1;
      }
      return -1;
  }

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 )