mirror of
https://github.com/brmlab/brmbiolab_sklad.git
synced 2025-10-29 14:34:00 +01:00
Initial commit
This commit is contained in:
commit
3b93da31de
1004 changed files with 265840 additions and 0 deletions
76
lib/Cake/View/Elements/exception_stack_trace.ctp
Normal file
76
lib/Cake/View/Elements/exception_stack_trace.ctp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
/**
|
||||
* Prints a stack trace for an exception
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 ' → ';
|
||||
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,
|
||||
h(implode(', ', $args))
|
||||
);
|
||||
$arguments = sprintf('<div id="trace-args-%s" class="cake-code-dump" style="display: none;"><pre>', $i);
|
||||
$arguments .= h(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>
|
||||
82
lib/Cake/View/Elements/sql_dump.ctp
Normal file
82
lib/Cake/View/Elements/sql_dump.ctp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
/**
|
||||
* SQL Dump element. Dumps out SQL log information
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
if (!class_exists('ConnectionManager') || Configure::read('debug') < 2) {
|
||||
return false;
|
||||
}
|
||||
$noLogs = !isset($sqlLogs);
|
||||
if ($noLogs):
|
||||
$sources = ConnectionManager::sourceList();
|
||||
|
||||
$sqlLogs = array();
|
||||
foreach ($sources as $source):
|
||||
$db = ConnectionManager::getDataSource($source);
|
||||
if (!method_exists($db, 'getLog')):
|
||||
continue;
|
||||
endif;
|
||||
$sqlLogs[$source] = $db->getLog();
|
||||
endforeach;
|
||||
endif;
|
||||
|
||||
if ($noLogs || isset($_forced_from_dbo_)):
|
||||
foreach ($sqlLogs 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, ', ') . " ]";
|
||||
}
|
||||
printf('<tr><td>%d</td><td>%s</td><td>%s</td><td style="text-align: right">%d</td><td style="text-align: right">%d</td><td style="text-align: right">%d</td></tr>%s',
|
||||
$k + 1,
|
||||
h($i['query']),
|
||||
$i['error'],
|
||||
$i['affected'],
|
||||
$i['numRows'],
|
||||
$i['took'],
|
||||
"\n"
|
||||
);
|
||||
endforeach;
|
||||
?>
|
||||
</tbody></table>
|
||||
<?php
|
||||
endforeach;
|
||||
else:
|
||||
printf('<p>%s</p>', __d('cake_dev', 'Encountered unexpected %s. Cannot generate SQL log.', '$sqlLogs'));
|
||||
endif;
|
||||
34
lib/Cake/View/Errors/fatal_error.ctp
Normal file
34
lib/Cake/View/Errors/fatal_error.ctp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
?>
|
||||
<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>
|
||||
41
lib/Cake/View/Errors/missing_action.ctp
Normal file
41
lib/Cake/View/Errors/missing_action.ctp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
?>
|
||||
<h2><?php echo __d('cake_dev', 'Missing Method in %s', h($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>' . h($action) . '</em>', '<em>' . h($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>' . h($controller) . '::</em>', '<em>' . h($action) . '()</em>', APP_DIR . DS . 'Controller' . DS . h($controller) . '.php'); ?>
|
||||
</p>
|
||||
<pre>
|
||||
<?php
|
||||
class <?php echo h($controller); ?> extends AppController {
|
||||
|
||||
<strong>
|
||||
public function <?php echo h($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'); ?>
|
||||
39
lib/Cake/View/Errors/missing_behavior.ctp
Normal file
39
lib/Cake/View/Errors/missing_behavior.ctp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$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>' . h($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>' . h($class) . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'Model' . DS . 'Behavior' . DS . h($class) . '.php'); ?>
|
||||
</p>
|
||||
<pre>
|
||||
<?php
|
||||
class <?php echo h($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'); ?>
|
||||
39
lib/Cake/View/Errors/missing_component.ctp
Normal file
39
lib/Cake/View/Errors/missing_component.ctp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$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>' . h($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>' . h($class) . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'Controller' . DS . 'Component' . DS . h($class) . '.php'); ?>
|
||||
</p>
|
||||
<pre>
|
||||
<?php
|
||||
class <?php echo h($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'); ?>
|
||||
40
lib/Cake/View/Errors/missing_connection.ctp
Normal file
40
lib/Cake/View/Errors/missing_connection.ctp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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', 'A Database connection using "%s" was missing or unable to connect.', h($class)); ?>
|
||||
<br />
|
||||
<?php
|
||||
if (isset($message)):
|
||||
echo __d('cake_dev', 'The database server returned this error: %s', h($message));
|
||||
endif;
|
||||
?>
|
||||
</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', h($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');
|
||||
39
lib/Cake/View/Errors/missing_controller.ctp
Normal file
39
lib/Cake/View/Errors/missing_controller.ctp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$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>' . h($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>' . h($class) . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'Controller' . DS . h($class) . '.php'); ?>
|
||||
</p>
|
||||
<pre>
|
||||
<?php
|
||||
class <?php echo h($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'); ?>
|
||||
31
lib/Cake/View/Errors/missing_database.ctp
Normal file
31
lib/Cake/View/Errors/missing_database.ctp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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'); ?>
|
||||
32
lib/Cake/View/Errors/missing_datasource.ctp
Normal file
32
lib/Cake/View/Errors/missing_datasource.ctp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$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>' . h($pluginDot . $class) . '</em>'); ?>
|
||||
<?php if (isset($message)): ?>
|
||||
<?php echo h($message); ?>
|
||||
<?php endif; ?>
|
||||
</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'); ?>
|
||||
27
lib/Cake/View/Errors/missing_datasource_config.ctp
Normal file
27
lib/Cake/View/Errors/missing_datasource_config.ctp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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>' . h($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'); ?>
|
||||
39
lib/Cake/View/Errors/missing_helper.ctp
Normal file
39
lib/Cake/View/Errors/missing_helper.ctp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$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>' . h($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>' . h($class) . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'View' . DS . 'Helper' . DS . h($class) . '.php'); ?>
|
||||
</p>
|
||||
<pre>
|
||||
<?php
|
||||
class <?php echo h($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'); ?>
|
||||
31
lib/Cake/View/Errors/missing_layout.ctp
Normal file
31
lib/Cake/View/Errors/missing_layout.ctp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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>' . h($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>' . h($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'); ?>
|
||||
43
lib/Cake/View/Errors/missing_plugin.ctp
Normal file
43
lib/Cake/View/Errors/missing_plugin.ctp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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>' . h($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 %s directory and was loaded', $plugin, APP_DIR . DS . 'Plugin'); ?>
|
||||
</p>
|
||||
<pre>
|
||||
<?php
|
||||
CakePlugin::load('<?php echo h($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 %s file', APP_DIR . DS . 'Config' . DS . 'bootstrap.php'); ?>
|
||||
</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'); ?>
|
||||
27
lib/Cake/View/Errors/missing_table.ctp
Normal file
27
lib/Cake/View/Errors/missing_table.ctp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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>' . h($table) . '</em>', '<em>' . h($class) . '</em>', '<em>' . h($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'); ?>
|
||||
31
lib/Cake/View/Errors/missing_view.ctp
Normal file
31
lib/Cake/View/Errors/missing_view.ctp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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>' . h(Inflector::camelize($this->request->controller)) . 'Controller::</em>', '<em>' . h($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', h($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'); ?>
|
||||
36
lib/Cake/View/Errors/pdo_error.ctp
Normal file
36
lib/Cake/View/Errors/pdo_error.ctp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<h2><?php echo __d('cake_dev', 'Database Error'); ?></h2>
|
||||
<p class="error">
|
||||
<strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
|
||||
<?php echo $message; ?>
|
||||
</p>
|
||||
<?php if (!empty($error->queryString)) : ?>
|
||||
<p class="notice">
|
||||
<strong><?php echo __d('cake_dev', 'SQL Query'); ?>: </strong>
|
||||
<?php echo h($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'); ?>
|
||||
27
lib/Cake/View/Errors/private_action.ctp
Normal file
27
lib/Cake/View/Errors/private_action.ctp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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>' . h($controller) . '::</em>', '<em>' . h($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'); ?>
|
||||
34
lib/Cake/View/Errors/scaffold_error.ctp
Normal file
34
lib/Cake/View/Errors/scaffold_error.ctp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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>
|
||||
<?php
|
||||
function _scaffoldError() {<br />
|
||||
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
||||
<?php echo $this->element('exception_stack_trace'); ?>
|
||||
951
lib/Cake/View/Helper.php
Normal file
951
lib/Cake/View/Helper.php
Normal file
|
|
@ -0,0 +1,951 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Router', 'Routing');
|
||||
App::uses('Hash', 'Utility');
|
||||
App::uses('Inflector', 'Utility');
|
||||
|
||||
/**
|
||||
* Abstract base class for all other Helpers in CakePHP.
|
||||
* Provides common methods and features.
|
||||
*
|
||||
* @package Cake.View
|
||||
*/
|
||||
class Helper extends Object {
|
||||
|
||||
/**
|
||||
* Settings for this helper.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $settings = array();
|
||||
|
||||
/**
|
||||
* 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', 'required', 'novalidate', 'formnovalidate'
|
||||
);
|
||||
|
||||
/**
|
||||
* 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 ($settings) {
|
||||
$this->settings = Hash::merge($this->settings, $settings);
|
||||
}
|
||||
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
|
||||
* @deprecated Accessing request properties through this method is deprecated and will be removed in 3.0.
|
||||
*/
|
||||
public function __get($name) {
|
||||
if (isset($this->_helperMap[$name]) && !isset($this->{$name})) {
|
||||
$settings = array('enabled' => false) + (array)$this->_helperMap[$name]['settings'];
|
||||
$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 Value to set.
|
||||
* @return void
|
||||
* @deprecated This method will be removed in 3.0
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
switch ($name) {
|
||||
case 'base':
|
||||
case 'here':
|
||||
case 'webroot':
|
||||
case 'data':
|
||||
$this->request->{$name} = $value;
|
||||
return;
|
||||
case 'action':
|
||||
$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 bool $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 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)) {
|
||||
return $this->url($path, !empty($options['fullBase']));
|
||||
}
|
||||
if (strpos($path, '://') !== false) {
|
||||
return $path;
|
||||
}
|
||||
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 (preg_match('|^([a-z0-9]+:)?//|', $path)) {
|
||||
return $path;
|
||||
}
|
||||
if (isset($plugin)) {
|
||||
$path = Inflector::underscore($plugin) . '/' . $path;
|
||||
}
|
||||
$path = $this->_encodeUrl($this->assetTimestamp($this->webroot($path)));
|
||||
|
||||
if (!empty($options['fullBase'])) {
|
||||
$path = rtrim(Router::fullBaseUrl(), '/') . '/' . ltrim($path, '/');
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a URL for use in HTML attributes.
|
||||
*
|
||||
* @param string $url The URL to encode.
|
||||
* @return string The URL encoded for both URL & HTML contexts.
|
||||
*/
|
||||
protected function _encodeUrl($url) {
|
||||
$path = parse_url($url, PHP_URL_PATH);
|
||||
$parts = array_map('rawurldecode', explode('/', $path));
|
||||
$parts = array_map('rawurlencode', $parts);
|
||||
$encoded = implode('/', $parts);
|
||||
return h(str_replace($path, $encoded, $url));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, '/') . '/',
|
||||
'',
|
||||
urldecode($path)
|
||||
);
|
||||
$webrootPath = WWW_ROOT . str_replace('/', DS, $filepath);
|
||||
if (file_exists($webrootPath)) {
|
||||
//@codingStandardsIgnoreStart
|
||||
return $path . '?' . @filemtime($webrootPath);
|
||||
//@codingStandardsIgnoreEnd
|
||||
}
|
||||
$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);
|
||||
//@codingStandardsIgnoreStart
|
||||
return $path . '?' . @filemtime($themePath);
|
||||
//@codingStandardsIgnoreEnd
|
||||
} else {
|
||||
$plugin = Inflector::camelize($segments[0]);
|
||||
if (CakePlugin::loaded($plugin)) {
|
||||
unset($segments[0]);
|
||||
$pluginPath = CakePlugin::path($plugin) . 'webroot' . DS . implode(DS, $segments);
|
||||
//@codingStandardsIgnoreStart
|
||||
return $path . '?' . @filemtime($pluginPath);
|
||||
//@codingStandardsIgnoreEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
* @deprecated This method will be removed in 3.0
|
||||
*/
|
||||
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 those listed in `Helper::$_minimizedAttributes`
|
||||
*
|
||||
* 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 bool $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) {
|
||||
if (is_array($value)) {
|
||||
$value = implode(' ', $value);
|
||||
}
|
||||
if (is_numeric($key)) {
|
||||
return sprintf($this->_minimizedAttributeFormat, $value, $value);
|
||||
}
|
||||
$truthy = array(1, '1', true, 'true', $key);
|
||||
$isMinimized = in_array($key, $this->_minimizedAttributes);
|
||||
if ($isMinimized && in_array($value, $truthy, true)) {
|
||||
return sprintf($this->_minimizedAttributeFormat, $key, $key);
|
||||
}
|
||||
if ($isMinimized) {
|
||||
return '';
|
||||
}
|
||||
return sprintf($this->_attributeFormat, $key, ($escape ? h($value) : $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string to be used as onclick handler for confirm dialogs.
|
||||
*
|
||||
* @param string $message Message to be displayed
|
||||
* @param string $okCode Code to be executed after user chose 'OK'
|
||||
* @param string $cancelCode Code to be executed after user chose 'Cancel'
|
||||
* @param array $options Array of options
|
||||
* @return string onclick JS code
|
||||
*/
|
||||
protected function _confirm($message, $okCode, $cancelCode = '', $options = array()) {
|
||||
$message = json_encode($message);
|
||||
$confirm = "if (confirm({$message})) { {$okCode} } {$cancelCode}";
|
||||
if (isset($options['escape']) && $options['escape'] === false) {
|
||||
$confirm = h($confirm);
|
||||
}
|
||||
return $confirm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 bool $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) ||
|
||||
(
|
||||
$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'
|
||||
);
|
||||
|
||||
// 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.
|
||||
*/
|
||||
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 . implode('', 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 Field name.
|
||||
* @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.
|
||||
*/
|
||||
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()) . ']';
|
||||
}
|
||||
|
||||
if (is_array($options)) {
|
||||
$options[$key] = $name;
|
||||
return $options;
|
||||
}
|
||||
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 Field name.
|
||||
* @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.
|
||||
*/
|
||||
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) && is_array($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;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the defaults for an input tag. Will set the
|
||||
* name, value, and id attributes for an array of html attributes.
|
||||
*
|
||||
* @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 class name 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 Data array or model name.
|
||||
* @param string $key Field name.
|
||||
* @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("&", "<", ">"), array("&amp;", "&lt;", "&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("&", "<", ">"), array("&amp;", "&lt;", "&gt;"), $this->_cleaned);
|
||||
}
|
||||
|
||||
}
|
||||
336
lib/Cake/View/Helper/CacheHelper.php
Normal file
336
lib/Cake/View/Helper/CacheHelper.php
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
<?php
|
||||
/**
|
||||
* CacheHelper helps create full page view caching.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 int
|
||||
*/
|
||||
protected $_counter = 0;
|
||||
|
||||
/**
|
||||
* Is CacheHelper enabled? should files + output be parsed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _enabled() {
|
||||
return $this->_View->cacheAction && (Configure::read('Cache.check') === true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the view file and stores content for cache file building.
|
||||
*
|
||||
* @param string $viewFile View file name.
|
||||
* @param string $output The output for the file.
|
||||
* @return string Updated content.
|
||||
*/
|
||||
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 Layout file name.
|
||||
* @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 output
|
||||
* @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 = $cacheAction[$index] + array('duration' => 0, 'callbacks' => false);
|
||||
} 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);
|
||||
try {
|
||||
$this->_writeFile($cached, $cacheTime, $useCallbacks);
|
||||
} catch (Exception $e) {
|
||||
$message = __d(
|
||||
'cake_dev',
|
||||
'Unable to write view cache file: "%s" for "%s"',
|
||||
$e->getMessage(),
|
||||
$this->request->here
|
||||
);
|
||||
$this->log($message, 'error');
|
||||
}
|
||||
$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 bool $useCallbacks Whether to include statements in cached file which
|
||||
* run callbacks.
|
||||
* @return bool 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';
|
||||
}
|
||||
$prefix = Configure::read('Cache.viewPrefix');
|
||||
if ($prefix) {
|
||||
$path = $prefix . '_' . $path;
|
||||
}
|
||||
$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->type(\'' . $this->_View->response->type() . '\');
|
||||
$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) {
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
3030
lib/Cake/View/Helper/FormHelper.php
Normal file
3030
lib/Cake/View/Helper/FormHelper.php
Normal file
File diff suppressed because it is too large
Load diff
1250
lib/Cake/View/Helper/HtmlHelper.php
Normal file
1250
lib/Cake/View/Helper/HtmlHelper.php
Normal file
File diff suppressed because it is too large
Load diff
360
lib/Cake/View/Helper/JqueryEngineHelper.php
Normal file
360
lib/Cake/View/Helper/JqueryEngineHelper.php
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
<?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.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 $this
|
||||
*/
|
||||
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 += $defaults;
|
||||
|
||||
$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 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 = html_entity_decode($this->url($url), ENT_COMPAT, Configure::read('App.encoding'));
|
||||
$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', 'xhr');
|
||||
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('isForm' => false, 'inline' => false);
|
||||
$selector = $this->selection;
|
||||
if (!$options['isForm']) {
|
||||
$selector = $this->selection . '.closest("form")';
|
||||
}
|
||||
$method = '.serialize()';
|
||||
if (!$options['inline']) {
|
||||
$method .= ';';
|
||||
}
|
||||
return $selector . $method;
|
||||
}
|
||||
|
||||
}
|
||||
592
lib/Cake/View/Helper/JsBaseEngineHelper.php
Normal file
592
lib/Cake/View/Helper/JsBaseEngineHelper.php
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 URL
|
||||
* @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 += $defaultOptions;
|
||||
|
||||
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 bool $quoteString If false, leaves string values unquoted
|
||||
* @param string $key Key name.
|
||||
* @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 . '"';
|
||||
}
|
||||
}
|
||||
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 implode(', ', $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;
|
||||
}
|
||||
|
||||
}
|
||||
436
lib/Cake/View/Helper/JsHelper.php
Normal file
436
lib/Cake/View/Helper/JsHelper.php
Normal file
|
|
@ -0,0 +1,436 @@
|
|||
<?php
|
||||
/**
|
||||
* Javascript Generator class file.
|
||||
*
|
||||
* CakePHP : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 bool
|
||||
*/
|
||||
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 string|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(, $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) && $out instanceof 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 bool $quoteString If false, leaves string values unquoted
|
||||
* @param string $key Key name.
|
||||
* @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 += $defaults;
|
||||
$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']) {
|
||||
$filename = md5($script);
|
||||
$path = WWW_ROOT . Configure::read('App.jsBaseUrl');
|
||||
if (file_exists($path . $filename . '.js')
|
||||
|| cache(str_replace(WWW_ROOT, '', $path) . $filename . '.js', $script, '+999 days', 'public')
|
||||
) {
|
||||
return $this->Html->script($filename);
|
||||
}
|
||||
}
|
||||
|
||||
$return = $this->Html->scriptBlock($script, $opts);
|
||||
if ($options['inline']) {
|
||||
return $return;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a script to the buffered scripts.
|
||||
*
|
||||
* @param string $script Script string to add to the buffer.
|
||||
* @param bool $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 bool $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 and adds to buffer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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 a CakePHP 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
376
lib/Cake/View/Helper/MootoolsEngineHelper.php
Normal file
376
lib/Cake/View/Helper/MootoolsEngineHelper.php
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 $this
|
||||
*/
|
||||
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 += $defaults;
|
||||
|
||||
$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 URL
|
||||
* @param array $options Options list.
|
||||
* @return string The completed ajax call.
|
||||
*/
|
||||
public function request($url, $options = array()) {
|
||||
$url = html_entity_decode($this->url($url), ENT_COMPAT, Configure::read('App.encoding'));
|
||||
$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'])) {
|
||||
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', '%s requires a "drag" option to properly function'), 'MootoolsEngine::drop()', 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('isForm' => false, 'inline' => false);
|
||||
$selection = $this->selection;
|
||||
if (!$options['isForm']) {
|
||||
$selection = '$(' . $this->selection . '.form)';
|
||||
}
|
||||
$method = '.toQueryString()';
|
||||
if (!$options['inline']) {
|
||||
$method .= ';';
|
||||
}
|
||||
return $selection . $method;
|
||||
}
|
||||
|
||||
}
|
||||
185
lib/Cake/View/Helper/NumberHelper.php
Normal file
185
lib/Cake/View/Helper/NumberHelper.php
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
/**
|
||||
* Number Helper.
|
||||
*
|
||||
* Methods to make numbers more readable.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('CakeNumber', 'Utility');
|
||||
App::uses('AppHelper', 'View/Helper');
|
||||
App::uses('Hash', 'Utility');
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @param string $method Method to call.
|
||||
* @param array $params Parameters to pass to method.
|
||||
* @return mixed Whatever is returned by called method, or false on failure
|
||||
*/
|
||||
public function __call($method, $params) {
|
||||
return call_user_func_array(array($this->_engine, $method), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number with a level of precision.
|
||||
*
|
||||
* @param float $number A floating point number.
|
||||
* @param int $precision The precision of the returned number.
|
||||
* @return float Formatted float.
|
||||
* @see CakeNumber::precision()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted-for-humans file size.
|
||||
*
|
||||
* @param int $size Size in bytes
|
||||
* @return string Human readable size
|
||||
* @see CakeNumber::toReadableSize()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
|
||||
*/
|
||||
public function toReadableSize($size) {
|
||||
return $this->_engine->toReadableSize($size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a percentage string.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `multiply`: Multiply the input value by 100 for decimal percentages.
|
||||
*
|
||||
* @param float $number A floating point number
|
||||
* @param int $precision The precision of the returned number
|
||||
* @param array $options Options
|
||||
* @return string Percentage string
|
||||
* @see CakeNumber::toPercentage()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage
|
||||
*/
|
||||
public function toPercentage($number, $precision = 2, $options = array()) {
|
||||
return $this->_engine->toPercentage($number, $precision, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a currency format.
|
||||
*
|
||||
* @param float $number A floating point number
|
||||
* @param int $options If integer then places, if string then before, if (,.-) then use it
|
||||
* or array with places and before keys
|
||||
* @return string formatted number
|
||||
* @see CakeNumber::format()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a currency format.
|
||||
*
|
||||
* @param float $number Number to format.
|
||||
* @param string $currency Shortcut to default options. Valid values are 'USD', 'EUR', 'GBP', otherwise
|
||||
* set at least 'before' and 'after' options.
|
||||
* 'USD' is the default currency, use CakeNumber::defaultCurrency() to change this default.
|
||||
* @param array $options Options list.
|
||||
* @return string Number formatted as a currency.
|
||||
* @see CakeNumber::currency()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
|
||||
*/
|
||||
public function currency($number, $currency = null, $options = array()) {
|
||||
return $this->_engine->currency($number, $currency, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a currency format to the Number helper. Makes reusing
|
||||
* currency formats easier.
|
||||
*
|
||||
* {{{ $this->Number->addFormat('NOK', array('before' => 'Kr. ')); }}}
|
||||
*
|
||||
* You can now use `NOK` as a shortform when formatting currency amounts.
|
||||
*
|
||||
* {{{ $this->Number->currency($value, 'NOK'); }}}
|
||||
*
|
||||
* Added formats are merged with the defaults defined in Cake\Utility\Number::$_currencyDefaults
|
||||
* See Cake\Utility\Number::currency() for more information on the various options and their function.
|
||||
*
|
||||
* @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 CakeNumber::addFormat()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter/setter for default currency
|
||||
*
|
||||
* @param string $currency The currency to be used in the future.
|
||||
* @return string Currency
|
||||
* @see CakeNumber::defaultCurrency()
|
||||
*/
|
||||
public function defaultCurrency($currency) {
|
||||
return $this->_engine->defaultCurrency($currency);
|
||||
}
|
||||
|
||||
}
|
||||
962
lib/Cake/View/Helper/PaginatorHelper.php
Normal file
962
lib/Cake/View/Helper/PaginatorHelper.php
Normal file
|
|
@ -0,0 +1,962 @@
|
|||
<?php
|
||||
/**
|
||||
* Pagination Helper class file.
|
||||
*
|
||||
* Generates pagination links
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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(
|
||||
__d('cake_dev', '%s does not implement a %s method, it is incompatible with %s', $classname, 'link()', 'PaginatorHelper')
|
||||
);
|
||||
}
|
||||
parent::__construct($View, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before render callback. Overridden to merge passed args with URL options.
|
||||
*
|
||||
* @param string $viewFile View file name.
|
||||
* @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];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience access to any of the paginator params.
|
||||
*
|
||||
* @param string $key Key of the paginator params array to retrieve.
|
||||
* @param string $model Optional model name. Uses the default if none is specified.
|
||||
* @return mixed Content of the requested param.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::params
|
||||
*/
|
||||
public function param($key, $model = null) {
|
||||
$params = $this->params($model);
|
||||
if (!isset($params[$key])) {
|
||||
return null;
|
||||
}
|
||||
return $params[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
* - `url` Allows sending routing parameters such as controllers, actions or passed arguments.
|
||||
* - `tag` The tag wrapping tag you want to use, defaults to 'span'. Set this to false to disable this option
|
||||
* - `escape` Whether you want the contents html entity encoded, defaults to true
|
||||
* - `model` The model to use, defaults to PaginatorHelper::defaultModel()
|
||||
* - `disabledTag` Tag to use instead of A tag when there is no previous page
|
||||
*
|
||||
* @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)$options + $defaults;
|
||||
return $this->_pagingLink('Prev', $title, $options, $disabledTitle, $disabledOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a "next" link for a set of paged records
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `url` Allows sending routing parameters such as controllers, actions or passed arguments.
|
||||
* - `tag` The tag wrapping tag you want to use, defaults to 'span'. Set this to false to disable this option
|
||||
* - `escape` Whether you want the contents html entity encoded, defaults to true
|
||||
* - `model` The model to use, defaults to PaginatorHelper::defaultModel()
|
||||
* - `disabledTag` Tag to use instead of A tag when there is no next page
|
||||
*
|
||||
* @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 $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)$options + $defaults;
|
||||
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.
|
||||
* - `lock` Lock direction. Will only use the default direction then, defaults to false.
|
||||
*
|
||||
* @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('url' => array(), 'model' => null);
|
||||
$url = $options['url'];
|
||||
unset($options['url']);
|
||||
|
||||
if (empty($title)) {
|
||||
$title = $key;
|
||||
|
||||
if (strpos($title, '.') !== false) {
|
||||
$title = str_replace('.', ' ', $title);
|
||||
}
|
||||
|
||||
$title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)));
|
||||
}
|
||||
$defaultDir = isset($options['direction']) ? $options['direction'] : 'asc';
|
||||
unset($options['direction']);
|
||||
|
||||
$locked = isset($options['lock']) ? $options['lock'] : false;
|
||||
unset($options['lock']);
|
||||
|
||||
$sortKey = $this->sortKey($options['model']);
|
||||
$defaultModel = $this->defaultModel();
|
||||
$isSorted = (
|
||||
$sortKey === $key ||
|
||||
$sortKey === $defaultModel . '.' . $key ||
|
||||
$key === $defaultModel . '.' . $sortKey
|
||||
);
|
||||
|
||||
$dir = $defaultDir;
|
||||
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 ($locked) {
|
||||
$dir = $defaultDir;
|
||||
$options['class'] .= ' locked';
|
||||
}
|
||||
}
|
||||
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('model' => null, 'escape' => true);
|
||||
$model = $options['model'];
|
||||
unset($options['model']);
|
||||
|
||||
if (!empty($this->options)) {
|
||||
$options += $this->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 bool $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 (!empty($url['page']) && $url['page'] == 1) {
|
||||
$url['page'] = null;
|
||||
}
|
||||
if (!empty($url['?']['page']) && $url['?']['page'] == 1) {
|
||||
unset($url['?']['page']);
|
||||
}
|
||||
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 Keys 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 Link type: 'Prev', 'Next'.
|
||||
* @param string $title Link title.
|
||||
* @param array $options Options list.
|
||||
* @param string $disabledTitle Disabled link title.
|
||||
* @param array $disabledOptions Disabled link options.
|
||||
* @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), 'disabledTag' => null
|
||||
);
|
||||
$options = (array)$options + $_defaults;
|
||||
$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)$disabledOptions + $_defaults;
|
||||
} elseif (!$this->{$check}($options['model'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (array_keys($_defaults) as $key) {
|
||||
${$key} = $options[$key];
|
||||
unset($options[$key]);
|
||||
}
|
||||
|
||||
if ($this->{$check}($model)) {
|
||||
$url = array_merge(
|
||||
array('page' => $paging['page'] + ($which === 'Prev' ? $step * -1 : $step)),
|
||||
$url
|
||||
);
|
||||
if ($tag === false) {
|
||||
return $this->link(
|
||||
$title,
|
||||
$url,
|
||||
compact('escape', 'model', 'class') + $options
|
||||
);
|
||||
}
|
||||
$link = $this->link($title, $url, compact('escape', 'model') + $options);
|
||||
return $this->Html->tag($tag, $link, compact('class'));
|
||||
}
|
||||
unset($options['rel']);
|
||||
if (!$tag) {
|
||||
if ($disabledTag) {
|
||||
$tag = $disabledTag;
|
||||
$disabledTag = null;
|
||||
} else {
|
||||
$tag = $_defaults['tag'];
|
||||
}
|
||||
}
|
||||
if ($disabledTag) {
|
||||
$title = $this->Html->tag($disabledTag, $title, compact('escape') + $options);
|
||||
return $this->Html->tag($tag, $title, compact('class'));
|
||||
}
|
||||
return $this->Html->tag($tag, $title, compact('escape', 'class') + $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 bool 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 bool 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 int $page The page number - if not set defaults to 1.
|
||||
* @return bool 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 int $page Page number you are checking.
|
||||
* @return bool Whether model has $page
|
||||
*/
|
||||
protected function _hasPage($model, $page) {
|
||||
$params = $this->params($model);
|
||||
return !empty($params) && $params[$page . 'Page'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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(
|
||||
'model' => $this->defaultModel(),
|
||||
'format' => 'pages',
|
||||
'separator' => __d('cake', ' of ')
|
||||
);
|
||||
|
||||
$paging = $this->params($options['model']);
|
||||
if (!$paging['pageCount']) {
|
||||
$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);
|
||||
}
|
||||
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'
|
||||
* - `currentTag` Tag to use for current page number, defaults to null
|
||||
*
|
||||
* @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', 'currentTag' => null
|
||||
);
|
||||
$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'], $options['currentTag']
|
||||
);
|
||||
|
||||
$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;
|
||||
}
|
||||
if ($currentTag) {
|
||||
$out .= $this->Html->tag($tag, $this->Html->tag($currentTag, $params['page']), array('class' => $currentClass));
|
||||
} else {
|
||||
$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;
|
||||
}
|
||||
if ($currentTag) {
|
||||
$out .= $this->Html->tag($tag, $this->Html->tag($currentTag, $i), array('class' => $currentClass));
|
||||
} else {
|
||||
$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|int $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)$options + array(
|
||||
'tag' => 'span',
|
||||
'after' => null,
|
||||
'model' => $this->defaultModel(),
|
||||
'separator' => ' | ',
|
||||
'ellipsis' => '...',
|
||||
'class' => null
|
||||
);
|
||||
|
||||
$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|int $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)$options + array(
|
||||
'tag' => 'span',
|
||||
'before' => null,
|
||||
'model' => $this->defaultModel(),
|
||||
'separator' => ' | ',
|
||||
'ellipsis' => '...',
|
||||
'class' => null
|
||||
);
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
}
|
||||
369
lib/Cake/View/Helper/PrototypeEngineHelper.php
Normal file
369
lib/Cake/View/Helper/PrototypeEngineHelper.php
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
<?php
|
||||
/**
|
||||
* Prototype Engine Helper for JsHelper
|
||||
*
|
||||
* Provides Prototype specific JavaScript for JsHelper. Requires at least
|
||||
* Prototype 1.6
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 bool
|
||||
*/
|
||||
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 $this
|
||||
*/
|
||||
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 += $defaults;
|
||||
|
||||
$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 URL.
|
||||
* @param array $options Options list.
|
||||
* @return string The completed ajax call.
|
||||
*/
|
||||
public function request($url, $options = array()) {
|
||||
$url = html_entity_decode($this->url($url), ENT_COMPAT, Configure::read('App.encoding'));
|
||||
$url = '"' . $url . '"';
|
||||
$options = $this->_mapOptions('request', $options);
|
||||
$type = '.Request';
|
||||
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('isForm' => false, 'inline' => false);
|
||||
$selection = $this->selection;
|
||||
if (!$options['isForm']) {
|
||||
$selection = '$(' . $this->selection . '.form)';
|
||||
}
|
||||
$method = '.serialize()';
|
||||
if (!$options['inline']) {
|
||||
$method .= ';';
|
||||
}
|
||||
return $selection . $method;
|
||||
}
|
||||
|
||||
}
|
||||
355
lib/Cake/View/Helper/RssHelper.php
Normal file
355
lib/Cake/View/Helper/RssHelper.php
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
<?php
|
||||
/**
|
||||
* RSS Helper class file.
|
||||
*
|
||||
* Simplifies the output of RSS feeds.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 Tag 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['link'])) {
|
||||
$elements['link'] = '/';
|
||||
}
|
||||
if (!isset($elements['title'])) {
|
||||
$elements['title'] = '';
|
||||
}
|
||||
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) {
|
||||
$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;
|
||||
default:
|
||||
$attrib = $att;
|
||||
}
|
||||
if ($val !== null && $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 int|string|DateTime $time UNIX timestamp or valid time string or DateTime object.
|
||||
* @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 bool $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';
|
||||
if (is_array($namespace)) {
|
||||
$xml .= ':' . $namespace['prefix'];
|
||||
$namespace = $namespace['url'];
|
||||
}
|
||||
$xml .= '="' . $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);
|
||||
if ($attrib) {
|
||||
foreach ($attrib as $key => $value) {
|
||||
$nodes->item(0)->setAttribute($key, $value);
|
||||
}
|
||||
}
|
||||
foreach ($children as $child) {
|
||||
$child = $elem->createElement($name, $child);
|
||||
$nodes->item(0)->appendChild($child);
|
||||
}
|
||||
|
||||
$xml = $elem->saveXml();
|
||||
$xml = trim(substr($xml, strpos($xml, '?>') + 2));
|
||||
return $xml;
|
||||
}
|
||||
|
||||
}
|
||||
162
lib/Cake/View/Helper/SessionHelper.php
Normal file
162
lib/Cake/View/Helper/SessionHelper.php
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
/**
|
||||
* Session Helper provides access to the Session in the Views.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 Session key to check.
|
||||
* @return bool
|
||||
* @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-notifications-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']) {
|
||||
$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 bool
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::valid
|
||||
*/
|
||||
public function valid() {
|
||||
return CakeSession::valid();
|
||||
}
|
||||
|
||||
}
|
||||
345
lib/Cake/View/Helper/TextHelper.php
Normal file
345
lib/Cake/View/Helper/TextHelper.php
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
/**
|
||||
* Text Helper
|
||||
*
|
||||
* Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('AppHelper', 'View/Helper');
|
||||
App::uses('Hash', 'Utility');
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @param string $method Method to call.
|
||||
* @param array $params Parameters to pass to method.
|
||||
* @return mixed Whatever is returned by called method, or false on failure
|
||||
*/
|
||||
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);
|
||||
|
||||
$pattern = '#(?<!href="|src="|">)((?:https?|ftp|nntp)://[\p{L}0-9.\-_:]+(?:[/?][^\s<]*)?)#ui';
|
||||
$text = preg_replace_callback(
|
||||
$pattern,
|
||||
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 = '[\p{L}0-9!#$%&\'*+\/=?^_`{|}~-]';
|
||||
$text = preg_replace_callback(
|
||||
'/(?<=\s|^|\(|\>|\;)(' . $atom . '*(?:\.' . $atom . '+)*@[\p{L}0-9-]+(?:\.[\p{L}0-9-]+)+)/ui',
|
||||
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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights a given phrase in a text. You can specify any expression in highlighter that
|
||||
* may include the \1 expression to include the $phrase found.
|
||||
*
|
||||
* @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
|
||||
* @see String::highlight()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats paragraphs around given text for all line breaks
|
||||
* <br /> added for single line return
|
||||
* <p> added for double line return
|
||||
*
|
||||
* @param string $text Text
|
||||
* @return string The text with proper <p> and <br /> tags
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoParagraph
|
||||
*/
|
||||
public function autoParagraph($text) {
|
||||
if (trim($text) !== '') {
|
||||
$text = preg_replace('|<br[^>]*>\s*<br[^>]*>|i', "\n\n", $text . "\n");
|
||||
$text = preg_replace("/\n\n+/", "\n\n", str_replace(array("\r\n", "\r"), "\n", $text));
|
||||
$texts = preg_split('/\n\s*\n/', $text, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$text = '';
|
||||
foreach ($texts as $txt) {
|
||||
$text .= '<p>' . nl2br(trim($txt, "\n")) . "</p>\n";
|
||||
}
|
||||
$text = preg_replace('|<p>\s*</p>|', '', $text);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips given text of all links (<a href=....)
|
||||
*
|
||||
* @param string $text Text
|
||||
* @return string The text without links
|
||||
* @see String::stripLinks()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
|
||||
*/
|
||||
public function stripLinks($text) {
|
||||
return $this->_engine->stripLinks($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates text.
|
||||
*
|
||||
* Cuts a string to the length of $length and replaces the last characters
|
||||
* with the ellipsis if the text is longer than length.
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `ellipsis` Will be used as Ending and appended to the trimmed string (`ending` is deprecated)
|
||||
* - `exact` If false, $text will not be cut mid-word
|
||||
* - `html` If true, HTML tags would be handled correctly
|
||||
*
|
||||
* @param string $text String to truncate.
|
||||
* @param int $length Length of returned string, including ellipsis.
|
||||
* @param array $options An array of html attributes and options.
|
||||
* @return string Trimmed string.
|
||||
* @see String::truncate()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates text starting from the end.
|
||||
*
|
||||
* Cuts a string to the length of $length and replaces the first characters
|
||||
* with the ellipsis if the text is longer than length.
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `ellipsis` Will be used as Beginning and prepended to the trimmed string
|
||||
* - `exact` If false, $text will not be cut mid-word
|
||||
*
|
||||
* @param string $text String to truncate.
|
||||
* @param int $length Length of returned string, including ellipsis.
|
||||
* @param array $options An array of html attributes and options.
|
||||
* @return string Trimmed string.
|
||||
* @see String::tail()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::tail
|
||||
*/
|
||||
public function tail($text, $length = 100, $options = array()) {
|
||||
return $this->_engine->tail($text, $length, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts an excerpt from the text surrounding the phrase with a number of characters on each side
|
||||
* determined by radius.
|
||||
*
|
||||
* @param string $text String to search the phrase in
|
||||
* @param string $phrase Phrase that will be searched for
|
||||
* @param int $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
|
||||
* @see String::excerpt()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a comma separated list where the last two items are joined with 'and', forming natural English
|
||||
*
|
||||
* @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.
|
||||
* @see String::toList()
|
||||
* @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);
|
||||
}
|
||||
|
||||
}
|
||||
500
lib/Cake/View/Helper/TimeHelper.php
Normal file
500
lib/Cake/View/Helper/TimeHelper.php
Normal file
|
|
@ -0,0 +1,500 @@
|
|||
<?php
|
||||
/**
|
||||
* Time Helper class file.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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
|
||||
*
|
||||
* @var stdClass
|
||||
*/
|
||||
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
|
||||
* @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 void
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
switch ($name) {
|
||||
case 'niceFormat':
|
||||
$this->_engine->{$name} = $value;
|
||||
break;
|
||||
default:
|
||||
$this->{$name} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic isset check for deprecated attributes.
|
||||
*
|
||||
* @param string $name Name of the attribute to check.
|
||||
* @return bool
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @param string $method Method to call.
|
||||
* @param array $params Parameters to pass to method.
|
||||
* @return mixed Whatever is returned by called method, or false on failure
|
||||
*/
|
||||
public function __call($method, $params) {
|
||||
return call_user_func_array(array($this->_engine, $method), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string representing the format for the function strftime and returns a
|
||||
* windows safe and i18n aware format.
|
||||
*
|
||||
* @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
|
||||
* @see CakeTime::convertSpecifiers()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts given time (in server's time zone) to user's local time, given his/her timezone.
|
||||
*
|
||||
* @param string $serverTime UNIX timestamp
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return int UNIX timestamp
|
||||
* @see CakeTime::convert()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns server's offset
|
||||
*
|
||||
* @return int Offset
|
||||
* @see CakeTime::serverOffset()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function serverOffset() {
|
||||
return $this->_engine->serverOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
|
||||
*
|
||||
* @param int|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
|
||||
* @see CakeTime::fromString()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a nicely formatted date string for given Datetime string.
|
||||
*
|
||||
* @param int|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, `CakeTime::$niceFormat` is used
|
||||
* @return string Formatted date string
|
||||
* @see CakeTime::nice()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted descriptive date string for given datetime string.
|
||||
*
|
||||
* @param int|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
|
||||
* @see CakeTime::niceShort()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a partial SQL string to search for all records between two dates.
|
||||
*
|
||||
* @param int|string|DateTime $begin UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param int|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.
|
||||
* @see CakeTime::daysAsSql()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a partial SQL string to search for all records between two times
|
||||
* occurring on the same day.
|
||||
*
|
||||
* @param int|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.
|
||||
* @see CakeTime::dayAsSql()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is today.
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool True if datetime string is today
|
||||
* @see CakeTime::isToday()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within this week.
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool True if datetime string is within current week
|
||||
* @see CakeTime::isThisWeek()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within this month
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool True if datetime string is within current month
|
||||
* @see CakeTime::isThisMonth()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within current year.
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool True if datetime string is within current year
|
||||
* @see CakeTime::isThisYear()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string was yesterday.
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool True if datetime string was yesterday
|
||||
* @see CakeTime::wasYesterday()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is tomorrow.
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool True if datetime string was yesterday
|
||||
* @see CakeTime::isTomorrow()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quarter
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param bool $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
|
||||
* @see CakeTime::toQuarter()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
|
||||
*
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return int Unix timestamp
|
||||
* @see CakeTime::toUnix()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a date formatted for Atom RSS feeds.
|
||||
*
|
||||
* @param int|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
|
||||
* @see CakeTime::toAtom()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats date for RSS feeds
|
||||
*
|
||||
* @param int|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
|
||||
* @see CakeTime::toRSS()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats date for RSS feeds
|
||||
*
|
||||
* ## 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 class name to use, defaults to `time-ago-in-words`.
|
||||
* - `title` - Defaults to the $dateTime input.
|
||||
*
|
||||
* @param int|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.
|
||||
* @see CakeTime::timeAgoInWords()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function timeAgoInWords($dateTime, $options = array()) {
|
||||
$element = null;
|
||||
|
||||
if (!empty($options['element'])) {
|
||||
$element = array(
|
||||
'tag' => 'span',
|
||||
'class' => 'time-ago-in-words',
|
||||
'title' => $dateTime
|
||||
);
|
||||
|
||||
if (is_array($options['element'])) {
|
||||
$element = $options['element'] + $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if specified datetime was within the interval specified, else false.
|
||||
*
|
||||
* @param string|int $timeInterval the numeric value with space then time type.
|
||||
* Example of valid types: 6 hours, 2 days, 1 minute.
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool
|
||||
* @see CakeTime::wasWithinLast()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if specified datetime is within the interval specified, else false.
|
||||
*
|
||||
* @param string|int $timeInterval the numeric value with space then time type.
|
||||
* Example of valid types: 6 hours, 2 days, 1 minute.
|
||||
* @param int|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return bool
|
||||
* @see CakeTime::isWithinLast()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gmt as a UNIX timestamp.
|
||||
*
|
||||
* @param int|string|DateTime $string UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @return int UNIX timestamp
|
||||
* @see CakeTime::gmt()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function gmt($string = null) {
|
||||
return $this->_engine->gmt($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
|
||||
* This function also accepts a time string and a format string as first and second parameters.
|
||||
* In that case this function behaves as a wrapper for TimeHelper::i18nFormat()
|
||||
*
|
||||
* ## Examples
|
||||
*
|
||||
* Create localized & formatted time:
|
||||
*
|
||||
* {{{
|
||||
* $this->Time->format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012
|
||||
* $this->Time->format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale
|
||||
* $this->Time->format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed
|
||||
* $this->Time->format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone
|
||||
* }}}
|
||||
*
|
||||
* @param int|string|DateTime $format date format string (or a UNIX timestamp, strtotime() valid string or DateTime object)
|
||||
* @param int|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string)
|
||||
* @param bool $invalid flag to ignore results of fromString == false
|
||||
* @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
|
||||
* @return string Formatted date string
|
||||
* @see CakeTime::format()
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
|
||||
* It takes into account the default date format for the current language if a LC_TIME file is used.
|
||||
*
|
||||
* @param int|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object
|
||||
* @param string $format strftime format string.
|
||||
* @param bool $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
|
||||
* @see CakeTime::i18nFormat()
|
||||
* @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);
|
||||
}
|
||||
|
||||
}
|
||||
203
lib/Cake/View/HelperCollection.php
Normal file
203
lib/Cake/View/HelperCollection.php
Normal file
|
|
@ -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 (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.View
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 View instance.
|
||||
*/
|
||||
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 bool whether 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 (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|CakeEvent $callback 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);
|
||||
}
|
||||
|
||||
}
|
||||
154
lib/Cake/View/JsonView.php
Normal file
154
lib/Cake/View/JsonView.php
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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 and layouts if you 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.
|
||||
*
|
||||
* You can also enable JSONP support by setting parameter `_jsonp` to true or a string to specify
|
||||
* custom query string paramater name which will contain the callback function name.
|
||||
*
|
||||
* @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
|
||||
* controllers' views.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $subDir = 'json';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Controller $controller Controller instance.
|
||||
*/
|
||||
public function __construct(Controller $controller = null) {
|
||||
parent::__construct($controller);
|
||||
if (isset($controller->response) && $controller->response instanceof CakeResponse) {
|
||||
$controller->response->type('json');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip loading helpers if this is a _serialize based view.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadHelpers() {
|
||||
if (isset($this->viewVars['_serialize'])) {
|
||||
return;
|
||||
}
|
||||
parent::loadHelpers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a JSON view.
|
||||
*
|
||||
* ### Special parameters
|
||||
* `_serialize` To convert a set of view variables into a JSON response.
|
||||
* Its value can be a string for single variable name or array for multiple names.
|
||||
* You can omit the`_serialize` parameter, and use a normal view + layout as well.
|
||||
* `_jsonp` Enables JSONP support and wraps response in callback function provided in query string.
|
||||
* - Setting it to true enables the default query string parameter "callback".
|
||||
* - Setting it to a string value, uses the provided query string parameter for finding the
|
||||
* JSONP callback name.
|
||||
*
|
||||
* @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) {
|
||||
$return = null;
|
||||
if (isset($this->viewVars['_serialize'])) {
|
||||
$return = $this->_serialize($this->viewVars['_serialize']);
|
||||
} elseif ($view !== false && $this->_getViewFileName($view)) {
|
||||
$return = parent::render($view, false);
|
||||
}
|
||||
|
||||
if (!empty($this->viewVars['_jsonp'])) {
|
||||
$jsonpParam = $this->viewVars['_jsonp'];
|
||||
if ($this->viewVars['_jsonp'] === true) {
|
||||
$jsonpParam = 'callback';
|
||||
}
|
||||
if (isset($this->request->query[$jsonpParam])) {
|
||||
$return = sprintf('%s(%s)', h($this->request->query[$jsonpParam]), $return);
|
||||
$this->response->type('js');
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize view vars
|
||||
*
|
||||
* @param array $serialize The viewVars that need to be serialized
|
||||
* @return string The serialized data
|
||||
*/
|
||||
protected function _serialize($serialize) {
|
||||
if (is_array($serialize)) {
|
||||
$data = array();
|
||||
foreach ($serialize as $alias => $key) {
|
||||
if (is_numeric($alias)) {
|
||||
$alias = $key;
|
||||
}
|
||||
if (array_key_exists($key, $this->viewVars)) {
|
||||
$data[$alias] = $this->viewVars[$key];
|
||||
}
|
||||
}
|
||||
$data = !empty($data) ? $data : null;
|
||||
} else {
|
||||
$data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null;
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=') && Configure::read('debug')) {
|
||||
return json_encode($data, JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
return json_encode($data);
|
||||
}
|
||||
|
||||
}
|
||||
99
lib/Cake/View/MediaView.php
Normal file
99
lib/Cake/View/MediaView.php
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* Methods to display or download any type of file
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
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.
|
||||
* - `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
|
||||
* @deprecated Deprecated since version 2.3, use CakeResponse::file() instead
|
||||
*/
|
||||
class MediaView extends View {
|
||||
|
||||
/**
|
||||
* Display or download the given file
|
||||
*
|
||||
* @param string $view Not used
|
||||
* @param string $layout Not used
|
||||
* @return void
|
||||
*/
|
||||
public function render($view = null, $layout = null) {
|
||||
$name = $download = $id = $modified = $path = $cache = $mimeType = $compress = null;
|
||||
extract($this->viewVars, EXTR_OVERWRITE);
|
||||
|
||||
$path = $path . $id;
|
||||
|
||||
if (is_array($mimeType)) {
|
||||
$this->response->type($mimeType);
|
||||
}
|
||||
|
||||
if ($cache) {
|
||||
if (!empty($modified) && !is_numeric($modified)) {
|
||||
$modified = strtotime($modified, time());
|
||||
} else {
|
||||
$modified = time();
|
||||
}
|
||||
$this->response->cache($modified, $cache);
|
||||
} else {
|
||||
$this->response->disableCache();
|
||||
}
|
||||
|
||||
if ($name !== null) {
|
||||
$name .= '.' . pathinfo($id, PATHINFO_EXTENSION);
|
||||
}
|
||||
$this->response->file($path, compact('name', 'download'));
|
||||
|
||||
if ($compress) {
|
||||
$this->response->compress();
|
||||
}
|
||||
$this->response->send();
|
||||
}
|
||||
|
||||
}
|
||||
91
lib/Cake/View/ScaffoldView.php
Normal file
91
lib/Cake/View/ScaffoldView.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
/**
|
||||
* Scaffold.
|
||||
*
|
||||
* Automatic forms and actions generation for rapid web application development.
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('View', 'View');
|
||||
|
||||
/**
|
||||
* ScaffoldView provides specific view file loading features for scaffolded views.
|
||||
*
|
||||
* @package Cake.View
|
||||
* @deprecated Dynamic scaffolding will be removed and replaced in 3.0
|
||||
*/
|
||||
class ScaffoldView extends View {
|
||||
|
||||
/**
|
||||
* 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 ($this->subDir !== null) {
|
||||
$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') {
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
55
lib/Cake/View/Scaffolds/form.ctp
Normal file
55
lib/Cake/View/Scaffolds/form.ctp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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)),
|
||||
array(),
|
||||
__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('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'index')
|
||||
) . "</li>\n";
|
||||
echo "\t\t<li>" . $this->Html->link(
|
||||
__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'add')
|
||||
) . "</li>\n";
|
||||
$done[] = $_details['controller'];
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
102
lib/Cake/View/Scaffolds/index.ctp
Normal file
102
lib/Cake/View/Scaffolds/index.ctp
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<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
|
||||
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]),
|
||||
array(),
|
||||
__d('cake', 'Are you sure you want to delete # %s?', ${$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>';
|
||||
echo $this->Html->link(
|
||||
__d('cake', 'List %s', Inflector::humanize($_details['controller'])),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'index')
|
||||
);
|
||||
echo '</li>';
|
||||
|
||||
echo '<li>';
|
||||
echo $this->Html->link(
|
||||
__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'add')
|
||||
);
|
||||
echo '</li>';
|
||||
$done[] = $_details['controller'];
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
194
lib/Cake/View/Scaffolds/view.ctp
Normal file
194
lib/Cake/View/Scaffolds/view.ctp
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<div class="<?php echo $pluralVar; ?> view">
|
||||
<h2><?php echo __d('cake', 'View %s', $singularHumanName); ?></h2>
|
||||
<dl>
|
||||
<?php
|
||||
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";
|
||||
echo $this->Html->link(
|
||||
${$singularVar}[$_alias][$_details['displayField']],
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])
|
||||
);
|
||||
echo "\n\t\t </dd>\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($isKey !== true) {
|
||||
echo "\t\t<dt>" . Inflector::humanize($_field) . "</dt>\n";
|
||||
echo "\t\t<dd>" . h(${$singularVar}[$modelClass][$_field]) . " </dd>\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<h3><?php echo __d('cake', 'Actions'); ?></h3>
|
||||
<ul>
|
||||
<?php
|
||||
echo "\t\t<li>";
|
||||
echo $this->Html->link(__d('cake', 'Edit %s', $singularHumanName), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey]));
|
||||
echo " </li>\n";
|
||||
|
||||
echo "\t\t<li>";
|
||||
echo $this->Form->postLink(__d('cake', 'Delete %s', $singularHumanName), array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]), array(), __d('cake', 'Are you sure you want to delete # %s?', ${$singularVar}[$modelClass][$primaryKey]));
|
||||
echo " </li>\n";
|
||||
|
||||
echo "\t\t<li>";
|
||||
echo $this->Html->link(__d('cake', 'List %s', $pluralHumanName), array('action' => 'index'));
|
||||
echo " </li>\n";
|
||||
|
||||
echo "\t\t<li>";
|
||||
echo $this->Html->link(__d('cake', 'New %s', $singularHumanName), array('action' => 'add'));
|
||||
echo " </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>";
|
||||
echo $this->Html->link(
|
||||
__d('cake', 'List %s', Inflector::humanize($_details['controller'])),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'index')
|
||||
);
|
||||
echo "</li>\n";
|
||||
echo "\t\t<li>";
|
||||
echo $this->Html->link(
|
||||
__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'add')
|
||||
);
|
||||
echo "</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
|
||||
$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 </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('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'edit', ${$singularVar}[$_alias][$_details['primaryKey']])
|
||||
);
|
||||
echo "</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";
|
||||
echo $this->Html->link(
|
||||
__d('cake', 'View'),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'view', ${$otherSingularVar}[$_details['primaryKey']])
|
||||
);
|
||||
echo "\n";
|
||||
echo "\t\t\t\t";
|
||||
echo $this->Html->link(
|
||||
__d('cake', 'Edit'),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'edit', ${$otherSingularVar}[$_details['primaryKey']])
|
||||
);
|
||||
echo "\n";
|
||||
echo "\t\t\t\t";
|
||||
echo $this->Form->postLink(
|
||||
__d('cake', 'Delete'),
|
||||
array('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'delete', ${$otherSingularVar}[$_details['primaryKey']]),
|
||||
array(),
|
||||
__d('cake', 'Are you sure you want to delete # %s?', ${$otherSingularVar}[$_details['primaryKey']])
|
||||
);
|
||||
echo "\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('plugin' => $_details['plugin'], 'controller' => $_details['controller'], 'action' => 'add')
|
||||
); ?> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
31
lib/Cake/View/ThemeView.php
Normal file
31
lib/Cake/View/ThemeView.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/**
|
||||
* A custom view class that is used for themeing
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) 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 http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('View', 'View');
|
||||
|
||||
/**
|
||||
* Theme view class
|
||||
*
|
||||
* Stub class for 2.1 Compatibility
|
||||
*
|
||||
* @package Cake.View
|
||||
* @deprecated Deprecated since 2.1, use View class instead
|
||||
*/
|
||||
class ThemeView extends View {
|
||||
|
||||
}
|
||||
1226
lib/Cake/View/View.php
Normal file
1226
lib/Cake/View/View.php
Normal file
File diff suppressed because it is too large
Load diff
226
lib/Cake/View/ViewBlock.php
Normal file
226
lib/Cake/View/ViewBlock.php
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v2.1
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Append content
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const APPEND = 'append';
|
||||
|
||||
/**
|
||||
* Prepend content
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PREPEND = 'prepend';
|
||||
|
||||
/**
|
||||
* Block content. An array of blocks indexed by name.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_blocks = array();
|
||||
|
||||
/**
|
||||
* The active blocks being captured.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_active = array();
|
||||
|
||||
/**
|
||||
* Should the currently captured content be discarded on ViewBlock::end()
|
||||
*
|
||||
* @var bool
|
||||
* @see ViewBlock::end()
|
||||
* @see ViewBlock::startIfEmpty()
|
||||
*/
|
||||
protected $_discardActiveBufferOnEnd = false;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @throws CakeException When starting a block twice
|
||||
* @return void
|
||||
*/
|
||||
public function start($name) {
|
||||
if (in_array($name, $this->_active)) {
|
||||
throw new CakeException(__("A view block with the name '%s' is already/still open.", $name));
|
||||
}
|
||||
$this->_active[] = $name;
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start capturing output for a 'block' if it is empty
|
||||
*
|
||||
* 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 startIfEmpty($name) {
|
||||
if (empty($this->_blocks[$name])) {
|
||||
return $this->start($name);
|
||||
}
|
||||
$this->_discardActiveBufferOnEnd = true;
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* End a capturing block. The compliment to ViewBlock::start()
|
||||
*
|
||||
* @return void
|
||||
* @see ViewBlock::start()
|
||||
*/
|
||||
public function end() {
|
||||
if ($this->_discardActiveBufferOnEnd) {
|
||||
$this->_discardActiveBufferOnEnd = false;
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concat content to an existing or new block.
|
||||
* Concating to a new block will create the block.
|
||||
*
|
||||
* Calling concat() 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 mixed $value The content for the block
|
||||
* @param string $mode If ViewBlock::APPEND content will be appended to existing content.
|
||||
* If ViewBlock::PREPEND it will be prepended.
|
||||
* @return void
|
||||
*/
|
||||
public function concat($name, $value = null, $mode = ViewBlock::APPEND) {
|
||||
if (isset($value)) {
|
||||
if (!isset($this->_blocks[$name])) {
|
||||
$this->_blocks[$name] = '';
|
||||
}
|
||||
if ($mode === ViewBlock::PREPEND) {
|
||||
$this->_blocks[$name] = $value . $this->_blocks[$name];
|
||||
} else {
|
||||
$this->_blocks[$name] .= $value;
|
||||
}
|
||||
} else {
|
||||
$this->start($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @deprecated As of 2.3 use ViewBlock::concat() instead.
|
||||
*/
|
||||
public function append($name, $value = null) {
|
||||
$this->concat($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content for a block. This will overwrite any
|
||||
* existing content.
|
||||
*
|
||||
* @param string $name Name of the block
|
||||
* @param mixed $value The content for the block.
|
||||
* @return void
|
||||
*/
|
||||
public function set($name, $value) {
|
||||
$this->_blocks[$name] = (string)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content for a block.
|
||||
*
|
||||
* @param string $name Name of the block
|
||||
* @param string $default Default string
|
||||
* @return string The block content or $default if the block does not exist.
|
||||
*/
|
||||
public function get($name, $default = '') {
|
||||
if (!isset($this->_blocks[$name])) {
|
||||
return $default;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
141
lib/Cake/View/XmlView.php
Normal file
141
lib/Cake/View/XmlView.php
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
/**
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('View', 'View');
|
||||
App::uses('Xml', 'Utility');
|
||||
App::uses('Hash', '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 Controller instance.
|
||||
*/
|
||||
public function __construct(Controller $controller = null) {
|
||||
parent::__construct($controller);
|
||||
|
||||
if (isset($controller->response) && $controller->response instanceof CakeResponse) {
|
||||
$controller->response->type('xml');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip loading helpers if this is a _serialize based view.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadHelpers() {
|
||||
if (isset($this->viewVars['_serialize'])) {
|
||||
return;
|
||||
}
|
||||
parent::loadHelpers();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'])) {
|
||||
return $this->_serialize($this->viewVars['_serialize']);
|
||||
}
|
||||
if ($view !== false && $this->_getViewFileName($view)) {
|
||||
return parent::render($view, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize view vars.
|
||||
*
|
||||
* @param array $serialize The viewVars that need to be serialized.
|
||||
* @return string The serialized data
|
||||
*/
|
||||
protected function _serialize($serialize) {
|
||||
$rootNode = isset($this->viewVars['_rootNode']) ? $this->viewVars['_rootNode'] : 'response';
|
||||
|
||||
if (is_array($serialize)) {
|
||||
$data = array($rootNode => array());
|
||||
foreach ($serialize as $alias => $key) {
|
||||
if (is_numeric($alias)) {
|
||||
$alias = $key;
|
||||
}
|
||||
$data[$rootNode][$alias] = $this->viewVars[$key];
|
||||
}
|
||||
} else {
|
||||
$data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null;
|
||||
if (is_array($data) && Hash::numeric(array_keys($data))) {
|
||||
$data = array($rootNode => array($serialize => $data));
|
||||
}
|
||||
}
|
||||
|
||||
$options = array();
|
||||
if (Configure::read('debug')) {
|
||||
$options['pretty'] = true;
|
||||
}
|
||||
|
||||
return Xml::fromArray($data, $options)->asXML();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue