diff --git a/cake/console/shells/tasks/fixture.php b/cake/console/shells/tasks/fixture.php index 8fd60782b..6a527672c 100644 --- a/cake/console/shells/tasks/fixture.php +++ b/cake/console/shells/tasks/fixture.php @@ -185,7 +185,9 @@ class FixtureTask extends BakeTask { if (!class_exists('CakeSchema')) { App::import('Model', 'CakeSchema', false); } - $table = $schema = $records = $import = $modelImport = $recordImport = null; + $table = $schema = $records = $import = $modelImport = null; + $importBits = array(); + if (!$useTable) { $useTable = Inflector::tableize($model); } elseif ($useTable != Inflector::tableize($model)) { @@ -194,16 +196,17 @@ class FixtureTask extends BakeTask { if (!empty($importOptions)) { if (isset($importOptions['schema'])) { - $modelImport = "'model' => '{$importOptions['schema']}'"; + $modelImport = true; + $importBits[] = "'model' => '{$importOptions['schema']}'"; } if (isset($importOptions['records'])) { - $recordImport = "'records' => true"; + $importBits[] = "'records' => true"; } - if ($modelImport && $recordImport) { - $modelImport .= ', '; + if ($this->connection != 'default') { + $importBits[] .= "'connection' => '{$this->connection}'"; } - if (!empty($modelImport) || !empty($recordImport)) { - $import = sprintf("array(%s%s)", $modelImport, $recordImport); + if (!empty($importBits)) { + $import = sprintf("array(%s)", implode(', ', $importBits)); } } diff --git a/cake/console/shells/tasks/test.php b/cake/console/shells/tasks/test.php index 0fe453040..e62286e77 100644 --- a/cake/console/shells/tasks/test.php +++ b/cake/console/shells/tasks/test.php @@ -177,7 +177,20 @@ class TestTask extends BakeTask { * @return string Class name the user chose. */ public function getClassName($objectType) { - $options = App::objects(strtolower($objectType)); + $type = strtolower($objectType); + if ($this->plugin) { + $path = Inflector::pluralize($type); + if ($type === 'helper') { + $path = 'views' . DS . $path; + } elseif ($type === 'component') { + $path = 'controllers' . DS . $path; + } elseif ($type === 'behavior') { + $path = 'models' . DS . $path; + } + $options = App::objects($type, App::pluginPath($this->plugin) . $path, false); + } else { + $options = App::objects($type); + } $this->out(__('Choose a %s class', $objectType)); $keys = array(); foreach ($options as $key => $option) { diff --git a/cake/libs/controller/components/email.php b/cake/libs/controller/components/email.php index 031ef8543..e9ee33a75 100755 --- a/cake/libs/controller/components/email.php +++ b/cake/libs/controller/components/email.php @@ -461,7 +461,7 @@ class EmailComponent extends Component { App::import('View', $this->Controller->view); } - $View = new $viewClass($this->Controller, false); + $View = new $viewClass($this->Controller); $View->layout = $this->layout; $msg = array(); @@ -499,6 +499,7 @@ class EmailComponent extends Component { $msg[] = '--alt-' . $this->_boundary . '--'; $msg[] = ''; + ClassRegistry::removeObject('view'); return $msg; } @@ -528,6 +529,7 @@ class EmailComponent extends Component { } $msg = array_merge($msg, $content); + ClassRegistry::removeObject('view'); return $msg; } @@ -777,14 +779,15 @@ class EmailComponent extends Component { * @access private */ function _formatAddress($string, $smtp = false) { - $hasAlias = preg_match('/((.*)\s)?<(.+)>/', $string, $matches); + $hasAlias = preg_match('/((.*))?\s?<(.+)>/', $string, $matches); if ($smtp && $hasAlias) { return $this->_strip('<' . $matches[3] . '>'); } elseif ($smtp) { return $this->_strip('<' . $string . '>'); } + if ($hasAlias && !empty($matches[2])) { - return $this->_strip($matches[2] . ' <' . $matches[3] . '>'); + return $this->_encode($matches[2]) . $this->_strip(' <' . $matches[3] . '>'); } return $this->_strip($string); } @@ -837,6 +840,18 @@ class EmailComponent extends Component { return @mail($to, $this->_encode($this->subject), $message, $header, $this->additionalParams); } + +/** + * Helper method to get socket, overridden in tests + * + * @param array $config Config data for the socket. + * @return void + * @access protected + */ + function _getSocket($config) { + $this->_smtpConnection = new CakeSocket($config); + } + /** * Sends out email via SMTP * @@ -853,7 +868,7 @@ class EmailComponent extends Component { 'timeout' => 30 ); $this->smtpOptions = array_merge($defaults, $this->smtpOptions); - $this->_smtpConnection = new CakeSocket($this->smtpOptions); + $this->_getSocket($this->smtpOptions); if (!$this->_smtpConnection->connect()) { $this->smtpError = $this->_smtpConnection->lastError(); @@ -867,7 +882,7 @@ class EmailComponent extends Component { if (isset($this->smtpOptions['client'])) { $host = $this->smtpOptions['client']; } elseif (!empty($httpHost)) { - $host = $httpHost; + list($host) = explode(':', $httpHost); } else { $host = 'localhost'; } diff --git a/cake/libs/model/datasources/datasource.php b/cake/libs/model/datasources/datasource.php index d38e8bf10..a6ebd4d1f 100644 --- a/cake/libs/model/datasources/datasource.php +++ b/cake/libs/model/datasources/datasource.php @@ -484,6 +484,7 @@ class DataSource extends Object { foreach ($keys as $key) { $val = null; + $type = null; if (strpos($query, $key) !== false) { switch ($key) { @@ -507,6 +508,7 @@ class DataSource extends Object { $val = ''; } } + $type = $model->getColumnType($model->primaryKey); break; case '{$__cakeForeignKey__$}': foreach ($model->associations() as $id => $name) { @@ -514,6 +516,8 @@ class DataSource extends Object { if ($assocName === $association) { if (isset($assoc['foreignKey'])) { $foreignKey = $assoc['foreignKey']; + $assocModel = $model->$assocName; + $type = $assocModel->getColumnType($assocModel->primaryKey); if (isset($data[$model->alias][$foreignKey])) { $val = $data[$model->alias][$foreignKey]; @@ -542,7 +546,7 @@ class DataSource extends Object { if (empty($val) && $val !== '0') { return false; } - $query = str_replace($key, $this->value($val, $model->getColumnType($model->primaryKey)), $query); + $query = str_replace($key, $this->value($val, $type), $query); } } return $query; diff --git a/cake/libs/set.php b/cake/libs/set.php index 14282682d..8d204b18c 100644 --- a/cake/libs/set.php +++ b/cake/libs/set.php @@ -62,9 +62,21 @@ class Set { * @return mixed Either filtered array, or true/false when in callback */ public static function filter($var, $isArray = false) { - if (is_array($var) && (!empty($var) || $isArray)) { - return array_filter($var, array('Set', 'filter')); + foreach ((array)$var as $k => $v) { + if (!empty($v) && is_array($v)) { + $var[$k] = array_filter($v, array('Set', '_filter')); + } } + return array_filter($var, array('Set', '_filter')); + } + +/** + * Set::filter callback function + * + * @param array $var Array to filter. + * @return boolean + */ + protected static function _filter($var) { if ($var === 0 || $var === '0' || !empty($var)) { return true; } diff --git a/cake/libs/view/helpers/cache.php b/cake/libs/view/helpers/cache.php index 34f1c9ef3..017ca89f9 100644 --- a/cake/libs/view/helpers/cache.php +++ b/cake/libs/view/helpers/cache.php @@ -241,6 +241,7 @@ class CacheHelper extends AppHelper { $controller->layout = $this->layout = \'' . $this->_View->layout. '\'; $controller->request = $this->request = unserialize(\'' . str_replace("'", "\\'", serialize($this->request)) . '\'); $controller->theme = $this->theme = \'' . $this->_View->theme . '\'; + $controller->viewVars = $this->viewVars = ' . var_export($this->_View->viewVars, true) . '; Router::setRequestInfo($controller->request);'; if ($useCallbacks == true) { @@ -251,6 +252,7 @@ class CacheHelper extends AppHelper { $file .= ' $this->loadHelpers(); + extract($this->viewVars, EXTR_SKIP); ?>'; $content = preg_replace("/(<\\?xml)/", "",$content); $file .= $content; diff --git a/cake/libs/view/helpers/js.php b/cake/libs/view/helpers/js.php index e285481ad..e8d50949a 100644 --- a/cake/libs/view/helpers/js.php +++ b/cake/libs/view/helpers/js.php @@ -477,6 +477,7 @@ abstract class JsBaseEngineHelper extends AppHelper { * @return void */ function __construct() { + parent::__construct(); $this->useNative = function_exists('json_encode'); } diff --git a/cake/libs/view/helpers/time.php b/cake/libs/view/helpers/time.php index 163212955..1de5876e3 100644 --- a/cake/libs/view/helpers/time.php +++ b/cake/libs/view/helpers/time.php @@ -253,10 +253,10 @@ class TimeHelper extends AppHelper { $y = $this->isThisYear($date) ? '' : ' %Y'; - if ($this->isToday($date)) { - $ret = __('Today, %s', strftime("%H:%M", $date)); - } elseif ($this->wasYesterday($date)) { - $ret = __('Yesterday, %s', strftime("%H:%M", $date)); + if ($this->isToday($dateString, $userOffset)) { + $ret = sprintf(__('Today, %s', strftime("%H:%M", $date)); + } elseif ($this->wasYesterday($dateString, $userOffset)) { + $ret = sprintf(__('Yesterday, %s', strftime("%H:%M", $date)); } else { $format = $this->convertSpecifiers("%b %eS{$y}, %H:%M", $date); $ret = strftime($format, $date); diff --git a/cake/tests/cases/console/shells/tasks/fixture.test.php b/cake/tests/cases/console/shells/tasks/fixture.test.php index 9265fdfb6..9cdf9a271 100644 --- a/cake/tests/cases/console/shells/tasks/fixture.test.php +++ b/cake/tests/cases/console/shells/tasks/fixture.test.php @@ -154,6 +154,17 @@ class FixtureTaskTest extends CakeTestCase { $this->assertPattern('/Third Article/', $result, 'Missing import data %s'); } +/** + * test that connection gets set to the import options when a different connection is used. + * + * @return void + */ + function testImportOptionsAlternateConnection() { + $this->Task->connection = 'test'; + $result = $this->Task->bake('Article', false, array('schema' => 'Article')); + $this->assertPattern("/'connection' => 'test'/", $result); + } + /** * test that execute passes runs bake depending with named model. * @@ -293,15 +304,15 @@ class FixtureTaskTest extends CakeTestCase { $this->assertPattern('/public \$fields = array\(/', $result); $result = $this->Task->bake('Article', 'comments', array('records' => true)); - $this->assertPattern("/public \\\$import \= array\('records' \=\> true\);/", $result); + $this->assertPattern("/public \\\$import \= array\('records' \=\> true, 'connection' => 'test'\);/", $result); $this->assertNoPattern('/public \$records/', $result); $result = $this->Task->bake('Article', 'comments', array('schema' => 'Article')); - $this->assertPattern("/public \\\$import \= array\('model' \=\> 'Article'\);/", $result); + $this->assertPattern("/public \\\$import \= array\('model' \=\> 'Article'\, 'connection' => 'test'\);/", $result); $this->assertNoPattern('/public \$fields/', $result); $result = $this->Task->bake('Article', 'comments', array('schema' => 'Article', 'records' => true)); - $this->assertPattern("/public \\\$import \= array\('model' \=\> 'Article'\, 'records' \=\> true\);/", $result); + $this->assertPattern("/public \\\$import \= array\('model' \=\> 'Article'\, 'records' \=\> true\, 'connection' => 'test'\);/", $result); $this->assertNoPattern('/public \$fields/', $result); $this->assertNoPattern('/public \$records/', $result); } @@ -359,4 +370,5 @@ class FixtureTaskTest extends CakeTestCase { $result = $this->Task->generateFixtureFile('Article', array()); } + } diff --git a/cake/tests/cases/console/shells/tasks/test.test.php b/cake/tests/cases/console/shells/tasks/test.test.php index 394098a38..b57ec9d2f 100644 --- a/cake/tests/cases/console/shells/tasks/test.test.php +++ b/cake/tests/cases/console/shells/tasks/test.test.php @@ -533,6 +533,37 @@ class TestTaskTest extends CakeTestCase { $this->Task->bake('Helper', 'Form'); } +/** + * test interactive with plugins lists from the plugin + * + * @return void + */ + function testInteractiveWithPlugin() { + $testApp = TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS; + App::build(array( + 'plugins' => array($testApp) + ), true); + + $this->Task->plugin = 'TestPlugin'; + $path = $testApp . 'test_plugin' . DS . 'tests' . DS . 'cases' . DS . 'helpers' . DS . 'other_helper.test.php'; + $this->Task->expects($this->any()) + ->method('in') + ->will($this->onConsecutiveCalls( + 5, //helper + 1 //OtherHelper + )); + + $this->Task->expects($this->once()) + ->method('createFile') + ->with($path, $this->anything()); + + $this->Task->stdout->expects($this->at(21)) + ->method('write') + ->with('1. OtherHelper'); + + $this->Task->execute(); + } + /** * Test filename generation for each type + plugins * diff --git a/cake/tests/cases/libs/controller/components/email.test.php b/cake/tests/cases/libs/controller/components/email.test.php index 411a93c09..878cc0da2 100755 --- a/cake/tests/cases/libs/controller/components/email.test.php +++ b/cake/tests/cases/libs/controller/components/email.test.php @@ -29,6 +29,7 @@ App::import('Core', 'CakeSocket'); */ class EmailTestComponent extends EmailComponent { + var $smtpSend = ''; /** * smtpSend method override for testing * @@ -39,6 +40,19 @@ class EmailTestComponent extends EmailComponent { return parent::_smtpSend($data, $code); } +/** + * undocumented function + * + * @return void + */ + function _smtpSend($data, $code = '250') { + if ($this->_debug) { + $this->smtpSend .= $data . "\n"; + return true; + } + return parent::_smtpSend($data, $code); + } + /** * Convenience setter method for testing. * @@ -49,6 +63,18 @@ class EmailTestComponent extends EmailComponent { $this->_smtpConnection = $socket; } +/** + * Allows mocks to be used with tests. + * + * @param array $config + * @return void + */ + function _getSocket($config) { + if (empty($this->_smtpConnection)) { + parent::_getSocket($config); + } + } + /** * Convenience getter method for testing. * @@ -413,46 +439,64 @@ TEMPDOC; * @return void */ function testSmtpSendMultipleTo() { - if ($this->skipIf(!@fsockopen('localhost', 25, $err, $errstr, .01), '%s No SMTP server running on localhost')) { - return; - } $this->Controller->EmailTest->reset(); $this->Controller->EmailTest->to = array('postmaster@localhost', 'root@localhost'); $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake SMTP multiple To test'; $this->Controller->EmailTest->replyTo = 'noreply@example.com'; $this->Controller->EmailTest->template = null; - - $this->Controller->EmailTest->delivery = 'smtp'; - $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->Controller->EmailTest->_debug = true; $this->Controller->EmailTest->sendAs = 'text'; - $expect = <<Host: localhost -Port: 25 -Timeout: 30 -To: postmaster@localhost, root@localhost -From: noreply@example.com -Subject: Cake SMTP multiple To test -Header: + $this->Controller->EmailTest->delivery = 'smtp'; -To: postmaster@localhost, root@localhost -From: noreply@example.com -Reply-To: noreply@example.com -Subject: Cake SMTP multiple To test -X-Mailer: CakePHP Email Component -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 7bitParameters: + $socket = $this->getMock('CakeSocket'); + $socket->expects($this->any()) + ->method('connect') + ->will($this->returnValue(true)); + $this->Controller->EmailTest->setConnectionSocket($socket); -Message: - -This is the body of the message - - -TEMPDOC; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); - $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + + $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern('/MAIL FROM: \n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern('/RCPT TO: \n/', $this->Controller->EmailTest->smtpSend); + $this->assertPattern( + '/To: postmaster@localhost, root@localhost[\n\r]/', + $this->Controller->EmailTest->smtpSend + ); + } + +/** + * test sending smtp from a host using a port. + * + * @return void + */ + function testSmtpSendHostWithPort() { + $bkp = env('HTTP_HOST'); + $_SERVER['HTTP_HOST'] = 'localhost:8080'; + + $this->Controller->EmailTest->reset(); + $this->Controller->EmailTest->to = array('root@localhost'); + $this->Controller->EmailTest->from = 'noreply@example.com'; + $this->Controller->EmailTest->subject = 'Cake SMTP host test'; + $this->Controller->EmailTest->replyTo = 'noreply@example.com'; + $this->Controller->EmailTest->template = null; + $this->Controller->EmailTest->delivery = 'smtp'; + $this->Controller->EmailTest->sendAs = 'text'; + $this->Controller->EmailTest->_debug = true; + + $socket = $this->getMock('CakeSocket'); + $socket->expects($this->any()) + ->method('connect') + ->will($this->returnValue(true)); + + $this->Controller->EmailTest->setConnectionSocket($socket); + $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message')); + + $this->assertPattern('/EHLO localhost\n/', $this->Controller->EmailTest->smtpSend); + + $_SERVER['HTTP_HOST'] = $bkp; } /** @@ -543,6 +587,8 @@ MSGBLOC; * @return void */ function testTemplates() { + ClassRegistry::flush(); + $this->Controller->EmailTest->to = 'postmaster@localhost'; $this->Controller->EmailTest->from = 'noreply@example.com'; $this->Controller->EmailTest->subject = 'Cake SMTP test'; @@ -634,6 +680,9 @@ HTMLBLOC; $expect = '
' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . '
'; $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'default', 'thin')); $this->assertEqual($this->Controller->Session->read('Message.email.message'), $this->__osFix($expect)); + + $result = ClassRegistry::getObject('view'); + $this->assertFalse($result); } /** @@ -1226,6 +1275,9 @@ HTMLBLOC; $result = $this->Controller->EmailTest->formatAddress('alias '); $this->assertEqual($result, 'alias '); + + $result = $this->Controller->EmailTest->formatAddress('alias'); + $this->assertEqual($result, 'alias '); $result = $this->Controller->EmailTest->formatAddress('email@example.com'); $this->assertEqual($result, 'email@example.com'); @@ -1242,4 +1294,21 @@ HTMLBLOC; $result = $this->Controller->EmailTest->formatAddress('alias name ', true); $this->assertEqual($result, ''); } + +/** + * test formatting addresses with multibyte chars + * + * @return void + */ + function testFormatAddressMultibyte() { + $this->Controller->EmailTest->charset = 'UTF-8'; + $result = $this->Controller->EmailTest->formatAddress('ÄÖÜTest '); + $this->assertEqual($result, '=?UTF-8?B?w4TDlsOcVGVzdCA=?= '); + + $result = $this->Controller->EmailTest->formatAddress('ÄÖÜTest'); + $this->assertEqual($result, '=?UTF-8?B?w4TDlsOcVGVzdA==?= '); + + $result = $this->Controller->EmailTest->formatAddress('ÄÖÜTest ', true); + $this->assertEqual($result, ''); + } } diff --git a/cake/tests/cases/libs/model/db_acl.test.php b/cake/tests/cases/libs/model/db_acl.test.php index 537f2f361..5b046717a 100644 --- a/cake/tests/cases/libs/model/db_acl.test.php +++ b/cake/tests/cases/libs/model/db_acl.test.php @@ -201,7 +201,7 @@ class DbAroUserTest extends CakeTestModel { * @access public */ public $useTable = 'auth_users'; - /** +/** * bindNode method * * @param mixed $ref diff --git a/cake/tests/cases/libs/set.test.php b/cake/tests/cases/libs/set.test.php index c648940bb..bbd3e581c 100644 --- a/cake/tests/cases/libs/set.test.php +++ b/cake/tests/cases/libs/set.test.php @@ -86,8 +86,20 @@ class SetTest extends CakeTestCase { */ function testFilter() { $result = Set::filter(array('0', false, true, 0, array('one thing', 'I can tell you', 'is you got to be', false))); - $expected = array('0', 2 => true, 3 => 0, 4 => array('one thing', 'I can tell you', 'is you got to be', false)); - $this->assertEquals($result, $expected); + $expected = array('0', 2 => true, 3 => 0, 4 => array('one thing', 'I can tell you', 'is you got to be')); + $this->assertSame($result, $expected); + + $result = Set::filter(array(1, array(false))); + $expected = array(1); + $this->assertEqual($expected, $result); + + $result = Set::filter(array(1, array(false, false))); + $expected = array(1); + $this->assertEqual($expected, $result); + + $result = Set::filter(array(1, array('empty', false))); + $expected = array(1, array('empty')); + $this->assertEqual($expected, $result); } /** diff --git a/cake/tests/cases/libs/view/helpers/cache.test.php b/cake/tests/cases/libs/view/helpers/cache.test.php index cc08e4d83..4aaa301c1 100644 --- a/cake/tests/cases/libs/view/helpers/cache.test.php +++ b/cake/tests/cases/libs/view/helpers/cache.test.php @@ -287,6 +287,42 @@ class CacheHelperTest extends CakeTestCase { $this->assertPattern('/7\. layout after content and after element with no cache tags/', $contents); } +/** + * test cache of view vars + * + * @access public + * @return void + */ + function testCacheViewVars() { + $this->Controller->cache_parsing(); + $this->Controller->params = array( + 'controller' => 'cache_test', + 'action' => 'cache_parsing', + 'url' => array(), + 'pass' => array(), + 'named' => array() + ); + $this->Controller->cacheAction = 21600; + $this->Controller->here = '/cacheTest/cache_parsing'; + $this->Controller->action = 'cache_parsing'; + + $View = new View($this->Controller); + $result = $View->render('index'); + $this->assertNoPattern('/cake:nocache/', $result); + $this->assertNoPattern('/php echo/', $result); + + $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php'; + $this->assertTrue(file_exists($filename)); + + $contents = file_get_contents($filename); + $this->assertPattern('/\$this\-\>viewVars/', $contents); + $this->assertPattern('/extract\(\$this\-\>viewVars, EXTR_SKIP\);/', $contents); + $this->assertPattern('/php echo \$variable/', $contents); + $this->assertPattern('/variableValue/', $contents); + + @unlink($filename); + } + /** * test cacheAction set to a boolean *