<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NemoPS &#187; php</title>
	<atom:link href="http://nemops.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://nemops.com</link>
	<description>Prestashop Tutorials, Modules and More!</description>
	<lastBuildDate>Wed, 05 Dec 2018 13:25:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.35</generator>
	<item>
		<title>Creating a “Clear cart” button in PrestaShop 1.7</title>
		<link>http://nemops.com/prestashop-1-7-clear-cart-button/</link>
		<comments>http://nemops.com/prestashop-1-7-clear-cart-button/#comments</comments>
		<pubDate>Mon, 06 Nov 2017 13:09:06 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[cart]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop 1.7]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3093</guid>
		<description><![CDATA[<p>Let&#8217; see how to create a button to empty the PrestaShop 1.7 shopping cart in one click! Version used: Prestashop 1.7.2.4 In this tutorial we will see how to apply my previous guide on Creating a “Clear cart” button in PrestaShop to PrestaShop 1.7, as it doesn&#8217;t work out of the box because of the [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-7-clear-cart-button/">Creating a “Clear cart” button in PrestaShop 1.7</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Let&#8217; see how to create a button to empty the PrestaShop 1.7 shopping cart in one click!<br />
<span id="more-3093"></span></p>
<ul>
<li>Version used: <strong>Prestashop 1.7.2.4</strong></li>
</ul>
<p>In this tutorial we will see how to apply my previous guide on <a href="http://nemops.com/clear-cart-button-prestashop">Creating a “Clear cart” button in PrestaShop</a> to PrestaShop 1.7, as it doesn&#8217;t work out of the box because of the new template.</p>
<p>The basic code still works, and the process is more or less the same, though the files needing modifications are totally different. For this tutorial, I will be using the classic (or standard) template, so wherever you read &#8220;themename&#8221;, just put <strong>classic</strong>. As a side not, please notice some files might be different if you use a custom PrestaShop theme.</p>
<h2>Adding the button to the cart page in PrestaShop 1.7</h2>
<p>The PrestaShop 1.7 template structure is quite different from 1.6, so we need to account for that. The main view for the cart is now located at <em>themes/*themename*/templates/checkout/</em>, and it&#8217;s called <strong>cart.tpl</strong>. Open it up, and locat the following block:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
      {block name='cart_overview'}
        {include file='checkout/_partials/cart-detailed.tpl' cart=$cart}
      {/block}
</pre>
<p>This represents the products list block, and we want to add the button right after it:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
    &lt;a class=&quot;btn btn-primary&quot; style=&quot;float:right&quot; id=&quot;removeAll&quot; href=&quot;javascript:void(0)&quot;&gt;
      Empty Cart
    &lt;/a&gt;
</pre>
<p>At this point, unlike 1.6 where we could add our code directly to the template, with PrestaShop 1.7 we have to use a new file, named <strong>custom.js</strong>.</p>
<div class="separator"></div>
<h2>Adding new javascript to a PrestaShop 1.7 template</h2>
<p>Open up <strong>custom.js</strong>, located in <em>themes/*themename*/assets/js</em>.<br />
It&#8217;s empty by default, so if not (as in the case of custom templates), just add the code at the end.</p>
<p>This file is loaded on all pages, and since we only want to run it on the cart one, we have to wrap our snippet with a condition:</p>
<pre class="brush: jscript; title: ; notranslate">
if(prestashop.page.page_name == 'cart')
{}
</pre>
<p>The <strong>prestashop</strong> javascript variable is a new global available in all pages of the shop, which contains a number of useful data that can be used in scripts. In this case, we use the current page name.</p>
<p>Here is all the rest of the code we need:</p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {

	    $('#removeAll').click(function(e) {
	        e.preventDefault()
	        $.ajax({
	            type: 'POST',
	            headers: { &quot;cache-control&quot;: &quot;no-cache&quot; },
	            url: prestashop.urls.base_url + &quot;cart&quot;,
	            async: true,
	            cache: false,
	            data: 'deleteAll=1&amp;token=' + prestashop.token + '&amp;ajax=true',
	            success: function(data){	
	                window.location.reload();
	            }
	        })
	    });
	});	
</pre>
<p><strong>Explanation:</strong> we are using the prestashop variable again, this time to fetch the base url. The cart controller, which we will be editing shortly, can be accessed at /cart by default, so we pass this url to the ajax call.<br />
For the querystring, we pass in <strong>deleteAll</strong>, to make sure we can refer to this action in the next step, a <strong>token</strong> required by PrestaShop 1.7, and <strong>ajax=true</strong>, so that the cart know the action has to be run in ajax mode.<br />
If the call is successful, we refresh the page to show that the cart is now empty.</p>
<div class="separator"></div>
<h2>Editing the CartController</h2>
<p>PrestaShop 1.7 discourages the use of overrides, but we will use one in any case <img src="http://nemops.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /><br />
Create a new file in <em>override/controllers/front</em>, and name it <strong>cartController.php</strong>. Reach back the original cart controller in the main <em>controllers/front</em>, and copy the whole <strong>updateCart</strong> method, pasting it into our new file:</p>
<pre class="brush: php; title: ; notranslate">
    protected function updateCart()
    {
        // Update the cart ONLY if $this-&gt;cookies are available, in order to avoid ghost carts created by bots
        if ($this-&gt;context-&gt;cookie-&gt;exists() &amp;&amp; !$this-&gt;errors &amp;&amp; !($this-&gt;context-&gt;customer-&gt;isLogged() &amp;&amp; !$this-&gt;isTokenValid())) {
            if (Tools::getIsset('add') || Tools::getIsset('update')) {
                $this-&gt;processChangeProductInCart();
            } elseif (Tools::getIsset('delete')) {
                $this-&gt;processDeleteProductInCart();
            } elseif (CartRule::isFeatureActive()) {
                if (Tools::getIsset('addDiscount')) {
                    if (!($code = trim(Tools::getValue('discount_name')))) {
                        $this-&gt;errors[] = $this-&gt;trans('You must enter a voucher code.', array(), 'Shop.Notifications.Error');
                    } elseif (!Validate::isCleanHtml($code)) {
                        $this-&gt;errors[] = $this-&gt;trans('The voucher code is invalid.', array(), 'Shop.Notifications.Error');
                    } else {
                        if (($cartRule = new CartRule(CartRule::getIdByCode($code))) &amp;&amp; Validate::isLoadedObject($cartRule)) {
                            if ($error = $cartRule-&gt;checkValidity($this-&gt;context, false, true)) {
                                $this-&gt;errors[] = $error;
                            } else {
                                $this-&gt;context-&gt;cart-&gt;addCartRule($cartRule-&gt;id);
                            }
                        } else {
                            $this-&gt;errors[] = $this-&gt;trans('This voucher does not exist.', array(), 'Shop.Notifications.Error');
                        }
                    }
                } elseif (($id_cart_rule = (int)Tools::getValue('deleteDiscount')) &amp;&amp; Validate::isUnsignedId($id_cart_rule)) {
                    $this-&gt;context-&gt;cart-&gt;removeCartRule($id_cart_rule);
                    CartRule::autoAddToCart($this-&gt;context);
                }
            }
        } elseif (!$this-&gt;isTokenValid() &amp;&amp; Tools::getValue('action') !== 'show' &amp;&amp; !Tools::getValue('ajax')) {
            Tools::redirect('index.php');
        }
    }
</pre>
<p>All we have to do now is add our condition, as part of all those ELSEIFs:</p>
<pre class="brush: php; title: ; notranslate">
            elseif (Tools::getIsset('deleteAll')) {
                $this-&gt;context-&gt;cart-&gt;delete();
                $this-&gt;context-&gt;cookie-&gt;id_cart = 0;
                die(1);
            }
</pre>
<p>Here is the final code:</p>
<pre class="brush: php; title: ; notranslate">
    protected function updateCart()
    {
        // Update the cart ONLY if $this-&gt;cookies are available, in order to avoid ghost carts created by bots
        if ($this-&gt;context-&gt;cookie-&gt;exists() &amp;&amp; !$this-&gt;errors &amp;&amp; !($this-&gt;context-&gt;customer-&gt;isLogged() &amp;&amp; !$this-&gt;isTokenValid())) {
            if (Tools::getIsset('add') || Tools::getIsset('update')) {
                $this-&gt;processChangeProductInCart();
            } elseif (Tools::getIsset('delete')) {
                $this-&gt;processDeleteProductInCart();

            } elseif (Tools::getIsset('deleteAll')) { /* Nemo */
                $this-&gt;context-&gt;cart-&gt;delete();
                $this-&gt;context-&gt;cookie-&gt;id_cart = 0;
                die(1);
            } elseif (CartRule::isFeatureActive()) {
                if (Tools::getIsset('addDiscount')) {
                    if (!($code = trim(Tools::getValue('discount_name')))) {
                        $this-&gt;errors[] = $this-&gt;trans('You must enter a voucher code.', array(), 'Shop.Notifications.Error');
                    } elseif (!Validate::isCleanHtml($code)) {
                        $this-&gt;errors[] = $this-&gt;trans('The voucher code is invalid.', array(), 'Shop.Notifications.Error');
                    } else {
                        if (($cartRule = new CartRule(CartRule::getIdByCode($code))) &amp;&amp; Validate::isLoadedObject($cartRule)) {
                            if ($error = $cartRule-&gt;checkValidity($this-&gt;context, false, true)) {
                                $this-&gt;errors[] = $error;
                            } else {
                                $this-&gt;context-&gt;cart-&gt;addCartRule($cartRule-&gt;id);
                            }
                        } else {
                            $this-&gt;errors[] = $this-&gt;trans('This voucher does not exist.', array(), 'Shop.Notifications.Error');
                        }
                    }
                } elseif (($id_cart_rule = (int)Tools::getValue('deleteDiscount')) &amp;&amp; Validate::isUnsignedId($id_cart_rule)) {
                    $this-&gt;context-&gt;cart-&gt;removeCartRule($id_cart_rule);
                    CartRule::autoAddToCart($this-&gt;context);
                }
            }
        } elseif (!$this-&gt;isTokenValid() &amp;&amp; Tools::getValue('action') !== 'show' &amp;&amp; !Tools::getValue('ajax')) {
            Tools::redirect('index.php');
        }
    }
</pre>
<p>We are done! Reach the back office, Advanced Parameters, Performance, and hit the clear cache button on the top right, so that the override takes place.</p>
<p>Should it not work, check that <strong>Disable all overrides</strong> is set to no, right below on the same page. If it still doesn&#8217;t, try editing the core CartController.php.</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-7-clear-cart-button/">Creating a “Clear cart” button in PrestaShop 1.7</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-1-7-clear-cart-button/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Make product fields multi-language in PrestaShop and ThirtyBees</title>
		<link>http://nemops.com/prestashop-thirtybees-multi-language-product-fields/</link>
		<comments>http://nemops.com/prestashop-thirtybees-multi-language-product-fields/#comments</comments>
		<pubDate>Mon, 18 Sep 2017 02:56:55 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3067</guid>
		<description><![CDATA[<p>In this tutorial we will learn how to make product fields translatable in PrestaShop 1.6, and see how to apply the method to the &#8220;price per&#8230;&#8221; field. Introduction You might have come across the need to translate the price per unit field in your PrestaShop or Thirtybees, but crashed against the software&#8217;s limitation, as that&#8217;s [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-thirtybees-multi-language-product-fields/">Make product fields multi-language in PrestaShop and ThirtyBees</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this tutorial we will learn how to make product fields translatable in PrestaShop 1.6, and see how to apply the method to the &#8220;price per&#8230;&#8221; field.<br />
<span id="more-3067"></span></p>
<h2>Introduction</h2>
<p>You might have come across the need to translate the price per unit field in your PrestaShop or Thirtybees, but crashed against the software&#8217;s limitation, as that&#8217;s a single language property. Any product field can be made multi-language with a simple modification, so let&#8217;s see how to do it using the Unity one as example in this tutorial!</p>
<div class="separator"></div>
<h2>Step 1 &#8211; Adding the new database column</h2>
<p>In order to make the field translatable, we have to add it to the <strong>product_lang </strong>table in the database. Not only, but  we also have to erase the same column in both the product and product_shop tables, to avoid conflicts when retrieving values from the database. Let&#8217;s add it first!</p>
<p>Using phpMyAdmin or Adminer, locate the <strong>*prefix*product_lang</strong> table in your database, and add a new column as <strong>VARCHAR</strong>, 24 characters long. Once done, it will look like this:</p>
<p><img src="http://nemops.com/wp-content/uploads/2017/09/multilang_field_db.png" alt="multilang_field_db" width="606" height="97" class="aligncenter size-full wp-image-3069" /></p>
<p>Next, let&#8217;s get rid of the leftovers: open the *prefix*product table and drop the <strong>unity</strong> column first, and then on the <strong>product_shop</strong> table.<br />
We are done! We just broke the Product class though, and have to compensate by letting it know where to grab the new values from.</p>
<div class="separator"></div>
<h2>Step 2 &#8211; Editing the product class</h2>
<p>We have a new column in the database, but at this point the Product class would still just ignore it. To have it lookup, and save into the correct table, we must tell it that the property we are wanting to translate is a multilanguage field. To do so, we must change its definition.</p>
<p>Open up <strong>Product.php</strong>, located in the <em>classes/</em> folder.</p>
<p>Scroll down until you find the following line, part of the <strong>$definition</strong> property:</p>
<pre class="brush: php; title: ; notranslate">
'unity'                     =&gt; ['type' =&gt; self::TYPE_STRING, 'shop' =&gt; true, 'validate' =&gt; 'isString'],
</pre>
<p>To make any field translatable, we can simply add &#8216;lang&#8217; => true as follows</p>
<pre class="brush: php; title: ; notranslate">
'unity'                     =&gt; ['type' =&gt; self::TYPE_STRING, 'shop' =&gt; true, 'validate' =&gt; 'isString', 'lang' =&gt; true],
</pre>
<p><strong>Please notice that, as always, using an override is strongly recommended, instead of editing core files.</strong></p>
<div class="separator"></div>
<h2>Step 3 &#8211; Editing the back office</h2>
<h3>The controller</h3>
<p>This is the most complicated part, as we will have to edit both the admin controller for products, and the correct template. For our example, the template is <strong>prices.tpl</strong>, but it will be different if the field you want to translate is in another tab.</p>
<p>Let&#8217;s start with the controller. The prices template does not offer us any option for translating fields, and therefore misses the indispensable $languages variable.<br />
Open up <strong>AdminProductsController</strong>, located in <em>controllers/admin</em></p>
<p>We are interested in the method called <strong>initFormPrices</strong>, so once you find it you can simply clone that to an override, or continue editing the core.</p>
<p>Right after $data is assigned, at the very beginning of the function, but <strong>before $product = $obj</strong>, add the following</p>
<pre class="brush: php; title: ; notranslate">
if (!$this-&gt;default_form_language) {
    $this-&gt;getLanguages();
}
$data-&gt;assign(array(
    'languages'=&gt; $this-&gt;_languages,
    'id_lang' =&gt; $this-&gt;context-&gt;language-&gt;id,
    'default_form_language' =&gt; $this-&gt;default_form_language,
));
</pre>
<p><strong>Explanation</strong>: Nothing too complex here, we are first checking if languages are loaded, and if not, assigning them to the controller. Then, we simply assign that class property to the template, along with a few other required ones. Please notice we do not use a common smarty assign, but the $data variable instead.</p>
<h3>The template</h3>
<p>Time to make our changes visible in the back office! For the unity field, let&#8217;s open up <em>*admin folder*/themes/default/template/controllers/products/prices.tpl</em></p>
<p>Locate the input with id unity, which will look more or less like the following:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;input id=&quot;unity&quot; name=&quot;unity&quot; type=&quot;text&quot; value=&quot;{$product-&gt;unity|htmlentitiesUTF8}&quot;  maxlength=&quot;255&quot; onkeyup=&quot;if (isArrowKey(event)) return ;unitySecond();&quot; onchange=&quot;unitySecond();&quot;/&gt;
</pre>
<p>Instead of this input, we will use a handy template PrestaShop makes available to us. Replace the above with the following code:</p>
<pre class="brush: php; title: ; notranslate">
{include file=&quot;controllers/products/input_text_lang.tpl&quot;
languages=$languages
input_class=&quot;{$class_input_ajax}{if !$product-&gt;id || Configuration::get('PS_FORCE_FRIENDLY_PRODUCT')}copy2friendlyUrl{/if} updateCurrentText&quot;
input_value=$product-&gt;unity
input_name=&quot;unity&quot;}
</pre>
<p>Save and refresh, and you will see the new field, translatable, appearing in the prices table of the back office. Time to test it, and see if it&#8217;s saving properly.<br />
We can take an extra step and translate the preview below as well:</p>
<pre class="brush: php; title: ; notranslate">
&lt;span id=&quot;unity_second&quot;&gt;{$product-&gt;unity}&lt;/span&gt;
</pre>
<p>to</p>
<pre class="brush: php; title: ; notranslate">
&lt;span id=&quot;unity_second&quot;&gt;{$product-&gt;unity.{$id_lang}}&lt;/span&gt;
</pre>
<p>At this point we can go ahead and test the Front Office. If everything has been done correctly, as soon as you change language, the class should automatically pick the correct translation for the field. Neat!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-thirtybees-multi-language-product-fields/">Make product fields multi-language in PrestaShop and ThirtyBees</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-thirtybees-multi-language-product-fields/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Create products from PHP in PrestaShop</title>
		<link>http://nemops.com/prestashop-create-products-from-php/</link>
		<comments>http://nemops.com/prestashop-create-products-from-php/#comments</comments>
		<pubDate>Tue, 09 May 2017 11:32:51 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[thirtybees]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=3017</guid>
		<description><![CDATA[<p>In this video we will see how to create a simple script to generate products with PHP in PrestaShop Watch the screencast Final Code</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-create-products-from-php/">Create products from PHP in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this video we will see how to create a simple script to generate products with PHP in PrestaShop<span id="more-3017"></span></p>
<h2>Watch the screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/0Kgn6HMcUsU" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<h3>Final Code</h3>
<pre class="brush: php; title: ; notranslate">
&lt;?php

include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');


// we have a csv file open
$default_lang = Configuration::get('PS_LANG_DEFAULT');
// looping through products
// this is a single line in the loop


$product = new Product(20);
$product-&gt;name = [$default_lang =&gt; 'Test'];
$product-&gt;link_rewrite = [$default_lang =&gt; 'test'];
$product-&gt;price = 13.90;
$product-&gt;quantity = 70;
$product-&gt;id_category = [3,4];
$product-&gt;id_category_default = 3;
StockAvailable::setQuantity((int)$product-&gt;id, 0, $product-&gt;quantity, Context::getContext()-&gt;shop-&gt;id);

$product-&gt;update();
</pre>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-create-products-from-php/">Create products from PHP in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-create-products-from-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating a &#8220;Clear cart&#8221; button in PrestaShop</title>
		<link>http://nemops.com/clear-cart-button-prestashop/</link>
		<comments>http://nemops.com/clear-cart-button-prestashop/#comments</comments>
		<pubDate>Wed, 13 Jul 2016 13:08:49 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[shopping cart]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2824</guid>
		<description><![CDATA[<p>In this tutorial, we will see how to add a button to empty the PrestaShop Cart in one click. Adding the button to the cart page The first thing we need is, of course, a button to play with. The ideal place where to add it is shopping-cart.tpl, specifically right after the order summary table. [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/clear-cart-button-prestashop/">Creating a &#8220;Clear cart&#8221; button in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this tutorial, we will see how to add a button to empty the PrestaShop Cart in one click.<br />
<span id="more-2824"></span></p>
<h2>Adding the button to the cart page</h2>
<p>The first thing we need is, of course, a button to play with. The ideal place where to add it is <strong>shopping-cart.tpl</strong>, specifically right after the order summary table. Therefore, open up the file, located in the theme folder, and read the end of the table, around line 454 of the default template:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
					{/foreach}
				&lt;/tbody&gt;
			{/if}
		&lt;/table&gt;
</pre>
<p>Right after the table, let&#8217;s add a simple button:</p>
<pre class="brush: xml; title: ; notranslate">
		&lt;a class=&quot;btn btn-default pull-right&quot; id=&quot;removeAll&quot; href=&quot;javascript:void(0)&quot;&gt;
			Empty Cart
		&lt;/a&gt;
</pre>
<p>Then, we need it to do something. We could use a submit, inside a form, but modern standards require speed, and nothing beats ajax in this.<br />
Right after the button, let&#8217;s add a script tag:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script&gt;
			$(document).ready(function() {
				$('#removeAll').click(function(e) {
				});
			});
				
&lt;/script&gt;
</pre>
<p>We want to target the click event of our new button, and fire an ajax request to the cart controller:</p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {
	$('#removeAll').click(function(e) {
		e.preventDefault()
		$.ajax({
			type: 'POST',
			headers: { &quot;cache-control&quot;: &quot;no-cache&quot; },
			url: baseUri + '?rand=' + new Date().getTime(),
			async: true,
			cache: false,
			dataType : &quot;json&quot;,
			data: 'controller=cart&amp;deleteAll=1&amp;token=' + static_token + '&amp;ajax=true',
			success: function(data){
				$('.opc-main-block, .step-num, #HOOK_SHOPPING_CART_EXTRA').fadeOut('fast');
				$('#order-detail-content').fadeOut('fast', function() {
					$('#emptyCartWarning').fadeIn('slow');	
				});
				ajaxCart.refresh();
			}
		})
	});
});
</pre>
<p><strong>Explanation:</strong> The url we call is simply the base one, plus a random value with the date, to avoid the request being cached. In terms of data, we need to pass in the controller (cart), and action (deleteAll, which doesn&#8217;t exist yet, but we will create in a second), the security token, and then ajax=true.<br />
On success, we fade out the page content, making sure any stuff from the One Page Checkout is hidden as well, and we also refresh the cart block.</p>
<p>The next step is to create something to handle the new deleteAll command.</p>
<div class="separator"></div>
<h2>Editing the CartController</h2>
<p>As always, instead of modifying the core file, make sure you use an override for this method. The function we are interested in is <strong>postProcess</strong>:</p>
<pre class="brush: php; title: ; notranslate">
    public function postProcess()
    {
        // Update the cart ONLY if $this-&gt;cookies are available, in order to avoid ghost carts created by bots
        if ($this-&gt;context-&gt;cookie-&gt;exists() &amp;&amp; !$this-&gt;errors &amp;&amp; !($this-&gt;context-&gt;customer-&gt;isLogged() &amp;&amp; !$this-&gt;isTokenValid())) {
            if (Tools::getIsset('add') || Tools::getIsset('update')) {
                $this-&gt;processChangeProductInCart();
            } elseif (Tools::getIsset('delete')) {
                $this-&gt;processDeleteProductInCart();
            } elseif (Tools::getIsset('changeAddressDelivery')) {
                $this-&gt;processChangeProductAddressDelivery();
            } elseif (Tools::getIsset('allowSeperatedPackage')) {
                $this-&gt;processAllowSeperatedPackage();
            } elseif (Tools::getIsset('duplicate')) {
                $this-&gt;processDuplicateProduct();
            }
            // Make redirection
            if (!$this-&gt;errors &amp;&amp; !$this-&gt;ajax) {
                $queryString = Tools::safeOutput(Tools::getValue('query', null));
                if ($queryString &amp;&amp; !Configuration::get('PS_CART_REDIRECT')) {
                    Tools::redirect('index.php?controller=search&amp;search='.$queryString);
                }

                // Redirect to previous page
                if (isset($_SERVER['HTTP_REFERER'])) {
                    preg_match('!http(s?)://(.*)/(.*)!', $_SERVER['HTTP_REFERER'], $regs);
                    if (isset($regs[3]) &amp;&amp; !Configuration::get('PS_CART_REDIRECT')) {
                        $url = preg_replace('/(\?)+content_only=1/', '', $_SERVER['HTTP_REFERER']);
                        Tools::redirect($url);
                    }
                }

                Tools::redirect('index.php?controller=order&amp;'.(isset($this-&gt;id_product) ? 'ipa='.$this-&gt;id_product : ''));
            }
        } elseif (!$this-&gt;isTokenValid()) {
            Tools::redirect('index.php');
        }
    }
</pre>
<p>See all those <strong>elseif</strong>s? We need another condition to target our deleteAll command. Therefore, at the end of the stack, add another:</p>
<pre class="brush: php; title: ; notranslate">
...
} elseif (Tools::getIsset('duplicate')) {
    $this-&gt;processDuplicateProduct();
} elseif (Tools::getIsset('deleteAll')) {

}
// Make redirection
if (!$this-&gt;errors &amp;&amp; !$this-&gt;ajax) {
...
</pre>
<p>Inside it, we do not need fancy stuff, only:</p>
<pre class="brush: php; title: ; notranslate">
elseif (Tools::getIsset('deleteAll')) {
                
    $this-&gt;context-&gt;cart-&gt;delete();
    $this-&gt;context-&gt;cookie-&gt;id_cart = 0;
    die(1);


}
</pre>
<p>This will clear the cart for good, and reset the id for the current user. You can also avoid resetting it, if you prefer.<br />
Save and test the button now. Make sure you clear the class_index.php file inside <em>cache/</em>, if you used an override.<br />
We are done!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/clear-cart-button-prestashop/">Creating a &#8220;Clear cart&#8221; button in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/clear-cart-button-prestashop/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>10 mistakes to avoid in PrestaShop Development</title>
		<link>http://nemops.com/prestashop-development-10-mistakes/</link>
		<comments>http://nemops.com/prestashop-development-10-mistakes/#comments</comments>
		<pubDate>Wed, 03 Feb 2016 11:16:31 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2696</guid>
		<description><![CDATA[<p>PrestaShop development is not easy at all. The software&#8217;s architecture requires a few good practices that are often ignored, making bug fixing an even more troublesome process for developers. In this article, we will see which are the ten most common mistakes you can make when developing for PrestaShop, and how to avoid them. 1- [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-development-10-mistakes/">10 mistakes to avoid in PrestaShop Development</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>PrestaShop development is not easy at all. The software&#8217;s architecture requires a few good practices that are often ignored, making bug fixing an even more troublesome process for developers. In this article, we will see which are the ten most common mistakes you can make when developing for PrestaShop, and how to avoid them.<br />
<span id="more-2696"></span></p>
<div class="separator"></div>
<h2>1- You don&#8217;t keep PS_DEV_MODE enabled</h2>
<p>On your dev sites, always keep development mode. If you don&#8217;t know how to, just reach out <em>config/defines.inc.php</em>, locate define(&#8216;_PS_MODE_DEV_&#8217;, false) and set it to true. If you need to test out performance, you might want to turn on _PS_DEBUG_PROFILING_ as well</p>
<h2>2- Not enough testing</h2>
<p>It&#8217;s obvious, but again often overlooked. <strong>Always make sure you test your modules on all the PrestaShop versions you want it to work with.</strong>. Test it not only locally, but online as well. If it involves category pages, make sure it works and it&#8217;s compatible with the Layered Navigation module. Also, try to have as many standard modules installed as you can, when you run your tests; this ensures your addon is compatible with at least the basic functionalities of the software.</p>
<h2>3- Core files modification</h2>
<p>I will never stress this highly enough: <strong>do not ever apply your modifications directly to core files</strong> (unless it&#8217;s impossible to do otherwise). <strong>Always use overrides</strong>, since it&#8217;s easier to point out a modification added with this method, rather than having to scrub through all the original files.</p>
<h2>4- Not enough comments</h2>
<p>Even if you use overrides, make sure you point out which part of the code you amended. I often found myself lost in overridden methods, since they were an almost identical copy of the original, with the tiniest modification to a single sql query, without anything pointing it out.</p>
<h2>5- Breaking the MVC pattern</h2>
<p>If you need to query the database, always use a class. It&#8217;s bad practice to run queries directly from controllers, so make sure you always use them exclusively to bind a class to a view. You will have to create another file, but the result is going to be cleaner and easier to maintain. For example, if you need you get a list of entries from your module&#8217;s table, you might want to have a class included in your controller <strong>with require_once at the very beginning of it</strong>. Alternatively, you can always access the module&#8217;s core file&#8217;s methods from any controller, using <strong>$this->module</strong>.</p>
<h2>6- Including CSS and Javascript in templates</h2>
<p>PrestaShop has two methods for inclusing Javascript and CSS: AddCSS and AddJS (please refer to: <a href="http://nemops.com/prestashop-functions-1/#.VrHbDrI4Hmg" title="Essential Prestashop Functions">Essential Prestashop Functions</a>). It&#8217;s not advised to use &laquo;style&raquo; tags directly within templates. You can use script tags, but only if it&#8217;s strictly necessary.</p>
<h2>7- Too much Javascript</h2>
<p>The modern web is full of fancy animations and pretty things that make a page render nice to the viewer, but also slower. Make sure you do not over-rely on javascript for page rendering. I have come across templates that could not be used at all without Javascript, and this is potentially harmful to any shop. Consider this: a single javascript error can kill the whole website&#8217;s accessibility. For this reason, always make sure your addon/theme runs fine without Javascript (just disable it from any browser console and test)</p>
<h2>8- No indentation indentation/formatting</h2>
<p>Try to format your code a bit. It&#8217;s not necessary to slavishly follow the standards PrestaShop requires to validate a module for the addons store, if you are selling it on your site. However, it&#8217;s a lot easier for us other developers to read your code, if it has a decent formatting.</p>
<h2>9- Extensive usage of custom code for the back office</h2>
<p>PrestaShop has tons of helpers for the back office, it&#8217;s better to rely on those instead of writing huge blocks of code with custom styling. It&#8217;s always better to output things with a template, whenever possible, and in any case use the standard css classes/boxes even when outputting directly from PHP.</p>
<h2>10 &#8211; Eccessive use of custom hooks</h2>
<p>Plenty templates I worked on had an insane amount of custom hooks. If you are a template developer, try to keep them at a bare minimum, unless strictly necessary, and rely on PrestaShop&#8217;s standard ones instead. A theme made up entirely with custom hooks is a real pain to deal with.</p>
<div class="separator"></div>
<h3>Want to know more about PrestaShop Development?</h3>
<p>Have a look at my <a href="http://nemops.com/prestashop-modules-course/" title="PrestaShop Modules Course">PrestaShop Modules Course</a></p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-development-10-mistakes/">10 mistakes to avoid in PrestaShop Development</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-development-10-mistakes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Essential Prestashop Functions – Day 3</title>
		<link>http://nemops.com/prestashop-functions-3/</link>
		<comments>http://nemops.com/prestashop-functions-3/#comments</comments>
		<pubDate>Mon, 03 Aug 2015 10:34:07 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2495</guid>
		<description><![CDATA[<p>Prestashop has lots of time-saving functions that we can use when developing modules or extensions. The third batch will be focused on product-related methods. NOTICE: Values with &#8220;=&#8221; in the declaration are optional. Getting a Product&#8217;s Price Both methods can be equally used to get a product&#8217;s price. While the first needs to be ran [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-functions-3/">Essential Prestashop Functions – Day 3</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Prestashop has lots of time-saving functions that we can use when developing modules or extensions. The third batch will be focused on product-related methods.</p>
<p><span id="more-2495"></span></p>
<p><strong>NOTICE: Values with &#8220;=&#8221; in the declaration are optional.</strong></p>
<h2>Getting a Product&#8217;s Price</h2>
<pre class="brush: php; title: ; notranslate">

// It needs an instance
Product::getPrice($tax = true, $id_product_attribute = null, $decimals = 6,
		$divisor = null, $only_reduc = false, $usereduc = true, $quantity = 1)

// Static way
Product::getPriceStatic($id_product, $usetax = true, $id_product_attribute = null, $decimals = 6, $divisor = null,
		$only_reduc = false, $usereduc = true, $quantity = 1, $force_associated_tax = false, $id_customer = null, $id_cart = null,
		$id_address = null, &amp;$specific_price_output = null, $with_ecotax = true, $use_group_reduction = true, Context $context = null,
		$use_customer_price = true);

</pre>
<p>Both methods can be equally used to get a product&#8217;s price. While the first needs to be ran by a product instance, the second is static and can be ran from every context, as long as you provide the product id.</p>
<h3>Example Usage</h3>
<pre class="brush: php; title: ; notranslate">

// get the product price, after instanciating a new object

$product = new Produc(4); // instanciate a product with id = 4
// get the price, but dynamically check if it needs to apply taxes or not
$product_price = $product-&gt;getPrice(Product::$_taxCalculationMethod == PS_TAX_INC);
// get the price of a specific combination, always with taxes
$product_attribute_price = $product-&gt;getPrice(true, 77);


// get price without instanciating an object
$products = array(
	0 =&gt; array('id_product' =&gt; 2),
	1 =&gt; array('id_product' =&gt; 86),
	2 =&gt; array('id_product' =&gt; 12),
);

foreach($products as $key =&gt; $product)
	$products[$key]['price'] = Product::getPriceStatic($product['id_product']);

</pre>
<div class="separator"></div>
<h2>Getting a Product&#8217;s Name</h2>
<pre class="brush: php; title: ; notranslate">

Product::getProductName($id_product, $id_product_attribute = null, $id_lang = null);

</pre>
<p>Retrieves the given product name in a single language (if not specified, the current one)</p>
<h3>Example Usage</h3>
<pre class="brush: php; title: ; notranslate">

// Gets the name in the current language
$name = Product::getProductName(34);

// Gets the combination name in a chosen language
$name = Product::getProductName(34, 6, 2);

</pre>
<div class="separator"></div>
<h2>Getting a Product&#8217;s Quantity</h2>
<pre class="brush: php; title: ; notranslate">


Product::getQuantity($id_product, $id_product_attribute = null, $cache_is_pack = null);

// This will consider a specific warehouse
Product::getRealQuantity($id_product, $id_product_attribute = 0, $id_warehouse = 0, $id_shop = null)

</pre>
<p>They both return the product&#8217;s quantity, but the latter is to be preferred with advanced stock management in mind.</p>
<h3>Example Usage</h3>
<pre class="brush: php; title: ; notranslate">

// gets the quantity of all products in the array
$products = array(
	0 =&gt; array('id_product' =&gt; 2),
	1 =&gt; array('id_product' =&gt; 86),
	2 =&gt; array('id_product' =&gt; 12),
);

foreach($products as $key =&gt; $product)
	$products[$key]['qty'] = Product::getQuantity($product['id_product']);


// Gets quantity for a specific combination of a product (product id = 6, combination id = 99)
$quantity = Product::getQuantity(6, 99);


// Gets the quantity in stock for the specific warehouse ID
$quantity = Product::getRealQuantity(6, 0, 1);

</pre>
<div class="separator"></div>
<h2>Getting and displaying Products Cover Image</h2>
<pre class="brush: php; title: ; notranslate">

// Returns an image ID
Product::getCover($id_product, Context $context = null);

// Uses the product rewrite and image id to get the actual image link
Link::getImageLink($name, $ids, $type = null);

</pre>
<p>These can be used in conjunction to display the product&#8217;s cover.</p>
<h3>Example Usage</h3>
<pre class="brush: php; title: ; notranslate">

// returns an array like array('id_image' =&gt; 66)
$cover = Product::getCover(5);

if($cover) // if there is an image
{
	// notice 'ipod-nano' is the product link_rewrite field here;
	$img_link = $this-&gt;context-&gt;link-&gt;getImageLink('ipod-nano', $cover['id_image']); // remember the previous is an array
}

</pre>
<div class="separator"></div>
<h2>Getting Product Features for the front office</h2>
<pre class="brush: php; title: ; notranslate">

// Gets features so they can be properly displayed
Product::getFrontFeatures($id_lang);

// The same, but static
Product::getFrontFeaturesStatic($id_lang, $id_product);

</pre>
<p>These methods come in handy when you want to display product features with their names and values.</p>
<h3>Example Usage</h3>
<pre class="brush: php; title: ; notranslate">

$product = new Product(10);
$features = $product-&gt;getFrontFeatures($this-&gt;context-&gt;language-&gt;id);


// static way
$features = Product::getFrontFeaturesStatic($this-&gt;context-&gt;language-&gt;id, 10);

</pre>
<div class="separator"></div>
<h2>Getting Product Categories</h2>
<pre class="brush: php; title: ; notranslate">



// Get ids of the categories this product belongs to
Product::getCategories();

// The same, Static
Product::getProductCategories($id_product);

// Get more data about categories, including name and link_rewrite
Product::getProductCategoriesFull($id_product, $id_lang = null);

// Get all parent categories, up to the root, in a single language. It will only consider the default one as starting point
Product::getParentCategories($id_lang = null);

</pre>
<p>They are all used to retrieve data about the product&#8217;s category association.</p>
<h3>Example Usage</h3>
<pre class="brush: php; title: ; notranslate">

$product = new Product(10);
// $categories will be ids only
$categories = $product-&gt;getCategories();

// Using the same Object, get all parents
$parent_categories = $product-&gt;getParentCategories();

// Static way, getting more data in the current language
$categories = Product::getProductCategoriesFull(10, $this-&gt;context-&gt;language-&gt;id);


</pre>
<div class="separator"></div>
<h3>Additional Resources</h3>
<ul>
<li><a href="http://nemops.com/prestashop-functions-1/#.Vb8upPnzrmg" title="Essential Prestashop Functions – Day 1">Essential Prestashop Functions – Day 1</a></li>
<li><a href="http://nemops.com/prestashop-functions-2/#.Vb9Bxvnzrmg" title="Essential Prestashop Functions – Day 2">Essential Prestashop Functions – Day 2</a></li>
<li><a href="http://nemops.com/prestashop-functions-4/#.Vc2cffnzrmg" title="Essential Prestashop Functions – Day 4">Essential Prestashop Functions – Day 4</a></li>
<li><a href="http://nemops.com/prestashop-functions-5/#.Ve6fNxHzrmg" title="Essential Prestashop Functions – Day 5">Essential Prestashop Functions – Day 5</a></li>
</ul>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-functions-3/">Essential Prestashop Functions – Day 3</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-functions-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
