I've just began using CakePHP and I have a question. I'm creating sort of a Task Manager system.
I have a 'Tasks' table, and this table has a user_id field for assigning a task to a user.
When I baked the application, the generated form has a user_id which was automatically linked to the users table, but I want to show the user's username instead of the user_id - how would I go about doing this?
Also, I need for when the form is saved, it saves the user_id into the field and not the username - So it needs to display the username for ease of use but save the user_id.
I'm still new to this whole Model and Controller so I'm not sure how I'd manage to do this. Thanks.
Update:
Here's where I am so far. In my jobs add.ctp I have added this code to help generate the form field:
foreach ($users as $user):
$options_array[$user['id']] = $user['username'];
endforeach;
print_r($options_array);
echo $this->Form->input('user_id', $options_array);
Unfortunately the print_r gives me:
Array ( [2] => 2 )
And not the desired output:
Array ( [2] => Dan )
$users is defined in the job_controller.php as so:
$users = $this->Job->User->find('list');
$clients = $this->Job->Client->find('list');
$stages = $this->Job->Stage->find('list');
$this->set(compact('users', 'clients', 'stages'));
I'm not sure what I'm doing wrong here.
Dan
If you are only looking for the id and username, then using the list should be cool, but you have to specify the username field.
$users = $this->Job->User->find('list', array('fields' => array('User.username'));
That should return the array as such:
array (
[1] => 'username_for_id_1',
[2] => 'username_for_id_2',
... all the other records...
[114] => 'username for id_114'
)
If you need more information from the User table, then you should use the ->find('all').
$users->Job->User->find('all');
// $users is now:
// array (
// [0] => array (
// 'User' => array(
// 'id' => 1,
// 'username' => 'username',
// ... the rest of the fields
// )
// Other affiliated models will be included with the 'User' if
// you haven't set 'recursive' = -1
// )
// )
Related
I have 2 tables i.e user and photo. According to user_id get all the user details and all the photos from the photo table.
I am creating a web-service using slim framework. How is it possible to make a array like above given format?
How to make a array like following format?
array(
[id]=>
[name]=>
[email]=>
[dob]=>
[gallery]=>array(
[0] => 1.png
[1] => 2.png
)
[address]=> xyz
)
If your question is strictly about how to make the nested array, then here is a solution.
// create the nested portion of the array
$images = ['1.png', '2.png'];
// create the rest of the array
$result = [
'id' => 1,
'name' => 'default',
'email' => '123#abc.com',
'dob' => '3/4/89',
'gallery' => $images,
'address' => 'xyz'
];
Note how we set 'gallery' => $images. If you need data from two different tables to be retrieved at the same time and formatted like this, then that would probably be easiest to achieve using a join in your query. If you need help with that just say so.
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.
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.