summaryrefslogtreecommitdiff
path: root/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2012-08-02 11:09:40 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2012-08-02 11:09:40 +0000
commit6dfd5d507d9863f987b30b0a5ab4268aea2ed875 (patch)
tree9c3de66b4aaa1e6bfa3c6442d807ec70bc479d11 /poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View
parentf4792ba1a7785220fef5adb1cb3e7ce8ac40152f (diff)
download2012-php-weave-6dfd5d507d9863f987b30b0a5ab4268aea2ed875.tar.gz
2012-php-weave-6dfd5d507d9863f987b30b0a5ab4268aea2ed875.tar.bz2
2012-php-weave-6dfd5d507d9863f987b30b0a5ab4268aea2ed875.zip
J'étais parti sur un download pourri de Cake. Les gars on abusé sur GitHub.
git-svn-id: file:///var/svn/2012-php-weave/trunk@7 d972a294-176a-4cf9-8ea1-fcd5b0c30f5c
Diffstat (limited to 'poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View')
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp75
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp74
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp45
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp38
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php914
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php321
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php2604
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php1214
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php361
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php592
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php434
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php376
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php149
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php901
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php370
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php345
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php163
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php277
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php458
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php203
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php108
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php238
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php91
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp94
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp146
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php1129
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php158
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php113
45 files changed, 12598 insertions, 0 deletions
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp
new file mode 100644
index 0000000..b744c16
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Prints a stack trace for an exception
+ *
+ * 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.View.Elements
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Debugger', 'Utility');
+?>
+<h3>Stack Trace</h3>
+<ul class="cake-stack-trace">
+<?php foreach ($error->getTrace() as $i => $stack): ?>
+ <li><?php
+ $excerpt = $arguments = '';
+ $params = array();
+
+ if (isset($stack['file']) && isset($stack['line'])):
+ printf(
+ '<a href="#" onclick="traceToggle(event, \'file-excerpt-%s\')">%s line %s</a>',
+ $i,
+ Debugger::trimPath($stack['file']),
+ $stack['line']
+ );
+ $excerpt = sprintf('<div id="file-excerpt-%s" class="cake-code-dump" style="display:none;"><pre>', $i);
+ $excerpt .= implode("\n", Debugger::excerpt($stack['file'], $stack['line'] - 1, 2));
+ $excerpt .= '</pre></div> ';
+ else:
+ echo '<a href="#">[internal function]</a>';
+ endif;
+ echo ' &rarr; ';
+ if ($stack['function']):
+ $args = array();
+ if (!empty($stack['args'])):
+ foreach ((array)$stack['args'] as $arg):
+ $args[] = Debugger::getType($arg);
+ $params[] = Debugger::exportVar($arg, 2);
+ endforeach;
+ endif;
+
+ $called = isset($stack['class']) ? $stack['class'] . $stack['type'] . $stack['function'] : $stack['function'];
+
+ printf(
+ '<a href="#" onclick="traceToggle(event, \'trace-args-%s\')">%s(%s)</a> ',
+ $i,
+ $called,
+ implode(', ', $args)
+ );
+ $arguments = sprintf('<div id="trace-args-%s" class="cake-code-dump" style="display: none;"><pre>', $i);
+ $arguments .= implode("\n", $params);
+ $arguments .= '</pre></div>';
+ endif;
+ echo $excerpt;
+ echo $arguments;
+ ?></li>
+<?php endforeach; ?>
+</ul>
+<script type="text/javascript">
+function traceToggle(event, id) {
+ var el = document.getElementById(id);
+ el.style.display = (el.style.display == 'block') ? 'none' : 'block';
+ event.preventDefault();
+ return false;
+}
+</script>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp
new file mode 100644
index 0000000..c8e634d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp
@@ -0,0 +1,74 @@
+<?php
+/**
+ * SQL Dump element. Dumps out SQL log information
+ *
+ * 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.View.Elements
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+if (!class_exists('ConnectionManager') || Configure::read('debug') < 2) {
+ return false;
+}
+$noLogs = !isset($logs);
+if ($noLogs):
+ $sources = ConnectionManager::sourceList();
+
+ $logs = array();
+ foreach ($sources as $source):
+ $db = ConnectionManager::getDataSource($source);
+ if (!method_exists($db, 'getLog')):
+ continue;
+ endif;
+ $logs[$source] = $db->getLog();
+ endforeach;
+endif;
+
+if ($noLogs || isset($_forced_from_dbo_)):
+ foreach ($logs as $source => $logInfo):
+ $text = $logInfo['count'] > 1 ? 'queries' : 'query';
+ printf(
+ '<table class="cake-sql-log" id="cakeSqlLog_%s" summary="Cake SQL Log" cellspacing="0">',
+ preg_replace('/[^A-Za-z0-9_]/', '_', uniqid(time(), true))
+ );
+ printf('<caption>(%s) %s %s took %s ms</caption>', $source, $logInfo['count'], $text, $logInfo['time']);
+ ?>
+ <thead>
+ <tr><th>Nr</th><th>Query</th><th>Error</th><th>Affected</th><th>Num. rows</th><th>Took (ms)</th></tr>
+ </thead>
+ <tbody>
+ <?php
+ foreach ($logInfo['log'] as $k => $i) :
+ $i += array('error' => '');
+ if (!empty($i['params']) && is_array($i['params'])) {
+ $bindParam = $bindType = null;
+ if (preg_match('/.+ :.+/', $i['query'])) {
+ $bindType = true;
+ }
+ foreach ($i['params'] as $bindKey => $bindVal) {
+ if ($bindType === true) {
+ $bindParam .= h($bindKey) ." => " . h($bindVal) . ", ";
+ } else {
+ $bindParam .= h($bindVal) . ", ";
+ }
+ }
+ $i['query'] .= " , params[ " . rtrim($bindParam, ', ') . " ]";
+ }
+ echo "<tr><td>" . ($k + 1) . "</td><td>" . h($i['query']) . "</td><td>{$i['error']}</td><td style = \"text-align: right\">{$i['affected']}</td><td style = \"text-align: right\">{$i['numRows']}</td><td style = \"text-align: right\">{$i['took']}</td></tr>\n";
+ endforeach;
+ ?>
+ </tbody></table>
+ <?php
+ endforeach;
+else:
+ echo '<p>Encountered unexpected $logs cannot generate SQL log</p>';
+endif;
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp
new file mode 100644
index 0000000..d7c6e76
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp
@@ -0,0 +1,35 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Fatal Error'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo h($error->getMessage()); ?>
+ <br>
+
+ <strong><?php echo __d('cake_dev', 'File'); ?>: </strong>
+ <?php echo h($error->getFile()); ?>
+ <br>
+
+ <strong><?php echo __d('cake_dev', 'Line'); ?>: </strong>
+ <?php echo h($error->getLine()); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'fatal_error.ctp'); ?>
+</p>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp
new file mode 100644
index 0000000..614933e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp
@@ -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
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Method in %s', $controller); ?></h2> <p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The action %1$s is not defined in controller %2$s', '<em>' . $action . '</em>', '<em>' . $controller . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create %1$s%2$s in file: %3$s.', '<em>' . $controller . '::</em>', '<em>' . $action . '()</em>', APP_DIR . DS . 'Controller' . DS . $controller . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $controller; ?> extends AppController {
+
+<strong>
+ public function <?php echo $action; ?>() {
+
+ }
+</strong>
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_action.ctp'); ?>
+</p>
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp
new file mode 100644
index 0000000..3bb8722
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp
@@ -0,0 +1,40 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Behavior'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'Model' . DS . 'Behavior' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class; ?> extends ModelBehavior {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_behavior.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp
new file mode 100644
index 0000000..d0e6d23
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp
@@ -0,0 +1,40 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Component'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR : CakePlugin::path($plugin)) . DS . 'Controller' . DS . 'Component' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class; ?> extends Component {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_component.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp
new file mode 100644
index 0000000..b29fb9f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp
@@ -0,0 +1,36 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Database Connection'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s requires a database connection', $class); ?>
+</p>
+<?php if (!$enabled) : ?>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s driver is NOT enabled', $class); ?>
+</p>
+<?php endif; ?>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s.', APP_DIR . DS . 'View' . DS . 'Errors' . DS . basename(__FILE__)); ?>
+</p>
+
+<?php
+echo $this->element('exception_stack_trace');
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp
new file mode 100644
index 0000000..b4acb8e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp
@@ -0,0 +1,40 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Controller'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'Controller' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class . ' extends ' . $plugin; ?>AppController {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_controller.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp
new file mode 100644
index 0000000..a8c892e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp
@@ -0,0 +1,33 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Database Connection'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Scaffold requires a database connection'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Confirm you have created the file: %s', APP_DIR . DS . 'Config' . DS . 'database.php'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_database.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp
new file mode 100644
index 0000000..d3df930
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp
@@ -0,0 +1,30 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Datasource'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Datasource class %s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_datasource.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp
new file mode 100644
index 0000000..3bc6ff7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp
@@ -0,0 +1,29 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Datasource Configuration'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The datasource configuration %1$s was not found in database.php.', '<em>' . $config . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_datasource_config.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp
new file mode 100644
index 0000000..62d7585
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp
@@ -0,0 +1,40 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Helper'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'View' . DS . 'Helper' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class; ?> extends AppHelper {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_helper.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp
new file mode 100644
index 0000000..f623b61
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp
@@ -0,0 +1,33 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Layout'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The layout file %s can not be found or does not exist.', '<em>' . $file . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Confirm you have created the file: %s', '<em>' . $file . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_layout.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp
new file mode 100644
index 0000000..9d3f7ce
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp
@@ -0,0 +1,45 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Plugin'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The application is trying to load a file from the %s plugin', '<em>' . $plugin . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Make sure your plugin %s is in the ' . APP_DIR . DS . 'Plugin directory and was loaded', $plugin); ?>
+</p>
+<pre>
+&lt;?php
+CakePlugin::load('<?php echo $plugin?>');
+
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Loading all plugins'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you wish to load all plugins at once, use the following line in your ' . APP_DIR . DS . 'Config' . DS . 'bootstrap.php file'); ?>
+</p>
+<pre>
+CakePlugin::loadAll();
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_plugin.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp
new file mode 100644
index 0000000..6e65871
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp
@@ -0,0 +1,29 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Database Table'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Table %1$s for model %2$s was not found in datasource %3$s.', '<em>' . $table . '</em>', '<em>' . $class . '</em>', '<em>' . $ds . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_table.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp
new file mode 100644
index 0000000..c3b5920
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp
@@ -0,0 +1,33 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing View'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The view for %1$s%2$s was not found.', '<em>' . Inflector::camelize($this->request->controller) . 'Controller::</em>', '<em>' . $this->request->action . '()</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Confirm you have created the file: %s', $file); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_view.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp
new file mode 100644
index 0000000..9aecee6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp
@@ -0,0 +1,38 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Database Error'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo h($error->getMessage()); ?>
+</p>
+<?php if (!empty($error->queryString)) : ?>
+ <p class="notice">
+ <strong><?php echo __d('cake_dev', 'SQL Query'); ?>: </strong>
+ <?php echo $error->queryString; ?>
+ </p>
+<?php endif; ?>
+<?php if (!empty($error->params)) : ?>
+ <strong><?php echo __d('cake_dev', 'SQL Query Params'); ?>: </strong>
+ <?php echo Debugger::dump($error->params); ?>
+<?php endif; ?>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'pdo_error.ctp'); ?>
+</p>
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp
new file mode 100644
index 0000000..74264a2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp
@@ -0,0 +1,29 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Private Method in %s', $controller); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s%s cannot be accessed directly.', '<em>' . $controller . '::</em>', '<em>' . $action . '()</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'private_action.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp
new file mode 100644
index 0000000..492c561
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp
@@ -0,0 +1,36 @@
+<?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.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Scaffold Error'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Method _scaffoldError in was not found in the controller'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'scaffold_error.ctp'); ?>
+</p>
+<pre>
+&lt;?php
+function _scaffoldError() {<br />
+
+}
+
+</pre>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php
new file mode 100644
index 0000000..f6b17ac
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php
@@ -0,0 +1,914 @@
+<?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.View
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Router', 'Routing');
+
+/**
+ * Abstract base class for all other Helpers in CakePHP.
+ * Provides common methods and features.
+ *
+ * @package Cake.View
+ */
+class Helper extends Object {
+
+/**
+ * List of helpers used by this helper
+ *
+ * @var array
+ */
+ public $helpers = array();
+
+/**
+ * A helper lookup table used to lazy load helper objects.
+ *
+ * @var array
+ */
+ protected $_helperMap = array();
+
+/**
+ * The current theme name if any.
+ *
+ * @var string
+ */
+ public $theme = null;
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request = null;
+
+/**
+ * Plugin path
+ *
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Holds the fields array('field_name' => array('type' => 'string', 'length' => 100),
+ * primaryKey and validates array('field_name')
+ *
+ * @var array
+ */
+ public $fieldset = array();
+
+/**
+ * Holds tag templates.
+ *
+ * @var array
+ */
+ public $tags = array();
+
+/**
+ * Holds the content to be cleaned.
+ *
+ * @var mixed
+ */
+ protected $_tainted = null;
+
+/**
+ * Holds the cleaned content.
+ *
+ * @var mixed
+ */
+ protected $_cleaned = null;
+
+/**
+ * The View instance this helper is attached to
+ *
+ * @var View
+ */
+ protected $_View;
+
+/**
+ * A list of strings that should be treated as suffixes, or
+ * sub inputs for a parent input. This is used for date/time
+ * inputs primarily.
+ *
+ * @var array
+ */
+ protected $_fieldSuffixes = array(
+ 'year', 'month', 'day', 'hour', 'min', 'second', 'meridian'
+ );
+
+/**
+ * The name of the current model entities are in scope of.
+ *
+ * @see Helper::setEntity()
+ * @var string
+ */
+ protected $_modelScope;
+
+/**
+ * The name of the current model association entities are in scope of.
+ *
+ * @see Helper::setEntity()
+ * @var string
+ */
+ protected $_association;
+
+/**
+ * The dot separated list of elements the current field entity is for.
+ *
+ * @see Helper::setEntity()
+ * @var string
+ */
+ protected $_entityPath;
+
+/**
+ * Minimized attributes
+ *
+ * @var array
+ */
+ protected $_minimizedAttributes = array(
+ 'compact', 'checked', 'declare', 'readonly', 'disabled', 'selected',
+ 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize',
+ 'autoplay', 'controls', 'loop', 'muted'
+ );
+
+/**
+ * Format to attribute
+ *
+ * @var string
+ */
+ protected $_attributeFormat = '%s="%s"';
+
+/**
+ * Format to attribute
+ *
+ * @var string
+ */
+ protected $_minimizedAttributeFormat = '%s="%s"';
+
+/**
+ * Default Constructor
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $this->_View = $View;
+ $this->request = $View->request;
+ if (!empty($this->helpers)) {
+ $this->_helperMap = ObjectCollection::normalizeObjectArray($this->helpers);
+ }
+ }
+
+/**
+ * Provide non fatal errors on missing method calls.
+ *
+ * @param string $method Method to invoke
+ * @param array $params Array of params for the method.
+ * @return void
+ */
+ public function __call($method, $params) {
+ trigger_error(__d('cake_dev', 'Method %1$s::%2$s does not exist', get_class($this), $method), E_USER_WARNING);
+ }
+
+/**
+ * Lazy loads helpers. Provides access to deprecated request properties as well.
+ *
+ * @param string $name Name of the property being accessed.
+ * @return mixed Helper or property found at $name
+ */
+ public function __get($name) {
+ if (isset($this->_helperMap[$name]) && !isset($this->{$name})) {
+ $settings = array_merge((array)$this->_helperMap[$name]['settings'], array('enabled' => false));
+ $this->{$name} = $this->_View->loadHelper($this->_helperMap[$name]['class'], $settings);
+ }
+ if (isset($this->{$name})) {
+ return $this->{$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;
+ }
+ }
+
+/**
+ * Provides backwards compatibility access for setting values to the request object.
+ *
+ * @param string $name Name of the property being accessed.
+ * @param mixed $value
+ * @return mixed Return the $value
+ */
+ 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;
+ }
+ return $this->{$name} = $value;
+ }
+
+/**
+ * Finds URL for specified action.
+ *
+ * Returns a URL pointing at the provided parameters.
+ *
+ * @param string|array $url Either a relative string url like `/products/view/23` or
+ * an array of url parameters. Using an array for urls will allow you to leverage
+ * the reverse routing features of CakePHP.
+ * @param boolean $full If true, the full base URL will be prepended to the result
+ * @return string Full translated URL with base path.
+ * @link http://book.cakephp.org/2.0/en/views/helpers.html
+ */
+ public function url($url = null, $full = false) {
+ return h(Router::url($url, $full));
+ }
+
+/**
+ * Checks if a file exists when theme is used, if no file is found default location is returned
+ *
+ * @param string $file The file to create a webroot path to.
+ * @return string Web accessible path to file.
+ */
+ public function webroot($file) {
+ $asset = explode('?', $file);
+ $asset[1] = isset($asset[1]) ? '?' . $asset[1] : null;
+ $webPath = "{$this->request->webroot}" . $asset[0];
+ $file = $asset[0];
+
+ if (!empty($this->theme)) {
+ $file = trim($file, '/');
+ $theme = $this->theme . '/';
+
+ if (DS === '\\') {
+ $file = str_replace('/', '\\', $file);
+ }
+
+ if (file_exists(Configure::read('App.www_root') . 'theme' . DS . $this->theme . DS . $file)) {
+ $webPath = "{$this->request->webroot}theme/" . $theme . $asset[0];
+ } else {
+ $themePath = App::themePath($this->theme);
+ $path = $themePath . 'webroot' . DS . $file;
+ if (file_exists($path)) {
+ $webPath = "{$this->request->webroot}theme/" . $theme . $asset[0];
+ }
+ }
+ }
+ if (strpos($webPath, '//') !== false) {
+ return str_replace('//', '/', $webPath . $asset[1]);
+ }
+ return $webPath . $asset[1];
+ }
+
+/**
+ * Generate url for given asset file. Depending on options passed provides full url with domain name.
+ * Also calls Helper::assetTimestamp() to add timestamp to local files
+ *
+ * @param string|array Path string or url array
+ * @param array $options Options array. Possible keys:
+ * `fullBase` Return full url with domain name
+ * `pathPrefix` Path prefix for relative urls
+ * `ext` Asset extension to append
+ * `plugin` False value will prevent parsing path as a plugin
+ * @return string Generated url
+ */
+ public function assetUrl($path, $options = array()) {
+ if (is_array($path)) {
+ $path = $this->url($path, !empty($options['fullBase']));
+ } elseif (strpos($path, '://') === false) {
+ if (!array_key_exists('plugin', $options) || $options['plugin'] !== false) {
+ list($plugin, $path) = $this->_View->pluginSplit($path, false);
+ }
+ if (!empty($options['pathPrefix']) && $path[0] !== '/') {
+ $path = $options['pathPrefix'] . $path;
+ }
+ if (
+ !empty($options['ext']) &&
+ strpos($path, '?') === false &&
+ substr($path, -strlen($options['ext'])) !== $options['ext']
+ ) {
+ $path .= $options['ext'];
+ }
+ if (isset($plugin)) {
+ $path = Inflector::underscore($plugin) . '/' . $path;
+ }
+ $path = h($this->assetTimestamp($this->webroot($path)));
+
+ if (!empty($options['fullBase'])) {
+ $base = $this->url('/', true);
+ $len = strlen($this->request->webroot);
+ if ($len) {
+ $base = substr($base, 0, -$len);
+ }
+ $path = $base . $path;
+ }
+ }
+
+ return $path;
+ }
+
+/**
+ * Adds a timestamp to a file based resource based on the value of `Asset.timestamp` in
+ * Configure. If Asset.timestamp is true and debug > 0, or Asset.timestamp == 'force'
+ * a timestamp will be added.
+ *
+ * @param string $path The file path to timestamp, the path must be inside WWW_ROOT
+ * @return string Path with a timestamp added, or not.
+ */
+ public function assetTimestamp($path) {
+ $stamp = Configure::read('Asset.timestamp');
+ $timestampEnabled = $stamp === 'force' || ($stamp === true && Configure::read('debug') > 0);
+ if ($timestampEnabled && strpos($path, '?') === false) {
+ $filepath = preg_replace('/^' . preg_quote($this->request->webroot, '/') . '/', '', $path);
+ $webrootPath = WWW_ROOT . str_replace('/', DS, $filepath);
+ if (file_exists($webrootPath)) {
+ return $path . '?' . @filemtime($webrootPath);
+ }
+ $segments = explode('/', ltrim($filepath, '/'));
+ if ($segments[0] === 'theme') {
+ $theme = $segments[1];
+ unset($segments[0], $segments[1]);
+ $themePath = App::themePath($theme) . 'webroot' . DS . implode(DS, $segments);
+ return $path . '?' . @filemtime($themePath);
+ } else {
+ $plugin = Inflector::camelize($segments[0]);
+ if (CakePlugin::loaded($plugin)) {
+ unset($segments[0]);
+ $pluginPath = CakePlugin::path($plugin) . 'webroot' . DS . implode(DS, $segments);
+ return $path . '?' . @filemtime($pluginPath);
+ }
+ }
+ }
+ return $path;
+ }
+
+/**
+ * Used to remove harmful tags from content. Removes a number of well known XSS attacks
+ * from content. However, is not guaranteed to remove all possibilities. Escaping
+ * content is the best way to prevent all possible attacks.
+ *
+ * @param string|array $output Either an array of strings to clean or a single string to clean.
+ * @return string|array cleaned content for output
+ */
+ public function clean($output) {
+ $this->_reset();
+ if (empty($output)) {
+ return null;
+ }
+ if (is_array($output)) {
+ foreach ($output as $key => $value) {
+ $return[$key] = $this->clean($value);
+ }
+ return $return;
+ }
+ $this->_tainted = $output;
+ $this->_clean();
+ return $this->_cleaned;
+ }
+
+/**
+ * Returns a space-delimited string with items of the $options array. If a
+ * key of $options array happens to be one of:
+ *
+ * - 'compact'
+ * - 'checked'
+ * - 'declare'
+ * - 'readonly'
+ * - 'disabled'
+ * - 'selected'
+ * - 'defer'
+ * - 'ismap'
+ * - 'nohref'
+ * - 'noshade'
+ * - 'nowrap'
+ * - 'multiple'
+ * - 'noresize'
+ *
+ * And its value is one of:
+ *
+ * - '1' (string)
+ * - 1 (integer)
+ * - true (boolean)
+ * - 'true' (string)
+ *
+ * Then the value will be reset to be identical with key's name.
+ * If the value is not one of these 3, the parameter is not output.
+ *
+ * 'escape' is a special option in that it controls the conversion of
+ * attributes to their html-entity encoded equivalents. Set to false to disable html-encoding.
+ *
+ * If value for any option key is set to `null` or `false`, that option will be excluded from output.
+ *
+ * @param array $options Array of options.
+ * @param array $exclude Array of options to be excluded, the options here will not be part of the return.
+ * @param string $insertBefore String to be inserted before options.
+ * @param string $insertAfter String to be inserted after options.
+ * @return string Composed attributes.
+ * @deprecated This method will be moved to HtmlHelper in 3.0
+ */
+ protected function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
+ if (!is_string($options)) {
+ $options = (array)$options + array('escape' => true);
+
+ if (!is_array($exclude)) {
+ $exclude = array();
+ }
+
+ $exclude = array('escape' => true) + array_flip($exclude);
+ $escape = $options['escape'];
+ $attributes = array();
+
+ foreach ($options as $key => $value) {
+ if (!isset($exclude[$key]) && $value !== false && $value !== null) {
+ $attributes[] = $this->_formatAttribute($key, $value, $escape);
+ }
+ }
+ $out = implode(' ', $attributes);
+ } else {
+ $out = $options;
+ }
+ return $out ? $insertBefore . $out . $insertAfter : '';
+ }
+
+/**
+ * Formats an individual attribute, and returns the string value of the composed attribute.
+ * Works with minimized attributes that have the same value as their name such as 'disabled' and 'checked'
+ *
+ * @param string $key The name of the attribute to create
+ * @param string $value The value of the attribute to create.
+ * @param boolean $escape Define if the value must be escaped
+ * @return string The composed attribute.
+ * @deprecated This method will be moved to HtmlHelper in 3.0
+ */
+ protected function _formatAttribute($key, $value, $escape = true) {
+ $attribute = '';
+ if (is_array($value)) {
+ $value = implode(' ' , $value);
+ }
+
+ if (is_numeric($key)) {
+ $attribute = sprintf($this->_minimizedAttributeFormat, $value, $value);
+ } elseif (in_array($key, $this->_minimizedAttributes)) {
+ if ($value === 1 || $value === true || $value === 'true' || $value === '1' || $value == $key) {
+ $attribute = sprintf($this->_minimizedAttributeFormat, $key, $key);
+ }
+ } else {
+ $attribute = sprintf($this->_attributeFormat, $key, ($escape ? h($value) : $value));
+ }
+ return $attribute;
+ }
+
+/**
+ * Sets this helper's model and field properties to the dot-separated value-pair in $entity.
+ *
+ * @param string $entity A field name, like "ModelName.fieldName" or "ModelName.ID.fieldName"
+ * @param boolean $setScope Sets the view scope to the model specified in $tagValue
+ * @return void
+ */
+ public function setEntity($entity, $setScope = false) {
+ if ($entity === null) {
+ $this->_modelScope = false;
+ }
+ if ($setScope === true) {
+ $this->_modelScope = $entity;
+ }
+ $parts = array_values(Hash::filter(explode('.', $entity)));
+ if (empty($parts)) {
+ return;
+ }
+ $count = count($parts);
+ $lastPart = isset($parts[$count - 1]) ? $parts[$count - 1] : null;
+
+ // Either 'body' or 'date.month' type inputs.
+ if (
+ ($count === 1 && $this->_modelScope && $setScope == false) ||
+ (
+ $count === 2 &&
+ in_array($lastPart, $this->_fieldSuffixes) &&
+ $this->_modelScope &&
+ $parts[0] !== $this->_modelScope
+ )
+ ) {
+ $entity = $this->_modelScope . '.' . $entity;
+ }
+
+ // 0.name, 0.created.month style inputs. Excludes inputs with the modelScope in them.
+ if (
+ $count >= 2 &&
+ is_numeric($parts[0]) &&
+ !is_numeric($parts[1]) &&
+ $this->_modelScope &&
+ strpos($entity, $this->_modelScope) === false
+ ) {
+ $entity = $this->_modelScope . '.' . $entity;
+ }
+
+ $this->_association = null;
+
+ $isHabtm = (
+ isset($this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type']) &&
+ $this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type'] === 'multiple' &&
+ $count == 1
+ );
+
+ // habtm models are special
+ if ($count == 1 && $isHabtm) {
+ $this->_association = $parts[0];
+ $entity = $parts[0] . '.' . $parts[0];
+ } else {
+ // check for associated model.
+ $reversed = array_reverse($parts);
+ foreach ($reversed as $i => $part) {
+ if ($i > 0 && preg_match('/^[A-Z]/', $part)) {
+ $this->_association = $part;
+ break;
+ }
+ }
+ }
+ $this->_entityPath = $entity;
+ }
+
+/**
+ * Returns the entity reference of the current context as an array of identity parts
+ *
+ * @return array An array containing the identity elements of an entity
+ */
+ public function entity() {
+ return explode('.', $this->_entityPath);
+ }
+
+/**
+ * Gets the currently-used model of the rendering context.
+ *
+ * @return string
+ */
+ public function model() {
+ if ($this->_association) {
+ return $this->_association;
+ }
+ return $this->_modelScope;
+ }
+
+/**
+ * Gets the currently-used model field of the rendering context.
+ * Strips off field suffixes such as year, month, day, hour, min, meridian
+ * when the current entity is longer than 2 elements.
+ *
+ * @return string
+ */
+ public function field() {
+ $entity = $this->entity();
+ $count = count($entity);
+ $last = $entity[$count - 1];
+ if ($count > 2 && in_array($last, $this->_fieldSuffixes)) {
+ $last = isset($entity[$count - 2]) ? $entity[$count - 2] : null;
+ }
+ return $last;
+ }
+
+/**
+ * Generates a DOM ID for the selected element, if one is not set.
+ * Uses the current View::entity() settings to generate a CamelCased id attribute.
+ *
+ * @param array|string $options Either an array of html attributes to add $id into, or a string
+ * with a view entity path to get a domId for.
+ * @param string $id The name of the 'id' attribute.
+ * @return mixed If $options was an array, an array will be returned with $id set. If a string
+ * was supplied, a string will be returned.
+ * @todo Refactor this method to not have as many input/output options.
+ */
+ public function domId($options = null, $id = 'id') {
+ if (is_array($options) && array_key_exists($id, $options) && $options[$id] === null) {
+ unset($options[$id]);
+ return $options;
+ } elseif (!is_array($options) && $options !== null) {
+ $this->setEntity($options);
+ return $this->domId();
+ }
+
+ $entity = $this->entity();
+ $model = array_shift($entity);
+ $dom = $model . join('', array_map(array('Inflector', 'camelize'), $entity));
+
+ if (is_array($options) && !array_key_exists($id, $options)) {
+ $options[$id] = $dom;
+ } elseif ($options === null) {
+ return $dom;
+ }
+ return $options;
+ }
+
+/**
+ * Gets the input field name for the current tag. Creates input name attributes
+ * using CakePHP's data[Model][field] formatting.
+ *
+ * @param array|string $options If an array, should be an array of attributes that $key needs to be added to.
+ * If a string or null, will be used as the View entity.
+ * @param string $field
+ * @param string $key The name of the attribute to be set, defaults to 'name'
+ * @return mixed If an array was given for $options, an array with $key set will be returned.
+ * If a string was supplied a string will be returned.
+ * @todo Refactor this method to not have as many input/output options.
+ */
+ protected function _name($options = array(), $field = null, $key = 'name') {
+ if ($options === null) {
+ $options = array();
+ } elseif (is_string($options)) {
+ $field = $options;
+ $options = 0;
+ }
+
+ if (!empty($field)) {
+ $this->setEntity($field);
+ }
+
+ if (is_array($options) && array_key_exists($key, $options)) {
+ return $options;
+ }
+
+ switch ($field) {
+ case '_method':
+ $name = $field;
+ break;
+ default:
+ $name = 'data[' . implode('][', $this->entity()) . ']';
+ break;
+ }
+
+ if (is_array($options)) {
+ $options[$key] = $name;
+ return $options;
+ } else {
+ return $name;
+ }
+ }
+
+/**
+ * Gets the data for the current tag
+ *
+ * @param array|string $options If an array, should be an array of attributes that $key needs to be added to.
+ * If a string or null, will be used as the View entity.
+ * @param string $field
+ * @param string $key The name of the attribute to be set, defaults to 'value'
+ * @return mixed If an array was given for $options, an array with $key set will be returned.
+ * If a string was supplied a string will be returned.
+ * @todo Refactor this method to not have as many input/output options.
+ */
+ public function value($options = array(), $field = null, $key = 'value') {
+ if ($options === null) {
+ $options = array();
+ } elseif (is_string($options)) {
+ $field = $options;
+ $options = 0;
+ }
+
+ if (is_array($options) && isset($options[$key])) {
+ return $options;
+ }
+
+ if (!empty($field)) {
+ $this->setEntity($field);
+ }
+ $result = null;
+ $data = $this->request->data;
+
+ $entity = $this->entity();
+ if (!empty($data) && !empty($entity)) {
+ $result = Hash::get($data, implode('.', $entity));
+ }
+
+ $habtmKey = $this->field();
+ if (empty($result) && isset($data[$habtmKey][$habtmKey]) && is_array($data[$habtmKey])) {
+ $result = $data[$habtmKey][$habtmKey];
+ } elseif (empty($result) && isset($data[$habtmKey]) && is_array($data[$habtmKey])) {
+ if (ClassRegistry::isKeySet($habtmKey)) {
+ $model = ClassRegistry::getObject($habtmKey);
+ $result = $this->_selectedArray($data[$habtmKey], $model->primaryKey);
+ }
+ }
+
+ if (is_array($options)) {
+ if ($result === null && isset($options['default'])) {
+ $result = $options['default'];
+ }
+ unset($options['default']);
+ }
+
+ if (is_array($options)) {
+ $options[$key] = $result;
+ return $options;
+ } else {
+ return $result;
+ }
+ }
+
+/**
+ * Sets the defaults for an input tag. Will set the
+ * name, value, and id attributes for an array of html attributes. Will also
+ * add a 'form-error' class if the field contains validation errors.
+ *
+ * @param string $field The field name to initialize.
+ * @param array $options Array of options to use while initializing an input field.
+ * @return array Array options for the form input.
+ */
+ protected function _initInputField($field, $options = array()) {
+ if ($field !== null) {
+ $this->setEntity($field);
+ }
+ $options = (array)$options;
+ $options = $this->_name($options);
+ $options = $this->value($options);
+ $options = $this->domId($options);
+ return $options;
+ }
+
+/**
+ * Adds the given class to the element options
+ *
+ * @param array $options Array options/attributes to add a class to
+ * @param string $class The classname being added.
+ * @param string $key the key to use for class.
+ * @return array Array of options with $key set.
+ */
+ public function addClass($options = array(), $class = null, $key = 'class') {
+ if (isset($options[$key]) && trim($options[$key]) != '') {
+ $options[$key] .= ' ' . $class;
+ } else {
+ $options[$key] = $class;
+ }
+ return $options;
+ }
+
+/**
+ * Returns a string generated by a helper method
+ *
+ * This method can be overridden in subclasses to do generalized output post-processing
+ *
+ * @param string $str String to be output.
+ * @return string
+ * @deprecated This method will be removed in future versions.
+ */
+ public function output($str) {
+ return $str;
+ }
+
+/**
+ * Before render callback. beforeRender is called before the view file is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The view file that is going to be rendered
+ * @return void
+ */
+ public function beforeRender($viewFile) {
+ }
+
+/**
+ * After render callback. afterRender is called after the view file is rendered
+ * but before the layout has been rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The view file that was rendered.
+ * @return void
+ */
+ public function afterRender($viewFile) {
+ }
+
+/**
+ * Before layout callback. beforeLayout is called before the layout is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $layoutFile The layout about to be rendered.
+ * @return void
+ */
+ public function beforeLayout($layoutFile) {
+ }
+
+/**
+ * After layout callback. afterLayout is called after the layout has rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $layoutFile The layout file that was rendered.
+ * @return void
+ */
+ public function afterLayout($layoutFile) {
+ }
+
+/**
+ * Before render file callback.
+ * Called before any view fragment is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The file about to be rendered.
+ * @return void
+ */
+ public function beforeRenderFile($viewfile) {
+ }
+
+/**
+ * After render file callback.
+ * Called after any view fragment is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The file just be rendered.
+ * @param string $content The content that was rendered.
+ * @return void
+ */
+ public function afterRenderFile($viewfile, $content) {
+ }
+
+/**
+ * Transforms a recordset from a hasAndBelongsToMany association to a list of selected
+ * options for a multiple select element
+ *
+ * @param string|array $data
+ * @param string $key
+ * @return array
+ */
+ protected function _selectedArray($data, $key = 'id') {
+ if (!is_array($data)) {
+ $model = $data;
+ if (!empty($this->request->data[$model][$model])) {
+ return $this->request->data[$model][$model];
+ }
+ if (!empty($this->request->data[$model])) {
+ $data = $this->request->data[$model];
+ }
+ }
+ $array = array();
+ if (!empty($data)) {
+ foreach ($data as $row) {
+ if (isset($row[$key])) {
+ $array[$row[$key]] = $row[$key];
+ }
+ }
+ }
+ return empty($array) ? null : $array;
+ }
+
+/**
+ * Resets the vars used by Helper::clean() to null
+ *
+ * @return void
+ */
+ protected function _reset() {
+ $this->_tainted = null;
+ $this->_cleaned = null;
+ }
+
+/**
+ * Removes harmful content from output
+ *
+ * @return void
+ */
+ protected function _clean() {
+ if (get_magic_quotes_gpc()) {
+ $this->_cleaned = stripslashes($this->_tainted);
+ } else {
+ $this->_cleaned = $this->_tainted;
+ }
+
+ $this->_cleaned = str_replace(array("&amp;", "&lt;", "&gt;"), array("&amp;amp;", "&amp;lt;", "&amp;gt;"), $this->_cleaned);
+ $this->_cleaned = preg_replace('#(&\#*\w+)[\x00-\x20]+;#u', "$1;", $this->_cleaned);
+ $this->_cleaned = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', "$1$2;", $this->_cleaned);
+ $this->_cleaned = html_entity_decode($this->_cleaned, ENT_COMPAT, "UTF-8");
+ $this->_cleaned = preg_replace('#(<[^>]+[\x00-\x20\"\'\/])(on|xmlns)[^>]*>#iUu', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*)[\\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2nojavascript...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=([\'\"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2novbscript...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=*([\'\"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#iUu', '$1=$2nomozbinding...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=([\'\"]*)[\x00-\x20]*data[\x00-\x20]*:#Uu', '$1=$2nodata...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*expression[\x00-\x20]*\([^>]*>#iU', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*behaviour[\x00-\x20]*\([^>]*>#iU', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*>#iUu', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#</*\w+:\w[^>]*>#i', "", $this->_cleaned);
+ do {
+ $oldstring = $this->_cleaned;
+ $this->_cleaned = preg_replace('#</*(applet|meta|xml|blink|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|title|base)[^>]*>#i', "", $this->_cleaned);
+ } while ($oldstring != $this->_cleaned);
+ $this->_cleaned = str_replace(array("&amp;", "&lt;", "&gt;"), array("&amp;amp;", "&amp;lt;", "&amp;gt;"), $this->_cleaned);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php
new file mode 100644
index 0000000..a480886
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php
@@ -0,0 +1,321 @@
+<?php
+/**
+ * CacheHelper helps create full page view caching.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 1.0.0.2277
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * CacheHelper helps create full page view caching.
+ *
+ * When using CacheHelper you don't call any of its methods, they are all automatically
+ * called by View, and use the $cacheAction settings set in the controller.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html
+ */
+class CacheHelper extends AppHelper {
+
+/**
+ * Array of strings replaced in cached views.
+ * The strings are found between `<!--nocache--><!--/nocache-->` in views
+ *
+ * @var array
+ */
+ protected $_replace = array();
+
+/**
+ * Array of string that are replace with there var replace above.
+ * The strings are any content inside `<!--nocache--><!--/nocache-->` and includes the tags in views
+ *
+ * @var array
+ */
+ protected $_match = array();
+
+/**
+ * Counter used for counting nocache section tags.
+ *
+ * @var integer
+ */
+ protected $_counter = 0;
+
+/**
+ * Is CacheHelper enabled? should files + output be parsed.
+ *
+ * @return boolean
+ */
+ protected function _enabled() {
+ return (($this->_View->cacheAction != false)) && (Configure::read('Cache.check') === true);
+ }
+
+/**
+ * Parses the view file and stores content for cache file building.
+ *
+ * @param string $viewFile
+ * @return void
+ */
+ public function afterRenderFile($viewFile, $output) {
+ if ($this->_enabled()) {
+ return $this->_parseContent($viewFile, $output);
+ }
+ }
+
+/**
+ * Parses the layout file and stores content for cache file building.
+ *
+ * @param string $layoutFile
+ * @return void
+ */
+ public function afterLayout($layoutFile) {
+ if ($this->_enabled()) {
+ $this->_View->output = $this->cache($layoutFile, $this->_View->output);
+ }
+ $this->_View->output = preg_replace('/<!--\/?nocache-->/', '', $this->_View->output);
+ }
+
+/**
+ * Parse a file + output. Matches nocache tags between the current output and the current file
+ * stores a reference of the file, so the generated can be swapped back with the file contents when
+ * writing the cache file.
+ *
+ * @param string $file The filename to process.
+ * @param string $out The output for the file.
+ * @return string Updated content.
+ */
+ protected function _parseContent($file, $out) {
+ $out = preg_replace_callback('/<!--nocache-->/', array($this, '_replaceSection'), $out);
+ $this->_parseFile($file, $out);
+ return $out;
+ }
+
+/**
+ * Main method used to cache a view
+ *
+ * @param string $file File to cache
+ * @param string $out output to cache
+ * @return string view ouput
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html
+ */
+ public function cache($file, $out) {
+ $cacheTime = 0;
+ $useCallbacks = false;
+ $cacheAction = $this->_View->cacheAction;
+
+ if (is_array($cacheAction)) {
+ $keys = array_keys($cacheAction);
+ $index = null;
+
+ foreach ($keys as $action) {
+ if ($action == $this->request->params['action']) {
+ $index = $action;
+ break;
+ }
+ }
+
+ if (!isset($index) && $this->request->params['action'] == 'index') {
+ $index = 'index';
+ }
+
+ $options = $cacheAction;
+ if (isset($cacheAction[$index])) {
+ if (is_array($cacheAction[$index])) {
+ $options = array_merge(array('duration' => 0, 'callbacks' => false), $cacheAction[$index]);
+ } else {
+ $cacheTime = $cacheAction[$index];
+ }
+ }
+ if (isset($options['duration'])) {
+ $cacheTime = $options['duration'];
+ }
+ if (isset($options['callbacks'])) {
+ $useCallbacks = $options['callbacks'];
+ }
+ } else {
+ $cacheTime = $cacheAction;
+ }
+
+ if ($cacheTime != '' && $cacheTime > 0) {
+ $cached = $this->_parseOutput($out);
+ $this->_writeFile($cached, $cacheTime, $useCallbacks);
+ $out = $this->_stripTags($out);
+ }
+ return $out;
+ }
+
+/**
+ * Parse file searching for no cache tags
+ *
+ * @param string $file The filename that needs to be parsed.
+ * @param string $cache The cached content
+ * @return void
+ */
+ protected function _parseFile($file, $cache) {
+ if (is_file($file)) {
+ $file = file_get_contents($file);
+ } elseif ($file = fileExistsInPath($file)) {
+ $file = file_get_contents($file);
+ }
+ preg_match_all('/(<!--nocache:\d{3}-->(?<=<!--nocache:\d{3}-->)[\\s\\S]*?(?=<!--\/nocache-->)<!--\/nocache-->)/i', $cache, $outputResult, PREG_PATTERN_ORDER);
+ preg_match_all('/(?<=<!--nocache-->)([\\s\\S]*?)(?=<!--\/nocache-->)/i', $file, $fileResult, PREG_PATTERN_ORDER);
+ $fileResult = $fileResult[0];
+ $outputResult = $outputResult[0];
+
+ if (!empty($this->_replace)) {
+ foreach ($outputResult as $i => $element) {
+ $index = array_search($element, $this->_match);
+ if ($index !== false) {
+ unset($outputResult[$i]);
+ }
+ }
+ $outputResult = array_values($outputResult);
+ }
+
+ if (!empty($fileResult)) {
+ $i = 0;
+ foreach ($fileResult as $cacheBlock) {
+ if (isset($outputResult[$i])) {
+ $this->_replace[] = $cacheBlock;
+ $this->_match[] = $outputResult[$i];
+ }
+ $i++;
+ }
+ }
+ }
+
+/**
+ * Munges the output from a view with cache tags, and numbers the sections.
+ * This helps solve issues with empty/duplicate content.
+ *
+ * @return string The content with cake:nocache tags replaced.
+ */
+ protected function _replaceSection() {
+ $this->_counter += 1;
+ return sprintf('<!--nocache:%03d-->', $this->_counter);
+ }
+
+/**
+ * Strip cake:nocache tags from a string. Since View::render()
+ * only removes un-numbered nocache tags, remove all the numbered ones.
+ * This is the complement to _replaceSection.
+ *
+ * @param string $content String to remove tags from.
+ * @return string String with tags removed.
+ */
+ protected function _stripTags($content) {
+ return preg_replace('#<!--/?nocache(\:\d{3})?-->#', '', $content);
+ }
+
+/**
+ * Parse the output and replace cache tags
+ *
+ * @param string $cache Output to replace content in.
+ * @return string with all replacements made to <!--nocache--><!--nocache-->
+ */
+ protected function _parseOutput($cache) {
+ $count = 0;
+ if (!empty($this->_match)) {
+ foreach ($this->_match as $found) {
+ $original = $cache;
+ $length = strlen($found);
+ $position = 0;
+
+ for ($i = 1; $i <= 1; $i++) {
+ $position = strpos($cache, $found, $position);
+
+ if ($position !== false) {
+ $cache = substr($original, 0, $position);
+ $cache .= $this->_replace[$count];
+ $cache .= substr($original, $position + $length);
+ } else {
+ break;
+ }
+ }
+ $count++;
+ }
+ return $cache;
+ }
+ return $cache;
+ }
+
+/**
+ * Write a cached version of the file
+ *
+ * @param string $content view content to write to a cache file.
+ * @param string $timestamp Duration to set for cache file.
+ * @param boolean $useCallbacks
+ * @return boolean success of caching view.
+ */
+ protected function _writeFile($content, $timestamp, $useCallbacks = false) {
+ $now = time();
+
+ if (is_numeric($timestamp)) {
+ $cacheTime = $now + $timestamp;
+ } else {
+ $cacheTime = strtotime($timestamp, $now);
+ }
+ $path = $this->request->here();
+ if ($path == '/') {
+ $path = 'home';
+ }
+ $cache = strtolower(Inflector::slug($path));
+
+ if (empty($cache)) {
+ return;
+ }
+ $cache = $cache . '.php';
+ $file = '<!--cachetime:' . $cacheTime . '--><?php';
+
+ if (empty($this->_View->plugin)) {
+ $file .= "
+ App::uses('{$this->_View->name}Controller', 'Controller');
+ ";
+ } else {
+ $file .= "
+ App::uses('{$this->_View->plugin}AppController', '{$this->_View->plugin}.Controller');
+ App::uses('{$this->_View->name}Controller', '{$this->_View->plugin}.Controller');
+ ";
+ }
+
+ $file .= '
+ $request = unserialize(base64_decode(\'' . base64_encode(serialize($this->request)) . '\'));
+ $response = new CakeResponse(array("charset" => Configure::read("App.encoding")));
+ $controller = new ' . $this->_View->name . 'Controller($request, $response);
+ $controller->plugin = $this->plugin = \'' . $this->_View->plugin . '\';
+ $controller->helpers = $this->helpers = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->helpers)) . '\'));
+ $controller->layout = $this->layout = \'' . $this->_View->layout . '\';
+ $controller->theme = $this->theme = \'' . $this->_View->theme . '\';
+ $controller->viewVars = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->viewVars)) . '\'));
+ Router::setRequestInfo($controller->request);
+ $this->request = $request;';
+
+ if ($useCallbacks == true) {
+ $file .= '
+ $controller->constructClasses();
+ $controller->startupProcess();';
+ }
+
+ $file .= '
+ $this->viewVars = $controller->viewVars;
+ $this->loadHelpers();
+ extract($this->viewVars, EXTR_SKIP);
+ ?>';
+ $content = preg_replace("/(<\\?xml)/", "<?php echo '$1'; ?>", $content);
+ $file .= $content;
+ return cache('views' . DS . $cache, $file, $timestamp);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php
new file mode 100644
index 0000000..e63614a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php
@@ -0,0 +1,2604 @@
+<?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.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ClassRegistry', 'Utility');
+App::uses('AppHelper', 'View/Helper');
+App::uses('Hash', 'Utility');
+
+/**
+ * Form helper library.
+ *
+ * Automatic generation of HTML FORMs from given data.
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html
+ */
+class FormHelper extends AppHelper {
+
+/**
+ * Other helpers used by FormHelper
+ *
+ * @var array
+ */
+ public $helpers = array('Html');
+
+/**
+ * Options used by DateTime fields
+ *
+ * @var array
+ */
+ protected $_options = array(
+ 'day' => array(), 'minute' => array(), 'hour' => array(),
+ 'month' => array(), 'year' => array(), 'meridian' => array()
+ );
+
+/**
+ * List of fields created, used with secure forms.
+ *
+ * @var array
+ */
+ public $fields = array();
+
+/**
+ * Constant used internally to skip the securing process,
+ * and neither add the field to the hash or to the unlocked fields.
+ *
+ * @var string
+ */
+ const SECURE_SKIP = 'skip';
+
+/**
+ * Defines the type of form being created. Set by FormHelper::create().
+ *
+ * @var string
+ */
+ public $requestType = null;
+
+/**
+ * The default model being used for the current form.
+ *
+ * @var string
+ */
+ public $defaultModel = null;
+
+/**
+ * Persistent default options used by input(). Set by FormHelper::create().
+ *
+ * @var array
+ */
+ protected $_inputDefaults = array();
+
+/**
+ * An array of field names that have been excluded from
+ * the Token hash used by SecurityComponent's validatePost method
+ *
+ * @see FormHelper::_secure()
+ * @see SecurityComponent::validatePost()
+ * @var array
+ */
+ protected $_unlockedFields = array();
+
+/**
+ * Holds the model references already loaded by this helper
+ * product of trying to inspect them out of field names
+ *
+ * @var array
+ */
+ protected $_models = array();
+
+/**
+ * Holds all the validation errors for models loaded and inspected
+ * it can also be set manually to be able to display custom error messages
+ * in the any of the input fields generated by this helper
+ *
+ * @var array
+ */
+ public $validationErrors = array();
+
+/**
+ * Copies the validationErrors variable from the View object into this instance
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ parent::__construct($View, $settings);
+ $this->validationErrors =& $View->validationErrors;
+ }
+
+/**
+ * Guess the location for a model based on its name and tries to create a new instance
+ * or get an already created instance of the model
+ *
+ * @param string $model
+ * @return Model model instance
+ */
+ protected function _getModel($model) {
+ $object = null;
+ if (!$model || $model === 'Model') {
+ return $object;
+ }
+
+ if (array_key_exists($model, $this->_models)) {
+ return $this->_models[$model];
+ }
+
+ if (ClassRegistry::isKeySet($model)) {
+ $object = ClassRegistry::getObject($model);
+ } elseif (isset($this->request->params['models'][$model])) {
+ $plugin = $this->request->params['models'][$model]['plugin'];
+ $plugin .= ($plugin) ? '.' : null;
+ $object = ClassRegistry::init(array(
+ 'class' => $plugin . $this->request->params['models'][$model]['className'],
+ 'alias' => $model
+ ));
+ } elseif (ClassRegistry::isKeySet($this->defaultModel)) {
+ $defaultObject = ClassRegistry::getObject($this->defaultModel);
+ if (in_array($model, array_keys($defaultObject->getAssociated()), true) && isset($defaultObject->{$model})) {
+ $object = $defaultObject->{$model};
+ }
+ } else {
+ $object = ClassRegistry::init($model, true);
+ }
+
+ $this->_models[$model] = $object;
+ if (!$object) {
+ return null;
+ }
+
+ $this->fieldset[$model] = array('fields' => null, 'key' => $object->primaryKey, 'validates' => null);
+ return $object;
+ }
+
+/**
+ * Inspects the model properties to extract information from them.
+ * Currently it can extract information from the the fields, the primary key and required fields
+ *
+ * The $key parameter accepts the following list of values:
+ *
+ * - key: Returns the name of the primary key for the model
+ * - fields: Returns the model schema
+ * - validates: returns the list of fields that are required
+ * - errors: returns the list of validation errors
+ *
+ * If the $field parameter is passed if will return the information for that sole field.
+ *
+ * `$this->_introspectModel('Post', 'fields', 'title');` will return the schema information for title column
+ *
+ * @param string $model name of the model to extract information from
+ * @param string $key name of the special information key to obtain (key, fields, validates, errors)
+ * @param string $field name of the model field to get information from
+ * @return mixed information extracted for the special key and field in a model
+ */
+ protected function _introspectModel($model, $key, $field = null) {
+ $object = $this->_getModel($model);
+ if (!$object) {
+ return;
+ }
+
+ if ($key === 'key') {
+ return $this->fieldset[$model]['key'] = $object->primaryKey;
+ }
+
+ if ($key === 'fields') {
+ if (!isset($this->fieldset[$model]['fields'])) {
+ $fields = $this->fieldset[$model]['fields'] = $object->schema();
+ foreach ($object->hasAndBelongsToMany as $alias => $assocData) {
+ $this->fieldset[$object->alias]['fields'][$alias] = array('type' => 'multiple');
+ }
+ }
+ if (empty($field)) {
+ return $this->fieldset[$model]['fields'];
+ } elseif (isset($this->fieldset[$model]['fields'][$field])) {
+ return $this->fieldset[$model]['fields'][$field];
+ } else {
+ return isset($object->hasAndBelongsToMany[$field]) ? array('type' => 'multiple') : null;
+ }
+ }
+
+ if ($key === 'errors' && !isset($this->validationErrors[$model])) {
+ $this->validationErrors[$model] =& $object->validationErrors;
+ return $this->validationErrors[$model];
+ } elseif ($key === 'errors' && isset($this->validationErrors[$model])) {
+ return $this->validationErrors[$model];
+ }
+
+ if ($key === 'validates' && !isset($this->fieldset[$model]['validates'])) {
+ $validates = array();
+ if (!empty($object->validate)) {
+ foreach ($object->validator() as $validateField => $validateProperties) {
+ if ($this->_isRequiredField($validateProperties)) {
+ $validates[$validateField] = true;
+ }
+ }
+ }
+ $this->fieldset[$model]['validates'] = $validates;
+ }
+
+ if ($key === 'validates') {
+ if (empty($field)) {
+ return $this->fieldset[$model]['validates'];
+ } else {
+ return isset($this->fieldset[$model]['validates'][$field]) ?
+ $this->fieldset[$model]['validates'] : null;
+ }
+ }
+ }
+
+/**
+ * Returns if a field is required to be filled based on validation properties from the validating object.
+ *
+ * @param CakeValidationSet $validationRules
+ * @return boolean true if field is required to be filled, false otherwise
+ */
+ protected function _isRequiredField($validationRules) {
+ foreach ($validationRules as $rule) {
+ $rule->isUpdate($this->requestType === 'put');
+ if (!$rule->isEmptyAllowed()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns false if given form field described by the current entity has no errors.
+ * Otherwise it returns the validation message
+ *
+ * @return mixed Either false when there or no errors, or an array of error
+ * strings. An error string could be ''.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::tagIsInvalid
+ */
+ public function tagIsInvalid() {
+ $entity = $this->entity();
+ $model = array_shift($entity);
+ $errors = array();
+ if (!empty($entity) && isset($this->validationErrors[$model])) {
+ $errors = $this->validationErrors[$model];
+ }
+ if (!empty($entity) && empty($errors)) {
+ $errors = $this->_introspectModel($model, 'errors');
+ }
+ if (empty($errors)) {
+ return false;
+ }
+ $errors = Hash::get($errors, join('.', $entity));
+ return $errors === null ? false : $errors;
+ }
+
+/**
+ * Returns an HTML FORM element.
+ *
+ * ### Options:
+ *
+ * - `type` Form method defaults to POST
+ * - `action` The controller action the form submits to, (optional).
+ * - `url` The url the form submits to. Can be a string or a url array. If you use 'url'
+ * you should leave 'action' undefined.
+ * - `default` Allows for the creation of Ajax forms. Set this to false to prevent the default event handler.
+ * Will create an onsubmit attribute if it doesn't not exist. If it does, default action suppression
+ * will be appended.
+ * - `onsubmit` Used in conjunction with 'default' to create ajax forms.
+ * - `inputDefaults` set the default $options for FormHelper::input(). Any options that would
+ * be set when using FormHelper::input() can be set here. Options set with `inputDefaults`
+ * can be overridden when calling input()
+ * - `encoding` Set the accept-charset encoding for the form. Defaults to `Configure::read('App.encoding')`
+ *
+ * @param string $model The model object which the form is being defined for. Should
+ * include the plugin name for plugin forms. e.g. `ContactManager.Contact`.
+ * @param array $options An array of html attributes and options.
+ * @return string An formatted opening FORM tag.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-create
+ */
+ public function create($model = null, $options = array()) {
+ $created = $id = false;
+ $append = '';
+
+ if (is_array($model) && empty($options)) {
+ $options = $model;
+ $model = null;
+ }
+
+ if (empty($model) && $model !== false && !empty($this->request->params['models'])) {
+ $model = key($this->request->params['models']);
+ } elseif (empty($model) && empty($this->request->params['models'])) {
+ $model = false;
+ }
+ $this->defaultModel = $model;
+
+ $key = null;
+ if ($model !== false) {
+ $object = $this->_getModel($model);
+ $key = $this->_introspectModel($model, 'key');
+ $this->setEntity($model, true);
+ }
+
+ if ($model !== false && $key) {
+ $recordExists = (
+ isset($this->request->data[$model]) &&
+ !empty($this->request->data[$model][$key]) &&
+ !is_array($this->request->data[$model][$key])
+ );
+
+ if ($recordExists) {
+ $created = true;
+ $id = $this->request->data[$model][$key];
+ }
+ }
+
+ $options = array_merge(array(
+ 'type' => ($created && empty($options['action'])) ? 'put' : 'post',
+ 'action' => null,
+ 'url' => null,
+ 'default' => true,
+ 'encoding' => strtolower(Configure::read('App.encoding')),
+ 'inputDefaults' => array()),
+ $options);
+ $this->inputDefaults($options['inputDefaults']);
+ unset($options['inputDefaults']);
+
+ if (!isset($options['id'])) {
+ $domId = isset($options['action']) ? $options['action'] : $this->request['action'];
+ $options['id'] = $this->domId($domId . 'Form');
+ }
+
+ if ($options['action'] === null && $options['url'] === null) {
+ $options['action'] = $this->request->here(false);
+ } elseif (empty($options['url']) || is_array($options['url'])) {
+ if (empty($options['url']['controller'])) {
+ if (!empty($model)) {
+ $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model));
+ } elseif (!empty($this->request->params['controller'])) {
+ $options['url']['controller'] = Inflector::underscore($this->request->params['controller']);
+ }
+ }
+ if (empty($options['action'])) {
+ $options['action'] = $this->request->params['action'];
+ }
+
+ $plugin = null;
+ if ($this->plugin) {
+ $plugin = Inflector::underscore($this->plugin);
+ }
+ $actionDefaults = array(
+ 'plugin' => $plugin,
+ 'controller' => $this->_View->viewPath,
+ 'action' => $options['action'],
+ );
+ $options['action'] = array_merge($actionDefaults, (array)$options['url']);
+ if (empty($options['action'][0]) && !empty($id)) {
+ $options['action'][0] = $id;
+ }
+ } elseif (is_string($options['url'])) {
+ $options['action'] = $options['url'];
+ }
+ unset($options['url']);
+
+ switch (strtolower($options['type'])) {
+ case 'get':
+ $htmlAttributes['method'] = 'get';
+ break;
+ case 'file':
+ $htmlAttributes['enctype'] = 'multipart/form-data';
+ $options['type'] = ($created) ? 'put' : 'post';
+ case 'post':
+ case 'put':
+ case 'delete':
+ $append .= $this->hidden('_method', array(
+ 'name' => '_method', 'value' => strtoupper($options['type']), 'id' => null,
+ 'secure' => self::SECURE_SKIP
+ ));
+ default:
+ $htmlAttributes['method'] = 'post';
+ break;
+ }
+ $this->requestType = strtolower($options['type']);
+
+ $action = $this->url($options['action']);
+ unset($options['type'], $options['action']);
+
+ if ($options['default'] == false) {
+ if (!isset($options['onsubmit'])) {
+ $options['onsubmit'] = '';
+ }
+ $htmlAttributes['onsubmit'] = $options['onsubmit'] . 'event.returnValue = false; return false;';
+ }
+ unset($options['default']);
+
+ if (!empty($options['encoding'])) {
+ $htmlAttributes['accept-charset'] = $options['encoding'];
+ unset($options['encoding']);
+ }
+
+ $htmlAttributes = array_merge($options, $htmlAttributes);
+
+ $this->fields = array();
+ $append .= $this->_csrfField();
+
+ if (!empty($append)) {
+ $append = $this->Html->useTag('block', ' style="display:none;"', $append);
+ }
+
+ if ($model !== false) {
+ $this->setEntity($model, true);
+ $this->_introspectModel($model, 'fields');
+ }
+ return $this->Html->useTag('form', $action, $htmlAttributes) . $append;
+ }
+
+/**
+ * Return a CSRF input if the _Token is present.
+ * Used to secure forms in conjunction with SecurityComponent
+ *
+ * @return string
+ */
+ protected function _csrfField() {
+ if (empty($this->request->params['_Token'])) {
+ return '';
+ }
+ if (!empty($this->request['_Token']['unlockedFields'])) {
+ foreach ((array)$this->request['_Token']['unlockedFields'] as $unlocked) {
+ $this->_unlockedFields[] = $unlocked;
+ }
+ }
+ return $this->hidden('_Token.key', array(
+ 'value' => $this->request->params['_Token']['key'], 'id' => 'Token' . mt_rand(),
+ 'secure' => self::SECURE_SKIP
+ ));
+ }
+
+/**
+ * Closes an HTML form, cleans up values set by FormHelper::create(), and writes hidden
+ * input fields where appropriate.
+ *
+ * If $options is set a form submit button will be created. Options can be either a string or an array.
+ *
+ * {{{
+ * array usage:
+ *
+ * array('label' => 'save'); value="save"
+ * array('label' => 'save', 'name' => 'Whatever'); value="save" name="Whatever"
+ * array('name' => 'Whatever'); value="Submit" name="Whatever"
+ * array('label' => 'save', 'name' => 'Whatever', 'div' => 'good') <div class="good"> value="save" name="Whatever"
+ * array('label' => 'save', 'name' => 'Whatever', 'div' => array('class' => 'good')); <div class="good"> value="save" name="Whatever"
+ * }}}
+ *
+ * @param string|array $options as a string will use $options as the value of button,
+ * @return string a closing FORM tag optional submit button.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#closing-the-form
+ */
+ public function end($options = null) {
+ $out = null;
+ $submit = null;
+
+ if ($options !== null) {
+ $submitOptions = array();
+ if (is_string($options)) {
+ $submit = $options;
+ } else {
+ if (isset($options['label'])) {
+ $submit = $options['label'];
+ unset($options['label']);
+ }
+ $submitOptions = $options;
+ }
+ $out .= $this->submit($submit, $submitOptions);
+ }
+ if (isset($this->request['_Token']) && !empty($this->request['_Token'])) {
+ $out .= $this->secure($this->fields);
+ $this->fields = array();
+ }
+ $this->setEntity(null);
+ $out .= $this->Html->useTag('formend');
+
+ $this->_View->modelScope = false;
+ return $out;
+ }
+
+/**
+ * Generates a hidden field with a security hash based on the fields used in the form.
+ *
+ * @param array $fields The list of fields to use when generating the hash
+ * @return string A hidden input field with a security hash
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::secure
+ */
+ public function secure($fields = array()) {
+ if (!isset($this->request['_Token']) || empty($this->request['_Token'])) {
+ return;
+ }
+ $locked = array();
+ $unlockedFields = $this->_unlockedFields;
+
+ foreach ($fields as $key => $value) {
+ if (!is_int($key)) {
+ $locked[$key] = $value;
+ unset($fields[$key]);
+ }
+ }
+
+ sort($unlockedFields, SORT_STRING);
+ sort($fields, SORT_STRING);
+ ksort($locked, SORT_STRING);
+ $fields += $locked;
+
+ $locked = implode(array_keys($locked), '|');
+ $unlocked = implode($unlockedFields, '|');
+ $fields = Security::hash(serialize($fields) . $unlocked . Configure::read('Security.salt'));
+
+ $out = $this->hidden('_Token.fields', array(
+ 'value' => urlencode($fields . ':' . $locked),
+ 'id' => 'TokenFields' . mt_rand()
+ ));
+ $out .= $this->hidden('_Token.unlocked', array(
+ 'value' => urlencode($unlocked),
+ 'id' => 'TokenUnlocked' . mt_rand()
+ ));
+ return $this->Html->useTag('block', ' style="display:none;"', $out);
+ }
+
+/**
+ * Add to or get the list of fields that are currently unlocked.
+ * Unlocked fields are not included in the field hash used by SecurityComponent
+ * unlocking a field once its been added to the list of secured fields will remove
+ * it from the list of fields.
+ *
+ * @param string $name The dot separated name for the field.
+ * @return mixed Either null, or the list of fields.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::unlockField
+ */
+ public function unlockField($name = null) {
+ if ($name === null) {
+ return $this->_unlockedFields;
+ }
+ if (!in_array($name, $this->_unlockedFields)) {
+ $this->_unlockedFields[] = $name;
+ }
+ $index = array_search($name, $this->fields);
+ if ($index !== false) {
+ unset($this->fields[$index]);
+ }
+ unset($this->fields[$name]);
+ }
+
+/**
+ * Determine which fields of a form should be used for hash.
+ * Populates $this->fields
+ *
+ * @param boolean $lock Whether this field should be part of the validation
+ * or excluded as part of the unlockedFields.
+ * @param string|array $field Reference to field to be secured. Should be dot separated to indicate nesting.
+ * @param mixed $value Field value, if value should not be tampered with.
+ * @return void
+ */
+ protected function _secure($lock, $field = null, $value = null) {
+ if (!$field) {
+ $field = $this->entity();
+ } elseif (is_string($field)) {
+ $field = Hash::filter(explode('.', $field));
+ }
+
+ foreach ($this->_unlockedFields as $unlockField) {
+ $unlockParts = explode('.', $unlockField);
+ if (array_values(array_intersect($field, $unlockParts)) === $unlockParts) {
+ return;
+ }
+ }
+
+ $field = implode('.', $field);
+ $field = preg_replace('/(\.\d+)+$/', '', $field);
+
+ if ($lock) {
+ if (!in_array($field, $this->fields)) {
+ if ($value !== null) {
+ return $this->fields[$field] = $value;
+ }
+ $this->fields[] = $field;
+ }
+ } else {
+ $this->unlockField($field);
+ }
+ }
+
+/**
+ * Returns true if there is an error for the given field, otherwise false
+ *
+ * @param string $field This should be "Modelname.fieldname"
+ * @return boolean If there are errors this method returns true, else false.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::isFieldError
+ */
+ public function isFieldError($field) {
+ $this->setEntity($field);
+ return (bool)$this->tagIsInvalid();
+ }
+
+/**
+ * Returns a formatted error message for given FORM field, NULL if no errors.
+ *
+ * ### Options:
+ *
+ * - `escape` bool Whether or not to html escape the contents of the error.
+ * - `wrap` mixed Whether or not the error message should be wrapped in a div. If a
+ * string, will be used as the HTML tag to use.
+ * - `class` string The classname for the error message
+ *
+ * @param string $field A field name, like "Modelname.fieldname"
+ * @param string|array $text Error message as string or array of messages.
+ * If array contains `attributes` key it will be used as options for error container
+ * @param array $options Rendering options for <div /> wrapper tag
+ * @return string If there are errors this method returns an error message, otherwise null.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::error
+ */
+ public function error($field, $text = null, $options = array()) {
+ $defaults = array('wrap' => true, 'class' => 'error-message', 'escape' => true);
+ $options = array_merge($defaults, $options);
+ $this->setEntity($field);
+
+ $error = $this->tagIsInvalid();
+ if ($error === false) {
+ return null;
+ }
+ if (is_array($text)) {
+ if (isset($text['attributes']) && is_array($text['attributes'])) {
+ $options = array_merge($options, $text['attributes']);
+ unset($text['attributes']);
+ }
+ $tmp = array();
+ foreach ($error as &$e) {
+ if (isset($text[$e])) {
+ $tmp[] = $text[$e];
+ } else {
+ $tmp[] = $e;
+ }
+ }
+ $text = $tmp;
+ }
+
+ if ($text !== null) {
+ $error = $text;
+ }
+ if (is_array($error)) {
+ foreach ($error as &$e) {
+ if (is_numeric($e)) {
+ $e = __d('cake', 'Error in field %s', Inflector::humanize($this->field()));
+ }
+ }
+ }
+ if ($options['escape']) {
+ $error = h($error);
+ unset($options['escape']);
+ }
+ if (is_array($error)) {
+ if (count($error) > 1) {
+ $listParams = array();
+ if (isset($options['listOptions'])) {
+ if (is_string($options['listOptions'])) {
+ $listParams[] = $options['listOptions'];
+ } else {
+ if (isset($options['listOptions']['itemOptions'])) {
+ $listParams[] = $options['listOptions']['itemOptions'];
+ unset($options['listOptions']['itemOptions']);
+ } else {
+ $listParams[] = array();
+ }
+ if (isset($options['listOptions']['tag'])) {
+ $listParams[] = $options['listOptions']['tag'];
+ unset($options['listOptions']['tag']);
+ }
+ array_unshift($listParams, $options['listOptions']);
+ }
+ unset($options['listOptions']);
+ }
+ array_unshift($listParams, $error);
+ $error = call_user_func_array(array($this->Html, 'nestedList'), $listParams);
+ } else {
+ $error = array_pop($error);
+ }
+ }
+ if ($options['wrap']) {
+ $tag = is_string($options['wrap']) ? $options['wrap'] : 'div';
+ unset($options['wrap']);
+ return $this->Html->tag($tag, $error, $options);
+ } else {
+ return $error;
+ }
+ }
+
+/**
+ * Returns a formatted LABEL element for HTML FORMs. Will automatically generate
+ * a for attribute if one is not provided.
+ *
+ * ### Options
+ *
+ * - `for` - Set the for attribute, if its not defined the for attribute
+ * will be generated from the $fieldName parameter using
+ * FormHelper::domId().
+ *
+ * Examples:
+ *
+ * The text and for attribute are generated off of the fieldname
+ *
+ * {{{
+ * echo $this->Form->label('Post.published');
+ * <label for="PostPublished">Published</label>
+ * }}}
+ *
+ * Custom text:
+ *
+ * {{{
+ * echo $this->Form->label('Post.published', 'Publish');
+ * <label for="PostPublished">Publish</label>
+ * }}}
+ *
+ * Custom class name:
+ *
+ * {{{
+ * echo $this->Form->label('Post.published', 'Publish', 'required');
+ * <label for="PostPublished" class="required">Publish</label>
+ * }}}
+ *
+ * Custom attributes:
+ *
+ * {{{
+ * echo $this->Form->label('Post.published', 'Publish', array(
+ * 'for' => 'post-publish'
+ * ));
+ * <label for="post-publish">Publish</label>
+ * }}}
+ *
+ * @param string $fieldName This should be "Modelname.fieldname"
+ * @param string $text Text that will appear in the label field. If
+ * $text is left undefined the text will be inflected from the
+ * fieldName.
+ * @param array|string $options An array of HTML attributes, or a string, to be used as a class name.
+ * @return string The formatted LABEL element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::label
+ */
+ public function label($fieldName = null, $text = null, $options = array()) {
+ if (empty($fieldName)) {
+ $fieldName = implode('.', $this->entity());
+ }
+
+ if ($text === null) {
+ if (strpos($fieldName, '.') !== false) {
+ $fieldElements = explode('.', $fieldName);
+ $text = array_pop($fieldElements);
+ } else {
+ $text = $fieldName;
+ }
+ if (substr($text, -3) == '_id') {
+ $text = substr($text, 0, -3);
+ }
+ $text = __(Inflector::humanize(Inflector::underscore($text)));
+ }
+
+ if (is_string($options)) {
+ $options = array('class' => $options);
+ }
+
+ if (isset($options['for'])) {
+ $labelFor = $options['for'];
+ unset($options['for']);
+ } else {
+ $labelFor = $this->domId($fieldName);
+ }
+
+ return $this->Html->useTag('label', $labelFor, $options, $text);
+ }
+
+/**
+ * Generate a set of inputs for `$fields`. If $fields is null the current model
+ * will be used.
+ *
+ * In addition to controller fields output, `$fields` can be used to control legend
+ * and fieldset rendering with the `fieldset` and `legend` keys.
+ * `$form->inputs(array('legend' => 'My legend'));` Would generate an input set with
+ * a custom legend. You can customize individual inputs through `$fields` as well.
+ *
+ * {{{
+ * $form->inputs(array(
+ * 'name' => array('label' => 'custom label')
+ * ));
+ * }}}
+ *
+ * In addition to fields control, inputs() allows you to use a few additional options.
+ *
+ * - `fieldset` Set to false to disable the fieldset. If a string is supplied it will be used as
+ * the classname for the fieldset element.
+ * - `legend` Set to false to disable the legend for the generated input set. Or supply a string
+ * to customize the legend text.
+ *
+ * @param array $fields An array of fields to generate inputs for, or null.
+ * @param array $blacklist a simple array of fields to not create inputs for.
+ * @return string Completed form inputs.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::inputs
+ */
+ public function inputs($fields = null, $blacklist = null) {
+ $fieldset = $legend = true;
+ $model = $this->model();
+ if (is_array($fields)) {
+ if (array_key_exists('legend', $fields)) {
+ $legend = $fields['legend'];
+ unset($fields['legend']);
+ }
+
+ if (isset($fields['fieldset'])) {
+ $fieldset = $fields['fieldset'];
+ unset($fields['fieldset']);
+ }
+ } elseif ($fields !== null) {
+ $fieldset = $legend = $fields;
+ if (!is_bool($fieldset)) {
+ $fieldset = true;
+ }
+ $fields = array();
+ }
+
+ if (empty($fields)) {
+ $fields = array_keys($this->_introspectModel($model, 'fields'));
+ }
+
+ if ($legend === true) {
+ $actionName = __d('cake', 'New %s');
+ $isEdit = (
+ strpos($this->request->params['action'], 'update') !== false ||
+ strpos($this->request->params['action'], 'edit') !== false
+ );
+ if ($isEdit) {
+ $actionName = __d('cake', 'Edit %s');
+ }
+ $modelName = Inflector::humanize(Inflector::underscore($model));
+ $legend = sprintf($actionName, __($modelName));
+ }
+
+ $out = null;
+ foreach ($fields as $name => $options) {
+ if (is_numeric($name) && !is_array($options)) {
+ $name = $options;
+ $options = array();
+ }
+ $entity = explode('.', $name);
+ $blacklisted = (
+ is_array($blacklist) &&
+ (in_array($name, $blacklist) || in_array(end($entity), $blacklist))
+ );
+ if ($blacklisted) {
+ continue;
+ }
+ $out .= $this->input($name, $options);
+ }
+
+ if (is_string($fieldset)) {
+ $fieldsetClass = sprintf(' class="%s"', $fieldset);
+ } else {
+ $fieldsetClass = '';
+ }
+
+ if ($fieldset && $legend) {
+ return $this->Html->useTag('fieldset', $fieldsetClass, $this->Html->useTag('legend', $legend) . $out);
+ } elseif ($fieldset) {
+ return $this->Html->useTag('fieldset', $fieldsetClass, $out);
+ } else {
+ return $out;
+ }
+ }
+
+/**
+ * Generates a form input element complete with label and wrapper div
+ *
+ * ### Options
+ *
+ * See each field type method for more information. Any options that are part of
+ * $attributes or $options for the different **type** methods can be included in `$options` for input().i
+ * Additionally, any unknown keys that are not in the list below, or part of the selected type's options
+ * will be treated as a regular html attribute for the generated input.
+ *
+ * - `type` - Force the type of widget you want. e.g. `type => 'select'`
+ * - `label` - Either a string label, or an array of options for the label. See FormHelper::label()
+ * - `div` - Either `false` to disable the div, or an array of options for the div.
+ * See HtmlHelper::div() for more options.
+ * - `options` - for widgets that take options e.g. radio, select
+ * - `error` - control the error message that is produced
+ * - `empty` - String or boolean to enable empty select box options.
+ * - `before` - Content to place before the label + input.
+ * - `after` - Content to place after the label + input.
+ * - `between` - Content to place between the label + input.
+ * - `format` - format template for element order. Any element that is not in the array, will not be in the output.
+ * - Default input format order: array('before', 'label', 'between', 'input', 'after', 'error')
+ * - Default checkbox format order: array('before', 'input', 'between', 'label', 'after', 'error')
+ * - Hidden input will not be formatted
+ * - Radio buttons cannot have the order of input and label elements controlled with these settings.
+ *
+ * @param string $fieldName This should be "Modelname.fieldname"
+ * @param array $options Each type of input takes different options.
+ * @return string Completed form widget.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#creating-form-elements
+ */
+ public function input($fieldName, $options = array()) {
+ $this->setEntity($fieldName);
+
+ $options = array_merge(
+ array('before' => null, 'between' => null, 'after' => null, 'format' => null),
+ $this->_inputDefaults,
+ $options
+ );
+
+ $modelKey = $this->model();
+ $fieldKey = $this->field();
+
+ if (!isset($options['type'])) {
+ $magicType = true;
+ $options['type'] = 'text';
+ if (isset($options['options'])) {
+ $options['type'] = 'select';
+ } elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) {
+ $options['type'] = 'password';
+ } elseif (isset($options['checked'])) {
+ $options['type'] = 'checkbox';
+ } elseif ($fieldDef = $this->_introspectModel($modelKey, 'fields', $fieldKey)) {
+ $type = $fieldDef['type'];
+ $primaryKey = $this->fieldset[$modelKey]['key'];
+ }
+
+ if (isset($type)) {
+ $map = array(
+ 'string' => 'text', 'datetime' => 'datetime',
+ 'boolean' => 'checkbox', 'timestamp' => 'datetime',
+ 'text' => 'textarea', 'time' => 'time',
+ 'date' => 'date', 'float' => 'number',
+ 'integer' => 'number'
+ );
+
+ if (isset($this->map[$type])) {
+ $options['type'] = $this->map[$type];
+ } elseif (isset($map[$type])) {
+ $options['type'] = $map[$type];
+ }
+ if ($fieldKey == $primaryKey) {
+ $options['type'] = 'hidden';
+ }
+ if (
+ $options['type'] === 'number' &&
+ $type === 'float' &&
+ !isset($options['step'])
+ ) {
+ $options['step'] = 'any';
+ }
+ }
+ if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') {
+ $options['type'] = 'select';
+ }
+
+ if ($modelKey === $fieldKey) {
+ $options['type'] = 'select';
+ if (!isset($options['multiple'])) {
+ $options['multiple'] = 'multiple';
+ }
+ }
+ }
+ $types = array('checkbox', 'radio', 'select');
+
+ if (
+ (!isset($options['options']) && in_array($options['type'], $types)) ||
+ (isset($magicType) && $options['type'] == 'text')
+ ) {
+ $varName = Inflector::variable(
+ Inflector::pluralize(preg_replace('/_id$/', '', $fieldKey))
+ );
+ $varOptions = $this->_View->getVar($varName);
+ if (is_array($varOptions)) {
+ if ($options['type'] !== 'radio') {
+ $options['type'] = 'select';
+ }
+ $options['options'] = $varOptions;
+ }
+ }
+
+ $autoLength = (!array_key_exists('maxlength', $options) && isset($fieldDef['length']));
+ if ($autoLength && $options['type'] == 'text') {
+ $options['maxlength'] = $fieldDef['length'];
+ }
+ if ($autoLength && $fieldDef['type'] == 'float') {
+ $options['maxlength'] = array_sum(explode(',', $fieldDef['length'])) + 1;
+ }
+
+ $divOptions = array();
+ $div = $this->_extractOption('div', $options, true);
+ unset($options['div']);
+
+ if (!empty($div)) {
+ $divOptions['class'] = 'input';
+ $divOptions = $this->addClass($divOptions, $options['type']);
+ if (is_string($div)) {
+ $divOptions['class'] = $div;
+ } elseif (is_array($div)) {
+ $divOptions = array_merge($divOptions, $div);
+ }
+ if ($this->_introspectModel($modelKey, 'validates', $fieldKey)) {
+ $divOptions = $this->addClass($divOptions, 'required');
+ }
+ if (!isset($divOptions['tag'])) {
+ $divOptions['tag'] = 'div';
+ }
+ }
+
+ $label = null;
+ if (isset($options['label']) && $options['type'] !== 'radio') {
+ $label = $options['label'];
+ unset($options['label']);
+ }
+
+ if ($options['type'] === 'radio') {
+ $label = false;
+ if (isset($options['options'])) {
+ $radioOptions = (array)$options['options'];
+ unset($options['options']);
+ }
+ }
+
+ if ($label !== false) {
+ $label = $this->_inputLabel($fieldName, $label, $options);
+ }
+
+ $error = $this->_extractOption('error', $options, null);
+ unset($options['error']);
+
+ $selected = $this->_extractOption('selected', $options, null);
+ unset($options['selected']);
+
+ if (isset($options['rows']) || isset($options['cols'])) {
+ $options['type'] = 'textarea';
+ }
+
+ if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time' || $options['type'] === 'select') {
+ $options += array('empty' => false);
+ }
+ if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time') {
+ $dateFormat = $this->_extractOption('dateFormat', $options, 'MDY');
+ $timeFormat = $this->_extractOption('timeFormat', $options, 12);
+ unset($options['dateFormat'], $options['timeFormat']);
+ }
+
+ $type = $options['type'];
+ $out = array_merge(
+ array('before' => null, 'label' => null, 'between' => null, 'input' => null, 'after' => null, 'error' => null),
+ array('before' => $options['before'], 'label' => $label, 'between' => $options['between'], 'after' => $options['after'])
+ );
+ $format = null;
+ if (is_array($options['format']) && in_array('input', $options['format'])) {
+ $format = $options['format'];
+ }
+ unset($options['type'], $options['before'], $options['between'], $options['after'], $options['format']);
+
+ switch ($type) {
+ case 'hidden':
+ $input = $this->hidden($fieldName, $options);
+ $format = array('input');
+ unset($divOptions);
+ break;
+ case 'checkbox':
+ $input = $this->checkbox($fieldName, $options);
+ $format = $format ? $format : array('before', 'input', 'between', 'label', 'after', 'error');
+ break;
+ case 'radio':
+ if (isset($out['between'])) {
+ $options['between'] = $out['between'];
+ $out['between'] = null;
+ }
+ $input = $this->radio($fieldName, $radioOptions, $options);
+ break;
+ case 'file':
+ $input = $this->file($fieldName, $options);
+ break;
+ case 'select':
+ $options += array('options' => array(), 'value' => $selected);
+ $list = $options['options'];
+ unset($options['options']);
+ $input = $this->select($fieldName, $list, $options);
+ break;
+ case 'time':
+ $options['value'] = $selected;
+ $input = $this->dateTime($fieldName, null, $timeFormat, $options);
+ break;
+ case 'date':
+ $options['value'] = $selected;
+ $input = $this->dateTime($fieldName, $dateFormat, null, $options);
+ break;
+ case 'datetime':
+ $options['value'] = $selected;
+ $input = $this->dateTime($fieldName, $dateFormat, $timeFormat, $options);
+ break;
+ case 'textarea':
+ $input = $this->textarea($fieldName, $options + array('cols' => '30', 'rows' => '6'));
+ break;
+ case 'url':
+ $input = $this->text($fieldName, array('type' => 'url') + $options);
+ break;
+ default:
+ $input = $this->{$type}($fieldName, $options);
+ }
+
+ if ($type != 'hidden' && $error !== false) {
+ $errMsg = $this->error($fieldName, $error);
+ if ($errMsg) {
+ $divOptions = $this->addClass($divOptions, 'error');
+ $out['error'] = $errMsg;
+ }
+ }
+
+ $out['input'] = $input;
+ $format = $format ? $format : array('before', 'label', 'between', 'input', 'after', 'error');
+ $output = '';
+ foreach ($format as $element) {
+ $output .= $out[$element];
+ unset($out[$element]);
+ }
+
+ if (!empty($divOptions['tag'])) {
+ $tag = $divOptions['tag'];
+ unset($divOptions['tag']);
+ $output = $this->Html->tag($tag, $output, $divOptions);
+ }
+ return $output;
+ }
+
+/**
+ * Extracts a single option from an options array.
+ *
+ * @param string $name The name of the option to pull out.
+ * @param array $options The array of options you want to extract.
+ * @param mixed $default The default option value
+ * @return mixed the contents of the option or default
+ */
+ protected function _extractOption($name, $options, $default = null) {
+ if (array_key_exists($name, $options)) {
+ return $options[$name];
+ }
+ return $default;
+ }
+
+/**
+ * Generate a label for an input() call.
+ *
+ * $options can contain a hash of id overrides. These overrides will be
+ * used instead of the generated values if present.
+ *
+ * @param string $fieldName
+ * @param string $label
+ * @param array $options Options for the label element.
+ * @return string Generated label element
+ * @deprecated 'NONE' option is deprecated and will be removed in 3.0
+ */
+ protected function _inputLabel($fieldName, $label, $options) {
+ $labelAttributes = $this->domId(array(), 'for');
+ $idKey = null;
+ if ($options['type'] === 'date' || $options['type'] === 'datetime') {
+ $firstInput = 'M';
+ if (
+ array_key_exists('dateFormat', $options) &&
+ ($options['dateFormat'] === null || $options['dateFormat'] === 'NONE')
+ ) {
+ $firstInput = 'H';
+ } elseif (!empty($options['dateFormat'])) {
+ $firstInput = substr($options['dateFormat'], 0, 1);
+ }
+ switch ($firstInput) {
+ case 'D':
+ $idKey = 'day';
+ $labelAttributes['for'] .= 'Day';
+ break;
+ case 'Y':
+ $idKey = 'year';
+ $labelAttributes['for'] .= 'Year';
+ break;
+ case 'M':
+ $idKey = 'month';
+ $labelAttributes['for'] .= 'Month';
+ break;
+ case 'H':
+ $idKey = 'hour';
+ $labelAttributes['for'] .= 'Hour';
+ }
+ }
+ if ($options['type'] === 'time') {
+ $labelAttributes['for'] .= 'Hour';
+ $idKey = 'hour';
+ }
+ if (isset($idKey) && isset($options['id']) && isset($options['id'][$idKey])) {
+ $labelAttributes['for'] = $options['id'][$idKey];
+ }
+
+ if (is_array($label)) {
+ $labelText = null;
+ if (isset($label['text'])) {
+ $labelText = $label['text'];
+ unset($label['text']);
+ }
+ $labelAttributes = array_merge($labelAttributes, $label);
+ } else {
+ $labelText = $label;
+ }
+
+ if (isset($options['id']) && is_string($options['id'])) {
+ $labelAttributes = array_merge($labelAttributes, array('for' => $options['id']));
+ }
+ return $this->label($fieldName, $labelText, $labelAttributes);
+ }
+
+/**
+ * Creates a checkbox input widget.
+ *
+ * ### Options:
+ *
+ * - `value` - the value of the checkbox
+ * - `checked` - boolean indicate that this checkbox is checked.
+ * - `hiddenField` - boolean to indicate if you want the results of checkbox() to include
+ * a hidden input with a value of ''.
+ * - `disabled` - create a disabled input.
+ * - `default` - Set the default value for the checkbox. This allows you to start checkboxes
+ * as checked, without having to check the POST data. A matching POST data value, will overwrite
+ * the default value.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname.fieldname"
+ * @param array $options Array of HTML attributes.
+ * @return string An HTML text input element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-select-checkbox-and-radio-inputs
+ */
+ public function checkbox($fieldName, $options = array()) {
+ $valueOptions = array();
+ if (isset($options['default'])) {
+ $valueOptions['default'] = $options['default'];
+ unset($options['default']);
+ }
+
+ $options = $this->_initInputField($fieldName, $options) + array('hiddenField' => true);
+ $value = current($this->value($valueOptions));
+ $output = "";
+
+ if (empty($options['value'])) {
+ $options['value'] = 1;
+ }
+ if (
+ (!isset($options['checked']) && !empty($value) && $value == $options['value']) ||
+ !empty($options['checked'])
+ ) {
+ $options['checked'] = 'checked';
+ }
+ if ($options['hiddenField']) {
+ $hiddenOptions = array(
+ 'id' => $options['id'] . '_',
+ 'name' => $options['name'],
+ 'value' => ($options['hiddenField'] !== true ? $options['hiddenField'] : '0'),
+ 'secure' => false
+ );
+ if (isset($options['disabled']) && $options['disabled'] == true) {
+ $hiddenOptions['disabled'] = 'disabled';
+ }
+ $output = $this->hidden($fieldName, $hiddenOptions);
+ }
+ unset($options['hiddenField']);
+
+ return $output . $this->Html->useTag('checkbox', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates a set of radio widgets. Will create a legend and fieldset
+ * by default. Use $options to control this
+ *
+ * ### Attributes:
+ *
+ * - `separator` - define the string in between the radio buttons
+ * - `between` - the string between legend and input set
+ * - `legend` - control whether or not the widget set has a fieldset & legend
+ * - `value` - indicate a value that is should be checked
+ * - `label` - boolean to indicate whether or not labels for widgets show be displayed
+ * - `hiddenField` - boolean to indicate if you want the results of radio() to include
+ * a hidden input with a value of ''. This is useful for creating radio sets that non-continuous
+ * - `disabled` - Set to `true` or `disabled` to disable all the radio buttons.
+ * - `empty` - Set to `true` to create a input with the value '' as the first option. When `true`
+ * the radio label will be 'empty'. Set this option to a string to control the label value.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname.fieldname"
+ * @param array $options Radio button options array.
+ * @param array $attributes Array of HTML attributes, and special attributes above.
+ * @return string Completed radio widget set.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-select-checkbox-and-radio-inputs
+ */
+ public function radio($fieldName, $options = array(), $attributes = array()) {
+ $attributes = $this->_initInputField($fieldName, $attributes);
+
+ $showEmpty = $this->_extractOption('empty', $attributes);
+ if ($showEmpty) {
+ $showEmpty = ($showEmpty === true) ? __('empty') : $showEmpty;
+ $options = array('' => $showEmpty) + $options;
+ }
+ unset($attributes['empty']);
+
+ $legend = false;
+ if (isset($attributes['legend'])) {
+ $legend = $attributes['legend'];
+ unset($attributes['legend']);
+ } elseif (count($options) > 1) {
+ $legend = __(Inflector::humanize($this->field()));
+ }
+
+ $label = true;
+ if (isset($attributes['label'])) {
+ $label = $attributes['label'];
+ unset($attributes['label']);
+ }
+
+ $separator = null;
+ if (isset($attributes['separator'])) {
+ $separator = $attributes['separator'];
+ unset($attributes['separator']);
+ }
+
+ $between = null;
+ if (isset($attributes['between'])) {
+ $between = $attributes['between'];
+ unset($attributes['between']);
+ }
+
+ $value = null;
+ if (isset($attributes['value'])) {
+ $value = $attributes['value'];
+ } else {
+ $value = $this->value($fieldName);
+ }
+
+ $disabled = array();
+ if (isset($attributes['disabled'])) {
+ $disabled = $attributes['disabled'];
+ }
+
+ $out = array();
+
+ $hiddenField = isset($attributes['hiddenField']) ? $attributes['hiddenField'] : true;
+ unset($attributes['hiddenField']);
+
+ foreach ($options as $optValue => $optTitle) {
+ $optionsHere = array('value' => $optValue);
+
+ if (isset($value) && $optValue == $value) {
+ $optionsHere['checked'] = 'checked';
+ }
+ if ($disabled && (!is_array($disabled) || in_array($optValue, $disabled))) {
+ $optionsHere['disabled'] = true;
+ }
+ $tagName = Inflector::camelize(
+ $attributes['id'] . '_' . Inflector::slug($optValue)
+ );
+
+ if ($label) {
+ $optTitle = $this->Html->useTag('label', $tagName, '', $optTitle);
+ }
+ $allOptions = array_merge($attributes, $optionsHere);
+ $out[] = $this->Html->useTag('radio', $attributes['name'], $tagName,
+ array_diff_key($allOptions, array('name' => '', 'type' => '', 'id' => '')),
+ $optTitle
+ );
+ }
+ $hidden = null;
+
+ if ($hiddenField) {
+ if (!isset($value) || $value === '') {
+ $hidden = $this->hidden($fieldName, array(
+ 'id' => $attributes['id'] . '_', 'value' => '', 'name' => $attributes['name']
+ ));
+ }
+ }
+ $out = $hidden . implode($separator, $out);
+
+ if ($legend) {
+ $out = $this->Html->useTag('fieldset', '', $this->Html->useTag('legend', $legend) . $between . $out);
+ }
+ return $out;
+ }
+
+/**
+ * Missing method handler - implements various simple input types. Is used to create inputs
+ * of various types. e.g. `$this->Form->text();` will create `<input type="text" />` while
+ * `$this->Form->range();` will create `<input type="range" />`
+ *
+ * ### Usage
+ *
+ * `$this->Form->search('User.query', array('value' => 'test'));`
+ *
+ * Will make an input like:
+ *
+ * `<input type="search" id="UserQuery" name="data[User][query]" value="test" />`
+ *
+ * The first argument to an input type should always be the fieldname, in `Model.field` format.
+ * The second argument should always be an array of attributes for the input.
+ *
+ * @param string $method Method name / input type to make.
+ * @param array $params Parameters for the method call
+ * @return string Formatted input method.
+ * @throws CakeException When there are no params for the method call.
+ */
+ public function __call($method, $params) {
+ $options = array();
+ if (empty($params)) {
+ throw new CakeException(__d('cake_dev', 'Missing field name for FormHelper::%s', $method));
+ }
+ if (isset($params[1])) {
+ $options = $params[1];
+ }
+ if (!isset($options['type'])) {
+ $options['type'] = $method;
+ }
+ $options = $this->_initInputField($params[0], $options);
+ return $this->Html->useTag('input', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates a textarea widget.
+ *
+ * ### Options:
+ *
+ * - `escape` - Whether or not the contents of the textarea should be escaped. Defaults to true.
+ *
+ * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
+ * @param array $options Array of HTML attributes, and special options above.
+ * @return string A generated HTML text input element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::textarea
+ */
+ public function textarea($fieldName, $options = array()) {
+ $options = $this->_initInputField($fieldName, $options);
+ $value = null;
+
+ if (array_key_exists('value', $options)) {
+ $value = $options['value'];
+ if (!array_key_exists('escape', $options) || $options['escape'] !== false) {
+ $value = h($value);
+ }
+ unset($options['value']);
+ }
+ return $this->Html->useTag('textarea', $options['name'], array_diff_key($options, array('type' => '', 'name' => '')), $value);
+ }
+
+/**
+ * Creates a hidden input field.
+ *
+ * @param string $fieldName Name of a field, in the form of "Modelname.fieldname"
+ * @param array $options Array of HTML attributes.
+ * @return string A generated hidden input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::hidden
+ */
+ public function hidden($fieldName, $options = array()) {
+ $secure = true;
+
+ if (isset($options['secure'])) {
+ $secure = $options['secure'];
+ unset($options['secure']);
+ }
+ $options = $this->_initInputField($fieldName, array_merge(
+ $options, array('secure' => self::SECURE_SKIP)
+ ));
+
+ if ($secure && $secure !== self::SECURE_SKIP) {
+ $this->_secure(true, null, '' . $options['value']);
+ }
+
+ return $this->Html->useTag('hidden', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates file input widget.
+ *
+ * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
+ * @param array $options Array of HTML attributes.
+ * @return string A generated file input.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::file
+ */
+ public function file($fieldName, $options = array()) {
+ $options += array('secure' => true);
+ $secure = $options['secure'];
+ $options['secure'] = self::SECURE_SKIP;
+
+ $options = $this->_initInputField($fieldName, $options);
+ $field = $this->entity();
+
+ foreach (array('name', 'type', 'tmp_name', 'error', 'size') as $suffix) {
+ $this->_secure($secure, array_merge($field, array($suffix)));
+ }
+
+ return $this->Html->useTag('file', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates a `<button>` tag. The type attribute defaults to `type="submit"`
+ * You can change it to a different value by using `$options['type']`.
+ *
+ * ### Options:
+ *
+ * - `escape` - HTML entity encode the $title of the button. Defaults to false.
+ *
+ * @param string $title The button's caption. Not automatically HTML encoded
+ * @param array $options Array of options and HTML attributes.
+ * @return string A HTML button tag.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::button
+ */
+ public function button($title, $options = array()) {
+ $options += array('type' => 'submit', 'escape' => false, 'secure' => false);
+ if ($options['escape']) {
+ $title = h($title);
+ }
+ if (isset($options['name'])) {
+ $name = str_replace(array('[', ']'), array('.', ''), $options['name']);
+ $this->_secure($options['secure'], $name);
+ }
+ return $this->Html->useTag('button', $options, $title);
+ }
+
+/**
+ * Create a `<button>` tag with a surrounding `<form>` that submits via POST.
+ *
+ * This method creates a `<form>` element. So do not use this method in an already opened form.
+ * Instead use FormHelper::submit() or FormHelper::button() to create buttons inside opened forms.
+ *
+ * ### Options:
+ *
+ * - `data` - Array with key/value to pass in input hidden
+ * - Other options is the same of button method.
+ *
+ * @param string $title The button's caption. Not automatically HTML encoded
+ * @param string|array $url URL as string or array
+ * @param array $options Array of options and HTML attributes.
+ * @return string A HTML button tag.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::postButton
+ */
+ public function postButton($title, $url, $options = array()) {
+ $out = $this->create(false, array('id' => false, 'url' => $url));
+ if (isset($options['data']) && is_array($options['data'])) {
+ foreach ($options['data'] as $key => $value) {
+ $out .= $this->hidden($key, array('value' => $value, 'id' => false));
+ }
+ unset($options['data']);
+ }
+ $out .= $this->button($title, $options);
+ $out .= $this->end();
+ return $out;
+ }
+
+/**
+ * Creates an HTML link, but access the url using method POST.
+ * Requires javascript to be enabled in browser.
+ *
+ * This method creates a `<form>` element. So do not use this method inside an existing form.
+ * Instead you should add a submit button using FormHelper::submit()
+ *
+ * ### Options:
+ *
+ * - `data` - Array with key/value to pass in input hidden
+ * - `confirm` - Can be used instead of $confirmMessage.
+ * - Other options is the same of HtmlHelper::link() method.
+ * - The option `onclick` will be replaced.
+ *
+ * @param string $title The content to be wrapped by <a> tags.
+ * @param string|array $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
+ * @param array $options Array of HTML attributes.
+ * @param string $confirmMessage JavaScript confirmation message.
+ * @return string An `<a />` element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::postLink
+ */
+ public function postLink($title, $url = null, $options = array(), $confirmMessage = false) {
+ if (!empty($options['confirm'])) {
+ $confirmMessage = $options['confirm'];
+ unset($options['confirm']);
+ }
+
+ $formName = uniqid('post_');
+ $formUrl = $this->url($url);
+ $out = $this->Html->useTag('form', $formUrl, array('name' => $formName, 'id' => $formName, 'style' => 'display:none;', 'method' => 'post'));
+ $out .= $this->Html->useTag('hidden', '_method', ' value="POST"');
+ $out .= $this->_csrfField();
+
+ $fields = array();
+ if (isset($options['data']) && is_array($options['data'])) {
+ foreach ($options['data'] as $key => $value) {
+ $fields[$key] = $value;
+ $out .= $this->hidden($key, array('value' => $value, 'id' => false));
+ }
+ unset($options['data']);
+ }
+ $out .= $this->secure($fields);
+ $out .= $this->Html->useTag('formend');
+
+ $url = '#';
+ $onClick = 'document.' . $formName . '.submit();';
+ if ($confirmMessage) {
+ $confirmMessage = str_replace(array("'", '"'), array("\'", '\"'), $confirmMessage);
+ $options['onclick'] = "if (confirm('{$confirmMessage}')) { {$onClick} }";
+ } else {
+ $options['onclick'] = $onClick;
+ }
+ $options['onclick'] .= ' event.returnValue = false; return false;';
+
+ $out .= $this->Html->link($title, $url, $options);
+ return $out;
+ }
+
+/**
+ * Creates a submit button element. This method will generate `<input />` elements that
+ * can be used to submit, and reset forms by using $options. image submits can be created by supplying an
+ * image path for $caption.
+ *
+ * ### Options
+ *
+ * - `div` - Include a wrapping div? Defaults to true. Accepts sub options similar to
+ * FormHelper::input().
+ * - `before` - Content to include before the input.
+ * - `after` - Content to include after the input.
+ * - `type` - Set to 'reset' for reset inputs. Defaults to 'submit'
+ * - Other attributes will be assigned to the input element.
+ *
+ * ### Options
+ *
+ * - `div` - Include a wrapping div? Defaults to true. Accepts sub options similar to
+ * FormHelper::input().
+ * - Other attributes will be assigned to the input element.
+ *
+ * @param string $caption The label appearing on the button OR if string contains :// or the
+ * extension .jpg, .jpe, .jpeg, .gif, .png use an image if the extension
+ * exists, AND the first character is /, image is relative to webroot,
+ * OR if the first character is not /, image is relative to webroot/img.
+ * @param array $options Array of options. See above.
+ * @return string A HTML submit button
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::submit
+ */
+ public function submit($caption = null, $options = array()) {
+ if (!is_string($caption) && empty($caption)) {
+ $caption = __d('cake', 'Submit');
+ }
+ $out = null;
+ $div = true;
+
+ if (isset($options['div'])) {
+ $div = $options['div'];
+ unset($options['div']);
+ }
+ $options += array('type' => 'submit', 'before' => null, 'after' => null, 'secure' => false);
+ $divOptions = array('tag' => 'div');
+
+ if ($div === true) {
+ $divOptions['class'] = 'submit';
+ } elseif ($div === false) {
+ unset($divOptions);
+ } elseif (is_string($div)) {
+ $divOptions['class'] = $div;
+ } elseif (is_array($div)) {
+ $divOptions = array_merge(array('class' => 'submit', 'tag' => 'div'), $div);
+ }
+
+ if (isset($options['name'])) {
+ $name = str_replace(array('[', ']'), array('.', ''), $options['name']);
+ $this->_secure($options['secure'], $name);
+ }
+ unset($options['secure']);
+
+ $before = $options['before'];
+ $after = $options['after'];
+ unset($options['before'], $options['after']);
+
+ $isUrl = strpos($caption, '://') !== false;
+ $isImage = preg_match('/\.(jpg|jpe|jpeg|gif|png|ico)$/', $caption);
+
+ if ($isUrl || $isImage) {
+ $unlockFields = array('x', 'y');
+ if (isset($options['name'])) {
+ $unlockFields = array(
+ $options['name'] . '_x', $options['name'] . '_y'
+ );
+ }
+ foreach ($unlockFields as $ignore) {
+ $this->unlockField($ignore);
+ }
+ }
+
+ if ($isUrl) {
+ unset($options['type']);
+ $tag = $this->Html->useTag('submitimage', $caption, $options);
+ } elseif ($isImage) {
+ unset($options['type']);
+ if ($caption{0} !== '/') {
+ $url = $this->webroot(IMAGES_URL . $caption);
+ } else {
+ $url = $this->webroot(trim($caption, '/'));
+ }
+ $url = $this->assetTimestamp($url);
+ $tag = $this->Html->useTag('submitimage', $url, $options);
+ } else {
+ $options['value'] = $caption;
+ $tag = $this->Html->useTag('submit', $options);
+ }
+ $out = $before . $tag . $after;
+
+ if (isset($divOptions)) {
+ $tag = $divOptions['tag'];
+ unset($divOptions['tag']);
+ $out = $this->Html->tag($tag, $out, $divOptions);
+ }
+ return $out;
+ }
+
+/**
+ * Returns a formatted SELECT element.
+ *
+ * ### Attributes:
+ *
+ * - `showParents` - If included in the array and set to true, an additional option element
+ * will be added for the parent of each option group. You can set an option with the same name
+ * and it's key will be used for the value of the option.
+ * - `multiple` - show a multiple select box. If set to 'checkbox' multiple checkboxes will be
+ * created instead.
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `escape` - If true contents of options will be HTML entity encoded. Defaults to true.
+ * - `value` The selected value of the input.
+ * - `class` - When using multiple = checkbox the classname to apply to the divs. Defaults to 'checkbox'.
+ *
+ * ### Using options
+ *
+ * A simple array will create normal options:
+ *
+ * {{{
+ * $options = array(1 => 'one', 2 => 'two);
+ * $this->Form->select('Model.field', $options));
+ * }}}
+ *
+ * While a nested options array will create optgroups with options inside them.
+ * {{{
+ * $options = array(
+ * 1 => 'bill',
+ * 'fred' => array(
+ * 2 => 'fred',
+ * 3 => 'fred jr.'
+ * )
+ * );
+ * $this->Form->select('Model.field', $options);
+ * }}}
+ *
+ * In the above `2 => 'fred'` will not generate an option element. You should enable the `showParents`
+ * attribute to show the fred option.
+ *
+ * If you have multiple options that need to have the same value attribute, you can
+ * use an array of arrays to express this:
+ *
+ * {{{
+ * $options = array(
+ * array('name' => 'United states', 'value' => 'USA'),
+ * array('name' => 'USA', 'value' => 'USA'),
+ * );
+ * }}}
+ *
+ * @param string $fieldName Name attribute of the SELECT
+ * @param array $options Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the
+ * SELECT element
+ * @param array $attributes The HTML attributes of the select element.
+ * @return string Formatted SELECT element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-select-checkbox-and-radio-inputs
+ */
+ public function select($fieldName, $options = array(), $attributes = array()) {
+ $select = array();
+ $style = null;
+ $tag = null;
+ $attributes += array(
+ 'class' => null,
+ 'escape' => true,
+ 'secure' => true,
+ 'empty' => '',
+ 'showParents' => false,
+ 'hiddenField' => true
+ );
+
+ $escapeOptions = $this->_extractOption('escape', $attributes);
+ $secure = $this->_extractOption('secure', $attributes);
+ $showEmpty = $this->_extractOption('empty', $attributes);
+ $showParents = $this->_extractOption('showParents', $attributes);
+ $hiddenField = $this->_extractOption('hiddenField', $attributes);
+ unset($attributes['escape'], $attributes['secure'], $attributes['empty'], $attributes['showParents'], $attributes['hiddenField']);
+ $id = $this->_extractOption('id', $attributes);
+
+ $attributes = $this->_initInputField($fieldName, array_merge(
+ (array)$attributes, array('secure' => self::SECURE_SKIP)
+ ));
+
+ if (is_string($options) && isset($this->_options[$options])) {
+ $options = $this->_generateOptions($options);
+ } elseif (!is_array($options)) {
+ $options = array();
+ }
+ if (isset($attributes['type'])) {
+ unset($attributes['type']);
+ }
+
+ if (!empty($attributes['multiple'])) {
+ $style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null;
+ $template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart';
+ $tag = $template;
+ if ($hiddenField) {
+ $hiddenAttributes = array(
+ 'value' => '',
+ 'id' => $attributes['id'] . ($style ? '' : '_'),
+ 'secure' => false,
+ 'name' => $attributes['name']
+ );
+ $select[] = $this->hidden(null, $hiddenAttributes);
+ }
+ } else {
+ $tag = 'selectstart';
+ }
+
+ if (!empty($tag) || isset($template)) {
+ if ((!isset($secure) || $secure == true) && empty($attributes['disabled'])) {
+ $this->_secure(true);
+ }
+ $select[] = $this->Html->useTag($tag, $attributes['name'], array_diff_key($attributes, array('name' => '', 'value' => '')));
+ }
+ $emptyMulti = (
+ $showEmpty !== null && $showEmpty !== false && !(
+ empty($showEmpty) && (isset($attributes) &&
+ array_key_exists('multiple', $attributes))
+ )
+ );
+
+ if ($emptyMulti) {
+ $showEmpty = ($showEmpty === true) ? '' : $showEmpty;
+ $options = array('' => $showEmpty) + $options;
+ }
+
+ if (!$id) {
+ $attributes['id'] = Inflector::camelize($attributes['id']);
+ }
+
+ $select = array_merge($select, $this->_selectOptions(
+ array_reverse($options, true),
+ array(),
+ $showParents,
+ array(
+ 'escape' => $escapeOptions,
+ 'style' => $style,
+ 'name' => $attributes['name'],
+ 'value' => $attributes['value'],
+ 'class' => $attributes['class'],
+ 'id' => $attributes['id']
+ )
+ ));
+
+ $template = ($style == 'checkbox') ? 'checkboxmultipleend' : 'selectend';
+ $select[] = $this->Html->useTag($template);
+ return implode("\n", $select);
+ }
+
+/**
+ * Returns a SELECT element for days.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param array $attributes HTML attributes for the select element
+ * @return string A generated day select box.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::day
+ */
+ public function day($fieldName = null, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('day', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ $attributes['value'] = date('d', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ return $this->select($fieldName . ".day", $this->_generateOptions('day'), $attributes);
+ }
+
+/**
+ * Returns a SELECT element for years
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `orderYear` - Ordering of year values in select options.
+ * Possible values 'asc', 'desc'. Default 'desc'
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param integer $minYear First year in sequence
+ * @param integer $maxYear Last year in sequence
+ * @param array $attributes Attribute array for the select elements.
+ * @return string Completed year select input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::year
+ */
+ public function year($fieldName, $minYear = null, $maxYear = null, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ if ((empty($attributes['value']) || $attributes['value'] === true) && $value = $this->value($fieldName)) {
+ if (is_array($value)) {
+ extract($value);
+ $attributes['value'] = $year;
+ } else {
+ if (empty($value)) {
+ if (!$attributes['empty'] && !$maxYear) {
+ $attributes['value'] = 'now';
+
+ } elseif (!$attributes['empty'] && $maxYear && !$attributes['value']) {
+ $attributes['value'] = $maxYear;
+ }
+ } else {
+ $attributes['value'] = $value;
+ }
+ }
+ }
+
+ if (strlen($attributes['value']) > 4 || $attributes['value'] === 'now') {
+ $attributes['value'] = date('Y', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ $yearOptions = array('min' => $minYear, 'max' => $maxYear, 'order' => 'desc');
+ if (isset($attributes['orderYear'])) {
+ $yearOptions['order'] = $attributes['orderYear'];
+ unset($attributes['orderYear']);
+ }
+ return $this->select(
+ $fieldName . '.year', $this->_generateOptions('year', $yearOptions),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a SELECT element for months.
+ *
+ * ### Attributes:
+ *
+ * - `monthNames` - If false, 2 digit numbers will be used instead of text.
+ * If a array, the given array will be used.
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param array $attributes Attributes for the select element
+ * @return string A generated month select dropdown.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::month
+ */
+ public function month($fieldName, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('month', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ $attributes['value'] = date('m', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ $defaults = array('monthNames' => true);
+ $attributes = array_merge($defaults, (array)$attributes);
+ $monthNames = $attributes['monthNames'];
+ unset($attributes['monthNames']);
+
+ return $this->select(
+ $fieldName . ".month",
+ $this->_generateOptions('month', array('monthNames' => $monthNames)),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a SELECT element for hours.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param boolean $format24Hours True for 24 hours format
+ * @param array $attributes List of HTML attributes
+ * @return string Completed hour select input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::hour
+ */
+ public function hour($fieldName, $format24Hours = false, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('hour', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ if ($format24Hours) {
+ $attributes['value'] = date('H', strtotime($attributes['value']));
+ } else {
+ $attributes['value'] = date('g', strtotime($attributes['value']));
+ }
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ return $this->select(
+ $fieldName . ".hour",
+ $this->_generateOptions($format24Hours ? 'hour24' : 'hour'),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a SELECT element for minutes.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param string $attributes Array of Attributes
+ * @return string Completed minute select input.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::minute
+ */
+ public function minute($fieldName, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('min', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ $attributes['value'] = date('i', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ $minuteOptions = array();
+
+ if (isset($attributes['interval'])) {
+ $minuteOptions['interval'] = $attributes['interval'];
+ unset($attributes['interval']);
+ }
+ return $this->select(
+ $fieldName . ".min", $this->_generateOptions('minute', $minuteOptions),
+ $attributes
+ );
+ }
+
+/**
+ * Selects values for dateTime selects.
+ *
+ * @param string $select Name of element field. ex. 'day'
+ * @param string $fieldName Name of fieldName being generated ex. Model.created
+ * @param array $attributes Array of attributes, must contain 'empty' key.
+ * @return array Attributes array with currently selected value.
+ */
+ protected function _dateTimeSelected($select, $fieldName, $attributes) {
+ if ((empty($attributes['value']) || $attributes['value'] === true) && $value = $this->value($fieldName)) {
+ if (is_array($value) && isset($value[$select])) {
+ $attributes['value'] = $value[$select];
+ } else {
+ if (empty($value)) {
+ if (!$attributes['empty']) {
+ $attributes['value'] = 'now';
+ }
+ } else {
+ $attributes['value'] = $value;
+ }
+ }
+ }
+ return $attributes;
+ }
+
+/**
+ * Returns a SELECT element for AM or PM.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param string $attributes Array of Attributes
+ * @return string Completed meridian select input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::meridian
+ */
+ public function meridian($fieldName, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ if ((empty($attributes['value']) || $attributes['value'] === true) && $value = $this->value($fieldName)) {
+ if (is_array($value)) {
+ extract($value);
+ $attributes['value'] = $meridian;
+ } else {
+ if (empty($value)) {
+ if (!$attributes['empty']) {
+ $attributes['value'] = date('a');
+ }
+ } else {
+ $attributes['value'] = date('a', strtotime($value));
+ }
+ }
+ }
+
+ if ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ return $this->select(
+ $fieldName . ".meridian", $this->_generateOptions('meridian'),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a set of SELECT elements for a full datetime setup: day, month and year, and then time.
+ *
+ * ### Attributes:
+ *
+ * - `monthNames` If false, 2 digit numbers will be used instead of text.
+ * If a array, the given array will be used.
+ * - `minYear` The lowest year to use in the year select
+ * - `maxYear` The maximum year to use in the year select
+ * - `interval` The interval for the minutes select. Defaults to 1
+ * - `separator` The contents of the string between select elements. Defaults to '-'
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` | `default` The default value to be used by the input. A value in `$this->data`
+ * matching the field name will override this value. If no default is provided `time()` will be used.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param string $dateFormat DMY, MDY, YMD, or null to not generate date inputs.
+ * @param string $timeFormat 12, 24, or null to not generate time inputs.
+ * @param string $attributes array of Attributes
+ * @return string Generated set of select boxes for the date and time formats chosen.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::dateTime
+ */
+ public function dateTime($fieldName, $dateFormat = 'DMY', $timeFormat = '12', $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $year = $month = $day = $hour = $min = $meridian = null;
+
+ if (empty($attributes['value'])) {
+ $attributes = $this->value($attributes, $fieldName);
+ }
+
+ if ($attributes['value'] === null && $attributes['empty'] != true) {
+ $attributes['value'] = time();
+ }
+
+ if (!empty($attributes['value'])) {
+ if (is_array($attributes['value'])) {
+ extract($attributes['value']);
+ } else {
+ if (is_numeric($attributes['value'])) {
+ $attributes['value'] = strftime('%Y-%m-%d %H:%M:%S', $attributes['value']);
+ }
+ $meridian = 'am';
+ $pos = strpos($attributes['value'], '-');
+ if ($pos !== false) {
+ $date = explode('-', $attributes['value']);
+ $days = explode(' ', $date[2]);
+ $day = $days[0];
+ $month = $date[1];
+ $year = $date[0];
+ } else {
+ $days[1] = $attributes['value'];
+ }
+
+ if (!empty($timeFormat)) {
+ $time = explode(':', $days[1]);
+
+ if (($time[0] > 12) && $timeFormat == '12') {
+ $time[0] = $time[0] - 12;
+ $meridian = 'pm';
+ } elseif ($time[0] == '12' && $timeFormat == '12') {
+ $meridian = 'pm';
+ } elseif ($time[0] == '00' && $timeFormat == '12') {
+ $time[0] = 12;
+ } elseif ($time[0] >= 12) {
+ $meridian = 'pm';
+ }
+ if ($time[0] == 0 && $timeFormat == '12') {
+ $time[0] = 12;
+ }
+ $hour = $min = null;
+ if (isset($time[1])) {
+ $hour = $time[0];
+ $min = $time[1];
+ }
+ }
+ }
+ }
+
+ $elements = array('Day', 'Month', 'Year', 'Hour', 'Minute', 'Meridian');
+ $defaults = array(
+ 'minYear' => null, 'maxYear' => null, 'separator' => '-',
+ 'interval' => 1, 'monthNames' => true
+ );
+ $attributes = array_merge($defaults, (array)$attributes);
+ if (isset($attributes['minuteInterval'])) {
+ $attributes['interval'] = $attributes['minuteInterval'];
+ unset($attributes['minuteInterval']);
+ }
+ $minYear = $attributes['minYear'];
+ $maxYear = $attributes['maxYear'];
+ $separator = $attributes['separator'];
+ $interval = $attributes['interval'];
+ $monthNames = $attributes['monthNames'];
+ $attributes = array_diff_key($attributes, $defaults);
+
+ if (isset($attributes['id'])) {
+ if (is_string($attributes['id'])) {
+ // build out an array version
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $attributes;
+ ${$selectAttrName}['id'] = $attributes['id'] . $element;
+ }
+ } elseif (is_array($attributes['id'])) {
+ // check for missing ones and build selectAttr for each element
+ $attributes['id'] += array(
+ 'month' => '', 'year' => '', 'day' => '',
+ 'hour' => '', 'minute' => '', 'meridian' => ''
+ );
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $attributes;
+ ${$selectAttrName}['id'] = $attributes['id'][strtolower($element)];
+ }
+ }
+ } else {
+ // build the selectAttrName with empty id's to pass
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $attributes;
+ }
+ }
+
+ $selects = array();
+ foreach (preg_split('//', $dateFormat, -1, PREG_SPLIT_NO_EMPTY) as $char) {
+ switch ($char) {
+ case 'Y':
+ $selectYearAttr['value'] = $year;
+ $selects[] = $this->year(
+ $fieldName, $minYear, $maxYear, $selectYearAttr
+ );
+ break;
+ case 'M':
+ $selectMonthAttr['value'] = $month;
+ $selectMonthAttr['monthNames'] = $monthNames;
+ $selects[] = $this->month($fieldName, $selectMonthAttr);
+ break;
+ case 'D':
+ $selectDayAttr['value'] = $day;
+ $selects[] = $this->day($fieldName, $selectDayAttr);
+ break;
+ }
+ }
+ $opt = implode($separator, $selects);
+
+ if (!empty($interval) && $interval > 1 && !empty($min)) {
+ $min = round($min * (1 / $interval)) * $interval;
+ }
+ $selectMinuteAttr['interval'] = $interval;
+ switch ($timeFormat) {
+ case '24':
+ $selectHourAttr['value'] = $hour;
+ $selectMinuteAttr['value'] = $min;
+ $opt .= $this->hour($fieldName, true, $selectHourAttr) . ':' .
+ $this->minute($fieldName, $selectMinuteAttr);
+ break;
+ case '12':
+ $selectHourAttr['value'] = $hour;
+ $selectMinuteAttr['value'] = $min;
+ $selectMeridianAttr['value'] = $meridian;
+ $opt .= $this->hour($fieldName, false, $selectHourAttr) . ':' .
+ $this->minute($fieldName, $selectMinuteAttr) . ' ' .
+ $this->meridian($fieldName, $selectMeridianAttr);
+ break;
+ default:
+ $opt .= '';
+ break;
+ }
+ return $opt;
+ }
+
+/**
+ * Gets the input field name for the current tag
+ *
+ * @param array $options
+ * @param string $field
+ * @param string $key
+ * @return array
+ */
+ protected function _name($options = array(), $field = null, $key = 'name') {
+ if ($this->requestType == 'get') {
+ if ($options === null) {
+ $options = array();
+ } elseif (is_string($options)) {
+ $field = $options;
+ $options = 0;
+ }
+
+ if (!empty($field)) {
+ $this->setEntity($field);
+ }
+
+ if (is_array($options) && isset($options[$key])) {
+ return $options;
+ }
+
+ $entity = $this->entity();
+ $model = $this->model();
+ $name = $model === $entity[0] && isset($entity[1]) ? $entity[1] : $entity[0];
+ $last = $entity[count($entity) - 1];
+ if (in_array($last, $this->_fieldSuffixes)) {
+ $name .= '[' . $last . ']';
+ }
+
+ if (is_array($options)) {
+ $options[$key] = $name;
+ return $options;
+ } else {
+ return $name;
+ }
+ }
+ return parent::_name($options, $field, $key);
+ }
+
+/**
+ * Returns an array of formatted OPTION/OPTGROUP elements
+ *
+ * @param array $elements
+ * @param array $parents
+ * @param boolean $showParents
+ * @param array $attributes
+ * @return array
+ */
+ protected function _selectOptions($elements = array(), $parents = array(), $showParents = null, $attributes = array()) {
+ $select = array();
+ $attributes = array_merge(
+ array('escape' => true, 'style' => null, 'value' => null, 'class' => null),
+ $attributes
+ );
+ $selectedIsEmpty = ($attributes['value'] === '' || $attributes['value'] === null);
+ $selectedIsArray = is_array($attributes['value']);
+
+ foreach ($elements as $name => $title) {
+ $htmlOptions = array();
+ if (is_array($title) && (!isset($title['name']) || !isset($title['value']))) {
+ if (!empty($name)) {
+ if ($attributes['style'] === 'checkbox') {
+ $select[] = $this->Html->useTag('fieldsetend');
+ } else {
+ $select[] = $this->Html->useTag('optiongroupend');
+ }
+ $parents[] = $name;
+ }
+ $select = array_merge($select, $this->_selectOptions(
+ $title, $parents, $showParents, $attributes
+ ));
+
+ if (!empty($name)) {
+ $name = $attributes['escape'] ? h($name) : $name;
+ if ($attributes['style'] === 'checkbox') {
+ $select[] = $this->Html->useTag('fieldsetstart', $name);
+ } else {
+ $select[] = $this->Html->useTag('optiongroup', $name, '');
+ }
+ }
+ $name = null;
+ } elseif (is_array($title)) {
+ $htmlOptions = $title;
+ $name = $title['value'];
+ $title = $title['name'];
+ unset($htmlOptions['name'], $htmlOptions['value']);
+ }
+
+ if ($name !== null) {
+ if (
+ (!$selectedIsArray && !$selectedIsEmpty && (string)$attributes['value'] == (string)$name) ||
+ ($selectedIsArray && in_array($name, $attributes['value']))
+ ) {
+ if ($attributes['style'] === 'checkbox') {
+ $htmlOptions['checked'] = true;
+ } else {
+ $htmlOptions['selected'] = 'selected';
+ }
+ }
+
+ if ($showParents || (!in_array($title, $parents))) {
+ $title = ($attributes['escape']) ? h($title) : $title;
+
+ if ($attributes['style'] === 'checkbox') {
+ $htmlOptions['value'] = $name;
+
+ $tagName = $attributes['id'] . Inflector::camelize(Inflector::slug($name));
+ $htmlOptions['id'] = $tagName;
+ $label = array('for' => $tagName);
+
+ if (isset($htmlOptions['checked']) && $htmlOptions['checked'] === true) {
+ $label['class'] = 'selected';
+ }
+
+ $name = $attributes['name'];
+
+ if (empty($attributes['class'])) {
+ $attributes['class'] = 'checkbox';
+ } elseif ($attributes['class'] === 'form-error') {
+ $attributes['class'] = 'checkbox ' . $attributes['class'];
+ }
+ $label = $this->label(null, $title, $label);
+ $item = $this->Html->useTag('checkboxmultiple', $name, $htmlOptions);
+ $select[] = $this->Html->div($attributes['class'], $item . $label);
+ } else {
+ $select[] = $this->Html->useTag('selectoption', $name, $htmlOptions, $title);
+ }
+ }
+ }
+ }
+
+ return array_reverse($select, true);
+ }
+
+/**
+ * Generates option lists for common <select /> menus
+ *
+ * @param string $name
+ * @param array $options
+ * @return array
+ */
+ protected function _generateOptions($name, $options = array()) {
+ if (!empty($this->options[$name])) {
+ return $this->options[$name];
+ }
+ $data = array();
+
+ switch ($name) {
+ case 'minute':
+ if (isset($options['interval'])) {
+ $interval = $options['interval'];
+ } else {
+ $interval = 1;
+ }
+ $i = 0;
+ while ($i < 60) {
+ $data[sprintf('%02d', $i)] = sprintf('%02d', $i);
+ $i += $interval;
+ }
+ break;
+ case 'hour':
+ for ($i = 1; $i <= 12; $i++) {
+ $data[sprintf('%02d', $i)] = $i;
+ }
+ break;
+ case 'hour24':
+ for ($i = 0; $i <= 23; $i++) {
+ $data[sprintf('%02d', $i)] = $i;
+ }
+ break;
+ case 'meridian':
+ $data = array('am' => 'am', 'pm' => 'pm');
+ break;
+ case 'day':
+ $min = 1;
+ $max = 31;
+
+ if (isset($options['min'])) {
+ $min = $options['min'];
+ }
+ if (isset($options['max'])) {
+ $max = $options['max'];
+ }
+
+ for ($i = $min; $i <= $max; $i++) {
+ $data[sprintf('%02d', $i)] = $i;
+ }
+ break;
+ case 'month':
+ if ($options['monthNames'] === true) {
+ $data['01'] = __d('cake', 'January');
+ $data['02'] = __d('cake', 'February');
+ $data['03'] = __d('cake', 'March');
+ $data['04'] = __d('cake', 'April');
+ $data['05'] = __d('cake', 'May');
+ $data['06'] = __d('cake', 'June');
+ $data['07'] = __d('cake', 'July');
+ $data['08'] = __d('cake', 'August');
+ $data['09'] = __d('cake', 'September');
+ $data['10'] = __d('cake', 'October');
+ $data['11'] = __d('cake', 'November');
+ $data['12'] = __d('cake', 'December');
+ } elseif (is_array($options['monthNames'])) {
+ $data = $options['monthNames'];
+ } else {
+ for ($m = 1; $m <= 12; $m++) {
+ $data[sprintf("%02s", $m)] = strftime("%m", mktime(1, 1, 1, $m, 1, 1999));
+ }
+ }
+ break;
+ case 'year':
+ $current = intval(date('Y'));
+
+ $min = !isset($options['min']) ? $current - 20 : (int)$options['min'];
+ $max = !isset($options['max']) ? $current + 20 : (int)$options['max'];
+
+ if ($min > $max) {
+ list($min, $max) = array($max, $min);
+ }
+ for ($i = $min; $i <= $max; $i++) {
+ $data[$i] = $i;
+ }
+ if ($options['order'] != 'asc') {
+ $data = array_reverse($data, true);
+ }
+ break;
+ }
+ $this->_options[$name] = $data;
+ return $this->_options[$name];
+ }
+
+/**
+ * Sets field defaults and adds field to form security input hash
+ *
+ * ### Options
+ *
+ * - `secure` - boolean whether or not the field should be added to the security fields.
+ * Disabling the field using the `disabled` option, will also omit the field from being
+ * part of the hashed key.
+ *
+ * @param string $field Name of the field to initialize options for.
+ * @param array $options Array of options to append options into.
+ * @return array Array of options for the input.
+ */
+ protected function _initInputField($field, $options = array()) {
+ if (isset($options['secure'])) {
+ $secure = $options['secure'];
+ unset($options['secure']);
+ } else {
+ $secure = (isset($this->request['_Token']) && !empty($this->request['_Token']));
+ }
+
+ $result = parent::_initInputField($field, $options);
+ if ($this->tagIsInvalid() !== false) {
+ $result = $this->addClass($result, 'form-error');
+ }
+ if (!empty($result['disabled']) || $secure === self::SECURE_SKIP) {
+ return $result;
+ }
+
+ $fieldName = null;
+ if (!empty($options['name'])) {
+ preg_match_all('/\[(.*?)\]/', $options['name'], $matches);
+ if (isset($matches[1])) {
+ $fieldName = $matches[1];
+ }
+ }
+
+ $this->_secure($secure, $fieldName);
+ return $result;
+ }
+
+/**
+ * Set/Get inputDefaults for form elements
+ *
+ * @param array $defaults New default values
+ * @param boolean Merge with current defaults
+ * @return array inputDefaults
+ */
+ public function inputDefaults($defaults = null, $merge = false) {
+ if (!is_null($defaults)) {
+ if ($merge) {
+ $this->_inputDefaults = array_merge($this->_inputDefaults, (array)$defaults);
+ } else {
+ $this->_inputDefaults = (array)$defaults;
+ }
+ }
+ return $this->_inputDefaults;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php
new file mode 100644
index 0000000..fb53cf3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php
@@ -0,0 +1,1214 @@
+<?php
+/**
+ * Html Helper class file.
+ *
+ * Simplifies the construction of HTML elements.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 0.9.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * Html Helper class for easy use of HTML widgets.
+ *
+ * HtmlHelper encloses all methods needed while working with HTML pages.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html
+ */
+class HtmlHelper extends AppHelper {
+
+/**
+ * Reference to the Response object
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * html tags used by this helper.
+ *
+ * @var array
+ */
+ protected $_tags = array(
+ 'meta' => '<meta%s/>',
+ 'metalink' => '<link href="%s"%s/>',
+ 'link' => '<a href="%s"%s>%s</a>',
+ 'mailto' => '<a href="mailto:%s" %s>%s</a>',
+ 'form' => '<form action="%s"%s>',
+ 'formend' => '</form>',
+ 'input' => '<input name="%s"%s/>',
+ 'textarea' => '<textarea name="%s"%s>%s</textarea>',
+ 'hidden' => '<input type="hidden" name="%s"%s/>',
+ 'checkbox' => '<input type="checkbox" name="%s" %s/>',
+ 'checkboxmultiple' => '<input type="checkbox" name="%s[]"%s />',
+ 'radio' => '<input type="radio" name="%s" id="%s"%s />%s',
+ 'selectstart' => '<select name="%s"%s>',
+ 'selectmultiplestart' => '<select name="%s[]"%s>',
+ 'selectempty' => '<option value=""%s>&nbsp;</option>',
+ 'selectoption' => '<option value="%s"%s>%s</option>',
+ 'selectend' => '</select>',
+ 'optiongroup' => '<optgroup label="%s"%s>',
+ 'optiongroupend' => '</optgroup>',
+ 'checkboxmultiplestart' => '',
+ 'checkboxmultipleend' => '',
+ 'password' => '<input type="password" name="%s" %s/>',
+ 'file' => '<input type="file" name="%s" %s/>',
+ 'file_no_model' => '<input type="file" name="%s" %s/>',
+ 'submit' => '<input %s/>',
+ 'submitimage' => '<input type="image" src="%s" %s/>',
+ 'button' => '<button%s>%s</button>',
+ 'image' => '<img src="%s" %s/>',
+ 'tableheader' => '<th%s>%s</th>',
+ 'tableheaderrow' => '<tr%s>%s</tr>',
+ 'tablecell' => '<td%s>%s</td>',
+ 'tablerow' => '<tr%s>%s</tr>',
+ 'block' => '<div%s>%s</div>',
+ 'blockstart' => '<div%s>',
+ 'blockend' => '</div>',
+ 'tag' => '<%s%s>%s</%s>',
+ 'tagstart' => '<%s%s>',
+ 'tagend' => '</%s>',
+ 'tagselfclosing' => '<%s%s/>',
+ 'para' => '<p%s>%s</p>',
+ 'parastart' => '<p%s>',
+ 'label' => '<label for="%s"%s>%s</label>',
+ 'fieldset' => '<fieldset%s>%s</fieldset>',
+ 'fieldsetstart' => '<fieldset><legend>%s</legend>',
+ 'fieldsetend' => '</fieldset>',
+ 'legend' => '<legend>%s</legend>',
+ 'css' => '<link rel="%s" type="text/css" href="%s" %s/>',
+ 'style' => '<style type="text/css"%s>%s</style>',
+ 'charset' => '<meta http-equiv="Content-Type" content="text/html; charset=%s" />',
+ 'ul' => '<ul%s>%s</ul>',
+ 'ol' => '<ol%s>%s</ol>',
+ 'li' => '<li%s>%s</li>',
+ 'error' => '<div%s>%s</div>',
+ 'javascriptblock' => '<script type="text/javascript"%s>%s</script>',
+ 'javascriptstart' => '<script type="text/javascript">',
+ 'javascriptlink' => '<script type="text/javascript" src="%s"%s></script>',
+ 'javascriptend' => '</script>'
+ );
+
+/**
+ * Breadcrumbs.
+ *
+ * @var array
+ */
+ protected $_crumbs = array();
+
+/**
+ * Names of script files that have been included once
+ *
+ * @var array
+ */
+ protected $_includedScripts = array();
+
+/**
+ * Options for the currently opened script block buffer if any.
+ *
+ * @var array
+ */
+ protected $_scriptBlockOptions = array();
+
+/**
+ * Document type definitions
+ *
+ * @var array
+ */
+ protected $_docTypes = array(
+ 'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+ 'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+ 'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
+ 'html5' => '<!DOCTYPE html>',
+ 'xhtml-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+ 'xhtml-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+ 'xhtml-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+ 'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
+ );
+
+/**
+ * Constructor
+ *
+ * ### Settings
+ *
+ * - `configFile` A file containing an array of tags you wish to redefine.
+ *
+ * ### Customizing tag sets
+ *
+ * Using the `configFile` option you can redefine the tag HtmlHelper will use.
+ * The file named should be compatible with HtmlHelper::loadConfig().
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ parent::__construct($View, $settings);
+ if (is_object($this->_View->response)) {
+ $this->response = $this->_View->response;
+ } else {
+ $this->response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ }
+ if (!empty($settings['configFile'])) {
+ $this->loadConfig($settings['configFile']);
+ }
+ }
+
+/**
+ * Adds a link to the breadcrumbs array.
+ *
+ * @param string $name Text for link
+ * @param string $link URL for link (if empty it won't be a link)
+ * @param string|array $options Link attributes e.g. array('id' => 'selected')
+ * @return void
+ * @see HtmlHelper::link() for details on $options that can be used.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
+ */
+ public function addCrumb($name, $link = null, $options = null) {
+ $this->_crumbs[] = array($name, $link, $options);
+ }
+
+/**
+ * Returns a doctype string.
+ *
+ * Possible doctypes:
+ *
+ * - html4-strict: HTML4 Strict.
+ * - html4-trans: HTML4 Transitional.
+ * - html4-frame: HTML4 Frameset.
+ * - html5: HTML5. Default value.
+ * - xhtml-strict: XHTML1 Strict.
+ * - xhtml-trans: XHTML1 Transitional.
+ * - xhtml-frame: XHTML1 Frameset.
+ * - xhtml11: XHTML1.1.
+ *
+ * @param string $type Doctype to use.
+ * @return string Doctype string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::docType
+ */
+ public function docType($type = 'html5') {
+ if (isset($this->_docTypes[$type])) {
+ return $this->_docTypes[$type];
+ }
+ return null;
+ }
+
+/**
+ * Creates a link to an external resource and handles basic meta tags
+ *
+ * Create a meta tag that is output inline:
+ *
+ * `$this->Html->meta('icon', 'favicon.ico');
+ *
+ * Append the meta tag to `$scripts_for_layout`:
+ *
+ * `$this->Html->meta('description', 'A great page', array('inline' => false));`
+ *
+ * Append the meta tag to custom view block:
+ *
+ * `$this->Html->meta('description', 'A great page', array('block' => 'metaTags'));`
+ *
+ * ### Options
+ *
+ * - `inline` Whether or not the link element should be output inline. Set to false to
+ * have the meta tag included in `$scripts_for_layout`, and appended to the 'meta' view block.
+ * - `block` Choose a custom block to append the meta tag to. Using this option
+ * will override the inline option.
+ *
+ * @param string $type The title of the external resource
+ * @param string|array $url The address of the external resource or string for content attribute
+ * @param array $options Other attributes for the generated tag. If the type attribute is html,
+ * rss, atom, or icon, the mime-type is returned.
+ * @return string A completed `<link />` element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::meta
+ */
+ public function meta($type, $url = null, $options = array()) {
+ $options += array('inline' => true, 'block' => null);
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = __FUNCTION__;
+ }
+ unset($options['inline']);
+
+ if (!is_array($type)) {
+ $types = array(
+ 'rss' => array('type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => $type, 'link' => $url),
+ 'atom' => array('type' => 'application/atom+xml', 'title' => $type, 'link' => $url),
+ 'icon' => array('type' => 'image/x-icon', 'rel' => 'icon', 'link' => $url),
+ 'keywords' => array('name' => 'keywords', 'content' => $url),
+ 'description' => array('name' => 'description', 'content' => $url),
+ );
+
+ if ($type === 'icon' && $url === null) {
+ $types['icon']['link'] = $this->webroot('favicon.ico');
+ }
+
+ if (isset($types[$type])) {
+ $type = $types[$type];
+ } elseif (!isset($options['type']) && $url !== null) {
+ if (is_array($url) && isset($url['ext'])) {
+ $type = $types[$url['ext']];
+ } else {
+ $type = $types['rss'];
+ }
+ } elseif (isset($options['type']) && isset($types[$options['type']])) {
+ $type = $types[$options['type']];
+ unset($options['type']);
+ } else {
+ $type = array();
+ }
+ } elseif ($url !== null) {
+ $inline = $url;
+ }
+ $options = array_merge($type, $options);
+ $out = null;
+
+ if (isset($options['link'])) {
+ if (isset($options['rel']) && $options['rel'] === 'icon') {
+ $out = sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
+ $options['rel'] = 'shortcut icon';
+ } else {
+ $options['link'] = $this->url($options['link'], true);
+ }
+ $out .= sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
+ } else {
+ $out = sprintf($this->_tags['meta'], $this->_parseAttributes($options, array('block', 'type'), ' ', ' '));
+ }
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Returns a charset META-tag.
+ *
+ * @param string $charset The character set to be used in the meta tag. If empty,
+ * The App.encoding value will be used. Example: "utf-8".
+ * @return string A meta tag containing the specified character set.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::charset
+ */
+ public function charset($charset = null) {
+ if (empty($charset)) {
+ $charset = strtolower(Configure::read('App.encoding'));
+ }
+ return sprintf($this->_tags['charset'], (!empty($charset) ? $charset : 'utf-8'));
+ }
+
+/**
+ * Creates an HTML link.
+ *
+ * If $url starts with "http://" this is treated as an external link. Else,
+ * it is treated as a path to controller/action and parsed with the
+ * HtmlHelper::url() method.
+ *
+ * If the $url is empty, $title is used instead.
+ *
+ * ### Options
+ *
+ * - `escape` Set to false to disable escaping of title and attributes.
+ * - `confirm` JavaScript confirmation message.
+ *
+ * @param string $title The content to be wrapped by <a> tags.
+ * @param string|array $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
+ * @param array $options Array of HTML attributes.
+ * @param string $confirmMessage JavaScript confirmation message.
+ * @return string An `<a />` element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::link
+ */
+ public function link($title, $url = null, $options = array(), $confirmMessage = false) {
+ $escapeTitle = true;
+ if ($url !== null) {
+ $url = $this->url($url);
+ } else {
+ $url = $this->url($title);
+ $title = htmlspecialchars_decode($url, ENT_QUOTES);
+ $title = h(urldecode($title));
+ $escapeTitle = false;
+ }
+
+ if (isset($options['escape'])) {
+ $escapeTitle = $options['escape'];
+ }
+
+ if ($escapeTitle === true) {
+ $title = h($title);
+ } elseif (is_string($escapeTitle)) {
+ $title = htmlentities($title, ENT_QUOTES, $escapeTitle);
+ }
+
+ if (!empty($options['confirm'])) {
+ $confirmMessage = $options['confirm'];
+ unset($options['confirm']);
+ }
+ if ($confirmMessage) {
+ $confirmMessage = str_replace("'", "\'", $confirmMessage);
+ $confirmMessage = str_replace('"', '\"', $confirmMessage);
+ $options['onclick'] = "return confirm('{$confirmMessage}');";
+ } elseif (isset($options['default']) && $options['default'] == false) {
+ if (isset($options['onclick'])) {
+ $options['onclick'] .= ' event.returnValue = false; return false;';
+ } else {
+ $options['onclick'] = 'event.returnValue = false; return false;';
+ }
+ unset($options['default']);
+ }
+ return sprintf($this->_tags['link'], $url, $this->_parseAttributes($options), $title);
+ }
+
+/**
+ * Creates a link element for CSS stylesheets.
+ *
+ * ### Usage
+ *
+ * Include one CSS file:
+ *
+ * `echo $this->Html->css('styles.css');`
+ *
+ * Include multiple CSS files:
+ *
+ * `echo $this->Html->css(array('one.css', 'two.css'));`
+ *
+ * Add the stylesheet to the `$scripts_for_layout` layout var:
+ *
+ * `$this->Html->css('styles.css', null, array('inline' => false));`
+ *
+ * Add the stylesheet to a custom block:
+ *
+ * `$this->Html->css('styles.css', null, array('block' => 'layoutCss'));`
+ *
+ * ### Options
+ *
+ * - `inline` If set to false, the generated tag will be appended to the 'css' block,
+ * and included in the `$scripts_for_layout` layout variable. Defaults to true.
+ * - `block` Set the name of the block link/style tag will be appended to. This overrides the `inline`
+ * option.
+ * - `plugin` False value will prevent parsing path as a plugin
+ *
+ * @param string|array $path The name of a CSS style sheet or an array containing names of
+ * CSS stylesheets. If `$path` is prefixed with '/', the path will be relative to the webroot
+ * of your application. Otherwise, the path will be relative to your CSS path, usually webroot/css.
+ * @param string $rel Rel attribute. Defaults to "stylesheet". If equal to 'import' the stylesheet will be imported.
+ * @param array $options Array of HTML attributes.
+ * @return string CSS <link /> or <style /> tag, depending on the type of link.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::css
+ */
+ public function css($path, $rel = null, $options = array()) {
+ $options += array('block' => null, 'inline' => true);
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = __FUNCTION__;
+ }
+ unset($options['inline']);
+
+ if (is_array($path)) {
+ $out = '';
+ foreach ($path as $i) {
+ $out .= "\n\t" . $this->css($i, $rel, $options);
+ }
+ if (empty($options['block'])) {
+ return $out . "\n";
+ }
+ return;
+ }
+
+ if (strpos($path, '//') !== false) {
+ $url = $path;
+ } else {
+ $url = $this->assetUrl($path, $options + array('pathPrefix' => CSS_URL, 'ext' => '.css'));
+
+ if (Configure::read('Asset.filter.css')) {
+ $pos = strpos($url, CSS_URL);
+ if ($pos !== false) {
+ $url = substr($url, 0, $pos) . 'ccss/' . substr($url, $pos + strlen(CSS_URL));
+ }
+ }
+ }
+
+ if ($rel == 'import') {
+ $out = sprintf($this->_tags['style'], $this->_parseAttributes($options, array('inline', 'block'), '', ' '), '@import url(' . $url . ');');
+ } else {
+ if ($rel == null) {
+ $rel = 'stylesheet';
+ }
+ $out = sprintf($this->_tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline', 'block'), '', ' '));
+ }
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Returns one or many `<script>` tags depending on the number of scripts given.
+ *
+ * If the filename is prefixed with "/", the path will be relative to the base path of your
+ * application. Otherwise, the path will be relative to your JavaScript path, usually webroot/js.
+ *
+ *
+ * ### Usage
+ *
+ * Include one script file:
+ *
+ * `echo $this->Html->script('styles.js');`
+ *
+ * Include multiple script files:
+ *
+ * `echo $this->Html->script(array('one.js', 'two.js'));`
+ *
+ * Add the script file to the `$scripts_for_layout` layout var:
+ *
+ * `$this->Html->script('styles.js', array('inline' => false));`
+ *
+ * Add the script file to a custom block:
+ *
+ * `$this->Html->script('styles.js', null, array('block' => 'bodyScript'));`
+ *
+ * ### Options
+ *
+ * - `inline` Whether script should be output inline or into `$scripts_for_layout`. When set to false,
+ * the script tag will be appended to the 'script' view block as well as `$scripts_for_layout`.
+ * - `block` The name of the block you want the script appended to. Leave undefined to output inline.
+ * Using this option will override the inline option.
+ * - `once` Whether or not the script should be checked for uniqueness. If true scripts will only be
+ * included once, use false to allow the same script to be included more than once per request.
+ * - `plugin` False value will prevent parsing path as a plugin
+ *
+ * @param string|array $url String or array of javascript files to include
+ * @param array|boolean $options Array of options, and html attributes see above. If boolean sets $options['inline'] = value
+ * @return mixed String of `<script />` tags or null if $inline is false or if $once is true and the file has been
+ * included before.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::script
+ */
+ public function script($url, $options = array()) {
+ if (is_bool($options)) {
+ list($inline, $options) = array($options, array());
+ $options['inline'] = $inline;
+ }
+ $options = array_merge(array('block' => null, 'inline' => true, 'once' => true), $options);
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = __FUNCTION__;
+ }
+ unset($options['inline']);
+
+ if (is_array($url)) {
+ $out = '';
+ foreach ($url as $i) {
+ $out .= "\n\t" . $this->script($i, $options);
+ }
+ if (empty($options['block'])) {
+ return $out . "\n";
+ }
+ return null;
+ }
+ if ($options['once'] && isset($this->_includedScripts[$url])) {
+ return null;
+ }
+ $this->_includedScripts[$url] = true;
+
+ if (strpos($url, '//') === false) {
+ $url = $this->assetUrl($url, $options + array('pathPrefix' => JS_URL, 'ext' => '.js'));
+
+ if (Configure::read('Asset.filter.js')) {
+ $url = str_replace(JS_URL, 'cjs/', $url);
+ }
+ }
+ $attributes = $this->_parseAttributes($options, array('block', 'once'), ' ');
+ $out = sprintf($this->_tags['javascriptlink'], $url, $attributes);
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Wrap $script in a script tag.
+ *
+ * ### Options
+ *
+ * - `safe` (boolean) Whether or not the $script should be wrapped in <![CDATA[ ]]>
+ * - `inline` (boolean) Whether or not the $script should be added to
+ * `$scripts_for_layout` / `script` block, or output inline. (Deprecated, use `block` instead)
+ * - `block` Which block you want this script block appended to.
+ * Defaults to `script`.
+ *
+ * @param string $script The script to wrap
+ * @param array $options The options to use. Options not listed above will be
+ * treated as HTML attributes.
+ * @return mixed string or null depending on the value of `$options['block']`
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptBlock
+ */
+ public function scriptBlock($script, $options = array()) {
+ $options += array('safe' => true, 'inline' => true);
+ if ($options['safe']) {
+ $script = "\n" . '//<![CDATA[' . "\n" . $script . "\n" . '//]]>' . "\n";
+ }
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = 'script';
+ }
+ unset($options['inline'], $options['safe']);
+
+ $attributes = $this->_parseAttributes($options, array('block'), ' ');
+ $out = sprintf($this->_tags['javascriptblock'], $attributes, $script);
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Begin a script block that captures output until HtmlHelper::scriptEnd()
+ * is called. This capturing block will capture all output between the methods
+ * and create a scriptBlock from it.
+ *
+ * ### Options
+ *
+ * - `safe` Whether the code block should contain a CDATA
+ * - `inline` Should the generated script tag be output inline or in `$scripts_for_layout`
+ *
+ * @param array $options Options for the code block.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptStart
+ */
+ public function scriptStart($options = array()) {
+ $options += array('safe' => true, 'inline' => true);
+ $this->_scriptBlockOptions = $options;
+ ob_start();
+ return null;
+ }
+
+/**
+ * End a Buffered section of Javascript capturing.
+ * Generates a script tag inline or in `$scripts_for_layout` depending on the settings
+ * used when the scriptBlock was started
+ *
+ * @return mixed depending on the settings of scriptStart() either a script tag or null
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptEnd
+ */
+ public function scriptEnd() {
+ $buffer = ob_get_clean();
+ $options = $this->_scriptBlockOptions;
+ $this->_scriptBlockOptions = array();
+ return $this->scriptBlock($buffer, $options);
+ }
+
+/**
+ * Builds CSS style data from an array of CSS properties
+ *
+ * ### Usage:
+ *
+ * {{{
+ * echo $html->style(array('margin' => '10px', 'padding' => '10px'), true);
+ *
+ * // creates
+ * 'margin:10px;padding:10px;'
+ * }}}
+ *
+ * @param array $data Style data array, keys will be used as property names, values as property values.
+ * @param boolean $oneline Whether or not the style block should be displayed on one line.
+ * @return string CSS styling data
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::style
+ */
+ public function style($data, $oneline = true) {
+ if (!is_array($data)) {
+ return $data;
+ }
+ $out = array();
+ foreach ($data as $key => $value) {
+ $out[] = $key . ':' . $value . ';';
+ }
+ if ($oneline) {
+ return join(' ', $out);
+ }
+ return implode("\n", $out);
+ }
+
+/**
+ * Returns the breadcrumb trail as a sequence of &raquo;-separated links.
+ *
+ * If `$startText` is an array, the accepted keys are:
+ *
+ * - `text` Define the text/content for the link.
+ * - `url` Define the target of the created link.
+ *
+ * All other keys will be passed to HtmlHelper::link() as the `$options` parameter.
+ *
+ * @param string $separator Text to separate crumbs.
+ * @param string|array|boolean $startText This will be the first crumb, if false it defaults to first crumb in array. Can
+ * also be an array, see above for details.
+ * @return string Composed bread crumbs
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
+ */
+ public function getCrumbs($separator = '&raquo;', $startText = false) {
+ $crumbs = $this->_prepareCrumbs($startText);
+ if (!empty($crumbs)) {
+ $out = array();
+ foreach ($crumbs as $crumb) {
+ if (!empty($crumb[1])) {
+ $out[] = $this->link($crumb[0], $crumb[1], $crumb[2]);
+ } else {
+ $out[] = $crumb[0];
+ }
+ }
+ return join($separator, $out);
+ } else {
+ return null;
+ }
+ }
+
+/**
+ * Returns breadcrumbs as a (x)html list
+ *
+ * This method uses HtmlHelper::tag() to generate list and its elements. Works
+ * similar to HtmlHelper::getCrumbs(), so it uses options which every
+ * crumb was added with.
+ *
+ * @param array $options Array of html attributes to apply to the generated list elements.
+ * @param string|array|boolean $startText This will be the first crumb, if false it defaults to first crumb in array. Can
+ * also be an array, see `HtmlHelper::getCrumbs` for details.
+ * @return string breadcrumbs html list
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
+ */
+ public function getCrumbList($options = array(), $startText = false) {
+ $crumbs = $this->_prepareCrumbs($startText);
+ if (!empty($crumbs)) {
+ $result = '';
+ $crumbCount = count($crumbs);
+ $ulOptions = $options;
+ foreach ($crumbs as $which => $crumb) {
+ $options = array();
+ if (empty($crumb[1])) {
+ $elementContent = $crumb[0];
+ } else {
+ $elementContent = $this->link($crumb[0], $crumb[1], $crumb[2]);
+ }
+ if ($which == 0) {
+ $options['class'] = 'first';
+ } elseif ($which == $crumbCount - 1) {
+ $options['class'] = 'last';
+ }
+ $result .= $this->tag('li', $elementContent, $options);
+ }
+ return $this->tag('ul', $result, $ulOptions);
+ } else {
+ return null;
+ }
+ }
+
+/**
+ * Prepends startText to crumbs array if set
+ *
+ * @param $startText
+ * @return array Crumb list including startText (if provided)
+ */
+ protected function _prepareCrumbs($startText) {
+ $crumbs = $this->_crumbs;
+ if ($startText) {
+ if (!is_array($startText)) {
+ $startText = array(
+ 'url' => '/',
+ 'text' => $startText
+ );
+ }
+ $startText += array('url' => '/', 'text' => __('Home'));
+ list($url, $text) = array($startText['url'], $startText['text']);
+ unset($startText['url'], $startText['text']);
+ array_unshift($crumbs, array($text, $url, $startText));
+ }
+ return $crumbs;
+ }
+
+/**
+ * Creates a formatted IMG element.
+ *
+ * This method will set an empty alt attribute if one is not supplied.
+ *
+ * ### Usage:
+ *
+ * Create a regular image:
+ *
+ * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP'));`
+ *
+ * Create an image link:
+ *
+ * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP', 'url' => 'http://cakephp.org'));`
+ *
+ * ### Options:
+ *
+ * - `url` If provided an image link will be generated and the link will point at
+ * `$options['url']`.
+ * - `fullBase` If true the src attribute will get a full address for the image file.
+ * - `plugin` False value will prevent parsing path as a plugin
+ *
+ * @param string $path Path to the image file, relative to the app/webroot/img/ directory.
+ * @param array $options Array of HTML attributes. See above for special options.
+ * @return string completed img tag
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::image
+ */
+ public function image($path, $options = array()) {
+ $path = $this->assetUrl($path, $options + array('pathPrefix' => IMAGES_URL));
+ $options = array_diff_key($options, array('fullBase' => '', 'pathPrefix' => ''));
+
+ if (!isset($options['alt'])) {
+ $options['alt'] = '';
+ }
+
+ $url = false;
+ if (!empty($options['url'])) {
+ $url = $options['url'];
+ unset($options['url']);
+ }
+
+ $image = sprintf($this->_tags['image'], $path, $this->_parseAttributes($options, null, '', ' '));
+
+ if ($url) {
+ return sprintf($this->_tags['link'], $this->url($url), null, $image);
+ }
+ return $image;
+ }
+
+/**
+ * Returns a row of formatted and named TABLE headers.
+ *
+ * @param array $names Array of tablenames. Each tablename also can be a key that points to an array with a set
+ * of attributes to its specific tag
+ * @param array $trOptions HTML options for TR elements.
+ * @param array $thOptions HTML options for TH elements.
+ * @return string Completed table headers
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tableHeaders
+ */
+ public function tableHeaders($names, $trOptions = null, $thOptions = null) {
+ $out = array();
+ foreach ($names as $arg) {
+ if (!is_array($arg)) {
+ $out[] = sprintf($this->_tags['tableheader'], $this->_parseAttributes($thOptions), $arg);
+ } else {
+ $out[] = sprintf($this->_tags['tableheader'], $this->_parseAttributes(current($arg)), key($arg));
+ }
+ }
+ return sprintf($this->_tags['tablerow'], $this->_parseAttributes($trOptions), join(' ', $out));
+ }
+
+/**
+ * Returns a formatted string of table rows (TR's with TD's in them).
+ *
+ * @param array $data Array of table data
+ * @param array $oddTrOptions HTML options for odd TR elements if true useCount is used
+ * @param array $evenTrOptions HTML options for even TR elements
+ * @param boolean $useCount adds class "column-$i"
+ * @param boolean $continueOddEven If false, will use a non-static $count variable,
+ * so that the odd/even count is reset to zero just for that call.
+ * @return string Formatted HTML
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tableCells
+ */
+ public function tableCells($data, $oddTrOptions = null, $evenTrOptions = null, $useCount = false, $continueOddEven = true) {
+ if (empty($data[0]) || !is_array($data[0])) {
+ $data = array($data);
+ }
+
+ if ($oddTrOptions === true) {
+ $useCount = true;
+ $oddTrOptions = null;
+ }
+
+ if ($evenTrOptions === false) {
+ $continueOddEven = false;
+ $evenTrOptions = null;
+ }
+
+ if ($continueOddEven) {
+ static $count = 0;
+ } else {
+ $count = 0;
+ }
+
+ foreach ($data as $line) {
+ $count++;
+ $cellsOut = array();
+ $i = 0;
+ foreach ($line as $cell) {
+ $cellOptions = array();
+
+ if (is_array($cell)) {
+ $cellOptions = $cell[1];
+ $cell = $cell[0];
+ } elseif ($useCount) {
+ $cellOptions['class'] = 'column-' . ++$i;
+ }
+ $cellsOut[] = sprintf($this->_tags['tablecell'], $this->_parseAttributes($cellOptions), $cell);
+ }
+ $options = $this->_parseAttributes($count % 2 ? $oddTrOptions : $evenTrOptions);
+ $out[] = sprintf($this->_tags['tablerow'], $options, implode(' ', $cellsOut));
+ }
+ return implode("\n", $out);
+ }
+
+/**
+ * Returns a formatted block tag, i.e DIV, SPAN, P.
+ *
+ * ### Options
+ *
+ * - `escape` Whether or not the contents should be html_entity escaped.
+ *
+ * @param string $name Tag name.
+ * @param string $text String content that will appear inside the div element.
+ * If null, only a start tag will be printed
+ * @param array $options Additional HTML attributes of the DIV tag, see above.
+ * @return string The formatted tag element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tag
+ */
+ public function tag($name, $text = null, $options = array()) {
+ if (is_array($options) && isset($options['escape']) && $options['escape']) {
+ $text = h($text);
+ unset($options['escape']);
+ }
+ if (!is_array($options)) {
+ $options = array('class' => $options);
+ }
+ if ($text === null) {
+ $tag = 'tagstart';
+ } else {
+ $tag = 'tag';
+ }
+ return sprintf($this->_tags[$tag], $name, $this->_parseAttributes($options, null, ' ', ''), $text, $name);
+ }
+
+/**
+ * Returns a formatted existent block of $tags
+ *
+ * @param string $tag Tag name
+ * @return string Formatted block
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::useTag
+ */
+ public function useTag($tag) {
+ if (!isset($this->_tags[$tag])) {
+ return '';
+ }
+ $args = func_get_args();
+ array_shift($args);
+ foreach ($args as &$arg) {
+ if (is_array($arg)) {
+ $arg = $this->_parseAttributes($arg, null, ' ', '');
+ }
+ }
+ return vsprintf($this->_tags[$tag], $args);
+ }
+
+/**
+ * Returns a formatted DIV tag for HTML FORMs.
+ *
+ * ### Options
+ *
+ * - `escape` Whether or not the contents should be html_entity escaped.
+ *
+ * @param string $class CSS class name of the div element.
+ * @param string $text String content that will appear inside the div element.
+ * If null, only a start tag will be printed
+ * @param array $options Additional HTML attributes of the DIV tag
+ * @return string The formatted DIV element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::div
+ */
+ public function div($class = null, $text = null, $options = array()) {
+ if (!empty($class)) {
+ $options['class'] = $class;
+ }
+ return $this->tag('div', $text, $options);
+ }
+
+/**
+ * Returns a formatted P tag.
+ *
+ * ### Options
+ *
+ * - `escape` Whether or not the contents should be html_entity escaped.
+ *
+ * @param string $class CSS class name of the p element.
+ * @param string $text String content that will appear inside the p element.
+ * @param array $options Additional HTML attributes of the P tag
+ * @return string The formatted P element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::para
+ */
+ public function para($class, $text, $options = array()) {
+ if (isset($options['escape'])) {
+ $text = h($text);
+ }
+ if ($class != null && !empty($class)) {
+ $options['class'] = $class;
+ }
+ if ($text === null) {
+ $tag = 'parastart';
+ } else {
+ $tag = 'para';
+ }
+ return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $text);
+ }
+
+/**
+ * Returns an audio/video element
+ *
+ * ### Usage
+ *
+ * Using an audio file:
+ *
+ * `echo $this->Html->media('audio.mp3', array('fullBase' => true));`
+ *
+ * Outputs:
+ *
+ * `<video src="http://www.somehost.com/files/audio.mp3">Fallback text</video>`
+ *
+ * Using a video file:
+ *
+ * `echo $this->Html->media('video.mp4', array('text' => 'Fallback text'));`
+ *
+ * Outputs:
+ *
+ * `<video src="/files/video.mp4">Fallback text</video>`
+ *
+ * Using multiple video files:
+ *
+ * {{{
+ * echo $this->Html->media(
+ * array('video.mp4', array('src' => 'video.ogv', 'type' => "video/ogg; codecs='theora, vorbis'")),
+ * array('tag' => 'video', 'autoplay')
+ * );
+ * }}}
+ *
+ * Outputs:
+ *
+ * {{{
+ * <video autoplay="autoplay">
+ * <source src="/files/video.mp4" type="video/mp4"/>
+ * <source src="/files/video.ogv" type="video/ogv; codecs='theora, vorbis'"/>
+ * </video>
+ * }}}
+ *
+ * ### Options
+ *
+ * - `tag` Type of media element to generate, either "audio" or "video".
+ * If tag is not provided it's guessed based on file's mime type.
+ * - `text` Text to include inside the audio/video tag
+ * - `pathPrefix` Path prefix to use for relative urls, defaults to 'files/'
+ * - `fullBase` If provided the src attribute will get a full address including domain name
+ *
+ * @param string|array $path Path to the video file, relative to the webroot/{$options['pathPrefix']} directory.
+ * Or an array where each item itself can be a path string or an associate array containing keys `src` and `type`
+ * @param array $options Array of HTML attributes, and special options above.
+ * @return string Generated media element
+ */
+ public function media($path, $options = array()) {
+ $options += array(
+ 'tag' => null,
+ 'pathPrefix' => 'files/',
+ 'text' => ''
+ );
+
+ if (!empty($options['tag'])) {
+ $tag = $options['tag'];
+ } else {
+ $tag = null;
+ }
+
+ if (is_array($path)) {
+ $sourceTags = '';
+ foreach ($path as &$source) {
+ if (is_string($source)) {
+ $source = array(
+ 'src' => $source,
+ );
+ }
+ if (!isset($source['type'])) {
+ $ext = pathinfo($source['src'], PATHINFO_EXTENSION);
+ $source['type'] = $this->response->getMimeType($ext);
+ }
+ $source['src'] = $this->assetUrl($source['src'], $options);
+ $sourceTags .= $this->useTag('tagselfclosing', 'source', $source);
+ }
+ unset($source);
+ $options['text'] = $sourceTags . $options['text'];
+ unset($options['fullBase']);
+ } else {
+ if (empty($path) && !empty($options['src'])) {
+ $path = $options['src'];
+ }
+ $options['src'] = $this->assetUrl($path, $options);
+ }
+
+ if ($tag === null) {
+ if (is_array($path)) {
+ $mimeType = $path[0]['type'];
+ } else {
+ $mimeType = $this->response->getMimeType(pathinfo($path, PATHINFO_EXTENSION));
+ }
+ if (preg_match('#^video/#', $mimeType)) {
+ $tag = 'video';
+ } else {
+ $tag = 'audio';
+ }
+ }
+
+ if (isset($options['poster'])) {
+ $options['poster'] = $this->assetUrl($options['poster'], array('pathPrefix' => IMAGES_URL) + $options);
+ }
+ $text = $options['text'];
+
+ $options = array_diff_key($options, array(
+ 'tag' => '',
+ 'fullBase' => '',
+ 'pathPrefix' => '',
+ 'text' => ''
+ ));
+ return $this->tag($tag, $text, $options);
+ }
+
+/**
+ * Build a nested list (UL/OL) out of an associative array.
+ *
+ * @param array $list Set of elements to list
+ * @param array $options Additional HTML attributes of the list (ol/ul) tag or if ul/ol use that as tag
+ * @param array $itemOptions Additional HTML attributes of the list item (LI) tag
+ * @param string $tag Type of list tag to use (ol/ul)
+ * @return string The nested list
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::nestedList
+ */
+ public function nestedList($list, $options = array(), $itemOptions = array(), $tag = 'ul') {
+ if (is_string($options)) {
+ $tag = $options;
+ $options = array();
+ }
+ $items = $this->_nestedListItem($list, $options, $itemOptions, $tag);
+ return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $items);
+ }
+
+/**
+ * Internal function to build a nested list (UL/OL) out of an associative array.
+ *
+ * @param array $items Set of elements to list
+ * @param array $options Additional HTML attributes of the list (ol/ul) tag
+ * @param array $itemOptions Additional HTML attributes of the list item (LI) tag
+ * @param string $tag Type of list tag to use (ol/ul)
+ * @return string The nested list element
+ * @see HtmlHelper::nestedList()
+ */
+ protected function _nestedListItem($items, $options, $itemOptions, $tag) {
+ $out = '';
+
+ $index = 1;
+ foreach ($items as $key => $item) {
+ if (is_array($item)) {
+ $item = $key . $this->nestedList($item, $options, $itemOptions, $tag);
+ }
+ if (isset($itemOptions['even']) && $index % 2 == 0) {
+ $itemOptions['class'] = $itemOptions['even'];
+ } elseif (isset($itemOptions['odd']) && $index % 2 != 0) {
+ $itemOptions['class'] = $itemOptions['odd'];
+ }
+ $out .= sprintf($this->_tags['li'], $this->_parseAttributes($itemOptions, array('even', 'odd'), ' ', ''), $item);
+ $index++;
+ }
+ return $out;
+ }
+
+/**
+ * Load Html tag configuration.
+ *
+ * Loads a file from APP/Config that contains tag data. By default the file is expected
+ * to be compatible with PhpReader:
+ *
+ * `$this->Html->loadConfig('tags.php');`
+ *
+ * tags.php could look like:
+ *
+ * {{{
+ * $tags = array(
+ * 'meta' => '<meta %s>'
+ * );
+ * }}}
+ *
+ * If you wish to store tag definitions in another format you can give an array
+ * containing the file name, and reader class name:
+ *
+ * `$this->Html->loadConfig(array('tags.ini', 'ini'));`
+ *
+ * Its expected that the `tags` index will exist from any configuration file that is read.
+ * You can also specify the path to read the configuration file from, if APP/Config is not
+ * where the file is.
+ *
+ * `$this->Html->loadConfig('tags.php', APP . 'Lib' . DS);`
+ *
+ * Configuration files can define the following sections:
+ *
+ * - `tags` The tags to replace.
+ * - `minimizedAttributes` The attributes that are represented like `disabled="disabled"`
+ * - `docTypes` Additional doctypes to use.
+ * - `attributeFormat` Format for long attributes e.g. `'%s="%s"'`
+ * - `minimizedAttributeFormat` Format for minimized attributes e.g. `'%s="%s"'`
+ *
+ * @param string|array $configFile String with the config file (load using PhpReader) or an array with file and reader name
+ * @param string $path Path with config file
+ * @return mixed False to error or loaded configs
+ * @throws ConfigureException
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#changing-the-tags-output-by-htmlhelper
+ */
+ public function loadConfig($configFile, $path = null) {
+ if (!$path) {
+ $path = APP . 'Config' . DS;
+ }
+ $file = null;
+ $reader = 'php';
+
+ if (!is_array($configFile)) {
+ $file = $configFile;
+ } elseif (isset($configFile[0])) {
+ $file = $configFile[0];
+ if (isset($configFile[1])) {
+ $reader = $configFile[1];
+ }
+ } else {
+ throw new ConfigureException(__d('cake_dev', 'Cannot load the configuration file. Wrong "configFile" configuration.'));
+ }
+
+ $readerClass = Inflector::camelize($reader) . 'Reader';
+ App::uses($readerClass, 'Configure');
+ if (!class_exists($readerClass)) {
+ throw new ConfigureException(__d('cake_dev', 'Cannot load the configuration file. Unknown reader.'));
+ }
+
+ $readerObj = new $readerClass($path);
+ $configs = $readerObj->read($file);
+ if (isset($configs['tags']) && is_array($configs['tags'])) {
+ $this->_tags = array_merge($this->_tags, $configs['tags']);
+ }
+ if (isset($configs['minimizedAttributes']) && is_array($configs['minimizedAttributes'])) {
+ $this->_minimizedAttributes = array_merge($this->_minimizedAttributes, $configs['minimizedAttributes']);
+ }
+ if (isset($configs['docTypes']) && is_array($configs['docTypes'])) {
+ $this->_docTypes = array_merge($this->_docTypes, $configs['docTypes']);
+ }
+ if (isset($configs['attributeFormat'])) {
+ $this->_attributeFormat = $configs['attributeFormat'];
+ }
+ if (isset($configs['minimizedAttributeFormat'])) {
+ $this->_minimizedAttributeFormat = $configs['minimizedAttributeFormat'];
+ }
+ return $configs;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php
new file mode 100644
index 0000000..d79a8ef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php
@@ -0,0 +1,361 @@
+<?php
+/**
+ * jQuery Engine Helper for JsHelper
+ *
+ * Provides jQuery specific Javascript for JsHelper.
+ *
+ * Implements the JsHelper interface for jQuery. All $options arrays
+ * support all options found in the JsHelper, as well as those in the jQuery
+ * documentation.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('JsBaseEngineHelper', 'View/Helper');
+
+/**
+ * jQuery Engine Helper for JsHelper
+ *
+ * Provides jQuery specific Javascript for JsHelper.
+ *
+ * Implements the JsHelper interface for jQuery. All $options arrays
+ * support all options found in the JsHelper, as well as those in the jQuery
+ * documentation.
+ *
+ * @package Cake.View.Helper
+ */
+class JqueryEngineHelper extends JsBaseEngineHelper {
+
+/**
+ * Option mappings for jQuery
+ *
+ * @var array
+ */
+ protected $_optionMap = array(
+ 'request' => array(
+ 'type' => 'dataType',
+ 'before' => 'beforeSend',
+ 'method' => 'type',
+ ),
+ 'sortable' => array(
+ 'complete' => 'stop',
+ ),
+ 'drag' => array(
+ 'snapGrid' => 'grid',
+ 'container' => 'containment',
+ ),
+ 'drop' => array(
+ 'leave' => 'out',
+ 'hover' => 'over'
+ ),
+ 'slider' => array(
+ 'complete' => 'stop',
+ 'direction' => 'orientation'
+ )
+ );
+
+/**
+ * Callback arguments lists
+ *
+ * @var string
+ */
+ protected $_callbackArguments = array(
+ 'slider' => array(
+ 'start' => 'event, ui',
+ 'slide' => 'event, ui',
+ 'change' => 'event, ui',
+ 'stop' => 'event, ui'
+ ),
+ 'sortable' => array(
+ 'start' => 'event, ui',
+ 'sort' => 'event, ui',
+ 'change' => 'event, ui',
+ 'beforeStop' => 'event, ui',
+ 'stop' => 'event, ui',
+ 'update' => 'event, ui',
+ 'receive' => 'event, ui',
+ 'remove' => 'event, ui',
+ 'over' => 'event, ui',
+ 'out' => 'event, ui',
+ 'activate' => 'event, ui',
+ 'deactivate' => 'event, ui'
+ ),
+ 'drag' => array(
+ 'start' => 'event, ui',
+ 'drag' => 'event, ui',
+ 'stop' => 'event, ui',
+ ),
+ 'drop' => array(
+ 'activate' => 'event, ui',
+ 'deactivate' => 'event, ui',
+ 'over' => 'event, ui',
+ 'out' => 'event, ui',
+ 'drop' => 'event, ui'
+ ),
+ 'request' => array(
+ 'beforeSend' => 'XMLHttpRequest',
+ 'error' => 'XMLHttpRequest, textStatus, errorThrown',
+ 'success' => 'data, textStatus',
+ 'complete' => 'XMLHttpRequest, textStatus',
+ 'xhr' => ''
+ )
+ );
+
+/**
+ * The variable name of the jQuery Object, useful
+ * when jQuery is put into noConflict() mode.
+ *
+ * @var string
+ */
+ public $jQueryObject = '$';
+
+/**
+ * Helper function to wrap repetitive simple method templating.
+ *
+ * @param string $method The method name being generated.
+ * @param string $template The method template
+ * @param array $options Array of options for method
+ * @param array $extraSafeKeys Extra safe keys
+ * @return string Composed method string
+ */
+ protected function _methodTemplate($method, $template, $options, $extraSafeKeys = array()) {
+ $options = $this->_mapOptions($method, $options);
+ $options = $this->_prepareCallbacks($method, $options);
+ $callbacks = array_keys($this->_callbackArguments[$method]);
+ if (!empty($extraSafeKeys)) {
+ $callbacks = array_merge($callbacks, $extraSafeKeys);
+ }
+ $options = $this->_parseOptions($options, $callbacks);
+ return sprintf($template, $this->selection, $options);
+ }
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return JqueryEngineHelper instance of $this. Allows chained methods.
+ */
+ public function get($selector) {
+ if ($selector == 'window' || $selector == 'document') {
+ $this->selection = $this->jQueryObject . '(' . $selector . ')';
+ } else {
+ $this->selection = $this->jQueryObject . '("' . $selector . '")';
+ }
+ return $this;
+ }
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
+ * - 'stop' - Whether you want the event to stopped. (defaults true)
+ *
+ * @param string $type Type of event to bind to the current dom id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ public function event($type, $callback, $options = array()) {
+ $defaults = array('wrap' => true, 'stop' => true);
+ $options = array_merge($defaults, $options);
+
+ $function = 'function (event) {%s}';
+ if ($options['wrap'] && $options['stop']) {
+ $callback .= "\nreturn false;";
+ }
+ if ($options['wrap']) {
+ $callback = sprintf($function, $callback);
+ }
+ return sprintf('%s.bind("%s", %s);', $this->selection, $type, $callback);
+ }
+
+/**
+ * Create a domReady event. For jQuery. This method does not
+ * bind a 'traditional event' as `$(document).bind('ready', fn)`
+ * Works in an entirely different fashion than `$(document).ready()`
+ * The first will not run the function when eval()'d as part of a response
+ * The second will. Because of the way that ajax pagination is done
+ * `$().ready()` is used.
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ public function domReady($functionBody) {
+ return $this->jQueryObject . '(document).ready(function () {' . $functionBody . '});';
+ }
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ public function each($callback) {
+ return $this->selection . '.each(function () {' . $callback . '});';
+ }
+
+/**
+ * Trigger an Effect.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ * @see JsBaseEngineHelper::effect()
+ */
+ public function effect($name, $options = array()) {
+ $speed = null;
+ if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
+ $speed = $this->value($options['speed']);
+ }
+ $effect = '';
+ switch ($name) {
+ case 'slideIn':
+ case 'slideOut':
+ $name = ($name == 'slideIn') ? 'slideDown' : 'slideUp';
+ case 'hide':
+ case 'show':
+ case 'fadeIn':
+ case 'fadeOut':
+ case 'slideDown':
+ case 'slideUp':
+ $effect = ".$name($speed);";
+ break;
+ }
+ return $this->selection . $effect;
+ }
+
+/**
+ * Create an $.ajax() call.
+ *
+ * If the 'update' key is set, success callback will be overridden.
+ *
+ * @param string|array $url
+ * @param array $options See JsHelper::request() for options.
+ * @return string The completed ajax call.
+ * @see JsBaseEngineHelper::request() for options list.
+ */
+ public function request($url, $options = array()) {
+ $url = $this->url($url);
+ $options = $this->_mapOptions('request', $options);
+ if (isset($options['data']) && is_array($options['data'])) {
+ $options['data'] = $this->_toQuerystring($options['data']);
+ }
+ $options['url'] = $url;
+ if (isset($options['update'])) {
+ $wrapCallbacks = isset($options['wrapCallbacks']) ? $options['wrapCallbacks'] : true;
+ $success = '';
+ if (isset($options['success']) && !empty($options['success'])) {
+ $success .= $options['success'];
+ }
+ $success .= $this->jQueryObject . '("' . $options['update'] . '").html(data);';
+ if (!$wrapCallbacks) {
+ $success = 'function (data, textStatus) {' . $success . '}';
+ }
+ $options['dataType'] = 'html';
+ $options['success'] = $success;
+ unset($options['update']);
+ }
+ $callbacks = array('success', 'error', 'beforeSend', 'complete');
+ if (!empty($options['dataExpression'])) {
+ $callbacks[] = 'data';
+ unset($options['dataExpression']);
+ }
+ $options = $this->_prepareCallbacks('request', $options);
+ $options = $this->_parseOptions($options, $callbacks);
+ return $this->jQueryObject . '.ajax({' . $options . '});';
+ }
+
+/**
+ * Create a sortable element.
+ *
+ * Requires both Ui.Core and Ui.Sortables to be loaded.
+ *
+ * @param array $options Array of options for the sortable.
+ * @return string Completed sortable script.
+ * @see JsBaseEngineHelper::sortable() for options list.
+ */
+ public function sortable($options = array()) {
+ $template = '%s.sortable({%s});';
+ return $this->_methodTemplate('sortable', $template, $options);
+ }
+
+/**
+ * Create a Draggable element
+ *
+ * Requires both Ui.Core and Ui.Draggable to be loaded.
+ *
+ * @param array $options Array of options for the draggable element.
+ * @return string Completed Draggable script.
+ * @see JsBaseEngineHelper::drag() for options list.
+ */
+ public function drag($options = array()) {
+ $template = '%s.draggable({%s});';
+ return $this->_methodTemplate('drag', $template, $options);
+ }
+
+/**
+ * Create a Droppable element
+ *
+ * Requires both Ui.Core and Ui.Droppable to be loaded.
+ *
+ * @param array $options Array of options for the droppable element.
+ * @return string Completed Droppable script.
+ * @see JsBaseEngineHelper::drop() for options list.
+ */
+ public function drop($options = array()) {
+ $template = '%s.droppable({%s});';
+ return $this->_methodTemplate('drop', $template, $options);
+ }
+
+/**
+ * Create a Slider element
+ *
+ * Requires both Ui.Core and Ui.Slider to be loaded.
+ *
+ * @param array $options Array of options for the droppable element.
+ * @return string Completed Slider script.
+ * @see JsBaseEngineHelper::slider() for options list.
+ */
+ public function slider($options = array()) {
+ $callbacks = array('start', 'change', 'slide', 'stop');
+ $template = '%s.slider({%s});';
+ return $this->_methodTemplate('slider', $template, $options, $callbacks);
+ }
+
+/**
+ * Serialize a form attached to $selector. If the current selection is not an input or
+ * form, errors will be created in the Javascript.
+ *
+ * @param array $options Options for the serialization
+ * @return string completed form serialization script.
+ * @see JsBaseEngineHelper::serializeForm() for option list.
+ */
+ public function serializeForm($options = array()) {
+ $options = array_merge(array('isForm' => false, 'inline' => false), $options);
+ $selector = $this->selection;
+ if (!$options['isForm']) {
+ $selector = $this->selection . '.closest("form")';
+ }
+ $method = '.serialize()';
+ if (!$options['inline']) {
+ $method .= ';';
+ }
+ return $selector . $method;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php
new file mode 100644
index 0000000..b3a293a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php
@@ -0,0 +1,592 @@
+<?php
+/**
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * JsEngineBaseClass
+ *
+ * Abstract Base Class for All JsEngines to extend. Provides generic methods.
+ *
+ * @package Cake.View.Helper
+ */
+abstract class JsBaseEngineHelper extends AppHelper {
+
+/**
+ * The js snippet for the current selection.
+ *
+ * @var string
+ */
+ public $selection;
+
+/**
+ * Collection of option maps. Option maps allow other helpers to use generic names for engine
+ * callbacks and options. Allowing uniform code access for all engine types. Their use is optional
+ * for end user use though.
+ *
+ * @var array
+ */
+ protected $_optionMap = array();
+
+/**
+ * An array of lowercase method names in the Engine that are buffered unless otherwise disabled.
+ * This allows specific 'end point' methods to be automatically buffered by the JsHelper.
+ *
+ * @var array
+ */
+ public $bufferedMethods = array('event', 'sortable', 'drag', 'drop', 'slider');
+
+/**
+ * Contains a list of callback names -> default arguments.
+ *
+ * @var array
+ */
+ protected $_callbackArguments = array();
+
+/**
+ * Create an `alert()` message in Javascript
+ *
+ * @param string $message Message you want to alter.
+ * @return string completed alert()
+ */
+ public function alert($message) {
+ return 'alert("' . $this->escape($message) . '");';
+ }
+
+/**
+ * Redirects to a URL. Creates a window.location modification snippet
+ * that can be used to trigger 'redirects' from Javascript.
+ *
+ * @param string|array $url
+ * @param array $options
+ * @return string completed redirect in javascript
+ */
+ public function redirect($url = null) {
+ return 'window.location = "' . Router::url($url) . '";';
+ }
+
+/**
+ * Create a `confirm()` message
+ *
+ * @param string $message Message you want confirmed.
+ * @return string completed confirm()
+ */
+ public function confirm($message) {
+ return 'confirm("' . $this->escape($message) . '");';
+ }
+
+/**
+ * Generate a confirm snippet that returns false from the current
+ * function scope.
+ *
+ * @param string $message Message to use in the confirm dialog.
+ * @return string completed confirm with return script
+ */
+ public function confirmReturn($message) {
+ $out = 'var _confirm = ' . $this->confirm($message);
+ $out .= "if (!_confirm) {\n\treturn false;\n}";
+ return $out;
+ }
+
+/**
+ * Create a `prompt()` Javascript function
+ *
+ * @param string $message Message you want to prompt.
+ * @param string $default Default message
+ * @return string completed prompt()
+ */
+ public function prompt($message, $default = '') {
+ return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
+ }
+
+/**
+ * Generates a JavaScript object in JavaScript Object Notation (JSON)
+ * from an array. Will use native JSON encode method if available, and $useNative == true
+ *
+ * ### Options:
+ *
+ * - `prefix` - String prepended to the returned data.
+ * - `postfix` - String appended to the returned data.
+ *
+ * @param array $data Data to be converted.
+ * @param array $options Set of options, see above.
+ * @return string A JSON code block
+ */
+ public function object($data = array(), $options = array()) {
+ $defaultOptions = array(
+ 'prefix' => '', 'postfix' => '',
+ );
+ $options = array_merge($defaultOptions, $options);
+
+ return $options['prefix'] . json_encode($data) . $options['postfix'];
+ }
+
+/**
+ * Converts a PHP-native variable of any type to a JSON-equivalent representation
+ *
+ * @param mixed $val A PHP variable to be converted to JSON
+ * @param boolean $quoteString If false, leaves string values unquoted
+ * @return string a JavaScript-safe/JSON representation of $val
+ */
+ public function value($val = array(), $quoteString = null, $key = 'value') {
+ if ($quoteString === null) {
+ $quoteString = true;
+ }
+ switch (true) {
+ case (is_array($val) || is_object($val)):
+ $val = $this->object($val);
+ break;
+ case ($val === null):
+ $val = 'null';
+ break;
+ case (is_bool($val)):
+ $val = ($val === true) ? 'true' : 'false';
+ break;
+ case (is_int($val)):
+ $val = $val;
+ break;
+ case (is_float($val)):
+ $val = sprintf("%.11f", $val);
+ break;
+ default:
+ $val = $this->escape($val);
+ if ($quoteString) {
+ $val = '"' . $val . '"';
+ }
+ break;
+ }
+ return $val;
+ }
+
+/**
+ * Escape a string to be JSON friendly.
+ *
+ * List of escaped elements:
+ *
+ * - "\r" => '\n'
+ * - "\n" => '\n'
+ * - '"' => '\"'
+ *
+ * @param string $string String that needs to get escaped.
+ * @return string Escaped string.
+ */
+ public function escape($string) {
+ return $this->_utf8ToHex($string);
+ }
+
+/**
+ * Encode a string into JSON. Converts and escapes necessary characters.
+ *
+ * @param string $string The string that needs to be utf8->hex encoded
+ * @return void
+ */
+ protected function _utf8ToHex($string) {
+ $length = strlen($string);
+ $return = '';
+ for ($i = 0; $i < $length; ++$i) {
+ $ord = ord($string{$i});
+ switch (true) {
+ case $ord == 0x08:
+ $return .= '\b';
+ break;
+ case $ord == 0x09:
+ $return .= '\t';
+ break;
+ case $ord == 0x0A:
+ $return .= '\n';
+ break;
+ case $ord == 0x0C:
+ $return .= '\f';
+ break;
+ case $ord == 0x0D:
+ $return .= '\r';
+ break;
+ case $ord == 0x22:
+ case $ord == 0x2F:
+ case $ord == 0x5C:
+ $return .= '\\' . $string{$i};
+ break;
+ case (($ord >= 0x20) && ($ord <= 0x7F)):
+ $return .= $string{$i};
+ break;
+ case (($ord & 0xE0) == 0xC0):
+ if ($i + 1 >= $length) {
+ $i += 1;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 1;
+ break;
+ case (($ord & 0xF0) == 0xE0):
+ if ($i + 2 >= $length) {
+ $i += 2;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 2;
+ break;
+ case (($ord & 0xF8) == 0xF0):
+ if ($i + 3 >= $length) {
+ $i += 3;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 3;
+ break;
+ case (($ord & 0xFC) == 0xF8):
+ if ($i + 4 >= $length) {
+ $i += 4;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 4;
+ break;
+ case (($ord & 0xFE) == 0xFC):
+ if ($i + 5 >= $length) {
+ $i += 5;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4} . $string{$i + 5};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 5;
+ break;
+ }
+ }
+ return $return;
+ }
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return JsBaseEngineHelper instance of $this. Allows chained methods.
+ */
+ abstract public function get($selector);
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - `wrap` - Whether you want the callback wrapped in an anonymous function. (defaults to true)
+ * - `stop` - Whether you want the event to stopped. (defaults to true)
+ *
+ * @param string $type Type of event to bind to the current dom id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ abstract public function event($type, $callback, $options = array());
+
+/**
+ * Create a domReady event. This is a special event in many libraries
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ abstract public function domReady($functionBody);
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ abstract public function each($callback);
+
+/**
+ * Trigger an Effect.
+ *
+ * ### Supported Effects
+ *
+ * The following effects are supported by all core JsEngines
+ *
+ * - `show` - reveal an element.
+ * - `hide` - hide an element.
+ * - `fadeIn` - Fade in an element.
+ * - `fadeOut` - Fade out an element.
+ * - `slideIn` - Slide an element in.
+ * - `slideOut` - Slide an element out.
+ *
+ * ### Options
+ *
+ * - `speed` - Speed at which the animation should occur. Accepted values are 'slow', 'fast'. Not all effects use
+ * the speed option.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ */
+ abstract public function effect($name, $options = array());
+
+/**
+ * Make an XHR request
+ *
+ * ### Event Options
+ *
+ * - `complete` - Callback to fire on complete.
+ * - `success` - Callback to fire on success.
+ * - `before` - Callback to fire on request initialization.
+ * - `error` - Callback to fire on request failure.
+ *
+ * ### Options
+ *
+ * - `method` - The method to make the request with defaults to GET in more libraries
+ * - `async` - Whether or not you want an asynchronous request.
+ * - `data` - Additional data to send.
+ * - `update` - Dom id to update with the content of the request.
+ * - `type` - Data type for response. 'json' and 'html' are supported. Default is html for most libraries.
+ * - `evalScripts` - Whether or not <script> tags should be eval'ed.
+ * - `dataExpression` - Should the `data` key be treated as a callback. Useful for supplying `$options['data']` as
+ * another Javascript expression.
+ *
+ * @param string|array $url Array or String URL to target with the request.
+ * @param array $options Array of options. See above for cross library supported options
+ * @return string XHR request.
+ */
+ abstract public function request($url, $options = array());
+
+/**
+ * Create a draggable element. Works on the currently selected element.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `handle` - selector to the handle element.
+ * - `snapGrid` - The pixel grid that movement snaps to, an array(x, y)
+ * - `container` - The element that acts as a bounding box for the draggable element.
+ *
+ * ### Event Options
+ *
+ * - `start` - Event fired when the drag starts
+ * - `drag` - Event fired on every step of the drag
+ * - `stop` - Event fired when dragging stops (mouse release)
+ *
+ * @param array $options Options array see above.
+ * @return string Completed drag script
+ */
+ abstract public function drag($options = array());
+
+/**
+ * Create a droppable element. Allows for draggable elements to be dropped on it.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `accept` - Selector for elements this droppable will accept.
+ * - `hoverclass` - Class to add to droppable when a draggable is over.
+ *
+ * ### Event Options
+ *
+ * - `drop` - Event fired when an element is dropped into the drop zone.
+ * - `hover` - Event fired when a drag enters a drop zone.
+ * - `leave` - Event fired when a drag is removed from a drop zone without being dropped.
+ *
+ * @param array $options Array of options for the drop. See above.
+ * @return string Completed drop script
+ */
+ abstract public function drop($options = array());
+
+/**
+ * Create a sortable element.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `containment` - Container for move action
+ * - `handle` - Selector to handle element. Only this element will start sort action.
+ * - `revert` - Whether or not to use an effect to move sortable into final position.
+ * - `opacity` - Opacity of the placeholder
+ * - `distance` - Distance a sortable must be dragged before sorting starts.
+ *
+ * ### Event Options
+ *
+ * - `start` - Event fired when sorting starts
+ * - `sort` - Event fired during sorting
+ * - `complete` - Event fired when sorting completes.
+ *
+ * @param array $options Array of options for the sortable. See above.
+ * @return string Completed sortable script.
+ */
+ abstract public function sortable($options = array());
+
+/**
+ * Create a slider UI widget. Comprised of a track and knob.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `handle` - The id of the element used in sliding.
+ * - `direction` - The direction of the slider either 'vertical' or 'horizontal'
+ * - `min` - The min value for the slider.
+ * - `max` - The max value for the slider.
+ * - `step` - The number of steps or ticks the slider will have.
+ * - `value` - The initial offset of the slider.
+ *
+ * ### Events
+ *
+ * - `change` - Fired when the slider's value is updated
+ * - `complete` - Fired when the user stops sliding the handle
+ *
+ * @param array $options Array of options for the slider. See above.
+ * @return string Completed slider script
+ */
+ abstract public function slider($options = array());
+
+/**
+ * Serialize the form attached to $selector.
+ * Pass `true` for $isForm if the current selection is a form element.
+ * Converts the form or the form element attached to the current selection into a string/json object
+ * (depending on the library implementation) for use with XHR operations.
+ *
+ * ### Options
+ *
+ * - `isForm` - is the current selection a form, or an input? (defaults to false)
+ * - `inline` - is the rendered statement going to be used inside another JS statement? (defaults to false)
+ *
+ * @param array $options options for serialization generation.
+ * @return string completed form serialization script
+ */
+ abstract public function serializeForm($options = array());
+
+/**
+ * Parse an options assoc array into an Javascript object literal.
+ * Similar to object() but treats any non-integer value as a string,
+ * does not include `{ }`
+ *
+ * @param array $options Options to be converted
+ * @param array $safeKeys Keys that should not be escaped.
+ * @return string Parsed JSON options without enclosing { }.
+ */
+ protected function _parseOptions($options, $safeKeys = array()) {
+ $out = array();
+ $safeKeys = array_flip($safeKeys);
+ foreach ($options as $key => $value) {
+ if (!is_int($value) && !isset($safeKeys[$key])) {
+ $value = $this->value($value);
+ }
+ $out[] = $key . ':' . $value;
+ }
+ sort($out);
+ return join(', ', $out);
+ }
+
+/**
+ * Maps Abstract options to engine specific option names.
+ * If attributes are missing from the map, they are not changed.
+ *
+ * @param string $method Name of method whose options are being worked with.
+ * @param array $options Array of options to map.
+ * @return array Array of mapped options.
+ */
+ protected function _mapOptions($method, $options) {
+ if (!isset($this->_optionMap[$method])) {
+ return $options;
+ }
+ foreach ($this->_optionMap[$method] as $abstract => $concrete) {
+ if (isset($options[$abstract])) {
+ $options[$concrete] = $options[$abstract];
+ unset($options[$abstract]);
+ }
+ }
+ return $options;
+ }
+
+/**
+ * Prepare callbacks and wrap them with function ([args]) { } as defined in
+ * _callbackArgs array.
+ *
+ * @param string $method Name of the method you are preparing callbacks for.
+ * @param array $options Array of options being parsed
+ * @param array $callbacks Additional Keys that contain callbacks
+ * @return array Array of options with callbacks added.
+ */
+ protected function _prepareCallbacks($method, $options, $callbacks = array()) {
+ $wrapCallbacks = true;
+ if (isset($options['wrapCallbacks'])) {
+ $wrapCallbacks = $options['wrapCallbacks'];
+ }
+ unset($options['wrapCallbacks']);
+ if (!$wrapCallbacks) {
+ return $options;
+ }
+ $callbackOptions = array();
+ if (isset($this->_callbackArguments[$method])) {
+ $callbackOptions = $this->_callbackArguments[$method];
+ }
+ $callbacks = array_unique(array_merge(array_keys($callbackOptions), (array)$callbacks));
+
+ foreach ($callbacks as $callback) {
+ if (empty($options[$callback])) {
+ continue;
+ }
+ $args = null;
+ if (!empty($callbackOptions[$callback])) {
+ $args = $callbackOptions[$callback];
+ }
+ $options[$callback] = 'function (' . $args . ') {' . $options[$callback] . '}';
+ }
+ return $options;
+ }
+
+/**
+ * Convenience wrapper method for all common option processing steps.
+ * Runs _mapOptions, _prepareCallbacks, and _parseOptions in order.
+ *
+ * @param string $method Name of method processing options for.
+ * @param array $options Array of options to process.
+ * @return string Parsed options string.
+ */
+ protected function _processOptions($method, $options) {
+ $options = $this->_mapOptions($method, $options);
+ $options = $this->_prepareCallbacks($method, $options);
+ $options = $this->_parseOptions($options, array_keys($this->_callbackArguments[$method]));
+ return $options;
+ }
+
+/**
+ * Convert an array of data into a query string
+ *
+ * @param array $parameters Array of parameters to convert to a query string
+ * @return string Querystring fragment
+ */
+ protected function _toQuerystring($parameters) {
+ $out = '';
+ $keys = array_keys($parameters);
+ $count = count($parameters);
+ for ($i = 0; $i < $count; $i++) {
+ $out .= $keys[$i] . '=' . $parameters[$keys[$i]];
+ if ($i < $count - 1) {
+ $out .= '&';
+ }
+ }
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php
new file mode 100644
index 0000000..5490fbb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php
@@ -0,0 +1,434 @@
+<?php
+/**
+ * Javascript Generator class file.
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('JsBaseEngineHelper', 'View/Helper');
+App::uses('Multibyte', 'I18n');
+
+/**
+ * Javascript Generator helper class for easy use of JavaScript.
+ *
+ * JsHelper provides an abstract interface for authoring JavaScript with a
+ * given client-side library.
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @property FormHelper $Form
+ */
+class JsHelper extends AppHelper {
+
+/**
+ * Whether or not you want scripts to be buffered or output.
+ *
+ * @var boolean
+ */
+ public $bufferScripts = true;
+
+/**
+ * Helper dependencies
+ *
+ * @var array
+ */
+ public $helpers = array('Html', 'Form');
+
+/**
+ * Variables to pass to Javascript.
+ *
+ * @var array
+ * @see JsHelper::set()
+ */
+ protected $_jsVars = array();
+
+/**
+ * Scripts that are queued for output
+ *
+ * @var array
+ * @see JsHelper::buffer()
+ */
+ protected $_bufferedScripts = array();
+
+/**
+ * Current Javascript Engine that is being used
+ *
+ * @var string
+ */
+ protected $_engineName;
+
+/**
+ * The javascript variable created by set() variables.
+ *
+ * @var string
+ */
+ public $setVariable = 'app';
+
+/**
+ * Constructor - determines engine helper
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Settings array contains name of engine helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $className = 'Jquery';
+ if (is_array($settings) && isset($settings[0])) {
+ $className = $settings[0];
+ } elseif (is_string($settings)) {
+ $className = $settings;
+ }
+ $engineName = $className;
+ list($plugin, $className) = pluginSplit($className);
+
+ $this->_engineName = $className . 'Engine';
+ $engineClass = $engineName . 'Engine';
+ $this->helpers[] = $engineClass;
+ parent::__construct($View, $settings);
+ }
+
+/**
+ * call__ Allows for dispatching of methods to the Engine Helper.
+ * methods in the Engines bufferedMethods list will be automatically buffered.
+ * You can control buffering with the buffer param as well. By setting the last parameter to
+ * any engine method to a boolean you can force or disable buffering.
+ *
+ * e.g. `$js->get('#foo')->effect('fadeIn', array('speed' => 'slow'), true);`
+ *
+ * Will force buffering for the effect method. If the method takes an options array you may also add
+ * a 'buffer' param to the options array and control buffering there as well.
+ *
+ * e.g. `$js->get('#foo')->event('click', $functionContents, array('buffer' => true));`
+ *
+ * The buffer parameter will not be passed onto the EngineHelper.
+ *
+ * @param string $method Method to be called
+ * @param array $params Parameters for the method being called.
+ * @return mixed Depends on the return of the dispatched method, or it could be an instance of the EngineHelper
+ */
+ public function __call($method, $params) {
+ if ($this->{$this->_engineName} && method_exists($this->{$this->_engineName}, $method)) {
+ $buffer = false;
+ $engineHelper = $this->{$this->_engineName};
+ if (in_array(strtolower($method), $engineHelper->bufferedMethods)) {
+ $buffer = true;
+ }
+ if (count($params) > 0) {
+ $lastParam = $params[count($params) - 1];
+ $hasBufferParam = (is_bool($lastParam) || is_array($lastParam) && isset($lastParam['buffer']));
+ if ($hasBufferParam && is_bool($lastParam)) {
+ $buffer = $lastParam;
+ unset($params[count($params) - 1]);
+ } elseif ($hasBufferParam && is_array($lastParam)) {
+ $buffer = $lastParam['buffer'];
+ unset($params['buffer']);
+ }
+ }
+
+ $out = call_user_func_array(array(&$engineHelper, $method), $params);
+ if ($this->bufferScripts && $buffer && is_string($out)) {
+ $this->buffer($out);
+ return null;
+ }
+ if (is_object($out) && is_a($out, 'JsBaseEngineHelper')) {
+ return $this;
+ }
+ return $out;
+ }
+ if (method_exists($this, $method . '_')) {
+ return call_user_func(array(&$this, $method . '_'), $params);
+ }
+ trigger_error(__d('cake_dev', 'JsHelper:: Missing Method %s is undefined', $method), E_USER_WARNING);
+ }
+
+/**
+ * Overwrite inherited Helper::value()
+ * See JsBaseEngineHelper::value() for more information on this method.
+ *
+ * @param mixed $val A PHP variable to be converted to JSON
+ * @param boolean $quoteString If false, leaves string values unquoted
+ * @return string a JavaScript-safe/JSON representation of $val
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::value
+ **/
+ public function value($val = array(), $quoteString = null, $key = 'value') {
+ if ($quoteString === null) {
+ $quoteString = true;
+ }
+ return $this->{$this->_engineName}->value($val, $quoteString);
+ }
+
+/**
+ * Writes all Javascript generated so far to a code block or
+ * caches them to a file and returns a linked script. If no scripts have been
+ * buffered this method will return null. If the request is an XHR(ajax) request
+ * onDomReady will be set to false. As the dom is already 'ready'.
+ *
+ * ### Options
+ *
+ * - `inline` - Set to true to have scripts output as a script block inline
+ * if `cache` is also true, a script link tag will be generated. (default true)
+ * - `cache` - Set to true to have scripts cached to a file and linked in (default false)
+ * - `clear` - Set to false to prevent script cache from being cleared (default true)
+ * - `onDomReady` - wrap cached scripts in domready event (default true)
+ * - `safe` - if an inline block is generated should it be wrapped in <![CDATA[ ... ]]> (default true)
+ *
+ * @param array $options options for the code block
+ * @return mixed Completed javascript tag if there are scripts, if there are no buffered
+ * scripts null will be returned.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::writeBuffer
+ */
+ public function writeBuffer($options = array()) {
+ $domReady = !$this->request->is('ajax');
+ $defaults = array(
+ 'onDomReady' => $domReady, 'inline' => true,
+ 'cache' => false, 'clear' => true, 'safe' => true
+ );
+ $options = array_merge($defaults, $options);
+ $script = implode("\n", $this->getBuffer($options['clear']));
+
+ if (empty($script)) {
+ return null;
+ }
+
+ if ($options['onDomReady']) {
+ $script = $this->{$this->_engineName}->domReady($script);
+ }
+ $opts = $options;
+ unset($opts['onDomReady'], $opts['cache'], $opts['clear']);
+
+ if (!$options['cache'] && $options['inline']) {
+ return $this->Html->scriptBlock($script, $opts);
+ }
+
+ if ($options['cache'] && $options['inline']) {
+ $filename = md5($script);
+ if (!file_exists(JS . $filename . '.js')) {
+ cache(str_replace(WWW_ROOT, '', JS) . $filename . '.js', $script, '+999 days', 'public');
+ }
+ return $this->Html->script($filename);
+ }
+ $this->Html->scriptBlock($script, $opts);
+ return null;
+ }
+
+/**
+ * Write a script to the buffered scripts.
+ *
+ * @param string $script Script string to add to the buffer.
+ * @param boolean $top If true the script will be added to the top of the
+ * buffered scripts array. If false the bottom.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::buffer
+ */
+ public function buffer($script, $top = false) {
+ if ($top) {
+ array_unshift($this->_bufferedScripts, $script);
+ } else {
+ $this->_bufferedScripts[] = $script;
+ }
+ }
+
+/**
+ * Get all the buffered scripts
+ *
+ * @param boolean $clear Whether or not to clear the script caches (default true)
+ * @return array Array of scripts added to the request.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::getBuffer
+ */
+ public function getBuffer($clear = true) {
+ $this->_createVars();
+ $scripts = $this->_bufferedScripts;
+ if ($clear) {
+ $this->_bufferedScripts = array();
+ $this->_jsVars = array();
+ }
+ return $scripts;
+ }
+
+/**
+ * Generates the object string for variables passed to javascript.
+ *
+ * @return string Generated JSON object of all set vars
+ */
+ protected function _createVars() {
+ if (!empty($this->_jsVars)) {
+ $setVar = (strpos($this->setVariable, '.')) ? $this->setVariable : 'window.' . $this->setVariable;
+ $this->buffer($setVar . ' = ' . $this->object($this->_jsVars) . ';', true);
+ }
+ }
+
+/**
+ * Generate an 'Ajax' link. Uses the selected JS engine to create a link
+ * element that is enhanced with Javascript. Options can include
+ * both those for HtmlHelper::link() and JsBaseEngine::request(), JsBaseEngine::event();
+ *
+ * ### Options
+ *
+ * - `confirm` - Generate a confirm() dialog before sending the event.
+ * - `id` - use a custom id.
+ * - `htmlAttributes` - additional non-standard htmlAttributes. Standard attributes are class, id,
+ * rel, title, escape, onblur and onfocus.
+ * - `buffer` - Disable the buffering and return a script tag in addition to the link.
+ *
+ * @param string $title Title for the link.
+ * @param string|array $url Mixed either a string URL or an cake url array.
+ * @param array $options Options for both the HTML element and Js::request()
+ * @return string Completed link. If buffering is disabled a script tag will be returned as well.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::link
+ */
+ public function link($title, $url = null, $options = array()) {
+ if (!isset($options['id'])) {
+ $options['id'] = 'link-' . intval(mt_rand());
+ }
+ list($options, $htmlOptions) = $this->_getHtmlOptions($options);
+ $out = $this->Html->link($title, $url, $htmlOptions);
+ $this->get('#' . $htmlOptions['id']);
+ $requestString = $event = '';
+ if (isset($options['confirm'])) {
+ $requestString = $this->confirmReturn($options['confirm']);
+ unset($options['confirm']);
+ }
+ $buffer = isset($options['buffer']) ? $options['buffer'] : null;
+ $safe = isset($options['safe']) ? $options['safe'] : true;
+ unset($options['buffer'], $options['safe']);
+
+ $requestString .= $this->request($url, $options);
+
+ if (!empty($requestString)) {
+ $event = $this->event('click', $requestString, $options + array('buffer' => $buffer));
+ }
+ if (isset($buffer) && !$buffer) {
+ $opts = array('safe' => $safe);
+ $out .= $this->Html->scriptBlock($event, $opts);
+ }
+ return $out;
+ }
+
+/**
+ * Pass variables into Javascript. Allows you to set variables that will be
+ * output when the buffer is fetched with `JsHelper::getBuffer()` or `JsHelper::writeBuffer()`
+ * The Javascript variable used to output set variables can be controlled with `JsHelper::$setVariable`
+ *
+ * @param string|array $one Either an array of variables to set, or the name of the variable to set.
+ * @param string|array $two If $one is a string, $two is the value for that key.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::set
+ */
+ public function set($one, $two = null) {
+ $data = null;
+ if (is_array($one)) {
+ if (is_array($two)) {
+ $data = array_combine($one, $two);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($one => $two);
+ }
+ if ($data == null) {
+ return false;
+ }
+ $this->_jsVars = array_merge($this->_jsVars, $data);
+ }
+
+/**
+ * Uses the selected JS engine to create a submit input
+ * element that is enhanced with Javascript. Options can include
+ * both those for FormHelper::submit() and JsBaseEngine::request(), JsBaseEngine::event();
+ *
+ * Forms submitting with this method, cannot send files. Files do not transfer over XmlHttpRequest
+ * and require an iframe or flash.
+ *
+ * ### Options
+ *
+ * - `url` The url you wish the XHR request to submit to.
+ * - `confirm` A string to use for a confirm() message prior to submitting the request.
+ * - `method` The method you wish the form to send by, defaults to POST
+ * - `buffer` Whether or not you wish the script code to be buffered, defaults to true.
+ * - Also see options for JsHelper::request() and JsHelper::event()
+ *
+ * @param string $caption The display text of the submit button.
+ * @param array $options Array of options to use. See the options for the above mentioned methods.
+ * @return string Completed submit button.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::submit
+ */
+ public function submit($caption = null, $options = array()) {
+ if (!isset($options['id'])) {
+ $options['id'] = 'submit-' . intval(mt_rand());
+ }
+ $formOptions = array('div');
+ list($options, $htmlOptions) = $this->_getHtmlOptions($options, $formOptions);
+ $out = $this->Form->submit($caption, $htmlOptions);
+
+ $this->get('#' . $htmlOptions['id']);
+
+ $options['data'] = $this->serializeForm(array('isForm' => false, 'inline' => true));
+ $requestString = $url = '';
+ if (isset($options['confirm'])) {
+ $requestString = $this->confirmReturn($options['confirm']);
+ unset($options['confirm']);
+ }
+ if (isset($options['url'])) {
+ $url = $options['url'];
+ unset($options['url']);
+ }
+ if (!isset($options['method'])) {
+ $options['method'] = 'post';
+ }
+ $options['dataExpression'] = true;
+
+ $buffer = isset($options['buffer']) ? $options['buffer'] : null;
+ $safe = isset($options['safe']) ? $options['safe'] : true;
+ unset($options['buffer'], $options['safe']);
+
+ $requestString .= $this->request($url, $options);
+ if (!empty($requestString)) {
+ $event = $this->event('click', $requestString, $options + array('buffer' => $buffer));
+ }
+ if (isset($buffer) && !$buffer) {
+ $opts = array('safe' => $safe);
+ $out .= $this->Html->scriptBlock($event, $opts);
+ }
+ return $out;
+ }
+
+/**
+ * Parse a set of Options and extract the Html options.
+ * Extracted Html Options are removed from the $options param.
+ *
+ * @param array $options Options to filter.
+ * @param array $additional Array of additional keys to extract and include in the return options array.
+ * @return array Array of js options and Htmloptions
+ */
+ protected function _getHtmlOptions($options, $additional = array()) {
+ $htmlKeys = array_merge(
+ array('class', 'id', 'escape', 'onblur', 'onfocus', 'rel', 'title', 'style'),
+ $additional
+ );
+ $htmlOptions = array();
+ foreach ($htmlKeys as $key) {
+ if (isset($options[$key])) {
+ $htmlOptions[$key] = $options[$key];
+ }
+ unset($options[$key]);
+ }
+ if (isset($options['htmlAttributes'])) {
+ $htmlOptions = array_merge($htmlOptions, $options['htmlAttributes']);
+ unset($options['htmlAttributes']);
+ }
+ return array($options, $htmlOptions);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php
new file mode 100644
index 0000000..3919754
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php
@@ -0,0 +1,376 @@
+<?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.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('JsBaseEngineHelper', 'View/Helper');
+
+/**
+ * MooTools Engine Helper for JsHelper
+ *
+ * Provides MooTools specific Javascript for JsHelper.
+ * Assumes that you have the following MooTools packages
+ *
+ * - Remote, Remote.HTML, Remote.JSON
+ * - Fx, Fx.Tween, Fx.Morph
+ * - Selectors, DomReady,
+ * - Drag, Drag.Move
+ *
+ * @package Cake.View.Helper
+ */
+class MootoolsEngineHelper extends JsBaseEngineHelper {
+
+/**
+ * Option mappings for MooTools
+ *
+ * @var array
+ */
+ protected $_optionMap = array(
+ 'request' => array(
+ 'complete' => 'onComplete',
+ 'success' => 'onSuccess',
+ 'before' => 'onRequest',
+ 'error' => 'onFailure'
+ ),
+ 'sortable' => array(
+ 'distance' => 'snap',
+ 'containment' => 'constrain',
+ 'sort' => 'onSort',
+ 'complete' => 'onComplete',
+ 'start' => 'onStart',
+ ),
+ 'drag' => array(
+ 'snapGrid' => 'snap',
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ 'stop' => 'onComplete',
+ ),
+ 'drop' => array(
+ 'drop' => 'onDrop',
+ 'hover' => 'onEnter',
+ 'leave' => 'onLeave',
+ ),
+ 'slider' => array(
+ 'complete' => 'onComplete',
+ 'change' => 'onChange',
+ 'direction' => 'mode',
+ 'step' => 'steps'
+ )
+ );
+
+/**
+ * Contains a list of callback names -> default arguments.
+ *
+ * @var array
+ */
+ protected $_callbackArguments = array(
+ 'slider' => array(
+ 'onTick' => 'position',
+ 'onChange' => 'step',
+ 'onComplete' => 'event'
+ ),
+ 'request' => array(
+ 'onRequest' => '',
+ 'onComplete' => '',
+ 'onCancel' => '',
+ 'onSuccess' => 'responseText, responseXML',
+ 'onFailure' => 'xhr',
+ 'onException' => 'headerName, value',
+ ),
+ 'drag' => array(
+ 'onBeforeStart' => 'element',
+ 'onStart' => 'element',
+ 'onSnap' => 'element',
+ 'onDrag' => 'element, event',
+ 'onComplete' => 'element, event',
+ 'onCancel' => 'element',
+ ),
+ 'drop' => array(
+ 'onBeforeStart' => 'element',
+ 'onStart' => 'element',
+ 'onSnap' => 'element',
+ 'onDrag' => 'element, event',
+ 'onComplete' => 'element, event',
+ 'onCancel' => 'element',
+ 'onDrop' => 'element, droppable, event',
+ 'onLeave' => 'element, droppable',
+ 'onEnter' => 'element, droppable',
+ ),
+ 'sortable' => array(
+ 'onStart' => 'element, clone',
+ 'onSort' => 'element, clone',
+ 'onComplete' => 'element',
+ )
+ );
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return MootoolsEngineHelper instance of $this. Allows chained methods.
+ */
+ public function get($selector) {
+ $this->_multipleSelection = false;
+ if ($selector == 'window' || $selector == 'document') {
+ $this->selection = "$(" . $selector . ")";
+ return $this;
+ }
+ if (preg_match('/^#[^\s.]+$/', $selector)) {
+ $this->selection = '$("' . substr($selector, 1) . '")';
+ return $this;
+ }
+ $this->_multipleSelection = true;
+ $this->selection = '$$("' . $selector . '")';
+ return $this;
+ }
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
+ * - 'stop' - Whether you want the event to stopped. (defaults true)
+ *
+ * @param string $type Type of event to bind to the current dom id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ public function event($type, $callback, $options = array()) {
+ $defaults = array('wrap' => true, 'stop' => true);
+ $options = array_merge($defaults, $options);
+
+ $function = 'function (event) {%s}';
+ if ($options['wrap'] && $options['stop']) {
+ $callback = "event.stop();\n" . $callback;
+ }
+ if ($options['wrap']) {
+ $callback = sprintf($function, $callback);
+ }
+ $out = $this->selection . ".addEvent(\"{$type}\", $callback);";
+ return $out;
+ }
+
+/**
+ * Create a domReady event. This is a special event in many libraries
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ public function domReady($functionBody) {
+ $this->selection = 'window';
+ return $this->event('domready', $functionBody, array('stop' => false));
+ }
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ public function each($callback) {
+ return $this->selection . '.each(function (item, index) {' . $callback . '});';
+ }
+
+/**
+ * Trigger an Effect.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ * @see JsBaseEngineHelper::effect()
+ */
+ public function effect($name, $options = array()) {
+ $speed = null;
+ if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
+ if ($options['speed'] == 'fast') {
+ $speed = '"short"';
+ } elseif ($options['speed'] == 'slow') {
+ $speed = '"long"';
+ }
+ }
+ $effect = '';
+ switch ($name) {
+ case 'hide':
+ $effect = 'setStyle("display", "none")';
+ break;
+ case 'show':
+ $effect = 'setStyle("display", "")';
+ break;
+ case 'fadeIn':
+ case 'fadeOut':
+ case 'slideIn':
+ case 'slideOut':
+ list($effectName, $direction) = preg_split('/([A-Z][a-z]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $direction = strtolower($direction);
+ if ($speed) {
+ $effect .= "set(\"$effectName\", {duration:$speed}).";
+ }
+ $effect .= "$effectName(\"$direction\")";
+ break;
+ }
+ return $this->selection . '.' . $effect . ';';
+ }
+
+/**
+ * Create an new Request.
+ *
+ * Requires `Request`. If you wish to use 'update' key you must have ```Request.HTML```
+ * if you wish to do Json requests you will need ```JSON``` and ```Request.JSON```.
+ *
+ * @param string|array $url
+ * @param array $options
+ * @return string The completed ajax call.
+ */
+ public function request($url, $options = array()) {
+ $url = $this->url($url);
+ $options = $this->_mapOptions('request', $options);
+ $type = $data = null;
+ if (isset($options['type']) || isset($options['update'])) {
+ if (isset($options['type']) && strtolower($options['type']) == 'json') {
+ $type = '.JSON';
+ }
+ if (isset($options['update'])) {
+ $options['update'] = str_replace('#', '', $options['update']);
+ $type = '.HTML';
+ }
+ unset($options['type']);
+ }
+ if (!empty($options['data'])) {
+ $data = $options['data'];
+ unset($options['data']);
+ }
+ $options['url'] = $url;
+ $options = $this->_prepareCallbacks('request', $options);
+ if (!empty($options['dataExpression'])) {
+ $callbacks[] = 'data';
+ unset($options['dataExpression']);
+ } elseif (!empty($data)) {
+ $data = $this->object($data);
+ }
+ $options = $this->_parseOptions($options, array_keys($this->_callbackArguments['request']));
+ return "var jsRequest = new Request$type({{$options}}).send($data);";
+ }
+
+/**
+ * Create a sortable element.
+ *
+ * Requires the `Sortables` plugin from MootoolsMore
+ *
+ * @param array $options Array of options for the sortable.
+ * @return string Completed sortable script.
+ * @see JsBaseEngineHelper::sortable() for options list.
+ */
+ public function sortable($options = array()) {
+ $options = $this->_processOptions('sortable', $options);
+ return 'var jsSortable = new Sortables(' . $this->selection . ', {' . $options . '});';
+ }
+
+/**
+ * Create a Draggable element.
+ *
+ * Requires the `Drag` plugin from MootoolsMore
+ *
+ * @param array $options Array of options for the draggable.
+ * @return string Completed draggable script.
+ * @see JsHelper::drag() for options list.
+ */
+ public function drag($options = array()) {
+ $options = $this->_processOptions('drag', $options);
+ return $this->selection . '.makeDraggable({' . $options . '});';
+ }
+
+/**
+ * Create a Droppable element.
+ *
+ * Requires the `Drag` and `Drag.Move` plugins from MootoolsMore
+ *
+ * Droppables in Mootools function differently from other libraries. Droppables
+ * are implemented as an extension of Drag. So in addition to making a get() selection for
+ * the droppable element. You must also provide a selector rule to the draggable element. Furthermore,
+ * Mootools droppables inherit all options from Drag.
+ *
+ * @param array $options Array of options for the droppable.
+ * @return string Completed droppable script.
+ * @see JsBaseEngineHelper::drop() for options list.
+ */
+ public function drop($options = array()) {
+ if (empty($options['drag'])) {
+ trigger_error(
+ __d('cake_dev', 'MootoolsEngine::drop() requires a "drag" option to properly function'), E_USER_WARNING
+ );
+ return false;
+ }
+ $options['droppables'] = $this->selection;
+
+ $this->get($options['drag']);
+ unset($options['drag']);
+
+ $options = $this->_mapOptions('drag', $this->_mapOptions('drop', $options));
+ $options = $this->_prepareCallbacks('drop', $options);
+ $safe = array_merge(array_keys($this->_callbackArguments['drop']), array('droppables'));
+ $optionString = $this->_parseOptions($options, $safe);
+ $out = $this->selection . '.makeDraggable({' . $optionString . '});';
+ $this->selection = $options['droppables'];
+ return $out;
+ }
+
+/**
+ * Create a slider control
+ *
+ * Requires `Slider` from MootoolsMore
+ *
+ * @param array $options Array of options for the slider.
+ * @return string Completed slider script.
+ * @see JsBaseEngineHelper::slider() for options list.
+ */
+ public function slider($options = array()) {
+ $slider = $this->selection;
+ $this->get($options['handle']);
+ unset($options['handle']);
+
+ if (isset($options['min']) && isset($options['max'])) {
+ $options['range'] = array($options['min'], $options['max']);
+ unset($options['min'], $options['max']);
+ }
+ $optionString = $this->_processOptions('slider', $options);
+ if (!empty($optionString)) {
+ $optionString = ', {' . $optionString . '}';
+ }
+ $out = 'var jsSlider = new Slider(' . $slider . ', ' . $this->selection . $optionString . ');';
+ $this->selection = $slider;
+ return $out;
+ }
+
+/**
+ * Serialize the form attached to $selector.
+ *
+ * @param array $options Array of options.
+ * @return string Completed serializeForm() snippet
+ * @see JsBaseEngineHelper::serializeForm()
+ */
+ public function serializeForm($options = array()) {
+ $options = array_merge(array('isForm' => false, 'inline' => false), $options);
+ $selection = $this->selection;
+ if (!$options['isForm']) {
+ $selection = '$(' . $this->selection . '.form)';
+ }
+ $method = '.toQueryString()';
+ if (!$options['inline']) {
+ $method .= ';';
+ }
+ return $selection . $method;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php
new file mode 100644
index 0000000..5889484
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * Number Helper.
+ *
+ * Methods to make numbers more readable.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeNumber', 'Utility');
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Number helper library.
+ *
+ * Methods to make numbers more readable.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html
+ * @see CakeNumber
+ */
+class NumberHelper extends AppHelper {
+
+/**
+ * CakeNumber instance
+ *
+ * @var CakeNumber
+ */
+ protected $_engine = null;
+
+/**
+ * Default Constructor
+ *
+ * ### Settings:
+ *
+ * - `engine` Class name to use to replace CakeNumber functionality
+ * The class needs to be placed in the `Utility` directory.
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper
+ * @throws CakeException When the engine class could not be found.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $settings = Hash::merge(array('engine' => 'CakeNumber'), $settings);
+ parent::__construct($View, $settings);
+ list($plugin, $engineClass) = pluginSplit($settings['engine'], true);
+ App::uses($engineClass, $plugin . 'Utility');
+ if (class_exists($engineClass)) {
+ $this->_engine = new $engineClass($settings);
+ } else {
+ throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+ }
+ }
+
+/**
+ * Call methods from CakeNumber utility class
+ */
+ public function __call($method, $params) {
+ return call_user_func_array(array($this->_engine, $method), $params);
+ }
+
+/**
+ * @see: CakeNumber::precision()
+ *
+ * @param float $number A floating point number.
+ * @param integer $precision The precision of the returned number.
+ * @return float Formatted float.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::precision
+ */
+ public function precision($number, $precision = 3) {
+ return $this->_engine->precision($number, $precision);
+ }
+
+/**
+ * @see: CakeNumber::toReadableSize()
+ *
+ * @param integer $size Size in bytes
+ * @return string Human readable size
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
+ */
+ public function toReadableSize($size) {
+ return $this->_engine->toReadableSize($size);
+ }
+
+/**
+ * @see: CakeNumber::toPercentage()
+ *
+ * @param float $number A floating point number
+ * @param integer $precision The precision of the returned number
+ * @return string Percentage string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage
+ */
+ public function toPercentage($number, $precision = 2) {
+ return $this->_engine->toPercentage($number, $precision);
+ }
+
+/**
+ * @see: CakeNumber::format()
+ *
+ * @param float $number A floating point number
+ * @param integer $options if int then places, if string then before, if (,.-) then use it
+ * or array with places and before keys
+ * @return string formatted number
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::format
+ */
+ public function format($number, $options = false) {
+ return $this->_engine->format($number, $options);
+ }
+
+/**
+ * @see: CakeNumber::currency()
+ *
+ * @param float $number
+ * @param string $currency Shortcut to default options. Valid values are 'USD', 'EUR', 'GBP', otherwise
+ * set at least 'before' and 'after' options.
+ * @param array $options
+ * @return string Number formatted as a currency.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
+ */
+ public function currency($number, $currency = 'USD', $options = array()) {
+ return $this->_engine->currency($number, $currency, $options);
+ }
+
+/**
+ * @see: CakeNumber::addFormat()
+ *
+ * @param string $formatName The format name to be used in the future.
+ * @param array $options The array of options for this format.
+ * @return void
+ * @see NumberHelper::currency()
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::addFormat
+ */
+ public function addFormat($formatName, $options) {
+ return $this->_engine->addFormat($formatName, $options);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php
new file mode 100644
index 0000000..05a9935
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php
@@ -0,0 +1,901 @@
+<?php
+/**
+ * Pagination Helper class file.
+ *
+ * Generates pagination links
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Pagination Helper class for easy generation of pagination links.
+ *
+ * PaginationHelper encloses all methods needed when working with pagination.
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html
+ */
+class PaginatorHelper extends AppHelper {
+
+/**
+ * Helper dependencies
+ *
+ * @var array
+ */
+ public $helpers = array('Html');
+
+/**
+ * The class used for 'Ajax' pagination links. Defaults to JsHelper. You should make sure
+ * that JsHelper is defined as a helper before PaginatorHelper, if you want to customize the JsHelper.
+ *
+ * @var string
+ */
+ protected $_ajaxHelperClass = 'Js';
+
+/**
+ * Holds the default options for pagination links
+ *
+ * The values that may be specified are:
+ *
+ * - `format` Format of the counter. Supported formats are 'range' and 'pages'
+ * and custom (default). In the default mode the supplied string is parsed and constants are replaced
+ * by their actual values.
+ * placeholders: %page%, %pages%, %current%, %count%, %start%, %end% .
+ * - `separator` The separator of the actual page and number of pages (default: ' of ').
+ * - `url` Url of the action. See Router::url()
+ * - `url['sort']` the key that the recordset is sorted.
+ * - `url['direction']` Direction of the sorting (default: 'asc').
+ * - `url['page']` Page number to use in links.
+ * - `model` The name of the model.
+ * - `escape` Defines if the title field for the link should be escaped (default: true).
+ * - `update` DOM id of the element updated with the results of the AJAX call.
+ * If this key isn't specified Paginator will use plain HTML links.
+ * - `paging['paramType']` The type of parameters to use when creating links. Valid options are
+ * 'querystring' and 'named'. See PaginatorComponent::$settings for more information.
+ * - `convertKeys` - A list of keys in url arrays that should be converted to querysting params
+ * if paramType == 'querystring'.
+ *
+ * @var array
+ */
+ public $options = array(
+ 'convertKeys' => array('page', 'limit', 'sort', 'direction')
+ );
+
+/**
+ * Constructor for the helper. Sets up the helper that is used for creating 'AJAX' links.
+ *
+ * Use `public $helpers = array('Paginator' => array('ajax' => 'CustomHelper'));` to set a custom Helper
+ * or choose a non JsHelper Helper. If you want to use a specific library with JsHelper declare JsHelper and its
+ * adapter before including PaginatorHelper in your helpers array.
+ *
+ * The chosen custom helper must implement a `link()` method.
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Array of settings.
+ * @throws CakeException When the AjaxProvider helper does not implement a link method.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $ajaxProvider = isset($settings['ajax']) ? $settings['ajax'] : 'Js';
+ $this->helpers[] = $ajaxProvider;
+ $this->_ajaxHelperClass = $ajaxProvider;
+ App::uses($ajaxProvider . 'Helper', 'View/Helper');
+ $classname = $ajaxProvider . 'Helper';
+ if (!class_exists($classname) || !method_exists($classname, 'link')) {
+ throw new CakeException(sprintf(
+ __d('cake_dev', '%s does not implement a link() method, it is incompatible with PaginatorHelper'), $classname
+ ));
+ }
+ parent::__construct($View, $settings);
+ }
+
+/**
+ * Before render callback. Overridden to merge passed args with url options.
+ *
+ * @param string $viewFile
+ * @return void
+ */
+ public function beforeRender($viewFile) {
+ $this->options['url'] = array_merge($this->request->params['pass'], $this->request->params['named']);
+ if (!empty($this->request->query)) {
+ $this->options['url']['?'] = $this->request->query;
+ }
+ parent::beforeRender($viewFile);
+ }
+
+/**
+ * Gets the current paging parameters from the resultset for the given model
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return array The array of paging parameters for the paginated resultset.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::params
+ */
+ public function params($model = null) {
+ if (empty($model)) {
+ $model = $this->defaultModel();
+ }
+ if (!isset($this->request->params['paging']) || empty($this->request->params['paging'][$model])) {
+ return null;
+ }
+ return $this->request->params['paging'][$model];
+ }
+
+/**
+ * Sets default options for all pagination links
+ *
+ * @param array|string $options Default options for pagination links. If a string is supplied - it
+ * is used as the DOM id element to update. See PaginatorHelper::$options for list of keys.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::options
+ */
+ public function options($options = array()) {
+ if (is_string($options)) {
+ $options = array('update' => $options);
+ }
+
+ if (!empty($options['paging'])) {
+ if (!isset($this->request->params['paging'])) {
+ $this->request->params['paging'] = array();
+ }
+ $this->request->params['paging'] = array_merge($this->request->params['paging'], $options['paging']);
+ unset($options['paging']);
+ }
+ $model = $this->defaultModel();
+
+ if (!empty($options[$model])) {
+ if (!isset($this->request->params['paging'][$model])) {
+ $this->request->params['paging'][$model] = array();
+ }
+ $this->request->params['paging'][$model] = array_merge(
+ $this->request->params['paging'][$model], $options[$model]
+ );
+ unset($options[$model]);
+ }
+ if (!empty($options['convertKeys'])) {
+ $options['convertKeys'] = array_merge($this->options['convertKeys'], $options['convertKeys']);
+ }
+ $this->options = array_filter(array_merge($this->options, $options));
+ }
+
+/**
+ * Gets the current page of the recordset for the given model
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return string The current page number of the recordset.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::current
+ */
+ public function current($model = null) {
+ $params = $this->params($model);
+
+ if (isset($params['page'])) {
+ return $params['page'];
+ }
+ return 1;
+ }
+
+/**
+ * Gets the current key by which the recordset is sorted
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @param array $options Options for pagination links. See #options for list of keys.
+ * @return string The name of the key by which the recordset is being sorted, or
+ * null if the results are not currently sorted.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortKey
+ */
+ public function sortKey($model = null, $options = array()) {
+ if (empty($options)) {
+ $params = $this->params($model);
+ $options = $params['options'];
+ }
+ if (isset($options['sort']) && !empty($options['sort'])) {
+ return $options['sort'];
+ }
+ if (isset($options['order'])) {
+ return is_array($options['order']) ? key($options['order']) : $options['order'];
+ }
+ if (isset($params['order'])) {
+ return is_array($params['order']) ? key($params['order']) : $params['order'];
+ }
+ return null;
+ }
+
+/**
+ * Gets the current direction the recordset is sorted
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @param array $options Options for pagination links. See #options for list of keys.
+ * @return string The direction by which the recordset is being sorted, or
+ * null if the results are not currently sorted.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortDir
+ */
+ public function sortDir($model = null, $options = array()) {
+ $dir = null;
+
+ if (empty($options)) {
+ $params = $this->params($model);
+ $options = $params['options'];
+ }
+
+ if (isset($options['direction'])) {
+ $dir = strtolower($options['direction']);
+ } elseif (isset($options['order']) && is_array($options['order'])) {
+ $dir = strtolower(current($options['order']));
+ } elseif (isset($params['order']) && is_array($params['order'])) {
+ $dir = strtolower(current($params['order']));
+ }
+
+ if ($dir == 'desc') {
+ return 'desc';
+ }
+ return 'asc';
+ }
+
+/**
+ * Generates a "previous" link for a set of paged records
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ *
+ * @param string $title Title for the link. Defaults to '<< Previous'.
+ * @param array $options Options for pagination link. See #options for list of keys.
+ * @param string $disabledTitle Title when the link is disabled.
+ * @param array $disabledOptions Options for the disabled pagination link. See #options for list of keys.
+ * @return string A "previous" link or $disabledTitle text if the link is disabled.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::prev
+ */
+ public function prev($title = '<< Previous', $options = array(), $disabledTitle = null, $disabledOptions = array()) {
+ $defaults = array(
+ 'rel' => 'prev'
+ );
+ $options = array_merge($defaults, (array)$options);
+ return $this->_pagingLink('Prev', $title, $options, $disabledTitle, $disabledOptions);
+ }
+
+/**
+ * Generates a "next" link for a set of paged records
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ *
+ * @param string $title Title for the link. Defaults to 'Next >>'.
+ * @param array $options Options for pagination link. See above for list of keys.
+ * @param string $disabledTitle Title when the link is disabled.
+ * @param array $disabledOptions Options for the disabled pagination link. See above for list of keys.
+ * @return string A "next" link or or $disabledTitle text if the link is disabled.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::next
+ */
+ public function next($title = 'Next >>', $options = array(), $disabledTitle = null, $disabledOptions = array()) {
+ $defaults = array(
+ 'rel' => 'next'
+ );
+ $options = array_merge($defaults, (array)$options);
+ return $this->_pagingLink('Next', $title, $options, $disabledTitle, $disabledOptions);
+ }
+
+/**
+ * Generates a sorting link. Sets named parameters for the sort and direction. Handles
+ * direction switching automatically.
+ *
+ * ### Options:
+ *
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ * - `direction` The default direction to use when this link isn't active.
+ *
+ * @param string $key The name of the key that the recordset should be sorted.
+ * @param string $title Title for the link. If $title is null $key will be used
+ * for the title and will be generated by inflection.
+ * @param array $options Options for sorting link. See above for list of keys.
+ * @return string A link sorting default by 'asc'. If the resultset is sorted 'asc' by the specified
+ * key the returned link will sort by 'desc'.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sort
+ */
+ public function sort($key, $title = null, $options = array()) {
+ $options = array_merge(array('url' => array(), 'model' => null), $options);
+ $url = $options['url'];
+ unset($options['url']);
+
+ if (empty($title)) {
+ $title = $key;
+ $title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)));
+ }
+ $dir = isset($options['direction']) ? $options['direction'] : 'asc';
+ unset($options['direction']);
+
+ $sortKey = $this->sortKey($options['model']);
+ $defaultModel = $this->defaultModel();
+ $isSorted = (
+ $sortKey === $key ||
+ $sortKey === $defaultModel . '.' . $key ||
+ $key === $defaultModel . '.' . $sortKey
+ );
+
+ if ($isSorted) {
+ $dir = $this->sortDir($options['model']) === 'asc' ? 'desc' : 'asc';
+ $class = $dir === 'asc' ? 'desc' : 'asc';
+ if (!empty($options['class'])) {
+ $options['class'] .= ' ' . $class;
+ } else {
+ $options['class'] = $class;
+ }
+ }
+ if (is_array($title) && array_key_exists($dir, $title)) {
+ $title = $title[$dir];
+ }
+
+ $url = array_merge(array('sort' => $key, 'direction' => $dir), $url, array('order' => null));
+ return $this->link($title, $url, $options);
+ }
+
+/**
+ * Generates a plain or Ajax link with pagination parameters
+ *
+ * ### Options
+ *
+ * - `update` The Id of the DOM element you wish to update. Creates Ajax enabled links
+ * with the AjaxHelper.
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ *
+ * @param string $title Title for the link.
+ * @param string|array $url Url for the action. See Router::url()
+ * @param array $options Options for the link. See #options for list of keys.
+ * @return string A link with pagination parameters.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::link
+ */
+ public function link($title, $url = array(), $options = array()) {
+ $options = array_merge(array('model' => null, 'escape' => true), $options);
+ $model = $options['model'];
+ unset($options['model']);
+
+ if (!empty($this->options)) {
+ $options = array_merge($this->options, $options);
+ }
+ if (isset($options['url'])) {
+ $url = array_merge((array)$options['url'], (array)$url);
+ unset($options['url']);
+ }
+ unset($options['convertKeys']);
+
+ $url = $this->url($url, true, $model);
+
+ $obj = isset($options['update']) ? $this->_ajaxHelperClass : 'Html';
+ return $this->{$obj}->link($title, $url, $options);
+ }
+
+/**
+ * Merges passed URL options with current pagination state to generate a pagination URL.
+ *
+ * @param array $options Pagination/URL options array
+ * @param boolean $asArray Return the url as an array, or a URI string
+ * @param string $model Which model to paginate on
+ * @return mixed By default, returns a full pagination URL string for use in non-standard contexts (i.e. JavaScript)
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::url
+ */
+ public function url($options = array(), $asArray = false, $model = null) {
+ $paging = $this->params($model);
+ $url = array_merge(array_filter($paging['options']), $options);
+
+ if (isset($url['order'])) {
+ $sort = $direction = null;
+ if (is_array($url['order'])) {
+ list($sort, $direction) = array($this->sortKey($model, $url), current($url['order']));
+ }
+ unset($url['order']);
+ $url = array_merge($url, compact('sort', 'direction'));
+ }
+ $url = $this->_convertUrlKeys($url, $paging['paramType']);
+
+ if ($asArray) {
+ return $url;
+ }
+ return parent::url($url);
+ }
+
+/**
+ * Converts the keys being used into the format set by options.paramType
+ *
+ * @param array $url Array of url params to convert
+ * @param string $type
+ * @return array converted url params.
+ */
+ protected function _convertUrlKeys($url, $type) {
+ if ($type == 'named') {
+ return $url;
+ }
+ if (!isset($url['?'])) {
+ $url['?'] = array();
+ }
+ foreach ($this->options['convertKeys'] as $key) {
+ if (isset($url[$key])) {
+ $url['?'][$key] = $url[$key];
+ unset($url[$key]);
+ }
+ }
+ return $url;
+ }
+
+/**
+ * Protected method for generating prev/next links
+ *
+ * @param string $which
+ * @param string $title
+ * @param array $options
+ * @param string $disabledTitle
+ * @param array $disabledOptions
+ * @return string
+ */
+ protected function _pagingLink($which, $title = null, $options = array(), $disabledTitle = null, $disabledOptions = array()) {
+ $check = 'has' . $which;
+ $_defaults = array(
+ 'url' => array(), 'step' => 1, 'escape' => true,
+ 'model' => null, 'tag' => 'span', 'class' => strtolower($which)
+ );
+ $options = array_merge($_defaults, (array)$options);
+ $paging = $this->params($options['model']);
+ if (empty($disabledOptions)) {
+ $disabledOptions = $options;
+ }
+
+ if (!$this->{$check}($options['model']) && (!empty($disabledTitle) || !empty($disabledOptions))) {
+ if (!empty($disabledTitle) && $disabledTitle !== true) {
+ $title = $disabledTitle;
+ }
+ $options = array_merge($_defaults, (array)$disabledOptions);
+ } elseif (!$this->{$check}($options['model'])) {
+ return null;
+ }
+
+ foreach (array_keys($_defaults) as $key) {
+ ${$key} = $options[$key];
+ unset($options[$key]);
+ }
+ $url = array_merge(array('page' => $paging['page'] + ($which == 'Prev' ? $step * -1 : $step)), $url);
+
+ if ($this->{$check}($model)) {
+ return $this->Html->tag($tag, $this->link($title, $url, array_merge($options, compact('escape'))), compact('class'));
+ } else {
+ unset($options['rel']);
+ return $this->Html->tag($tag, $title, array_merge($options, compact('escape', 'class')));
+ }
+ }
+
+/**
+ * Returns true if the given result set is not at the first page
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return boolean True if the result set is not at the first page.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPrev
+ */
+ public function hasPrev($model = null) {
+ return $this->_hasPage($model, 'prev');
+ }
+
+/**
+ * Returns true if the given result set is not at the last page
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return boolean True if the result set is not at the last page.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasNext
+ */
+ public function hasNext($model = null) {
+ return $this->_hasPage($model, 'next');
+ }
+
+/**
+ * Returns true if the given result set has the page number given by $page
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @param integer $page The page number - if not set defaults to 1.
+ * @return boolean True if the given result set has the specified page number.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPage
+ */
+ public function hasPage($model = null, $page = 1) {
+ if (is_numeric($model)) {
+ $page = $model;
+ $model = null;
+ }
+ $paging = $this->params($model);
+ return $page <= $paging['pageCount'];
+ }
+
+/**
+ * Does $model have $page in its range?
+ *
+ * @param string $model Model name to get parameters for.
+ * @param integer $page Page number you are checking.
+ * @return boolean Whether model has $page
+ */
+ protected function _hasPage($model, $page) {
+ $params = $this->params($model);
+ if (!empty($params)) {
+ if ($params["{$page}Page"] == true) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Gets the default model of the paged sets
+ *
+ * @return string Model name or null if the pagination isn't initialized.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::defaultModel
+ */
+ public function defaultModel() {
+ if ($this->_defaultModel != null) {
+ return $this->_defaultModel;
+ }
+ if (empty($this->request->params['paging'])) {
+ return null;
+ }
+ list($this->_defaultModel) = array_keys($this->request->params['paging']);
+ return $this->_defaultModel;
+ }
+
+/**
+ * Returns a counter string for the paged result set
+ *
+ * ### Options
+ *
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel();
+ * - `format` The format string you want to use, defaults to 'pages' Which generates output like '1 of 5'
+ * set to 'range' to generate output like '1 - 3 of 13'. Can also be set to a custom string, containing
+ * the following placeholders `{:page}`, `{:pages}`, `{:current}`, `{:count}`, `{:model}`, `{:start}`, `{:end}` and any
+ * custom content you would like.
+ * - `separator` The separator string to use, default to ' of '
+ *
+ * The `%page%` style placeholders also work, but are deprecated and will be removed in a future version.
+ * @param array $options Options for the counter string. See #options for list of keys.
+ * @return string Counter string.
+ * @deprecated The %page% style placeholders are deprecated.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::counter
+ */
+ public function counter($options = array()) {
+ if (is_string($options)) {
+ $options = array('format' => $options);
+ }
+
+ $options = array_merge(
+ array(
+ 'model' => $this->defaultModel(),
+ 'format' => 'pages',
+ 'separator' => __d('cake', ' of ')
+ ),
+ $options);
+
+ $paging = $this->params($options['model']);
+ if ($paging['pageCount'] == 0) {
+ $paging['pageCount'] = 1;
+ }
+ $start = 0;
+ if ($paging['count'] >= 1) {
+ $start = (($paging['page'] - 1) * $paging['limit']) + 1;
+ }
+ $end = $start + $paging['limit'] - 1;
+ if ($paging['count'] < $end) {
+ $end = $paging['count'];
+ }
+
+ switch ($options['format']) {
+ case 'range':
+ if (!is_array($options['separator'])) {
+ $options['separator'] = array(' - ', $options['separator']);
+ }
+ $out = $start . $options['separator'][0] . $end . $options['separator'][1];
+ $out .= $paging['count'];
+ break;
+ case 'pages':
+ $out = $paging['page'] . $options['separator'] . $paging['pageCount'];
+ break;
+ default:
+ $map = array(
+ '%page%' => $paging['page'],
+ '%pages%' => $paging['pageCount'],
+ '%current%' => $paging['current'],
+ '%count%' => $paging['count'],
+ '%start%' => $start,
+ '%end%' => $end,
+ '%model%' => strtolower(Inflector::humanize(Inflector::tableize($options['model'])))
+ );
+ $out = str_replace(array_keys($map), array_values($map), $options['format']);
+
+ $newKeys = array(
+ '{:page}', '{:pages}', '{:current}', '{:count}', '{:start}', '{:end}', '{:model}'
+ );
+ $out = str_replace($newKeys, array_values($map), $out);
+ break;
+ }
+ return $out;
+ }
+
+/**
+ * Returns a set of numbers for the paged result set
+ * uses a modulus to decide how many numbers to show on each side of the current page (default: 8).
+ *
+ * `$this->Paginator->numbers(array('first' => 2, 'last' => 2));`
+ *
+ * Using the first and last options you can create links to the beginning and end of the page set.
+ *
+ * ### Options
+ *
+ * - `before` Content to be inserted before the numbers
+ * - `after` Content to be inserted after the numbers
+ * - `model` Model to create numbers for, defaults to PaginatorHelper::defaultModel()
+ * - `modulus` how many numbers to include on either side of the current page, defaults to 8.
+ * - `separator` Separator content defaults to ' | '
+ * - `tag` The tag to wrap links in, defaults to 'span'
+ * - `first` Whether you want first links generated, set to an integer to define the number of 'first'
+ * links to generate.
+ * - `last` Whether you want last links generated, set to an integer to define the number of 'last'
+ * links to generate.
+ * - `ellipsis` Ellipsis content, defaults to '...'
+ * - `class` Class for wrapper tag
+ * - `currentClass` Class for wrapper tag on current active page, defaults to 'current'
+ *
+ * @param array $options Options for the numbers, (before, after, model, modulus, separator)
+ * @return string numbers string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::numbers
+ */
+ public function numbers($options = array()) {
+ if ($options === true) {
+ $options = array(
+ 'before' => ' | ', 'after' => ' | ', 'first' => 'first', 'last' => 'last'
+ );
+ }
+
+ $defaults = array(
+ 'tag' => 'span', 'before' => null, 'after' => null, 'model' => $this->defaultModel(), 'class' => null,
+ 'modulus' => '8', 'separator' => ' | ', 'first' => null, 'last' => null, 'ellipsis' => '...', 'currentClass' => 'current'
+ );
+ $options += $defaults;
+
+ $params = (array)$this->params($options['model']) + array('page' => 1);
+ unset($options['model']);
+
+ if ($params['pageCount'] <= 1) {
+ return false;
+ }
+
+ extract($options);
+ unset($options['tag'], $options['before'], $options['after'], $options['model'],
+ $options['modulus'], $options['separator'], $options['first'], $options['last'],
+ $options['ellipsis'], $options['class'], $options['currentClass']
+ );
+
+ $out = '';
+
+ if ($modulus && $params['pageCount'] > $modulus) {
+ $half = intval($modulus / 2);
+ $end = $params['page'] + $half;
+
+ if ($end > $params['pageCount']) {
+ $end = $params['pageCount'];
+ }
+ $start = $params['page'] - ($modulus - ($end - $params['page']));
+ if ($start <= 1) {
+ $start = 1;
+ $end = $params['page'] + ($modulus - $params['page']) + 1;
+ }
+
+ if ($first && $start > 1) {
+ $offset = ($start <= (int)$first) ? $start - 1 : $first;
+ if ($offset < $start - 1) {
+ $out .= $this->first($offset, compact('tag', 'separator', 'ellipsis', 'class'));
+ } else {
+ $out .= $this->first($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('after' => $separator));
+ }
+ }
+
+ $out .= $before;
+
+ for ($i = $start; $i < $params['page']; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator;
+ }
+
+ if ($class) {
+ $currentClass .= ' ' . $class;
+ }
+ $out .= $this->Html->tag($tag, $params['page'], array('class' => $currentClass));
+ if ($i != $params['pageCount']) {
+ $out .= $separator;
+ }
+
+ $start = $params['page'] + 1;
+ for ($i = $start; $i < $end; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator;
+ }
+
+ if ($end != $params['page']) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $end), $options), compact('class'));
+ }
+
+ $out .= $after;
+
+ if ($last && $end < $params['pageCount']) {
+ $offset = ($params['pageCount'] < $end + (int)$last) ? $params['pageCount'] - $end : $last;
+ if ($offset <= $last && $params['pageCount'] - $end > $offset) {
+ $out .= $this->last($offset, compact('tag', 'separator', 'ellipsis', 'class'));
+ } else {
+ $out .= $this->last($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('before' => $separator));
+ }
+ }
+
+ } else {
+ $out .= $before;
+
+ for ($i = 1; $i <= $params['pageCount']; $i++) {
+ if ($i == $params['page']) {
+ if ($class) {
+ $currentClass .= ' ' . $class;
+ }
+ $out .= $this->Html->tag($tag, $i, array('class' => $currentClass));
+ } else {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
+ }
+ if ($i != $params['pageCount']) {
+ $out .= $separator;
+ }
+ }
+
+ $out .= $after;
+ }
+
+ return $out;
+ }
+
+/**
+ * Returns a first or set of numbers for the first pages.
+ *
+ * `echo $this->Paginator->first('< first');`
+ *
+ * Creates a single link for the first page. Will output nothing if you are on the first page.
+ *
+ * `echo $this->Paginator->first(3);`
+ *
+ * Will create links for the first 3 pages, once you get to the third or greater page. Prior to that
+ * nothing will be output.
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `after` Content to insert after the link/tag
+ * - `model` The model to use defaults to PaginatorHelper::defaultModel()
+ * - `separator` Content between the generated links, defaults to ' | '
+ * - `ellipsis` Content for ellipsis, defaults to '...'
+ *
+ * @param string|integer $first if string use as label for the link. If numeric, the number of page links
+ * you want at the beginning of the range.
+ * @param array $options An array of options.
+ * @return string numbers string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::first
+ */
+ public function first($first = '<< first', $options = array()) {
+ $options = array_merge(
+ array(
+ 'tag' => 'span',
+ 'after' => null,
+ 'model' => $this->defaultModel(),
+ 'separator' => ' | ',
+ 'ellipsis' => '...',
+ 'class' => null
+ ),
+ (array)$options);
+
+ $params = array_merge(array('page' => 1), (array)$this->params($options['model']));
+ unset($options['model']);
+
+ if ($params['pageCount'] <= 1) {
+ return false;
+ }
+ extract($options);
+ unset($options['tag'], $options['after'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
+
+ $out = '';
+
+ if (is_int($first) && $params['page'] >= $first) {
+ if ($after === null) {
+ $after = $ellipsis;
+ }
+ for ($i = 1; $i <= $first; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
+ if ($i != $first) {
+ $out .= $separator;
+ }
+ }
+ $out .= $after;
+ } elseif ($params['page'] > 1 && is_string($first)) {
+ $options += array('rel' => 'first');
+ $out = $this->Html->tag($tag, $this->link($first, array('page' => 1), $options), compact('class')) . $after;
+ }
+ return $out;
+ }
+
+/**
+ * Returns a last or set of numbers for the last pages.
+ *
+ * `echo $this->Paginator->last('last >');`
+ *
+ * Creates a single link for the last page. Will output nothing if you are on the last page.
+ *
+ * `echo $this->Paginator->last(3);`
+ *
+ * Will create links for the last 3 pages. Once you enter the page range, no output will be created.
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `before` Content to insert before the link/tag
+ * - `model` The model to use defaults to PaginatorHelper::defaultModel()
+ * - `separator` Content between the generated links, defaults to ' | '
+ * - `ellipsis` Content for ellipsis, defaults to '...'
+ *
+ * @param string|integer $last if string use as label for the link, if numeric print page numbers
+ * @param array $options Array of options
+ * @return string numbers string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::last
+ */
+ public function last($last = 'last >>', $options = array()) {
+ $options = array_merge(
+ array(
+ 'tag' => 'span',
+ 'before' => null,
+ 'model' => $this->defaultModel(),
+ 'separator' => ' | ',
+ 'ellipsis' => '...',
+ 'class' => null
+ ),
+ (array)$options);
+
+ $params = array_merge(array('page' => 1), (array)$this->params($options['model']));
+ unset($options['model']);
+
+ if ($params['pageCount'] <= 1) {
+ return false;
+ }
+
+ extract($options);
+ unset($options['tag'], $options['before'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
+
+ $out = '';
+ $lower = $params['pageCount'] - $last + 1;
+
+ if (is_int($last) && $params['page'] <= $lower) {
+ if ($before === null) {
+ $before = $ellipsis;
+ }
+ for ($i = $lower; $i <= $params['pageCount']; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
+ if ($i != $params['pageCount']) {
+ $out .= $separator;
+ }
+ }
+ $out = $before . $out;
+ } elseif ($params['page'] < $params['pageCount'] && is_string($last)) {
+ $options += array('rel' => 'last');
+ $out = $before . $this->Html->tag(
+ $tag, $this->link($last, array('page' => $params['pageCount']), $options), compact('class')
+ );
+ }
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php
new file mode 100644
index 0000000..c1feb6d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php
@@ -0,0 +1,370 @@
+<?php
+/**
+ * Prototype Engine Helper for JsHelper
+ *
+ * Provides Prototype specific Javascript for JsHelper. Requires at least
+ * Prototype 1.6
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('JsBaseEngineHelper', 'View/Helper');
+
+/**
+ * Prototype Engine Helper for JsHelper
+ *
+ * Provides Prototype specific Javascript for JsHelper. Requires at least
+ * Prototype 1.6
+ *
+ * @package Cake.View.Helper
+ */
+class PrototypeEngineHelper extends JsBaseEngineHelper {
+
+/**
+ * Is the current selection a multiple selection? or is it just a single element.
+ *
+ * @var boolean
+ */
+ protected $_multiple = false;
+
+/**
+ * Option mappings for Prototype
+ *
+ * @var array
+ */
+ protected $_optionMap = array(
+ 'request' => array(
+ 'async' => 'asynchronous',
+ 'data' => 'parameters',
+ 'before' => 'onCreate',
+ 'success' => 'onSuccess',
+ 'complete' => 'onComplete',
+ 'error' => 'onFailure'
+ ),
+ 'sortable' => array(
+ 'sort' => 'onChange',
+ 'complete' => 'onUpdate',
+ ),
+ 'drag' => array(
+ 'snapGrid' => 'snap',
+ 'container' => 'constraint',
+ 'stop' => 'onEnd',
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ ),
+ 'drop' => array(
+ 'hover' => 'onHover',
+ 'drop' => 'onDrop',
+ 'hoverClass' => 'hoverclass',
+ ),
+ 'slider' => array(
+ 'direction' => 'axis',
+ 'change' => 'onSlide',
+ 'complete' => 'onChange',
+ 'value' => 'sliderValue',
+ )
+ );
+
+/**
+ * Contains a list of callback names -> default arguments.
+ *
+ * @var array
+ */
+ protected $_callbackArguments = array(
+ 'slider' => array(
+ 'onSlide' => 'value',
+ 'onChange' => 'value',
+ ),
+ 'drag' => array(
+ 'onStart' => 'event',
+ 'onDrag' => 'event',
+ 'change' => 'draggable',
+ 'onEnd' => 'event',
+ ),
+ 'drop' => array(
+ 'onHover' => 'draggable, droppable, event',
+ 'onDrop' => 'draggable, droppable, event',
+ ),
+ 'request' => array(
+ 'onCreate' => 'transport',
+ 'onComplete' => 'transport',
+ 'onFailure' => 'response, jsonHeader',
+ 'onRequest' => 'transport',
+ 'onSuccess' => 'response, jsonHeader'
+ ),
+ 'sortable' => array(
+ 'onStart' => 'element',
+ 'onChange' => 'element',
+ 'onUpdate' => 'element',
+ ),
+ );
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return PrototypeEngineHelper instance of $this. Allows chained methods.
+ */
+ public function get($selector) {
+ $this->_multiple = false;
+ if ($selector == 'window' || $selector == 'document') {
+ $this->selection = "$(" . $selector . ")";
+ return $this;
+ }
+ if (preg_match('/^#[^\s.]+$/', $selector)) {
+ $this->selection = '$("' . substr($selector, 1) . '")';
+ return $this;
+ }
+ $this->_multiple = true;
+ $this->selection = '$$("' . $selector . '")';
+ return $this;
+ }
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - `wrap` - Whether you want the callback wrapped in an anonymous function. (defaults true)
+ * - `stop` - Whether you want the event to stopped. (defaults true)
+ *
+ * @param string $type Type of event to bind to the current 946 id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ public function event($type, $callback, $options = array()) {
+ $defaults = array('wrap' => true, 'stop' => true);
+ $options = array_merge($defaults, $options);
+
+ $function = 'function (event) {%s}';
+ if ($options['wrap'] && $options['stop']) {
+ $callback = "event.stop();\n" . $callback;
+ }
+ if ($options['wrap']) {
+ $callback = sprintf($function, $callback);
+ }
+ $out = $this->selection . ".observe(\"{$type}\", $callback);";
+ return $out;
+ }
+
+/**
+ * Create a domReady event. This is a special event in many libraries
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ public function domReady($functionBody) {
+ $this->selection = 'document';
+ return $this->event('dom:loaded', $functionBody, array('stop' => false));
+ }
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ public function each($callback) {
+ return $this->selection . '.each(function (item, index) {' . $callback . '});';
+ }
+
+/**
+ * Trigger an Effect.
+ *
+ * ### Note: Effects require Scriptaculous to be loaded.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ * @see JsBaseEngineHelper::effect()
+ */
+ public function effect($name, $options = array()) {
+ $effect = '';
+ $optionString = null;
+ if (isset($options['speed'])) {
+ if ($options['speed'] == 'fast') {
+ $options['duration'] = 0.5;
+ } elseif ($options['speed'] == 'slow') {
+ $options['duration'] = 2;
+ } else {
+ $options['duration'] = 1;
+ }
+ unset($options['speed']);
+ }
+ if (!empty($options)) {
+ $optionString = ', {' . $this->_parseOptions($options) . '}';
+ }
+ switch ($name) {
+ case 'hide':
+ case 'show':
+ $effect = $this->selection . '.' . $name . '();';
+ break;
+ case 'slideIn':
+ case 'slideOut':
+ $name = ($name == 'slideIn') ? 'slideDown' : 'slideUp';
+ $effect = 'Effect.' . $name . '(' . $this->selection . $optionString . ');';
+ break;
+ case 'fadeIn':
+ case 'fadeOut':
+ $name = ($name == 'fadeIn') ? 'appear' : 'fade';
+ $effect = $this->selection . '.' . $name . '(' . substr($optionString, 2) . ');';
+ break;
+ }
+ return $effect;
+ }
+
+/**
+ * Create an Ajax or Ajax.Updater call.
+ *
+ * @param string|array $url
+ * @param array $options
+ * @return string The completed ajax call.
+ */
+ public function request($url, $options = array()) {
+ $url = '"' . $this->url($url) . '"';
+ $options = $this->_mapOptions('request', $options);
+ $type = '.Request';
+ $data = null;
+ if (isset($options['type']) && strtolower($options['type']) == 'json') {
+ unset($options['type']);
+ }
+ if (isset($options['update'])) {
+ $url = '"' . str_replace('#', '', $options['update']) . '", ' . $url;
+ $type = '.Updater';
+ unset($options['update'], $options['type']);
+ }
+ $safe = array_keys($this->_callbackArguments['request']);
+ $options = $this->_prepareCallbacks('request', $options, $safe);
+ if (!empty($options['dataExpression'])) {
+ $safe[] = 'parameters';
+ unset($options['dataExpression']);
+ }
+ $options = $this->_parseOptions($options, $safe);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ return "var jsRequest = new Ajax$type($url$options);";
+ }
+
+/**
+ * Create a sortable element.
+ *
+ * #### Note: Requires scriptaculous to be loaded.
+ *
+ * The scriptaculous implementation of sortables does not support the 'start'
+ * and 'distance' options.
+ *
+ * @param array $options Array of options for the sortable.
+ * @return string Completed sortable script.
+ * @see JsBaseEngineHelper::sortable() for options list.
+ */
+ public function sortable($options = array()) {
+ $options = $this->_processOptions('sortable', $options);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ return 'var jsSortable = Sortable.create(' . $this->selection . $options . ');';
+ }
+
+/**
+ * Create a Draggable element.
+ *
+ * #### Note: Requires scriptaculous to be loaded.
+ *
+ * @param array $options Array of options for the draggable.
+ * @return string Completed draggable script.
+ * @see JsBaseEngineHelper::draggable() for options list.
+ */
+ public function drag($options = array()) {
+ $options = $this->_processOptions('drag', $options);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ if ($this->_multiple) {
+ return $this->each('new Draggable(item' . $options . ');');
+ }
+ return 'var jsDrag = new Draggable(' . $this->selection . $options . ');';
+ }
+
+/**
+ * Create a Droppable element.
+ *
+ * #### Note: Requires scriptaculous to be loaded.
+ *
+ * @param array $options Array of options for the droppable.
+ * @return string Completed droppable script.
+ * @see JsBaseEngineHelper::droppable() for options list.
+ */
+ public function drop($options = array()) {
+ $options = $this->_processOptions('drop', $options);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ return 'Droppables.add(' . $this->selection . $options . ');';
+ }
+
+/**
+ * Creates a slider control widget.
+ *
+ * ### Note: Requires scriptaculous to be loaded.
+ *
+ * @param array $options Array of options for the slider.
+ * @return string Completed slider script.
+ * @see JsBaseEngineHelper::slider() for options list.
+ */
+ public function slider($options = array()) {
+ $slider = $this->selection;
+ $this->get($options['handle']);
+ unset($options['handle']);
+
+ if (isset($options['min']) && isset($options['max'])) {
+ $options['range'] = sprintf('$R(%s,%s)', $options['min'], $options['max']);
+ unset($options['min'], $options['max']);
+ }
+ $options = $this->_mapOptions('slider', $options);
+ $options = $this->_prepareCallbacks('slider', $options);
+ $optionString = $this->_parseOptions(
+ $options, array_merge(array_keys($this->_callbackArguments['slider']), array('range'))
+ );
+ if (!empty($optionString)) {
+ $optionString = ', {' . $optionString . '}';
+ }
+ $out = 'var jsSlider = new Control.Slider(' . $this->selection . ', ' . $slider . $optionString . ');';
+ $this->selection = $slider;
+ return $out;
+ }
+
+/**
+ * Serialize the form attached to $selector.
+ *
+ * @param array $options Array of options.
+ * @return string Completed serializeForm() snippet
+ * @see JsBaseEngineHelper::serializeForm()
+ */
+ public function serializeForm($options = array()) {
+ $options = array_merge(array('isForm' => false, 'inline' => false), $options);
+ $selection = $this->selection;
+ if (!$options['isForm']) {
+ $selection = '$(' . $this->selection . '.form)';
+ }
+ $method = '.serialize()';
+ if (!$options['inline']) {
+ $method .= ';';
+ }
+ return $selection . $method;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php
new file mode 100644
index 0000000..bd41284
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php
@@ -0,0 +1,345 @@
+<?php
+/**
+ * RSS Helper class file.
+ *
+ * Simplifies the output of RSS feeds.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('Xml', 'Utility');
+
+/**
+ * RSS Helper class for easy output RSS structures.
+ *
+ * @package Cake.View.Helper
+ * @property TimeHelper $Time
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html
+ */
+class RssHelper extends AppHelper {
+
+/**
+ * Helpers used by RSS Helper
+ *
+ * @var array
+ */
+ public $helpers = array('Time');
+
+/**
+ * Base URL
+ *
+ * @var string
+ */
+ public $base = null;
+
+/**
+ * URL to current action.
+ *
+ * @var string
+ */
+ public $here = null;
+
+/**
+ * Parameter array.
+ *
+ * @var array
+ */
+ public $params = array();
+
+/**
+ * Current action.
+ *
+ * @var string
+ */
+ public $action = null;
+
+/**
+ * POSTed model data
+ *
+ * @var array
+ */
+ public $data = null;
+
+/**
+ * Name of the current model
+ *
+ * @var string
+ */
+ public $model = null;
+
+/**
+ * Name of the current field
+ *
+ * @var string
+ */
+ public $field = null;
+
+/**
+ * Default spec version of generated RSS
+ *
+ * @var string
+ */
+ public $version = '2.0';
+
+/**
+ * Returns an RSS document wrapped in `<rss />` tags
+ *
+ * @param array $attrib `<rss />` tag attributes
+ * @param string $content
+ * @return string An RSS document
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::document
+ */
+ public function document($attrib = array(), $content = null) {
+ if ($content === null) {
+ $content = $attrib;
+ $attrib = array();
+ }
+ if (!isset($attrib['version']) || empty($attrib['version'])) {
+ $attrib['version'] = $this->version;
+ }
+
+ return $this->elem('rss', $attrib, $content);
+ }
+
+/**
+ * Returns an RSS `<channel />` element
+ *
+ * @param array $attrib `<channel />` tag attributes
+ * @param array $elements Named array elements which are converted to tags
+ * @param string $content Content (`<item />`'s belonging to this channel
+ * @return string An RSS `<channel />`
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::channel
+ */
+ public function channel($attrib = array(), $elements = array(), $content = null) {
+ if (!isset($elements['title']) && !empty($this->_View->pageTitle)) {
+ $elements['title'] = $this->_View->pageTitle;
+ }
+ if (!isset($elements['link'])) {
+ $elements['link'] = '/';
+ }
+ if (!isset($elements['description'])) {
+ $elements['description'] = '';
+ }
+ $elements['link'] = $this->url($elements['link'], true);
+
+ $elems = '';
+ foreach ($elements as $elem => $data) {
+ $attributes = array();
+ if (is_array($data)) {
+ if (strtolower($elem) == 'cloud') {
+ $attributes = $data;
+ $data = array();
+ } elseif (isset($data['attrib']) && is_array($data['attrib'])) {
+ $attributes = $data['attrib'];
+ unset($data['attrib']);
+ } else {
+ $innerElements = '';
+ foreach ($data as $subElement => $value) {
+ $innerElements .= $this->elem($subElement, array(), $value);
+ }
+ $data = $innerElements;
+ }
+ }
+ $elems .= $this->elem($elem, $attributes, $data);
+ }
+ return $this->elem('channel', $attrib, $elems . $content, !($content === null));
+ }
+
+/**
+ * Transforms an array of data using an optional callback, and maps it to a set
+ * of `<item />` tags
+ *
+ * @param array $items The list of items to be mapped
+ * @param string|array $callback A string function name, or array containing an object
+ * and a string method name
+ * @return string A set of RSS `<item />` elements
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::items
+ */
+ public function items($items, $callback = null) {
+ if ($callback != null) {
+ $items = array_map($callback, $items);
+ }
+
+ $out = '';
+ $c = count($items);
+
+ for ($i = 0; $i < $c; $i++) {
+ $out .= $this->item(array(), $items[$i]);
+ }
+ return $out;
+ }
+
+/**
+ * Converts an array into an `<item />` element and its contents
+ *
+ * @param array $att The attributes of the `<item />` element
+ * @param array $elements The list of elements contained in this `<item />`
+ * @return string An RSS `<item />` element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::item
+ */
+ public function item($att = array(), $elements = array()) {
+ $content = null;
+
+ if (isset($elements['link']) && !isset($elements['guid'])) {
+ $elements['guid'] = $elements['link'];
+ }
+
+ foreach ($elements as $key => $val) {
+ $attrib = array();
+
+ $escape = true;
+ if (is_array($val) && isset($val['convertEntities'])) {
+ $escape = $val['convertEntities'];
+ unset($val['convertEntities']);
+ }
+
+ switch ($key) {
+ case 'pubDate' :
+ $val = $this->time($val);
+ break;
+ case 'category' :
+ if (is_array($val) && !empty($val[0])) {
+ foreach ($val as $category) {
+ $attrib = array();
+ if (is_array($category) && isset($category['domain'])) {
+ $attrib['domain'] = $category['domain'];
+ unset($category['domain']);
+ }
+ $categories[] = $this->elem($key, $attrib, $category);
+ }
+ $elements[$key] = implode('', $categories);
+ continue 2;
+ } elseif (is_array($val) && isset($val['domain'])) {
+ $attrib['domain'] = $val['domain'];
+ }
+ break;
+ case 'link':
+ case 'guid':
+ case 'comments':
+ if (is_array($val) && isset($val['url'])) {
+ $attrib = $val;
+ unset($attrib['url']);
+ $val = $val['url'];
+ }
+ $val = $this->url($val, true);
+ break;
+ case 'source':
+ if (is_array($val) && isset($val['url'])) {
+ $attrib['url'] = $this->url($val['url'], true);
+ $val = $val['title'];
+ } elseif (is_array($val)) {
+ $attrib['url'] = $this->url($val[0], true);
+ $val = $val[1];
+ }
+ break;
+ case 'enclosure':
+ if (is_string($val['url']) && is_file(WWW_ROOT . $val['url']) && file_exists(WWW_ROOT . $val['url'])) {
+ if (!isset($val['length']) && strpos($val['url'], '://') === false) {
+ $val['length'] = sprintf("%u", filesize(WWW_ROOT . $val['url']));
+ }
+ if (!isset($val['type']) && function_exists('mime_content_type')) {
+ $val['type'] = mime_content_type(WWW_ROOT . $val['url']);
+ }
+ }
+ $val['url'] = $this->url($val['url'], true);
+ $attrib = $val;
+ $val = null;
+ break;
+ }
+ if (!is_null($val) && $escape) {
+ $val = h($val);
+ }
+ $elements[$key] = $this->elem($key, $attrib, $val);
+ }
+ if (!empty($elements)) {
+ $content = implode('', $elements);
+ }
+ return $this->elem('item', (array)$att, $content, !($content === null));
+ }
+
+/**
+ * Converts a time in any format to an RSS time
+ *
+ * @param integer|string|DateTime $time
+ * @return string An RSS-formatted timestamp
+ * @see TimeHelper::toRSS
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::time
+ */
+ public function time($time) {
+ return $this->Time->toRSS($time);
+ }
+
+/**
+ * Generates an XML element
+ *
+ * @param string $name The name of the XML element
+ * @param array $attrib The attributes of the XML element
+ * @param string|array $content XML element content
+ * @param boolean $endTag Whether the end tag of the element should be printed
+ * @return string XML
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::elem
+ */
+ public function elem($name, $attrib = array(), $content = null, $endTag = true) {
+ $namespace = null;
+ if (isset($attrib['namespace'])) {
+ $namespace = $attrib['namespace'];
+ unset($attrib['namespace']);
+ }
+ $cdata = false;
+ if (is_array($content) && isset($content['cdata'])) {
+ $cdata = true;
+ unset($content['cdata']);
+ }
+ if (is_array($content) && array_key_exists('value', $content)) {
+ $content = $content['value'];
+ }
+ $children = array();
+ if (is_array($content)) {
+ $children = $content;
+ $content = null;
+ }
+
+ $xml = '<' . $name;
+ if (!empty($namespace)) {
+ $xml .= ' xmlns:"' . $namespace . '"';
+ }
+ $bareName = $name;
+ if (strpos($name, ':') !== false) {
+ list($prefix, $bareName) = explode(':', $name, 2);
+ switch ($prefix) {
+ case 'atom':
+ $xml .= ' xmlns:atom="http://www.w3.org/2005/Atom"';
+ break;
+ }
+ }
+ if ($cdata && !empty($content)) {
+ $content = '<![CDATA[' . $content . ']]>';
+ }
+ $xml .= '>' . $content . '</' . $name . '>';
+ $elem = Xml::build($xml, array('return' => 'domdocument'));
+ $nodes = $elem->getElementsByTagName($bareName);
+ foreach ($attrib as $key => $value) {
+ $nodes->item(0)->setAttribute($key, $value);
+ }
+ foreach ($children as $k => $child) {
+ $child = $elem->createElement($name, $child);
+ $nodes->item(0)->appendChild($child);
+ }
+
+ $xml = $elem->saveXml();
+ $xml = trim(substr($xml, strpos($xml, '?>') + 2));
+ return $xml;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php
new file mode 100644
index 0000000..259c4df
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Session Helper provides access to the Session in the 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.View.Helper
+ * @since CakePHP(tm) v 1.1.7.3328
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('CakeSession', 'Model/Datasource');
+
+/**
+ * Session Helper.
+ *
+ * Session reading from the view.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html
+ */
+class SessionHelper extends AppHelper {
+
+/**
+ * Used to read a session values set in a controller for a key or return values for all keys.
+ *
+ * In your view: `$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 values from the session vars
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::read
+ */
+ public function read($name = null) {
+ return CakeSession::read($name);
+ }
+
+/**
+ * Used to check is a session key has been set
+ *
+ * In your view: `$this->Session->check('Controller.sessKey');`
+ *
+ * @param string $name
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::check
+ */
+ public function check($name) {
+ return CakeSession::check($name);
+ }
+
+/**
+ * Returns last error encountered in a session
+ *
+ * In your view: `$this->Session->error();`
+ *
+ * @return string last error
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#displaying-notifcations-or-flash-messages
+ */
+ public function error() {
+ return CakeSession::error();
+ }
+
+/**
+ * Used to render the message set in Controller::Session::setFlash()
+ *
+ * In your view: $this->Session->flash('somekey');
+ * Will default to flash if no param is passed
+ *
+ * You can pass additional information into the flash message generation. This allows you
+ * to consolidate all the parameters for a given type of flash message into the view.
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array('params' => array('class' => 'new-flash')));
+ * }}}
+ *
+ * The above would generate a flash message with a custom class name. Using $attrs['params'] you
+ * can pass additional data into the element rendering that will be made available as local variables
+ * when the element is rendered:
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array('params' => array('name' => $user['User']['name'])));
+ * }}}
+ *
+ * This would pass the current user's name into the flash message, so you could create personalized
+ * messages without the controller needing access to that data.
+ *
+ * Lastly you can choose the element that is rendered when creating the flash message. Using
+ * custom elements allows you to fully customize how flash messages are generated.
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array('element' => 'my_custom_element'));
+ * }}}
+ *
+ * If you want to use an element from a plugin for rendering your flash message you can do that using the
+ * plugin param:
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array(
+ * 'element' => 'my_custom_element',
+ * 'params' => array('plugin' => 'my_plugin')
+ * ));
+ * }}}
+ *
+ * @param string $key The [Message.]key you are rendering in the view.
+ * @param array $attrs Additional attributes to use for the creation of this flash message.
+ * Supports the 'params', and 'element' keys that are used in the helper.
+ * @return string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::flash
+ */
+ public function flash($key = 'flash', $attrs = array()) {
+ $out = false;
+
+ if (CakeSession::check('Message.' . $key)) {
+ $flash = CakeSession::read('Message.' . $key);
+ $message = $flash['message'];
+ unset($flash['message']);
+
+ if (!empty($attrs)) {
+ $flash = array_merge($flash, $attrs);
+ }
+
+ if ($flash['element'] == 'default') {
+ $class = 'message';
+ if (!empty($flash['params']['class'])) {
+ $class = $flash['params']['class'];
+ }
+ $out = '<div id="' . $key . 'Message" class="' . $class . '">' . $message . '</div>';
+ } elseif ($flash['element'] == '' || $flash['element'] == null) {
+ $out = $message;
+ } else {
+ $options = array();
+ if (isset($flash['params']['plugin'])) {
+ $options['plugin'] = $flash['params']['plugin'];
+ }
+ $tmpVars = $flash['params'];
+ $tmpVars['message'] = $message;
+ $out = $this->_View->element($flash['element'], $tmpVars, $options);
+ }
+ CakeSession::delete('Message.' . $key);
+ }
+ return $out;
+ }
+
+/**
+ * Used to check is a session is valid in a view
+ *
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::valid
+ */
+ public function valid() {
+ return CakeSession::valid();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php
new file mode 100644
index 0000000..096029e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * Text Helper
+ *
+ * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Text helper library.
+ *
+ * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html
+ * @see String
+ */
+class TextHelper extends AppHelper {
+
+/**
+ * helpers
+ *
+ * @var array
+ */
+ public $helpers = array('Html');
+
+/**
+ * An array of md5sums and their contents.
+ * Used when inserting links into text.
+ *
+ * @var array
+ */
+ protected $_placeholders = array();
+
+/**
+ * String utility instance
+ */
+ protected $_engine;
+
+/**
+ * Constructor
+ *
+ * ### Settings:
+ *
+ * - `engine` Class name to use to replace String functionality.
+ * The class needs to be placed in the `Utility` directory.
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Settings array Settings array
+ * @throws CakeException when the engine class could not be found.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $settings = Hash::merge(array('engine' => 'String'), $settings);
+ parent::__construct($View, $settings);
+ list($plugin, $engineClass) = pluginSplit($settings['engine'], true);
+ App::uses($engineClass, $plugin . 'Utility');
+ if (class_exists($engineClass)) {
+ $this->_engine = new $engineClass($settings);
+ } else {
+ throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+ }
+ }
+
+/**
+ * Call methods from String utility class
+ */
+ public function __call($method, $params) {
+ return call_user_func_array(array($this->_engine, $method), $params);
+ }
+
+/**
+ * Adds links (<a href=....) to a given text, by finding text that begins with
+ * strings like http:// and ftp://.
+ *
+ * ### Options
+ *
+ * - `escape` Control HTML escaping of input. Defaults to true.
+ *
+ * @param string $text Text
+ * @param array $options Array of HTML options, and options listed above.
+ * @return string The text with links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLinkUrls
+ */
+ public function autoLinkUrls($text, $options = array()) {
+ $this->_placeholders = array();
+ $options += array('escape' => true);
+
+ $text = preg_replace_callback(
+ '#(?<!href="|src="|">)((?:https?|ftp|nntp)://[^\s<>()]+)#i',
+ array(&$this, '_insertPlaceHolder'),
+ $text
+ );
+ $text = preg_replace_callback(
+ '#(?<!href="|">)(?<!\b[[:punct:]])(?<!http://|https://|ftp://|nntp://)www.[^\n\%\ <]+[^<\n\%\,\.\ <](?<!\))#i',
+ array(&$this, '_insertPlaceHolder'),
+ $text
+ );
+ if ($options['escape']) {
+ $text = h($text);
+ }
+ return $this->_linkUrls($text, $options);
+ }
+
+/**
+ * Saves the placeholder for a string, for later use. This gets around double
+ * escaping content in URL's.
+ *
+ * @param array $matches An array of regexp matches.
+ * @return string Replaced values.
+ */
+ protected function _insertPlaceHolder($matches) {
+ $key = md5($matches[0]);
+ $this->_placeholders[$key] = $matches[0];
+ return $key;
+ }
+
+/**
+ * Replace placeholders with links.
+ *
+ * @param string $text The text to operate on.
+ * @param array $htmlOptions The options for the generated links.
+ * @return string The text with links inserted.
+ */
+ protected function _linkUrls($text, $htmlOptions) {
+ $replace = array();
+ foreach ($this->_placeholders as $hash => $url) {
+ $link = $url;
+ if (!preg_match('#^[a-z]+\://#', $url)) {
+ $url = 'http://' . $url;
+ }
+ $replace[$hash] = $this->Html->link($link, $url, $htmlOptions);
+ }
+ return strtr($text, $replace);
+ }
+
+/**
+ * Links email addresses
+ *
+ * @param string $text The text to operate on
+ * @param array $options An array of options to use for the HTML.
+ * @return string
+ * @see TextHelper::autoLinkEmails()
+ */
+ protected function _linkEmails($text, $options) {
+ $replace = array();
+ foreach ($this->_placeholders as $hash => $url) {
+ $replace[$hash] = $this->Html->link($url, 'mailto:' . $url, $options);
+ }
+ return strtr($text, $replace);
+ }
+
+/**
+ * Adds email links (<a href="mailto:....) to a given text.
+ *
+ * ### Options
+ *
+ * - `escape` Control HTML escaping of input. Defaults to true.
+ *
+ * @param string $text Text
+ * @param array $options Array of HTML options, and options listed above.
+ * @return string The text with links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLinkEmails
+ */
+ public function autoLinkEmails($text, $options = array()) {
+ $options += array('escape' => true);
+ $this->_placeholders = array();
+
+ $atom = '[a-z0-9!#$%&\'*+\/=?^_`{|}~-]';
+ $text = preg_replace_callback(
+ '/(' . $atom . '+(?:\.' . $atom . '+)*@[a-z0-9-]+(?:\.[a-z0-9-]+)+)/i',
+ array(&$this, '_insertPlaceholder'),
+ $text
+ );
+ if ($options['escape']) {
+ $text = h($text);
+ }
+ return $this->_linkEmails($text, $options);
+ }
+
+/**
+ * Convert all links and email addresses to HTML links.
+ *
+ * ### Options
+ *
+ * - `escape` Control HTML escaping of input. Defaults to true.
+ *
+ * @param string $text Text
+ * @param array $options Array of HTML options, and options listed above.
+ * @return string The text with links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLink
+ */
+ public function autoLink($text, $options = array()) {
+ $text = $this->autoLinkUrls($text, $options);
+ return $this->autoLinkEmails($text, array_merge($options, array('escape' => false)));
+ }
+
+/**
+ * @see String::highlight()
+ *
+ * @param string $text Text to search the phrase in
+ * @param string $phrase The phrase that will be searched
+ * @param array $options An array of html attributes and options.
+ * @return string The highlighted text
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
+ */
+ public function highlight($text, $phrase, $options = array()) {
+ return $this->_engine->highlight($text, $phrase, $options);
+ }
+
+/**
+ * @see String::stripLinks()
+ *
+ * @param string $text Text
+ * @return string The text without links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
+ */
+ public function stripLinks($text) {
+ return $this->_engine->stripLinks($text);
+ }
+
+/**
+ * @see String::truncate()
+ *
+ * @param string $text String to truncate.
+ * @param integer $length Length of returned string, including ellipsis.
+ * @param array $options An array of html attributes and options.
+ * @return string Trimmed string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::truncate
+ */
+ public function truncate($text, $length = 100, $options = array()) {
+ return $this->_engine->truncate($text, $length, $options);
+ }
+
+/**
+ * @see String::excerpt()
+ *
+ * @param string $text String to search the phrase in
+ * @param string $phrase Phrase that will be searched for
+ * @param integer $radius The amount of characters that will be returned on each side of the founded phrase
+ * @param string $ending Ending that will be appended
+ * @return string Modified string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::excerpt
+ */
+ public function excerpt($text, $phrase, $radius = 100, $ending = '...') {
+ return $this->_engine->excerpt($text, $phrase, $radius, $ending);
+ }
+
+/**
+ * @see String::toList()
+ *
+ * @param array $list The list to be joined
+ * @param string $and The word used to join the last and second last items together with. Defaults to 'and'
+ * @param string $separator The separator used to join all the other items together. Defaults to ', '
+ * @return string The glued together string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
+ */
+ public function toList($list, $and = 'and', $separator = ', ') {
+ return $this->_engine->toList($list, $and, $separator);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php
new file mode 100644
index 0000000..2849179
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php
@@ -0,0 +1,458 @@
+<?php
+/**
+ * Time Helper class file.
+ *
+ * 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.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeTime', 'Utility');
+App::uses('Multibyte', 'I18n');
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Time Helper class for easy use of time data.
+ *
+ * Manipulation of time data.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html
+ * @see CakeTime
+ */
+class TimeHelper extends AppHelper {
+
+/**
+ * CakeTime instance
+ */
+ protected $_engine = null;
+
+/**
+ * Constructor
+ *
+ * ### Settings:
+ *
+ * - `engine` Class name to use to replace CakeTime functionality
+ * The class needs to be placed in the `Utility` directory.
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Settings array Settings array
+ * @throws CakeException When the engine class could not be found.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $settings = Hash::merge(array('engine' => 'CakeTime'), $settings);
+ parent::__construct($View, $settings);
+ list($plugin, $engineClass) = pluginSplit($settings['engine'], true);
+ App::uses($engineClass, $plugin . 'Utility');
+ if (class_exists($engineClass)) {
+ $this->_engine = new $engineClass($settings);
+ } else {
+ throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+ }
+ }
+
+/**
+ * Magic accessor for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to set.
+ * @param string $value Value of the attribute to set.
+ * @return mixed
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'niceFormat':
+ $this->_engine->{$name} = $value;
+ break;
+ default:
+ $this->{$name} = $value;
+ break;
+ }
+ }
+
+/**
+ * Magic isset check for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to check.
+ * @return boolean
+ */
+ public function __isset($name) {
+ if (isset($this->{$name})) {
+ return true;
+ }
+ $magicGet = array('niceFormat');
+ if (in_array($name, $magicGet)) {
+ return $this->__get($name) !== null;
+ }
+ return null;
+ }
+
+/**
+ * Magic accessor for attributes that were deprecated.
+ *
+ * @param string $name Name of the attribute to get.
+ * @return mixed
+ */
+ public function __get($name) {
+ if (isset($this->_engine->{$name})) {
+ return $this->_engine->{$name};
+ }
+ $magicGet = array('niceFormat');
+ if (in_array($name, $magicGet)) {
+ return $this->_engine->{$name};
+ }
+ return null;
+ }
+
+/**
+ * Call methods from CakeTime utility class
+ */
+ public function __call($method, $params) {
+ return call_user_func_array(array($this->_engine, $method), $params);
+ }
+
+/**
+ * @see CakeTime::convertSpecifiers()
+ *
+ * @param string $format Format with specifiers for strftime function.
+ * Accepts the special specifier %S which mimics the modifier S for date()
+ * @param string $time UNIX timestamp
+ * @return string windows safe and date() function compatible format for strftime
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function convertSpecifiers($format, $time = null) {
+ return $this->_engine->convertSpecifiers($format, $time);
+ }
+
+/**
+ * @see CakeTime::convert()
+ *
+ * @param string $serverTime UNIX timestamp
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return integer UNIX timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function convert($serverTime, $timezone) {
+ return $this->_engine->convert($serverTime, $timezone);
+ }
+
+/**
+ * @see CakeTime::serverOffset()
+ *
+ * @return integer Offset
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function serverOffset() {
+ return $this->_engine->serverOffset();
+ }
+
+/**
+ * @see CakeTime::fromString()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Parsed timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function fromString($dateString, $timezone = null) {
+ return $this->_engine->fromString($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::nice()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function nice($dateString = null, $timezone = null, $format = null) {
+ return $this->_engine->nice($dateString, $timezone, $format);
+ }
+
+/**
+ * @see CakeTime::niceShort()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime objectp
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Described, relative date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function niceShort($dateString = null, $timezone = null) {
+ return $this->_engine->niceShort($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::daysAsSql()
+ *
+ * @param integer|string|DateTime $begin UNIX timestamp, strtotime() valid string or DateTime object
+ * @param integer|string|DateTime $end UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $fieldName Name of database field to compare with
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Partial SQL string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function daysAsSql($begin, $end, $fieldName, $timezone = null) {
+ return $this->_engine->daysAsSql($begin, $end, $fieldName, $timezone);
+ }
+
+/**
+ * @see CakeTime::dayAsSql()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $fieldName Name of database field to compare with
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Partial SQL string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function dayAsSql($dateString, $fieldName, $timezone = null) {
+ return $this->_engine->dayAsSql($dateString, $fieldName, $timezone);
+ }
+
+/**
+ * @see CakeTime::isToday()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is today
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isToday($dateString, $timezone = null) {
+ return $this->_engine->isToday($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isThisWeek()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current week
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isThisWeek($dateString, $timezone = null) {
+ return $this->_engine->isThisWeek($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isThisMonth()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current month
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isThisMonth($dateString, $timezone = null) {
+ return $this->_engine->isThisMonth($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isThisYear()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current year
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isThisYear($dateString, $timezone = null) {
+ return $this->_engine->isThisYear($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::wasYesterday()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string was yesterday
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ *
+ */
+ public function wasYesterday($dateString, $timezone = null) {
+ return $this->_engine->wasYesterday($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isTomorrow()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string was yesterday
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isTomorrow($dateString, $timezone = null) {
+ return $this->_engine->isTomorrow($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::toQuarter()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param boolean $range if true returns a range in Y-m-d format
+ * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toQuarter($dateString, $range = false) {
+ return $this->_engine->toQuarter($dateString, $range);
+ }
+
+/**
+ * @see CakeTime::toUnix()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return integer Unix timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toUnix($dateString, $timezone = null) {
+ return $this->_engine->toUnix($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::toAtom()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toAtom($dateString, $timezone = null) {
+ return $this->_engine->toAtom($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::toRSS()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toRSS($dateString, $timezone = null) {
+ return $this->_engine->toRSS($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::timeAgoInWords()
+ *
+ * ## Addition options
+ *
+ * - `element` - The element to wrap the formatted time in.
+ * Has a few additional options:
+ * - `tag` - The tag to use, defaults to 'span'.
+ * - `class` - The classname to use, defaults to `time-ago-in-words`.
+ * - `title` - Defaults to the $dateTime input.
+ *
+ * @param integer|string|DateTime $dateTime UNIX timestamp, strtotime() valid string or DateTime object
+ * @param array $options Default format if timestamp is used in $dateString
+ * @return string Relative time string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function timeAgoInWords($dateTime, $options = array()) {
+ $element = null;
+ $stringDate = '';
+
+ if (is_array($options) && !empty($options['element'])) {
+ $element = array(
+ 'tag' => 'span',
+ 'class' => 'time-ago-in-words',
+ 'title' => $dateTime
+ );
+
+ if (is_array($options['element'])) {
+ $element = array_merge($element, $options['element']);
+ } else {
+ $element['tag'] = $options['element'];
+ }
+ unset($options['element']);
+ }
+ $relativeDate = $this->_engine->timeAgoInWords($dateTime, $options);
+
+ if ($element) {
+ $relativeDate = sprintf(
+ '<%s%s>%s</%s>',
+ $element['tag'],
+ $this->_parseAttributes($element, array('tag')),
+ $relativeDate,
+ $element['tag']
+ );
+ }
+ return $relativeDate;
+ }
+
+/**
+ * @see CakeTime::wasWithinLast()
+ *
+ * @param string|integer $timeInterval the numeric value with space then time type.
+ * Example of valid types: 6 hours, 2 days, 1 minute.
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function wasWithinLast($timeInterval, $dateString, $timezone = null) {
+ return $this->_engine->wasWithinLast($timeInterval, $dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isWithinLast()
+ *
+ * @param string|integer $timeInterval the numeric value with space then time type.
+ * Example of valid types: 6 hours, 2 days, 1 minute.
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isWithinNext($timeInterval, $dateString, $timezone = null) {
+ return $this->_engine->isWithinNext($timeInterval, $dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::gmt()
+ *
+ * @param integer|string|DateTime $string UNIX timestamp, strtotime() valid string or DateTime object
+ * @return integer UNIX timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function gmt($string = null) {
+ return $this->_engine->gmt($string);
+ }
+
+/**
+ * @see CakeTime::format()
+ *
+ * @param integer|string|DateTime $format date format string (or a UNIX timestamp, strtotime() valid string or DateTime object)
+ * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string)
+ * @param boolean $invalid flag to ignore results of fromString == false
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function format($format, $date = null, $invalid = false, $timezone = null) {
+ return $this->_engine->format($format, $date, $invalid, $timezone);
+ }
+
+/**
+ * @see CakeTime::i18nFormat()
+ *
+ * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $format strftime format string.
+ * @param boolean $invalid flag to ignore results of fromString == false
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted and translated date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function i18nFormat($date, $format = null, $invalid = false, $timezone = null) {
+ return $this->_engine->i18nFormat($date, $format, $invalid, $timezone);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php
new file mode 100644
index 0000000..f07019c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Helpers collection is used as a registry for loaded helpers and handles loading
+ * and constructing helper 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.View
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * Helpers collection is used as a registry for loaded helpers and handles loading
+ * and constructing helper class objects.
+ *
+ * @package Cake.View
+ */
+class HelperCollection extends ObjectCollection implements CakeEventListener {
+
+/**
+ * View object to use when making helpers.
+ *
+ * @var View
+ */
+ protected $_View;
+
+/**
+ * Constructor
+ *
+ * @param View $view
+ */
+ public function __construct(View $view) {
+ $this->_View = $view;
+ }
+
+/**
+ * Tries to lazy load a helper based on its name, if it cannot be found
+ * in the application folder, then it tries looking under the current plugin
+ * if any
+ *
+ * @param string $helper The helper name to be loaded
+ * @return boolean wheter the helper could be loaded or not
+ * @throws MissingHelperException When a helper could not be found.
+ * App helpers are searched, and then plugin helpers.
+ */
+ public function __isset($helper) {
+ if (parent::__isset($helper)) {
+ return true;
+ }
+
+ try {
+ $this->load($helper);
+ } catch (MissingHelperException $exception) {
+ if ($this->_View->plugin) {
+ $this->load($this->_View->plugin . '.' . $helper);
+ return true;
+ }
+ }
+
+ if (!empty($exception)) {
+ throw $exception;
+ }
+
+ return true;
+ }
+
+/**
+ * Provide public read access to the loaded objects
+ *
+ * @param string $name Name of property to read
+ * @return mixed
+ */
+ public function __get($name) {
+ if ($result = parent::__get($name)) {
+ return $result;
+ }
+ if ($this->__isset($name)) {
+ return $this->_loaded[$name];
+ }
+ return null;
+ }
+
+/**
+ * Loads/constructs a helper. Will return the instance in the registry if it already exists.
+ * By setting `$enable` to false you can disable callbacks for a helper. Alternatively you
+ * can set `$settings['enabled'] = false` to disable callbacks. This alias is provided so that when
+ * declaring $helpers arrays you can disable callbacks on helpers.
+ *
+ * You can alias your helper as an existing helper by setting the 'className' key, i.e.,
+ * {{{
+ * public $helpers = array(
+ * 'Html' => array(
+ * 'className' => 'AliasedHtml'
+ * );
+ * );
+ * }}}
+ * All calls to the `Html` helper would use `AliasedHtml` instead.
+ *
+ * @param string $helper Helper name to load
+ * @param array $settings Settings for the helper.
+ * @return Helper A helper object, Either the existing loaded helper or a new one.
+ * @throws MissingHelperException when the helper could not be found
+ */
+ public function load($helper, $settings = array()) {
+ if (is_array($settings) && isset($settings['className'])) {
+ $alias = $helper;
+ $helper = $settings['className'];
+ }
+ list($plugin, $name) = pluginSplit($helper, true);
+ if (!isset($alias)) {
+ $alias = $name;
+ }
+
+ if (isset($this->_loaded[$alias])) {
+ return $this->_loaded[$alias];
+ }
+ $helperClass = $name . 'Helper';
+ App::uses($helperClass, $plugin . 'View/Helper');
+ if (!class_exists($helperClass)) {
+ throw new MissingHelperException(array(
+ 'class' => $helperClass,
+ 'plugin' => substr($plugin, 0, -1)
+ ));
+ }
+ $this->_loaded[$alias] = new $helperClass($this->_View, $settings);
+
+ $vars = array('request', 'theme', 'plugin');
+ foreach ($vars as $var) {
+ $this->_loaded[$alias]->{$var} = $this->_View->{$var};
+ }
+ $enable = isset($settings['enabled']) ? $settings['enabled'] : true;
+ if ($enable) {
+ $this->enable($alias);
+ }
+ return $this->_loaded[$alias];
+ }
+
+/**
+ * Returns a list of all events that will fire in the View during it's lifecycle.
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'View.beforeRenderFile' => 'trigger',
+ 'View.afterRenderFile' => 'trigger',
+ 'View.beforeRender' => 'trigger',
+ 'View.afterRender' => 'trigger',
+ 'View.beforeLayout' => 'trigger',
+ 'View.afterLayout' => 'trigger'
+ );
+ }
+
+/**
+ * Trigger a callback method on every object in the collection.
+ * Used to trigger methods on objects in the collection. Will fire the methods in the
+ * order they were attached.
+ *
+ * ### Options
+ *
+ * - `breakOn` Set to the value or values you want the callback propagation to stop on.
+ * Can either be a scalar value, or an array of values to break on. Defaults to `false`.
+ *
+ * - `break` Set to true to enabled breaking. When a trigger is broken, the last returned value
+ * will be returned. If used in combination with `collectReturn` the collected results will be returned.
+ * Defaults to `false`.
+ *
+ * - `collectReturn` Set to true to collect the return of each object into an array.
+ * This array of return values will be returned from the trigger() call. Defaults to `false`.
+ *
+ * - `modParams` Allows each object the callback gets called on to modify the parameters to the next object.
+ * Setting modParams to an integer value will allow you to modify the parameter with that index.
+ * Any non-null value will modify the parameter index indicated.
+ * Defaults to false.
+ *
+ *
+ * @param string $callback|CakeEvent Method to fire on all the objects. Its assumed all the objects implement
+ * the method you are calling. If an instance of CakeEvent is provided, then then Event name will parsed to
+ * get the callback name. This is done by getting the last word after any dot in the event name
+ * (eg. `Model.afterSave` event will trigger the `afterSave` callback)
+ * @param array $params Array of parameters for the triggered callback.
+ * @param array $options Array of options.
+ * @return mixed Either the last result or all results if collectReturn is on.
+ * @throws CakeException when modParams is used with an index that does not exist.
+ */
+ public function trigger($callback, $params = array(), $options = array()) {
+ if ($callback instanceof CakeEvent) {
+ $callback->omitSubject = true;
+ }
+ return parent::trigger($callback, $params, $options);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php
new file mode 100644
index 0000000..3cf669c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php
@@ -0,0 +1,108 @@
+<?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
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+
+/**
+ * A view class that is used for JSON responses.
+ *
+ * By setting the '_serialize' key in your controller, you can specify a view variable
+ * that should be serialized to JSON and used as the response for the request.
+ * This allows you to omit views + layouts, if your just need to emit a single view
+ * variable as the JSON response.
+ *
+ * In your controller, you could do the following:
+ *
+ * `$this->set(array('posts' => $posts, '_serialize' => 'posts'));`
+ *
+ * When the view is rendered, the `$posts` view variable will be serialized
+ * into JSON.
+ *
+ * You can also define `'_serialize'` as an array. This will create a top level object containing
+ * all the named view variables:
+ *
+ * {{{
+ * $this->set(compact('posts', 'users', 'stuff'));
+ * $this->set('_serialize', array('posts', 'users'));
+ * }}}
+ *
+ * The above would generate a JSON object that looks like:
+ *
+ * `{"posts": [...], "users": [...]}`
+ *
+ * If you don't use the `_serialize` key, you will need a view. You can use extended
+ * views to provide layout like functionality.
+ *
+ * @package Cake.View
+ * @since CakePHP(tm) v 2.1.0
+ */
+class JsonView extends View {
+
+/**
+ * JSON views are always located in the 'json' sub directory for a
+ * controllers views.
+ *
+ * @var string
+ */
+ public $subDir = 'json';
+
+/**
+ * Constructor
+ *
+ * @param Controller $controller
+ */
+ public function __construct(Controller $controller = null) {
+ parent::__construct($controller);
+ if (isset($controller->response) && $controller->response instanceof CakeResponse) {
+ $controller->response->type('json');
+ }
+ }
+
+/**
+ * Render a JSON view.
+ *
+ * Uses the special '_serialize' parameter to convert a set of
+ * view variables into a JSON response. Makes generating simple
+ * JSON responses very easy. You can omit the '_serialize' parameter,
+ * and use a normal view + layout as well.
+ *
+ * @param string $view The view being rendered.
+ * @param string $layout The layout being rendered.
+ * @return string The rendered view.
+ */
+ public function render($view = null, $layout = null) {
+ if (isset($this->viewVars['_serialize'])) {
+ $serialize = $this->viewVars['_serialize'];
+ if (is_array($serialize)) {
+ $data = array();
+ foreach ($serialize as $key) {
+ $data[$key] = $this->viewVars[$key];
+ }
+ } else {
+ $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null;
+ }
+ $content = json_encode($data);
+ $this->Blocks->set('content', $content);
+ return $content;
+ }
+ if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ $content = $this->_render($viewFileName);
+ $this->Blocks->set('content', $content);
+ return $content;
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php
new file mode 100644
index 0000000..49a3140
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * Methods to display or download any type of file
+ *
+ * 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.View
+ * @since CakePHP(tm) v 1.2.0.5714
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('CakeRequest', 'Network');
+
+/**
+ * Media View provides a custom view implementation for sending files to visitors. Its great
+ * for making the response of a controller action be a file that is saved somewhere on the filesystem.
+ *
+ * An example use comes from the CakePHP internals. MediaView is used to serve plugin and theme assets,
+ * as they are not normally accessible from an application's webroot. Unlike other views, MediaView
+ * uses several viewVars that have special meaning:
+ *
+ * - `id` The filename on the server's filesystem, including extension.
+ * - `name` The filename that will be sent to the user, specified without the extension.
+ * - `download` Set to true to set a `Content-Disposition` header. This is ideal for file downloads.
+ * - `extension` The extension of the file being served. This is used to set the mimetype.
+ * If not provided its extracted from filename provided as `id`.
+ * - `path` The absolute path, including the trailing / on the server's filesystem to `id`.
+ * - `mimeType` The mime type of the file if CakeResponse doesn't know about it.
+ * Must be an associative array with extension as key and mime type as value eg. array('ini' => 'text/plain')
+ *
+ * ### Usage
+ *
+ * {{{
+ * class ExampleController extends AppController {
+ * public function download() {
+ * $this->viewClass = 'Media';
+ * $params = array(
+ * 'id' => 'example.zip',
+ * 'name' => 'example',
+ * 'download' => true,
+ * 'extension' => 'zip',
+ * 'path' => APP . 'files' . DS
+ * );
+ * $this->set($params);
+ * }
+ * }
+ * }}}
+ *
+ * @package Cake.View
+ */
+class MediaView extends View {
+
+/**
+ * Indicates whether response gzip compression was enabled for this class
+ *
+ * @var boolean
+ */
+ protected $_compressionEnabled = false;
+
+/**
+ * Display or download the given file
+ *
+ * @param string $view Not used
+ * @param string $layout Not used
+ * @return mixed
+ * @throws NotFoundException
+ */
+ public function render($view = null, $layout = null) {
+ $name = $download = $extension = $id = $modified = $path = $cache = $mimeType = $compress = null;
+ extract($this->viewVars, EXTR_OVERWRITE);
+
+ if (is_dir($path)) {
+ $path = $path . $id;
+ } else {
+ $path = APP . $path . $id;
+ }
+
+ if (!is_file($path)) {
+ if (Configure::read('debug')) {
+ throw new NotFoundException(sprintf('The requested file %s was not found', $path));
+ }
+ throw new NotFoundException('The requested file was not found');
+ }
+
+ if (is_array($mimeType)) {
+ $this->response->type($mimeType);
+ }
+
+ if (!isset($extension)) {
+ $extension = pathinfo($id, PATHINFO_EXTENSION);
+ }
+
+ if ($this->_isActive()) {
+ $extension = strtolower($extension);
+ $chunkSize = 8192;
+ $buffer = '';
+ $fileSize = @filesize($path);
+ $handle = fopen($path, 'rb');
+
+ if ($handle === false) {
+ return false;
+ }
+ if (!empty($modified) && !is_numeric($modified)) {
+ $modified = strtotime($modified, time());
+ } else {
+ $modified = time();
+ }
+ if (!$extension || $this->response->type($extension) === false) {
+ $download = true;
+ }
+
+ if ($cache) {
+ $this->response->cache($modified, $cache);
+ } else {
+ $this->response->header(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+ }
+
+ if ($download) {
+ $agent = env('HTTP_USER_AGENT');
+
+ if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) {
+ $contentType = 'application/octetstream';
+ } elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
+ $contentType = 'application/force-download';
+ }
+
+ if (!empty($contentType)) {
+ $this->response->type($contentType);
+ }
+ if (is_null($name)) {
+ $name = $id;
+ } elseif ($extension) {
+ $name .= '.' . $extension;
+ }
+ $this->response->download($name);
+ $this->response->header(array('Accept-Ranges' => 'bytes'));
+
+ $httpRange = env('HTTP_RANGE');
+ if (isset($httpRange)) {
+ list($toss, $range) = explode('=', $httpRange);
+
+ $size = $fileSize - 1;
+ $length = $fileSize - $range;
+
+ $this->response->header(array(
+ 'Content-Length' => $length,
+ 'Content-Range' => 'bytes ' . $range . $size . '/' . $fileSize
+ ));
+
+ $this->response->statusCode(206);
+ fseek($handle, $range);
+ } else {
+ $this->response->header('Content-Length', $fileSize);
+ }
+ } else {
+ $this->response->header(array(
+ 'Content-Length' => $fileSize
+ ));
+ }
+ $this->_clearBuffer();
+ if ($compress) {
+ $this->_compressionEnabled = $this->response->compress();
+ }
+
+ $this->response->send();
+ return $this->_sendFile($handle);
+ }
+
+ return false;
+ }
+
+/**
+ * Reads out a file handle, and echos the content to the client.
+ *
+ * @param resource $handle A file handle or stream
+ * @return void
+ */
+ protected function _sendFile($handle) {
+ $chunkSize = 8192;
+ $buffer = '';
+ while (!feof($handle)) {
+ if (!$this->_isActive()) {
+ fclose($handle);
+ return false;
+ }
+ set_time_limit(0);
+ $buffer = fread($handle, $chunkSize);
+ echo $buffer;
+ if (!$this->_compressionEnabled) {
+ $this->_flushBuffer();
+ }
+ }
+ fclose($handle);
+ }
+
+/**
+ * Returns true if connection is still active
+ *
+ * @return boolean
+ */
+ protected function _isActive() {
+ return connection_status() == 0 && !connection_aborted();
+ }
+
+/**
+ * Clears the contents of the topmost output buffer and discards them
+ *
+ * @return boolean
+ */
+ protected function _clearBuffer() {
+ return @ob_end_clean();
+ }
+
+/**
+ * Flushes the contents of the output buffer
+ *
+ * @return void
+ */
+ protected function _flushBuffer() {
+ @flush();
+ @ob_flush();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php
new file mode 100644
index 0000000..5cb9fb6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php
@@ -0,0 +1,91 @@
+<?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.View
+ * @since Cake v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ThemeView', 'View');
+
+/**
+ * ScaffoldView provides specific view file loading features for scaffolded views.
+ *
+ * @package Cake.View
+ */
+class ScaffoldView extends ThemeView {
+
+/**
+ * Override _getViewFileName Appends special scaffolding views in.
+ *
+ * @param string $name name of the view file to get.
+ * @return string action
+ * @throws MissingViewException
+ */
+ protected function _getViewFileName($name = null) {
+ if ($name === null) {
+ $name = $this->action;
+ }
+ $name = Inflector::underscore($name);
+ $prefixes = Configure::read('Routing.prefixes');
+
+ if (!empty($prefixes)) {
+ foreach ($prefixes as $prefix) {
+ if (strpos($name, $prefix . '_') !== false) {
+ $name = substr($name, strlen($prefix) + 1);
+ break;
+ }
+ }
+ }
+
+ if ($name === 'add' || $name == 'edit') {
+ $name = 'form';
+ }
+
+ $scaffoldAction = 'scaffold.' . $name;
+
+ if (!is_null($this->subDir)) {
+ $subDir = strtolower($this->subDir) . DS;
+ } else {
+ $subDir = null;
+ }
+
+ $names[] = $this->viewPath . DS . $subDir . $scaffoldAction;
+ $names[] = 'Scaffolds' . DS . $subDir . $name;
+
+ $paths = $this->_paths($this->plugin);
+ $exts = array($this->ext);
+ if ($this->ext !== '.ctp') {
+ array_push($exts, '.ctp');
+ }
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ foreach ($names as $name) {
+ if (file_exists($path . $name . $ext)) {
+ return $path . $name . $ext;
+ }
+ }
+ }
+ }
+
+ if ($name === 'Scaffolds' . DS . $subDir . 'error') {
+ return CAKE . 'View' . DS . 'Errors' . DS . 'scaffold_error.ctp';
+ }
+
+ throw new MissingViewException($paths[0] . $name . $this->ext);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp
new file mode 100644
index 0000000..b672595
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp
@@ -0,0 +1,51 @@
+<?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.View.Scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> form">
+<?php
+ echo $this->Form->create();
+ echo $this->Form->inputs($scaffoldFields, array('created', 'modified', 'updated'));
+ echo $this->Form->end(__d('cake', 'Submit'));
+?>
+</div>
+<div class="actions">
+ <h3><?php echo __d('cake', 'Actions'); ?></h3>
+ <ul>
+<?php if ($this->request->action != 'add'): ?>
+ <li><?php echo $this->Form->postLink(
+ __d('cake', 'Delete'),
+ array('action' => 'delete', $this->Form->value($modelClass . '.' . $primaryKey)),
+ null,
+ __d('cake', 'Are you sure you want to delete # %s?', $this->Form->value($modelClass . '.' . $primaryKey)));
+ ?></li>
+<?php endif; ?>
+ <li><?php echo $this->Html->link(__d('cake', 'List') . ' ' . $pluralHumanName, array('action' => 'index')); ?></li>
+<?php
+ $done = array();
+ foreach ($associations as $_type => $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>\n";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp
new file mode 100644
index 0000000..fffec7f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp
@@ -0,0 +1,94 @@
+<?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.View.Scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> index">
+<h2><?php echo $pluralHumanName; ?></h2>
+<table cellpadding="0" cellspacing="0">
+<tr>
+<?php foreach ($scaffoldFields as $_field): ?>
+ <th><?php echo $this->Paginator->sort($_field); ?></th>
+<?php endforeach; ?>
+ <th><?php echo __d('cake', 'Actions'); ?></th>
+</tr>
+<?php
+$i = 0;
+foreach (${$pluralVar} as ${$singularVar}):
+ echo "<tr>";
+ foreach ($scaffoldFields as $_field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $_alias => $_details) {
+ if ($_field === $_details['foreignKey']) {
+ $isKey = true;
+ echo "<td>" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "</td>";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "<td>" . h(${$singularVar}[$modelClass][$_field]) . "</td>";
+ }
+ }
+
+ echo '<td class="actions">';
+ echo $this->Html->link(__d('cake', 'View'), array('action' => 'view', ${$singularVar}[$modelClass][$primaryKey]));
+ echo $this->Html->link(__d('cake', 'Edit'), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey]));
+ echo $this->Form->postLink(
+ __d('cake', 'Delete'),
+ array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]),
+ null,
+ __d('cake', 'Are you sure you want to delete').' #' . ${$singularVar}[$modelClass][$primaryKey]
+ );
+ echo '</td>';
+ echo '</tr>';
+
+endforeach;
+
+?>
+</table>
+ <p><?php
+ echo $this->Paginator->counter(array(
+ 'format' => __d('cake', 'Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
+ ));
+ ?></p>
+ <div class="paging">
+ <?php
+ echo $this->Paginator->prev('< ' . __d('cake', 'previous'), array(), null, array('class' => 'prev disabled'));
+ echo $this->Paginator->numbers(array('separator' => ''));
+ echo $this->Paginator->next(__d('cake', 'next') .' >', array(), null, array('class' => 'next disabled'));
+ ?>
+ </div>
+</div>
+<div class="actions">
+ <h3><?php echo __d('cake', 'Actions'); ?></h3>
+ <ul>
+ <li><?php echo $this->Html->link(__d('cake', 'New %s', $singularHumanName), array('action' => 'add')); ?></li>
+<?php
+ $done = array();
+ foreach ($associations as $_type => $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "<li>" . $this->Html->link(__d('cake', 'List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>";
+ echo "<li>" . $this->Html->link(__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp
new file mode 100644
index 0000000..c383d12
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp
@@ -0,0 +1,146 @@
+<?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.View.Scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> view">
+<h2><?php echo __d('cake', 'View %s', $singularHumanName); ?></h2>
+ <dl>
+<?php
+$i = 0;
+foreach ($scaffoldFields as $_field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $_alias => $_details) {
+ if ($_field === $_details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t<dt>" . Inflector::humanize($_alias) . "</dt>\n";
+ echo "\t\t<dd>\n\t\t\t" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "\n\t\t&nbsp;</dd>\n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t<dt>" . Inflector::humanize($_field) . "</dt>\n";
+ echo "\t\t<dd>" . h(${$singularVar}[$modelClass][$_field]) . "&nbsp;</dd>\n";
+ }
+}
+?>
+ </dl>
+</div>
+<div class="actions">
+ <h3><?php echo __d('cake', 'Actions'); ?></h3>
+ <ul>
+<?php
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'Edit %s', $singularHumanName), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey])) . " </li>\n";
+ echo "\t\t<li>" . $this->Form->postLink(__d('cake', 'Delete %s', $singularHumanName), array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]), null, __d('cake', 'Are you sure you want to delete').' #' . ${$singularVar}[$modelClass][$primaryKey] . '?') . " </li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'List %s', $pluralHumanName), array('action' => 'index')) . " </li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'New %s', $singularHumanName), array('action' => 'add')) . " </li>\n";
+
+ $done = array();
+ foreach ($associations as $_type => $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>\n";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div>
+<?php
+if (!empty($associations['hasOne'])) :
+foreach ($associations['hasOne'] as $_alias => $_details): ?>
+<div class="related">
+ <h3><?php echo __d('cake', "Related %s", Inflector::humanize($_details['controller'])); ?></h3>
+<?php if (!empty(${$singularVar}[$_alias])): ?>
+ <dl>
+<?php
+ $i = 0;
+ $otherFields = array_keys(${$singularVar}[$_alias]);
+ foreach ($otherFields as $_field) {
+ echo "\t\t<dt>" . Inflector::humanize($_field) . "</dt>\n";
+ echo "\t\t<dd>\n\t" . ${$singularVar}[$_alias][$_field] . "\n&nbsp;</dd>\n";
+ }
+?>
+ </dl>
+<?php endif; ?>
+ <div class="actions">
+ <ul>
+ <li><?php echo $this->Html->link(__d('cake', 'Edit %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'edit', ${$singularVar}[$_alias][$_details['primaryKey']]))."</li>\n"; ?>
+ </ul>
+ </div>
+</div>
+<?php
+endforeach;
+endif;
+
+if (empty($associations['hasMany'])) {
+ $associations['hasMany'] = array();
+}
+if (empty($associations['hasAndBelongsToMany'])) {
+ $associations['hasAndBelongsToMany'] = array();
+}
+$relations = array_merge($associations['hasMany'], $associations['hasAndBelongsToMany']);
+$i = 0;
+foreach ($relations as $_alias => $_details):
+$otherSingularVar = Inflector::variable($_alias);
+?>
+<div class="related">
+ <h3><?php echo __d('cake', "Related %s", Inflector::humanize($_details['controller'])); ?></h3>
+<?php if (!empty(${$singularVar}[$_alias])): ?>
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+<?php
+ $otherFields = array_keys(${$singularVar}[$_alias][0]);
+ if (isset($_details['with'])) {
+ $index = array_search($_details['with'], $otherFields);
+ unset($otherFields[$index]);
+ }
+ foreach ($otherFields as $_field) {
+ echo "\t\t<th>" . Inflector::humanize($_field) . "</th>\n";
+ }
+?>
+ <th class="actions">Actions</th>
+ </tr>
+<?php
+ $i = 0;
+ foreach (${$singularVar}[$_alias] as ${$otherSingularVar}):
+ echo "\t\t<tr>\n";
+
+ foreach ($otherFields as $_field) {
+ echo "\t\t\t<td>" . ${$otherSingularVar}[$_field] . "</td>\n";
+ }
+
+ echo "\t\t\t<td class=\"actions\">\n";
+ echo "\t\t\t\t" . $this->Html->link(__d('cake', 'View'), array('controller' => $_details['controller'], 'action' => 'view', ${$otherSingularVar}[$_details['primaryKey']])). "\n";
+ echo "\t\t\t\t" . $this->Html->link(__d('cake', 'Edit'), array('controller' => $_details['controller'], 'action' => 'edit', ${$otherSingularVar}[$_details['primaryKey']])). "\n";
+ echo "\t\t\t\t" . $this->Form->postLink(__d('cake', 'Delete'), array('controller' => $_details['controller'], 'action' => 'delete', ${$otherSingularVar}[$_details['primaryKey']]), null, __d('cake', 'Are you sure you want to delete', true).' #' . ${$otherSingularVar}[$_details['primaryKey']] . '?'). "\n";
+ echo "\t\t\t</td>\n";
+ echo "\t\t</tr>\n";
+ endforeach;
+?>
+ </table>
+<?php endif; ?>
+ <div class="actions">
+ <ul>
+ <li><?php echo $this->Html->link(__d('cake', "New %s", Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')); ?> </li>
+ </ul>
+ </div>
+</div>
+<?php endforeach; ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php
new file mode 100644
index 0000000..6b3617c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * A custom view class that is used for themeing
+ *
+ * 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.View
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+
+/**
+ * Theme view class
+ *
+ * Stub class for 2.1 Compatibility
+ *
+ * @package Cake.View
+ */
+class ThemeView extends View {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php
new file mode 100644
index 0000000..59ce0ac
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php
@@ -0,0 +1,1129 @@
+<?php
+/**
+ * Methods for displaying presentation data in the view.
+ *
+ * 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.View
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HelperCollection', 'View');
+App::uses('AppHelper', 'View/Helper');
+App::uses('Router', 'Routing');
+App::uses('ViewBlock', 'View');
+App::uses('CakeEvent', 'Event');
+App::uses('CakeEventManager', 'Event');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * View, the V in the MVC triad. View interacts with Helpers and view variables passed
+ * in from the controller to render the results of the controller action. Often this is HTML,
+ * but can also take the form of JSON, XML, PDF's or streaming files.
+ *
+ * CakePHP uses a two-step-view pattern. This means that the view content is rendered first,
+ * and then inserted into the selected layout. This also means you can pass data from the view to the
+ * layout using `$this->set()`
+ *
+ * Since 2.1, the base View class also includes support for themes by default. Theme views are regular
+ * view files that can provide unique HTML and static assets. If theme views are not found for the
+ * current view the default app view files will be used. You can set `$this->theme = 'mytheme'`
+ * in your Controller to use the Themes.
+ *
+ * Example of theme path with `$this->theme = 'SuperHot';` Would be `app/View/Themed/SuperHot/Posts`
+ *
+ * @package Cake.View
+ * @property CacheHelper $Cache
+ * @property FormHelper $Form
+ * @property HtmlHelper $Html
+ * @property JsHelper $Js
+ * @property NumberHelper $Number
+ * @property PaginatorHelper $Paginator
+ * @property RssHelper $Rss
+ * @property SessionHelper $Session
+ * @property TextHelper $Text
+ * @property TimeHelper $Time
+ * @property ViewBlock $Blocks
+ */
+class View extends Object {
+
+/**
+ * Helpers collection
+ *
+ * @var HelperCollection
+ */
+ public $Helpers;
+
+/**
+ * ViewBlock instance.
+ *
+ * @var ViewBlock
+ */
+ public $Blocks;
+
+/**
+ * Name of the plugin.
+ *
+ * @link http://manual.cakephp.org/chapter/plugins
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Name of the controller.
+ *
+ * @var string Name of controller
+ */
+ public $name = null;
+
+/**
+ * Current passed params
+ *
+ * @var mixed
+ */
+ public $passedArgs = array();
+
+/**
+ * An array of names of built-in helpers to include.
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ */
+ public $helpers = array('Html');
+
+/**
+ * Path to View.
+ *
+ * @var string Path to View
+ */
+ public $viewPath = null;
+
+/**
+ * Variables for the view
+ *
+ * @var array
+ */
+ public $viewVars = array();
+
+/**
+ * Name of view to use with this View.
+ *
+ * @var string
+ */
+ public $view = null;
+
+/**
+ * Name of layout to use with this View.
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Path to Layout.
+ *
+ * @var string Path to Layout
+ */
+ public $layoutPath = null;
+
+/**
+ * Turns on or off Cake's conventional mode of applying layout files. On by default.
+ * Setting to off means that layouts will not be automatically applied to rendered views.
+ *
+ * @var boolean
+ */
+ public $autoLayout = true;
+
+/**
+ * File extension. Defaults to Cake's template ".ctp".
+ *
+ * @var string
+ */
+ public $ext = '.ctp';
+
+/**
+ * Sub-directory for this view file. This is often used for extension based routing.
+ * Eg. With an `xml` extension, $subDir would be `xml/`
+ *
+ * @var string
+ */
+ public $subDir = null;
+
+/**
+ * Theme name.
+ *
+ * @var string
+ */
+ public $theme = null;
+
+/**
+ * Used to define methods a controller that will be cached.
+ *
+ * @see Controller::$cacheAction
+ * @var mixed
+ */
+ public $cacheAction = false;
+
+/**
+ * Holds current errors for the model validation.
+ *
+ * @var array
+ */
+ public $validationErrors = array();
+
+/**
+ * True when the view has been rendered.
+ *
+ * @var boolean
+ */
+ public $hasRendered = false;
+
+/**
+ * List of generated DOM UUIDs.
+ *
+ * @var array
+ */
+ public $uuids = 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
+ */
+ public $request;
+
+/**
+ * Reference to the Response object
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * The Cache configuration View will use to store cached elements. Changing this will change
+ * the default configuration elements are stored under. You can also choose a cache config
+ * per element.
+ *
+ * @var string
+ * @see View::element()
+ */
+ public $elementCache = 'default';
+
+/**
+ * List of variables to collect from the associated controller.
+ *
+ * @var array
+ */
+ protected $_passedVars = array(
+ 'viewVars', 'autoLayout', 'ext', 'helpers', 'view', 'layout', 'name', 'theme',
+ 'layoutPath', 'viewPath', 'request', 'plugin', 'passedArgs', 'cacheAction'
+ );
+
+/**
+ * Scripts (and/or other <head /> tags) for the layout.
+ *
+ * @var array
+ */
+ protected $_scripts = array();
+
+/**
+ * Holds an array of paths.
+ *
+ * @var array
+ */
+ protected $_paths = array();
+
+/**
+ * Indicate that helpers have been loaded.
+ *
+ * @var boolean
+ */
+ protected $_helpersLoaded = false;
+
+/**
+ * The names of views and their parents used with View::extend();
+ *
+ * @var array
+ */
+ protected $_parents = array();
+
+/**
+ * The currently rendering view file. Used for resolving parent files.
+ *
+ * @var string
+ */
+ protected $_current = null;
+
+/**
+ * Currently rendering an element. Used for finding parent fragments
+ * for elements.
+ *
+ * @var string
+ */
+ protected $_currentType = '';
+
+/**
+ * Content stack, used for nested templates that all use View::extend();
+ *
+ * @var array
+ */
+ protected $_stack = array();
+
+/**
+ * Instance of the CakeEventManager this View object is using
+ * to dispatch inner events. Usually the manager is shared with
+ * the controller, so it it possible to register view events in
+ * the controller layer.
+ *
+ * @var CakeEventManager
+ */
+ protected $_eventManager = null;
+
+/**
+ * The view file to be rendered, only used inside _execute()
+ */
+ private $__viewFileName = null;
+
+/**
+ * Whether the event manager was already configured for this object
+ *
+ * @var boolean
+ */
+ protected $_eventManagerConfigured = false;
+
+ const TYPE_VIEW = 'view';
+ const TYPE_ELEMENT = 'element';
+ const TYPE_LAYOUT = 'layout';
+
+/**
+ * Constructor
+ *
+ * @param Controller $controller A controller object to pull View::_passedVars from.
+ */
+ public function __construct(Controller $controller = null) {
+ if (is_object($controller)) {
+ $count = count($this->_passedVars);
+ for ($j = 0; $j < $count; $j++) {
+ $var = $this->_passedVars[$j];
+ $this->{$var} = $controller->{$var};
+ }
+ $this->_eventManager = $controller->getEventManager();
+ }
+ if (empty($this->request) && !($this->request = Router::getRequest(true))) {
+ $this->request = new CakeRequest(null, false);
+ $this->request->base = '';
+ $this->request->here = $this->request->webroot = '/';
+ }
+ if (is_object($controller) && isset($controller->response)) {
+ $this->response = $controller->response;
+ } else {
+ $this->response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ }
+ $this->Helpers = new HelperCollection($this);
+ $this->Blocks = new ViewBlock();
+ parent::__construct();
+ }
+
+/**
+ * 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();
+ }
+ if (!$this->_eventManagerConfigured) {
+ $this->_eventManager->attach($this->Helpers);
+ $this->_eventManagerConfigured = true;
+ }
+ return $this->_eventManager;
+ }
+
+/**
+ * Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string.
+ *
+ * This realizes the concept of Elements, (or "partial layouts") and the $params array is used to send
+ * data to be used in the element. Elements can be cached improving performance by using the `cache` option.
+ *
+ * @param string $name Name of template file in the/app/View/Elements/ folder,
+ * or `MyPlugin.template` to use the template element from MyPlugin. If the element
+ * is not found in the plugin, the normal view path cascade will be searched.
+ * @param array $data Array of data to be made available to the rendered view (i.e. the Element)
+ * @param array $options Array of options. Possible keys are:
+ * - `cache` - Can either be `true`, to enable caching using the config in View::$elementCache. Or an array
+ * If an array, the following keys can be used:
+ * - `config` - Used to store the cached element in a custom cache configuration.
+ * - `key` - Used to define the key used in the Cache::write(). It will be prefixed with `element_`
+ * - `plugin` - Load an element from a specific plugin. This option is deprecated, see below.
+ * - `callbacks` - Set to true to fire beforeRender and afterRender helper callbacks for this element.
+ * Defaults to false.
+ * @return string Rendered Element
+ * @deprecated The `$options['plugin']` is deprecated and will be removed in CakePHP 3.0. Use
+ * `Plugin.element_name` instead.
+ */
+ public function element($name, $data = array(), $options = array()) {
+ $file = $plugin = $key = null;
+ $callbacks = false;
+
+ if (isset($options['plugin'])) {
+ $name = Inflector::camelize($options['plugin']) . '.' . $name;
+ }
+
+ if (isset($options['callbacks'])) {
+ $callbacks = $options['callbacks'];
+ }
+
+ if (isset($options['cache'])) {
+ $underscored = null;
+ if ($plugin) {
+ $underscored = Inflector::underscore($plugin);
+ }
+ $keys = array_merge(array($underscored, $name), array_keys($options), array_keys($data));
+ $caching = array(
+ 'config' => $this->elementCache,
+ 'key' => implode('_', $keys)
+ );
+ if (is_array($options['cache'])) {
+ $defaults = array(
+ 'config' => $this->elementCache,
+ 'key' => $caching['key']
+ );
+ $caching = array_merge($defaults, $options['cache']);
+ }
+ $key = 'element_' . $caching['key'];
+ $contents = Cache::read($key, $caching['config']);
+ if ($contents !== false) {
+ return $contents;
+ }
+ }
+
+ $file = $this->_getElementFilename($name);
+
+ if ($file) {
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ if ($callbacks) {
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeRender', $this, array($file)));
+ }
+
+ $this->_currentType = self::TYPE_ELEMENT;
+ $element = $this->_render($file, array_merge($this->viewVars, $data));
+
+ if ($callbacks) {
+ $this->getEventManager()->dispatch(new CakeEvent('View.afterRender', $this, array($file, $element)));
+ }
+ if (isset($options['cache'])) {
+ Cache::write($key, $element, $caching['config']);
+ }
+ return $element;
+ }
+ $file = 'Elements' . DS . $name . $this->ext;
+
+ if (Configure::read('debug') > 0) {
+ return __d('cake_dev', 'Element Not Found: %s', $file);
+ }
+ }
+
+/**
+ * Renders view for given view file and layout.
+ *
+ * Render triggers helper callbacks, which are fired before and after the view are rendered,
+ * as well as before and after the layout. The helper callbacks are called:
+ *
+ * - `beforeRender`
+ * - `afterRender`
+ * - `beforeLayout`
+ * - `afterLayout`
+ *
+ * If View::$autoRender is false and no `$layout` is provided, the view will be returned bare.
+ *
+ * View and layout names can point to plugin views/layouts. Using the `Plugin.view` syntax
+ * a plugin view/layout can be used instead of the app ones. If the chosen plugin is not found
+ * the view will be located along the regular view path cascade.
+ *
+ * @param string $view Name of view file to use
+ * @param string $layout Layout to use.
+ * @return string Rendered Element
+ * @throws CakeException if there is an error in the view.
+ */
+ public function render($view = null, $layout = null) {
+ if ($this->hasRendered) {
+ return true;
+ }
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ $this->Blocks->set('content', '');
+
+ if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
+ $this->_currentType = self::TYPE_VIEW;
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeRender', $this, array($viewFileName)));
+ $this->Blocks->set('content', $this->_render($viewFileName));
+ $this->getEventManager()->dispatch(new CakeEvent('View.afterRender', $this, array($viewFileName)));
+ }
+
+ if ($layout === null) {
+ $layout = $this->layout;
+ }
+ if ($layout && $this->autoLayout) {
+ $this->Blocks->set('content', $this->renderLayout('', $layout));
+ }
+ $this->hasRendered = true;
+ return $this->Blocks->get('content');
+ }
+
+/**
+ * Renders a layout. Returns output from _render(). Returns false on error.
+ * Several variables are created for use in layout.
+ *
+ * - `title_for_layout` - A backwards compatible place holder, you should set this value if you want more control.
+ * - `content_for_layout` - contains rendered view file
+ * - `scripts_for_layout` - Contains content added with addScript() as well as any content in
+ * the 'meta', 'css', and 'script' blocks. They are appended in that order.
+ *
+ * Deprecated features:
+ *
+ * - `$scripts_for_layout` is deprecated and will be removed in CakePHP 3.0.
+ * Use the block features instead. `meta`, `css` and `script` will be populated
+ * by the matching methods on HtmlHelper.
+ * - `$title_for_layout` is deprecated and will be removed in CakePHP 3.0
+ * - `$content_for_layout` is deprecated and will be removed in CakePHP 3.0.
+ * Use the `content` block instead.
+ *
+ * @param string $content Content to render in a view, wrapped by the surrounding layout.
+ * @param string $layout Layout name
+ * @return mixed Rendered output, or false on error
+ * @throws CakeException if there is an error in the view.
+ */
+ public function renderLayout($content, $layout = null) {
+ $layoutFileName = $this->_getLayoutFileName($layout);
+ if (empty($layoutFileName)) {
+ return $this->Blocks->get('content');
+ }
+
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ if (empty($content)) {
+ $content = $this->Blocks->get('content');
+ }
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeLayout', $this, array($layoutFileName)));
+
+ $scripts = implode("\n\t", $this->_scripts);
+ $scripts .= $this->Blocks->get('meta') . $this->Blocks->get('css') . $this->Blocks->get('script');
+
+ $this->viewVars = array_merge($this->viewVars, array(
+ 'content_for_layout' => $content,
+ 'scripts_for_layout' => $scripts,
+ ));
+
+ if (!isset($this->viewVars['title_for_layout'])) {
+ $this->viewVars['title_for_layout'] = Inflector::humanize($this->viewPath);
+ }
+
+ $this->_currentType = self::TYPE_LAYOUT;
+ $this->Blocks->set('content', $this->_render($layoutFileName));
+
+ $this->getEventManager()->dispatch(new CakeEvent('View.afterLayout', $this, array($layoutFileName)));
+ return $this->Blocks->get('content');
+ }
+
+/**
+ * Render cached view. Works in concert with CacheHelper and Dispatcher to
+ * render cached view files.
+ *
+ * @param string $filename the cache file to include
+ * @param string $timeStart the page render start time
+ * @return boolean Success of rendering the cached file.
+ */
+ public function renderCache($filename, $timeStart) {
+ ob_start();
+ include ($filename);
+
+ if (Configure::read('debug') > 0 && $this->layout != 'xml') {
+ echo "<!-- Cached Render Time: " . round(microtime(true) - $timeStart, 4) . "s -->";
+ }
+ $out = ob_get_clean();
+
+ if (preg_match('/^<!--cachetime:(\\d+)-->/', $out, $match)) {
+ if (time() >= $match['1']) {
+ @unlink($filename);
+ unset ($out);
+ return false;
+ } else {
+ if ($this->layout === 'xml') {
+ header('Content-type: text/xml');
+ }
+ $commentLength = strlen('<!--cachetime:' . $match['1'] . '-->');
+ return substr($out, $commentLength);
+ }
+ }
+ }
+
+/**
+ * Returns a list of variables available in the current View context
+ *
+ * @return array Array of the set view variable names.
+ */
+ public function getVars() {
+ return array_keys($this->viewVars);
+ }
+
+/**
+ * Returns the contents of the given View variable(s)
+ *
+ * @param string $var The view var you want the contents of.
+ * @return mixed The content of the named var if its set, otherwise null.
+ * @deprecated Will be removed in 3.0 Use View::get() instead.
+ */
+ public function getVar($var) {
+ return $this->get($var);
+ }
+
+/**
+ * Returns the contents of the given View variable or a block.
+ * Blocks are checked before view variables.
+ *
+ * @param string $var The view var you want the contents of.
+ * @return mixed The content of the named var if its set, otherwise null.
+ */
+ public function get($var) {
+ if (!isset($this->viewVars[$var])) {
+ return null;
+ }
+ return $this->viewVars[$var];
+ }
+
+/**
+ * Get the names of all the existing blocks.
+ *
+ * @return array An array containing the blocks.
+ * @see ViewBlock::keys()
+ */
+ public function blocks() {
+ return $this->Blocks->keys();
+ }
+
+/**
+ * Start capturing output for a 'block'
+ *
+ * @param string $name The name of the block to capture for.
+ * @return void
+ * @see ViewBlock::start()
+ */
+ public function start($name) {
+ return $this->Blocks->start($name);
+ }
+
+/**
+ * Append to an existing or new block. Appending to a new
+ * block will create the block.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ * @see ViewBlock::append()
+ */
+ public function append($name, $value = null) {
+ return $this->Blocks->append($name, $value);
+ }
+
+/**
+ * Set the content for a block. This will overwrite any
+ * existing content.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ * @see ViewBlock::assign()
+ */
+ public function assign($name, $value) {
+ return $this->Blocks->set($name, $value);
+ }
+
+/**
+ * Fetch the content for a block. If a block is
+ * empty or undefined '' will be returned.
+ *
+ * @param string $name Name of the block
+ * @return The block content or '' if the block does not exist.
+ * @see ViewBlock::fetch()
+ */
+ public function fetch($name) {
+ return $this->Blocks->get($name);
+ }
+
+/**
+ * End a capturing block. The compliment to View::start()
+ *
+ * @return void
+ * @see ViewBlock::start()
+ */
+ public function end() {
+ return $this->Blocks->end();
+ }
+
+/**
+ * Provides view or element extension/inheritance. Views can extends a
+ * parent view and populate blocks in the parent template.
+ *
+ * @param string $name The view or element to 'extend' the current one with.
+ * @return void
+ * @throws LogicException when you extend a view with itself or make extend loops.
+ * @throws LogicException when you extend an element which doesn't exist
+ */
+ public function extend($name) {
+ if ($name[0] === '/' || $this->_currentType === self::TYPE_VIEW) {
+ $parent = $this->_getViewFileName($name);
+ } else {
+ switch ($this->_currentType) {
+ case self::TYPE_ELEMENT:
+ $parent = $this->_getElementFileName($name);
+ if (!$parent) {
+ list($plugin, $name) = $this->pluginSplit($name);
+ $paths = $this->_paths($plugin);
+ $defaultPath = $paths[0] . 'Elements' . DS;
+ throw new LogicException(__d(
+ 'cake_dev',
+ 'You cannot extend an element which does not exist (%s).',
+ $defaultPath . $name . $this->ext
+ ));
+ }
+ break;
+ case self::TYPE_LAYOUT:
+ $parent = $this->_getLayoutFileName($name);
+ break;
+ default:
+ $parent = $this->_getViewFileName($name);
+ }
+ }
+
+ if ($parent == $this->_current) {
+ throw new LogicException(__d('cake_dev', 'You cannot have views extend themselves.'));
+ }
+ if (isset($this->_parents[$parent]) && $this->_parents[$parent] == $this->_current) {
+ throw new LogicException(__d('cake_dev', 'You cannot have views extend in a loop.'));
+ }
+ $this->_parents[$this->_current] = $parent;
+ }
+
+/**
+ * Adds a script block or other element to be inserted in $scripts_for_layout in
+ * the `<head />` of a document layout
+ *
+ * @param string $name Either the key name for the script, or the script content. Name can be used to
+ * update/replace a script element.
+ * @param string $content The content of the script being added, optional.
+ * @return void
+ * @deprecated Will be removed in 3.0. Supersceeded by blocks functionality.
+ * @see View::start()
+ */
+ public function addScript($name, $content = null) {
+ if (empty($content)) {
+ if (!in_array($name, array_values($this->_scripts))) {
+ $this->_scripts[] = $name;
+ }
+ } else {
+ $this->_scripts[$name] = $content;
+ }
+ }
+
+/**
+ * Generates a unique, non-random DOM ID for an object, based on the object type and the target URL.
+ *
+ * @param string $object Type of object, i.e. 'form' or 'link'
+ * @param string $url The object's target URL
+ * @return string
+ */
+ public function uuid($object, $url) {
+ $c = 1;
+ $url = Router::url($url);
+ $hash = $object . substr(md5($object . $url), 0, 10);
+ while (in_array($hash, $this->uuids)) {
+ $hash = $object . substr(md5($object . $url . $c), 0, 10);
+ $c++;
+ }
+ $this->uuids[] = $hash;
+ return $hash;
+ }
+
+/**
+ * Allows a template or element to set a variable that will be available in
+ * a layout or other element. Analogous to Controller::set().
+ *
+ * @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
+ */
+ public function set($one, $two = null) {
+ $data = null;
+ if (is_array($one)) {
+ if (is_array($two)) {
+ $data = array_combine($one, $two);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($one => $two);
+ }
+ if ($data == null) {
+ return false;
+ }
+ $this->viewVars = $data + $this->viewVars;
+ }
+
+/**
+ * Magic accessor for helpers. Provides access to attributes that were deprecated.
+ *
+ * @param string $name Name of the attribute to get.
+ * @return mixed
+ */
+ public function __get($name) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name};
+ case 'action':
+ return $this->request->params['action'];
+ case 'params':
+ return $this->request;
+ case 'output':
+ return $this->Blocks->get('content');
+ }
+ if (isset($this->Helpers->{$name})) {
+ $this->{$name} = $this->Helpers->{$name};
+ return $this->Helpers->{$name};
+ }
+ return $this->{$name};
+ }
+
+/**
+ * Magic accessor for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to set.
+ * @param string $value Value of the attribute to set.
+ * @return mixed
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'output':
+ return $this->Blocks->set('content', $value);
+ default:
+ $this->{$name} = $value;
+ }
+ }
+
+/**
+ * Magic isset check for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to check.
+ * @return boolean
+ */
+ public function __isset($name) {
+ if (isset($this->{$name})) {
+ return true;
+ }
+ $magicGet = array('base', 'here', 'webroot', 'data', 'action', 'params', 'output');
+ if (in_array($name, $magicGet)) {
+ return $this->__get($name) !== null;
+ }
+ return false;
+ }
+
+/**
+ * Interact with the HelperCollection to load all the helpers.
+ *
+ * @return void
+ */
+ public function loadHelpers() {
+ $helpers = HelperCollection::normalizeObjectArray($this->helpers);
+ foreach ($helpers as $name => $properties) {
+ list($plugin, $class) = pluginSplit($properties['class']);
+ $this->{$class} = $this->Helpers->load($properties['class'], $properties['settings']);
+ }
+ $this->_helpersLoaded = true;
+ }
+
+/**
+ * Renders and returns output for given view filename with its
+ * array of data. Handles parent/extended views.
+ *
+ * @param string $viewFile Filename of the view
+ * @param array $data Data to include in rendered view. If empty the current View::$viewVars will be used.
+ * @return string Rendered output
+ * @throws CakeException when a block is left open.
+ */
+ protected function _render($viewFile, $data = array()) {
+ if (empty($data)) {
+ $data = $this->viewVars;
+ }
+ $this->_current = $viewFile;
+ $initialBlocks = count($this->Blocks->unclosed());
+
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeRenderFile', $this, array($viewFile)));
+ $content = $this->_evaluate($viewFile, $data);
+ $afterEvent = new CakeEvent('View.afterRenderFile', $this, array($viewFile, $content));
+ //TODO: For BC puporses, set extra info in the event object. Remove when appropriate
+ $afterEvent->modParams = 1;
+ $this->getEventManager()->dispatch($afterEvent);
+ $content = $afterEvent->data[1];
+
+ if (isset($this->_parents[$viewFile])) {
+ $this->_stack[] = $this->fetch('content');
+ $this->assign('content', $content);
+
+ $content = $this->_render($this->_parents[$viewFile]);
+ $this->assign('content', array_pop($this->_stack));
+ }
+
+ $remainingBlocks = count($this->Blocks->unclosed());
+
+ if ($initialBlocks !== $remainingBlocks) {
+ throw new CakeException(__d('cake_dev', 'The "%s" block was left open. Blocks are not allowed to cross files.', $this->Blocks->active()));
+ }
+
+ return $content;
+ }
+
+/**
+ * Sandbox method to evaluate a template / view script in.
+ *
+ * @param string $viewFn Filename of the view
+ * @param array $___dataForView Data to include in rendered view.
+ * If empty the current View::$viewVars will be used.
+ * @return string Rendered output
+ */
+ protected function _evaluate($viewFile, $dataForView) {
+ $this->__viewFile = $viewFile;
+ extract($dataForView);
+ ob_start();
+
+ include $this->__viewFile;
+
+ unset($this->_viewFile);
+ return ob_get_clean();
+ }
+
+/**
+ * Loads a helper. Delegates to the `HelperCollection::load()` to load the helper
+ *
+ * @param string $helperName Name of the helper to load.
+ * @param array $settings Settings for the helper
+ * @return Helper a constructed helper object.
+ * @see HelperCollection::load()
+ */
+ public function loadHelper($helperName, $settings = array()) {
+ return $this->Helpers->load($helperName, $settings);
+ }
+
+/**
+ * Returns filename of given action's template file (.ctp) as a string.
+ * CamelCased action names will be under_scored! This means that you can have
+ * LongActionNames that refer to long_action_names.ctp views.
+ *
+ * @param string $name Controller action to find template filename for
+ * @return string Template filename
+ * @throws MissingViewException when a view file could not be found.
+ */
+ protected function _getViewFileName($name = null) {
+ $subDir = null;
+
+ if (!is_null($this->subDir)) {
+ $subDir = $this->subDir . DS;
+ }
+
+ if ($name === null) {
+ $name = $this->view;
+ }
+ $name = str_replace('/', DS, $name);
+ list($plugin, $name) = $this->pluginSplit($name);
+
+ if (strpos($name, DS) === false && $name[0] !== '.') {
+ $name = $this->viewPath . DS . $subDir . Inflector::underscore($name);
+ } elseif (strpos($name, DS) !== false) {
+ if ($name[0] === DS || $name[1] === ':') {
+ if (is_file($name)) {
+ return $name;
+ }
+ $name = trim($name, DS);
+ } elseif ($name[0] === '.') {
+ $name = substr($name, 3);
+ } elseif (!$plugin || $this->viewPath !== $this->name) {
+ $name = $this->viewPath . DS . $subDir . $name;
+ }
+ }
+ $paths = $this->_paths($plugin);
+ $exts = $this->_getExtensions();
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ if (file_exists($path . $name . $ext)) {
+ return $path . $name . $ext;
+ }
+ }
+ }
+ $defaultPath = $paths[0];
+
+ if ($this->plugin) {
+ $pluginPaths = App::path('plugins');
+ foreach ($paths as $path) {
+ if (strpos($path, $pluginPaths[0]) === 0) {
+ $defaultPath = $path;
+ break;
+ }
+ }
+ }
+ throw new MissingViewException(array('file' => $defaultPath . $name . $this->ext));
+ }
+
+/**
+ * Splits a dot syntax plugin name into its plugin and filename.
+ * If $name does not have a dot, then index 0 will be null.
+ * It checks if the plugin is loaded, else filename will stay unchanged for filenames containing dot
+ *
+ * @param string $name The name you want to plugin split.
+ * @param boolean $fallback If true uses the plugin set in the current CakeRequest when parsed plugin is not loaded
+ * @return array Array with 2 indexes. 0 => plugin name, 1 => filename
+ */
+ public function pluginSplit($name, $fallback = true) {
+ $plugin = null;
+ list($first, $second) = pluginSplit($name);
+ if (CakePlugin::loaded($first) === true) {
+ $name = $second;
+ $plugin = $first;
+ }
+ if (isset($this->plugin) && !$plugin && $fallback) {
+ $plugin = $this->plugin;
+ }
+ return array($plugin, $name);
+ }
+
+/**
+ * Returns layout filename for this template as a string.
+ *
+ * @param string $name The name of the layout to find.
+ * @return string Filename for layout file (.ctp).
+ * @throws MissingLayoutException when a layout cannot be located
+ */
+ protected function _getLayoutFileName($name = null) {
+ if ($name === null) {
+ $name = $this->layout;
+ }
+ $subDir = null;
+
+ if (!is_null($this->layoutPath)) {
+ $subDir = $this->layoutPath . DS;
+ }
+ list($plugin, $name) = $this->pluginSplit($name);
+ $paths = $this->_paths($plugin);
+ $file = 'Layouts' . DS . $subDir . $name;
+
+ $exts = $this->_getExtensions();
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ if (file_exists($path . $file . $ext)) {
+ return $path . $file . $ext;
+ }
+ }
+ }
+ throw new MissingLayoutException(array('file' => $paths[0] . $file . $this->ext));
+ }
+
+/**
+ * Get the extensions that view files can use.
+ *
+ * @return array Array of extensions view files use.
+ */
+ protected function _getExtensions() {
+ $exts = array($this->ext);
+ if ($this->ext !== '.ctp') {
+ array_push($exts, '.ctp');
+ }
+ return $exts;
+ }
+
+/**
+ * Finds an element filename, returns false on failure.
+ *
+ * @param string $name The name of the element to find.
+ * @return mixed Either a string to the element filename or false when one can't be found.
+ */
+ protected function _getElementFileName($name) {
+ list($plugin, $name) = $this->pluginSplit($name);
+
+ $paths = $this->_paths($plugin);
+ $exts = $this->_getExtensions();
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ if (file_exists($path . 'Elements' . DS . $name . $ext)) {
+ return $path . 'Elements' . DS . $name . $ext;
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Return all possible paths to find view files in order
+ *
+ * @param string $plugin Optional plugin name to scan for view files.
+ * @param boolean $cached Set to true to force a refresh of view paths.
+ * @return array paths
+ */
+ protected function _paths($plugin = null, $cached = true) {
+ if ($plugin === null && $cached === true && !empty($this->_paths)) {
+ return $this->_paths;
+ }
+ $paths = array();
+ $viewPaths = App::path('View');
+ $corePaths = array_merge(App::core('View'), App::core('Console/Templates/skel/View'));
+
+ if (!empty($plugin)) {
+ $count = count($viewPaths);
+ for ($i = 0; $i < $count; $i++) {
+ if (!in_array($viewPaths[$i], $corePaths)) {
+ $paths[] = $viewPaths[$i] . 'Plugin' . DS . $plugin . DS;
+ }
+ }
+ $paths = array_merge($paths, App::path('View', $plugin));
+ }
+
+ $paths = array_unique(array_merge($paths, $viewPaths));
+ if (!empty($this->theme)) {
+ $themePaths = array();
+ foreach ($paths as $path) {
+ if (strpos($path, DS . 'Plugin' . DS) === false) {
+ if ($plugin) {
+ $themePaths[] = $path . 'Themed' . DS . $this->theme . DS . 'Plugin' . DS . $plugin . DS;
+ }
+ $themePaths[] = $path . 'Themed' . DS . $this->theme . DS;
+ }
+ }
+ $paths = array_merge($themePaths, $paths);
+ }
+ $paths = array_merge($paths, $corePaths);
+ if ($plugin !== null) {
+ return $paths;
+ }
+ return $this->_paths = $paths;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php
new file mode 100644
index 0000000..5636d74
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php
@@ -0,0 +1,158 @@
+<?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
+ * @since CakePHP(tm) v2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * ViewBlock implements the concept of Blocks or Slots in the View layer.
+ * Slots or blocks are combined with extending views and layouts to afford slots
+ * of content that are present in a layout or parent view, but are defined by the child
+ * view or elements used in the view.
+ *
+ * @package Cake.View
+ */
+class ViewBlock {
+
+/**
+ * Block content. An array of blocks indexed by name.
+ *
+ * @var array
+ */
+ protected $_blocks = array();
+
+/**
+ * The active blocks being captured.
+ *
+ * @var array
+ */
+ protected $_active = array();
+
+/**
+ * Start capturing output for a 'block'
+ *
+ * Blocks allow you to create slots or blocks of dynamic content in the layout.
+ * view files can implement some or all of a layout's slots.
+ *
+ * You can end capturing blocks using View::end(). Blocks can be output
+ * using View::get();
+ *
+ * @param string $name The name of the block to capture for.
+ * @return void
+ */
+ public function start($name) {
+ $this->_active[] = $name;
+ ob_start();
+ }
+
+/**
+ * End a capturing block. The compliment to ViewBlock::start()
+ *
+ * @return void
+ * @see ViewBlock::start()
+ */
+ public function end() {
+ if (!empty($this->_active)) {
+ $active = end($this->_active);
+ $content = ob_get_clean();
+ if (!isset($this->_blocks[$active])) {
+ $this->_blocks[$active] = '';
+ }
+ $this->_blocks[$active] .= $content;
+ array_pop($this->_active);
+ }
+ }
+
+/**
+ * Append to an existing or new block. Appending to a new
+ * block will create the block.
+ *
+ * Calling append() without a value will create a new capturing
+ * block that needs to be finished with View::end(). The content
+ * of the new capturing context will be added to the existing block context.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ */
+ public function append($name, $value = null) {
+ if (isset($value)) {
+ if (!is_string($value)) {
+ throw new CakeException(__d('cake_dev', '$value must be a string.'));
+ }
+ if (!isset($this->_blocks[$name])) {
+ $this->_blocks[$name] = '';
+ }
+ $this->_blocks[$name] .= $value;
+ } else {
+ $this->start($name);
+ }
+ }
+
+/**
+ * Set the content for a block. This will overwrite any
+ * existing content.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ */
+ public function set($name, $value) {
+ if (!is_string($value)) {
+ throw new CakeException(__d('cake_dev', 'Blocks can only contain strings.'));
+ }
+ $this->_blocks[$name] = $value;
+ }
+
+/**
+ * Get the content for a block.
+ *
+ * @param string $name Name of the block
+ * @return The block content or '' if the block does not exist.
+ */
+ public function get($name) {
+ if (!isset($this->_blocks[$name])) {
+ return '';
+ }
+ return $this->_blocks[$name];
+ }
+
+/**
+ * Get the names of all the existing blocks.
+ *
+ * @return array An array containing the blocks.
+ */
+ public function keys() {
+ return array_keys($this->_blocks);
+ }
+
+/**
+ * Get the name of the currently open block.
+ *
+ * @return mixed Either null or the name of the last open block.
+ */
+ public function active() {
+ return end($this->_active);
+ }
+
+/**
+ * Get the names of the unclosed/active blocks.
+ *
+ * @return array An array of unclosed blocks.
+ */
+ public function unclosed() {
+ return $this->_active;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php
new file mode 100644
index 0000000..f89efa6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php
@@ -0,0 +1,113 @@
+<?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
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('Xml', 'Utility');
+
+/**
+ * A view class that is used for creating XML responses.
+ *
+ * By setting the '_serialize' key in your controller, you can specify a view variable
+ * that should be serialized to XML and used as the response for the request.
+ * This allows you to omit views + layouts, if your just need to emit a single view
+ * variable as the XML response.
+ *
+ * In your controller, you could do the following:
+ *
+ * `$this->set(array('posts' => $posts, '_serialize' => 'posts'));`
+ *
+ * When the view is rendered, the `$posts` view variable will be serialized
+ * into XML.
+ *
+ * **Note** The view variable you specify must be compatible with Xml::fromArray().
+ *
+ * You can also define `'_serialize'` as an array. This will create an additional
+ * top level element named `<response>` containing all the named view variables:
+ *
+ * {{{
+ * $this->set(compact('posts', 'users', 'stuff'));
+ * $this->set('_serialize', array('posts', 'users'));
+ * }}}
+ *
+ * The above would generate a XML object that looks like:
+ *
+ * `<response><posts>...</posts><users>...</users></response>`
+ *
+ * If you don't use the `_serialize` key, you will need a view. You can use extended
+ * views to provide layout like functionality.
+ *
+ * @package Cake.View
+ * @since CakePHP(tm) v 2.1.0
+ */
+class XmlView extends View {
+
+/**
+ * The subdirectory. XML views are always in xml.
+ *
+ * @var string
+ */
+ public $subDir = 'xml';
+
+/**
+ * Constructor
+ *
+ * @param Controller $controller
+ */
+ public function __construct(Controller $controller = null) {
+ parent::__construct($controller);
+
+ if (isset($controller->response) && $controller->response instanceof CakeResponse) {
+ $controller->response->type('xml');
+ }
+ }
+
+/**
+ * Render a XML view.
+ *
+ * Uses the special '_serialize' parameter to convert a set of
+ * view variables into a XML response. Makes generating simple
+ * XML responses very easy. You can omit the '_serialize' parameter,
+ * and use a normal view + layout as well.
+ *
+ * @param string $view The view being rendered.
+ * @param string $layout The layout being rendered.
+ * @return string The rendered view.
+ */
+ public function render($view = null, $layout = null) {
+ if (isset($this->viewVars['_serialize'])) {
+ $serialize = $this->viewVars['_serialize'];
+ if (is_array($serialize)) {
+ $data = array('response' => array());
+ foreach ($serialize as $key) {
+ $data['response'][$key] = $this->viewVars[$key];
+ }
+ } else {
+ $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null;
+ if (is_array($data) && Set::numeric(array_keys($data))) {
+ $data = array('response' => array($serialize => $data));
+ }
+ }
+ $content = Xml::fromArray($data)->asXML();
+ return $content;
+ }
+ if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ $content = $this->_render($viewFileName);
+ $this->Blocks->set('content', (string)$content);
+ return $content;
+ }
+ }
+
+}