Skip to content

Commit

Permalink
Merge branch 'master' into 2.3
Browse files Browse the repository at this point in the history
Conflicts:
	lib/Cake/VERSION.txt
  • Loading branch information
markstory committed Jul 19, 2012
2 parents 7979ee5 + 3b46cd4 commit 3c6b509
Show file tree
Hide file tree
Showing 28 changed files with 390 additions and 49 deletions.
2 changes: 1 addition & 1 deletion lib/Cake/Console/Command/Task/ModelTask.php
Expand Up @@ -414,7 +414,7 @@ public function fieldValidation($fieldName, $metaData, $primaryKey = 'id') {
for ($i = 1, $m = $defaultChoice / 2; $i < $m; $i++) {
$line = sprintf("%2d. %s", $i, $this->_validations[$i]);
$optionText .= $line . str_repeat(" ", 31 - strlen($line));
$optionText .= sprintf("%2d. %s", $m + $i, $this->_validations[$m + $i]);
$optionText .= sprintf("%2d. %s\n", $m + $i, $this->_validations[$m + $i]);
}
$this->out($optionText);
$this->out(__d('cake_console', "%s - Do not do any validation on this field.", $defaultChoice));
Expand Down
41 changes: 30 additions & 11 deletions lib/Cake/Console/Shell.php
Expand Up @@ -165,23 +165,13 @@ public function __construct($stdout = null, $stderr = null, $stdin = null) {
if ($this->stdout == null) {
$this->stdout = new ConsoleOutput('php://stdout');
}
CakeLog::config('stdout', array(
'engine' => 'ConsoleLog',
'types' => array('notice', 'info'),
'stream' => $this->stdout,
));
if ($this->stderr == null) {
$this->stderr = new ConsoleOutput('php://stderr');
}
CakeLog::config('stderr', array(
'engine' => 'ConsoleLog',
'types' => array('emergency', 'alert', 'critical', 'error', 'warning', 'debug'),
'stream' => $this->stderr,
));
if ($this->stdin == null) {
$this->stdin = new ConsoleInput('php://stdin');
}

$this->_useLogger();
$parent = get_parent_class($this);
if ($this->tasks !== null && $this->tasks !== false) {
$this->_mergeVars(array('tasks'), $parent, true);
Expand Down Expand Up @@ -379,6 +369,10 @@ public function runCommand($command, $argv) {
return false;
}

if (!empty($this->params['quiet'])) {
$this->_useLogger(false);
}

$this->command = $command;
if (!empty($this->params['help'])) {
return $this->_displayHelp($command);
Expand Down Expand Up @@ -825,4 +819,29 @@ protected function _pluginPath($pluginName) {
return current(App::path('plugins')) . $pluginName . DS;
}

/**
* Used to enable or disable logging stream output to stdout and stderr
* If you don't wish to see in your stdout or stderr everything that is logged
* through CakeLog, call this function with first param as false
*
* @param boolean $enable wheter to enable CakeLog output or not
* @return void
**/
protected function _useLogger($enable = true) {
if (!$enable) {
CakeLog::drop('stdout');
CakeLog::drop('stderr');
return;
}
CakeLog::config('stdout', array(
'engine' => 'ConsoleLog',
'types' => array('notice', 'info'),
'stream' => $this->stdout,
));
CakeLog::config('stderr', array(
'engine' => 'ConsoleLog',
'types' => array('emergency', 'alert', 'critical', 'error', 'warning', 'debug'),
'stream' => $this->stderr,
));
}
}
5 changes: 3 additions & 2 deletions lib/Cake/Controller/Component/SecurityComponent.php
Expand Up @@ -229,7 +229,7 @@ public function startup(Controller $controller) {
}
}
$this->generateToken($controller->request);
if ($isPost) {
if ($isPost && is_array($controller->request->data)) {
unset($controller->request->data['_Token']);
}
}
Expand Down Expand Up @@ -585,12 +585,13 @@ protected function _expireTokens($tokens) {
* @param string $method Method to execute
* @param array $params Parameters to send to method
* @return mixed Controller callback method's response
* @throws BadRequestException When a the blackholeCallback is not callable.
*/
protected function _callback(Controller $controller, $method, $params = array()) {
if (is_callable(array($controller, $method))) {
return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
} else {
return null;
throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
}
}

Expand Down
7 changes: 6 additions & 1 deletion lib/Cake/Log/Engine/ConsoleLog.php
Expand Up @@ -49,11 +49,16 @@ class ConsoleLog extends BaseLog {
*/
public function __construct($config = array()) {
parent::__construct($config);
if (DS == '\\' && !(bool)env('ANSICON')) {
$outputAs = ConsoleOutput::PLAIN;
} else {
$outputAs = ConsoleOutput::COLOR;
}
$config = Hash::merge(array(
'stream' => 'php://stderr',
'types' => null,
'scopes' => array(),
'outputAs' => ConsoleOutput::COLOR,
'outputAs' => $outputAs,
), $this->_config);
$config = $this->config($config);
if ($config['stream'] instanceof ConsoleOutput) {
Expand Down
10 changes: 10 additions & 0 deletions lib/Cake/Model/Behavior/TranslateBehavior.php
Expand Up @@ -393,6 +393,16 @@ public function afterSave(Model $model, $created) {
$conditions = array('model' => $model->alias, 'foreign_key' => $model->id);
$RuntimeModel = $this->translateModel($model);

$fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']);
if ($created) {
foreach ($fields as $field) {
if (!isset($tempData[$field])) {
//set the field value to an empty string
$tempData[$field] = '';
}
}
}

foreach ($tempData as $field => $value) {
unset($conditions['content']);
$conditions['field'] = $field;
Expand Down
11 changes: 6 additions & 5 deletions lib/Cake/Model/Behavior/TreeBehavior.php
Expand Up @@ -124,11 +124,13 @@ public function beforeFind(Model $Model, $query) {
*/
public function beforeDelete(Model $Model, $cascade = true) {
extract($this->settings[$Model->alias]);
$data = current($Model->find('first', array(
$data = $Model->find('first', array(
'conditions' => array($Model->alias . '.' . $Model->primaryKey => $Model->id),
'fields' => array($Model->alias . '.' . $left, $Model->alias . '.' . $right),
'recursive' => -1)));
$this->_deletedRow = $data;
'recursive' => -1));
if ($data) {
$this->_deletedRow = current($data);
}
return true;
}

Expand Down Expand Up @@ -369,8 +371,7 @@ public function generateTreeList(Model $Model, $conditions = null, $keyPath = nu
$valuePath = array('%s%s', '{n}.tree_prefix', $valuePath);

} else {
$valuePath[0] = '{' . (count($valuePath) - 1) . '}' . $valuePath[0];
$valuePath[] = '{n}.tree_prefix';
array_unshift($valuePath, '%s' . $valuePath[0], '{n}.tree_prefix');
}
$order = $Model->alias . '.' . $left . ' asc';
$results = $Model->find('all', compact('conditions', 'fields', 'order', 'recursive'));
Expand Down
1 change: 1 addition & 0 deletions lib/Cake/Model/BehaviorCollection.php
Expand Up @@ -285,6 +285,7 @@ public function implementedEvents() {
'Model.beforeFind' => 'trigger',
'Model.afterFind' => 'trigger',
'Model.beforeValidate' => 'trigger',
'Model.afterValidate' => 'trigger',
'Model.beforeSave' => 'trigger',
'Model.afterSave' => 'trigger',
'Model.beforeDelete' => 'trigger',
Expand Down
11 changes: 11 additions & 0 deletions lib/Cake/Model/ModelBehavior.php
Expand Up @@ -146,6 +146,17 @@ public function beforeValidate(Model $model) {
return true;
}

/**
* afterValidate is called just after model data was validated, you can use this callback
* to perform any data cleanup or preparation if needed
*
* @param Model $model Model using this behavior
* @return mixed False will stop this event from being passed to other behaviors
*/
public function afterValidate(Model $model) {
return true;
}

/**
* beforeSave is called before a model is saved. Returning false from a beforeSave callback
* will abort the save operation.
Expand Down
6 changes: 3 additions & 3 deletions lib/Cake/Network/CakeRequest.php
Expand Up @@ -175,16 +175,16 @@ protected function _processPost() {
if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
$this->data['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
}
if (isset($this->data['_method'])) {
$isArray = is_array($this->data);
if ($isArray && isset($this->data['_method'])) {
if (!empty($_SERVER)) {
$_SERVER['REQUEST_METHOD'] = $this->data['_method'];
} else {
$_ENV['REQUEST_METHOD'] = $this->data['_method'];
}
unset($this->data['_method']);
}

if (isset($this->data['data'])) {
if ($isArray && isset($this->data['data'])) {
$data = $this->data['data'];
if (count($this->data) <= 1) {
$this->data = $data;
Expand Down
4 changes: 2 additions & 2 deletions lib/Cake/Routing/Dispatcher.php
Expand Up @@ -43,7 +43,7 @@ class Dispatcher implements CakeEventListener {
/**
* Event manager, used to handle dispatcher filters
*
* @var CakeEventMaanger
* @var CakeEventManager
*/
protected $_eventManager;

Expand All @@ -62,7 +62,7 @@ public function __construct($base = false) {
* Returns the CakeEventManager instance or creates one if none was
* creted. Attaches the default listeners and filters
*
* @return CakeEventmanger
* @return CakeEventManager
*/
public function getEventManager() {
if (!$this->_eventManager) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Cake/Routing/Route/CakeRoute.php
Expand Up @@ -497,9 +497,9 @@ protected function _writeUrl($params) {
$named = array();
foreach ($params['named'] as $key => $value) {
if (is_array($value)) {
$flat = Hash::flatten($value, '][');
$flat = Hash::flatten($value, '%5D%5B');
foreach ($flat as $namedKey => $namedValue) {
$named[] = $key . "[$namedKey]" . $separator . rawurlencode($namedValue);
$named[] = $key . "%5B{$namedKey}%5D" . $separator . rawurlencode($namedValue);
}
} else {
$named[] = $key . $separator . rawurlencode($value);
Expand Down
34 changes: 33 additions & 1 deletion lib/Cake/Test/Case/Console/ShellTest.php
Expand Up @@ -80,6 +80,10 @@ public function mergeVars($properties, $class, $normalize = true) {
return $this->_mergeVars($properties, $class, $normalize);
}

public function useLogger($enable = true) {
$this->_useLogger($enable);
}

}

/**
Expand Down Expand Up @@ -825,7 +829,7 @@ public function testFileAndConsoleLogging() {
require_once CORE_TEST_CASES . DS . 'Log' . DS . 'Engine' . DS . 'ConsoleLogTest.php';
$mock = $this->getMock('ConsoleLog', array('write'), array(
array('types' => 'error'),
));
));
TestCakeLog::config('console', array(
'engine' => 'ConsoleLog',
'stream' => 'php://stderr',
Expand All @@ -840,4 +844,32 @@ public function testFileAndConsoleLogging() {
$this->assertContains($this->Shell->testMessage, $contents);
}

/**
* Tests that _useLogger works properly
*
* @return void
**/
public function testProtectedUseLogger() {
CakeLog::drop('stdout');
CakeLog::drop('stderr');
$this->Shell->useLogger(true);
$this->assertNotEmpty(CakeLog::stream('stdout'));
$this->assertNotEmpty(CakeLog::stream('stderr'));
$this->Shell->useLogger(false);
$this->assertFalse(CakeLog::stream('stdout'));
$this->assertFalse(CakeLog::stream('stderr'));
}

/**
* Test file and console and logging quiet output
*/
public function testQuietLog() {
$output = $this->getMock('ConsoleOutput', array(), array(), '', false);
$error = $this->getMock('ConsoleOutput', array(), array(), '', false);
$in = $this->getMock('ConsoleInput', array(), array(), '', false);
$this->Shell = $this->getMock('ShellTestShell', array('_useLogger'), array($output, $error, $in));
$this->Shell->expects($this->once())->method('_useLogger')->with(false);
$this->Shell->runCommand('foo', array('--quiet'));
}

}
33 changes: 33 additions & 0 deletions lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php
Expand Up @@ -107,6 +107,20 @@ public function header($status) {

}

class BrokenCallbackController extends Controller {

public $name = 'UncallableCallback';

public $components = array('Session', 'TestSecurity');

public function index() {
}

protected function _fail() {
}

}

/**
* SecurityComponentTest class
*
Expand Down Expand Up @@ -161,6 +175,25 @@ public function tearDown() {
unset($this->Controller);
}

/**
* Test that requests are still blackholed when controller has incorrect
* visibility keyword in the blackhole callback
*
* @expectedException BadRequestException
*/
public function testBlackholeWithBrokenCallback() {
$request = new CakeRequest('posts/index', false);
$request->addParams(array(
'controller' => 'posts', 'action' => 'index')
);
$this->Controller = new BrokenCallbackController($request);
$this->Controller->Components->init($this->Controller);
$this->Controller->Security = $this->Controller->TestSecurity;
$this->Controller->Security->blackHoleCallback = '_fail';
$this->Controller->Security->startup($this->Controller);
$this->Controller->Security->blackHole($this->Controller, 'csrf');
}

/**
* test that initialize can set properties.
*
Expand Down
17 changes: 17 additions & 0 deletions lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php
Expand Up @@ -116,4 +116,21 @@ public function testCombinedLogWriting() {
$this->assertContains($message, $logOutput);
}

/**
* test default value of stream 'outputAs'
*/
public function testDefaultOutputAs() {
TestCakeLog::config('test_console_log', array(
'engine' => 'TestConsoleLog',
));
if (DS == '\\' && !(bool)env('ANSICON')) {
$expected = ConsoleOutput::PLAIN;
} else {
$expected = ConsoleOutput::COLOR;
}
$stream = TestCakeLog::stream('test_console_log');
$config = $stream->config();
$this->assertEquals($expected, $config['outputAs']);
}

}
28 changes: 28 additions & 0 deletions lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php
Expand Up @@ -531,6 +531,34 @@ public function testSaveCreate() {
$this->assertEquals($expected, $result);
}

/**
* Test that saving only some of the translated fields allows the record to be found again.
*
* @return void
*/
public function testSavePartialFields() {
$this->loadFixtures('Translate', 'TranslatedItem');

$TestModel = new TranslatedItem();
$TestModel->locale = 'spa';
$data = array(
'slug' => 'fourth_translated',
'title' => 'Leyenda #4',
);
$TestModel->create($data);
$TestModel->save();
$result = $TestModel->read();
$expected = array(
'TranslatedItem' => array(
'id' => $TestModel->id,
'translated_article_id' => null,
'locale' => 'spa',
'content' => '',
) + $data
);
$this->assertEquals($expected, $result);
}

/**
* testSaveUpdate method
*
Expand Down

0 comments on commit 3c6b509

Please sign in to comment.