mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge branch '2.1' of https://github.com/cakephp/cakephp into 2.1-cookie-response
This commit is contained in:
commit
574b5dcd41
63 changed files with 4433 additions and 2500 deletions
|
@ -23,7 +23,66 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
// Setup a 'default' cache configuration for use in the application.
|
||||
/**
|
||||
* Cache Engine Configuration
|
||||
* Default settings provided below
|
||||
*
|
||||
* File storage engine.
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'File', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
|
||||
* 'prefix' => 'cake_', //[optional] prefix every cache file with this string
|
||||
* 'lock' => false, //[optional] use file locking
|
||||
* 'serialize' => true, // [optional]
|
||||
* 'mask' => 0666, // [optional] permission mask to use when creating cache files
|
||||
* ));
|
||||
*
|
||||
* APC (http://pecl.php.net/package/APC)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Apc', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* ));
|
||||
*
|
||||
* Xcache (http://xcache.lighttpd.net/)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Xcache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'user' => 'user', //user from xcache.admin.user settings
|
||||
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
||||
* ));
|
||||
*
|
||||
* Memcache (http://memcached.org/)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Memcache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'servers' => array(
|
||||
* '127.0.0.1:11211' // localhost, default port 11211
|
||||
* ), //[optional]
|
||||
* 'persistent' => true, // [optional] set this to false for non-persistent connections
|
||||
* 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
|
||||
* ));
|
||||
*
|
||||
* Wincache (http://php.net/wincache)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Wincache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* ));
|
||||
*/
|
||||
Cache::config('default', array('engine' => 'File'));
|
||||
|
||||
/**
|
||||
|
|
|
@ -231,71 +231,13 @@
|
|||
*/
|
||||
//date_default_timezone_set('UTC');
|
||||
|
||||
/**
|
||||
*
|
||||
* Cache Engine Configuration
|
||||
* Default settings provided below
|
||||
*
|
||||
* File storage engine.
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'File', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
|
||||
* 'prefix' => 'cake_', //[optional] prefix every cache file with this string
|
||||
* 'lock' => false, //[optional] use file locking
|
||||
* 'serialize' => true, [optional]
|
||||
* ));
|
||||
*
|
||||
* APC (http://pecl.php.net/package/APC)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Apc', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* ));
|
||||
*
|
||||
* Xcache (http://xcache.lighttpd.net/)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Xcache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'user' => 'user', //user from xcache.admin.user settings
|
||||
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
||||
* ));
|
||||
*
|
||||
* Memcache (http://memcached.org/)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Memcache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'servers' => array(
|
||||
* '127.0.0.1:11211' // localhost, default port 11211
|
||||
* ), //[optional]
|
||||
* 'persistent' => true, // [optional] set this to false for non-persistent connections
|
||||
* 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
|
||||
* ));
|
||||
*
|
||||
* Wincache (http://php.net/wincache)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Wincache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* ));
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pick the caching engine to use. If APC is enabled use it.
|
||||
* If running via cli - apc is disabled by default. ensure it's available and enabled in this case
|
||||
*
|
||||
* Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
|
||||
* Please check the comments in boostrap.php for more info on the cache engines available
|
||||
* and their setttings.
|
||||
*/
|
||||
$engine = 'File';
|
||||
if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
|
||||
|
|
|
@ -121,9 +121,9 @@ if (isset($filePresent)):
|
|||
App::uses('Validation', 'Utility');
|
||||
if (!Validation::alphaNumeric('cakephp')) {
|
||||
echo '<p><span class="notice">';
|
||||
__d('cake_dev', 'PCRE has not been compiled with Unicode support.');
|
||||
echo '<br/>';
|
||||
__d('cake_dev', 'Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
|
||||
echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.');
|
||||
echo '<br/>';
|
||||
echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
|
||||
echo '</span></p>';
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -126,7 +126,7 @@ class ControllerTask extends BakeTask {
|
|||
protected function _interactive() {
|
||||
$this->interactive = true;
|
||||
$this->hr();
|
||||
$this->out(__d('cake_console', "Bake Controller\nPath: %s", $this->path));
|
||||
$this->out(__d('cake_console', "Bake Controller\nPath: %s", $this->getPath()));
|
||||
$this->hr();
|
||||
|
||||
if (empty($this->connection)) {
|
||||
|
|
|
@ -70,12 +70,19 @@ class ExtractTask extends AppShell {
|
|||
protected $_tokens = array();
|
||||
|
||||
/**
|
||||
* Extracted strings
|
||||
* Extracted strings indexed by domain.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_strings = array();
|
||||
|
||||
/**
|
||||
* Singular strings and their line numbers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_lines = array();
|
||||
|
||||
/**
|
||||
* Destination path
|
||||
*
|
||||
|
@ -325,8 +332,10 @@ class ExtractTask extends AppShell {
|
|||
if ($mapCount == count($strings)) {
|
||||
extract(array_combine($map, $strings));
|
||||
$domain = isset($domain) ? $domain : 'default';
|
||||
|
||||
$string = isset($plural) ? $singular . "\0" . $plural : $singular;
|
||||
$this->_strings[$domain][$string][$this->_file][] = $line;
|
||||
$this->_strings[$domain][] = $string;
|
||||
$this->_lines[$domain][$singular][$this->_file][] = $line;
|
||||
} else {
|
||||
$this->_markerError($this->_file, $line, $functionName, $count);
|
||||
}
|
||||
|
@ -406,7 +415,8 @@ class ExtractTask extends AppShell {
|
|||
$message = $rule;
|
||||
}
|
||||
if ($message) {
|
||||
$this->_strings[$domain][$message][$file][] = 'validation for field ' . $field;
|
||||
$this->_strings[$domain][] = $message;
|
||||
$this->_lines[$domain][$message][$file][] = 'validation for field ' . $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +429,16 @@ class ExtractTask extends AppShell {
|
|||
*/
|
||||
protected function _buildFiles() {
|
||||
foreach ($this->_strings as $domain => $strings) {
|
||||
foreach ($strings as $string => $files) {
|
||||
$added = array();
|
||||
rsort($strings);
|
||||
|
||||
foreach ($strings as $i => $string) {
|
||||
$plural = false;
|
||||
$singular = $string;
|
||||
if (strpos($string, "\0") !== false) {
|
||||
list($singular, $plural) = explode("\0", $string);
|
||||
}
|
||||
$files = $this->_lines[$domain][$singular];
|
||||
$occurrences = array();
|
||||
foreach ($files as $file => $lines) {
|
||||
$occurrences[] = $file . ':' . implode(';', $lines);
|
||||
|
@ -427,17 +446,21 @@ class ExtractTask extends AppShell {
|
|||
$occurrences = implode("\n#: ", $occurrences);
|
||||
$header = '#: ' . str_replace($this->_paths, '', $occurrences) . "\n";
|
||||
|
||||
if (strpos($string, "\0") === false) {
|
||||
if ($plural === false && !empty($added[$singular])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($plural === false) {
|
||||
$sentence = "msgid \"{$string}\"\n";
|
||||
$sentence .= "msgstr \"\"\n\n";
|
||||
} else {
|
||||
list($singular, $plural) = explode("\0", $string);
|
||||
$sentence = "msgid \"{$singular}\"\n";
|
||||
$sentence .= "msgid_plural \"{$plural}\"\n";
|
||||
$sentence .= "msgstr[0] \"\"\n";
|
||||
$sentence .= "msgstr[1] \"\"\n\n";
|
||||
}
|
||||
|
||||
$added[$singular] = true;
|
||||
$this->_store($domain, $header, $sentence);
|
||||
if ($domain != 'default' && $this->_merge) {
|
||||
$this->_store('default', $header, $sentence);
|
||||
|
|
|
@ -137,7 +137,7 @@ class FixtureTask extends BakeTask {
|
|||
protected function _interactive() {
|
||||
$this->DbConfig->interactive = $this->Model->interactive = $this->interactive = true;
|
||||
$this->hr();
|
||||
$this->out(__d('cake_console', "Bake Fixture\nPath: %s", $this->path));
|
||||
$this->out(__d('cake_console', "Bake Fixture\nPath: %s", $this->getPath()));
|
||||
$this->hr();
|
||||
|
||||
if (!isset($this->connection)) {
|
||||
|
|
|
@ -190,7 +190,7 @@ class ModelTask extends BakeTask {
|
|||
*/
|
||||
protected function _interactive() {
|
||||
$this->hr();
|
||||
$this->out(__d('cake_console', "Bake Model\nPath: %s", $this->path));
|
||||
$this->out(__d('cake_console', "Bake Model\nPath: %s", $this->getPath()));
|
||||
$this->hr();
|
||||
$this->interactive = true;
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ class TestTask extends BakeTask {
|
|||
$this->interactive = true;
|
||||
$this->hr();
|
||||
$this->out(__d('cake_console', 'Bake Tests'));
|
||||
$this->out(__d('cake_console', 'Path: %s', $this->path));
|
||||
$this->out(__d('cake_console', 'Path: %s', $this->getPath()));
|
||||
$this->hr();
|
||||
|
||||
if ($type) {
|
||||
|
|
|
@ -195,7 +195,7 @@ class ViewTask extends BakeTask {
|
|||
*/
|
||||
protected function _interactive() {
|
||||
$this->hr();
|
||||
$this->out(sprintf("Bake View\nPath: %s", $this->path));
|
||||
$this->out(sprintf("Bake View\nPath: %s", $this->getPath()));
|
||||
$this->hr();
|
||||
|
||||
$this->DbConfig->interactive = $this->Controller->interactive = $this->interactive = true;
|
||||
|
|
|
@ -108,11 +108,13 @@ abstract class BaseAuthorize {
|
|||
*/
|
||||
public function action($request, $path = '/:plugin/:controller/:action') {
|
||||
$plugin = empty($request['plugin']) ? null : Inflector::camelize($request['plugin']) . '/';
|
||||
return str_replace(
|
||||
$path = str_replace(
|
||||
array(':controller', ':action', ':plugin/'),
|
||||
array(Inflector::camelize($request['controller']), $request['action'], $plugin),
|
||||
$this->settings['actionPath'] . $path
|
||||
);
|
||||
$path = str_replace('//', '/', $path);
|
||||
return trim($path, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -495,7 +495,8 @@ class CookieComponent extends Component {
|
|||
* @return array Map of key and values
|
||||
*/
|
||||
protected function _explode($string) {
|
||||
if ($string[0] === '{' || $string[0] === '[') {
|
||||
$first = substr($string, 0, 1);
|
||||
if ($first === '{' || $first === '[') {
|
||||
$ret = json_decode($string, true);
|
||||
return ($ret != null) ? $ret : $string;
|
||||
}
|
||||
|
|
|
@ -160,7 +160,10 @@ class RequestHandlerComponent extends Component {
|
|||
* switched based on the parsed extension or Accept-Type header. For example, if `controller/action.xml`
|
||||
* is requested, the view path becomes `app/View/Controller/xml/action.ctp`. Also if
|
||||
* `controller/action` is requested with `Accept-Type: application/xml` in the headers
|
||||
* the view path will become `app/View/Controller/xml/action.ctp`.
|
||||
* the view path will become `app/View/Controller/xml/action.ctp`. Layout and template
|
||||
* types will only switch to mime-types recognized by CakeResponse. If you need to declare
|
||||
* additional mime-types, you can do so using CakeResponse::type() in your controllers beforeFilter()
|
||||
* method.
|
||||
* - If a helper with the same name as the extension exists, it is added to the controller.
|
||||
* - If the extension is of a type that RequestHandler understands, it will set that
|
||||
* Content-type in the response header.
|
||||
|
|
|
@ -860,7 +860,7 @@ class App {
|
|||
),
|
||||
'Vendor' => array(
|
||||
'%s' . 'Vendor' . DS,
|
||||
VENDORS
|
||||
dirname(dirname(CAKE)) . DS . 'vendors' . DS,
|
||||
),
|
||||
'Plugin' => array(
|
||||
APP . 'Plugin' . DS,
|
||||
|
|
|
@ -217,6 +217,7 @@ class ErrorHandler {
|
|||
$log = LOG_NOTICE;
|
||||
break;
|
||||
case E_DEPRECATED:
|
||||
case E_USER_DEPRECATED:
|
||||
$error = 'Deprecated';
|
||||
$log = LOG_NOTICE;
|
||||
break;
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('AppModel', 'Model');
|
||||
App::uses('Model', 'Model');
|
||||
|
||||
/**
|
||||
* ACL Node
|
||||
*
|
||||
* @package Cake.Model
|
||||
*/
|
||||
class AclNode extends AppModel {
|
||||
class AclNode extends Model {
|
||||
|
||||
/**
|
||||
* Explicitly disable in-memory query caching for ACL models
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('AppModel', 'Model');
|
||||
App::uses('AclNode', 'Model');
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('AppModel', 'Model');
|
||||
App::uses('AclNode', 'Model');
|
||||
|
||||
/**
|
||||
|
|
|
@ -745,7 +745,7 @@ class Sqlserver extends DboSource {
|
|||
*/
|
||||
protected function _execute($sql, $params = array(), $prepareOptions = array()) {
|
||||
$this->_lastAffected = false;
|
||||
if (strncasecmp($sql, 'SELECT', 6) == 0) {
|
||||
if (strncasecmp($sql, 'SELECT', 6) == 0 || preg_match('/^EXEC(?:UTE)?\s/mi', $sql) > 0) {
|
||||
$prepareOptions += array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL);
|
||||
return parent::_execute($sql, $params, $prepareOptions);
|
||||
}
|
||||
|
|
|
@ -1966,7 +1966,15 @@ class Model extends Object implements CakeEventListener {
|
|||
* or 'only' to only validate the records, but not save them.
|
||||
* - atomic: If true (default), will attempt to save all records in a single transaction.
|
||||
* Should be set to false if database/table does not support transactions.
|
||||
* - fieldList: Equivalent to the $fieldList parameter in Model::save()
|
||||
* - fieldList: Equivalent to the $fieldList parameter in Model::save().
|
||||
* It should be an associate array with model name as key and array of fields as value. Eg.
|
||||
* {{{
|
||||
* array(
|
||||
* 'SomeModel' => array('field'),
|
||||
* 'AssociatedModel' => array('field', 'otherfield')
|
||||
* )
|
||||
* }}}
|
||||
* - deep: see saveMany/saveAssociated
|
||||
*
|
||||
* @param array $data Record data to save. This can be either a numerically-indexed array (for saving multiple
|
||||
* records of the same type), or an array indexed by association name.
|
||||
|
@ -1986,11 +1994,7 @@ class Model extends Object implements CakeEventListener {
|
|||
return $this->saveMany($data, $options);
|
||||
}
|
||||
if ($options['validate'] === 'only') {
|
||||
$validatesAssoc = $this->validateAssociated($data, $options);
|
||||
if (isset($this->validationErrors[$this->alias]) && $this->validationErrors[$this->alias] === false) {
|
||||
return false;
|
||||
}
|
||||
return $validatesAssoc;
|
||||
return $this->validateAssociated($data, $options);
|
||||
}
|
||||
return $this->saveAssociated($data, $options);
|
||||
}
|
||||
|
@ -2005,6 +2009,7 @@ class Model extends Object implements CakeEventListener {
|
|||
* - atomic: If true (default), will attempt to save all records in a single transaction.
|
||||
* Should be set to false if database/table does not support transactions.
|
||||
* - fieldList: Equivalent to the $fieldList parameter in Model::save()
|
||||
* - deep: If set to true, all associated data will be saved as well.
|
||||
*
|
||||
* @param array $data Record data to save. This should be a numerically-indexed array
|
||||
* @param array $options Options to use when saving record data, See $options above.
|
||||
|
@ -2018,7 +2023,7 @@ class Model extends Object implements CakeEventListener {
|
|||
$data = $this->data;
|
||||
}
|
||||
|
||||
$options = array_merge(array('validate' => 'first', 'atomic' => true), $options);
|
||||
$options = array_merge(array('validate' => 'first', 'atomic' => true, 'deep' => false), $options);
|
||||
$this->validationErrors = $validationErrors = array();
|
||||
|
||||
if (empty($data) && $options['validate'] !== false) {
|
||||
|
@ -2039,12 +2044,21 @@ class Model extends Object implements CakeEventListener {
|
|||
}
|
||||
$return = array();
|
||||
foreach ($data as $key => $record) {
|
||||
$validates = ($this->create(null) !== null && $this->save($record, $options));
|
||||
$validates = $this->create(null) !== null;
|
||||
$saved = false;
|
||||
if ($validates) {
|
||||
if ($options['deep']) {
|
||||
$saved = $this->saveAssociated($record, array_merge($options, array('atomic' => false)));
|
||||
} else {
|
||||
$saved = $this->save($record, $options);
|
||||
}
|
||||
}
|
||||
$validates = ($validates && ($saved === true || (is_array($saved) && !in_array(false, $saved, true))));
|
||||
if (!$validates) {
|
||||
$validationErrors[$key] = $this->validationErrors;
|
||||
}
|
||||
if (!$options['atomic']) {
|
||||
$return[] = $validates;
|
||||
$return[$key] = $validates;
|
||||
} elseif (!$validates) {
|
||||
break;
|
||||
}
|
||||
|
@ -2072,6 +2086,7 @@ class Model extends Object implements CakeEventListener {
|
|||
*
|
||||
* - atomic: If true (default), returns boolean. If false returns array.
|
||||
* - fieldList: Equivalent to the $fieldList parameter in Model::save()
|
||||
* - deep: If set to true, all associated data will be validated as well.
|
||||
*
|
||||
* @param array $data Record data to validate. This should be a numerically-indexed array
|
||||
* @param array $options Options to use when validating record data (see above), See also $options of validates().
|
||||
|
@ -2081,14 +2096,21 @@ class Model extends Object implements CakeEventListener {
|
|||
* depending on whether each record validated successfully.
|
||||
*/
|
||||
public function validateMany($data, $options = array()) {
|
||||
$options = array_merge(array('atomic' => true), $options);
|
||||
$options = array_merge(array('atomic' => true, 'deep' => false), $options);
|
||||
$this->validationErrors = $validationErrors = $return = array();
|
||||
foreach ($data as $key => $record) {
|
||||
$validates = $this->create($record) && $this->validates($options);
|
||||
if (!$validates) {
|
||||
$validationErrors[$key] = $this->validationErrors;
|
||||
if ($options['deep']) {
|
||||
$validates = $this->validateAssociated($record, $options);
|
||||
} else {
|
||||
$validates = $this->create($record) && $this->validates($options);
|
||||
}
|
||||
$return[] = $validates;
|
||||
if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) {
|
||||
$validationErrors[$key] = $this->validationErrors;
|
||||
$validates = false;
|
||||
} else {
|
||||
$validates = true;
|
||||
}
|
||||
$return[$key] = $validates;
|
||||
}
|
||||
$this->validationErrors = $validationErrors;
|
||||
if (!$options['atomic']) {
|
||||
|
@ -2109,7 +2131,15 @@ class Model extends Object implements CakeEventListener {
|
|||
* 'first' to validate *all* records before any are saved(default),
|
||||
* - `atomic` If true (default), will attempt to save all records in a single transaction.
|
||||
* Should be set to false if database/table does not support transactions.
|
||||
* - `fieldList` Equivalent to the $fieldList parameter in Model::save()
|
||||
* - fieldList: Equivalent to the $fieldList parameter in Model::save().
|
||||
* It should be an associate array with model name as key and array of fields as value. Eg.
|
||||
* {{{
|
||||
* array(
|
||||
* 'SomeModel' => array('field'),
|
||||
* 'AssociatedModel' => array('field', 'otherfield')
|
||||
* )
|
||||
* }}}
|
||||
* - deep: If set to true, not only directly associated data is saved, but deeper nested associated data as well.
|
||||
*
|
||||
* @param array $data Record data to save. This should be an array indexed by association name.
|
||||
* @param array $options Options to use when saving record data, See $options above.
|
||||
|
@ -2123,7 +2153,7 @@ class Model extends Object implements CakeEventListener {
|
|||
$data = $this->data;
|
||||
}
|
||||
|
||||
$options = array_merge(array('validate' => 'first', 'atomic' => true), $options);
|
||||
$options = array_merge(array('validate' => 'first', 'atomic' => true, 'deep' => false), $options);
|
||||
$this->validationErrors = $validationErrors = array();
|
||||
|
||||
if (empty($data) && $options['validate'] !== false) {
|
||||
|
@ -2146,13 +2176,26 @@ class Model extends Object implements CakeEventListener {
|
|||
$validates = true;
|
||||
foreach ($data as $association => $values) {
|
||||
if (isset($associations[$association]) && $associations[$association] === 'belongsTo') {
|
||||
if ($this->{$association}->create(null) !== null && $this->{$association}->save($values, $options)) {
|
||||
$data[$this->alias][$this->belongsTo[$association]['foreignKey']] = $this->{$association}->id;
|
||||
$validates = $this->{$association}->create(null) !== null;
|
||||
$saved = false;
|
||||
if ($validates) {
|
||||
if ($options['deep']) {
|
||||
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
|
||||
} else {
|
||||
$saved = $this->{$association}->save($values, array_merge($options, array('atomic' => false)));
|
||||
}
|
||||
$validates = ($saved === true || (is_array($saved) && !in_array(false, $saved, true)));
|
||||
}
|
||||
if ($validates) {
|
||||
if (!empty($data[$this->alias])) {
|
||||
$data[$this->alias][$this->belongsTo[$association]['foreignKey']] = $this->{$association}->id;
|
||||
} else {
|
||||
$data[$this->belongsTo[$association]['foreignKey']] = $this->{$association}->id;
|
||||
}
|
||||
} else {
|
||||
$validationErrors[$association] = $this->{$association}->validationErrors;
|
||||
$validates = false;
|
||||
}
|
||||
$return[$association][] = $validates;
|
||||
$return[$association] = $validates;
|
||||
}
|
||||
}
|
||||
if ($validates && !($this->create(null) !== null && $this->save($data, $options))) {
|
||||
|
@ -2170,11 +2213,20 @@ class Model extends Object implements CakeEventListener {
|
|||
switch ($type) {
|
||||
case 'hasOne':
|
||||
$values[$this->{$type}[$association]['foreignKey']] = $this->id;
|
||||
if (!($this->{$association}->create(null) !== null && $this->{$association}->save($values, $options))) {
|
||||
$validationErrors[$association] = $this->{$association}->validationErrors;
|
||||
$validates = false;
|
||||
$validates = $this->{$association}->create(null) !== null;
|
||||
$saved = false;
|
||||
if ($validates) {
|
||||
if ($options['deep']) {
|
||||
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
|
||||
} else {
|
||||
$saved = $this->{$association}->save($values, $options);
|
||||
}
|
||||
}
|
||||
$return[$association][] = $validates;
|
||||
$validates = ($validates && ($saved === true || (is_array($saved) && !in_array(false, $saved, true))));
|
||||
if (!$validates) {
|
||||
$validationErrors[$association] = $this->{$association}->validationErrors;
|
||||
}
|
||||
$return[$association] = $validates;
|
||||
break;
|
||||
case 'hasMany':
|
||||
foreach ($values as $i => $value) {
|
||||
|
@ -2217,6 +2269,7 @@ class Model extends Object implements CakeEventListener {
|
|||
*
|
||||
* - atomic: If true (default), returns boolean. If false returns array.
|
||||
* - fieldList: Equivalent to the $fieldList parameter in Model::save()
|
||||
* - deep: If set to true, not only directly associated data , but deeper nested associated data is validated as well.
|
||||
*
|
||||
* @param array $data Record data to validate. This should be an array indexed by association name.
|
||||
* @param array $options Options to use when validating record data (see above), See also $options of validates().
|
||||
|
@ -2225,7 +2278,7 @@ class Model extends Object implements CakeEventListener {
|
|||
* depending on whether each record validated successfully.
|
||||
*/
|
||||
public function validateAssociated($data, $options = array()) {
|
||||
$options = array_merge(array('atomic' => true), $options);
|
||||
$options = array_merge(array('atomic' => true, 'deep' => false), $options);
|
||||
$this->validationErrors = $validationErrors = $return = array();
|
||||
if (!($this->create($data) && $this->validates($options))) {
|
||||
$validationErrors[$this->alias] = $this->validationErrors;
|
||||
|
@ -2234,12 +2287,23 @@ class Model extends Object implements CakeEventListener {
|
|||
$return[$this->alias] = true;
|
||||
}
|
||||
$associations = $this->getAssociated();
|
||||
$validates = true;
|
||||
foreach ($data as $association => $values) {
|
||||
$validates = true;
|
||||
if (isset($associations[$association])) {
|
||||
if (in_array($associations[$association], array('belongsTo', 'hasOne'))) {
|
||||
$validates = $this->{$association}->create($values) && $this->{$association}->validates($options);
|
||||
$return[$association][] = $validates;
|
||||
if ($options['deep']) {
|
||||
$validates = $this->{$association}->validateAssociated($values, $options);
|
||||
} else {
|
||||
$validates = $this->{$association}->create($values) !== null && $this->{$association}->validates($options);
|
||||
}
|
||||
if (is_array($validates)) {
|
||||
if (in_array(false, $validates, true)) {
|
||||
$validates = false;
|
||||
} else {
|
||||
$validates = true;
|
||||
}
|
||||
}
|
||||
$return[$association] = $validates;
|
||||
} elseif ($associations[$association] === 'hasMany') {
|
||||
$validates = $this->{$association}->validateMany($values, $options);
|
||||
$return[$association] = $validates;
|
||||
|
@ -2662,6 +2726,10 @@ class Model extends Object implements CakeEventListener {
|
|||
protected function _findCount($state, $query, $results = array()) {
|
||||
if ($state === 'before') {
|
||||
$db = $this->getDataSource();
|
||||
$query['order'] = false;
|
||||
if (!method_exists($db, 'calculate') || !method_exists($db, 'expression')) {
|
||||
return $query;
|
||||
}
|
||||
if (empty($query['fields'])) {
|
||||
$query['fields'] = $db->calculate($this, 'count');
|
||||
} elseif (is_string($query['fields']) && !preg_match('/count/i', $query['fields'])) {
|
||||
|
@ -2669,7 +2737,6 @@ class Model extends Object implements CakeEventListener {
|
|||
$db->expression($query['fields']), 'count'
|
||||
));
|
||||
}
|
||||
$query['order'] = false;
|
||||
return $query;
|
||||
} elseif ($state === 'after') {
|
||||
foreach (array(0, $this->alias) as $key) {
|
||||
|
|
|
@ -208,6 +208,7 @@ class CakeResponse {
|
|||
'hh' => 'text/plain',
|
||||
'html' => array('text/html', '*/*'),
|
||||
'htm' => array('text/html', '*/*'),
|
||||
'ics' => 'text/calendar',
|
||||
'm' => 'text/plain',
|
||||
'rtf' => 'text/rtf',
|
||||
'rtx' => 'text/richtext',
|
||||
|
@ -1147,4 +1148,4 @@ class CakeResponse {
|
|||
|
||||
$this->_cookies[$config['name']] = $config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -686,6 +686,9 @@ class CakeEmail {
|
|||
if ($email === $alias) {
|
||||
$return[] = $email;
|
||||
} else {
|
||||
if (strpos($alias, ',') !== false) {
|
||||
$alias = '"' . $alias . '"';
|
||||
}
|
||||
$return[] = sprintf('%s <%s>', $this->_encode($alias), $email);
|
||||
}
|
||||
}
|
||||
|
@ -1109,9 +1112,6 @@ class CakeEmail {
|
|||
$restore = mb_internal_encoding();
|
||||
mb_internal_encoding($this->_appCharset);
|
||||
}
|
||||
if (strpos($text, ',') !== false) {
|
||||
$text = '"' . $text . '"';
|
||||
}
|
||||
$return = mb_encode_mimeheader($text, $this->headerCharset, 'B');
|
||||
if ($internalEncoding) {
|
||||
mb_internal_encoding($restore);
|
||||
|
|
|
@ -1077,15 +1077,17 @@ class Router {
|
|||
* Instructs the router to parse out file extensions from the URL. For example,
|
||||
* http://example.com/posts.rss would yield an file extension of "rss".
|
||||
* The file extension itself is made available in the controller as
|
||||
* $this->params['url']['ext'], and is used by the RequestHandler component to
|
||||
* `$this->params['ext']`, and is used by the RequestHandler component to
|
||||
* automatically switch to alternate layouts and templates, and load helpers
|
||||
* corresponding to the given content, i.e. RssHelper.
|
||||
* corresponding to the given content, i.e. RssHelper. Switching layouts and helpers
|
||||
* requires that the chosen extension has a defined mime type in `CakeResponse`
|
||||
*
|
||||
* A list of valid extension can be passed to this method, i.e. Router::parseExtensions('rss', 'xml');
|
||||
* If no parameters are given, anything after the first . (dot) after the last / in the URL will be
|
||||
* parsed, excluding querystring parameters (i.e. ?q=...).
|
||||
*
|
||||
* @return void
|
||||
* @see RequestHandler::startup()
|
||||
*/
|
||||
public static function parseExtensions() {
|
||||
self::$_parseExtensions = true;
|
||||
|
|
|
@ -48,13 +48,13 @@ class AllTests extends PHPUnit_Framework_TestSuite {
|
|||
$suite->addTestFile($path . 'AllEventTest.php');
|
||||
$suite->addTestFile($path . 'AllHelpersTest.php');
|
||||
$suite->addTestFile($path . 'AllLogTest.php');
|
||||
$suite->addTestFile($path . 'AllI18nTest.php');
|
||||
$suite->addTestFile($path . 'Model' . DS . 'ModelTest.php');
|
||||
$suite->addTestFile($path . 'AllRoutingTest.php');
|
||||
$suite->addTestFile($path . 'AllNetworkTest.php');
|
||||
$suite->addTestFile($path . 'AllTestSuiteTest.php');;
|
||||
$suite->addTestFile($path . 'AllUtilityTest.php');
|
||||
$suite->addTestFile($path . 'AllViewTest.php');
|
||||
$suite->addTestFile($path . 'AllI18nTest.php');
|
||||
return $suite;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,27 +93,37 @@ class ExtractTaskTest extends CakeTestCase {
|
|||
// home.ctp
|
||||
$pattern = '/msgid "Your tmp directory is writable."\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Your tmp directory is NOT writable."\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "The %s is being used for caching. To change the config edit ';
|
||||
$pattern .= 'APP\/config\/core.php "\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Your cache is NOT working. Please check ';
|
||||
$pattern .= 'the settings in APP\/config\/core.php"\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Your database configuration file is present."\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Your database configuration file is NOT present."\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Rename config\/database.php.default to ';
|
||||
$pattern .= 'config\/database.php"\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Cake is able to connect to the database."\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Cake is NOT able to connect to the database."\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "Editing this Page"\nmsgstr ""\n/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "To change the content of this page, create: APP\/views\/pages\/home\.ctp/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
|
@ -121,10 +131,13 @@ class ExtractTaskTest extends CakeTestCase {
|
|||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
// extract.ctp
|
||||
$pattern = '/\#: (\\\\|\/)extract\.ctp:6\n';
|
||||
$pattern = '/\#: (\\\\|\/)extract\.ctp:15;6\n';
|
||||
$pattern .= 'msgid "You have %d new message."\nmsgid_plural "You have %d new messages."/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/msgid "You have %d new message."\nmsgstr ""/';
|
||||
$this->assertNotRegExp($pattern, $result, 'No duplicate msgid');
|
||||
|
||||
$pattern = '/\#: (\\\\|\/)extract\.ctp:7\n';
|
||||
$pattern .= 'msgid "You deleted %d message."\nmsgid_plural "You deleted %d messages."/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
@ -134,7 +147,7 @@ class ExtractTaskTest extends CakeTestCase {
|
|||
$pattern .= 'msgid "Editing this Page"\nmsgstr ""/';
|
||||
$this->assertRegExp($pattern, $result);
|
||||
|
||||
$pattern = '/\#: (\\\\|\/)extract\.ctp:17\nmsgid "';
|
||||
$pattern = '/\#: (\\\\|\/)extract\.ctp:18\nmsgid "';
|
||||
$pattern .= 'Hot features!';
|
||||
$pattern .= '\\\n - No Configuration: Set-up the database and let the magic begin';
|
||||
$pattern .= '\\\n - Extremely Simple: Just look at the name...It\'s Cake';
|
||||
|
|
|
@ -75,7 +75,7 @@ class ActionsAuthorizeTest extends CakeTestCase {
|
|||
|
||||
$this->Acl->expects($this->once())
|
||||
->method('check')
|
||||
->with($user, '/controllers/Posts/index')
|
||||
->with($user, 'controllers/Posts/index')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->assertFalse($this->auth->authorize($user['User'], $request));
|
||||
|
@ -104,7 +104,7 @@ class ActionsAuthorizeTest extends CakeTestCase {
|
|||
|
||||
$this->Acl->expects($this->once())
|
||||
->method('check')
|
||||
->with($user, '/controllers/Posts/index')
|
||||
->with($user, 'controllers/Posts/index')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$this->assertTrue($this->auth->authorize($user['User'], $request));
|
||||
|
@ -134,7 +134,7 @@ class ActionsAuthorizeTest extends CakeTestCase {
|
|||
$expected = array('TestPlugin.TestPluginAuthUser' => array('id' => 1, 'user' => 'mariano'));
|
||||
$this->Acl->expects($this->once())
|
||||
->method('check')
|
||||
->with($expected, '/controllers/Posts/index')
|
||||
->with($expected, 'controllers/Posts/index')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$this->assertTrue($this->auth->authorize($user, $request));
|
||||
|
@ -154,8 +154,23 @@ class ActionsAuthorizeTest extends CakeTestCase {
|
|||
));
|
||||
|
||||
$result = $this->auth->action($request);
|
||||
$this->assertEquals('controllers/Posts/index', $result);
|
||||
}
|
||||
|
||||
$this->assertEquals('/controllers/Posts/index', $result);
|
||||
/**
|
||||
* Make sure that action() doesn't create double slashes anywhere.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testActionNoDoubleSlash() {
|
||||
$this->auth->settings['actionPath'] = '/controllers/';
|
||||
$request = array(
|
||||
'plugin' => null,
|
||||
'controller' => 'posts',
|
||||
'action' => 'index'
|
||||
);
|
||||
$result = $this->auth->action($request);
|
||||
$this->assertEquals('controllers/Posts/index', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,6 +187,6 @@ class ActionsAuthorizeTest extends CakeTestCase {
|
|||
));
|
||||
|
||||
$result = $this->auth->action($request);
|
||||
$this->assertEquals('/controllers/DebugKit/Posts/index', $result);
|
||||
$this->assertEquals('controllers/DebugKit/Posts/index', $result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -490,6 +490,21 @@ class CookieComponentTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading empty values.
|
||||
*/
|
||||
public function testReadEmpty() {
|
||||
$_COOKIE['CakeTestCookie'] = array(
|
||||
'JSON' => '{"name":"value"}',
|
||||
'Empty' => '',
|
||||
'String' => '{"somewhat:"broken"}'
|
||||
);
|
||||
$this->assertEqual(array('name' => 'value'), $this->Cookie->read('JSON'));
|
||||
$this->assertEqual('value', $this->Cookie->read('JSON.name'));
|
||||
$this->assertEqual('', $this->Cookie->read('Empty'));
|
||||
$this->assertEqual('{"somewhat:"broken"}', $this->Cookie->read('String'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that no error is issued for non array data.
|
||||
*
|
||||
|
@ -502,6 +517,7 @@ class CookieComponentTest extends CakeTestCase {
|
|||
$this->assertNull($this->Cookie->read('value'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* test that deleting a top level keys kills the child elements too.
|
||||
*
|
||||
|
|
|
@ -915,7 +915,7 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testValidateNestedNumericSets() {
|
||||
|
||||
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$key = $this->Controller->request->params['_Token']['key'];
|
||||
$unlocked = '';
|
||||
|
@ -1122,13 +1122,15 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$this->Security->validatePost = false;
|
||||
$this->Security->csrfCheck = true;
|
||||
$this->Security->csrfExpires = '+10 minutes';
|
||||
$csrfExpires = strtotime('+10 minutes');
|
||||
$this->Security->startup($this->Controller);
|
||||
$this->Security->startup($this->Controller);
|
||||
|
||||
$token = $this->Security->Session->read('_Token');
|
||||
$this->assertEquals(count($token['csrfTokens']), 2, 'Missing the csrf token.');
|
||||
foreach ($token['csrfTokens'] as $key => $expires) {
|
||||
$this->assertEquals(strtotime('+10 minutes'), $expires, 'Token expiry does not match');
|
||||
$diff = $csrfExpires - $expires;
|
||||
$this->assertTrue($diff === 0 || $diff === 1, 'Token expiry does not match');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2525,6 +2525,7 @@ class I18nTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testPoQuotedString () {
|
||||
Configure::write('Config.language', 'po');
|
||||
$expected = 'this is a "quoted string" (translated)';
|
||||
$this->assertEquals($expected, __('this is a "quoted string"'));
|
||||
}
|
||||
|
|
|
@ -278,13 +278,13 @@ class SqliteTest extends CakeTestCase {
|
|||
'user' => array(
|
||||
'type' => 'string',
|
||||
'length' => 255,
|
||||
'null' => false,
|
||||
'null' => true,
|
||||
'default' => null
|
||||
),
|
||||
'password' => array(
|
||||
'type' => 'string',
|
||||
'length' => 255,
|
||||
'null' => false,
|
||||
'null' => true,
|
||||
'default' => null
|
||||
),
|
||||
'created' => array(
|
||||
|
|
|
@ -633,4 +633,31 @@ class SqlserverTest extends CakeTestCase {
|
|||
$this->assertEquals('nate', $results[1]['User']['user']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the return of stored procedures is honoured
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testStoredProcedureReturn() {
|
||||
$sql = <<<SQL
|
||||
CREATE PROCEDURE cake_test_procedure
|
||||
AS
|
||||
BEGIN
|
||||
RETURN 2;
|
||||
END
|
||||
SQL;
|
||||
$this->Dbo->execute($sql);
|
||||
|
||||
$sql = <<<SQL
|
||||
DECLARE @return_value int
|
||||
EXEC @return_value = [cake_test_procedure]
|
||||
SELECT 'value' = @return_value
|
||||
SQL;
|
||||
$query = $this->Dbo->execute($sql);
|
||||
$this->Dbo->execute('DROP PROC cake_test_procedure');
|
||||
|
||||
$result = $query->fetch();
|
||||
$this->assertEquals(2, $result['value']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class CacheSessionTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public static function teardownAfterClass() {
|
||||
Cache::clear('session_test');
|
||||
Cache::clear(false, 'session_test');
|
||||
Cache::drop('session_test');
|
||||
|
||||
Configure::write('Session', self::$_sessionBackup);
|
||||
|
|
|
@ -555,7 +555,9 @@ class ModelDeleteTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
public function testDeleteDependent() {
|
||||
$this->loadFixtures('Bidding', 'BiddingMessage');
|
||||
$this->loadFixtures('Bidding', 'BiddingMessage', 'Article',
|
||||
'ArticlesTag', 'Comment', 'User', 'Attachment'
|
||||
);
|
||||
$Bidding = new Bidding();
|
||||
$result = $Bidding->find('all');
|
||||
$expected = array(
|
||||
|
@ -626,6 +628,20 @@ class ModelDeleteTest extends BaseModelTest {
|
|||
),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$Article = new Article();
|
||||
$result = $Article->Comment->find('count', array(
|
||||
'conditions' => array('Comment.article_id' => 1)
|
||||
));
|
||||
$this->assertEquals(4, $result);
|
||||
|
||||
$result = $Article->delete(1, true);
|
||||
$this->assertIdentical(true, true);
|
||||
|
||||
$result = $Article->Comment->find('count', array(
|
||||
'conditions' => array('Comment.article_id' => 1)
|
||||
));
|
||||
$this->assertEquals(0, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2083,13 +2083,13 @@ class ModelIntegrationTest extends BaseModelTest {
|
|||
),
|
||||
'user' => array(
|
||||
'type' => 'string',
|
||||
'null' => false,
|
||||
'null' => true,
|
||||
'default' => '',
|
||||
'length' => 255
|
||||
),
|
||||
'password' => array(
|
||||
'type' => 'string',
|
||||
'null' => false,
|
||||
'null' => true,
|
||||
'default' => '',
|
||||
'length' => 255
|
||||
),
|
||||
|
|
|
@ -2973,7 +2973,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
public function testSaveAllAtomic() {
|
||||
$this->loadFixtures('Article', 'User');
|
||||
$this->loadFixtures('Article', 'User', 'Comment');
|
||||
$TestModel = new Article();
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
|
@ -3041,6 +3041,779 @@ class ModelWriteTest extends BaseModelTest {
|
|||
$this->assertSame($result, array('Article' => true, 'Comment' => array(true, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* testSaveAllDeepAssociated method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSaveAllDeepAssociated() {
|
||||
$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
|
||||
$TestModel = new Article();
|
||||
$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
|
||||
$TestModel->hasAndBelongsToMany = array();
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
), array('deep' => true));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->findById(2);
|
||||
$expected = array(
|
||||
'First Comment for Second Article',
|
||||
'Second Comment for Second Article',
|
||||
'First new comment',
|
||||
'Second new comment'
|
||||
);
|
||||
$this->assertEquals($expected, Set::extract($result['Comment'], '{n}.comment'));
|
||||
|
||||
$result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
|
||||
$this->assertEquals(5, $result);
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
|
||||
)
|
||||
), array('deep' => true));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->findById(2);
|
||||
$expected = array(
|
||||
'First Comment for Second Article',
|
||||
'Second Comment for Second Article',
|
||||
'First new comment',
|
||||
'Second new comment',
|
||||
'Third new comment',
|
||||
'Fourth new comment'
|
||||
);
|
||||
$this->assertEquals($expected, Set::extract($result['Comment'], '{n}.comment'));
|
||||
|
||||
$result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
|
||||
$this->assertEquals(2, $result);
|
||||
$data = array(
|
||||
'Attachment' => array(
|
||||
'attachment' => 'deepsave insert',
|
||||
),
|
||||
'Comment' => array(
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
'user_id' => 5,
|
||||
'Article' => array(
|
||||
'title' => 'First Article deepsave insert',
|
||||
'body' => 'First Article Body deepsave insert',
|
||||
'User' => array(
|
||||
'user' => '',
|
||||
'password' => 'magic'
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$TestModel->Comment->Attachment->create();
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$expected = array('User' => array('user' => array('This field cannot be left blank')));
|
||||
$this->assertEquals($expected, $TestModel->validationErrors);
|
||||
|
||||
$data['Comment']['Article']['User']['user'] = 'deepsave';
|
||||
$TestModel->Comment->Attachment->create();
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
|
||||
$expected = array(
|
||||
'Attachment' => array(
|
||||
'id' => '3',
|
||||
'comment_id' => '11',
|
||||
'attachment' => 'deepsave insert',
|
||||
),
|
||||
'Comment' => array(
|
||||
'id' => '11',
|
||||
'article_id' => '4',
|
||||
'user_id' => '5',
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
)
|
||||
);
|
||||
unset($result['Attachment']['created'], $result['Attachment']['updated']);
|
||||
$this->assertEquals($expected['Attachment'], $result['Attachment']);
|
||||
|
||||
unset($result['Comment']['created'], $result['Comment']['updated']);
|
||||
$this->assertEquals($result['Comment'], $expected['Comment']);
|
||||
|
||||
$result = $TestModel->findById($result['Comment']['article_id']);
|
||||
$expected = array(
|
||||
'Article' => array(
|
||||
'id' => '4',
|
||||
'user_id' => '6',
|
||||
'title' => 'First Article deepsave insert',
|
||||
'body' => 'First Article Body deepsave insert',
|
||||
'published' => 'N',
|
||||
),
|
||||
'User' => array(
|
||||
'id' => '6',
|
||||
'user' => 'deepsave',
|
||||
'password' => 'magic',
|
||||
),
|
||||
'Comment' => array(
|
||||
array(
|
||||
'id' => '11',
|
||||
'article_id' => '4',
|
||||
'user_id' => '5',
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
)
|
||||
)
|
||||
);
|
||||
unset(
|
||||
$result['Article']['created'], $result['Article']['updated'],
|
||||
$result['User']['created'], $result['User']['updated'],
|
||||
$result['Comment'][0]['created'], $result['Comment'][0]['updated']
|
||||
);
|
||||
$this->assertEquals($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* testSaveAllDeepMany
|
||||
* tests the validate methods with deeper recursive data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSaveAllDeepMany() {
|
||||
$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
|
||||
$TestModel = new Article();
|
||||
$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
|
||||
$TestModel->hasAndBelongsToMany = array();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'id' => 1, 'body' => '',
|
||||
'Comment' => array(
|
||||
array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
|
||||
array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
|
||||
array('comment' => '', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
)
|
||||
);
|
||||
$TestModel->Comment->validate['comment'] = 'notEmpty';
|
||||
$result = $TestModel->saveAll($data, array('deep' => true));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$expected = array(
|
||||
0 => array(
|
||||
'body' => array('This field cannot be left blank')
|
||||
),
|
||||
1 => array(
|
||||
'Comment' => array(
|
||||
0 => array(
|
||||
'User' => array(
|
||||
'password' => array('This field cannot be left blank')
|
||||
)
|
||||
),
|
||||
1 => array(
|
||||
'comment' => array('This field cannot be left blank')
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$result = $TestModel->validationErrors;
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'Article' => array('id' => 1),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First comment deepsaved article 1', 'published' => 'Y', 'User' => array('user' => 'savemany', 'password' => 'manysaved')),
|
||||
array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => 'moresaved')),
|
||||
array('comment' => 'Second comment deepsaved article 2', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
)
|
||||
);
|
||||
$result = $TestModel->saveAll($data, array('deep' => true));
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
/**
|
||||
* testSaveAllDeepValidateOnly
|
||||
* tests the validate methods with deeper recursive data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSaveAllDeepValidateOnly() {
|
||||
$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
|
||||
$TestModel = new Article();
|
||||
$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
|
||||
$TestModel->hasAndBelongsToMany = array();
|
||||
$TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
|
||||
$TestModel->Comment->validate['comment'] = 'notEmpty';
|
||||
|
||||
$result = $TestModel->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'deep' => true)
|
||||
);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'deep' => true)
|
||||
);
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $TestModel->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'atomic' => false, 'deep' => true)
|
||||
);
|
||||
$expected = array(
|
||||
'Article' => true,
|
||||
'Comment' => array(
|
||||
true,
|
||||
true
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'atomic' => false, 'deep' => true)
|
||||
);
|
||||
$expected = array(
|
||||
'Article' => true,
|
||||
'Comment' => array(
|
||||
false,
|
||||
true
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'deep' => true)
|
||||
);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'deep' => true)
|
||||
);
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsave'))
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'atomic' => false, 'deep' => true)
|
||||
);
|
||||
$expected = array(
|
||||
'Article' => true,
|
||||
'Comment' => array(
|
||||
true,
|
||||
true
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'atomic' => false, 'deep' => true)
|
||||
);
|
||||
$expected = array(
|
||||
'Article' => true,
|
||||
'Comment' => array(
|
||||
true,
|
||||
false
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$expected = array(
|
||||
'Comment' => array(
|
||||
1 => array(
|
||||
'Attachment' => array(
|
||||
'attachment' => array('This field cannot be left blank')
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$result = $TestModel->validationErrors;
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$data = array(
|
||||
'Attachment' => array(
|
||||
'attachment' => 'deepsave insert',
|
||||
),
|
||||
'Comment' => array(
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
'user_id' => 5,
|
||||
'Article' => array(
|
||||
'title' => 'First Article deepsave insert',
|
||||
'body' => 'First Article Body deepsave insert',
|
||||
'User' => array(
|
||||
'user' => 'deepsave',
|
||||
'password' => 'magic'
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
|
||||
$expected = array(
|
||||
'Attachment' => true,
|
||||
'Comment' => true
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$data = array(
|
||||
'Attachment' => array(
|
||||
'attachment' => 'deepsave insert',
|
||||
),
|
||||
'Comment' => array(
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
'user_id' => 5,
|
||||
'Article' => array(
|
||||
'title' => 'First Article deepsave insert',
|
||||
'body' => 'First Article Body deepsave insert',
|
||||
'User' => array(
|
||||
'user' => '',
|
||||
'password' => 'magic'
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->validationErrors;
|
||||
$expected = array(
|
||||
'Comment' => array(
|
||||
'Article' => array(
|
||||
'User' => array(
|
||||
'user' => array('This field cannot be left blank')
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
|
||||
$expected = array(
|
||||
'Attachment' => true,
|
||||
'Comment' => false
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data['Comment']['Article']['body'] = '';
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->validationErrors;
|
||||
$expected = array(
|
||||
'Comment' => array(
|
||||
'Article' => array(
|
||||
'body' => array('This field cannot be left blank')
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
|
||||
$expected = array(
|
||||
'Attachment' => true,
|
||||
'Comment' => false
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data['Comment']['comment'] = '';
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->validationErrors;
|
||||
$expected = array(
|
||||
'Comment' => array(
|
||||
'comment' => array('This field cannot be left blank')
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
|
||||
$expected = array(
|
||||
'Attachment' => true,
|
||||
'Comment' => false
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data['Attachment']['attachment'] = '';
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->validationErrors;
|
||||
$expected = array('attachment' => array('This field cannot be left blank'));
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->validationErrors;
|
||||
$expected = array('comment' => array('This field cannot be left blank'));
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
|
||||
$expected = array(
|
||||
'Attachment' => false,
|
||||
'Comment' => false
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testSaveAllNotDeepAssociated method
|
||||
* test that only directly associated data gets saved
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSaveAllNotDeepAssociated() {
|
||||
$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
|
||||
$TestModel = new Article();
|
||||
$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
|
||||
$TestModel->hasAndBelongsToMany = array();
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array(
|
||||
'comment' => 'First new comment', 'published' => 'Y', 'user_id' => 2,
|
||||
'User' => array('user' => 'newuser', 'password' => 'newuserpass')
|
||||
),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
), array('deep' => false));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 4),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
|
||||
)
|
||||
), array('deep' => false));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$data = array(
|
||||
'Attachment' => array(
|
||||
'attachment' => 'deepsave insert',
|
||||
),
|
||||
'Comment' => array(
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
'user_id' => 4,
|
||||
'article_id' => 1,
|
||||
'Article' => array(
|
||||
'title' => 'First Article deepsave insert',
|
||||
'body' => 'First Article Body deepsave insert',
|
||||
'User' => array(
|
||||
'user' => 'deepsave',
|
||||
'password' => 'magic'
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
$expected = $TestModel->User->find('count');
|
||||
|
||||
$TestModel->Comment->Attachment->create();
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => false));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->User->find('count');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
|
||||
$expected = array(
|
||||
'Attachment' => array(
|
||||
'id' => '2',
|
||||
'comment_id' => '11',
|
||||
'attachment' => 'deepsave insert',
|
||||
),
|
||||
'Comment' => array(
|
||||
'id' => '11',
|
||||
'article_id' => 1,
|
||||
'user_id' => '4',
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
)
|
||||
);
|
||||
unset($result['Attachment']['created'], $result['Attachment']['updated']);
|
||||
$this->assertEquals($expected['Attachment'], $result['Attachment']);
|
||||
|
||||
unset($result['Comment']['created'], $result['Comment']['updated']);
|
||||
$this->assertEquals($expected['Comment'], $result['Comment']);
|
||||
}
|
||||
|
||||
/**
|
||||
* testSaveAllNotDeepMany
|
||||
* tests the save methods to not save deeper recursive data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSaveAllNotDeepMany() {
|
||||
$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
|
||||
$TestModel = new Article();
|
||||
$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
|
||||
$TestModel->hasAndBelongsToMany = array();
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'id' => 1, 'body' => '',
|
||||
'Comment' => array(
|
||||
array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
|
||||
array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
|
||||
array('comment' => '', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
)
|
||||
);
|
||||
$TestModel->Comment->validate['comment'] = 'notEmpty';
|
||||
$result = $TestModel->saveAll($data, array('deep' => false));
|
||||
$this->assertFalse($result);
|
||||
|
||||
$expected = array(
|
||||
0 => array(
|
||||
'body' => array('This field cannot be left blank')
|
||||
)
|
||||
);
|
||||
$result = $TestModel->validationErrors;
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'Article' => array('id' => 1, 'body' => 'Ignore invalid comment'),
|
||||
'Comment' => array(
|
||||
array('comment' => '', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'Article' => array('id' => 2, 'body' => 'Same here'),
|
||||
'Comment' => array(
|
||||
array('comment' => '', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
)
|
||||
);
|
||||
$result = $TestModel->saveAll($data, array('deep' => false));
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
/**
|
||||
* testSaveAllNotDeepValidateOnly
|
||||
* tests the validate methods to not validate deeper recursive data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSaveAllNotDeepValidateOnly() {
|
||||
$this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
|
||||
$TestModel = new Article();
|
||||
$TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
|
||||
$TestModel->hasAndBelongsToMany = array();
|
||||
$TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
|
||||
$TestModel->Comment->validate['comment'] = 'notEmpty';
|
||||
|
||||
$result = $TestModel->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2, 'body' => ''),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'deep' => false)
|
||||
);
|
||||
$this->assertFalse($result);
|
||||
|
||||
$expected = array('body' => array('This field cannot be left blank'));
|
||||
$result = $TestModel->validationErrors;
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'deep' => false)
|
||||
);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->saveAll(
|
||||
array(
|
||||
'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
|
||||
array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'atomic' => false, 'deep' => false)
|
||||
);
|
||||
$expected = array(
|
||||
'Article' => true,
|
||||
'Comment' => array(
|
||||
true,
|
||||
true
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'deep' => false)
|
||||
);
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
|
||||
'Comment' => array(
|
||||
array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
|
||||
array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
|
||||
)
|
||||
),
|
||||
array('validate' => 'only', 'atomic' => false, 'deep' => false)
|
||||
);
|
||||
$expected = array(
|
||||
'Article' => true,
|
||||
'Comment' => array(
|
||||
true,
|
||||
true
|
||||
)
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$expected = array();
|
||||
$result = $TestModel->validationErrors;
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$data = array(
|
||||
'Attachment' => array(
|
||||
'attachment' => 'deepsave insert',
|
||||
),
|
||||
'Comment' => array(
|
||||
'comment' => 'First comment deepsave insert',
|
||||
'published' => 'Y',
|
||||
'user_id' => 5,
|
||||
'Article' => array(
|
||||
'title' => 'First Article deepsave insert ignored',
|
||||
'body' => 'First Article Body deepsave insert',
|
||||
'User' => array(
|
||||
'user' => '',
|
||||
'password' => 'magic'
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->validationErrors;
|
||||
$expected = array();
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
|
||||
$expected = array(
|
||||
'Attachment' => true,
|
||||
'Comment' => true
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data['Comment']['Article']['body'] = '';
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
|
||||
$this->assertTrue($result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->validationErrors;
|
||||
$expected = array();
|
||||
$this->assertSame($expected, $result);
|
||||
|
||||
$result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
|
||||
$expected = array(
|
||||
'Attachment' => true,
|
||||
'Comment' => true
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testSaveAllHasMany method
|
||||
*
|
||||
|
@ -3212,7 +3985,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
$db->expects($this->once())->method('rollback');
|
||||
$db->expects($this->any())->method('describe')
|
||||
->will($this->returnValue(array(
|
||||
'id' => array('type' => 'integer'),
|
||||
'id' => array('type' => 'integer', 'length' => 11),
|
||||
'title' => array('type' => 'string'),
|
||||
'body' => array('type' => 'text'),
|
||||
'published' => array('type' => 'string')
|
||||
|
@ -3409,7 +4182,8 @@ class ModelWriteTest extends BaseModelTest {
|
|||
|
||||
$result = $TestModel->find('all', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('author_id', 'title','body','published')
|
||||
'fields' => array('author_id', 'title','body','published'),
|
||||
'order' => array('Post.created' => 'ASC')
|
||||
));
|
||||
|
||||
$expected = array(
|
||||
|
@ -4540,7 +5314,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
$db->expects($this->once())->method('rollback');
|
||||
$db->expects($this->any())->method('describe')
|
||||
->will($this->returnValue(array(
|
||||
'id' => array('type' => 'integer'),
|
||||
'id' => array('type' => 'integer', 'length' => 11),
|
||||
'title' => array('type' => 'string'),
|
||||
'body' => array('type' => 'text'),
|
||||
'published' => array('type' => 'string')
|
||||
|
@ -4741,7 +5515,8 @@ class ModelWriteTest extends BaseModelTest {
|
|||
|
||||
$result = $TestModel->find('all', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('author_id', 'title','body','published')
|
||||
'fields' => array('author_id', 'title','body','published'),
|
||||
'order' => array('Post.created' => 'ASC')
|
||||
));
|
||||
|
||||
$expected = array(
|
||||
|
@ -5510,11 +6285,11 @@ class ModelWriteTest extends BaseModelTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* validateSaveAllFieldListBelongsTo
|
||||
* testSaveAllFieldListValidateBelongsTo
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validateSaveAllFieldListBelongsTo() {
|
||||
public function testSaveAllFieldListValidateBelongsTo() {
|
||||
$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
|
||||
$TestModel = new Post();
|
||||
|
||||
|
@ -5541,8 +6316,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
|
||||
$result = $TestModel->find('all');
|
||||
$expected = array(
|
||||
'Post' =>
|
||||
array (
|
||||
'Post' => array (
|
||||
'id' => '4',
|
||||
'author_id' => '5',
|
||||
'title' => 'Post without body',
|
||||
|
@ -5551,8 +6325,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
'created' => $ts,
|
||||
'updated' => $ts,
|
||||
),
|
||||
'Author' =>
|
||||
array (
|
||||
'Author' => array (
|
||||
'id' => '5',
|
||||
'user' => 'bob',
|
||||
'password' => NULL,
|
||||
|
@ -5681,4 +6454,95 @@ class ModelWriteTest extends BaseModelTest {
|
|||
$this->assertEmpty($TestModel->validationErrors);
|
||||
}
|
||||
|
||||
/**
|
||||
* testSaveAllDeepFieldListValidateBelongsTo
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSaveAllDeepFieldListValidateBelongsTo() {
|
||||
$this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
|
||||
$TestModel = new Post();
|
||||
$TestModel->Author->bindModel(array('hasMany' => array('Comment' => array('foreignKey' => 'user_id'))), false);
|
||||
$TestModel->recursive = 2;
|
||||
|
||||
$result = $TestModel->find('all');
|
||||
$this->assertCount(3, $result);
|
||||
$this->assertFalse(isset($result[3]));
|
||||
$ts = date('Y-m-d H:i:s');
|
||||
|
||||
// test belongsTo
|
||||
$fieldList = array(
|
||||
'Post' => array('title', 'author_id'),
|
||||
'Author' => array('user'),
|
||||
'Comment' => array('comment')
|
||||
);
|
||||
$TestModel->saveAll(array(
|
||||
'Post' => array(
|
||||
'title' => 'Post without body',
|
||||
'body' => 'This will not be saved',
|
||||
),
|
||||
'Author' => array(
|
||||
'user' => 'bob',
|
||||
'test' => 'This will not be saved',
|
||||
'Comment' => array(
|
||||
array('id' => 5, 'comment' => 'I am still published', 'published' => 'N'))
|
||||
|
||||
)), array('fieldList' => $fieldList, 'deep' => true));
|
||||
|
||||
$result = $TestModel->Author->Comment->find('first', array(
|
||||
'conditions' => array('Comment.id' => 5),
|
||||
'fields' => array('comment', 'published')
|
||||
));
|
||||
$expected = array(
|
||||
'Comment' => array(
|
||||
'comment' => 'I am still published',
|
||||
'published' => 'Y'
|
||||
)
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testSaveAllDeepFieldListHasMany method
|
||||
*
|
||||
* return @void
|
||||
*/
|
||||
public function testSaveAllDeepFieldListHasMany() {
|
||||
$this->loadFixtures('Article', 'Comment', 'User');
|
||||
$TestModel = new Article();
|
||||
$TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
|
||||
|
||||
$this->db->truncate($TestModel);
|
||||
$this->db->truncate(new Comment());
|
||||
|
||||
$fieldList = array(
|
||||
'Article' => array('id'),
|
||||
'Comment' => array('article_id', 'user_id'),
|
||||
'User' => array('user')
|
||||
);
|
||||
|
||||
$result = $TestModel->saveAll(array(
|
||||
'Article' => array('id' => 2, 'title' => 'I will not save'),
|
||||
'Comment' => array(
|
||||
array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
|
||||
array(
|
||||
'comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2,
|
||||
'User' => array('user' => 'nopassword', 'password' => 'not saved')
|
||||
)
|
||||
)
|
||||
), array('fieldList' => $fieldList, 'deep' => true));
|
||||
|
||||
$result = $TestModel->Comment->User->find('first', array(
|
||||
'conditions' => array('User.user' => 'nopassword'),
|
||||
'fields' => array('user', 'password')
|
||||
));
|
||||
$expected = array(
|
||||
'User' => array(
|
||||
'user' => 'nopassword',
|
||||
'password' => ''
|
||||
)
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -641,6 +641,13 @@ class Attachment extends CakeTestModel {
|
|||
* @var string 'Attachment'
|
||||
*/
|
||||
public $name = 'Attachment';
|
||||
|
||||
/**
|
||||
* belongsTo property
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $belongsTo = array('Comment');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -395,6 +395,8 @@ class CakeEmailTest extends CakeTestCase {
|
|||
$this->CakeEmail->subject('You have a new message.');
|
||||
$this->assertSame($this->CakeEmail->subject(), 'You have a new message.');
|
||||
|
||||
$this->CakeEmail->subject('You have a new message, I think.');
|
||||
$this->assertSame($this->CakeEmail->subject(), 'You have a new message, I think.');
|
||||
$this->CakeEmail->subject(1);
|
||||
$this->assertSame($this->CakeEmail->subject(), '1');
|
||||
|
||||
|
|
|
@ -49,13 +49,15 @@ class DebugTransportTest extends CakeTestCase {
|
|||
$email->bcc('phpnut@cakephp.org');
|
||||
$email->messageID('<4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>');
|
||||
$email->subject('Testing Message');
|
||||
$date = date(DATE_RFC2822);
|
||||
$email->setHeaders(array('X-Mailer' => $email::EMAIL_CLIENT, 'Date' => $date));
|
||||
$email->expects($this->any())->method('message')->will($this->returnValue(array('First Line', 'Second Line', '')));
|
||||
|
||||
$headers = "From: CakePHP Test <noreply@cakephp.org>\r\n";
|
||||
$headers .= "To: CakePHP <cake@cakephp.org>\r\n";
|
||||
$headers .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
|
||||
$headers .= "X-Mailer: CakePHP Email\r\n";
|
||||
$headers .= "Date: " . date(DATE_RFC2822) . "\r\n";
|
||||
$headers .= "Date: " . $date . "\r\n";
|
||||
$headers .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n";
|
||||
$headers .= "Subject: Testing Message\r\n";
|
||||
$headers .= "MIME-Version: 1.0\r\n";
|
||||
|
|
|
@ -220,6 +220,8 @@ class SmtpTransportTest extends CakeTestCase {
|
|||
$email->bcc('phpnut@cakephp.org');
|
||||
$email->messageID('<4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>');
|
||||
$email->subject('Testing SMTP');
|
||||
$date = date(DATE_RFC2822);
|
||||
$email->setHeaders(array('X-Mailer' => $email::EMAIL_CLIENT, 'Date' => $date));
|
||||
$email->expects($this->any())->method('message')->will($this->returnValue(array('First Line', 'Second Line', '')));
|
||||
|
||||
$data = "From: CakePHP Test <noreply@cakephp.org>\r\n";
|
||||
|
@ -227,7 +229,7 @@ class SmtpTransportTest extends CakeTestCase {
|
|||
$data .= "To: CakePHP <cake@cakephp.org>\r\n";
|
||||
$data .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
|
||||
$data .= "X-Mailer: CakePHP Email\r\n";
|
||||
$data .= "Date: " . date(DATE_RFC2822) . "\r\n";
|
||||
$data .= "Date: " . $date . "\r\n";
|
||||
$data .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n";
|
||||
$data .= "Subject: Testing SMTP\r\n";
|
||||
$data .= "MIME-Version: 1.0\r\n";
|
||||
|
|
462
lib/Cake/Test/Case/Utility/CakeNumberTest.php
Normal file
462
lib/Cake/Test/Case/Utility/CakeNumberTest.php
Normal file
|
@ -0,0 +1,462 @@
|
|||
<?php
|
||||
/**
|
||||
* CakeNumberTest file
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
|
||||
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice
|
||||
*
|
||||
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
|
||||
* @package Cake.Test.Case.View.Helper
|
||||
* @since CakePHP(tm) v 1.2.0.4206
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('View', 'View');
|
||||
App::uses('CakeNumber', 'Utility');
|
||||
|
||||
/**
|
||||
* CakeNumberTest class
|
||||
*
|
||||
* @package Cake.Test.Case.Utility
|
||||
*/
|
||||
class CakeNumberTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->Number = new CakeNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown() {
|
||||
parent::tearDown();
|
||||
unset($this->Number);
|
||||
}
|
||||
|
||||
/**
|
||||
* testFormatAndCurrency method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormat() {
|
||||
$value = '100100100';
|
||||
|
||||
$result = $this->Number->format($value, '#');
|
||||
$expected = '#100,100,100';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->format($value, 3);
|
||||
$expected = '100,100,100.000';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->format($value);
|
||||
$expected = '100,100,100';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->format($value, '-');
|
||||
$expected = '100-100-100';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test currency method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrency() {
|
||||
$value = '100100100';
|
||||
|
||||
$result = $this->Number->currency($value);
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, '#');
|
||||
$expected = '#100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, false);
|
||||
$expected = '100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€100.100.100,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '£100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, '', array('thousands' => ' ', 'wholeSymbol' => '€', 'wholePosition' => 'after', 'decimals' => ',', 'zero' => 'Gratuit'));
|
||||
$expected = '100 100 100,00€';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(1000.45, NULL, array('after' => 'øre', 'before' => 'Kr. ', 'decimals' => ',', 'thousands' => '.'));
|
||||
$expected = 'Kr. 1.000,45';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.5, 'USD');
|
||||
$expected = '50c';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.5, NULL, array('after' => 'øre'));
|
||||
$expected = '50øre';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(1, null, array('wholeSymbol' => '$ '));
|
||||
$expected = '$ 1.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(1, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after'));
|
||||
$expected = '1.00 $';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.2, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after', 'fractionSymbol' => 'cents'));
|
||||
$expected = '20cents';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.2, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after', 'fractionSymbol' => 'cents', 'fractionPosition' => 'before'));
|
||||
$expected = 'cents20';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(311, 'USD', array('wholePosition' => 'after'));
|
||||
$expected = '311.00$';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.2, 'EUR');
|
||||
$expected = '€0,20';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(12, null, array('wholeSymbol' => ' dollars', 'wholePosition' => 'after', 'fractionSymbol' => ' cents', 'fractionPosition' => 'after'));
|
||||
$expected = '12.00 dollars';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.12, null, array('wholeSymbol' => ' dollars', 'wholePosition' => 'after', 'fractionSymbol' => ' cents', 'fractionPosition' => 'after'));
|
||||
$expected = '12 cents';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.5, null, array('fractionSymbol' => false, 'fractionPosition' => 'before', 'wholeSymbol' => '$'));
|
||||
$expected = '$0.50';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding currency format options to the number helper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyAddFormat() {
|
||||
$this->Number->addFormat('NOK', array('before' => 'Kr. '));
|
||||
$result = $this->Number->currency(1000, 'NOK');
|
||||
$expected = 'Kr. 1,000.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$this->Number->addFormat('Other', array('before' => '$$ ', 'after' => 'c!'));
|
||||
$result = $this->Number->currency(0.22, 'Other');
|
||||
$expected = '22c!';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(-10, 'Other');
|
||||
$expected = '($$ 10.00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$this->Number->addFormat('Other2', array('before' => '$ ', 'after' => false));
|
||||
$result = $this->Number->currency(0.22, 'Other2');
|
||||
$expected = '$ 0.22';
|
||||
$this->assertEquals($expected,$result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyPositive method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyPositive() {
|
||||
$value = '100100100';
|
||||
|
||||
$result = $this->Number->currency($value);
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD', array('before' => '#'));
|
||||
$expected = '#100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, false);
|
||||
$expected = '100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€100.100.100,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '£100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyNegative method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyNegative() {
|
||||
$value = '-100100100';
|
||||
|
||||
$result = $this->Number->currency($value);
|
||||
$expected = '($100,100,100.00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '(€100.100.100,00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '(£100,100,100.00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD', array('negative' => '-'));
|
||||
$expected = '-$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR', array('negative' => '-'));
|
||||
$expected = '-€100.100.100,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('negative' => '-'));
|
||||
$expected = '-£100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyCentsPositive method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyCentsPositive() {
|
||||
$value = '0.99';
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '99c';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€0,99';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '99p';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyCentsNegative method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyCentsNegative() {
|
||||
$value = '-0.99';
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '(99c)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '(€0,99)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '(99p)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD', array('negative' => '-'));
|
||||
$expected = '-99c';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR', array('negative' => '-'));
|
||||
$expected = '-€0,99';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('negative' => '-'));
|
||||
$expected = '-99p';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyZero method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyZero() {
|
||||
$value = '0';
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '$0.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€0,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '£0.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('zero' => 'FREE!'));
|
||||
$expected = 'FREE!';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyOptions method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyOptions() {
|
||||
$value = '1234567.89';
|
||||
|
||||
$result = $this->Number->currency($value, null, array('before' => 'GBP'));
|
||||
$expected = 'GBP1,234,567.89';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('places' => 0));
|
||||
$expected = '£1,234,568';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('1234567.8912345', null, array('before' => 'GBP', 'places' => 3));
|
||||
$expected = 'GBP1,234,567.891';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('650.120001', null, array('before' => 'GBP', 'places' => 4));
|
||||
$expected = 'GBP650.1200';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('escape' => true));
|
||||
$expected = '&#163;1,234,567.89';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'USD', array('after' => false));
|
||||
$expected = '$0.35';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'GBP', array('after' => false));
|
||||
$expected = '£0.35';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'GBP');
|
||||
$expected = '35p';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'EUR');
|
||||
$expected = '€0,35';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testToReadableSize method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToReadableSize() {
|
||||
$result = $this->Number->toReadableSize(0);
|
||||
$expected = '0 Bytes';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1);
|
||||
$expected = '1 Byte';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(45);
|
||||
$expected = '45 Bytes';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1023);
|
||||
$expected = '1023 Bytes';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024);
|
||||
$expected = '1 KB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*512);
|
||||
$expected = '512 KB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024-1);
|
||||
$expected = '1.00 MB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*512);
|
||||
$expected = '512.00 MB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024-1);
|
||||
$expected = '1.00 GB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*512);
|
||||
$expected = '512.00 GB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024-1);
|
||||
$expected = '1.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024*512);
|
||||
$expected = '512.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024*1024-1);
|
||||
$expected = '1024.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024*1024*1024);
|
||||
$expected = (1024 * 1024) . '.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testToPercentage method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToPercentage() {
|
||||
$result = $this->Number->toPercentage(45, 0);
|
||||
$expected = '45%';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toPercentage(45, 2);
|
||||
$expected = '45.00%';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toPercentage(0, 0);
|
||||
$expected = '0%';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toPercentage(0, 4);
|
||||
$expected = '0.0000%';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
}
|
807
lib/Cake/Test/Case/Utility/CakeTimeTest.php
Normal file
807
lib/Cake/Test/Case/Utility/CakeTimeTest.php
Normal file
|
@ -0,0 +1,807 @@
|
|||
<?php
|
||||
/**
|
||||
* CakeTimeTest file
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
|
||||
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice
|
||||
*
|
||||
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
|
||||
* @package Cake.Test.Case.View.Helper
|
||||
* @since CakePHP(tm) v 1.2.0.4206
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
App::uses('CakeTime', 'Utility');
|
||||
|
||||
/**
|
||||
* CakeTimeTest class
|
||||
*
|
||||
* @package Cake.Test.Case.View.Helper
|
||||
*/
|
||||
class CakeTimeTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->Time = new CakeTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown() {
|
||||
unset($this->Time);
|
||||
}
|
||||
|
||||
/**
|
||||
* testToQuarter method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToQuarter() {
|
||||
$result = $this->Time->toQuarter('2007-12-25');
|
||||
$this->assertEquals($result, 4);
|
||||
|
||||
$result = $this->Time->toQuarter('2007-9-25');
|
||||
$this->assertEquals($result, 3);
|
||||
|
||||
$result = $this->Time->toQuarter('2007-3-25');
|
||||
$this->assertEquals($result, 1);
|
||||
|
||||
$result = $this->Time->toQuarter('2007-3-25', true);
|
||||
$this->assertEquals($result, array('2007-01-01', '2007-03-31'));
|
||||
|
||||
$result = $this->Time->toQuarter('2007-5-25', true);
|
||||
$this->assertEquals($result, array('2007-04-01', '2007-06-30'));
|
||||
|
||||
$result = $this->Time->toQuarter('2007-8-25', true);
|
||||
$this->assertEquals($result, array('2007-07-01', '2007-09-30'));
|
||||
|
||||
$result = $this->Time->toQuarter('2007-12-25', true);
|
||||
$this->assertEquals($result, array('2007-10-01', '2007-12-31'));
|
||||
}
|
||||
|
||||
/**
|
||||
* testTimeAgoInWords method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTimeAgoInWords() {
|
||||
$result = $this->Time->timeAgoInWords('-1 week');
|
||||
$this->assertEquals($result, '1 week ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('+1 week');
|
||||
$this->assertEquals($result, '1 week');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+4 months +2 weeks +3 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '4 months, 2 weeks, 3 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+4 months +2 weeks +2 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '4 months, 2 weeks, 2 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+4 months +2 weeks +1 day'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '4 months, 2 weeks, 1 day');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +2 weeks +1 day'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '3 months, 2 weeks, 1 day');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +2 weeks'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '3 months, 2 weeks');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +1 week +6 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '3 months, 1 week, 6 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 weeks +1 day'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '2 months, 2 weeks, 1 day');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 weeks'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '2 months, 2 weeks');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +1 week +6 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '2 months, 1 week, 6 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+1 month +1 week +6 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '1 month, 1 week, 6 days');
|
||||
|
||||
for ($i = 0; $i < 200; $i ++) {
|
||||
$years = mt_rand(0, 3);
|
||||
$months = mt_rand(0, 11);
|
||||
$weeks = mt_rand(0, 3);
|
||||
$days = mt_rand(0, 6);
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
$seconds = 0;
|
||||
$relative_date = '';
|
||||
|
||||
// Trying to take into account the number of days in a month
|
||||
$month = date('m') - $months;
|
||||
if ($month <= 0) {
|
||||
$month = $months % 12;
|
||||
}
|
||||
$time = mktime(0, 0, 0, $month, 1, date('y') - $years);
|
||||
$diffDays = date('t') - date('t', $time);
|
||||
|
||||
if ($diffDays > 0 && date('j') - date('t', $time) - $days > 0 && $months > 0 && $weeks === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($years > 0) {
|
||||
// years and months and days
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $years . ' year' . ($years > 1 ? 's' : '');
|
||||
$relative_date .= $months > 0 ? ($relative_date ? ', -' : '-') . $months . ' month' . ($months > 1 ? 's' : '') : '';
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', -' : '-') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($months) > 0) {
|
||||
// months, weeks and days
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $months . ' month' . ($months > 1 ? 's' : '');
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', -' : '-') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($weeks) > 0) {
|
||||
// weeks and days
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $weeks . ' week' . ($weeks > 1 ? 's' : '');
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($days) > 0) {
|
||||
// days and hours
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '');
|
||||
$relative_date .= $hours > 0 ? ($relative_date ? ', -' : '-') . $hours . ' hour' . ($hours > 1 ? 's' : '') : '';
|
||||
} elseif (abs($hours) > 0) {
|
||||
// hours and minutes
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $hours . ' hour' . ($hours > 1 ? 's' : '');
|
||||
$relative_date .= $minutes > 0 ? ($relative_date ? ', -' : '-') . $minutes . ' minute' . ($minutes > 1 ? 's' : '') : '';
|
||||
} elseif (abs($minutes) > 0) {
|
||||
// minutes only
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
|
||||
} else {
|
||||
// seconds only
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $seconds . ' second' . ($seconds != 1 ? 's' : '');
|
||||
}
|
||||
|
||||
if (date('j/n/y', strtotime(str_replace(',', '', $relative_date))) != '1/1/70') {
|
||||
$result = $this->Time->timeAgoInWords(strtotime(str_replace(',', '', $relative_date)), array('end' => '8 years'), true);
|
||||
if ($relative_date == '0 seconds') {
|
||||
$relative_date = '0 seconds ago';
|
||||
}
|
||||
|
||||
$relative_date = str_replace('-', '', $relative_date) . ' ago';
|
||||
$this->assertEquals($result, $relative_date);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 200; $i ++) {
|
||||
$years = mt_rand(0, 3);
|
||||
$months = mt_rand(0, 11);
|
||||
$weeks = mt_rand(0, 3);
|
||||
$days = mt_rand(0, 6);
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
$seconds = 0;
|
||||
|
||||
$relative_date = '';
|
||||
|
||||
if ($years > 0) {
|
||||
// years and months and days
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $years . ' year' . ($years > 1 ? 's' : '');
|
||||
$relative_date .= $months > 0 ? ($relative_date ? ', ' : '') . $months . ' month' . ($months > 1 ? 's' : '') : '';
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($months) > 0) {
|
||||
// months, weeks and days
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $months . ' month' . ($months > 1 ? 's' : '');
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($weeks) > 0) {
|
||||
// weeks and days
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '');
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($days) > 0) {
|
||||
// days and hours
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '');
|
||||
$relative_date .= $hours > 0 ? ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '') : '';
|
||||
} elseif (abs($hours) > 0) {
|
||||
// hours and minutes
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '');
|
||||
$relative_date .= $minutes > 0 ? ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '') : '';
|
||||
} elseif (abs($minutes) > 0) {
|
||||
// minutes only
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
|
||||
} else {
|
||||
// seconds only
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $seconds . ' second' . ($seconds != 1 ? 's' : '');
|
||||
}
|
||||
|
||||
if (date('j/n/y', strtotime(str_replace(',', '', $relative_date))) != '1/1/70') {
|
||||
$result = $this->Time->timeAgoInWords(strtotime(str_replace(',', '', $relative_date)), array('end' => '8 years'), true);
|
||||
if ($relative_date == '0 seconds') {
|
||||
$relative_date = '0 seconds ago';
|
||||
}
|
||||
|
||||
$relative_date = str_replace('-', '', $relative_date) . '';
|
||||
$this->assertEquals($result, $relative_date);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 years -5 months -2 days'), array('end' => '3 years'), true);
|
||||
$this->assertEquals($result, '2 years, 5 months, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('2007-9-25');
|
||||
$this->assertEquals($result, 'on 25/9/07');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('2007-9-25', 'Y-m-d');
|
||||
$this->assertEquals($result, 'on 2007-09-25');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('2007-9-25', 'Y-m-d', true);
|
||||
$this->assertEquals($result, 'on 2007-09-25');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 weeks -2 days'), 'Y-m-d', false);
|
||||
$this->assertEquals($result, '2 weeks, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 weeks +2 days'), 'Y-m-d', true);
|
||||
$this->assertRegExp('/^2 weeks, [1|2] day(s)?$/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '1 month'));
|
||||
$this->assertEquals($result, 'on ' . date('j/n/y', strtotime('+2 months +2 days')));
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '3 month'));
|
||||
$this->assertRegExp('/2 months/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +12 days'), array('end' => '3 month'));
|
||||
$this->assertRegExp('/2 months, 1 week/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +5 days'), array('end' => '4 month'));
|
||||
$this->assertEquals($result, '3 months, 5 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 months -2 days'), array('end' => '3 month'));
|
||||
$this->assertEquals($result, '2 months, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 months -2 days'), array('end' => '3 month'));
|
||||
$this->assertEquals($result, '2 months, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '3 month'));
|
||||
$this->assertRegExp('/2 months/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '1 month', 'format' => 'Y-m-d'));
|
||||
$this->assertEquals($result, 'on ' . date('Y-m-d', strtotime('+2 months +2 days')));
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 months -2 days'), array('end' => '1 month', 'format' => 'Y-m-d'));
|
||||
$this->assertEquals($result, 'on ' . date('Y-m-d', strtotime('-2 months -2 days')));
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-13 months -5 days'), array('end' => '2 years'));
|
||||
$this->assertEquals($result, '1 year, 1 month, 5 days ago');
|
||||
|
||||
$fourHours = $this->Time->timeAgoInWords(strtotime('-5 days -2 hours'), array('userOffset' => -4));
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-5 days -2 hours'), array('userOffset' => 4));
|
||||
$this->assertEquals($fourHours, $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 hours'));
|
||||
$expected = '2 hours ago';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-12 minutes'));
|
||||
$expected = '12 minutes ago';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-12 seconds'));
|
||||
$expected = '12 seconds ago';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$time = strtotime('-3 years -12 months');
|
||||
$result = $this->Time->timeAgoInWords($time);
|
||||
$expected = 'on ' . date('j/n/y', $time);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testNice method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNice() {
|
||||
$time = time() + 2 * DAY;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
|
||||
|
||||
$time = time() - 2 * DAY;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
|
||||
|
||||
$time = time();
|
||||
$this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
|
||||
|
||||
$time = 0;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
|
||||
|
||||
$time = null;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
|
||||
|
||||
$time = time();
|
||||
$this->assertEquals(date('D', $time), $this->Time->nice($time, null, '%a'));
|
||||
$this->assertEquals(date('M d, Y', $time), $this->Time->nice($time, null, '%b %d, %Y'));
|
||||
|
||||
$this->Time->niceFormat = '%Y-%d-%m';
|
||||
$this->assertEquals(date('Y-d-m', $time), $this->Time->nice($time));
|
||||
}
|
||||
|
||||
/**
|
||||
* testNiceShort method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNiceShort() {
|
||||
$time = time() + 2 * DAY;
|
||||
if (date('Y', $time) == date('Y')) {
|
||||
$this->assertEquals(date('M jS, H:i', $time), $this->Time->niceShort($time));
|
||||
} else {
|
||||
$this->assertEquals(date('M jS Y, H:i', $time), $this->Time->niceShort($time));
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$this->assertEquals('Today, ' . date('H:i', $time), $this->Time->niceShort($time));
|
||||
|
||||
$time = time() - DAY;
|
||||
$this->assertEquals('Yesterday, ' . date('H:i', $time), $this->Time->niceShort($time));
|
||||
}
|
||||
|
||||
/**
|
||||
* testDaysAsSql method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDaysAsSql() {
|
||||
$begin = time();
|
||||
$end = time() + DAY;
|
||||
$field = 'my_field';
|
||||
$expected = '(my_field >= \''.date('Y-m-d', $begin).' 00:00:00\') AND (my_field <= \''.date('Y-m-d', $end).' 23:59:59\')';
|
||||
$this->assertEquals($expected, $this->Time->daysAsSql($begin, $end, $field));
|
||||
}
|
||||
|
||||
/**
|
||||
* testDayAsSql method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDayAsSql() {
|
||||
$time = time();
|
||||
$field = 'my_field';
|
||||
$expected = '(my_field >= \''.date('Y-m-d', $time).' 00:00:00\') AND (my_field <= \''.date('Y-m-d', $time).' 23:59:59\')';
|
||||
$this->assertEquals($expected, $this->Time->dayAsSql($time, $field));
|
||||
}
|
||||
|
||||
/**
|
||||
* testToUnix method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToUnix() {
|
||||
$this->assertEquals(time(), $this->Time->toUnix(time()));
|
||||
$this->assertEquals(strtotime('+1 day'), $this->Time->toUnix('+1 day'));
|
||||
$this->assertEquals(strtotime('+0 days'), $this->Time->toUnix('+0 days'));
|
||||
$this->assertEquals(strtotime('-1 days'), $this->Time->toUnix('-1 days'));
|
||||
$this->assertEquals(false, $this->Time->toUnix(''));
|
||||
$this->assertEquals(false, $this->Time->toUnix(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* testToAtom method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToAtom() {
|
||||
$this->assertEquals(date('Y-m-d\TH:i:s\Z'), $this->Time->toAtom(time()));
|
||||
}
|
||||
|
||||
/**
|
||||
* testToRss method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToRss() {
|
||||
$this->assertEquals(date('r'), $this->Time->toRss(time()));
|
||||
|
||||
if (!$this->skipIf(!class_exists('DateTimeZone'), '%s DateTimeZone class not available.')) {
|
||||
$timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
|
||||
foreach ($timezones as $timezone) {
|
||||
$yourTimezone = new DateTimeZone($timezone);
|
||||
$yourTime = new DateTime('now', $yourTimezone);
|
||||
$userOffset = $yourTimezone->getOffset($yourTime) / HOUR;
|
||||
$this->assertEquals($yourTime->format('r'), $this->Time->toRss(time(), $userOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* testFormat method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormat() {
|
||||
$format = 'D-M-Y';
|
||||
$arr = array(time(), strtotime('+1 days'), strtotime('+1 days'), strtotime('+0 days'));
|
||||
foreach ($arr as $val) {
|
||||
$this->assertEquals(date($format, $val), $this->Time->format($format, $val));
|
||||
}
|
||||
|
||||
$result = $this->Time->format('Y-m-d', null, 'never');
|
||||
$this->assertEquals($result, 'never');
|
||||
}
|
||||
|
||||
/**
|
||||
* testOfGmt method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGmt() {
|
||||
$hour = 3;
|
||||
$min = 4;
|
||||
$sec = 2;
|
||||
$month = 5;
|
||||
$day = 14;
|
||||
$year = 2007;
|
||||
$time = mktime($hour, $min, $sec, $month, $day, $year);
|
||||
$expected = gmmktime($hour, $min, $sec, $month, $day, $year);
|
||||
$this->assertEquals($expected, $this->Time->gmt(date('Y-n-j G:i:s', $time)));
|
||||
|
||||
$hour = date('H');
|
||||
$min = date('i');
|
||||
$sec = date('s');
|
||||
$month = date('m');
|
||||
$day = date('d');
|
||||
$year = date('Y');
|
||||
$expected = gmmktime($hour, $min, $sec, $month, $day, $year);
|
||||
$this->assertEquals($expected, $this->Time->gmt(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsToday method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsToday() {
|
||||
$result = $this->Time->isToday('+1 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isToday('+1 days');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isToday('+0 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isToday('-1 day');
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsThisWeek method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsThisWeek() {
|
||||
// A map of days which goes from -1 day of week to +1 day of week
|
||||
$map = array(
|
||||
'Mon' => array(-1, 7), 'Tue' => array(-2, 6), 'Wed' => array(-3, 5),
|
||||
'Thu' => array(-4, 4), 'Fri' => array(-5, 3), 'Sat' => array(-6, 2),
|
||||
'Sun' => array(-7, 1)
|
||||
);
|
||||
$days = $map[date('D')];
|
||||
|
||||
for ($day = $days[0] + 1; $day < $days[1]; $day++) {
|
||||
$this->assertTrue($this->Time->isThisWeek(($day > 0 ? '+' : '') . $day . ' days'));
|
||||
}
|
||||
$this->assertFalse($this->Time->isThisWeek($days[0] . ' days'));
|
||||
$this->assertFalse($this->Time->isThisWeek('+' . $days[1] . ' days'));
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsThisMonth method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsThisMonth() {
|
||||
$result = $this->Time->isThisMonth('+0 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isThisMonth($time = mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y')));
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') - mt_rand(1, 12)));
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') + mt_rand(1, 12)));
|
||||
$this->assertFalse($result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsThisYear method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsThisYear() {
|
||||
$result = $this->Time->isThisYear('+0 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isThisYear(mktime(0, 0, 0, mt_rand(1, 12), mt_rand(1, 28), date('Y')));
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testWasYesterday method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testWasYesterday() {
|
||||
$result = $this->Time->wasYesterday('+1 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->wasYesterday('+1 days');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->wasYesterday('+0 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->wasYesterday('-1 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->wasYesterday('-1 days');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->wasYesterday('-2 days');
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsTomorrow method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsTomorrow() {
|
||||
$result = $this->Time->isTomorrow('+1 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isTomorrow('+1 days');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isTomorrow('+0 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isTomorrow('-1 day');
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testWasWithinLast method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testWasWithinLast() {
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 week', '-1 week'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 second', '-1 second'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 minute', '-1 minute'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 month', '-1 month'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
|
||||
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 week', '-1 day'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('2 week', '-1 week'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 second', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('10 minutes', '-1 second'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('23 minutes', '-1 minute'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('0 year', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('13 month', '-1 month'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('2 days', '-1 day'));
|
||||
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 week', '-2 weeks'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 second', '-2 seconds'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 hour', '-2 hours'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 month', '-2 months'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 year', '-2 years'));
|
||||
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 day', '-2 weeks'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('0 days', '-2 days'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 hour', '-20 seconds'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 year', '-60 minutes -30 seconds'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('3 years', '-2 months'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('5 months', '-4 months'));
|
||||
|
||||
$this->assertTrue($this->Time->wasWithinLast('5 ', '-3 days'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 ', '-1 hour'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 ', '-1 minute'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 ', '-23 hours -59 minutes -59 seconds'));
|
||||
}
|
||||
|
||||
/**
|
||||
* testUserOffset method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUserOffset() {
|
||||
$timezoneServer = new DateTimeZone(date_default_timezone_get());
|
||||
$timeServer = new DateTime('now', $timezoneServer);
|
||||
$yourTimezone = $timezoneServer->getOffset($timeServer) / HOUR;
|
||||
|
||||
$expected = time();
|
||||
$result = $this->Time->fromString(time(), $yourTimezone);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test fromString()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFromString() {
|
||||
$result = $this->Time->fromString('');
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $this->Time->fromString(0, 0);
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $this->Time->fromString('+1 hour');
|
||||
$expected = strtotime('+1 hour');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$timezone = date('Z', time());
|
||||
$result = $this->Time->fromString('+1 hour', $timezone);
|
||||
$expected = $this->Time->convert(strtotime('+1 hour'), $timezone);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test converting time specifiers using a time definition localfe file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConvertSpecifiers() {
|
||||
App::build(array(
|
||||
'locales' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
|
||||
), true);
|
||||
Configure::write('Config.language', 'time_test');
|
||||
$time = strtotime('Thu Jan 14 11:43:39 2010');
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%a', $time);
|
||||
$expected = 'jue';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%A', $time);
|
||||
$expected = 'jueves';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%c', $time);
|
||||
$expected = 'jue %d ene %Y %H:%M:%S %Z';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%C', $time);
|
||||
$expected = '20';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%D', $time);
|
||||
$expected = '%m/%d/%y';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%b', $time);
|
||||
$expected = 'ene';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%h', $time);
|
||||
$expected = 'ene';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%B', $time);
|
||||
$expected = 'enero';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%n', $time);
|
||||
$expected = "\n";
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%n', $time);
|
||||
$expected = "\n";
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%p', $time);
|
||||
$expected = 'AM';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%P', $time);
|
||||
$expected = 'am';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%r', $time);
|
||||
$expected = '%I:%M:%S AM';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%R', $time);
|
||||
$expected = '11:43';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%t', $time);
|
||||
$expected = "\t";
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%T', $time);
|
||||
$expected = '%H:%M:%S';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%u', $time);
|
||||
$expected = 4;
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%x', $time);
|
||||
$expected = '%d/%m/%y';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%X', $time);
|
||||
$expected = '%H:%M:%S';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test convert %e on windows.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConvertPercentE() {
|
||||
$this->skipIf(DIRECTORY_SEPARATOR !== '\\', 'Cannot run windows tests on non-windows OS.');
|
||||
|
||||
$time = strtotime('Thu Jan 14 11:43:39 2010');
|
||||
$result = $this->Time->convertSpecifiers('%e', $time);
|
||||
$expected = '14';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%e', strtotime('2011-01-01'));
|
||||
$expected = ' 1';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test formatting dates taking in account preferred i18n locale file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testI18nFormat() {
|
||||
App::build(array(
|
||||
'locales' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
|
||||
), true);
|
||||
Configure::write('Config.language', 'time_test');
|
||||
|
||||
$time = strtotime('Thu Jan 14 13:59:28 2010');
|
||||
|
||||
$result = $this->Time->i18nFormat($time);
|
||||
$expected = '14/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, '%c');
|
||||
$expected = 'jue 14 ene 2010 13:59:28 ' . strftime('%Z', $time);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
|
||||
$expected = 'Time is 01:59:28 PM, and date is 14/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$time = strtotime('Wed Jan 13 13:59:28 2010');
|
||||
|
||||
$result = $this->Time->i18nFormat($time);
|
||||
$expected = '13/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, '%c');
|
||||
$expected = 'mié 13 ene 2010 13:59:28 ' . strftime('%Z', $time);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
|
||||
$expected = 'Time is 01:59:28 PM, and date is 13/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat('invalid date', '%x', 'Date invalid');
|
||||
$expected = 'Date invalid';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test new format() syntax which inverts first and secod parameters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormatNewSyntax() {
|
||||
$time = time();
|
||||
$this->assertEquals($this->Time->format($time), $this->Time->i18nFormat($time));
|
||||
$this->assertEquals($this->Time->format($time, '%c'), $this->Time->i18nFormat($time, '%c'));
|
||||
}
|
||||
}
|
|
@ -25,6 +25,16 @@ App::uses('String', 'Utility');
|
|||
*/
|
||||
class StringTest extends CakeTestCase {
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->Text = new String();
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
parent::tearDown();
|
||||
unset($this->Text);
|
||||
}
|
||||
|
||||
/**
|
||||
* testUuidGeneration method
|
||||
*
|
||||
|
@ -344,4 +354,291 @@ This is the song that never ends.
|
|||
TEXT;
|
||||
$this->assertTextEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testTruncate method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTruncate() {
|
||||
$text1 = 'The quick brown fox jumps over the lazy dog';
|
||||
$text2 = 'Heizölrückstoßabdämpfung';
|
||||
$text3 = '<b>© 2005-2007, Cake Software Foundation, Inc.</b><br />written by Alexander Wegener';
|
||||
$text4 = '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But the following image tag should be conform <img src="mypic.jpg" alt="Me, myself and I" /></b><br />Great, or?';
|
||||
$text5 = '0<b>1<i>2<span class="myclass">3</span>4<u>5</u>6</i>7</b>8<b>9</b>0';
|
||||
$text6 = '<p><strong>Extra dates have been announced for this year\'s tour.</strong></p><p>Tickets for the new shows in</p>';
|
||||
$text7 = 'El moño está en el lugar correcto. Eso fue lo que dijo la niña, ¿habrá dicho la verdad?';
|
||||
$text8 = 'Vive la R' . chr(195) . chr(169) . 'publique de France';
|
||||
$text9 = 'НОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
|
||||
|
||||
$this->assertSame($this->Text->truncate($text1, 15), 'The quick br...');
|
||||
$this->assertSame($this->Text->truncate($text1, 15, array('exact' => false)), 'The quick...');
|
||||
$this->assertSame($this->Text->truncate($text1, 100), 'The quick brown fox jumps over the lazy dog');
|
||||
$this->assertSame($this->Text->truncate($text2, 10), 'Heiz&ou...');
|
||||
$this->assertSame($this->Text->truncate($text2, 10, array('exact' => false)), '...');
|
||||
$this->assertSame($this->Text->truncate($text3, 20), '<b>© 2005-20...');
|
||||
$this->assertSame($this->Text->truncate($text4, 15), '<img src="my...');
|
||||
$this->assertSame($this->Text->truncate($text5, 6, array('ending' => '')), '0<b>1<');
|
||||
$this->assertSame($this->Text->truncate($text1, 15, array('html' => true)), 'The quick br...');
|
||||
$this->assertSame($this->Text->truncate($text1, 15, array('exact' => false, 'html' => true)), 'The quick...');
|
||||
$this->assertSame($this->Text->truncate($text2, 10, array('html' => true)), 'Heizölr...');
|
||||
$this->assertSame($this->Text->truncate($text2, 10, array('exact' => false, 'html' => true)), '...');
|
||||
$this->assertSame($this->Text->truncate($text3, 20, array('html' => true)), '<b>© 2005-2007, Cake...</b>');
|
||||
$this->assertSame($this->Text->truncate($text4, 15, array('html' => true)), '<img src="mypic.jpg"> This image ...');
|
||||
$this->assertSame($this->Text->truncate($text4, 45, array('html' => true)), '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But t...</b>');
|
||||
$this->assertSame($this->Text->truncate($text4, 90, array('html' => true)), '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But the following image tag should be conform <img src="mypic.jpg" alt="Me, myself and I" /></b><br />Grea...');
|
||||
$this->assertSame($this->Text->truncate($text5, 6, array('ending' => '', 'html' => true)), '0<b>1<i>2<span class="myclass">3</span>4<u>5</u></i></b>');
|
||||
$this->assertSame($this->Text->truncate($text5, 20, array('ending' => '', 'html' => true)), $text5);
|
||||
$this->assertSame($this->Text->truncate($text6, 57, array('exact' => false, 'html' => true)), "<p><strong>Extra dates have been announced for this year's...</strong></p>");
|
||||
$this->assertSame($this->Text->truncate($text7, 255), $text7);
|
||||
$this->assertSame($this->Text->truncate($text7, 15), 'El moño está...');
|
||||
$this->assertSame($this->Text->truncate($text8, 15), 'Vive la R'.chr(195).chr(169).'pu...');
|
||||
$this->assertSame($this->Text->truncate($text9, 10), 'НОПРСТУ...');
|
||||
|
||||
$text = '<p><span style="font-size: medium;"><a>Iamatestwithnospacesandhtml</a></span></p>';
|
||||
$result = $this->Text->truncate($text, 10, array(
|
||||
'ending' => '...',
|
||||
'exact' => false,
|
||||
'html' => true
|
||||
));
|
||||
$expected = '<p><span style="font-size: medium;"><a>...</a></span></p>';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
|
||||
Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
|
||||
este artículo de El País.</span></p>
|
||||
<p><span style="font-size: medium;"><span style="font-size:
|
||||
large;">Por qué Steve era distinto.</span></span></p>
|
||||
<p><span style="font-size: medium;"><a href="http://www.elpais.com/
|
||||
articulo/primer/plano/Steve/era/distinto/elpepueconeg/
|
||||
20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
|
||||
Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
|
||||
<p><span style="font-size: medium;">Ya se ha publicado la biografía de
|
||||
Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
|
||||
Isaacson</strong>", aquí os dejamos la dirección de amazon donde
|
||||
podeís adquirirla.</span></p>
|
||||
<p><span style="font-size: medium;"><a>http://www.amazon.com/Steve-
|
||||
Jobs-Walter-Isaacson/dp/1451648537</a></span></p>';
|
||||
$result = $this->Text->truncate($text, 500, array(
|
||||
'ending' => '... ',
|
||||
'exact' => false,
|
||||
'html' => true
|
||||
));
|
||||
$expected = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
|
||||
Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
|
||||
este artículo de El País.</span></p>
|
||||
<p><span style="font-size: medium;"><span style="font-size:
|
||||
large;">Por qué Steve era distinto.</span></span></p>
|
||||
<p><span style="font-size: medium;"><a href="http://www.elpais.com/
|
||||
articulo/primer/plano/Steve/era/distinto/elpepueconeg/
|
||||
20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
|
||||
Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
|
||||
<p><span style="font-size: medium;">Ya se ha publicado la biografía de
|
||||
Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
|
||||
Isaacson</strong>", aquí os dejamos la dirección de amazon donde
|
||||
podeís adquirirla.</span></p>
|
||||
<p><span style="font-size: medium;"><a>... </a></span></p>';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlight method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlight() {
|
||||
$text = 'This is a test text';
|
||||
$phrases = array('This', 'text');
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$expected = '<b>This</b> is a test <b>text</b>';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This is a test text';
|
||||
$phrases = null;
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($result, $text);
|
||||
|
||||
$text = 'This is a (test) text';
|
||||
$phrases = '(test';
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals('This is a <b>(test</b>) text', $result);
|
||||
|
||||
$text = 'Ich saß in einem Café am Übergang';
|
||||
$expected = 'Ich <b>saß</b> in einem <b>Café</b> am <b>Übergang</b>';
|
||||
$phrases = array('saß', 'café', 'übergang');
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlightHtml method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlightHtml() {
|
||||
$text1 = '<p>strongbow isn’t real cider</p>';
|
||||
$text2 = '<p>strongbow <strong>isn’t</strong> real cider</p>';
|
||||
$text3 = '<img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
|
||||
$text4 = 'What a strong mouse: <img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
|
||||
$options = array('format' => '<b>\1</b>', 'html' => true);
|
||||
|
||||
$expected = '<p><b>strong</b>bow isn’t real cider</p>';
|
||||
$this->assertEquals($this->Text->highlight($text1, 'strong', $options), $expected);
|
||||
|
||||
$expected = '<p><b>strong</b>bow <strong>isn’t</strong> real cider</p>';
|
||||
$this->assertEquals($this->Text->highlight($text2, 'strong', $options), $expected);
|
||||
|
||||
$this->assertEquals($this->Text->highlight($text3, 'strong', $options), $text3);
|
||||
|
||||
$this->assertEquals($this->Text->highlight($text3, array('strong', 'what'), $options), $text3);
|
||||
|
||||
$expected = '<b>What</b> a <b>strong</b> mouse: <img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
|
||||
$this->assertEquals($this->Text->highlight($text4, array('strong', 'what'), $options), $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlightMulti method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlightMulti() {
|
||||
$text = 'This is a test text';
|
||||
$phrases = array('This', 'text');
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => array('<b>\1</b>', '<em>\1</em>')));
|
||||
$expected = '<b>This</b> is a test <em>text</em>';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* testStripLinks method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testStripLinks() {
|
||||
$text = 'This is a test text';
|
||||
$expected = 'This is a test text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This is a <a href="#">test</a> text';
|
||||
$expected = 'This is a test text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This <strong>is</strong> a <a href="#">test</a> <a href="#">text</a>';
|
||||
$expected = 'This <strong>is</strong> a test text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This <strong>is</strong> a <a href="#">test</a> and <abbr>some</abbr> other <a href="#">text</a>';
|
||||
$expected = 'This <strong>is</strong> a test and <abbr>some</abbr> other text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlightCaseInsensitivity method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlightCaseInsensitivity() {
|
||||
$text = 'This is a Test text';
|
||||
$expected = 'This is a <b>Test</b> text';
|
||||
|
||||
$result = $this->Text->highlight($text, 'test', array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Text->highlight($text, array('test'), array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testExcerpt method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExcerpt() {
|
||||
$text = 'This is a phrase with test text to play with';
|
||||
|
||||
$expected = '...ase with test text to ...';
|
||||
$result = $this->Text->excerpt($text, 'test', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = 'This is a...';
|
||||
$result = $this->Text->excerpt($text, 'not_found', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = 'This is a phras...';
|
||||
$result = $this->Text->excerpt($text, null, 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = $text;
|
||||
$result = $this->Text->excerpt($text, null, 200, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = '...a phrase w...';
|
||||
$result = $this->Text->excerpt($text, 'phrase', 2, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$phrase = 'This is a phrase with test text';
|
||||
$expected = $text;
|
||||
$result = $this->Text->excerpt($text, $phrase, 13, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'aaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
$phrase = 'bbbbbbbb';
|
||||
$result = $this->Text->excerpt($text, $phrase, 10);
|
||||
$expected = '...aaaaaaaaaabbbbbbbbaaaaaaaaaa...';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testExcerptCaseInsensitivity method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExcerptCaseInsensitivity() {
|
||||
$text = 'This is a phrase with test text to play with';
|
||||
|
||||
$expected = '...ase with test text to ...';
|
||||
$result = $this->Text->excerpt($text, 'TEST', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = 'This is a...';
|
||||
$result = $this->Text->excerpt($text, 'NOT_FOUND', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testListGeneration method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testListGeneration() {
|
||||
$result = $this->Text->toList(array());
|
||||
$this->assertEquals($result, '');
|
||||
|
||||
$result = $this->Text->toList(array('One'));
|
||||
$this->assertEquals($result, 'One');
|
||||
|
||||
$result = $this->Text->toList(array('Larry', 'Curly', 'Moe'));
|
||||
$this->assertEquals($result, 'Larry, Curly and Moe');
|
||||
|
||||
$result = $this->Text->toList(array('Dusty', 'Lucky', 'Ned'), 'y');
|
||||
$this->assertEquals($result, 'Dusty, Lucky y Ned');
|
||||
|
||||
$result = $this->Text->toList(array(1 => 'Dusty', 2 => 'Lucky', 3 => 'Ned'), 'y');
|
||||
$this->assertEquals($result, 'Dusty, Lucky y Ned');
|
||||
|
||||
$result = $this->Text->toList(array(1 => 'Dusty', 2 => 'Lucky', 3 => 'Ned'), 'and', ' + ');
|
||||
$this->assertEquals($result, 'Dusty + Lucky and Ned');
|
||||
|
||||
$result = $this->Text->toList(array('name1' => 'Dusty', 'name2' => 'Lucky'));
|
||||
$this->assertEquals($result, 'Dusty and Lucky');
|
||||
|
||||
$result = $this->Text->toList(array('test_0' => 'banana', 'test_1' => 'apple', 'test_2' => 'lemon'));
|
||||
$this->assertEquals($result, 'banana, apple and lemon');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1462,6 +1462,31 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->assertEquals(array(), $this->Form->fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* testTagIsInvalid method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTagIsInvalid() {
|
||||
$Contact = ClassRegistry::getObject('Contact');
|
||||
$Contact->validationErrors[0]['email'] = array('Please provide an email');
|
||||
|
||||
$this->Form->setEntity('Contact.0.email');
|
||||
$result = $this->Form->tagIsInvalid();
|
||||
$expected = array('Please provide an email');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$this->Form->setEntity('Contact.1.email');
|
||||
$result = $this->Form->tagIsInvalid();
|
||||
$expected = false;
|
||||
$this->assertIdentical($expected, $result);
|
||||
|
||||
$this->Form->setEntity('Contact.0.name');
|
||||
$result = $this->Form->tagIsInvalid();
|
||||
$expected = false;
|
||||
$this->assertIdentical($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testPasswordValidation method
|
||||
*
|
||||
|
|
|
@ -1725,7 +1725,7 @@ class HtmlHelperTest extends CakeTestCase {
|
|||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$result = $this->Html->media('video.ogv', array('type' => 'video'));
|
||||
$result = $this->Html->media('video.ogv', array('tag' => 'video'));
|
||||
$expected = array('video' => array('src' => 'files/video.ogv'), '/video');
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
|
@ -1743,6 +1743,13 @@ class HtmlHelperTest extends CakeTestCase {
|
|||
'/video'
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$result = $this->Html->media(null, array('src' => 'video.webm'));
|
||||
$expected = array(
|
||||
'video' => array('src' => 'files/video.webm'),
|
||||
'/video'
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,6 +20,17 @@
|
|||
App::uses('View', 'View');
|
||||
App::uses('NumberHelper', 'View/Helper');
|
||||
|
||||
/**
|
||||
* NumberHelperTestObject class
|
||||
*/
|
||||
class NumberHelperTestObject extends NumberHelper {
|
||||
|
||||
public function attach(CakeNumber $cakeNumber) {
|
||||
$this->_CakeNumber = $cakeNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* NumberHelperTest class
|
||||
*
|
||||
|
@ -27,13 +38,6 @@ App::uses('NumberHelper', 'View/Helper');
|
|||
*/
|
||||
class NumberHelperTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* helper property
|
||||
*
|
||||
* @var mixed null
|
||||
*/
|
||||
public $helper = null;
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
|
@ -42,7 +46,9 @@ class NumberHelperTest extends CakeTestCase {
|
|||
public function setUp() {
|
||||
parent::setUp();
|
||||
$view = $this->getMock('View', array(), array(), '', false);
|
||||
$this->Number = new NumberHelper($view);
|
||||
$this->CakeNumber = $this->getMock('CakeNumber');
|
||||
$this->Number = new NumberHelperTestObject($view);
|
||||
$this->Number->attach($this->CakeNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,416 +61,19 @@ class NumberHelperTest extends CakeTestCase {
|
|||
unset($this->Number);
|
||||
}
|
||||
|
||||
/**
|
||||
* testFormatAndCurrency method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormat() {
|
||||
$value = '100100100';
|
||||
|
||||
$result = $this->Number->format($value, '#');
|
||||
$expected = '#100,100,100';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->format($value, 3);
|
||||
$expected = '100,100,100.000';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->format($value);
|
||||
$expected = '100,100,100';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->format($value, '-');
|
||||
$expected = '100-100-100';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test currency method.
|
||||
*
|
||||
* @return void
|
||||
* test CakeNumber class methods are called correctly
|
||||
*/
|
||||
public function testCurrency() {
|
||||
$value = '100100100';
|
||||
|
||||
$result = $this->Number->currency($value);
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, '#');
|
||||
$expected = '#100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, false);
|
||||
$expected = '100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€100.100.100,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '£100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, '', array('thousands' => ' ', 'wholeSymbol' => '€', 'wholePosition' => 'after', 'decimals' => ',', 'zero' => 'Gratuit'));
|
||||
$expected = '100 100 100,00€';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(1000.45, NULL, array('after' => 'øre', 'before' => 'Kr. ', 'decimals' => ',', 'thousands' => '.'));
|
||||
$expected = 'Kr. 1.000,45';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.5, 'USD');
|
||||
$expected = '50c';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.5, NULL, array('after' => 'øre'));
|
||||
$expected = '50øre';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(1, null, array('wholeSymbol' => '$ '));
|
||||
$expected = '$ 1.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(1, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after'));
|
||||
$expected = '1.00 $';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.2, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after', 'fractionSymbol' => 'cents'));
|
||||
$expected = '20cents';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.2, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after', 'fractionSymbol' => 'cents', 'fractionPosition' => 'before'));
|
||||
$expected = 'cents20';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(311, 'USD', array('wholePosition' => 'after'));
|
||||
$expected = '311.00$';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.2, 'EUR');
|
||||
$expected = '€0,20';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(12, null, array('wholeSymbol' => ' dollars', 'wholePosition' => 'after', 'fractionSymbol' => ' cents', 'fractionPosition' => 'after'));
|
||||
$expected = '12.00 dollars';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.12, null, array('wholeSymbol' => ' dollars', 'wholePosition' => 'after', 'fractionSymbol' => ' cents', 'fractionPosition' => 'after'));
|
||||
$expected = '12 cents';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(0.5, null, array('fractionSymbol' => false, 'fractionPosition' => 'before', 'wholeSymbol' => '$'));
|
||||
$expected = '$0.50';
|
||||
$this->assertEquals($expected, $result);
|
||||
public function testNumberHelperProxyMethodCalls() {
|
||||
$methods = array(
|
||||
'precision', 'toReadableSize', 'toPercentage', 'format',
|
||||
'currency', 'addFormat',
|
||||
);
|
||||
foreach ($methods as $method) {
|
||||
$this->CakeNumber->expects($this->at(0))->method($method);
|
||||
$this->Number->{$method}('who', 'what', 'when', 'where', 'how');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding currency format options to the number helper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyAddFormat() {
|
||||
$this->Number->addFormat('NOK', array('before' => 'Kr. '));
|
||||
$result = $this->Number->currency(1000, 'NOK');
|
||||
$expected = 'Kr. 1,000.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$this->Number->addFormat('Other', array('before' => '$$ ', 'after' => 'c!'));
|
||||
$result = $this->Number->currency(0.22, 'Other');
|
||||
$expected = '22c!';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency(-10, 'Other');
|
||||
$expected = '($$ 10.00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$this->Number->addFormat('Other2', array('before' => '$ ', 'after' => false));
|
||||
$result = $this->Number->currency(0.22, 'Other2');
|
||||
$expected = '$ 0.22';
|
||||
$this->assertEquals($expected,$result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyPositive method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyPositive() {
|
||||
$value = '100100100';
|
||||
|
||||
$result = $this->Number->currency($value);
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD', array('before' => '#'));
|
||||
$expected = '#100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, false);
|
||||
$expected = '100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€100.100.100,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '£100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyNegative method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyNegative() {
|
||||
$value = '-100100100';
|
||||
|
||||
$result = $this->Number->currency($value);
|
||||
$expected = '($100,100,100.00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '(€100.100.100,00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '(£100,100,100.00)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD', array('negative' => '-'));
|
||||
$expected = '-$100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR', array('negative' => '-'));
|
||||
$expected = '-€100.100.100,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('negative' => '-'));
|
||||
$expected = '-£100,100,100.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyCentsPositive method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyCentsPositive() {
|
||||
$value = '0.99';
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '99c';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€0,99';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '99p';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyCentsNegative method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyCentsNegative() {
|
||||
$value = '-0.99';
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '(99c)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '(€0,99)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '(99p)';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'USD', array('negative' => '-'));
|
||||
$expected = '-99c';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR', array('negative' => '-'));
|
||||
$expected = '-€0,99';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('negative' => '-'));
|
||||
$expected = '-99p';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyZero method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyZero() {
|
||||
$value = '0';
|
||||
|
||||
$result = $this->Number->currency($value, 'USD');
|
||||
$expected = '$0.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'EUR');
|
||||
$expected = '€0,00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP');
|
||||
$expected = '£0.00';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('zero' => 'FREE!'));
|
||||
$expected = 'FREE!';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCurrencyOptions method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCurrencyOptions() {
|
||||
$value = '1234567.89';
|
||||
|
||||
$result = $this->Number->currency($value, null, array('before' => 'GBP'));
|
||||
$expected = 'GBP1,234,567.89';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('places' => 0));
|
||||
$expected = '£1,234,568';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('1234567.8912345', null, array('before' => 'GBP', 'places' => 3));
|
||||
$expected = 'GBP1,234,567.891';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('650.120001', null, array('before' => 'GBP', 'places' => 4));
|
||||
$expected = 'GBP650.1200';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency($value, 'GBP', array('escape' => true));
|
||||
$expected = '&#163;1,234,567.89';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'USD', array('after' => false));
|
||||
$expected = '$0.35';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'GBP', array('after' => false));
|
||||
$expected = '£0.35';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'GBP');
|
||||
$expected = '35p';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->currency('0.35', 'EUR');
|
||||
$expected = '€0,35';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testToReadableSize method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToReadableSize() {
|
||||
$result = $this->Number->toReadableSize(0);
|
||||
$expected = '0 Bytes';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1);
|
||||
$expected = '1 Byte';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(45);
|
||||
$expected = '45 Bytes';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1023);
|
||||
$expected = '1023 Bytes';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024);
|
||||
$expected = '1 KB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*512);
|
||||
$expected = '512 KB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024-1);
|
||||
$expected = '1.00 MB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*512);
|
||||
$expected = '512.00 MB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024-1);
|
||||
$expected = '1.00 GB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*512);
|
||||
$expected = '512.00 GB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024-1);
|
||||
$expected = '1.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024*512);
|
||||
$expected = '512.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024*1024-1);
|
||||
$expected = '1024.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toReadableSize(1024*1024*1024*1024*1024*1024);
|
||||
$expected = (1024 * 1024) . '.00 TB';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testToPercentage method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToPercentage() {
|
||||
$result = $this->Number->toPercentage(45, 0);
|
||||
$expected = '45%';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toPercentage(45, 2);
|
||||
$expected = '45.00%';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toPercentage(0, 0);
|
||||
$expected = '0%';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Number->toPercentage(0, 4);
|
||||
$expected = '0.0000%';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
App::uses('View', 'View');
|
||||
App::uses('TextHelper', 'View/Helper');
|
||||
|
||||
class TextHelperTestObject extends TextHelper {
|
||||
|
||||
public function attach(String $string) {
|
||||
$this->_String = $string;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TextHelperTest class
|
||||
*
|
||||
|
@ -48,185 +56,20 @@ class TextHelperTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* testTruncate method
|
||||
*
|
||||
* @return void
|
||||
* test String class methods are called correctly
|
||||
*/
|
||||
public function testTruncate() {
|
||||
$text1 = 'The quick brown fox jumps over the lazy dog';
|
||||
$text2 = 'Heizölrückstoßabdämpfung';
|
||||
$text3 = '<b>© 2005-2007, Cake Software Foundation, Inc.</b><br />written by Alexander Wegener';
|
||||
$text4 = '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But the following image tag should be conform <img src="mypic.jpg" alt="Me, myself and I" /></b><br />Great, or?';
|
||||
$text5 = '0<b>1<i>2<span class="myclass">3</span>4<u>5</u>6</i>7</b>8<b>9</b>0';
|
||||
$text6 = '<p><strong>Extra dates have been announced for this year\'s tour.</strong></p><p>Tickets for the new shows in</p>';
|
||||
$text7 = 'El moño está en el lugar correcto. Eso fue lo que dijo la niña, ¿habrá dicho la verdad?';
|
||||
$text8 = 'Vive la R' . chr(195) . chr(169) . 'publique de France';
|
||||
$text9 = 'НОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
|
||||
|
||||
$this->assertSame($this->Text->truncate($text1, 15), 'The quick br...');
|
||||
$this->assertSame($this->Text->truncate($text1, 15, array('exact' => false)), 'The quick...');
|
||||
$this->assertSame($this->Text->truncate($text1, 100), 'The quick brown fox jumps over the lazy dog');
|
||||
$this->assertSame($this->Text->truncate($text2, 10), 'Heiz&ou...');
|
||||
$this->assertSame($this->Text->truncate($text2, 10, array('exact' => false)), '...');
|
||||
$this->assertSame($this->Text->truncate($text3, 20), '<b>© 2005-20...');
|
||||
$this->assertSame($this->Text->truncate($text4, 15), '<img src="my...');
|
||||
$this->assertSame($this->Text->truncate($text5, 6, array('ending' => '')), '0<b>1<');
|
||||
$this->assertSame($this->Text->truncate($text1, 15, array('html' => true)), 'The quick br...');
|
||||
$this->assertSame($this->Text->truncate($text1, 15, array('exact' => false, 'html' => true)), 'The quick...');
|
||||
$this->assertSame($this->Text->truncate($text2, 10, array('html' => true)), 'Heizölr...');
|
||||
$this->assertSame($this->Text->truncate($text2, 10, array('exact' => false, 'html' => true)), '...');
|
||||
$this->assertSame($this->Text->truncate($text3, 20, array('html' => true)), '<b>© 2005-2007, Cake...</b>');
|
||||
$this->assertSame($this->Text->truncate($text4, 15, array('html' => true)), '<img src="mypic.jpg"> This image ...');
|
||||
$this->assertSame($this->Text->truncate($text4, 45, array('html' => true)), '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But t...</b>');
|
||||
$this->assertSame($this->Text->truncate($text4, 90, array('html' => true)), '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But the following image tag should be conform <img src="mypic.jpg" alt="Me, myself and I" /></b><br />Grea...');
|
||||
$this->assertSame($this->Text->truncate($text5, 6, array('ending' => '', 'html' => true)), '0<b>1<i>2<span class="myclass">3</span>4<u>5</u></i></b>');
|
||||
$this->assertSame($this->Text->truncate($text5, 20, array('ending' => '', 'html' => true)), $text5);
|
||||
$this->assertSame($this->Text->truncate($text6, 57, array('exact' => false, 'html' => true)), "<p><strong>Extra dates have been announced for this year's...</strong></p>");
|
||||
$this->assertSame($this->Text->truncate($text7, 255), $text7);
|
||||
$this->assertSame($this->Text->truncate($text7, 15), 'El moño está...');
|
||||
$this->assertSame($this->Text->truncate($text8, 15), 'Vive la R'.chr(195).chr(169).'pu...');
|
||||
$this->assertSame($this->Text->truncate($text9, 10), 'НОПРСТУ...');
|
||||
|
||||
$text = '<p><span style="font-size: medium;"><a>Iamatestwithnospacesandhtml</a></span></p>';
|
||||
$result = $this->Text->truncate($text, 10, array(
|
||||
'ending' => '...',
|
||||
'exact' => false,
|
||||
'html' => true
|
||||
));
|
||||
$expected = '<p><span style="font-size: medium;"><a>...</a></span></p>';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
|
||||
Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
|
||||
este artículo de El País.</span></p>
|
||||
<p><span style="font-size: medium;"><span style="font-size:
|
||||
large;">Por qué Steve era distinto.</span></span></p>
|
||||
<p><span style="font-size: medium;"><a href="http://www.elpais.com/
|
||||
articulo/primer/plano/Steve/era/distinto/elpepueconeg/
|
||||
20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
|
||||
Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
|
||||
<p><span style="font-size: medium;">Ya se ha publicado la biografía de
|
||||
Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
|
||||
Isaacson</strong>", aquí os dejamos la dirección de amazon donde
|
||||
podeís adquirirla.</span></p>
|
||||
<p><span style="font-size: medium;"><a>http://www.amazon.com/Steve-
|
||||
Jobs-Walter-Isaacson/dp/1451648537</a></span></p>';
|
||||
$result = $this->Text->truncate($text, 500, array(
|
||||
'ending' => '... ',
|
||||
'exact' => false,
|
||||
'html' => true
|
||||
));
|
||||
$expected = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
|
||||
Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
|
||||
este artículo de El País.</span></p>
|
||||
<p><span style="font-size: medium;"><span style="font-size:
|
||||
large;">Por qué Steve era distinto.</span></span></p>
|
||||
<p><span style="font-size: medium;"><a href="http://www.elpais.com/
|
||||
articulo/primer/plano/Steve/era/distinto/elpepueconeg/
|
||||
20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
|
||||
Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
|
||||
<p><span style="font-size: medium;">Ya se ha publicado la biografía de
|
||||
Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
|
||||
Isaacson</strong>", aquí os dejamos la dirección de amazon donde
|
||||
podeís adquirirla.</span></p>
|
||||
<p><span style="font-size: medium;"><a>... </a></span></p>';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlight method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlight() {
|
||||
$text = 'This is a test text';
|
||||
$phrases = array('This', 'text');
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$expected = '<b>This</b> is a test <b>text</b>';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This is a test text';
|
||||
$phrases = null;
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($result, $text);
|
||||
|
||||
$text = 'This is a (test) text';
|
||||
$phrases = '(test';
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals('This is a <b>(test</b>) text', $result);
|
||||
|
||||
$text = 'Ich saß in einem Café am Übergang';
|
||||
$expected = 'Ich <b>saß</b> in einem <b>Café</b> am <b>Übergang</b>';
|
||||
$phrases = array('saß', 'café', 'übergang');
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlightHtml method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlightHtml() {
|
||||
$text1 = '<p>strongbow isn’t real cider</p>';
|
||||
$text2 = '<p>strongbow <strong>isn’t</strong> real cider</p>';
|
||||
$text3 = '<img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
|
||||
$text4 = 'What a strong mouse: <img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
|
||||
$options = array('format' => '<b>\1</b>', 'html' => true);
|
||||
|
||||
$expected = '<p><b>strong</b>bow isn’t real cider</p>';
|
||||
$this->assertEquals($this->Text->highlight($text1, 'strong', $options), $expected);
|
||||
|
||||
$expected = '<p><b>strong</b>bow <strong>isn’t</strong> real cider</p>';
|
||||
$this->assertEquals($this->Text->highlight($text2, 'strong', $options), $expected);
|
||||
|
||||
$this->assertEquals($this->Text->highlight($text3, 'strong', $options), $text3);
|
||||
|
||||
$this->assertEquals($this->Text->highlight($text3, array('strong', 'what'), $options), $text3);
|
||||
|
||||
$expected = '<b>What</b> a <b>strong</b> mouse: <img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
|
||||
$this->assertEquals($this->Text->highlight($text4, array('strong', 'what'), $options), $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlightMulti method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlightMulti() {
|
||||
$text = 'This is a test text';
|
||||
$phrases = array('This', 'text');
|
||||
$result = $this->Text->highlight($text, $phrases, array('format' => array('<b>\1</b>', '<em>\1</em>')));
|
||||
$expected = '<b>This</b> is a test <em>text</em>';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* testStripLinks method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testStripLinks() {
|
||||
$text = 'This is a test text';
|
||||
$expected = 'This is a test text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This is a <a href="#">test</a> text';
|
||||
$expected = 'This is a test text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This <strong>is</strong> a <a href="#">test</a> <a href="#">text</a>';
|
||||
$expected = 'This <strong>is</strong> a test text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'This <strong>is</strong> a <a href="#">test</a> and <abbr>some</abbr> other <a href="#">text</a>';
|
||||
$expected = 'This <strong>is</strong> a test and <abbr>some</abbr> other text';
|
||||
$result = $this->Text->stripLinks($text);
|
||||
$this->assertEquals($expected, $result);
|
||||
public function testTextHelperProxyMethodCalls() {
|
||||
$this->String = $this->getMock('String');
|
||||
unset($this->Text);
|
||||
$this->Text = new TextHelperTestObject($this->View);
|
||||
$this->Text->attach($this->String);
|
||||
$methods = array(
|
||||
'highlight', 'stripLinks', 'truncate', 'excerpt', 'toList',
|
||||
);
|
||||
foreach ($methods as $method) {
|
||||
$this->String->expects($this->at(0))->method($method);
|
||||
$this->Text->{$method}('who', 'what', 'when', 'where', 'how');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -405,107 +248,4 @@ podeís adquirirla.</span></p>
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testHighlightCaseInsensitivity method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHighlightCaseInsensitivity() {
|
||||
$text = 'This is a Test text';
|
||||
$expected = 'This is a <b>Test</b> text';
|
||||
|
||||
$result = $this->Text->highlight($text, 'test', array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Text->highlight($text, array('test'), array('format' => '<b>\1</b>'));
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testExcerpt method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExcerpt() {
|
||||
$text = 'This is a phrase with test text to play with';
|
||||
|
||||
$expected = '...ase with test text to ...';
|
||||
$result = $this->Text->excerpt($text, 'test', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = 'This is a...';
|
||||
$result = $this->Text->excerpt($text, 'not_found', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = 'This is a phras...';
|
||||
$result = $this->Text->excerpt($text, null, 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = $text;
|
||||
$result = $this->Text->excerpt($text, null, 200, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = '...a phrase w...';
|
||||
$result = $this->Text->excerpt($text, 'phrase', 2, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$phrase = 'This is a phrase with test text';
|
||||
$expected = $text;
|
||||
$result = $this->Text->excerpt($text, $phrase, 13, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'aaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
$phrase = 'bbbbbbbb';
|
||||
$result = $this->Text->excerpt($text, $phrase, 10);
|
||||
$expected = '...aaaaaaaaaabbbbbbbbaaaaaaaaaa...';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testExcerptCaseInsensitivity method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExcerptCaseInsensitivity() {
|
||||
$text = 'This is a phrase with test text to play with';
|
||||
|
||||
$expected = '...ase with test text to ...';
|
||||
$result = $this->Text->excerpt($text, 'TEST', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$expected = 'This is a...';
|
||||
$result = $this->Text->excerpt($text, 'NOT_FOUND', 9, '...');
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testListGeneration method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testListGeneration() {
|
||||
$result = $this->Text->toList(array());
|
||||
$this->assertEquals($result, '');
|
||||
|
||||
$result = $this->Text->toList(array('One'));
|
||||
$this->assertEquals($result, 'One');
|
||||
|
||||
$result = $this->Text->toList(array('Larry', 'Curly', 'Moe'));
|
||||
$this->assertEquals($result, 'Larry, Curly and Moe');
|
||||
|
||||
$result = $this->Text->toList(array('Dusty', 'Lucky', 'Ned'), 'y');
|
||||
$this->assertEquals($result, 'Dusty, Lucky y Ned');
|
||||
|
||||
$result = $this->Text->toList(array(1 => 'Dusty', 2 => 'Lucky', 3 => 'Ned'), 'y');
|
||||
$this->assertEquals($result, 'Dusty, Lucky y Ned');
|
||||
|
||||
$result = $this->Text->toList(array(1 => 'Dusty', 2 => 'Lucky', 3 => 'Ned'), 'and', ' + ');
|
||||
$this->assertEquals($result, 'Dusty + Lucky and Ned');
|
||||
|
||||
$result = $this->Text->toList(array('name1' => 'Dusty', 'name2' => 'Lucky'));
|
||||
$this->assertEquals($result, 'Dusty and Lucky');
|
||||
|
||||
$result = $this->Text->toList(array('test_0' => 'banana', 'test_1' => 'apple', 'test_2' => 'lemon'));
|
||||
$this->assertEquals($result, 'banana, apple and lemon');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,18 @@
|
|||
*/
|
||||
App::uses('TimeHelper', 'View/Helper');
|
||||
App::uses('View', 'View');
|
||||
App::uses('CakeTime', 'Utility');
|
||||
|
||||
/**
|
||||
* TimeHelperTestObject class
|
||||
*/
|
||||
class TimeHelperTestObject extends TimeHelper {
|
||||
|
||||
public function attach(CakeTime $cakeTime) {
|
||||
$this->_CakeTime = $cakeTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TimeHelperTest class
|
||||
|
@ -26,15 +38,20 @@ App::uses('View', 'View');
|
|||
*/
|
||||
class TimeHelperTest extends CakeTestCase {
|
||||
|
||||
public $Time = null;
|
||||
|
||||
public $CakeTime = null;
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
$controller = null;
|
||||
$View = new View($controller);
|
||||
$this->Time = new TimeHelper($View);
|
||||
$View = new View(null);
|
||||
$this->CakeTime = $this->getMock('CakeTime');
|
||||
$this->Time = new TimeHelperTestObject($View);
|
||||
$this->Time->attach($this->CakeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,767 +61,24 @@ class TimeHelperTest extends CakeTestCase {
|
|||
*/
|
||||
public function tearDown() {
|
||||
unset($this->Time);
|
||||
unset($this->CakeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* testToQuarter method
|
||||
*
|
||||
* @return void
|
||||
* test CakeTime class methods are called correctly
|
||||
*/
|
||||
public function testToQuarter() {
|
||||
$result = $this->Time->toQuarter('2007-12-25');
|
||||
$this->assertEquals($result, 4);
|
||||
|
||||
$result = $this->Time->toQuarter('2007-9-25');
|
||||
$this->assertEquals($result, 3);
|
||||
|
||||
$result = $this->Time->toQuarter('2007-3-25');
|
||||
$this->assertEquals($result, 1);
|
||||
|
||||
$result = $this->Time->toQuarter('2007-3-25', true);
|
||||
$this->assertEquals($result, array('2007-01-01', '2007-03-31'));
|
||||
|
||||
$result = $this->Time->toQuarter('2007-5-25', true);
|
||||
$this->assertEquals($result, array('2007-04-01', '2007-06-30'));
|
||||
|
||||
$result = $this->Time->toQuarter('2007-8-25', true);
|
||||
$this->assertEquals($result, array('2007-07-01', '2007-09-30'));
|
||||
|
||||
$result = $this->Time->toQuarter('2007-12-25', true);
|
||||
$this->assertEquals($result, array('2007-10-01', '2007-12-31'));
|
||||
}
|
||||
|
||||
/**
|
||||
* testTimeAgoInWords method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTimeAgoInWords() {
|
||||
$result = $this->Time->timeAgoInWords('-1 week');
|
||||
$this->assertEquals($result, '1 week ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('+1 week');
|
||||
$this->assertEquals($result, '1 week');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+4 months +2 weeks +3 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '4 months, 2 weeks, 3 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+4 months +2 weeks +2 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '4 months, 2 weeks, 2 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+4 months +2 weeks +1 day'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '4 months, 2 weeks, 1 day');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +2 weeks +1 day'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '3 months, 2 weeks, 1 day');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +2 weeks'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '3 months, 2 weeks');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +1 week +6 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '3 months, 1 week, 6 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 weeks +1 day'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '2 months, 2 weeks, 1 day');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 weeks'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '2 months, 2 weeks');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +1 week +6 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '2 months, 1 week, 6 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+1 month +1 week +6 days'), array('end' => '8 years'), true);
|
||||
$this->assertEquals($result, '1 month, 1 week, 6 days');
|
||||
|
||||
for ($i = 0; $i < 200; $i ++) {
|
||||
$years = mt_rand(0, 3);
|
||||
$months = mt_rand(0, 11);
|
||||
$weeks = mt_rand(0, 3);
|
||||
$days = mt_rand(0, 6);
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
$seconds = 0;
|
||||
$relative_date = '';
|
||||
|
||||
// Trying to take into account the number of days in a month
|
||||
$month = date('m') - $months;
|
||||
if ($month <= 0) {
|
||||
$month = $months % 12;
|
||||
}
|
||||
$time = mktime(0, 0, 0, $month, 1, date('y') - $years);
|
||||
$diffDays = date('t') - date('t', $time);
|
||||
|
||||
if ($diffDays > 0 && date('j') - date('t', $time) - $days > 0 && $months > 0 && $weeks === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($years > 0) {
|
||||
// years and months and days
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $years . ' year' . ($years > 1 ? 's' : '');
|
||||
$relative_date .= $months > 0 ? ($relative_date ? ', -' : '-') . $months . ' month' . ($months > 1 ? 's' : '') : '';
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', -' : '-') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($months) > 0) {
|
||||
// months, weeks and days
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $months . ' month' . ($months > 1 ? 's' : '');
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', -' : '-') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($weeks) > 0) {
|
||||
// weeks and days
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $weeks . ' week' . ($weeks > 1 ? 's' : '');
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($days) > 0) {
|
||||
// days and hours
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $days . ' day' . ($days > 1 ? 's' : '');
|
||||
$relative_date .= $hours > 0 ? ($relative_date ? ', -' : '-') . $hours . ' hour' . ($hours > 1 ? 's' : '') : '';
|
||||
} elseif (abs($hours) > 0) {
|
||||
// hours and minutes
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $hours . ' hour' . ($hours > 1 ? 's' : '');
|
||||
$relative_date .= $minutes > 0 ? ($relative_date ? ', -' : '-') . $minutes . ' minute' . ($minutes > 1 ? 's' : '') : '';
|
||||
} elseif (abs($minutes) > 0) {
|
||||
// minutes only
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
|
||||
} else {
|
||||
// seconds only
|
||||
$relative_date .= ($relative_date ? ', -' : '-') . $seconds . ' second' . ($seconds != 1 ? 's' : '');
|
||||
}
|
||||
|
||||
if (date('j/n/y', strtotime(str_replace(',', '', $relative_date))) != '1/1/70') {
|
||||
$result = $this->Time->timeAgoInWords(strtotime(str_replace(',', '', $relative_date)), array('end' => '8 years'), true);
|
||||
if ($relative_date == '0 seconds') {
|
||||
$relative_date = '0 seconds ago';
|
||||
}
|
||||
|
||||
$relative_date = str_replace('-', '', $relative_date) . ' ago';
|
||||
$this->assertEquals($result, $relative_date);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 200; $i ++) {
|
||||
$years = mt_rand(0, 3);
|
||||
$months = mt_rand(0, 11);
|
||||
$weeks = mt_rand(0, 3);
|
||||
$days = mt_rand(0, 6);
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
$seconds = 0;
|
||||
|
||||
$relative_date = '';
|
||||
|
||||
if ($years > 0) {
|
||||
// years and months and days
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $years . ' year' . ($years > 1 ? 's' : '');
|
||||
$relative_date .= $months > 0 ? ($relative_date ? ', ' : '') . $months . ' month' . ($months > 1 ? 's' : '') : '';
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($months) > 0) {
|
||||
// months, weeks and days
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $months . ' month' . ($months > 1 ? 's' : '');
|
||||
$relative_date .= $weeks > 0 ? ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '') : '';
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($weeks) > 0) {
|
||||
// weeks and days
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '');
|
||||
$relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
|
||||
} elseif (abs($days) > 0) {
|
||||
// days and hours
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '');
|
||||
$relative_date .= $hours > 0 ? ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '') : '';
|
||||
} elseif (abs($hours) > 0) {
|
||||
// hours and minutes
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '');
|
||||
$relative_date .= $minutes > 0 ? ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '') : '';
|
||||
} elseif (abs($minutes) > 0) {
|
||||
// minutes only
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
|
||||
} else {
|
||||
// seconds only
|
||||
$relative_date .= ($relative_date ? ', ' : '') . $seconds . ' second' . ($seconds != 1 ? 's' : '');
|
||||
}
|
||||
|
||||
if (date('j/n/y', strtotime(str_replace(',', '', $relative_date))) != '1/1/70') {
|
||||
$result = $this->Time->timeAgoInWords(strtotime(str_replace(',', '', $relative_date)), array('end' => '8 years'), true);
|
||||
if ($relative_date == '0 seconds') {
|
||||
$relative_date = '0 seconds ago';
|
||||
}
|
||||
|
||||
$relative_date = str_replace('-', '', $relative_date) . '';
|
||||
$this->assertEquals($result, $relative_date);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 years -5 months -2 days'), array('end' => '3 years'), true);
|
||||
$this->assertEquals($result, '2 years, 5 months, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('2007-9-25');
|
||||
$this->assertEquals($result, 'on 25/9/07');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('2007-9-25', 'Y-m-d');
|
||||
$this->assertEquals($result, 'on 2007-09-25');
|
||||
|
||||
$result = $this->Time->timeAgoInWords('2007-9-25', 'Y-m-d', true);
|
||||
$this->assertEquals($result, 'on 2007-09-25');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 weeks -2 days'), 'Y-m-d', false);
|
||||
$this->assertEquals($result, '2 weeks, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 weeks +2 days'), 'Y-m-d', true);
|
||||
$this->assertRegExp('/^2 weeks, [1|2] day(s)?$/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '1 month'));
|
||||
$this->assertEquals($result, 'on ' . date('j/n/y', strtotime('+2 months +2 days')));
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '3 month'));
|
||||
$this->assertRegExp('/2 months/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +12 days'), array('end' => '3 month'));
|
||||
$this->assertRegExp('/2 months, 1 week/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+3 months +5 days'), array('end' => '4 month'));
|
||||
$this->assertEquals($result, '3 months, 5 days');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 months -2 days'), array('end' => '3 month'));
|
||||
$this->assertEquals($result, '2 months, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 months -2 days'), array('end' => '3 month'));
|
||||
$this->assertEquals($result, '2 months, 2 days ago');
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '3 month'));
|
||||
$this->assertRegExp('/2 months/', $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('+2 months +2 days'), array('end' => '1 month', 'format' => 'Y-m-d'));
|
||||
$this->assertEquals($result, 'on ' . date('Y-m-d', strtotime('+2 months +2 days')));
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 months -2 days'), array('end' => '1 month', 'format' => 'Y-m-d'));
|
||||
$this->assertEquals($result, 'on ' . date('Y-m-d', strtotime('-2 months -2 days')));
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-13 months -5 days'), array('end' => '2 years'));
|
||||
$this->assertEquals($result, '1 year, 1 month, 5 days ago');
|
||||
|
||||
$fourHours = $this->Time->timeAgoInWords(strtotime('-5 days -2 hours'), array('userOffset' => -4));
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-5 days -2 hours'), array('userOffset' => 4));
|
||||
$this->assertEquals($fourHours, $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-2 hours'));
|
||||
$expected = '2 hours ago';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-12 minutes'));
|
||||
$expected = '12 minutes ago';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->timeAgoInWords(strtotime('-12 seconds'));
|
||||
$expected = '12 seconds ago';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$time = strtotime('-3 years -12 months');
|
||||
$result = $this->Time->timeAgoInWords($time);
|
||||
$expected = 'on ' . date('j/n/y', $time);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testNice method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNice() {
|
||||
$time = time() + 2 * DAY;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
|
||||
|
||||
$time = time() - 2 * DAY;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
|
||||
|
||||
$time = time();
|
||||
$this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
|
||||
|
||||
$time = 0;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
|
||||
|
||||
$time = null;
|
||||
$this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
|
||||
|
||||
$time = time();
|
||||
$this->assertEquals(date('D', $time), $this->Time->nice($time, null, '%a'));
|
||||
$this->assertEquals(date('M d, Y', $time), $this->Time->nice($time, null, '%b %d, %Y'));
|
||||
|
||||
$this->Time->niceFormat = '%Y-%d-%m';
|
||||
$this->assertEquals(date('Y-d-m', $time), $this->Time->nice($time));
|
||||
}
|
||||
|
||||
/**
|
||||
* testNiceShort method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testNiceShort() {
|
||||
$time = time() + 2 * DAY;
|
||||
if (date('Y', $time) == date('Y')) {
|
||||
$this->assertEquals(date('M jS, H:i', $time), $this->Time->niceShort($time));
|
||||
} else {
|
||||
$this->assertEquals(date('M jS Y, H:i', $time), $this->Time->niceShort($time));
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$this->assertEquals('Today, ' . date('H:i', $time), $this->Time->niceShort($time));
|
||||
|
||||
$time = time() - DAY;
|
||||
$this->assertEquals('Yesterday, ' . date('H:i', $time), $this->Time->niceShort($time));
|
||||
}
|
||||
|
||||
/**
|
||||
* testDaysAsSql method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDaysAsSql() {
|
||||
$begin = time();
|
||||
$end = time() + DAY;
|
||||
$field = 'my_field';
|
||||
$expected = '(my_field >= \''.date('Y-m-d', $begin).' 00:00:00\') AND (my_field <= \''.date('Y-m-d', $end).' 23:59:59\')';
|
||||
$this->assertEquals($expected, $this->Time->daysAsSql($begin, $end, $field));
|
||||
}
|
||||
|
||||
/**
|
||||
* testDayAsSql method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDayAsSql() {
|
||||
$time = time();
|
||||
$field = 'my_field';
|
||||
$expected = '(my_field >= \''.date('Y-m-d', $time).' 00:00:00\') AND (my_field <= \''.date('Y-m-d', $time).' 23:59:59\')';
|
||||
$this->assertEquals($expected, $this->Time->dayAsSql($time, $field));
|
||||
}
|
||||
|
||||
/**
|
||||
* testToUnix method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToUnix() {
|
||||
$this->assertEquals(time(), $this->Time->toUnix(time()));
|
||||
$this->assertEquals(strtotime('+1 day'), $this->Time->toUnix('+1 day'));
|
||||
$this->assertEquals(strtotime('+0 days'), $this->Time->toUnix('+0 days'));
|
||||
$this->assertEquals(strtotime('-1 days'), $this->Time->toUnix('-1 days'));
|
||||
$this->assertEquals(false, $this->Time->toUnix(''));
|
||||
$this->assertEquals(false, $this->Time->toUnix(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* testToAtom method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToAtom() {
|
||||
$this->assertEquals(date('Y-m-d\TH:i:s\Z'), $this->Time->toAtom(time()));
|
||||
}
|
||||
|
||||
/**
|
||||
* testToRss method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testToRss() {
|
||||
$this->assertEquals(date('r'), $this->Time->toRss(time()));
|
||||
|
||||
if (!$this->skipIf(!class_exists('DateTimeZone'), '%s DateTimeZone class not available.')) {
|
||||
$timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
|
||||
foreach ($timezones as $timezone) {
|
||||
$yourTimezone = new DateTimeZone($timezone);
|
||||
$yourTime = new DateTime('now', $yourTimezone);
|
||||
$userOffset = $yourTimezone->getOffset($yourTime) / HOUR;
|
||||
$this->assertEquals($yourTime->format('r'), $this->Time->toRss(time(), $userOffset));
|
||||
}
|
||||
public function testTimeHelperProxyMethodCalls() {
|
||||
$methods = array(
|
||||
'convertSpecifiers', 'convert', 'serverOffset', 'fromString',
|
||||
'nice', 'niceShort', 'daysAsSql', 'dayAsSql',
|
||||
'isToday', 'isThisMonth', 'isThisYear', 'wasYesterday',
|
||||
'isTomorrow', 'toQuarter', 'toUnix', 'toAtom', 'toRSS',
|
||||
'timeAgoInWords', 'wasWithinLast', 'gmt', 'format', 'i18nFormat',
|
||||
);
|
||||
foreach ($methods as $method) {
|
||||
$this->CakeTime->expects($this->at(0))->method($method);
|
||||
$this->Time->{$method}('who', 'what', 'when', 'where', 'how');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* testFormat method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormat() {
|
||||
$format = 'D-M-Y';
|
||||
$arr = array(time(), strtotime('+1 days'), strtotime('+1 days'), strtotime('+0 days'));
|
||||
foreach ($arr as $val) {
|
||||
$this->assertEquals(date($format, $val), $this->Time->format($format, $val));
|
||||
}
|
||||
|
||||
$result = $this->Time->format('Y-m-d', null, 'never');
|
||||
$this->assertEquals($result, 'never');
|
||||
}
|
||||
|
||||
/**
|
||||
* testOfGmt method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGmt() {
|
||||
$hour = 3;
|
||||
$min = 4;
|
||||
$sec = 2;
|
||||
$month = 5;
|
||||
$day = 14;
|
||||
$year = 2007;
|
||||
$time = mktime($hour, $min, $sec, $month, $day, $year);
|
||||
$expected = gmmktime($hour, $min, $sec, $month, $day, $year);
|
||||
$this->assertEquals($expected, $this->Time->gmt(date('Y-n-j G:i:s', $time)));
|
||||
|
||||
$hour = date('H');
|
||||
$min = date('i');
|
||||
$sec = date('s');
|
||||
$month = date('m');
|
||||
$day = date('d');
|
||||
$year = date('Y');
|
||||
$expected = gmmktime($hour, $min, $sec, $month, $day, $year);
|
||||
$this->assertEquals($expected, $this->Time->gmt(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsToday method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsToday() {
|
||||
$result = $this->Time->isToday('+1 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isToday('+1 days');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isToday('+0 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isToday('-1 day');
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsThisWeek method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsThisWeek() {
|
||||
// A map of days which goes from -1 day of week to +1 day of week
|
||||
$map = array(
|
||||
'Mon' => array(-1, 7), 'Tue' => array(-2, 6), 'Wed' => array(-3, 5),
|
||||
'Thu' => array(-4, 4), 'Fri' => array(-5, 3), 'Sat' => array(-6, 2),
|
||||
'Sun' => array(-7, 1)
|
||||
);
|
||||
$days = $map[date('D')];
|
||||
|
||||
for ($day = $days[0] + 1; $day < $days[1]; $day++) {
|
||||
$this->assertTrue($this->Time->isThisWeek(($day > 0 ? '+' : '') . $day . ' days'));
|
||||
}
|
||||
$this->assertFalse($this->Time->isThisWeek($days[0] . ' days'));
|
||||
$this->assertFalse($this->Time->isThisWeek('+' . $days[1] . ' days'));
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsThisMonth method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsThisMonth() {
|
||||
$result = $this->Time->isThisMonth('+0 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isThisMonth($time = mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y')));
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') - mt_rand(1, 12)));
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') + mt_rand(1, 12)));
|
||||
$this->assertFalse($result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsThisYear method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsThisYear() {
|
||||
$result = $this->Time->isThisYear('+0 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isThisYear(mktime(0, 0, 0, mt_rand(1, 12), mt_rand(1, 28), date('Y')));
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testWasYesterday method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testWasYesterday() {
|
||||
$result = $this->Time->wasYesterday('+1 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->wasYesterday('+1 days');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->wasYesterday('+0 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->wasYesterday('-1 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->wasYesterday('-1 days');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->wasYesterday('-2 days');
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testIsTomorrow method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIsTomorrow() {
|
||||
$result = $this->Time->isTomorrow('+1 day');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isTomorrow('+1 days');
|
||||
$this->assertTrue($result);
|
||||
$result = $this->Time->isTomorrow('+0 day');
|
||||
$this->assertFalse($result);
|
||||
$result = $this->Time->isTomorrow('-1 day');
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testWasWithinLast method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testWasWithinLast() {
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 week', '-1 week'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 second', '-1 second'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 minute', '-1 minute'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 month', '-1 month'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
|
||||
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 week', '-1 day'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('2 week', '-1 week'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 second', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('10 minutes', '-1 second'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('23 minutes', '-1 minute'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('0 year', '-1 year'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('13 month', '-1 month'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('2 days', '-1 day'));
|
||||
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 week', '-2 weeks'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 second', '-2 seconds'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 hour', '-2 hours'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 month', '-2 months'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 year', '-2 years'));
|
||||
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 day', '-2 weeks'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
|
||||
$this->assertFalse($this->Time->wasWithinLast('0 days', '-2 days'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 hour', '-20 seconds'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 year', '-60 minutes -30 seconds'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('3 years', '-2 months'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('5 months', '-4 months'));
|
||||
|
||||
$this->assertTrue($this->Time->wasWithinLast('5 ', '-3 days'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 ', '-1 hour'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 ', '-1 minute'));
|
||||
$this->assertTrue($this->Time->wasWithinLast('1 ', '-23 hours -59 minutes -59 seconds'));
|
||||
}
|
||||
|
||||
/**
|
||||
* testUserOffset method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUserOffset() {
|
||||
$timezoneServer = new DateTimeZone(date_default_timezone_get());
|
||||
$timeServer = new DateTime('now', $timezoneServer);
|
||||
$yourTimezone = $timezoneServer->getOffset($timeServer) / HOUR;
|
||||
|
||||
$expected = time();
|
||||
$result = $this->Time->fromString(time(), $yourTimezone);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test fromString()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFromString() {
|
||||
$result = $this->Time->fromString('');
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $this->Time->fromString(0, 0);
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $this->Time->fromString('+1 hour');
|
||||
$expected = strtotime('+1 hour');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$timezone = date('Z', time());
|
||||
$result = $this->Time->fromString('+1 hour', $timezone);
|
||||
$expected = $this->Time->convert(strtotime('+1 hour'), $timezone);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test converting time specifiers using a time definition localfe file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConvertSpecifiers() {
|
||||
App::build(array(
|
||||
'locales' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
|
||||
), true);
|
||||
Configure::write('Config.language', 'time_test');
|
||||
$time = strtotime('Thu Jan 14 11:43:39 2010');
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%a', $time);
|
||||
$expected = 'jue';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%A', $time);
|
||||
$expected = 'jueves';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%c', $time);
|
||||
$expected = 'jue %d ene %Y %H:%M:%S %Z';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%C', $time);
|
||||
$expected = '20';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%D', $time);
|
||||
$expected = '%m/%d/%y';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%b', $time);
|
||||
$expected = 'ene';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%h', $time);
|
||||
$expected = 'ene';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%B', $time);
|
||||
$expected = 'enero';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%n', $time);
|
||||
$expected = "\n";
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%n', $time);
|
||||
$expected = "\n";
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%p', $time);
|
||||
$expected = 'AM';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%P', $time);
|
||||
$expected = 'am';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%r', $time);
|
||||
$expected = '%I:%M:%S AM';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%R', $time);
|
||||
$expected = '11:43';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%t', $time);
|
||||
$expected = "\t";
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%T', $time);
|
||||
$expected = '%H:%M:%S';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%u', $time);
|
||||
$expected = 4;
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%x', $time);
|
||||
$expected = '%d/%m/%y';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%X', $time);
|
||||
$expected = '%H:%M:%S';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test convert %e on windows.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testConvertPercentE() {
|
||||
$this->skipIf(DIRECTORY_SEPARATOR !== '\\', 'Cannot run windows tests on non-windows OS.');
|
||||
|
||||
$time = strtotime('Thu Jan 14 11:43:39 2010');
|
||||
$result = $this->Time->convertSpecifiers('%e', $time);
|
||||
$expected = '14';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->convertSpecifiers('%e', strtotime('2011-01-01'));
|
||||
$expected = ' 1';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test formatting dates taking in account preferred i18n locale file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testI18nFormat() {
|
||||
App::build(array(
|
||||
'locales' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
|
||||
), true);
|
||||
Configure::write('Config.language', 'time_test');
|
||||
|
||||
$time = strtotime('Thu Jan 14 13:59:28 2010');
|
||||
|
||||
$result = $this->Time->i18nFormat($time);
|
||||
$expected = '14/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, '%c');
|
||||
$expected = 'jue 14 ene 2010 13:59:28 ' . strftime('%Z', $time);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
|
||||
$expected = 'Time is 01:59:28 PM, and date is 14/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$time = strtotime('Wed Jan 13 13:59:28 2010');
|
||||
|
||||
$result = $this->Time->i18nFormat($time);
|
||||
$expected = '13/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, '%c');
|
||||
$expected = 'mié 13 ene 2010 13:59:28 ' . strftime('%Z', $time);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
|
||||
$expected = 'Time is 01:59:28 PM, and date is 13/01/10';
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = $this->Time->i18nFormat('invalid date', '%x', 'Date invalid');
|
||||
$expected = 'Date invalid';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test new format() syntax which inverts first and secod parameters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFormatNewSyntax() {
|
||||
$time = time();
|
||||
$this->assertEquals($this->Time->format($time), $this->Time->i18nFormat($time));
|
||||
$this->assertEquals($this->Time->format($time, '%c'), $this->Time->i18nFormat($time, '%c'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,6 +244,7 @@ class MediaViewTest extends CakeTestCase {
|
|||
'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS,
|
||||
'id' => 'no_section.ini',
|
||||
'extension' => 'ini',
|
||||
'name' => 'config'
|
||||
);
|
||||
$this->MediaView->expects($this->exactly(2))
|
||||
->method('_isActive')
|
||||
|
@ -270,7 +271,7 @@ class MediaViewTest extends CakeTestCase {
|
|||
|
||||
$this->MediaView->response->expects($this->once())
|
||||
->method('download')
|
||||
->with('no_section.ini');
|
||||
->with('config.ini');
|
||||
|
||||
$this->MediaView->response->expects($this->at(4))
|
||||
->method('header')
|
||||
|
@ -357,7 +358,7 @@ class MediaViewTest extends CakeTestCase {
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
function testRenderUpperExtesnion() {
|
||||
public function testRenderUpperExtension() {
|
||||
$this->MediaView->viewVars = array(
|
||||
'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS .'img' . DS,
|
||||
'id' => 'test_2.JPG',
|
||||
|
@ -376,4 +377,27 @@ class MediaViewTest extends CakeTestCase {
|
|||
$this->MediaView->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test downloading files with extension not explicitly set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRenderExtensionNotSet() {
|
||||
$this->MediaView->viewVars = array(
|
||||
'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS .'img' . DS,
|
||||
'id' => 'test_2.JPG',
|
||||
);
|
||||
|
||||
$this->MediaView->response->expects($this->any())
|
||||
->method('type')
|
||||
->with('jpg')
|
||||
->will($this->returnArgument(0));
|
||||
|
||||
$this->MediaView->expects($this->at(0))
|
||||
->method('_isActive')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$this->MediaView->render();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -726,7 +726,7 @@ class ViewTest extends CakeTestCase {
|
|||
'path' => CACHE . 'views' . DS,
|
||||
'prefix' => ''
|
||||
));
|
||||
Cache::clear('test_view');
|
||||
Cache::clear(false, 'test_view');
|
||||
|
||||
$View = new TestView($this->PostsController);
|
||||
$View->elementCache = 'test_view';
|
||||
|
@ -763,6 +763,7 @@ class ViewTest extends CakeTestCase {
|
|||
$result = Cache::read('element__test_element_cache_param_foo', 'test_view');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
Cache::clear(false, 'test_view');
|
||||
Cache::drop('test_view');
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@ class UserFixture extends CakeTestFixture {
|
|||
*/
|
||||
public $fields = array(
|
||||
'id' => array('type' => 'integer', 'key' => 'primary'),
|
||||
'user' => array('type' => 'string', 'null' => false),
|
||||
'password' => array('type' => 'string', 'null' => false),
|
||||
'user' => array('type' => 'string', 'null' => true),
|
||||
'password' => array('type' => 'string', 'null' => true),
|
||||
'created' => 'datetime',
|
||||
'updated' => 'datetime'
|
||||
);
|
||||
|
|
|
@ -12,6 +12,7 @@ echo __dn('domain', 'You deleted %d message (domain).', 'You deleted %d messages
|
|||
|
||||
// Duplicated Message
|
||||
echo __('Editing this Page');
|
||||
echo __('You have %d new message.');
|
||||
|
||||
// Multiline
|
||||
__('Hot features!'
|
||||
|
|
254
lib/Cake/Utility/CakeNumber.php
Normal file
254
lib/Cake/Utility/CakeNumber.php
Normal file
|
@ -0,0 +1,254 @@
|
|||
<?php
|
||||
/**
|
||||
* CakeNumber Utility.
|
||||
*
|
||||
* Methods to make numbers more readable.
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Utility
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Number helper library.
|
||||
*
|
||||
* Methods to make numbers more readable.
|
||||
*
|
||||
* @package Cake.Utility
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html
|
||||
*/
|
||||
class CakeNumber {
|
||||
|
||||
/**
|
||||
* Currencies supported by the helper. You can add additional currency formats
|
||||
* with CakeNumber::addFormat
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_currencies = array(
|
||||
'USD' => array(
|
||||
'wholeSymbol' => '$', 'wholePosition' => 'before', 'fractionSymbol' => 'c', 'fractionPosition' => 'after',
|
||||
'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()', 'escape' => true
|
||||
),
|
||||
'GBP' => array(
|
||||
'wholeSymbol' => '£', 'wholePosition' => 'before', 'fractionSymbol' => 'p', 'fractionPosition' => 'after',
|
||||
'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()','escape' => false
|
||||
),
|
||||
'EUR' => array(
|
||||
'wholeSymbol' => '€', 'wholePosition' => 'before', 'fractionSymbol' => false, 'fractionPosition' => 'after',
|
||||
'zero' => 0, 'places' => 2, 'thousands' => '.', 'decimals' => ',', 'negative' => '()', 'escape' => false
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Default options for currency formats
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_currencyDefaults = array(
|
||||
'wholeSymbol' => '', 'wholePosition' => 'before', 'fractionSymbol' => '', 'fractionPosition' => 'after',
|
||||
'zero' => '0', 'places' => 2, 'thousands' => ',', 'decimals' => '.','negative' => '()', 'escape' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Formats a number with a level of precision.
|
||||
*
|
||||
* @param float $number A floating point number.
|
||||
* @param integer $precision The precision of the returned number.
|
||||
* @return float Formatted float.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::precision
|
||||
*/
|
||||
public function precision($number, $precision = 3) {
|
||||
return sprintf("%01.{$precision}f", $number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted-for-humans file size.
|
||||
*
|
||||
* @param integer $size Size in bytes
|
||||
* @return string Human readable size
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
|
||||
*/
|
||||
public function toReadableSize($size) {
|
||||
switch (true) {
|
||||
case $size < 1024:
|
||||
return __dn('cake', '%d Byte', '%d Bytes', $size, $size);
|
||||
case round($size / 1024) < 1024:
|
||||
return __d('cake', '%d KB', $this->precision($size / 1024, 0));
|
||||
case round($size / 1024 / 1024, 2) < 1024:
|
||||
return __d('cake', '%.2f MB', $this->precision($size / 1024 / 1024, 2));
|
||||
case round($size / 1024 / 1024 / 1024, 2) < 1024:
|
||||
return __d('cake', '%.2f GB', $this->precision($size / 1024 / 1024 / 1024, 2));
|
||||
default:
|
||||
return __d('cake', '%.2f TB', $this->precision($size / 1024 / 1024 / 1024 / 1024, 2));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a percentage string.
|
||||
*
|
||||
* @param float $number A floating point number
|
||||
* @param integer $precision The precision of the returned number
|
||||
* @return string Percentage string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage
|
||||
*/
|
||||
public function toPercentage($number, $precision = 2) {
|
||||
return $this->precision($number, $precision) . '%';
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a currency format.
|
||||
*
|
||||
* @param float $number A floating point number
|
||||
* @param integer $options if int then places, if string then before, if (,.-) then use it
|
||||
* or array with places and before keys
|
||||
* @return string formatted number
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::format
|
||||
*/
|
||||
public function format($number, $options = false) {
|
||||
$places = 0;
|
||||
if (is_int($options)) {
|
||||
$places = $options;
|
||||
}
|
||||
|
||||
$separators = array(',', '.', '-', ':');
|
||||
|
||||
$before = $after = null;
|
||||
if (is_string($options) && !in_array($options, $separators)) {
|
||||
$before = $options;
|
||||
}
|
||||
$thousands = ',';
|
||||
if (!is_array($options) && in_array($options, $separators)) {
|
||||
$thousands = $options;
|
||||
}
|
||||
$decimals = '.';
|
||||
if (!is_array($options) && in_array($options, $separators)) {
|
||||
$decimals = $options;
|
||||
}
|
||||
|
||||
$escape = true;
|
||||
if (is_array($options)) {
|
||||
$options = array_merge(array('before' => '$', 'places' => 2, 'thousands' => ',', 'decimals' => '.'), $options);
|
||||
extract($options);
|
||||
}
|
||||
|
||||
$out = $before . number_format($number, $places, $decimals, $thousands) . $after;
|
||||
|
||||
if ($escape) {
|
||||
return h($out);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a currency format.
|
||||
*
|
||||
* ### Options
|
||||
*
|
||||
* - `before` - The currency symbol to place before whole numbers ie. '$'
|
||||
* - `after` - The currency symbol to place after decimal numbers ie. 'c'. Set to boolean false to
|
||||
* use no decimal symbol. eg. 0.35 => $0.35.
|
||||
* - `zero` - The text to use for zero values, can be a string or a number. ie. 0, 'Free!'
|
||||
* - `places` - Number of decimal places to use. ie. 2
|
||||
* - `thousands` - Thousands separator ie. ','
|
||||
* - `decimals` - Decimal separator symbol ie. '.'
|
||||
* - `negative` - Symbol for negative numbers. If equal to '()', the number will be wrapped with ( and )
|
||||
* - `escape` - Should the output be htmlentity escaped? Defaults to true
|
||||
*
|
||||
* @param float $number
|
||||
* @param string $currency Shortcut to default options. Valid values are 'USD', 'EUR', 'GBP', otherwise
|
||||
* set at least 'before' and 'after' options.
|
||||
* @param array $options
|
||||
* @return string Number formatted as a currency.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
|
||||
*/
|
||||
public function currency($number, $currency = 'USD', $options = array()) {
|
||||
$default = self::$_currencyDefaults;
|
||||
|
||||
if (isset(self::$_currencies[$currency])) {
|
||||
$default = self::$_currencies[$currency];
|
||||
} elseif (is_string($currency)) {
|
||||
$options['before'] = $currency;
|
||||
}
|
||||
|
||||
$options = array_merge($default, $options);
|
||||
|
||||
if (isset($options['before']) && $options['before'] !== '') {
|
||||
$options['wholeSymbol'] = $options['before'];
|
||||
}
|
||||
if (isset($options['after']) && !$options['after'] !== '') {
|
||||
$options['fractionSymbol'] = $options['after'];
|
||||
}
|
||||
|
||||
$result = $options['before'] = $options['after'] = null;
|
||||
|
||||
$symbolKey = 'whole';
|
||||
if ($number == 0 ) {
|
||||
if ($options['zero'] !== 0 ) {
|
||||
return $options['zero'];
|
||||
}
|
||||
} elseif ($number < 1 && $number > -1 ) {
|
||||
if ($options['fractionSymbol'] !== false) {
|
||||
$multiply = intval('1' . str_pad('', $options['places'], '0'));
|
||||
$number = $number * $multiply;
|
||||
$options['places'] = null;
|
||||
$symbolKey = 'fraction';
|
||||
}
|
||||
}
|
||||
|
||||
$position = $options[$symbolKey.'Position'] != 'after' ? 'before' : 'after';
|
||||
$options[$position] = $options[$symbolKey.'Symbol'];
|
||||
|
||||
$abs = abs($number);
|
||||
$result = $this->format($abs, $options);
|
||||
|
||||
if ($number < 0 ) {
|
||||
if ($options['negative'] == '()') {
|
||||
$result = '(' . $result .')';
|
||||
} else {
|
||||
$result = $options['negative'] . $result;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a currency format to the Number helper. Makes reusing
|
||||
* currency formats easier.
|
||||
*
|
||||
* {{{ $number->addFormat('NOK', array('before' => 'Kr. ')); }}}
|
||||
*
|
||||
* You can now use `NOK` as a shortform when formatting currency amounts.
|
||||
*
|
||||
* {{{ $number->currency($value, 'NOK'); }}}
|
||||
*
|
||||
* Added formats are merged with the following defaults.
|
||||
*
|
||||
* {{{
|
||||
* array(
|
||||
* 'before' => '$', 'after' => 'c', 'zero' => 0, 'places' => 2, 'thousands' => ',',
|
||||
* 'decimals' => '.', 'negative' => '()', 'escape' => true
|
||||
* )
|
||||
* }}}
|
||||
*
|
||||
* @param string $formatName The format name to be used in the future.
|
||||
* @param array $options The array of options for this format.
|
||||
* @return void
|
||||
* @see NumberHelper::currency()
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::addFormat
|
||||
*/
|
||||
public function addFormat($formatName, $options) {
|
||||
self::$_currencies[$formatName] = $options + self::$_currencyDefaults;
|
||||
}
|
||||
|
||||
}
|
766
lib/Cake/Utility/CakeTime.php
Normal file
766
lib/Cake/Utility/CakeTime.php
Normal file
|
@ -0,0 +1,766 @@
|
|||
<?php
|
||||
/**
|
||||
* CakeTime utility class file.
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package Cake.Utility
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('Multibyte', 'I18n');
|
||||
|
||||
/**
|
||||
* Time Helper class for easy use of time data.
|
||||
*
|
||||
* Manipulation of time data.
|
||||
*
|
||||
* @package Cake.Utility
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html
|
||||
*/
|
||||
class CakeTime {
|
||||
|
||||
/**
|
||||
* The format to use when formatting a time using `TimeHelper::nice()`
|
||||
*
|
||||
* The format should use the locale strings as defined in the PHP docs under
|
||||
* `strftime` (http://php.net/manual/en/function.strftime.php)
|
||||
*
|
||||
* @var string
|
||||
* @see TimeHelper::format()
|
||||
*/
|
||||
public $niceFormat = '%a, %b %eS %Y, %H:%M';
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function convertSpecifiers($format, $time = null) {
|
||||
if (!$time) {
|
||||
$time = time();
|
||||
}
|
||||
$this->__time = $time;
|
||||
return preg_replace_callback('/\%(\w+)/', array($this, '_translateSpecifier'), $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auxiliary function to translate a matched specifier element from a regular expression into
|
||||
* a windows safe and i18n aware specifier
|
||||
*
|
||||
* @param array $specifier match from regular expression
|
||||
* @return string converted element
|
||||
*/
|
||||
protected function _translateSpecifier($specifier) {
|
||||
switch ($specifier[1]) {
|
||||
case 'a':
|
||||
$abday = __dc('cake', 'abday', 5);
|
||||
if (is_array($abday)) {
|
||||
return $abday[date('w', $this->__time)];
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
$day = __dc('cake', 'day', 5);
|
||||
if (is_array($day)) {
|
||||
return $day[date('w', $this->__time)];
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
$format = __dc('cake', 'd_t_fmt', 5);
|
||||
if ($format != 'd_t_fmt') {
|
||||
return $this->convertSpecifiers($format, $this->__time);
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
return sprintf("%02d", date('Y', $this->__time) / 100);
|
||||
case 'D':
|
||||
return '%m/%d/%y';
|
||||
case 'e':
|
||||
if (DS === '/') {
|
||||
return '%e';
|
||||
}
|
||||
$day = date('j', $this->__time);
|
||||
if ($day < 10) {
|
||||
$day = ' ' . $day;
|
||||
}
|
||||
return $day;
|
||||
case 'eS' :
|
||||
return date('jS', $this->__time);
|
||||
case 'b':
|
||||
case 'h':
|
||||
$months = __dc('cake', 'abmon', 5);
|
||||
if (is_array($months)) {
|
||||
return $months[date('n', $this->__time) -1];
|
||||
}
|
||||
return '%b';
|
||||
case 'B':
|
||||
$months = __dc('cake', 'mon', 5);
|
||||
if (is_array($months)) {
|
||||
return $months[date('n', $this->__time) -1];
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
return "\n";
|
||||
case 'p':
|
||||
case 'P':
|
||||
$default = array('am' => 0, 'pm' => 1);
|
||||
$meridiem = $default[date('a', $this->__time)];
|
||||
$format = __dc('cake', 'am_pm', 5);
|
||||
if (is_array($format)) {
|
||||
$meridiem = $format[$meridiem];
|
||||
return ($specifier[1] == 'P') ? strtolower($meridiem) : strtoupper($meridiem);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
$complete = __dc('cake', 't_fmt_ampm', 5);
|
||||
if ($complete != 't_fmt_ampm') {
|
||||
return str_replace('%p', $this->_translateSpecifier(array('%p', 'p')), $complete);
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
return date('H:i', $this->__time);
|
||||
case 't':
|
||||
return "\t";
|
||||
case 'T':
|
||||
return '%H:%M:%S';
|
||||
case 'u':
|
||||
return ($weekDay = date('w', $this->__time)) ? $weekDay : 7;
|
||||
case 'x':
|
||||
$format = __dc('cake', 'd_fmt', 5);
|
||||
if ($format != 'd_fmt') {
|
||||
return $this->convertSpecifiers($format, $this->__time);
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
$format = __dc('cake', 't_fmt', 5);
|
||||
if ($format != 't_fmt') {
|
||||
return $this->convertSpecifiers($format, $this->__time);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $specifier[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts given time (in server's time zone) to user's local time, given his/her offset from GMT.
|
||||
*
|
||||
* @param string $serverTime UNIX timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return integer UNIX timestamp
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function convert($serverTime, $userOffset) {
|
||||
$serverOffset = $this->serverOffset();
|
||||
$gmtTime = $serverTime - $serverOffset;
|
||||
$userTime = $gmtTime + $userOffset * (60*60);
|
||||
return $userTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns server's offset from GMT in seconds.
|
||||
*
|
||||
* @return integer Offset
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function serverOffset() {
|
||||
return date('Z', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
|
||||
*
|
||||
* @param string $dateString Datetime string
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Parsed timestamp
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function fromString($dateString, $userOffset = null) {
|
||||
if (empty($dateString)) {
|
||||
return false;
|
||||
}
|
||||
if (is_integer($dateString) || is_numeric($dateString)) {
|
||||
$date = intval($dateString);
|
||||
} else {
|
||||
$date = strtotime($dateString);
|
||||
}
|
||||
if ($userOffset !== null) {
|
||||
return $this->convert($date, $userOffset);
|
||||
}
|
||||
if ($date === -1) {
|
||||
return false;
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a nicely formatted date string for given Datetime string.
|
||||
*
|
||||
* See http://php.net/manual/en/function.strftime.php for information on formatting
|
||||
* using locale strings.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used
|
||||
* @return string Formatted date string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function nice($dateString = null, $userOffset = null, $format = null) {
|
||||
if ($dateString != null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
} else {
|
||||
$date = time();
|
||||
}
|
||||
if (!$format) {
|
||||
$format = $this->niceFormat;
|
||||
}
|
||||
$format = $this->convertSpecifiers($format, $date);
|
||||
return $this->_strftime($format, $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted descriptive date string for given datetime string.
|
||||
*
|
||||
* If the given date is today, the returned string could be "Today, 16:54".
|
||||
* If the given date was yesterday, the returned string could be "Yesterday, 16:54".
|
||||
* If $dateString's year is the current year, the returned string does not
|
||||
* include mention of the year.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Described, relative date string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function niceShort($dateString = null, $userOffset = null) {
|
||||
$date = $dateString ? $this->fromString($dateString, $userOffset) : time();
|
||||
|
||||
$y = $this->isThisYear($date) ? '' : ' %Y';
|
||||
|
||||
if ($this->isToday($dateString, $userOffset)) {
|
||||
$ret = __d('cake', 'Today, %s', $this->_strftime("%H:%M", $date));
|
||||
} elseif ($this->wasYesterday($dateString, $userOffset)) {
|
||||
$ret = __d('cake', 'Yesterday, %s', $this->_strftime("%H:%M", $date));
|
||||
} else {
|
||||
$format = $this->convertSpecifiers("%b %eS{$y}, %H:%M", $date);
|
||||
$ret = $this->_strftime($format, $date);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a partial SQL string to search for all records between two dates.
|
||||
*
|
||||
* @param string $begin Datetime string or Unix timestamp
|
||||
* @param string $end Datetime string or Unix timestamp
|
||||
* @param string $fieldName Name of database field to compare with
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Partial SQL string.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function daysAsSql($begin, $end, $fieldName, $userOffset = null) {
|
||||
$begin = $this->fromString($begin, $userOffset);
|
||||
$end = $this->fromString($end, $userOffset);
|
||||
$begin = date('Y-m-d', $begin) . ' 00:00:00';
|
||||
$end = date('Y-m-d', $end) . ' 23:59:59';
|
||||
|
||||
return "($fieldName >= '$begin') AND ($fieldName <= '$end')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a partial SQL string to search for all records between two times
|
||||
* occurring on the same day.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param string $fieldName Name of database field to compare with
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Partial SQL string.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function dayAsSql($dateString, $fieldName, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return $this->daysAsSql($dateString, $dateString, $fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is today.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean True if datetime string is today
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isToday($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d', $date) == date('Y-m-d', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within this week.
|
||||
*
|
||||
* @param string $dateString
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean True if datetime string is within current week
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isThisWeek($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('W o', $date) == date('W o', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within this month
|
||||
* @param string $dateString
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean True if datetime string is within current month
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isThisMonth($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString);
|
||||
return date('m Y', $date) == date('m Y', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within current year.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean True if datetime string is within current year
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isThisYear($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y', $date) == date('Y', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string was yesterday.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean True if datetime string was yesterday
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*
|
||||
*/
|
||||
public function wasYesterday($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is tomorrow.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean True if datetime string was yesterday
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isTomorrow($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quarter
|
||||
*
|
||||
* @param string $dateString
|
||||
* @param boolean $range if true returns a range in Y-m-d format
|
||||
* @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toQuarter($dateString, $range = false) {
|
||||
$time = $this->fromString($dateString);
|
||||
$date = ceil(date('m', $time) / 3);
|
||||
|
||||
if ($range === true) {
|
||||
$range = 'Y-m-d';
|
||||
}
|
||||
|
||||
if ($range !== false) {
|
||||
$year = date('Y', $time);
|
||||
|
||||
switch ($date) {
|
||||
case 1:
|
||||
$date = array($year.'-01-01', $year.'-03-31');
|
||||
break;
|
||||
case 2:
|
||||
$date = array($year.'-04-01', $year.'-06-30');
|
||||
break;
|
||||
case 3:
|
||||
$date = array($year.'-07-01', $year.'-09-30');
|
||||
break;
|
||||
case 4:
|
||||
$date = array($year.'-10-01', $year.'-12-31');
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
|
||||
*
|
||||
* @param string $dateString Datetime string to be represented as a Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return integer Unix timestamp
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toUnix($dateString, $userOffset = null) {
|
||||
return $this->fromString($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a date formatted for Atom RSS feeds.
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Formatted date string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toAtom($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d\TH:i:s\Z', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats date for RSS feeds
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Formatted date string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toRSS($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
|
||||
if (!is_null($userOffset)) {
|
||||
if ($userOffset == 0) {
|
||||
$timezone = '+0000';
|
||||
} else {
|
||||
$hours = (int) floor(abs($userOffset));
|
||||
$minutes = (int) (fmod(abs($userOffset), $hours) * 60);
|
||||
$timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT);
|
||||
}
|
||||
return date('D, d M Y H:i:s', $date) . ' ' . $timezone;
|
||||
}
|
||||
return date("r", $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either a relative date or a formatted date depending
|
||||
* on the difference between the current time and given datetime.
|
||||
* $datetime should be in a <i>strtotime</i> - parsable format, like MySQL's datetime datatype.
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `format` => a fall back format if the relative time is longer than the duration specified by end
|
||||
* - `end` => The end of relative time telling
|
||||
* - `userOffset` => Users offset from GMT (in hours)
|
||||
*
|
||||
* Relative dates look something like this:
|
||||
* 3 weeks, 4 days ago
|
||||
* 15 seconds ago
|
||||
*
|
||||
* Default date formatting is d/m/yy e.g: on 18/2/09
|
||||
*
|
||||
* The returned string includes 'ago' or 'on' and assumes you'll properly add a word
|
||||
* like 'Posted ' before the function output.
|
||||
*
|
||||
* @param string $dateTime Datetime string or Unix timestamp
|
||||
* @param array $options Default format if timestamp is used in $dateString
|
||||
* @return string Relative time string.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function timeAgoInWords($dateTime, $options = array()) {
|
||||
$userOffset = null;
|
||||
if (is_array($options) && isset($options['userOffset'])) {
|
||||
$userOffset = $options['userOffset'];
|
||||
}
|
||||
$now = time();
|
||||
if (!is_null($userOffset)) {
|
||||
$now = $this->convert(time(), $userOffset);
|
||||
}
|
||||
$inSeconds = $this->fromString($dateTime, $userOffset);
|
||||
$backwards = ($inSeconds > $now);
|
||||
|
||||
$format = 'j/n/y';
|
||||
$end = '+1 month';
|
||||
|
||||
if (is_array($options)) {
|
||||
if (isset($options['format'])) {
|
||||
$format = $options['format'];
|
||||
unset($options['format']);
|
||||
}
|
||||
if (isset($options['end'])) {
|
||||
$end = $options['end'];
|
||||
unset($options['end']);
|
||||
}
|
||||
} else {
|
||||
$format = $options;
|
||||
}
|
||||
|
||||
if ($backwards) {
|
||||
$futureTime = $inSeconds;
|
||||
$pastTime = $now;
|
||||
} else {
|
||||
$futureTime = $now;
|
||||
$pastTime = $inSeconds;
|
||||
}
|
||||
$diff = $futureTime - $pastTime;
|
||||
|
||||
// If more than a week, then take into account the length of months
|
||||
if ($diff >= 604800) {
|
||||
$current = array();
|
||||
$date = array();
|
||||
|
||||
list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime));
|
||||
|
||||
list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime));
|
||||
$years = $months = $weeks = $days = $hours = $minutes = $seconds = 0;
|
||||
|
||||
if ($future['Y'] == $past['Y'] && $future['m'] == $past['m']) {
|
||||
$months = 0;
|
||||
$years = 0;
|
||||
} else {
|
||||
if ($future['Y'] == $past['Y']) {
|
||||
$months = $future['m'] - $past['m'];
|
||||
} else {
|
||||
$years = $future['Y'] - $past['Y'];
|
||||
$months = $future['m'] + ((12 * $years) - $past['m']);
|
||||
|
||||
if ($months >= 12) {
|
||||
$years = floor($months / 12);
|
||||
$months = $months - ($years * 12);
|
||||
}
|
||||
|
||||
if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] == 1) {
|
||||
$years --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($future['d'] >= $past['d']) {
|
||||
$days = $future['d'] - $past['d'];
|
||||
} else {
|
||||
$daysInPastMonth = date('t', $pastTime);
|
||||
$daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y']));
|
||||
|
||||
if (!$backwards) {
|
||||
$days = ($daysInPastMonth - $past['d']) + $future['d'];
|
||||
} else {
|
||||
$days = ($daysInFutureMonth - $past['d']) + $future['d'];
|
||||
}
|
||||
|
||||
if ($future['m'] != $past['m']) {
|
||||
$months --;
|
||||
}
|
||||
}
|
||||
|
||||
if ($months == 0 && $years >= 1 && $diff < ($years * 31536000)) {
|
||||
$months = 11;
|
||||
$years --;
|
||||
}
|
||||
|
||||
if ($months >= 12) {
|
||||
$years = $years + 1;
|
||||
$months = $months - 12;
|
||||
}
|
||||
|
||||
if ($days >= 7) {
|
||||
$weeks = floor($days / 7);
|
||||
$days = $days - ($weeks * 7);
|
||||
}
|
||||
} else {
|
||||
$years = $months = $weeks = 0;
|
||||
$days = floor($diff / 86400);
|
||||
|
||||
$diff = $diff - ($days * 86400);
|
||||
|
||||
$hours = floor($diff / 3600);
|
||||
$diff = $diff - ($hours * 3600);
|
||||
|
||||
$minutes = floor($diff / 60);
|
||||
$diff = $diff - ($minutes * 60);
|
||||
$seconds = $diff;
|
||||
}
|
||||
$relativeDate = '';
|
||||
$diff = $futureTime - $pastTime;
|
||||
|
||||
if ($diff > abs($now - $this->fromString($end))) {
|
||||
$relativeDate = __d('cake', 'on %s', date($format, $inSeconds));
|
||||
} else {
|
||||
if ($years > 0) {
|
||||
// years and months and days
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years);
|
||||
$relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : '';
|
||||
$relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
|
||||
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
|
||||
} elseif (abs($months) > 0) {
|
||||
// months, weeks and days
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months);
|
||||
$relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
|
||||
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
|
||||
} elseif (abs($weeks) > 0) {
|
||||
// weeks and days
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks);
|
||||
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
|
||||
} elseif (abs($days) > 0) {
|
||||
// days and hours
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days);
|
||||
$relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : '';
|
||||
} elseif (abs($hours) > 0) {
|
||||
// hours and minutes
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours);
|
||||
$relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : '';
|
||||
} elseif (abs($minutes) > 0) {
|
||||
// minutes only
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes);
|
||||
} else {
|
||||
// seconds only
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds);
|
||||
}
|
||||
|
||||
if (!$backwards) {
|
||||
$relativeDate = __d('cake', '%s ago', $relativeDate);
|
||||
}
|
||||
}
|
||||
return $relativeDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if specified datetime was within the interval specified, else false.
|
||||
*
|
||||
* @param mixed $timeInterval the numeric value with space then time type.
|
||||
* Example of valid types: 6 hours, 2 days, 1 minute.
|
||||
* @param mixed $dateString the datestring or unix timestamp to compare
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function wasWithinLast($timeInterval, $dateString, $userOffset = null) {
|
||||
$tmp = str_replace(' ', '', $timeInterval);
|
||||
if (is_numeric($tmp)) {
|
||||
$timeInterval = $tmp . ' ' . __d('cake', 'days');
|
||||
}
|
||||
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
$interval = $this->fromString('-' . $timeInterval);
|
||||
|
||||
if ($date >= $interval && $date <= time()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gmt as a UNIX timestamp.
|
||||
*
|
||||
* @param string $string UNIX timestamp or a valid strtotime() date string
|
||||
* @return integer UNIX timestamp
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function gmt($string = null) {
|
||||
if ($string != null) {
|
||||
$string = $this->fromString($string);
|
||||
} else {
|
||||
$string = time();
|
||||
}
|
||||
$hour = intval(date("G", $string));
|
||||
$minute = intval(date("i", $string));
|
||||
$second = intval(date("s", $string));
|
||||
$month = intval(date("n", $string));
|
||||
$day = intval(date("j", $string));
|
||||
$year = intval(date("Y", $string));
|
||||
|
||||
return gmmktime($hour, $minute, $second, $month, $day, $year);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
*
|
||||
* @param string $format date format string (or a DateTime string)
|
||||
* @param string $date Datetime string (or a date format string)
|
||||
* @param boolean $invalid flag to ignore results of fromString == false
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Formatted date string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function format($format, $date = null, $invalid = false, $userOffset = null) {
|
||||
$time = $this->fromString($date, $userOffset);
|
||||
$_time = $this->fromString($format, $userOffset);
|
||||
|
||||
if (is_numeric($_time) && $time === false) {
|
||||
$format = $date;
|
||||
return $this->i18nFormat($_time, $format, $invalid, $userOffset);
|
||||
}
|
||||
if ($time === false && $invalid !== false) {
|
||||
return $invalid;
|
||||
}
|
||||
return date($format, $time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
|
||||
* It take in account the default date format for the current language if a LC_TIME file is used.
|
||||
*
|
||||
* @param string $date Datetime string
|
||||
* @param string $format strftime format string.
|
||||
* @param boolean $invalid flag to ignore results of fromString == false
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return string Formatted and translated date string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function i18nFormat($date, $format = null, $invalid = false, $userOffset = null) {
|
||||
$date = $this->fromString($date, $userOffset);
|
||||
if ($date === false && $invalid !== false) {
|
||||
return $invalid;
|
||||
}
|
||||
if (empty($format)) {
|
||||
$format = '%x';
|
||||
}
|
||||
$format = $this->convertSpecifiers($format, $date);
|
||||
return $this->_strftime($format, $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multibyte wrapper for strftime.
|
||||
*
|
||||
* Handles utf8_encoding the result of strftime when necessary.
|
||||
*
|
||||
* @param string $format Format string.
|
||||
* @param int $date Timestamp to format.
|
||||
* @return string formatted string with correct encoding.
|
||||
*/
|
||||
protected function _strftime($format, $date) {
|
||||
$format = strftime($format, $date);
|
||||
$encoding = Configure::read('App.encoding');
|
||||
|
||||
if (!empty($encoding) && $encoding === 'UTF-8') {
|
||||
if (function_exists('mb_check_encoding')) {
|
||||
$valid = mb_check_encoding($format, $encoding);
|
||||
} else {
|
||||
$valid = !Multibyte::checkMultibyte($format);
|
||||
}
|
||||
if (!$valid) {
|
||||
$format = utf8_encode($format);
|
||||
}
|
||||
}
|
||||
return $format;
|
||||
}
|
||||
}
|
|
@ -241,6 +241,11 @@ class Debugger {
|
|||
$error = 'Notice';
|
||||
$level = LOG_NOTICE;
|
||||
break;
|
||||
case E_DEPRECATED:
|
||||
case E_USER_DEPRECATED:
|
||||
$error = 'Deprecated';
|
||||
$level = LOG_NOTICE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
|
@ -805,5 +810,4 @@ class Debugger {
|
|||
trigger_error(__d('cake_dev', 'Please change the value of \'Security.cipherSeed\' in app/Config/core.php to a numeric (digits only) seed value specific to your application'), E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -352,4 +352,252 @@ class String {
|
|||
}
|
||||
return $wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `format` The piece of html with that the phrase will be highlighted
|
||||
* - `html` If true, will ignore any HTML tags, ensuring that only the correct text is highlighted
|
||||
*
|
||||
* @param string $text Text to search the phrase in
|
||||
* @param string $phrase The phrase that will be searched
|
||||
* @param array $options An array of html attributes and options.
|
||||
* @return string The highlighted text
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
|
||||
*/
|
||||
public function highlight($text, $phrase, $options = array()) {
|
||||
if (empty($phrase)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$default = array(
|
||||
'format' => '<span class="highlight">\1</span>',
|
||||
'html' => false
|
||||
);
|
||||
$options = array_merge($default, $options);
|
||||
extract($options);
|
||||
|
||||
if (is_array($phrase)) {
|
||||
$replace = array();
|
||||
$with = array();
|
||||
|
||||
foreach ($phrase as $key => $segment) {
|
||||
$segment = '(' . preg_quote($segment, '|') . ')';
|
||||
if ($html) {
|
||||
$segment = "(?![^<]+>)$segment(?![^<]+>)";
|
||||
}
|
||||
|
||||
$with[] = (is_array($format)) ? $format[$key] : $format;
|
||||
$replace[] = "|$segment|iu";
|
||||
}
|
||||
|
||||
return preg_replace($replace, $with, $text);
|
||||
} else {
|
||||
$phrase = '(' . preg_quote($phrase, '|') . ')';
|
||||
if ($html) {
|
||||
$phrase = "(?![^<]+>)$phrase(?![^<]+>)";
|
||||
}
|
||||
|
||||
return preg_replace("|$phrase|iu", $format, $text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips given text of all links (<a href=....)
|
||||
*
|
||||
* @param string $text Text
|
||||
* @return string The text without links
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
|
||||
*/
|
||||
public function stripLinks($text) {
|
||||
return preg_replace('|<a\s+[^>]+>|im', '', preg_replace('|<\/a>|im', '', $text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates text.
|
||||
*
|
||||
* Cuts a string to the length of $length and replaces the last characters
|
||||
* with the ending if the text is longer than length.
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `ending` Will be used as Ending and appended to the trimmed string
|
||||
* - `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 integer $length Length of returned string, including ellipsis.
|
||||
* @param array $options An array of html attributes and options.
|
||||
* @return string Trimmed string.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::truncate
|
||||
*/
|
||||
public function truncate($text, $length = 100, $options = array()) {
|
||||
$default = array(
|
||||
'ending' => '...', 'exact' => true, 'html' => false
|
||||
);
|
||||
$options = array_merge($default, $options);
|
||||
extract($options);
|
||||
|
||||
if (!function_exists('mb_strlen')) {
|
||||
class_exists('Multibyte');
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
|
||||
return $text;
|
||||
}
|
||||
$totalLength = mb_strlen(strip_tags($ending));
|
||||
$openTags = array();
|
||||
$truncate = '';
|
||||
|
||||
preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
|
||||
foreach ($tags as $tag) {
|
||||
if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
|
||||
if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {
|
||||
array_unshift($openTags, $tag[2]);
|
||||
} else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
|
||||
$pos = array_search($closeTag[1], $openTags);
|
||||
if ($pos !== false) {
|
||||
array_splice($openTags, $pos, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
$truncate .= $tag[1];
|
||||
|
||||
$contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
|
||||
if ($contentLength + $totalLength > $length) {
|
||||
$left = $length - $totalLength;
|
||||
$entitiesLength = 0;
|
||||
if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
|
||||
foreach ($entities[0] as $entity) {
|
||||
if ($entity[1] + 1 - $entitiesLength <= $left) {
|
||||
$left--;
|
||||
$entitiesLength += mb_strlen($entity[0]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
|
||||
break;
|
||||
} else {
|
||||
$truncate .= $tag[3];
|
||||
$totalLength += $contentLength;
|
||||
}
|
||||
if ($totalLength >= $length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mb_strlen($text) <= $length) {
|
||||
return $text;
|
||||
} else {
|
||||
$truncate = mb_substr($text, 0, $length - mb_strlen($ending));
|
||||
}
|
||||
}
|
||||
if (!$exact) {
|
||||
$spacepos = mb_strrpos($truncate, ' ');
|
||||
if ($html) {
|
||||
$truncateCheck = mb_substr($truncate, 0, $spacepos);
|
||||
$lastOpenTag = mb_strrpos($truncateCheck, '<');
|
||||
$lastCloseTag = mb_strrpos($truncateCheck, '>');
|
||||
if ($lastOpenTag > $lastCloseTag) {
|
||||
preg_match_all('/<[\w]+[^>]*>/s', $truncate, $lastTagMatches);
|
||||
$lastTag = array_pop($lastTagMatches[0]);
|
||||
$spacepos = mb_strrpos($truncate, $lastTag) + mb_strlen($lastTag);
|
||||
}
|
||||
$bits = mb_substr($truncate, $spacepos);
|
||||
preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
|
||||
if (!empty($droppedTags)) {
|
||||
if (!empty($openTags)) {
|
||||
foreach ($droppedTags as $closingTag) {
|
||||
if (!in_array($closingTag[1], $openTags)) {
|
||||
array_unshift($openTags, $closingTag[1]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($droppedTags as $closingTag) {
|
||||
array_push($openTags, $closingTag[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$truncate = mb_substr($truncate, 0, $spacepos);
|
||||
}
|
||||
$truncate .= $ending;
|
||||
|
||||
if ($html) {
|
||||
foreach ($openTags as $tag) {
|
||||
$truncate .= '</' . $tag . '>';
|
||||
}
|
||||
}
|
||||
|
||||
return $truncate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 integer $radius The amount of characters that will be returned on each side of the founded phrase
|
||||
* @param string $ending Ending that will be appended
|
||||
* @return string Modified string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::excerpt
|
||||
*/
|
||||
public function excerpt($text, $phrase, $radius = 100, $ending = '...') {
|
||||
if (empty($text) or empty($phrase)) {
|
||||
return $this->truncate($text, $radius * 2, array('ending' => $ending));
|
||||
}
|
||||
|
||||
$append = $prepend = $ending;
|
||||
|
||||
$phraseLen = mb_strlen($phrase);
|
||||
$textLen = mb_strlen($text);
|
||||
|
||||
$pos = mb_strpos(mb_strtolower($text), mb_strtolower($phrase));
|
||||
if ($pos === false) {
|
||||
return mb_substr($text, 0, $radius) . $ending;
|
||||
}
|
||||
|
||||
$startPos = $pos - $radius;
|
||||
if ($startPos <= 0) {
|
||||
$startPos = 0;
|
||||
$prepend = '';
|
||||
}
|
||||
|
||||
$endPos = $pos + $phraseLen + $radius;
|
||||
if ($endPos >= $textLen) {
|
||||
$endPos = $textLen;
|
||||
$append = '';
|
||||
}
|
||||
|
||||
$excerpt = mb_substr($text, $startPos, $endPos - $startPos);
|
||||
$excerpt = $prepend . $excerpt . $append;
|
||||
|
||||
return $excerpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
|
||||
*/
|
||||
public function toList($list, $and = 'and', $separator = ', ') {
|
||||
if (count($list) > 1) {
|
||||
return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list);
|
||||
} else {
|
||||
return array_pop($list);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ if ($noLogs || isset($_forced_from_dbo_)):
|
|||
foreach ($logs as $source => $logInfo):
|
||||
$text = $logInfo['count'] > 1 ? 'queries' : 'query';
|
||||
printf(
|
||||
'<table class="cake-sql-log" id="cakeSqlLog_%s" summary="Cake SQL Log" cellspacing="0" border = "0">',
|
||||
'<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']);
|
||||
|
@ -49,13 +49,13 @@ if ($noLogs || isset($_forced_from_dbo_)):
|
|||
<?php
|
||||
foreach ($logInfo['log'] as $k => $i) :
|
||||
$i += array('error' => '');
|
||||
if(!empty($i['params']) && is_array($i['params'])) {
|
||||
if (!empty($i['params']) && is_array($i['params'])) {
|
||||
$bindParam = $bindType = null;
|
||||
if(preg_match('/.+ :.+/', $i['query'])) {
|
||||
if (preg_match('/.+ :.+/', $i['query'])) {
|
||||
$bindType = true;
|
||||
}
|
||||
foreach($i['params'] as $bindKey => $bindVal) {
|
||||
if($bindType === true) {
|
||||
foreach ($i['params'] as $bindKey => $bindVal) {
|
||||
if ($bindType === true) {
|
||||
$bindParam .= h($bindKey) ." => " . h($bindVal) . ", ";
|
||||
} else {
|
||||
$bindParam .= h($bindVal) . ", ";
|
||||
|
|
|
@ -271,7 +271,7 @@ class Helper extends Object {
|
|||
* `plugin` False value will prevent parsing path as a plugin
|
||||
* @return string Generated url
|
||||
*/
|
||||
public function assetUrl($path, array $options) {
|
||||
public function assetUrl($path, $options = array()) {
|
||||
if (is_array($path)) {
|
||||
$path = $this->url($path, !empty($options['fullBase']));
|
||||
} elseif (strpos($path, '://') === false) {
|
||||
|
|
|
@ -272,8 +272,8 @@ class FormHelper extends AppHelper {
|
|||
* Returns false if given form field described by the current entity has no errors.
|
||||
* Otherwise it returns the validation message
|
||||
*
|
||||
* @return mixed Either false when there or no errors, or the error
|
||||
* string. The error string could be ''.
|
||||
* @return mixed Either false when there or no errors, or an array of error
|
||||
* strings. An error string could be ''.
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::tagIsInvalid
|
||||
*/
|
||||
public function tagIsInvalid() {
|
||||
|
@ -289,8 +289,8 @@ class FormHelper extends AppHelper {
|
|||
if (empty($errors)) {
|
||||
return false;
|
||||
}
|
||||
$error = Set::classicExtract($errors, join('.', $entity));
|
||||
return $error === null ? false : $error;
|
||||
$errors = Set::classicExtract($errors, join('.', $entity));
|
||||
return $errors === null ? false : $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -739,7 +739,7 @@ class FormHelper extends AppHelper {
|
|||
*
|
||||
* ### Options
|
||||
*
|
||||
* - `for` - Set the for attribute, if its not defined the for attribute
|
||||
* - `for` - Set the for attribute, if its not defined the for attribute
|
||||
* will be generated from the $fieldName parameter using
|
||||
* FormHelper::domId().
|
||||
*
|
||||
|
@ -776,8 +776,8 @@ class FormHelper extends AppHelper {
|
|||
* }}}
|
||||
*
|
||||
* @param string $fieldName This should be "Modelname.fieldname"
|
||||
* @param string $text Text that will appear in the label field. If
|
||||
* $text is left undefined the text will be inflected from the
|
||||
* @param string $text Text that will appear in the label field. If
|
||||
* $text is left undefined the text will be inflected from the
|
||||
* fieldName.
|
||||
* @param mixed $options An array of HTML attributes, or a string, to be used as a class name.
|
||||
* @return string The formatted LABEL element
|
||||
|
|
|
@ -991,9 +991,9 @@ class HtmlHelper extends AppHelper {
|
|||
* Using multiple video files:
|
||||
*
|
||||
* {{{
|
||||
* echo $this->Html->video(
|
||||
* echo $this->Html->media(
|
||||
* array('video.mp4', array('src' => 'video.ogv', 'type' => "video/ogg; codecs='theora, vorbis'")),
|
||||
* array('type' => 'video', 'autoplay')
|
||||
* array('tag' => 'video', 'autoplay')
|
||||
* );
|
||||
* }}}
|
||||
*
|
||||
|
@ -1008,8 +1008,8 @@ class HtmlHelper extends AppHelper {
|
|||
*
|
||||
* ### Options
|
||||
*
|
||||
* - `type` Type of media element to generate, valid values are "audio" or "video".
|
||||
* If type is not provided media type is guessed based on file's mime type.
|
||||
* - `tag` Type of media element to generate, either "audio" or "video".
|
||||
* If tag is not provided it's guessed based on file's mime type.
|
||||
* - `text` Text to include inside the audio/video tag
|
||||
* - `pathPrefix` Path prefix to use for relative urls, defaults to 'files/'
|
||||
* - `fullBase` If provided the src attribute will get a full address including domain name
|
||||
|
@ -1017,15 +1017,19 @@ class HtmlHelper extends AppHelper {
|
|||
* @param string|array $path Path to the video file, relative to the webroot/{$options['pathPrefix']} directory.
|
||||
* Or an array where each item itself can be a path string or an associate array containing keys `src` and `type`
|
||||
* @param array $options Array of HTML attributes, and special options above.
|
||||
* @return string Generated video tag
|
||||
* @return string Generated media element
|
||||
*/
|
||||
public function media($path, $options = array()) {
|
||||
$options += array('type' => null, 'pathPrefix' => 'files/', 'text' => '');
|
||||
$options += array(
|
||||
'tag' => null,
|
||||
'pathPrefix' => 'files/',
|
||||
'text' => ''
|
||||
);
|
||||
|
||||
if (!empty($options['type'])) {
|
||||
$type = $options['type'];
|
||||
if (!empty($options['tag'])) {
|
||||
$tag = $options['tag'];
|
||||
} else {
|
||||
$type = null;
|
||||
$tag = null;
|
||||
}
|
||||
|
||||
if (is_array($path)) {
|
||||
|
@ -1047,19 +1051,22 @@ class HtmlHelper extends AppHelper {
|
|||
$options['text'] = $sourceTags . $options['text'];
|
||||
unset($options['fullBase']);
|
||||
} else {
|
||||
if (empty($path) && !empty($options['src'])) {
|
||||
$path = $options['src'];
|
||||
}
|
||||
$options['src'] = $this->assetUrl($path, $options);
|
||||
}
|
||||
|
||||
if ($type === null) {
|
||||
if ($tag === null) {
|
||||
if (is_array($path)) {
|
||||
$mimeType = $path[0]['type'];
|
||||
} else {
|
||||
$mimeType = $this->response->getMimeType(pathinfo($path, PATHINFO_EXTENSION));
|
||||
}
|
||||
if (preg_match('#^video/#', $mimeType)) {
|
||||
$type = 'video';
|
||||
$tag = 'video';
|
||||
} else {
|
||||
$type = 'audio';
|
||||
$tag = 'audio';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1069,12 +1076,12 @@ class HtmlHelper extends AppHelper {
|
|||
$text = $options['text'];
|
||||
|
||||
$options = array_diff_key($options, array(
|
||||
'type' => '',
|
||||
'tag' => '',
|
||||
'fullBase' => '',
|
||||
'pathPrefix' => '',
|
||||
'text' => ''
|
||||
));
|
||||
return $this->tag($type, $text, $options);
|
||||
return $this->tag($tag, $text, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('CakeNumber', 'Utility');
|
||||
App::uses('AppHelper', 'View/Helper');
|
||||
|
||||
/**
|
||||
|
@ -28,42 +29,33 @@ App::uses('AppHelper', 'View/Helper');
|
|||
*
|
||||
* @package Cake.View.Helper
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html
|
||||
* @see CakeNumber
|
||||
*/
|
||||
class NumberHelper extends AppHelper {
|
||||
|
||||
/**
|
||||
* Currencies supported by the helper. You can add additional currency formats
|
||||
* with NumberHelper::addFormat
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_currencies = array(
|
||||
'USD' => array(
|
||||
'wholeSymbol' => '$', 'wholePosition' => 'before', 'fractionSymbol' => 'c', 'fractionPosition' => 'after',
|
||||
'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()', 'escape' => true
|
||||
),
|
||||
'GBP' => array(
|
||||
'wholeSymbol' => '£', 'wholePosition' => 'before', 'fractionSymbol' => 'p', 'fractionPosition' => 'after',
|
||||
'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()','escape' => false
|
||||
),
|
||||
'EUR' => array(
|
||||
'wholeSymbol' => '€', 'wholePosition' => 'before', 'fractionSymbol' => false, 'fractionPosition' => 'after',
|
||||
'zero' => 0, 'places' => 2, 'thousands' => '.', 'decimals' => ',', 'negative' => '()', 'escape' => false
|
||||
)
|
||||
);
|
||||
/** CakeNumber instance
|
||||
*/
|
||||
protected $_CakeNumber = null;
|
||||
|
||||
/* Default Constructor
|
||||
*
|
||||
* @param View $View The View this helper is being attached to.
|
||||
* @param array $settings Configuration settings for the helper
|
||||
*/
|
||||
function __construct(View $View, $settings = array()) {
|
||||
parent::__construct($View, $settings);
|
||||
$this->_CakeNumber = new CakeNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call methods from CakeNumber utility class
|
||||
*/
|
||||
function __call($method, $params) {
|
||||
return call_user_func_array(array($this->_CakeNumber, $method), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default options for currency formats
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_currencyDefaults = array(
|
||||
'wholeSymbol' => '', 'wholePosition' => 'before', 'fractionSymbol' => '', 'fractionPosition' => 'after',
|
||||
'zero' => '0', 'places' => 2, 'thousands' => ',', 'decimals' => '.','negative' => '()', 'escape' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Formats a number with a level of precision.
|
||||
* @see: CakeNumber::precision()
|
||||
*
|
||||
* @param float $number A floating point number.
|
||||
* @param integer $precision The precision of the returned number.
|
||||
|
@ -71,33 +63,22 @@ class NumberHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::precision
|
||||
*/
|
||||
public function precision($number, $precision = 3) {
|
||||
return sprintf("%01.{$precision}f", $number);
|
||||
return $this->_CakeNumber->precision($number, $precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted-for-humans file size.
|
||||
* @see: CakeNumber::toReadableSize()
|
||||
*
|
||||
* @param integer $size Size in bytes
|
||||
* @return string Human readable size
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
|
||||
*/
|
||||
public function toReadableSize($size) {
|
||||
switch (true) {
|
||||
case $size < 1024:
|
||||
return __dn('cake', '%d Byte', '%d Bytes', $size, $size);
|
||||
case round($size / 1024) < 1024:
|
||||
return __d('cake', '%d KB', $this->precision($size / 1024, 0));
|
||||
case round($size / 1024 / 1024, 2) < 1024:
|
||||
return __d('cake', '%.2f MB', $this->precision($size / 1024 / 1024, 2));
|
||||
case round($size / 1024 / 1024 / 1024, 2) < 1024:
|
||||
return __d('cake', '%.2f GB', $this->precision($size / 1024 / 1024 / 1024, 2));
|
||||
default:
|
||||
return __d('cake', '%.2f TB', $this->precision($size / 1024 / 1024 / 1024 / 1024, 2));
|
||||
}
|
||||
return $this->_CakeNumber->toReadableSize($size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a percentage string.
|
||||
* @see: CakeNumber::toPercentage()
|
||||
*
|
||||
* @param float $number A floating point number
|
||||
* @param integer $precision The precision of the returned number
|
||||
|
@ -105,11 +86,11 @@ class NumberHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage
|
||||
*/
|
||||
public function toPercentage($number, $precision = 2) {
|
||||
return $this->precision($number, $precision) . '%';
|
||||
return $this->_CakeNumber->toPercentage($number, $precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a currency format.
|
||||
* @see: CakeNumber::format()
|
||||
*
|
||||
* @param float $number A floating point number
|
||||
* @param integer $options if int then places, if string then before, if (,.-) then use it
|
||||
|
@ -118,54 +99,11 @@ class NumberHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::format
|
||||
*/
|
||||
public function format($number, $options = false) {
|
||||
$places = 0;
|
||||
if (is_int($options)) {
|
||||
$places = $options;
|
||||
}
|
||||
|
||||
$separators = array(',', '.', '-', ':');
|
||||
|
||||
$before = $after = null;
|
||||
if (is_string($options) && !in_array($options, $separators)) {
|
||||
$before = $options;
|
||||
}
|
||||
$thousands = ',';
|
||||
if (!is_array($options) && in_array($options, $separators)) {
|
||||
$thousands = $options;
|
||||
}
|
||||
$decimals = '.';
|
||||
if (!is_array($options) && in_array($options, $separators)) {
|
||||
$decimals = $options;
|
||||
}
|
||||
|
||||
$escape = true;
|
||||
if (is_array($options)) {
|
||||
$options = array_merge(array('before' => '$', 'places' => 2, 'thousands' => ',', 'decimals' => '.'), $options);
|
||||
extract($options);
|
||||
}
|
||||
|
||||
$out = $before . number_format($number, $places, $decimals, $thousands) . $after;
|
||||
|
||||
if ($escape) {
|
||||
return h($out);
|
||||
}
|
||||
return $out;
|
||||
return $this->_CakeNumber->format($number, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number into a currency format.
|
||||
*
|
||||
* ### Options
|
||||
*
|
||||
* - `before` - The currency symbol to place before whole numbers ie. '$'
|
||||
* - `after` - The currency symbol to place after decimal numbers ie. 'c'. Set to boolean false to
|
||||
* use no decimal symbol. eg. 0.35 => $0.35.
|
||||
* - `zero` - The text to use for zero values, can be a string or a number. ie. 0, 'Free!'
|
||||
* - `places` - Number of decimal places to use. ie. 2
|
||||
* - `thousands` - Thousands separator ie. ','
|
||||
* - `decimals` - Decimal separator symbol ie. '.'
|
||||
* - `negative` - Symbol for negative numbers. If equal to '()', the number will be wrapped with ( and )
|
||||
* - `escape` - Should the output be htmlentity escaped? Defaults to true
|
||||
* @see: CakeNumber::currency()
|
||||
*
|
||||
* @param float $number
|
||||
* @param string $currency Shortcut to default options. Valid values are 'USD', 'EUR', 'GBP', otherwise
|
||||
|
@ -175,73 +113,11 @@ class NumberHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
|
||||
*/
|
||||
public function currency($number, $currency = 'USD', $options = array()) {
|
||||
$default = $this->_currencyDefaults;
|
||||
|
||||
if (isset($this->_currencies[$currency])) {
|
||||
$default = $this->_currencies[$currency];
|
||||
} elseif (is_string($currency)) {
|
||||
$options['before'] = $currency;
|
||||
}
|
||||
|
||||
$options = array_merge($default, $options);
|
||||
|
||||
if (isset($options['before']) && $options['before'] !== '') {
|
||||
$options['wholeSymbol'] = $options['before'];
|
||||
}
|
||||
if (isset($options['after']) && !$options['after'] !== '') {
|
||||
$options['fractionSymbol'] = $options['after'];
|
||||
}
|
||||
|
||||
$result = $options['before'] = $options['after'] = null;
|
||||
|
||||
$symbolKey = 'whole';
|
||||
if ($number == 0 ) {
|
||||
if ($options['zero'] !== 0 ) {
|
||||
return $options['zero'];
|
||||
}
|
||||
} elseif ($number < 1 && $number > -1 ) {
|
||||
if ($options['fractionSymbol'] !== false) {
|
||||
$multiply = intval('1' . str_pad('', $options['places'], '0'));
|
||||
$number = $number * $multiply;
|
||||
$options['places'] = null;
|
||||
$symbolKey = 'fraction';
|
||||
}
|
||||
}
|
||||
|
||||
$position = $options[$symbolKey.'Position'] != 'after' ? 'before' : 'after';
|
||||
$options[$position] = $options[$symbolKey.'Symbol'];
|
||||
|
||||
$abs = abs($number);
|
||||
$result = $this->format($abs, $options);
|
||||
|
||||
if ($number < 0 ) {
|
||||
if ($options['negative'] == '()') {
|
||||
$result = '(' . $result .')';
|
||||
} else {
|
||||
$result = $options['negative'] . $result;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
return $this->_CakeNumber->currency($number, $currency, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a currency format to the Number helper. Makes reusing
|
||||
* currency formats easier.
|
||||
*
|
||||
* {{{ $number->addFormat('NOK', array('before' => 'Kr. ')); }}}
|
||||
*
|
||||
* You can now use `NOK` as a shortform when formatting currency amounts.
|
||||
*
|
||||
* {{{ $number->currency($value, 'NOK'); }}}
|
||||
*
|
||||
* Added formats are merged with the following defaults.
|
||||
*
|
||||
* {{{
|
||||
* array(
|
||||
* 'before' => '$', 'after' => 'c', 'zero' => 0, 'places' => 2, 'thousands' => ',',
|
||||
* 'decimals' => '.', 'negative' => '()', 'escape' => true
|
||||
* )
|
||||
* }}}
|
||||
* @see: CakeNumber::addFormat()
|
||||
*
|
||||
* @param string $formatName The format name to be used in the future.
|
||||
* @param array $options The array of options for this format.
|
||||
|
@ -250,7 +126,7 @@ class NumberHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::addFormat
|
||||
*/
|
||||
public function addFormat($formatName, $options) {
|
||||
$this->_currencies[$formatName] = $options + $this->_currencyDefaults;
|
||||
return $this->_CakeNumber->addFormat($formatName, $options);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
*/
|
||||
|
||||
App::uses('AppHelper', 'View/Helper');
|
||||
App::uses('HtmlHelper', 'Helper');
|
||||
App::uses('Multibyte', 'I18n');
|
||||
|
||||
/**
|
||||
* Text helper library.
|
||||
|
@ -31,6 +29,7 @@ App::uses('Multibyte', 'I18n');
|
|||
* @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 {
|
||||
|
||||
|
@ -50,66 +49,26 @@ class TextHelper extends AppHelper {
|
|||
protected $_placeholders = array();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `format` The piece of html with that the phrase will be highlighted
|
||||
* - `html` If true, will ignore any HTML tags, ensuring that only the correct text is highlighted
|
||||
*
|
||||
* @param string $text Text to search the phrase in
|
||||
* @param string $phrase The phrase that will be searched
|
||||
* @param array $options An array of html attributes and options.
|
||||
* @return string The highlighted text
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
|
||||
* String utility instance
|
||||
*/
|
||||
public function highlight($text, $phrase, $options = array()) {
|
||||
if (empty($phrase)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$default = array(
|
||||
'format' => '<span class="highlight">\1</span>',
|
||||
'html' => false
|
||||
);
|
||||
$options = array_merge($default, $options);
|
||||
extract($options);
|
||||
|
||||
if (is_array($phrase)) {
|
||||
$replace = array();
|
||||
$with = array();
|
||||
|
||||
foreach ($phrase as $key => $segment) {
|
||||
$segment = '(' . preg_quote($segment, '|') . ')';
|
||||
if ($html) {
|
||||
$segment = "(?![^<]+>)$segment(?![^<]+>)";
|
||||
}
|
||||
|
||||
$with[] = (is_array($format)) ? $format[$key] : $format;
|
||||
$replace[] = "|$segment|iu";
|
||||
}
|
||||
|
||||
return preg_replace($replace, $with, $text);
|
||||
} else {
|
||||
$phrase = '(' . preg_quote($phrase, '|') . ')';
|
||||
if ($html) {
|
||||
$phrase = "(?![^<]+>)$phrase(?![^<]+>)";
|
||||
}
|
||||
|
||||
return preg_replace("|$phrase|iu", $format, $text);
|
||||
}
|
||||
}
|
||||
protected $_String;
|
||||
|
||||
/**
|
||||
* Strips given text of all links (<a href=....)
|
||||
* Constructor
|
||||
*
|
||||
* @param string $text Text
|
||||
* @return string The text without links
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
|
||||
* @param View $View the view object the helper is attached to.
|
||||
* @param array $settings Settings array Settings array
|
||||
*/
|
||||
public function stripLinks($text) {
|
||||
return preg_replace('|<a\s+[^>]+>|im', '', preg_replace('|<\/a>|im', '', $text));
|
||||
public function __construct(View $View, $settings = array()) {
|
||||
parent::__construct($View, $settings);
|
||||
$this->_String = new String($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call methods from String utility class
|
||||
*/
|
||||
public function __call($method, $params) {
|
||||
return call_user_func_array(array($this->_String, $method), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,16 +198,31 @@ class TextHelper extends AppHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Truncates text.
|
||||
* @see String::highlight()
|
||||
*
|
||||
* Cuts a string to the length of $length and replaces the last characters
|
||||
* with the ending if the text is longer than length.
|
||||
* @param string $text Text to search the phrase in
|
||||
* @param string $phrase The phrase that will be searched
|
||||
* @param array $options An array of html attributes and options.
|
||||
* @return string The highlighted text
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
|
||||
*/
|
||||
public function highlight($text, $phrase, $options = array()) {
|
||||
return $this->_String->highlight($text, $phrase, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see String::stripLinks()
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `ending` Will be used as Ending and appended to the trimmed string
|
||||
* - `exact` If false, $text will not be cut mid-word
|
||||
* - `html` If true, HTML tags would be handled correctly
|
||||
* @param string $text Text
|
||||
* @return string The text without links
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
|
||||
*/
|
||||
public function stripLinks($text) {
|
||||
return $this->_String->stripLinks($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see String::truncate()
|
||||
*
|
||||
* @param string $text String to truncate.
|
||||
* @param integer $length Length of returned string, including ellipsis.
|
||||
|
@ -257,113 +231,11 @@ class TextHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::truncate
|
||||
*/
|
||||
public function truncate($text, $length = 100, $options = array()) {
|
||||
$default = array(
|
||||
'ending' => '...', 'exact' => true, 'html' => false
|
||||
);
|
||||
$options = array_merge($default, $options);
|
||||
extract($options);
|
||||
|
||||
if (!function_exists('mb_strlen')) {
|
||||
class_exists('Multibyte');
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
|
||||
return $text;
|
||||
}
|
||||
$totalLength = mb_strlen(strip_tags($ending));
|
||||
$openTags = array();
|
||||
$truncate = '';
|
||||
|
||||
preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
|
||||
foreach ($tags as $tag) {
|
||||
if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
|
||||
if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {
|
||||
array_unshift($openTags, $tag[2]);
|
||||
} else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
|
||||
$pos = array_search($closeTag[1], $openTags);
|
||||
if ($pos !== false) {
|
||||
array_splice($openTags, $pos, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
$truncate .= $tag[1];
|
||||
|
||||
$contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
|
||||
if ($contentLength + $totalLength > $length) {
|
||||
$left = $length - $totalLength;
|
||||
$entitiesLength = 0;
|
||||
if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
|
||||
foreach ($entities[0] as $entity) {
|
||||
if ($entity[1] + 1 - $entitiesLength <= $left) {
|
||||
$left--;
|
||||
$entitiesLength += mb_strlen($entity[0]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
|
||||
break;
|
||||
} else {
|
||||
$truncate .= $tag[3];
|
||||
$totalLength += $contentLength;
|
||||
}
|
||||
if ($totalLength >= $length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mb_strlen($text) <= $length) {
|
||||
return $text;
|
||||
} else {
|
||||
$truncate = mb_substr($text, 0, $length - mb_strlen($ending));
|
||||
}
|
||||
}
|
||||
if (!$exact) {
|
||||
$spacepos = mb_strrpos($truncate, ' ');
|
||||
if ($html) {
|
||||
$truncateCheck = mb_substr($truncate, 0, $spacepos);
|
||||
$lastOpenTag = mb_strrpos($truncateCheck, '<');
|
||||
$lastCloseTag = mb_strrpos($truncateCheck, '>');
|
||||
if ($lastOpenTag > $lastCloseTag) {
|
||||
preg_match_all('/<[\w]+[^>]*>/s', $truncate, $lastTagMatches);
|
||||
$lastTag = array_pop($lastTagMatches[0]);
|
||||
$spacepos = mb_strrpos($truncate, $lastTag) + mb_strlen($lastTag);
|
||||
}
|
||||
$bits = mb_substr($truncate, $spacepos);
|
||||
preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
|
||||
if (!empty($droppedTags)) {
|
||||
if (!empty($openTags)) {
|
||||
foreach ($droppedTags as $closingTag) {
|
||||
if (!in_array($closingTag[1], $openTags)) {
|
||||
array_unshift($openTags, $closingTag[1]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($droppedTags as $closingTag) {
|
||||
array_push($openTags, $closingTag[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$truncate = mb_substr($truncate, 0, $spacepos);
|
||||
}
|
||||
$truncate .= $ending;
|
||||
|
||||
if ($html) {
|
||||
foreach ($openTags as $tag) {
|
||||
$truncate .= '</' . $tag . '>';
|
||||
}
|
||||
}
|
||||
|
||||
return $truncate;
|
||||
return $this->_String->truncate($text, $length, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts an excerpt from the text surrounding the phrase with a number of characters on each side
|
||||
* determined by radius.
|
||||
* @see String::excerpt()
|
||||
*
|
||||
* @param string $text String to search the phrase in
|
||||
* @param string $phrase Phrase that will be searched for
|
||||
|
@ -373,40 +245,11 @@ class TextHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::excerpt
|
||||
*/
|
||||
public function excerpt($text, $phrase, $radius = 100, $ending = '...') {
|
||||
if (empty($text) or empty($phrase)) {
|
||||
return $this->truncate($text, $radius * 2, array('ending' => $ending));
|
||||
}
|
||||
|
||||
$append = $prepend = $ending;
|
||||
|
||||
$phraseLen = mb_strlen($phrase);
|
||||
$textLen = mb_strlen($text);
|
||||
|
||||
$pos = mb_strpos(mb_strtolower($text), mb_strtolower($phrase));
|
||||
if ($pos === false) {
|
||||
return mb_substr($text, 0, $radius) . $ending;
|
||||
}
|
||||
|
||||
$startPos = $pos - $radius;
|
||||
if ($startPos <= 0) {
|
||||
$startPos = 0;
|
||||
$prepend = '';
|
||||
}
|
||||
|
||||
$endPos = $pos + $phraseLen + $radius;
|
||||
if ($endPos >= $textLen) {
|
||||
$endPos = $textLen;
|
||||
$append = '';
|
||||
}
|
||||
|
||||
$excerpt = mb_substr($text, $startPos, $endPos - $startPos);
|
||||
$excerpt = $prepend . $excerpt . $append;
|
||||
|
||||
return $excerpt;
|
||||
return $this->_String->excerpt($text, $phrase, $radius, $ending);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a comma separated list where the last two items are joined with 'and', forming natural English
|
||||
* @see String::toList()
|
||||
*
|
||||
* @param array $list The list to be joined
|
||||
* @param string $and The word used to join the last and second last items together with. Defaults to 'and'
|
||||
|
@ -415,10 +258,7 @@ class TextHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
|
||||
*/
|
||||
public function toList($list, $and = 'and', $separator = ', ') {
|
||||
if (count($list) > 1) {
|
||||
return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list);
|
||||
} else {
|
||||
return array_pop($list);
|
||||
}
|
||||
return $this->_String->toList($list, $and, $separator);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('CakeTime', 'Utility');
|
||||
App::uses('Multibyte', 'I18n');
|
||||
App::uses('AppHelper', 'View/Helper');
|
||||
|
||||
|
@ -27,19 +28,14 @@ App::uses('AppHelper', 'View/Helper');
|
|||
*
|
||||
* @package Cake.View.Helper
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html
|
||||
* @see CakeTime
|
||||
*/
|
||||
class TimeHelper extends AppHelper {
|
||||
|
||||
/**
|
||||
* The format to use when formatting a time using `TimeHelper::nice()`
|
||||
*
|
||||
* The format should use the locale strings as defined in the PHP docs under
|
||||
* `strftime` (http://php.net/manual/en/function.strftime.php)
|
||||
*
|
||||
* @var string
|
||||
* @see TimeHelper::format()
|
||||
* CakeTime instance
|
||||
*/
|
||||
public $niceFormat = '%a, %b %eS %Y, %H:%M';
|
||||
protected $_CakeTime = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -48,15 +44,69 @@ class TimeHelper extends AppHelper {
|
|||
* @param array $settings Settings array Settings array
|
||||
*/
|
||||
public function __construct(View $View, $settings = array()) {
|
||||
if (isset($settings['niceFormat'])) {
|
||||
$this->niceFormat = $settings['niceFormat'];
|
||||
}
|
||||
parent::__construct($View, $settings);
|
||||
$this->_CakeTime = new CakeTime($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string representing the format for the function strftime and returns a
|
||||
* windows safe and i18n aware format.
|
||||
* Magic accessor for deprecated attributes.
|
||||
*
|
||||
* @param string $name Name of the attribute to set.
|
||||
* @param string $value Value of the attribute to set.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
switch ($name) {
|
||||
case 'niceFormat':
|
||||
$this->_CakeTime->{$name} = $value; break;
|
||||
default:
|
||||
$this->{$name} = $value; break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic isset check for deprecated attributes.
|
||||
*
|
||||
* @param string $name Name of the attribute to check.
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset($name) {
|
||||
if (isset($this->{$name})) {
|
||||
return true;
|
||||
}
|
||||
$magicGet = array('niceFormat');
|
||||
if (in_array($name, $magicGet)) {
|
||||
return $this->__get($name) !== null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic accessor for attributes that were deprecated.
|
||||
*
|
||||
* @param string $name Name of the attribute to get.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name) {
|
||||
if (isset($this->_CakeTime->{$name})) {
|
||||
return $this->_CakeTime->{$name};
|
||||
}
|
||||
$magicGet = array('niceFormat');
|
||||
if (in_array($name, $magicGet)) {
|
||||
return $this->_CakeTime->{$name};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call methods from CakeTime utility class
|
||||
*/
|
||||
public function __call($method, $params) {
|
||||
return call_user_func_array(array($this->_CakeTime, $method), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CakeTime::convertSpecifiers()
|
||||
*
|
||||
* @param string $format Format with specifiers for strftime function.
|
||||
* Accepts the special specifier %S which mimics the modifier S for date()
|
||||
|
@ -65,112 +115,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function convertSpecifiers($format, $time = null) {
|
||||
if (!$time) {
|
||||
$time = time();
|
||||
}
|
||||
$this->__time = $time;
|
||||
return preg_replace_callback('/\%(\w+)/', array($this, '_translateSpecifier'), $format);
|
||||
return $this->_CakeTime->convertSpecifiers($format, $time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auxiliary function to translate a matched specifier element from a regular expression into
|
||||
* a windows safe and i18n aware specifier
|
||||
*
|
||||
* @param array $specifier match from regular expression
|
||||
* @return string converted element
|
||||
*/
|
||||
protected function _translateSpecifier($specifier) {
|
||||
switch ($specifier[1]) {
|
||||
case 'a':
|
||||
$abday = __dc('cake', 'abday', 5);
|
||||
if (is_array($abday)) {
|
||||
return $abday[date('w', $this->__time)];
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
$day = __dc('cake', 'day', 5);
|
||||
if (is_array($day)) {
|
||||
return $day[date('w', $this->__time)];
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
$format = __dc('cake', 'd_t_fmt', 5);
|
||||
if ($format != 'd_t_fmt') {
|
||||
return $this->convertSpecifiers($format, $this->__time);
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
return sprintf("%02d", date('Y', $this->__time) / 100);
|
||||
case 'D':
|
||||
return '%m/%d/%y';
|
||||
case 'e':
|
||||
if (DS === '/') {
|
||||
return '%e';
|
||||
}
|
||||
$day = date('j', $this->__time);
|
||||
if ($day < 10) {
|
||||
$day = ' ' . $day;
|
||||
}
|
||||
return $day;
|
||||
case 'eS' :
|
||||
return date('jS', $this->__time);
|
||||
case 'b':
|
||||
case 'h':
|
||||
$months = __dc('cake', 'abmon', 5);
|
||||
if (is_array($months)) {
|
||||
return $months[date('n', $this->__time) -1];
|
||||
}
|
||||
return '%b';
|
||||
case 'B':
|
||||
$months = __dc('cake', 'mon', 5);
|
||||
if (is_array($months)) {
|
||||
return $months[date('n', $this->__time) -1];
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
return "\n";
|
||||
case 'p':
|
||||
case 'P':
|
||||
$default = array('am' => 0, 'pm' => 1);
|
||||
$meridiem = $default[date('a', $this->__time)];
|
||||
$format = __dc('cake', 'am_pm', 5);
|
||||
if (is_array($format)) {
|
||||
$meridiem = $format[$meridiem];
|
||||
return ($specifier[1] == 'P') ? strtolower($meridiem) : strtoupper($meridiem);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
$complete = __dc('cake', 't_fmt_ampm', 5);
|
||||
if ($complete != 't_fmt_ampm') {
|
||||
return str_replace('%p', $this->_translateSpecifier(array('%p', 'p')), $complete);
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
return date('H:i', $this->__time);
|
||||
case 't':
|
||||
return "\t";
|
||||
case 'T':
|
||||
return '%H:%M:%S';
|
||||
case 'u':
|
||||
return ($weekDay = date('w', $this->__time)) ? $weekDay : 7;
|
||||
case 'x':
|
||||
$format = __dc('cake', 'd_fmt', 5);
|
||||
if ($format != 'd_fmt') {
|
||||
return $this->convertSpecifiers($format, $this->__time);
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
$format = __dc('cake', 't_fmt', 5);
|
||||
if ($format != 't_fmt') {
|
||||
return $this->convertSpecifiers($format, $this->__time);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $specifier[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts given time (in server's time zone) to user's local time, given his/her offset from GMT.
|
||||
* @see CakeTime::convert()
|
||||
*
|
||||
* @param string $serverTime UNIX timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -178,24 +127,21 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function convert($serverTime, $userOffset) {
|
||||
$serverOffset = $this->serverOffset();
|
||||
$gmtTime = $serverTime - $serverOffset;
|
||||
$userTime = $gmtTime + $userOffset * (60*60);
|
||||
return $userTime;
|
||||
return $this->_CakeTime->convert($serverTime, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns server's offset from GMT in seconds.
|
||||
* @see CakeTime::serverOffset()
|
||||
*
|
||||
* @return integer Offset
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function serverOffset() {
|
||||
return date('Z', time());
|
||||
return $this->_CakeTime->serverOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
|
||||
* @see CakeTime::fromString()
|
||||
*
|
||||
* @param string $dateString Datetime string
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -203,28 +149,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function fromString($dateString, $userOffset = null) {
|
||||
if (empty($dateString)) {
|
||||
return false;
|
||||
}
|
||||
if (is_integer($dateString) || is_numeric($dateString)) {
|
||||
$date = intval($dateString);
|
||||
} else {
|
||||
$date = strtotime($dateString);
|
||||
}
|
||||
if ($userOffset !== null) {
|
||||
return $this->convert($date, $userOffset);
|
||||
}
|
||||
if ($date === -1) {
|
||||
return false;
|
||||
}
|
||||
return $date;
|
||||
return $this->_CakeTime->fromString($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a nicely formatted date string for given Datetime string.
|
||||
*
|
||||
* See http://php.net/manual/en/function.strftime.php for information on formatting
|
||||
* using locale strings.
|
||||
* @see CakeTime::nice()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -233,25 +162,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function nice($dateString = null, $userOffset = null, $format = null) {
|
||||
if ($dateString != null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
} else {
|
||||
$date = time();
|
||||
}
|
||||
if (!$format) {
|
||||
$format = $this->niceFormat;
|
||||
}
|
||||
$format = $this->convertSpecifiers($format, $date);
|
||||
return $this->_strftime($format, $date);
|
||||
return $this->_CakeTime->nice($dateString, $userOffset, $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted descriptive date string for given datetime string.
|
||||
*
|
||||
* If the given date is today, the returned string could be "Today, 16:54".
|
||||
* If the given date was yesterday, the returned string could be "Yesterday, 16:54".
|
||||
* If $dateString's year is the current year, the returned string does not
|
||||
* include mention of the year.
|
||||
* @see CakeTime::niceShort()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -259,24 +174,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function niceShort($dateString = null, $userOffset = null) {
|
||||
$date = $dateString ? $this->fromString($dateString, $userOffset) : time();
|
||||
|
||||
$y = $this->isThisYear($date) ? '' : ' %Y';
|
||||
|
||||
if ($this->isToday($dateString, $userOffset)) {
|
||||
$ret = __d('cake', 'Today, %s', $this->_strftime("%H:%M", $date));
|
||||
} elseif ($this->wasYesterday($dateString, $userOffset)) {
|
||||
$ret = __d('cake', 'Yesterday, %s', $this->_strftime("%H:%M", $date));
|
||||
} else {
|
||||
$format = $this->convertSpecifiers("%b %eS{$y}, %H:%M", $date);
|
||||
$ret = $this->_strftime($format, $date);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
return $this->_CakeTime->niceShort($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a partial SQL string to search for all records between two dates.
|
||||
* @see CakeTime::daysAsSql()
|
||||
*
|
||||
* @param string $begin Datetime string or Unix timestamp
|
||||
* @param string $end Datetime string or Unix timestamp
|
||||
|
@ -286,17 +188,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function daysAsSql($begin, $end, $fieldName, $userOffset = null) {
|
||||
$begin = $this->fromString($begin, $userOffset);
|
||||
$end = $this->fromString($end, $userOffset);
|
||||
$begin = date('Y-m-d', $begin) . ' 00:00:00';
|
||||
$end = date('Y-m-d', $end) . ' 23:59:59';
|
||||
|
||||
return "($fieldName >= '$begin') AND ($fieldName <= '$end')";
|
||||
return $this->_CakeTime->daysAsSql($begin, $end, $fieldName, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a partial SQL string to search for all records between two times
|
||||
* occurring on the same day.
|
||||
* @see CakeTime::dayAsSql()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param string $fieldName Name of database field to compare with
|
||||
|
@ -305,12 +201,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function dayAsSql($dateString, $fieldName, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return $this->daysAsSql($dateString, $dateString, $fieldName);
|
||||
return $this->_CakeTime->dayAsSql($dateString, $fieldName, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is today.
|
||||
* @see CakeTime::isToday()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -318,12 +213,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isToday($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d', $date) == date('Y-m-d', time());
|
||||
return $this->_CakeTime->isToday($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within this week.
|
||||
* @see CakeTime::isThisWeek()
|
||||
*
|
||||
* @param string $dateString
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -331,24 +225,23 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isThisWeek($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('W o', $date) == date('W o', time());
|
||||
return $this->_CakeTime->isThisWeek($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within this month
|
||||
* @see CakeTime::isThisMonth()
|
||||
*
|
||||
* @param string $dateString
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
* @return boolean True if datetime string is within current month
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isThisMonth($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString);
|
||||
return date('m Y', $date) == date('m Y', time());
|
||||
return $this->_CakeTime->isThisMonth($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is within current year.
|
||||
* @see CakeTime::isThisYear()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -356,12 +249,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isThisYear($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y', $date) == date('Y', time());
|
||||
return $this->_CakeTime->isThisYear($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string was yesterday.
|
||||
* @see CakeTime::wasYesterday()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -370,12 +262,11 @@ class TimeHelper extends AppHelper {
|
|||
*
|
||||
*/
|
||||
public function wasYesterday($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday'));
|
||||
return $this->_CakeTime->wasYesterday($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given datetime string is tomorrow.
|
||||
* @see CakeTime::isTomorrow()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -383,12 +274,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function isTomorrow($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow'));
|
||||
return $this->_CakeTime->isTomorrow($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quarter
|
||||
* @see CakeTime::toQuarter()
|
||||
*
|
||||
* @param string $dateString
|
||||
* @param boolean $range if true returns a range in Y-m-d format
|
||||
|
@ -396,36 +286,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toQuarter($dateString, $range = false) {
|
||||
$time = $this->fromString($dateString);
|
||||
$date = ceil(date('m', $time) / 3);
|
||||
|
||||
if ($range === true) {
|
||||
$range = 'Y-m-d';
|
||||
}
|
||||
|
||||
if ($range !== false) {
|
||||
$year = date('Y', $time);
|
||||
|
||||
switch ($date) {
|
||||
case 1:
|
||||
$date = array($year.'-01-01', $year.'-03-31');
|
||||
break;
|
||||
case 2:
|
||||
$date = array($year.'-04-01', $year.'-06-30');
|
||||
break;
|
||||
case 3:
|
||||
$date = array($year.'-07-01', $year.'-09-30');
|
||||
break;
|
||||
case 4:
|
||||
$date = array($year.'-10-01', $year.'-12-31');
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $date;
|
||||
return $this->_CakeTime->toQuarter($dateString, $range);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
|
||||
* @see CakeTime::toUnix()
|
||||
*
|
||||
* @param string $dateString Datetime string to be represented as a Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -433,11 +298,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toUnix($dateString, $userOffset = null) {
|
||||
return $this->fromString($dateString, $userOffset);
|
||||
return $this->_CakeTime->toUnix($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a date formatted for Atom RSS feeds.
|
||||
* @see CakeTime::toAtom()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -445,12 +310,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toAtom($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
return date('Y-m-d\TH:i:s\Z', $date);
|
||||
return $this->_CakeTime->toAtom($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats date for RSS feeds
|
||||
* @see CakeTime::toRSS()
|
||||
*
|
||||
* @param string $dateString Datetime string or Unix timestamp
|
||||
* @param integer $userOffset User's offset from GMT (in hours)
|
||||
|
@ -458,40 +322,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function toRSS($dateString, $userOffset = null) {
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
|
||||
if (!is_null($userOffset)) {
|
||||
if ($userOffset == 0) {
|
||||
$timezone = '+0000';
|
||||
} else {
|
||||
$hours = (int) floor(abs($userOffset));
|
||||
$minutes = (int) (fmod(abs($userOffset), $hours) * 60);
|
||||
$timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT);
|
||||
}
|
||||
return date('D, d M Y H:i:s', $date) . ' ' . $timezone;
|
||||
}
|
||||
return date("r", $date);
|
||||
return $this->_CakeTime->toRSS($dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either a relative date or a formatted date depending
|
||||
* on the difference between the current time and given datetime.
|
||||
* $datetime should be in a <i>strtotime</i> - parsable format, like MySQL's datetime datatype.
|
||||
*
|
||||
* ### Options:
|
||||
*
|
||||
* - `format` => a fall back format if the relative time is longer than the duration specified by end
|
||||
* - `end` => The end of relative time telling
|
||||
* - `userOffset` => Users offset from GMT (in hours)
|
||||
*
|
||||
* Relative dates look something like this:
|
||||
* 3 weeks, 4 days ago
|
||||
* 15 seconds ago
|
||||
*
|
||||
* Default date formatting is d/m/yy e.g: on 18/2/09
|
||||
*
|
||||
* The returned string includes 'ago' or 'on' and assumes you'll properly add a word
|
||||
* like 'Posted ' before the function output.
|
||||
* @see CakeTime::timeAgoInWords()
|
||||
*
|
||||
* @param string $dateTime Datetime string or Unix timestamp
|
||||
* @param array $options Default format if timestamp is used in $dateString
|
||||
|
@ -499,163 +334,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function timeAgoInWords($dateTime, $options = array()) {
|
||||
$userOffset = null;
|
||||
if (is_array($options) && isset($options['userOffset'])) {
|
||||
$userOffset = $options['userOffset'];
|
||||
}
|
||||
$now = time();
|
||||
if (!is_null($userOffset)) {
|
||||
$now = $this->convert(time(), $userOffset);
|
||||
}
|
||||
$inSeconds = $this->fromString($dateTime, $userOffset);
|
||||
$backwards = ($inSeconds > $now);
|
||||
|
||||
$format = 'j/n/y';
|
||||
$end = '+1 month';
|
||||
|
||||
if (is_array($options)) {
|
||||
if (isset($options['format'])) {
|
||||
$format = $options['format'];
|
||||
unset($options['format']);
|
||||
}
|
||||
if (isset($options['end'])) {
|
||||
$end = $options['end'];
|
||||
unset($options['end']);
|
||||
}
|
||||
} else {
|
||||
$format = $options;
|
||||
}
|
||||
|
||||
if ($backwards) {
|
||||
$futureTime = $inSeconds;
|
||||
$pastTime = $now;
|
||||
} else {
|
||||
$futureTime = $now;
|
||||
$pastTime = $inSeconds;
|
||||
}
|
||||
$diff = $futureTime - $pastTime;
|
||||
|
||||
// If more than a week, then take into account the length of months
|
||||
if ($diff >= 604800) {
|
||||
$current = array();
|
||||
$date = array();
|
||||
|
||||
list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime));
|
||||
|
||||
list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime));
|
||||
$years = $months = $weeks = $days = $hours = $minutes = $seconds = 0;
|
||||
|
||||
if ($future['Y'] == $past['Y'] && $future['m'] == $past['m']) {
|
||||
$months = 0;
|
||||
$years = 0;
|
||||
} else {
|
||||
if ($future['Y'] == $past['Y']) {
|
||||
$months = $future['m'] - $past['m'];
|
||||
} else {
|
||||
$years = $future['Y'] - $past['Y'];
|
||||
$months = $future['m'] + ((12 * $years) - $past['m']);
|
||||
|
||||
if ($months >= 12) {
|
||||
$years = floor($months / 12);
|
||||
$months = $months - ($years * 12);
|
||||
}
|
||||
|
||||
if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] == 1) {
|
||||
$years --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($future['d'] >= $past['d']) {
|
||||
$days = $future['d'] - $past['d'];
|
||||
} else {
|
||||
$daysInPastMonth = date('t', $pastTime);
|
||||
$daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y']));
|
||||
|
||||
if (!$backwards) {
|
||||
$days = ($daysInPastMonth - $past['d']) + $future['d'];
|
||||
} else {
|
||||
$days = ($daysInFutureMonth - $past['d']) + $future['d'];
|
||||
}
|
||||
|
||||
if ($future['m'] != $past['m']) {
|
||||
$months --;
|
||||
}
|
||||
}
|
||||
|
||||
if ($months == 0 && $years >= 1 && $diff < ($years * 31536000)) {
|
||||
$months = 11;
|
||||
$years --;
|
||||
}
|
||||
|
||||
if ($months >= 12) {
|
||||
$years = $years + 1;
|
||||
$months = $months - 12;
|
||||
}
|
||||
|
||||
if ($days >= 7) {
|
||||
$weeks = floor($days / 7);
|
||||
$days = $days - ($weeks * 7);
|
||||
}
|
||||
} else {
|
||||
$years = $months = $weeks = 0;
|
||||
$days = floor($diff / 86400);
|
||||
|
||||
$diff = $diff - ($days * 86400);
|
||||
|
||||
$hours = floor($diff / 3600);
|
||||
$diff = $diff - ($hours * 3600);
|
||||
|
||||
$minutes = floor($diff / 60);
|
||||
$diff = $diff - ($minutes * 60);
|
||||
$seconds = $diff;
|
||||
}
|
||||
$relativeDate = '';
|
||||
$diff = $futureTime - $pastTime;
|
||||
|
||||
if ($diff > abs($now - $this->fromString($end))) {
|
||||
$relativeDate = __d('cake', 'on %s', date($format, $inSeconds));
|
||||
} else {
|
||||
if ($years > 0) {
|
||||
// years and months and days
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years);
|
||||
$relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : '';
|
||||
$relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
|
||||
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
|
||||
} elseif (abs($months) > 0) {
|
||||
// months, weeks and days
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months);
|
||||
$relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
|
||||
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
|
||||
} elseif (abs($weeks) > 0) {
|
||||
// weeks and days
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks);
|
||||
$relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
|
||||
} elseif (abs($days) > 0) {
|
||||
// days and hours
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days);
|
||||
$relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : '';
|
||||
} elseif (abs($hours) > 0) {
|
||||
// hours and minutes
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours);
|
||||
$relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : '';
|
||||
} elseif (abs($minutes) > 0) {
|
||||
// minutes only
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes);
|
||||
} else {
|
||||
// seconds only
|
||||
$relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds);
|
||||
}
|
||||
|
||||
if (!$backwards) {
|
||||
$relativeDate = __d('cake', '%s ago', $relativeDate);
|
||||
}
|
||||
}
|
||||
return $relativeDate;
|
||||
return $this->_CakeTime->timeAgoInWords($dateTime, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if specified datetime was within the interval specified, else false.
|
||||
* @see CakeTime::wasWithinLast()
|
||||
*
|
||||
* @param mixed $timeInterval the numeric value with space then time type.
|
||||
* Example of valid types: 6 hours, 2 days, 1 minute.
|
||||
|
@ -665,48 +348,22 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
|
||||
*/
|
||||
public function wasWithinLast($timeInterval, $dateString, $userOffset = null) {
|
||||
$tmp = str_replace(' ', '', $timeInterval);
|
||||
if (is_numeric($tmp)) {
|
||||
$timeInterval = $tmp . ' ' . __d('cake', 'days');
|
||||
}
|
||||
|
||||
$date = $this->fromString($dateString, $userOffset);
|
||||
$interval = $this->fromString('-' . $timeInterval);
|
||||
|
||||
if ($date >= $interval && $date <= time()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $this->_CakeTime->wasWithinLast($timeInterval, $dateString, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gmt as a UNIX timestamp.
|
||||
* @see CakeTime::gmt()
|
||||
*
|
||||
* @param string $string UNIX timestamp or a valid strtotime() date string
|
||||
* @return integer UNIX timestamp
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function gmt($string = null) {
|
||||
if ($string != null) {
|
||||
$string = $this->fromString($string);
|
||||
} else {
|
||||
$string = time();
|
||||
}
|
||||
$hour = intval(date("G", $string));
|
||||
$minute = intval(date("i", $string));
|
||||
$second = intval(date("s", $string));
|
||||
$month = intval(date("n", $string));
|
||||
$day = intval(date("j", $string));
|
||||
$year = intval(date("Y", $string));
|
||||
|
||||
return gmmktime($hour, $minute, $second, $month, $day, $year);
|
||||
return $this->_CakeTime->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()
|
||||
* @see CakeTime::format()
|
||||
*
|
||||
* @param string $format date format string (or a DateTime string)
|
||||
* @param string $date Datetime string (or a date format string)
|
||||
|
@ -716,22 +373,11 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function format($format, $date = null, $invalid = false, $userOffset = null) {
|
||||
$time = $this->fromString($date, $userOffset);
|
||||
$_time = $this->fromString($format, $userOffset);
|
||||
|
||||
if (is_numeric($_time) && $time === false) {
|
||||
$format = $date;
|
||||
return $this->i18nFormat($_time, $format, $invalid, $userOffset);
|
||||
}
|
||||
if ($time === false && $invalid !== false) {
|
||||
return $invalid;
|
||||
}
|
||||
return date($format, $time);
|
||||
return $this->_CakeTime->format($format, $date, $invalid, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
|
||||
* It take in account the default date format for the current language if a LC_TIME file is used.
|
||||
* @see CakeTime::i18nFormat()
|
||||
*
|
||||
* @param string $date Datetime string
|
||||
* @param string $format strftime format string.
|
||||
|
@ -741,40 +387,7 @@ class TimeHelper extends AppHelper {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
*/
|
||||
public function i18nFormat($date, $format = null, $invalid = false, $userOffset = null) {
|
||||
$date = $this->fromString($date, $userOffset);
|
||||
if ($date === false && $invalid !== false) {
|
||||
return $invalid;
|
||||
}
|
||||
if (empty($format)) {
|
||||
$format = '%x';
|
||||
}
|
||||
$format = $this->convertSpecifiers($format, $date);
|
||||
return $this->_strftime($format, $date);
|
||||
return $this->_CakeTime->i18nFormat($date, $format, $invalid, $userOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multibyte wrapper for strftime.
|
||||
*
|
||||
* Handles utf8_encoding the result of strftime when necessary.
|
||||
*
|
||||
* @param string $format Format string.
|
||||
* @param int $date Timestamp to format.
|
||||
* @return string formatted string with correct encoding.
|
||||
*/
|
||||
protected function _strftime($format, $date) {
|
||||
$format = strftime($format, $date);
|
||||
$encoding = Configure::read('App.encoding');
|
||||
|
||||
if (!empty($encoding) && $encoding === 'UTF-8') {
|
||||
if (function_exists('mb_check_encoding')) {
|
||||
$valid = mb_check_encoding($format, $encoding);
|
||||
} else {
|
||||
$valid = !Multibyte::checkMultibyte($format);
|
||||
}
|
||||
if (!$valid) {
|
||||
$format = utf8_encode($format);
|
||||
}
|
||||
}
|
||||
return $format;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,11 @@ App::uses('CakeRequest', 'Network');
|
|||
* - `id` The filename on the server's filesystem, including extension.
|
||||
* - `name` The filename that will be sent to the user, specified without the extension.
|
||||
* - `download` Set to true to set a `Content-Disposition` header. This is ideal for file downloads.
|
||||
* - `extension` The extension of the file being served. This is used to set the mimetype
|
||||
* - `extension` The extension of the file being served. This is used to set the mimetype.
|
||||
* If not provided its extracted from filename provided as `id`.
|
||||
* - `path` The absolute path, including the trailing / on the server's filesystem to `id`.
|
||||
* - `mimeType` The mime type of the file if CakeResponse doesn't know about it.
|
||||
* Must be an associative array with extension as key and mime type as value eg. array('ini' => 'text/plain')
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
|
@ -101,7 +103,11 @@ class MediaView extends View {
|
|||
$this->response->type($mimeType);
|
||||
}
|
||||
|
||||
if (isset($extension) && $this->_isActive()) {
|
||||
if (!isset($extension)) {
|
||||
$extension = pathinfo($id, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
if ($this->_isActive()) {
|
||||
$extension = strtolower($extension);
|
||||
$chunkSize = 8192;
|
||||
$buffer = '';
|
||||
|
@ -116,7 +122,7 @@ class MediaView extends View {
|
|||
} else {
|
||||
$modified = time();
|
||||
}
|
||||
if ($this->response->type($extension) === false) {
|
||||
if (!$extension || $this->response->type($extension) === false) {
|
||||
$download = true;
|
||||
}
|
||||
|
||||
|
@ -145,6 +151,8 @@ class MediaView extends View {
|
|||
}
|
||||
if (is_null($name)) {
|
||||
$name = $id;
|
||||
} elseif ($extension) {
|
||||
$name .= '.' . $extension;
|
||||
}
|
||||
$this->response->download($name);
|
||||
$this->response->header(array('Accept-Ranges' => 'bytes'));
|
||||
|
|
|
@ -23,6 +23,10 @@ define('TIME_START', microtime(true));
|
|||
if (!defined('E_DEPRECATED')) {
|
||||
define('E_DEPRECATED', 8192);
|
||||
}
|
||||
|
||||
if (!defined('E_USER_DEPRECATED')) {
|
||||
define('E_USER_DEPRECATED', E_USER_NOTICE);
|
||||
}
|
||||
error_reporting(E_ALL & ~E_DEPRECATED);
|
||||
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
|
|
Loading…
Reference in a new issue