Routing data via a unique field in CakePHP - php

How do you set up routing to view data via a field other than the ID in CakePHP? I'm trying to view my users via /username/'username' in CakePHP 2.4.
So far, I have this in my routes.php, however I can't figure out how to pass the username to my Users controller and use that instead of an ID if needs be.
Router::connect(
'/username/:username',
array('controller' => 'users', 'action' => 'view'),
array(
'pass' => array('username')
)
);
And my controller function, I have this, which throws a Fatal error: Call to undefined function findByUsername():
public function view($id = null, $username = null) {
if ($user = $this->User-findByUsername($username)) {
$this->set('user', $user);
} elseif ($user != $this->User-findByUsername($username)) {
throw new NotFoundException(__('Invalid user'));
} else {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->set('user', $this->User->find('first', $options));
}
}

First solution
Don't do anything with routers. They are just fine as they are in default CakePHP package. There were couple of syntax errors in your code. This should work when called either
"app/controller/view/-/username"
or
"app/controller/view/id"
Controller action code itself like this
<?php
public function view($id, $username = null) {
if(!is_null($username)) {
if($user = $this->User->findByUsername($username))
$this->set('user', $user);
elseif (count($this->User->findByUsername($username)) == 0)
throw new NotFoundException(__('Invalid user'));
}
else {
if($id == '-') || !$this->User->exists($id))
throw new NotFoundException(__('Invalid user'));
else {
$options = array('conditions' => array("User.{$this->User->primaryKey}" => $id));
$this->set('user', $this->User->find('first', $options));
}
}
}
?>
Second solution
With only one parameter this could be done like this (personally I don't like this, it breaks straightforwardness of Cake-style to do it). Call this like this:
"app/controller/view/username"
or
"app/controller/view/id"
And controller action code itself:
<?php
public function view($param) {
if(!is_numeric($param))) { // $param is not numeric => it is username
if($user = $this->User->findByUsername($param))
$this->set('user', $user);
elseif (count($this->User->findByUsername($param)) == 0)
throw new NotFoundException(__('Invalid user'));
}
else { // $param is numeric => it is id
if(!$this->User->exists($param))
throw new NotFoundException(__('Invalid user'));
else {
$options = array('conditions' => array("User.{$this->User->primaryKey}" => $param));
$this->set('user', $this->User->find('first', $options));
}
}
}
?>

Related

ACL grants access to all Users in Symfony?

I try to understand how ACL works but even if I set them for an item ($client in this case), everybody has access.
SET ACL
public function setACL($repository, $mask, $selectUser = false)
{
$objectIdentity = ObjectIdentity::fromDomainObject($repository);
$acl = $this->aclProvider->createAcl($objectIdentity);
if($selectUser === false){
$user = $this->tokenStorage->getToken()->getUser();
}else{
$user = $this->entityManager->getRepository('AppBundle:User')->find($selectUser);
}
$securityIdentity = UserSecurityIdentity::fromAccount($user);
$acl->insertObjectAce($securityIdentity, $mask);
$this->aclProvider->updateAcl($acl);
return;
}
$selectUser is for setting it manually (via Console Comannd etc.) does it work that way at all?
GET ACL
public function getACL($repository, $granted)
{
if (is_array($repository)) {
foreach ($repository as $rp) {
if (false === $this->authorizationChecker->isGranted($granted, get_class($rp))) {
$this->get('log')->writeLog('Access denied.', __LINE__, 3);
return new JsonResponse(array(
'result' => 'error',
'message' => 'Not allowed'
));
}
}
} else {
if (false === $this->authorizationChecker->isGranted($granted, get_class($repository))) {
$this->get('log')->writeLog('Access denied.', __LINE__, 3);
return new JsonResponse(array(
'result' => 'error',
'message' => 'Not allowed'
));
}
}
return true;
}
Set ACL for $client
$this->get('global_functions')->setACL($client, MaskBuilder::MASK_OWNER);
But when I try to
Get ACL
$this->get('global_functions')->getACL($client, 'VIEW');
I get access with whatever user I am trying this...
Where am I wrong?
Solved it myself...
$this->authorizationChecker->isGranted($granted, get_class($repository)) should be $this->authorizationChecker->isGranted($granted, $repository)

cakephp : go to previous page after editing a player

