Why do we want to rewrite Croogo's UsersController or better extend the UsersAppController over a Plugin? - Very simple, the Croogo core User edit() function is not ready yet and maby we want use our own smtp for E-Mail delivery or a new _sendEmail() function.

First of all we must create our Plugin in the Application - Source Files /Plugin folder. I name the demo Plugin "Demo" and create my /Plugin/Demo/Controller folder. Now the extend game can begin, we create the new controller file called DemoUsersController.php inside the /Controller folder. Here is the basic CakePHP file structure:

<?php
/**
 * Demo User Controller
 *
 * @package       Demo
 * @since         Demo v0.1
 * @copyright     Copyright (c) LuMAX W3B - Lukas Marks (http://lumax-web.de)
 * @link          http://lumax-web.de
 * @license       http://lumax-web.de/community-lizenz
 */
App::uses('CakeEmail', 'Network/Email');
App::uses('UsersAppController', 'Users.Controller');

class DemoUsersController extends UsersAppController {
}

As you can see we extend the UsersAppController Model and in our case we just need the frontend controller actions like activate() add() edit() forgot() index() login() logout() reset() and view() and I personaly always code the KISS (keep it simple stupid) way.

/**
	 * Components
	 *
	 * @var array
	 * @access public
	 */
	public $components = array(
		'Security',
		'Search.Prg' => array(
			'presetForm' => array(
				'paramType' => 'querystring',
			),
			'commonProcess' => array(
				'paramType' => 'querystring',
				'filterEmpty' => true,
			),
		),
		'RequestHandler',
	);

	/**
	 * Preset Variables Search
	 *
	 * @var array
	 * @access public
	 */
	public $presetVars = true;
	
	/**
	 * Plugin name
	 *
	 * @var string
	 */
	public $pluginName = 'Demo';
	
	/**
	 * Models used by the Controller
	 *
	 * @var array
	 * @access public
	 */
	public $uses = array('Users.User');
	
	/**
	 * Controller name for Views
	 *
	 * @var string
	 * @access public
	 */
	public $name = 'DemoUsers';

	public function beforeFilter() {
		
		parent::beforeFilter();
		
		if (isset($this->request->query['sid'])) {
			$this->Session->id($this->request->query['sid']);
		}
		if (isset($this->request->data['sid'])) {
			$this->Session->id($this->request->data['sid']);
		}
		
		if ( ($this->action == 'v2_0_demo_users_auth_check_sid') ||
		     ($this->action == 'v2_0_demo_users_auth_login') ||
		     ($this->action == 'v2_0_demo_users_auth_logout') ) {
			 // $this->Security->enable = false;
		        $this->Security->csrfCheck = false; // Cross-Site Scripting Schutz deaktivieren
		        $this->Security->validatePost = false; // Post Validierung deaktivieren
		}
	}

We need the $components, $presetVars, $pluginName, $uses, $name and the beforeFilter() function inside the Model class first. You recognize perhaps the special $this->action handling for the "v2_0_demo_users_auth_check_sid", "v2_0_demo_users_auth_login" and "v2_0_demo_users_auth_logout" actions, well this is a different RESTful API story you can integrate into your Croogo Plugin. When you do the RESTful API right you want allow GET and POST over REST, so we have to disable the CakePHP Security::csrfCheck and Security::validatePost or your posted data from extern gonna be blackholed, which is completely correct when you act outside the REST paradigm.

The biggest changes happen in the add() and forgot() functions, because we integrate the new _sendEmail($sendEmail = array()) protected function.

/**
	 * Convenience method to send email
	 *
	 * @param string $from_email Sender email
	 * @param string $from_name Sender name
	 * @param string $to_email Receiver email
	 * @param string $to_name Receiver name
	 * @param string $subject Subject
	 * @param string $emailFormat text, html, both
	 * @param string $template Template to use
	 * @param string $theme Theme to use
	 * @param array  $viewVars Vars to use inside template
	 * @return boolean True if email was sent, False otherwise.
	 */
	 protected function _sendEmail($sendEmail = array()) {
		$_sendEmail = array(
			'config' => null,
			'from_email' => Configure::read('Site.email'),
			'from_name' => Configure::read('Site.title'),
			'sender_email' => Configure::read('Site.email'),
			'sender_name' => Configure::read('Site.title'),
			'to_email' => null,
			'to_name' => null,
			'cc_email' => null,
			'cc_name' => null,
			'bcc_email' => null,
			'bcc_name' => null,
			'subject' => null,
			'emailFormat' => 'text',
			'charset' => 'utf-8',
			'headerCharset' => 'utf-8',
			'template' => false,
			'theme' => null,
			'viewVars' => null,
		);
		$sendEmail = Hash::merge($_sendEmail, $sendEmail);
        
		$success = false;
        
		try {
			$Email = new CakeEmail();
			$Email->config($sendEmail['config']);
			$Email->from($sendEmail['from_email'], $sendEmail['from_name']);
			$Email->sender($sendEmail['sender_email'], $sendEmail['sender_name']);
			$Email->to($sendEmail['to_email'], $sendEmail['to_name']);
			$Email->cc($sendEmail['cc_email'], $sendEmail['cc_name']);
			$Email->bcc($sendEmail['bcc_email'], $sendEmail['bcc_name']);
			$Email->subject($sendEmail['subject']);
			$Email->emailFormat($sendEmail['emailFormat']);
			$Email->charset($sendEmail['charset']);
			$Email->headerCharset($sendEmail['headerCharset']);
			$Email->template($sendEmail['template']);
			$Email->theme($sendEmail['theme']);
			$Email->viewVars($sendEmail['viewVars']);
			$success = $Email->send();
		} catch (SocketException $e) {
			$this->log(sprintf('Error sending email: %s', $e->getMessage()));
		}
		return $success;
	}

The _sendEmail() function incorporates the CakeEmail methods, please read the CakePHP Network Email API for further clearance.