Mar 20, 2018
kalpesh

Setting up Magento 2.2.3 on Valet+ (requires MacOS)

Wondering what is Valet+? It is a development environment for MacOS. If you have previously used Vagrant and/or Docker, I think you would just love Valet+. Valet+ is very easy yet fast development environment, as it doesn’t require you to edit /etc/hosts, vhosts, mysql, etc.. For more information on Valet+ and how it differs with Valet, please read this: https://github.com/weprovide/valet-plus/blob/master/readme.md

Let me know in comments section which one you prefer out of these 3?

Okay so let’s come to topic and start preparing to install Valet and Magento.

1.) Install Homebrew if you do not have it already on your Mac

2.) Let’s install PHP 7.1

brew install homebrew/php/php71

If you already have php70, you can unlink it before running above command:

brew unlink php70

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
Kalpeshs-MBP:~ kalpesh$ brew install php71
Updating Homebrew...
==> Installing php71 from homebrew/php
==> Installing dependencies for homebrew/php/php71: libpng, freetype, gettext, icu4c, jpeg, libtool, unixodbc, readline
==> Installing homebrew/php/php71 dependency: libpng
==> Downloading https://downloads.sourceforge.net/libpng/libpng-1.6.34.tar.xz
==> Downloading from https://downloads.sourceforge.net/project/libpng/libpng16/1.6.34/libpng-1.6.34.tar.xz
######################################################################## 100.0%
==> ./configure --disable-silent-rules --prefix=/usr/local/Cellar/libpng/1.6.34
==> make
==> make test
==> make install
🍺 /usr/local/Cellar/libpng/1.6.34: 26 files, 1.2MB, built in 2 minutes 22 seconds
==> Installing homebrew/php/php71 dependency: freetype
==> Downloading https://downloads.sourceforge.net/project/freetype/freetype2/2.9/freetype-2.9.tar.bz2
==> Downloading from https://svwh.dl.sourceforge.net/project/freetype/freetype2/2.9/freetype-2.9.tar.bz2
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/freetype/2.9 --without-harfbuzz
==> make
==> make install
🍺 /usr/local/Cellar/freetype/2.9: 60 files, 2.7MB, built in 1 minute 53 seconds
==> Installing homebrew/php/php71 dependency: gettext
==> Downloading https://homebrew.bintray.com/bottles/gettext-0.19.8.1.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring gettext-0.19.8.1.yosemite.bottle.tar.gz
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local,
because macOS provides the BSD gettext library & some software gets confused if both are in the library path.

If you need to have this software first in your PATH run:
echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> ~/.bash_profile

For compilers to find this software you may need to set:
LDFLAGS: -L/usr/local/opt/gettext/lib
CPPFLAGS: -I/usr/local/opt/gettext/include

==> Summary
🍺 /usr/local/Cellar/gettext/0.19.8.1: 1,934 files, 17.0MB
==> Installing homebrew/php/php71 dependency: icu4c
==> Downloading https://ssl.icu-project.org/files/icu4c/60.2/icu4c-60_2-src.tgz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/icu4c/60.2 --disable-samples --disable-tests --enable-static --with-library-bits=64
==> make
==> make install
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local,
because macOS provides libicucore.dylib (but nothing else).

If you need to have this software first in your PATH run:
echo 'export PATH="/usr/local/opt/icu4c/bin:$PATH"' >> ~/.bash_profile
echo 'export PATH="/usr/local/opt/icu4c/sbin:$PATH"' >> ~/.bash_profile

For compilers to find this software you may need to set:
LDFLAGS: -L/usr/local/opt/icu4c/lib
CPPFLAGS: -I/usr/local/opt/icu4c/include
For pkg-config to find this software you may need to set:
PKG_CONFIG_PATH: /usr/local/opt/icu4c/lib/pkgconfig

