Magento import product image

How to import product image with the magento import tools ?
It’s quite easy, when you know how to fill your import file and put your file in the right directory.

The directory : create if needed a /media/import/ direcory in your magento root file, in my case it’s /home/www/eshop/media/import/
Paths in the import tool are always relative to you media/import directory.

The imported file : on you image or small_image columns, you need to put your file name prefixed by a “/”.

Some examples:
picture file ==> string in the import file
/home/www/eshop/media/import/product1.jpg ==> /product1.jpg
/home/www/eshop/media/import/ProductPage/product1.jpg ==> /ProductPage/product1.jpg

Hope this will help you.

PHP form limited to 1000 fields

Since PHP 5.3.9 form are limited to 1000 fields by default.
To fix it, you can edit your php.ini file and modify this variable

max_input_vars = 4000

And don’t forget to restart apache.

You can also edit it in your .htaccess file

 php_value max_input_vars 4000 

Change it directly in your php file with this

 ini_set('php_value max_input_vars', 4000); 

won’t work.

But change this varible may not fix your issue.
If you have suhosin installed, you laso have to edit his configuration file (/etc/php5/apache2/conf.d/suhosin.ini)

suhosin.get.max_vars = 4000 
suhosin.post.max_vars = 4000 
suhosin.request.max_vars = 4000 

To check your suhison configuration, use phpinfo() or in your php script

echo ini_get('suhosin.post.max_vars');

Fatal error : Declaration of {{path}}::validate() must be compatible with that of Sonata\AdminBundle\Admin\AdminInterface::validate()

You are trying to setup a custom validator on Sonata and 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 250

Don’t panic, just add this at the begining of your class

use Sonata\AdminBundle\Validator\ErrorElement;

in our example it’s in this file : /AdminBundle/Admin/AnnonceAdmin.php

Doctrine2 override save method

With Doctrine2 you cannot override save method but you can execute preUpdate() method.
See below how to implement it.

On your entity class, for example AdminBundle/Entity/Annonce.php, add the HasLifecycleCallbacks annontation

/**
 * @ORM\Entity(repositoryClass="Tripix\AdminBundle\Repository\AnnonceRepository")
 * @ORM\HasLifecycleCallbacks
 */

And your method, with the annotation

/** @ORM\PreUpdate() */
        public function preUpdate()
        {
                $this->created_at = new \DateTime("now");
        }

That’s all, it should works.

A complete example, just in case :

<?php
namespace Tripix\AdminBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * @ORM\Entity(repositoryClass="Tripix\AdminBundle\Repository\AnnonceRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Annonce
{

/** @ORM\PreUpdate() */
        public function preUpdate()
        {
                $this->created_at = new \DateTime("now");
        }

    public function __construct()
    {
        $this->created_at = new \DateTime("now");
        $this->visuels = new ArrayCollection();
    }

Symfony2 sonata custom CRUD template

It is possible to change templates use by default.

First, override the controller action method, in your AdminBundle/Controller/SecteurAdminController.php file

 /**
     * return the Response object associated to the list action
     *
     * @return Response
     */
    public function listAction()
    {
        if (false === $this->admin->isGranted('LIST')) {
            throw new AccessDeniedException();
        }

        $datagrid = $this->admin->getDatagrid();
        $formView = $datagrid->getForm()->createView();

        // set the theme for the current Admin Form
        $this->get('twig')->getExtension('form')->setTheme($formView, $this->admin->getFilterTheme());

        //custom code from here
        $total = 0;
        $enable = 0;
        $new = 0;
        $site = $this->admin->site;

        $repository = $this->getDoctrine()->getRepository('TripixAdminBundle:Annonce');
        $total = $repository->getNombreAnnonceTotal($site);
        $enable = $repository->getNombreAnnonceEnabled($site);
        $new = $repository->getNombreAnnonceNew($site);



        return $this->render('TripixAdminBundle:CRUD:list_secteur.html.twig', array(
            'action'   => 'list',
            'form'     => $formView,
            'datagrid' => $datagrid,
            'total'     => $total,
            'enable'    => $enable,
            'new'       => $new,
        ));
    }

The import thing on previous code is the render() fonction, the first parameter is the template to use.
In our example, the template file will be /AdminBundle/Ressources/view/CRUD/list_secteur.html.twig

You can use the /AdminBundle/Ressources/view/CRUD/base_secteur.html.twig file as example for your custom template.

Parent function to override on the controller are here : /vendor/bundles/Sonata/AdminBundle/Controller/CRUDController.php

Symfony2 Sonata add custom column on page list

To add a custom column on a page list, just follow these steps. In the example, we will add a “Nombre d’annoce(s)” column.

On your admin class file (ex: /AdminBundle/Admin/SecteurAdmin.php), on your configureListFields() fonction, add a new entry on the listMapper object

    /**
     * @param \Sonata\AdminBundle\Datagrid\ListMapper $listMapper
     * @return void
     */
    protected function configureListFields(ListMapper $listMapper) {
        $listMapper
                ->addIdentifier('titre')
                ->add('Tri', 'string', array('template' => 'TripixAdminBundle:Admin:list_tri.html.twig'))
                ->add('Nb', 'string', array('label' => 'Nombre d\'annonce(s)', 'template' => 'TripixAdminBundle:Admin:list_nb_annonce.html.twig'))
                ->add('_action', 'actions', array(
                    'actions' => array(
                        'edit' => array(),
                        'delete' => array(),
                    )
                ))
        ;
    }

This new entry said to use the TripixADminBundle:Admin:list_tri.html.twig template.

Now, create your template file (list_nb_annonce.html) in the /AdminBundle/ressources/view/admin/ directory.

{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% block field%}
{% if admin.datagrid.results|length > 1 %}
 <div>
        <strong>{{ object.getNombreAnnonce}}</strong>
    </div>
{% endif %}
{% endblock %}

In our example, getNombreAnnonce() is not defined, let’s do it
In the /adminBundle/Entity/Secteur.php file, add

   public function getNombreAnnonce()
    {
      return count($this->getAnnonces());
    }

That’s all.

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;

fpdf € transform into ? with UTF-8

You try to write a € character on your pdf doc but it is transformed into a “?”.
You can replace it by the chr(128) sign.

$this->MultiCell(170, $this->hh, $price." ".chr(128), 0, 'L', false);

When the sign is inside a string, you can use this

$contenu = str_replace('€', chr(128), $contenu);
$this->MultiCell(170, $this->hh, $contenu, 0, 'L', false);

But you have special characters too, you need to encode string into UTF-8

$contenu = str_replace('€', chr(128), $contenu);
$this->MultiCell(170, $this->hh, utf8_decode($contenu), 0, 'L', false);

This works well for “é” or “ç” but not for “€”.
The ultimate solution is :

$contenu = str_replace('€', utf8_encode(chr(128)), $contenu);
$this->MultiCell(170, $this->hh, utf8_decode($contenu), 0, 'L', false);