CakePHP: sending latest user id to admin's create_employee view - php

I am trying to send the latest user's id from UsersController to AdminController whose add_employee() action creates a new employee. My users and employees table are separate and what I want to do is when Admin creates a new user its entry go into users table. Then he opens create employee form and the latest user id will be assigned to the new employee the admin is creating. So when admin will open create new employee form the latest user id will be shown in the form.
My UsersController has this code for sending latest user it to AdminsController:
public function get_latest_user_id()
{
$content = $this->User->query("SELECT id FROM users ORDER BY id DESC LIMIT 0,1");
$this->set('latest_user', $content);
}
AdminsController page's add_employee contains this code:
public function add_employee()
{
$this->loadModel('Employee');
$this->set('latest_user', $this->requestAction('/Users/get_latest_user_id'));
if ($this->request->is('post'))
{
$this->Employee->create();
if ($this->Employee->save($this->request->data))
{
$this->Session->setFlash(__('The employee profile has been saved.'));
return $this->redirect(array('action' => 'list_of_employees'));
}
else
{
$this->Session->setFlash(__('The employee profile could not be saved. Please, try again.'));
}
}
}
So UserController's get_latest_user_id function sends latest user id to add_employee function of AdminController. There latest_user is set to latest user id so that when add_employee view is called it is there. But it is not showing. So I want to know that am i doing it right? Please help and thanks.
In add_employee.ctp I am displaying it like this:
echo $latest_user['User']['id'];

Move get_latest_user_id to the User model
public function get_latest_user_id()
{
$user = $this->query("SELECT id FROM users ORDER BY id DESC LIMIT 1");
if (empty($user)) {
return 0;
}
// return only the Id
return $user[0]['users']['id'];
}
In the controller:
public function add_employee()
{
$this->loadModel('Employee');
$this->loadModel('User');
$this->set('latest_user', $this->User->get_latest_user_id());
if ($this->request->is('post'))
{
// ....
}
}

cornelb is right that you should move the method to your User model. Although a more Cake-ish approach would be to use a find('first'), rather than doing a direct query():
// app/Model/User.php
public function getLatest() {
// Get the latest user
$user = $this->find('first', array(
'fields' => array('id'), // Only interested in id? Use this.
'order' => array('User.id' => 'DESC')
));
if (!empty($user)) {
return $user['User']['id'];
} else {
// Nothing was returned, this is very awkward
throw new NotFoundException(__('No users found!'));
}
}
And in your controller:
// app/Controller/AdminsController.php
public function add_employee() {
$this->loadModel('User');
$this->set('latestUser', $this->User->getLatest());
// ...
}

Related

CakePHP 3 - ownership authorisation for associated tables

