mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge branch 'master' into 2.3
This commit is contained in:
commit
728300786b
26 changed files with 574 additions and 123 deletions
28
README
28
README
|
@ -1,28 +0,0 @@
|
|||
CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC. Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.
|
||||
|
||||
The Cake Software Foundation - promoting development related to CakePHP
|
||||
http://cakefoundation.org/
|
||||
|
||||
CakePHP - the rapid development PHP framework
|
||||
http://www.cakephp.org
|
||||
|
||||
Cookbook - user documentation for learning about CakePHP
|
||||
http://book.cakephp.org
|
||||
|
||||
API - quick reference to CakePHP
|
||||
http://api.cakephp.org
|
||||
|
||||
The Bakery - everything CakePHP
|
||||
http://bakery.cakephp.org
|
||||
|
||||
The Show - live and archived podcasts about CakePHP and more
|
||||
http://live.cakephp.org
|
||||
|
||||
CakePHP TV - screen casts from events and video tutorials
|
||||
http://tv.cakephp.org
|
||||
|
||||
CakePHP Google Group - community mailing list and forum
|
||||
http://groups.google.com/group/cake-php
|
||||
|
||||
#cakephp on irc.freenode.net - chat with CakePHP developers
|
||||
irc://irc.freenode.net/cakephp
|
39
README.md
Normal file
39
README.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
CakePHP
|
||||
=======
|
||||
|
||||
[![CakePHP](http://cakephp.org/img/cake-logo.png)](http://www.cakephp.org)
|
||||
|
||||
CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.
|
||||
Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.
|
||||
|
||||
Some Handy Links
|
||||
----------------
|
||||
|
||||
[CakePHP](http://www.cakephp.org) - The rapid development PHP framework
|
||||
|
||||
[Cookbook](http://book.cakephp.org) - THE Cake user documentation; start learning here!
|
||||
|
||||
[Plugins](http://plugins.cakephp.org/) - A repository of extensions to the framework
|
||||
|
||||
[The Bakery](http://bakery.cakephp.org) - Tips, tutorials and articles
|
||||
|
||||
[API](http://api.cakephp.org) - A reference to Cake's classes
|
||||
|
||||
[CakePHP TV](http://tv.cakephp.org) - Screen casts from events and video tutorials
|
||||
|
||||
[The Cake Software Foundation](http://cakefoundation.org/) - promoting development related to CakePHP
|
||||
|
||||
Get Support!
|
||||
------------
|
||||
|
||||
[Our Google Group](http://groups.google.com/group/cake-php) - community mailing list and forum
|
||||
|
||||
[#cakephp](http://webchat.freenode.net/?channels=#cakephp) on irc.freenode.net - Come chat with us, we have cake.
|
||||
|
||||
[Q & A](http://ask.cakephp.org/) - Ask questions here, all questions welcome
|
||||
|
||||
[Lighthouse](http://cakephp.lighthouseapp.com/) - Got issues? Please tell us!
|
||||
|
||||
[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp)
|
||||
|
||||
![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif)
|
|
@ -84,20 +84,41 @@ class IniReader implements ConfigReaderInterface {
|
|||
/**
|
||||
* Read an ini file and return the results as an array.
|
||||
*
|
||||
* @param string $file Name of the file to read. The chosen file
|
||||
* must be on the reader's path.
|
||||
* @return array
|
||||
* For backwards compatibility, acl.ini.php will be treated specially until 3.0.
|
||||
*
|
||||
* @param string $key The identifier to read from. If the key has a . it will be treated
|
||||
* as a plugin prefix. The chosen file must be on the reader's path.
|
||||
* @return array Parsed configuration values.
|
||||
* @throws ConfigureException when files don't exist.
|
||||
* Or when files contain '..' as this could lead to abusive reads.
|
||||
* @throws ConfigureException
|
||||
*/
|
||||
public function read($file) {
|
||||
$filename = $this->_path . $file;
|
||||
if (!file_exists($filename)) {
|
||||
$filename .= '.ini';
|
||||
if (!file_exists($filename)) {
|
||||
throw new ConfigureException(__d('cake_dev', 'Could not load configuration files: %s or %s', substr($filename, 0, -4), $filename));
|
||||
public function read($key) {
|
||||
if (strpos($key, '..') !== false) {
|
||||
throw new ConfigureException(__d('cake_dev', 'Cannot load configuration files with ../ in them.'));
|
||||
}
|
||||
if (substr($key, -8) === '.ini.php') {
|
||||
$key = substr($key, 0, -8);
|
||||
list($plugin, $key) = pluginSplit($key);
|
||||
$key .= '.ini.php';
|
||||
} else {
|
||||
if (substr($key, -4) === '.ini') {
|
||||
$key = substr($key, 0, -4);
|
||||
}
|
||||
$contents = parse_ini_file($filename, true);
|
||||
list($plugin, $key) = pluginSplit($key);
|
||||
$key .= '.ini';
|
||||
}
|
||||
|
||||
if ($plugin) {
|
||||
$file = App::pluginPath($plugin) . 'Config' . DS . $key;
|
||||
} else {
|
||||
$file = $this->_path . $key;
|
||||
}
|
||||
if (!is_file($file)) {
|
||||
throw new ConfigureException(__d('cake_dev', 'Could not load configuration file: %s', $file));
|
||||
}
|
||||
|
||||
$contents = parse_ini_file($file, true);
|
||||
if (!empty($this->_section) && isset($contents[$this->_section])) {
|
||||
$values = $this->_parseNestedValues($contents[$this->_section]);
|
||||
} else {
|
||||
|
|
|
@ -93,7 +93,7 @@ class ConsoleInputOption {
|
|||
}
|
||||
if (strlen($this->_short) > 1) {
|
||||
throw new ConsoleException(
|
||||
__d('cake_console', 'Short options must be one letter.')
|
||||
__d('cake_console', 'Short option "%s" is invalid, short options must be one letter.', $this->_short)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -361,8 +361,8 @@ class Shell extends Object {
|
|||
array_shift($argv);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->OptionParser = $this->getOptionParser();
|
||||
try {
|
||||
list($this->params, $this->args) = $this->OptionParser->parse($argv, $command);
|
||||
} catch (ConsoleException $e) {
|
||||
$this->out($this->OptionParser->help($command));
|
||||
|
|
|
@ -63,6 +63,20 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
|
|||
*/
|
||||
protected $_methods = array();
|
||||
|
||||
/**
|
||||
* Holds the available custom callback methods from the model
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_modelMethods = array();
|
||||
|
||||
/**
|
||||
* Holds the list of behavior names that were attached when this object was created
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_behaviors = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -280,15 +294,19 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
|
|||
* @return array List of callables to be used as validation methods
|
||||
*/
|
||||
public function getMethods() {
|
||||
if (!empty($this->_methods)) {
|
||||
$behaviors = $this->_model->Behaviors->enabled();
|
||||
if (!empty($this->_methods) && $behaviors === $this->_behaviors) {
|
||||
return $this->_methods;
|
||||
}
|
||||
$this->_behaviors = $behaviors;
|
||||
|
||||
$methods = array();
|
||||
if (empty($this->_modelMethods)) {
|
||||
foreach (get_class_methods($this->_model) as $method) {
|
||||
$methods[strtolower($method)] = array($this->_model, $method);
|
||||
$this->_modelMethods[strtolower($method)] = array($this->_model, $method);
|
||||
}
|
||||
}
|
||||
|
||||
$methods = $this->_modelMethods;
|
||||
foreach (array_keys($this->_model->Behaviors->methods()) as $method) {
|
||||
$methods += array(strtolower($method) => array($this->_model, $method));
|
||||
}
|
||||
|
|
|
@ -282,6 +282,17 @@ class CakeValidationRule {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets interal state for this rule, by default it will become valid
|
||||
* and it will set isUpdate() to false
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
public function reset() {
|
||||
$this->_valid = true;
|
||||
$this->_recordExists = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns passed options for this rule
|
||||
*
|
||||
|
|
|
@ -117,6 +117,7 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable {
|
|||
* @return array list of validation errors for this field
|
||||
*/
|
||||
public function validate($data, $isUpdate = false) {
|
||||
$this->reset();
|
||||
$errors = array();
|
||||
foreach ($this->getRules() as $name => $rule) {
|
||||
$rule->isUpdate($isUpdate);
|
||||
|
@ -143,6 +144,17 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable {
|
|||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets interal state for all validation rules in this set
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
public function reset() {
|
||||
foreach ($this->getRules() as $rule) {
|
||||
$rule->reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a rule for a given name if exists
|
||||
*
|
||||
|
|
|
@ -100,6 +100,7 @@ class CakeResponse {
|
|||
'dir' => 'application/x-director',
|
||||
'dms' => 'application/octet-stream',
|
||||
'doc' => 'application/msword',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'drw' => 'application/drafting',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'dwg' => 'application/acad',
|
||||
|
@ -136,6 +137,7 @@ class CakeResponse {
|
|||
'pot' => 'application/vnd.ms-powerpoint',
|
||||
'pps' => 'application/vnd.ms-powerpoint',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'ppz' => 'application/vnd.ms-powerpoint',
|
||||
'pre' => 'application/x-freelance',
|
||||
'prt' => 'application/pro_eng',
|
||||
|
@ -181,6 +183,7 @@ class CakeResponse {
|
|||
'xll' => 'application/vnd.ms-excel',
|
||||
'xlm' => 'application/vnd.ms-excel',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xlw' => 'application/vnd.ms-excel',
|
||||
'zip' => 'application/zip',
|
||||
'aif' => 'audio/x-aiff',
|
||||
|
|
|
@ -56,6 +56,47 @@ class IniReaderTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testConstruct() {
|
||||
$reader = new IniReader($this->path);
|
||||
$config = $reader->read('acl.ini');
|
||||
|
||||
$this->assertTrue(isset($config['admin']));
|
||||
$this->assertTrue(isset($config['paul']['groups']));
|
||||
$this->assertEquals('ads', $config['admin']['deny']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading files.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRead() {
|
||||
$reader = new IniReader($this->path);
|
||||
$config = $reader->read('nested');
|
||||
$this->assertTrue($config['bools']['test_on']);
|
||||
|
||||
$config = $reader->read('nested.ini');
|
||||
$this->assertTrue($config['bools']['test_on']);
|
||||
}
|
||||
|
||||
/**
|
||||
* No other sections should exist.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadOnlyOneSection() {
|
||||
$reader = new IniReader($this->path, 'admin');
|
||||
$config = $reader->read('acl.ini');
|
||||
|
||||
$this->assertTrue(isset($config['groups']));
|
||||
$this->assertEquals('administrators', $config['groups']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading acl.ini.php.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadSpecialAclIniPhp() {
|
||||
$reader = new IniReader($this->path);
|
||||
$config = $reader->read('acl.ini.php');
|
||||
|
||||
|
@ -65,24 +106,11 @@ class IniReaderTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* no other sections should exist.
|
||||
* Test without section.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadingOnlyOneSection() {
|
||||
$reader = new IniReader($this->path, 'admin');
|
||||
$config = $reader->read('acl.ini.php');
|
||||
|
||||
$this->assertTrue(isset($config['groups']));
|
||||
$this->assertEquals('administrators', $config['groups']);
|
||||
}
|
||||
|
||||
/**
|
||||
* test without section
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadingWithoutSection() {
|
||||
public function testReadWithoutSection() {
|
||||
$reader = new IniReader($this->path);
|
||||
$config = $reader->read('no_section.ini');
|
||||
|
||||
|
@ -94,11 +122,11 @@ class IniReaderTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* test that names with .'s get exploded into arrays.
|
||||
* Test that names with .'s get exploded into arrays.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadingValuesWithDots() {
|
||||
public function testReadValuesWithDots() {
|
||||
$reader = new IniReader($this->path);
|
||||
$config = $reader->read('nested.ini');
|
||||
|
||||
|
@ -110,7 +138,7 @@ class IniReaderTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* test boolean reading
|
||||
* Test boolean reading.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
@ -131,18 +159,93 @@ class IniReaderTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* test read file without extension
|
||||
* Test an exception is thrown by reading files that exist without .ini extension.
|
||||
*
|
||||
* @expectedException ConfigureException
|
||||
* @return void
|
||||
*/
|
||||
public function testReadingWithoutExtension() {
|
||||
public function testReadWithExistentFileWithoutExtension() {
|
||||
$reader = new IniReader($this->path);
|
||||
$config = $reader->read('nested');
|
||||
$this->assertTrue($config['bools']['test_on']);
|
||||
$reader->read('no_ini_extension');
|
||||
}
|
||||
|
||||
/**
|
||||
* test dump method.
|
||||
* Test an exception is thrown by reading files that don't exist.
|
||||
*
|
||||
* @expectedException ConfigureException
|
||||
* @return void
|
||||
*/
|
||||
public function testReadWithNonExistentFile() {
|
||||
$reader = new IniReader($this->path);
|
||||
$reader->read('fake_values');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading an empty file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadEmptyFile() {
|
||||
$reader = new IniReader($this->path);
|
||||
$config = $reader->read('empty');
|
||||
$this->assertEquals(array(), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading keys with ../ doesn't work.
|
||||
*
|
||||
* @expectedException ConfigureException
|
||||
* @return void
|
||||
*/
|
||||
public function testReadWithDots() {
|
||||
$reader = new IniReader($this->path);
|
||||
$reader->read('../empty');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading from plugins.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadPluginValue() {
|
||||
App::build(array(
|
||||
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
|
||||
), App::RESET);
|
||||
CakePlugin::load('TestPlugin');
|
||||
$reader = new IniReader($this->path);
|
||||
$result = $reader->read('TestPlugin.nested');
|
||||
|
||||
$this->assertTrue(isset($result['database']['db']['username']));
|
||||
$this->assertEquals('bar', $result['database']['db']['username']);
|
||||
$this->assertFalse(isset($result['database.db.username']));
|
||||
$this->assertFalse(isset($result['database']['db.username']));
|
||||
|
||||
$result = $reader->read('TestPlugin.nested.ini');
|
||||
$this->assertEquals('foo', $result['database']['db']['password']);
|
||||
CakePlugin::unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading acl.ini.php from plugins.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadPluginSpecialAclIniPhpValue() {
|
||||
App::build(array(
|
||||
'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
|
||||
), App::RESET);
|
||||
CakePlugin::load('TestPlugin');
|
||||
$reader = new IniReader($this->path);
|
||||
$result = $reader->read('TestPlugin.acl.ini.php');
|
||||
|
||||
$this->assertTrue(isset($result['admin']));
|
||||
$this->assertTrue(isset($result['paul']['groups']));
|
||||
$this->assertEquals('ads', $result['admin']['deny']);
|
||||
CakePlugin::unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test dump method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
|
@ -1681,6 +1681,35 @@ class ModelValidationTest extends BaseModelTest {
|
|||
$this->assertEquals($expected, array_keys($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that methods are refreshed when the list of behaviors change
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMethodsRefresh() {
|
||||
$this->loadFixtures('Article', 'Comment');
|
||||
$TestModel = new Article();
|
||||
$Validator = $TestModel->validator();
|
||||
|
||||
$result = $Validator->getMethods();
|
||||
|
||||
$expected = array_map('strtolower', get_class_methods('Article'));
|
||||
$this->assertEquals($expected, array_keys($result));
|
||||
|
||||
$TestModel->Behaviors->attach('Containable');
|
||||
$newList = array(
|
||||
'contain',
|
||||
'resetbindings',
|
||||
'containments',
|
||||
'fielddependencies',
|
||||
'containmentsmap'
|
||||
);
|
||||
$this->assertEquals(array_merge($expected, $newList), array_keys($Validator->getMethods()));
|
||||
|
||||
$TestModel->Behaviors->detach('Containable');
|
||||
$this->assertEquals($expected, array_keys($Validator->getMethods()));
|
||||
}
|
||||
|
||||
/**
|
||||
* testSetValidationDomain method
|
||||
*
|
||||
|
|
|
@ -3242,7 +3242,6 @@ class ModelWriteTest extends BaseModelTest {
|
|||
)
|
||||
),
|
||||
1 => array(
|
||||
'body' => array('This field cannot be left blank'),
|
||||
'Comment' => array(
|
||||
0 => array(
|
||||
'User' => array(
|
||||
|
@ -3687,9 +3686,6 @@ class ModelWriteTest extends BaseModelTest {
|
|||
$expected = array(
|
||||
0 => array(
|
||||
'body' => array('This field cannot be left blank')
|
||||
),
|
||||
1 => array(
|
||||
'body' => array('This field cannot be left blank')
|
||||
)
|
||||
);
|
||||
$result = $TestModel->validationErrors;
|
||||
|
@ -3703,7 +3699,7 @@ class ModelWriteTest extends BaseModelTest {
|
|||
)
|
||||
),
|
||||
array(
|
||||
'Article' => array('id' => 2, 'body' => 'Same here'),
|
||||
'Article' => array('id' => 2),
|
||||
'Comment' => array(
|
||||
array('comment' => '', 'published' => 'Y', 'user_id' => 2)
|
||||
)
|
||||
|
|
|
@ -276,7 +276,7 @@ class Article extends CakeTestModel {
|
|||
public $validate = array(
|
||||
'user_id' => 'numeric',
|
||||
'title' => array('required' => false, 'rule' => 'notEmpty'),
|
||||
'body' => 'notEmpty',
|
||||
'body' => array('required' => false, 'rule' => 'notEmpty'),
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1162,8 +1162,12 @@ class CakeEmailTest extends CakeTestCase {
|
|||
$this->CakeEmail->config(array('empty'));
|
||||
$this->CakeEmail->template('image');
|
||||
$this->CakeEmail->emailFormat('html');
|
||||
|
||||
$server = env('SERVER_NAME') ? env('SERVER_NAME') : 'localhost';
|
||||
|
||||
if (env('SERVER_PORT') != null && env('SERVER_PORT') != 80) {
|
||||
$server .= ':' . env('SERVER_PORT');
|
||||
}
|
||||
|
||||
$expected = '<img src="http://' . $server . '/img/image.gif" alt="cool image" width="100" height="100" />';
|
||||
$result = $this->CakeEmail->send();
|
||||
$this->assertContains($expected, $result['message']);
|
||||
|
|
|
@ -1487,39 +1487,77 @@ class ValidationTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* testDecimal method
|
||||
* Test numbers with any number of decimal places, including none.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDecimal() {
|
||||
$this->assertTrue(Validation::decimal('+1234.54321'));
|
||||
$this->assertTrue(Validation::decimal('-1234.54321'));
|
||||
$this->assertTrue(Validation::decimal('1234.54321'));
|
||||
$this->assertTrue(Validation::decimal('+0123.45e6'));
|
||||
$this->assertTrue(Validation::decimal('-0123.45e6'));
|
||||
$this->assertTrue(Validation::decimal('0123.45e6'));
|
||||
$this->assertTrue(Validation::decimal(1234.56));
|
||||
$this->assertTrue(Validation::decimal(1234.00));
|
||||
$this->assertTrue(Validation::decimal('1234.00'));
|
||||
$this->assertTrue(Validation::decimal(.0));
|
||||
$this->assertTrue(Validation::decimal(.00));
|
||||
$this->assertTrue(Validation::decimal('.00'));
|
||||
$this->assertTrue(Validation::decimal(.01));
|
||||
$this->assertTrue(Validation::decimal('.01'));
|
||||
public function testDecimalWithPlacesNull() {
|
||||
$this->assertTrue(Validation::decimal('+1234.54321', null));
|
||||
$this->assertTrue(Validation::decimal('-1234.54321', null));
|
||||
$this->assertTrue(Validation::decimal('1234.54321', null));
|
||||
$this->assertTrue(Validation::decimal('+0123.45e6', null));
|
||||
$this->assertTrue(Validation::decimal('-0123.45e6', null));
|
||||
$this->assertTrue(Validation::decimal('0123.45e6', null));
|
||||
$this->assertTrue(Validation::decimal(1234.56, null));
|
||||
$this->assertTrue(Validation::decimal(1234.00, null));
|
||||
$this->assertTrue(Validation::decimal(1234., null));
|
||||
$this->assertTrue(Validation::decimal('1234.00', null));
|
||||
$this->assertTrue(Validation::decimal(.0, null));
|
||||
$this->assertTrue(Validation::decimal(.00, null));
|
||||
$this->assertTrue(Validation::decimal('.00', null));
|
||||
$this->assertTrue(Validation::decimal(.01, null));
|
||||
$this->assertTrue(Validation::decimal('.01', null));
|
||||
$this->assertTrue(Validation::decimal('1234', null));
|
||||
$this->assertTrue(Validation::decimal('-1234', null));
|
||||
$this->assertTrue(Validation::decimal('+1234', null));
|
||||
$this->assertTrue(Validation::decimal((float) 1234, null));
|
||||
$this->assertTrue(Validation::decimal((double) 1234, null));
|
||||
$this->assertTrue(Validation::decimal((int) 1234, null));
|
||||
|
||||
$this->assertFalse(Validation::decimal(''));
|
||||
$this->assertFalse(Validation::decimal('string'));
|
||||
$this->assertFalse(Validation::decimal('1234'));
|
||||
$this->assertFalse(Validation::decimal('-1234'));
|
||||
$this->assertFalse(Validation::decimal('+1234'));
|
||||
$this->assertFalse(Validation::decimal('', null));
|
||||
$this->assertFalse(Validation::decimal('string', null));
|
||||
$this->assertFalse(Validation::decimal('1234.', null));
|
||||
}
|
||||
|
||||
/**
|
||||
* testDecimalWithPlaces method
|
||||
* Test numbers with any number of decimal places greater than 0, or a float|double.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDecimalWithPlaces() {
|
||||
public function testDecimalWithPlacesTrue() {
|
||||
$this->assertTrue(Validation::decimal('+1234.54321', true));
|
||||
$this->assertTrue(Validation::decimal('-1234.54321', true));
|
||||
$this->assertTrue(Validation::decimal('1234.54321', true));
|
||||
$this->assertTrue(Validation::decimal('+0123.45e6', true));
|
||||
$this->assertTrue(Validation::decimal('-0123.45e6', true));
|
||||
$this->assertTrue(Validation::decimal('0123.45e6', true));
|
||||
$this->assertTrue(Validation::decimal(1234.56, true));
|
||||
$this->assertTrue(Validation::decimal(1234.00, true));
|
||||
$this->assertTrue(Validation::decimal(1234., true));
|
||||
$this->assertTrue(Validation::decimal('1234.00', true));
|
||||
$this->assertTrue(Validation::decimal(.0, true));
|
||||
$this->assertTrue(Validation::decimal(.00, true));
|
||||
$this->assertTrue(Validation::decimal('.00', true));
|
||||
$this->assertTrue(Validation::decimal(.01, true));
|
||||
$this->assertTrue(Validation::decimal('.01', true));
|
||||
$this->assertTrue(Validation::decimal((float) 1234, true));
|
||||
$this->assertTrue(Validation::decimal((double) 1234, true));
|
||||
|
||||
$this->assertFalse(Validation::decimal('', true));
|
||||
$this->assertFalse(Validation::decimal('string', true));
|
||||
$this->assertFalse(Validation::decimal('1234.', true));
|
||||
$this->assertFalse(Validation::decimal((int) 1234, true));
|
||||
$this->assertFalse(Validation::decimal('1234', true));
|
||||
$this->assertFalse(Validation::decimal('-1234', true));
|
||||
$this->assertFalse(Validation::decimal('+1234', true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test numbers with exactly that many number of decimal places.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDecimalWithPlacesNumeric() {
|
||||
$this->assertTrue(Validation::decimal('.27', '2'));
|
||||
$this->assertTrue(Validation::decimal(0.27, 2));
|
||||
$this->assertTrue(Validation::decimal(-0.27, 2));
|
||||
|
@ -1532,12 +1570,36 @@ class ValidationTest extends CakeTestCase {
|
|||
$this->assertTrue(Validation::decimal(1234.5678, 4));
|
||||
$this->assertTrue(Validation::decimal(-1234.5678, 4));
|
||||
$this->assertTrue(Validation::decimal(1234.5678, 4));
|
||||
$this->assertTrue(Validation::decimal('.00', 2));
|
||||
$this->assertTrue(Validation::decimal(.01, 2));
|
||||
$this->assertTrue(Validation::decimal('.01', 2));
|
||||
|
||||
$this->assertFalse(Validation::decimal('', 1));
|
||||
$this->assertFalse(Validation::decimal('string', 1));
|
||||
$this->assertFalse(Validation::decimal(1234., 1));
|
||||
$this->assertFalse(Validation::decimal('1234.', 1));
|
||||
$this->assertFalse(Validation::decimal(.0, 1));
|
||||
$this->assertFalse(Validation::decimal(.00, 2));
|
||||
$this->assertFalse(Validation::decimal((float) 1234, 1));
|
||||
$this->assertFalse(Validation::decimal((double) 1234, 1));
|
||||
$this->assertFalse(Validation::decimal((int) 1234, 1));
|
||||
$this->assertFalse(Validation::decimal('1234.5678', '3'));
|
||||
$this->assertFalse(Validation::decimal(1234.5678, 3));
|
||||
$this->assertFalse(Validation::decimal(-1234.5678, 3));
|
||||
$this->assertFalse(Validation::decimal(1234.5678, 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test decimal() with invalid places parameter.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDecimalWithInvalidPlaces() {
|
||||
$this->assertFalse(Validation::decimal('.27', 'string'));
|
||||
$this->assertFalse(Validation::decimal(1234.5678, (array) true));
|
||||
$this->assertFalse(Validation::decimal(-1234.5678, (object) true));
|
||||
}
|
||||
|
||||
/**
|
||||
* testDecimalCustomRegex method
|
||||
*
|
||||
|
|
|
@ -4328,6 +4328,30 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->assertRegExp('/"' . $key . '"/', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a select box has no options it should not be added to the fields list
|
||||
* as it always fail post validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSelectNoSecureWithNoOptions() {
|
||||
$this->Form->request['_Token'] = array('key' => 'testkey');
|
||||
$this->assertEquals(array(), $this->Form->fields);
|
||||
|
||||
$this->Form->select(
|
||||
'Model.select',
|
||||
array()
|
||||
);
|
||||
$this->assertEquals(array(), $this->Form->fields);
|
||||
|
||||
$this->Form->select(
|
||||
'Model.select',
|
||||
array(),
|
||||
array('empty' => true)
|
||||
);
|
||||
$this->assertEquals(array('Model.select'), $this->Form->fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* testInputMultipleCheckboxes method
|
||||
*
|
||||
|
|
60
lib/Cake/Test/test_app/Config/acl.ini
Normal file
60
lib/Cake/Test/test_app/Config/acl.ini
Normal file
|
@ -0,0 +1,60 @@
|
|||
;<?php exit() ?>
|
||||
; SVN FILE: $Id$
|
||||
;/**
|
||||
; * Test App Ini Based Acl Config File
|
||||
; *
|
||||
; *
|
||||
; * PHP 5
|
||||
; *
|
||||
; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
; *
|
||||
; * Licensed under The MIT License
|
||||
; * Redistributions of files must retain the above copyright notice.
|
||||
; *
|
||||
; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
; * @link http://cakephp.org CakePHP(tm) Project
|
||||
;; * @package Cake.Test.test_app.Config
|
||||
; * @since CakePHP(tm) v 0.10.0.1076
|
||||
; * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
; */
|
||||
|
||||
;-------------------------------------
|
||||
;Users
|
||||
;-------------------------------------
|
||||
|
||||
[admin]
|
||||
groups = administrators
|
||||
allow =
|
||||
deny = ads
|
||||
|
||||
[paul]
|
||||
groups = users
|
||||
allow =
|
||||
deny =
|
||||
|
||||
[jenny]
|
||||
groups = users
|
||||
allow = ads
|
||||
deny = images, files
|
||||
|
||||
[nobody]
|
||||
groups = anonymous
|
||||
allow =
|
||||
deny =
|
||||
|
||||
;-------------------------------------
|
||||
;Groups
|
||||
;-------------------------------------
|
||||
|
||||
[administrators]
|
||||
deny =
|
||||
allow = posts, comments, images, files, stats, ads
|
||||
|
||||
[users]
|
||||
allow = posts, comments, images, files
|
||||
deny = stats, ads
|
||||
|
||||
[anonymous]
|
||||
allow =
|
||||
deny = posts, comments, images, files, stats, ads
|
1
lib/Cake/Test/test_app/Config/empty.ini
Normal file
1
lib/Cake/Test/test_app/Config/empty.ini
Normal file
|
@ -0,0 +1 @@
|
|||
; do nothing this is an empty file.
|
3
lib/Cake/Test/test_app/Config/no_ini_extension
Normal file
3
lib/Cake/Test/test_app/Config/no_ini_extension
Normal file
|
@ -0,0 +1,3 @@
|
|||
; Test file for testing config file without .ini extension.
|
||||
some_key = some_value
|
||||
bool_key = 1
|
60
lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php
Normal file
60
lib/Cake/Test/test_app/Plugin/TestPlugin/Config/acl.ini.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
;<?php exit() ?>
|
||||
; SVN FILE: $Id$
|
||||
;/**
|
||||
; * Test App Ini Based Acl Config File
|
||||
; *
|
||||
; *
|
||||
; * PHP 5
|
||||
; *
|
||||
; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
; *
|
||||
; * Licensed under The MIT License
|
||||
; * Redistributions of files must retain the above copyright notice.
|
||||
; *
|
||||
; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
; * @link http://cakephp.org CakePHP(tm) Project
|
||||
;; * @package Cake.Test.test_app.Config
|
||||
; * @since CakePHP(tm) v 0.10.0.1076
|
||||
; * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
; */
|
||||
|
||||
;-------------------------------------
|
||||
;Users
|
||||
;-------------------------------------
|
||||
|
||||
[admin]
|
||||
groups = administrators
|
||||
allow =
|
||||
deny = ads
|
||||
|
||||
[paul]
|
||||
groups = users
|
||||
allow =
|
||||
deny =
|
||||
|
||||
[jenny]
|
||||
groups = users
|
||||
allow = ads
|
||||
deny = images, files
|
||||
|
||||
[nobody]
|
||||
groups = anonymous
|
||||
allow =
|
||||
deny =
|
||||
|
||||
;-------------------------------------
|
||||
;Groups
|
||||
;-------------------------------------
|
||||
|
||||
[administrators]
|
||||
deny =
|
||||
allow = posts, comments, images, files, stats, ads
|
||||
|
||||
[users]
|
||||
allow = posts, comments, images, files
|
||||
deny = stats, ads
|
||||
|
||||
[anonymous]
|
||||
allow =
|
||||
deny = posts, comments, images, files, stats, ads
|
|
@ -0,0 +1,4 @@
|
|||
; Test file for testing ini files with . syntax
|
||||
[database]
|
||||
db.username = bar
|
||||
db.password = foo
|
|
@ -201,8 +201,8 @@ class CakeHtmlReporter extends CakeBaseReporter {
|
|||
$show = $this->_queryString($show);
|
||||
$query = $this->_queryString($query);
|
||||
|
||||
echo "<p><a href='" . $this->baseUrl() . $show . "'>Run more tests</a> | <a href='" . $this->baseUrl() . $query . "&show_passes=1'>Show Passes</a> | \n";
|
||||
echo "<a href='" . $this->baseUrl() . $query . "&debug=1'>Enable Debug Output</a> | \n";
|
||||
echo "<p><a href='" . $this->baseUrl() . $show . "'>Run more tests</a> | <a href='" . $this->baseUrl() . $query . "&show_passes=1'>Show Passes</a> | \n";
|
||||
echo "<a href='" . $this->baseUrl() . $query . "&debug=1'>Enable Debug Output</a> | \n";
|
||||
echo "<a href='" . $this->baseUrl() . $query . "&code_coverage=true'>Analyze Code Coverage</a></p>\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -923,7 +923,10 @@ class CakeTime {
|
|||
* This function also accepts a time string and a format string as first and second parameters.
|
||||
* In that case this function behaves as a wrapper for TimeHelper::i18nFormat()
|
||||
*
|
||||
* ## Examples:
|
||||
* ## Examples
|
||||
*
|
||||
* Create localized & formatted time:
|
||||
*
|
||||
* {{{
|
||||
* CakeTime::format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012
|
||||
* CakeTime::format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale
|
||||
|
@ -937,6 +940,7 @@ class CakeTime {
|
|||
* @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
|
||||
* @return string Formatted date string
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
|
||||
* @see CakeTime::i18nFormat()
|
||||
*/
|
||||
public static function format($date, $format = null, $default = false, $timezone = null) {
|
||||
//Backwards compatible params order
|
||||
|
|
|
@ -372,23 +372,39 @@ class Validation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks that a value is a valid decimal. If $places is null, the $check is allowed to be a scientific float
|
||||
* If no decimal point is found a false will be returned. Both the sign and exponent are optional.
|
||||
* Checks that a value is a valid decimal. Both the sign and exponent are optional.
|
||||
*
|
||||
* Valid Places:
|
||||
*
|
||||
* - null => Any number of decimal places, including none. The '.' is not required.
|
||||
* - true => Any number of decimal places greater than 0, or a float|double. The '.' is required.
|
||||
* - 1..N => Exactly that many number of decimal places. The '.' is required.
|
||||
*
|
||||
* @param integer $check The value the test for decimal
|
||||
* @param integer $places if set $check value must have exactly $places after the decimal point
|
||||
* @param string $regex If a custom regular expression is used this is the only validation that will occur.
|
||||
* @param integer $places
|
||||
* @param string $regex If a custom regular expression is used, this is the only validation that will occur.
|
||||
* @return boolean Success
|
||||
*/
|
||||
public static function decimal($check, $places = null, $regex = null) {
|
||||
if (is_null($regex)) {
|
||||
$lnum = '[0-9]+';
|
||||
$dnum = "[0-9]*[\.]{$lnum}";
|
||||
$sign = '[+-]?';
|
||||
$exp = "(?:[eE]{$sign}{$lnum})?";
|
||||
|
||||
if ($places === null) {
|
||||
$regex = "/^{$sign}(?:{$lnum}|{$dnum}){$exp}$/";
|
||||
|
||||
} elseif ($places === true) {
|
||||
if (is_float($check) && floor($check) === $check) {
|
||||
$check = sprintf("%.1f", $check);
|
||||
}
|
||||
if (is_null($regex)) {
|
||||
if (is_null($places)) {
|
||||
$regex = '/^[-+]?[0-9]*\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/';
|
||||
} else {
|
||||
$regex = '/^[-+]?[0-9]*\\.{1}[0-9]{' . $places . '}$/';
|
||||
$regex = "/^{$sign}{$dnum}{$exp}$/";
|
||||
|
||||
} elseif (is_numeric($places)) {
|
||||
$places = '[0-9]{' . $places . '}';
|
||||
$dnum = "(?:[0-9]*[\.]{$places}|{$lnum}[\.]{$places})";
|
||||
$regex = "/^{$sign}{$dnum}{$exp}$/";
|
||||
}
|
||||
}
|
||||
return self::_check($check, $regex);
|
||||
|
@ -796,7 +812,7 @@ class Validation {
|
|||
* @return boolean Success of match
|
||||
*/
|
||||
protected static function _check($check, $regex) {
|
||||
if (preg_match($regex, $check)) {
|
||||
if (is_string($regex) && preg_match($regex, $check)) {
|
||||
self::$errors[] = false;
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -1005,7 +1005,11 @@ class FormHelper extends AppHelper {
|
|||
}
|
||||
}
|
||||
|
||||
$autoLength = (!array_key_exists('maxlength', $options) && isset($fieldDef['length']));
|
||||
$autoLength = (
|
||||
!array_key_exists('maxlength', $options) &&
|
||||
isset($fieldDef['length']) &&
|
||||
is_scalar($fieldDef['length'])
|
||||
);
|
||||
if ($autoLength && $options['type'] == 'text') {
|
||||
$options['maxlength'] = $fieldDef['length'];
|
||||
}
|
||||
|
@ -1847,7 +1851,12 @@ class FormHelper extends AppHelper {
|
|||
}
|
||||
|
||||
if (!empty($tag) || isset($template)) {
|
||||
if ((!isset($secure) || $secure == true) && empty($attributes['disabled'])) {
|
||||
$hasOptions = (count($options) > 0 || $showEmpty);
|
||||
if (
|
||||
(!isset($secure) || $secure == true) &&
|
||||
empty($attributes['disabled']) &&
|
||||
$hasOptions
|
||||
) {
|
||||
$this->_secure(true);
|
||||
}
|
||||
$select[] = $this->Html->useTag($tag, $attributes['name'], array_diff_key($attributes, array('name' => '', 'value' => '')));
|
||||
|
|
|
@ -893,7 +893,7 @@ class View extends Object {
|
|||
|
||||
include $this->__viewFile;
|
||||
|
||||
unset($this->_viewFile);
|
||||
unset($this->__viewFile);
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue