2

I have a json array like this:

$json = '[["Nome","contains","av"],"and",[["IdAreoporto","=",1],"and",["!",["IdAreoporto","=",3]]]]';

which basically is an sql. I need to obtain this:

$json = '((Nome like "%av%") and ((IdAreoporto = 1) and (not(IdAreoporto = 3))))';

so basically:

  1. change parenthesis
  2. replace commas with spaces
  3. remove quotes except if array length=3 and array[1] = 'contains'
  4. add % to array[2] just if array[1] = 'contains'

I tried a recursive function but I cannot make it work. Please can anybody help? it's driving me crazy. I tried to solve point 3 like this:

function setFilter( $filtri ){

    $json = json_decode($filtri, false);    

    if(is_array($json)){
        $count_j = count($json);

        if(($count_j==3) && (!is_array($json[0])) && (!is_array($json[1])) && (!is_array($json[2])) ){  

            if($json[1]=='contains'){
              $json[2]='|'.$json[2].'|'; 
            }  

        } else {

            foreach ($json as $item) {                  

                if(is_array($item)){                    
            $item = setFilter( json_encode($item) );    
          };

        }

        }       

  };    

  $json2 = json_encode($json);   
  return $json2;  
}

So the Idea was to put a | where I want to keep the quote, then remove all the quotes, then replace | with quote.

any help? thank you!

****EDIT - I answer my last comment ****

I solved my last problem in the comment like this, what do you think?

// If there are three elements, manipulate the string into the required format
        if (count($json) == 3) {

            if ($json[$i] == 'contains'){
            $json[$i] = 'like';                                     // Change 'contains' to 'like'
            $json[$i + 1] = '"%'.$json[$i + 1].'%"';                // Encapsulate the following token in percentage symbols and quotes
          } else if ($json[$i] == 'notcontains'){
            $json[$i] = 'not like';                                 // Change 'notcontains' to 'not like'
            $json[$i + 1] = '"%'.$json[$i + 1].'%"';                // Encapsulate the following token in percentage symbols and quotes
          } else if ($json[$i] == 'startswith'){
            $json[$i] = 'like';                                    // Change 'startswith' to 'like'
            $json[$i + 1] = '"'.$json[$i + 1].'%"';                // Encapsulate the following token in percentage symbols and quotes
          } else if ($json[$i] == 'endswith'){
            $json[$i] = 'like';                                    // Change 'endswith' to 'like'
            $json[$i + 1] = '"%'.$json[$i + 1].'"';                // Encapsulate the following token in percentage symbols and quotes       
          } else {        
            // I need to find out datatype so that I can add quotes in case of string           
            if(!is_array($json[$i])){                           
              $array = ["=", "<>", "<", ">", "<=", ">="];
              if (stripos(json_encode($array), $json[$i]) !== false) {                
                if (gettype($json[$i]=='string')){
                  $json[$i + 1] = '"'.$json[$i + 1].'"';           // it's a string, add quotes
                }
              };            
            }   
        };  

1 Answer 1

2

The best approach is to decode the entire JSON into an array, allowing the function to recursively call itself. The solution below returns the string you are expecting:

// Your input string
$json = '[["Nome","contains","av"],"and",[["IdAreoporto","=",1],"and",["!",["IdAreoporto","=",3]]]]';

function setFilter($filtri) {

    // Decode the JSON string if it is a JSON string, otherwise simply use the array
    $json = (is_array($filtri)) ? $filtri : json_decode($filtri, true);

    // Where the string will be built
    $string = '';

    // For each top-level element in the array
    for ($i = 0; $i < count($json); $i++) {

        // If there are three elements, manipulate the string into the required format
        if (count($json) == 3 && $json[$i] == 'contains') {
            $json[$i] = 'like';                                     // Change 'contains' to 'like'
            $json[$i + 1] = '"%'.$json[$i + 1].'%"';                // Encapsulate the following token in percentage symbols and quotes
        }

        // More string manipulation
        if ($json[$i] == '!') {
            $json[$i] = 'not';
        }

        // If the current token is an array, put it into the function recursively, otherwise simply add it to the string 
        $string .= (is_array($json[$i])) ? setFilter($json[$i]) : ' ' . $json[$i] . ' ' ;
    }

    // Return the cleaned up string back to its caller (will either be another instance of the same function or the original caller)
    return '('.trim($string).')';  
}

echo setFilter($json);

The end result will be:

((Nome like "%av%") and ((IdAreoporto = 1) and (not (IdAreoporto = 3))))
Sign up to request clarification or add additional context in comments.

3 Comments

Hello Jack. I wanted to thank you but rules were I should just click "accept"..but now I have one more question so I want also to thank you so much!! I wanted to ask you this: if you compare the 3rd parameter sometimes it has double quotes and sometimes not (["Nome","contains","av"] ["IdAreoporto","=",1]). so I actually do not need to add quotes always, i need to keep the original quote if present and just add % if the string is contain. Is there a way to keep the original quote? thank you!
just to explain better, the problem arise when i have "=" as 2nd parameter. in that case the 3rd parameter could be a string or a number. in your answer I cannot see quotes when doing $json[$i + 1] so I don't know if they were present or not.
I edited my answer with my solution to my last problem. what do you think? (it works!) thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.