summaryrefslogtreecommitdiff
path: root/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller
diff options
context:
space:
mode:
Diffstat (limited to 'poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller')
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php82
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php165
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php70
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php160
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php172
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php539
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php178
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php143
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php162
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php128
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php67
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php102
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php271
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php68
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php722
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php523
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php464
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php383
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php730
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php598
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php190
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php129
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php1228
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php447
25 files changed, 7763 insertions, 0 deletions
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php
new file mode 100644
index 0000000..5778648
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Error Handling Controller
+ *
+ * Controller used by ErrorHandler to render error views.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Error Handling Controller
+ *
+ * Controller used by ErrorHandler to render error views.
+ *
+ * @package Cake.Controller
+ */
+class CakeErrorController extends AppController {
+
+/**
+ * Controller name
+ *
+ * @var string
+ */
+ public $name = 'CakeError';
+
+/**
+ * Uses Property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * __construct
+ *
+ * @param CakeRequest $request
+ * @param CakeResponse $response
+ */
+ public function __construct($request = null, $response = null) {
+ parent::__construct($request, $response);
+ if (count(Router::extensions())) {
+ $this->components[] = 'RequestHandler';
+ }
+ $this->constructClasses();
+ if ($this->Components->enabled('Auth')) {
+ $this->Components->disable('Auth');
+ }
+ if ($this->Components->enabled('Security')) {
+ $this->Components->disable('Security');
+ }
+ $this->startupProcess();
+
+ $this->_set(array('cacheAction' => false, 'viewPath' => 'Errors'));
+ }
+
+/**
+ * Escapes the viewVars.
+ *
+ * @return void
+ */
+ public function beforeRender() {
+ parent::beforeRender();
+ foreach ($this->viewVars as $key => $value) {
+ if (!is_object($value)) {
+ $this->viewVars[$key] = h($value);
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php
new file mode 100644
index 0000000..876174e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php
@@ -0,0 +1,165 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ComponentCollection', 'Controller');
+
+/**
+ * Base class for an individual Component. Components provide reusable bits of
+ * controller logic that can be composed into a controller. Components also
+ * provide request life-cycle callbacks for injecting logic at specific points.
+ *
+ * ## Life cycle callbacks
+ *
+ * Components can provide several callbacks that are fired at various stages of the request
+ * cycle. The available callbacks are:
+ *
+ * - `initialize()` - Fired before the controller's beforeFilter method.
+ * - `startup()` - Fired after the controller's beforeFilter method.
+ * - `beforeRender()` - Fired before the view + layout are rendered.
+ * - `shutdown()` - Fired after the action is complete and the view has been rendered
+ * but before Controller::afterFilter().
+ * - `beforeRedirect()` - Fired before a redirect() is done.
+ *
+ * @package Cake.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html
+ * @see Controller::$components
+ */
+class Component extends Object {
+
+/**
+ * Component collection class used to lazy load components.
+ *
+ * @var ComponentCollection
+ */
+ protected $_Collection;
+
+/**
+ * Settings for this Component
+ *
+ * @var array
+ */
+ public $settings = array();
+
+/**
+ * Other Components this component uses.
+ *
+ * @var array
+ */
+ public $components = array();
+
+/**
+ * A component lookup table used to lazy load component objects.
+ *
+ * @var array
+ */
+ protected $_componentMap = array();
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
+ * @param array $settings Array of configuration settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->_Collection = $collection;
+ $this->settings = $settings;
+ $this->_set($settings);
+ if (!empty($this->components)) {
+ $this->_componentMap = ComponentCollection::normalizeObjectArray($this->components);
+ }
+ }
+
+/**
+ * Magic method for lazy loading $components.
+ *
+ * @param string $name Name of component to get.
+ * @return mixed A Component object or null.
+ */
+ public function __get($name) {
+ if (isset($this->_componentMap[$name]) && !isset($this->{$name})) {
+ $settings = array_merge((array)$this->_componentMap[$name]['settings'], array('enabled' => false));
+ $this->{$name} = $this->_Collection->load($this->_componentMap[$name]['class'], $settings);
+ }
+ if (isset($this->{$name})) {
+ return $this->{$name};
+ }
+ }
+
+/**
+ * Called before the Controller::beforeFilter().
+ *
+ * @param Controller $controller Controller with components to initialize
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::initialize
+ */
+ public function initialize(Controller $controller) {
+ }
+
+/**
+ * Called after the Controller::beforeFilter() and before the controller action
+ *
+ * @param Controller $controller Controller with components to startup
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::startup
+ */
+ public function startup(Controller $controller) {
+ }
+
+/**
+ * Called before the Controller::beforeRender(), and before
+ * the view class is loaded, and before Controller::render()
+ *
+ * @param Controller $controller Controller with components to beforeRender
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRender
+ */
+ public function beforeRender(Controller $controller) {
+ }
+
+/**
+ * Called after Controller::render() and before the output is printed to the browser.
+ *
+ * @param Controller $controller Controller with components to shutdown
+ * @return void
+ * @link @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::shutdown
+ */
+ public function shutdown(Controller $controller) {
+ }
+
+/**
+ * Called before Controller::redirect(). Allows you to replace the url that will
+ * be redirected to with a new url. The return of this method can either be an array or a string.
+ *
+ * If the return is an array and contains a 'url' key. You may also supply the following:
+ *
+ * - `status` The status code for the redirect
+ * - `exit` Whether or not the redirect should exit.
+ *
+ * If your response is a string or an array that does not contain a 'url' key it will
+ * be used as the new url to redirect to.
+ *
+ * @param Controller $controller Controller with components to beforeRedirect
+ * @param string|array $url Either the string or url array that is being redirected to.
+ * @param integer $status The status code of the redirect
+ * @param boolean $exit Will the script exit.
+ * @return array|null Either an array or null.
+ * @link @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRedirect
+ */
+ public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php
new file mode 100644
index 0000000..7cd9813
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Access Control List interface.
+ * Implementing classes are used by AclComponent to perform ACL checks in Cake.
+ *
+ * @package Cake.Controller.Component
+ */
+interface AclInterface {
+
+/**
+ * Empty method to be overridden in subclasses
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ */
+ public function check($aro, $aco, $action = "*");
+
+/**
+ * Allow methods are used to grant an ARO access to an ACO.
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*");
+
+/**
+ * Deny methods are used to remove permission from an ARO to access an ACO.
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*");
+
+/**
+ * Inherit methods modify the permission for an ARO to be that of its parent object.
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*");
+
+/**
+ * Initialization method for the Acl implementation
+ *
+ * @param AclComponent $component
+ */
+ public function initialize(Component $component);
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php
new file mode 100644
index 0000000..37c756b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('AclInterface', 'Controller/Component/Acl');
+App::uses('Hash', 'Utility');
+
+/**
+ * DbAcl implements an ACL control system in the database. ARO's and ACO's are
+ * structured into trees and a linking table is used to define permissions. You
+ * can install the schema for DbAcl with the Schema Shell.
+ *
+ * `$aco` and `$aro` parameters can be slash delimited paths to tree nodes.
+ *
+ * eg. `controllers/Users/edit`
+ *
+ * Would point to a tree structure like
+ *
+ * {{{
+ * controllers
+ * Users
+ * edit
+ * }}}
+ *
+ * @package Cake.Controller.Component
+ */
+class DbAcl extends Object implements AclInterface {
+
+/**
+ * Constructor
+ *
+ */
+ public function __construct() {
+ parent::__construct();
+ $this->Permission = ClassRegistry::init(array('class' => 'Permission', 'alias' => 'Permission'));
+ $this->Aro = $this->Permission->Aro;
+ $this->Aco = $this->Permission->Aco;
+ }
+
+/**
+ * Initializes the containing component and sets the Aro/Aco objects to it.
+ *
+ * @param AclComponent $component
+ * @return void
+ */
+ public function initialize(Component $component) {
+ $component->Aro = $this->Aro;
+ $component->Aco = $this->Aco;
+ }
+
+/**
+ * Checks if the given $aro has access to action $action in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success (true if ARO has access to action in ACO, false otherwise)
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#checking-permissions-the-acl-component
+ */
+ public function check($aro, $aco, $action = "*") {
+ return $this->Permission->check($aro, $aco, $action);
+ }
+
+/**
+ * Allow $aro to have access to action $actions in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $actions Action (defaults to *)
+ * @param integer $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit)
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#assigning-permissions
+ */
+ public function allow($aro, $aco, $actions = "*", $value = 1) {
+ return $this->Permission->allow($aro, $aco, $actions, $value);
+ }
+
+/**
+ * Deny access for $aro to action $action in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#assigning-permissions
+ */
+ public function deny($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action, -1);
+ }
+
+/**
+ * Let access for $aro to action $action in $aco be inherited
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action, 0);
+ }
+
+/**
+ * Allow $aro to have access to action $actions in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @see allow()
+ */
+ public function grant($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action);
+ }
+
+/**
+ * Deny access for $aro to action $action in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @see deny()
+ */
+ public function revoke($aro, $aco, $action = "*") {
+ return $this->deny($aro, $aco, $action);
+ }
+
+/**
+ * Get an array of access-control links between the given Aro and Aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @return array Indexed array with: 'aro', 'aco' and 'link'
+ */
+ public function getAclLink($aro, $aco) {
+ return $this->Permission->getAclLink($aro, $aco);
+ }
+
+/**
+ * Get the keys used in an ACO
+ *
+ * @param array $keys Permission model info
+ * @return array ACO keys
+ */
+ protected function _getAcoKeys($keys) {
+ return $this->Permission->getAcoKeys($keys);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php
new file mode 100644
index 0000000..8810668
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('AclInterface', 'Controller/Component/Acl');
+
+/**
+ * IniAcl implements an access control system using an INI file. An example
+ * of the ini file used can be found in /config/acl.ini.php.
+ *
+ * @package Cake.Controller.Component
+ */
+class IniAcl extends Object implements AclInterface {
+
+/**
+ * Array with configuration, parsed from ini file
+ *
+ * @var array
+ */
+ public $config = null;
+
+/**
+ * The Hash::extract() path to the user/aro identifier in the
+ * acl.ini file. This path will be used to extract the string
+ * representation of a user used in the ini file.
+ *
+ * @var string
+ */
+ public $userPath = 'User.username';
+
+/**
+ * Initialize method
+ *
+ * @param AclBase $component
+ * @return void
+ */
+ public function initialize(Component $component) {
+ }
+
+/**
+ * No op method, allow cannot be done with IniAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*") {
+ }
+
+/**
+ * No op method, deny cannot be done with IniAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*") {
+ }
+
+/**
+ * No op method, inherit cannot be done with IniAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ }
+
+/**
+ * Main ACL check function. Checks to see if the ARO (access request object) has access to the
+ * ACO (access control object).Looks at the acl.ini.php file for permissions
+ * (see instructions in /config/acl.ini.php).
+ *
+ * @param string $aro ARO
+ * @param string $aco ACO
+ * @param string $action Action
+ * @return boolean Success
+ */
+ public function check($aro, $aco, $action = null) {
+ if ($this->config == null) {
+ $this->config = $this->readConfigFile(APP . 'Config' . DS . 'acl.ini.php');
+ }
+ $aclConfig = $this->config;
+
+ if (is_array($aro)) {
+ $aro = Hash::get($aro, $this->userPath);
+ }
+
+ if (isset($aclConfig[$aro]['deny'])) {
+ $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny']));
+
+ if (array_search($aco, $userDenies)) {
+ return false;
+ }
+ }
+
+ if (isset($aclConfig[$aro]['allow'])) {
+ $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow']));
+
+ if (array_search($aco, $userAllows)) {
+ return true;
+ }
+ }
+
+ if (isset($aclConfig[$aro]['groups'])) {
+ $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
+
+ foreach ($userGroups as $group) {
+ if (array_key_exists($group, $aclConfig)) {
+ if (isset($aclConfig[$group]['deny'])) {
+ $groupDenies = $this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
+
+ if (array_search($aco, $groupDenies)) {
+ return false;
+ }
+ }
+
+ if (isset($aclConfig[$group]['allow'])) {
+ $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
+
+ if (array_search($aco, $groupAllows)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Parses an INI file and returns an array that reflects the
+ * INI file's section structure. Double-quote friendly.
+ *
+ * @param string $filename File
+ * @return array INI section structure
+ */
+ public function readConfigFile($filename) {
+ App::uses('IniReader', 'Configure');
+ $iniFile = new IniReader(dirname($filename) . DS);
+ return $iniFile->read(basename($filename));
+ }
+
+/**
+ * Removes trailing spaces on all array elements (to prepare for searching)
+ *
+ * @param array $array Array to trim
+ * @return array Trimmed array
+ */
+ public function arrayTrim($array) {
+ foreach ($array as $key => $value) {
+ $array[$key] = trim($value);
+ }
+ array_unshift($array, "");
+ return $array;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php
new file mode 100644
index 0000000..28b3b94
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php
@@ -0,0 +1,539 @@
+<?php
+/**
+ * PHP configuration based AclInterface implementation
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component.Acl
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * PhpAcl implements an access control system using a plain PHP configuration file.
+ * An example file can be found in app/Config/acl.php
+ *
+ * @package Cake.Controller.Component.Acl
+ */
+class PhpAcl extends Object implements AclInterface {
+
+ const DENY = false;
+ const ALLOW = true;
+
+/**
+ * Options:
+ * - policy: determines behavior of the check method. Deny policy needs explicit allow rules, allow policy needs explicit deny rules
+ * - config: absolute path to config file that contains the acl rules (@see app/Config/acl.php)
+ *
+ * @var array
+ */
+ public $options = array();
+
+/**
+ * Aro Object
+ *
+ * @var PhpAro
+ */
+ public $Aro = null;
+
+/**
+ * Aco Object
+ *
+ * @var PhpAco
+ */
+ public $Aco = null;
+
+/**
+ * Constructor
+ *
+ * Sets a few default settings up.
+ */
+ public function __construct() {
+ $this->options = array(
+ 'policy' => self::DENY,
+ 'config' => APP . 'Config' . DS . 'acl.php',
+ );
+ }
+
+/**
+ * Initialize method
+ *
+ * @param AclComponent $Component Component instance
+ * @return void
+ */
+ public function initialize(Component $Component) {
+ if (!empty($Component->settings['adapter'])) {
+ $this->options = array_merge($this->options, $Component->settings['adapter']);
+ }
+
+ App::uses('PhpReader', 'Configure');
+ $Reader = new PhpReader(dirname($this->options['config']) . DS);
+ $config = $Reader->read(basename($this->options['config']));
+ $this->build($config);
+ $Component->Aco = $this->Aco;
+ $Component->Aro = $this->Aro;
+ }
+
+/**
+ * build and setup internal ACL representation
+ *
+ * @param array $config configuration array, see docs
+ * @return void
+ * @throws AclException When required keys are missing.
+ */
+ public function build(array $config) {
+ if (empty($config['roles'])) {
+ throw new AclException(__d('cake_dev','"roles" section not found in configuration.'));
+ }
+
+ if (empty($config['rules']['allow']) && empty($config['rules']['deny'])) {
+ throw new AclException(__d('cake_dev','Neither "allow" nor "deny" rules were provided in configuration.'));
+ }
+
+ $rules['allow'] = !empty($config['rules']['allow']) ? $config['rules']['allow'] : array();
+ $rules['deny'] = !empty($config['rules']['deny']) ? $config['rules']['deny'] : array();
+ $roles = !empty($config['roles']) ? $config['roles'] : array();
+ $map = !empty($config['map']) ? $config['map'] : array();
+ $alias = !empty($config['alias']) ? $config['alias'] : array();
+
+ $this->Aro = new PhpAro($roles, $map, $alias);
+ $this->Aco = new PhpAco($rules);
+ }
+
+/**
+ * No op method, allow cannot be done with PhpAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*") {
+ return $this->Aco->access($this->Aro->resolve($aro), $aco, $action, 'allow');
+ }
+
+/**
+ * deny ARO access to ACO
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*") {
+ return $this->Aco->access($this->Aro->resolve($aro), $aco, $action, 'deny');
+ }
+
+/**
+ * No op method
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ return false;
+ }
+
+/**
+ * Main ACL check function. Checks to see if the ARO (access request object) has access to the
+ * ACO (access control object).
+ *
+ * @param string $aro ARO
+ * @param string $aco ACO
+ * @param string $action Action
+ * @return boolean true if access is granted, false otherwise
+ */
+ public function check($aro, $aco, $action = "*") {
+ $allow = $this->options['policy'];
+ $prioritizedAros = $this->Aro->roles($aro);
+
+ if ($action && $action != "*") {
+ $aco .= '/' . $action;
+ }
+
+ $path = $this->Aco->path($aco);
+
+ if (empty($path)) {
+ return $allow;
+ }
+
+ foreach ($path as $depth => $node) {
+ foreach ($prioritizedAros as $aros) {
+ if (!empty($node['allow'])) {
+ $allow = $allow || count(array_intersect($node['allow'], $aros)) > 0;
+ }
+
+ if (!empty($node['deny'])) {
+ $allow = $allow && count(array_intersect($node['deny'], $aros)) == 0;
+ }
+ }
+ }
+
+ return $allow;
+ }
+
+}
+
+/**
+ * Access Control Object
+ *
+ */
+class PhpAco {
+
+/**
+ * holds internal ACO representation
+ *
+ * @var array
+ */
+ protected $_tree = array();
+
+/**
+ * map modifiers for ACO paths to their respective PCRE pattern
+ *
+ * @var array
+ */
+ public static $modifiers = array(
+ '*' => '.*',
+ );
+
+ public function __construct(array $rules = array()) {
+ foreach (array('allow', 'deny') as $type) {
+ if (empty($rules[$type])) {
+ $rules[$type] = array();
+ }
+ }
+
+ $this->build($rules['allow'], $rules['deny']);
+ }
+
+/**
+ * return path to the requested ACO with allow and deny rules attached on each level
+ *
+ * @return array
+ */
+ public function path($aco) {
+ $aco = $this->resolve($aco);
+ $path = array();
+ $level = 0;
+ $root = $this->_tree;
+ $stack = array(array($root, 0));
+
+ while (!empty($stack)) {
+ list($root, $level) = array_pop($stack);
+
+ if (empty($path[$level])) {
+ $path[$level] = array();
+ }
+
+ foreach ($root as $node => $elements) {
+ $pattern = '/^' . str_replace(array_keys(self::$modifiers), array_values(self::$modifiers), $node) . '$/';
+
+ if ($node == $aco[$level] || preg_match($pattern, $aco[$level])) {
+ // merge allow/denies with $path of current level
+ foreach (array('allow', 'deny') as $policy) {
+ if (!empty($elements[$policy])) {
+ if (empty($path[$level][$policy])) {
+ $path[$level][$policy] = array();
+ }
+ $path[$level][$policy] = array_merge($path[$level][$policy], $elements[$policy]);
+ }
+ }
+
+ // traverse
+ if (!empty($elements['children']) && isset($aco[$level + 1])) {
+ array_push($stack, array($elements['children'], $level + 1));
+ }
+ }
+ }
+ }
+
+ return $path;
+ }
+
+/**
+ * allow/deny ARO access to ARO
+ *
+ * @return void
+ */
+ public function access($aro, $aco, $action, $type = 'deny') {
+ $aco = $this->resolve($aco);
+ $depth = count($aco);
+ $root = $this->_tree;
+ $tree = &$root;
+
+ foreach ($aco as $i => $node) {
+ if (!isset($tree[$node])) {
+ $tree[$node] = array(
+ 'children' => array(),
+ );
+ }
+
+ if ($i < $depth - 1) {
+ $tree = &$tree[$node]['children'];
+ } else {
+ if (empty($tree[$node][$type])) {
+ $tree[$node][$type] = array();
+ }
+
+ $tree[$node][$type] = array_merge(is_array($aro) ? $aro : array($aro), $tree[$node][$type]);
+ }
+ }
+
+ $this->_tree = &$root;
+ }
+
+/**
+ * resolve given ACO string to a path
+ *
+ * @param string $aco ACO string
+ * @return array path
+ */
+ public function resolve($aco) {
+ if (is_array($aco)) {
+ return array_map('strtolower', $aco);
+ }
+
+ // strip multiple occurences of '/'
+ $aco = preg_replace('#/+#', '/', $aco);
+ // make case insensitive
+ $aco = ltrim(strtolower($aco), '/');
+ return array_filter(array_map('trim', explode('/', $aco)));
+ }
+
+/**
+ * build a tree representation from the given allow/deny informations for ACO paths
+ *
+ * @param array $allow ACO allow rules
+ * @param array $deny ACO deny rules
+ * @return void
+ */
+ public function build(array $allow, array $deny = array()) {
+ $stack = array();
+ $this->_tree = array();
+ $tree = array();
+ $root = &$tree;
+
+ foreach ($allow as $dotPath => $aros) {
+ if (is_string($aros)) {
+ $aros = array_map('trim', explode(',', $aros));
+ }
+
+ $this->access($aros, $dotPath, null, 'allow');
+ }
+
+ foreach ($deny as $dotPath => $aros) {
+ if (is_string($aros)) {
+ $aros = array_map('trim', explode(',', $aros));
+ }
+
+ $this->access($aros, $dotPath, null, 'deny');
+ }
+ }
+
+}
+
+/**
+ * Access Request Object
+ *
+ */
+class PhpAro {
+
+/**
+ * role to resolve to when a provided ARO is not listed in
+ * the internal tree
+ *
+ * @var string
+ */
+ const DEFAULT_ROLE = 'Role/default';
+
+/**
+ * map external identifiers. E.g. if
+ *
+ * array('User' => array('username' => 'jeff', 'role' => 'editor'))
+ *
+ * is passed as an ARO to one of the methods of AclComponent, PhpAcl
+ * will check if it can be resolved to an User or a Role defined in the
+ * configuration file.
+ *
+ * @var array
+ * @see app/Config/acl.php
+ */
+ public $map = array(
+ 'User' => 'User/username',
+ 'Role' => 'User/role',
+ );
+
+/**
+ * aliases to map
+ *
+ * @var array
+ */
+ public $aliases = array();
+
+/**
+ * internal ARO representation
+ *
+ * @var array
+ */
+ protected $_tree = array();
+
+ public function __construct(array $aro = array(), array $map = array(), array $aliases = array()) {
+ if (!empty($map)) {
+ $this->map = $map;
+ }
+
+ $this->aliases = $aliases;
+ $this->build($aro);
+ }
+
+/**
+ * From the perspective of the given ARO, walk down the tree and
+ * collect all inherited AROs levelwise such that AROs from different
+ * branches with equal distance to the requested ARO will be collected at the same
+ * index. The resulting array will contain a prioritized list of (list of) roles ordered from
+ * the most distant AROs to the requested one itself.
+ *
+ * @param string|array $aro An ARO identifier
+ * @return array prioritized AROs
+ */
+ public function roles($aro) {
+ $aros = array();
+ $aro = $this->resolve($aro);
+ $stack = array(array($aro, 0));
+
+ while (!empty($stack)) {
+ list($element, $depth) = array_pop($stack);
+ $aros[$depth][] = $element;
+
+ foreach ($this->_tree as $node => $children) {
+ if (in_array($element, $children)) {
+ array_push($stack, array($node, $depth + 1));
+ }
+ }
+ }
+
+ return array_reverse($aros);
+ }
+
+/**
+ * resolve an ARO identifier to an internal ARO string using
+ * the internal mapping information.
+ *
+ * @param string|array $aro ARO identifier (User.jeff, array('User' => ...), etc)
+ * @return string internal aro string (e.g. User/jeff, Role/default)
+ */
+ public function resolve($aro) {
+ foreach ($this->map as $aroGroup => $map) {
+ list ($model, $field) = explode('/', $map, 2);
+ $mapped = '';
+
+ if (is_array($aro)) {
+ if (isset($aro['model']) && isset($aro['foreign_key']) && $aro['model'] == $aroGroup) {
+ $mapped = $aroGroup . '/' . $aro['foreign_key'];
+ } elseif (isset($aro[$model][$field])) {
+ $mapped = $aroGroup . '/' . $aro[$model][$field];
+ } elseif (isset($aro[$field])) {
+ $mapped = $aroGroup . '/' . $aro[$field];
+ }
+ } elseif (is_string($aro)) {
+ $aro = ltrim($aro, '/');
+
+ if (strpos($aro, '/') === false) {
+ $mapped = $aroGroup . '/' . $aro;
+ } else {
+ list($aroModel, $aroValue) = explode('/', $aro, 2);
+
+ $aroModel = Inflector::camelize($aroModel);
+
+ if ($aroModel == $model || $aroModel == $aroGroup) {
+ $mapped = $aroGroup . '/' . $aroValue;
+ }
+ }
+ }
+
+ if (isset($this->_tree[$mapped])) {
+ return $mapped;
+ }
+
+ // is there a matching alias defined (e.g. Role/1 => Role/admin)?
+ if (!empty($this->aliases[$mapped])) {
+ return $this->aliases[$mapped];
+ }
+ }
+ return self::DEFAULT_ROLE;
+ }
+
+/**
+ * adds a new ARO to the tree
+ *
+ * @param array $aro one or more ARO records
+ * @return void
+ */
+ public function addRole(array $aro) {
+ foreach ($aro as $role => $inheritedRoles) {
+ if (!isset($this->_tree[$role])) {
+ $this->_tree[$role] = array();
+ }
+
+ if (!empty($inheritedRoles)) {
+ if (is_string($inheritedRoles)) {
+ $inheritedRoles = array_map('trim', explode(',', $inheritedRoles));
+ }
+
+ foreach ($inheritedRoles as $dependency) {
+ // detect cycles
+ $roles = $this->roles($dependency);
+
+ if (in_array($role, Hash::flatten($roles))) {
+ $path = '';
+
+ foreach ($roles as $roleDependencies) {
+ $path .= implode('|', (array)$roleDependencies) . ' -> ';
+ }
+
+ trigger_error(__d('cake_dev', 'cycle detected when inheriting %s from %s. Path: %s', $role, $dependency, $path . $role));
+ continue;
+ }
+
+ if (!isset($this->_tree[$dependency])) {
+ $this->_tree[$dependency] = array();
+ }
+
+ $this->_tree[$dependency][] = $role;
+ }
+ }
+ }
+ }
+
+/**
+ * adds one or more aliases to the internal map. Overwrites existing entries.
+ *
+ * @param array $alias alias from => to (e.g. Role/13 -> Role/editor)
+ * @return void
+ */
+ public function addAlias(array $alias) {
+ $this->aliases = array_merge($this->aliases, $alias);
+ }
+
+/**
+ * build an ARO tree structure for internal processing
+ *
+ * @param array $aros array of AROs as key and their inherited AROs as values
+ * @return void
+ */
+ public function build(array $aros) {
+ $this->_tree = array();
+ $this->addRole($aros);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php
new file mode 100644
index 0000000..66ee9a3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Component', 'Controller');
+App::uses('AclInterface', 'Controller/Component/Acl');
+
+/**
+ * Access Control List factory class.
+ *
+ * Uses a strategy pattern to allow custom ACL implementations to be used with the same component interface.
+ * You can define by changing `Configure::write('Acl.classname', 'DbAcl');` in your core.php. Concrete ACL
+ * implementations should extend `AclBase` and implement the methods it defines.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html
+ */
+class AclComponent extends Component {
+
+/**
+ * Instance of an ACL class
+ *
+ * @var AclInterface
+ */
+ protected $_Instance = null;
+
+/**
+ * Aro object.
+ *
+ * @var string
+ */
+ public $Aro;
+
+/**
+ * Aco object
+ *
+ * @var string
+ */
+ public $Aco;
+
+/**
+ * Constructor. Will return an instance of the correct ACL class as defined in `Configure::read('Acl.classname')`
+ *
+ * @param ComponentCollection $collection
+ * @param array $settings
+ * @throws CakeException when Acl.classname could not be loaded.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ parent::__construct($collection, $settings);
+ $name = Configure::read('Acl.classname');
+ if (!class_exists($name)) {
+ list($plugin, $name) = pluginSplit($name, true);
+ App::uses($name, $plugin . 'Controller/Component/Acl');
+ if (!class_exists($name)) {
+ throw new CakeException(__d('cake_dev', 'Could not find %s.', $name));
+ }
+ }
+ $this->adapter($name);
+ }
+
+/**
+ * Sets or gets the Adapter object currently in the AclComponent.
+ *
+ * `$this->Acl->adapter();` will get the current adapter class while
+ * `$this->Acl->adapter($obj);` will set the adapter class
+ *
+ * Will call the initialize method on the adapter if setting a new one.
+ *
+ * @param AclInterface|string $adapter Instance of AclInterface or a string name of the class to use. (optional)
+ * @return AclInterface|void either null, or the adapter implementation.
+ * @throws CakeException when the given class is not an instance of AclInterface
+ */
+ public function adapter($adapter = null) {
+ if ($adapter) {
+ if (is_string($adapter)) {
+ $adapter = new $adapter();
+ }
+ if (!$adapter instanceof AclInterface) {
+ throw new CakeException(__d('cake_dev', 'AclComponent adapters must implement AclInterface'));
+ }
+ $this->_Instance = $adapter;
+ $this->_Instance->initialize($this);
+ return;
+ }
+ return $this->_Instance;
+ }
+
+/**
+ * Pass-thru function for ACL check instance. Check methods
+ * are used to check whether or not an ARO can access an ACO
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function check($aro, $aco, $action = "*") {
+ return $this->_Instance->check($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL allow instance. Allow methods
+ * are used to grant an ARO access to an ACO.
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*") {
+ return $this->_Instance->allow($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL deny instance. Deny methods
+ * are used to remove permission from an ARO to access an ACO.
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*") {
+ return $this->_Instance->deny($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL inherit instance. Inherit methods
+ * modify the permission for an ARO to be that of its parent object.
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ return $this->_Instance->inherit($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL grant instance. An alias for AclComponent::allow()
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @deprecated
+ */
+ public function grant($aro, $aco, $action = "*") {
+ trigger_error(__d('cake_dev', 'AclComponent::grant() is deprecated, use allow() instead'), E_USER_WARNING);
+ return $this->_Instance->allow($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL grant instance. An alias for AclComponent::deny()
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @deprecated
+ */
+ public function revoke($aro, $aco, $action = "*") {
+ trigger_error(__d('cake_dev', 'AclComponent::revoke() is deprecated, use deny() instead'), E_USER_WARNING);
+ return $this->_Instance->deny($aro, $aco, $action);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php
new file mode 100644
index 0000000..3f279b0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+
+/**
+ * An authorization adapter for AuthComponent. Provides the ability to authorize using the AclComponent,
+ * If AclComponent is not already loaded it will be loaded using the Controller's ComponentCollection.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ * @see AclComponent::check()
+ */
+class ActionsAuthorize extends BaseAuthorize {
+
+/**
+ * Authorize a user using the AclComponent.
+ *
+ * @param array $user The user to authorize
+ * @param CakeRequest $request The request needing authorization.
+ * @return boolean
+ */
+ public function authorize($user, CakeRequest $request) {
+ $Acl = $this->_Collection->load('Acl');
+ $user = array($this->settings['userModel'] => $user);
+ return $Acl->check($user, $this->action($request));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php
new file mode 100644
index 0000000..d9dc724
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Security', 'Utility');
+App::uses('Hash', 'Utility');
+
+/**
+ * Base Authentication class with common methods and properties.
+ *
+ * @package Cake.Controller.Component.Auth
+ */
+abstract class BaseAuthenticate {
+
+/**
+ * Settings for this object.
+ *
+ * - `fields` The fields to use to identify a user by.
+ * - `userModel` The model name of the User, defaults to User.
+ * - `scope` Additional conditions to use when looking up and authenticating users,
+ * i.e. `array('User.is_active' => 1).`
+ * - `recursive` The value of the recursive key passed to find(). Defaults to 0.
+ * - `contain` Extra models to contain and store in session.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'fields' => array(
+ 'username' => 'username',
+ 'password' => 'password'
+ ),
+ 'userModel' => 'User',
+ 'scope' => array(),
+ 'recursive' => 0,
+ 'contain' => null,
+ );
+
+/**
+ * A Component collection, used to get more components.
+ *
+ * @var ComponentCollection
+ */
+ protected $_Collection;
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection The Component collection used on this request.
+ * @param array $settings Array of settings to use.
+ */
+ public function __construct(ComponentCollection $collection, $settings) {
+ $this->_Collection = $collection;
+ $this->settings = Hash::merge($this->settings, $settings);
+ }
+
+/**
+ * Find a user record using the standard options.
+ *
+ * @param string $username The username/identifier.
+ * @param string $password The unhashed password.
+ * @return Mixed Either false on failure, or an array of user data.
+ */
+ protected function _findUser($username, $password) {
+ $userModel = $this->settings['userModel'];
+ list($plugin, $model) = pluginSplit($userModel);
+ $fields = $this->settings['fields'];
+
+ $conditions = array(
+ $model . '.' . $fields['username'] => $username,
+ $model . '.' . $fields['password'] => $this->_password($password),
+ );
+ if (!empty($this->settings['scope'])) {
+ $conditions = array_merge($conditions, $this->settings['scope']);
+ }
+ $result = ClassRegistry::init($userModel)->find('first', array(
+ 'conditions' => $conditions,
+ 'recursive' => (int)$this->settings['recursive'],
+ 'contain' => $this->settings['contain'],
+ ));
+ if (empty($result) || empty($result[$model])) {
+ return false;
+ }
+ $user = $result[$model];
+ unset($user[$fields['password']]);
+ unset($result[$model]);
+ return array_merge($user, $result);
+ }
+
+/**
+ * Hash the plain text password so that it matches the hashed/encrypted password
+ * in the datasource.
+ *
+ * @param string $password The plain text password.
+ * @return string The hashed form of the password.
+ */
+ protected function _password($password) {
+ return Security::hash($password, null, true);
+ }
+
+/**
+ * Authenticate a user based on the request information.
+ *
+ * @param CakeRequest $request Request to get authentication information from.
+ * @param CakeResponse $response A response object that can have headers added.
+ * @return mixed Either false on failure, or an array of user data on success.
+ */
+ abstract public function authenticate(CakeRequest $request, CakeResponse $response);
+
+/**
+ * Allows you to hook into AuthComponent::logout(),
+ * and implement specialized logout behavior.
+ *
+ * All attached authentication objects will have this method
+ * called when a user logs out.
+ *
+ * @param array $user The user about to be logged out.
+ * @return void
+ */
+ public function logout($user) {
+ }
+
+/**
+ * Get a user based on information in the request. Primarily used by stateless authentication
+ * systems like basic and digest auth.
+ *
+ * @param CakeRequest $request Request object.
+ * @return mixed Either false or an array of user information
+ */
+ public function getUser($request) {
+ return false;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php
new file mode 100644
index 0000000..9bf2d1b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Hash', 'Utility');
+
+/**
+ * Abstract base authorization adapter for AuthComponent.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ */
+abstract class BaseAuthorize {
+
+/**
+ * Controller for the request.
+ *
+ * @var Controller
+ */
+ protected $_Controller = null;
+
+/**
+ * Component collection instance for getting more components.
+ *
+ * @var ComponentCollection
+ */
+ protected $_Collection;
+
+/**
+ * Settings for authorize objects.
+ *
+ * - `actionPath` - The path to ACO nodes that contains the nodes for controllers. Used as a prefix
+ * when calling $this->action();
+ * - `actionMap` - Action -> crud mappings. Used by authorization objects that want to map actions to CRUD roles.
+ * - `userModel` - Model name that ARO records can be found under. Defaults to 'User'.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'actionPath' => null,
+ 'actionMap' => array(
+ 'index' => 'read',
+ 'add' => 'create',
+ 'edit' => 'update',
+ 'view' => 'read',
+ 'delete' => 'delete',
+ 'remove' => 'delete'
+ ),
+ 'userModel' => 'User'
+ );
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection The controller for this request.
+ * @param string $settings An array of settings. This class does not use any settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->_Collection = $collection;
+ $controller = $collection->getController();
+ $this->controller($controller);
+ $this->settings = Hash::merge($this->settings, $settings);
+ }
+
+/**
+ * Checks user authorization.
+ *
+ * @param array $user Active user data
+ * @param CakeRequest $request
+ * @return boolean
+ */
+ abstract public function authorize($user, CakeRequest $request);
+
+/**
+ * Accessor to the controller object.
+ *
+ * @param Controller $controller null to get, a controller to set.
+ * @return mixed
+ * @throws CakeException
+ */
+ public function controller(Controller $controller = null) {
+ if ($controller) {
+ if (!$controller instanceof Controller) {
+ throw new CakeException(__d('cake_dev', '$controller needs to be an instance of Controller'));
+ }
+ $this->_Controller = $controller;
+ return true;
+ }
+ return $this->_Controller;
+ }
+
+/**
+ * Get the action path for a given request. Primarily used by authorize objects
+ * that need to get information about the plugin, controller, and action being invoked.
+ *
+ * @param CakeRequest $request The request a path is needed for.
+ * @param string $path
+ * @return string the action path for the given request.
+ */
+ public function action($request, $path = '/:plugin/:controller/:action') {
+ $plugin = empty($request['plugin']) ? null : Inflector::camelize($request['plugin']) . '/';
+ $path = str_replace(
+ array(':controller', ':action', ':plugin/'),
+ array(Inflector::camelize($request['controller']), $request['action'], $plugin),
+ $this->settings['actionPath'] . $path
+ );
+ $path = str_replace('//', '/', $path);
+ return trim($path, '/');
+ }
+
+/**
+ * Maps crud actions to actual action names. Used to modify or get the current mapped actions.
+ *
+ * Create additional mappings for a standard CRUD operation:
+ *
+ * {{{
+ * $this->Auth->mapActions(array('create' => array('add', 'register'));
+ * }}}
+ *
+ * Create mappings for custom CRUD operations:
+ *
+ * {{{
+ * $this->Auth->mapActions(array('my_action' => 'admin'));
+ * }}}
+ *
+ * You can use the custom CRUD operations to create additional generic permissions
+ * that behave like CRUD operations. Doing this will require additional columns on the
+ * permissions lookup. When using with DbAcl, you'll have to add additional _admin type columns
+ * to the `aros_acos` table.
+ *
+ * @param array $map Either an array of mappings, or undefined to get current values.
+ * @return mixed Either the current mappings or null when setting.
+ * @see AuthComponent::mapActions()
+ */
+ public function mapActions($map = array()) {
+ if (empty($map)) {
+ return $this->settings['actionMap'];
+ }
+ $crud = array('create', 'read', 'update', 'delete');
+ foreach ($map as $action => $type) {
+ if (in_array($action, $crud) && is_array($type)) {
+ foreach ($type as $typedAction) {
+ $this->settings['actionMap'][$typedAction] = $action;
+ }
+ } else {
+ $this->settings['actionMap'][$action] = $type;
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php
new file mode 100644
index 0000000..df65e9c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * Basic Authentication adapter for AuthComponent.
+ *
+ * Provides Basic HTTP authentication support for AuthComponent. Basic Auth will authenticate users
+ * against the configured userModel and verify the username and passwords match. Clients using Basic Authentication
+ * must support cookies. Since AuthComponent identifies users based on Session contents, clients using Basic
+ * Auth must support cookies.
+ *
+ * ### Using Basic auth
+ *
+ * In your controller's components array, add auth + the required settings.
+ * {{{
+ * public $components = array(
+ * 'Auth' => array(
+ * 'authenticate' => array('Basic')
+ * )
+ * );
+ * }}}
+ *
+ * In your login function just call `$this->Auth->login()` without any checks for POST data. This
+ * will send the authentication headers, and trigger the login dialog in the browser/client.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ */
+class BasicAuthenticate extends BaseAuthenticate {
+
+/**
+ * Settings for this object.
+ *
+ * - `fields` The fields to use to identify a user by.
+ * - `userModel` The model name of the User, defaults to User.
+ * - `scope` Additional conditions to use when looking up and authenticating users,
+ * i.e. `array('User.is_active' => 1).`
+ * - `recursive` The value of the recursive key passed to find(). Defaults to 0.
+ * - `contain` Extra models to contain and store in session.
+ * - `realm` The realm authentication is for. Defaults the server name.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'fields' => array(
+ 'username' => 'username',
+ 'password' => 'password'
+ ),
+ 'userModel' => 'User',
+ 'scope' => array(),
+ 'recursive' => 0,
+ 'contain' => null,
+ 'realm' => '',
+ );
+
+/**
+ * Constructor, completes configuration for basic authentication.
+ *
+ * @param ComponentCollection $collection The Component collection used on this request.
+ * @param array $settings An array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings) {
+ parent::__construct($collection, $settings);
+ if (empty($this->settings['realm'])) {
+ $this->settings['realm'] = env('SERVER_NAME');
+ }
+ }
+
+/**
+ * Authenticate a user using basic HTTP auth. Will use the configured User model and attempt a
+ * login using basic HTTP auth.
+ *
+ * @param CakeRequest $request The request to authenticate with.
+ * @param CakeResponse $response The response to add headers to.
+ * @return mixed Either false on failure, or an array of user data on success.
+ */
+ public function authenticate(CakeRequest $request, CakeResponse $response) {
+ $result = $this->getUser($request);
+
+ if (empty($result)) {
+ $response->header($this->loginHeaders());
+ $response->statusCode(401);
+ $response->send();
+ return false;
+ }
+ return $result;
+ }
+
+/**
+ * Get a user based on information in the request. Used by cookie-less auth for stateless clients.
+ *
+ * @param CakeRequest $request Request object.
+ * @return mixed Either false or an array of user information
+ */
+ public function getUser($request) {
+ $username = env('PHP_AUTH_USER');
+ $pass = env('PHP_AUTH_PW');
+
+ if (empty($username) || empty($pass)) {
+ return false;
+ }
+ return $this->_findUser($username, $pass);
+ }
+
+/**
+ * Generate the login headers
+ *
+ * @return string Headers for logging in.
+ */
+ public function loginHeaders() {
+ return sprintf('WWW-Authenticate: Basic realm="%s"', $this->settings['realm']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php
new file mode 100644
index 0000000..7fa486d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+
+/**
+ * An authorization adapter for AuthComponent. Provides the ability to authorize using a controller callback.
+ * Your controller's isAuthorized() method should return a boolean to indicate whether or not the user is authorized.
+ *
+ * {{{
+ * public function isAuthorized($user) {
+ * if (!empty($this->request->params['admin'])) {
+ * return $user['role'] == 'admin';
+ * }
+ * return !empty($user);
+ * }
+ * }}}
+ *
+ * the above is simple implementation that would only authorize users of the 'admin' role to access
+ * admin routing.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ */
+class ControllerAuthorize extends BaseAuthorize {
+
+/**
+ * Get/set the controller this authorize object will be working with. Also checks that isAuthorized is implemented.
+ *
+ * @param Controller $controller null to get, a controller to set.
+ * @return mixed
+ * @throws CakeException
+ */
+ public function controller(Controller $controller = null) {
+ if ($controller) {
+ if (!method_exists($controller, 'isAuthorized')) {
+ throw new CakeException(__d('cake_dev', '$controller does not implement an isAuthorized() method.'));
+ }
+ }
+ return parent::controller($controller);
+ }
+
+/**
+ * Checks user authorization using a controller callback.
+ *
+ * @param array $user Active user data
+ * @param CakeRequest $request
+ * @return boolean
+ */
+ public function authorize($user, CakeRequest $request) {
+ return (bool)$this->_Controller->isAuthorized($user);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php
new file mode 100644
index 0000000..83761b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+App::uses('Router', 'Routing');
+
+/**
+ * An authorization adapter for AuthComponent. Provides the ability to authorize using CRUD mappings.
+ * CRUD mappings allow you to translate controller actions into *C*reate *R*ead *U*pdate *D*elete actions.
+ * This is then checked in the AclComponent as specific permissions.
+ *
+ * For example, taking `/posts/index` as the current request. The default mapping for `index`, is a `read` permission
+ * check. The Acl check would then be for the `posts` controller with the `read` permission. This allows you
+ * to create permission systems that focus more on what is being done to resources, rather than the specific actions
+ * being visited.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ * @see AclComponent::check()
+ */
+class CrudAuthorize extends BaseAuthorize {
+
+/**
+ * Sets up additional actionMap values that match the configured `Routing.prefixes`.
+ *
+ * @param ComponentCollection $collection The component collection from the controller.
+ * @param string $settings An array of settings. This class does not use any settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ parent::__construct($collection, $settings);
+ $this->_setPrefixMappings();
+ }
+
+/**
+ * sets the crud mappings for prefix routes.
+ *
+ * @return void
+ */
+ protected function _setPrefixMappings() {
+ $crud = array('create', 'read', 'update', 'delete');
+ $map = array_combine($crud, $crud);
+
+ $prefixes = Router::prefixes();
+ if (!empty($prefixes)) {
+ foreach ($prefixes as $prefix) {
+ $map = array_merge($map, array(
+ $prefix . '_index' => 'read',
+ $prefix . '_add' => 'create',
+ $prefix . '_edit' => 'update',
+ $prefix . '_view' => 'read',
+ $prefix . '_remove' => 'delete',
+ $prefix . '_create' => 'create',
+ $prefix . '_read' => 'read',
+ $prefix . '_update' => 'update',
+ $prefix . '_delete' => 'delete'
+ ));
+ }
+ }
+ $this->mapActions($map);
+ }
+
+/**
+ * Authorize a user using the mapped actions and the AclComponent.
+ *
+ * @param array $user The user to authorize
+ * @param CakeRequest $request The request needing authorization.
+ * @return boolean
+ */
+ public function authorize($user, CakeRequest $request) {
+ if (!isset($this->settings['actionMap'][$request->params['action']])) {
+ trigger_error(__d('cake_dev',
+ 'CrudAuthorize::authorize() - Attempted access of un-mapped action "%1$s" in controller "%2$s"',
+ $request->action,
+ $request->controller
+ ),
+ E_USER_WARNING
+ );
+ return false;
+ }
+ $user = array($this->settings['userModel'] => $user);
+ $Acl = $this->_Collection->load('Acl');
+ return $Acl->check(
+ $user,
+ $this->action($request, ':controller'),
+ $this->settings['actionMap'][$request->params['action']]
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php
new file mode 100644
index 0000000..bdea7d8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * Digest Authentication adapter for AuthComponent.
+ *
+ * Provides Digest HTTP authentication support for AuthComponent. Unlike most AuthComponent adapters,
+ * DigestAuthenticate requires a special password hash that conforms to RFC2617. You can create this
+ * password using `DigestAuthenticate::password()`. If you wish to use digest authentication alongside other
+ * authentication methods, its recommended that you store the digest authentication separately.
+ *
+ * Clients using Digest Authentication must support cookies. Since AuthComponent identifies users based
+ * on Session contents, clients without support for cookies will not function properly.
+ *
+ * ### Using Digest auth
+ *
+ * In your controller's components array, add auth + the required settings.
+ * {{{
+ * public $components = array(
+ * 'Auth' => array(
+ * 'authenticate' => array('Digest')
+ * )
+ * );
+ * }}}
+ *
+ * In your login function just call `$this->Auth->login()` without any checks for POST data. This
+ * will send the authentication headers, and trigger the login dialog in the browser/client.
+ *
+ * ### Generating passwords compatible with Digest authentication.
+ *
+ * Due to the Digest authentication specification, digest auth requires a special password value. You
+ * can generate this password using `DigestAuthenticate::password()`
+ *
+ * `$digestPass = DigestAuthenticate::password($username, env('SERVER_NAME'), $password);`
+ *
+ * Its recommended that you store this digest auth only password separate from password hashes used for other
+ * login methods. For example `User.digest_pass` could be used for a digest password, while `User.password` would
+ * store the password hash for use with other methods like Basic or Form.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ */
+class DigestAuthenticate extends BaseAuthenticate {
+
+/**
+ * Settings for this object.
+ *
+ * - `fields` The fields to use to identify a user by.
+ * - `userModel` The model name of the User, defaults to User.
+ * - `scope` Additional conditions to use when looking up and authenticating users,
+ * i.e. `array('User.is_active' => 1).`
+ * - `recursive` The value of the recursive key passed to find(). Defaults to 0.
+ * - `contain` Extra models to contain and store in session.
+ * - `realm` The realm authentication is for, Defaults to the servername.
+ * - `nonce` A nonce used for authentication. Defaults to `uniqid()`.
+ * - `qop` Defaults to auth, no other values are supported at this time.
+ * - `opaque` A string that must be returned unchanged by clients.
+ * Defaults to `md5($settings['realm'])`
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'fields' => array(
+ 'username' => 'username',
+ 'password' => 'password'
+ ),
+ 'userModel' => 'User',
+ 'scope' => array(),
+ 'recursive' => 0,
+ 'contain' => null,
+ 'realm' => '',
+ 'qop' => 'auth',
+ 'nonce' => '',
+ 'opaque' => ''
+ );
+
+/**
+ * Constructor, completes configuration for digest authentication.
+ *
+ * @param ComponentCollection $collection The Component collection used on this request.
+ * @param array $settings An array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings) {
+ parent::__construct($collection, $settings);
+ if (empty($this->settings['realm'])) {
+ $this->settings['realm'] = env('SERVER_NAME');
+ }
+ if (empty($this->settings['nonce'])) {
+ $this->settings['nonce'] = uniqid('');
+ }
+ if (empty($this->settings['opaque'])) {
+ $this->settings['opaque'] = md5($this->settings['realm']);
+ }
+ }
+
+/**
+ * Authenticate a user using Digest HTTP auth. Will use the configured User model and attempt a
+ * login using Digest HTTP auth.
+ *
+ * @param CakeRequest $request The request to authenticate with.
+ * @param CakeResponse $response The response to add headers to.
+ * @return mixed Either false on failure, or an array of user data on success.
+ */
+ public function authenticate(CakeRequest $request, CakeResponse $response) {
+ $user = $this->getUser($request);
+
+ if (empty($user)) {
+ $response->header($this->loginHeaders());
+ $response->statusCode(401);
+ $response->send();
+ return false;
+ }
+ return $user;
+ }
+
+/**
+ * Get a user based on information in the request. Used by cookie-less auth for stateless clients.
+ *
+ * @param CakeRequest $request Request object.
+ * @return mixed Either false or an array of user information
+ */
+ public function getUser($request) {
+ $digest = $this->_getDigest();
+ if (empty($digest)) {
+ return false;
+ }
+ $user = $this->_findUser($digest['username'], null);
+ if (empty($user)) {
+ return false;
+ }
+ $password = $user[$this->settings['fields']['password']];
+ unset($user[$this->settings['fields']['password']]);
+ if ($digest['response'] === $this->generateResponseHash($digest, $password)) {
+ return $user;
+ }
+ return false;
+ }
+
+/**
+ * Find a user record using the standard options.
+ *
+ * @param string $username The username/identifier.
+ * @param string $password Unused password, digest doesn't require passwords.
+ * @return Mixed Either false on failure, or an array of user data.
+ */
+ protected function _findUser($username, $password) {
+ $userModel = $this->settings['userModel'];
+ list($plugin, $model) = pluginSplit($userModel);
+ $fields = $this->settings['fields'];
+
+ $conditions = array(
+ $model . '.' . $fields['username'] => $username,
+ );
+ if (!empty($this->settings['scope'])) {
+ $conditions = array_merge($conditions, $this->settings['scope']);
+ }
+ $result = ClassRegistry::init($userModel)->find('first', array(
+ 'conditions' => $conditions,
+ 'recursive' => (int)$this->settings['recursive']
+ ));
+ if (empty($result) || empty($result[$model])) {
+ return false;
+ }
+ return $result[$model];
+ }
+
+/**
+ * Gets the digest headers from the request/environment.
+ *
+ * @return array Array of digest information.
+ */
+ protected function _getDigest() {
+ $digest = env('PHP_AUTH_DIGEST');
+ if (empty($digest) && function_exists('apache_request_headers')) {
+ $headers = apache_request_headers();
+ if (!empty($headers['Authorization']) && substr($headers['Authorization'], 0, 7) == 'Digest ') {
+ $digest = substr($headers['Authorization'], 7);
+ }
+ }
+ if (empty($digest)) {
+ return false;
+ }
+ return $this->parseAuthData($digest);
+ }
+
+/**
+ * Parse the digest authentication headers and split them up.
+ *
+ * @param string $digest The raw digest authentication headers.
+ * @return array An array of digest authentication headers
+ */
+ public function parseAuthData($digest) {
+ if (substr($digest, 0, 7) == 'Digest ') {
+ $digest = substr($digest, 7);
+ }
+ $keys = $match = array();
+ $req = array('nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1);
+ preg_match_all('/(\w+)=([\'"]?)([a-zA-Z0-9@=.\/_-]+)\2/', $digest, $match, PREG_SET_ORDER);
+
+ foreach ($match as $i) {
+ $keys[$i[1]] = $i[3];
+ unset($req[$i[1]]);
+ }
+
+ if (empty($req)) {
+ return $keys;
+ }
+ return null;
+ }
+
+/**
+ * Generate the response hash for a given digest array.
+ *
+ * @param array $digest Digest information containing data from DigestAuthenticate::parseAuthData().
+ * @param string $password The digest hash password generated with DigestAuthenticate::password()
+ * @return string Response hash
+ */
+ public function generateResponseHash($digest, $password) {
+ return md5(
+ $password .
+ ':' . $digest['nonce'] . ':' . $digest['nc'] . ':' . $digest['cnonce'] . ':' . $digest['qop'] . ':' .
+ md5(env('REQUEST_METHOD') . ':' . $digest['uri'])
+ );
+ }
+
+/**
+ * Creates an auth digest password hash to store
+ *
+ * @param string $username The username to use in the digest hash.
+ * @param string $password The unhashed password to make a digest hash for.
+ * @param string $realm The realm the password is for.
+ * @return string the hashed password that can later be used with Digest authentication.
+ */
+ public static function password($username, $password, $realm) {
+ return md5($username . ':' . $realm . ':' . $password);
+ }
+
+/**
+ * Generate the login headers
+ *
+ * @return string Headers for logging in.
+ */
+ public function loginHeaders() {
+ $options = array(
+ 'realm' => $this->settings['realm'],
+ 'qop' => $this->settings['qop'],
+ 'nonce' => $this->settings['nonce'],
+ 'opaque' => $this->settings['opaque']
+ );
+ $opts = array();
+ foreach ($options as $k => $v) {
+ $opts[] = sprintf('%s="%s"', $k, $v);
+ }
+ return 'WWW-Authenticate: Digest ' . implode(',', $opts);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php
new file mode 100644
index 0000000..0a51f52
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * An authentication adapter for AuthComponent. Provides the ability to authenticate using POST
+ * data. Can be used by configuring AuthComponent to use it via the AuthComponent::$authenticate setting.
+ *
+ * {{{
+ * $this->Auth->authenticate = array(
+ * 'Form' => array(
+ * 'scope' => array('User.active' => 1)
+ * )
+ * )
+ * }}}
+ *
+ * When configuring FormAuthenticate you can pass in settings to which fields, model and additional conditions
+ * are used. See FormAuthenticate::$settings for more information.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ */
+class FormAuthenticate extends BaseAuthenticate {
+
+/**
+ * Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields`
+ * to find POST data that is used to find a matching record in the `settings.userModel`. Will return false if
+ * there is no post data, either username or password is missing, of if the scope conditions have not been met.
+ *
+ * @param CakeRequest $request The request that contains login information.
+ * @param CakeResponse $response Unused response object.
+ * @return mixed. False on login failure. An array of User data on success.
+ */
+ public function authenticate(CakeRequest $request, CakeResponse $response) {
+ $userModel = $this->settings['userModel'];
+ list($plugin, $model) = pluginSplit($userModel);
+
+ $fields = $this->settings['fields'];
+ if (empty($request->data[$model])) {
+ return false;
+ }
+ if (
+ empty($request->data[$model][$fields['username']]) ||
+ empty($request->data[$model][$fields['password']])
+ ) {
+ return false;
+ }
+ return $this->_findUser(
+ $request->data[$model][$fields['username']],
+ $request->data[$model][$fields['password']]
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php
new file mode 100644
index 0000000..311b95a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php
@@ -0,0 +1,722 @@
+<?php
+/**
+ * Authentication component
+ *
+ * Manages user logins and permissions.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('Router', 'Routing');
+App::uses('Security', 'Utility');
+App::uses('Debugger', 'Utility');
+App::uses('Hash', 'Utility');
+App::uses('CakeSession', 'Model/Datasource');
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * Authentication control component class
+ *
+ * Binds access control with user authentication and session management.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
+ */
+class AuthComponent extends Component {
+
+ const ALL = 'all';
+
+/**
+ * Other components utilized by AuthComponent
+ *
+ * @var array
+ */
+ public $components = array('Session', 'RequestHandler');
+
+/**
+ * An array of authentication objects to use for authenticating users. You can configure
+ * multiple adapters and they will be checked sequentially when users are identified.
+ *
+ * {{{
+ * $this->Auth->authenticate = array(
+ * 'Form' => array(
+ * 'userModel' => 'Users.User'
+ * )
+ * );
+ * }}}
+ *
+ * Using the class name without 'Authenticate' as the key, you can pass in an array of settings for each
+ * authentication object. Additionally you can define settings that should be set to all authentications objects
+ * using the 'all' key:
+ *
+ * {{{
+ * $this->Auth->authenticate = array(
+ * 'all' => array(
+ * 'userModel' => 'Users.User',
+ * 'scope' => array('User.active' => 1)
+ * ),
+ * 'Form',
+ * 'Basic'
+ * );
+ * }}}
+ *
+ * You can also use AuthComponent::ALL instead of the string 'all'.
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
+ */
+ public $authenticate = array('Form');
+
+/**
+ * Objects that will be used for authentication checks.
+ *
+ * @var array
+ */
+ protected $_authenticateObjects = array();
+
+/**
+ * An array of authorization objects to use for authorizing users. You can configure
+ * multiple adapters and they will be checked sequentially when authorization checks are done.
+ *
+ * {{{
+ * $this->Auth->authorize = array(
+ * 'Crud' => array(
+ * 'actionPath' => 'controllers/'
+ * )
+ * );
+ * }}}
+ *
+ * Using the class name without 'Authorize' as the key, you can pass in an array of settings for each
+ * authorization object. Additionally you can define settings that should be set to all authorization objects
+ * using the 'all' key:
+ *
+ * {{{
+ * $this->Auth->authorize = array(
+ * 'all' => array(
+ * 'actionPath' => 'controllers/'
+ * ),
+ * 'Crud',
+ * 'CustomAuth'
+ * );
+ * }}}
+ *
+ * You can also use AuthComponent::ALL instead of the string 'all'
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#authorization
+ */
+ public $authorize = false;
+
+/**
+ * Objects that will be used for authorization checks.
+ *
+ * @var array
+ */
+ protected $_authorizeObjects = array();
+
+/**
+ * The name of an optional view element to render when an Ajax request is made
+ * with an invalid or expired session
+ *
+ * @var string
+ */
+ public $ajaxLogin = null;
+
+/**
+ * Settings to use when Auth needs to do a flash message with SessionComponent::setFlash().
+ * Available keys are:
+ *
+ * - `element` - The element to use, defaults to 'default'.
+ * - `key` - The key to use, defaults to 'auth'
+ * - `params` - The array of additional params to use, defaults to array()
+ *
+ * @var array
+ */
+ public $flash = array(
+ 'element' => 'default',
+ 'key' => 'auth',
+ 'params' => array()
+ );
+
+/**
+ * The session key name where the record of the current user is stored. If
+ * unspecified, it will be "Auth.User".
+ *
+ * @var string
+ */
+ public static $sessionKey = 'Auth.User';
+
+/**
+ * The current user, used for stateless authentication when
+ * sessions are not available.
+ *
+ * @var array
+ */
+ protected static $_user = array();
+
+/**
+ * A URL (defined as a string or array) to the controller action that handles
+ * logins. Defaults to `/users/login`
+ *
+ * @var mixed
+ */
+ public $loginAction = array(
+ 'controller' => 'users',
+ 'action' => 'login',
+ 'plugin' => null
+ );
+
+/**
+ * Normally, if a user is redirected to the $loginAction page, the location they
+ * were redirected from will be stored in the session so that they can be
+ * redirected back after a successful login. If this session value is not
+ * set, the user will be redirected to the page specified in $loginRedirect.
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$loginRedirect
+ */
+ public $loginRedirect = null;
+
+/**
+ * The default action to redirect to after the user is logged out. While AuthComponent does
+ * not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout().
+ * Defaults to AuthComponent::$loginAction.
+ *
+ * @var mixed
+ * @see AuthComponent::$loginAction
+ * @see AuthComponent::logout()
+ */
+ public $logoutRedirect = null;
+
+/**
+ * Error to display when user attempts to access an object or action to which they do not have
+ * access.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$authError
+ */
+ public $authError = null;
+
+/**
+ * Controller actions for which user validation is not required.
+ *
+ * @var array
+ * @see AuthComponent::allow()
+ */
+ public $allowedActions = array();
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Response object
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * Method list for bound controller
+ *
+ * @var array
+ */
+ protected $_methods = array();
+
+/**
+ * Initializes AuthComponent for use in the controller
+ *
+ * @param Controller $controller A reference to the instantiating controller object
+ * @return void
+ */
+ public function initialize(Controller $controller) {
+ $this->request = $controller->request;
+ $this->response = $controller->response;
+ $this->_methods = $controller->methods;
+
+ if (Configure::read('debug') > 0) {
+ Debugger::checkSecurityKeys();
+ }
+ }
+
+/**
+ * Main execution method. Handles redirecting of invalid users, and processing
+ * of login form data.
+ *
+ * @param Controller $controller A reference to the instantiating controller object
+ * @return boolean
+ */
+ public function startup(Controller $controller) {
+ $methods = array_flip(array_map('strtolower', $controller->methods));
+ $action = strtolower($controller->request->params['action']);
+
+ $isMissingAction = (
+ $controller->scaffold === false &&
+ !isset($methods[$action])
+ );
+
+ if ($isMissingAction) {
+ return true;
+ }
+
+ if (!$this->_setDefaults()) {
+ return false;
+ }
+ $request = $controller->request;
+
+ $url = '';
+
+ if (isset($request->url)) {
+ $url = $request->url;
+ }
+ $url = Router::normalize($url);
+ $loginAction = Router::normalize($this->loginAction);
+
+ $allowedActions = $this->allowedActions;
+ $isAllowed = (
+ $this->allowedActions == array('*') ||
+ in_array($action, array_map('strtolower', $allowedActions))
+ );
+
+ if ($loginAction != $url && $isAllowed) {
+ return true;
+ }
+
+ if ($loginAction == $url) {
+ if (empty($request->data)) {
+ if (!$this->Session->check('Auth.redirect') && !$this->loginRedirect && env('HTTP_REFERER')) {
+ $this->Session->write('Auth.redirect', $controller->referer(null, true));
+ }
+ }
+ return true;
+ } else {
+ if (!$this->_getUser()) {
+ if (!$request->is('ajax')) {
+ $this->flash($this->authError);
+ $this->Session->write('Auth.redirect', $request->here());
+ $controller->redirect($loginAction);
+ return false;
+ } elseif (!empty($this->ajaxLogin)) {
+ $controller->viewPath = 'Elements';
+ echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
+ $this->_stop();
+ return false;
+ } else {
+ $controller->redirect(null, 403);
+ }
+ }
+ }
+ if (empty($this->authorize) || $this->isAuthorized($this->user())) {
+ return true;
+ }
+
+ $this->flash($this->authError);
+ $default = '/';
+ if (!empty($this->loginRedirect)) {
+ $default = $this->loginRedirect;
+ }
+ $controller->redirect($controller->referer($default), null, true);
+ return false;
+ }
+
+/**
+ * Attempts to introspect the correct values for object properties.
+ *
+ * @return boolean
+ */
+ protected function _setDefaults() {
+ $defaults = array(
+ 'logoutRedirect' => $this->loginAction,
+ 'authError' => __d('cake', 'You are not authorized to access that location.')
+ );
+ foreach ($defaults as $key => $value) {
+ if (empty($this->{$key})) {
+ $this->{$key} = $value;
+ }
+ }
+ return true;
+ }
+
+/**
+ * Uses the configured Authorization adapters to check whether or not a user is authorized.
+ * Each adapter will be checked in sequence, if any of them return true, then the user will
+ * be authorized for the request.
+ *
+ * @param array $user The user to check the authorization of. If empty the user in the session will be used.
+ * @param CakeRequest $request The request to authenticate for. If empty, the current request will be used.
+ * @return boolean True if $user is authorized, otherwise false
+ */
+ public function isAuthorized($user = null, $request = null) {
+ if (empty($user) && !$this->user()) {
+ return false;
+ } elseif (empty($user)) {
+ $user = $this->user();
+ }
+ if (empty($request)) {
+ $request = $this->request;
+ }
+ if (empty($this->_authorizeObjects)) {
+ $this->constructAuthorize();
+ }
+ foreach ($this->_authorizeObjects as $authorizer) {
+ if ($authorizer->authorize($user, $request) === true) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Loads the authorization objects configured.
+ *
+ * @return mixed Either null when authorize is empty, or the loaded authorization objects.
+ * @throws CakeException
+ */
+ public function constructAuthorize() {
+ if (empty($this->authorize)) {
+ return;
+ }
+ $this->_authorizeObjects = array();
+ $config = Hash::normalize((array)$this->authorize);
+ $global = array();
+ if (isset($config[AuthComponent::ALL])) {
+ $global = $config[AuthComponent::ALL];
+ unset($config[AuthComponent::ALL]);
+ }
+ foreach ($config as $class => $settings) {
+ list($plugin, $class) = pluginSplit($class, true);
+ $className = $class . 'Authorize';
+ App::uses($className, $plugin . 'Controller/Component/Auth');
+ if (!class_exists($className)) {
+ throw new CakeException(__d('cake_dev', 'Authorization adapter "%s" was not found.', $class));
+ }
+ if (!method_exists($className, 'authorize')) {
+ throw new CakeException(__d('cake_dev', 'Authorization objects must implement an authorize method.'));
+ }
+ $settings = array_merge($global, (array)$settings);
+ $this->_authorizeObjects[] = new $className($this->_Collection, $settings);
+ }
+ return $this->_authorizeObjects;
+ }
+
+/**
+ * Takes a list of actions in the current controller for which authentication is not required, or
+ * no parameters to allow all actions.
+ *
+ * You can use allow with either an array, or var args.
+ *
+ * `$this->Auth->allow(array('edit', 'add'));` or
+ * `$this->Auth->allow('edit', 'add');` or
+ * `$this->Auth->allow();` to allow all actions
+ *
+ * @param string|array $action,... Controller action name or array of actions
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-public
+ */
+ public function allow($action = null) {
+ $args = func_get_args();
+ if (empty($args) || $action === null) {
+ $this->allowedActions = $this->_methods;
+ } else {
+ if (isset($args[0]) && is_array($args[0])) {
+ $args = $args[0];
+ }
+ $this->allowedActions = array_merge($this->allowedActions, $args);
+ }
+ }
+
+/**
+ * Removes items from the list of allowed/no authentication required actions.
+ *
+ * You can use deny with either an array, or var args.
+ *
+ * `$this->Auth->deny(array('edit', 'add'));` or
+ * `$this->Auth->deny('edit', 'add');` or
+ * `$this->Auth->deny();` to remove all items from the allowed list
+ *
+ * @param string|array $action,... Controller action name or array of actions
+ * @return void
+ * @see AuthComponent::allow()
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-require-authorization
+ */
+ public function deny($action = null) {
+ $args = func_get_args();
+ if (empty($args) || $action === null) {
+ $this->allowedActions = array();
+ } else {
+ if (isset($args[0]) && is_array($args[0])) {
+ $args = $args[0];
+ }
+ foreach ($args as $arg) {
+ $i = array_search($arg, $this->allowedActions);
+ if (is_int($i)) {
+ unset($this->allowedActions[$i]);
+ }
+ }
+ $this->allowedActions = array_values($this->allowedActions);
+ }
+ }
+
+/**
+ * Maps action names to CRUD operations. Used for controller-based authentication. Make sure
+ * to configure the authorize property before calling this method. As it delegates $map to all the
+ * attached authorize objects.
+ *
+ * @param array $map Actions to map
+ * @return void
+ * @see BaseAuthorize::mapActions()
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#mapping-actions-when-using-crudauthorize
+ */
+ public function mapActions($map = array()) {
+ if (empty($this->_authorizeObjects)) {
+ $this->constructAuthorize();
+ }
+ foreach ($this->_authorizeObjects as $auth) {
+ $auth->mapActions($map);
+ }
+ }
+
+/**
+ * Log a user in. If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not
+ * specified, the request will be used to identify a user. If the identification was successful,
+ * the user record is written to the session key specified in AuthComponent::$sessionKey. Logging in
+ * will also change the session id in order to help mitigate session replays.
+ *
+ * @param array $user Either an array of user data, or null to identify a user using the current request.
+ * @return boolean True on login success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#identifying-users-and-logging-them-in
+ */
+ public function login($user = null) {
+ $this->_setDefaults();
+
+ if (empty($user)) {
+ $user = $this->identify($this->request, $this->response);
+ }
+ if ($user) {
+ $this->Session->renew();
+ $this->Session->write(self::$sessionKey, $user);
+ }
+ return $this->loggedIn();
+ }
+
+/**
+ * Logs a user out, and returns the login action to redirect to.
+ * Triggers the logout() method of all the authenticate objects, so they can perform
+ * custom logout logic. AuthComponent will remove the session data, so
+ * there is no need to do that in an authentication object. Logging out
+ * will also renew the session id. This helps mitigate issues with session replays.
+ *
+ * @return string AuthComponent::$logoutRedirect
+ * @see AuthComponent::$logoutRedirect
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#logging-users-out
+ */
+ public function logout() {
+ $this->_setDefaults();
+ if (empty($this->_authenticateObjects)) {
+ $this->constructAuthenticate();
+ }
+ $user = $this->user();
+ foreach ($this->_authenticateObjects as $auth) {
+ $auth->logout($user);
+ }
+ $this->Session->delete(self::$sessionKey);
+ $this->Session->delete('Auth.redirect');
+ $this->Session->renew();
+ return Router::normalize($this->logoutRedirect);
+ }
+
+/**
+ * Get the current user.
+ *
+ * Will prefer the static user cache over sessions. The static user
+ * cache is primarily used for stateless authentication. For stateful authentication,
+ * cookies + sessions will be used.
+ *
+ * @param string $key field to retrieve. Leave null to get entire User record
+ * @return mixed User record. or null if no user is logged in.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user
+ */
+ public static function user($key = null) {
+ if (empty(self::$_user) && !CakeSession::check(self::$sessionKey)) {
+ return null;
+ }
+ if (!empty(self::$_user)) {
+ $user = self::$_user;
+ } else {
+ $user = CakeSession::read(self::$sessionKey);
+ }
+ if ($key === null) {
+ return $user;
+ }
+ if ($value = Hash::get($user, $key)) {
+ return $value;
+ }
+ return null;
+ }
+
+/**
+ * Similar to AuthComponent::user() except if the session user cannot be found, connected authentication
+ * objects will have their getUser() methods called. This lets stateless authentication methods function correctly.
+ *
+ * @return boolean true if a user can be found, false if one cannot.
+ */
+ protected function _getUser() {
+ $user = $this->user();
+ if ($user) {
+ return true;
+ }
+ if (empty($this->_authenticateObjects)) {
+ $this->constructAuthenticate();
+ }
+ foreach ($this->_authenticateObjects as $auth) {
+ $result = $auth->getUser($this->request);
+ if (!empty($result) && is_array($result)) {
+ self::$_user = $result;
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * If no parameter is passed, gets the authentication redirect URL. Pass a url in to
+ * set the destination a user should be redirected to upon logging in. Will fallback to
+ * AuthComponent::$loginRedirect if there is no stored redirect value.
+ *
+ * @param string|array $url Optional URL to write as the login redirect URL.
+ * @return string Redirect URL
+ */
+ public function redirect($url = null) {
+ if (!is_null($url)) {
+ $redir = $url;
+ $this->Session->write('Auth.redirect', $redir);
+ } elseif ($this->Session->check('Auth.redirect')) {
+ $redir = $this->Session->read('Auth.redirect');
+ $this->Session->delete('Auth.redirect');
+
+ if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
+ $redir = $this->loginRedirect;
+ }
+ } else {
+ $redir = $this->loginRedirect;
+ }
+ return Router::normalize($redir);
+ }
+
+/**
+ * Use the configured authentication adapters, and attempt to identify the user
+ * by credentials contained in $request.
+ *
+ * @param CakeRequest $request The request that contains authentication data.
+ * @param CakeResponse $response The response
+ * @return array User record data, or false, if the user could not be identified.
+ */
+ public function identify(CakeRequest $request, CakeResponse $response) {
+ if (empty($this->_authenticateObjects)) {
+ $this->constructAuthenticate();
+ }
+ foreach ($this->_authenticateObjects as $auth) {
+ $result = $auth->authenticate($request, $response);
+ if (!empty($result) && is_array($result)) {
+ return $result;
+ }
+ }
+ return false;
+ }
+
+/**
+ * loads the configured authentication objects.
+ *
+ * @return mixed either null on empty authenticate value, or an array of loaded objects.
+ * @throws CakeException
+ */
+ public function constructAuthenticate() {
+ if (empty($this->authenticate)) {
+ return;
+ }
+ $this->_authenticateObjects = array();
+ $config = Hash::normalize((array)$this->authenticate);
+ $global = array();
+ if (isset($config[AuthComponent::ALL])) {
+ $global = $config[AuthComponent::ALL];
+ unset($config[AuthComponent::ALL]);
+ }
+ foreach ($config as $class => $settings) {
+ list($plugin, $class) = pluginSplit($class, true);
+ $className = $class . 'Authenticate';
+ App::uses($className, $plugin . 'Controller/Component/Auth');
+ if (!class_exists($className)) {
+ throw new CakeException(__d('cake_dev', 'Authentication adapter "%s" was not found.', $class));
+ }
+ if (!method_exists($className, 'authenticate')) {
+ throw new CakeException(__d('cake_dev', 'Authentication objects must implement an authenticate method.'));
+ }
+ $settings = array_merge($global, (array)$settings);
+ $this->_authenticateObjects[] = new $className($this->_Collection, $settings);
+ }
+ return $this->_authenticateObjects;
+ }
+
+/**
+ * Hash a password with the application's salt value (as defined with Configure::write('Security.salt');
+ *
+ * This method is intended as a convenience wrapper for Security::hash(). If you want to use
+ * a hashing/encryption system not supported by that method, do not use this method.
+ *
+ * @param string $password Password to hash
+ * @return string Hashed password
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#hashing-passwords
+ */
+ public static function password($password) {
+ return Security::hash($password, null, true);
+ }
+
+/**
+ * Component shutdown. If user is logged in, wipe out redirect.
+ *
+ * @param Controller $controller Instantiating controller
+ * @return void
+ */
+ public function shutdown(Controller $controller) {
+ if ($this->loggedIn()) {
+ $this->Session->delete('Auth.redirect');
+ }
+ }
+
+/**
+ * Check whether or not the current user has data in the session, and is considered logged in.
+ *
+ * @return boolean true if the user is logged in, false otherwise
+ */
+ public function loggedIn() {
+ return $this->user() != array();
+ }
+
+/**
+ * Set a flash message. Uses the Session component, and values from AuthComponent::$flash.
+ *
+ * @param string $message The message to set.
+ * @return void
+ */
+ public function flash($message) {
+ $this->Session->setFlash($message, $this->flash['element'], $this->flash['params'], $this->flash['key']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php
new file mode 100644
index 0000000..9f0879f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php
@@ -0,0 +1,523 @@
+<?php
+/**
+ * Cookie Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.4213
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('Security', 'Utility');
+App::uses('Hash', 'Utility');
+
+/**
+ * Cookie Component.
+ *
+ * Cookie handling for the controller.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html
+ *
+ */
+class CookieComponent extends Component {
+
+/**
+ * The name of the cookie.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->name = 'CookieName';
+ *
+ * @var string
+ */
+ public $name = 'CakeCookie';
+
+/**
+ * The time a cookie will remain valid.
+ *
+ * Can be either integer Unix timestamp or a date string.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->time = '5 Days';
+ *
+ * @var mixed
+ */
+ public $time = null;
+
+/**
+ * Cookie path.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->path = '/';
+ *
+ * The path on the server in which the cookie will be available on.
+ * If public $cookiePath is set to '/foo/', the cookie will only be available
+ * within the /foo/ directory and all sub-directories such as /foo/bar/ of domain.
+ * The default value is the entire domain.
+ *
+ * @var string
+ */
+ public $path = '/';
+
+/**
+ * Domain path.
+ *
+ * The domain that the cookie is available.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->domain = '.example.com';
+ *
+ * To make the cookie available on all subdomains of example.com.
+ * Set $this->Cookie->domain = '.example.com'; in your controller beforeFilter
+ *
+ * @var string
+ */
+ public $domain = '';
+
+/**
+ * Secure HTTPS only cookie.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->secure = true;
+ *
+ * Indicates that the cookie should only be transmitted over a secure HTTPS connection.
+ * When set to true, the cookie will only be set if a secure connection exists.
+ *
+ * @var boolean
+ */
+ public $secure = false;
+
+/**
+ * Encryption key.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->key = 'SomeRandomString';
+ *
+ * @var string
+ */
+ public $key = null;
+
+/**
+ * HTTP only cookie
+ *
+ * Set to true to make HTTP only cookies. Cookies that are HTTP only
+ * are not accessible in Javascript.
+ *
+ * @var boolean
+ */
+ public $httpOnly = false;
+
+/**
+ * Values stored in the cookie.
+ *
+ * Accessed in the controller using $this->Cookie->read('Name.key');
+ *
+ * @see CookieComponent::read();
+ * @var string
+ */
+ protected $_values = array();
+
+/**
+ * Type of encryption to use.
+ *
+ * Currently two methods are available: cipher and rijndael
+ * Defaults to Security::cipher();
+ *
+ * @var string
+ */
+ protected $_type = 'cipher';
+
+/**
+ * Used to reset cookie time if $expire is passed to CookieComponent::write()
+ *
+ * @var string
+ */
+ protected $_reset = null;
+
+/**
+ * Expire time of the cookie
+ *
+ * This is controlled by CookieComponent::time;
+ *
+ * @var string
+ */
+ protected $_expires = 0;
+
+/**
+ * A reference to the Controller's CakeResponse object
+ *
+ * @var CakeResponse
+ */
+ protected $_response = null;
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection for this component
+ * @param array $settings Array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->key = Configure::read('Security.salt');
+ parent::__construct($collection, $settings);
+ if (isset($this->time)) {
+ $this->_expire($this->time);
+ }
+
+ $controller = $collection->getController();
+ if ($controller && isset($controller->response)) {
+ $this->_response = $controller->response;
+ } else {
+ $this->_response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ }
+ }
+
+/**
+ * Start CookieComponent for use in the controller
+ *
+ * @param Controller $controller
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ $this->_expire($this->time);
+
+ $this->_values[$this->name] = array();
+ if (isset($_COOKIE[$this->name])) {
+ $this->_values[$this->name] = $this->_decrypt($_COOKIE[$this->name]);
+ }
+ }
+
+/**
+ * Write a value to the $_COOKIE[$key];
+ *
+ * Optional [Name.], required key, optional $value, optional $encrypt, optional $expires
+ * $this->Cookie->write('[Name.]key, $value);
+ *
+ * By default all values are encrypted.
+ * You must pass $encrypt false to store values in clear test
+ *
+ * You must use this method before any output is sent to the browser.
+ * Failure to do so will result in header already sent errors.
+ *
+ * @param string|array $key Key for the value
+ * @param mixed $value Value
+ * @param boolean $encrypt Set to true to encrypt value, false otherwise
+ * @param integer|string $expires Can be either Unix timestamp, or date string
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::write
+ */
+ public function write($key, $value = null, $encrypt = true, $expires = null) {
+ if (empty($this->_values[$this->name])) {
+ $this->read();
+ }
+
+ if (is_null($encrypt)) {
+ $encrypt = true;
+ }
+ $this->_encrypted = $encrypt;
+ $this->_expire($expires);
+
+ if (!is_array($key)) {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $name => $value) {
+ if (strpos($name, '.') === false) {
+ $this->_values[$this->name][$name] = $value;
+ $this->_write("[$name]", $value);
+ } else {
+ $names = explode('.', $name, 2);
+ if (!isset($this->_values[$this->name][$names[0]])) {
+ $this->_values[$this->name][$names[0]] = array();
+ }
+ $this->_values[$this->name][$names[0]] = Hash::insert($this->_values[$this->name][$names[0]], $names[1], $value);
+ $this->_write('[' . implode('][', $names) . ']', $value);
+ }
+ }
+ $this->_encrypted = true;
+ }
+
+/**
+ * Read the value of the $_COOKIE[$key];
+ *
+ * Optional [Name.], required key
+ * $this->Cookie->read(Name.key);
+ *
+ * @param string $key Key of the value to be obtained. If none specified, obtain map key => values
+ * @return string or null, value for specified key
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::read
+ */
+ public function read($key = null) {
+ if (empty($this->_values[$this->name]) && isset($_COOKIE[$this->name])) {
+ $this->_values[$this->name] = $this->_decrypt($_COOKIE[$this->name]);
+ }
+ if (empty($this->_values[$this->name])) {
+ $this->_values[$this->name] = array();
+ }
+ if (is_null($key)) {
+ return $this->_values[$this->name];
+ }
+
+ if (strpos($key, '.') !== false) {
+ $names = explode('.', $key, 2);
+ $key = $names[0];
+ }
+ if (!isset($this->_values[$this->name][$key])) {
+ return null;
+ }
+
+ if (!empty($names[1])) {
+ return Hash::get($this->_values[$this->name][$key], $names[1]);
+ }
+ return $this->_values[$this->name][$key];
+ }
+
+/**
+ * Delete a cookie value
+ *
+ * Optional [Name.], required key
+ * $this->Cookie->read('Name.key);
+ *
+ * You must use this method before any output is sent to the browser.
+ * Failure to do so will result in header already sent errors.
+ *
+ * @param string $key Key of the value to be deleted
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::delete
+ */
+ public function delete($key) {
+ if (empty($this->_values[$this->name])) {
+ $this->read();
+ }
+ if (strpos($key, '.') === false) {
+ if (isset($this->_values[$this->name][$key]) && is_array($this->_values[$this->name][$key])) {
+ foreach ($this->_values[$this->name][$key] as $idx => $val) {
+ $this->_delete("[$key][$idx]");
+ }
+ }
+ $this->_delete("[$key]");
+ unset($this->_values[$this->name][$key]);
+ return;
+ }
+ $names = explode('.', $key, 2);
+ if (isset($this->_values[$this->name][$names[0]])) {
+ $this->_values[$this->name][$names[0]] = Hash::remove($this->_values[$this->name][$names[0]], $names[1]);
+ }
+ $this->_delete('[' . implode('][', $names) . ']');
+ }
+
+/**
+ * Destroy current cookie
+ *
+ * You must use this method before any output is sent to the browser.
+ * Failure to do so will result in header already sent errors.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::destroy
+ */
+ public function destroy() {
+ if (isset($_COOKIE[$this->name])) {
+ $this->_values[$this->name] = $this->_decrypt($_COOKIE[$this->name]);
+ }
+
+ foreach ($this->_values[$this->name] as $name => $value) {
+ if (is_array($value)) {
+ foreach ($value as $key => $val) {
+ unset($this->_values[$this->name][$name][$key]);
+ $this->_delete("[$name][$key]");
+ }
+ }
+ unset($this->_values[$this->name][$name]);
+ $this->_delete("[$name]");
+ }
+ }
+
+/**
+ * Will allow overriding default encryption method. Use this method
+ * in ex: AppController::beforeFilter() before you have read or
+ * written any cookies.
+ *
+ * @param string $type Encryption method
+ * @return void
+ */
+ public function type($type = 'cipher') {
+ $availableTypes = array(
+ 'cipher',
+ 'rijndael'
+ );
+ if (!in_array($type, $availableTypes)) {
+ trigger_error(__d('cake_dev', 'You must use cipher or rijndael for cookie encryption type'), E_USER_WARNING);
+ $type = 'cipher';
+ }
+ $this->_type = $type;
+ }
+
+/**
+ * Set the expire time for a session variable.
+ *
+ * Creates a new expire time for a session variable.
+ * $expire can be either integer Unix timestamp or a date string.
+ *
+ * Used by write()
+ * CookieComponent::write(string, string, boolean, 8400);
+ * CookieComponent::write(string, string, boolean, '5 Days');
+ *
+ * @param integer|string $expires Can be either Unix timestamp, or date string
+ * @return integer Unix timestamp
+ */
+ protected function _expire($expires = null) {
+ $now = time();
+ if (is_null($expires)) {
+ return $this->_expires;
+ }
+ $this->_reset = $this->_expires;
+
+ if ($expires == 0) {
+ return $this->_expires = 0;
+ }
+
+ if (is_integer($expires) || is_numeric($expires)) {
+ return $this->_expires = $now + intval($expires);
+ }
+ return $this->_expires = strtotime($expires, $now);
+ }
+
+/**
+ * Set cookie
+ *
+ * @param string $name Name for cookie
+ * @param string $value Value for cookie
+ * @return void
+ */
+ protected function _write($name, $value) {
+ $this->_response->cookie(array(
+ 'name' => $this->name . $name,
+ 'value' => $this->_encrypt($value),
+ 'expire' => $this->_expires,
+ 'path' => $this->path,
+ 'domain' => $this->domain,
+ 'secure' => $this->secure,
+ 'httpOnly' => $this->httpOnly
+ ));
+
+ if (!is_null($this->_reset)) {
+ $this->_expires = $this->_reset;
+ $this->_reset = null;
+ }
+ }
+
+/**
+ * Sets a cookie expire time to remove cookie value
+ *
+ * @param string $name Name of cookie
+ * @return void
+ */
+ protected function _delete($name) {
+ $this->_response->cookie(array(
+ 'name' => $this->name . $name,
+ 'value' => '',
+ 'expire' => time() - 42000,
+ 'path' => $this->path,
+ 'domain' => $this->domain,
+ 'secure' => $this->secure,
+ 'httpOnly' => $this->httpOnly
+ ));
+ }
+
+/**
+ * Encrypts $value using public $type method in Security class
+ *
+ * @param string $value Value to encrypt
+ * @return string encrypted string
+ * @return string Encoded values
+ */
+ protected function _encrypt($value) {
+ if (is_array($value)) {
+ $value = $this->_implode($value);
+ }
+
+ if ($this->_encrypted === true) {
+ $type = $this->_type;
+ $value = "Q2FrZQ==." . base64_encode(Security::$type($value, $this->key, 'encrypt'));
+ }
+ return $value;
+ }
+
+/**
+ * Decrypts $value using public $type method in Security class
+ *
+ * @param array $values Values to decrypt
+ * @return string decrypted string
+ */
+ protected function _decrypt($values) {
+ $decrypted = array();
+ $type = $this->_type;
+
+ foreach ((array)$values as $name => $value) {
+ if (is_array($value)) {
+ foreach ($value as $key => $val) {
+ $pos = strpos($val, 'Q2FrZQ==.');
+ $decrypted[$name][$key] = $this->_explode($val);
+
+ if ($pos !== false) {
+ $val = substr($val, 8);
+ $decrypted[$name][$key] = $this->_explode(Security::$type(base64_decode($val), $this->key, 'decrypt'));
+ }
+ }
+ } else {
+ $pos = strpos($value, 'Q2FrZQ==.');
+ $decrypted[$name] = $this->_explode($value);
+
+ if ($pos !== false) {
+ $value = substr($value, 8);
+ $decrypted[$name] = $this->_explode(Security::$type(base64_decode($value), $this->key, 'decrypt'));
+ }
+ }
+ }
+ return $decrypted;
+ }
+
+/**
+ * Implode method to keep keys are multidimensional arrays
+ *
+ * @param array $array Map of key and values
+ * @return string A json encoded string.
+ */
+ protected function _implode(array $array) {
+ return json_encode($array);
+ }
+
+/**
+ * Explode method to return array from string set in CookieComponent::_implode()
+ * Maintains reading backwards compatibility with 1.x CookieComponent::_implode().
+ *
+ * @param string $string A string containing JSON encoded data, or a bare string.
+ * @return array Map of key and values
+ */
+ protected function _explode($string) {
+ $first = substr($string, 0, 1);
+ if ($first === '{' || $first === '[') {
+ $ret = json_decode($string, true);
+ return ($ret != null) ? $ret : $string;
+ }
+ $array = array();
+ foreach (explode(',', $string) as $pair) {
+ $key = explode('|', $pair);
+ if (!isset($key[1])) {
+ return $key[0];
+ }
+ $array[$key[0]] = $key[1];
+ }
+ return $array;
+ }
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php
new file mode 100644
index 0000000..d0f55ef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php
@@ -0,0 +1,464 @@
+<?php
+/**
+ * Email Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.3467
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('Multibyte', 'I18n');
+App::uses('CakeEmail', 'Network/Email');
+
+/**
+ * EmailComponent
+ *
+ * This component is used for handling Internet Message Format based
+ * based on the standard outlined in http://www.rfc-editor.org/rfc/rfc2822.txt
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/email.html
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
+ * @deprecated Use Network/CakeEmail
+ */
+class EmailComponent extends Component {
+
+/**
+ * Recipient of the email
+ *
+ * @var string
+ */
+ public $to = null;
+
+/**
+ * The mail which the email is sent from
+ *
+ * @var string
+ */
+ public $from = null;
+
+/**
+ * The email the recipient will reply to
+ *
+ * @var string
+ */
+ public $replyTo = null;
+
+/**
+ * The read receipt email
+ *
+ * @var string
+ */
+ public $readReceipt = null;
+
+/**
+ * The mail that will be used in case of any errors like
+ * - Remote mailserver down
+ * - Remote user has exceeded his quota
+ * - Unknown user
+ *
+ * @var string
+ */
+ public $return = null;
+
+/**
+ * Carbon Copy
+ *
+ * List of email's that should receive a copy of the email.
+ * The Recipient WILL be able to see this list
+ *
+ * @var array
+ */
+ public $cc = array();
+
+/**
+ * Blind Carbon Copy
+ *
+ * List of email's that should receive a copy of the email.
+ * The Recipient WILL NOT be able to see this list
+ *
+ * @var array
+ */
+ public $bcc = array();
+
+/**
+ * The date to put in the Date: header. This should be a date
+ * conforming with the RFC2822 standard. Leave null, to have
+ * today's date generated.
+ *
+ * @var string
+ */
+ public $date = null;
+
+/**
+ * The subject of the email
+ *
+ * @var string
+ */
+ public $subject = null;
+
+/**
+ * Associative array of a user defined headers
+ * Keys will be prefixed 'X-' as per RFC2822 Section 4.7.5
+ *
+ * @var array
+ */
+ public $headers = array();
+
+/**
+ * List of additional headers
+ *
+ * These will NOT be used if you are using safemode and mail()
+ *
+ * @var string
+ */
+ public $additionalParams = null;
+
+/**
+ * Layout for the View
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Template for the view
+ *
+ * @var string
+ */
+ public $template = null;
+
+/**
+ * Line feed character(s) to be used when sending using mail() function
+ * By default PHP_EOL is used.
+ * RFC2822 requires it to be CRLF but some Unix
+ * mail transfer agents replace LF by CRLF automatically
+ * (which leads to doubling CR if CRLF is used).
+ *
+ * @var string
+ */
+ public $lineFeed = PHP_EOL;
+
+/**
+ * What format should the email be sent in
+ *
+ * Supported formats:
+ * - text
+ * - html
+ * - both
+ *
+ * @var string
+ */
+ public $sendAs = 'text';
+
+/**
+ * What method should the email be sent by
+ *
+ * Supported methods:
+ * - mail
+ * - smtp
+ * - debug
+ *
+ * @var string
+ */
+ public $delivery = 'mail';
+
+/**
+ * charset the email is sent in
+ *
+ * @var string
+ */
+ public $charset = 'utf-8';
+
+/**
+ * List of files that should be attached to the email.
+ *
+ * Can be both absolute and relative paths
+ *
+ * @var array
+ */
+ public $attachments = array();
+
+/**
+ * What mailer should EmailComponent identify itself as
+ *
+ * @var string
+ */
+ public $xMailer = 'CakePHP Email Component';
+
+/**
+ * The list of paths to search if an attachment isn't absolute
+ *
+ * @var array
+ */
+ public $filePaths = array();
+
+/**
+ * List of options to use for smtp mail method
+ *
+ * Options is:
+ * - port
+ * - host
+ * - timeout
+ * - username
+ * - password
+ * - client
+ *
+ * @var array
+ */
+ public $smtpOptions = array();
+
+/**
+ * Contains the rendered plain text message if one was sent.
+ *
+ * @var string
+ */
+ public $textMessage = null;
+
+/**
+ * Contains the rendered HTML message if one was sent.
+ *
+ * @var string
+ */
+ public $htmlMessage = null;
+
+/**
+ * Whether to generate a Message-ID header for the
+ * e-mail. True to generate a Message-ID, False to let
+ * it be handled by sendmail (or similar) or a string
+ * to completely override the Message-ID.
+ *
+ * If you are sending Email from a shell, be sure to set this value. As you
+ * could encounter delivery issues if you do not.
+ *
+ * @var mixed
+ */
+ public $messageId = true;
+
+/**
+ * Controller reference
+ *
+ * @var Controller
+ */
+ protected $_controller = null;
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
+ * @param array $settings Array of configuration settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->_controller = $collection->getController();
+ parent::__construct($collection, $settings);
+ }
+
+/**
+ * Initialize component
+ *
+ * @param Controller $controller Instantiating controller
+ * @return void
+ */
+ public function initialize(Controller $controller) {
+ if (Configure::read('App.encoding') !== null) {
+ $this->charset = Configure::read('App.encoding');
+ }
+ }
+
+/**
+ * Send an email using the specified content, template and layout
+ *
+ * @param string|array $content Either an array of text lines, or a string with contents
+ * If you are rendering a template this variable will be sent to the templates as `$content`
+ * @param string $template Template to use when sending email
+ * @param string $layout Layout to use to enclose email body
+ * @return boolean Success
+ */
+ public function send($content = null, $template = null, $layout = null) {
+ $lib = new CakeEmail();
+ $lib->charset = $this->charset;
+
+ $lib->from($this->_formatAddresses((array)$this->from));
+ if (!empty($this->to)) {
+ $lib->to($this->_formatAddresses((array)$this->to));
+ }
+ if (!empty($this->cc)) {
+ $lib->cc($this->_formatAddresses((array)$this->cc));
+ }
+ if (!empty($this->bcc)) {
+ $lib->bcc($this->_formatAddresses((array)$this->bcc));
+ }
+ if (!empty($this->replyTo)) {
+ $lib->replyTo($this->_formatAddresses((array)$this->replyTo));
+ }
+ if (!empty($this->return)) {
+ $lib->returnPath($this->_formatAddresses((array)$this->return));
+ }
+ if (!empty($readReceipt)) {
+ $lib->readReceipt($this->_formatAddresses((array)$this->readReceipt));
+ }
+
+ $lib->subject($this->subject)->messageID($this->messageId);
+ $lib->helpers($this->_controller->helpers);
+
+ $headers = array('X-Mailer' => $this->xMailer);
+ foreach ($this->headers as $key => $value) {
+ $headers['X-' . $key] = $value;
+ }
+ if ($this->date != false) {
+ $headers['Date'] = $this->date;
+ }
+ $lib->setHeaders($headers);
+
+ if ($template) {
+ $this->template = $template;
+ }
+ if ($layout) {
+ $this->layout = $layout;
+ }
+ $lib->template($this->template, $this->layout)->viewVars($this->_controller->viewVars)->emailFormat($this->sendAs);
+
+ if (!empty($this->attachments)) {
+ $lib->attachments($this->_formatAttachFiles());
+ }
+
+ $lib->transport(ucfirst($this->delivery));
+ if ($this->delivery === 'mail') {
+ $lib->config(array('eol' => $this->lineFeed, 'additionalParameters' => $this->additionalParams));
+ } elseif ($this->delivery === 'smtp') {
+ $lib->config($this->smtpOptions);
+ } else {
+ $lib->config(array());
+ }
+
+ $sent = $lib->send($content);
+
+ $this->htmlMessage = $lib->message(CakeEmail::MESSAGE_HTML);
+ if (empty($this->htmlMessage)) {
+ $this->htmlMessage = null;
+ }
+ $this->textMessage = $lib->message(CakeEmail::MESSAGE_TEXT);
+ if (empty($this->textMessage)) {
+ $this->textMessage = null;
+ }
+
+ $this->_header = array();
+ $this->_message = array();
+
+ return $sent;
+ }
+
+/**
+ * Reset all EmailComponent internal variables to be able to send out a new email.
+ *
+ * @return void
+ */
+ public function reset() {
+ $this->template = null;
+ $this->to = array();
+ $this->from = null;
+ $this->replyTo = null;
+ $this->return = null;
+ $this->cc = array();
+ $this->bcc = array();
+ $this->subject = null;
+ $this->additionalParams = null;
+ $this->date = null;
+ $this->attachments = array();
+ $this->htmlMessage = null;
+ $this->textMessage = null;
+ $this->messageId = true;
+ $this->delivery = 'mail';
+ }
+
+/**
+ * Format the attach array
+ *
+ * @return array
+ */
+ protected function _formatAttachFiles() {
+ $files = array();
+ foreach ($this->attachments as $filename => $attachment) {
+ $file = $this->_findFiles($attachment);
+ if (!empty($file)) {
+ if (is_int($filename)) {
+ $filename = basename($file);
+ }
+ $files[$filename] = $file;
+ }
+ }
+ return $files;
+ }
+
+/**
+ * Find the specified attachment in the list of file paths
+ *
+ * @param string $attachment Attachment file name to find
+ * @return string Path to located file
+ */
+ protected function _findFiles($attachment) {
+ if (file_exists($attachment)) {
+ return $attachment;
+ }
+ foreach ($this->filePaths as $path) {
+ if (file_exists($path . DS . $attachment)) {
+ $file = $path . DS . $attachment;
+ return $file;
+ }
+ }
+ return null;
+ }
+
+/**
+ * Format addresses to be an array with email as key and alias as value
+ *
+ * @param array $addresses
+ * @return array
+ */
+ protected function _formatAddresses($addresses) {
+ $formatted = array();
+ foreach ($addresses as $address) {
+ if (preg_match('/((.*))?\s?<(.+)>/', $address, $matches) && !empty($matches[2])) {
+ $formatted[$this->_strip($matches[3])] = $matches[2];
+ } else {
+ $address = $this->_strip($address);
+ $formatted[$address] = $address;
+ }
+ }
+ return $formatted;
+ }
+
+/**
+ * Remove certain elements (such as bcc:, to:, %0a) from given value.
+ * Helps prevent header injection / manipulation on user content.
+ *
+ * @param string $value Value to strip
+ * @param boolean $message Set to true to indicate main message content
+ * @return string Stripped value
+ */
+ protected function _strip($value, $message = false) {
+ $search = '%0a|%0d|Content-(?:Type|Transfer-Encoding)\:';
+ $search .= '|charset\=|mime-version\:|multipart/mixed|(?:[^a-z]to|b?cc)\:.*';
+
+ if ($message !== true) {
+ $search .= '|\r|\n';
+ }
+ $search = '#(?:' . $search . ')#i';
+ while (preg_match($search, $value)) {
+ $value = preg_replace($search, '', $value);
+ }
+ return $value;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php
new file mode 100644
index 0000000..bd3d31c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php
@@ -0,0 +1,383 @@
+<?php
+/**
+ * Paginator Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Hash', 'Utility');
+
+/**
+ * This component is used to handle automatic model data pagination. The primary way to use this
+ * component is to call the paginate() method. There is a convenience wrapper on Controller as well.
+ *
+ * ### Configuring pagination
+ *
+ * You configure pagination using the PaginatorComponent::$settings. This allows you to configure
+ * the default pagination behavior in general or for a specific model. General settings are used when there
+ * are no specific model configuration, or the model you are paginating does not have specific settings.
+ *
+ * {{{
+ * $this->Paginator->settings = array(
+ * 'limit' => 20,
+ * 'maxLimit' => 100
+ * );
+ * }}}
+ *
+ * The above settings will be used to paginate any model. You can configure model specific settings by
+ * keying the settings with the model name.
+ *
+ * {{{
+ * $this->Paginator->settings = array(
+ * 'Post' => array(
+ * 'limit' => 20,
+ * 'maxLimit' => 100
+ * ),
+ * 'Comment' => array( ... )
+ * );
+ * }}}
+ *
+ * This would allow you to have different pagination settings for `Comment` and `Post` models.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html
+ */
+class PaginatorComponent extends Component {
+
+/**
+ * Pagination settings. These settings control pagination at a general level.
+ * You can also define sub arrays for pagination settings for specific models.
+ *
+ * - `maxLimit` The maximum limit users can choose to view. Defaults to 100
+ * - `limit` The initial number of items per page. Defaults to 20.
+ * - `page` The starting page, defaults to 1.
+ * - `paramType` What type of parameters you want pagination to use?
+ * - `named` Use named parameters / routed parameters.
+ * - `querystring` Use query string parameters.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'paramType' => 'named'
+ );
+
+/**
+ * A list of parameters users are allowed to set using request parameters. Modifying
+ * this list will allow users to have more influence over pagination,
+ * be careful with what you permit.
+ *
+ * @var array
+ */
+ public $whitelist = array(
+ 'limit', 'sort', 'page', 'direction'
+ );
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
+ * @param array $settings Array of configuration settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $settings = array_merge($this->settings, (array)$settings);
+ $this->Controller = $collection->getController();
+ parent::__construct($collection, $settings);
+ }
+
+/**
+ * Handles automatic pagination of model records.
+ *
+ * @param Model|string $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
+ * @param string|array $scope Additional find conditions to use while paginating
+ * @param array $whitelist List of allowed fields for ordering. This allows you to prevent ordering
+ * on non-indexed, or undesirable columns.
+ * @return array Model query results
+ * @throws MissingModelException
+ */
+ public function paginate($object = null, $scope = array(), $whitelist = array()) {
+ if (is_array($object)) {
+ $whitelist = $scope;
+ $scope = $object;
+ $object = null;
+ }
+
+ $object = $this->_getObject($object);
+
+ if (!is_object($object)) {
+ throw new MissingModelException($object);
+ }
+
+ $options = $this->mergeOptions($object->alias);
+ $options = $this->validateSort($object, $options, $whitelist);
+ $options = $this->checkLimit($options);
+
+ $conditions = $fields = $order = $limit = $page = $recursive = null;
+
+ if (!isset($options['conditions'])) {
+ $options['conditions'] = array();
+ }
+
+ $type = 'all';
+
+ if (isset($options[0])) {
+ $type = $options[0];
+ unset($options[0]);
+ }
+
+ extract($options);
+
+ if (is_array($scope) && !empty($scope)) {
+ $conditions = array_merge($conditions, $scope);
+ } elseif (is_string($scope)) {
+ $conditions = array($conditions, $scope);
+ }
+ if ($recursive === null) {
+ $recursive = $object->recursive;
+ }
+
+ $extra = array_diff_key($options, compact(
+ 'conditions', 'fields', 'order', 'limit', 'page', 'recursive'
+ ));
+ if ($type !== 'all') {
+ $extra['type'] = $type;
+ }
+
+ if (intval($page) < 1) {
+ $page = 1;
+ }
+ $page = $options['page'] = (int)$page;
+
+ if ($object->hasMethod('paginate')) {
+ $results = $object->paginate(
+ $conditions, $fields, $order, $limit, $page, $recursive, $extra
+ );
+ } else {
+ $parameters = compact('conditions', 'fields', 'order', 'limit', 'page');
+ if ($recursive != $object->recursive) {
+ $parameters['recursive'] = $recursive;
+ }
+ $results = $object->find($type, array_merge($parameters, $extra));
+ }
+ $defaults = $this->getDefaults($object->alias);
+ unset($defaults[0]);
+
+ if ($object->hasMethod('paginateCount')) {
+ $count = $object->paginateCount($conditions, $recursive, $extra);
+ } else {
+ $parameters = compact('conditions');
+ if ($recursive != $object->recursive) {
+ $parameters['recursive'] = $recursive;
+ }
+ $count = $object->find('count', array_merge($parameters, $extra));
+ }
+ $pageCount = intval(ceil($count / $limit));
+ $page = max(min($page, $pageCount), 1);
+
+ $paging = array(
+ 'page' => $page,
+ 'current' => count($results),
+ 'count' => $count,
+ 'prevPage' => ($page > 1),
+ 'nextPage' => ($count > ($page * $limit)),
+ 'pageCount' => $pageCount,
+ 'order' => $order,
+ 'limit' => $limit,
+ 'options' => Hash::diff($options, $defaults),
+ 'paramType' => $options['paramType']
+ );
+ if (!isset($this->Controller->request['paging'])) {
+ $this->Controller->request['paging'] = array();
+ }
+ $this->Controller->request['paging'] = array_merge(
+ (array)$this->Controller->request['paging'],
+ array($object->alias => $paging)
+ );
+
+ if (
+ !in_array('Paginator', $this->Controller->helpers) &&
+ !array_key_exists('Paginator', $this->Controller->helpers)
+ ) {
+ $this->Controller->helpers[] = 'Paginator';
+ }
+ return $results;
+ }
+
+/**
+ * Get the object pagination will occur on.
+ *
+ * @param string|Model $object The object you are looking for.
+ * @return mixed The model object to paginate on.
+ */
+ protected function _getObject($object) {
+ if (is_string($object)) {
+ $assoc = null;
+ if (strpos($object, '.') !== false) {
+ list($object, $assoc) = pluginSplit($object);
+ }
+
+ if ($assoc && isset($this->Controller->{$object}->{$assoc})) {
+ $object = $this->Controller->{$object}->{$assoc};
+ } elseif (
+ $assoc && isset($this->Controller->{$this->Controller->modelClass}) &&
+ isset($this->Controller->{$this->Controller->modelClass}->{$assoc}
+ )) {
+ $object = $this->Controller->{$this->Controller->modelClass}->{$assoc};
+ } elseif (isset($this->Controller->{$object})) {
+ $object = $this->Controller->{$object};
+ } elseif (
+ isset($this->Controller->{$this->Controller->modelClass}) && isset($this->Controller->{$this->Controller->modelClass}->{$object}
+ )) {
+ $object = $this->Controller->{$this->Controller->modelClass}->{$object};
+ }
+ } elseif (empty($object) || $object === null) {
+ if (isset($this->Controller->{$this->Controller->modelClass})) {
+ $object = $this->Controller->{$this->Controller->modelClass};
+ } else {
+ $className = null;
+ $name = $this->Controller->uses[0];
+ if (strpos($this->Controller->uses[0], '.') !== false) {
+ list($name, $className) = explode('.', $this->Controller->uses[0]);
+ }
+ if ($className) {
+ $object = $this->Controller->{$className};
+ } else {
+ $object = $this->Controller->{$name};
+ }
+ }
+ }
+ return $object;
+ }
+
+/**
+ * Merges the various options that Pagination uses.
+ * Pulls settings together from the following places:
+ *
+ * - General pagination settings
+ * - Model specific settings.
+ * - Request parameters
+ *
+ * The result of this method is the aggregate of all the option sets combined together. You can change
+ * PaginatorComponent::$whitelist to modify which options/values can be set using request parameters.
+ *
+ * @param string $alias Model alias being paginated, if the general settings has a key with this value
+ * that key's settings will be used for pagination instead of the general ones.
+ * @return array Array of merged options.
+ */
+ public function mergeOptions($alias) {
+ $defaults = $this->getDefaults($alias);
+ switch ($defaults['paramType']) {
+ case 'named':
+ $request = $this->Controller->request->params['named'];
+ break;
+ case 'querystring':
+ $request = $this->Controller->request->query;
+ break;
+ }
+ $request = array_intersect_key($request, array_flip($this->whitelist));
+ return array_merge($defaults, $request);
+ }
+
+/**
+ * Get the default settings for a $model. If there are no settings for a specific model, the general settings
+ * will be used.
+ *
+ * @param string $alias Model name to get default settings for.
+ * @return array An array of pagination defaults for a model, or the general settings.
+ */
+ public function getDefaults($alias) {
+ if (isset($this->settings[$alias])) {
+ $defaults = $this->settings[$alias];
+ } else {
+ $defaults = $this->settings;
+ }
+ return array_merge(
+ array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named'),
+ $defaults
+ );
+ }
+
+/**
+ * Validate that the desired sorting can be performed on the $object. Only fields or
+ * virtualFields can be sorted on. The direction param will also be sanitized. Lastly
+ * sort + direction keys will be converted into the model friendly order key.
+ *
+ * You can use the whitelist parameter to control which columns/fields are available for sorting.
+ * This helps prevent users from ordering large result sets on un-indexed values.
+ *
+ * @param Model $object The model being paginated.
+ * @param array $options The pagination options being used for this request.
+ * @param array $whitelist The list of columns that can be used for sorting. If empty all keys are allowed.
+ * @return array An array of options with sort + direction removed and replaced with order if possible.
+ */
+ public function validateSort($object, $options, $whitelist = array()) {
+ if (isset($options['sort'])) {
+ $direction = null;
+ if (isset($options['direction'])) {
+ $direction = strtolower($options['direction']);
+ }
+ if ($direction != 'asc' && $direction != 'desc') {
+ $direction = 'asc';
+ }
+ $options['order'] = array($options['sort'] => $direction);
+ }
+
+ if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
+ $field = key($options['order']);
+ if (!in_array($field, $whitelist)) {
+ $options['order'] = null;
+ }
+ }
+
+ if (!empty($options['order']) && is_array($options['order'])) {
+ $order = array();
+ foreach ($options['order'] as $key => $value) {
+ $field = $key;
+ $alias = $object->alias;
+ if (strpos($key, '.') !== false) {
+ list($alias, $field) = explode('.', $key);
+ }
+
+ if ($object->hasField($field)) {
+ $order[$alias . '.' . $field] = $value;
+ } elseif ($object->hasField($key, true)) {
+ $order[$field] = $value;
+ } elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
+ $order[$alias . '.' . $field] = $value;
+ }
+ }
+ $options['order'] = $order;
+ }
+
+ return $options;
+ }
+
+/**
+ * Check the limit parameter and ensure its within the maxLimit bounds.
+ *
+ * @param array $options An array of options with a limit key to be checked.
+ * @return array An array of options for pagination
+ */
+ public function checkLimit($options) {
+ $options['limit'] = (int)$options['limit'];
+ if (empty($options['limit']) || $options['limit'] < 1) {
+ $options['limit'] = 1;
+ }
+ $options['limit'] = min($options['limit'], $options['maxLimit']);
+ return $options;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php
new file mode 100644
index 0000000..544e01c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php
@@ -0,0 +1,730 @@
+<?php
+/**
+ * Request object for handling alternative HTTP requests
+ *
+ * Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers,
+ * and the like. These units have no use for Ajax requests, and this Component can tell how Cake
+ * should respond to the different needs of a handheld computer and a desktop machine.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.4.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Xml', 'Utility');
+
+/**
+ * Request object for handling alternative HTTP requests
+ *
+ * Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers,
+ * and the like. These units have no use for Ajax requests, and this Component can tell how Cake
+ * should respond to the different needs of a handheld computer and a desktop machine.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/request-handling.html
+ *
+ */
+class RequestHandlerComponent extends Component {
+
+/**
+ * The layout that will be switched to for Ajax requests
+ *
+ * @var string
+ * @see RequestHandler::setAjax()
+ */
+ public $ajaxLayout = 'ajax';
+
+/**
+ * Determines whether or not callbacks will be fired on this component
+ *
+ * @var boolean
+ */
+ public $enabled = true;
+
+/**
+ * Holds the reference to Controller::$request
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Holds the reference to Controller::$response
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * Contains the file extension parsed out by the Router
+ *
+ * @var string
+ * @see Router::parseExtensions()
+ */
+ public $ext = null;
+
+/**
+ * The template to use when rendering the given content type.
+ *
+ * @var string
+ */
+ protected $_renderType = null;
+
+/**
+ * A mapping between extensions and deserializers for request bodies of that type.
+ * By default only JSON and XML are mapped, use RequestHandlerComponent::addInputType()
+ *
+ * @var array
+ */
+ protected $_inputTypeMap = array(
+ 'json' => array('json_decode', true)
+ );
+
+/**
+ * Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT
+ *
+ * @param ComponentCollection $collection ComponentCollection object.
+ * @param array $settings Array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $default = array('checkHttpCache' => true);
+ parent::__construct($collection, $settings + $default);
+ $this->addInputType('xml', array(array($this, 'convertXml')));
+
+ $Controller = $collection->getController();
+ $this->request = $Controller->request;
+ $this->response = $Controller->response;
+ }
+
+/**
+ * Checks to see if a file extension has been parsed by the Router, or if the
+ * HTTP_ACCEPT_TYPE has matches only one content type with the supported extensions.
+ * If there is only one matching type between the supported content types & extensions,
+ * and the requested mime-types, RequestHandler::$ext is set to that value.
+ *
+ * @param Controller $controller A reference to the controller
+ * @param array $settings Array of settings to _set().
+ * @return void
+ * @see Router::parseExtensions()
+ */
+ public function initialize(Controller $controller, $settings = array()) {
+ if (isset($this->request->params['ext'])) {
+ $this->ext = $this->request->params['ext'];
+ }
+ if (empty($this->ext) || $this->ext == 'html') {
+ $this->_setExtension();
+ }
+ $this->params = $controller->params;
+ $this->_set($settings);
+ }
+
+/**
+ * Set the extension based on the accept headers.
+ * Compares the accepted types and configured extensions.
+ * If there is one common type, that is assigned as the ext/content type
+ * for the response.
+ *
+ * If html is one of the preferred types, no content type will be set, this
+ * is to avoid issues with browsers that prefer html and several other content types.
+ *
+ * @return void
+ */
+ protected function _setExtension() {
+ $accept = $this->request->parseAccept();
+ if (empty($accept)) {
+ return;
+ }
+ $extensions = Router::extensions();
+ $preferred = array_shift($accept);
+ $preferredTypes = $this->response->mapType($preferred);
+ $similarTypes = array_intersect($extensions, $preferredTypes);
+ if (count($similarTypes) === 1 && !in_array('xhtml', $preferredTypes) && !in_array('html', $preferredTypes)) {
+ $this->ext = array_shift($similarTypes);
+ }
+ }
+
+/**
+ * The startup method of the RequestHandler enables several automatic behaviors
+ * related to the detection of certain properties of the HTTP request, including:
+ *
+ * - Disabling layout rendering for Ajax requests (based on the HTTP_X_REQUESTED_WITH header)
+ * - If Router::parseExtensions() is enabled, the layout and template type are
+ * switched based on the parsed extension or Accept-Type header. For example, if `controller/action.xml`
+ * is requested, the view path becomes `app/View/Controller/xml/action.ctp`. Also if
+ * `controller/action` is requested with `Accept-Type: application/xml` in the headers
+ * the view path will become `app/View/Controller/xml/action.ctp`. Layout and template
+ * types will only switch to mime-types recognized by CakeResponse. If you need to declare
+ * additional mime-types, you can do so using CakeResponse::type() in your controllers beforeFilter()
+ * method.
+ * - If a helper with the same name as the extension exists, it is added to the controller.
+ * - If the extension is of a type that RequestHandler understands, it will set that
+ * Content-type in the response header.
+ * - If the XML data is POSTed, the data is parsed into an XML object, which is assigned
+ * to the $data property of the controller, which can then be saved to a model object.
+ *
+ * @param Controller $controller A reference to the controller
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ $controller->request->params['isAjax'] = $this->request->is('ajax');
+ $isRecognized = (
+ !in_array($this->ext, array('html', 'htm')) &&
+ $this->response->getMimeType($this->ext)
+ );
+
+ if (!empty($this->ext) && $isRecognized) {
+ $this->renderAs($controller, $this->ext);
+ } elseif ($this->request->is('ajax')) {
+ $this->renderAs($controller, 'ajax');
+ } elseif (empty($this->ext) || in_array($this->ext, array('html', 'htm'))) {
+ $this->respondAs('html', array('charset' => Configure::read('App.encoding')));
+ }
+
+ foreach ($this->_inputTypeMap as $type => $handler) {
+ if ($this->requestedWith($type)) {
+ $input = call_user_func_array(array($controller->request, 'input'), $handler);
+ $controller->request->data = $input;
+ }
+ }
+ }
+
+/**
+ * Helper method to parse xml input data, due to lack of anonymous functions
+ * this lives here.
+ *
+ * @param string $xml
+ * @return array Xml array data
+ */
+ public function convertXml($xml) {
+ try {
+ $xml = Xml::build($xml);
+ if (isset($xml->data)) {
+ return Xml::toArray($xml->data);
+ }
+ return Xml::toArray($xml);
+ } catch (XmlException $e) {
+ return array();
+ }
+ }
+
+/**
+ * Handles (fakes) redirects for Ajax requests using requestAction()
+ *
+ * @param Controller $controller A reference to the controller
+ * @param string|array $url A string or array containing the redirect location
+ * @param integer|array $status HTTP Status for redirect
+ * @param boolean $exit
+ * @return void
+ */
+ public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
+ if (!$this->request->is('ajax')) {
+ return;
+ }
+ foreach ($_POST as $key => $val) {
+ unset($_POST[$key]);
+ }
+ if (is_array($url)) {
+ $url = Router::url($url + array('base' => false));
+ }
+ if (!empty($status)) {
+ $statusCode = $this->response->httpCodes($status);
+ $code = key($statusCode);
+ $this->response->statusCode($code);
+ }
+ $this->response->body($this->requestAction($url, array('return', 'bare' => false)));
+ $this->response->send();
+ $this->_stop();
+ }
+
+/**
+ * Checks if the response can be considered different according to the request
+ * headers, and the caching response headers. If it was not modified, then the
+ * render process is skipped. And the client will get a blank response with a
+ * "304 Not Modified" header.
+ *
+ * @params Controller $controller
+ * @return boolean false if the render process should be aborted
+ **/
+ public function beforeRender(Controller $controller) {
+ $shouldCheck = $this->settings['checkHttpCache'];
+ if ($shouldCheck && $this->response->checkNotModified($this->request)) {
+ return false;
+ }
+ }
+
+/**
+ * Returns true if the current HTTP request is Ajax, false otherwise
+ *
+ * @return boolean True if call is Ajax
+ * @deprecated use `$this->request->is('ajax')` instead.
+ */
+ public function isAjax() {
+ return $this->request->is('ajax');
+ }
+
+/**
+ * Returns true if the current HTTP request is coming from a Flash-based client
+ *
+ * @return boolean True if call is from Flash
+ * @deprecated use `$this->request->is('flash')` instead.
+ */
+ public function isFlash() {
+ return $this->request->is('flash');
+ }
+
+/**
+ * Returns true if the current request is over HTTPS, false otherwise.
+ *
+ * @return boolean True if call is over HTTPS
+ * @deprecated use `$this->request->is('ssl')` instead.
+ */
+ public function isSSL() {
+ return $this->request->is('ssl');
+ }
+
+/**
+ * Returns true if the current call accepts an XML response, false otherwise
+ *
+ * @return boolean True if client accepts an XML response
+ */
+ public function isXml() {
+ return $this->prefers('xml');
+ }
+
+/**
+ * Returns true if the current call accepts an RSS response, false otherwise
+ *
+ * @return boolean True if client accepts an RSS response
+ */
+ public function isRss() {
+ return $this->prefers('rss');
+ }
+
+/**
+ * Returns true if the current call accepts an Atom response, false otherwise
+ *
+ * @return boolean True if client accepts an RSS response
+ */
+ public function isAtom() {
+ return $this->prefers('atom');
+ }
+
+/**
+ * Returns true if user agent string matches a mobile web browser, or if the
+ * client accepts WAP content.
+ *
+ * @return boolean True if user agent is a mobile web browser
+ */
+ public function isMobile() {
+ return $this->request->is('mobile') || $this->accepts('wap');
+ }
+
+/**
+ * Returns true if the client accepts WAP content
+ *
+ * @return boolean
+ */
+ public function isWap() {
+ return $this->prefers('wap');
+ }
+
+/**
+ * Returns true if the current call a POST request
+ *
+ * @return boolean True if call is a POST
+ * @deprecated Use $this->request->is('post'); from your controller.
+ */
+ public function isPost() {
+ return $this->request->is('post');
+ }
+
+/**
+ * Returns true if the current call a PUT request
+ *
+ * @return boolean True if call is a PUT
+ * @deprecated Use $this->request->is('put'); from your controller.
+ */
+ public function isPut() {
+ return $this->request->is('put');
+ }
+
+/**
+ * Returns true if the current call a GET request
+ *
+ * @return boolean True if call is a GET
+ * @deprecated Use $this->request->is('get'); from your controller.
+ */
+ public function isGet() {
+ return $this->request->is('get');
+ }
+
+/**
+ * Returns true if the current call a DELETE request
+ *
+ * @return boolean True if call is a DELETE
+ * @deprecated Use $this->request->is('delete'); from your controller.
+ */
+ public function isDelete() {
+ return $this->request->is('delete');
+ }
+
+/**
+ * Gets Prototype version if call is Ajax, otherwise empty string.
+ * The Prototype library sets a special "Prototype version" HTTP header.
+ *
+ * @return string Prototype version of component making Ajax call
+ */
+ public function getAjaxVersion() {
+ if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
+ return env('HTTP_X_PROTOTYPE_VERSION');
+ }
+ return false;
+ }
+
+/**
+ * Adds/sets the Content-type(s) for the given name. This method allows
+ * content-types to be mapped to friendly aliases (or extensions), which allows
+ * RequestHandler to automatically respond to requests of that type in the
+ * startup method.
+ *
+ * @param string $name The name of the Content-type, i.e. "html", "xml", "css"
+ * @param string|array $type The Content-type or array of Content-types assigned to the name,
+ * i.e. "text/html", or "application/xml"
+ * @return void
+ * @deprecated use `$this->response->type()` instead.
+ */
+ public function setContent($name, $type = null) {
+ $this->response->type(array($name => $type));
+ }
+
+/**
+ * Gets the server name from which this request was referred
+ *
+ * @return string Server address
+ * @deprecated use $this->request->referer() from your controller instead
+ */
+ public function getReferer() {
+ return $this->request->referer(false);
+ }
+
+/**
+ * Gets remote client IP
+ *
+ * @param boolean $safe
+ * @return string Client IP address
+ * @deprecated use $this->request->clientIp() from your, controller instead.
+ */
+ public function getClientIP($safe = true) {
+ return $this->request->clientIp($safe);
+ }
+
+/**
+ * Determines which content types the client accepts. Acceptance is based on
+ * the file extension parsed by the Router (if present), and by the HTTP_ACCEPT
+ * header. Unlike CakeRequest::accepts() this method deals entirely with mapped content types.
+ *
+ * Usage:
+ *
+ * `$this->RequestHandler->accepts(array('xml', 'html', 'json'));`
+ *
+ * Returns true if the client accepts any of the supplied types.
+ *
+ * `$this->RequestHandler->accepts('xml');`
+ *
+ * Returns true if the client accepts xml.
+ *
+ * @param string|array $type Can be null (or no parameter), a string type name, or an
+ * array of types
+ * @return mixed If null or no parameter is passed, returns an array of content
+ * types the client accepts. If a string is passed, returns true
+ * if the client accepts it. If an array is passed, returns true
+ * if the client accepts one or more elements in the array.
+ * @see RequestHandlerComponent::setContent()
+ */
+ public function accepts($type = null) {
+ $accepted = $this->request->accepts();
+
+ if ($type == null) {
+ return $this->mapType($accepted);
+ } elseif (is_array($type)) {
+ foreach ($type as $t) {
+ $t = $this->mapAlias($t);
+ if (in_array($t, $accepted)) {
+ return true;
+ }
+ }
+ return false;
+ } elseif (is_string($type)) {
+ $type = $this->mapAlias($type);
+ return in_array($type, $accepted);
+ }
+ return false;
+ }
+
+/**
+ * Determines the content type of the data the client has sent (i.e. in a POST request)
+ *
+ * @param string|array $type Can be null (or no parameter), a string type name, or an array of types
+ * @return mixed If a single type is supplied a boolean will be returned. If no type is provided
+ * The mapped value of CONTENT_TYPE will be returned. If an array is supplied the first type
+ * in the request content type will be returned.
+ */
+ public function requestedWith($type = null) {
+ if (!$this->request->is('post') && !$this->request->is('put')) {
+ return null;
+ }
+
+ list($contentType) = explode(';', env('CONTENT_TYPE'));
+ if ($type == null) {
+ return $this->mapType($contentType);
+ } elseif (is_array($type)) {
+ foreach ($type as $t) {
+ if ($this->requestedWith($t)) {
+ return $t;
+ }
+ }
+ return false;
+ } elseif (is_string($type)) {
+ return ($type == $this->mapType($contentType));
+ }
+ }
+
+/**
+ * Determines which content-types the client prefers. If no parameters are given,
+ * the single content-type that the client most likely prefers is returned. If $type is
+ * an array, the first item in the array that the client accepts is returned.
+ * Preference is determined primarily by the file extension parsed by the Router
+ * if provided, and secondarily by the list of content-types provided in
+ * HTTP_ACCEPT.
+ *
+ * @param string|array $type An optional array of 'friendly' content-type names, i.e.
+ * 'html', 'xml', 'js', etc.
+ * @return mixed If $type is null or not provided, the first content-type in the
+ * list, based on preference, is returned. If a single type is provided
+ * a boolean will be returned if that type is preferred.
+ * If an array of types are provided then the first preferred type is returned.
+ * If no type is provided the first preferred type is returned.
+ * @see RequestHandlerComponent::setContent()
+ */
+ public function prefers($type = null) {
+ $acceptRaw = $this->request->parseAccept();
+
+ if (empty($acceptRaw)) {
+ return $this->ext;
+ }
+ $accepts = array_shift($acceptRaw);
+ $accepts = $this->mapType($accepts);
+
+ if ($type == null) {
+ if (empty($this->ext) && !empty($accepts)) {
+ return $accepts[0];
+ }
+ return $this->ext;
+ }
+
+ $types = (array)$type;
+
+ if (count($types) === 1) {
+ if (!empty($this->ext)) {
+ return in_array($this->ext, $types);
+ }
+ return in_array($types[0], $accepts);
+ }
+
+ $intersect = array_values(array_intersect($accepts, $types));
+ if (empty($intersect)) {
+ return false;
+ }
+ return $intersect[0];
+ }
+
+/**
+ * Sets the layout and template paths for the content type defined by $type.
+ *
+ * ### Usage:
+ *
+ * Render the response as an 'ajax' response.
+ *
+ * `$this->RequestHandler->renderAs($this, 'ajax');`
+ *
+ * Render the response as an xml file and force the result as a file download.
+ *
+ * `$this->RequestHandler->renderAs($this, 'xml', array('attachment' => 'myfile.xml');`
+ *
+ * @param Controller $controller A reference to a controller object
+ * @param string $type Type of response to send (e.g: 'ajax')
+ * @param array $options Array of options to use
+ * @return void
+ * @see RequestHandlerComponent::setContent()
+ * @see RequestHandlerComponent::respondAs()
+ */
+ public function renderAs(Controller $controller, $type, $options = array()) {
+ $defaults = array('charset' => 'UTF-8');
+
+ if (Configure::read('App.encoding') !== null) {
+ $defaults['charset'] = Configure::read('App.encoding');
+ }
+ $options = array_merge($defaults, $options);
+
+ if ($type == 'ajax') {
+ $controller->layout = $this->ajaxLayout;
+ return $this->respondAs('html', $options);
+ }
+ $controller->ext = '.ctp';
+
+ $viewClass = Inflector::classify($type);
+ $viewName = $viewClass . 'View';
+ if (!class_exists($viewName)) {
+ App::uses($viewName, 'View');
+ }
+ if (class_exists($viewName)) {
+ $controller->viewClass = $viewClass;
+ } elseif (empty($this->_renderType)) {
+ $controller->viewPath .= DS . $type;
+ } else {
+ $remove = preg_replace("/([\/\\\\]{$this->_renderType})$/", DS . $type, $controller->viewPath);
+ $controller->viewPath = $remove;
+ }
+ $this->_renderType = $type;
+ $controller->layoutPath = $type;
+
+ if ($this->response->getMimeType($type)) {
+ $this->respondAs($type, $options);
+ }
+
+ $helper = ucfirst($type);
+ $isAdded = (
+ in_array($helper, $controller->helpers) ||
+ array_key_exists($helper, $controller->helpers)
+ );
+
+ if (!$isAdded) {
+ App::uses('AppHelper', 'View/Helper');
+ App::uses($helper . 'Helper', 'View/Helper');
+ if (class_exists($helper . 'Helper')) {
+ $controller->helpers[] = $helper;
+ }
+ }
+ }
+
+/**
+ * Sets the response header based on type map index name. This wraps several methods
+ * available on CakeResponse. It also allows you to use Content-Type aliases.
+ *
+ * @param string|array $type Friendly type name, i.e. 'html' or 'xml', or a full content-type,
+ * like 'application/x-shockwave'.
+ * @param array $options If $type is a friendly type name that is associated with
+ * more than one type of content, $index is used to select which content-type to use.
+ * @return boolean Returns false if the friendly type name given in $type does
+ * not exist in the type map, or if the Content-type header has
+ * already been set by this method.
+ * @see RequestHandlerComponent::setContent()
+ */
+ public function respondAs($type, $options = array()) {
+ $defaults = array('index' => null, 'charset' => null, 'attachment' => false);
+ $options = $options + $defaults;
+
+ if (strpos($type, '/') === false) {
+ $cType = $this->response->getMimeType($type);
+ if ($cType === false) {
+ return false;
+ }
+ if (is_array($cType) && isset($cType[$options['index']])) {
+ $cType = $cType[$options['index']];
+ }
+ if (is_array($cType)) {
+ if ($this->prefers($cType)) {
+ $cType = $this->prefers($cType);
+ } else {
+ $cType = $cType[0];
+ }
+ }
+ } else {
+ $cType = $type;
+ }
+
+ if ($cType != null) {
+ if (empty($this->request->params['requested'])) {
+ $this->response->type($cType);
+ }
+
+ if (!empty($options['charset'])) {
+ $this->response->charset($options['charset']);
+ }
+ if (!empty($options['attachment'])) {
+ $this->response->download($options['attachment']);
+ }
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Returns the current response type (Content-type header), or null if not alias exists
+ *
+ * @return mixed A string content type alias, or raw content type if no alias map exists,
+ * otherwise null
+ */
+ public function responseType() {
+ return $this->mapType($this->response->type());
+ }
+
+/**
+ * Maps a content-type back to an alias
+ *
+ * @param string|array $cType Either a string content type to map, or an array of types.
+ * @return string|array Aliases for the types provided.
+ * @deprecated Use $this->response->mapType() in your controller instead.
+ */
+ public function mapType($cType) {
+ return $this->response->mapType($cType);
+ }
+
+/**
+ * Maps a content type alias back to its mime-type(s)
+ *
+ * @param string|array $alias String alias to convert back into a content type. Or an array of aliases to map.
+ * @return string Null on an undefined alias. String value of the mapped alias type. If an
+ * alias maps to more than one content type, the first one will be returned.
+ */
+ public function mapAlias($alias) {
+ if (is_array($alias)) {
+ return array_map(array($this, 'mapAlias'), $alias);
+ }
+ $type = $this->response->getMimeType($alias);
+ if ($type) {
+ if (is_array($type)) {
+ return $type[0];
+ }
+ return $type;
+ }
+ return null;
+ }
+
+/**
+ * Add a new mapped input type. Mapped input types are automatically
+ * converted by RequestHandlerComponent during the startup() callback.
+ *
+ * @param string $type The type alias being converted, ie. json
+ * @param array $handler The handler array for the type. The first index should
+ * be the handling callback, all other arguments should be additional parameters
+ * for the handler.
+ * @return void
+ * @throws CakeException
+ */
+ public function addInputType($type, $handler) {
+ if (!is_array($handler) || !isset($handler[0]) || !is_callable($handler[0])) {
+ throw new CakeException(__d('cake_dev', 'You must give a handler callback.'));
+ }
+ $this->_inputTypeMap[$type] = $handler;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php
new file mode 100644
index 0000000..3b5eb86
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php
@@ -0,0 +1,598 @@
+<?php
+/**
+ * Security Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.8.2156
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('String', 'Utility');
+App::uses('Hash', 'Utility');
+App::uses('Security', 'Utility');
+
+/**
+ * The Security Component creates an easy way to integrate tighter security in
+ * your application. It provides methods for various tasks like:
+ *
+ * - Restricting which HTTP methods your application accepts.
+ * - CSRF protection.
+ * - Form tampering protection
+ * - Requiring that SSL be used.
+ * - Limiting cross controller communication.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html
+ */
+class SecurityComponent extends Component {
+
+/**
+ * The controller method that will be called if this request is black-hole'd
+ *
+ * @var string
+ */
+ public $blackHoleCallback = null;
+
+/**
+ * List of controller actions for which a POST request is required
+ *
+ * @var array
+ * @see SecurityComponent::requirePost()
+ */
+ public $requirePost = array();
+
+/**
+ * List of controller actions for which a GET request is required
+ *
+ * @var array
+ * @see SecurityComponent::requireGet()
+ */
+ public $requireGet = array();
+
+/**
+ * List of controller actions for which a PUT request is required
+ *
+ * @var array
+ * @see SecurityComponent::requirePut()
+ */
+ public $requirePut = array();
+
+/**
+ * List of controller actions for which a DELETE request is required
+ *
+ * @var array
+ * @see SecurityComponent::requireDelete()
+ */
+ public $requireDelete = array();
+
+/**
+ * List of actions that require an SSL-secured connection
+ *
+ * @var array
+ * @see SecurityComponent::requireSecure()
+ */
+ public $requireSecure = array();
+
+/**
+ * List of actions that require a valid authentication key
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ public $requireAuth = array();
+
+/**
+ * Controllers from which actions of the current controller are allowed to receive
+ * requests.
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ public $allowedControllers = array();
+
+/**
+ * Actions from which actions of the current controller are allowed to receive
+ * requests.
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ public $allowedActions = array();
+
+/**
+ * Deprecated property, superseded by unlockedFields.
+ *
+ * @var array
+ * @deprecated
+ * @see SecurityComponent::$unlockedFields
+ */
+ public $disabledFields = array();
+
+/**
+ * Form fields to exclude from POST validation. Fields can be unlocked
+ * either in the Component, or with FormHelper::unlockField().
+ * Fields that have been unlocked are not required to be part of the POST
+ * and hidden unlocked fields do not have their values checked.
+ *
+ * @var array
+ */
+ public $unlockedFields = array();
+
+/**
+ * Whether to validate POST data. Set to false to disable for data coming from 3rd party
+ * services, etc.
+ *
+ * @var boolean
+ */
+ public $validatePost = true;
+
+/**
+ * Whether to use CSRF protected forms. Set to false to disable CSRF protection on forms.
+ *
+ * @var boolean
+ * @see http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
+ * @see SecurityComponent::$csrfExpires
+ */
+ public $csrfCheck = true;
+
+/**
+ * The duration from when a CSRF token is created that it will expire on.
+ * Each form/page request will generate a new token that can only be submitted once unless
+ * it expires. Can be any value compatible with strtotime()
+ *
+ * @var string
+ */
+ public $csrfExpires = '+30 minutes';
+
+/**
+ * Controls whether or not CSRF tokens are use and burn. Set to false to not generate
+ * new tokens on each request. One token will be reused until it expires. This reduces
+ * the chances of users getting invalid requests because of token consumption.
+ * It has the side effect of making CSRF less secure, as tokens are reusable.
+ *
+ * @var boolean
+ */
+ public $csrfUseOnce = true;
+
+/**
+ * Control the number of tokens a user can keep open.
+ * This is most useful with one-time use tokens. Since new tokens
+ * are created on each request, having a hard limit on the number of open tokens
+ * can be useful in controlling the size of the session file.
+ *
+ * When tokens are evicted, the oldest ones will be removed, as they are the most likely
+ * to be dead/expired.
+ *
+ * @var integer
+ */
+ public $csrfLimit = 100;
+
+/**
+ * Other components used by the Security component
+ *
+ * @var array
+ */
+ public $components = array('Session');
+
+/**
+ * Holds the current action of the controller
+ *
+ * @var string
+ */
+ protected $_action = null;
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Component startup. All security checking happens here.
+ *
+ * @param Controller $controller Instantiating controller
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ $this->request = $controller->request;
+ $this->_action = $this->request->params['action'];
+ $this->_methodsRequired($controller);
+ $this->_secureRequired($controller);
+ $this->_authRequired($controller);
+
+ $isPost = ($this->request->is('post') || $this->request->is('put'));
+ $isNotRequestAction = (
+ !isset($controller->request->params['requested']) ||
+ $controller->request->params['requested'] != 1
+ );
+
+ if ($isPost && $isNotRequestAction && $this->validatePost) {
+ if ($this->_validatePost($controller) === false) {
+ return $this->blackHole($controller, 'auth');
+ }
+ }
+ if ($isPost && $isNotRequestAction && $this->csrfCheck) {
+ if ($this->_validateCsrf($controller) === false) {
+ return $this->blackHole($controller, 'csrf');
+ }
+ }
+ $this->generateToken($controller->request);
+ if ($isPost && is_array($controller->request->data)) {
+ unset($controller->request->data['_Token']);
+ }
+ }
+
+/**
+ * Sets the actions that require a POST request, or empty for all actions
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requirePost
+ */
+ public function requirePost() {
+ $args = func_get_args();
+ $this->_requireMethod('Post', $args);
+ }
+
+/**
+ * Sets the actions that require a GET request, or empty for all actions
+ *
+ * @return void
+ */
+ public function requireGet() {
+ $args = func_get_args();
+ $this->_requireMethod('Get', $args);
+ }
+
+/**
+ * Sets the actions that require a PUT request, or empty for all actions
+ *
+ * @return void
+ */
+ public function requirePut() {
+ $args = func_get_args();
+ $this->_requireMethod('Put', $args);
+ }
+
+/**
+ * Sets the actions that require a DELETE request, or empty for all actions
+ *
+ * @return void
+ */
+ public function requireDelete() {
+ $args = func_get_args();
+ $this->_requireMethod('Delete', $args);
+ }
+
+/**
+ * Sets the actions that require a request that is SSL-secured, or empty for all actions
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requireSecure
+ */
+ public function requireSecure() {
+ $args = func_get_args();
+ $this->_requireMethod('Secure', $args);
+ }
+
+/**
+ * Sets the actions that require an authenticated request, or empty for all actions
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requireAuth
+ */
+ public function requireAuth() {
+ $args = func_get_args();
+ $this->_requireMethod('Auth', $args);
+ }
+
+/**
+ * Black-hole an invalid request with a 400 error or custom callback. If SecurityComponent::$blackHoleCallback
+ * is specified, it will use this callback by executing the method indicated in $error
+ *
+ * @param Controller $controller Instantiating controller
+ * @param string $error Error method
+ * @return mixed If specified, controller blackHoleCallback's response, or no return otherwise
+ * @see SecurityComponent::$blackHoleCallback
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#handling-blackhole-callbacks
+ * @throws BadRequestException
+ */
+ public function blackHole(Controller $controller, $error = '') {
+ if ($this->blackHoleCallback == null) {
+ throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
+ } else {
+ return $this->_callback($controller, $this->blackHoleCallback, array($error));
+ }
+ }
+
+/**
+ * Sets the actions that require a $method HTTP request, or empty for all actions
+ *
+ * @param string $method The HTTP method to assign controller actions to
+ * @param array $actions Controller actions to set the required HTTP method to.
+ * @return void
+ */
+ protected function _requireMethod($method, $actions = array()) {
+ if (isset($actions[0]) && is_array($actions[0])) {
+ $actions = $actions[0];
+ }
+ $this->{'require' . $method} = (empty($actions)) ? array('*'): $actions;
+ }
+
+/**
+ * Check if HTTP methods are required
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if $method is required
+ */
+ protected function _methodsRequired(Controller $controller) {
+ foreach (array('Post', 'Get', 'Put', 'Delete') as $method) {
+ $property = 'require' . $method;
+ if (is_array($this->$property) && !empty($this->$property)) {
+ $require = $this->$property;
+ if (in_array($this->_action, $require) || $this->$property == array('*')) {
+ if (!$this->request->is($method)) {
+ if (!$this->blackHole($controller, $method)) {
+ return null;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Check if access requires secure connection
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if secure connection required
+ */
+ protected function _secureRequired(Controller $controller) {
+ if (is_array($this->requireSecure) && !empty($this->requireSecure)) {
+ $requireSecure = $this->requireSecure;
+
+ if (in_array($this->_action, $requireSecure) || $this->requireSecure == array('*')) {
+ if (!$this->request->is('ssl')) {
+ if (!$this->blackHole($controller, 'secure')) {
+ return null;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Check if authentication is required
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if authentication required
+ */
+ protected function _authRequired(Controller $controller) {
+ if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($this->request->data)) {
+ $requireAuth = $this->requireAuth;
+
+ if (in_array($this->request->params['action'], $requireAuth) || $this->requireAuth == array('*')) {
+ if (!isset($controller->request->data['_Token'] )) {
+ if (!$this->blackHole($controller, 'auth')) {
+ return null;
+ }
+ }
+
+ if ($this->Session->check('_Token')) {
+ $tData = $this->Session->read('_Token');
+
+ if (
+ !empty($tData['allowedControllers']) &&
+ !in_array($this->request->params['controller'], $tData['allowedControllers']) ||
+ !empty($tData['allowedActions']) &&
+ !in_array($this->request->params['action'], $tData['allowedActions'])
+ ) {
+ if (!$this->blackHole($controller, 'auth')) {
+ return null;
+ }
+ }
+ } else {
+ if (!$this->blackHole($controller, 'auth')) {
+ return null;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Validate submitted form
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if submitted form is valid
+ */
+ protected function _validatePost(Controller $controller) {
+ if (empty($controller->request->data)) {
+ return true;
+ }
+ $data = $controller->request->data;
+
+ if (!isset($data['_Token']) || !isset($data['_Token']['fields']) || !isset($data['_Token']['unlocked'])) {
+ return false;
+ }
+
+ $locked = '';
+ $check = $controller->request->data;
+ $token = urldecode($check['_Token']['fields']);
+ $unlocked = urldecode($check['_Token']['unlocked']);
+
+ if (strpos($token, ':')) {
+ list($token, $locked) = explode(':', $token, 2);
+ }
+ unset($check['_Token']);
+
+ $locked = explode('|', $locked);
+ $unlocked = explode('|', $unlocked);
+
+ $lockedFields = array();
+ $fields = Hash::flatten($check);
+ $fieldList = array_keys($fields);
+ $multi = array();
+
+ foreach ($fieldList as $i => $key) {
+ if (preg_match('/(\.\d+)+$/', $key)) {
+ $multi[$i] = preg_replace('/(\.\d+)+$/', '', $key);
+ unset($fieldList[$i]);
+ }
+ }
+ if (!empty($multi)) {
+ $fieldList += array_unique($multi);
+ }
+
+ $unlockedFields = array_unique(
+ array_merge((array)$this->disabledFields, (array)$this->unlockedFields, $unlocked)
+ );
+
+ foreach ($fieldList as $i => $key) {
+ $isLocked = (is_array($locked) && in_array($key, $locked));
+
+ if (!empty($unlockedFields)) {
+ foreach ($unlockedFields as $off) {
+ $off = explode('.', $off);
+ $field = array_values(array_intersect(explode('.', $key), $off));
+ $isUnlocked = ($field === $off);
+ if ($isUnlocked) {
+ break;
+ }
+ }
+ }
+
+ if ($isUnlocked || $isLocked) {
+ unset($fieldList[$i]);
+ if ($isLocked) {
+ $lockedFields[$key] = $fields[$key];
+ }
+ }
+ }
+ sort($unlocked, SORT_STRING);
+ sort($fieldList, SORT_STRING);
+ ksort($lockedFields, SORT_STRING);
+
+ $fieldList += $lockedFields;
+ $unlocked = implode('|', $unlocked);
+ $check = Security::hash(serialize($fieldList) . $unlocked . Configure::read('Security.salt'));
+ return ($token === $check);
+ }
+
+/**
+ * Manually add CSRF token information into the provided request object.
+ *
+ * @param CakeRequest $request The request object to add into.
+ * @return boolean
+ */
+ public function generateToken(CakeRequest $request) {
+ if (isset($request->params['requested']) && $request->params['requested'] === 1) {
+ if ($this->Session->check('_Token')) {
+ $request->params['_Token'] = $this->Session->read('_Token');
+ }
+ return false;
+ }
+ $authKey = Security::generateAuthKey();
+ $token = array(
+ 'key' => $authKey,
+ 'allowedControllers' => $this->allowedControllers,
+ 'allowedActions' => $this->allowedActions,
+ 'unlockedFields' => array_merge($this->disabledFields, $this->unlockedFields),
+ 'csrfTokens' => array()
+ );
+
+ $tokenData = array();
+ if ($this->Session->check('_Token')) {
+ $tokenData = $this->Session->read('_Token');
+ if (!empty($tokenData['csrfTokens']) && is_array($tokenData['csrfTokens'])) {
+ $token['csrfTokens'] = $this->_expireTokens($tokenData['csrfTokens']);
+ }
+ }
+ if ($this->csrfUseOnce || empty($token['csrfTokens'])) {
+ $token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
+ }
+ if (!$this->csrfUseOnce) {
+ $csrfTokens = array_keys($token['csrfTokens']);
+ $token['key'] = $csrfTokens[0];
+ }
+ $this->Session->write('_Token', $token);
+ $request->params['_Token'] = array(
+ 'key' => $token['key'],
+ 'unlockedFields' => $token['unlockedFields']
+ );
+ return true;
+ }
+
+/**
+ * Validate that the controller has a CSRF token in the POST data
+ * and that the token is legit/not expired. If the token is valid
+ * it will be removed from the list of valid tokens.
+ *
+ * @param Controller $controller A controller to check
+ * @return boolean Valid csrf token.
+ */
+ protected function _validateCsrf(Controller $controller) {
+ $token = $this->Session->read('_Token');
+ $requestToken = $controller->request->data('_Token.key');
+ if (isset($token['csrfTokens'][$requestToken]) && $token['csrfTokens'][$requestToken] >= time()) {
+ if ($this->csrfUseOnce) {
+ $this->Session->delete('_Token.csrfTokens.' . $requestToken);
+ }
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Expire CSRF nonces and remove them from the valid tokens.
+ * Uses a simple timeout to expire the tokens.
+ *
+ * @param array $tokens An array of nonce => expires.
+ * @return array An array of nonce => expires.
+ */
+ protected function _expireTokens($tokens) {
+ $now = time();
+ foreach ($tokens as $nonce => $expires) {
+ if ($expires < $now) {
+ unset($tokens[$nonce]);
+ }
+ }
+ $overflow = count($tokens) - $this->csrfLimit;
+ if ($overflow > 0) {
+ $tokens = array_slice($tokens, $overflow + 1, null, true);
+ }
+ return $tokens;
+ }
+
+/**
+ * Calls a controller callback method
+ *
+ * @param Controller $controller Controller to run callback on
+ * @param string $method Method to execute
+ * @param array $params Parameters to send to method
+ * @return mixed Controller callback method's response
+ * @throws BadRequestException When a the blackholeCallback is not callable.
+ */
+ protected function _callback(Controller $controller, $method, $params = array()) {
+ if (is_callable(array($controller, $method))) {
+ return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
+ } else {
+ throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php
new file mode 100644
index 0000000..ed42bff
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * SessionComponent. Provides access to Sessions from the Controller layer
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('CakeSession', 'Model/Datasource');
+
+/**
+ * The CakePHP SessionComponent provides a way to persist client data between
+ * page requests. It acts as a wrapper for the `$_SESSION` as well as providing
+ * convenience methods for several `$_SESSION` related functions.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html
+ * @link http://book.cakephp.org/2.0/en/development/sessions.html
+ */
+class SessionComponent extends Component {
+
+/**
+ * Get / Set the userAgent
+ *
+ * @param string $userAgent Set the userAgent
+ * @return void
+ */
+ public function userAgent($userAgent = null) {
+ return CakeSession::userAgent($userAgent);
+ }
+
+/**
+ * Used to write a value to a session key.
+ *
+ * In your controller: $this->Session->write('Controller.sessKey', 'session value');
+ *
+ * @param string $name The name of the key your are setting in the session.
+ * This should be in a Controller.key format for better organizing
+ * @param string $value The value you want to store in a session.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::write
+ */
+ public function write($name, $value = null) {
+ return CakeSession::write($name, $value);
+ }
+
+/**
+ * Used to read a session values for a key or return values for all keys.
+ *
+ * In your controller: $this->Session->read('Controller.sessKey');
+ * Calling the method without a param will return all session vars
+ *
+ * @param string $name the name of the session key you want to read
+ * @return mixed value from the session vars
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::read
+ */
+ public function read($name = null) {
+ return CakeSession::read($name);
+ }
+
+/**
+ * Wrapper for SessionComponent::del();
+ *
+ * In your controller: $this->Session->delete('Controller.sessKey');
+ *
+ * @param string $name the name of the session key you want to delete
+ * @return boolean true is session variable is set and can be deleted, false is variable was not set.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::delete
+ */
+ public function delete($name) {
+ return CakeSession::delete($name);
+ }
+
+/**
+ * Used to check if a session variable is set
+ *
+ * In your controller: $this->Session->check('Controller.sessKey');
+ *
+ * @param string $name the name of the session key you want to check
+ * @return boolean true is session variable is set, false if not
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::check
+ */
+ public function check($name) {
+ return CakeSession::check($name);
+ }
+
+/**
+ * Used to determine the last error in a session.
+ *
+ * In your controller: $this->Session->error();
+ *
+ * @return string Last session error
+ */
+ public function error() {
+ return CakeSession::error();
+ }
+
+/**
+ * Used to set a session variable that can be used to output messages in the view.
+ *
+ * In your controller: $this->Session->setFlash('This has been saved');
+ *
+ * Additional params below can be passed to customize the output, or the Message.[key].
+ * You can also set additional parameters when rendering flash messages. See SessionHelper::flash()
+ * for more information on how to do that.
+ *
+ * @param string $message Message to be flashed
+ * @param string $element Element to wrap flash message in.
+ * @param array $params Parameters to be sent to layout as view variables
+ * @param string $key Message key, default is 'flash'
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#creating-notification-messages
+ */
+ public function setFlash($message, $element = 'default', $params = array(), $key = 'flash') {
+ CakeSession::write('Message.' . $key, compact('message', 'element', 'params'));
+ }
+
+/**
+ * Used to renew a session id
+ *
+ * In your controller: $this->Session->renew();
+ *
+ * @return void
+ */
+ public function renew() {
+ return CakeSession::renew();
+ }
+
+/**
+ * Used to check for a valid session.
+ *
+ * In your controller: $this->Session->valid();
+ *
+ * @return boolean true is session is valid, false is session is invalid
+ */
+ public function valid() {
+ return CakeSession::valid();
+ }
+
+/**
+ * Used to destroy sessions
+ *
+ * In your controller: $this->Session->destroy();
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::destroy
+ */
+ public function destroy() {
+ return CakeSession::destroy();
+ }
+
+/**
+ * Get/Set the session id.
+ *
+ * When fetching the session id, the session will be started
+ * if it has not already been started. When setting the session id,
+ * the session will not be started.
+ *
+ * @param string $id Id to use (optional)
+ * @return string The current session id.
+ */
+ public function id($id = null) {
+ if (empty($id)) {
+ CakeSession::start();
+ }
+ return CakeSession::id($id);
+ }
+
+/**
+ * Returns a bool, whether or not the session has been started.
+ *
+ * @return boolean
+ */
+ public function started() {
+ return CakeSession::started();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php
new file mode 100644
index 0000000..43dca08
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Components collection is used as a registry for loaded components and handles loading
+ * and constructing component class objects.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+App::uses('Component', 'Controller');
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * Components collection is used as a registry for loaded components and handles loading
+ * and constructing component class objects.
+ *
+ * @package Cake.Controller
+ */
+class ComponentCollection extends ObjectCollection implements CakeEventListener {
+
+/**
+ * The controller that this collection was initialized with.
+ *
+ * @var Controller
+ */
+ protected $_Controller = null;
+
+/**
+ * Initializes all the Components for a controller.
+ * Attaches a reference of each component to the Controller.
+ *
+ * @param Controller $Controller Controller to initialize components for.
+ * @return void
+ */
+ public function init(Controller $Controller) {
+ if (empty($Controller->components)) {
+ return;
+ }
+ $this->_Controller = $Controller;
+ $components = ComponentCollection::normalizeObjectArray($Controller->components);
+ foreach ($components as $name => $properties) {
+ $Controller->{$name} = $this->load($properties['class'], $properties['settings']);
+ }
+ }
+
+/**
+ * Get the controller associated with the collection.
+ *
+ * @return Controller.
+ */
+ public function getController() {
+ return $this->_Controller;
+ }
+
+/**
+ * Loads/constructs a component. Will return the instance in the registry if it already exists.
+ * You can use `$settings['enabled'] = false` to disable callbacks on a component when loading it.
+ * Callbacks default to on. Disabled component methods work as normal, only callbacks are disabled.
+ *
+ * You can alias your component as an existing component by setting the 'className' key, i.e.,
+ * {{{
+ * public $components = array(
+ * 'Email' => array(
+ * 'className' => 'AliasedEmail'
+ * );
+ * );
+ * }}}
+ * All calls to the `Email` component would use `AliasedEmail` instead.
+ *
+ * @param string $component Component name to load
+ * @param array $settings Settings for the component.
+ * @return Component A component object, Either the existing loaded component or a new one.
+ * @throws MissingComponentException when the component could not be found
+ */
+ public function load($component, $settings = array()) {
+ if (is_array($settings) && isset($settings['className'])) {
+ $alias = $component;
+ $component = $settings['className'];
+ }
+ list($plugin, $name) = pluginSplit($component, true);
+ if (!isset($alias)) {
+ $alias = $name;
+ }
+ if (isset($this->_loaded[$alias])) {
+ return $this->_loaded[$alias];
+ }
+ $componentClass = $name . 'Component';
+ App::uses($componentClass, $plugin . 'Controller/Component');
+ if (!class_exists($componentClass)) {
+ throw new MissingComponentException(array(
+ 'class' => $componentClass,
+ 'plugin' => substr($plugin, 0, -1)
+ ));
+ }
+ $this->_loaded[$alias] = new $componentClass($this, $settings);
+ $enable = isset($settings['enabled']) ? $settings['enabled'] : true;
+ if ($enable) {
+ $this->enable($alias);
+ }
+ return $this->_loaded[$alias];
+ }
+
+/**
+ * Returns the implemented events that will get routed to the trigger function
+ * in order to dispatch them separately on each component
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'Controller.initialize' => array('callable' => 'trigger'),
+ 'Controller.startup' => array('callable' => 'trigger'),
+ 'Controller.beforeRender' => array('callable' => 'trigger'),
+ 'Controller.beforeRedirect' => array('callable' => 'trigger'),
+ 'Controller.shutdown' => array('callable' => 'trigger'),
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php
new file mode 100644
index 0000000..fa8b7da
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php
@@ -0,0 +1,1228 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeResponse', 'Network');
+App::uses('ClassRegistry', 'Utility');
+App::uses('ComponentCollection', 'Controller');
+App::uses('View', 'View');
+App::uses('CakeEvent', 'Event');
+App::uses('CakeEventListener', 'Event');
+App::uses('CakeEventManager', 'Event');
+
+/**
+ * Application controller class for organization of business logic.
+ * Provides basic functionality, such as rendering views inside layouts,
+ * automatic model availability, redirection, callbacks, and more.
+ *
+ * Controllers should provide a number of 'action' methods. These are public methods on the controller
+ * that are not prefixed with a '_' and not part of Controller. Each action serves as an endpoint for
+ * performing a specific action on a resource or collection of resources. For example adding or editing a new
+ * object, or listing a set of objects.
+ *
+ * You can access request parameters, using `$this->request`. The request object contains all the POST, GET and FILES
+ * that were part of the request.
+ *
+ * After performing the required actions, controllers are responsible for creating a response. This usually
+ * takes the form of a generated View, or possibly a redirection to another controller action. In either case
+ * `$this->response` allows you to manipulate all aspects of the response.
+ *
+ * Controllers are created by Dispatcher based on request parameters and routing. By default controllers and actions
+ * use conventional names. For example `/posts/index` maps to `PostsController::index()`. You can re-map urls
+ * using Router::connect().
+ *
+ * @package Cake.Controller
+ * @property AclComponent $Acl
+ * @property AuthComponent $Auth
+ * @property CookieComponent $Cookie
+ * @property EmailComponent $Email
+ * @property PaginatorComponent $Paginator
+ * @property RequestHandlerComponent $RequestHandler
+ * @property SecurityComponent $Security
+ * @property SessionComponent $Session
+ * @link http://book.cakephp.org/2.0/en/controllers.html
+ */
+class Controller extends Object implements CakeEventListener {
+
+/**
+ * The name of this controller. Controller names are plural, named after the model they manipulate.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/controllers.html#controller-attributes
+ */
+ public $name = null;
+
+/**
+ * An array containing the class names of models this controller uses.
+ *
+ * Example: `public $uses = array('Product', 'Post', 'Comment');`
+ *
+ * Can be set to several values to express different options:
+ *
+ * - `true` Use the default inflected model name.
+ * - `array()` Use only models defined in the parent class.
+ * - `false` Use no models at all, do not merge with parent class either.
+ * - `array('Post', 'Comment')` Use only the Post and Comment models. Models
+ * Will also be merged with the parent class.
+ *
+ * The default value is `true`.
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
+ */
+ public $uses = true;
+
+/**
+ * An array containing the names of helpers this controller uses. The array elements should
+ * not contain the "Helper" part of the classname.
+ *
+ * Example: `public $helpers = array('Html', 'Javascript', 'Time', 'Ajax');`
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
+ */
+ public $helpers = array();
+
+/**
+ * An instance of a CakeRequest object that contains information about the current request.
+ * This object contains all the information about a request and several methods for reading
+ * additional information about the request.
+ *
+ * @var CakeRequest
+ * @link http://book.cakephp.org/2.0/en/controllers/request-response.html#cakerequest
+ */
+ public $request;
+
+/**
+ * An instance of a CakeResponse object that contains information about the impending response
+ *
+ * @var CakeResponse
+ * @link http://book.cakephp.org/2.0/en/controllers/request-response.html#cakeresponse
+ */
+ public $response;
+
+/**
+ * The classname to use for creating the response object.
+ *
+ * @var string
+ */
+ protected $_responseClass = 'CakeResponse';
+
+/**
+ * The name of the views subfolder containing views for this controller.
+ *
+ * @var string
+ */
+ public $viewPath = null;
+
+/**
+ * The name of the layouts subfolder containing layouts for this controller.
+ *
+ * @var string
+ */
+ public $layoutPath = null;
+
+/**
+ * Contains variables to be handed to the view.
+ *
+ * @var array
+ */
+ public $viewVars = array();
+
+/**
+ * The name of the view file to render. The name specified
+ * is the filename in /app/View/<SubFolder> without the .ctp extension.
+ *
+ * @var string
+ */
+ public $view = null;
+
+/**
+ * The name of the layout file to render the view inside of. The name specified
+ * is the filename of the layout in /app/View/Layouts without the .ctp
+ * extension.
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Set to true to automatically render the view
+ * after action logic.
+ *
+ * @var boolean
+ */
+ public $autoRender = true;
+
+/**
+ * Set to true to automatically render the layout around views.
+ *
+ * @var boolean
+ */
+ public $autoLayout = true;
+
+/**
+ * Instance of ComponentCollection used to handle callbacks.
+ *
+ * @var ComponentCollection
+ */
+ public $Components = null;
+
+/**
+ * Array containing the names of components this controller uses. Component names
+ * should not contain the "Component" portion of the classname.
+ *
+ * Example: `public $components = array('Session', 'RequestHandler', 'Acl');`
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html
+ */
+ public $components = array('Session');
+
+/**
+ * The name of the View class this controller sends output to.
+ *
+ * @var string
+ */
+ public $viewClass = 'View';
+
+/**
+ * Instance of the View created during rendering. Won't be set until after
+ * Controller::render() is called.
+ *
+ * @var View
+ */
+ public $View;
+
+/**
+ * File extension for view templates. Defaults to Cake's conventional ".ctp".
+ *
+ * @var string
+ */
+ public $ext = '.ctp';
+
+/**
+ * Automatically set to the name of a plugin.
+ *
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Used to define methods a controller that will be cached. To cache a
+ * single action, the value is set to an array containing keys that match
+ * action names and values that denote cache expiration times (in seconds).
+ *
+ * Example:
+ *
+ * {{{
+ * public $cacheAction = array(
+ * 'view/23/' => 21600,
+ * 'recalled/' => 86400
+ * );
+ * }}}
+ *
+ * $cacheAction can also be set to a strtotime() compatible string. This
+ * marks all the actions in the controller for view caching.
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html#additional-configuration-options
+ */
+ public $cacheAction = false;
+
+/**
+ * Holds all params passed and named.
+ *
+ * @var mixed
+ */
+ public $passedArgs = array();
+
+/**
+ * Triggers Scaffolding
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/controllers/scaffolding.html
+ */
+ public $scaffold = false;
+
+/**
+ * Holds current methods of the controller. This is a list of all the methods reachable
+ * via url. Modifying this array, will allow you to change which methods can be reached.
+ *
+ * @var array
+ */
+ public $methods = array();
+
+/**
+ * This controller's primary model class name, the Inflector::singularize()'ed version of
+ * the controller's $name property.
+ *
+ * Example: For a controller named 'Comments', the modelClass would be 'Comment'
+ *
+ * @var string
+ */
+ public $modelClass = null;
+
+/**
+ * This controller's model key name, an underscored version of the controller's $modelClass property.
+ *
+ * Example: For a controller named 'ArticleComments', the modelKey would be 'article_comment'
+ *
+ * @var string
+ */
+ public $modelKey = null;
+
+/**
+ * Holds any validation errors produced by the last call of the validateErrors() method/
+ *
+ * @var array Validation errors, or false if none
+ */
+ public $validationErrors = null;
+
+/**
+ * The class name of the parent class you wish to merge with.
+ * Typically this is AppController, but you may wish to merge vars with a different
+ * parent class.
+ *
+ * @var string
+ */
+ protected $_mergeParent = 'AppController';
+
+/**
+ * Instance of the CakeEventManager this controller is using
+ * to dispatch inner events.
+ *
+ * @var CakeEventManager
+ */
+ protected $_eventManager = null;
+
+/**
+ * Constructor.
+ *
+ * @param CakeRequest $request Request object for this controller. Can be null for testing,
+ * but expect that features that use the request parameters will not work.
+ * @param CakeResponse $response Response object for this controller.
+ */
+ public function __construct($request = null, $response = null) {
+ if ($this->name === null) {
+ $this->name = substr(get_class($this), 0, -10);
+ }
+
+ if ($this->viewPath == null) {
+ $this->viewPath = $this->name;
+ }
+
+ $this->modelClass = Inflector::singularize($this->name);
+ $this->modelKey = Inflector::underscore($this->modelClass);
+ $this->Components = new ComponentCollection();
+
+ $childMethods = get_class_methods($this);
+ $parentMethods = get_class_methods('Controller');
+
+ $this->methods = array_diff($childMethods, $parentMethods);
+
+ if ($request instanceof CakeRequest) {
+ $this->setRequest($request);
+ }
+ if ($response instanceof CakeResponse) {
+ $this->response = $response;
+ }
+ parent::__construct();
+ }
+
+/**
+ * Provides backwards compatibility to avoid problems with empty and isset to alias properties.
+ * Lazy loads models using the loadModel() method if declared in $uses
+ *
+ * @param string $name
+ * @return void
+ */
+ public function __isset($name) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ case 'action':
+ case 'params':
+ return true;
+ }
+
+ if (is_array($this->uses)) {
+ foreach ($this->uses as $modelClass) {
+ list($plugin, $class) = pluginSplit($modelClass, true);
+ if ($name === $class) {
+ return $this->loadModel($modelClass);
+ }
+ }
+ }
+
+ if ($name === $this->modelClass) {
+ list($plugin, $class) = pluginSplit($name, true);
+ if (!$plugin) {
+ $plugin = $this->plugin ? $this->plugin . '.' : null;
+ }
+ return $this->loadModel($plugin . $this->modelClass);
+ }
+
+ return false;
+ }
+
+/**
+ * Provides backwards compatibility access to the request object properties.
+ * Also provides the params alias.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function __get($name) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name};
+ case 'action':
+ return isset($this->request->params['action']) ? $this->request->params['action'] : '';
+ case 'params':
+ return $this->request;
+ case 'paginate':
+ return $this->Components->load('Paginator')->settings;
+ }
+
+ if (isset($this->{$name})) {
+ return $this->{$name};
+ }
+
+ return null;
+ }
+
+/**
+ * Provides backwards compatibility access for setting values to the request object.
+ *
+ * @param string $name
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name} = $value;
+ case 'action':
+ return $this->request->params['action'] = $value;
+ case 'params':
+ return $this->request->params = $value;
+ case 'paginate':
+ return $this->Components->load('Paginator')->settings = $value;
+ }
+ return $this->{$name} = $value;
+ }
+
+/**
+ * Sets the request objects and configures a number of controller properties
+ * based on the contents of the request. The properties that get set are
+ *
+ * - $this->request - To the $request parameter
+ * - $this->plugin - To the $request->params['plugin']
+ * - $this->view - To the $request->params['action']
+ * - $this->autoLayout - To the false if $request->params['bare']; is set.
+ * - $this->autoRender - To false if $request->params['return'] == 1
+ * - $this->passedArgs - The the combined results of params['named'] and params['pass]
+ *
+ * @param CakeRequest $request
+ * @return void
+ */
+ public function setRequest(CakeRequest $request) {
+ $this->request = $request;
+ $this->plugin = isset($request->params['plugin']) ? Inflector::camelize($request->params['plugin']) : null;
+ $this->view = isset($request->params['action']) ? $request->params['action'] : null;
+ if (isset($request->params['pass']) && isset($request->params['named'])) {
+ $this->passedArgs = array_merge($request->params['pass'], $request->params['named']);
+ }
+
+ if (array_key_exists('return', $request->params) && $request->params['return'] == 1) {
+ $this->autoRender = false;
+ }
+ if (!empty($request->params['bare'])) {
+ $this->autoLayout = false;
+ }
+ }
+
+/**
+ * Dispatches the controller action. Checks that the action
+ * exists and isn't private.
+ *
+ * @param CakeRequest $request
+ * @return mixed The resulting response.
+ * @throws PrivateActionException When actions are not public or prefixed by _
+ * @throws MissingActionException When actions are not defined and scaffolding is
+ * not enabled.
+ */
+ public function invokeAction(CakeRequest $request) {
+ try {
+ $method = new ReflectionMethod($this, $request->params['action']);
+
+ if ($this->_isPrivateAction($method, $request)) {
+ throw new PrivateActionException(array(
+ 'controller' => $this->name . "Controller",
+ 'action' => $request->params['action']
+ ));
+ }
+ return $method->invokeArgs($this, $request->params['pass']);
+
+ } catch (ReflectionException $e) {
+ if ($this->scaffold !== false) {
+ return $this->_getScaffold($request);
+ }
+ throw new MissingActionException(array(
+ 'controller' => $this->name . "Controller",
+ 'action' => $request->params['action']
+ ));
+ }
+ }
+
+/**
+ * Check if the request's action is marked as private, with an underscore,
+ * or if the request is attempting to directly accessing a prefixed action.
+ *
+ * @param ReflectionMethod $method The method to be invoked.
+ * @param CakeRequest $request The request to check.
+ * @return boolean
+ */
+ protected function _isPrivateAction(ReflectionMethod $method, CakeRequest $request) {
+ $privateAction = (
+ $method->name[0] === '_' ||
+ !$method->isPublic() ||
+ !in_array($method->name, $this->methods)
+ );
+ $prefixes = Router::prefixes();
+
+ if (!$privateAction && !empty($prefixes)) {
+ if (empty($request->params['prefix']) && strpos($request->params['action'], '_') > 0) {
+ list($prefix) = explode('_', $request->params['action']);
+ $privateAction = in_array($prefix, $prefixes);
+ }
+ }
+ return $privateAction;
+ }
+
+/**
+ * Returns a scaffold object to use for dynamically scaffolded controllers.
+ *
+ * @param CakeRequest $request
+ * @return Scaffold
+ */
+ protected function _getScaffold(CakeRequest $request) {
+ return new Scaffold($this, $request);
+ }
+
+/**
+ * Merge components, helpers, and uses vars from
+ * Controller::$_mergeParent and PluginAppController.
+ *
+ * @return void
+ */
+ protected function _mergeControllerVars() {
+ $pluginController = $pluginDot = null;
+ $mergeParent = is_subclass_of($this, $this->_mergeParent);
+ $pluginVars = array();
+ $appVars = array();
+
+ if (!empty($this->plugin)) {
+ $pluginController = $this->plugin . 'AppController';
+ if (!is_subclass_of($this, $pluginController)) {
+ $pluginController = null;
+ }
+ $pluginDot = $this->plugin . '.';
+ }
+
+ if ($pluginController) {
+ $merge = array('components', 'helpers');
+ $this->_mergeVars($merge, $pluginController);
+ }
+
+ if ($mergeParent || !empty($pluginController)) {
+ $appVars = get_class_vars($this->_mergeParent);
+ $uses = $appVars['uses'];
+ $merge = array('components', 'helpers');
+ $this->_mergeVars($merge, $this->_mergeParent, true);
+ }
+
+ if ($this->uses === null) {
+ $this->uses = false;
+ }
+ if ($this->uses === true) {
+ $this->uses = array($pluginDot . $this->modelClass);
+ }
+ if (isset($appVars['uses']) && $appVars['uses'] === $this->uses) {
+ array_unshift($this->uses, $pluginDot . $this->modelClass);
+ }
+ if ($pluginController) {
+ $pluginVars = get_class_vars($pluginController);
+ }
+ if ($this->uses !== false) {
+ $this->_mergeUses($pluginVars);
+ $this->_mergeUses($appVars);
+ } else {
+ $this->uses = array();
+ $this->modelClass = '';
+ }
+ }
+
+/**
+ * Helper method for merging the $uses property together.
+ *
+ * Merges the elements not already in $this->uses into
+ * $this->uses.
+ *
+ * @param array $merge The data to merge in.
+ * @return void
+ */
+ protected function _mergeUses($merge) {
+ if (!isset($merge['uses'])) {
+ return;
+ }
+ if ($merge['uses'] === true) {
+ return;
+ }
+ $this->uses = array_merge(
+ $this->uses,
+ array_diff($merge['uses'], $this->uses)
+ );
+ }
+
+/**
+ * Returns a list of all events that will fire in the controller during it's lifecycle.
+ * You can override this function to add you own listener callbacks
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'Controller.initialize' => 'beforeFilter',
+ 'Controller.beforeRender' => 'beforeRender',
+ 'Controller.beforeRedirect' => array('callable' => 'beforeRedirect', 'passParams' => true),
+ 'Controller.shutdown' => 'afterFilter'
+ );
+ }
+
+/**
+ * Loads Model classes based on the uses property
+ * see Controller::loadModel(); for more info.
+ * Loads Components and prepares them for initialization.
+ *
+ * @return mixed true if models found and instance created.
+ * @see Controller::loadModel()
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::constructClasses
+ * @throws MissingModelException
+ */
+ public function constructClasses() {
+ $this->_mergeControllerVars();
+ $this->Components->init($this);
+ if ($this->uses) {
+ $this->uses = (array)$this->uses;
+ list(, $this->modelClass) = pluginSplit(current($this->uses));
+ }
+ return true;
+ }
+
+/**
+ * Returns the CakeEventManager manager instance that is handling any callbacks.
+ * You can use this instance to register any new listeners or callbacks to the
+ * controller events, or create your own events and trigger them at will.
+ *
+ * @return CakeEventManager
+ */
+ public function getEventManager() {
+ if (empty($this->_eventManager)) {
+ $this->_eventManager = new CakeEventManager();
+ $this->_eventManager->attach($this->Components);
+ $this->_eventManager->attach($this);
+ }
+ return $this->_eventManager;
+ }
+
+/**
+ * Perform the startup process for this controller.
+ * Fire the Components and Controller callbacks in the correct order.
+ *
+ * - Initializes components, which fires their `initialize` callback
+ * - Calls the controller `beforeFilter`.
+ * - triggers Component `startup` methods.
+ *
+ * @return void
+ */
+ public function startupProcess() {
+ $this->getEventManager()->dispatch(new CakeEvent('Controller.initialize', $this));
+ $this->getEventManager()->dispatch(new CakeEvent('Controller.startup', $this));
+ }
+
+/**
+ * Perform the various shutdown processes for this controller.
+ * Fire the Components and Controller callbacks in the correct order.
+ *
+ * - triggers the component `shutdown` callback.
+ * - calls the Controller's `afterFilter` method.
+ *
+ * @return void
+ */
+ public function shutdownProcess() {
+ $this->getEventManager()->dispatch(new CakeEvent('Controller.shutdown', $this));
+ }
+
+/**
+ * Queries & sets valid HTTP response codes & messages.
+ *
+ * @param integer|array $code If $code is an integer, then the corresponding code/message is
+ * returned if it exists, null if it does not exist. If $code is an array,
+ * then the 'code' and 'message' keys of each nested array are added to the default
+ * HTTP codes. Example:
+ *
+ * httpCodes(404); // returns array(404 => 'Not Found')
+ *
+ * httpCodes(array(
+ * 701 => 'Unicorn Moved',
+ * 800 => 'Unexpected Minotaur'
+ * )); // sets these new values, and returns true
+ *
+ * @return array Associative array of the HTTP codes as keys, and the message
+ * strings as values, or null of the given $code does not exist.
+ * @deprecated Use CakeResponse::httpCodes();
+ */
+ public function httpCodes($code = null) {
+ return $this->response->httpCodes($code);
+ }
+
+/**
+ * Loads and instantiates models required by this controller.
+ * If the model is non existent, it will throw a missing database table error, as Cake generates
+ * dynamic models for the time being.
+ *
+ * @param string $modelClass Name of model class to load
+ * @param integer|string $id Initial ID the instanced model class should have
+ * @return mixed true when single model found and instance created, error returned if model not found.
+ * @throws MissingModelException if the model class cannot be found.
+ */
+ public function loadModel($modelClass = null, $id = null) {
+ if ($modelClass === null) {
+ $modelClass = $this->modelClass;
+ }
+
+ $this->uses = ($this->uses) ? (array)$this->uses : array();
+ if (!in_array($modelClass, $this->uses)) {
+ $this->uses[] = $modelClass;
+ }
+
+ list($plugin, $modelClass) = pluginSplit($modelClass, true);
+
+ $this->{$modelClass} = ClassRegistry::init(array(
+ 'class' => $plugin . $modelClass, 'alias' => $modelClass, 'id' => $id
+ ));
+ if (!$this->{$modelClass}) {
+ throw new MissingModelException($modelClass);
+ }
+ return true;
+ }
+
+/**
+ * Redirects to given $url, after turning off $this->autoRender.
+ * Script execution is halted after the redirect.
+ *
+ * @param string|array $url A string or array-based URL pointing to another location within the app,
+ * or an absolute URL
+ * @param integer $status Optional HTTP status code (eg: 404)
+ * @param boolean $exit If true, exit() will be called after the redirect
+ * @return mixed void if $exit = false. Terminates script if $exit = true
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::redirect
+ */
+ public function redirect($url, $status = null, $exit = true) {
+ $this->autoRender = false;
+
+ if (is_array($status)) {
+ extract($status, EXTR_OVERWRITE);
+ }
+ $event = new CakeEvent('Controller.beforeRedirect', $this, array($url, $status, $exit));
+ //TODO: Remove the following line when the events are fully migrated to the CakeEventManager
+ list($event->break, $event->breakOn, $event->collectReturn) = array(true, false, true);
+ $this->getEventManager()->dispatch($event);
+
+ if ($event->isStopped()) {
+ return;
+ }
+ $response = $event->result;
+ extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
+
+ if ($url !== null) {
+ $this->response->header('Location', Router::url($url, true));
+ }
+
+ if (is_string($status)) {
+ $codes = array_flip($this->response->httpCodes());
+ if (isset($codes[$status])) {
+ $status = $codes[$status];
+ }
+ }
+
+ if ($status) {
+ $this->response->statusCode($status);
+ }
+
+ if ($exit) {
+ $this->response->send();
+ $this->_stop();
+ }
+ }
+
+/**
+ * Parse beforeRedirect Response
+ *
+ * @param mixed $response Response from beforeRedirect callback
+ * @param string|array $url The same value of beforeRedirect
+ * @param integer $status The same value of beforeRedirect
+ * @param boolean $exit The same value of beforeRedirect
+ * @return array Array with keys url, status and exit
+ */
+ protected function _parseBeforeRedirect($response, $url, $status, $exit) {
+ if (is_array($response) && isset($response[0])) {
+ foreach ($response as $resp) {
+ if (is_array($resp) && isset($resp['url'])) {
+ extract($resp, EXTR_OVERWRITE);
+ } elseif ($resp !== null) {
+ $url = $resp;
+ }
+ }
+ } elseif (is_array($response)) {
+ extract($response, EXTR_OVERWRITE);
+ }
+ return compact('url', 'status', 'exit');
+ }
+
+/**
+ * Convenience and object wrapper method for CakeResponse::header().
+ *
+ * @param string $status The header message that is being set.
+ * @return void
+ * @deprecated Use CakeResponse::header()
+ */
+ public function header($status) {
+ $this->response->header($status);
+ }
+
+/**
+ * Saves a variable for use inside a view template.
+ *
+ * @param string|array $one A string or an array of data.
+ * @param string|array $two Value in case $one is a string (which then works as the key).
+ * Unused if $one is an associative array, otherwise serves as the values to $one's keys.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#interacting-with-views
+ */
+ public function set($one, $two = null) {
+ if (is_array($one)) {
+ if (is_array($two)) {
+ $data = array_combine($one, $two);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($one => $two);
+ }
+ $this->viewVars = $data + $this->viewVars;
+ }
+
+/**
+ * Internally redirects one action to another. Does not perform another HTTP request unlike Controller::redirect()
+ *
+ * Examples:
+ *
+ * {{{
+ * setAction('another_action');
+ * setAction('action_with_parameters', $parameter1);
+ * }}}
+ *
+ * @param string $action The new action to be 'redirected' to
+ * @param mixed Any other parameters passed to this method will be passed as
+ * parameters to the new action.
+ * @return mixed Returns the return value of the called action
+ */
+ public function setAction($action) {
+ $this->request->params['action'] = $action;
+ $this->view = $action;
+ $args = func_get_args();
+ unset($args[0]);
+ return call_user_func_array(array(&$this, $action), $args);
+ }
+
+/**
+ * Returns number of errors in a submitted FORM.
+ *
+ * @return integer Number of errors
+ */
+ public function validate() {
+ $args = func_get_args();
+ $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
+
+ if ($errors === false) {
+ return 0;
+ }
+ return count($errors);
+ }
+
+/**
+ * Validates models passed by parameters. Example:
+ *
+ * `$errors = $this->validateErrors($this->Article, $this->User);`
+ *
+ * @param mixed A list of models as a variable argument
+ * @return array Validation errors, or false if none
+ */
+ public function validateErrors() {
+ $objects = func_get_args();
+
+ if (empty($objects)) {
+ return false;
+ }
+
+ $errors = array();
+ foreach ($objects as $object) {
+ if (isset($this->{$object->alias})) {
+ $object = $this->{$object->alias};
+ }
+ $object->set($object->data);
+ $errors = array_merge($errors, $object->invalidFields());
+ }
+
+ return $this->validationErrors = (!empty($errors) ? $errors : false);
+ }
+
+/**
+ * Instantiates the correct view class, hands it its data, and uses it to render the view output.
+ *
+ * @param string $view View to use for rendering
+ * @param string $layout Layout to use
+ * @return CakeResponse A response object containing the rendered view.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::render
+ */
+ public function render($view = null, $layout = null) {
+ $event = new CakeEvent('Controller.beforeRender', $this);
+ $this->getEventManager()->dispatch($event);
+ if ($event->isStopped()) {
+ $this->autoRender = false;
+ return $this->response;
+ }
+
+ if (!empty($this->uses) && is_array($this->uses)) {
+ foreach ($this->uses as $model) {
+ list($plugin, $className) = pluginSplit($model);
+ $this->request->params['models'][$className] = compact('plugin', 'className');
+ }
+ }
+
+ $viewClass = $this->viewClass;
+ if ($this->viewClass != 'View') {
+ list($plugin, $viewClass) = pluginSplit($viewClass, true);
+ $viewClass = $viewClass . 'View';
+ App::uses($viewClass, $plugin . 'View');
+ }
+
+ $View = new $viewClass($this);
+
+ $models = ClassRegistry::keys();
+ foreach ($models as $currentModel) {
+ $currentObject = ClassRegistry::getObject($currentModel);
+ if (is_a($currentObject, 'Model')) {
+ $className = get_class($currentObject);
+ list($plugin) = pluginSplit(App::location($className));
+ $this->request->params['models'][$currentObject->alias] = compact('plugin', 'className');
+ $View->validationErrors[$currentObject->alias] =& $currentObject->validationErrors;
+ }
+ }
+
+ $this->autoRender = false;
+ $this->View = $View;
+ $this->response->body($View->render($view, $layout));
+ return $this->response;
+ }
+
+/**
+ * Returns the referring URL for this request.
+ *
+ * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers
+ * @param boolean $local If true, restrict referring URLs to local server
+ * @return string Referring URL
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::referer
+ */
+ public function referer($default = null, $local = false) {
+ if ($this->request) {
+ $referer = $this->request->referer($local);
+ if ($referer == '/' && $default != null) {
+ return Router::url($default, true);
+ }
+ return $referer;
+ }
+ return '/';
+ }
+
+/**
+ * Forces the user's browser not to cache the results of the current request.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::disableCache
+ * @deprecated Use CakeResponse::disableCache()
+ */
+ public function disableCache() {
+ $this->response->disableCache();
+ }
+
+/**
+ * Shows a message to the user for $pause seconds, then redirects to $url.
+ * Uses flash.ctp as the default layout for the message.
+ * Does not work if the current debug level is higher than 0.
+ *
+ * @param string $message Message to display to the user
+ * @param string|array $url Relative string or array-based URL to redirect to after the time expires
+ * @param integer $pause Time to show the message
+ * @param string $layout Layout you want to use, defaults to 'flash'
+ * @return void Renders flash layout
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::flash
+ */
+ public function flash($message, $url, $pause = 1, $layout = 'flash') {
+ $this->autoRender = false;
+ $this->set('url', Router::url($url));
+ $this->set('message', $message);
+ $this->set('pause', $pause);
+ $this->set('page_title', $message);
+ $this->render(false, $layout);
+ }
+
+/**
+ * Converts POST'ed form data to a model conditions array, suitable for use in a Model::find() call.
+ *
+ * @param array $data POST'ed data organized by model and field
+ * @param string|array $op A string containing an SQL comparison operator, or an array matching operators
+ * to fields
+ * @param string $bool SQL boolean operator: AND, OR, XOR, etc.
+ * @param boolean $exclusive If true, and $op is an array, fields not included in $op will not be
+ * included in the returned conditions
+ * @return array An array of model conditions
+ * @deprecated
+ */
+ public function postConditions($data = array(), $op = null, $bool = 'AND', $exclusive = false) {
+ if (!is_array($data) || empty($data)) {
+ if (!empty($this->request->data)) {
+ $data = $this->request->data;
+ } else {
+ return null;
+ }
+ }
+ $cond = array();
+
+ if ($op === null) {
+ $op = '';
+ }
+
+ $arrayOp = is_array($op);
+ foreach ($data as $model => $fields) {
+ foreach ($fields as $field => $value) {
+ $key = $model . '.' . $field;
+ $fieldOp = $op;
+ if ($arrayOp) {
+ if (array_key_exists($key, $op)) {
+ $fieldOp = $op[$key];
+ } elseif (array_key_exists($field, $op)) {
+ $fieldOp = $op[$field];
+ } else {
+ $fieldOp = false;
+ }
+ }
+ if ($exclusive && $fieldOp === false) {
+ continue;
+ }
+ $fieldOp = strtoupper(trim($fieldOp));
+ if ($fieldOp === 'LIKE') {
+ $key = $key . ' LIKE';
+ $value = '%' . $value . '%';
+ } elseif ($fieldOp && $fieldOp != '=') {
+ $key = $key . ' ' . $fieldOp;
+ }
+ $cond[$key] = $value;
+ }
+ }
+ if ($bool != null && strtoupper($bool) != 'AND') {
+ $cond = array($bool => $cond);
+ }
+ return $cond;
+ }
+
+/**
+ * Handles automatic pagination of model records.
+ *
+ * @param Model|string $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
+ * @param string|array $scope Conditions to use while paginating
+ * @param array $whitelist List of allowed options for paging
+ * @return array Model query results
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::paginate
+ * @deprecated Use PaginatorComponent instead
+ */
+ public function paginate($object = null, $scope = array(), $whitelist = array()) {
+ return $this->Components->load('Paginator', $this->paginate)->paginate($object, $scope, $whitelist);
+ }
+
+/**
+ * Called before the controller action. You can use this method to configure and customize components
+ * or perform logic that needs to happen before each controller action.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function beforeFilter() {
+ }
+
+/**
+ * Called after the controller action is run, but before the view is rendered. You can use this method
+ * to perform logic or set view variables that are required on every request.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function beforeRender() {
+ }
+
+/**
+ * The beforeRedirect method is invoked when the controller's redirect method is called but before any
+ * further action. If this method returns false the controller will not continue on to redirect the request.
+ * The $url, $status and $exit variables have same meaning as for the controller's method. You can also
+ * return a string which will be interpreted as the url to redirect to or return associative array with
+ * key 'url' and optionally 'status' and 'exit'.
+ *
+ * @param string|array $url A string or array-based URL pointing to another location within the app,
+ * or an absolute URL
+ * @param integer $status Optional HTTP status code (eg: 404)
+ * @param boolean $exit If true, exit() will be called after the redirect
+ * @return mixed
+ * false to stop redirection event,
+ * string controllers a new redirection url or
+ * array with the keys url, status and exit to be used by the redirect method.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function beforeRedirect($url, $status = null, $exit = true) {
+ }
+
+/**
+ * Called after the controller action is run and rendered.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function afterFilter() {
+ }
+
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called example index, edit, etc.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function beforeScaffold($method) {
+ return true;
+ }
+
+/**
+ * Alias to beforeScaffold()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::beforeScaffold()
+ * @deprecated
+ */
+ protected function _beforeScaffold($method) {
+ return $this->beforeScaffold($method);
+ }
+
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called either edit or update.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function afterScaffoldSave($method) {
+ return true;
+ }
+
+/**
+ * Alias to afterScaffoldSave()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::afterScaffoldSave()
+ * @deprecated
+ */
+ protected function _afterScaffoldSave($method) {
+ return $this->afterScaffoldSave($method);
+ }
+
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called either edit or update.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function afterScaffoldSaveError($method) {
+ return true;
+ }
+
+/**
+ * Alias to afterScaffoldSaveError()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::afterScaffoldSaveError()
+ * @deprecated
+ */
+ protected function _afterScaffoldSaveError($method) {
+ return $this->afterScaffoldSaveError($method);
+ }
+
+/**
+ * This method should be overridden in child classes.
+ * If not it will render a scaffold error.
+ * Method MUST return true in child classes
+ *
+ * @param string $method name of method called example index, edit, etc.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function scaffoldError($method) {
+ return false;
+ }
+
+/**
+ * Alias to scaffoldError()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::scaffoldError()
+ * @deprecated
+ */
+ protected function _scaffoldError($method) {
+ return $this->scaffoldError($method);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php
new file mode 100644
index 0000000..8543126
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php
@@ -0,0 +1,447 @@
+<?php
+/**
+ * Scaffold.
+ *
+ * Automatic forms and actions generation for rapid web application development.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since Cake v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Scaffold', 'View');
+
+/**
+ * Scaffolding is a set of automatic actions for starting web development work faster.
+ *
+ * Scaffold inspects your database tables, and making educated guesses, sets up a
+ * number of pages for each of your Models. These pages have data forms that work,
+ * and afford the web developer an early look at the data, and the possibility to over-ride
+ * scaffolded actions with custom-made ones.
+ *
+ * @package Cake.Controller
+ */
+class Scaffold {
+
+/**
+ * Controller object
+ *
+ * @var Controller
+ */
+ public $controller = null;
+
+/**
+ * Name of the controller to scaffold
+ *
+ * @var string
+ */
+ public $name = null;
+
+/**
+ * Name of current model this view context is attached to
+ *
+ * @var string
+ */
+ public $model = null;
+
+/**
+ * Path to View.
+ *
+ * @var string
+ */
+ public $viewPath;
+
+/**
+ * Name of layout to use with this View.
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Valid session.
+ *
+ * @var boolean
+ */
+ protected $_validSession = null;
+
+/**
+ * List of variables to collect from the associated controller
+ *
+ * @var array
+ */
+ protected $_passedVars = array(
+ 'layout', 'name', 'viewPath', 'request'
+ );
+
+/**
+ * Title HTML element for current scaffolded view
+ *
+ * @var string
+ */
+ public $scaffoldTitle = null;
+
+/**
+ * Construct and set up given controller with given parameters.
+ *
+ * @param Controller $controller Controller to scaffold
+ * @param CakeRequest $request Request parameters.
+ * @throws MissingModelException
+ */
+ public function __construct(Controller $controller, CakeRequest $request) {
+ $this->controller = $controller;
+
+ $count = count($this->_passedVars);
+ for ($j = 0; $j < $count; $j++) {
+ $var = $this->_passedVars[$j];
+ $this->{$var} = $controller->{$var};
+ }
+
+ $this->redirect = array('action' => 'index');
+
+ $this->modelClass = $controller->modelClass;
+ $this->modelKey = $controller->modelKey;
+
+ if (!is_object($this->controller->{$this->modelClass})) {
+ throw new MissingModelException($this->modelClass);
+ }
+
+ $this->ScaffoldModel = $this->controller->{$this->modelClass};
+ $this->scaffoldTitle = Inflector::humanize(Inflector::underscore($this->viewPath));
+ $this->scaffoldActions = $controller->scaffold;
+ $title = __d('cake', 'Scaffold :: ') . Inflector::humanize($request->action) . ' :: ' . $this->scaffoldTitle;
+ $modelClass = $this->controller->modelClass;
+ $primaryKey = $this->ScaffoldModel->primaryKey;
+ $displayField = $this->ScaffoldModel->displayField;
+ $singularVar = Inflector::variable($modelClass);
+ $pluralVar = Inflector::variable($this->controller->name);
+ $singularHumanName = Inflector::humanize(Inflector::underscore($modelClass));
+ $pluralHumanName = Inflector::humanize(Inflector::underscore($this->controller->name));
+ $scaffoldFields = array_keys($this->ScaffoldModel->schema());
+ $associations = $this->_associations();
+
+ $this->controller->set(compact(
+ 'title_for_layout', 'modelClass', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
+ 'singularHumanName', 'pluralHumanName', 'scaffoldFields', 'associations'
+ ));
+ $this->controller->set('title_for_layout', $title);
+
+ if ($this->controller->viewClass) {
+ $this->controller->viewClass = 'Scaffold';
+ }
+ $this->_validSession = (
+ isset($this->controller->Session) && $this->controller->Session->valid() != false
+ );
+ $this->_scaffold($request);
+ }
+
+/**
+ * Renders a view action of scaffolded model.
+ *
+ * @param CakeRequest $request Request Object for scaffolding
+ * @return mixed A rendered view of a row from Models database table
+ * @throws NotFoundException
+ */
+ protected function _scaffoldView(CakeRequest $request) {
+ if ($this->controller->beforeScaffold('view')) {
+ if (isset($request->params['pass'][0])) {
+ $this->ScaffoldModel->id = $request->params['pass'][0];
+ }
+ if (!$this->ScaffoldModel->exists()) {
+ throw new NotFoundException(__d('cake', 'Invalid %s', Inflector::humanize($this->modelKey)));
+ }
+ $this->ScaffoldModel->recursive = 1;
+ $this->controller->request->data = $this->ScaffoldModel->read();
+ $this->controller->set(
+ Inflector::variable($this->controller->modelClass), $this->request->data
+ );
+ $this->controller->render($this->request['action'], $this->layout);
+ } elseif ($this->controller->scaffoldError('view') === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Renders index action of scaffolded model.
+ *
+ * @param array $params Parameters for scaffolding
+ * @return mixed A rendered view listing rows from Models database table
+ */
+ protected function _scaffoldIndex($params) {
+ if ($this->controller->beforeScaffold('index')) {
+ $this->ScaffoldModel->recursive = 0;
+ $this->controller->set(
+ Inflector::variable($this->controller->name), $this->controller->paginate()
+ );
+ $this->controller->render($this->request['action'], $this->layout);
+ } elseif ($this->controller->scaffoldError('index') === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Renders an add or edit action for scaffolded model.
+ *
+ * @param string $action Action (add or edit)
+ * @return mixed A rendered view with a form to edit or add a record in the Models database table
+ */
+ protected function _scaffoldForm($action = 'edit') {
+ $this->controller->viewVars['scaffoldFields'] = array_merge(
+ $this->controller->viewVars['scaffoldFields'],
+ array_keys($this->ScaffoldModel->hasAndBelongsToMany)
+ );
+ $this->controller->render($action, $this->layout);
+ }
+
+/**
+ * Saves or updates the scaffolded model.
+ *
+ * @param CakeRequest $request Request Object for scaffolding
+ * @param string $action add or edit
+ * @return mixed Success on save/update, add/edit form if data is empty or error if save or update fails
+ * @throws NotFoundException
+ */
+ protected function _scaffoldSave(CakeRequest $request, $action = 'edit') {
+ $formAction = 'edit';
+ $success = __d('cake', 'updated');
+ if ($action === 'add') {
+ $formAction = 'add';
+ $success = __d('cake', 'saved');
+ }
+
+ if ($this->controller->beforeScaffold($action)) {
+ if ($action == 'edit') {
+ if (isset($request->params['pass'][0])) {
+ $this->ScaffoldModel->id = $request['pass'][0];
+ }
+ if (!$this->ScaffoldModel->exists()) {
+ throw new NotFoundException(__d('cake', 'Invalid %s', Inflector::humanize($this->modelKey)));
+ }
+ }
+
+ if (!empty($request->data)) {
+ if ($action == 'create') {
+ $this->ScaffoldModel->create();
+ }
+
+ if ($this->ScaffoldModel->save($request->data)) {
+ if ($this->controller->afterScaffoldSave($action)) {
+ $message = __d('cake',
+ 'The %1$s has been %2$s',
+ Inflector::humanize($this->modelKey),
+ $success
+ );
+ return $this->_sendMessage($message);
+ } else {
+ return $this->controller->afterScaffoldSaveError($action);
+ }
+ } else {
+ if ($this->_validSession) {
+ $this->controller->Session->setFlash(__d('cake', 'Please correct errors below.'));
+ }
+ }
+ }
+
+ if (empty($request->data)) {
+ if ($this->ScaffoldModel->id) {
+ $this->controller->data = $request->data = $this->ScaffoldModel->read();
+ } else {
+ $this->controller->data = $request->data = $this->ScaffoldModel->create();
+ }
+ }
+
+ foreach ($this->ScaffoldModel->belongsTo as $assocName => $assocData) {
+ $varName = Inflector::variable(Inflector::pluralize(
+ preg_replace('/(?:_id)$/', '', $assocData['foreignKey'])
+ ));
+ $this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
+ }
+ foreach ($this->ScaffoldModel->hasAndBelongsToMany as $assocName => $assocData) {
+ $varName = Inflector::variable(Inflector::pluralize($assocName));
+ $this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
+ }
+
+ return $this->_scaffoldForm($formAction);
+ } elseif ($this->controller->scaffoldError($action) === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Performs a delete on given scaffolded Model.
+ *
+ * @param CakeRequest $request Request for scaffolding
+ * @return mixed Success on delete, error if delete fails
+ * @throws MethodNotAllowedException When HTTP method is not a DELETE
+ * @throws NotFoundException When id being deleted does not exist.
+ */
+ protected function _scaffoldDelete(CakeRequest $request) {
+ if ($this->controller->beforeScaffold('delete')) {
+ if (!$request->is('post')) {
+ throw new MethodNotAllowedException();
+ }
+ $id = false;
+ if (isset($request->params['pass'][0])) {
+ $id = $request->params['pass'][0];
+ }
+ $this->ScaffoldModel->id = $id;
+ if (!$this->ScaffoldModel->exists()) {
+ throw new NotFoundException(__d('cake', 'Invalid %s', Inflector::humanize($this->modelClass)));
+ }
+ if ($this->ScaffoldModel->delete()) {
+ $message = __d('cake', 'The %1$s with id: %2$s has been deleted.', Inflector::humanize($this->modelClass), $id);
+ return $this->_sendMessage($message);
+ } else {
+ $message = __d('cake',
+ 'There was an error deleting the %1$s with id: %2$s',
+ Inflector::humanize($this->modelClass),
+ $id
+ );
+ return $this->_sendMessage($message);
+ }
+ } elseif ($this->controller->scaffoldError('delete') === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Sends a message to the user. Either uses Sessions or flash messages depending
+ * on the availability of a session
+ *
+ * @param string $message Message to display
+ * @return void
+ */
+ protected function _sendMessage($message) {
+ if ($this->_validSession) {
+ $this->controller->Session->setFlash($message);
+ $this->controller->redirect($this->redirect);
+ } else {
+ $this->controller->flash($message, $this->redirect);
+ }
+ }
+
+/**
+ * Show a scaffold error
+ *
+ * @return mixed A rendered view showing the error
+ */
+ protected function _scaffoldError() {
+ return $this->controller->render('error', $this->layout);
+ }
+
+/**
+ * When methods are now present in a controller
+ * scaffoldView is used to call default Scaffold methods if:
+ * `public $scaffold;` is placed in the controller's class definition.
+ *
+ * @param CakeRequest $request Request object for scaffolding
+ * @return mixed A rendered view of scaffold action, or showing the error
+ * @throws MissingActionException When methods are not scaffolded.
+ * @throws MissingDatabaseException When the database connection is undefined.
+ */
+ protected function _scaffold(CakeRequest $request) {
+ $db = ConnectionManager::getDataSource($this->ScaffoldModel->useDbConfig);
+ $prefixes = Configure::read('Routing.prefixes');
+ $scaffoldPrefix = $this->scaffoldActions;
+
+ if (isset($db)) {
+ if (empty($this->scaffoldActions)) {
+ $this->scaffoldActions = array(
+ 'index', 'list', 'view', 'add', 'create', 'edit', 'update', 'delete'
+ );
+ } elseif (!empty($prefixes) && in_array($scaffoldPrefix, $prefixes)) {
+ $this->scaffoldActions = array(
+ $scaffoldPrefix . '_index',
+ $scaffoldPrefix . '_list',
+ $scaffoldPrefix . '_view',
+ $scaffoldPrefix . '_add',
+ $scaffoldPrefix . '_create',
+ $scaffoldPrefix . '_edit',
+ $scaffoldPrefix . '_update',
+ $scaffoldPrefix . '_delete'
+ );
+ }
+
+ if (in_array($request->params['action'], $this->scaffoldActions)) {
+ if (!empty($prefixes)) {
+ $request->params['action'] = str_replace($scaffoldPrefix . '_', '', $request->params['action']);
+ }
+ switch ($request->params['action']) {
+ case 'index':
+ case 'list':
+ $this->_scaffoldIndex($request);
+ break;
+ case 'view':
+ $this->_scaffoldView($request);
+ break;
+ case 'add':
+ case 'create':
+ $this->_scaffoldSave($request, 'add');
+ break;
+ case 'edit':
+ case 'update':
+ $this->_scaffoldSave($request, 'edit');
+ break;
+ case 'delete':
+ $this->_scaffoldDelete($request);
+ break;
+ }
+ } else {
+ throw new MissingActionException(array(
+ 'controller' => $this->controller->name,
+ 'action' => $request->action
+ ));
+ }
+ } else {
+ throw new MissingDatabaseException(array('connection' => $this->ScaffoldModel->useDbConfig));
+ }
+ }
+
+/**
+ * Returns associations for controllers models.
+ *
+ * @return array Associations for model
+ */
+ protected function _associations() {
+ $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+ $associations = array();
+
+ foreach ($keys as $key => $type) {
+ foreach ($this->ScaffoldModel->{$type} as $assocKey => $assocData) {
+ $associations[$type][$assocKey]['primaryKey'] =
+ $this->ScaffoldModel->{$assocKey}->primaryKey;
+
+ $associations[$type][$assocKey]['displayField'] =
+ $this->ScaffoldModel->{$assocKey}->displayField;
+
+ $associations[$type][$assocKey]['foreignKey'] =
+ $assocData['foreignKey'];
+
+ $associations[$type][$assocKey]['controller'] =
+ Inflector::pluralize(Inflector::underscore($assocData['className']));
+
+ if ($type == 'hasAndBelongsToMany') {
+ $associations[$type][$assocKey]['with'] = $assocData['with'];
+ }
+ }
+ }
+ return $associations;
+ }
+
+}