==> Summary
🍺 /usr/local/Cellar/icu4c/60.2: 249 files, 67.2MB, built in 9 minutes 15 seconds
==> Installing homebrew/php/php71 dependency: jpeg
==> Downloading http://www.ijg.org/files/jpegsrc.v9c.tar.gz
######################################################################## 100.0%
==> ./configure --disable-silent-rules --prefix=/usr/local/Cellar/jpeg/9c
==> make install
🍺 /usr/local/Cellar/jpeg/9c: 21 files, 736.3KB, built in 1 minute 30 seconds
==> Installing homebrew/php/php71 dependency: libtool
==> Downloading https://homebrew.bintray.com/bottles/libtool-2.4.6_1.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring libtool-2.4.6_1.yosemite.bottle.tar.gz
==> Caveats
In order to prevent conflicts with Apple's own libtool we have prepended a "g"
so, you have instead: glibtool and glibtoolize.
==> Summary
🍺 /usr/local/Cellar/libtool/2.4.6_1: 70 files, 3.7MB
==> Installing homebrew/php/php71 dependency: unixodbc
==> Downloading http://www.unixodbc.org/unixODBC-2.3.5.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/unixodbc/2.3.5_1 --sysconfdir=/usr/local/etc --enable-static --enable-gui=no
==> make install
🍺 /usr/local/Cellar/unixodbc/2.3.5_1: 41 files, 1.9MB, built in 4 minutes 22 seconds
==> Installing homebrew/php/php71 dependency: readline
==> Downloading https://homebrew.bintray.com/bottles/readline-7.0.3_1.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring readline-7.0.3_1.yosemite.bottle.tar.gz
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local,
because macOS provides the BSD libedit library, which shadows libreadline.
In order to prevent conflicts when programs look for libreadline we are
defaulting this GNU Readline installation to keg-only..

For compilers to find this software you may need to set:
LDFLAGS: -L/usr/local/opt/readline/lib
CPPFLAGS: -I/usr/local/opt/readline/include

==> Summary
🍺 /usr/local/Cellar/readline/7.0.3_1: 46 files, 1.5MB
==> Installing homebrew/php/php71
==> Downloading https://php.net/get/php-7.1.14.tar.bz2/from/this/mirror
==> Downloading from https://secure.php.net/get/php-7.1.14.tar.bz2/from/this/mirror
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/php71/7.1.14_25 --localstatedir=/usr/local/var --sysconfdir=/usr/local/etc/php/7.1 --with-config-file-path=/usr/local/etc/php/7
==> make
==> make install
==> Caveats
The php.ini file can be found in:
/usr/local/etc/php/7.1/php.ini

✩✩✩✩ Extensions ✩✩✩✩

If you are having issues with custom extension compiling, ensure that you are using the brew version, by placing /usr/local/bin before /usr/sbin in your PATH:

PATH="/usr/local/bin:$PATH"

PHP71 Extensions will always be compiled against this PHP. Please install them using --without-homebrew-php to enable compiling against system PHP.

✩✩✩✩ PHP CLI ✩✩✩✩

If you wish to swap the PHP you use on the command line, you should add the following to ~/.bashrc, ~/.zshrc, ~/.profile or your shell's equivalent configuration file:
export PATH="$(brew --prefix homebrew/php/php71)/bin:$PATH"

✩✩✩✩ FPM ✩✩✩✩

To launch php-fpm on startup:
mkdir -p ~/Library/LaunchAgents
cp /usr/local/opt/php71/homebrew.mxcl.php71.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.php71.plist

The control script is located at /usr/local/opt/php71/sbin/php71-fpm

OS X 10.8 and newer come with php-fpm pre-installed, to ensure you are using the brew version you need to make sure /usr/local/sbin is before /usr/sbin in your PATH:

PATH="/usr/local/sbin:$PATH"

You may also need to edit the plist to use the correct "UserName".

Please note that the plist was called 'homebrew-php.josegonzalez.php71.plist' in old versions of this formula.

With the release of macOS Sierra the Apache module is now not built by default. If you want to build it on your system you have to install php with the --with-httpd option. See brew options php71 for more details.

By 31st March 2018 we will deprecate and archive the PHP tap.
Some of the formulae will be migrated to homebrew-core.

For more details, see https://github.com/Homebrew/homebrew-php/issues/4721

To have launchd start homebrew/php/php71 now and restart at login:
brew services start homebrew/php/php71
==> Summary
🍺 /usr/local/Cellar/php71/7.1.14_25: 345 files, 39.9MB, built in 11 minutes 5 seconds

3.) Install Composer

brew install homebrew/php/composer

4.) Finally install Valet+

