How to fix approval system in CakePHP - php

I made a blog and I can leave comments to my articles, then I made an Approve button, need to make the approve function.
I need to make it to work. I just can't, no matter what I try. I want to be able to approve or not a comment before it's posted. I have tried everything I could think of.
<?php
namespace App\Controller;
class CommentsController extends AppController
{
public function index()
{
$comments = $this->Comments->find('all');
$this->set(compact('comments'));
}
public function view($id = null)
{
$comment = $this->Comments->get($id);
$this->set(compact('comment'));
}
public function add()
{
$comment = $this->Comments->newEntity();
if ($this->request->is('post')) {
$comment = $this->Comments->patchEntity($comment, $this->request->data);
$comment->user_id = $this->Auth->user('id');
$comment->aproved = 0;
$comment->article_id = $this->request->data['article_id'];
if ($this->Comments->save($comment)) {
$this->Flash->success(__('Your comment has been saved.'));
return $this->redirect(['controller' => 'Articles', 'action' => 'view', $comment->article_id]);
}
$this->Flash->error(__('Unable to add your comment.'));
}
$this->set('comment', $comment);
}
public function aprove()
{
}
}

Try this
Your link should look like this:
$this->Html->link('approve', array('controller' => 'your-controller', 'action' => 'aprove', $comment_id, $value['Comment']['aproved']));
and your controller function is:
public function aprove($comment_id, $approve_value)
{
if(isset($comment_id) && !empty($comment_id)){
$approve = $this->Comments->find('first',array('conditions'=>array('id'=>$comment_id),'fields'=>array('Comment.id, Comment.approve')));
if(!empty($approve)){
$this->Comments->id = $approve['Comment']['id'];
$this->Comments->saveField('aproved', $approve_value);
}
}
}

Related

Cake 3 PHP error while with adding articles in CMS tutorial

