I'm building an API with custom query filter, in my filter, there are rules that value cannot be empty and some fields has to be an array.
I have managed to filter out empty fields if they are submitted but I can't convert request input to the array, is there a way to do it?
Here is my code:
public function removeEmptyFieldsFromRequest($request)
{
$emptyFields = [];
foreach ($request->all() as $name => $value)
{
if (is_null($value)){
$emptyFields[] = $name;
}
$fields = ['transmissions', 'grades', 'colors', 'equipment', 'lots', 'chassis', 'auctions', 'models'];
if (in_array($name, $fields)){
// here need to convert request value from a string into the array
}
}
$request = $request->except($emptyFields);
return $request;
}
I want to make this filter usable in different cases, I know that I can change the input name to the array on the front end
In Laravel if your parameters is like field[0],field[1],...
you can get it with $request->field and it is array so you can check
is_array($request->field)
and in your case you can check it with below code
is_array($value)
if you query string is like this : /?a=1&b=2&a=3&c=1&a=2.
You can create a function that parses the query string something like this:
$uri = explode('?', Request::capture()->getRequestUri());
$queryStringArr = explode('&',$uri[1]);
$params = [];
foreach ($queryStringArr as $item) {
$i = explode('=',$item);
if (!empty($params[$i[0]])){
$params[$i[0]]=array_merge((is_array($params[$i[0]]))?$params[$i[0]]:[$params[$i[0]]],[$i[1]]);
}else{
$params[$i[0]]=$i[1];
}
}
print_r($params);die;
Which gives.
Array
(
[a] => Array
(
[0] => 1
[1] => 3
[2] => 2
)
[b] => 2
[c] => 1
)
I haven't tested it much so give it a thought yourself.
Related
I am struggling with what would appear to be a pretty straight forward task. I have looked at and tried all kinds of functions and suggestion on SO hoping that maybe there is something simple and functional out there. Nothing I tried gives me the logic to do the restructuring.
I have a long complex array. However very much simplified the logic problem I am trying to solve generically is as follows:
$cost_type = Array
(
0 => "ISP2",
1 => "ISP3",
2 => "ISP4"
);
$supplier_name = Array
(
0 => "NAME-A",
1 => "NAME-B",
2 => "NAME-C"
);
$propertyid = Array
(
0 => "property1",
1 => "property2",
2 => "property2"
);
and I need to convert it to the following set of arrays (noting the concatenation of the two arrays with a common property id.....
$property1
(
array['charges']
[0] =>IPS2
array ['names']
[0] =>NAME-A
)
$property2
(
array['charges']
[0] ->IPS3
[1] =>IPS4
array['names']
[0] =>NAME-B
[1] =>NAME-c
)
I have tried everything over the course of the last few hours and a simple solution totally evades me.
If you can join the three arrays as you say in comments above this code will generate the look you want.
I loop through the array with property and keep key as the key to find names and charges in the other subarrays.
$cost_type = Array
(
0 => "ISP2",
1 => "ISP3",
2 => "ISP4"
);
$supplier_name =Array
(
0 => "NAME-A",
1 => "NAME-B",
2 => "NAME-C"
);
$propertyid = Array
(
0 => "property1",
1 => "property2",
2 => "property2"
);
$arr[] = $cost_type;
$arr[] = $supplier_name;
$arr[] = $propertyid;
$result = array();
Foreach($arr[2] as $key => $prop){
$result[$prop]["charges"][] =$arr[0][$key];
$result[$prop]["names"][] = $arr[1][$key];
}
Var_dump($result);
https://3v4l.org/EilvE
The following code converts the original array in the expected result:
$res = array();
foreach($arr[2] as $k => $foo){ // foreach property
if(!isset($res[$foo])){ // add property if not yet in list
$res[$foo] = array(
'charges' => array($arr[0][$k]),
'names' => array($arr[1][$k])
);
}else{ // add new value to already existing property
$res[$foo]['charges'][] = $arr[0][$k];
$res[$foo]['names'][] = $arr[1][$k];
}
}
Check it out here: https://eval.in/904473
Of course, it assumes a bunch on things about the data, but it should work for any number of items.
And if you need the property in another variable, just access it with $res['name of it].
Run this code you will get smiler result as you want :
$twodimantion=array();
$properties=array('property1','property2','property3');
$charges=array('ISP2','ISP3','ISP4');
$names=array('NAME-A','NAME-B','NAME-C');
foreach ($properties as $key => $property) {
$twodimantion['charge'][$key]=$charges[$key];
$twodimantion['names'][$key]=$names[$key];
$twoarray[$property]=$twodimantion;
}
echo '<pre>';
print_r($twoarray);
echo '</pre>';
I can't say I completely follow what you are trying to do, but I think this may be part of the way there for you.
When trying to restructure data in PHP, it's often helpful to create a empty array (or other data structure) to store the new data in first. Then you find a way to loop over your initial data structure that allows you to insert items into your reformatted structure in the right sequence.
<?php
$properties = []; // Array to hold final result
// Loop over your initial inputs
foreach ($groupsOfValues as $groupName => $groupValues) {
$temp = []; // Array to hold each groupings reformatted data
// Loop over the items in one of the inputs
for ($i=0; $i<count($group) && $i<count($properties)+1; $i++) {
if (!is_array($temp[$groupName])) {
$temp[$groupName] = [];
}
$temp[$groupName][] = $group[$i];
}
$properties[] = $temp;
}
I am trying to return pull a value based on an attribute from an array, and it seems straight forward enough but I can't seem to nail down the correct way to accomplish this.
Here is the array I am trying to pull from:
[1] => InfoOptions Object
(
[description] => INFO
[optSequence] => 2
[eqpObject] => CUSTOMER NTWK ENG
[attribute] =>
[eqpValue] =>
[dlrSequence] => 10
)
[2] => InfoOptions Object
(
[description] =>
[optSequence] => 3
[eqpObject] => CUSTOMER TEST
[attribute] => CUSTOMER
[eqpValue] => Jon Doe
[dlrSequence] => 10
)
Here is what I have so far:
if (is_array($provisionCVResult->path->infoOptions-_InfoOptions)) {
foreach ($provisionCVResult->path->infoOptions ->InfoOptions as $cv_obj) {
$CVA = array();
$result = null;
foreach ($CV_obj as $value) {
if($value['attribute'] == 'CUSTOMER') {
$CVA["eqpValue"] = $cv_obj->eqpValue;
break;
}
}
$this->cvArrayDataList[] = $CVA;
}
}
Where am I going wrong?
If $provisionCVResult->path->InfoOptions is an array, it does not make sense to write $provisionCVResult->path->InfoOptions ->InfoOptions in the foreach
EDIT: I red in the comments that the array is $provisionCVResult->path->InfoOptions->InfoOptions
PHP is case sensitive so $cv_obj and $CV_obj are two different variables
The second foreach is not needed
So, assuming $provisionCVResult->path->InfoOptions->InfoOptions is returning an array of InfoOptions Object, I think you should do something like this:
if (is_array($provisionCVResult->path->InfoOptions->InfoOptions))
{
$result = null;
foreach($provisionCVResult->path->InfoOptions->InfoOptions as $cv_obj)
{
if($cv_obj->attribute == 'CUSTOMER')
{
$this->cvArrayDataList[] = array("eqpValue" => $cv_obj->eqpValue);
}
}
}
Having a quick look, try changing
$value['attribute'] == 'CUSTOMER'
To
$value->attribute == 'CUSTOMER'
As the element is an "InfoOptions object" and not an array.
Note I would also recommend using strict comparison, e.g '===' instead of '=='.
Given the following array of key names in the following format (number of fields can change):
$field_names = Array
(
[0] => web
[1] => results
[2] => result
[3] => title
)
I'd like to access the 'content' key value of the following multi-leveled array:
$values=stdClass Object(
[web] => Array(
[results] => Array(
[result] => Array(
[title] => Array(
[type] => default
[content] => Sample content
)
)
)
)
)
Sample example how value can be accessed given above arrays:
$value = $values->{$field_names[0]}[$field_names[1]][$field_names[2]][$field_names[3]]['content'];
For the sake of simplicity (keep it plain PHP), I won't get into much details as the existing code is part of some handler which is part of some plugin which is part of some module which is part of another module which is part of content management system in order to parse YQL results, but its logic is broken.
The code looks like:
$field = array_shift($field_names);
$value = $values->$field;
foreach ($field_names as $field) {
if (is_array($value)) {
$value = $value[$field];
}
}
I've tried to do a dirty patch like:
$value = is_string($value[$field]) ? $value[$field] : $value[$field]['content'];
And it worked for one example, but it doesn't work for all cases, like one above.
I'm aware of recursive functions and array_walk_recursive(), but I'd like to avoid headache of using them in order to make it simple as possible.
Is there any simple way of accessing value of multi-leveled array having dynamic array of key names?
Recursive solutions can also be simple
Your data:
$field_names = Array("web", "results","result","title");
$values->web["results"]["result"]["title"]=
Array("type"=> "default", "content"=>"Sample content");
The function:
function getField($obj, $keys) {
return ($key=array_shift($keys)) ? getField($obj[$key], $keys) : $obj["content"];
}
echo getField((Array)$values, $field_names);
But if you want a not recursive one, here it is:
$obj=(Array)$values;
while ($key=array_shift($field_names)) $obj=$obj[$key];
echo $obj['content'];
Here's a simple way, not recursive using a reference (taken from How to write getter/setter to access multi-level array by key names?):
function get($object, $path) {
$prop = array_shift($path);
$temp =& $object->$prop;
foreach($path as $key) {
$temp =& $temp[$key];
}
return $temp;
}
$value = get($values, $field_names)['content']; //PHP 5.4.0
Here is my code that I am working on to create an array so the end product will return the following:
$values=user_email => displayname
user_email => displayname
user_email => displayname
I am using the array listed below:
array [0] => std.class Object( [id] = 12
[user_login] = bob
)
[1] => std.class Object( [id] = 15
[user_login] = frank
)
When I run my code that is listed below it only runs on the last value. I have tried using the "." at the variable name but it only seems to add it to the variable instead of the array where I need it.
What I hope to do is:
Run a wp_user_query to return all the personnel in a group
get the results
after I get the results, use the [id] for each user to determine their $displayname and $email
they are then sent into a new array using their email as key
Here is the code that I have been working on, and as of right now it does everything correctly except return every user, it only returns the last user
function show_user_dropdown($values, $field){
if( $field->id == 155 ){
$wp_user_search = new WP_User_Query( array( 'role' => 'Hrrepresentative', 'fields' => array('user_login', 'ID') ) );
$authors = $wp_user_search->get_results();
$value['options']=array();
foreach ($authors as $a) {
$displayname=get_the_author_meta('display_name', $a->ID);
$emailname=get_the_author_meta('user_email', $a->ID);
$validation=array($emailname=>$displayname);
$values['options']=$validation;
$values['use_key'] = true;
}
}
return $values;
}
What do I need to do to fix this?
You have both 'values' and 'value'. I don't think the array notation is working how you think it is. I think you'd be better off doing something like this:
$values[$id]['option'] = $validation;
edit: to elaborate, you only have 1 value for $values (the last run through the foreach loop). You also would be overwriting the previous value in $values['option'] regardless. You need to use a multidimensional array with an index.
To get the array structure you showed, try:
$values['options'][$emailname] = $displayname;
You are reassigning $values['options']=$validation; in your loop.
Use it this way:
$values['options'][]=$validation;
I have a weird phenomenon. I hope someone can explain to me what is happening there:
I want to create a filter. The origin is something like '-10' or '10-20' or '20+' (type string) and the result should be 'Under $10', ... as well as 'product_price < 10', ... for a sql command.
But storing the array back on the original string doesn't work. It just delivers '$Array' as result. Is it not possible to pass by reference and change the type?
Thanks for your knowledge!
foreach($filters as &$filter){
preg_match ('#^\-(\d+)$#ism', $filter, $match);
if ($match[1]){
$filter = array(
'Under $'.intval($match[1]),
'product_price < '.intval($match[1])
);
}
...
}
return $filtering;
}
P.S.: I am not looking for a solution, because I could change the origin string into array, or I could change the foreach in to a pass by value and create a new array with the arrays like $newFilter[] = ... I am only curious
You can change it's type. Proof by construction:
<?php
header('Content-type:text/plain');
$arr = array(
'1',
'2',
);
foreach ($arr as &$filter) {
$filter = array($filter);
}
print_r($arr);
?>
Prints:
Array
(
[0] => Array
(
[0] => 1
)
[1] => Array
(
[0] => 2
)
)
You should change your foreach into
foreach($filters as $index => $filter)
and update your filter by doing
$filters[$index] = array(...);
I believe the $filter variable created by the foreach() statement is a copy of the data in the array and not a reference to it.