In the CakePHP 3 Blog Tutorial, users are conditionally authorized to use actions like edit and delete based on ownership with the following code:
public function isAuthorized($user)
{
// All registered users can add articles
if ($this->request->getParam('action') === 'add') {
return true;
}
// The owner of an article can edit and delete it
if (in_array($this->request->getParam('action'), ['edit', 'delete'])) {
$articleId = (int)$this->request->getParam('pass.0');
if ($this->Articles->isOwnedBy($articleId, $user['id'])) {
return true;
}
}
return parent::isAuthorized($user);
}
public function isOwnedBy($articleId, $userId)
{
return $this->exists(['id' => $articleId, 'user_id' => $userId]);
}
I've been attempting to implement something similar for my own tables. For example, I have a Payments table, which is linked to Users through several different tables as follows:
Users->Customers->Bookings->Payments.
Foreign keys for each:
user_id in Customers table = Users->id (User hasOne Customer)
customer_id in Bookings table = Customers->id (Customer hasMany Bookings)
booking_id in Payments table = Bookings->id(Booking hasMany Payments)
My AppController's initialize function:
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Auth',[
'authorize' => 'Controller',
]);
$this->Auth->allow(['display']); //primarily for PagesController, all other actions across the various controllers deny access by default
}
In my PaymentsController, I have the following
public function initialize()
{
parent::initialize();
}
public function isAuthorized($user)
{
if (in_array($this->request->action,['view', 'edit', 'index', 'add']
return (bool)($user['role_id'] === 1); //admin functions
}
if (in_array($this->request->action,['cart'])) {
return (bool)($user['role_id'] === 2) //customer function
}
if (in_array($this->request->action, ['cart'])) {
$bookingId = (int)$this->request->getParam('pass.0');
if ($this->Payments->isOwnedBy($bookingId, $user['id'])) {
return true;
}
}
return parent::isAuthorized($user);
}
public function isOwnedBy($bookingId, $userId)
{
return $this->exists(['id' => $bookingId, 'user_id' => $userId]);
}
I'm unsure as to how to link through the different tables to determine ownership.
Currently if a customer who is paying for Booking #123 could just change the URL so they are paying for Booking #111, provided that Booking exists in the database.
Additionally, the Booking ID is passed to the Cart function (since customers are paying for a specific booking). For example: If customer is paying for Booking #123, then the URL = localhost/project/payments/cart/123. Upon submitting their cart, a new Payment entry is created.
Also, regarding the getParam and isOwnedBy methods, hovering over them in my editor shows this:
Method 'getParam' not found in \Cake\Network\Request
Method 'isOwnedBy' not found in App\Model\Table\PaymentsTable
However, I've gone through the entire BlogTutorial and can't find anywhere else that getParam or isOwnedBy is used or set up in the Model.
In the IsAuthorized function in PaymentsController:
if (in_array($this->request->action, ['cart'])) {
$id = $this->request->getParam('pass'); //use $this->request->param('pass') for CakePHP 3.3.x and below.
$booking = $this->Payments->Bookings->get($id,[
'contain' => ['Artists']
]);
if ($booking->artist->user_id == $user['id']) {
return true;
}
}

Update existing record in CakePHP

I want to create the following in CakePHP:
Starting page: User enters a loginname which pre exists in the DB. Table name loginname.
Once the user has entered the right loginname, the user continues to the registration form, where the user can add personal data to the existing record.
When the user saves the form, the record with only the loginname has personal data added.
This is what i have:
Logic for starting page:
public function checkCodeRespondent() {
//set var
$password = $this->data['Respondent']['loginname'];
//set condition for hasAny function
$condition = array('Respondent.loginname'=>$password);
//if password matches continue to registreer
if($this->Respondent->hasAny($condition)){
//find data by password
$respondent = $this->findByPass($password);
//set var for current id
$id= $respondent['Respondent']['id'];
//redirect with current id
$this->redirect(array('action' => 'aanmelden', $id));
} else {
//if password does not match, return to index with errormessage
$this->redirect(array('action' => 'index'));
}
}
public function findByPass($pass) {
$respondent = $this->Respondent->find('first', array('conditions' => array('pass' => $pass)));
return $respondent;
}
And this is the logic for saving the data to the record:
public function registreren() {
if($this->request->isPost()) {
$this->Respondent->id = $id;
if ($this->Respondent->save($this->request->data)){
$this->Flash->success(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
}
}
I thought i got my id through the function checkCodeRespondent() , but that's not working. What am i forgetting or what am i doing wrong? If i need to give more info, i'm happy to help ofcourse.
Update: I read that i need to add echo $form->input('id');, only when i debug($this->request); the id value is empty. What do i need to change in my code?
If you have added hidden field for id then just replace:
$this->Respondent->id = $id;
By:
$this->Respondent->id = $this->request->data['Respondent']['id'];
And in your view, give name="data[Respondent][id]" in the hidden field of id like:
<input type="hidden" name="data[Respondent][id]" value="value of id">
that should work fine for you if no other issues out there.

Saving user ID to database using CodeIgniter

I am trying to create an application with which users can enrol on to a course. To enrol a user has to be approved by the admin. A user will select a course by clicking on a course,then the course ID and the user ID should get saved in a database. However I can't get the user ID to save in a database. I have added the user ID as a part of the session. So how can I save the user ID which is now in the session?
Here is the model:
public function select_course()
{
$data['users_id']=$this->input->post($this->session->userdata('users_id'));
$query =$this->db->insert('gp_approval_course',$data);
if ($query)
{
return true;
}
else
{
return false;
}
}
Here is the controller:
public function add_course()
{
$this->load->model('model_users');
if ($this->model_users->select_course())
{
echo "You have selected a course to enroll on to!";
echo ($this->session->userdata('users_id'));
return true;
}
else
{
echo "Database problem";
return false;
}
}
change
$data['users_id']=$this->input->post($this->session->userdata('users_id'));
to
$data['users_id']=$this->session->userdata('users_id');
$data['course_id'] = $this->input->post('your_course_id_var');

Populate Fields From one Controller, in another.. CAKEPHP

I am currently trying to allow the users to archive events that have already been completed.
Then the event will be viewed in the Archive Table.
So basically I have one archive table, and one event table, and when the user wants to archive the event, they should be able to view the event in the archive add form (which needs to be populated by the $id of the event).
But I do not know how to populate the field.. I have tried setting a value.. but the events are not sessions so that didn't work, and I have also tried setting the $id at the start of the form, but that also didn't work.
Here is the code to my archive function in the events controller.
public function archive($id = null) {
if ($this->request->is('post')) {
$event = $this->Event->read($id);
$archive['Archive'] = $event['Event'];
$archive['Archive']['eventID'] = $archive['Archive']['archiveID'];
unset($archive['Archive']['archiveID']);
$this->loadModel('Archive');
$this->Archive->create();
if ($this->Archive->save($archive)) {
$this->Session->setFlash(__('The event has been archived'));
$this->Event->delete($id);
$this->redirect(array('action' => 'eventmanage'));
} else {
$this->Session->setFlash(__('The event could not be archived. Please, contact the administrator.'));
}
}
}
You need to do one of the following:
Set the values for the fields using $this->request->data in the controller.
public function add($id = null) {
if ($this->request->is('post')) {
[..snip..]
}
$this->loadModel('Event');
$event = $this->Event->read($id);
$this->request->data['Archive'] = $event['Event'];
}
OR
Update the form to set the values.
Update the existing code with the same event read:
public function add($id = null) {
if ($this->request->is('post')) {
[..snip..]
}
$this->loadModel('Event');
$this->set('event', $this->Event->read($id));
}
Then in your form in the Archives/add.ctp file, update each input to reflect the value of the $event.
echo $this->Form->input('eventID', array('type' => 'hidden', 'value' => $event['Event']['id']));
OR
Write a function that will move the record.
Put a button on the Event View called 'Archive'. Create a method in the Event Controller that will archive the event.
public function archive($id = null) {
if ($this->request->is('post')) {
$event = $this->Event->read($id);
$archive['Archive'] = $event['Event'];
$archive['Archive']['event_id'] = $archive['Archive']['id'];
unset($archive['Archive']['id']);
$this->loadModel('Archive');
$this->Archive->create();
if ($this->Archive->save($archive)) {
$this->Session->setFlash(__('The event has been archived'));
$this->Event->delete($id);
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The event could not be archived. Please, contact the administrator.'));
}
}
}

CakePHP check or add user id to posts

I have the following two actions in my controller:
function add()
{
if (!empty($this->data))
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been saved.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
function edit($id = null)
{
$this->Favour->id = $id;
if (empty($this->data))
{
$this->data = $this->Favour->read();
}
else
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been updated.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
1) I want to be able to add the logged in user id to the add action so that the new post is created with that user as its author id (their is a foreign key in the db table). I'm not sure how to talk to fields within the controller itself.
2) And for the edit action I want to make it so that only the author can edit the post so for example user 200 creates post 20 but user 100 cannot edit this post because his id is not 200! I'm not using ACL for my app but just simple authentication.
I've thought about doing a simple if statement in the action like:
function edit($id = null)
{
$this->Favour->id = $id;
$this->Favour->user_id = $user_id;
if($this->Auth->user('id') != $user_id)
{
$this->Session->setFlash('You do not have permission to edit that favour!');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
else
{
if (empty($this->data))
{
$this->data = $this->Favour->read();
}
else
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been updated.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
Would this be correct? BUT how do I get the user id from the favour?
function add() {
if (!empty($this->data)) {
$this->data['Favour']['user_id'] = $this->Auth->user('id');
if ($this->Favour->save($this->data)) {
//etc
This code assumes:
Your user is logged in
the user can access the add function
You are storing the id value of the logged in user in the field id
You have a foreign key in Favours table called user_id that matches the data type of the user id
As for edit; couple ways of achieving it.
I'd do:
function edit($id) {
$this->Favour->id = $id;
$favour_author = $this->Favour->field('user_id');
// get the user of this post
if($this->Auth->user('id') != $favour_author) {
$this->Session->setFlash('You do not own this post.');
$this->redirect('/someplace');
}
if (empty($this->data)) {
$this->data = $this->Favour->read();
}
// carry on.
If you use Auth Component, you can access the logged-in user record in $this->Auth->user() in controller. So to access the id: $this->Auth->user('id'). If you write your own authentication, it's up to you.
how to talk to fields within the controller itself.
What do you mean?

Categories