Get list of all registered scripts and styles in WP

Another one for the future references.

global $enqueued_scripts;
global $enqueued_styles;

add_action( 'wp_print_scripts', 'cyb_list_scripts' );
function cyb_list_scripts() {
    global $wp_scripts;
    global $enqueued_scripts;
    $enqueued_scripts = array();
    foreach( $wp_scripts->queue as $handle ) {
        $enqueued_scripts[] = $wp_scripts->registered[$handle]->src;
    }
}

add_action( 'wp_print_styles', 'cyb_list_styles' );
function cyb_list_styles() {
    global $wp_styles;
    global $enqueued_styles;
    $enqueued_styles = array();
    foreach( $wp_styles->queue as $handle ) {
        $enqueued_styles[] = $wp_styles->registered[$handle]->src;
    }
}

Print somewhere:

    global $enqueued_scripts;
    var_dump( $enqueued_scripts );
    global $enqueued_styles;
    var_dump( $enqueued_styles );

Thanks to @cybmeta at stack overflow.

Convert POST/GET queries to object in JS

A handy JS string prototype function for converting POST/GET queries to objects.

String.prototype.toURLobject = function() 
{
	var query = decodeURIComponent(this);
	var parts = query.split("&");
	var obj = {};
	for(var i = 0; i < parts.length; i++)
	{
		var pair = parts[i].split("=");
		var index = pair[0].indexOf("[]");
		if (index != -1)
		{
			var name = pair[0].substr(0, index);
			if (!obj.hasOwnProperty(name))
			{
				obj[name] = [];
				obj[name].push(pair[1]);
			}
			else
				obj[name].push(pair[1]);
		}
		else
			obj[pair[0]] = pair[1];
	}

	return obj;
}

App development with Cordova – how to

This is an ongoing post, meaning it will most likely change in the future.

This isn’t exactly a tutorial on how to develop mobile app with Cordova, but more of a list of checklists, hints and how-tos. Everytime I come back to the Cordova and app development I stumble upon outdated or scarce documentation on how to do things, so I decided to put all the knowledge I found in this post.

Development and deployment

I was working on an app about a year ago and then when I returned after all that time to work on a new app, I found out that a lot has changed since the last time I messed with cordova and phonegap. Official android documentation suggest developers should use their Android Studio, while I like to keep my options open – meaning I’d like to use more or less the same tools on Win and Mac environments, so that’s using the CLI (command line interface) way of working on apps, because it’s easier to jump between the two OSes – CLI commands are the more or less the same on every device. I COULD use Phonegap which promises a “code once deploy all” idea, but the execution leaves a lot to be desired.

So I thought to myself “well, I’ll use Eclipse on Win, because it builds app and directly deploy it to the device” and went with it, until I’ve hit the first possible block – installing cordova plugin and using it. That’s when I found out that Eclipse doesn’t really BUILD the .apk when I execute the Run command in IDE, it just… runs the app? I’m not really sure what it does, but it didn’t copy the config.xml settings, it didn’t compile installed plugins correctly (see the next two sections about www and config files) and when I ran the application nothing really worked – I was getting ReferenceError: Camera Is Not Defined error, while envoking the take picture function of cordova, which made me believe something went wrong while installing the camera plugin. So I totally switched to CLI building and plugin/camera actually worked!

So my workflow went something like this:

  1. CLI command: cordova create myApp
  2. CLI command: cordova platform add android
  3. CLI command: cordova plugin add org.apache.cordova.camera
  4. modified config.xml (in myApp root directory) and AndroidManifest.xml – see below
  5. plug the phone to the computer, accept RSA fingeprint
  6. CLI command: cordova run android

And when I envoked the take picture function (see below) I actually got the camera working without any issues, so I’m sticking to CLI environment now.

After installing the plugin I added the code below to config.xml (in root directory of my app)

    
<feature name="Camera">
  <param name="android-package" value="org.apache.cordova.CameraLauncher"/>
</feature>

