Merge branch 'master' into 2.3

This commit is contained in:
mark_story 2012-08-30 19:43:11 +01:00
commit 728300786b
26 changed files with 574 additions and 123 deletions

28
README
View file

@ -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
View 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)

View file

@ -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.'));
}
$contents = parse_ini_file($filename, true);
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);
}
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 {

View file

@ -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)
);
}
}

View file

@ -361,8 +361,8 @@ class Shell extends Object {
array_shift($argv);
}
$this->OptionParser = $this->getOptionParser();
try {
$this->OptionParser = $this->getOptionParser();
list($this->params, $this->args) = $this->OptionParser->parse($argv, $command);
} catch (ConsoleException $e) {
$this->out($this->OptionParser->help($command));

View file

@ -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();
foreach (get_class_methods($this->_model) as $method) {
$methods[strtolower($method)] = array($this->_model, $method);
if (empty($this->_modelMethods)) {
foreach (get_class_methods($this->_model) as $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));
}

View file

@ -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
*

View file

@ -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
*

View file

@ -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',

View file

@ -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
*/

View file

@ -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
*

View file

@ -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)
)

View file

@ -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'),
);
/**

View file

@ -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']);

View file

@ -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
*

View file

@ -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
*

View 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

View file

@ -0,0 +1 @@
; do nothing this is an empty file.

View file

@ -0,0 +1,3 @@
; Test file for testing config file without .ini extension.
some_key = some_value
bool_key = 1

View 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

View file

@ -0,0 +1,4 @@
; Test file for testing ini files with . syntax
[database]
db.username = bar
db.password = foo

View file

@ -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 . "&amp;show_passes=1'>Show Passes</a> | \n";
echo "<a href='" . $this->baseUrl() . $query . "&amp;debug=1'>Enable Debug Output</a> | \n";
echo "<a href='" . $this->baseUrl() . $query . "&amp;code_coverage=true'>Analyze Code Coverage</a></p>\n";
}

View file

@ -923,13 +923,16 @@ 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:
* {{{
* 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
* CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed
* CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone
* }}}
* ## 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
* CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed
* CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone
* }}}
*
* @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string)
* @param integer|string|DateTime $format date format string (or UNIX timestamp, strtotime() valid string or DateTime object)
@ -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

View file

@ -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_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 . '}$/';
$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);
}
$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 {

View file

@ -817,7 +817,7 @@ class FormHelper extends AppHelper {
* - `fieldset` Set to false to disable the fieldset. If a string is supplied it will be used as
* the classname for the fieldset element.
* - `legend` Set to false to disable the legend for the generated input set. Or supply a string
* to customize the legend text.
* to customize the legend text.
*
* @param array $fields An array of fields to generate inputs for, or null.
* @param array $blacklist a simple array of fields to not create inputs for.
@ -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' => '')));

View file

@ -893,7 +893,7 @@ class View extends Object {
include $this->__viewFile;
unset($this->_viewFile);
unset($this->__viewFile);
return ob_get_clean();
}