In the below function, when I call
mmmr(array(1,2,3,3,4,3), 'mode', 'ceil'); // null
it returns null. Works fine if I don't set the third ($round) argument.
mmmr(array(1,2,3,3,4,3), 'mode'); // 3
What am I missing? Coffee?
function mmmr( array $array, $output = 'mean', $round = false ) {
switch( $output ) {
case 'mode':
if( $round == "ceil" ) {
foreach( $array as $key => $value ) {
$array[$key] = ceil( $value );
}
} elseif( $round == "floor" ) {
foreach( $array as $key => $value ) {
$array[$key] = floor( $value );
}
} elseif( $round == "normal" ) {
foreach( $array as $key => $value ) {
$array[$key] = round( $value );
}
}
$v = array_count_values( $array );
arsort( $v );
foreach( $v as $k => $v ) {
$total = $k;
break;
}
break;
}
return $total;
}
array_count_values() can only count STRING and INTEGER values. ceil(), floor(), and round() return a float. Casting it to an int fixes your problem:
<?php
function mmmr( array $array, $output = 'mean', $round = false ) {
switch( $output ) {
case 'mode':
if( $round == "ceil" ) {
foreach( $array as $key => $value ) {
$array[$key] = (int) ceil( $value ); // (int)
}
} elseif( $round == "floor" ) {
foreach( $array as $key => $value ) {
$array[$key] = (int) floor( $value ); // (int)
}
} elseif( $round == "normal" ) {
foreach( $array as $key => $value ) {
$array[$key] = (int) round( $value ); // (int)
}
}
$v = array_count_values( $array );
arsort( $v );
foreach( $v as $k => $v ) {
$total = $k;
break;
}
break;
}
return $total;
}
echo mmmr(array(1,2,3,3,4,3), 'mode', 'ceil'); // Returns 3
Related
i have a custome post type known as "Motor_supply"
i want to show "Motor_supply" titles by a category as a "selectbox" in metabox on shop_order
i want to know how can i create a loop and put published "Motor_supply" posts titles in it
i have this code
class select_motor {
private $config = '{"title":"\u062a\u062e\u0635\u06cc\u0635 \u0645\u0648\u062a\u0648\u0631","prefix":"select_motor","domain":"select_motor","class_name":"select_motor","post-type":["post"],"context":"normal","priority":"default","cpt":"shop_order","fields":[{"type":"select","label":"select motor","options":"option-one : MOTOR_1\r\noption-one : MOTOR_2","id":"select_motorselect-motor"}]}';
public function __construct() {
$this->config = json_decode( $this->config, true );
$this->process_cpts();
add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] );
add_action( 'save_post', [ $this, 'save_post' ] );
}
public function process_cpts() {
if ( !empty( $this->config['cpt'] ) ) {
if ( empty( $this->config['post-type'] ) ) {
$this->config['post-type'] = [];
}
$parts = explode( ',', $this->config['cpt'] );
$parts = array_map( 'trim', $parts );
$this->config['post-type'] = array_merge( $this->config['post-type'], $parts );
}
}
private function select( $field ) {
printf(
'<select id="%s" name="%s">%s</select>',
$field['id'], $field['id'],
$this->select_options( $field )
);
}
private function select_options( $field ) {
$output = [];
$options = explode( "\r\n", $field['options'] );
$i = 0;
foreach ( $options as $option ) {
$pair = explode( ':', $option );
$pair = array_map( 'trim', $pair );
$output[] = sprintf(
'<option %s value="%s"> %s</option>',
$this->select_selected( $field, $pair[0] ),
$pair[0], $pair[1]
);
$i++;
}
return implode( '<br>', $output );
}
private function value( $field ) {
global $post;
if ( metadata_exists( 'post', $post->ID, $field['id'] ) ) {
$value = get_post_meta( $post->ID, $field['id'], true );
} else if ( isset( $field['default'] ) ) {
$value = $field['default'];
} else {
return '';
}
return str_replace( '\u0027', "'", $value );
}
}
new select_motor;
On the login page of the website, this warning is shown
Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'wp_sensitive_page_meta' not found or invalid function name in /home/DOMAINNAME/domains/DOMAINNAME.com/public_html/wp-includes/plugin.php on line 525
No users are able to login to the site. I am able to ssh to the site and view the file where the warning occurs. Here is the function in plugins.php where the error occurs
function do_action($tag, $arg = '') {
global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;
if ( ! isset($wp_actions[$tag]) )
$wp_actions[$tag] = 1;
else
++$wp_actions[$tag];
// Do 'all' actions first
if ( isset($wp_filter['all']) ) {
$wp_current_filter[] = $tag;
$all_args = func_get_args();
_wp_call_all_hook($all_args);
}
if ( !isset($wp_filter[$tag]) ) {
if ( isset($wp_filter['all']) )
array_pop($wp_current_filter);
return;
}
if ( !isset($wp_filter['all']) )
$wp_current_filter[] = $tag;
$args = array();
if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
$args[] =& $arg[0];
else
$args[] = $arg;
for ( $a = 2, $num = func_num_args(); $a < $num; $a++ )
$args[] = func_get_arg($a);
// Sort
if ( !isset( $merged_filters[ $tag ] ) ) {
ksort($wp_filter[$tag]);
$merged_filters[ $tag ] = true;
}
reset( $wp_filter[ $tag ] );
do {
foreach ( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) )
call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
} while ( next($wp_filter[$tag]) !== false );
array_pop($wp_current_filter);
}
I have expressions like this =>
({2606} OR {2549} OR {2543} OR ({2605} AND {2562})) AND ({2387} OR {2383} OR {1990} OR {2412} OR {2411} OR {2409} OR ({2408} AND {2593}))
I want output like this Array.
[
"AND" => [
"OR" => [ 2606, 2549, 2543, "AND" => [ 2605, 2562 ] ],
"OR" => [ 2387, 2383, 1990, 2412, 2411, 2409, "AND" => [ 2408, 2593 ] ]
]
]
Need a php script for this.
$rule = "({2606} OR {2549} OR {2543} OR ({2605} AND {2562})) AND ({2387} OR {2383} OR {1990} OR {2412} OR {2411} OR {2409} OR ({2408} AND {2593}))";
$previous_rule = '';
// Clean Curly Braces and Trim is there's a space.
$rule = trim( str_replace( array( "{", "}" ) , "", $rule ) );
echo "INPUT: " . $rule . "<br><br>";
foreach( range('a', 'z') as $letter ){
$substituted_part = "(". substitution( $rule ) . ")";
$$letter = $substituted_part;
$rule = str_replace( $substituted_part, $letter, $rule );
if( $previous_rule != $rule )
$previous_rule = $rule;
else
break;
}
echo "<PRE>";
print_r( replaceOriginal($rule) );
function replaceOriginal( $rule ){
if( preg_match("/[a-z]/i", $rule) ){
if( strpos( $rule, "AND" ) !== false )
$processed_rule = array( "AND" => explode(" AND ", $rule ) );
else if( strpos( $rule, "OR" ) !== false )
$processed_rule = array( "OR" => explode(" OR ", $rule ) );
foreach( $processed_rule as $operator => $values ){
$processed_rule[$operator] = process( $values );
}
return $processed_rule;
}
}
function process( $values ){
foreach( $values as $key => $value ){
if( !empty( $GLOBALS[$value] ) ){
$substituted_value = str_replace( array( "(", ")" ) , "", $GLOBALS[$value] );
$values[$key] = replaceOriginal( $substituted_value );;
}
}
return $values;
}
function substitution( $rule ){
// Get anything thats wrapped in parentheses.
if( preg_match_all('#\((([^()]+|(?R))*)\)#', $rule, $matches) ){
foreach( $matches[1] as $value ){
return substitution( $value );
}
}else{
return $rule;
}
}
Thanks for clicking on the question. I am trying to find and replace text within a string that contains serialize arrays. For example :
'fgm2wc_options', 'a:19:{s:15:"automatic_empty";N;s:3:"url";s:25:"http://example.com/store/";s:8:"hostname";s:9:"localhost";s:4:"port";s:4:"3306";s:8:"database";s:22:"apgadmin_store_magento";s:8:"username" ... }
I want to change http://example.com/ to smth else I can do it with str_replace but it will not change the string length indicator ( e.g s:25 ).
This is a function i am using:
function recursive_unserialize_replace( $old_url = '', $new_url = '', $data = '', $serialised = false ) {
$new_url = rtrim( $new_url, '/' );
$data = explode( ', ', $data );
try {
if ( is_string( $data ) && ( $unserialized = #unserialize( $data ) ) !== false ) {
$data = recursive_unserialize_replace( $old_url, $new_url, $unserialized, true );
} elseif ( is_array( $data ) ) {
$_tmp = array( );
foreach ( $data as $key => $value ) {
$_tmp[ $key ] = recursive_unserialize_replace( $old_url, $new_url, $value );
}
$data = $_tmp;
unset( $_tmp );
} else {
if ( is_string( $data ) ) {
$data = str_replace( $old_url, $new_url, $data );
}
}
if ( $serialised ) {
return serialize( $data );
}
} catch( Exception $error ) {
}
return $data;
}
Any ideas ?
For anyone interested this is the solution i came up with:
function unserialize_replace( $old_url = '', $new_url = '', $database_string = '' ) {
if ( substr( $old_url, -1 ) !== '/' ) {
$new_url = rtrim( $new_url, '/' );
}
$serialized_arrays = preg_match_all( "/a:\d+:.*\;\}+/", $database_string, $matches );
if( !empty( $serialized_arrays ) && is_array( $matches ) ) {
foreach ( $matches[ 0 ] as $match ) {
$unserialized = #unserialize( $match );
if ( $unserialized ) {
$buffer = str_replace( $old_url, $new_url, $unserialized );
$buffer = serialize( $buffer );
$database_string = str_replace( $match, $buffer, $database_string );
}
}
}
if ( is_string( $database_string ) ) {
$database_string = str_replace( $old_url, $new_url, $database_string );
}
return $database_string;
}
Thanks for the suggestions. Please let me know if you see anything wrong and anything i can improve
I'm looking to manually write a multidimensional $_GET query string, saw this done the other day, but can't quite remember it!
something like:
www.url.com?val1=abc&val2=cde&[val3=fgh&val4=ijk]
http://domain.tld/path/to/script.php?arr[a][b][c]=foo
and
var_dump($_GET);
Since array parameters in URL's are postfixed by brackets, I'd try a function like this:
<?php
function array_map_scope( $callback, array $array, array $arguments = array(), $scope = array() ) {
if( !is_callable( $callback ) ) {
return( false );
}
$output = array();
foreach( $array as $key => $value ) {
if( is_array( $value ) ) {
$output[$key] = array_map_scope( $callback, $value, $arguments, array_push_value( $scope, $key ) );
} else {
$output[$key] = call_user_func_array( $callback, array_merge( array( $value, array_push_value( $scope, $key ) ), $arguments ) );
}
}
return( $output );
}
function array_push_value( $array, $value ) {
$array[] = $value;
return( $array );
}
function urlParam( $value, $key, $name ) {
return( $name.'['.implode( array_map( 'urlencode', $key ), '][' ).']='.urlencode( $value ) );
}
function array_values_recursive( $array ) {
$output = array();
foreach( $array as $value ) {
if( is_array( $value ) ) {
$output = array_merge( $output, array_values_recursive( $value ) );
} else {
$output[] = $value;
}
}
return( $output );
}
function array2URL( $name, $array ) {
$array = array_map_scope( 'urlParam', $array, array( urlencode( $name ) ) );
return( implode( array_values_recursive( $array ), '&' ) );
}
echo array2URL('test', array( 'a'=>'a','b'=>array('ba'=>'ba','bb'=>'bb'),'c'=>'c' ) );
?>
Rely on http_build_query() to perfectly format a query string for you.
Either use it directly in your script to generate the substring after ? in the url or use a sandbox to set up your array data, call the function, then copy-paste the output in your static file.
Code: (Demo)
$array = [
'indexed value',
'foo' => 'first level value',
'bar' => ['baz' => 'second level']
];
echo http_build_query($array);
// 0=indexed+value&foo=first+level+value&bar%5Bbaz%5D=second+level
A fringe case consideration