jvlucas Posted July 3, 2020 Share Posted July 3, 2020 ¿Cual es la forma mas rápida de subir productos con sus imágenes a prestashop?, la idea es un script así que descarto la importación de csv directamente desde prestashop. Link to comment Share on other sites More sharing options...
Prestafan33 Posted July 3, 2020 Share Posted July 3, 2020 Lo más rápido es un CSV. Si quieres hacer un script también puedes, pero no es tarea sencilla, y al final igualmente vas a necesitar un archivo con la fuente de datos, sea CSV, sea XML o el formato que quieras. Muchas veces lo más sencillo es crear un script que adapte la fuente la datos a un formato importable directamente por Prestashop. No te aconsejo tampoco crear un script que "ataque" directamente a la base de datos de Prestashop, porque insertar productos puede tener más complicaciones de lo que parece a simple vista viendo las tablas (especialmente si tienen combinaciones). Si vas a hacerlo con un script, lo mejor es usar las clases propias de Prestashop para que funcione como debe y no tengas problemas luego. Un buen punto de partida si decides crear tu propio script es mirar en /src/Core/Import, ahí puedes estudiar cómo se realiza la importación de los archivos CSV para hacer algo similar. 1 Link to comment Share on other sites More sharing options...
jvlucas Posted July 3, 2020 Author Share Posted July 3, 2020 (edited) Muchas gracias por responder, ahora mismo lo tengo de esa manera (atacando las clases de prestashop), pero es muy lento, tengo subir muchos productos y agota el tiempo de ejecución de php de mi servidor. Alguna sugerencia. Edited July 3, 2020 by jvlucas Mayuscula al inicio. (see edit history) Link to comment Share on other sites More sharing options...
Prestafan33 Posted July 3, 2020 Share Posted July 3, 2020 (edited) 17 minutes ago, jvlucas said: Muchas gracias por responder, ahora mismo lo tengo de esa manera (atacando las clases de prestashop), pero es muy lento, tengo subir muchos productos y agota el tiempo de ejecución de php de mi servidor. Alguna sugerencia. Yo cuando he hecho algo parecido lo que he hecho para evitar los timeouts ha sido procesar solo un número determinado de productos en cada ejecución (por ejemplo, 50), y luego que el script se llame a sí mismo usando curl, pasando el número de último producto procesado, para que continúe a partir de ahí. Te pongo un ejemplo: private function callNextStep($file, $continuePos) { $key = sha1(_COOKIE_KEY_.'nombre_modulo'); $url = $this->context->link->getModuleLink('nombre_modulo', 'nombre_controlador'); $url.= '?action='.Tools::getValue('action').'&token='.$key.'&continue='.$continuePos.'&file='.urlencode($file); $cmd = 'curl -ssl -k -X GET "'.$url.'"'; $cmd .= ' >/dev/null 2>&1 &'; //descartamos la respuesta exec($cmd, $output, $exit); return true; } Esto lo hacía dentro de un módulo que tenía un controlador para procesar las llamadas, pero si lo haces directamente con un simple script externo puedes adaptarlo igualmente. Otra versión un poco más "elegante" (pero que al final acaba haciendo lo mismo): protected function callNextStep($nextProductToProcess) { $url = Tools::getHttpHost(true).__PS_BASE_URI__.'module/'.$this->module->name.'/xml?action=processProducts&key='.$this->module->secret_key; $url.= '&continue='.$nextProductToProcess; $this->curlCall($url); } public function curlCall($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_USERAGENT, 'api'); curl_setopt($curl, CURLOPT_TIMEOUT, 2); curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); curl_setopt($curl, CURLOPT_FORBID_REUSE, true); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT, 10); curl_setopt($curl, CURLOPT_FRESH_CONNECT, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_exec($curl); $result = curl_getinfo($curl); curl_close($curl); } Edited July 3, 2020 by Prestafan33 (see edit history) 1 Link to comment Share on other sites More sharing options...
jvlucas Posted July 3, 2020 Author Share Posted July 3, 2020 Ostras muchísimas gracias, no he trabajado nunca con curl intentare integrarlo en el proceso. Link to comment Share on other sites More sharing options...
gusman126 Posted July 7, 2020 Share Posted July 7, 2020 (edited) En 3/7/2020 a las 1:08 PM, Prestafan33 dijo: Yo cuando he hecho algo parecido lo que he hecho para evitar los timeouts ha sido procesar solo un número determinado de productos en cada ejecución (por ejemplo, 50), y luego que el script se llame a sí mismo usando curl, pasando el número de último producto procesado, para que continúe a partir de ahí. Te pongo un ejemplo: private function callNextStep($file, $continuePos) { $key = sha1(_COOKIE_KEY_.'nombre_modulo'); $url = $this->context->link->getModuleLink('nombre_modulo', 'nombre_controlador'); $url.= '?action='.Tools::getValue('action').'&token='.$key.'&continue='.$continuePos.'&file='.urlencode($file); $cmd = 'curl -ssl -k -X GET "'.$url.'"'; $cmd .= ' >/dev/null 2>&1 &'; //descartamos la respuesta exec($cmd, $output, $exit); return true; } Esto lo hacía dentro de un módulo que tenía un controlador para procesar las llamadas, pero si lo haces directamente con un simple script externo puedes adaptarlo igualmente. Otra versión un poco más "elegante" (pero que al final acaba haciendo lo mismo): protected function callNextStep($nextProductToProcess) { $url = Tools::getHttpHost(true).__PS_BASE_URI__.'module/'.$this->module->name.'/xml?action=processProducts&key='.$this->module->secret_key; $url.= '&continue='.$nextProductToProcess; $this->curlCall($url); } public function curlCall($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_USERAGENT, 'api'); curl_setopt($curl, CURLOPT_TIMEOUT, 2); curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); curl_setopt($curl, CURLOPT_FORBID_REUSE, true); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT, 10); curl_setopt($curl, CURLOPT_FRESH_CONNECT, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_exec($curl); $result = curl_getinfo($curl); curl_close($curl); } Interesante que haga una llamada CURL cuando termine. gracias Yo suelo añadirlo a un cron y verifico el tiempo de ejecución configurado en el PHP y lo paro 5 segundos antes, Al principio compruebo si el ultimo producto tiene imagen (en mi código siempre añado las imágenes al final) y si no tiene, elimino ese producto, ya que no se ha añadido correctamente y continuo añadiendo. Lo de ultima posición, seria interesante si fuera siempre el mismo fichero, yo compruebo si existe el producto del CSV con la referencia o añadiendo en una tabla especial el dato del CSV y cual es el ID de prestashop, ya que el fichero CSV puede cambiar entre un dia y otro Edited July 7, 2020 by gusman126 (see edit history) Link to comment Share on other sites More sharing options...
Prestafan33 Posted July 7, 2020 Share Posted July 7, 2020 30 minutes ago, gusman126 said: Lo de ultima posición, seria interesante si fuera siempre el mismo fichero, yo compruebo si existe el producto del CSV con la referencia o añadiendo en una tabla especial el dato del CSV y cual es el ID de prestashop, ya que el fichero CSV puede cambiar entre un dia y otro Sí, el código del ejemplo que he puesto lo utilizo para importar ficheros grandes de productos y poder dividir el procesamiento de cada fichero (el mismo) en lotes. Lo que hace mi controlador cuando es llamado es comprobar si se le ha pasado la variable "continue" en la URL, y si es así, "saltarse" líneas de producto del fichero hasta llegar al número que se le ha pasado, que es el último procesado en la llamada anterior. Y luego continuar importando desde ahí. Claro, al principio tienes que probar un poco cuánto se tarda en procesar cada producto, el timeout que tienes en el servidor y calcular cuántos productos puedes procesar antes de tener que dar el salto a la siguiente llamada. Y ser siempre bastante conservador, porque dependiendo de la carga del servidor puede que en unos momentos te pueda importar 50 productos en un minuto y en otros 30 solamente. 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