I have players in pages. I'm for instance on page 13. Here I click on the edit function to edit a player. Now after the edit I want to get back to that page 13 but It stays at the edit page.
edit action :
public function admin_edit($id = null) {
if (!$this->Player->exists($id)) {
throw new NotFoundException(__('Invalid player'));
}
if ($this->request->is(array('post', 'put'))) {
$data = $this->request->data['Player'];
if(!$data['player_image']['name']){
unset($data['player_image']);
}
if ($this->Player->save($data)) {
$this->Session->setFlash(__('The player has been saved.'));
$this->redirect($this->referer());
} else {
$this->Session->setFlash(__('The player could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('Player.' . $this->Player->primaryKey => $id));
$this->request->data = $this->Player->find('first', $options);
}
$videos = $this->Player->Video->find('list');
$this->set(compact('videos'));
}
view action :
public function admin_view($id = null) {
if (!$this->Player->exists($id)) {
throw new NotFoundException(__('Invalid player'));
}
$options = array('conditions' => array('Player.' . $this->Player->primaryKey => $id));
$this->set('player', $this->Player->find('first', $options));
}
You can save the referring page in the else section of the if/else structure of the edit function. Then use that stored value in the if (i.e., $this->request->is(array('post', 'put')) = TRUE section.
So your code would look something like:
public function admin_edit($id = null) {
if ($this->request->is(array('post', 'put'))) {
/* your other code */
$sendback = $this->Session->read('referer');
$this->Session->delete('referer');
$this->redirect($sendback);
} else {
/* your other code */
$this->Session->write('referer', $this->referer());
}
}

MD5 password Login, not working

I'm trying to make a new Login/Register System. My users are able to register now but i cant get the information when they try to login
if(Input::exists()){
if (Token::check(Input::get('token'))){
$validate = new Validate();
$validation = $validate->check($_POST, array(
'username' => array('required' => true),
'password' => array('required' => true)
));
if($validation->passed()){
// log user in
$user = new User();
$login = $user->login(Input::get('username'), md5('password'));
if($login){
echo "succes";
} else {
echo '<p>Sorry, logging in failed</p>';
}
}else{
foreach($validation->errors() as $error){
echo $error, "<br>";
}
}
}
}
This it the code why can't they login? I think it's something with the md5('password').
Because i always get the Error: Sorry, logging in failed.
This is the Passed()
public function passed() {
return $this->_passed;
}
And this is the one for the login()
public function login($username = null, $password = null){
$user = $this->find($username);
if($user){
if($this->data()->password === Hash::make($password, $this->data()->salt)){
echo 'OK!';
}
}
return false;
}
private function data(){
return $this->_data;
}
i used to use salts but it took very long to generate one i i also don't know that either why that is like that i will also make soon an topic about that but for now i want to use MD5 just to make my other functionality.
Looks as though you are using Laravel? or something similar.
Try this instead:
$login = $user->login(Input::get('username'), 'password');
or perhaps you want:
$login = $user->login(Input::get('username'), Input::get('password'));
The login() function seems to be already doing the conversion to hash with Hash::make

Trying to build upvote system in cakephp

I am trying to build an upvote system in cakephp but I am having some trouble and am ending up with unidentified index errors and array to string conversion.
This is my function in my PostsController:
public function like ($id=null, $like=NULL) {
if(!$id) {throw new NotFoundException(__('Invalid post'));
}
$post = $this -> Post-> findById($id);
$like = $this->Like->find('all', array(
'conditions' => array('username' =>
array($this->Auth->user('username')))
));
if(!$post) {throw new NotFoundException(__('Invalid post'));
}
$this -> set('post',$post);
$this -> set('like', $like);
if ($like['Like']['username'] == $post['Post']['username'] && $like['Like']['article_id'] == $post['Post']['id']){
$this->redirect(array('action'=>'index'));
}
else{
$this->Like->saveField('username', $this->Auth->user('username'));
$this->Like->saveField('article_id', $post);
$this->redirect(array('action'=>'index'));
}
}
At the top of my controller I do var $uses = array('Post','Like'); So my PostsController knows to use the Like model too. Now I know what problem is, I just don't know how to fix it. When I set the fields, username gets set in the DB, but $post returns an array of all posts. What I want to happen is for it to only return the current post I am on. This is what I am doing in my view:
<?php echo $this->Html->link(
'Like',
array('action'=>'Like',$post['Post']['id']));
?>
And this is the action that goes with that view:
public function view ($id=null) {
if(!$id) {throw new NotFoundException(__('Invalid post'));
}
$post = $this -> Post-> findById($id);
if(!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this -> set('post',$post);
}
How can I get my link function to only return the current post I want to like and not an array of all the posts?
EDIT - Forgot to mention I'm getting an Undefined index: Like error on the 13th line of my posts controller.
You have
$like = $this->Like->find('all', array(
'conditions' => array('username' =>
array($this->Auth->user('username')))
));
This will give an array with more items, so you cannot use $like['Like']. This is why you are getting the warning.
You could use $like[0]['Like'].
If you need to go through each of the likes, you can do
foreach ($like as $currentLike) {
if ($currentLike['Like']['username'] == $post['Post']['username'] ....
}
Please include more details about why you are making these comparisons and redirects, and maybe more of the code can be refactored.

cakePHP User Edit creates empty user

I currently have a probem with cakePHP:
If I open /users/edit/4 for example, a new empty user entry is created in the users database.
My UsersController:
public function edit($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->request->data = $this->User->find('first', $options);
}
}
What am I doing wrong?
With kind regards,
Battlestr1k3
You did not add the $id
public function edit($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is(array('post', 'put'))) {
$this->request->data['User']['id'] = $id;
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->request->data = $this->User->find('first', $options);
}
}
TRY THIS
public function edit($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is(array('post', 'put'))) {
$this->User->id = $id;
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->request->data = $this->User->find('first', $options);
}
}
Thank you both for your fast answers, they both worked.
I was confused, because the code got even called when I made a GET-Request with a browser, but the problem was a javascript function which made a POST-Request in the background.
With kind regards,
Battlestr1k3

Categories