Jump to content

shopimport.nl

Members
  • Posts

    51
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

shopimport.nl's Achievements

Newbie

Newbie (1/14)

13

Reputation

  1. Did you enable 'Enable B2B mode' in the Customer Settings menu? I didn't need myself but I presume it will be prepared for your 0% tax within Europe which indeed is a standard rule. I think it is called intra-Community supply.
  2. With prestashop 1.6.1.12 I still have missing translations while the translation do exist in other modules. I've developed to find more translations when you go the the backoffice -> translations -> module translations. And then you should see more translations filled in and you should save the form as these are not yet saved before. In the file controllers/admin/AdminTranslationsController.php in the function public function initFormModules() just before $this->tpl_view_vars add this line: $this->refill(); And just before the function initFormModules() add these functions: protected function translationsByMd5() { $this->translationsByMd5 = array(); $name_var = $this->translations_informations[$this->type_selected]['var']; foreach( $GLOBALS[$name_var] as $key => $value ) { preg_match('/_([^_]*)$/',$key,$m); if(!isset($this->translationsByMd5[$m[1]])) { $this->translationsByMd5[$m[1]] = $value; } } } protected function drill() { foreach( $this->modules_translations as $theme_name => &$l1) { foreach( $l1 as $module_name => &$l2 ) { foreach( $l2 as $template_name => &$l3 ) { foreach( $l3 as $key => &$l4 ) { if(isset($l4['trad']) && $l4['trad'] == '' ) { $keyMd5 = md5(preg_replace("/\\\*'/", "\'", $key) ); $l4['trad'] = $this->translationsByMd5[$keyMd5] ?: ''; } } } } } } protected function refill() { $this->translationsByMd5(); $this->drill(); }
  3. I did experience slow PDF (invoice) generation with my prestashop upgrade to 1.6.5 and found the fix. Maybe worth to try for your image PNG logo issue. Upgrade the 3rd party software tcpdf which is located in tools/tcpdf First make a backup of tools/tcpdf Download the zip from https://sourceforge.net/projects/tcpdf/files/ unpack it and copy it OVER the original one If you replace the whole folder then prestashop still cannot generate invoices. Maybe there is a file in tools/tcpdf which is prestashop specific. I didn't look into this as it's working now. My tcpdf upgraded from 5.9.179 to 6.2.11. The version is listed at the top of the tcpdf.php file
  4. I've prepared a script. The script will read the img/p folder and check for each file if it exists in the database table ps_image. In case it doesn't exists then it prints the file and deletes the file. I commented the unlink() so you can run it without really deleting and when you are confident then you can uncomment the "unlink()" command and it will really delete the image files. You need to configure the root of the shop path. And you can set a max number of files that the script will read from the img/p folder. The script is not yet prepared for the new img/p/1/2/3/ structure, only for the structure to have all jpg files directly in the img/p. It should be relative easy to improve this. Copy this script into a file "cleanup.php" in the root of your shop. Then edit the value $shop_root and the run the script by the browser (http://yourdomain.com/cleanup.php) or on the console (login with ssh for the experts). The query to check the ps_image table will always result in 1 row to ensure that no files will be deleted when there are database errors. So the script is secured for unexpected mysql errors (like overload of mysql server which you don't want to result in not finding the images and thus would remove the image files). <?php // root path of the shop $shop_root='/home/kooozybe/public_html/shop/'; // limit number of image files to check, set to 10 for testing $limit=1000000; include $shop_root . '/config/settings.inc.php'; $pdo = new PDO( 'mysql:host='._DB_SERVER_.';dbname='._DB_NAME_, _DB_USER_, _DB_PASSWD_ ); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $r=$pdo->query('select count(1) cnt from ps_image')->fetch(); echo 'count images database: '.$r['cnt']; // reset some counters $cnt_files=0; $cnt_checked=0; $cnt_not_found=0; $cnt_found=0; $path=$shop_root.'/img/p'; if ($handle = opendir($path)) { while ($cnt_files != $limit && false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { $cnt_files++; $pi = explode('-',$entry); if($pi[0]>0 && $pi[1]>0) { $cnt_checked++; if(!checkExistsDb($pdo,$pi[0],$pi[1])) { $cnt_not_found++; echo 'rm '.$path.'/'.$entry."\r\n"; // this will delete files unlink($path.'/'.$entry); } else { $cnt_found++; } } } } closedir($handle); } echo 'files: '.$cnt_files.' checked: '.$cnt_checked.' not_found: '.$cnt_not_found.' found: '.$cnt_found; function checkExistsDb($pdo, $id_product, $id_image) { $r=$pdo->query($q='select \'ok\' ok, (select id_image from ps_image where id_product = '.(int)$id_product.' and id_image = '.(int)$id_image.') id_image'); $row=$r->fetch(); if($row['ok']!='ok') die( 'Problem with query, please correct'); return $row['id_image']?true:false; }
  5. I've prepared a script. The script will read the img/p folder and check for each file if it exists in the database table ps_image. In case it doesn't exists then it prints the file and deletes the file. I commented the unlink() so you can run it without really deleting and when you are confident then you can uncomment the "unlink()" command and it will really delete the image files. You need to configure the root of the shop path. And you can set a max number of files that the script will read from the img/p folder. The script is not yet prepared for the new img/p/1/2/3/ structure, only for the structure to have all jpg files directly in the img/p. It should be relative easy to improve this. Copy this script into a file "cleanup.php" in the root of your shop. Then edit the value $shop_root and the run the script by the browser (http://yourdomain.com/cleanup.php) or on the console (login with ssh for the experts). The query to check the ps_image table will always result in 1 row to ensure that no files will be deleted when there are database errors. So the script is secured for unexpected mysql errors (like overload of mysql server which you don't want to result in not finding the images and thus would remove the image files). <?php // root path of the shop $shop_root='/home/kooozybe/public_html/shop/'; // limit number of image files to check, set to 10 for testing $limit=1000000; include $shop_root . '/config/settings.inc.php'; $pdo = new PDO( 'mysql:host='._DB_SERVER_.';dbname='._DB_NAME_, _DB_USER_, _DB_PASSWD_ ); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $r=$pdo->query('select count(1) cnt from ps_image')->fetch(); echo 'count images database: '.$r['cnt']; // reset some counters $cnt_files=0; $cnt_checked=0; $cnt_not_found=0; $cnt_found=0; $path=$shop_root.'/img/p'; if ($handle = opendir($path)) { while ($cnt_files != $limit && false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { $cnt_files++; $pi = explode('-',$entry); if($pi[0]>0 && $pi[1]>0) { $cnt_checked++; if(!checkExistsDb($pdo,$pi[0],$pi[1])) { $cnt_not_found++; echo 'rm '.$path.'/'.$entry."\r\n"; // this will delete files unlink($path.'/'.$entry); } else { $cnt_found++; } } } } closedir($handle); } echo 'files: '.$cnt_files.' checked: '.$cnt_checked.' not_found: '.$cnt_not_found.' found: '.$cnt_found; function checkExistsDb($pdo, $id_product, $id_image) { $r=$pdo->query($q='select \'ok\' ok, (select id_image from ps_image where id_product = '.(int)$id_product.' and id_image = '.(int)$id_image.') id_image'); $row=$r->fetch(); if($row['ok']!='ok') die( 'Problem with query, please correct'); return $row['id_image']?true:false; } I hope this will help you
  6. I investigated slow detele and the root cause for my environment is InnoDB engine which mysql is using and prestashop is using by default. First I suspected slow queries. There are MANY queries when you delete one product. And also to correct the position I see hundreds or more of these taking all long time (first value in seconds) 0.4297:UPDATE `ps_category_product` SET `position` = '0' WHERE `id_category` = 107 AND `id_product` = 1328 ====== 0.1726:UPDATE `ps_category_product` SET `position` = '1' WHERE `id_category` = 107 AND `id_product` = 1346 ====== 0.0882:UPDATE `ps_category_product` SET `position` = '2' WHERE `id_category` = 107 AND `id_product` = 1348 ====== 0.4659:UPDATE `ps_category_product` SET `position` = '3' WHERE `id_category` = 107 AND `id_product` = 1376 Then I dig into the code and see this comment: // Deleting products can be quite long on a cheap server. Let's say 1.5 seconds by product (I've seen it!). I can tell you I don't have a cheap server... Then I discovered that mysql is very slow for delete/update/insert when using InnoDB. I changed all tables to MyISAM and voila, no more LONGGGG delays. Maybe even 100 times faster!! How I did: Export your full database to an sql file (I use mysqldump, but can also be myphpadmin). Then first make a copy of the file (so you have a backup). Then replace "InnoDB" with "MyISAM" and import again. Also my shop is faster again for normal usage (select). Maybe because I optimized the mysql server.
  7. Nice it's working for 1.5.3! I little bit improved it to be less depending on future versions. Instead of replacing the original classes/Messages.php this function makes use of the override. Just add this function in the override/classes/Messages.php so just below: class Message extends MessageCore { public static function getMessagesByOrderId($id_order, $private = false, Context $context = null) { $m=parent::getMessagesByOrderId($id_order, $private, $context); $o = Db::getInstance()->executeS(' SELECT ct.*, m.*, e.`firstname` AS efirstname, e.`lastname` AS elastname FROM `'._DB_PREFIX_.'customer_thread` ct LEFT JOIN `'._DB_PREFIX_.'customer_message` m ON m.`id_customer_thread` = ct.`id_customer_thread` LEFT OUTER JOIN `'._DB_PREFIX_.'employee` e ON e.`id_employee` = m.`id_employee` WHERE ct.`id_order` = '.(int)$id_order.' ORDER BY ct.`date_add` DESC' ); return array_merge($o,$m); } } Thanks to the original person who posted this fix!
  8. @funcker you might want to review the standard module (Prestashop 1.5.4): European VAT number Developed by :PrestaShop| Version :1.2 | Category :Billing and Invoicing Description : Enable entering of the VAT intra-community number when creating the address (You must fill in the company field to allow keyboarding VAT number) Please share if this is what you are looking for.
  9. I'm also studying the possibilities of the ecommerce conversions. I use PS 1.5.3.1 with paypal, ogone, ideal and some others. Without doing any changes I noticed in google analytics that I have e-commerce overview, product performance, sales performance, transactions, days before transaction. I might not have all the english terms as I'm translating it. @charlie123, I'm not yet up to the level of knowledge you have, however if I check some seperate orders based on the order number in prestashop which I put in the search screen whithin ecommerce->transactions then I see properly the paypal orders (I checked only some). I see that I'm using paypal module version :3.4.5 which was the default. I also see that 3.4.6 is available on PrestaShop Addons. When a user is NOT refered back to the webshop, but moves to another website WITHIN paypal then the order in prestashop will nicely be set to paid (as paypal will send a server-to-server request to prestashop) BUT then no browser javascript will be executed and analytics will not get notified about the order. I wonder if google analytics would accept also server-to-server requests for e-commerce conversion as then it will ensure better quality of (ordering) data. Anyway, let me know if you think I can check more for you?
  10. in modules/pagesnotfound/pagesnotfound.php search the line if (strstr($_SERVER['PHP_SELF'], '404.php') && !strstr($_SERVER['REQUEST_URI'], '404.php')) and change into if (Context::getContext()->controller->php_self == '404' || (strstr($_SERVER['PHP_SELF'], '404.php') && !strstr($_SERVER['REQUEST_URI'], '404.php')))
  11. I changed some code and now I get cheapest product from only the products defined in the cart rule and not on the whole order. It was really crazy. I have a watch and you can select a watch strap for a discount. I select all watches and all watch straps as products in the condition tab. I select 50% discount for cheapest product and I expected that the watch strap was cheapest. BUT actually when someone ordered a cheaper tiny think e.g. 2 euro then he gets 1 euro discount as that was the cheapest product. So I changed cart core logic and I still don't understand why presta is having so many side effects on cart rules. I see many but no time to show them and discuss here.
  12. I have prestashop 1.5.3.1 with 6 multishops and about 2000 products having 5000 images with 5 types (large / small etc). I generate images in backoffice with the option 'Erase previous images' disabled to prevent resizing all. And since I enabled watermark module it takes ages and will not finish and will not do it's job which is resize only non existing images. Due to a bug in regeneration module whatever you do it will ALLWAYS regenerate ALL watermark images. So if you delete one image from img/p folder and generate it again with 'Erase previous images' disabled then it will nicely regenerate first without watermark and after that the watermark module is requested to redo ALL images. Within watermark module it already takes into account multi shop in case you upload different watermark images. However the regenerate button will ALSO call the watermark per shop which is not needed. I only selected 2 image types to process for watermark. So it requests in my sitatuation 6x5000x2=60000 image resizes with watermark. Even while only 1 should be enough. I developed a solution, just put this in override/controllers/admin/AdminImagesController.php as it solved the issue for me. <?php class AdminImagesController extends AdminImagesControllerCore {// override _regenerateWatermark to do nothing as it would regenerate ALL images for watermark protected function _regenerateWatermark($dir) { return; } // do the watermark per missing image just before the real generation as then the real generation (without watermark) is not needed anymore. protected function _regenerateNewImages($dir, $type, $productsImages = false){ if (!is_dir($dir)) return false; if ($productsImages) { foreach (Image::getAllImages() as $image) { $imageObj = new Image($image['id_image']); $existing_img = $dir.$imageObj->getExistingImgPath().'.jpg'; if (file_exists($existing_img) && filesize($existing_img)) { $needFile=false; foreach ($type as $imageType) if (!file_exists($dir.$imageObj->getExistingImgPath().'-'.stripslashes($imageType['name']).'.jpg')) { $needFile=true; continue; } if($needFile) { Hook::exec('actionWatermark', array('id_image' => $imageObj->id, 'id_product' => $imageObj->id_product)); } } } } $errors=parent::_regenerateNewImages($dir, $type, $productsImages); return $errors; } }
  13. @eleazar In function validateOrder() in PaymentModule class it generates the reference ONCE for all sub orders! You see $reference = Order::generateReference(); And later a foreach in which $reference is used. So it's not the same as id_order which will be different for the sub orders.
  14. You mention that id_order is primary key. Indeed this is true, however different functions do query the orders based on reference field! So one cart resulting in multiple (back)orders should have the same reference in order to work properly! You will see the issue when you have multi line orders . And most people will not have it I think, still it needs to be covered. See in clases/order/order.php getOrdersTotalPaid() , getBrother(), getByReference() This for me indicated that reference IS used!
  15. I agree that the solution from jdrda is not using core files and nicely uses the override. What I ment with "I refused to edit core files" is just for myself that I try never to touch core prestashop files. Especially when it's not a real bug, but more a different approach. However if I could edit the core files the I would not solve it in the function add() but then I would solve it in validateOrder() however this one is too big to handle in override and do edits because on next release it might contain improvements from prestashop core and then I would use the copy of an old version. I hope this explains. Then about the LOCK database i have to review more in detail. Am I right that it finds the max id_order and increases with 1 just because the new order record is not yet made and when it's made in the $order->add() (called from validateOrder) then it will define id_order and most probably with the same id as the one 'predicted'. However it seems not to be a hard assignment. So it's still free for the database to calculate another id. E.g. when you delete the latest order then the database will skip the ID while the max order_id will not. (I sometimes delete test orders). But indeed the LOCK will then prevent that another order will take the number. I would like to know when the table is unlocked? you mention its unlocked on the return but this would be too early as the new order is not yet added. Will it unlock when the connection is closed? And maybe I'm wrong, but a cart can generate multiple (back)orders and these should have the same reference!! That's why I proposed to use cart id. I'm pretty sure that this can be the case however I didn't experience in practise yet and are just (trying) to reverse engineer. Anyway, nice technical discussing! And I would like to know why core team decided to use the random letters as reference. Is there another (payment) risk we didn't think of here?
×
×
  • Create New...