Debug Magento 2 using PhpStorm

I had to spend some time to get my PhpStorm working with debugging a Magento 2 store we are developing. This is a short notice of what I found out and how I got it working.

A couple of weeks ago I had a working setup where I could debug both command line commands and pages using PhpStorm. Last weeks I have been developing a command line but swapped back to some page coding now and it did not work. In my initial setup I mainly followed this setup but since I use MAMP(none PRO) this article was helpful.

After a bit of struggling I found out the reason why it was not working any longer. Because of some mysterious reason I had checked the “Use path mappings…” check box. DON’T!

And as you see above it works just fine with using localhost in the servers configuration.

Another useful things to solve this was to add xdebug.remote_log="/tmp/xdebug.log" to the two php.ini files and restart MAMP and then look at the log with tail -f /tmp/xdebug.log. I noticed I had a couple of lines like this:
I: Connecting to configured address/port: localhost:9000.
W: Creating socket for 'localhost:9000', poll success, but error: Operation now in progress (19).
W: Creating socket for 'localhost:9000', poll success, but error: Operation now in progress (19).
I: Connected to client. :-)

The lines starting with W(guess meaning Warning) should not be there. It means the connection was not completely successful even though reading the line indicates some sort of success but there is the error too.

And while we are at it. I have not yet figured out the meaning of this button.

There seems to be no need to listen for PHP debug connections using this setup.

Configure WLAN on Raspberry Pi Z W

To setup my Raspberry Pi Z W I have combined two different guides since editing the files on the SD did not work, nor did I had the energy to setup Vagrant.

Start by flashing a micro SD card as described here using Etcher.

Insert the card into a Mac or PC and add enable_uart=1 to the end of config.txt as described here.

Insert the SD card in the Raspberry Pi and boot it as described here using a USB serial cable. Then in a terminal window run screen /dev/tty.usbserial-A7005Gpd 115200 (change to your device tty) to connect to the serial terminal on the Raspberry Pi.

Now you can follow this guide from step 3. Though I did not configure mine for two networks and here are how my configuration files look like:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf


country=SE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
ssid="SSID_OF_NETWORK_1"
psk="password"
id_str="home"
}

sudo nano /etc/network/interfaces


source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

iface eth0 inet manual

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf

iface home inet dhcp

Ta bort plast som fastnat

Fick ju lite problem med skrivaren på grund av felaktiga inställningar och var lite fundersam till hur plockar man isär den och sedan sätter ihop den för att få bort plast som fastnat. Som tur är har andra redan gjort det och det fanns bra filmer på YouTube. Denna tyckte jag var bäst.

En sak som är viktig vad gäller PrimaCreator skrivaren är att den säljs under flera olika namn och det vanligaste verkar vara MonoPrice Select Mini och söker man på det hittar man tex denna utmärkta Wiki med gott om kunskap om skrivaren och instruktioner.

Ny 3D skrivare och inställningar till den

För ca en månad sedan dök det upp en post i 3D Sweden om en 3D skrivare som kostade relativt lite och verkade vara av bra kvalité, PrimaCreator P120. Så jag slog till och beställde en.

Så här om helgen var det dags att testa den rejält men stötte på problem. Det gick bra med t.ex. den katt söm följde med en fil för på minneskortet men så fort jag slicade själv så gick det åt skogen. Testade en hel del men sedan i ren desperation postade jag i 3D Sweden och fick rätt snabbt svar! Tack Niklas! Det visade sig vara först och främst Retraction Distance som var fel. När jag ställde in det på 3.15mm så fungerade det perfekt.

För andra som skaffar denna skrivare och köper samma plast(filament) så här finns mina inställningar för Cura:
generella Cura profilen
material filen

Och här är en bild på skrivarinställningarna och start och slut kod.

Start kod:
; From Niklas Ramström
G28 ; home all axes
G92 E0 ;zero the extruded length
G1 X5 Y119 E10 F1000.0 ; extrude 10mm to prime the nozzle
G92 E0 ;zero the extruded length again
G1 Z3.0 F9000 ;move the head 3mm up just to be safe
G92 E0 ;zero the extruded length again

Slut kod:
; Mix of Niklas Ramström and default
M104 S0 ; turn off extruder
M140 S0 ; turn off bed

G92 E1
G1 E-1 F300

G91 ; use relative coordinates
G1 Z0.6 F5000 ; lift nozzle by 0.6mm
G90 ; use absolute coordinates
G28 X0 ; home X axis
G1 Y119; move Y axis to end position
M84 ; disable motors
M107 ; turn off fan

LetsEncrypt certificates for a new site

How do you add certificates for a newly setup website? Like this:

sudo ./letsencrypt-auto run -d www.friluftslivifjallen.se,friluftslivifjallen.se --redirect

I have the old letsencrypt client installed so for a newer installation change letsencrypt-auto to certbot. More about the certbot command line options can be found here.

This post is just a quick self-reminder to be used in the future when I set up new sites on my server.

Simple local hosting

Sometimes you just want to host some files locally on you machine. For instance when debugging javascript with webworkers importing javascript files, it is required that these files come from a web URL instead of a file://-URL.

Just saw this great suggestion on Stackoverflow. Start a local webserver using Python or Javascript and you now have the files available at http://localhost!
sudo python3 -m http.server 80
or if you do not have Python 3 installed
sudo python -m SimpleHTTPServer 80

Automatic versioning information in Git projects

When developing software using several different libraries etc it is always good to know which version of which library is used in a certain installation etc. Though there is no really easy way in Git to solve this as in CVS for instance with its keywords.

