webmatersweetch Posted May 22, 2019 Share Posted May 22, 2019 Bonjour ! Je viens de finaliser un module assez simple qui regroupe l'emplacement de stock de mes produits en fonction de leurs références. Le module fonctionne très bien en local, mais quand je le passe sur le serveur et que j'ajoutes mon CSV sur la BDD directement avec 2365 entrées, le site ce met à ralentir fortement, pourtant le module génère pour moi peu de ressource... Alors peut être que dans mon AdminController je fais quelque chose de mal ? J'ai trouvé aucun moyen de savoir d'ou vient l'erreur. le DEBUG ne m'affiche rien. Voici quelques ressources de mon module : Mon AdminController : lass AdminSweetchEmplacementsController extends ModuleAdminController { // Changement pagination protected $_default_pagination = 10; public function __construct(){ // Variable $this->table = 'sweetchemplacement'; $this->className = 'SweetchEmplacement'; $this->bulk_actions = array( 'delete' => array( 'text' => 'Supprimer ?', 'confirm' => 'Sur ?' ) ); parent::__construct(); // Nom du produit $this->_select = 'pa.`id_product` as id_product, pl.`name` as product_name'; $this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.`reference` = a.`product_reference`) LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = pa.`id_product` AND pl.`id_lang` = 1)'; $this->_group = 'GROUP BY a.`id_sweetchemplacement`'; $this->_defaultOrderBy = 'emplacement'; $this->_orderWay = 'DESC'; $this->fields_list['product_reference'] = array( 'title' => 'ID Référence', 'align' => 'left', 'width' => 100 ); $this->fields_list['product_name'] = array( 'title' => 'Nom du produit', 'align' => 'left', 'width' => 200, 'search' => true, 'filter_key' => 'pl!name', ); $this->fields_list['emplacement'] = array( 'title' => 'Emplacement stock', 'align' => 'left', 'width' => 100, 'search' => true ); $this->bootstrap = true; $this->meta_title = 'Sweetch Emplacement'; } public function renderList() { $this->addRowAction('edit'); $this->addRowAction('view'); $this->addRowAction('delete'); return parent::renderList(); } public function renderView(){ $tpl = $this->context->smarty->createTemplate(dirname(__FILE__).'/../../views/templates/admin/view.tpl'); $tpl->assign('sweetchemplacement', $this->object); return $tpl->fetch(); } public function renderForm(){ $this->context = Context::getContext(); $this->context->controller = $this; $this->fields_form = array( 'legend' => array( 'title' => 'Créer ou Modifier un emplacement' ), 'input' => array( array( 'type' => 'text', 'label' => 'Référence du produit', 'name' => 'product_reference', 'desc' => 'Doit être un numéro flotant' ), array( 'type' => 'text', 'label' => 'Emplacement Stock', 'desc' => 'Doit être un numéro flotant', 'name' => 'emplacement', ), ), 'submit' => array('title' => 'Sauvegarder') ); return parent::renderForm(); } } Mon fichier core module : class SweetchEmplacements extends Module { public function __construct(){ // Name & Description $this->name = 'sweetchemplacements'; $this->author = 'Sweetch'; $this->version = '1.0.0'; $this->bootstrap = true; $this->displayName = $this->l('Sweetch WareHouse'); $this->description = $this->l('Warehouse product for company'); parent::__construct(); } public function getContent(){ return $this->display(__FILE__, 'getContent.tpl'); } // Install public function install(){ if (!parent::install()) { return false; } if (!$this->installDB()) { return false; } if (!$this->installTab('AdminCatalog','AdminSweetchEmplacements', 'Sweetch Emplacement')) { return false; } return true; } // Uninstall public function uninstall(){ if (!parent::uninstall()) { return false; } if (!$this->uninstallDB()) { return false; } if (!$this->uninstallTab('AdminSweetchEmplacements')) { return false; } return true; } public function installDB(){ return ( Db::getInstance()->Execute(' CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'sweetchemplacement` ( `id_sweetchemplacement` int(10) NOT NULL AUTO_INCREMENT, `product_reference` varchar(255) NOT NULL, `emplacement` float(10) NOT NULL DEFAULT 0, `date_add` datetime NOT NULL, PRIMARY KEY (`id_sweetchemplacement`) ) ENGINE = '._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8;') ); } public function uninstallDB(){ return ( Db::getInstance()->Execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.'sweetchemplacement`') ); } public function installTab($parent, $class_name, $name){ $tab = new Tab(); $tab->id_parent = (int)Tab::getIdFromClassName($parent); $tab->name = array(); foreach (Language::getLanguages(true) as $lang) { $tab->name[$lang['id_lang']] = $name; } $tab->class_name = $class_name; $tab->module = $this->name; $tab->active = 1; return $tab->add(); } public function uninstallTab($class_name){ $id_tab = (int)Tab::getIdFromClassName($class_name); $tab = new Tab((int)$id_tab); return $tab->delete(); } } Merci pour vos futurs indications... ! Link to comment Share on other sites More sharing options...
Janett Posted May 22, 2019 Share Posted May 22, 2019 (edited) Le forum n'est pas l'endroit le plus pratique pour commenter du code... Le problème vient plutôt de votre requête SQL en fait. Du coup, pour rendre le code un peu plus lisible, je te propose dans un premier temps une version épurée, n'hésite pas à poser des questions. Module (modules/sweetchemplacements/sweetchemplacements.php) : <?php if (!defined('_PS_VERSION_')) { exit; } require_once __DIR__ . '/classes/SweetchEmplacement.php'; class SweetchEmplacements extends Module { /** * Name of your ModuleAdminController */ const MODULE_ADMIN_CONTROLLER = 'AdminSweetchEmplacements'; /** * Constructor */ public function __construct() { $this->name = 'sweetchemplacements'; $this->tab = 'administration'; $this->version = '1.0.0'; $this->author = 'Sweetch'; $this->need_instance = 0; parent::__construct(); // Must be placed after call to parent because translator must be initialized for next lines $this->displayName = $this->l('Sweetch WareHouse'); $this->description = $this->l('Warehouse product for company'); } /** * Install Module * * @return bool */ public function install() { return parent::install() && $this->installDB() && $this->installTabs(); } /** * Install database * * @return bool */ public function installDB() { return Db::getInstance()->execute(' CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'sweetchemplacement` ( `id_sweetchemplacement` int(10) unsigned NOT NULL AUTO_INCREMENT, `product_reference` varchar(255) NOT NULL, `emplacement` float(10) NOT NULL DEFAULT 0, `date_add` datetime NOT NULL, PRIMARY KEY (`id_sweetchemplacement`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;'); } /** * Install Tabs * * @return bool */ public function installTabs() { if (Tab::getIdFromClassName(static::MODULE_ADMIN_CONTROLLER)) { return true; } $tab = new Tab(); $tab->class_name = static::MODULE_ADMIN_CONTROLLER; $tab->module = $this->name; $tab->active = true; $tab->id_parent = -1; $tab->name = array_fill_keys( Language::getIDs(false), $this->displayName ); return $tab->add(); } /** * Uninstall Module * * @return bool */ public function uninstall() { return parent::uninstall() && $this->uninstallDB() && $this->uninstallTabs(); } /** * Uninstall database * * @return bool */ public function uninstallDB() { return Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'sweetchemplacement`'); } /** * Uninstall Tabs * * @return bool */ public function uninstallTabs() { $id_tab = (int) Tab::getIdFromClassName(static::MODULE_ADMIN_CONTROLLER); if ($id_tab) { $tab = new Tab($id_tab); return $tab->delete(); } return true; } /** * Redirect to your ModuleAdminController when click on Configure button */ public function getContent() { Tools::redirectAdmin($this->context->link->getAdminLink(static::MODULE_ADMIN_CONTROLLER)); } } ObjectModel (modules/sweetchemplacements/classes/SweetchEmplacement.php) : <?php class SweetchEmplacement extends ObjectModel { /** * @var string */ public $product_reference; /** * @var float */ public $emplacement; /** * @var string */ public $date_add; public static $definition = array( 'table' => 'sweetchemplacement', 'primary' => 'id_sweetchemplacement', 'multilang' => false, 'fields' => array( 'product_reference' => array('type' => self::TYPE_STRING, 'validate' => 'isReference', 'size' => 255), 'emplacement' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'), 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), ), ); } ModuleAdminController : (modules/sweetchemplacements/controllers/admin/AdminSweetchEmplacementsController.php) <?php class AdminSweetchEmplacementsController extends ModuleAdminController { public function __construct() { $this->table = 'sweetchemplacement'; $this->className = 'SweetchEmplacement'; $this->bootstrap = true; $this->addRowAction('edit'); $this->addRowAction('delete'); parent::__construct(); // Problem is here, your query is not good $this->_select = 'pa.`id_product` as id_product, pl.`name` as product_name'; $this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON (pa.`reference` = a.`product_reference`)'; $this->_join .= 'LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.`id_product` = pa.`id_product` AND pl.`id_lang` = ' . (int) $this->context->language->id . ')'; $this->_group = 'GROUP BY a.`reference`'; // Not right choice $this->_defaultOrderBy = 'emplacement'; $this->_orderWay = 'DESC'; $this->_default_pagination = 10; // Here, if you would use Translator, this lines must be after call to parent because translator must be initialized $this->meta_title = 'Sweetch Emplacement'; $this->bulk_actions = array( 'delete' => array( 'text' => 'Supprimer ?', 'confirm' => 'Sur ?', ), ); $this->fields_list = array( 'product_reference' => array( 'title' => 'ID Référence', 'align' => 'left', 'width' => 100, ), 'product_name' => array( 'title' => 'Nom du produit', 'align' => 'left', 'width' => 200, 'search' => true, 'filter_key' => 'pl!name', ), 'emplacement' => array( 'title' => 'Emplacement stock', 'align' => 'left', 'width' => 100, 'search' => true, ), ); $this->fields_form = array( 'legend' => array( 'title' => 'Créer ou Modifier un emplacement', ), 'input' => array( array( 'type' => 'text', 'label' => 'Référence du produit', 'name' => 'product_reference', 'desc' => 'Doit être un numéro flotant', ), array( 'type' => 'text', 'label' => 'Emplacement Stock', 'desc' => 'Doit être un numéro flotant', 'name' => 'emplacement', ), ), 'submit' => array('title' => 'Sauvegarder'), ); } } Le module fonctionne mais ce n'est pas l'idéal car la requête SQL générée est pas top Quote #1055 - Expression #5 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'prestashop.pa.id_product' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by Bref le point d'amélioration est à faire ici, il vaut mieux se baser sur des ID que sur des références pour faire des jointures. Donc revoir la partie base de données, structure de la table, identifiants pour les jointures etc... Edited May 22, 2019 by Janett (see edit history) Link to comment Share on other sites More sharing options...
webmatersweetch Posted May 22, 2019 Author Share Posted May 22, 2019 Alors déjà un grand merci pour cette re-structuration plus pro du module. Deuxième point, si je comprend bien ce qui fâche c'est $this->_group = 'GROUP BY a.`reference`'; // Not right choice et puis surement ceci $this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON (pa.`reference` = a.`product_reference`)'; car je fais un lien avec un varchar et ceci être peut-être lié au problème ? Comment-avez eu cette aide ? #1055 - Expression #5 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'prestashop.pa.id_product' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by Et comment puis-je savoir si la requête est bonne ? car son localhost mon site ne plante pas... Merci beaucoup. Link to comment Share on other sites More sharing options...
Janett Posted May 22, 2019 Share Posted May 22, 2019 En cliquant sur l'icône dans le carré rouge, la requête SQL générée s'affiche. Il vous suffit de tenter de l'exécuter dans phpmyadmin par exemple. Ce n'est pas spécialement le fait que ce soit un varchar dans la jointure, le problème c'est surtout que sans le group by, la requête vous renvoie plusieurs résultats pour 1 seul produit, ce qui implique que votre jointure n'est pas suffisamment précise. Normalement il n'y a pas besoin de group by dans votre cas, si la requête est bien construite. Link to comment Share on other sites More sharing options...
webmatersweetch Posted May 22, 2019 Author Share Posted May 22, 2019 Je vais repenser la construction. Merci pour les infos importantes. 😀 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now