itora web

12May/110

CakePHP check the owner

update cake 2.0: $this->request->is('ajax') invece del vecchio RequestHandler.
Capita spesso di dover verificar il proprietario di un item prima di modificarlo.
In cakePHP non esiste (per ora) un metodo dedicato a tale scopo. Cosa abbastanza strana, visto che la convenzione di associare lo User Model ad un altro Model tramite il campo user_id e' esiste da parecchio tempo.
Ho scritto un metodo da inserire nell'app_controller che permette di verificare che l'utente che modifica un iteme sia effettivamente il proprietario. Il metodo e' flessibile e puo' essere utilizzato con qualunque modello sia associato alla tabella Users tramite il campo user_id.

    function _isOwner($data, $options = array()){
	    if (empty($options['message'])) {
			$flash_message = "You are not allowed to access to this area";
	    }
	    else {
			$flash_message = $options['message'];
	    }

	    if (empty($options['scope'])) {
			$scope = $this->modelClass;
	    }
	    else {
			$scope = $options['scope'];
	    }

	    if (empty($options['redirect'])) {
			$redirect = false;
	    }
	    else {
			$redirect = $options['redirect'];
	    }

	    if ($scope == 'User') {
			$user_field = "id";
	    }
	    else {
			$user_field = "user_id";
	    }
	    $current_user = $this->Session->read('Auth.User.id');
	    if ($data[$scope][$user_field] == $current_user) {
		    return true;
	    }
	    else {
		    if ($redirect) {
			    $this->Session->setFlash($flash_message, 'error');
				//RequestHandler->isAjax() is buggy
			    if($this->request->is('ajax')) {
			    	$this->set('success', false);
			    	$this->set('error', $flash_message);
			    }
			    else {
			    	$this->redirect($redirect);
			    }
		    }
		    return false;
	    }
    }

Qualche esempio pratico:

$post = $this->Post->findById($post_id);
$this->_isOwner($post, array('redirect'=>'/'));

Se l'utente loggato non e' il proprietario del post esso verra reindirizzato alla root.
Se invece un utente vuole modificare il proprio profilo all'indirizzo sito.com/users/edit/3 il campo da verificar enon sara' piu' 'user_id' ma l'id del modello 'User'. Per fare questo dobbiamo solo aggiungere impostare il parametro 'scope'.

$user = $this->->User->findById($id);
$this->_isOwner($user, array('scope'=> 'User'))

Oltre a scope, gi altri parametri che si possono passare a questa funzione sono:
message = Il messaggio che vogliamo mostrare dopo il redirect nel caso non ci vada bene quello di default
redirect = L'url alla quale vogliamo reindirizzare l'utente. Se questo falore non e' impostato, la funzione restituira' solo TRUE o FALSE senza effettuare il redirect.