Though the following trick creates a nice way of keeping track.

The concept is to utilise GIT Hooks and that we write a script that generates a file with the versioning information in it and then our build system integrates this with the code. The following example is made using C but should be easy to adopt to other languages.

Create and edit the file .git/hooks/post-commit to look like this:


#!/bin/sh
#
version=$(git describe --tags --long)
echo "#define LIBRARY_NAME_VERSION \""$version"\"" > ./version.h

Make the script executable:

chmod a+x .git/hooks/post-commit

For this to work though you must have made a tag, see GIT Tagging. Once your repository is tagged you can test the script:

.git/hooks/post-commit
more version.h

You should have got something like this:


#define LIBRARY_NAME_VERSION "v0.4-0-g76ed9ef"

Now you can use this in your code for instance to output versioning information at startup.

And finally add version.h to your GIT ignore file or you will have a continuous flow of commits to include the latest change of this file, since it will change after each commit 🙂

echo version.h >> .gitignore

How-to create a reasonably secure Arduino client that post data into a Rails application – part II

In part I I described how to create the Rails application but now lets focus on the Arduino. First you need to find a library for you GSM/GPRS shield you are using. I have the Seeedstudio GPRS Shield even though I do not have version 2.0 no good library existed for it. The libraries Seeedstudio list on their wiki and product pages all work great but they have which I consider a major flaw; they do NOT use the same methods etc as the official Arduino GSM library does. Thus if someone has developed a client using that shield you would need to re-write the code if you have another GSM shield. Both provide same functionality but through a different API. NOT a good solution in my eyes.

The official GSM library is written to be extended with support for other shields and I started to look into it. After examining the code for a while I noticed it is not written very well. The library as such is large and uses a lot of unnecessary RAM. My intentions is to create a client that will be RAM efficient to run on a Duemilanove which has only 2 kb RAM. Thus I started to write yet another GSM library for the Seeedstudio Shield. The result is the GSMGPRS_Shield library.

Anyway that was a sidetrack from the main, to create a reasonably secure Arduino client. Now we got a library to send and receive information to a HTTP server! So the next step is to find a good REST client. I found a number of different libraries that could be used either just for HTTP communication or both HTTP and REST.

HttpClient which is mainly developed for the Spark and not the best on a vanilla Arduino. Then there is the HTTPClient by Interactive Matter. Yet another HttpClient by Adrian McEwen. And uHTTP though all of these are based on the EthernetClient class and thus has to be re-written if going to be used with any GSM library. So much for code reusability.

There also exists a number of REST client libraries, like spark-restclient which is of course developed for the Spark. Another one is arduino-restclient but again both are built on the EthernetClient class.

After a bit of investigation I decided to use arduino-restclient but modify it to work with my GSMGPRS_Shield library. My fork is available here. My modified version uses the F() macro to put almost all strings into PROGMEM to save ram and cleaned up some other parts as well.

Next I needed MD5, SHA-1 and Base64 encoding since those are used in a request that is going to be received by API_Auth that we used on the rails side. MD5 support is provided by ArduinoMD5. Adafruit has created a stripped down SHA-1 library that I use. For Base64 encoding I used arduino-base64 but created a fork of it since it stored it’s whole Base64 alphabet in RAM instead of PROGMEM.

Then finally it was more or less just to set all this together and create the client. I have put the Arduino sketch on Github, ArduinoAuthenticatedClient.

A quick walkthrough of the code:
Change the secret key to the one generated by your rails application and make sure you set the ID in authHeaderStr to the correct id. In my example the id is 3. The numbers after the id and the : is where the authentication string will be copied.

    const char PROGMEM secretKey[] = "wJ+LuCJKuFOcEdV0rdbp0BtkLdLm/EvH31KwiILc/xC35zgDd+KMBTuvmpH9uhNtOvfTr8rl7j6CHVSM8BB7XA==";
    char *authHeaderStr = "Authorization: APIAuth 3:123456789012345678901234567=";

In general the code is a quite straight forward HTTP/REST client. The interesting part is the getHMACSignature_P function that concatenates the four different strings that are used to create the signature. But first we create the MD5 hash of the requests body and Base64 encode that:

    unsigned char* hash=MD5::make_hash(body);  
    base64_encode(b64, (char *)hash, 16);
    strncpy(&contentMD5Str[CONTENT_MD5_STR_CONTENT_START], b64, 22);
    free(hash);
    rest.setHeader(contentMD5Str);

Then we use that as one of the four strings to create the HMAC signature, which we also Base64 encode before setting the authentication header:

   base64_encode(b64,
      (char *)getHMACSignature_P((uint8_t *)secretKey, sizeof(secretKey)-1,
        &contentTypeHeaderStr[CONTENT_TYPE_STR_CONTENT_START],
        &contentMD5Str[CONTENT_MD5_STR_CONTENT_START],
        resourcePath,
        &dateStr[DATE_STR_CONTENT_START]),
      20);

    strncpy(&authHeaderStr[AUTH_HEADER_STR_CONTENT_START], b64, 27);
    rest.setHeader(authHeaderStr);

Two comments:

  1. I use my web server here at YellowOrb as host because I needed some public machine. I setup up an SSH tunnel from that to my local machine which runs the Rails application.
  2. The time stamp of the request is important since the receiving Rails application will not accept the request if it is to old. Thus, change the char *dateStr ="Date: Thu, 13 Nov 2014 14:18:11 GMT"; to something appropriate.