I've got a problem with CMS Tutorial for Cake 3, it was going fine until I've added Auth component.
Now, no matter what user I use to add new article it always results in error 'Unable to add your article.'
This is how my ArticlesController looks like:
<?php
namespace App\Controller;
class ArticlesController extends AppController
{
//Wyświetla wszystkie artykuły
public function index()
{
$this->loadComponent('Paginator');
$articles = $this->Paginator->paginate($this->Articles->find());
$this->set(compact('articles'));
}
//Wyświetla pojedynczy artykuł na podstawie sluga
public function view($slug = null)
{
$article = $this->Articles->findBySlug($slug)->firstOrFail();
$this->set(compact('article'));
}
//Dodawanie artykułu
public function add()
{
$article = $this->Articles->newEntity();
if ($this->request->is('post')) {
$article = $this->Articles->patchEntity($article, $this->request->getData());
$article->user_id = $this->Auth->user('id');
if ($this->Articles->save($article)) {
$this->Flash->success(__('Your article has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your article.'));
}
//Pobiera listę tagów dzięki połączeniu Many to Many w ArticlesTable
$tags = $this->Articles->Tags->find('list');
//Ustawia tagi do widoku
$this->set('tags', $tags);
$this->set('article', $article);
}
//Edycja artykułu
public function edit($slug)
{
$article = $this->Articles->findBySlug($slug)->contain('Tags')->firstOrFail();
if ($this->request->is(['post', 'put'])) {
$this->Articles->patchEntity($article, $this->request->getData(), [
// Added: Disable modification of user_id.
'accessibleFields' => ['user_id' => false]
]);
if ($this->Articles->save($article)) {
$this->Flash->success(__('Your article has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your article.'));
}
//Pobiera listę tagów dzięki połączeniu Many to Many w ArticlesTable
$tags = $this->Articles->Tags->find('list');
//Ustawia tagi do widoku
$this->set('tags', $tags);
$this->set('article', $article);
}
//Usuwanie Artykułu
public function delete($slug)
{
$this->request->allowMethod(['post', 'delete']);
$article = $this->Articles->findBySlug($slug)->firstOrFail();
if ($this->Articles->delete($article)) {
$this->Flash->success(__('The {0} article has been deleted.', $article->title));
return $this->redirect(['action' => 'index']);
}
}
//Wyszukiwanie artykułu po tagach
public function tags()
{
// The 'pass' key is provided by CakePHP and contains all
// the passed URL path segments in the request.
$tags = $this->request->getParam('pass');
// Use the ArticlesTable to find tagged articles.
$articles = $this->Articles->find('tagged', [
'tags' => $tags
]);
// Pass variables into the view template context.
$this->set([
'articles' => $articles,
'tags' => $tags
]);
}
public function isAuthorized($user)
{
$action = $this->request->getParam('action');
// The add and tags actions are always allowed to logged in users.
if (in_array($action, ['add', 'tags'])) {
return true;
}
// All other actions require a slug.
$slug = $this->request->getParam('pass.0');
if (!$slug) {
return false;
}
// Check that the article belongs to the current user.
$article = $this->Articles->findBySlug($slug)->first();
return $article->user_id === $user['id'];
}
public function initialize()
{
parent::initialize();
// Allow the tags
$this->Auth->allow(['tags']);
} }
I've tried to not miss any steps, but I still don't know why it won't work. Editing is just fine, it checks what user added article and it allow to edit to him.
Any ideas, or is it Cake 3 bug?

Auth Component Redirection issue using Plugin in Cakephp

i'm getting redirected to this url http://localhost/project_name/PanelAdmin/users/login?redirect=%2FPanelAdmin%2Fusers%2Fedit using auth component instead of http://localhost/project_name/PanelAdmin/users/login if unauthorised access to edit action. The page which i get is the login one which is correct but i want to change the url to something like this http://localhost/project_name/PanelAdmin/users/login.
AppController.php
<?php
namespace PanelAdmin\Controller;
use App\Controller\AppController as BaseController;
use Cake\Event\Event;
class AppController extends BaseController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize'=> 'Controller',
'authenticate' => [
'Form' => [
// fields used in login form
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
// login Url
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
// where to be redirected after logout
'logoutRedirect' => [
'controller' => 'Topics',
'action' => 'index'//,
//'home'
],
// if unauthorized user go to an unallowed action he will be redirected to this url
'unauthorizedRedirect' => [
'controller' => 'Topics',
'action' => 'index'//,
//'home'
],
'authError' => 'Did you really think you are allowed to see that?',
]);
// Allow the display action so our pages controller still works and user can visit index and view actions.
$this->Auth->allow(['index','display','view']);
}
public function isAuthorized($user)
{
$this->Flash->error('You aren\'t allowed');
return false;
}
public function beforeFilter(Event $event)
{
$this->Auth->allow(['index', 'view', 'display']);
}
public function beforeRender(Event $event)
{
if (!array_key_exists('_serialize', $this->viewVars) &&
in_array($this->response->type(), ['application/json', 'application/xml'])
) {
$this->set('_serialize', true);
}
}
}
?>
UsersController.php
<?php
namespace PanelAdmin\Controller;
use Cake\Controller\Controller;
use Cake\ORM\TableRegistry;
use Cake\Event\Event;
class UsersController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash'); // Include the FlashComponent
// Auth component allow visitors to access add action to register and access logout action
$this->Auth->allow(['logout', 'add']);
}
public function login()
{
if ($this->request->is('post')) {
// Auth component identify if sent user data belongs to a user
$user = $this->Auth->identify();
if ($user) {
//
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password, try again.'));
}
}
public function logout(){
$this->Flash->success('You successfully have loged out');
return $this->redirect($this->Auth->logout());
}
public function index()
{
$this->set('users',$this->Users->find('all'));
}
public function view($id)
{
$user = $this->Users->get($id);
$this->set('user',$user);
}
public function add()
{
$user = $this->Users->newEntity();
if($this->request->is('post')) {
$this->Users->patchEntity($user,$this->request->data);
if($this->Users->save($user)){
$this->Flash->success(__('Your account has been registered .'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to register your account.'));
}
$this->set('user',$user);
}
public function edit($id)
{
$user = $this->Users->get($id);
if ($this->request->is(['post', 'put'])) {
$this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('Your profile data has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your profile.'));
}
$this->set('user', $user);
}
public function delete($id)
{
$this->request->allowMethod(['post', 'delete']);
$user = $this->Users->get($id);
if ($this->Users->delete($user)) {
$this->Flash->success(__('The user with id: {0} has been deleted.', h($id)));
return $this->redirect(['action' => 'index']);
}
}
}
?>
TopicsController.php
<?php
namespace PanelAdmin\Controller;
use Cake\Controller\Controller;
use Cake\ORM\TableRegistry;
class TopicsController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash'); // Include the FlashComponent
}
public function isAuthorized($user)
{
$action = $this->request->params['action'];
// registered users can add topics and view index
if (in_array($action, ['index', 'add','topics'])) {
return true;
}
// All other actions require an id or users cannot do it
if (empty($this->request->params['pass'][0])) {
return false;
}
// The owner of a topic can edit and delete it
// the owner of topic is known by its id and user_id value of topic .
if (in_array($this->request->action, ['edit', 'delete'])) {
// get topic id from the request
$topicId = (int)$this->request->params['pass'][0];
// check if the topic is owned by the user
if ($this->Topics->isOwnedBy($topicId, $user['id'])) {
return true;
}
}
return parent::isAuthorized($user);
}
public function index()
{
// find('all') get all records from Topics model
// We uses set() to pass data to view
$this->set('topics', $this->Topics->find('all'));
}
public function view($id)
{
// get() method get only one topic record using
// the $id paraameter is received from the requested url
// if request is /topics/view/5 the $id parameter value is 3
$topic = $this->Topics->get($id);
$this->set(compact('topic'));
}
public function add()
{
$topic = $this->Topics->newEntity();
//if the user topics data to your application, the POST request informations are registered in $this->request
if ($this->request->is('post')) { //
$topic = $this->Topics->patchEntity($topic, $this->request->data);
$topic->user_id = $this->Auth->user('id');
if ($this->Topics->save($topic)) {
// success() method of FlashComponent restore messages in session variable.
// Flash messages are displayed in views
$this->Flash->success(__('Your topic has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your topic.'));
}
$this->set('topic', $topic);
}
public function edit($id = null)
{
$topic = $this->Topics->get($id);
if ($this->request->is(['post', 'put'])) {
$this->Topics->patchEntity($topic, $this->request->data);
if ($this->Topics->save($topic)) {
$this->Flash->success(__('Your topic has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your topic.'));
}
$this->set('topic', $topic);
}
public function delete($id)
{
//if user wants to delete a record by a GET request ,allowMethod() method give an Exception as the only available request for deleting is POST
$this->request->allowMethod(['post', 'delete']);
$topic = $this->Topics->get($id);
if ($this->Topics->delete($topic)) {
$this->Flash->success(__('The topic with id: {0} has been deleted.', h($id)));
return $this->redirect(['action' => 'index']);
}
}
}
?>
You have to create a CustomAuthComponent.php file in src/Controller/Component/
Put the code in CustomAuthComponent.php
<?php
namespace App\Controller\Component;
use Cake\Controller\Component\AuthComponent;
class CustomAuthComponent extends AuthComponent
{
protected function _loginActionRedirectUrl()
{
return $this->_config['loginAction'];
}
}
After that in your AppController.php find and replace $this->loadComponent('Auth',..... with $this->loadComponent('CustomAuth',.......
After that find and replace $this->Auth with $this->CustomAuth in every Controller file.
That worked for me.

message in setFlash is empty

I have this code but the flash message is displayed incorrectly.
I want to display the message in:
http://xxx/cake/ ----(add action)
but actually the message is shown in:
http://xxx/cake/users/ ----(index action)
How can i solve this? I don't have any view to activation. I just want redirect to the add action and display the flash message after that.
class UsersController extends AppController {
public function index() {
$this->User->recursive = 0;
$this->set('users', $this->paginate());
}
public function add() {
}
public function activation() {
$email = $this->request->query['email'];
$codeLink = $this->request->query['code'];
if($this->User->activationAccount($email, $codeLink)) {
$this->Session->setFlash(__('Success'));///should be shown in add
$this->redirect(array('action' => 'add'));
}
else {
$this->Session->setFlash(__('Error.'));//should be shown in add
$this->redirect(array('action' => 'add'));
}
}
}
routes.php
Router::connect('/', array('controller' => 'users', 'action' => 'add'));
Just destroy this session:
array
'fb_400xxxxxxx96_state' => string 'ce3xxasdxxxxxxasdasdxxxxxxxf' (length=32)
public function add() {
$this->Session->destroy();
//some code
}
may be you should have a look at this tuto which cover this

CakePHP - Only one Query from external Model

I've two Models:
class Post extends AppModel {
var $name = 'Post';
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
}
and
class User extends AppModel {
var $name = 'User';
var $hasMany = 'Post';
}
Now I'm having a problem with a query in the PostsController. I've an add() function and the view add.ctp which is basically a form. Now I would like to show some User information in that form.
class PostsController extends AppController {
var $name = 'Posts';
var $helper = array('Html', 'Form');
var $uses = array('User');
public function index() {
$this->set('posts', $this->Post->find('all'));
}
function add() {
$user_id = 1;
$this->set('user', $this->User->findById($user_id));
if ($this->request->is('post')) {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}
}
But now the add-view-page shows that actually two queries where triggered. So if I print_r($user) within the add-view I'm getting an array with two arrays. One for a Post with user_id = 1 and one for the actual User with id = 1. But I would like to get only the User id = 1.
Try setting recursive to false on the User model before calling findById, so you won't get any data from associated models. Like this:
function add() {
$user_id = 1;
$this->User->recursive = false;
$this->set('user', $this->User->findById($user_id));
if ($this->request->is('post')) {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}

Real-world testing of CakePHP controllers?

I'm writing a new application with CakePHP (just-released 1.2.4), using SimpleTest 1.0.1. I have read the relevant sections of the Cookbook, searched on the Bakery, and read Mark Story's postings on controller testing (the hard way and with mocks).
Unfortunately, none of this talks about real-world testing of non-trivial controllers. Lots of apps put areas of the site behind a login, yet I cannot figure out how to test the simple scenario of:
guest access to protected page redirects?
valid credentials sets expected session variables?
invalid credentials re-displays login page with error message?
The controller and test below do not work as I thought they would. Both assertions fail and I also get a PHP error:
FAILED
[NULL] should not be null at [.../app/tests/cases/controllers/users_controller.test.php line 79]
.../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin
FAILED
Equal expectation fails as [NULL] does not match [Integer: 1] at [.../app/tests/cases/controllers/users_controller.test.php line 80]
.../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin
ERROR
Unexpected PHP error [Undefined index: action] severity [E_NOTICE] in [.../cake/libs/controller/components/auth.php line 266]
.../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin
Here is the controller (baked plus Mark Story's "hard way" testing method):
class UsersController extends AppController
{
var $name = 'Users';
var $helpers = array('Html', 'Form');
var $components = array('Auth');
function login()
{
}
function logout()
{
$this->redirect($this->Auth->logout());
}
function index()
{
$this->set('users', $this->paginate());
}
function view($id = null)
{
if (!$id)
{
$this->Session->setFlash(__('Invalid User.', true));
$this->redirect(array('action'=>'index'));
}
$this->set('user', $this->User->read(null, $id));
}
function add()
{
if (!empty($this->data))
{
$this->User->create();
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));
}
}
}
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);
}
}
function delete($id = null)
{
if (!$id)
{
$this->Session->setFlash(__('Invalid id for User', true));
$this->redirect(array('action'=>'index'));
}
if ($this->User->del($id))
{
$this->Session->setFlash(__('User deleted', true));
$this->redirect(array('action'=>'index'));
}
}
}
Here is the test:
/* SVN FILE: $Id$ */
/* UsersController Test cases generated on: 2009-08-05 17:08:03 : 1249507923*/
App::import('Controller', 'Users');
class TestUsers extends UsersController
{
var $autoRender = false;
var $redirectUrl;
var $redirectStatus;
var $renderedAction;
var $renderedLayout;
var $renderedFile;
var $stopped;
function redirect($url, $status = null, $exit = true)
{
$this->redirectUrl = $url;
$this->redirectStatus = $status;
}
function render($action = null, $layout = null, $file = null)
{
$this->renderedAction = $action;
$this->renderedLayout = (is_null($layout) ? $this->layout : $layout);
$this->renderedFile = $file;
}
function _stop($status = 0)
{
$this->stopped = $status;
}
}
class UsersControllerTest extends CakeTestCase
{
var $fixtures = array('user');
var $Users = null;
function startTest()
{
$this->Users = new TestUsers();
$this->Users->constructClasses();
$this->Users->Component->initialize($this->Users);
}
function prepareForAction()
{
$this->Users->beforeFilter();
$this->Users->Component->startup($this->Users);
}
function endTest()
{
$this->Users->Session->destroy();
unset($this->Users);
ClassRegistry::flush();
}
//-----------------------------------------------------------------------
function testUsersControllerInstance()
{
$this->assertTrue(is_a($this->Users, 'UsersController'));
}
function testLogin()
{
$this->Users->data = array(
'User' => array(
'username' => 'admin',
'password' => 'admin'
)
);
$this->prepareForAction();
$this->Users->login();
$this->assertNotNull($this->Users->redirectUrl);
$this->assertEqual($this->Users->Session->read('Auth.User.id'), 1);
}
}
The test you have isn't really testing your UsersContoller, you're really testing the AuthComponent. If you want to do this you need to make sure you setup your TestUsersController the same as it would be in your app. In the case of your testLogin you need to set the controller's action and url:
function testLogin()
{
$this->Users->data = array(
'User' => array(
'username' => 'admin',
'password' => 'admin'
)
);
$this->Users->params['url']['url'] = '/users/login';
$this->Users->params['action'] = 'login';
$this->prepareForAction();
$this->Users->login();
$this->assertNotNull($this->Users->redirectUrl);
$this->assertEqual($this->Users->Session->read('Auth.User.id'), 1);
}
Alternately, I would suggest taking another look at Mark's mock objects post and using those methods to write tests for the controller code and mocking the auth component.

Categories