Logical Operators expression to a PHP array - php

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;
}
}

Related

get all custom post type titles and show it as selectbox in a meta box

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;

I have used return create_function in my application below. php 7.2

how to win?
PHP 7.2.0, the create_function() is deprecated.
Thanks for your help,
or wait for developers?
Edited and cleared Code
return create_function( '', "
global $chery_core_version;
$path = trailingslashit( dirname( __FILE__ ) ) . 'cherry-core.php';
$data = get_file_data( $path, array(
'version' => 'Version'
) );
if ( isset( $data['version'] ) ) {
$version = $data['version'];
}
$old_versions = null;
if ( null !== $chery_core_version ) {
$old_versions = array_keys( $chery_core_version );
}
if ( is_array( $old_versions ) && isset( $old_versions[0] ) ) {
$compare = version_compare( $old_versions[0], $version, '<' );
if ( $compare ) {
$chery_core_version = array();
$chery_core_version[ $version ] = $path;
}
} else {
$chery_core_version = array();
$chery_core_version[ $version ] = $path;
}
" );
Use anonymous functions instead:
return function () {
global $chery_core_version;
$path = trailingslashit(__DIR__) . 'cherry-core.php';
$data = get_file_data( $path, [
'version' => 'Version'
] );
if ( isset( $data['version'] ) ) {
$version = $data['version'];
}
$old_versions = null;
if ( null !== $chery_core_version ) {
$old_versions = array_keys( $chery_core_version );
}
if ( is_array( $old_versions ) && isset( $old_versions[0] ) ) {
$compare = version_compare( $old_versions[0], $version, '<' );
if ( $compare ) {
$chery_core_version = [];
$chery_core_version[ $version ] = $path;
}
} else {
$chery_core_version = [];
$chery_core_version[ $version ] = $path;
}
};

Replacing text within string that contains serialize arrays

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

Slimmest OpenID Implementation?

Is there an implementation of OpenID that is under 5K or at least under 10K?
Please format the code with http://beta.phpformatter.com/ with the following settings to get the true size:
Indentation:
Indentation style: {K&R (One true brace style)}
Indent with: {Tabs}
Starting indentation: [1]
Indentation: [1]
Common:
[x] Remove all comments
[x] Remove empty lines
[x] Align assignments statements nicely
[ ] Put a comment with the condition after if, while, for, foreach, declare and catch statements
Improvement:
[x] Remove lines with just a semicolon (;)
[x] Make normal comments (//) from perl comments (#)
[x] Make long opening tag (
Brackets:
[x] Space inside brackets- ( )
[x] Space inside empty brackets- ( )
[x] Space inside block brackets- [ ]
[x] Space inside empty block brackets- [ ]
Edit:
Alix Axel's answer seems great, not perfect but is getting there. BTW: this is 6.4K So it is no longer the smallest, but i'm going through it to clean it up lots more.
<?php
class openID {
function __construct( $url = null, $realm = null, $return = null, $redirect = true, $verify = false ) {
$data = array( );
if ( ( $verify !== true ) && ( self::Value( $_REQUEST, 'openid_mode' ) !== false ) ) {
if ( strcmp( 'id_res', self::Value( $_REQUEST, 'openid_mode' ) ) === 0 ) {
$data[ 'openid.sig' ] = $_REQUEST[ 'openid_sig' ];
$data[ 'openid.mode' ] = 'check_authentication';
$data[ 'openid.signed' ] = $_REQUEST[ 'openid_signed' ];
$data[ 'openid.assoc_handle' ] = $_REQUEST[ 'openid_assoc_handle' ];
if ( array_key_exists( 'openid_op_endpoint', $_REQUEST ) === true ) {
$data[ 'openid.ns' ] = 'http://specs.openid.net/auth/2.0';
}
foreach ( explode( ',', self::Value( $_REQUEST, 'openid_signed' ) ) as $value ) {
$data[ 'openid.' . $value ] = $_REQUEST[ 'openid_' . str_replace( '.', '_', $value ) ];
}
if ( preg_match( '~is_valid\s*:\s*true~i', self::CURL( self::__construct( $_REQUEST[ 'openid_identity' ], false, false, false, true ), $data, 'POST' ) ) > 0 ) {
return self::Value( $_REQUEST, 'openid_claimed_id', self::Value( $_REQUEST, 'openid_identity' ) );
}
}
} else if ( ( $result = self::CURL( $url ) ) !== false ) {
$xml = self::XML( $result );
$server = strval( self::XML( $xml, '//xrd/service/uri', 0 ) );
if ( empty( $server ) === true ) {
$server = strval( self::XML( $xml, '//head/link[#rel="openid.server" or #rel="openid2.provider"]/#href', 0 ) );
}
if ( self::URL( $server ) === true ) {
if ( $redirect === true ) {
$realm = ( isset( $realm ) === true ) ? $realm : sprintf( '%s://%s/', $_SERVER[ "HTTPS" ] ? "https" : "http", $_SERVER[ 'HTTP_HOST' ] );
$return = ( isset( $return ) === true ) ? $return : sprintf( '%s://%s', $_SERVER[ "HTTPS" ] ? "https" : "http", $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ] );
$delegate = ( preg_match( '~http://specs[.]openid[.]net/auth/2[.]0/server~', $result ) > 0 ) ? 'http://specs.openid.net/auth/2.0/identifier_select' : $url;
if ( preg_match( '~rel="openid[.]delegate"|<[^>]*Delegate[^>]*>~i', $result ) > 0 ) {
$delegate = parent::Value( ph()->Text->Regex( $result, '<([^>]*)Delegate[^>]*>([^>]+)</\1Delegate>', 1 ), 0 );
if ( empty( $delegate ) === true ) {
$delegate = strval( self::XML( $xml, '//head/link[#rel="openid.delegate"]/#href', 0, $delegate ) );
}
}
if ( preg_match( '~rel="openid2[.]provider"|http://specs[.]openid[.]net/auth/2[.]0~i', $result ) > 0 ) {
$data[ 'openid.ns' ] = 'http://specs.openid.net/auth/2.0';
if ( preg_match( '~rel="openid2[.]local_id"|<(Local|Canonical)ID[^>]*>~i', $result ) > 0 ) {
$delegate = self::Value( self::Regex( $result, '<(Local|Canonical)ID[^>]*>([^>]+)</\1ID>', 1 ), 0 );
if ( empty( $delegate ) === true ) {
$delegate = strval( self::XML( $xml, '//head/link[#rel="openid2.local_id"]/#href', 0, $delegate ) );
}
}
}
$data[ 'openid.mode' ] = 'checkid_setup';
$data[ 'openid.return_to' ] = $return;
$data[ 'openid.claimed_id' ] = $data[ 'openid.identity' ] = $delegate;
$data[ 'openid.' . ( ( array_key_exists( 'openid.ns', $data ) === true ) ? 'realm' : 'trust_root' ) ] = $realm;
self::Redirect( sprintf( '%s%s%s', $server, ( strpos( $server, '?' ) !== false ) ? '&' : '?', http_build_query( $data, '', '&' ) ) );
}
return $server;
}
}
return false;
}
function CURL( $url, $data = null, $method = "GET", $options = array( ) ) {
$result = false;
if ( ( extension_loaded( "curl" ) === true ) && ( $this->URL( $url ) === true ) ) {
$curl = curl_init( $url );
if ( is_resource( $curl ) === true ) {
curl_setopt( $curl, CURLOPT_FAILONERROR, true );
curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false );
if ( preg_match( "~^GET$~i", $method ) > 0 ) {
curl_setopt( $curl, CURLOPT_HTTPGET, true );
} else if ( preg_match( "~^POST$~i", $method ) > 0 ) {
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $data );
}
$result = curl_exec( $curl );
if ( $result !== false ) {
curl_close( $curl );
}
}
}
return $result;
}
function Redirect( $url, $permanent = false ) {
if ( headers_sent() !== true ) {
header( "Location: " . $url, true, ( $permanent === true ) ? 301 : 302 );
}
exit( );
}
function Regex( $string, $pattern, $key = null, $modifiers = null, $flag = PREG_PATTERN_ORDER, $default = false ) {
$matches = array( );
if ( preg_match_all( "~" . $pattern . "~" . $modifiers, $string, $matches, $flag ) > 0 ) {
if ( isset( $key ) === true ) {
return ( $key === true ) ? $matches : Value( $matches, $key, $default );
}
return true;
}
return $default;
}
function URL( $value ) {
return (bool) filter_var( $value, FILTER_VALIDATE_URL );
}
function Value( $data, $key = null, $default = false ) {
if ( isset( $key ) === true ) {
foreach ( (array) $key as $value ) {
if ( is_object( $data ) === true ) {
$data = get_object_vars( $data );
}
if ( array_key_exists( $value, (array) $data ) !== true ) {
return $default;
}
$data = $data[ $value ];
}
}
return $data;
}
function XML( $xml, $xpath = null, $key = null, $default = false ) {
if ( extension_loaded( "SimpleXML" ) === true ) {
libxml_use_internal_errors( true );
if ( ( is_string( $xml ) === true ) && ( class_exists( "DOMDocument" ) === true ) ) {
$dom = new DOMDocument();
if ( $dom->loadHTML( $xml ) === true ) {
return $this->XML( simplexml_import_dom( $dom ), $xpath, $key, $default );
}
} else if ( is_object( $xml ) === true ) {
if ( isset( $xpath ) === true ) {
$xml = $xml->xpath( $xpath );
if ( isset( $key ) === true ) {
$xml = $this->Value( $xml, $key, $default );
}
}
return $xml;
}
}
return false;
}
}
new openID( "https://www.google.com/accounts/o8/id" );
?>
Slim down Lightopenid
First of I really don't get your filesize limitation. I find it kind of b*llshit if you ask me....
You could make a call graph(use some sort of dead code detector) of lightopenid to see which functions(only a few are used) you are using. A lot of these big functions aren't used standard for example I believe you can remove the big function protected function request_streams($url, $method='GET', $params=array()) on line 198. I also removed some other functions which aren't used when using it with example-google.php example. My final lightopenid class looks like this(I bet you can even eliminate more code when using call graph/dead code detector).
But now I got the filesize down to 9.8KB. If you compress it you can get it down even more. I got it down to your desired 10K mark, but now the code can not be read by humans anymore.
Code searches:
You could also have a look at these resources/searches to see if any are lighter(I highly doubt that):
https://github.com/search?langOverride=&language=php&q=openid&repo=&start_value=1&type=Repositories&x=17&y=33
http://code.google.com/hosting/search?q=openid+label:php&btn=Search+projects
Inspired by lightopenid and part of phunction (depends on 5 other methods):
public static function OpenID($id, $realm = null, $return = null, $verify = true)
{
$data = array();
if (($verify === true) && (array_key_exists('openid_mode', $_REQUEST) === true))
{
$result = parent::Value($_REQUEST, 'openid_claimed_id', parent::Value($_REQUEST, 'openid_identity'));
if (strcmp('id_res', parent::Value($_REQUEST, 'openid_mode')) === 0)
{
$data['openid.mode'] = 'check_authentication';
foreach (array('ns', 'sig', 'signed', 'assoc_handle') as $key)
{
$data['openid.' . $key] = parent::Value($_REQUEST, 'openid_' . $key);
if (strcmp($key, 'signed') === 0)
{
foreach (explode(',', parent::Value($_REQUEST, 'openid_signed')) as $value)
{
$data['openid.' . $value] = parent::Value($_REQUEST, 'openid_' . str_replace('.', '_', $value));
}
}
}
return (preg_match('~is_valid\s*:\s*true~', self::CURL(self::OpenID($result, false, false, false), array_filter($data, 'is_string'), 'POST')) > 0) ? $result : false;
}
}
else if (($result = self::XML(self::CURL($id))) !== false)
{
$server = null;
$protocol = array
(
array('specs.openid.net/auth/2.0/server', 'specs.openid.net/auth/2.0/signon', array('openid2.provider', 'openid2.local_id')),
array('openid.net/signon/1.1', 'openid.net/signon/1.0', array('openid.server', 'openid.delegate')),
);
foreach ($protocol as $key => $value)
{
while ($namespace = array_shift($value))
{
if (is_array($namespace) === true)
{
$server = strval(self::XML($result, sprintf('//head/link[contains(#rel, "%s")]/#href', $namespace[0]), 0));
$delegate = strval(self::XML($result, sprintf('//head/link[contains(#rel, "%s")]/#href', $namespace[1]), 0, $id));
}
else if (is_object($xml = self::XML($result, sprintf('//xrd/service[contains(type, "http://%s")]', $namespace), 0)) === true)
{
$server = parent::Value($xml, 'uri');
if ($key === 0)
{
$delegate = 'http://specs.openid.net/auth/2.0/identifier_select';
if (strcmp($namespace, 'specs.openid.net/auth/2.0/server') !== 0)
{
$delegate = parent::Value($xml, 'localid', parent::Value($xml, 'canonicalid', $id));
}
}
else if ($key === 1)
{
$delegate = parent::Value($xml, 'delegate', $id);
}
}
if (ph()->Is->URL($server) === true)
{
if (($realm !== false) && ($return !== false))
{
$data['openid.mode'] = 'checkid_setup';
$data['openid.identity'] = $delegate;
$data['openid.return_to'] = parent::URL($return, null, null);
if ($key === 0)
{
$data['openid.ns'] = 'http://specs.openid.net/auth/2.0';
$data['openid.realm'] = parent::URL($realm, false, false);
$data['openid.claimed_id'] = $delegate;
}
else if ($key === 1)
{
$data['openid.trust_root'] = parent::URL($realm, false, false);
}
parent::Redirect(parent::URL($server, null, $data));
}
return $server;
}
}
}
}
return false;
}
Usage:
OpenID('https://www.google.com/accounts/o8/id');
PS: I've updated the code I had previously posted because it was sub-optimal and prone to some bugs.
The slimmest openid implementation I know is LightOpenId
It has got 30kb with comments, so if you run it through that formatter it gets much smaller
EDIT: I found a smaller one here (just 6.6 kb after reformatting)

Manually write a url query string containing nested array data

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

Categories