Jump to content

Paul C

Members
  • Posts

    801
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by Paul C

  1. On 1/22/2021 at 5:09 PM, serwol said:

    Hello, with this function is it possible to change front product display in a category ?

    I've developped a module widget that display a form with selects to find some products and I managed to get the ids of the product but I don't know how to alter the product list.

    Have a look at the stock ps_viewedproduct module. The function getViewedProducts() should contain the code you need to get the display data correctly, and the template in that module illustrates how to display them.

  2. As an update (if anyone is interested!) I seem to have narrowed it down to trying to instantiate an object serialized as "O:39:"Symfony\Component\VarDumper\Cloner\Data":6:{s:45:...etc". I can force the profiler to display by just simply muting the unserialize error i.e. modifying /vendor/symfony/symfony/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php and using @unserialize in the method unserialize($data).

     public function unserialize($data)
     {
         $this->data = \is_array($data) ? $data : @unserialize($data);
     }

    Obviously this is just throwing away the data so not ideal, although I can't actually see what's now missing from the profiler.....

  3. Making changes to the root category (confusingly not the one that is flagged "is_root_category" as that's actually the "home" category) sounds scary but the actual category changes were fine and the structure hasn't changed since 1.6. I'm now questioning whether the categories caused this at all.

    I'm beginning to think that the issue might actually be down to the collations in the database (I think that they should be  utf8mb4_general_ci but not all of them are). Basically I'm thinking there's a size mismatch in the serialized data but I am indeed exploring the data itself it to see if there are any clues....

    Thank you for the heads up on the Prestools - I'd never heard of it before but it looks like it could be useful!

     

    UPDATE: Prestools integrity check didn't find any issues (and under the category menu displayed the category tree correctly and completely) so am guessing the category fixes were a red herring and the profiler issue is something completely separate. All 124 categories are present and correct. Have changed the collation off the tables to utf8mb4_general_ci too, just in case but no luck yet.

  4. On another note (and as a bump) I'm also getting loads of "Translation not found" errors too, even though they are all defined in xlf files in 'app/Resources/translations/en-GB' and the locale is set to 'en-GB'. Seems this is an old version of symfony as I found out when I looked at the docs.....

     

    As an update the categories show fine as options for the main menu now. No idea why they weren't - other than maybe some caching issue? The only outstanding problem is this "unserialize" one but I have have no idea where the data is coming from. Guess I'll just need to keep digging.

  5. After a fairly long break from Prestashop I find myself once again falling down the rabbit hole. I have a site that was on 1.6.1.0 that I have migrated over to 1.7.7.0 and then upgraded to 1.7.7.1.

    Initially I upgraded the site to 1.6.1.24 (to allow me to use at least php 7.1) and then performed an in-place upgrade to 1.7.6.9. Upgrade was fine except the categories were broken. I then did a fresh 1.7.7.0 install and migrated the products over (from 1.6.1.0) using a migration plugin but the result was the same - so obviously a problem with the category structure on the source store. No custom modules are installed.

    After much analysis I managed to fix the issue by removing an extra "root" category in the database which seemed to have been inserted at some point (Home category had this extra category as its parent, and then that category had the real category "root" as its parent). I also refactored the level_depth (one less) via SQL. Verifying the PS_ROOT_CATEGORY and PS_HOME_CATEGORY configuration was correct and making sure the home category was set correctly for the store (there is only one store as multishop is disabled) resulted in the correct home category being displayed on the admin page and everything seems to work fine (SQL is as expected, categories display correctly and I can add and delete categories without error in the backoffice). The only weird thing I noticed was that the categories weren't available in the main menu plugin so I uninstalled it, along with any other module referencing categories... hmm.

    HOWEVER, I now get an error when running debug mode "An error occurred while loading the web debug toolbar."

    Opening the symfony profiler shows the image attached...

    Am really hoping someone has seen this and it's a really trivial thing to fix because it's annoying the heck out of me. I'm assuming it's not working for a reason. I have tried removing the cache files (/var/cache/dev/*), cookies, php session files etc. Accessing the backoffice from a browser on another machine makes no difference. Am now stuck on options to try. I could delete all the categories and put them back in again using the back office but that would be a pain as I need to keep the ids the same as well as the products needing to be placed in the correct categories. 

    Running this on Ubuntu 20.04 (WSL 1) with apache 2, PHP 7.3.25-1+ubuntu20.04.1+deb.sury.org+1, MYSQL 8.0.22-0ubuntu0.20.04.3. All the settings and php modules are those recommended and required. No errors in the php error log....

    symfony-category-error.png

  6. Performance not great here in the UK although I've seen worse from an install on cheap shared hosting :D

     

    Have you tried memcache? That might be interesting although even the RPi2 is a bit low on memory - still might be worth a try.

  7. I suspect that you have no default attribute set. One of them has to be otherwise the price shows as 0. Many importers fail on this but you can test it out by going to one of the products via the back office and setting a default - if that fixes it then you'll have to either do them manually or via SQL I'm afraid.

  8. The most efficient way would be to have "Vintage", "Modern" and "Chillout" as a feature value e.g. one called "Trend". That way you can use the standard "blocklayered" widget to allow people to home in on what they're looking for e.g. "Vintage" at a price between 300-500. You would lose the category listing for "Vintage" though - although a search on "Vintage" should result in that list (and you can hard-code a link to the search if you feel that might be a common thing for people to do and name it "All Vintage"). Even if you have a category "Vintage" you would probably need to filter out all the chairs if someone was looking for a sofa though anyway.

     

    One of the biggest challenges in an ecommerce store is getting the categories right - there's always a temptation to have too many categories which instead of making it easier for people to find things can actually make it harder/more confusing (think of returning customers trying to find something they saw in a previous visit). You need to try and get into the head of your "majority" customer and decide how they would best be served and then stick to just that. I always maintain that if you have lots of products in multiple categories, then you've got it wrong.

     

    EDIT: Added some clarification/fixed typos!

  9. I'm not sure if you're talking about a module you have written yourself or a built-in one. You can execute module functions within php (it's actually how the custom Prestashop hook smarty function operates to arbitrarily add hook output in a template) but it would seem to me that you would want to create a module front controller for this - but just make sure that it's "content-only" so you don't fetch an entire page.

     

    A little more detail on what specifically you're trying to achieve would help.

  10. If It was me I'd add 2 customisation fields to the product (meters and pieces) and then do any necessary validation on them on the product page itself.

     

    That way they get added to the cart as Prestashop expects and the rest is standard. You would need to make sure that the fields were mandatory to prevent getting an order with those fields blank (if the customer doesn't notice they need to specify them).

     

    Even though they are text fields you can hard-code the customisation fields in your theme as dropdown boxes based on a particular criteria so they only show up for products in a certain category (or better - that have those specific customisation fields present, just in case you forget to add them to the product).

     

    I've used this method successfully in a jewellery site where we wanted the customer to choose the size. Unfortunately if you use combinations then Prestashop expects you to have stock of one of each size, whereas in fact the exact same single ring gets resized - so this was the only way of getting the UI to work as expected but maintain the proper stock handling.

     

    Some people have also added modifications to the cart controller so you don;t have to "save" the customisation before adding to the cart which makes it an even more seamless process.

  11. The problem with doing it this way is that although the store has an address - it isn't an Address object that we can easily refer to (The Store object should really be consistent and use a "proper" Address object in my opinion but that's an issue for the core developers and changing it could break legacy code).

     

    The line :

    $this->context->cart->id_address_delivery = $deliveryAddress->id;

    Should set the delivery address but for some reason it isn't - it must be being overwritten somewhere later in the process. Changing it on the fly won't work as the Order refers to the Address object (via its id) so it has to be able to find it. It probably doesn't need to be associated with the specific customer but it does have to be "owned" by a customer I think (you could try setting the customer_id field to 0 later though to stop it showing in their address book - once it works as expected).

     

    I don't have easy access to the source right now to track down where the address is being changed but will have a look into it once I get the chance.

     

    I still think it would be easier if this were done in a custom carrier though. I suspect it would solve a lot of the issues! There are already modules available to do this but I understand if you don't want to pay for one ;)

  12. You could probably modify config/defines.inc.php and test e.g.

    if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1')
        $developer = true;
    else
        $developer = false;
    
    /* Debug only */
    if (!defined('_PS_MODE_DEV_'))
        define('_PS_MODE_DEV_', $developer);

    Obviously 127.0.0.1 should be replaced with your external IP address which you'll get from the likes of www.whatsmyip.org if you don't know what it is.

    • Like 1
    • Thanks 1
  13.  

    Thanks Paul,
     
    but I have 5600 product and I have to add combination for every one.
     
    And script is easier way

     

     

    There's absolutely no reason not to write your script using the Prestashop objects rather than raw sql. I regularly import 1,000s of products, including images and attributes that way. Never had to worry about changes to the Prestashop database structure as a result ;)

     

    By modifying the database directly with sql you're only saving a little time writing the script, but every upgrade you apply to that store in the future will require you to check if that part of the database is affected and modify your script if it has. Rinse and repeat.

  14. Ah I think I we need to change the address in the Cart object! Doh.

    public function _setPickupAddress($pickup_store)
    {
            $store = new Store((int)$pickup_store); // Get the store object
            $deliveryAddress = new Address(); // Create a new address object
            $deliveryAddress->id_customer = $this->context->customer->id;
            $deliveryAddress->id_country = $store->id_country;
            $deliveryAddress->id_state = $store->id_state;
            $deliveryAddress->firstname = 'Livré à : '; // You may need to play with these
            $deliveryAddress->lastname = $store->name; // for it to make sense
            $deliveryAddress->alias = 'Livré à : '.$store->name; // Used in the customer's address list to identify this address
            $deliveryAddress->address1 = $store->address1;
            $deliveryAddress->address2 = $store->address2;
            $deliveryAddress->postcode = $store->postcode;
            $deliveryAddress->city = $store->city;
            $deliveryAddress->phone = $store->phone;
     
            $deliveryAddress->save();
     
            if (Validate::isLoadedObject($deliveryAddress))
            {
              $this->context->cart->id_address_delivery = $deliveryAddress->id_address;
              $this->context->smarty->assign('delivery', $deliveryAddress);
            }
    }
  15. Well that's what I'm saying. It sounds to me like the point at which you're capturing the data is before the order exists - so no database record to store the value in. If you store the value in the Cart object (and therefor table) instead however you can save it right at the point you capture it from the user (on submission of the form). If you really need to store it in the Order, then you're going to need to hold it somewhere else until the order is created (so I would suggest that again, the place to store it is in the Cart object).

     

    Payment modules kick off the order creation in their ValidateOrder() member function but that can be called within a return/callback controller from the payment provider, so not so easily accessible. There are hooks in the order creation process that you can use from your module though to take action on a new order but I don't think you can guarantee that you'll have any access to the user session or cookie. There's a very good reason that all the other data captured during the checkout process (e.g. the delivery and invoice addresses) are stored initially in the Cart object ;)

     

    EDIT: I just noticed that you only mention displaying it on the order confirmation page. If that's really the only place you need to see it then there's probably no need to store it in anything other than the user cookie, although I suspect you need that information after the order has completed too?

  16. The problem you face is that the order object isn't created until after the payment is made. You may have to store the data in the cart object instead. You do have access to that cart object from the order when it finally IS created though.

     

    You can access the current cart object from the context during the form submission handling though very easily (on the plus side).

     

    EDIT: To add the field "properly" you should also override the Cart class and add your variable e.g.

    class Cart extends CartCore
    {
      public $my_var;
    
      $definition['fields']['my_var'] = array('type' => self::TYPE_STRING);
    
    }

    I haven't got the source to hand to check the syntax but I'm pretty sure that above is the form that the definition takes. Obviously you need to adjust to suit your variable type and add any necessary constraints, as required. Also remember to clear the object cache otherwise your override won't take effect (i.e. delete ./cache/class_index.php).

  17. You probably can't have a : in the name. Unfortunately these fields are validated as "names" not just any text... It would make sense to have something relating to your store I guess in place of the first and last names?

    $deliveryAddress->firstname = 'Lettersonly'; // You may need to play with these
    $deliveryAddress->lastname = 'sameforthis'; // for it to make sense
  18. Yup. I should have checked the required fields for the address object!

     

    EDIT: The alias can only be max 32 characters, so if your store names are long you may have to change it to something else e.g. "Pickup"

    public function _setPickupAddress($pickup_store)
    {
            $store = new Store((int)$pickup_store); // Get the store object
            $deliveryAddress = new Address(); // Create a new address object
            $deliveryAddress->id_customer = $this->context->customer->id;
            $deliveryAddress->id_country = $store->id_country;
            $deliveryAddress->id_state = $store->id_state;
            $deliveryAddress->firstname = 'Livré à : '; // You may need to play with these
            $deliveryAddress->lastname = $store->name; // for it to make sense
            $deliveryAddress->alias = 'Livré à : '.$store->name; // Used in the customer's address list to identify this address
            $deliveryAddress->address1 = $store->address1;
            $deliveryAddress->address2 = $store->address2;
            $deliveryAddress->postcode = $store->postcode;
            $deliveryAddress->city = $store->city;
            $deliveryAddress->phone = $store->phone;
     
            $deliveryAddress->save();
     
            if (Validate::isLoadedObject($deliveryAddress))
             $this->context->smarty->assign('delivery', $deliveryAddress);
    }
×
×
  • Create New...

Important Information

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