cordova-plugin-stripe 1.5.3 manifest merger will fail with update to com.support.android to 26.0.0

If you’ve recently upgraded your Android SDK and end up getting these errors in your Ionic/Cordova projects, you may need to install the cordova-android-support-gradle-release plugin (via cordova plugin add):

Manifest merger failed : Attribute meta-data#android.support.VERSION@value value=(25.3.1) from [com.android.support:appcompat-v7:25.3.1] AndroidManifest.xml:27:9-31
is also present at [com.android.support:support-v4:26.0.0-alpha1] AndroidManifest.xml:27:9-38 value=(26.0.0-alpha1).
Suggestion: add 'tools:replace="android:value"' to  element at AndroidManifest.xml:25:5-27:34 to override.

More info on cordova-android-support-gradle-release plugin: https://github.com/dpa99c/cordova-android-support-gradle-release

In this particular case with the Stripe plugin, it specifies 25.3.1 com.android.support in its build.gradle. The above plugin will handle the conflicting release versions as pointed out by the build error message.

*     *     *

Visit GameSlush for a quick break from work.

Ionic 3: ionic start -n … if you use spaces in the project name, npm dependencies will not install

Just a warning for those migrating to or starting to develop with Ionic 3 framework, if you create a new project with illegal characters in a package.json “name”, npm dependencies will not install.

You might encounter an error right away when performing “ionic serve” or “ionic cordova run” like:

Error: Cannot find module '@ionic/app-scripts'

The error/warning is hidden in Ionic 3 CLI with the spinner unless you specified “–verbose” with “ionic start”.

You will have to fix the name in package.json in the project folder (e.g. replace spaces with dashes) and re-“npm install”.

This didn’t happen in prior versions of Ionic as it kept the package.json “name” to something like ionic-hello-world.

*    *    *

Take a break from work and enjoy a game at GameSlush.com.

Apache to Nginx transition on WordPress – don’t forget the permalinks

After having transitioned from Apache to Nginx as the web service for this blog, I noticed an immediate drop-off from search engine traffic to links outside of the index page. Just attributing it to blind bad luck for a few days, I later realized that permalinks were broken because I didn’t correctly translate the rewrite rules from the Apache configuration to Nginx.

Apache config for WordPress permalinks:

  Options FollowSymLinks
  Options SymLinksIfOwnerMatch
  RewriteEngine On
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]

Correct equivalent Nginx config:

  location / {
    index index.php;
    try_files $uri $uri/ /index.php?$args;
  }

For a minute I thought search engines were blacklisting me for unpopular opinions on this blog.  Don’t attribute to malice what can be attributed to (my own) stupidity.

*     *     *

If you’re looking for a cheap alternative to home security that costs literally one-twentieth of what most security companies charge, try out Simple Home Monitor for free.

Socket.io 1.4 to 1.7.2 temporary fix for #2405: Server socket id doesn’t match client’s socket id

If you’re affected by the major change outlined by this reported issue here’s a temporary fix you may want to try to get things working again without having to change all of your own code:

find . -name "socket.io.js" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;
find . -name "socket.io.js" -exec sed -i -e 's/this\.nsps\[nsp\]\.id \= this\.engine\.id;/this\.nsps\[nsp\]\.id \= nsp \+ "\#" \+ this\.engine\.id;/' {} \;
find . -name "socket.io.js.map" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;
find . -name "socket.io.js.map" -exec sed -i -e 's/this\.nsps\[nsp\]\.id \= this\.engine\.id;/this\.nsps\[nsp\]\.id \= nsp \+ "\#" \+ this\.engine\.id;/' {} \;
find . -name "socket.io.slim.js.map" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;
find . -name "socket.io.slim.js.map" -exec sed -i -e 's/this\.nsps\[nsp\]\.id \= this\.engine\.id;/this\.nsps\[nsp\]\.id \= nsp \+ "\#" \+ this\.engine\.id;/' {} \;
find . -name "socket.io.min.js" -exec sed -i -e 's/n\.id\=o\.engine\.id/n\.id\=n\.nsp\+"\#"\+o\.engine\.id/' {} \;
find . -name "socket.io.min.js" -exec sed -i -e 's/this\.nsps\[t\]\.id\=this\.engine\.id/this\.nsps\[t\]\.id\=t\+"\#"\+this\.engine\.id/' {} \;
find . -name "socket.io.slim.min.js" -exec sed -i -e 's/n\.id\=o\.engine\.id/n\.id\=n\.nsp\+"\#"\+o\.engine\.id/' {} \;
find . -name "socket.io.slim.min.js" -exec sed -i -e 's/this\.nsps\[t\]\.id\=this\.engine\.id/this\.nsps\[t\]\.id\=t\+"\#"\+this\.engine\.id/' {} \;
find . -name "manager.js" -exec sed -i -e 's/socket\.id \= self\.engine\.id;/socket\.id \= socket\.nsp \+ "\#" \+ self\.engine\.id;/' {} \;

Running this as a bash script in the root folder of your projects that depend on socket.io-client will replace all instances in the socket.io-client code to use the naming convention prior to v1.4 (and thus maintain consistency across client and server): the namespace followed by # and then the engine id.

If you run the bash script and want to undo the above changes, you’ll have to reverse the sed regular expressions and rerun the script.

*     *     *

