Jump to content

Paul C

  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Paul C

  1. Do you mean listed in the front office? If so, then yes it's possible I guess but would take a little work unless you just use the blocklayered module. That can be used to FILTER on a feature (although not sort I don't think). There's a hook in the CategoryController (ActionProductListOverride) that lets you build your own product listing - that's probably where I'd start on a custom solution. If it's the Back Office then all you would need to do is override AdminProductController to change which fields are presented in the listing (plus probably a callback and/or table join/additional sql to look up the feature value).
  2. Get rid of the ?> at the end of the file. It's unnecessary, really bad practice and the source of all types of problems
  3. Search is your friend : http://www.prestashop.com/forums/topic/241470-adding-a-custom-field-during-the-checkout-process/page__p__1214488#entry1214488
  4. All you should need to do is to go to Modules->Positions and remove the module from the "Top of Pages". By default the module inserts its content in there and by using the smarty plugin you're displaying it now twice.
  5. Assuming that you have an array of categories that the product belongs to I would set it via: $cats = array('1', '2', '3'); $product->id_category_default = $cats[0]; $product->updateCategories($cats); If you only have 1 category to set (12 in your example) then just do: $product->id_category_default = 12; $product->updateCategories(array('12'));
  6. I'm not sure I understand what you're trying to do either so can't say if overriding the Cart object is in fact what you should be doing. - Do you need to store the extra information in the database or is it generated/calculated from existing data? - Is the information used at any time other than during checkout? - How is the information set? Where/when would you modify the cart object to add the information? Paul
  7. I've written scripts to import features via a source xml file and wrote my own way of handling it. Not sure if this is what you mean? The main code to handle the "import" is within a custom admin controller (this includes removing features that are no longer present in the product entry as well as adding values that don't exist): public function processProductFeatures($features, &$product) { $_errors = array(); $feed_features = array(); // Check if there is anything to add if (!is_array($features)) return; // Add each feature to the product foreach ($features as $feature) { $id_feature = Feature::addFeatureImport($feature['name']); if ($id_feature) { $id_feature_value = FeatureValue::addPreDefFeatureValueImport($id_feature, $feature['value']); if (!$id_feature_value) $this->addProductWarning($feature['name'], isset($product->id) ? $product->id : null, 'Error adding new feature value. Value: '.$feature['value']); } else $this->addProductWarning($feature['name'], isset($product->id) ? $product->id : null, 'Error adding new feature.'); if ($id_feature && $id_feature_value) { //$product->addFeaturesToDB($id_feature, $id_feature_value); Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value); // maintain a list of the features for the product according to the feed $feed_features[] = array('id_feature' => $id_feature, 'id_product' => $product->id, 'id_feature_value' => $id_feature_value); } } // Now get a complete list of features for a product -- We need to make sure that none have been // removed as per the feed, and if they have, we need to remove them from the site too. $store_features = $product->getFeatures(); // Build an array of product features no longer in the feed $remove_features = array(); if (is_array($store_features) && is_array($feed_features)) { foreach ($store_features as $feature) { $in_feed = false; foreach ($feed_features as $feed_feature) if ($feature['id_feature'] == $feed_feature['id_feature']) $in_feed = true; if (!$in_feed) $remove_features[] = array('id_feature' => $feature['id_feature'], 'id_feature_value' => $feature['id_feature_value']); } if (!empty($remove_features)) foreach ($remove_features as $remove_feature) FeatureValue::removeFromProduct((int)$remove_feature['id_feature'], (int)$remove_feature['id_feature_value'], (int)$product->id); } else { if (is_array($feed_features) && !is_array($store_features)) $_errors[] = Tools::displayError('(Product :'.$product->id.') Mismatch in attributes. Some features were not added.'); else if (!is_array($feed_features) && is_array($store_features)) $_errors[] = Tools::displayError('(Product :'.$product->id.') Mismatch in attributes. Some features could not be removed.'); } $this->_errors = array_merge($this->_errors, $_errors); return (empty($_errors) ? true : false); } The above uses a couple of extra functions added to the FeatureValue class (for convenience) via an override: static public function addPreDefFeatureValueImport($id_feature, $name) { $rq = Db::getInstance()->ExecuteS(' SELECT fv.`id_feature_value` FROM '._DB_PREFIX_.'feature_value fv LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.`id_feature_value` = fv.`id_feature_value`) WHERE `value` = \''.pSQL($name).'\' AND fv.`id_feature` = '.(int)$id_feature.' GROUP BY fv.`id_feature_value` LIMIT 1'); if (!isset($rq[0]['id_feature_value']) OR !$id_feature_value = (int)$rq[0]['id_feature_value']) { // Feature doesn't exist, create it $featureValue = new FeatureValue(); $languages = Language::getLanguages(); foreach ($languages AS $language) $featureValue->value[$language['id_lang']] = strval($name); $featureValue->id_feature = (int)$id_feature; $featureValue->custom = 0; $featureValue->add(); return (int)$featureValue->id; } return (int)$id_feature_value; } static public function removeFromProduct($id_feature, $id_feature_value, $id_product) { Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'feature_product` WHERE `id_feature` = '.(int)$id_feature. ' AND `id_feature_value` = '.(int)$id_feature_value. ' AND `id_product` = '.(int)$id_product); } You'll see that I'm not passing multiple languages, since these don't exist in the feed I'm working with but you could easily pass the feature value "name" as a language array and modify the code accordingly. You would also need to override the addFeatureImport() function that already exists in the Feature class as it also only accepts a single language name (although the id returned will be the same regardless of language - it only matters when you're creating a new feature or feature value). In the SQL you would search for only one language "name" from the array you pass. I never delete a feature value completely as in my case I want a standard set available (note that when adding a feature value $featureValue->custom = 0). I only remove a feature from a product if it is no longer specified in the feed. Not sure if the above helps, but best of luck! (Apologies for any typos as I've modified the above code examples from my own project to remove any irrelevant code!) Paul
  8. The easiest way to do this would be to use a "Feature" Year : 1978 You can even have pre-defined values to save typing them over again subsequently.
  9. Unfortunately for you it isn't quite as simple as that since during the order process it isn't actually an Order object that's being manipulated but rather it is a Cart object. If you look at the function _processCarrier() in the ParentOrderController class you'll see that there's a hook function available which you could use to insert your own code into the process. In a module this would be implemented as: public function hookActionCarrierProcess(Array $params) { $cart = $params['cart']; if (!($cart instanceof Cart)) return; $cart->myField = Tools::getValue('myFieldName'); } You could override the Cart class and add your field to that. When it finally becomes an order (e.g. by the time you want to generate the invoice) the order object has a data member $id_cart which you can use to get the Cart object and thus your saved data. To display the data on the invoice you can use the hook function hookDisplayPDFInvoice(). public function hookDisplayPDFInvoice(Array $params) { $order_invoice = $params['object']; if (!($order_invoice instanceof OrderInvoice)) return; $order = new Order((int)$order_invoice->id_order); $cart = new Cart($order->id_cart); return 'My field data was :'.$cart->myField; }
  10. I don't know about the "right" way but you can use the context variable. e.g. something like: if ($this->context->controller instanceof ProductController) { // Do something that should only happen on the product page }
  11. My guess would be that the cache files need to be deleted as it may be using the cached version that still has the link in it!. Easiest way is to turn off the compile and cache options in "Performance preferences"
  12. Have you by any chance forgotten to put : <?php On the first line of the file and either don;t have blank space at the end of the file or preferably DON'T put: ?> at the end of the file.... The uninstall function doesn't really make any sense as you're trying to uninstall twice... better with just: public function uninstall() { return parent:uninstall(); } Can't see anything else obviously wrong....
  13. No, your hook function doesn't need to display anything. As long as you make an appropriate call to $this->registerHook() in the install function. What version of Prestashop are you using though? (Your code isn't correct for 1.5.4 plus you're accessing the variable $smarty when it hasn't been declared/initialised).
  14. There's a copy of the MySQL Workbench model in each Prestashop release now as /docs/dev/dbmodel.mwb That's about as much documentation as I know of... To be fair the structure isn't rocket science though, so that should give you a good idea of how the tables are related.
  15. Do yo really need to have the categories so specific? It would seem that you're placing the "brand" in there too which seems to be to be redundant. I'm pretty sure it would be much more efficient to have all compressors in one category and then use the layered navigation to filter e.g. first by "brand/manufacturer" (AGCO) and then maybe use a "feature" called "Series" with a value = Terragator 1000 to further filter down. Paul
  16. If another module overrides a DIFFERENT member function of the class then it will add that function to the override class. If another module tries to override the same function then the module won't install and there will be an error message
  17. If you implement the data class extended from ObjectModel, then you'll have all the CRUD functionality you need. Create an associated AdminController (ModuleAdminController when it's in your module) extended class to manage create/edit/delete in the Back Office. Simple The Language data class and AdminLanguagesController can be used as inspiration
  18. <prestashop-root>/classes/module/Module.php is where the class is declared....
  19. Try: array( 'type' => 'radio', 'label' => $this->l('Site'), 'name' => 'checkboxURL', 'class' => 't', 'values' => array( array( 'id' => 'prod', 'value' => 1, 'label' => $this->l('Production') ), array( 'id' => 'test', 'value' => 0, 'label' => $this->l('Test') ) ), 'is_bool' => true, 'required' => true )
  20. It really depends on what you want to do..... Which version of Prestashop are you using? In 1.5 There's a hook in the CategoryController called in assignProductList(): actionProductListOverride($params) The keys to the $params array are: nbProducts(integer), catProducts(product array) and hookExecuted(bool) Or you could look at the Product class and override the getProductProperties() method.
  21. You can just include the following at the start of your file: <?php include(dirname(__FILE__).'/../../config/config.inc.php'); include(dirname(__FILE__).'/../../init.php'); include(dirname(__FILE__).'/yourmodule.php'); $module = new YourModule(); echo $module->yourAjaxHandler(); That will load up all the Prestashop goodness in your script, and also then allow you to place the actual ajax call function within your module (from where you can access the facilities you need). You can also use Tools:getValue('post_or_get_variable') if you need to pass parameters. This is exactly how the blocklayered module works btw and that would be a good source of "inspiration"
  22. I wrote some stuff a while back about doing this kind of thing in Prestashop 1.4 which can be found on my site. In 1.5 support for this has actually been added. You can use the following smarty code: {hook h="hookname"} you appear to also be able to pass parameters in the smarty code where the additional paramaters are passed in the $params array as key=>value e.g. {hook h="myHook" order_id= X cart_id=Y} In the hook function these could be accessed via: $order_id = (int)$params['order_id']; $cart_id = (int)$params['cart_id']; The above is from looking at the code as I haven't had time to explore further. Good luck!
  23. Here's a little tip. In 1.5.x Go to the "Advanced Parameters->Performance" Menu option. In the first section under the "Cache" On/Off option there is a set of radio buttons for "Debug Console". Enable the one that says "Always Open Console" and Save. When you navigate to your product page you'll see every variable that's set. The price is in there. Unfortunately you won't know what the actual cart total will be unless you can also read the Quantity input by the user, To do that you're either going to have to do the calculation in Javascript or write a handler. It would be a good idea to outline what you're trying to achieve as that makes helping you a lot easier....
  24. I assume that there's no way you can send it along with the call, since the admin screen you're running javascript on will be able to correctly identify the store?
  25. It looks to me like you're expecting the function move_uploaded_file() to return 'false' on success?? If not then there's a problem with your logic
  • Create New...

Important Information

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