I've been runing on my issue all night long tried many method to update an entry of User model and I didn't figure it out.
I tried with saveField, updateAll and findBy then save but all i've got is new entry on my DB or no update.
Here is the code, Hope you'll help
<?php
public function email_verification($token) {
$this->User->create();
$user = $this->User->findByEmailToken($token);
$this->User->set(array('email_token' => 'valid'), $user);
$this->User->save($user, false);
}
?>
Thanks in advance
Ahum:
$this->User->set(array('email_token' => 'valid'), $user);
$this->User->save($user, false);
The save() call saves your record with your original data..... since you pass in $user!
Replace the call to $this->user->set() with:
$user['User']['email_token'] => 'valid';
Try code below:
<?php
public function email_verification($token) {
$user = $this->User->findByEmailToken($token);
$user['User']['email_token'] = 'valid';
if ($this->User->save($user)) {
....
....
} else {
debug($this->User->validationErrors);
}
}
?>
Related
I'm working on a project using CakePHP 3.x.
I have UserAddress, ServiceRequests, Service models.
There is a button on service/view/$id which when clicked will ask user to select address from service-requests/serviceArea which has a list of addresses added by user. service-requests/serviceArea view will contain a select button which when clicked will call add action in ServiceRequests controller with passing two parameters serviceId and userAddressId
This is the serviceArea function created by me.
public function serviceArea($id = null)
{
public $uses = array('UserAddress');
$service = $id;
$query = $userAddresses->find('all')
->where(['UserAddresses.user_id =' => $this->Auth->user('id')]);
$this->set(compact('userAddresses'));
$this->set('_serialize', ['userAddresses']);
}
How to display the address and also pass the $service parameter to the serviceArea view.
I am new to CakePHP, so if you think question is incomplete any edit to it will be appreciated instead of down-voting.
Thank You.
Edit 2
Thank for your answer #jazzcat
After changing my code according to yours and visiting http://domain.com/service-requests/service-area/$id. It is showing error as
Record not found in table "service_requests"
and pointing to the ServiceRequestsController on line no 33
The ServiceRequestController as containing line no 33 is
<?php
namespace App\Controller;
use App\Controller\AppController;
/**
* ServiceRequests Controller
*
* #property \App\Model\Table\ServiceRequestsTable $ServiceRequests
*/
class ServiceRequestsController extends AppController
{
/**
* isAuthorized method
*
*/
public function isAuthorized($user)
{
$action = $this->request->params['action'];
// The add and index actions are always allowed.
if(in_array($action, ['index', 'add', 'serviceRequests'])) {
return true;
}
// All other actions require an id.
if (empty($this->request->params['pass'][0])) {
return false;
}
// Check that the service request belongs to the current user.
$id = $this->request->params['pass'][0];
$serviceRequest = $this->ServiceRequests->get($id); // line : 33
if($serviceRequest->user_id == $user['id']) {
return true;
}
return parent::isAuthorized($user);
}
/* Other actions */
}
?>
This worked for me.
Just added the serviceArea action name in the isAuthorized method
if(in_array($action, ['index', 'add', 'serviceArea'])) {
return true;
}
and it's working fine as expected.
There is alot wrong with your code. Please read the docs
Is the table named user_addresses or user_address ?
You seem to mix the both.
The following would be the correct way to do it assuming your table is named user_addresses
public function serviceArea($id = null)
{
$this->loadModel('UserAddresses');
$userAddresses = $this->UserAddresses->find('all')
->where(['UserAddresses.user_id =' => $this->Auth->user('id')]);
// If you want to filter on the serviceArea ID aswell
if($id)
$userAddresses->andWhere(['id' => $id]);
// Setting SerivceArea ID to compact makes it available in view.
$serviceAreaId = $id;
$this->set(compact('userAddresses', 'serviceAreaId'));
$this->set('_serialize', ['userAddresses']);
}
This snippet:
$id = $this->request->params['pass'][0];
$serviceRequest = $this->ServiceRequests->get($id); // line : 33
Just checks if the first parameter passed to the method exists in ServiceRequests.
(That parameter could be anything, you have to keep that in mind when creating all your methods in that controller, that is to say the least.. bad)
I'm assuming that the service_requests table is associated with the users table and an user_id column exists in the service_requests table.
If that is the case this should work:
public function isAuthorized($user)
{
$action = $this->request->params['action'];
// The add and index actions are always allowed.
if(in_array($action, ['index', 'add'])) {
return true;
}
// Is not authorized if an argument is not passed to the method.
// Don't know why you'd want this , but sure.
if (empty($this->request->params['pass'][0])) {
return false;
}
// Check that the service request belongs to the current user.
$user_id = $this->Auth->user('id');
$serviceRequest = $this->ServiceRequests->find()->where(['ServiceRequests.user_id' => $user_id])->first();
if(!empty($serviceRequest)) {
return true;
}
return parent::isAuthorized($user);
}
I have used a component for uploading image,there is no problem in controller after add component.Here the code
class OesUsersController extends AppController {
var $helpers = array('Html', 'Form');
var $components = array('upload');
public function index() {
}
public function upload()
{
if (empty($this->data))
{
$this->render();
}
else
{
$this->cleanUpFields();
// set the upload destination folder
$destination = realpath('../../app/webroot/img/uploads/') . '/';
// grab the file
$file = $this->data['Image']['filedata'];
// upload the image using the upload component
$result = $this->Upload->upload($file, $destination, null, array('type' => 'resizecrop', 'size' => array('400', '300'), 'output' => 'jpg'));
if (!$result){
$this->data['Image']['filedata'] = $this->Upload->result;
} else {
// display error
$errors = $this->Upload->errors;
// piece together errors
if(is_array($errors)){ $errors = implode("<br />",$errors); }
$this->Session->setFlash($errors);
$this->redirect('/images/upload');
exit();
}
if ($this->Image->save($this->data)) {
$this->Session->setFlash('Image has been added.');
$this->redirect('/images/index');
} else {
$this->Session->setFlash('Please correct errors below.');
unlink($destination.$this->Upload->result);
}
}
}
The problem is image doesn't come from add.ctp
here the add.ctp code
<label for="Image">Image:</label>
<input type="file" name="data[Image][filedata]" id="ImageFiledata" />
add function code
public function add() {
$clint_ip=$this->request->clientIp();
if ($this->request->is('post')) {
$this->OesUser->create();
pr($this->request->data);
$this->request->data['OesUser']['user_otpkey']=String::uuid();
$this->request->data['OesUser']['user_regdate']=date("Y-m-d H:i:s");
$this->request->data['OesUser']['user_ip']=$clint_ip;
$this->barcode($this->request->data['OesUser']['user_otpkey']);
if ($this->OesUser->save($this->request->data)) {
$this->Session->setFlash(__('The oes user has been saved'), 'flash_success');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The oes user could not be saved. Please, try again.'), 'flash_fail');
}
}
$this->set('ip',$clint_ip);
}
here, database field name: image
controller name :OesUsers
Model name :OesUser
for full work I have taken help from this link
http://labs.iamkoa.net/2007/10/23/image-upload-component-cakephp/
How is your entire form looks like in add.ctp?
It sounds to me that you did not add
enctype="multipart/form-data"
to the form. That will cause the form not to post the file.
And also, it is recommended to use Form helper to create form.
When using Form helper, specify the form type to file
$this->Form->create('model',array('type'=>'file'));
My question is how can I refresh my view "search.ctp" to take into account the record I just deleted. The problem is the following.
My controller code
public function search() {
if ($this->request->is('post')) {
$this->set("isPost", TRUE);
$query = $this->data;
$output = $this->Question->find("all", array("conditions"=>array("Question.lectureId"=>$query["Lecture"]["Lecture"],
"Question.type"=>$query["Lecture"]["status"])));
$this->set("questions", $output);
} else {
$this->LoadModel("Lecture");
$outputL = array();
$for = $this->Lecture->find("all", array("fields" => array("_id", "title")));
foreach ($for as $key => $value) {
$outputL[$value["Lecture"]["_id"]] = $value["Lecture"]["title"];
}
$this->set("lectures",$outputL);
//
$statuses = array(
"" => "Select a question type",
"anonymousQuestion" => "anonymousQuestion",
"handUp" => "handUp",
"userQuestion" => "userQuestion"
);
$this->set("statuses", $statuses);
}
}
So the following happens;
I open the view "search.ctp" ("my admin interface"), set the 2 search params,
and use the submit button to post that data. Then my IF statement recognizes that as POSt and gives me back my query results. The problem is when i delete a record...
It redirects me back to my search action to enter the query params again... How do i just refresh the page with the same query params and NOT leave my view.
o forgot my delete function code:
public function delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Question->id = $id;
if (!$this->Question->exists()) {
throw new NotFoundException(__('Invalid configuration'));
}
if ($this->Question->delete()) {
$this->Session->setFlash(__('Question deleted'));
return $this->redirect(array("action"=>"search"));
}
$this->Session->setFlash(__('Question was not deleted'));
$this->redirect(array('action' => 'search'));
}
As a workaround i made another function that does the same thing with GET request that my search function does with a POST request. Basically returns the data with the query params. And i used the Session helper to carry the query over to my other function. Dont know how smart that was, but it does the trick for me...
Still would be nice to know if someone has a solution where i dont have to make another function/view
This is my test:
public function testIncludeNumComment() {
$post = array(...stuff.....);
$result = $this->Comments->includeNumComments($post);
echo "end"; //this is not printed
$expected =1;
$this->assertEquals($result, $expected);
}
Then, my controller function is this one:
public function includeNumComments($post){
echo "printed";
$comments = $this->Comment->getNumComments($post['Post']['id']);
echo "not printed";
return $comments;
}
As you can see, this call on the controller to the model function doesn't work
$this->Comment->getNumComments($idPost);
And what is more, when i introduce an echo "hi"; at the very start of the getNumComments function inside the Comment model, it is not printed either.
It's like it didn't find the function or something like that. (but it doesn't show any error by screen during the test)
It stops there and it doesn't execute more code.
I am completely sure that function works well, it just returns the number of comments from a post. The question is: why it isn't working on the test case?
Thanks.
UPDATE:
The test setUp looks like this:
public function setUp() {
parent::setUp();
$this->Comments = new TestCommentsController();
$this->Comments->constructClasses();
}
$result = $this->Comments->includeNumComments($post);
this doesnt make much sense if your model is "Comment"
so change it to:
$result = $this->Comment->includeNumComments($post);
Check that you include the TestCommentsController like following:
App::uses('TestCommentsController', 'Controller');
Then write beforeFilter function in AppController like following:
class AppController extends Controller {
......
...
public function beforeFilter() {
// you stuff
}
}
Then add this to you controller which contains test function:
public function beforeFilter(){
parent::beforeFilter();
$this->Comments = new TestCommentsController();
$this->Comments->constructClasses();
}
.....
NOW keep going with...
public function testIncludeNumComment() {
$post = array(...stuff.....);
$result = $this->Comments->includeNumComments($post);
echo "end"; //this is not printed
$expected =1;
$this->assertEquals($result, $expected);
}
This might not be the problem with saveAll, the situation is like this. I have table messages, and table sent_messages, which holds message id and user id. Models are created, where Messaage hasMany SentMessage, and SentMessage belongsTo Message. I need to save just one message in messages table, and save user ids and message id in *sent_messages* table. The problem starts when I try to save that in MessageController. Here is the code:
function custom() {
if (!empty($this->data)) {
$this->loadModel('User');
$userIDs = $this->User->listActiveUsers();
$this->data['Message']['message_type_id'] = 2;
if ($this->Message->save($this->data)) {
array_pop($this->data);
foreach ($userIDs as $key => $value ) {
$this->data['SentMessage'][$key]['user_id'] = $value;
$this->data['SentMessage'][$key]['message_id'] = $this->Message->getLastInsertID();
}
//die($this->Message->SentMessage->saveAll($this->data));
if ($this->Message->SentMessage->saveAll($this->data)) {
$this->Session->setFlash('Data saved', 'success');
}
else {
$this->Session->setFlash('Data not saved', 'error');
}
}
}
}
Any help would be appreciated.
I think your issue come from using "$key" as key for $userIDs array, saveAll take unindexed array for hasMany relations as parameters.
More-over, saveAll is perfect to save two related model in same time. Here something that should work :
function custom() {
if (!empty($this->data)) {
$this->loadModel('User');
$this->data['Message']['message_type_id'] = 2;
$userIDs = $this->User->listActiveUsers();
foreach ($userIDs as $value ) {
$this->data['SentMessage'][]['user_id'] = $value;
}
if ($this->Message->saveAll($this->data)) {
$this->Session->setFlash('Data saved', 'success');
} else {
$this->Session->setFlash('Data not saved', 'error');
}
}
}
Check the doc ! http://book.cakephp.org/view/1031/Saving-Your-Data
About using loadModel, I suppose that your SentMessage model is related to User, so you can use : $this->Message->SentMessage->User. But well no idea of which is the more efficient.
Easiest Way to save all data in cakephp
$this->ModelName->saveAll($data_array);
Note : name of the fields in table and in array should be same.