Augmenter le nombre maximun de produits par categorie

janvier 14th, 2015 | by | magento

Jan
14

 

Suite à la migration d'un client sur un nouveau serveur j'ai été confronté à un problème pour ajouter des produits au dela de 1000 pour une catégorie.
Les produits étaient ajoutés puis lorsque l'on sauvegardait nous avions bien le message disant que la catégorie avait bien été sauvegardée mais les produits n'étaient pas ajoutés…

Le problème vient de la variable php max_input_vars.
Le plus simple est d'augmenter cette valeur dans votre php.ini ou via votre htaccess mais nous allons voir comment modifier cela uniquement pour la sauvegarde des catégories sur Magento.

Nous allons donc surcharger le contrôleur d'administration des catégories.

Il faut donc créer un fichier config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- /app/code/local/NAMESPACE/Categorylimit/etc/config.xml -->
<config>
   ...
   <admin>
      <routers>
         <adminhtml>
            <args>
               <namespace_categorylimit before="Mage_Adminhtml">Namespace_Categorylimit_Adminhtml</namespace_catergorylimit>
            </args> 
         </adminhtml>
      </routers>
   </admin>
   ...
</config>

Ce fichier dit à Magento d'appeler notre module avant "Mage_Adminhtml". Il reste donc à surcharger la methode save du CategoryController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
// /app/etc/local/NAMESPACE/Categorylimit/controllers/Adminhtml/Catalog/CategoryController.php
 
class Namespace_Categorylimit_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Catalog_CategoryController
{
 
  /**
     * Category save
     */
    public function saveAction()
    {
        if (!$category = $this->_initCategory()) {
            return;
        }
 
        $storeId = $this->getRequest()->getParam('store');
        $refreshTree = 'false';
        if ($data = $this->getRequest()->getPost()) {
            $category->addData($data['general']);
            if (!$category->getId()) {
                $parentId = $this->getRequest()->getParam('parent');
                if (!$parentId) {
                    if ($storeId) {
                        $parentId = Mage::app()->getStore($storeId)->getRootCategoryId();
                    }
                    else {
                        $parentId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
                    }
                }
                $parentCategory = Mage::getModel('catalog/category')->load($parentId);
                $category->setPath($parentCategory->getPath());
            }
 
            /**
             * Process "Use Config Settings" checkboxes
             */
            if ($useConfig = $this->getRequest()->getPost('use_config')) {
                foreach ($useConfig as $attributeCode) {
                    $category->setData($attributeCode, null);
                }
            }
 
            /**
             * Create Permanent Redirect for old URL key
             */
            if ($category->getId() && isset($data['general']['url_key_create_redirect']))
            // && $category->getOrigData('url_key') != $category->getData('url_key')
            {
                $category->setData('save_rewrites_history', (bool)$data['general']['url_key_create_redirect']);
            }
 
            $category->setAttributeSetId($category->getDefaultAttributeSetId());
 
            if (isset($data['category_products']) &&
                !$category->getProductsReadonly()) {
                $products = array();
                $cat_products_array = explode('&', $data['category_products']);
foreach($cat_products_array as $products) {
    $temp_array = array();
    parse_str($products, $temp_array);
    list($key, $val) = each($temp_array);
    if (!empty($key) && !empty($val)) {
        $products[$key] = $val;
    }
}
                $category->setPostedProducts($products);
            }
 
            Mage::dispatchEvent('catalog_category_prepare_save', array(
                'category' => $category,
                'request' => $this->getRequest()
            ));
 
            /**
             * Proceed with $_POST['use_config']
             * set into category model for proccessing through validation
             */
            $category->setData("use_post_data_config", $this->getRequest()->getPost('use_config'));
 
            try {
                $validate = $category->validate();
                if ($validate !== true) {
                    foreach ($validate as $code => $error) {
                        if ($error === true) {
                            Mage::throwException(Mage::helper('catalog')->__('Attribute "%s" is required.', $category->getResource()->getAttribute($code)->getFrontend()->getLabel()));
                        }
                        else {
                            Mage::throwException($error);
                        }
                    }
                }
 
                /**
                 * Check "Use Default Value" checkboxes values
                 */
                if ($useDefaults = $this->getRequest()->getPost('use_default')) {
                    foreach ($useDefaults as $attributeCode) {
                        $category->setData($attributeCode, false);
                    }
                }
 
                /**
                 * Unset $_POST['use_config'] before save
                 */
                $category->unsetData('use_post_data_config');
 
                $category->save();
                Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('catalog')->__('The category has been saved.'));
                $refreshTree = 'true';
            }
            catch (Exception $e){
                $this->_getSession()->addError($e->getMessage())
                    ->setCategoryData($data);
                $refreshTree = 'false';
            }
        }
        $url = $this->getUrl('*/*/edit', array('_current' => true, 'id' => $category->getId()));
        $this->getResponse()->setBody(
            '<script type="text/javascript">parent.updateContent("' . $url . '", {}, '.$refreshTree.');</script>'
        );
    }
}

En fait la modification porte sur cette ligne :

1
parse_str($data['category_products'], $products);

que l'on remplace par :

1
2
3
4
5
6
7
8
9
$cat_products_array = explode('&', $data['category_products']);
foreach($cat_products_array as $products) {
    $temp_array = array();
    parse_str($products, $temp_array);
    list($key, $val) = each($temp_array);
    if (!empty($key) && !empty($val)) {
        $products[$key] = $val;
    }
}

