Merge branch '2.0' of github.com:cakephp/cakephp into 2.0

This commit is contained in:
Jose Lorenzo Rodriguez 2011-08-29 16:55:27 -04:30
commit 0e85170f28
18 changed files with 174 additions and 74 deletions

View file

@ -240,7 +240,9 @@ class FileEngine extends CacheEngine {
} }
$path = $this->_File->getRealPath(); $path = $this->_File->getRealPath();
$this->_File = null; $this->_File = null;
unlink($path); if (file_exists($path)) {
unlink($path);
}
} }
$dir->close(); $dir->close();
return true; return true;

View file

@ -65,6 +65,8 @@ class BakeShell extends Shell {
* @return mixed * @return mixed
*/ */
public function main() { public function main() {
Configure::write('Cache.disable', 1);
if (!is_dir($this->DbConfig->path)) { if (!is_dir($this->DbConfig->path)) {
$path = $this->Project->execute(); $path = $this->Project->execute();
if (!empty($path)) { if (!empty($path)) {

View file

@ -43,6 +43,17 @@ class BakeTask extends Shell {
*/ */
public $interactive = false; public $interactive = false;
/**
* Disable caching for baking.
* This forces the most current database schema to be used.
*
* @return void
*/
function startup() {
Configure::write('Cache.disable', 1);
parent::startup();
}
/** /**
* Gets the path for output. Checks the plugin property * Gets the path for output. Checks the plugin property
* and returns the correct path. * and returns the correct path.

View file

@ -316,35 +316,30 @@ class FixtureTask extends BakeTask {
$insert = substr($insert, 0, (int)$fieldInfo['length'] - 2); $insert = substr($insert, 0, (int)$fieldInfo['length'] - 2);
} }
} }
$insert = "'$insert'";
break; break;
case 'timestamp': case 'timestamp':
$ts = time(); $insert = time();
$insert = "'$ts'";
break; break;
case 'datetime': case 'datetime':
$ts = date('Y-m-d H:i:s'); $insert = date('Y-m-d H:i:s');
$insert = "'$ts'";
break; break;
case 'date': case 'date':
$ts = date('Y-m-d'); $insert = date('Y-m-d');
$insert = "'$ts'";
break; break;
case 'time': case 'time':
$ts = date('H:i:s'); $insert = date('H:i:s');
$insert = "'$ts'";
break; break;
case 'boolean': case 'boolean':
$insert = 1; $insert = 1;
break; break;
case 'text': case 'text':
$insert = "'Lorem ipsum dolor sit amet, aliquet feugiat."; $insert = "Lorem ipsum dolor sit amet, aliquet feugiat.";
$insert .= " Convallis morbi fringilla gravida,"; $insert .= " Convallis morbi fringilla gravida,";
$insert .= " phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin"; $insert .= " phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin";
$insert .= " venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla"; $insert .= " venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla";
$insert .= " vestibulum massa neque ut et, id hendrerit sit,"; $insert .= " vestibulum massa neque ut et, id hendrerit sit,";
$insert .= " feugiat in taciti enim proin nibh, tempor dignissim, rhoncus"; $insert .= " feugiat in taciti enim proin nibh, tempor dignissim, rhoncus";
$insert .= " duis vestibulum nunc mattis convallis.'"; $insert .= " duis vestibulum nunc mattis convallis.";
break; break;
} }
$record[$field] = $insert; $record[$field] = $insert;
@ -365,7 +360,8 @@ class FixtureTask extends BakeTask {
foreach ($records as $record) { foreach ($records as $record) {
$values = array(); $values = array();
foreach ($record as $field => $value) { foreach ($record as $field => $value) {
$values[] = "\t\t\t'$field' => $value"; $val = var_export($value, true);
$values[] = "\t\t\t'$field' => $val";
} }
$out .= "\t\tarray(\n"; $out .= "\t\tarray(\n";
$out .= implode(",\n", $values); $out .= implode(",\n", $values);
@ -408,7 +404,7 @@ class FixtureTask extends BakeTask {
foreach ($records as $record) { foreach ($records as $record) {
$row = array(); $row = array();
foreach ($record[$modelObject->alias] as $field => $value) { foreach ($record[$modelObject->alias] as $field => $value) {
$row[$field] = $db->value($value, $schema[$field]['type']); $row[$field] = $value;
} }
$out[] = $row; $out[] = $row;
} }

View file

@ -427,6 +427,9 @@ class App {
* *
* `App::objects('MyPlugin.Model');` returns `array('MyPluginPost', 'MyPluginComment');` * `App::objects('MyPlugin.Model');` returns `array('MyPluginPost', 'MyPluginComment');`
* *
* When scanning directories, files and directories beginning with `.` will be excluded as these
* are commonly used by version control systems.
*
* @param string $type Type of object, i.e. 'Model', 'Controller', 'View/Helper', 'file', 'class' or 'plugin' * @param string $type Type of object, i.e. 'Model', 'Controller', 'View/Helper', 'file', 'class' or 'plugin'
* @param mixed $path Optional Scan only the path given. If null, paths for the chosen type will be used. * @param mixed $path Optional Scan only the path given. If null, paths for the chosen type will be used.
* @param boolean $cache Set to false to rescan objects of the chosen type. Defaults to true. * @param boolean $cache Set to false to rescan objects of the chosen type. Defaults to true.
@ -476,12 +479,13 @@ class App {
if ($dir != APP && is_dir($dir)) { if ($dir != APP && is_dir($dir)) {
$files = new RegexIterator(new DirectoryIterator($dir), $extension); $files = new RegexIterator(new DirectoryIterator($dir), $extension);
foreach ($files as $file) { foreach ($files as $file) {
if (!$file->isDot()) { $fileName = basename($file);
if (!$file->isDot() && $fileName[0] !== '.') {
$isDir = $file->isDir() ; $isDir = $file->isDir() ;
if ($isDir && $includeDirectories) { if ($isDir && $includeDirectories) {
$objects[] = basename($file); $objects[] = $fileName;
} elseif (!$includeDirectories && !$isDir) { } elseif (!$includeDirectories && !$isDir) {
$objects[] = substr(basename($file), 0, -4); $objects[] = substr($fileName, 0, -4);
} }
} }
} }

View file

@ -93,6 +93,7 @@ class L10n {
/* Arabic */ 'ara' => 'ar', /* Arabic */ 'ara' => 'ar',
/* Armenian - Armenia */ 'hye' => 'hy', /* Armenian - Armenia */ 'hye' => 'hy',
/* Basque */ 'baq' => 'eu', /* Basque */ 'baq' => 'eu',
/* Tibetan */ 'bod' => 'bo',
/* Bosnian */ 'bos' => 'bs', /* Bosnian */ 'bos' => 'bs',
/* Bulgarian */ 'bul' => 'bg', /* Bulgarian */ 'bul' => 'bg',
/* Byelorussian */ 'bel' => 'be', /* Byelorussian */ 'bel' => 'be',
@ -194,6 +195,9 @@ class L10n {
'ar-ye' => array('language' => 'Arabic (Yemen)', 'locale' => 'ar_ye', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'), 'ar-ye' => array('language' => 'Arabic (Yemen)', 'locale' => 'ar_ye', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
'be' => array('language' => 'Byelorussian', 'locale' => 'bel', 'localeFallback' => 'bel', 'charset' => 'utf-8', 'direction' => 'ltr'), 'be' => array('language' => 'Byelorussian', 'locale' => 'bel', 'localeFallback' => 'bel', 'charset' => 'utf-8', 'direction' => 'ltr'),
'bg' => array('language' => 'Bulgarian', 'locale' => 'bul', 'localeFallback' => 'bul', 'charset' => 'utf-8', 'direction' => 'ltr'), 'bg' => array('language' => 'Bulgarian', 'locale' => 'bul', 'localeFallback' => 'bul', 'charset' => 'utf-8', 'direction' => 'ltr'),
'bo' => array('language' => 'Tibetan', 'locale' => 'bod', 'localeFallback' => 'bod', 'charset' => 'utf-8', 'direction' => 'ltr'),
'bo-cn' => array('language' => 'Tibetan (China)', 'locale' => 'bo_cn', 'localeFallback' => 'bod', 'charset' => 'utf-8', 'direction' => 'ltr'),
'bo-in' => array('language' => 'Tibetan (India)', 'locale' => 'bo_in', 'localeFallback' => 'bod', 'charset' => 'utf-8', 'direction' => 'ltr'),
'bs' => array('language' => 'Bosnian', 'locale' => 'bos', 'localeFallback' => 'bos', 'charset' => 'utf-8', 'direction' => 'ltr'), 'bs' => array('language' => 'Bosnian', 'locale' => 'bos', 'localeFallback' => 'bos', 'charset' => 'utf-8', 'direction' => 'ltr'),
'ca' => array('language' => 'Catalan', 'locale' => 'cat', 'localeFallback' => 'cat', 'charset' => 'utf-8', 'direction' => 'ltr'), 'ca' => array('language' => 'Catalan', 'locale' => 'cat', 'localeFallback' => 'cat', 'charset' => 'utf-8', 'direction' => 'ltr'),
'cs' => array('language' => 'Czech', 'locale' => 'cze', 'localeFallback' => 'cze', 'charset' => 'utf-8', 'direction' => 'ltr'), 'cs' => array('language' => 'Czech', 'locale' => 'cze', 'localeFallback' => 'cze', 'charset' => 'utf-8', 'direction' => 'ltr'),

View file

@ -605,23 +605,35 @@ class CakeRequest implements ArrayAccess {
* *
* `$this->request->accepts('json');` * `$this->request->accepts('json');`
* *
* This method will order the returned content types by the preference values indicated
* by the client.
*
* @param string $type The content type to check for. Leave null to get all types a client accepts. * @param string $type The content type to check for. Leave null to get all types a client accepts.
* @return mixed Either an array of all the types the client accepts or a boolean if they accept the * @return mixed Either an array of all the types the client accepts or a boolean if they accept the
* provided type. * provided type.
*/ */
public function accepts($type = null) { public function accepts($type = null) {
$acceptTypes = explode(',', $this->header('accept')); $accept = array();
$acceptTypes = array_map('trim', $acceptTypes); $header = explode(',', $this->header('accept'));
foreach ($acceptTypes as $i => $accepted) { foreach (array_filter(array_reverse($header)) as $value) {
if (strpos($accepted, ';') !== false) { $prefPos = strpos($value, ';');
list($accepted) = explode(';', $accepted); if ($prefPos !== false) {
$acceptTypes[$i] = $accepted; $prefValue = (float) substr($value, strpos($value, '=') + 1);
$value = trim(substr($value, 0, $prefPos));
} else {
$prefValue = 1.0;
$value = trim($value);
}
if ($prefValue) {
$accept[$value] = $prefValue;
} }
} }
arsort($accept);
$accept = array_keys($accept);
if ($type === null) { if ($type === null) {
return $acceptTypes; return $accept;
} }
return in_array($type, $acceptTypes); return in_array($type, $accept);
} }
/** /**

View file

@ -36,8 +36,7 @@ class AllComponentsTest extends PHPUnit_Framework_TestSuite {
$suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentTest.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentTest.php');
$suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentCollectionTest.php'); $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentCollectionTest.php');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'Controller' . DS . 'Component'); $suite->addTestDirectoryRecursive(CORE_TEST_CASES . DS . 'Controller' . DS . 'Component');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'Controller' . DS . 'Component' . DS . 'Auth');
return $suite; return $suite;
} }
} }

View file

@ -164,6 +164,31 @@ class FixtureTaskTest extends CakeTestCase {
$this->assertPattern("/'connection' => 'test'/", $result); $this->assertPattern("/'connection' => 'test'/", $result);
} }
/**
* Ensure that fixture data doesn't get overly escaped.
*
* @return void
*/
function testImportRecordsNoEscaping() {
$Article = ClassRegistry::init('Article');
$Article->updateAll(array('body' => "'Body \"value\"'"));
$this->Task->interactive = true;
$this->Task->expects($this->at(0))
->method('in')
->will($this->returnValue('WHERE 1=1 LIMIT 10'));
$this->Task->connection = 'test';
$this->Task->path = '/my/path/';
$result = $this->Task->bake('Article', false, array(
'fromTable' => true,
'schema' => 'Article',
'records' => false
));
$this->assertRegExp("/'body' => 'Body \"value\"'/", $result, 'Data has bad escaping');
}
/** /**
* test that execute passes runs bake depending with named model. * test that execute passes runs bake depending with named model.
* *

View file

@ -157,7 +157,7 @@ class RequestHandlerComponentTest extends CakeTestCase {
*/ */
public function testInitializeCallback() { public function testInitializeCallback() {
$this->assertNull($this->RequestHandler->ext); $this->assertNull($this->RequestHandler->ext);
$this->Controller->request->params['url']['ext'] = 'rss'; $this->Controller->request->params['ext'] = 'rss';
$this->RequestHandler->initialize($this->Controller); $this->RequestHandler->initialize($this->Controller);
$this->assertEqual($this->RequestHandler->ext, 'rss'); $this->assertEqual($this->RequestHandler->ext, 'rss');
} }
@ -222,7 +222,7 @@ class RequestHandlerComponentTest extends CakeTestCase {
*/ */
public function testAutoResponseType() { public function testAutoResponseType() {
$this->Controller->ext = '.thtml'; $this->Controller->ext = '.thtml';
$this->Controller->request->params['url']['ext'] = 'rss'; $this->Controller->request->params['ext'] = 'rss';
$this->RequestHandler->initialize($this->Controller); $this->RequestHandler->initialize($this->Controller);
$this->RequestHandler->startup($this->Controller); $this->RequestHandler->startup($this->Controller);
$this->assertEqual($this->Controller->ext, '.ctp'); $this->assertEqual($this->Controller->ext, '.ctp');
@ -240,7 +240,7 @@ class RequestHandlerComponentTest extends CakeTestCase {
$this->assertEquals($this->Controller->layout, $this->RequestHandler->ajaxLayout); $this->assertEquals($this->Controller->layout, $this->RequestHandler->ajaxLayout);
$this->_init(); $this->_init();
$this->Controller->request->params['url']['ext'] = 'js'; $this->Controller->request->params['ext'] = 'js';
$this->RequestHandler->initialize($this->Controller); $this->RequestHandler->initialize($this->Controller);
$this->RequestHandler->startup($this->Controller); $this->RequestHandler->startup($this->Controller);
$this->assertNotEqual($this->Controller->layout, 'ajax'); $this->assertNotEqual($this->Controller->layout, 'ajax');

View file

@ -305,6 +305,21 @@ class AppTest extends CakeTestCase {
App::build(); App::build();
} }
/**
* Make sure that .svn and friends are excluded from App::objects('plugin')
*/
public function testListObjectsIgnoreDotDirectories() {
$path = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS;
App::build(array(
'plugins' => array($path)
), true);
mkdir($path . '.svn');
$result = App::objects('plugin', null, false);
rmdir($path . '.svn');
$this->assertNotContains('.svn', $result);
}
/** /**
* Tests listing objects within a plugin * Tests listing objects within a plugin
* *

View file

@ -785,7 +785,7 @@ class CakeRequestTestCase extends CakeTestCase {
$result = $request->accepts(); $result = $request->accepts();
$expected = array( $expected = array(
'text/xml', 'application/xml', 'application/xhtml+xml', 'text/html', 'text/plain', 'image/png' 'text/xml', 'application/xhtml+xml', 'text/html', 'image/png', 'text/plain', 'application/xml'
); );
$this->assertEquals($expected, $result, 'Content types differ.'); $this->assertEquals($expected, $result, 'Content types differ.');
@ -813,6 +813,19 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertTrue($request->accepts('text/html')); $this->assertTrue($request->accepts('text/html'));
} }
/**
* Content types from accepts() should respect the client's q preference values.
*
* @return void
*/
public function testAcceptWithQvalueSorting() {
$_SERVER['HTTP_ACCEPT'] = 'text/html;q=0.8,application/json;q=0.7,application/xml;q=1.0';
$request = new CakeRequest('/', false);
$result = $request->accepts();
$expected = array('application/xml', 'text/html', 'application/json');
$this->assertEquals($expected, $result);
}
/** /**
* testBaseUrlAndWebrootWithModRewrite method * testBaseUrlAndWebrootWithModRewrite method
* *

View file

@ -106,6 +106,8 @@ class InflectorTest extends CakeTestCase {
$this->assertEqual(Inflector::singularize('bases'), 'basis'); $this->assertEqual(Inflector::singularize('bases'), 'basis');
$this->assertEqual(Inflector::singularize('analyses'), 'analysis'); $this->assertEqual(Inflector::singularize('analyses'), 'analysis');
$this->assertEqual(Inflector::singularize('curves'), 'curve'); $this->assertEqual(Inflector::singularize('curves'), 'curve');
$this->assertEqual(Inflector::singularize('cafes'), 'cafe');
$this->assertEqual(Inflector::singularize('roofs'), 'roof');
$this->assertEqual(Inflector::singularize(''), ''); $this->assertEqual(Inflector::singularize(''), '');
} }
@ -153,6 +155,8 @@ class InflectorTest extends CakeTestCase {
$this->assertEqual(Inflector::pluralize('tax'), 'taxes'); $this->assertEqual(Inflector::pluralize('tax'), 'taxes');
$this->assertEqual(Inflector::pluralize('wave'), 'waves'); $this->assertEqual(Inflector::pluralize('wave'), 'waves');
$this->assertEqual(Inflector::pluralize('bureau'), 'bureaus'); $this->assertEqual(Inflector::pluralize('bureau'), 'bureaus');
$this->assertEqual(Inflector::pluralize('cafe'), 'cafes');
$this->assertEqual(Inflector::pluralize('roof'), 'roofs');
$this->assertEqual(Inflector::pluralize(''), ''); $this->assertEqual(Inflector::pluralize(''), '');
} }

View file

@ -1366,6 +1366,7 @@ class ValidationTest extends CakeTestCase {
$this->assertTrue(Validation::date('Dec 27 2006', array('Mdy'))); $this->assertTrue(Validation::date('Dec 27 2006', array('Mdy')));
$this->assertFalse(Validation::date('27 Dec 2006', array('Mdy'))); $this->assertFalse(Validation::date('27 Dec 2006', array('Mdy')));
$this->assertFalse(Validation::date('2006 December 27', array('Mdy'))); $this->assertFalse(Validation::date('2006 December 27', array('Mdy')));
$this->assertTrue(Validation::date('Sep 12, 2011', array('Mdy')));
} }
/** /**

View file

@ -18,6 +18,8 @@
*/ */
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT'); PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
App::uses('Folder', 'Utility');
class CakeTestSuite extends PHPUnit_Framework_TestSuite { class CakeTestSuite extends PHPUnit_Framework_TestSuite {
/** /**
@ -27,13 +29,10 @@ class CakeTestSuite extends PHPUnit_Framework_TestSuite {
* @return void * @return void
*/ */
public function addTestDirectory($directory = '.') { public function addTestDirectory($directory = '.') {
$files = new DirectoryIterator($directory); $folder = new Folder($directory);
list($dirs, $files) = $folder->read(true, false, true);
foreach ($files as $file) { foreach ($files as $file) {
if (!$file->isFile()) {
continue;
}
$file = $file->getRealPath();
$this->addTestFile($file); $this->addTestFile($file);
} }
} }
@ -45,15 +44,12 @@ class CakeTestSuite extends PHPUnit_Framework_TestSuite {
* @return void * @return void
*/ */
public function addTestDirectoryRecursive($directory = '.') { public function addTestDirectoryRecursive($directory = '.') {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); $folder = new Folder($directory);
$files = $folder->tree(null, false, 'files');
foreach ($files as $file) { foreach ($files as $file) {
if (!$file->isFile()) {
continue;
}
$file = $file->getRealPath();
$this->addTestFile($file); $this->addTestFile($file);
} }
} }
} }

View file

@ -145,29 +145,33 @@ class Folder {
} }
$skipHidden = isset($exceptions['.']) || $exceptions === true; $skipHidden = isset($exceptions['.']) || $exceptions === true;
if (false === ($dir = @opendir($this->path))) { try {
$iterator = new DirectoryIterator($this->path);
} catch (UnexpectedValueException $e) {
return array($dirs, $files); return array($dirs, $files);
} }
while (false !== ($item = readdir($dir))) { foreach ($iterator as $item) {
if ($item === '.' || $item === '..' || ($skipHidden && $item[0] === '.') || isset($exceptions[$item])) { if ($item->isDot()) {
continue; continue;
} }
$name = $item->getFileName();
$path = Folder::addPathElement($this->path, $item); if ($skipHidden && $name[0] === '.' || isset($exceptions[$name])) {
if (is_dir($path)) { continue;
$dirs[] = $fullPath ? $path : $item; }
if ($fullPath) {
$name = $item->getPathName();
}
if ($item->isDir()) {
$dirs[] = $name;
} else { } else {
$files[] = $fullPath ? $path : $item; $files[] = $name;
} }
} }
if ($sort || $this->sort) { if ($sort || $this->sort) {
sort($dirs); sort($dirs);
sort($files); sort($files);
} }
closedir($dir);
return array($dirs, $files); return array($dirs, $files);
} }
@ -380,37 +384,48 @@ class Folder {
* @param string $type either file or dir. null returns both files and directories * @param string $type either file or dir. null returns both files and directories
* @return mixed array of nested directories and files in each directory * @return mixed array of nested directories and files in each directory
*/ */
public function tree($path, $exceptions = true, $type = null) { public function tree($path = null, $exceptions = true, $type = null) {
$original = $this->path; if ($path == null) {
$path = rtrim($path, DS); $path = $this->path;
if (!$this->cd($path)) { }
$files = array();
$directories = array($path);
$skipHidden = false;
if ($exceptions === false) {
$skipHidden = true;
}
if (is_array($exceptions)) {
$exceptions = array_flip($exceptions);
}
try {
$directory = new RecursiveDirectoryIterator($path);
$iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
} catch (UnexpectedValueException $e) {
if ($type === null) { if ($type === null) {
return array(array(), array()); return array(array(), array());
} }
return array(); return array();
} }
$this->_files = array(); foreach ($iterator as $item) {
$this->_directories = array($this->realpath($path)); $name = $item->getFileName();
$directories = array(); if ($skipHidden && $name[0] === '.' || isset($exceptions[$name])) {
continue;
if ($exceptions === false) { }
$exceptions = true; if ($item->isFile()) {
$files[] = $item->getPathName();
} else if ($item->isDir()) {
$directories[] = $item->getPathName();
}
} }
while (!empty($this->_directories)) {
$dir = array_pop($this->_directories);
$this->_tree($dir, $exceptions);
$directories[] = $dir;
}
if ($type === null) { if ($type === null) {
return array($directories, $this->_files); return array($directories, $files);
} }
if ($type === 'dir') { if ($type === 'dir') {
return $directories; return $directories;
} }
$this->cd($original); return $files;
return $this->_files;
} }
/** /**

View file

@ -67,6 +67,7 @@ class Inflector {
'atlas' => 'atlases', 'atlas' => 'atlases',
'beef' => 'beefs', 'beef' => 'beefs',
'brother' => 'brothers', 'brother' => 'brothers',
'cafe' => 'cafes',
'child' => 'children', 'child' => 'children',
'corpus' => 'corpuses', 'corpus' => 'corpuses',
'cow' => 'cows', 'cow' => 'cows',

View file

@ -300,7 +300,7 @@ class Validation {
$regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])(\\/|-|\\.|\\x20)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.|\\x20)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.|\\x20)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%'; $regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])(\\/|-|\\.|\\x20)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.|\\x20)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.|\\x20)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
$regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\\/|-|\\.|\\x20)(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})(\\/|-|\\.|\\x20)(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%'; $regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\\/|-|\\.|\\x20)(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})(\\/|-|\\.|\\x20)(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%';
$regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/'; $regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/';
$regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/'; $regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep)(tember)?|(Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/';
$regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)[ /]((1[6-9]|[2-9]\\d)\\d{2})$%'; $regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)[ /]((1[6-9]|[2-9]\\d)\\d{2})$%';
$regex['my'] = '%^(((0[123456789]|10|11|12)([- /.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$%'; $regex['my'] = '%^(((0[123456789]|10|11|12)([- /.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$%';