On my app a user may or may not have a profile. An example would be:
Array
(
[User] => Array
(
[id] => 7
[username] => noprofile
[password] => 3b8cdb0c849f00f3634d9b29def1dac4e9235795
[email] => noprofile#noprofile.com
[status] => 0
[code] => 114a10ebb6ffe364805aa70cd44bee7c
)
[Profile] => Array
(
[id] =>
[firstname] =>
[lastname] =>
[gender] =>
[dob] =>
[user_id] =>
)
)
Here the user noprofile has no matching content in the profiles table.
How do I show a 404 for when this happens? I've tried:
public function view ( $username )
{
$this->Profile->User->recursive = 2;
$profile = $this->Profile->User->find('first', array(
'conditions' => array('User.username' => $username)
));
if (empty($profile))
{
echo 'echo1';
throw new NotFoundException('No profile');
}
else {
echo 'echo2';
}
$this->set(compact('profile'));
}
But it doesn't show the 404! I'm using CakePHP 2.0.
It's because it finds the user so therefore profile is not empty! How do I check for the profile being empty then?
cakephp 2.0 has changed the way to display errors. Now you have to throw an exception. In your case, instead of :
$this->cakeError('error404');
you have to do:
throw new NotFoundException();
Edited:
On the other hand, you migth want to do a JOIN in your find query (and recursive -1), to foce the query to retreive the user's info ONLY if he has a profile.
Hope this helps
if (empty($profile['Profile']['id'])) {
throw new NotFoundException();
}
I expect there are better ways to do it but that's a quick fix. $profile, as you said, will not be empty as the user is found.
Related
I have a form that produces the following array upon submition (see below).
I am using this data in my controller to perform several operations, after which I save each one individually. (Saving them all at once is not an option).
What I would need to do is to find a way to validate each of this models.
I have tried already:
$this->Model->set($pertinentData);
$this->Model2->set($pertinentData);
if($this->Model->validates() && $this->Model2->validates()){
//Do whatever
}
This produces unaccurate results, says it validates when I can see it doesn't and viceversa.
Anybody has any idea of a viable option? Ain't there a way to create a tableless model where I can define validation rules for these fields like:
Order.package_id
User.first_name
etc...
Any idea is appreciated. Below the array that the form produces.
Thanks.
Array
(
[Order] => Array
(
[id] => 15
[package_id] => 1743
[tariff_id] => 5470
[tarjeta] => 332
[numero_tarjeta] => 121204045050
[vencimiento_tarjeta] => 10/20
[cod_tarjeta] => 170
[titular_tarjeta] => JESUS CRISTO
[tarjeta_nacimiento] => 22/04/1988
[tarjeta_pais] => Argentina
[tarjeta_provincia] => Buenos Aires
[tarjeta_ciudad] => Ciudad
[tarjeta_cp] => 1428
[tarjeta_calle] => Calle
[tarjeta_numero] => 1477
[tarjeta_piso] => 2
)
[User] => Array
(
[id] =>
[email] => bla8#gmail.com
[phone] => 1568134449
[first_name] => Jesus
[last_name] => Something
[documento_tipo] => dni
[dni] => 335556666
[nacionalidad] => argentino
[birthdate] => 22/04/2019
)
[OrdersCompanion] => Array
(
[1] => Array
(
[first_name] => Chango
[last_name] => Mas
[documento_tipo] => dni
[dni] => 445556666
[nacionalidad] => argentino
[birthdate] => 30/02/2010
)
[1] => Array
(
[first_name] => Chango
[last_name] => Mas
[documento_tipo] => dni
[dni] => 445556666
[nacionalidad] => argentino
[birthdate] => 30/02/2010
)
)
)
You can usea tableless model by defining $useTable= false in the model. Like this
public $useTable = false;
Define all your custom validation and, of course, your schema (since your model has no table you have to define manually the model schema). Then in your controller, you must first indicate that it has no model, and then declare the $model variable. This is to avoid the automatic model-controller binding of cakePHP, your controller would look like this
public $useModel = false;
$model = ClassRegistry::init('ContactOperation');
Now your model is related to your controller as you want, and you can easily make your custom validation, previously defined.
$model->set($this->request->data);
if($model->validates()) {
$this->Session->setFlash(_('Thank you!'));
// do email sending and possibly redirect
// elsewhere for now, scrub the form
// redirect to root '/'.
unset($this->request->data);
$this->redirect('/');
} else {
$this->Session->setFlash(_('Errors occurred.'));
// display the form with errors.
}
You can find more detail from here
i want to make if clause for button. If admin is logged in it will shown otherwise not.
if($this->Session->User['role'] == 'admin') {
echo
'<li> <ul class="pull-right">Admin skiltis</ul></li>';
}
I can't get that role from session and compare if it admin or not..
Using $_SESSION['Auth']['User'] directly is a bad practice, as depending how the AuthComponent is configured, it may not be available.
You should better pass the authenticated user from the controller to the views and then only check his properties:
AppController:
$authenticated_user = $this->Auth->user();
if(isset($authenticated_user))
{
$this->set(compact('authenticated_user'));
}
Views:
if(isset($authenticated_user) && $authenticated_user['role'] == 'admin'){
...
}
By the way you should also use the HtmlHelper in your views to generate links instead of printing <a> tags manually with hardcoded urls to benefit from many Cake features.
Try to make a little debug on your code.
First check if your session was started.
You can do this by executing the command "session_status()" if the result is "PHP_SESSION_NONE" your session isnt started. You can fix it by putting a "session_start()" before any print was made by your page.
If value of print_r($_SESSION); is something like,
Array ( [Config] => Array ( [userAgent] => 4df452d8263aa05ef9324f37499322b0 [time] => 1401090120 [countdown] => 10 ) [Message] => Array ( ) [Auth] => Array ( [User] => Array ( [id] => 8 [username] => aaaaa [email] => aaa#gmail.com [role] => admin [created] => 2014-05-26 02:43:20 [modified] => 2014-05-26 02:43:20 [status] => 1 ) ) )
Thae try this code, I think it will work,
if($_SESSION['Auth']['User']['role'] == 'admin') {
echo
'<li> <ul class="pull-right">Admin skiltis</ul></li>';
}
I have a hasMany through with Course, User, and CourseMembership
I am trying to create an unsubscribe button on the Courses view. At the moment this is the array I have:
(
[Course] => Array
(
[id] => 1
[name] => Flying
[description] => Oh! The Magic!
[created] => 2014-03-05 14:45:21
[modified] => 2014-03-05 14:45:21
)
[Lesson] => Array
(
[0] => Array
(
[id] => 1
[title] => Growing Wings
[description] => Here's how you grow wings!
[course_id] => 1
[created] => 2014-03-05 14:19:38
[modified] => 2014-03-05 14:19:38
)
[1] => Array
(
[id] => 2
[title] => Taking Flight
[description] => You are finally ready to take flight.
[course_id] => 1
[created] => 2014-03-06 11:49:51
[modified] => 2014-03-06 11:49:51
)
)
[CourseMembership] => Array
(
[0] => Array
(
[id] => 1
[user_id] => 4
[course_id] => 1
)
)
)
I set up a CourseMemberships controller with a delete action.
But I am having trouble setting up the model in Courses to distinguish the appropriate ID of the CourseMembership where the user_id is the logged in user (CakeSession::read("Auth.User.id");) and the course is the current course.
Edit:
Here's the Courses unsubscribe() controller:
public function unsubscribe($id = null) {
$this->Course->id = $id;
$userid = CakeSession::read("Auth.User.id");
if (!$this->Course->exists()) {
throw new NotFoundException(__('Invalid course'));
}
$this->request->onlyAllow('post', 'delete');
if ($this->Course->CourseMembership->delete(array('CourseMembership.user_id'=> $userid))) {
$this->Session->setFlash(__('The course has been deleted.'));
} else {
$this->Session->setFlash(__('The course could not be deleted. Please, try again.'));
}
return $this->redirect(array('action' => 'index'));
}
Edit:
Here's the link I'm creating to unsubscribe.
<?php echo $this->Form->postLink(__('Unsubscribe'), array('controller' => 'CourseMemberships', 'action' => 'unsubscribe', $course['Course']['id'], CakeSession::read("Auth.User.id")), null, __('Are you sure you want to delete # %s?', $course['Course']['id'])); ?>
If I understand correctly, you want to delete the subscription to a specific course of the user logged in. So in your unsubscribe action in the Courses controller you may be have something like this:
// Courses Controller
public function unsubscribe($id = null){
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Course->id = $id;
if (!$this->Course->exists()) {
throw new NotFoundException(__d('Course', 'Invalid course'));
}
if($this->Course->CourseMembership->unsubscribe($id, CakeSession::read('Auth.User.id'))){
$this->Session->setFlash(__d('Course', 'Unsubscribed!'));
$this->redirect(array('controller' => 'courses', 'action' => 'go_here_etc'));
}
$this->Session->setFlash(__d('Course', 'Attention! Not Unsubscribed!'));
$this->redirect(array('controller' => 'courses', 'action' => 'go_here_etc'));
}
//CourseMembership Model
public function unsubscribe($courseId, $userId){
// I assume that each user can subscribe only one time the same course. This calls the ids inputted in the unsubscribe link.
return $this->deleteAll(array('CourseMembership.course_id' => $courseId, 'CourseMembership.user_id' => $userId));
}
I am trying to make my way through an inherited Yii Framework site. Very little Object Oriented knowledge previously.
I'm printing some user information to see what is there like this...
print_r(Yii::app()->user);
And that's printing out this...
CWebUser Object (
[allowAutoLogin] => 1
[guestName] => Guest
[loginUrl] => Array
(
[0] => /site/login
)
[identityCookie] =>
[authTimeout] => 7200
[autoRenewCookie] =>
[autoUpdateFlash] => 1
[loginRequiredAjaxResponse] =>
[_keyPrefix:CWebUser:private] => 7c6285462394c9a141b5d66dce54e8f2
[_access:CWebUser:private] => Array
(
[Admin] =>
[Judge] =>
[Student] => 1
)
[behaviors] => Array
(
)
[_initialized:CApplicationComponent:private] => 1
[_e:CComponent:private] =>
[_m:CComponent:private] =>
)
I'm trying to get out the information that this user is a Student. I see it! It's ]there!
[Student] => 1
But how would I get that information out?
UPDATE:
Here's the parts of CWebUser that appear to have something to do with _access
private $_access=array();
public function checkAccess($operation,$params=array(),$allowCaching=true)
{
if($allowCaching && $params===array() && isset($this->_access[$operation]))
return $this->_access[$operation];
$access=Yii::app()->getAuthManager()->checkAccess($operation,$this->getId(),$params);
if($allowCaching && $params===array())
$this->_access[$operation]=$access;
return $access;
}
The following should tell you whether the user has 'Student' access:
$isStudent = Yii::app()->user->checkAccess('Student') == 1;
'student' is part of the $_access array. But $_access is private so you can not access it directly.
But there must be a method (function) to get it!
look in the CWebUser class there should be a method like
getStudent();
isStudent();
or may be
$access = getAccess();
$access['student'];
Edit:
checkAccess
seems to be used someting like this checkAccess('student');
I'm working on retrieving a stack of data and for some reason some of the data gets corrupted. For instance, I've got some Post models that each are related to Comment models (hasMany), and each of the Comment models belongsTo a User. When retrieving the data, here's what I get from the database for the comments:
[Post] => Array
(
)
[Comments] => Array
(
[0] => Array
(
[content] => "2010 has definitely been a busy year!"
[created] => 2010-02-10 13:47:15
[user_id] => 18
[post_id] => 1
[User] => Array
(
[id] => U8
[username] => Uace
[first_name] => Uace
)
[_explicitType] => Comment
)
[0] => Array
(
[content] => "I can't wait..."
[created] => 2009-12-10 13:57:36
[user_id] => 18
[post_id] => 1
[User] => Array
(
[id] => U8
[username] => Uace
[first_name] => Uace
)
[_explicitType] => Comment
)
)
The first character of each of the Comments[i][User] arrays has been replaced with a capital U, though in each case it should be different (such as ID of 18, username of Jace, etc).
I traced it back to an array manipulation I was working with to assign an _explicitType field for Flex interaction (Thanks, Paweł Mysior!) in the afterFind() function. Here's the loop where I stuck in the _explicitType:
if (is_array($results)) {
foreach ( $results as &$item )
{
$item['_explicitType'] = $this->name;
}
} else {
$item[$this->name]['_explicitType'] = $this->name;
}
I assume it has to do with the assignment by reference, but I can't think of why it is happening.
It is very strange.
Set debug to 2 in core.php and look in the sql log at the bottom of the page, maybe you'll find something there. Also look through all models (app, post, user, comment). There might be some beforeFind() that are causing this to happen. Does it also happen when you do a simple User->find()?
Btw. how do you retrieve data here?
I think found the issue. I moved the check for the array inside the foreach() and that seems to be working correctly now. I assume this is because on non-array items, it actually broke things. Here's my altered loop with logging on the test cases:
foreach ( $results as &$item )
{
if(is_array($item)) {
$item['_explicitType'] = $this->name;
} else {
$copy = $item;
$copy['_explicitType'] = $this->name;
$this->log($copy, LOG_DEBUG);
}
}
And sure enough, it logged the data with capital U's replacing the first letter.