You may enjoy playing a game at GameSlush.com because it also uses socket.io.

Socket.io 1.3.2: client events received in browsers prior to all JS being loaded

FireFox experiences a race condition between the loading of code in scripts and receiving socket.io events if a socket establishes a connection concurrently with the loading of scripts.  If a socket.io client in FireFox connects to the socket.io server in a script, but there are socket event handlers yet to be loaded (or general JS yet to be loaded), events from the socket.io server may be received and unhandled properly on the client side due to “missing” code.  IE and Chrome tend to finish loading all JavaScript prior to handling the first socket.io event from the server, so the issue is not evident outside of FireFox.

Not documented on socket.io’s page or its GitHub page, socket.io has an “autoConnect” option on the client side initialization that helps solve this problem.  Here’s an effective connection paradigm to follow when using socket.io clients on browsers:

First, create the io Manager and initialize the socket with autoConnect = false, that way we don’t connect to the socket.io server until we set up all of our event handlers.

var socket = io('http://server_host', { autoConnect: false });</pre>
Second, set up our event handlers.
<pre class="js">socket.on('foo', function() {
  console.log('bar');
}

Finally, after all of our JS, images, frames, etc. are loaded and we are completely ready to handle all incoming socket events, follow through with connecting to the server.

window.onload = function() {
  socket.connect();
}

Socket.io 1.2.0: Handling global authorization events when client connects to a custom namespace

The documentation on socket.io’s page and its GitHub page are inconsistent (namely due to the latter being out of date, but contains information not covered by the former). A problem arises when using global authorization middleware on the server, having a client trying to connect to a custom namespace, and having the server deny access to the connecting client by passing an error to next() in the middleware.

Sample server authorization middleware code that denies access globally to all incoming connections:

io.use(function(socket, next) {
  next(new Error('not authorized'));
});

Sample client connecting code with error handler:

var socket = require('socket.io-client')('http://localhost/customnamespace');

socket.on('error', function(err) {
  console.log(err); // 'not authorized' not output, 
                    // since this is a '/customnamespace' event handler
});

The client needs to handle both the events coming from the global namespace and the custom namespace, otherwise the socket connection seemingly hangs on the client side as it receives no feedback from the custom namespace event handlers. None of the socket.io documentation seems to cover this shortcoming.

You can simply get any namespace socket from the socket Manager by calling Manager.socket([namespace]). To get the socket Manager from any socket, simply reference the ‘io’ property of the socket object. From there we would use ‘/’ to get the global namespace socket.

Here’s the proposed workaround that continues the sample client code above:

var socket = require('socket.io-client')('http://localhost/customnamespace');
var manager = socket.io;
var socketGlobalNs = manager.socket('/');

socket.on('error', function(err) {
  console.log(err); // 'not authorized' not output, 
});

socketGlobalNs.on('error', function(err) {
  console.log(err); // This will output 'not authorized'
});

PHP’s setcookie() with $expire set but not $domain will blow away the cookie in Internet Explorer (IE)

Spent a whole day figuring out this one.  Yet another reason why Internet Explorer is the bane of web development. Found a plethora of suggested solutions on the net, and even an old bug logged for PHP in 2001, but the reason behind the bug is still a mystery.

As the title states, if you use setcookie() with $expire set and $domain not set, then IE may simply let the cookie expire, ignoring the value you put in $expire. Furthermore, IE may request the page a second time, as if it didn’t understand the cookie set directive and decided to start all over. I couldn’t reproduce this in Firefox, Chrome, Safari, or any other browser, and oddly enough, I could not reproduce this using inPrivate browsing in IE. In other words, all of the examples below work in other browsers as you would expect them to. IE is the lone failure on the setcookie example #2 below.

PHP’s setcookie() syntax:

bool setcookie ( string $name [, string $value 
  [, int $expire = 0 [, string $path [, string $domain 
  [, bool $secure = false [, bool $httponly = false ]]]]]] )

1. Cookie successfully stored in IE, but expires at the end of the browser session:

setcookie(session_name(), session_id(), 0, '/');

2. The following blows away the cookie in IE:

setcookie(session_name(), session_id(), time() + 60 * 60 * 24, '/');

3. To successfully store the cookie in IE and have an expiry date, we must supply the $domain to setcookie():

setcookie(session_name(), session_id(), 
  time() + 60 * 60 * 24, '/', '.chrislo.ca');

Some solutions on the net suggested that the time needed to be bigger in example #2 due to difference in GMT-ness of the time provided, but no matter how large the expiry time is set, the cookie still gets blown away in IE. Appending the domain magically fixed it.

Using the background function of Processing.js with images

“Background image must be the same dimensions as the canvas.”

In case you are looking for a workaround for Processing.js background function that forces you to scale your background image, try this trick to make your browser do the scaling for you.

Set the CSS background for the canvas element to your image, and use “cover” or “contain” to stretch your background to fit the canvas:

<canvas style="background: url(<!-- your background image path -->); 
  background-size: cover"></canvas>

In your JS, you can set Processing’s background opacity to zero alpha (transparent), or simply use clearRect without the help from Processing:

background(0, 0);
// OR
document.getElementById('canvas').getContext('2d')
  .clearRect(/* x */, /* y */, /* w */, /* h */);

Of course you can dynamically set the CSS of the canvas in your script whenever you feel like changing your background image.