ee9ab130bed03e317d73f4ed613a0c3c29e07187
Author: AD7six
Date: 2009-02-26 12:42:47 +0100
diff --git a/plugins/users/config/users_bootstrap.php b/plugins/users/config/users_bootstrap.php
new file mode 100644
index 0000000..6afdabf
--- /dev/null
+++ b/plugins/users/config/users_bootstrap.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Short description for bootstrap.php
+ *
+ * Long description for bootstrap.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users.config.bootstrap.php
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+//Configure::write('Users.database', 'thisone');
+Configure::write('Users.layout', 'users_default');
+Configure::write('Users.admin_layout', 'users_admin_default');
+Configure::write('Users.legacy_password_callback', 'md5');
+Configure::write('Email.domain', 'emailsfromthis.com');
+Configure::write('Email.defaults.from', 'Friendly Name <email@adderss.com>');
\ No newline at end of file
diff --git a/plugins/users/controllers/components/users.php b/plugins/users/controllers/components/users.php
new file mode 100644
index 0000000..5e663da
--- /dev/null
+++ b/plugins/users/controllers/components/users.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Short description for users.php
+ *
+ * Long description for users.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users.controllers.components
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * UsersComponent class
+ *
+ * @uses
+ * @package users
+ * @subpackage users.controllers.components
+ */
+class UsersComponent extends Object {
+/**
+ * components property
+ *
+ * @var array
+ * @access public
+ */
+ var $components = array('Auth');
+/**
+ * initialize method
+ *
+ * @return void
+ * @access public
+ */
+ function initialize() {
+ $this->Auth->loginAction = '/users/login';
+ $this->Auth->logoutRedirect = '/';
+
+ $this->Auth->fields = array('username'=> 'username', 'password'=>'password');
+ $this->Auth->authorize = 'object';
+ $this->Auth->object = $this;
+ $this->Auth->authenticate = $this;
+ }
+/**
+ * startup method
+ *
+ * @param mixed $controller
+ * @return void
+ * @access public
+ */
+ function startup(&$controller) {
+ }
+/**
+ * isAuthorized method
+ *
+ * @param mixed $user
+ * @param mixed $controller
+ * @param mixed $action
+ * @return void
+ * @access public
+ */
+ function isAuthorized($user, $controller, $action) {
+ return false;
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/controllers/emails_controller.php b/plugins/users/controllers/emails_controller.php
new file mode 100644
index 0000000..aabdb55
--- /dev/null
+++ b/plugins/users/controllers/emails_controller.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Short description for emails_controller.php
+ *
+ * Long description for emails_controller.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users.controllers
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * EmailsController class
+ *
+ * Used to handle even triggered email sending
+ *
+ * @uses
+ * @package users
+ * @subpackage users.controllers
+ */
+class EmailsController extends AppController {
+/**
+ * name property
+ *
+ * @var string 'Emails'
+ * @access public
+ */
+ var $name = 'Emails';
+/**
+ * uses property
+ *
+ * @var array
+ * @access public
+ */
+ var $uses = array();
+/**
+ * components property
+ *
+ * @var array
+ * @access public
+ */
+ var $components = array('Email');
+/**
+ * send method
+ *
+ * Expected to be called by request action only
+ *
+ * @return void
+ * @access public
+ */
+ function send() {
+ if (empty($this->params['requested'])) {
+ return $this->redirect($this->referer());
+ }
+ $data = $this->__defaults($this->params['data']);
+ $keys = array_diff(array_keys($data), array('data'));
+ foreach ($keys as $field) {
+ $this->Email->$field = $data[$field];
+ }
+ $this->set('data', $data['data']);
+ if (Configure::read()) {
+ Configure::write('debug', 3);
+ if (Configure::read() > 2) {
+ $this->Email->delivery = 'debug';
+ }
+ }
+ $return = $this->Email->send();
+ return $return;
+ }
+/**
+ * defaults method
+ *
+ * Populate the passed data array with configured/derived defaults for all keys that are required but
+ * missing
+ *
+ * @param mixed $data
+ * @return void
+ * @access private
+ */
+ function __defaults($data) {
+ if (!$domain = Configure::read('Email.domain')) {
+ $domain = substr(env('HTTP_BASE'), 1);
+ if (!$domain) {
+ $domain = APP_DIR;
+ }
+ }
+ $fallbacks = array(
+ 'template' => 'missing',
+ 'reply_to' => 'noreply@' . $domain,
+ 'from' => $domain . ' Mailer <mailer@' . $domain . '>',
+ );
+ if ($defaults = Configure::read('Email.defaults')) {
+ $defaults = am($fallbacks, $defaults);
+ } else {
+ $defaults = $fallbacks;
+ }
+ $data = am($defaults, $data);
+ if (empty($data['subject'])) {
+ $subject = Inflector::humanize(Inflector::underscore(str_replace('/', ' ', $data['template'])));
+ $data['subject'] = __d('email_subjects', $subject, true);
+ }
+ $data['domain'] = $domain;
+ return $data;
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/controllers/users_controller.php b/plugins/users/controllers/users_controller.php
new file mode 100644
index 0000000..334df65
--- /dev/null
+++ b/plugins/users/controllers/users_controller.php
@@ -0,0 +1,515 @@
+<?php
+/**
+ * Short description for users_controller.php
+ *
+ * Long description for users_controller.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users.controllers
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * AppController class
+ *
+ * @uses
+ * @package users
+ * @subpackage users.controllers
+ */
+class UsersController extends AppController {
+/**
+ * name property
+ *
+ * @var string 'Users'
+ * @access public
+ */
+ var $name = 'Users';
+/**
+ * components property
+ *
+ * @var array
+ * @access public
+ */
+ var $components = array('Auth', 'RequestHandler', 'Cookie', 'Security');
+/**
+ * helpers property
+ *
+ * @var array
+ * @access public
+ */
+ var $helpers = array('Form', 'Menu' => array('genericElement' => false));
+/**
+ * beforeFilter method
+ *
+ * Allow access to the recovery methods if debug is enabled
+ * Set the black hole to prevent white-screen-of-death symptoms for invalid form submissions.
+ *
+ * @return void
+ * @access public
+ */
+ function beforeFilter() {
+ parent::beforeFilter();
+ $this->Auth->allow('register', 'forgotten_password', 'reset_password', 'confirm_account',
+ 'logout');
+ $this->Security->blackHoleCallback = '_blackHole';
+ if ($this->action == 'login' && $callback = Configure::read('Users.legacy_password_callback')) {
+ $this->__oldPassword = $this->data['User'][$this->Auth->fields['password']];
+ }
+ }
+/**
+ * beforeRender method
+ *
+ * @return void
+ * @access public
+ */
+ function beforeRender() {
+ parent::beforeRender();
+ $this->set('authFields', $this->Auth->fields);
+ unset($this->data['User'][$this->Auth->fields['password']]);
+ unset($this->data['User']['confirm']);
+ unset($this->data['User']['current_password']);
+ $this->set('data', $this->data);
+ if (empty($this->params['admin'])) {
+ if ($layout = Configure::read('Users.layout')) {
+ $this->layout = $layout;
+ }
+ } else {
+ if ($layout = Configure::read('Users.admin_layout')) {
+ $this->layout = $layout;
+ }
+ }
+ }
+/**
+ * admin_add method
+ *
+ * @return void
+ * @access public
+ */
+ function admin_add () {
+ if ($this->data) {
+ if ($this->User->saveAll($this->data)) {
+ $display = $this->User->display();
+ $this->Session->setFlash(sprintf(__d('users', 'User "%s" added', true), $display));
+ return $this->redirect($this->referer());
+ } else {
+ $this->data = $this->User->data;
+ $this->Session->setFlash(__d('users', 'errors in form', true));
+ }
+ }
+ $this->render('admin_edit');
+ }
+/**
+ * admin_delete method
+ *
+ * Includes fall back logic to work only via post even if the Security component isn't loaded
+ *
+ * @param mixed $id
+ * @return void
+ * @access public
+ */
+ function admin_delete($id) {
+ $this->User->id = $id;
+ if ($this->User->exists()) {
+ if (!$this->data) {
+ return $this->_blackHole('post');
+ } elseif ($this->data['_App']['submit'] == 'cancel') {
+ return $this->redirect($this->referer());
+ }
+ $display = $this->User->display($id);
+ if ($this->User->del($id)) {
+ $this->Session->setFlash(sprintf(__d('users', 'User %s "%s" deleted', true), $id, $display));
+ } else {
+ $this->Session->setFlash(sprintf(__d('users', 'Problem deleting User %s "%s"', true), $id, $display));
+ }
+ } else {
+ $this->Session->setFlash(sprintf(__d('users', 'User with id %s doesn\'t exist', true), $id));
+ }
+ return $this->redirect($this->referer());
+ }
+/**
+ * admin_edit method
+ *
+ * @param mixed $id
+ * @return void
+ * @access public
+ */
+ function admin_edit($id) {
+ if ($this->data) {
+ if ($this->User->saveAll($this->data)) {
+ $display = $this->User->display();
+ $this->Session->setFlash(sprintf(__d('users', 'User "%s" updated', true), $display));
+ return $this->redirect($this->referer());
+ } else {
+ $this->data = $this->User->data;
+ $this->Session->setFlash(__d('users', 'errors in form', true));
+ }
+ } else {
+ $this->data = $this->User->read(null, $id);
+ }
+ }
+/**
+ * admin_index method
+ *
+ * Use the Filter component to check for POST/GET data to use for searching.
+ * An example of how to load a component for one action only
+ *
+ * @return void
+ * @access public
+ */
+ function admin_index() {
+ $conditions = $this->_parseSearchFilter();
+ if ($conditions) {
+ $this->set('filters', $this->User->searchFilterFields());
+ $this->set('addFilter', true);
+ }
+ $this->User->recursive = 1;
+ $this->data = $this->paginate($conditions);
+ $ids = Set::extract($this->data, '/User/id');
+ $displayNames = $this->User->find('list', array('conditions' => array('User.id' => $ids)));
+ $this->set(compact('displayNames'));
+ }
+
+/**
+ * admin_login method
+ *
+ * @return void
+ * @access public
+ */
+ function admin_login() {
+ return $this->redirect(array('admin' => false, 'action' => 'login'));
+ }
+/**
+ * admin_logout method
+ *
+ * @return void
+ * @access public
+ */
+ function admin_logout() {
+ $this->logout();
+ }
+/**
+ * admin_search method
+ *
+ * @param mixed $term
+ * @return void
+ * @access public
+ */
+ function admin_search($term = null) {
+ if ($this->data) {
+ $term = trim($this->data['User']['query']);
+ $url = array(urlencode($term));
+ $this->redirect($url);
+ }
+ if (!$term) {
+ $this->redirect(array('action' => 'index'));
+ }
+ $conditions = $this->{$this->modelClass}->searchConditions($term, isset($this->passedArgs['extended']));
+ $this->Session->setFlash(sprintf(__('All %s matching the term "%s"', true),
+ Inflector::humanize(Inflector::underscore($this->name)), htmlspecialchars($term)));
+ $this->data = $this->paginate($conditions);
+ $ids = Set::extract($this->data, '/User/id');
+ $displayNames = $this->User->find('list', array('conditions' => array('User.id' => $ids)));
+ $this->set(compact('displayNames'));
+ $this->render('admin_index');
+ }
+/**
+ * admin_view method
+ *
+ * @param mixed $id
+ * @return void
+ * @access public
+ */
+ function admin_view ($id) {
+ $this->data = $this->User->read(null, $id);
+ if(!$this->data) {
+ $this->Session->setFlash(__d('users', 'Invalid User', true));
+ return $this->redirect($this->referer());
+ }
+ }
+/**
+ * change_password method
+ *
+ * Used for changing the password of a logged in user
+ *
+ * @return void
+ * @access public
+ */
+ function change_password() {
+ if ($this->data) {
+ list($return, $message) = $this->User->changePassword($this->data, $this->Auth->user());
+ if ($message) {
+ $this->Session->setFlash($message);
+ }
+ if ($return) {
+ return $this->redirect('/');
+ }
+ }
+ $strengths = array_keys($this->User->passwordPolicies());
+ $this->set('strengths', array_combine($strengths, $strengths));
+ }
+/**
+ * confirm method
+ *
+ * @param mixed $token
+ * @return void
+ * @access public
+ */
+ function confirm_account($token = null) {
+ $this->set('token', $token);
+ if (!$this->data) {
+ return;
+ }
+ list($return, $message) = $this->User->confirmAccount($this->data);
+ if ($message) {
+ $this->Session->setFlash($message);
+ }
+ if ($return) {
+ $this->Session->write('Auth.redirect', '/'); // Prevent auth from sending you back here
+ return $this->redirect('/');
+ }
+ }
+/**
+ * edit method
+ *
+ * @return void
+ * @access public
+ */
+ function edit() {
+ if ($this->data) {
+ $this->data['User']['id'] = $this->Auth->user('id');
+ if ($this->User->save($this->data)) {
+ $this->Session->setFlash(__d('users', 'profile updated', true));
+ return $this->redirect($this->referer());
+ } else {
+ $this->Session->setFlash(__d('users', 'errors in form', true));
+ }
+ } else {
+ $this->data = $this->User->read(null, $this->Auth->user('id'));
+ }
+ }
+/**
+ * forgotten_password method
+ *
+ * Send the user an email with a confirmation link/token in it. Use the $email (which could be an email or a username)
+ * to find the users id. Don't send another email if there is one that is pending
+ *
+ * @access public
+ * @return void
+ */
+ function forgotten_password() {
+ if ($this->data) {
+ $email = $this->data['User']['email'];
+ if (!$email) {
+ $this->Session->setFlash(__d('users', 'email missing', true));
+ return;
+ }
+ list($return, $message) = $this->User->forgottenPassword($this->data['User']['email']);
+ if ($message) {
+ $this->Session->setFlash($message);
+ }
+ if ($return) {
+ $this->redirect(array('action' => 'reset_password'));
+ }
+ }
+ }
+/**
+ * login method
+ *
+ * @TODO add remember me cookie
+ * @return void
+ * @access public
+ */
+ function login() {
+ if($this->Auth->user('id')) {
+ if(!empty($this->data['User']['redirect'])){
+ $this->redirect($this->data['User']['redirect']);
+ } else {
+ $this->redirect($this->Auth->redirect());
+ }
+ } elseif($this->data && $callback = Configure::read('Users.legacy_password_callback')) {
+ $OldPassword = ClassRegistry::init('Users.OldPassword');
+ $id = $OldPassword->field('id', array(
+ 'username' => $this->data['User'][$this->Auth->fields['username']],
+ 'password' => call_user_func($callback, $this->__oldPassword)
+ ));
+ if ($id) {
+ $uId = $this->User->field('id', array(
+ $this->Auth->fields['username'] => $this->data['User'][$this->Auth->fields['username']]
+ ));
+ $this->User->id = $uId;
+ $password = $this->Auth->password($this->__oldPassword);
+ $this->User->saveField($this->Auth->fields['password'], $password,
+ array('callbacks' => false));
+ if ($this->Auth->login($uId)) {
+ $OldPassword->delete($id);
+ return $this->redirect($this->Auth->redirect());
+ }
+ }
+ }
+ }
+/**
+ * logout method
+ *
+ * @return void
+ * @access public
+ */
+ function logout() {
+ if ($this->Auth->user()) {
+ $this->Cookie->del('User');
+ $this->Session->destroy();
+ $this->Session->setFlash(__d('users', 'now logged out', true));
+ }
+ $this->redirect($this->Auth->logout());
+ }
+/**
+ * profile method
+ *
+ * @param mixed $username
+ * @access public
+ * @return void
+ */
+ function profile($username = null) {
+ $conditions = array(
+ 'Profile.published' => 1,
+ $this->Auth->fields['username'] => $username
+ );
+ $this->User->recursive = 0;
+ if ($username && $username != $this->Auth->user($this->Auth->fields['username'])) {
+ $id = $this->User->field('id', $conditions);
+ } else {
+ $id = $this->Auth->user('id');
+ }
+ if (!$id) {
+ $this->Session->setFlash(__d('users', 'Profile not found', true));
+ return $this->redirect($this->referer());
+ }
+ $conditions['User.id'] = $id;
+ $this->data = $this->User->find('first', compact('conditions'));
+ if (!$this->data) {
+ $this->Session->setFlash(__d('users', 'User not found', true));
+ return $this->redirect($this->referer());
+ }
+ }
+/**
+ * register method
+ *
+ * @access public
+ * @return void
+ */
+ function register() {
+ if ($this->data) {
+ list($return, $message) = $this->User->register($this->data);
+ if ($message) {
+ $this->Session->setFlash($message);
+ }
+ if ($return) {
+ $this->Auth->login($this->User->id);
+ return $this->redirect('/');
+ }
+ }
+ }
+/**
+ * reset_password method
+ *
+ * Used to set a new password after requesting a reset via the forgotten password method
+ *
+ * @param string $token
+ * @access public
+ * @return void
+ */
+ function reset_password($token = null) {
+ $loggedInUser = $this->User->id = $this->Auth->user('id');
+ if ($loggedInUser) {
+ $this->redirect(array('action' => 'change_password'));
+ }
+ $this->set('token', $token);
+ $this->set('fields', $this->User->Behaviors->UserAccount->settings['User']['fields']);
+ if (!$this->data) {
+ return $this->render('confirm');
+ }
+ list($return, $message) = $this->User->resetPassword($this->data);
+ if ($message) {
+ $this->Session->setFlash($message);
+ }
+ if ($return) {
+ $this->Session->write('Auth.redirect', '/'); // Prevent auth from sending you back here
+ return $this->redirect(array('action' => 'login'));
+ }
+ $view = 'confirm';
+ if ($this->data) {
+ if (empty($this->User->validationErrors[$this->Auth->fields['username']]) &&
+ empty($this->User->validationErrors['token'])) {
+ $view = 'reset_password';
+ }
+ }
+ $this->render($view);
+ }
+/**
+ * blackHole method. Handles form submissions deemed invalid by the security component
+ *
+ * If a login is blackholed, there are 2 possible causes
+ * 1) The user went to /users/login but the form was tampered or the security token out of date
+ * 2) They used the sidebar login form, and the <not-users> controller doesn't use the security component
+ *
+ * In the first case, there is nothing to do but send the user back to the login form. In the second case, check if
+ * their form submission contains a valid (session) user login token, and if so allow them to login; Otheriwse send to
+ * the login form. This logic allows the users controller to use the security component, without forcing the rest of the
+ * application to do so.
+ *
+ * If a user is already logged in, and the current action is not a login, then the user submitted a stale form -
+ * call the parent blackHole handling method.
+ *
+ * @param mixed $reason
+ * @return void
+ * @access protected
+ */
+ function _blackHole($reason = null) {
+ if (Configure::read()) {
+ return true;
+ }
+ $this->Session->setFlash(__d('users', 'Invalid login submission', true));
+ $this->redirect(array());
+ }
+/**
+ * parseSearchFilter method
+ *
+ * @param mixed $alias null
+ * @param string $mode 'both'
+ * @param array $ignore array()
+ * @param array $filter array()
+ * @return void
+ * @access protected
+ */
+ function _parseSearchFilter($ignore = array('limit', 'show', 'sort', 'page', 'direction', 'step'), $filter = array()) {
+ $filter = am($filter, $this->params['named']);
+ foreach ($ignore as $ignore) {
+ unset ($filter[$ignore]);
+ }
+ foreach ($filter as $key => $val) {
+ if (!strpos($key, '.')) {
+ unset($filter[$key]);
+ $filter['User..' . $key] = $val;
+ }
+ }
+ if ($filter) {
+ $out = 'Filtering for:<br />';
+ $currentFilters = array();
+ foreach ($filter as $field => $filter) {
+ $currentFilters[] = Inflector::humanize($field) . ' ' . $filter;
+ }
+ $this->Session->setFlash($out . implode(',<br />', $currentFilters));
+ }
+ return $filter;
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/models/behaviors/user_account.php b/plugins/users/models/behaviors/user_account.php
new file mode 100644
index 0000000..070e2ac
--- /dev/null
+++ b/plugins/users/models/behaviors/user_account.php
@@ -0,0 +1,860 @@
+<?php
+/* SVN FILE: $Id: user_account.php 797 2009-02-18 21:20:51Z ad7six $ */
+/**
+ * User Account behavior
+ *
+ * A configurable and portable user account management system allowing account confirmation and password recovery
+ *
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 2008, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2008, Andy Dawson
+ * @link www.ad7six.com
+ * @package base
+ * @subpackage base.models.behaviors
+ * @since v 1.0
+ * @version $Revision: 797 $
+ * @modifiedby $LastChangedBy: ad7six $
+ * @lastmodified $Date: 2009-02-18 22:20:51 +0100 (Wed, 18 Feb 2009) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * UserAccountBehavior class
+ *
+ * @uses ModelBehavior
+ * @package base
+ * @subpackage base.models.behaviors
+ */
+class UserAccountBehavior extends ModelBehavior {
+/**
+ * name property
+ *
+ * @var string 'UserAccount'
+ * @access public
+ */
+ var $name = 'UserAccount';
+/**
+ * defaultSettings property
+ *
+ * Fields:
+ * current - the field for the user's current password
+ * email - the field for the user's email
+ * password - the same as the Auth component password field
+ * password_confirm - a second password input to match the password
+ * confirmation - used in the password recovery process. A field that the user must enter, defaults to username
+ * username - the same as the Auth component username field
+ * token - the field used for entering the (email) token. included here to reduce code repeition
+ *
+ * All Fields can be either "field" or "associatedModel.field"
+ * Password Policies:
+ * Define the rules for what is an acceptable password. salts as concatonated, that is the salt for 'strong'
+ * includes all weaker policies
+ * Password Policy:
+ * The current password policy
+ * Token:
+ * fields - which fields to be used when generating a token, defaults to al
+ * length - how long to make the token, defaults to whatever Security::hash returns
+ * recursive - the recursive value to be used when generating a token
+ *
+ * The fields and recursive settings allow a user's profile or address to be included in the token, whilst excluding
+ * counterCache fields or other fields that may change often and are not useful to include in the token
+ *
+ * @var array
+ * @access protected
+ */
+ var $_defaultSettings = array(
+ 'sendEmails' => array(
+ 'welcome' => true,
+ 'accountChange' => true,
+ ),
+ 'fields' => array(
+ 'current' => 'current_password',
+ 'email' => 'email',
+ 'password' => 'password',
+ 'password_confirm' => 'confirm',
+ 'confirmation' => 'username',
+ 'username' => 'username',
+ 'token' => 'token',
+ ),
+ 'passwordPolicies' => array(
+ 'weak' => array('length' => 6, 'salt' => 'abcdefghijklmnopqrstuvwxyz0123456789'),
+ 'normal' => array('length' => 8),
+ 'medium' => array('length' => 8, 'salt' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
+ 'strong' => array('length' => 8, 'salt' => '!@#~$%&/()=+?"\',.;:-_*\/'),
+ 'super' => array('length' => 40),
+ ),
+ 'passwordPolicy' => 'medium',
+ 'token' => array(
+ 'fields' => '*',
+ 'length' => 0,
+ 'recursive' => -1,
+ )
+ );
+/**
+ * setup method
+ *
+ * @param mixed $Model
+ * @param array $config
+ * @return void
+ * @access public
+ */
+ function setup(&$Model, $config = array()) {
+ $this->settings[$Model->alias] = Set::merge($this->_defaultSettings, $config);
+ }
+/**
+ * afterSave method
+ *
+ * If the user's password, email or username are changed notify the user by email
+ *
+ * @param mixed $created
+ * @return void
+ * @access public
+ */
+ function afterSave(&$Model, $created) {
+ if ($created) {
+ if ($this->settings[$Model->alias]['sendEmails']['welcome']) {
+ $data[$Model->alias]['emailType'] = 'private';
+ $Model->sendMail('welcome', $data);
+ }
+ return;
+ }
+ if (!$this->settings[$Model->alias]['sendEmails']['accountChange']) {
+ return;
+ }
+ extract($this->settings[$Model->alias]);
+ if(!empty($__passwordChanged)) {
+ $data[$Model->alias]['change'] = 'password';
+ $data[$Model->alias]['emailType'] = 'private';
+ $Model->sendMail('account_change', $data);
+ unset ($this->settings[$Model->alias]['__passwordChanged']);
+ }
+ if(!empty($__emailChanged)) {
+ $data[$Model->alias]['to'] = $__emailChanged;
+ $data[$Model->alias]['change'] = 'email';
+ $data[$Model->alias]['oldValue'] = $__emailChanged;
+ $data[$Model->alias]['emailType'] = 'private';
+ $Model->sendMail('account_change', $data);
+ unset ($this->settings[$Model->alias]['__emailChanged']);
+ }
+ if(!empty($__usernameChanged)) {
+ $data[$Model->alias]['change'] = 'username';
+ $data[$Model->alias]['oldValue'] = $__usernameChanged;
+ $data[$Model->alias]['emailType'] = 'private';
+ $Model->sendMail('account_change', $data);
+ unset ($this->settings[$Model->alias]['__usernameChanged']);
+ }
+ }
+/**
+ * beforeSave method
+ *
+ * If attempting to change the password, email or username make a note to be able to mail the user if successful
+ *
+ * @access public
+ * @return void
+ */
+ function beforeSave(&$Model) {
+ extract($this->settings[$Model->alias]['fields']);
+ if ($Model->id) {
+ if(isset($Model->data[$Model->alias][$password])) {
+ $currentPassword = $Model->field($password);
+ if ($currentPassword && $Model->data[$Model->alias][$password] != $currentPassword) {
+ $this->settings[$Model->alias]['__passwordChanged'] = true;
+ }
+ }
+ if(!empty($Model->data[$Model->alias][$email]) &&
+ $Model->data[$Model->alias][$email] != $Model->field($email)) {
+ $this->settings[$Model->alias]['__emailChanged'] = $Model->field($email);
+ }
+ if($email != $username && isset($Model->data[$Model->alias][$username]) &&
+ $Model->data[$Model->alias][$username] != $Model->field($username)) {
+ $this->settings[$Model->alias]['__usernameChanged'] = $Model->field($username);
+ }
+ }
+ return $Model->data;
+ }
+/**
+ * beforeValidate method
+ *
+ * Setup validation rules
+ * If a generated password is requested, and strength is selected - only allow modification
+ * if the user selects a strength stronger than the system default
+ *
+ * @return void
+ * @access public
+ */
+ function beforeValidate(&$Model) {
+ $this->_setupValidation($Model);
+ extract($this->settings[$Model->alias]);
+ if (!empty($Model->data[$Model->alias]['generate'])) {
+ unset ($Model->data[$Model->alias]['generate']);
+ $strengths = array_keys($passwordPolicies);
+ $current = array_search($passwordPolicy, $strengths);
+ if (isset($Model->data[$Model->alias]['strength'])) {
+ $requested = array_search($Model->data[$Model->alias]['strength'], $strengths);
+ if ($requested > $current) {
+ $this->settings[$Model->alias]['passwordPolicy'] =
+ $Model->data[$Model->alias]['strength'];
+ }
+ }
+ $this->settings[$Model->alias]['temp_password'] =
+ $Model->data[$Model->alias][$fields['password_confirm']] = $this->generatePassword($Model);
+ $Model->data[$Model->alias][$fields['password']] =
+ Security::hash($Model->data[$Model->alias][$fields['password_confirm']], null, true);
+ }
+ return true;
+ }
+/**
+ * changePassword method
+ *
+ * Process a change of password request
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param array $loggedInUser
+ * @return array(bool, string) success/fail and an optional message
+ * @access public
+ */
+ function changePassword(&$Model, $data, $loggedInUser = array()) {
+ if (isset($loggedInUser[$Model->alias])) {
+ $loggedInUser = $loggedInUser[$Model->alias];
+ }
+ extract($this->settings[$Model->alias]);
+ $data[$Model->alias][$Model->primaryKey] = $loggedInUser[$Model->primaryKey];
+ $data[$Model->alias][$fields['username']] = $loggedInUser[$fields['username']];
+ if ($data = $Model->save($data, true, array($fields['current'], $fields['password'], $fields['password_confirm']))) {
+ $message = __d('users', 'Your password has been changed', true);
+ if ($Model->data[$Model->alias]['generate']) {
+ $message .= sprintf(__d('users', '. Your new password is <strong>%s</strong>', true), $temp_password);
+ unset ($this->settings[$Model->alias]['temp_password']);
+ }
+ return array(true, $message);
+ } else {
+ $message = __d('users', 'There was a problem changing your password', true);
+ }
+ return array(false, $message);
+ }
+/**
+ * confirmAccount method
+ *
+ * Process a password confirmation request
+ * If $password is true, return true on success - as this process forms the first part of a password reset
+ *
+ * @param mixed $Model
+ * @param array $data
+ * @param bool $force
+ * @param bool $password
+ * @return array(bool, string) success/fail and an optional message
+ * @access public
+ */
+ function confirmAccount(&$Model, $data = array(), $force = false, $password = false) {
+ extract($this->settings[$Model->alias]);
+ if (!$force) {
+ $missing = false;
+ foreach (array('email', 'confirmation', 'token') as $field) {
+ if ($fields[$field] === false) {
+ continue;
+ }
+ $field = $fields[$field];
+ $alias = $Model->alias;
+ if (strpos('.', $field)) {
+ list($alias, $field) = explode($field, '.');
+ }
+ if (!$data[$alias][$field]) {
+ $missing = true;
+ if ($alias == $Model->alias) {
+ $Model->invalidate($field, 'missing');
+ } else {
+ $Model->$alias->invalidate($field, 'missing');
+ }
+ }
+ }
+ if ($missing) {
+ return array(false, null);
+ }
+ $conditions = array($Model->alias . '.' . $fields['email'] => $data[$Model->alias][$fields['email']]);
+ $fields = '*';
+ $recursive = 0;
+ $user = $Model->find('first', compact('fields', 'recursive', 'conditions'));
+ $fields = $this->settings[$Model->alias]['fields'];
+ if (!$user) {
+ $Model->invalidate('token', 'not found');
+ $message = __d('users', 'token not found', true);
+ if (Configure::read()) {
+ $message .= ' <br />DEBUG:' . __d('users', 'email not found', true);
+ }
+ return array(false, $message);
+ }
+ $Model->id = $user[$Model->alias][$Model->primaryKey];
+ if ($fields['confirmation'] !== false && !$Model->userAccountField($fields['confirmation'], $data, true)) {
+ $Model->invalidate('token', 'not found');
+ $message = __d('users', 'token not found', true);
+ if (Configure::read()) {
+ $message .= ' <br />DEBUG:' . sprintf(__d('users', '%s does not match for email %s', true),
+ $fields['confirmation'], $data[$Model->alias][$fields['email']]);
+ }
+ return array(false, $message);
+ }
+ $token = $this->token($Model, $user);
+ if ($token !== $data[$Model->alias]['token']) {
+ $Model->invalidate('token', 'not found');
+ $message = __d('users', 'token not found', true);
+ if (Configure::read()) {
+ $message .= ' <br />DEBUG:' . __d('users', 'token does not match', true);
+ $message .= ' <br />' . $token;
+ }
+ return array(false, $message);
+ }
+ $expires = strtotime($user[$Model->alias]['modified']) + 60 * 60 * 24;
+ if ($expires < time() && !$force) {
+ $Model->invalidate('token', 'expired');
+ if ($password) {
+ $Model->sendMail('new_password');
+ $message = __d('users', 'email token expired', true);
+ } else {
+ $Model->sendMail('new_token');
+ $message = __d('users', 'confirm email token expired', true);
+ }
+ return array(false, $message);
+ }
+ }
+ if ($password) {
+ return true;
+ }
+ $message = '';
+ $Model->id = $user[$Model->alias][$Model->primaryKey];
+ if ($return = $Model->saveField('email_verified', true)) {
+ $message = __d('users', 'Thank you for confirming your account', true);
+ return array(true, $message);
+ }
+ return array(false, $message);
+ }
+/**
+ * display method
+ *
+ * Fall back. Assumes that find list is setup such that it returns users real names
+ *
+ * @param mixed $id
+ * @return string
+ * @access public
+ */
+ function display(&$Model, $id = null, $format = null) {
+ if (!$id) {
+ if (!$Model->id) {
+ return false;
+ }
+ $id = $Model->id;
+ }
+ if ($format) {
+ // TODO
+ }
+ return current($Model->find('list', array('conditions' => array($Model->alias . '.' . $Model->primaryKey => $id))));
+ }
+/**
+ * forgottenPassword method
+ *
+ * Process a forgotten password request
+ *
+ * @param mixed $Model
+ * @param array $request
+ * @return array(bool, string) success/fail and an optional message
+ * @access public
+ */
+ function forgottenPassword(&$Model, $request = '') {
+ $request = trim($request);
+ extract($this->settings[$Model->alias]);
+ $Model->recursive = 0;
+ if ($fields['username'] == $fields['email']) {
+ $conditions = array($Model->alias . '.' . $fields['email'] => $request);
+ } else {
+ $conditions = array('OR' => array(
+ $Model->alias . '.' . $fields['email'] => $request,
+ $Model->alias . '.' . $fields['username'] => $request
+ ));
+ }
+ $id = $Model->field($Model->primaryKey, $conditions);
+ $message = '';
+ if ($id) {
+ $Model->id = $id;
+ $Model->log($request, 'forgotten_password_valid');
+ $expires = strtotime($Model->field('modified')) + 60 * 60 * 24;
+ if ($expires < time()) {
+ $Model->save(array());
+ };
+ $data[$Model->alias]['token'] = $this->token($Model);
+ $data[$Model->alias]['emailType'] = 'private';
+ if ($Model->sendMail('forgotten_password', $data)) {
+ $message = __d('users', 'password change email sent', true);
+ return array(true, $message);
+ }
+ $message = __d('users', 'problem sending email', true);
+ } else {
+ $Model->log($request, 'forgotten_password_invalid');
+ $message = __d('users', 'password change email sent', true);
+ if (Configure::read()) {
+ $message .= ' <br />DEBUG:' . __d('users', 'email not found', true);
+ }
+ return array(true, $message);
+ }
+ return array(false, $message);
+ }
+/**
+ * generatePassword method
+ *
+ * The length of the password is the maximum of the requested length or the lenght specified by the current password
+ * policy
+ *
+ * @param mixed $Model
+ * @param int $length
+ * @return string
+ * @access public
+ */
+ function generatePassword(&$Model, $length = 6) {
+ extract($this->settings[$Model->alias]);
+ $salt = '';
+ foreach ($passwordPolicies as $name => $policy) {
+ if (isset($policy['salt'])) {
+ $salt .= $policy['salt'];
+ }
+ if (isset($policy['length'])) {
+ $length = max ($length, $policy['length']);
+ }
+ if ($name == $passwordPolicy) {
+ break;
+ }
+ }
+ $_id = $Model->id;
+ $_data = $Model->data;
+ do {
+ $Model->create();
+ $password = $this->__generateRandom($length, $salt);
+ $Model->data[$Model->alias][$fields['password']] = Security::hash($password, null, true);
+ $Model->data[$Model->alias][$fields['password_confirm']] = $password;
+ } while (!$Model->validates());
+ $Model->create();
+ $Model->id = $_id;
+ $Model->data = $_data;
+ return $password;
+ }
+/**
+ * passwordPolicies method
+ *
+ * Returns all password policies
+ *
+ * @param mixed $Model
+ * @return array
+ * @access public
+ */
+ function passwordPolicies(&$Model) {
+ return $this->settings[$Model->alias]['passwordPolicies'];
+ }
+/**
+ * passwordPolicy method
+ *
+ * Returns the current password policy
+ *
+ * @param mixed $Model
+ * @return string
+ * @access public
+ */
+ function passwordPolicy(&$Model) {
+ return $this->settings[$Model->alias]['passwordPolicy'];
+ }
+/**
+ * register method
+ *
+ * Process a user registration request
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @return array(bool, string) success/fail and an optional message
+ * @access public
+ */
+ function register(&$Model, $data, $whitelist = array()) {
+ extract($this->settings[$Model->alias]);
+ if ($_data = $Model->save($data, true, $whitelist)) {
+ $message = sprintf(__d('users', 'Welcome %s!', true), $Model->display());
+ if ($data[$Model->alias]['generate']) {
+ $message .= sprintf(__d('users', '. Your password is <strong>%s</strong>', true),
+ $_data[$Model->alias][$fields['password_confirm']]);
+ }
+ return array(true, $message);
+ } else {
+ $message = __d('users', 'errors in form', true);
+ }
+ return array(false, $message);
+ }
+/**
+ * ResetPassword method
+ *
+ * Process a password reset request. If force is true, it is not necessary to enter the current/previous password
+ *
+ * @param mixed $Model
+ * @param array $data
+ * @param bool $force
+ * @return array(bool, string) success/fail and an optional message
+ * @access public
+ */
+ function resetPassword(&$Model, $data = array(), $force = false) {
+ extract($this->settings[$Model->alias]);
+ $return = $this->confirmAccount($Model, $data, $force, true);
+ if ($return !== true) {
+ return $return;
+ }
+ if (!$force) {
+ if (!isset($data[$Model->alias][$fields['password']])) {
+ $message = __d('users', 'please enter your new password', true);
+ return array(false, $message);
+ }
+ }
+ $message = '';
+ $Model->id = $Model->field($Model->primaryKey, array($fields['username'] =>
+ $data[$Model->alias][$fields['username']]));
+ $data[$Model->alias]['email_verified'] = 1;
+ if ($return = $Model->save($data, true, array($fields['password'], $fields['password_confirm'], 'email_verified'))) {
+ $message = __d('users', 'Your password has been changed. Please login', true);
+ if (!empty($data[$Model->alias]['generate'])) {
+ $temp_password = $this->settings[$Model->alias]['temp_password'];
+ $message .= sprintf(__d('users', '. Your new password is <strong>%s</strong>', true), $temp_password);
+ unset ($this->settings[$Model->alias]['temp_password']);
+ }
+ return array(true, $message);
+ }
+ return array(false, $message);
+ }
+/**
+ * sendMail method
+ *
+ * Send the user an email via request action to the emails controller, send method.
+ *
+ * @param mixed $Model
+ * @param mixed $template
+ * @param array $data
+ * @param mixed $subject
+ * @return bool
+ * @access public
+ */
+ function sendMail(&$Model, $template, $data = array(), $subject = null) {
+ if (!$Model->id) {
+ if (empty($data[$Model->primaryKey])) {
+ return false;
+ }
+ $Model->id = $data[$Model->primaryKey];
+ }
+ $fields = $this->settings[$Model->alias]['fields'];
+ $defaultData = $Model->read();
+ $eData = Set::merge($defaultData, $data);
+ $to = $eData[$Model->alias]['email'];
+ $data = array(
+ 'to' => $Model->display() . " <{$to}>",
+ 'template' => 'users/' . $template,
+ 'layout' => 'default',
+ 'data' => $eData,
+ );
+ $this->requestAction(array('plugin' => 'users', 'controller' => 'emails', 'action' => 'send'),
+ array('data' => $data));
+ return true;
+ }
+/**
+ * token method
+ *
+ * Returns a token derived from the user record data
+ * If data is not passed, it is taken from the user record - using the settings defined for token
+ *
+ * @param mixed $Model
+ * @param array $data
+ * @param mixed $params
+ * @return string
+ * @access public
+ */
+ function token(&$Model, $data = array(), $params = array()) {
+ extract($this->settings[$Model->alias]['token']);
+ extract($params);
+ if (!$data) {
+ $conditions = array($Model->primaryKey => $Model->id);
+ $data = $Model->find('first', compact('conditions', 'fields', 'recursive'));
+ } elseif ($recursive === -1) {
+ $data = array($Model->alias => $data[$Model->alias]);
+ }
+ $return = Security::hash(serialize($data), null, true);
+ if ($length) {
+ while(strlen($return) < $length) {
+ $return .= Security::hash($return, null, true);
+ }
+ $return = substr($return, 0, $length);
+ }
+ return $return;
+ }
+/**
+ * userAccountField method
+ *
+ * Override this method in the user mode if more complex logic is required
+ *
+ * @param mixed $Model
+ * @param string $field
+ * @return void
+ * @access public
+ */
+ function userAccountField(&$Model, $field = 'username', $data) {
+ $field = $this->settings[$Model->alias]['fields'][$field];
+ $alias = $Model->alias;
+ if (strpos('.', $field)) {
+ list($alias, $field) = explode($field, '.');
+ }
+ if (!$data[$alias][$field]) {
+ $missing = true;
+ if ($alias == $Model->alias) {
+ $Model->invalidate($field, 'missing');
+ } else {
+ $Model->$alias->invalidate($field, 'missing');
+ }
+ }
+ return $Model->field($field);
+ }
+
+/**
+ * validateConfirmMatch method
+ *
+ * Does the password confirm match the password
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $compare
+ * @return bool
+ * @access public
+ */
+ function validateConfirmMatch (&$Model, $data, $compare) {
+ $key = key($data);
+ $value = $data[$key];
+ $compare = $Model->data[$Model->alias][$compare[0]];
+ return (Security::hash($value, null, true) === $compare);
+ }
+/**
+ * validateCurrentPassword method
+ *
+ * Is the value the same as the current password
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @return bool
+ * @access public
+ */
+ function validateCurrentPassword(&$Model, $data) {
+ $key = key($data);
+ $value = $data[$key];
+ if (!$value) {
+ return false;
+ }
+ extract($this->settings[$Model->alias]);
+ return (Security::hash($value, null, true) === $Model->field($fields['password']));
+ }
+/**
+ * validatePasswordCase method
+ *
+ * At least one UPPER and one lower case letter?
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $compare
+ * @return bool
+ * @access public
+ */
+ function validatePasswordCase(&$Model, $data, $compare) {
+ if (in_array($this->settings[$Model->alias]['passwordPolicy'], array('weak', 'normal'))) {
+ return true;
+ }
+ $key = key($data);
+ $value = $data[$key];
+ $compare = $Model->data[$Model->alias][$compare[0]];
+ if (!(preg_match('/.*[a-z].*/', $compare))) {
+ return false;
+ }
+ if (!(preg_match('/.*[A-Z].*/', $compare))) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * validatePasswordDifferent method
+ *
+ * Is the new password different from the old one?
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $compare
+ * @return bool
+ * @access public
+ */
+ function validatePasswordDifferent(&$Model, $data, $compare) {
+ if (!isset($Model->data[$Model->alias][$compare[1]])) {
+ return true;
+ }
+ $key = key($data);
+ $value = $data[$key];
+ $password = $Model->data[$Model->alias][$compare[0]];
+ $current = $Model->data[$Model->alias][$compare[1]];
+ return ($password != $current);
+ }
+/**
+ * validatePasswordLength method
+ *
+ * Is the password at least as long as the current password policy minimum?
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $compare
+ * @return bool
+ * @access public
+ */
+ function validatePasswordLength(&$Model, $data, $compare) {
+ $key = key($data);
+ $value = $data[$key];
+ $compare = $Model->data[$Model->alias][$compare[0]];
+ $length = strlen($compare);
+ if ($length < $this->settings[$Model->alias]['passwordPolicies'][$this->settings[$Model->alias]['passwordPolicy']]['length']) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * validatePasswordNotEmpty method
+ *
+ * Detect an empty password
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $compare
+ * @return bool
+ * @access public
+ */
+ function validatePasswordNotEmpty(&$Model, $data, $compare) {
+ $key = key($data);
+ $value = $data[$key];
+ $compare = $Model->data[$Model->alias][$compare[0]];
+ return (preg_match('/[^\\s]/', $compare));
+ }
+/**
+ * validatePasswordNumber method
+ *
+ * Contains 1 number, but isn't all numbers?
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $compare
+ * @return bool
+ * @access public
+ */
+ function validatePasswordNumber(&$Model, $data, $compare) {
+ if ($this->settings[$Model->alias]['passwordPolicy'] == 'weak') {
+ return true;
+ }
+ $key = key($data);
+ $value = $data[$key];
+ $compare = $Model->data[$Model->alias][$compare[0]];
+ if (!(preg_match('/.*\d.*/', $compare))) {
+ return false;
+ }
+ if (!(preg_match('/.*[a-zA-Z].*/i', $compare))) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * validatePasswordSpecialChar method
+ *
+ * Contains at least 1 special char?
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $compare
+ * @return bool
+ * @access public
+ */
+ function validatePasswordSpecialChar(&$Model, $data, $compare) {
+ if (in_array($this->settings[$Model->alias]['passwordPolicy'], array('weak', 'normal', 'medium'))) {
+ return true;
+ }
+ $key = key($data);
+ $value = $data[$key];
+ $compare = $Model->data[$Model->alias][$compare[0]];
+ if (!(preg_match('/.*[^\w].*/', $compare))) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * validatePasswordUsername method
+ *
+ * Does the password contain the username?
+ *
+ * @param mixed $Model
+ * @param mixed $data
+ * @param mixed $params
+ * @return bool
+ * @access public
+ */
+ function validatePasswordUsername(&$Model, $data, $params) {
+ if ($this->settings[$Model->alias]['passwordPolicy'] == 'weak' || !isset($Model->data[$Model->alias][$params[1]])) {
+ return true;
+ }
+ $key = key($data);
+ $value = $data[$key];
+ $compare = $Model->data[$Model->alias][$params[0]];
+ $username = $Model->data[$Model->alias][$params[1]];
+ if (strpos($compare, $username) !== false) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * generateRandom method
+ *
+ * Returns a random string of the requested length and using the passed salt
+ *
+ * @param int $length
+ * @param string $salt
+ * @return string
+ * @access private
+ */
+ function __generateRandom($length = 8, $salt = 'abcdefghijklmnopqrstuvwxyz0123456789') {
+ $salt = str_shuffle ($salt);
+ $return = "";
+ $i = 0;
+ while ($i < $length) {
+ $num = rand(0, strlen($salt) -1);
+ $tmp = $salt[$num];
+ $return .= $tmp;
+ $i++;
+ }
+ return str_shuffle($return);
+ }
+/**
+ * setupValidation method
+ *
+ * Add validation rules specific to this behavior. Prepend the behaviors validation rules
+ * To allow the behavior to modify the model's data for any other validation rules
+ *
+ * @param mixed $Model
+ * @return void
+ * @access protected
+ */
+ function _setupValidation(&$Model) {
+ extract ($this->settings[$Model->alias]['fields']);
+ $Model->validate[$password_confirm] = array('notSame' => array('rule' => 'validateConfirmMatch', $password));
+ $Model->validate[$current] = array('notCurrent' => array('rule' => 'validateCurrentPassword'));
+ $Model->validate[$password] = array(
+ 'missing' => array('rule' => 'validatePasswordNotEmpty', $password_confirm, 'last' => true),
+ 'tooShort' => array('rule' => 'validatePasswordLength', $password_confirm, 'last' => true),
+ 'containsUsername' => array('rule' => 'validatePasswordUsername', 'confirm', $username, 'last' => true),
+ 'number' => array('rule' => 'validatePasswordNumber', $password_confirm, 'last' => true),
+ 'case' => array('rule' => 'validatePasswordCase', $password_confirm, 'last' => true),
+ 'special' => array('rule' => 'validatePasswordSpecialChar', $password_confirm, 'last' => true),
+ 'notChanged' => array('rule' => 'validatePasswordDifferent', $password_confirm, $current, 'last' => true),
+ );
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/models/old_password.php b/plugins/users/models/old_password.php
new file mode 100644
index 0000000..619fd8b
--- /dev/null
+++ b/plugins/users/models/old_password.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Short description for old_password.php
+ *
+ * If passwords were previously stored with a different hash mechanism, the old passwords can be stored and queried here to
+ * allow code not to be held back by the previous incarnation. Intended to transparently migrate user's passwords from old
+ * to new hash mechanism (md5+nosalt => sha1+salt) when they login. This isn't a model for any "you used that password
+ * before" type logic.
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users.models
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * OldPassword class
+ *
+ * @uses
+ * @package users
+ * @subpackage users.models
+ */
+class OldPassword extends UsersAppModel {
+/**
+ * name property
+ *
+ * @var string 'OldPassword'
+ * @access public
+ */
+ var $name = 'OldPassword';
+/**
+ * beforeFind method
+ *
+ * No table, no find
+ *
+ * @return void
+ * @access public
+ */
+ function beforeFind() {
+ if (!$this->useTable) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * setSource method
+ * If the table doesn't exist - np problem
+ *
+ * @param string $tableName 'old_passwords'
+ * @return void
+ * @access public
+ */
+ function setSource($tableName = 'old_passwords') {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $sources = $db->listSources();
+ if (is_array($sources) && !in_array(strtolower($this->tablePrefix . $tableName), array_map('strtolower', $sources))) {
+ $this->useTable = false;
+ return;
+ }
+ parent::setSource($tableName);
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/models/profile.php b/plugins/users/models/profile.php
new file mode 100644
index 0000000..b25972b
--- /dev/null
+++ b/plugins/users/models/profile.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Short description for profile.php
+ *
+ * Long description for profile.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users.models
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Profile class
+ *
+ * @uses
+ * @package users
+ * @subpackage users.models
+ */
+class Profile extends UsersAppModel {
+/**
+ * name property
+ *
+ * @var string 'Profile'
+ * @access public
+ */
+ var $name = 'Profile';
+/**
+ * belongsTo property
+ *
+ * @var array
+ * @access public
+ */
+ var $belongsTo = array('User' => array('className' => 'Users.User'));
+/**
+ * validate property
+ *
+ * @TODO
+ * @var array
+ * @access public
+ */
+ var $validate = array(
+ );
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/models/tmp/logs/configure.log b/plugins/users/models/tmp/logs/configure.log
new file mode 100644
index 0000000..8bb8317
--- /dev/null
+++ b/plugins/users/models/tmp/logs/configure.log
@@ -0,0 +1,326 @@
+2009-02-26 12:20:32 Configure: Looking for :i18n.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:20:32 Configure: Looking for :l10n.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/l10n.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/l10n.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:20:32 Configure: Looking for :i18n.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:20:32 Configure: Looking for :mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/datasources/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/datasources/dbo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/pages/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/scaffolds/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/errors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/xml/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/rss/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/js/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/controller/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/controller/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/cache/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/datasources/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/datasources/dbo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/controller/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/controller/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/controller/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/pages/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/scaffolds/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/errors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/xml/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/rss/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/js/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/config/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/config/unicode/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/config/unicode/casefolding/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/console/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/console/libs/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/model/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/model/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/model/datasources/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/model/datasources/dbo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/view/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/view/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/controller/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/controller/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/cases/libs/cache/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/fixtures/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/locale/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/locale/po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/locale/po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/models/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/tests/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/themed/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/themed/test_plugin_theme/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/themed/test_plugin_theme/tests/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/themed/test_plugin_theme/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/views/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/controllers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/controllers/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/vendors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/vendors/css/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/vendors/sample/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/vendors/img/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/vendors/shells/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/vendors/shells/tasks/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin/vendors/shells/templates/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin_two/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin_two/vendors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/tasks/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/plugins/test_plugin_two/vendors/shells/templates/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/config/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_6_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_6_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_10_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_10_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_0_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_0_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_10_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_10_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_1_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_1_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_11_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_11_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_14_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_14_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_4_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_4_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_7_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_7_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_13_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_13_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_6_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_6_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_5_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_5_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_9_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_9_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_2_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_2_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_12_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_12_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_1_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_1_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_7_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_7_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_2_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_2_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_12_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_12_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_5_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_5_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_8_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_8_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_9_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_9_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_3_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_3_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_4_po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_4_po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_8_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_8_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_13_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_13_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_11_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_11_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_0_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_0_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/po/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/po/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_14_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_14_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_3_mo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/locale/rule_3_mo/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/models/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/models/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/models/datasources/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/tests_apps/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/pages/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/scaffolds/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/themed/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/themed/test_theme/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/themed/test_theme/posts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/themed/test_theme/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/elements/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/elements/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/elements/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/elements/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/elements/nocache/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/errors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/posts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/layouts/xml/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/layouts/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/layouts/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/layouts/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/layouts/rss/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/views/layouts/js/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/controllers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/controllers/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/tmp/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/Test/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/css/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/sample/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/img/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/somename/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/shells/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/shells/tasks/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/test_app/vendors/shells/templates/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/groups/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/tests/lib/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/tasks/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/plugins/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/config/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/config/sql/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/locale/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/locale/eng/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/locale/eng/LC_MESSAGES/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/models/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/models/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/models/datasources/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/pages/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/scaffolds/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/elements/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/elements/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/elements/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/elements/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/errors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/layouts/xml/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/layouts/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/layouts/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/layouts/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/layouts/rss/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/views/layouts/js/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/cases/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/cases/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/cases/models/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/cases/controllers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/cases/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/cases/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/fixtures/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tests/groups/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/controllers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/controllers/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/logs/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/cache/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/cache/persistent/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/cache/models/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/cache/views/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/tests/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/tmp/sessions/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/webroot/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/webroot/css/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/webroot/img/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/webroot/js/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/vendors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/vendors/shells/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/vendors/shells/tasks/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/skel/vendors/shells/templates/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/console/libs/templates/views/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/datasources/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/model/datasources/dbo/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/helpers/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/pages/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/scaffolds/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/elements/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/errors/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/xml/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/html/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/email/text/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/rss/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/view/layouts/js/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/controller/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/controller/components/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/cake/libs/cache/mi.php
+2009-02-26 12:20:32 Configure: Checking :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:20:32 Configure: FOUND :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:20:32 Configure: Looking for :controller.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/controller.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/controller.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
+2009-02-26 12:20:32 Configure: Looking for :component.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/component.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/component.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/component.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:20:32 Configure: Looking for :view.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/view.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/view.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/view.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/view.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:20:32 Configure: Looking for :helper.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/helper.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/helper.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/helper.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/helper.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/helper.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:20:32 Configure: Looking for :overloadable.php
+2009-02-26 12:20:32 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:20:32 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
diff --git a/plugins/users/models/user.php b/plugins/users/models/user.php
new file mode 100644
index 0000000..5353640
--- /dev/null
+++ b/plugins/users/models/user.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Short description for user.php
+ *
+ * Long description for user.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users.models
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * UsersAppModel class
+ *
+ * @uses
+ * @package users
+ * @subpackage users.models
+ */
+class User extends UsersAppModel {
+/**
+ * name property
+ *
+ * @var string 'User'
+ * @access public
+ */
+ var $name = 'User';
+/**
+ * displayField property
+ *
+ * @var string 'username'
+ * @access public
+ */
+ var $displayField = 'username';
+/**
+ * hasOne property
+ *
+ * @var array
+ * @access public
+ */
+ var $hasOne = array('Users.Profile');
+/**
+ * actsAs property
+ *
+ * @var array
+ * @access public
+ */
+ var $actsAs = array('Users.UserAccount' => array('passwordPolicy' => 'medium'));
+/**
+ * validates property
+ *
+ * Rules for passwords are handled by the UserAccount behavior
+ *
+ * @var array
+ * @access public
+ */
+ var $validate = array(
+ 'username' => array(
+ 'missing' => array('rule' => 'notEmpty', 'last' => true),
+ 'alphaNumeric' => array('rule' => 'alphaNumeric', 'last' => true),
+ 'tooShort' => array('rule' => array('minLength', 3), 'last' => true),
+ 'isUnique'
+ ),
+ 'first_name' => array(
+ 'missing' => array('rule' => 'notEmpty')
+ ),
+ 'last_name' => array(
+ 'missing' => array('rule' => 'notEmpty')
+ ),
+ 'email' => array(
+ 'missing' => array('rule' => 'notEmpty', 'last' => true),
+ 'email' => array('rule' => 'email', 'last' => true),
+ 'isUnique'
+ ),
+ );
+/**
+ * searchConditions method
+ *
+ * Generate conditions array for searching all relevant fields for a (simple) search term
+ *
+ * @param string $term ''
+ * @return void
+ * @access public
+ */
+ function searchConditions($term = '') {
+ if (strpos($term, '%') === false) {
+ $term = '%' . $term . '%';
+ }
+ $conditions['OR'][$this->alias . '.username LIKE'] = $term;
+ $conditions['OR'][$this->alias . '.first_name LIKE'] = $term;
+ $conditions['OR'][$this->alias . '.last_name LIKE'] = $term;
+ $conditions['OR'][$this->alias . '.email LIKE'] = $term;
+ $conditions['OR']['Profile.location LIKE'] = $term;
+ $conditions['OR']['Profile.url LIKE'] = $term;
+ $conditions['OR']['Profile.bio LIKE'] = $term;
+ return $conditions;
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/tmp/logs/configure.log b/plugins/users/tmp/logs/configure.log
new file mode 100644
index 0000000..bd8020e
--- /dev/null
+++ b/plugins/users/tmp/logs/configure.log
@@ -0,0 +1,186 @@
+2009-02-26 12:11:46 Configure: Looking for :i18n.php
+2009-02-26 12:11:46 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:11:46 Configure: Looking for :l10n.php
+2009-02-26 12:11:46 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/l10n.php
+2009-02-26 12:11:46 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/l10n.php
+2009-02-26 12:11:46 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:11:46 Configure: Looking for :i18n.php
+2009-02-26 12:11:46 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:11:46 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:11:46 Configure: Looking for :i18n.php
+2009-02-26 12:11:46 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:11:46 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:12:12 Configure: Looking for :i18n.php
+2009-02-26 12:12:12 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:12:12 Configure: Looking for :l10n.php
+2009-02-26 12:12:12 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/l10n.php
+2009-02-26 12:12:12 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/l10n.php
+2009-02-26 12:12:12 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/i18n.php
+2009-02-26 12:13:08 Configure: Looking for :mi.php
+2009-02-26 12:13:08 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/vendors/mi.php
+2009-02-26 12:13:08 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/vendors/css/mi.php
+2009-02-26 12:13:08 Configure: Checking :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:13:08 Configure: FOUND :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:13:08 Configure: Looking for :controller.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/controller.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/controller.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
+2009-02-26 12:13:08 Configure: Looking for :component.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/component.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/component.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/component.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:13:08 Configure: Looking for :view.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/view.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/view.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/view.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/view.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:13:08 Configure: Looking for :helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:13:08 Configure: Looking for :overloadable.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
+2009-02-26 12:13:08 Configure: Looking for :app_helper.php
+2009-02-26 12:13:08 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/app_helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/app_helper.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/app_helper.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/app_helper.php
+2009-02-26 12:13:08 Configure: Looking for :html.php
+2009-02-26 12:13:08 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/html.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/html.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/html.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/html.php
+2009-02-26 12:13:08 Configure: Looking for :form.php
+2009-02-26 12:13:08 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/form.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/form.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/form.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/form.php
+2009-02-26 12:13:08 Configure: Looking for :session.php
+2009-02-26 12:13:08 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/session.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/session.php
+2009-02-26 12:13:08 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/session.php
+2009-02-26 12:13:08 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/session.php
+2009-02-26 12:13:11 Configure: Looking for :mi.php
+2009-02-26 12:13:11 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/vendors/mi.php
+2009-02-26 12:13:11 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/vendors/css/mi.php
+2009-02-26 12:13:11 Configure: Checking :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:13:11 Configure: FOUND :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:13:11 Configure: Looking for :controller.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/controller.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/controller.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
+2009-02-26 12:13:11 Configure: Looking for :component.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/component.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/component.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/component.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:13:11 Configure: Looking for :view.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/view.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/view.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/view.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/view.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:13:11 Configure: Looking for :helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:13:11 Configure: Looking for :overloadable.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
+2009-02-26 12:13:11 Configure: Looking for :app_helper.php
+2009-02-26 12:13:11 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/app_helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/app_helper.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/app_helper.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/app_helper.php
+2009-02-26 12:13:11 Configure: Looking for :html.php
+2009-02-26 12:13:11 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/html.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/html.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/html.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/html.php
+2009-02-26 12:13:11 Configure: Looking for :form.php
+2009-02-26 12:13:11 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/form.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/form.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/form.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/form.php
+2009-02-26 12:13:11 Configure: Looking for :session.php
+2009-02-26 12:13:11 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/session.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/session.php
+2009-02-26 12:13:11 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/session.php
+2009-02-26 12:13:11 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/session.php
+2009-02-26 12:20:33 Configure: Looking for :mi.php
+2009-02-26 12:20:33 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/vendors/mi.php
+2009-02-26 12:20:33 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/vendors/css/mi.php
+2009-02-26 12:20:33 Configure: Checking :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:20:33 Configure: FOUND :/home/andy/dev/cakes/cake/vendors/mi.php
+2009-02-26 12:20:33 Configure: Looking for :controller.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/controller.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/controller.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
+2009-02-26 12:20:33 Configure: Looking for :component.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/component.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/component.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/component.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/component.php
+2009-02-26 12:20:33 Configure: Looking for :view.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/view.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/view.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/view.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/view.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:20:33 Configure: Looking for :helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/model/behaviors/helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/controller/components/helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:20:33 Configure: Looking for :overloadable.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/overloadable.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helper.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/view.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/controller/controller.php
+2009-02-26 12:20:33 Configure: Looking for :app_helper.php
+2009-02-26 12:20:33 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/app_helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/app_helper.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/app_helper.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/app_helper.php
+2009-02-26 12:20:33 Configure: Looking for :html.php
+2009-02-26 12:20:33 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/html.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/html.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/html.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/html.php
+2009-02-26 12:20:33 Configure: Looking for :form.php
+2009-02-26 12:20:33 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/form.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/form.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/form.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/form.php
+2009-02-26 12:20:33 Configure: Looking for :session.php
+2009-02-26 12:20:33 Configure: Checking :/home/andy/dev/apps/plugins/plugins/users/views/helpers/session.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/apps/plugins/plugins/users/session.php
+2009-02-26 12:20:33 Configure: DIRECT CHECK :/home/andy/dev/cakes/cake/cake/libs/view/helpers/session.php
+2009-02-26 12:20:33 Configure: DIRECT FIND :/home/andy/dev/cakes/cake/cake/libs/view/helpers/session.php
diff --git a/plugins/users/users_app_controller.php b/plugins/users/users_app_controller.php
new file mode 100644
index 0000000..f048577
--- /dev/null
+++ b/plugins/users/users_app_controller.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Short description for users_app_controller.php
+ *
+ * Long description for users_app_controller.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * AppController class
+ *
+ * @uses
+ * @package users
+ * @subpackage users.plugins.users
+ */
+class UsersAppController extends AppController {
+}
\ No newline at end of file
diff --git a/plugins/users/users_app_model.php b/plugins/users/users_app_model.php
new file mode 100644
index 0000000..e32c9dc
--- /dev/null
+++ b/plugins/users/users_app_model.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Short description for users_app_model.php
+ *
+ * Long description for users_app_model.php
+ *
+ * PHP version 4 and 5
+ *
+ * Copyright (c) 2009, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2009, Andy Dawson
+ * @link www.ad7six.com
+ * @package users
+ * @subpackage users
+ * @since v 1.0 (20-Feb-2009)
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * AppModel class
+ *
+ * @uses
+ * @package users
+ * @subpackage users.plugins.users
+ */
+class UsersAppModel extends AppModel {
+/**
+ * construct method
+ *
+ * @param bool $id false
+ * @param mixed $table null
+ * @param mixed $ds null
+ * @return void
+ * @access private
+ */
+ function __construct($id = false, $table = null, $ds = null) {
+ if ($config = Configure::read('Users.database')) {
+ $this->useDbConfig = $config;
+ }
+ parent::__construct($id, $table, $ds);
+ }
+ function setSource($tableName) {
+ if (!Configure::read()) {
+ return parent::setSource($tableName);
+ }
+ $this->setDataSource($this->useDbConfig);
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $db->cacheSources = ($this->cacheSources && $db->cacheSources);
+
+ if ($db->isInterfaceSupported('listSources')) {
+ $sources = $db->listSources();
+ if (is_array($sources) && !in_array(strtolower($this->tablePrefix . $tableName), array_map('strtolower', $sources))) {
+ debug(Debugger::trace());
+ debug (array($this->alias, $this->tablePrefix . $tableName));
+ debug ($sources);
+ return $this->cakeError('missingTable', array(array(
+ 'className' => $this->alias,
+ 'table' => $this->tablePrefix . $tableName
+ )));
+ }
+ $this->_schema = null;
+ }
+ $this->table = $this->useTable = $tableName;
+ $this->tableToModel[$this->table] = $this->alias;
+ $this->schema();
+ }
+}
\ No newline at end of file
diff --git a/plugins/users/vendors/css/admin_default.css b/plugins/users/vendors/css/admin_default.css
new file mode 100644
index 0000000..576f529
--- /dev/null
+++ b/plugins/users/vendors/css/admin_default.css
@@ -0,0 +1,521 @@
+/* SVN FILE: $Id: admin_default.css 501 2008-11-07 12:48:34Z ad7six $ */
+/**
+ * Default styles. Inspiration taken from sites including Ohloh, Assembla and others
+ * If you notice a striking similarity between these styles and any other public site
+ * please let me know to give attribution or to request these styles be changed for clarity.
+ *
+ * Copyright (c) 2008, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2008, Andy Dawson
+ * @link www.ad7six.com
+ * @package base
+ * @subpackage base.vendors.css
+ * @since v 1.0
+ * @version $Revision: 501 $
+ * @modifiedby $LastChangedBy: ad7six $
+ * @lastmodified $Date: 2008-11-07 13:48:34 +0100 (Fri, 07 Nov 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+* {
+ margin: 0px;
+ padding: 0px;
+}
+
+a {
+ text-decoration:dotted;
+ color: #003d4c;
+}
+h1, #content h2{
+ color: #e32;
+ background:#003d4c;
+ padding: 1px 5px;
+}
+#content h2 a {
+ color: #e32;
+}
+h2 {
+ padding-top:0;
+}
+#header {
+ padding:10px 0;
+}
+
+dl dt {
+ float:left;
+ width: 250px;
+}
+dl dd {
+ padding: 2px;
+ margin: 0 0 5px 300px;
+}
+table tbody tr td {
+ text-align:left;
+}
+tr.even {
+ background: #F2F2F2;
+}
+tr.odd, tr.even {
+ cursor: pointer;
+}
+tr:hover {
+ background: yellow;
+}
+table tr td {
+ background: transparent;
+}
+
+.clearfix:after, div#context div.photo:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+body {
+ /* text-align: center; */
+ margin: 0 auto;
+ font-family: Arial, sans-serif;
+ background:#fff;
+ max-width:1200px;
+}
+p.tagline {
+ font-style: italic;
+}
+
+#navcontainer {
+ clear: right;
+ margin: 0;
+ text-align: center;
+ padding: 5px 5px 15px 5px;
+}
+
+#navcontainer ul {
+ margin: 0 auto;
+ text-align: center;
+ width: 100%;
+ height: 1.5em;
+ padding: 0;
+ list-style-type: none;
+ text-align: center;
+ border-top:1px solid #DDDDDD;
+ border-bottom:1px solid #DDDDDD;
+}
+
+#navcontainer ul li {
+ display: block;
+ float: left;
+ text-align: center;
+ padding: 0;
+ margin: 0;
+}
+
+#navcontainer ul li a, #navcontainer ul li h2 {
+ width: 10em;
+ height: 1em;
+ padding: 5px;
+ margin: 0;
+ text-decoration: none;
+ display: block;
+ text-align: center;
+ font: normal 70%/80% "Lucida Grande", "Lucida Sans Unicode", verdana, lucida, sans-serif;
+ color: #444444;
+}
+
+#navcontainer ul li a:hover, #navcontainer ul li h2, #navcontainer li a.active {
+ border-bottom:3px solid #333333;
+ color: #111111;
+}
+
+#container {
+ /* text-align: left; */
+
+}
+#container table {
+ width: 100%;
+}
+#wrapper {
+ position: relative;
+ margin-bottom: 1em;
+}
+
+#content {
+ float: left;
+ width: 80%;
+ max-width:850px;
+ padding: 5px;
+}
+#content ul, #sideBar ul {
+ padding-left: 20px;
+}
+ul.menu, ul.menu li > ul {
+ list-style-type: none;
+}
+#content ul.floater {
+ list-style-type: none;
+ padding-left: 0;
+}
+#content ul.floater li {
+ font-size:160%;
+ font-weight:bold;
+ clear: left;
+}
+#content ul.floater li ul {
+ list-style-type: none;
+ padding-left: 0;
+ width: 32%;
+ float: left;
+}
+#content ul.floater li ul li {
+ font-size:100%;
+ font-weight:normal;
+}
+ol {
+ margin: 0 0 1em 0;
+ padding: 0 0 0 20px;
+}
+#content p {
+ margin-bottom: 1em;
+}
+
+#lowerMenu {
+ -moz-border-radius: 10px;
+ background: #003d4c;
+ color: #FFFFFF;
+ padding: 50px 50px 0 50px;
+ clear: right;
+ font-size: smaller;
+}
+
+#lowerMenu div {
+ width: 33%;
+ float: left;
+ text-align: justify;
+}
+
+#lowerMenu div ul {
+ list-style-type: none;
+}
+
+#lowerMenu a {
+ text-decoration:dotted;
+ color: #FFFFFF;
+}
+
+#footer {
+ clear: both;
+ margin: 0;
+ padding: 5px 0 15px 0;
+ text-align: right;
+}
+
+#footer a {
+}
+
+#sideBar {
+ width: 300px;
+ float: right;
+ padding-left: 5px;
+ margin-bottom: -5px;
+ margin-top: 5px;
+}
+
+#sideBar div {
+ background: #EEEEDD;
+ -moz-border-radius-topright: 20px;
+ -moz-border-radius-bottomleft: 20px;
+ margin-bottom: 5px;
+ padding: 5px 5px 10px 5px;
+ text-align: justify;
+}
+
+#sideBar div h3 {
+ margin: 0 0 0.5em 0;
+}
+
+/* Forms */
+form {
+ clear: both;
+ margin-right: 20px;
+ padding: 0;
+ width: 100%;
+}
+fieldset {
+ border: 1px solid #ccc;
+ margin-top: 30px;
+ padding: 16px 20px;
+}
+fieldset legend {
+ background:#fff;
+ color: #e32;
+ font-size: 160%;
+ font-weight: bold;
+}
+fieldset fieldset {
+ margin-top: 0px;
+ margin-bottom: 20px;
+ padding: 16px 0;
+}
+fieldset fieldset legend {
+ font-size: 120%;
+ font-weight: normal;
+ margin-left: 20px;
+}
+fieldset fieldset div {
+ clear: left;
+ margin: 0 20px;
+}
+form div {
+ clear: both;
+ margin-bottom: 0.5em;
+ padding: .2em;
+ vertical-align: text-top;
+}
+form div.input {
+ color: #444;
+}
+form div.floater {
+ padding-right: 20px;
+ width: 45%;
+ float: left;
+ clear: none;
+}
+form div.required {
+ color: #333;
+ font-weight: bold;
+}
+form div.submit {
+ border: 0;
+ clear: both;
+ margin-top: 10px;
+ margin-left: 140px;
+}
+label {
+ display: block;
+ font-size: 110%;
+ padding-right: 20px;
+}
+input, textarea {
+ clear: both;
+ display: block;
+ font-size: 140%;
+ font-family: "frutiger linotype", "lucida grande", "verdana", sans-serif;
+ padding: 2px;
+ width: 90%;
+}
+select {
+ clear: both;
+ font-size: 120%;
+ vertical-align: text-bottom;
+}
+select[multiple=multiple] {
+ width: 100%;
+}
+option {
+ font-size: 120%;
+ padding: 0 3px;
+}
+input[type=checkbox] {
+ clear: left;
+ float: left;
+ margin: 0px 6px 7px 2px;
+ width: auto;
+}
+input[type=submit] {
+ display: inline;
+ font-size: 110%;
+ padding: 2px 5px;
+ width: auto;
+ vertical-align: bottom;
+}
+input[type=hidden] {
+ display: none;
+}
+div.sideBar form {
+ font-size: smaller;
+}
+
+form.compact fieldset {
+ border: none;
+ margin: 0;
+ padding: 0;
+}
+form.compact legend {
+ background: transparent;
+}
+form.compact div.input {
+ background: transparent;
+}
+form.compact div.checkbox {
+ clear: left;
+}
+form.compact label {
+ font-size: 80%;
+}
+form.compact input {
+ font-size: 80%;
+}
+form.compact div.submit {
+ margin: 0;
+ margin-bottom: 10px;
+ clear: none;
+ float: right;
+}
+
+
+/* Notices and Errors */
+/* Notices and Errors */
+.notice {
+ background: #ffcc00;
+ color: #000;
+ display: block;
+ font-family: Courier, monospace;
+ font-size: 120%;
+ line-height: 140%;
+ padding: 0.8em;
+ margin: 1em 0;
+}
+.success {
+ background: green;
+ color: #fff;
+}
+div.error-message {
+ color: #900;
+ font-weight: bold;
+}
+div.message {
+ text-align: center;
+ position: relative;
+ padding:4px;
+ margin: 0px;
+ margin-bottom: 20px;
+ background-color: #e5f0fc;
+ border: 1px solid #ccc;
+}
+.flashWarn {
+ background-color: #e5f0fc;
+ border:1px solid yellow;
+}
+.flashError, #authMessage {
+ background-color:#FFE8E8;
+ border:1px solid red;
+ color: red;
+}
+#pagination {
+ text-align:center;
+}
+pre {
+ text-align:left;
+}
+/* code blocks */
+pre.code {
+ display: none;
+ padding: 1em 30px;
+ line-height: 1.1em;
+ overflow: auto;
+ background: #f3f3f0;
+}
+ol.code {
+ margin: 1em 0;
+ padding: 0;
+ font-size: 0.75em;
+ line-height: 1.8em;
+ overflow: hidden;
+ color: #939399;
+ text-align: left;
+ list-style-position: inside;
+ border: 1px solid #d3d3d0;
+ overflow: auto;
+}
+ol.code li {
+ float: left;
+ clear: both;
+ width: 99%;
+ white-space: nowrap;
+ margin: 0;
+ padding: 0 0 0 1%;
+ background: #f3f3f0;
+}
+ol.code li.even { background: #fff; }
+ol.code li code {
+ font: 1.2em courier, monospace;
+ color: #c30;
+ white-space: pre;
+ padding-left: 0.5em;
+}
+.code .comment { color: #939399; }
+.code .default { color: #44c; }
+.code .keyword { color: #373; }
+.code .string { color: #c30; }
+
+div#hoverMenu {
+ position: absolute;
+ right: 40px;
+ top: 45px;
+ font-size: 60%;
+}
+div#hoverMenu a {
+ float: right;
+ -moz-border-radius: 10px;
+ background: #000;
+ color: #fff;
+ padding: 0.5em;
+ margin-left: 0.5em;
+}
+div.file div.photo {
+ float: right;
+}
+div#context div.photo {
+ float: left;
+}
+div#sideBar h4 {
+ position: relative;
+}
+
+div#sideBar h4 span {
+ position: absolute;
+ right: 0;
+}
+div.options ul.node-options a, a.treeOptionsToggle {
+ color: #993;
+}
+ul.tree-options {
+ margin: 0;
+ padding-left: none;
+ display: inline;
+}
+ul.tree-options li {
+ margin-right: 10px;
+ display: inline;
+}
+ul.tree-options a {
+ color: #993;
+ text-decoration: none;
+}
+li.disabled a{
+ color:#CCC;
+}
+li.pending a{
+ color:#AAA;
+ font-style: italic;
+}
+div#searchFilter form div {
+}
+div#searchFilter form div div.filter {
+ display:inline;
+}
+div#searchFilter form div label {
+ display:inline;
+}
+div#searchFilter form div input {
+ clear:none;
+ width: 40%;
+ display:inline;
+}
+td.description {
+ font-style: italic;
+}
\ No newline at end of file
diff --git a/plugins/users/views/elements/admin/header.ctp b/plugins/users/views/elements/admin/header.ctp
new file mode 100644
index 0000000..dd9cdd0
--- /dev/null
+++ b/plugins/users/views/elements/admin/header.ctp
@@ -0,0 +1,22 @@
+<?php /* SVN FILE: $Id: header.ctp 391 2008-10-03 13:57:50Z ad7six $ */ ?>
+<div id='header' class="clearfix">
+<div id='navcontainer'>
+<?php
+$menu->settings('main', array('activeMode' => 'controller'));
+$this->element('admin/menu/auto', array('ignore' => array()));
+$menu->add(array(
+ 'title' => 'Main Admin',
+ 'url' => '/admin',
+));
+$menu->add(array(
+ 'title' => 'Users',
+ 'url' => array('controller' => 'users', 'action' => 'index')
+));
+$menu->add(array(
+ 'title' => 'Logout',
+ 'url' => array('admin' => false, 'prefix' => null, 'plugin' => null, 'controller' => 'users', 'action' => 'logout')
+));
+echo $menu->generate();
+?>
+</div>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/admin/menu/bar.ctp b/plugins/users/views/elements/admin/menu/bar.ctp
new file mode 100644
index 0000000..55a766c
--- /dev/null
+++ b/plugins/users/views/elements/admin/menu/bar.ctp
@@ -0,0 +1,11 @@
+<?php /* SVN FILE: $Id: bar.ctp 386 2008-10-01 05:27:39Z ad7six $ */ ?>
+<div id="sideBar"><?php
+ $sections = $menu->sections();
+ foreach ($sections as $section) {
+ echo '<div><h2><span>' . $section . '</span></h2>';
+ echo $menu->generate($section);
+ echo '</div>';
+ }
+ echo $this->element('admin/search');
+?>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/admin/search.ctp b/plugins/users/views/elements/admin/search.ctp
new file mode 100644
index 0000000..716dad8
--- /dev/null
+++ b/plugins/users/views/elements/admin/search.ctp
@@ -0,0 +1,9 @@
+<?php /* SVN FILE: $Id: search.ctp 322 2008-09-12 17:58:52Z ad7six $ */ ?>
+<div id='search'><?php
+echo '<h2><span>Search All Users</span></h2>';
+echo $form->create(null, array('action' => 'search', 'class' => 'compact clearfix'));
+echo $form->input('query', array('label' => false));
+echo $form->input('extended', array('label' => 'extended search', 'type' => 'hidden'));
+echo $form->submit('Search');
+echo $form->end();
+?></div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/context.ctp b/plugins/users/views/elements/context.ctp
new file mode 100644
index 0000000..b14062f
--- /dev/null
+++ b/plugins/users/views/elements/context.ctp
@@ -0,0 +1,19 @@
+<?php /* SVN FILE: $Id: context.ctp 395 2008-10-04 11:15:09Z AD7six $ */
+$user = $session->read('Auth.User');
+if ($user) {
+ echo '<div id="context"><h3>Logged in as ' . $user['username'] . '</h3></div>';
+}
+if ($this->name == 'Users') {
+ if ($this->action == 'login') {
+ echo $this->element('static/terms_and_conditions');
+ } elseif ($this->action == 'register') {
+ echo $this->element('static/terms_and_conditions');
+ } else {
+ $element = $this->action . '_blurb';
+ if ($this->action == 'reset_password' && isset($this->data['User']['generate'])) {
+ $element = 'change_password_blurb';
+ }
+ echo $this->element('static/' . $element);
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/html/footer.ctp b/plugins/users/views/elements/email/html/footer.ctp
new file mode 100644
index 0000000..6ca8c9e
--- /dev/null
+++ b/plugins/users/views/elements/email/html/footer.ctp
@@ -0,0 +1,7 @@
+<?php /* SVN FILE: $Id: footer.ctp 401 2008-10-06 16:11:47Z ad7six $ */ ?>
+<div id="footer"><p><?php
+ echo $html->link(sprintf(__('Sent from %s', true), substr(env('HTTP_BASE'), 1)), $html->url('/', true));
+echo ' | ' . $html->link(
+ $html->image('cake.power.gif', array('alt'=> sprintf(__('Powered by %s', true), 'CakePHP : Rapid Development Framework'),'border'=>"0")),
+ 'http://www.cakephp.org', null, null, false); ?>
+</p></div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/html/header.ctp b/plugins/users/views/elements/email/html/header.ctp
new file mode 100644
index 0000000..1fd42b5
--- /dev/null
+++ b/plugins/users/views/elements/email/html/header.ctp
@@ -0,0 +1,16 @@
+<?php /* SVN FILE: $Id: header.ctp 577 2008-11-29 21:27:45Z AD7six $ */
+if (!isset($emailData['MiEmail']['type']) || !in_array($emailData['MiEmail']['type'], array('normal', 'newsletter_copy'))) {
+ return;
+}
+?>
+<div class="message">Mail not displayed correctly? <?php
+if ($emailData['MiEmail']['type'] == 'normal') {
+ echo $html->link(__('See this message in your browser', true),
+ array('full_base' => true, 'controller' => 'emails', 'action' => 'view',
+ $emailData['MiEmail']['id'], Inflector::slug($emailData['MiEmail']['subject'])));
+} else {
+ echo $html->link(__('See this message in your browser', true),
+ array('full_base' => true, 'controller' => 'emails', 'action' => 'newsletter',
+ $emailData['MiEmail']['chain_id'], Inflector::slug($emailData['MiEmail']['subject'])));
+}
+?></div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/html/users/account_change.ctp b/plugins/users/views/elements/email/html/users/account_change.ctp
new file mode 100644
index 0000000..8af9733
--- /dev/null
+++ b/plugins/users/views/elements/email/html/users/account_change.ctp
@@ -0,0 +1,17 @@
+<?php /* SVN FILE: $Id: account_change.ctp 559 2008-11-26 15:08:50Z ad7six $ */
+extract($data);
+extract ($data['User']) ?>
+<p>Hello <?php echo trim($first_name); ?>,</p>
+
+<p>This messages is to confirm that your <?php echo $change ?> has been changed.</p>
+<?php if ($oldValue) : ?>
+<p>Your old <?php echo $change ?> (<?php echo $oldValue ?>), is nolonger valid for your account.</p>
+<?php endif; ?>
+<br />
+<p>If you have not changed your <?php echo $change ?> - please <?php echo $html->link('contact us', array(
+ 'controller' => 'contact',
+ 'action' => 'us',
+ 'category' => '!',
+ 'subject' => 'My ' . $change . ' has changed and I didn\'t request it',
+ 'from' => $email
+)) ?> as soon as possible.</p>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/html/users/forgotten_password.ctp b/plugins/users/views/elements/email/html/users/forgotten_password.ctp
new file mode 100644
index 0000000..4461603
--- /dev/null
+++ b/plugins/users/views/elements/email/html/users/forgotten_password.ctp
@@ -0,0 +1,13 @@
+<?php /* SVN FILE: $Id: forgotten_password.ctp 574 2008-11-29 19:57:55Z ad7six $ */
+extract ($data['User']) ?>
+<p>Hello <?php echo trim($first_name); ?>,</p>
+
+<p>A request has been made to reset your password.</p>
+<br />
+<p>To get a new password please go to the following url:</p>
+<p><?php echo $html->link($html->url(array('admin' => false, 'controller' => 'users', 'action' => 'reset_password', $token), true)) ?></p>
+<br />
+<p>Where you will be prompted to choose a new password. If the above link does not work correctly your token is :</p>
+<p><?php echo $token ?></p>
+<br />
+<p>If you didn't request to change your password, you can safely ignore this email. Your password has not been changed nor given to anyone by us.</p>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/html/users/new_token.ctp b/plugins/users/views/elements/email/html/users/new_token.ctp
new file mode 100644
index 0000000..1f06074
--- /dev/null
+++ b/plugins/users/views/elements/email/html/users/new_token.ctp
@@ -0,0 +1,9 @@
+<?php /* SVN FILE: $Id: new_token.ctp 571 2008-11-28 20:33:47Z ad7six $ */
+extract ($data) ?>
+<p>Hello <?php echo trim($first_name); ?>,</p>
+<br />
+<p>Your previous token expired.</p>
+<p>Please visit <?php echo $html->link ($html->url(array('controller' => 'users', 'action' => 'confirm', $token), true)); ?> to change your password.</p>
+<br />
+<p>If the above link does not work correctly your token is :</p>
+<p><?php echo $token ?></p>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/html/users/welcome.ctp b/plugins/users/views/elements/email/html/users/welcome.ctp
new file mode 100644
index 0000000..0c22b04
--- /dev/null
+++ b/plugins/users/views/elements/email/html/users/welcome.ctp
@@ -0,0 +1,14 @@
+<?php /* SVN FILE: $Id: welcome.ctp 571 2008-11-28 20:33:47Z ad7six $ */
+extract ($data['User']) ?>
+<p>Hello <?php echo trim($first_name); ?>,</p>
+
+<p>Thanks for registering (Username: <?php echo $username?>)!</p>
+<br />
+<p>To verify your email and fully enable your account please <?php
+echo $html->link('confirm your account', $html->url(array('admin' => false, 'controller' => 'users', 'action' => 'confirm', $token), true)); ?>
+ within the next 24 hours:</p>
+<br />
+<p>If the above link does not work correctly your token is :</p>
+<p><?php echo $token ?></p>
+<br />
+<p>If you did not request an account with us please ignore this email.</p>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/text/footer.ctp b/plugins/users/views/elements/email/text/footer.ctp
new file mode 100644
index 0000000..004bbfb
--- /dev/null
+++ b/plugins/users/views/elements/email/text/footer.ctp
@@ -0,0 +1,8 @@
+<?php /* SVN FILE: $Id: footer.ctp 401 2008-10-06 16:11:47Z ad7six $ */ ?>
+
+___________________
+<?php
+$footerText = sprintf(__('Sent from %s', true), $domain);
+$footerText .= ' | ' . sprintf(__('Powered by %s', true), 'http://www.cakephp.org');
+echo $footerText;
+?>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/text/header.ctp b/plugins/users/views/elements/email/text/header.ctp
new file mode 100644
index 0000000..2c32b42
--- /dev/null
+++ b/plugins/users/views/elements/email/text/header.ctp
@@ -0,0 +1,18 @@
+<?php /* SVN FILE: $Id: header.ctp 577 2008-11-29 21:27:45Z AD7six $ */
+if (!isset($emailData['MiEmail']['type']) || !in_array($emailData['MiEmail']['type'], array('normal', 'newsletter_copy'))) {
+ return;
+}
+?>
+See this email in glorious technicolor here:
+
+<?php
+if ($emailData['MiEmail']['type'] == 'normal') {
+ echo $html->url(array('full_base' => true, 'controller' => 'emails', 'action' => 'view',
+ $emailData['MiEmail']['id'], Inflector::slug($emailData['MiEmail']['subject'])));
+} else {
+ echo $html->url(array('full_base' => true, 'controller' => 'emails', 'action' => 'newsletter',
+ $emailData['MiEmail']['chain_id'], Inflector::slug($emailData['MiEmail']['subject'])));
+}
+?>
+
+___________________
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/text/users/account_change.ctp b/plugins/users/views/elements/email/text/users/account_change.ctp
new file mode 100644
index 0000000..fc8d569
--- /dev/null
+++ b/plugins/users/views/elements/email/text/users/account_change.ctp
@@ -0,0 +1,19 @@
+<?php /* SVN FILE: $Id: account_change.ctp 702 2008-12-15 12:43:09Z ad7six $ */
+extract($data);
+extract ($data['User']) ?>
+Hello <?php echo trim($first_name); ?>,
+
+This messages is to confirm that your <?php echo $change ?> has been changed.
+
+<?php if (!empty($oldValue)) : ?>
+
+Your old <?php echo $change ?> (<?php echo $oldValue ?>), is nolonger valid for your account.
+<?php endif; ?>
+
+If you have not changed your <?php echo $change ?> - please contact us as soon
+as possible.
+
+<?php echo $html->url(array(
+ 'controller' => 'contact',
+ 'action' => 'us',
+), true) ?>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/text/users/forgotten_password.ctp b/plugins/users/views/elements/email/text/users/forgotten_password.ctp
new file mode 100644
index 0000000..e29fda4
--- /dev/null
+++ b/plugins/users/views/elements/email/text/users/forgotten_password.ctp
@@ -0,0 +1,17 @@
+<?php /* SVN FILE: $Id: forgotten_password.ctp 574 2008-11-29 19:57:55Z ad7six $ */
+extract ($data['User']) ?>
+Hello <?php echo trim($first_name); ?>,
+
+A request has been made to reset your password.
+
+To get a new password please go to the following url:
+<?php echo $html->url(array('admin' => false, 'controller' => 'users', 'action' => 'reset_password', $token), true) ?>
+
+
+Where you will be prompted to choose a new password. If the above link does not
+work correctly your token is :
+<?php echo $token ?>
+
+
+If you didn't request to change your password, you can safely ignore this email.
+Your password has not been changed nor given to anyone by us.
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/text/users/new_token.ctp b/plugins/users/views/elements/email/text/users/new_token.ctp
new file mode 100644
index 0000000..e16aefd
--- /dev/null
+++ b/plugins/users/views/elements/email/text/users/new_token.ctp
@@ -0,0 +1,10 @@
+<?php /* SVN FILE: $Id: new_token.ctp 571 2008-11-28 20:33:47Z ad7six $ */
+extract ($data) ?>
+Hello <?php echo trim($first_name); ?>,
+
+Your previous token expired.
+
+Please visit <?php echo $html->url(array('controller' => 'users', 'action' => 'confirm', $token), true); ?> to change your password.
+
+If the above link does not work your token is:
+<?php echo $token ?>
\ No newline at end of file
diff --git a/plugins/users/views/elements/email/text/users/welcome.ctp b/plugins/users/views/elements/email/text/users/welcome.ctp
new file mode 100644
index 0000000..301e0b6
--- /dev/null
+++ b/plugins/users/views/elements/email/text/users/welcome.ctp
@@ -0,0 +1,16 @@
+<?php /* SVN FILE: $Id: welcome.ctp 571 2008-11-28 20:33:47Z ad7six $ */
+extract ($data['User']) ?>
+Hello <?php echo trim($first_name); ?>,
+
+Thanks for registering (Username: <?php echo $username?>)!
+
+To verify your email and fully enable your account please click the following
+link within the next 24 hours:
+<?php echo $html->url(array('admin' => false, 'controller' => 'users', 'action' => 'confirm', $token), true) ?>
+
+
+If the above link does not work correctly your token is :
+<?php echo $token ?>
+
+
+If you did not request an account with us please ignore this email.
\ No newline at end of file
diff --git a/plugins/users/views/elements/flash.ctp b/plugins/users/views/elements/flash.ctp
new file mode 100644
index 0000000..4e21649
--- /dev/null
+++ b/plugins/users/views/elements/flash.ctp
@@ -0,0 +1,16 @@
+<?php /* SVN FILE: $Id: flash.ctp 339 2008-09-15 13:56:08Z ad7six $ */
+$messages = $session->read('Message');
+$emailFlash = '';
+if (isset($isEmail)) {
+ if ($isEmail === true || !Configure::read()) {
+ $emailFlash = $this->element('email/html/header');
+ echo $emailFlash;
+ return;
+ }
+} elseif (!$messages) {
+ return;
+}
+foreach (array_keys($messages) as $key) {
+ $session->flash($key);
+}
+echo $emailFlash;
\ No newline at end of file
diff --git a/plugins/users/views/elements/footer.ctp b/plugins/users/views/elements/footer.ctp
new file mode 100644
index 0000000..3771ae3
--- /dev/null
+++ b/plugins/users/views/elements/footer.ctp
@@ -0,0 +1,9 @@
+<?php /* SVN FILE: $Id: footer.ctp 391 2008-10-03 13:57:50Z ad7six $ */ ?>
+<div id="lowerMenu">
+ <h3>About</h3>
+ <p>This users plugin is designed such that it can be plugged-in to any project.</p>
+</div>
+<div id="footer"><p>
+ by <?php echo $html->link('AD7six.com', 'http://www.ad7six.com'); ?>
+ | Powered by <?php echo $html->link($html->image('cake.power.gif', array('alt'=>"CakePHP : Rapid Development Framework", 'border'=>"0")), 'http://www.cakephp.org', null, null, false); ?>
+</p></div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/header.ctp b/plugins/users/views/elements/header.ctp
new file mode 100644
index 0000000..d029be6
--- /dev/null
+++ b/plugins/users/views/elements/header.ctp
@@ -0,0 +1,18 @@
+<?php /* SVN FILE: $Id: header.ctp 545 2008-11-23 21:40:38Z ad7six $ */ ?>
+<div id='header' class='clearfix'>
+ <h1><?php echo $html->link('Users Plugin', '/users'); ?></h1>
+ <p class="tagline"><?php echo __d('users', 'Because every application has uses', true) ?></p>
+ <div id='navcontainer'><?php
+$menu->add(__('Main App', true), '/');
+$menu->add(__('Users Plugin Home', true), '/users');
+if ($session->check('Auth.User') && empty($isEmail)) {
+ $menu->add(__('Your Profile', true), array('controller' => 'users', 'action' => 'profile'));
+ $menu->add(__('Admin', true), '/admin/users');
+ $menu->add(__('Logout', true), array('controller' => 'users', 'action' => 'logout'));
+} else {
+ $menu->add(__('Register', true), array('controller' => 'users', 'action' => 'register'));
+ $menu->add(__('Login', true), array('controller' => 'users', 'action' => 'login'), null, array('htmlAttributes' => array('class' => 'login')));
+}
+echo $menu->generate();
+ ?></div>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/menu/sections.ctp b/plugins/users/views/elements/menu/sections.ctp
new file mode 100644
index 0000000..db29c93
--- /dev/null
+++ b/plugins/users/views/elements/menu/sections.ctp
@@ -0,0 +1,11 @@
+<?php /* SVN FILE: $Id: sections.ctp 381 2008-09-30 16:56:15Z ad7six $ */
+if (!isset($sections)) {
+ $sections = $menu->sections();
+}
+foreach ((array)$sections as $section) {
+ $out = $menu->generate($section);
+ if ($out) {
+ echo '<div><h2><span>' . $section . '</span></h2>' . $out . '</div>';
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/views/elements/menu/side.ctp b/plugins/users/views/elements/menu/side.ctp
new file mode 100644
index 0000000..18e0c50
--- /dev/null
+++ b/plugins/users/views/elements/menu/side.ctp
@@ -0,0 +1,11 @@
+<?php /* SVN FILE: $Id: side.ctp 381 2008-09-30 16:56:15Z ad7six $ */ ?>
+<div id="sideBar">
+<?php
+$topMenu = $menu->sections(0);
+if ($topMenu) {
+ echo $this->element('menu/sections', array('sections' => array($topMenu)));
+}
+echo $this->element('context');
+echo $this->element('menu/sections');
+?>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/paging.ctp b/plugins/users/views/elements/paging.ctp
new file mode 100644
index 0000000..96f5133
--- /dev/null
+++ b/plugins/users/views/elements/paging.ctp
@@ -0,0 +1,8 @@
+<?php /* SVN FILE: $Id: paging.ctp 401 2008-10-06 16:11:47Z ad7six $ */ ?>
+<div id='navigation'>
+<?php
+echo $paginator->prev('Previous', array(), null);
+echo $paginator->numbers(array('separator' => ', '));
+echo $paginator->next('Next', array(), null);
+?>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/static/change_password_blurb.ctp b/plugins/users/views/elements/static/change_password_blurb.ctp
new file mode 100644
index 0000000..11f19d7
--- /dev/null
+++ b/plugins/users/views/elements/static/change_password_blurb.ctp
@@ -0,0 +1,5 @@
+<div>
+<h3>Password Hints</h3>
+<p>Treat passwords in the same way you'd treat your house alarm code - don't choose something too easy and don't
+choose something your friends would guess!</p>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/static/forgotten_password_blurb.ctp b/plugins/users/views/elements/static/forgotten_password_blurb.ctp
new file mode 100644
index 0000000..e171f08
--- /dev/null
+++ b/plugins/users/views/elements/static/forgotten_password_blurb.ctp
@@ -0,0 +1,9 @@
+<div>
+<h3>Password Recovery Process</h3>
+<ul><li>Enter your username or email.
+</li><li>We'll send you an email containing a unique code
+</li><li>Check your email, click the link/enter the code, enter your new password
+</li><li>Done.
+</li></ul>
+<p><em>The link we send you will expire upon use or in 24hrs - whichever comes first.</em></p>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/static/reset_password_blurb.ctp b/plugins/users/views/elements/static/reset_password_blurb.ctp
new file mode 100644
index 0000000..74659d8
--- /dev/null
+++ b/plugins/users/views/elements/static/reset_password_blurb.ctp
@@ -0,0 +1,4 @@
+<div>
+<h3>Reset Password</h3>
+<p>Prove you can read your mail, are who you say you are and we'll let you back in :)</p>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/elements/static/terms_and_conditions.ctp b/plugins/users/views/elements/static/terms_and_conditions.ctp
new file mode 100644
index 0000000..cb6ecd2
--- /dev/null
+++ b/plugins/users/views/elements/static/terms_and_conditions.ctp
@@ -0,0 +1,9 @@
+<div>
+<h3>T&Cs</h3>
+<ul><li>Play nicely children.
+</li><li>This app is a demo, and doesn't do anything.
+</li><li>Register to be able to test the standard user emails.
+</li><li>Download and install to be able to see and use the standard admin functionality
+</li><li>After downloading, if you modify the database you can run <code>cake bake_admin all</code> to generate a backend for your schema
+</li></ul>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/helpers/menu.php b/plugins/users/views/helpers/menu.php
new file mode 100644
index 0000000..06b95bf
--- /dev/null
+++ b/plugins/users/views/helpers/menu.php
@@ -0,0 +1,684 @@
+<?php
+/* SVN FILE: $Id: menu.php 773 2009-02-01 22:42:40Z ad7six $ */
+/**
+ * Short description for menu.php
+ *
+ * Long description for menu.php
+ *
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 2008, Andy Dawson
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2008, Andy Dawson
+ * @link www.ad7six.com
+ * @package base
+ * @subpackage base.views.helpers
+ * @since v 1.0
+ * @version $Revision: 773 $
+ * @modifiedby $LastChangedBy: ad7six $
+ * @lastmodified $Date: 2009-02-01 23:42:40 +0100 (Sun, 01 Feb 2009) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * MenuHelper class
+ *
+ * @uses AppHelper
+ * @package base
+ * @subpackage base.views.helpers
+ */
+class MenuHelper extends AppHelper {
+/**
+ * name property
+ *
+ * @var string 'Menu'
+ * @access public
+ */
+ var $name = 'Menu';
+/**
+ * helpers property
+ *
+ * @var array
+ * @access public
+ */
+ var $helpers = array('Html');
+/**
+ * defaultSettings property
+ *
+ * @var array
+ * @access private
+ */
+ var $__defaultSettings = array(
+ 'activeMode' => 'url', // url // controller[name] // action[and controller name] // false [do nothing]
+ 'hereMode' => 'active', // active[mark the li as active] // text[no link just text] // false[do nothing]
+ 'hereKey' => null, // the key for the item to mark as active automatic based on activeMode if not specified
+ 'order' => null, // the order the whole section should be output. only used if generating many menus at once
+ 'genericElement' => 'menu/generic', // use is deprecated
+ 'uniqueKey' => 'title', // determins how data is stored internally, and how duplicate items are detected
+ 'overwrite' => false, // Overwrite the menu item if it already has been defined?
+ 'showWarnings' => true, // Trigger an error if trying to redefine a menu item and overwrite is false
+ 'headerTag' => false, // used to automatically wrap the section name in a (e.g.) h3 tag on display
+ 'typeTag' => 'ul', // The tag used for the menu links as a whole.
+ 'itemTag' => 'li', // The tag used for each menu link
+ 'wrap' => false, // a sprintf string to wrap the output of the menu e.g. "<div>%s</div>"
+ 'class' => 'menu', // the class attribute for the top level
+ 'id' => false, // the id attribute for the top level
+ 'splitCount' => false, // inject </ul><ul> after this number of menu items
+ 'autoI18n' => false // automatically put titles throught __() ?
+ );
+/**
+ * settings property
+ *
+ * @var array
+ * @access public
+ */
+ var $settings = array();
+/**
+ * section property
+ *
+ * The current section
+ *
+ * @var string 'menu'
+ * @access private
+ */
+ var $__section = 'menu';
+/**
+ * data property
+ *
+ * Holds the menu data as they get built. References flatData.
+ *
+ * @var array
+ * @access private
+ */
+ var $__data = array();
+/**
+ * flatData property
+ *
+ * A flat list of menu data
+ *
+ * @var array
+ * @access private
+ */
+ var $__flatData = array();
+/**
+ * here property
+ *
+ * Place holder for router normalized "here"
+ *
+ * @var string ''
+ * @access private
+ */
+ var $__here = '';
+/**
+ * construct method
+ *
+ * @param array $options
+ * @return void
+ * @access private
+ */
+ function __construct($options = array()) {
+ $this->__defaultSettings = am($this->__defaultSettings, $options);
+ parent::__construct($options);
+ }
+/**
+ * beforeRender method
+ *
+ * If genericElement is set, 'render' the named element. This can be used to prevent repeating menu logic if
+ * for example there are some menu items which don't change based on the specific view file
+ * The result is echoed to display errors even though the element should contain no output
+ *
+ * @access public
+ * @return void
+ */
+ function beforeRender() {
+ if (!isset($this->params['requested']) && $this->__defaultSettings['genericElement']) {
+ $view =& ClassRegistry:: getObject('view');
+ if ($view) {
+ echo $view->element($this->__defaultSettings['genericElement']);
+ }
+ }
+ return true;
+ }
+/**
+ * Add a menu item.
+ *
+ * Add a menu item syntax examples:
+ * $menu->add($title, $url); adds an entry with $title and $url to the current menu section
+ * $menu->add('menu', $title, $url); add specifically to the 'menu' section
+ * $menu->add('context', $title, $url); add an entry with $title and $url to the menu named "context"
+ * $menu->add('context', $title, $url, 'subSection'); add an entry with $title and $url to subsection "subSection for the menu named "context"
+ * $menu->add(array('url' => $url, 'title' => $title, 'options' => array('escapeTitle' => false))); array syntax, not escaping title
+ * $menu->add(array('url' => $url, 'title' => $title, 'options' => array('htmlAttributes' => array('id' => 'foo'))); array syntax, setting id for link
+ *
+ * @param string $section
+ * @param mixed $title
+ * @param mixed $url
+ * @param mixed $under
+ * @param array $options
+ * @access public
+ * @return void
+ */
+ function add($section = null, $title = null, $url = null, $under = null, $options = array()) {
+ $htmlAttributes = array();
+ $confirmMessage = false;
+ $escapeTitle = true;
+ if (is_array($section)) {
+ if (isset($section[0]['title'])) {
+ foreach ($section as $row) {
+ $this->add($row);
+ }
+ return;
+ }
+ $settings = array_merge(array('section' => $this->__section, 'settings' => array()), $section);
+ $this->__section = $settings['section'];
+ extract($settings);
+ } elseif (($section && $url !== false) ||
+ (is_string ($url) && $url[0] !== 'h' && $url[0] !== '/'&& $url[0] !== '#') || is_array($under)) {
+ if ($under) {
+ $options = $under;
+ }
+ $settings = array();
+ $options = $under;
+ $under = $url;
+ $url = $title;
+ $title = $section;
+ $section = $this->__section;
+ }
+ if (!isset($this->settings[$section])) {
+ $this->settings($section, $settings);
+ }
+ extract(array_merge($this->settings[$section], $settings));
+ if (isset($$uniqueKey)) {
+ if (is_array($$uniqueKey)) {
+ if ($uniqueKey === 'url') {
+ $key = Router::normalize($$uniqueKey);
+ } else {
+ $key = serialize($$uniqueKey);
+ }
+ } else {
+ $key = $$uniqueKey;
+ }
+ } else {
+ $key = $title;
+ }
+ if (is_array($under)) {
+ if ($uniqueKey === 'url') {
+ $under = Router::normalize($under);
+ } else {
+ $under = serialize($under);
+ }
+ }
+ list($here, $markActive, $url) = $this->__setHere($section, $url, $key, $activeMode, $hereMode, $options);
+ $htmlAttributes = array();
+ $confirmMessage = false;
+ $escapeTitle = true;
+ if ($options) {
+ extract($options);
+ }
+ $item = array(
+ 'here' => $here,
+ 'markActive' => $markActive,
+ 'url' => $url,
+ 'title' => $title,
+ 'under' => $under,
+ 'inPath'=> false,
+ 'sibling' => false,
+ 'children' => array(),
+ 'htmlAttributes' => $htmlAttributes,
+ 'confirmMessage' => $confirmMessage,
+ 'escapeTitle' => $escapeTitle
+ );
+ if ($under) {
+ if (!isset($this->__flatData[$section][$under])) {
+ $parent = array(
+ 'placeholder' => true,
+ 'here' => false,
+ 'markActive' => false,
+ 'url' => null,
+ 'title' => null,
+ 'under' => false,
+ 'inPath'=> false,
+ 'sibling' => false,
+ 'children' => array(),
+ 'htmlAttributes' => array(),
+ 'confirmMessage' => false,
+ 'escapeTitle' => true
+ );
+ $parent[$uniqueKey] = strpos('{', $under)?unserialize($under):$under;
+ $this->__flatData[$section][$under] = $parent;
+ $this->__data[$section][$under] =& $this->__flatData[$section][$under];
+ }
+ $this->__flatData[$section][$key] = $item;
+ $this->__flatData[$section][$under]['children'][$key] =& $this->__flatData[$section][$key];
+ } elseif (isset($this->__flatData[$section][$key]) && !empty($this->__flatData[$section][$key]['placeholder'])) {
+ $item['children'] =& $this->__flatData[$section][$key]['children'];
+ unset($this->__data[$section][$key]);
+ unset($this->__flatData[$section][$key]);
+ $this->__flatData[$section][$key] = $item;
+ $this->__data[$section][$key] =& $this->__flatData[$section][$key];
+ } elseif (!isset($this->__flatData[$section][$key]) || $overwrite) {
+ $this->__flatData[$section][$key] = $item;
+ $this->__data[$section][$key] =& $this->__flatData[$section][$key];
+ } elseif ($showWarnings) {
+ if ($uniqueKey === 'title') {
+ $altKey = 'url';
+ } else {
+ $altKey = 'title';
+ }
+ trigger_error ('MenuHelper::add<br /> Duplicate menu item detected for item "' . $title .
+ '" in menu "' . $section . '".<br />You can change the field used to detect duplicates' .
+ ' which is currently set to ' . $uniqueKey . ', can be changed to ' . $altKey . '.');
+ }
+ if ($hereMode === 'text' && $here === true) {
+ $this->__flatData[$section][$key]['url'] = false;
+ }
+ }
+/**
+ * addAttribute method
+ *
+ * @param mixed $tag
+ * @param string $id
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ * @access public
+ */
+ function addAttribute($tag, $id = '', $key = '', $value = null) {
+ if (!is_null($value)) {
+ $this->__attributes[$tag][$id][$key] = $value;
+ } elseif (!(isset($this->__attributes[$tag][$id]) && in_array($key, $this->__attributes[$tag][$id]))) {
+ $this->__attributes[$tag][$id][] = $key;
+ }
+ }
+/**
+ * del method
+ *
+ * Delete a menu item. Specify the section name alone to delete the entire section.
+ * Specify the section and key to delete a single menu item.
+ * Specify just the key to delete an entry from the currently active menu section
+ *
+ * @param mixed $section
+ * @param mixed $key
+ * @return void
+ * @access public
+ */
+ function del($section, $key = null) {
+ if (is_null($key)) {
+ if (isset($this->__flatData[$section])) {
+ unset ($this->__flatData[$section]);
+ unset ($this->__data[$section]);
+ return;
+ }
+ $key = $section;
+ $section = $this->__section;
+ }
+ unset ($this->__flatData[$section][$key]);
+ unset ($this->__data[$section][$key]);
+ }
+/**
+ * display menu method
+ *
+ * display menu syntax examples:
+ * echo $menu->display(); echo the currently active menu
+ * echo $menu->displaydisplay('menu'); as above but explicit
+ * echo $menu->display('menu', array('element' => 'menus/item'); use an element for each item's content
+ * echo $menu->display('menu', array('callback' => 'menuItem'); use loose method menuItem for each item's content
+ * echo $menu->display('menu', array('callback' => array(&$object, 'method'); call $object->method($data) for each item's content
+ *
+ * @param mixed $section the section name or the numerical order
+ * @param array $settings to be passed to the tree helper
+ * @param bool $createEmpty
+ * @access public
+ * @return void
+ */
+ function display($section = null, $settings = array(), $createEmpty = true) {
+ if (is_array($section)) {
+ extract(array_merge(array('section' => $this->__section), $section));
+ }
+ $this->settings($section, $settings);
+ if (!$section) {
+ $section = $this->__section;
+ }
+ if (!isset($this->settings[$section]) || empty($this->__data[$section])) {
+ $return = '';
+ } else {
+ $settings = am($this->settings[$section], $settings);
+ $this->__attributes = array();
+ $return = $this->__display($section, $settings, $this->__data[$section]);
+ }
+ if ($this->settings[$section]['wrap']) {
+ $return = sprintf($this->settings[$section]['wrap'], $return);
+ }
+ unset ($this->settings[$section]);
+ unset ($this->__data[$section]);
+ unset ($this->__flatData[$section]);
+ return $return . "\r\n";
+ }
+/**
+ * displayAll method
+ *
+ * @param array $settings
+ * @param bool $createEmpty
+ * @return void
+ * @access public
+ */
+ function displayAll($settings = array(), $createEmpty = true) {
+ $return = '';
+ foreach($this->sections() as $section) {
+ $return .= $this->display($section, $settings, $createEmpty);
+ }
+ return $return;
+ }
+/**
+ * sections method
+ *
+ * Return the names of all sections currently stored by the helper, in the order they should be processed
+ *
+ * @access public
+ * @return mixed array of menu sections if no order passed. name of the section name matching the order if passed.
+ */
+ function sections ($order = null) {
+ $sequence = array();
+ foreach ($this->settings as $key => $settings) {
+ if ($order !== null && $settings['order'] == $order) {
+ return $key;
+ } elseif (!isset($sequence[$settings['order']])) {
+ $sequence[$settings['order']] = $key;
+ } else {
+ $sequence[$settings['order'] . rand()] = $key;
+ }
+ }
+ if ($order !== null) {
+ return false;
+ }
+ ksort($sequence);
+ return $sequence;
+ }
+/**
+ * settings method
+ *
+ * @param mixed $section
+ * @param array $settings
+ * @return void
+ * @access public
+ */
+ function settings($section = null, $settings = array()) {
+ if ($section === null) {
+ $section = $this->__section;
+ } elseif (!$section) {
+ $section = $this->__section = 'menu';
+ } else {
+ $this->__section = $section;
+ }
+ if (!$this->__here) {
+ if (isset($this->params['url']['url'])) {
+ $this->__here = Router::normalize('/' . $this->params['url']['url']);
+ } else {
+ $this->__here = '/';
+ }
+ }
+ if (!isset($this->settings[$section])) {
+ $settings = array_merge($this->__defaultSettings, $settings);
+ $this->settings[$section] = $settings;
+ } elseif ($settings) {
+ $this->settings[$section] = array_merge($this->settings[$section], $settings);
+ }
+ if (!is_numeric($this->settings[$section]['order'])) {
+ $this->settings[$section]['order'] = count($this->settings);
+ }
+ return $this->settings[$section];
+ }
+/**
+ * attributes method
+ *
+ * @param mixed $rType
+ * @param bool $clear
+ * @return void
+ * @access private
+ */
+ function __attributes($tag, $clear = true) {
+ if (empty($this->__attributes[$tag])) {
+ return '';
+ }
+ foreach ($this->__attributes[$tag] as $i => &$values) {
+ foreach ($values as $j => &$val) {
+ if (is_array($val)) {
+ $_a = '';
+ foreach ($val as $k => &$v) {
+ $_a .= $k . ':' . $v;
+ }
+ $val = implode(';', $_a);
+ }
+ if (is_string($j)) {
+ $val = $j . ':' . $val . ';';
+ }
+ }
+ $values = $i . '="' . implode(' ', $values) . '"';
+ }
+ $return = ' ' . implode(' ', $this->__attributes[$tag]) . ' ';
+ if ($clear) {
+ unset($this->__attributes[$tag]);
+ }
+ return $return;
+ }
+/**
+ * internal callback
+ *
+ * Used to return the output from the html helper using the parameters for this menu option
+ *
+ * @param mixed $data
+ * @return void
+ * @access private
+ */
+ function __menuItem($data) {
+ if ($data['markActive']) {
+ $this->addAttribute($this->settings[$this->__section]['itemTag'], 'class', 'active');
+ }
+ if ($this->settings[$this->__section]['autoI18n']) {
+ $data['title'] = __($data['title'], true);
+ }
+
+ if ($data['url'] === false) {
+ return $data['title'];
+ } else {
+ return $this->Html->link($data['title'], $data['url'], $data['htmlAttributes'],
+ $data['confirmMessage'], $data['escapeTitle']);
+ }
+ }
+/**
+ * display method
+ *
+ * Generate a menu. Works recurslively for nested menus
+ *
+ * @param mixed $section
+ * @param mixed $settings
+ * @param mixed $data
+ * @return void
+ * @access private
+ */
+ function __display($section, $settings, $data, $header = true, $prefix = "\r\n") {
+ $return = '';
+ $start = true;
+ if ($settings['splitCount']) {
+ $total = count($data);
+ $splitCount = $total / $settings['splitCount'];
+ $rounded = (int)$splitCount;
+ if ($rounded < $splitCount) {
+ $splitCount = $rounded + 1;
+ }
+ $splitCounter = 0;
+ }
+ $typeTag = $settings['typeTag'];
+ $itemTag = $settings['itemTag'];
+ foreach ($data as $i => &$result) {
+ if ($settings['splitCount']) {
+ if ($splitCounter && !($splitCounter % $splitCount) && $splitCounter != $total) {
+ $return .= "$prefix</$typeTag><$typeTag>";
+ }
+ $splitCounter++;
+ }
+ $contents = $this->menuItem($result);
+ $attributes = $this->__attributes($itemTag);
+ $return .= "$prefix\t<$itemTag{$attributes}>$contents</$itemTag>";
+ if (!empty($result['children'])) {
+ $settings = am($settings, array('class' => false, 'id' => false));
+ $return .= $this->__display($section, $settings, $result['children'], false, $prefix . "\t");
+ }
+ if ($start) {
+ $start = false;
+ $return = $prefix . $this->__displayHead($section, $settings, $header) . $return;
+ }
+ }
+ $return .= "$prefix</$typeTag>";
+ return $return;
+ }
+/**
+ * displayHead method
+ *
+ * Optionally announce the start of this menu (create <h3>name of menu</h3>)
+ * Generate a ul tag with appropriate attributes
+ *
+ * @param mixed $section
+ * @param mixed $settings
+ * @param bool $header
+ * @return void
+ * @access private
+ */
+ function __displayHead($section, $settings, $header = false) {
+ $return = '';
+ if ($header) {
+ $section = Inflector::humanize(Inflector::underscore($section));
+ if ($settings['autoI18n']) {
+ $section = __($section, true);
+ }
+ if (!empty($settings['headerTag'])) {
+ $tag = $settings['headerTag'];
+ $return .= "<$tag>$section</$tag>";
+ }
+ if (!empty($settings['class'])) {
+ $this->addAttribute($settings['typeTag'], 'class', $settings['class']);
+ }
+ if (!empty($settings['id'])) {
+ $this->addAttribute($settings['typeTag'], 'id', $settings['id']);
+ }
+ }
+ $tag = $settings['typeTag'];
+ $attributes = $this->__attributes($tag);
+ $return .= "<$tag{$attributes}>";
+ return $return;
+ }
+/**
+ * setHere method
+ *
+ * Used internally to detect whether the current menu item links to the page currently
+ * being rendered and modify the url if appropriate
+ *
+ * @param mixed $section
+ * @param mixed $url
+ * @param mixed $activeMode
+ * @param mixed $hereMode
+ * @access private
+ * @return array($here, $markActive, $url)
+ */
+ function __setHere($section, $url, $key, $activeMode, $hereMode, $options) {
+ $view =& ClassRegistry:: getObject('view');
+ if (isset($this->settings[$section]['hereKey']) || !$view) {
+ return array(false, false, $url);
+ }
+ $here = $markActive = false;
+ if (!empty($options['markActive'])) {
+ $markActive = true;
+ } elseif ($activeMode == 'url' && Router::normalize($url) == $this->__here) {
+ $here = true;
+ } elseif (is_array($url) &&
+ (!isset($url['controller']) ||
+ Inflector::underscore($url['controller']) == Inflector::underscore($view->name))) {
+ if ($activeMode == 'controller') {
+ $here = true;
+ } elseif ($activeMode == 'action' &&
+ (!isset($url['action']) || $url['action'] == Inflector::underscore($view->action))) {
+ $here = true;
+ }
+ }
+ if ($here) {
+ $this->settings[$section]['hereKey'] = $key;
+ if ($hereMode == 'text') {
+ $url = false;
+ } elseif ($hereMode) {
+ $markActive = true;
+ }
+ }
+ return array($here, $markActive, $url);
+ }
+/**
+ * addm method
+ *
+ * @deprecated
+ * @param string $section
+ * @param array $data
+ * @access public
+ * @return void
+ */
+ function addm($section = null, $data = array()) {
+ if (is_array($section)) {
+ return $this->add($section);
+ }
+ $this->__section = $section;
+ return $this->add($data);
+ }
+/**
+ *
+ * addItemAttribute method
+ *
+ * @deprecated
+ * @param string $id
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ * @access public
+ */
+ function addItemAttribute($id = '', $key = '', $value = null) {
+ $this->addAttribute($this->settings[$this->__section]['itemTag'], $id, $key, $value);
+ }
+/**
+ * addTypeAttribute method
+ *
+ * @deprecated
+ * @param string $id
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ * @access public
+ */
+ function addTypeAttribute($id = '', $key = '', $value = null) {
+ $this->addAttribute($this->settings[$this->__section]['typeTag'], $id, $key, $value);
+ }
+/**
+ * internal callback
+ *
+ * @deprecated
+ * @param array $data
+ * @access public
+ * @return void
+ */
+ function menuItem(&$data) {
+ return $this->__menuItem($data);
+ }
+/**
+ * generate method
+ *
+ * @deprecated
+ * @param mixed $section
+ * @param array $settings
+ * @param bool $createEmpty
+ * @return void
+ * @access public
+ */
+ function generate($section = null, $settings = array(), $createEmpty = true) {
+ return $this->display($section, $settings, $createEmpty);
+ }
+}
+?>
\ No newline at end of file
diff --git a/plugins/users/views/layouts/email/html/default.ctp b/plugins/users/views/layouts/email/html/default.ctp
new file mode 100644
index 0000000..4d94561
--- /dev/null
+++ b/plugins/users/views/layouts/email/html/default.ctp
@@ -0,0 +1,34 @@
+<?php /* SVN FILE: $Id: default.ctp 521 2008-11-15 13:14:35Z ad7six $ */
+include (VIEWS . 'layouts/default.ctp');
+$contents = ob_get_clean();
+ob_start();
+preg_match_all('@<script.*>.*</script>@iU', $contents, $matches);
+foreach ($matches[0] as $match) {
+ $contents = str_replace($match, '', $contents);
+}
+preg_match_all('@<link\s*rel="stylesheet"[^>]*type="text/css"[^>]*href="([^"]*)"[^>]*/>@i', $contents, $result, PREG_PATTERN_ORDER);
+App::import('Vendor', 'MiCompressor');
+$styles = '';
+foreach ($result[1] as $cssFile) {
+ $contents = str_replace($result[0], '', $contents);
+ $cssFile = str_replace($this->webroot . 'css/', '', $cssFile);
+ if (strpos($cssFile, 'mini.css') !== false) {
+ list($_, $request) = explode('?', $cssFile);
+ $compress = true;
+ $type = 'css';
+ $log = false;
+ $styles .= MiCompressor::serve(compact('request', 'compress', 'type', 'log')) . "\r\n";
+ } elseif (file_exists(CSS . $cssFile)) {
+ $styles .= file_get_contents(CSS . $cssFile);
+ } else {
+ // No fallback. Use mini!
+ }
+}
+$base = $html->url('/', true);
+$styleTag = '<style type="text/css">' . $styles . '</style>';
+$contents = str_replace('</head>', $styleTag . '</head>', $contents);
+$contents = str_replace('href="/', 'href="' . $base, $contents);
+$contents = str_replace('src="/', 'src="' . $base, $contents);
+$contents = preg_replace(array("@[\r\n\t]+@", '@>\s+<@', '@\s+@', '@\s?{\s?@', '@\s?}\s?@'), array(' ', '><', ' ', '{', '}'), $contents);
+echo $contents;
+?>
\ No newline at end of file
diff --git a/plugins/users/views/layouts/email/text/default.ctp b/plugins/users/views/layouts/email/text/default.ctp
new file mode 100644
index 0000000..dba4851
--- /dev/null
+++ b/plugins/users/views/layouts/email/text/default.ctp
@@ -0,0 +1,5 @@
+<?php /* SVN FILE: $Id: default.ctp 401 2008-10-06 16:11:47Z ad7six $ */
+echo $this->element('email/text/header') . "\r\n";
+echo $content_for_layout . "\r\n";
+echo $this->element('email/text/footer');
+?>
\ No newline at end of file
diff --git a/plugins/users/views/layouts/users_admin_default.ctp b/plugins/users/views/layouts/users_admin_default.ctp
new file mode 100644
index 0000000..42bd41f
--- /dev/null
+++ b/plugins/users/views/layouts/users_admin_default.ctp
@@ -0,0 +1,27 @@
+<?php echo $html->docType('xhtml-trans'); ?>
+<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
+<head>
+<?php echo $html->charset(); ?>
+<title><?php echo htmlspecialchars($title_for_layout); ?></title>
+<?php
+echo $html->meta('icon');
+echo $html->css(array('cake.generic.css', '/users/css/admin_default'));
+echo $scripts_for_layout;
+?>
+</head>
+<body>
+<?php echo $this->element('admin/header'); ?>
+ <div id='container'>
+ <div id='content'><?php
+ echo $this->element('flash');
+ echo $content_for_layout;
+ ?></div>
+ <?php echo $this->element('admin/menu/bar'); ?>
+ </div>
+<?php
+if (isset($javascript)) {
+ //echo $javascript->link('');
+}
+?>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/users/views/layouts/users_default.ctp b/plugins/users/views/layouts/users_default.ctp
new file mode 100644
index 0000000..3681953
--- /dev/null
+++ b/plugins/users/views/layouts/users_default.ctp
@@ -0,0 +1,31 @@
+<?php /* SVN FILE: $Id: default.ctp 560 2008-11-27 15:14:51Z ad7six $ */
+echo $html->docType('xhtml-trans'); ?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<?php echo $html->charset(); ?>
+<title><?php echo htmlspecialchars($title_for_layout); ?></title>
+<?php
+echo $html->meta('icon');
+echo $html->css(array('/users/css/default'));
+echo $scripts_for_layout;
+?>
+</head>
+<body id="<?php echo $this->name; ?>" class="<?php echo $this->action; ?>">
+ <div id="container">
+ <?php echo $this->element('header'); ?>
+ <div id='wrapper' class="clearfix">
+ <div id="content"><?php
+ echo $this->element('flash');
+ echo $content_for_layout;
+ ?></div>
+ <?php echo $this->element('menu/side'); ?>
+ </div>
+ <?php echo $this->element('footer'); ?>
+ </div>
+<?php
+if (isset($javascript)) {
+ //echo $javascript->link('');
+}
+?>
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/users/views/users/admin_edit.ctp b/plugins/users/views/users/admin_edit.ctp
new file mode 100644
index 0000000..bbaae71
--- /dev/null
+++ b/plugins/users/views/users/admin_edit.ctp
@@ -0,0 +1,23 @@
+<?php /* SVN FILE: $Id: admin_edit.ctp 357 2008-09-17 14:17:24Z ad7six $ */
+if ($data) {
+ extract($data);
+}
+$action = in_array($this->action, array('add', 'admin_add'))?'Add':'Edit';
+$action = Inflector::humanize($action);
+$name = isset($this->data['User']['id'])?$this->data['User']['username']:' new';
+?>
+<h1><?php echo $this->name . ' - ' . $action . ' ' . $name ?></h1>
+<div class="form-container">
+<?php
+echo $form->create();
+echo $form->inputs(array(
+ 'legend' => false,
+ 'id',
+ 'username',
+ 'first_name',
+ 'last_name',
+ 'email',
+ 'email_verified',
+));
+echo $form->end('Submit');
+?></div>
\ No newline at end of file
diff --git a/plugins/users/views/users/admin_index.ctp b/plugins/users/views/users/admin_index.ctp
new file mode 100644
index 0000000..53d943a
--- /dev/null
+++ b/plugins/users/views/users/admin_index.ctp
@@ -0,0 +1,30 @@
+<?php /* SVN FILE: $Id: admin_index.ctp 326 2008-09-12 18:23:33Z ad7six $ */ ?>
+<h1>Users</h1>
+<div class="container">
+<?php
+$pass = $this->passedArgs;
+$pass['action'] = str_replace(Configure::read('Routing.admin') . '_', '', $this->action); // temp
+$paginator->options(array('url' => $pass));
+?>
+<table>
+<?php
+$th = array(
+ $paginator->sort('Id', 'id'),
+ $paginator->sort('Name', 'last_name'),
+ $paginator->sort('Username', 'username'),
+ $paginator->sort('Email', 'email'),
+);
+echo $html->tableHeaders($th);
+foreach ($data as $row) {
+ extract($row);
+ $tr = array(
+ $html->link($User['id'], array('action' => 'view', $User['id'])),
+ $displayNames[$User['id']],
+ $User['username'],
+ $User['email'],
+ );
+ echo $html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'));
+}
+?>
+</table>
+<?php echo $this->element('paging'); ?></div>
\ No newline at end of file
diff --git a/plugins/users/views/users/admin_view.ctp b/plugins/users/views/users/admin_view.ctp
new file mode 100644
index 0000000..d00e18a
--- /dev/null
+++ b/plugins/users/views/users/admin_view.ctp
@@ -0,0 +1,25 @@
+<?php /* SVN FILE: $Id: admin_view.ctp 574 2008-11-29 19:57:55Z ad7six $ */
+extract($data); ?>
+<h1><?php echo $User['username'] ?></h1>
+<div class="container">
+<table>
+<?php
+ extract($data);
+ echo $html->tableCells(array('id',$User['id']));
+ echo $html->tableCells(array('username',$User['username']));
+ echo $html->tableCells(array('name',$User['first_name'] . ' ' . $User['last_name']));
+ echo $html->tableCells(array('email',$User['email']));
+ echo $html->tableCells(array('email_verified',$User['email_verified']));
+?>
+</table>
+</div>
+<?php
+$menu->add(array(
+ 'section' => 'This User',
+ 'title' => 'Edit',
+ 'url' => array('action' => 'edit', $User['id'])
+));
+$menu->add(array(
+ 'title' => 'Delete',
+ 'url' => array('action' => 'delete', $User['id'])
+));
\ No newline at end of file
diff --git a/plugins/users/views/users/change_password.ctp b/plugins/users/views/users/change_password.ctp
new file mode 100644
index 0000000..1a6cd61
--- /dev/null
+++ b/plugins/users/views/users/change_password.ctp
@@ -0,0 +1,17 @@
+<?php /* SVN FILE: $Id: change_password.ctp 603 2008-12-01 23:53:51Z ad7six $ */ ?>
+<div class="container form">
+<?php
+echo $form->create(null, array('action' => 'change_password'));
+echo $form->inputs(array(
+ 'legend' => __d('users', 'Please enter a new password', true),
+ 'username' => array('type' => 'hidden'),
+ 'current_password' => array('type' => 'password'),
+ 'password',
+ 'confirm' => array('type' => 'password'),
+ 'generate' => array(
+ 'type' => 'checkbox',
+ 'label' => __d('users', 'Generate me a random password (shown on the next screen)', true)
+ ),
+));
+echo $form->end(__d('users', 'Submit', true));
+?></div>
\ No newline at end of file
diff --git a/plugins/users/views/users/confirm.ctp b/plugins/users/views/users/confirm.ctp
new file mode 100644
index 0000000..fe5995c
--- /dev/null
+++ b/plugins/users/views/users/confirm.ctp
@@ -0,0 +1,12 @@
+<?php /* SVN FILE: $Id: confirm.ctp 695 2008-12-12 13:50:20Z ad7six $ */ ?>
+<div class="container form">
+<?php
+echo $form->create(null, array('url' => '/' . $this->params['url']['url']));
+$inputs = array('legend' => __d('users', 'Please enter your email token', true), $fields['email']);
+if ($fields['confirmation']) {
+ $inputs[] = $fields['confirmation'];
+}
+$inputs['token'] = array('legend' => __d('users', 'token', true), 'size' => 40, 'default' => $token);
+echo $form->inputs($inputs);
+echo $form->end(__d('users', 'Submit', true));
+?></div>
\ No newline at end of file
diff --git a/plugins/users/views/users/edit.ctp b/plugins/users/views/users/edit.ctp
new file mode 100644
index 0000000..c8fcf1d
--- /dev/null
+++ b/plugins/users/views/users/edit.ctp
@@ -0,0 +1,21 @@
+<<<?php /* SVN FILE: $Id: edit.ctp 603 2008-12-01 23:53:51Z ad7six $ */ ?>
+<div class="container form">
+<?php
+$action = in_array($this->action, array('add', 'admin_add'))?'Add':'Edit';
+$action = Inflector::humanize($action);
+$profilePic = '';
+if ($data['User']['pic']) {
+ $profilePic = $this->element('thumb', array('data' => $data['User'], 'size' => 'thumb'));
+}
+echo $form->create(null, array('type' => 'file'));
+echo $form->inputs(array(
+ 'legend' => __d('users', 'Edit your profile', true),
+ 'id',
+ 'pic' => array('type' => 'file', 'before' => $profilePic, 'label' => __d('users', 'Your profile picture', true)),
+ 'email',
+ 'first_name',
+ 'last_name',
+));
+echo $form->end('Submit');
+echo $this->element('editor', array('process' => 'div#content textarea'));
+?></div>
\ No newline at end of file
diff --git a/plugins/users/views/users/forgotten_password.ctp b/plugins/users/views/users/forgotten_password.ctp
new file mode 100644
index 0000000..c5d1e87
--- /dev/null
+++ b/plugins/users/views/users/forgotten_password.ctp
@@ -0,0 +1,17 @@
+<?php /* SVN FILE: $Id: forgotten_password.ctp 603 2008-12-01 23:53:51Z ad7six $ */ ?>
+<div id="forgotten_password" class="container form">
+<h2><?php echo __d('users', 'forgotten password', true) ?></h2>
+<p><?php __d('users', 'If you\'ve forgotten your password you can reset it by submitting the form below') ?></p>
+<p><?php __d('users', "We'll send you an email that you must read to proceed, this helps to confirm that it's really you requesting to change your password.");
+echo __d('users', 'All you need to do is check the mail - click the link and enter a new password to regain access to your account.') ?></p>
+<?php
+echo $form->create(null, array('action' => 'forgotten_password'));
+if ($authFields['username'] == 'email') {
+ echo $form->input('email');
+} else {
+ echo $form->input('email', array('label' => __d('users', 'email or username', true)));
+}
+echo $form->submit(__d('users', 'reset password', true)) ;
+echo $form->end();
+?>
+</div>
\ No newline at end of file
diff --git a/plugins/users/views/users/login.ctp b/plugins/users/views/users/login.ctp
new file mode 100644
index 0000000..c3389a5
--- /dev/null
+++ b/plugins/users/views/users/login.ctp
@@ -0,0 +1,16 @@
+<?php /* SVN FILE: $Id: login.ctp 613 2008-12-03 14:43:14Z ad7six $ */ ?>
+<div class="container form">
+<?php
+echo $form->create(null, array('action' => 'login'));
+$after = '<p>' . $html->link(__d('users', 'forgotten password', true), array('action' => 'forgotten_password')) .
+ ' ' . $html->link(__d('users', 'sign up', true), array('action' => 'register')) .
+ '</p>';
+echo $form->inputs(array(
+ 'legend' => 'Login',
+ $authFields['username'],
+ $authFields['password'] => array('value' => '', 'after' => $after),
+ 'remember_me' => array('label' => __d('users', 'remember_me', true),
+ 'type' => 'checkbox', 'after' => '<p>' . __d('users', 'for 2 weeks unless I sign out.', true) . '</p>'),
+));
+echo $form->end(__d('users', 'Login', true));
+?></div>
\ No newline at end of file
diff --git a/plugins/users/views/users/profile.ctp b/plugins/users/views/users/profile.ctp
new file mode 100644
index 0000000..ea11882
--- /dev/null
+++ b/plugins/users/views/users/profile.ctp
@@ -0,0 +1,23 @@
+<?php /* SVN FILE: $Id: profile.ctp 574 2008-11-29 19:57:55Z ad7six $ */
+extract ($data);
+?>
+ <h3><?php echo $User['username'] ?></h3>
+<?php
+if ($User['pic']) {
+ echo $this->element('thumb', array('data' => $User, 'size' => 'medium'));
+}
+?>
+<dl>
+ <dt>Username</dt>
+ <dd><?php echo $User['username']; ?></dd>
+ <dt>Name</dt>
+ <dd><?php echo $User['first_name'] . ' ' . $User['last_name']; ?>.</dd>
+ <dt>Email</dt>
+ <dd><?php echo $User['email']; ?>.</dd>
+</dl>
+<?php
+$menu->addm('Options', array(
+ array('title' => 'Your profile', 'url' => array('action' => 'profile', $session->read('Auth.User.username'))),
+ array('title' => 'Edit Your profile', 'url' => array('action' => 'edit')),
+ array('title' => 'Change your password', 'url' => array('action' => 'change_password')),
+));
\ No newline at end of file
diff --git a/plugins/users/views/users/register.ctp b/plugins/users/views/users/register.ctp
new file mode 100644
index 0000000..f67e0d8
--- /dev/null
+++ b/plugins/users/views/users/register.ctp
@@ -0,0 +1,19 @@
+<?php /* SVN FILE: $Id: register.ctp 560 2008-11-27 15:14:51Z ad7six $ */
+echo $form->create(null, array('url' => '/' . $this->params['url']['url']));
+$out = $form->input('username');
+
+$firstName = $form->input('first_name', array('fieldset' => false, 'div' => 'floater'));
+$lastName = $form->input('last_name', array('fieldset' => false, 'div' => 'floater floaterLast'));
+$out .= $html->tag('div', $firstName . $lastName, array('class' => 'input clearFix'));
+
+$out .= $form->input('email');
+$password = $form->input('password', array('fieldset' => false, 'div' => 'floater', 'error' => false));
+$confirm = $form->input('confirm', array('fieldset' => false, 'div' => 'floater floaterLast', 'type' => 'password'));
+$pwError = $form->error('password');
+$out .= $html->tag('div', $password . $confirm . $pwError, array('class' => 'input clearFix'));
+
+$out .= $form->input('generate', array('fieldset' => false, 'type' => 'checkbox',
+ 'label' => __d('users', 'Generate me a random password (shown on the next screen)', true)));
+echo sprintf($html->tags['fieldset'], '', sprintf($html->tags['legend'], __d('users', 'Registration', true)) . $out);
+echo $form->end(__d('users', 'sign up', true));
+?>
\ No newline at end of file
diff --git a/plugins/users/views/users/reset_password.ctp b/plugins/users/views/users/reset_password.ctp
new file mode 100644
index 0000000..bd6c524
--- /dev/null
+++ b/plugins/users/views/users/reset_password.ctp
@@ -0,0 +1,26 @@
+<?php /* SVN FILE: $Id: reset_password.ctp 703 2008-12-15 12:51:17Z ad7six $ */ ?>
+<div class="container form">
+<?php
+echo $form->create(null, array('url' => '/' . $this->params['url']['url']));
+$inputs = array(
+ 'legend' => __d('users', 'Please enter a new password', true),
+ 'token' => array('type' => 'hidden'),
+ $fields['email'] => array('type' => 'hidden'),
+);
+if ($fields['username'] != 'email') {
+ $inputs[$fields['username']] = array('type' => 'hidden', 'value' => 'x');
+}
+if ($fields['confirmation'] && !isset($inputs[$fields['confirmation']])) {
+ $inputs[] = $fields['confirmation'];
+}
+$inputs = am($inputs, array(
+ $fields['password'],
+ $fields['password_confirm'] => array('type' => 'password'),
+ 'generate' => array(
+ 'type' => 'checkbox',
+ 'label' => __d('users', 'Generate me a random password (shown on the next screen)', true)
+ ),
+));
+echo $form->inputs($inputs);
+echo $form->end(__d('users', 'Submit', true));
+?></div>
\ No newline at end of file
