I'm trying to access data in my Model for my controller method.
For starters what is the difference between these two???
$post = $this->Post->find('first',array('conditions'=>array('Post.id'=>$id)));
$this->set(compact('post'));
and
$this->Post->id = $id;
$this->data = $this->Post->read();
as I'm trying to compare the user_id for a post against the logged in user like so:
if($this->Post->user_id != $this->Auth->user('id'))
but it doesn't work as intended (it always returns false)... what is the difference between the two code chunks and why doesn't my line above work properly?
test to see if it helps to compare this code "userid":
function index() {
$user_id = $this->data['Post']['user_id'];
if($user_id != $this->Auth->user('id')){
//go
}
}
This is what I ended up with:
$post = $this->Post->find('first',array('conditions'=>array('Post.id'=>Tiny::reverseTiny($id))));
if ($this->request->is('post') || $this->request->is('put'))
{
$this->Post->id = $post['Post']['id'];
if ($this->Post->save($this->request->data))
{
$this->Session->setFlash('Your post has been updated');
$this->redirect(array('controller' => 'posts', 'action' => 'index'));
}
else
{
$this->Session->setFlash('Server broke!');
}
}
else
{
if($post['Post']['user_id'] != $this->Auth->user('id'))
{
$this->Session->setFlash('Not yours!');
$this->redirect(array('controller' => 'posts', 'action' => 'index'));
}
else
{
$this->request->data = $this->Post->read(null, $post['Post']['id']);
}
}
There are differences between find() and read(), read will grab all related model data and set the active record of the model to the result. Whereas a find will just all related model data in a query and assign the result to the variable.
Use debug($this->data) to reveal the structure of your returned data. You will find it is $this->data['Post']['user_id'] for the User ID.
Related
I need to check if a user is existing in the mgrUser table. now the propblem is the controller is in the adminController while the model is in the mgrUserModel. how do i use Auth for this? Thats the reason why I made a generic login code.
public function login() {
// if ($this->Auth->login()) {
// return $this->redirect($this->Auth->redirectUrl());
// }
// $this->Flash->error(
// __('Username ou password incorrect')
// );
//since the model is in a different view, I needed to includ the mgrModel and create a generic login
//will revamp the code to fit the built in Aut code for php cake
if(isset($_POST['submit'])) {
$User_ID = htmlspecialchars($_POST['user_id']);
$Pass = htmlspecialchars($_POST['pass']);
try {
$mgrUserModel = new MgrUser();
$isValid = $mgrUserModel->find('first', array(
'conditions' => array("user_id" => $User_ID)
));
if($isValid != null){
if (($isValid['MgrUser']['pass']) == $Pass) {
//this doesnot work
$this->Auth->allow();
$this->redirect($this->Auth->redirectUrl());
}
else{
}
}
} catch (Exception $e) {
//echo "not logged in";
}
// this echo will show the id and pass that was taken based on the user_id and pass that the user will input
//for testing only
// echo $isValid2['MgrUser']['id'];
// echo $isValid2['MgrUser']['pass'];
}
}
You need double == to compare things,
function checkMe()
{
if($user == 'me'){
$this->Auth->allow('detail');
}
}
what you did was assign "me" string to variable $user which always returns true because assignment was possible
Anyway you should use it in beforeFilter which is running before every action from this controller, which makes much more sense
public function beforeFilter() {
parent::beforeFilter();
if($user == 'me'){
$this->Auth->allow('detail');
}
}
the Auth component could be configured to read the user information via another userModel (The model name of the users table). It defaults to Users.
please consult the book for appropriate cakephp version: https://book.cakephp.org/3.0/en/controllers/components/authentication.html#configuring-authentication-handlers
I am new to this and I have reached an impasse that has got me stuck for the past day
I have 3 tables Posts,Categories, and Users with a 1-many relationship where a category can have many posts.
The category table simply has two fields : id and cat_desc, with id being set as the primary key
in my postscontroller I have an add function
public function add() {
if ($this->request->is('post')) {
$data = $this->Post->Cat->find('list', ['fields' => array('cat_desc')]);
$this->set('cats', $data);
$this->request->data['Post']['user_id'] = $this->Auth->user('id');
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
}
$this->set('title_for_layout',"'Add a Post");
}
in my view i try to call the list for the dropdown
echo $this->form->create('Post', array('action'=>'add'));
echo $this->form->input('title');
echo $this->Form->input('category', array('options' => array('options'=> $cats))
);
echo $this->form->input('amount');
echo $this->form->input('body');
echo $this->form->end(__('Create a Post', true));
I am getting an undefined variable cats. Any help would be greatly appreciated and I thank you all for your posts as it has helped get me to this point :)
When you first navigate to the page, the request type will be "get". The way your code is, $cats will only be set if the request type is a "post" (so it will only be defined when you submit the form.) Just move the code that sets $cats to outside the if statement if($this->request->is('post'))
//controller
public function add() {
if ($this->request->is('post')) {
$this->request->data['Post']['user_id'] = $this->Auth->user('id');
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
} else {
$cats = $this->Post->Cat->find('list', ['fields' => array('cat_desc')]);
$this->set('cats', $cats);
$this->set('title_for_layout',"'Add a Post");
}
}
//view
echo $this->Form->input('cat_id', $cats, array(options here));
When register action tries to save data nothing happens and user gets returned to same page
after some debugging I found when running '$this->Participant->create()' it returns no new id
if ($this->request->is('post') || $this->request->is('put')) {
if (!isset($this->data['Participant']['typeSel'])) {
$regType = $this->data['Participant']['type'];
// for pilots and visitors, copy the name/email from TeamMember to Participant
if ($regType == 'pilot' || $regType == 'visitor') {
$this->request->data['Participant']['name'] =
ucwords(strtolower($this->request->data['TeamMember'][0]['first_name'])) . ' '
. ucwords(strtolower($this->request->data['TeamMember'][0]['family_name']));
$this->request->data['Participant']['email'] = $this->request->data['TeamMember'][0]['email'];
}
// mark valid inside the team (if not joining)
if ($regType != 'jointeam') {
foreach ($this->request->data['TeamMember'] as & $teamMember) {
$teamMember['validate_inteam'] = 'yes';
if ($regType == 'visitor') {
$teamMember['free_entrance'] = 'yes';
$teamMember['num_tables'] = 0;
}
}
$numTeamMembers = count($this->data['TeamMember']);
}
// set password
$this->request->data['Participant']['password'] =
Security::hash($this->data['Participant']['password1'], null, true);
// perform registration itself
if ($regType == 'jointeam') {
$this->TeamMember->create($this->request->data);
if ($this->TeamMember->save($this->request->data)) {
$this->Session->setFlash('Your registration was recorded. An email was dispatched to the team coordinator for approval.');
$this->Mail->sendTeamValidationEmail(
$this->Participant->findById($this->data['TeamMember']['participant_id']));
$this->redirect(array(
'controller' => 'pages',
'action' => 'welcome'));
}
else {
$this->Session->setFlash('Your registration could not be completed. Please try again.');
}
}
else {
$this->Participant->create(); // $this->Participant->id remains empty
if ($this->Participant->saveAll($this->request->data)) {
$this->Session->setFlash('Your registration was recorded. You will receive an email with further details during the next 24 hours.');
$this->Mail->sendConfirmEmail($this->Participant->findById($this->Participant->id));
$this->redirect(array(
'controller' => 'pages',
'action' => 'welcome'));
}
else {
$this->Session->setFlash('Your registration could not be completed. Please try again.');
}
}
}
}
How can I get the create function to add the id.
There seems to be no problem with the DB because you can log in and fetch data on other controllers
You are misunderstanding what those methods do.
$this->Participant->create();
It clears the model (unsets the id), so does the exact opposite of what you expect.
This method is needed for Cake to actually make it possible to create a new record using save(), saveMany(), saveAll() etc.
Those methods then set the Model->id again (after a successful save of course).
Also, using saveAll() you should rather look at callbacks if you need those IDs, as it can only provide you with the id of the last stored record then this way (it will overwrite it for each save).
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;
}
I've noticed that their is many different ways to pass an ID to a form when editing a database entry. So for example for a edit user profile form I have the following code:
function edit($id = null)
{
$this->layout = 'page';
// this line isn't needed?
//$this->User->id = $id;
if (empty($this->data))
{
$this->data = $this->User->read();
}
else
{
if ($this->User->save($this->data))
{
$this->Session->setFlash('Your profile has been updated', 'flash', array('header' => 'Announcement', 'myclass' => 'success'));
$this->redirect(array('controller' => 'users', 'action' => 'view', $id));
}
}
}
Now the function expects an id passing in the url e.g. /users/edit/2 But let's say I wanted it to be something more user friendly like /profile/edit (rewrote by routing) I would no longer be passing in the ID as part of the url. As you can see in my code I have a line I have commented out because it isn't needed?
Also in the form I ALSO Need <?php echo $this->Form->input('id', array('type' => 'hidden')); ?> why?
Basically this is more of what are the options available to me to build various types of edit forms and passing data to the form. And what is the need for the hidden field in the form if the data is being passed either via the URL or some other way
I've also noticed on some sites that they have things like Form Keys and the username stored in meta tags in the page header???
EDIT:
public function beforeFilter()
{
$this->set('authUser', $this->Auth->user());
//
$user = $this->Auth->user();
if (!empty($user))
{
Configure::write('User', $user[$this->Auth->getModel()->alias]);
}
}
public function beforeRender()
{
$user = $this->Auth->user();
if (!empty($user))
{
$user = $user[$this->Auth->getModel()->alias];
}
$this->set(compact('user'));
}
// NEW VERSION
function settings()
{
$this->layout = 'page';
$this->set('title_for_layout', 'Edit Profile');
$this->User->id = $user['id'];
if (empty($this->data))
{
$this->data = $this->User->read();
}
else
{
if ($this->User->save($this->data))
{
$this->Session->setFlash('Your settings have been updated', 'flash', array('myclass' => 'success'));
$this->redirect(array('controller' => 'users', 'action' => 'settings'));
}
}
}
Also in the form I ALSO Need Form->input('id',
array('type' => 'hidden')); ?> why?
Having the id hidden in the form removes the need for your controller action to grab the $id from the uri (aka passed as parameter). When in the form, it will automatically be placed into your $data array.
what is the need for the hidden field
in the form if the data is being
passed either via the URL or some
other way
It's not needed in the form if it's available from the uri. You'd simply grab the $id and assign it to the User model (as the commented out code does).
let's say I wanted it to be something
more user friendly like /profile/edit
I assume that would be when the user is editing his own profile. In that case, your system should be able to retrieve the user's id via the session.