Pour expliquer, on découpe les produits de la catégorie une plusieurs morceaux pour ne plus être limiter par le serveur.

Il ne reste plus qu'à déclarer notre module app/etc/modules/Namespace_Categorylimit.xml

No Comments »

Résoudre le problème « Index process is working now. Please try run this process later »

décembre 29th, 2014 | by | magento

Déc
29

Lorsque l'on essaie de ré-indexer les données de Magento, il arrive que l'on tombe sur cette erreur et une fois tombé dessus, difficile de s'en sortir sans manipulation spécifique.
Vider le cache ne solutionne pas le problème. La solution se trouve dans le dossier /var/locks/. Le site créé un fichier, avec un id correspondant à chaque type d'indexation, pour dire qu'il est en cours de ré-indexation et bloquer tout autre action.
Sauf que parfois ces fichiers ne sont pas supprimés : manque de droit, indexation non terminée normalement...

Il faut donc supprimer tous les fichiers du dossier /var/locks/ et mettre ce dossier en 755 (ou 777 s'il le faut) pour que le serveur puisse recréer les fichiers .lock

Si cela ne fonctionne toujours pas, il faudra certainement aller voir du coté du script /shell/indexer.php pour indexer manuellement.

Et voilà, vous pouvez ré-indexer toutes vos données !

No Comments »

SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED

octobre 29th, 2014 | by | magento, sql

Oct
29

 

Cette erreur est survenue un jour ou j'ai voulu supprimer un produit dans le backoffice.

 

SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`DBNAME`.`q`.`items_count` - 1)'

 

Impossible de supprimer le produit !

Voici la solution :

- Allez dans votre base de données et faites une sauvegarde (toujours)
- Allez dans la table sales_flat_quote et affichez la structure- Modifiez le champ items_count et modifiez l'attribut en "Blank"
- Sauvegardez

 

Qu'est ce que signifie l'attribut UNSIGNED ?

Avec le petit tableau qui va bien

 

No Comments »

Désactiver les logs dans la base de données sur Magento

octobre 20th, 2014 | by | magento

Oct
20

A la recherche d'optimisations pour améliorer la vitesse de chargement de Magento, je me suis penché sur les logs.

Car Magento logs énormément de choses et pas seulement dans les fichiers du dossier var/log, il enregistre énormément de choses dans la base de donnés notamment sur les clients.

Cela prend beaucoup de ressource car fait appel à la base pour chaque insertion mais l’alourdi également inutilement.
On se retrouve rapidement avec plusieurs centaines de Mo voir Go de logs.

Désactiver le log dans System > Configuration > Advanced > Disable Modules Output ne suffit pas car il n'a pas de "output" à proprement parlé.

De plus, modifier dans System > Configuration > Developer > Log Settings > Enabled désactivera seulement les logs fichier du dossier var/log

Pour vraiment arrêter les logs sql voici comment faire :

1 - Ouvrir le fichier app/etc/local.xml

2 - Insérer ce code avant la balise fermante </config>

<frontend>
    <events>
        <controller_action_predispatch>
            <observers><log><type>disabled</type></log></observers>
        </controller_action_predispatch>
        <controller_action_postdispatch>
            <observers><log><type>disabled</type></log></observers>
        </controller_action_postdispatch>
        <customer_login>
            <observers><log><type>disabled</type></log></observers>
        </customer_login>
        <customer_logout>
            <observers><log><type>disabled</type></log></observers>
        </customer_logout>
        <sales_quote_save_after>
            <observers><log><type>disabled</type></log></observers>
        </sales_quote_save_after>
        <checkout_quote_destroy>
            <observers><log><type>disabled</type></log></observers>
        </checkout_quote_destroy>
    </events>
</frontend>

3 - sauvegarder le fichier

4 - Aller dans System > Configuration > Advanced et mettre Disable pour Mage_Log

5 - Pour finir, nettoyer le cache dans System > Cache Management

Magento n'écrira plus dans les tables de logs !

Ce n'est pas fini car il faut maintenant vider ces tables.

Toujours faire une sauvegarde quand on modifie la base !

Il suffit donc de faire des TRUNCATE :

TRUNCATE log_customer;
TRUNCATE log_quote;
TRUNCATE log_summary;
TRUNCATE log_summary_type;
TRUNCATE log_url;
TRUNCATE log_url_info;
TRUNCATE log_visitor;
TRUNCATE log_visitor_info;
TRUNCATE log_visitor_online;
TRUNCATE report_event;

 

 

No Comments »

Comment modifier le nombre de produits dans le crosselling du panier ?

septembre 24th, 2014 | by | magento

Sep
24

Pour diminuer ou augmenter le nombre de produits du crosselling affichés dans le panier cela se passe dans directement dans le code.

Oui c'est pas bien. Nous verrons par la suite comment rendre cette valeur administrable via un module custom.

Pour le moment nous allons modifier cette valeur "à l'arrache" dans le fichier app/code/core/Mage/Checkout/Block/Cart/Crossell.php

Vous pouvez copier ce fichier dans votre dossier local, ce qui est légèrement plus propre.

Vous allez trouver ceci :

class Mage_Checkout_Block_Cart_Crosssell extends Mage_Catalog_Block_Product_Abstract
{
    protected $_maxItemCount = 4;

Et vous n'avez qu'à changer le chiffre avec celui que vous désirez.

La suite bientôt...

No Comments »