Skip to content

Instantly share code, notes, and snippets.

@lgedeon
Last active December 15, 2017 20:54
Show Gist options
  • Save lgedeon/217d91df3bde105985984010744a0de6 to your computer and use it in GitHub Desktop.
Save lgedeon/217d91df3bde105985984010744a0de6 to your computer and use it in GitHub Desktop.
Several snippets that could be handy on many projects.
<?php
// todo store as an option and address all concerns at https://core.trac.wordpress.org/ticket/14671
function helper_count_required_args ( $function ) {
static $arg_counts = array();
$key = is_scalar( $function ) ? $function : serialize( $function );
if ( isset( $arg_counts[$key] ) ) {
return $arg_counts[$key];
}
if ( is_string( $function ) && function_exists( $function ) ) {
$r = new ReflectionFunction( $function );
} elseif ( isset( $function[0], $function[1] ) && method_exists( $function[0], $function[1] ) ) {
$r = new ReflectionMethod( $function[0], $function[1] );
} else {
return $arg_counts[$key] = false;
}
return $arg_counts[$key] = $r->getNumberOfRequiredParameters();
}
function helper_die_on_nth( $n ) {
static $i = 1;
if ( $i == $n ) {
echo "n = $n"; die();
}
$i++;
}
// Helper: Convert array to html list. So ugly.... If I can make it -pretty- well less ugly, I might share.
function array_to_html_list( $array, $classes = '', $outer_key = '' ) {
$html = '';
// accept array of classes for each level or a single class for all. @todo maybe do striping classes
$class = is_array( $classes ) ? array_shift( $classes ) : $classes;
if ( is_object( $array ) ) {
$array = get_object_vars( $array );
}
if ( is_array( $array ) ) {
foreach ( $array as $key => $node ) {
$html .= array_to_html_list( $node, $classes, $key );
}
$html = "<ul class=\"$class\">$html</ul>";
if ( '' !== $outer_key ) {
$html = "<li class\"$class\">[$outer_key] $html</li>";
}
return $html;
}
return "<li class=\"$class\">[$outer_key] $array</li>";
}
/**
* Call a function on each combination of the values of multiple arrays.
*
* First parameter should by a callable function name or an array with the
* following key value pairs:
*
* 'callback' string A callable function or method name.
* 'break_early' boolean True if function can quit early.
* 'break_on' mixed Value that if returned by callback will short-circuit iteration.
*
* The second and following parameters should be arrays of values to be passed into the
* callback function.
*
* Example:
* ione_do_with_arrays( 'printf', '%s %s, ', array('red','green','yellow'),array('apples','peppers'));
*
* Prints: red apples, red peppers, green apples, green peppers, yellow apples, yellow peppers,
*
* @return mixed An nested array of values returned from callback or the break_on value.
*/
function ione_do_with_arrays() {
// Function accepts multiple arrays to iterate through.
$arrays = func_get_args();
$args = array();
/**
* The first argument is either the function we call on each combination of values
* requested or an array of additional arguments.
*/
$first_arg = array_shift( $arrays );
if ( is_callable( $first_arg ) ) {
$args['callback'] = $first_arg;
} elseif ( isset( $first_arg['callback'] ) && is_callable( $args['callback'] ) ) {
$args = $first_arg;
} else {
return false;
}
// Set defaults for breaking early.
$args = array_merge( array(
'break_early' => false,
'break_on' => false,
), $args );
// Values are set up, now start doing the real work.
return _private_ione_do_with_arrays( $args, $arrays );
}
/**
* Not intended to be called directly. Parameters are set up inside ione_do_with_arrays
* so that this function can focus on recursion.
*
*/
function _private_ione_do_with_arrays( $args, $arrays ) {
$results = array();
foreach ( $arrays as $position => $array ) {
if ( is_array( $array ) ) {
// Replace the first array we find with each of its values and recurse.
foreach ( $array as $key => $value ) {
$arrays[ $position ] = $value;
// Call this function again to loop through the next array.
$results[ $key ] = _private_ione_do_with_arrays( $args, $arrays );
// If we allow breaking early and have found break-on value, return.
if ( $args['break_early'] && $args['break_on'] === $results[ $key ] ) {
return $results[ $key ];
}
}
return $results;
}
}
/**
* If we haven't returned yet, none of the values in $arrays are really arrays and
* we can finally do what we were created to do.
*/
return call_user_func_array( $args['callback'], $arrays );
}
/**
* Test if one string is contained inside another.
*
* This test happens so often it should be part of core.
*
* @param string $needle Search for this string.
* @param string $haystack Search within this string.
*
* @return bool
*/
function ione_wp_contains( $needle, $haystack ) {
if ( is_string( $needle ) && is_string( $haystack ) ) {
return ( false !== stripos( $haystack, $needle ) );
}
return false;
}
/**
* Make sure value is of right type and, if applicable, class.
*
* If variable does not match type and class of default, return default instead.
*
* Usage examples:
* $in_string = helper_match_type( strpos( $haystack, $needle ), true ); // true if $needle is in haystack.
* $post_meta = helper_match_type( get_post_meta( $post_id, $meta_key, true ), array() ); // always returns an array.
*
* @param mixed $test Test value to be checked.
* @param mixed $default Default to use if type of $test does not match.
*
* @return mixed array Will return a variable of the same type as $default.
*/
function helper_match_type( $test, $default ) {
if ( is_object( $default ) ) {
if ( get_class( $test ) === get_class( $default ) ) {
return $test;
}
} elseif ( is_array( $default ) ) {
if ( ! is_array( $test ) ) {
return $default;
}
foreach ( $default as $key => $_default ) {
if ( isset( $test[ $key ] ) ) {
$test[ $key ] = helper_match_type( $test[ $key ], $_default );
} else {
$test[ $key ] = $default;
}
}
return $test;
} elseif ( gettype( $test ) === gettype( $default ) ) {
return $test;
}
return $default;
}
function helper_wrap_each( $array, $before, $after ) {
foreach ( $array as $key => $value ) {
$array[ $key ] = $before . $value . $after;
}
return $array;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment