Categories
PHP

Pad and Trim Input Arrays

PHP function to get an input array to have only, and all of the keys specified. This is useful if you have an array of user input with fields as keys, and you want to pad to ensure all keys are present, while stripping any not part of the template array:
[php]<?php
/**
* Fill and strip array according to $keys
* @param array $input
* @param array $keys
* @param mixed $fill
* @return array
*/
function array_purge_fill($input, $keys, $fill = ”) {
$keys = array_flip($keys);
$input = array_intersect_key($input, $keys); //strip extra keys from input

//Add empty values for missing keys
$diff = array_diff_key($keys, $input);
$diff = array_fill_keys(array_flip($diff), $fill);

return array_merge($input, $diff);
}[/php]

Example:

[php]<?php $input = array( ‘name’=>’Mike’, ‘phone’=>’12345’, ‘extra_value’ => true );
$keys = array(‘name’, ‘phone’, ’email’);

$newInput = array_purge_fill($input, $keys);
//has name, phone, email keys. Email will be empty, ‘extra_value’ will be removed[/php]

Categories
WordPress

WordPress Menus with URLs That Don’t Break

WordPress has a handy Menus feature in the Appearance area of the admin. You can link to Pages and Post Categories and these will migrate fine as you move your site from a development to production environments and the site URL changes.

Sometimes though you may need to refer to internal URLs not supported by Menus natively  using the Custom URL feature. The problem is that specifying the absolute URL here will break when the site is deployed.

A simple solution is to add a filter and use a placeholder value in Custom URLs added to a menu.

wordpress-menu-custom-urls

Then add a filter in your themes functions.php file, or as a must-use plugin as a more robust solution:

<?php 
/**
* Replace (site_url) placeholder in navigation menus
* Helps keep menus portable between dev/staging/production environments
*/
add_filter(
	'wp_nav_menu', 
	function($menu) {
		$menu = str_replace('(site_url)', home_url(), $menu);
		return preg_replace('~https?\:\/\/(https?\:\/\/)~', '$1', $menu);
	},
20
);

Note: this code uses an Anonymous function which requires PHP5.3+.
For older versions define this as a regular function and pass in its name as a string to add_filter()