Jump to content

Paul C

  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Paul C

  1. Not sure I understand your question as obviously the same technique to calculate the price in the cart should always get the same price if used elsewhere..... Exactly where/why are you trying to get the price?
  2. Just an update for anyone searching for this in the future. Apparently it's INTENDED to work this way (although it hasn't up until 1.5.4 due to those stub files) To be fair it is documented in the new docs for 1.5 overrides. Attached is a modified version of Autoload.php I'm now using in development that makes it behave as it always used to.... life is too short to have to remember to delete a cache file.... It will add a little overhead, so probably best to use the standard in production (but remember that if you patch the production system you'll need to remember to delete the cache file). Paul
  3. I noticed this today. You'll notice that all the "empty" override classes from the override directory are gone, which is good as they would overwrite the changes that weren't meant to be overwritten on upgrade.... I think the side-effect though is that changes aren't now being detected in order to recreate the class_index.php file. Just a hunch which I guess I'll have to go and try and work out from the source.... If you install your overrides via a module there shouldn't be a problem though. EDIT: Yup Autoload::load($classname) is now broken and will use the Core class and ignore any subsequent overrides as it has cached the Core class as the non-core declaration.using the following: // Since the classname does not exists (we only have a classCore class), we have to emulate the declaration of this class $class_infos = new ReflectionClass($classname.'Core'); eval(($class_infos->isAbstract() ? 'abstract ' : '').'class '.$classname.' extends '.$classname.'Core {}'); Previously it would have stored the path to the "empty" class declaration in the override directory.... now it stores the path to the core class....
  4. Looking better but there's a missing css file in your theme that's causing an issue (since the page looks ok it doesn't seem to be required.... http://www.saugaat.in/themes/saugaat/css/sprytabbedpanels.css If it's referenced in header.tpl then remove it from there, otherwise you need to find where it's being redirected - it has a permanent 301 redirect on it that's pointing to the 404 error page.... possibly in the site .htaccess file?
  5. The smarty setting should be "Never recompile template files" and the cache should be enabled. Under the CCC settings try also using "Keep HTML as original" for "Minify HTML". This is because in some cases the CPU is the limiting factor on the hosting not the bandwidth and compressing the pages can sometimes be slower than just sending them.... I would also test the site response with things like the Facebook plugins disabled and the default theme, just to measure their impact.
  6. It looks like there are two problems to me. Firstly the waiting time from the host seems WAY too long. This is either because there's just too much processing being done to generate the page or a server performance issue (Bluehost?). Secondly there are a few other problems with the site configuration but the above is making them even worse than they need to be. It seems the site is even waiting on a GET of "page-not-found" which is never a good thing for your homepage, there's a 301 redirect for a css resource that seems unnecessary and the Facebook integration is also adding a significant overhead to the page load times. A Page Speed score of 50/100 is poor.
  7. I suggest that you have a look at the code in the AdminImportController class. That should answer most questions on the subject
  8. If you manually remove the function "loadRoutes" from the Dispatcher class definition in /override/classes/Dispatcher.php that should get you back to where you would have been if the module had uninstalled properly (unless it overrides any other functions in there in which case you'll need to keep removing the function it complains about until it doesn't complain anymore!). If no other module has overrides in there - and you haven't added any manually, then you should also be able to just delete the file /override/classes/Dispatcher.php and the install should use the copy from the module's override/classes directory when you install it.
  9. Haha I like the "this is all a bit bum tightening for me" comment I'm actually going to move the site that this code is used on to so once that's done I can post back with how I solved it in 1.5.3 - the above was for 1.4 and I know for a fact that it won't work in 1.5+ In 1.5 it should be possible to write a module that can populate an array with all the prices per customer group so you can display/manipulate them as you wish in the product templates. The above is complicated because the group prices weren't just a discounted rate (they don't have to be) but specific pricing per product that is imported into the store. They also had different TAX rules (RRP included VAT and the member price was excluding VAT). I'll be working on this in the next few days. P.S. I was never particularly happy with the above solution but it worked (and still does)! Hoping to do it slightly more elegantly next time....
  10. Have you tried using a call like: $category = new Category(1); // Get something to test with $nbProducts = $category->getProducts($lang_id, 0, 0, null, null, true); The above function call should return the count of products in a category
  11. It all depends on when you need to change the data. Is it on adding to the shopping cart or is it when the customer places an order (for example - it could be at any point including after the order has been placed). The timing is very important....
  12. Sorry I didn't see this post before as I have actually had to do this for someone a while back (PS 1.4) To display on the various product pages I had to override the Product class and add something like the following in Product::getProductProperties(): $row['price_member'] = Tools::ps_round(Product::getGroupPriceStatic((int)$row['id_product'], (bool)!Group::getPriceDisplayMethod(2), ((isset($row['id_product_attribute']) AND !empty($row['id_product_attribute'])) ? (int)($row['id_product_attribute']) : NULL), 6), 2); $row['price_rrp'] = Tools::ps_round(Product::getGroupPriceStatic((int)$row['id_product'], (bool)!Group::getPriceDisplayMethod(1), ((isset($row['id_product_attribute']) AND !empty($row['id_product_attribute'])) ? (int)($row['id_product_attribute']) : NULL), 6, 1), 2); This makes use of another function I added to the Product class (also in the same override file): /** * Get product group price * * @param integer $id_product Product id * @param boolean $usetax With taxes or not (optional) * @param integer $id_product_attribute Product attribute id (optional). If set to false, do not apply the combination price impact. NULL does apply the default combination price impact. * @param integer $decimals Number of decimals (optional) * @param integer $id_group group ID (for customer group specific price) * @param boolean $only_reduc Returns only the reduction amount * @param boolean $usereduc Set if the returned amount will include reduction * @param integer $quantity Required for quantity discount application (default value: 1) * @param boolean $forceAssociatedTax Force to apply the associated tax. Only works when the parameter $usetax is true * @param integer $id_cart Cart ID. Required when the cookie is not accessible (e.g., inside a payment module, a cron task...) * @param integer $id_address Customer address ID. Required for price (tax included) calculation regarding the guest localization * @param variable_reference $specificPriceOutput. If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object * @param boolean $with_ecotax insert ecotax in price output. * @return float Product price */ public static function getGroupPriceStatic($id_product, $usetax = true, $id_product_attribute = NULL, $decimals = 6, $id_group = 2, $only_reduc = false, $usereduc = true, $quantity = 1, $forceAssociatedTax = false, $id_cart = NULL, $id_address = NULL, &$specificPriceOutput = NULL, $with_ecotax = TRUE) { global $cookie, $cart; $cur_cart = $cart; if (!Validate::isBool($usetax) OR !Validate::isUnsignedId($id_product)) die(Tools::displayError()); // Initializations if (!is_object($cur_cart) OR (Validate::isUnsignedInt($id_cart) AND $id_cart)) { /* * When a user (e.g., guest, customer, Google...) is on PrestaShop, he has already its cart as the global (see /init.php) * When a non-user calls directly this method (e.g., payment module...) is on PrestaShop, he does not have already it BUT knows the cart ID */ if (!$id_cart AND !Validate::isCookie($cookie)) die(Tools::displayError()); $cur_cart = $id_cart ? new Cart((int)($id_cart)) : new Cart((int)($cookie->id_cart)); } if ((int)($id_cart)) { if (!isset(self::$_cart_quantity[(int)($id_cart).'_'.(int)($id_product)]) OR self::$_cart_quantity[(int)($id_cart).'_'.(int)($id_product)] != (int)($quantity)) self::$_cart_quantity[(int)($id_cart).'_'.(int)($id_product)] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' SELECT SUM(`quantity`) FROM `'._DB_PREFIX_.'cart_product` WHERE `id_product` = '.(int)($id_product).' AND `id_cart` = '.(int)($id_cart) ); $cart_quantity = self::$_cart_quantity[(int)($id_cart).'_'.(int)($id_product)]; } $quantity = ($id_cart AND $cart_quantity) ? $cart_quantity : $quantity; $id_currency = (int)(Validate::isLoadedObject($cur_cart) ? $cur_cart->id_currency : ((isset($cookie->id_currency) AND (int)($cookie->id_currency)) ? $cookie->id_currency : Configuration::get('PS_CURRENCY_DEFAULT'))); if (!$id_address) $id_address = $cur_cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}; if (Tax::excludeTaxeOption()) $usetax = false; $id_country = (int)Country::getDefaultCountryId(); $id_state = 0; $id_county = 0; $id_state = 0; $address_infos = Address::getCountryAndState($id_address); if ($address_infos['id_country']) { $id_country = (int)($address_infos['id_country']); $id_state = (int)($address_infos['id_state']); $id_county = (int)County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']); } if ($usetax != false AND !empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT')) $usetax = false; $id_shop = (int)(Shop::getCurrentShop()); return Product::priceCalculation($id_shop, $id_product, $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $usetax, $decimals, $only_reduc, $usereduc, $with_ecotax, $specificPriceOutput, true); } The 5th parameter in the above function is the group for which you want the price. In my case I only needed the standard price and one other group price which was for members. It has a default of 2 only because that was my member price group. I notice that I also had an override for the ProductController which I assume was a catch-all for cases where the product data didn't go through Product::getProductProperties() class ProductController extends ProductControllerCore { public function process() { parent::process(); if (Validate::isLoadedObject($this->product)) self::$smarty->assign(array( 'price_member' => Product::getGroupPriceStatic($this->product->id, false), 'price_rrp' => Product::getGroupPriceStatic($this->product->id, true, NULL, $decimals = 2, $id_group = 1) )); } }
  13. I'll have a further think on it as it has now become an intellectual challenge! Have drawn blanks so far though on how it could be done....
  14. Yes. It appears that the cookie is so deeply linked to the new multi-shop code that there's no alternative but to have your static (if they are static?) webpages in the same directory as Prestashop (or below) if you want to have them access the Prestashop cookie!! I tried hacking about with it a bit but I could only ever generate a guest cookie and never managed to access my logged in customer one....
  15. That's weird. In general all that is required in terms of permissions is read/write access by the php interpreter (Prestashop will try and create a config.xml file in the module directory so needs to be able to write). I know that some servers complain if you use a sledgehammer and set the permissions to 777 and in general 755 is best for directories and 644 for files (if this is sufficient, otherwise you'll need to try 775 and 664 next...). Did you run the installer on the server or did you ftp the entire store and manually import the database? The installer checks the permissions on key directories for you. One other thing to look out for is that Unix (Linux) is case-sensitive whereas windows isn't, so if you have a filename that's camel-case it MIGHT work on wampp but not a Unix/Linux based server...
  16. In the same way the blocklayered module displays a subset of products (based on the filters applied) you could write a module that only displays products with certain product ids - the display side of it is trivial as all you have to do is pass the product list to the existing product-list.tpl template for display. Another "model" for this is the product compare subsystem which does something very similar (allows you to specify a set of products) but with an enhanced display format. A quick proof of concept might be to replace the contents of product-comparison.tpl with the contents of product-list.tpl and see how it looks when you compare 2 products.... you might get errors as there may be smarty variables required in product-list.tpl that aren't assigned by the product comparison code. I'm not sure how you would be able to get to the point of building the url in your scenario though? Is this something that you would hand-craft or is is built somehow automatically? Paul
  17. It seems to be the multishop code that's causing the issues. If the file is within the shop directory (or a subdirectory below that) it executes fine, but if it is outside the shop directory it redirects to the store default url..... The only way I could get it to work is to override the Shop class and then make a copy of the Shop::initialize() member function and add it to the override. I then prevented it executing the following: header('location: '.$url); exit; What I did was add a define before including config.inc.php and modified the above (in my version it's at about line 389 in the original core Shop.php file function) to be: if (!defined('_EXTERNAL_SCRIPT_')) { header('location: '.$url); exit; } The code in your script would then be: define('_EXTERNAL_SCRIPT_', 'true'); include('prestashop/config/config.inc.php'); $context = Context::getContext(); echo '<pre>',print_r($context->cookie, true).'</pre>'; So not more straightforward after all.......
  18. You should only provide entries in the array for "active" installed languages. If you look at the AdminImport Controller you can see that the import code sets all the languages to just the single entry that's in the import CSV: static function createMultiLangField($field) { $languages = Language::getLanguages(false); $res = array(); foreach ($languages AS $lang) $res[$lang['id_lang']] = $field; return $res; } To use the above you would do something like: $category = new Category(); $category->name = createMultiLangField('my_category_name'); Note that until run time you have no idea which languages are installed. You could work out in the above loop if 'id_lang' relates to e.g. Spanish and if so use the Spanish translation but otherwise use English (assuming English is the default). If someone then has English, Spanish and French installed then the array will have three entries: English,Spanish,English. French users would then have to translate the category name from English themselves.
  19. You only have two options: You either build an array with the same category name for each language installed OR you have a lookup array that contains the category name in EVERY language available to Prestashop and pass the correct translation in each entry of the multi-lang array..... I would go for the first option and let the store owner sort out the translations I guess a compromise would be to have a lookup for the languages you support in your module and if a particular language isn;t found then use the default.
  20. I'm not 100% sure what you're trying to do as I don't know where you're accessing the products from that you would need to use the above code (if you have the id of an order then you should be able to instantiate the object and access the products directly from there). It sounds like you want to add a field ( e.g. comment ) to the product objects contained in an order object though? I assume AFTER the order has been placed (otherwise it would be the products in the Cart object you would manipulate). To do this you could override the Product object and add support for your field, and then add the corresponding field in the database table. This way any changes to the "comment" member variable of the product would be persistent (if you just try setting the variable on the object it will work within the current scope of the object but be lost when the object is recreated at the next page view). Another way of doing this is to create your own independent object that maps your customisation to either the order or a combination of order and product id. This would store its data in a separate table. This is better since you're not making any changes to the basic functionality (or underlying database structure) but instead extending it. I'm wondering though if maybe you should be using the "customisation" feature.... unless I'm misunderstanding what you're trying to achieve.
  21. No problem, best of luck! I notice that my EDIT in the above is actually in the wrong place - it really refers to 3) not 2) so should probably be under there
  22. The problem is that this is really non-trivial. Not sure I would be able to write a detailed how-to blind without seeing what's going on behind the scenes. A few observations/suggestions though: 1) The smarty.post.customGB issue is a bit of a red herring. All that variable does is store a copy of the data POSTed by a form. Within the order controller (i.e. back in the PHP world) you would access the POSTed variable using something like: $customGB = Tools:getValue('customGB','optional-default-value'); 2) There are several different ways that you could approach storing this additional data. You could override the Cart object and add an extra field (and also add the appropriate field in the associated database table) but that's kind of messy and I think over-complicating things for the future. A better approach might be to create a new object (and database table) that associates the cart_id with a serialised version of the $customGB array. If the number of options are always limited to a specific maximum number, then you can skip serialising the array and just store the options in separate fields. You can then use this anywhere you have a cart id to check if associated 'Gift Box' information exists and use it appropriately (e.g. in the admin area as well as in emails). EDIT: Actually your override can pass the additional template variables via the $extraVars parameter, so your override validateOrder function could simply call the parent valdateOrder() function AFTER you've retrieved the gift box data passing the result via $extraVars. MUCH simpler and more future-proof. 3) The actual display of the selected options in the order email is going to have to be done within the 'PaymentModule' class it looks like, as this is where the template variables are assigned and the email sent. The most straight-forward approach would likely be to override this and copy out the 'validateOrder' function from the core file. You can then modify this function in your override to also look up any associated Gift Box data and pass it to the email template along with all the other data (invoice and delivery addresses, products list etc.). 4) Once you've retrieved and assigned your data via smarty you can then code the order email template to display the data. I assume that this is an existing store, otherwise I would be strongly recommending you use 1.5.x for new developments!! Hope this helps!
  23. It should be even easier now. Try the following: <?php include('path_to_prestashop/config/config.inc.php'); $context = Context::getContext(); echo '<pre>',print_r($context->cookie, true).'</pre>';
  24. There's a reason that: $ p-> name = "Product name"; Doesn't work, and that's because it should be an array of language strings and not just a string. If you look in the AdminImportController.php file you'll see that these are actually populated using a function: static function createMultiLangField($field) { $languages = Language::getLanguages(false); $res = array(); foreach ($languages as $lang) $res[$lang['id_lang']] = $field; return $res; } Use a similar function in your own code and the problem with the name will be fixed. You can see which fields require this by looking at the above admin import file for clues (in later PS1.5 versions the admin "tabs" are in controllers/admin)
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More