Im getting an array within array of 'Cylinders' data from POST:
Array
(
[serie] => Array
(
[0] => 1234
[1] => 3545
)
[seriesap] => Array
(
[0] => 1234234
[1] => 345345
)
[type] => Array
(
[0] => 4546
[1] => csdfwe
)
[admission] => Array
(
[0] => 04-05-2015
[1] => 04-05-2015
)
[invoice] => Array
(
[0] => fei76867
[1] => feiasodjf
)
)
Now, the fields inside the keys: serie, type, admission, etc dont change, but the info inside those key do change, i mean there could be even 15 items in there.
At the end i need to save to the database:
$cylinder = new Cylinder();
$cylinder->serie = ??;
$cylinder->seriesap = ??;
$cylinder->type = ??;
$cylinder->admission = ??;
$cylinder->invoice = ??;
$cylinder->save
How can i accomplish this task and save all the cylinders?
I have tried all the foreach's that i could think of nothing seems to work.
/edit/
This is what Im doing so far:
$cyldata = $_POST['cylinder']; //this is the post from top.
$num_elements = 0;
while($num_elements < count($cyldata['serie'])){
$cylinder = new Cylinder();
$cylinder->serie = $cyldata['serie'][$num_elements];
$cylinder->type = $cyldata['type'][$num_elements];
$cylinder->admission = $cyldata['admission'][$num_elements];
$cylinder->seriesap = $cyldata['seriesap'][$num_elements];
$cylinder->save
$num_elements++;
}
But it feels ugly, all those saves doesnt feel right. Dirty solution if you ask me.
First, you need to convert you input data to another format:
$cyldata = $_POST['cylinder']; //this is the post from top.
$num_elements = 0;
$sqlData = array();
while($num_elements < count($cyldata['serie'])){
$sqlData[] = array(
'serie' => $cyldata['serie'][$num_elements],
'type' => $cyldata['type'][$num_elements],
'admission' => $cyldata['admission'][$num_elements],
'seriesap' => $cyldata['seriesap'][$num_elements],
'invoice' => $cyldata['invoice'][$num_elements], // you miss this field, aren't you?
'created_at' => Carbon\Carbon::now(), // only if your table has this column
'updated_at' => Carbon\Carbon::now(), // only if your table has this column
);
$num_elements++;
}
Second, use the Fluent query builder to do a batch insert:
DB::table('table_name')->insert($sqlData);
Note: the created_at and updated_at appear here if your table has these field. When working with Eloquent model, these field is updated automatically. However, we do not use Eloquent, so that we have to assign the value to these field manually.
I don't know what forced you to use $_POST global array in order to receive the data from the user.
Perhaps, this is what you want.
/**
* Store the form inputs in the table
*
* #param Request $request
*/
public function store( Request $request ) {
$data = Input::get();
for($i = 0; $i < count($data['serie']); $i++) {
$c = new Cylinder();
$c->serie = $data['serie'][$i];
$c->type = $data['type'][$i];
$c->admission = $data['admission'][$i];
$c->seriesap = $data['seriesap'][$i];
$c->save(); // fixed typo
}
}
Because you are having an array to insert the data to database, you can try the create method from the model:
Cylinder::create($array);
but it actually needs the key of the array to be the field_name in your database. Or you can do this with the query builder:
DB::table('table_name')->insert($array);
and again it is required to set the key of the array to be the field_name in your database.
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'm having an array which contains record ids as follows:
Array
(
[0] => 113
[1] => 43
[2] => 64
)
so for achieving the corresponding records, i'd have to run 3 queries:
select * from mytable where id=113
select * from mytable where id=43
select * from mytable where id=64
my question: wouldn't it be possible executing just ONE query on the whole table then directly access the mysqli result like an associative array by passing the ID?
something like $record = $res['id'][113];?
thanks in advance
You need the IN clause
SELECT * FROM mytable WHERE id IN ( 113,43,64 );
Custom function indexme takes an array of arrays (numeric or associative) and by default gets the first element value of each sub-array and makes it the associative index in a return array. Optionally, a column name can be passed as the second parameter to designate which column value to use for the index.
$array = array(array('id' => 12, 'name' => 'Joe'), array('id' => 9, 'name' => 'Jane'));
$array_keyed = indexme($array);
// > array(12 => array('id' => 12, 'name' => 'Joe'), 9 => array('id' => 9, 'name' => 'Jane'));
print $array_keyed[12]['name'];
// > Joe
function indexme($arr, $key = '') { // <- custom function indexme
$return_arr = array();
if ( '' == $key ) {
$keys = array_keys($arr[0]);
$key = $keys[0];
}
foreach ( $arr as $value ) {
$return_arr[$value[$key]] = $value;
}
return $return_arr;
}
Pass the mysqli response to this function to make an ID indexed array:
$results_keyed = indexme($result->fetch_assoc(), 'id');
Check out the accepted answer on this page MySQL Prepared statements with a variable size variable list for a nice solution to the WHERE IN technique.
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 cannot seem to get CI's session library to function the way I want it to. Essentially, I am storing 2 different categories of data within the sessions. The data within the 2 categories may contain the same value. Right now my attempt to add a key => value pair to the session is failing, as it is only allowing 1 key => value pair to be associated with the array. It overrides itself each time I do a post.
$arr = array(
'favorite_products' => array(),
'viewed_products' => array()
);
$arr["favorite_products"][] = $fav_id;
$this->session->set_userdata($arr);
This is what the array looks when I print_r it:
Array ( [favorite_products] => Array ( [4f1066c2b7fff] => 1648406 ) [viewed_products] => Array ( ))
Am I doing something wrong, or is this just the way CI's session library works?
Make sure you are destroying your session between attempts, but this code should work just fine...
$arr = array(
'favorite_products' => array(),
'viewed_products' => array()
);
$arr["favorite_products"][] = $fav_id;
$arr["favorite_products"][] = 033333; // another id
$this->session->set_userdata($arr);
should give you...
Array (
[favorite_products] => Array (
[0] => 1648406,
[1] => 033333
),
[viewed_products] => Array ()
)
If you are trying to do this between requests...
// if it doesn't already exist in the session, create an empty array.
if( ! ($favorite_products = $this->session->get_userdata("favorite_products")))
{
$favorite_products = array();
}
$favorite_products[] = "new id or info";
$this->session->set_userdata("favorite_products", $favorite_products);
Form (newreports.php) when on submit needs to save to table as well as save hidden data (27 records with 7 columns each) to a BelongsTo table. 7 columns are: id,user_id,reports_id,count,area,area_id,comments. Area needs to pre-fill as 0-26 and reports_id needs to be the same for all (100). User_id should pre-fill from the form entry. Also, id should auto-fill. I think this can be done in my controller for function newreports().
Do I need to write the array like this or is there a simplified way?
$this->Report->saveAll(
Array
(
[Report] => Array
(
[0] => Array
(
[id] => //leave blank because it will auto-fill?
[user_id] => //dynamically from form input
[reports_id] => //dynamically from form input
[area_id] => //dynamically from form input
[area] => 0
[count] => // this should be blank as there are no counts yet
[comments] => // this should be blank as there are no comments yet
)
[1] => Array
(
[id] => //leave blank because it will auto-fill?
[user_id] => //dynamically from form input
[reports_id] => //dynamically from form input
[area_id] => //dynamically from form input
[area] => 1
[count] => // this should be blank as there are no counts yet
[comments] => // this should be blank as there are no comments yet
)
)
)
This is what did it for me
$count = 27;
$v = 0;
do {
######### save report rows to database
$this->Report->create();
$this->Report->set(array('reports_id' => $id , 'area' => $v));
$this->Report->save();
$v++;
} while ($v < $count);
If your form/view code is written the right way, you should be able to get away with $this->Report->saveAll($this->data['Report']);.
View the HTML source for your form. The values of the name attributes for the input tags should be something like data[Report][0][id], data[Report][0][user_id], etc. The second record should have fields looking like data[Report][1][id], data[Report][2][user_id], etc.
When this gets POSTed, it will automatically import in to the correct array structure in $this->data.
If this form will always create new records, then leave out the data[Report][][id] fields (or leave them empty), and saveAll will create new records.
Update to handle first comment.
It's not clear if you want an assignment to $data after or before the controller saves all that hidden data. Let's deal with both parts; first, the save.
So, your own answer nearly gets it right for creating the data.
$count = 27;
$v = 0;
$data = array('Report' => array());
do {
$data['Report'][] = array('reports_id' => $id, 'area' => $v);
$v++;
} while ($v < $count);
// save report rows to database
$this->Report->saveAll($data['Report']);
So, that prepares a data structure, much like you've done in your original question, and in your answer. However, we use saveAll() to create them all in one go.
The next part, is to retrieve the saved data, and put into $this->data, so you can use it in the form that your users will see after the redirect, as per your comment. You'll need something like this in the controller.
$reports = $this->Report->find('all', array(
'conditions' => array(
'reports_id' => $id
)
));
// merge this in with existing data
$this->data = Set::merge($reports, $this->data);
It is assumed that $id is on the URL as a part of the redirect. And that's how you assign that data to $this->data, so you can use it in your form.
And in your form, you can reference the multiple fields like so:
$this->Form->create('Report');
foreach ($data['Report'] as $i => $report) {
$this->Form->input('Report.'.$i.'.id');
$this->Form->input('Report.'.$i.'.user_id');
$this->Form->input('Report.'.$i.'.reports_id');
$this->Form->input('Report.'.$i.'.area_id');
$this->Form->input('Report.'.$i.'.area');
$this->Form->input('Report.'.$i.'.count');
$this->Form->input('Report.'.$i.'.comment');
}
$this->Form->end('Submit);
You can read more about forms for multiple records at the CakePHP manual.