Cake php RESTfull POST method not working - php

This is my controller function accepting only two parameters user_id,location.
class UserLocationsController extends AppController {
public function add() {
if ($this->request->is('post')) {
$this->UserLocation->create();
if ($this->UserLocation->save($this->request->data)) {
$this->Session->setFlash(__('The user location has been saved.'));
return $this->redirect(array('action' => 'index'));
}
} else {
$this->Session->setFlash(__('The user location could not be saved. Please, try again.'));
}
}
$users = $this->UserLocation->User->find('list');
$this->set(compact('users'));
}
}
when submit the form it is successfully save to data base.but I need to use this with rest client.(without form).I tested it with user_id and location parameters and post method but not saved data to DB.
$this->request->data
is empty when try with rest client. how can I save data without form?

Related

CakePHP Redirecting to the View page after adding a new record

I have a CakePHP lead management website, and when you make a new lead, I want it to redirect you to the view page for that lead, but I can't figure it out.
Here is my current add controller.
/**
* Add method
*
* #return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
*/
public function add()
{
$lead = $this->Leads->newEmptyEntity();
if ($this->request->is('post')) {
$lead = $this->Leads->patchEntity($lead, $this->request->getData());
if ($this->Leads->save($lead)) {
$this->Flash->success(__('The lead has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The lead could not be saved. Please, try again.'));
}
}
$this->set(compact('lead'));
$this->set('user', $user);
}
The line that I am conserned about is return $this->redirect(['action' => 'index']);.
For the edit controller, I was able to do return $this->redirect(['action' => 'view', $id]); but that doesn't work here, and I can't figure it out.
Any help would be appreciated. If it matters, IDs are just a sequential counter in MySQL.
Try this:
/**
* Add method
*
* #return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
*/
public function add()
{
$lead = $this->Leads->newEmptyEntity();
if ($this->request->is('post')) {
$lead = $this->Leads->patchEntity($lead, $this->request->getData());
if ($savedLead = $this->Leads->save($lead)) {
$this->Flash->success(__('The lead has been saved.'));
return $this->redirect(['action' => 'view', $savedLead->id]);
} else {
$this->Flash->error(__('The lead could not be saved. Please, try again.'));
}
}
$this->set(compact('lead'));
$this->set('user', $user);
}
Here, you need to set a variable containing the result of recording you saved (savedLead in your case). This variable will contain the id of the newly saved recording, and you can pass it to your view method.
Whats the problem with
return $this->redirect(['action' => 'view', $lead->id]);
?

CakePHP saving foreignKeys not working

I have 3 tables: Computers hasMany Brands, Brands belongsTo Computers and Parts. Now i have these fields in my Brands description,computer_id,part_id. I have the code below to save my data. It will save the description and part_id....But my computer_id does not save at all.
Usually my URL written http://192.168.6.253/computers/brands/add/1 where 1 is computer_id.
How will I save it? Im still beginner in this framework
Controller
public function add($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
//Assign value to link computer_id
$data = $this->Brand->Computer->findById($id);
$this->set('computers', $data);
//assign select values to parts select
$this->set('parts', $this->Brand->Part->find('list',
array('fields' => array('description'))));
if ($this->request->is('post')) {
$this->Brand->create();
if ($this->Brand->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
$this->redirect(array('action' => 'table/'.$id));
} else {
$this->Session->setFlash(__('Unable to add your post.'));
}
}
}
View
<?php
echo $this->Form->create('Brand');
echo $this->Form->input('part_id',array('empty'=>' '));
echo $this->Form->input('description');
echo $this->Form->input('computer_id',array('type'=>hidden));
echo $this->Form->end('Save Post');
?>
If you are not requiring to send the computer id through the form since it's a url param... you can adjust your add function like this
if ($this->request->is('post')) {
$this->request->data['Brand']['computer_id'] = $id; //manually add the id to the request data object
$this->Brand->create();
if ($this->Brand->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
$this->redirect(array('action' => 'table/'.$id));
} else {
$this->Session->setFlash(__('Unable to add your post.'));
}
}
That's a very basic way of doing it without checking for data integrity, anyone could easily change the param to a 2, but it conforms with your current setup.

CakePHP isAuthorized not working properley when passing arguments

I'm using isAuthorized to deny access to methods if the record id doesn't belong to the user. Profiles can have many documents and documents belong to one profile:
Controller/DocumentsController.php
public function add($id = null) {
if ($this->request->is('post')) {
$this->request->data['Document']['profile_id'] = $id;
$this->request->data['Document']['user_id'] = $this->Auth->user('id');
$this->Document->create();
if ($this->Document->save($this->request->data)) {
$this->Session->setFlash(__('The document has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The document could not be saved. Please, try again.'));
}
}
}
public function isAuthorized($user) {
if ($this->action === 'index') {
return true;
}
if (in_array($this->action, array('view', 'add', 'edit', 'delete'))) {
$document_id = $this->request->params['pass'][0];
if ($this->Document->isOwnedBy($document_id, $user['id'])) {
return true;
}
}
return parent::isAuthorized($this->Auth->user());
}
Model/Document.php
public function isOwnedBy($document, $user) {
return $this->field('id', array('id' => $document, 'user_id' => $user)) === $document;
}
I'm passing the profile id as $id to docments/add from one of my profile views via Cake link helper:
View/Profiles/view.ctp
echo $this->Html->link('New Document',
array('controller' => 'documents', 'action' => 'add',$profile['Profile']['id'])
);
What happens when I click on New Document from profiles/view is that it sends the request but doesn't redirect, just refreshes the page, or it redirects back to profiles/view, not sure which. My first guess is since I'm not defining the profile id in the isAuthorized callback within DocumentsController, isOwnedBy is returning false. Any suggestions on how to get the profile id in isAuthorized within DocumentsController?
Thanks in advance!
The solution to this is relativley easy. When using isAuthorized with parameters from another controller, be sure to reference the right model.
if ($this->Document->Profile->isOwnedBy($document_id, $user['id'])) {
return true;
}

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.'));
}
}
}

MVC undrestandig

i research about mvc and n-tier architecture different. but i can't understand how model pass data to view in mvc?
for example in cakephp I have an controller and action like this:
function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid user', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
if ($this->User->save($this->data)) {
$this->Session->setFlash(__('The user has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->User->read(null, $id);
}
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));
}
in this section:
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid user', true));
$this->redirect(array('action' => 'index'));
}
we check that id passed or not. if have not be set we redirect user. than:
if (!empty($this->data)) {
if ($this->User->save($this->data)) {
$this->Session->setFlash(__('The user has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
}
}
if submitted data from view we update row in db. then :
if (empty($this->data)) {
$this->data = $this->User->read(null, $id);
}
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));
and if id have been set and if not data submitted its mains the page early opened and data in relation this id will be read from db and displayed in view.
now I can't understanding how and where model pass data to view in this cakephp's standard mvc????
thanks for help.
Models do not send data to the view. controllers do, by calling the set method. controllers use models to get data from database and then send it to the view:
$this->set('myVariable','myValue');
or you can use compact to send complex data at once like in your example:
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));

Categories