Added this to AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

I used the getPicture function as described here.

NOTE: Don’t forget to include cordova.js in your application HTML – make sure it’s relative to your app run location (without “/”).

What’s up with multiple WWW folders in Cordova app?

User MBilau said this over at stack overflow:

You should be editing the files in the /www/ file. When the CLI tools run prepare, which happens a lot, these files are copied into the appropriate platform’s /www/ file. (This is because each platform can have it’s web assets in a different location.) So do all of your work in the main /www/ folder – this is the one you should be putting into version control.

For more information try reading the documentation guide about The config.xml file which describes some of this: http://cordova.apache.org/docs/en/3.1.0/config_ref_index.md.html#The%20config.xml%20File

I’ve also written up a pretty long answer in another question that is pretty similar: Should a phonegap plugin be declared in the config.xml file?

Too bad I found this out when I already ran cordova plugin add command and overwrote about 20 hours of my work (yes, I know, backups and all that) in android/assets/www folder, that gets overwritten any time you run a cordova command.

Whats up with multiple config.xml files?

There is a pretty good explanation here, again by MBilau, some excerpts:

/myApp/
/www/
This is where your “cross-platform’ files go. The build tools copy these files over to the correct asset folder for each platform, like /assets/www/ for android or just /www/ for iOs. This is where you should be doing most/all of your work and is what should probably be version controlled.

/platforms/
/android/
/ios/
These will only appear after `cordova platform add`. You should generally not touch these file as they are recreated quite often, although changes will persist.

/plugins/
/android/
These will only appear after `cordova plugin add`. They pretty much just contain the native and web plugin code for all platforms that a plugin supports.

/ios/
/merges/
This is where you can place platform-specific code that you write that will get merged in with your cross platform source, see the “customize each platform” section of: http://cordova.apache.org/docs/en/3.0.0/guide_cli_index.md.html

www folder in your app root location is your go-to location when working on a app:

You should make all of your changes to files in /www/, which is the “cross platform” source code. Whatever is in this folder will generally get copied and propagated to the platform level www folder when you use the command line tools (whether its /assets/www for Android or just /www/ for iOS). This way, you only need a single source folder for your app – this is the folder that you should have under version control.

 Useful Cordova CLI commands

  • cordova run --list displays all devices you can run your app on (plugged devices and emulators)
  • cordova run --target=XXXXX runs on one of the devices, listed with –list command
  • cordova emulate android runs your application on emulator
  • android list avd displays all installed android emulators
  • emulator.exe -avd emulator_name starts the specified emulator_name
  • android avd starts android virtual device manager
  • adb start-server starts adb, so you can run apps on plugged mobile devices

Genymotion emulator, VirtualBox and Unable to load R3 module error

I’ve been using Genymotion emulator because it seriously kicks ass (lightning fast compared to default Android emulator) and encountered a strange VirtualBox error when starting Genymotion devices (or any for that matter) – Unable to load R3 module. It seems VirtualBox cant run virtual devices if you have altered windows installation that runs VB. I’ve actually altered some of my win .dll files when installing various windows theme patchers, so that could be the problem – the other computer I use don’t have any altered .dll files and VB runs without any issue. VB version 4.3.12 and older should work okay.

org.apache.cordova.camera

Android version 4.4 broke some stuff regarding getting the images from gallery, where you’d get an invalid image location that could’t be resolved when used in <img> src attribute (for example).

Here’s a fix for that issue:

if (imageURI.substring(0,21)=="content://com.android") {
	photo_split = imageURI.split("%3A");
	imageURI = "content://media/external/images/media/"+photo_split[1];
}

With this snippet you get the actual file location in the system.

Signing your APK

To sign your .apk file use Cywgin and following two commands:

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

Enter your (developer) information and then follow it up with the jarsigner:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name

Zipalign your APK

To zipalign your apk file use the following command (where unaligned_app.apk stands for your current built file and aligned_app.apk for the new aligned apk file. You can also use -f parameter to overwrite the original filename):