composer global require weprovide/valet-plus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Kalpeshs-MBP:valet kalpesh$ composer global require weprovide/valet-plus
Changed current directory to /Users/kalpesh/.composer
Using version ^1.0 for weprovide/valet-plus
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 15 installs, 0 updates, 0 removals
- Installing tightenco/collect (v5.4.33): Downloading (100%)
- Installing symfony/process (v3.4.6): Downloading (100%)
- Installing nategood/httpful (0.2.20): Downloading (100%)
- Installing psr/container (1.0.0): Downloading (100%)
- Installing container-interop/container-interop (1.2.0): Downloading (100%)
- Installing php-di/invoker (1.3.3): Downloading (100%)
- Installing psr/log (1.0.2): Downloading (100%)
- Installing symfony/debug (v4.0.6): Downloading (100%)
- Installing symfony/polyfill-mbstring (v1.7.0): Downloading (100%)
- Installing symfony/console (v3.4.6): Downloading (100%)
- Installing mnapoli/silly (1.5.1): Downloading (100%)
- Installing psr/simple-cache (1.0.1): Downloading (100%)
- Installing illuminate/contracts (v5.6.12): Downloading (100%)
- Installing illuminate/container (v5.6.12): Downloading (100%)
- Installing weprovide/valet-plus (1.0.11): Downloading (100%)
symfony/console suggests installing symfony/event-dispatcher ()
symfony/console suggests installing symfony/lock ()
Writing lock file
Generating autoload files

5.) Add export PATH in your .bash_profile

vi ~/.bash_profile

and add below line on top (after PATH line if you have one already)

export PATH=”$PATH:$HOME/.composer/vendor/bin”

to reflect our current changes in the current terminal tab session, run:

Continue reading »

May 4, 2017
kalpesh

Redirect request with POST data using .htaccess

By default, if you want to redirect request with POST data, browser redirects it via GET with 302 redirect. This also drops all the POST data associated with the request. Browser does this as a precaution to prevent any unintentional re-submitting of POST transaction.

But what if you want to redirect anyway POST request with it’s data? In HTTP 1.1, there is a status code for this. Status code 307 indicates that the request should be repeated with the same HTTP method and data. So your POST request will be repeated along with it’s data if you use this status code.

From https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,
If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

I did this in one of the website to redirect HTTP request to HTTPS for a specific page.

1
2
3
4
5
RewriteEngine on
RewriteCond %{SERVER_PORT} !443
RewriteCond %{REQUEST_URI} string_to_match_in_url
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=307]

For this to work, you need to have mod_rewrite enabled on the server. The first RewriteCond checks if the request is NOT coming as HTTPS, otherwise it will go in endless loop. If yes, the second RewriteCond checks if the URL contains a string we are looking for. Then if that URL is being submitted as POST method. If everything matches, then we redirect the request using HTTPS secure protocol retaining the POST method and the associated data.

Apr 17, 2017
kalpesh

Magento 2 upgrade from 2.0.* to latest version using composer via CLI

In this post I will show you how to upgrade Magento 2.0.5 (2.0.*) to 2.1.6 which is latest CE version as of today. We will do it using composer via server command-line interface. It is recommended to take code and DB backup and do this upgrade on your development/stage server first.

Magento 2 comes with Web Setup Wizard (under Admin > System) where you can upgrade from admin panel itself, but for some reason it was always failing for me at Readiness Check’s Component Dependency check.

Step 1.) Edit the composer.json which should be located at the root of your store. Change version and magento/product-community-edition from 2.0.* (whatever you have currently) to 2.1.6 or any latest version you wish to upgrade to. Also change sample data versions from 100.0.* to 100.1.*

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
    "name": "magento/project-community-edition",
    "description": "eCommerce Platform for Growth (Community Edition)",
    "type": "project",
    "version": "2.1.6",
    "require": {
        "magento/product-community-edition": "2.1.6",
        "composer/composer": "@alpha",
        "magento/module-bundle-sample-data": "100.1.*",
        "magento/module-theme-sample-data": "100.1.*",
        "magento/module-widget-sample-data": "100.1.*",
        "magento/module-catalog-sample-data": "100.1.*",
        "magento/module-customer-sample-data": "100.1.*",
        "magento/module-cms-sample-data": "100.1.*",
        "magento/module-tax-sample-data": "100.1.*",
        "magento/module-review-sample-data": "100.1.*",
        "magento/module-catalog-rule-sample-data": "100.1.*",
        "magento/module-sales-rule-sample-data": "100.1.*",
        "magento/module-sales-sample-data": "100.1.*",
        "magento/module-grouped-product-sample-data": "100.1.*",
        "magento/module-downloadable-sample-data": "100.1.*",
        "magento/module-msrp-sample-data": "100.1.*",
        "magento/module-configurable-sample-data": "100.1.*",
        "magento/module-product-links-sample-data": "100.1.*",
        "magento/module-wishlist-sample-data": "100.1.*",
        "magento/module-swatches-sample-data": "100.1.*",
        "magento/sample-data-media": "100.1.*",
        "magento/module-offline-shipping-sample-data": "100.1.*"
    },...

