Aleksandar Krstic

Personal Blog

PHP console log – The easiest way

PHP console log – The easiest way is to use JavaScript inside PHP, and that can be done with the simple trick.


$str = "Cars";
$arr = array("Volvo", "BMW", "Saab");

echo("<script>console.log('Log: ".$str."');</script>");
echo "<br>";
echo("<script>console.log('Log: ".json_encode($arr)."');</script>");

You will probably notice the difference between 2 logs. One have json_encode, another doesn’t. There is no need to use it when we want to log a string, but when we want to log an array, we need it, because otherwise it will just log information that you dealing with array(s), without values.

Example with json_encode.

PHP console log

Without json_encode.

PHP console log

MySQL Union with Order By

When you execute commands that contains UNION and ORDER BY in MySQL like this one:


(SELECT col1 FROM tab1 WHERE ... ORDER BY col1 ASC) 
UNION
(SELECT col1 FROM tab2 WHERE ... ORDER BY col1 ASC);

you expect to get col1 from tab1 (ordered ascending by col1) “joined” with col1 from tab2 (ordered ascending by col1).

And in some cases you will get the desired rusult, but in some situations query execution will ignore ORDER BY in both SELECT statements.

I think that depends on version of mysql server, which is used. In my case it doesn’t work on Linux Server – MariaDB 10.0.25, but it works on MAMP’s MySQL – 5.6.35.

Anyway, the only way to make sure that ORDER BY will work for all SELECT’s in UNION, is simply to add LIMIT.

So, the example from above should look like this:


(SELECT col1 FROM tab1 WHERE ... ORDER BY col1 ASC LIMIT 10) 
UNION
(SELECT col1 FROM tab2 WHERE ... ORDER BY col1 ASC LIMIT 10);

This is the official explanation from dev.mysql.com

“Use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows. Therefore, the use of ORDER BY in this context is typically in conjunction with LIMIT, so that it is used to determine the subset of the selected rows to retrieve for the SELECT, even though it does not necessarily affect the order of those rows in the final UNION result. If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.”

Hope that this article helped with this, at least for me, unusual problem.

Magento 2 – Cookies with JavaScript

This article is basically follow up on previous one.

There I talked about popup/sliding panel handling, but if you want to improve that with cookies usage (for example, to auto-load popup just once per session or similar …) here you can find some useful tips.

In Magento 2 you can achieve that with PHP or JavaScript (jQuery, mage/cookies, js-cookie, …)

From what I have experienced, the best way is with the js-cookie plugin (inheritor of jQuery Cookies which is “retired” from 2015).

Why not PHP?
PHP approach cannot be implemented in custom block from Magento backend, and JavaScript can through require.js.

Why not jQuery Cookies plugin?
As I mentioned, it’s retired from 2015, and people who worked on it continued the job on js-cookie plugin. Beside that, cookie retrieving not working anymore (at least for me).

So which one?
That plugin can be found here – https://github.com/js-cookie/js-cookie

Only file that you need is – https://github.com/js-cookie/js-cookie/blob/master/src/js.cookie.js

So, steps for the implementation are:

1. Place js.cookie.js in \lib\web
2. Run Static Content Deploy command – php bin/magento setup:static-content:deploy
3. Go to place where you want to use js-cookie and call it.

    require(
        [
            'jquery',
            'js.cookie'
        ],
        function($, Cookies) { …. }

Usage:
Set cookie – Cookies.set(‘name’, ‘value’, { expires: 30 }); // expires in 30 days
Get cookie – Cookies.get(‘name’); //returns value
Remove cookie – Cookies.remove(‘name’);

Complete documentation can be found here
https://github.com/js-cookie/js-cookie

Updated code from the previous article now looks:

<script type="text/javascript">
    require(
        [
            'jquery',
            'Magento_Ui/js/modal/modal',
            'js.cookie'
        ],
        function($, modal, Cookie){
            var options = {
                type: 'popup', // there is also a slide type. By default sliding from the right.
                responsive: true,
                innerScroll: true,
                buttons: [{
                    text: $.mage.__('Close'),
                    class: '',
                    click: function () {
                        this.closeModal();
                    }
                }]
            };
 
            var popup = modal(options, $('#popup-modal'));
             
            //Popup appears on winodow load only once in session
            $( document ).ready(function() {
                    var cookieGet = Cookies.getJSON('amishown');
                    if (cookieGet === null || cookieGet === undefined){
                    $("#popup-modal").modal("openModal");
	            var cookieSet = Cookies.set('amishown', 'shown');
                    } 
             });
        }
    );
</script>

Magento 2 – Popup/slide modal handling

Magento 2 offers very easy way to use popup or sliding panels.

It can be achieved with the following piece of jQuery code anywhere you want (blocks, pages, templates, …).

<script type="text/javascript">
	require(
		[
			'jquery',
			'Magento_Ui/js/modal/modal'
		],
		function($, modal){
			var options = {
				type: 'popup', // there is also a slide type. By default sliding from the right.
				responsive: true,
				innerScroll: true,
				buttons: [{
					text: $.mage.__('Close'),
					class: '',
					click: function () {
						this.closeModal();
					}
				}]
			};

			var popup = modal(options, $('#popup-modal'));
			
			//Popup appears on click on specific emelent with id=click-me			
			$("#click-me").on('click',function(){ 
				$("#popup-modal").modal("openModal");
			});
			
			//Popup appears on winodow load
			$('#popup-modal').modal('openModal');
		}
	);
</script>

Also, you will need some html.

<!-- Link which will trigger popup on click. -->
<a href="#" id="click-me">Click me</a>

<!-- Popup content. -->
<div id="popup-modal">Here goes content modal</div>

As you can it is very easy to handle events (click, on window load, hover, …).

There are 2 types of modals in magento – Popup and Sliding Panel.

More about modal options you can find in official Magento documentation.

Magento 2 – Bulk update product position in category

Magento 2 offers manual way to update position of product in category. This is okay, but in case when you have 5000 products, it’s not that easy to re-order them one by one.

Also, there is a premium tool called “Store Manager for Magento”, and it’s very good, but if you don’t want to spend money on it, this is what I suggest:

*This presumes that you have csv file with sku and position columns ready.

1. Create table temp1 with the following query

CREATE TABLE temp1
SELECT a.category_id, a.product_id, a.position, b.sku
FROM catalog_category_product AS a, catalog_product_entity AS b
WHERE a.product_id = b.entity_id

2. Create table temp2 with 2 columns sku and position (they need to matach structure of same fields in temp1 table)

3. Import you csv file to temp2 table via phpMyAdmin.

4. Execute the following query in order to update temp1 from temp2

UPDATE temp1 t1 
INNER JOIN temp2 t2 
ON t1.sku = t2.sku 
SET t1.position = t2.position

5. Execute the following query in order to update catalog_category_product from temp1

UPDATE catalog_category_product t1 
INNER JOIN temp1 t2 
ON t1.product_id = t2.product_id 
AND t1.category_id = t2.category_id 
SET t1.position = t2.position

IMPORTANT: This will update position of product in all categories in which that product exist.