zipalign -v 4 unaligned_app.apk aligned_app.apk

Make sure you have the zipalign in system PATH variables (normally in android-sdk/build-tools/sdk_version/).

Published Simple shortcode buttons

I’ve completed my first official WP plugin, available here: https://wordpress.org/plugins/simple-shortcode-buttons/
You can read more about it here: http://davidp.net/simple-shortcode-buttons/.

It’s basically a WordPress editor (TinyMCE) button generator, that makes inserting shortcodes into text painless. I’ve been using it on some of my projects lately and it has proven to be really useful, so I took some time and made it official, so everyone can use it now.

Sketchr, a wireframing tool

I’ve been thinking about making an Infinite Dreams sequel (not direct sequel but more of a spiritual successor) and came across another idea, tied in directly with ID2 development  – I’d need a level editor to create levels. Original ID was programmed in Flash and I’ve also developed a small level editor for that game, also in flash, but ID2 will be HTML5 so I decided to make a level editor in HTML5.

Enter:

sketchr2

*I’ve miss-typed the ‘sketcher’ but kinda liked the ‘sketchr’ idea, so it’s Sketchr now.

Screenshot of the current version:

Click to enlarge

Sketchr is basically a wireframing tool that exports final product as JSON object. Users can place two types of shape objects (seen as Presets in screenshot) on canvas and add additional presets, defining ID, color and shape type of each one. Users  can also change canvas size (in pixels and percents), change grid size and turn on or off Snap to grid option, forcing shape resizing or movement to snap to grid or being free to move and resize if Snap to grid is turned off.

There will be a version control in next iterations of Sketchr, where every sketch edit gets an unique ID and links to previous version and newer if availible. Users will be able to open older version of sketches and create completely new branches of edits. Basic saving already works now, it’s just that every new sketch gets an ID that stays the same through all the edits of sketch.

Next iterations of Sketchr will also include an option to set a background image to sketch, so object placement becomes easier

If you’re interesting in joing the Sketchr beta, submit the form below:

Beta closed.

in_associative_array PHP function

Pretty straightforward function for determining if associative array already contains value in specified array column.

function in_associative_array($needle, $haystack, $column, $nivo = 1)
{
	/*
		$haystack = array(
			[0] = array(
				"column1" => "value1",
				"column2" => "value2"
			),
			[1] = array(
				"column1" => "value1",
				"column2" => "value2"
			)	
		)	
	*/
	
	if ($nivo == 1)
	foreach($haystack as $item)
	{
		if (isset($item[ $column ]) && $item[ $column ] == $needle)
			return true;
	}
	
	/*
		$haystack = array(
			"column1" => "value1",
			"column2" => "value2",
			"column3" => "value1",
		)	
	*/	
	if ($nivo == 0)
	foreach($haystack as $key => $item)
	{
		if ($key == $column && $item == $needle)
			return true;
	}	
		
	
	return false;
}

Phaser Sprite.destroy()

I’ve been messing around with Phaser lately and it turned out to be an amazing game development library. I was always keen on using my on tech on everything I worked as it seemed easier to manage (“i know where everything is and what everything does” argument and similar nonsense) but Phaser really stands out for it’s simplicity, and what it offers. For a price of 0!

Anyway, while I mostly embraced Phaser’s concepts I cannot agree with the recycling sprites theory, telling me to kill() sprites and reuse them. So I should create multiple objects, add them to groups and then call kill() method on them when I don’t need them anymore and reuse them later (reset() method in conjunction with getFirstDead() method). While this sounds pretty straightforward and somewhat logic I disagree with it.

I am using multiple objects of same “class” but with various types (let’s say red, blue and yellow cars) and if I use kill() method on them I still need to cycle through all dead cars and get first red car if I wanna reuse red car. This seems kind of overkill – why would I wanna do that if I can simply create new red car and be done with it, not worrying about if I have any red car to in a pool of dead red cars to reuse.