Step 2.) composer update (Run this command on the server/terminal. You may need to create GitHub OAuth token to pass the rate limit. Login to your Github account (or create one) and head to Developer Settings > Personal access tokens and generate new token with full control of private repositories.)
Continue reading »

Nov 17, 2016
kalpesh

Magento: Multiple security vulnerabilities in Aheadworks Follow up Email extension

IMPORTANT: If you are using this extension in any of the Magento store, please patch or upgrade it immediately if you have not done it yet. You can find more details on the affected versions and patches here:
https://blog.aheadworks.com/2016/10/security-issue-follow-up-email-vulnerability/
https://blog.aheadworks.com/2016/10/follow-email-security-patch/

While modifying Aheadworks follow up extension on our store to meet our specific requirements, I discovered multiple security vulnerabilities in the extension. As the vulnerabilities were pretty serious, I immediately sent my discoveries to Magento team which they promptly sent to Aheadworks team. Aheadworks was quick enough to fix the vulnerabilities and rolled out the patches.

Link of the extension in Magento Marketplace:
https://marketplace.magento.com/aheadworks-follow-up-email.html
It allows store owners to send automated emails to customers who had abandoned their cart.
Aheadworks follow up email extension

All the below vulnerabilities were found in the extension.

1. SQL injection
2. Directory Traversal vulnerability
Attacker can traverse to any directory on the server. In earlier PHP versions (prior to 5.3.4), attacker can read any file on server including /etc/passwd
3. Unrestricted Directories creation
Attacker can create any number of directories and subdirectories with their desired name wherever web server has permissions

I will not disclose any technical details and PoC of the vulnerabilties here to prevent wild exploits on Magento websites having this extension installed.

Timeline:
Oct 6, 2016 – Discovered the SQL injection vulnerability
Oct 6, 2016 – Emailed the vulnerability to Magento security and marketplace team
Oct 7, 2016 – Emailed the vulnerability to Magento team
Oct 7, 2016 – Magento forwarded my discoveries to Aheadworks team
Oct 11, 2016 – Aheadworks released new version 3.6.6 and patch for older versions of the extension
Oct 25, 2016 – Found further vulnerabilities on the same controller action, this time Directory Traversal and Unrestricted Directories creation vulnerabilities
Oct 25, 2016 – Emailed the details to Magento team, they promptly notified to Aheadworks team
Oct 27, 2016 – Fixed the vulnerabilities in new version 3.6.7 and released the patch for older versions

Mar 28, 2016
kalpesh

[Resolved] WordPress update error

If you are getting below (or any WordPress update) error when you are updating your WordPress to latest version, the problem could be:

500 Internal Server Error

PHP Fatal error: Call to undefined function wp_oembed_add_host_js() in /var/www/production/blog/wp-admin/about.php on line 31

PHP version. Make sure the PHP version you have meets the required PHP version of new WordPress update.
Opcode cache. If you are using opcode cache like APC, clear the cache.
WordPress cache. Flush the WordPress cache (Wordfence, WP Super Cache, W3 Total Cache, etc.) you are using.
CloudFlare. If you are using external cache like CloudFlare, make sure you also flush it if you still see the above error.

Refresh the update page and see if this resolves for you!

Pages:1234567...34»

Welcome to my Blog

Kalpesh MehtaHelping Magento developers in their day-to-day development problems since 2011. Most of the problems and solutions here are my own experiences while working on different projects. Enjoy the blog and don't forget to throw comments and likes/+1's/tweets on posts you like. Thanks for visiting!

Certifications