So I simply went and used destroy() on the cars I wanted to destroy (let’s say in a game.physics.arcade.overlap() callbacks) and got various undefined errors, because of the way loops through objects in Phaser happen. When I want to destroy objects from various arrays and list I go from the last to first index and remove stuff designated to be destroyed, not fearing I’ll run out of bounds (removing objects from arrays while going from 0 index to size – 1 will quickly produce out of bounds errors), but Phaser loops (for overlaps, rendering, updates, etc.) work from index 0 to last, which is logical, the way they are meant to. So if I remove something from object arrays on the run stuff like out of bounds indexes and similar occur relatively quickly.

So in order to DESTROY something from object groups I called the kill() method on regular update loops and then called the cleanUp() method at the end of each update loop, like this:

	
function cleanUp()
{
	var aCleanup = [];
	cars.forEachDead(function(item){
		aCleanup.push(item);
	});
	
	var i = aCleanup.length - 1;
	while(i > -1)
	{
		var getitem = aCleanup[i];
		getitem.destroy();
		i--;
	}
}

Here I iterate through all the cars I’ve set as dead in regular update functions, save them into cleanup array and then go through it and call destroy() method on every car set to be removed, without getting any errors.

Prettier, customizable print_r function

When developing random stuff with PHP I tend to rely heavily on various variable printing so I made a small function that I use to print variables the way I want to.

<?php
	function print_pre($text, $ret = false, $inStyles = array()) {
	$aStyles = array("-webkit-border-radius" => "3px", 
		"-moz-border-radius" => "3px", 
		"border-radius" => "3px",
		"background-color" => "#F0F0F0", 
		"padding" => "3px",
		"border" => "1px solid #A8A8A8");
	
	if (is_array($inStyles))
	{
		foreach($inStyles as $key => $value)
			$aStyles[$key] = $value;
	}
		
	$applyStyles = array();	
	foreach($aStyles as $key => $value)
		array_push($applyStyles, $key . ": " . $value . ";");

	$return = "<pre style='".implode(" ", $applyStyles)."'>" . print_r($text, true) . "</pre>";
	if($ret) return $return;
	print($return);
}
?>

It’s pretty straightforward – it takes 3 arguments, 1st being variable we want to display, 2nd if we want the return string returned or directly printed on page and finally CSS styling pairs as associative array.

Few examples of use

Default print

print_pre("Test string", true);

Result:

Test string

Custom style

print_pre("Test string", false, array("background-color" => "#000", "color" => "#fff"));

Result:

Test string

Printing an object

$array = array("name" => "david", "age" => (date("Y") - 1987), "gender" => "male");
$object = json_decode(json_encode($array), FALSE);
print_pre($object, false, array("background-color" => "blue", "color" => "#fff"));

Result:

stdClass Object
(
    [name] => david
    [age] => 30
    [gender] => male
)

Getting the return print string of regular array and echoing it as a variable

$array = array("name" => "david", "age" => (date("Y") - 1987), "gender" => "male");
$value = print_pre($array, true, array("background-color" => "yellow", "color" => "gray"));
echo $value;

Result:

Array
(
    [name] => david
    [age] => 30
    [gender] => male
)

PHPExcel lock cells

I’ve been using wonderful PHPExcel library for exporting my mysql data to excel via PHP and encountered a little setback trying to lock particular cells to prevent my client from editing values I’d need to process when uploading the file back to the system so I tried the most straightforward method I found in the official documentation but nothing seemed to work until I came across this solution:

$obj_Sheet->getProtection()->setPassword('pass_to_remove_protection');
$obj_Sheet->getProtection()->setSheet(true);
$obj_Sheet->getStyle('B2:J5')->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);

First I set the password to remove protection (‘pass_to_remove_protection’) that anyone can use to remove protection (as long as they know the password), then I turn on sheet protection and finally set all cells in a range from B2 to J5 to unprotected. This basically locked EVERYTHING on selected sheet and unlocked the fields I specified as unlocked.