Skip to content

Commit

Permalink
Merge branch 'master' into 3.next
Browse files Browse the repository at this point in the history
  • Loading branch information
markstory committed Aug 3, 2017
2 parents f7fc345 + c88cf7d commit 4253fe7
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -75,7 +75,7 @@ script:
- if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION != 7.0 ]]; then vendor/bin/phpunit; fi

- if [[ $PHPCS = 1 ]]; then composer cs-check; fi
- if [[ $PHPSTAN = 1 ]]; then composer require --dev phpstan/phpstan:^0.7 && vendor/bin/phpstan analyse -c phpstan.neon -l 1 src; fi
- if [[ $PHPSTAN = 1 ]]; then composer require --dev phpstan/phpstan:^0.8 && vendor/bin/phpstan analyse -c phpstan.neon -l 1 src; fi

after_success:
- if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.0 ]]; then bash <(curl -s https://codecov.io/bash); fi
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon
Expand Up @@ -15,7 +15,7 @@ parameters:
- '#Access to an undefined property Cake\\[a-zA-Z0-9_\\]+::\$_validViewOptions#'
- '#Access to an undefined property Cake\\Database\\Driver::\$_connection#'
- '#Constant XC_TYPE_VAR not found#'
- '#Call to static method id\(\) on an unknown class PHPUnit_Runner_Version#'
- '#Class PHPUnit_Runner_Version not found and could not be autoloaded#'
earlyTerminatingMethodCalls:
Cake\Shell\Shell:
- abort
Expand Down
2 changes: 1 addition & 1 deletion src/Auth/DefaultPasswordHasher.php
Expand Up @@ -74,6 +74,6 @@ public function check($password, $hashedPassword)
*/
public function needsRehash($password)
{
return password_needs_rehash($password, $this->_config['hashType']);
return password_needs_rehash($password, $this->_config['hashType'], $this->_config['hashOptions']);
}
}
48 changes: 24 additions & 24 deletions src/Console/Shell.php
Expand Up @@ -702,13 +702,8 @@ public function out($message = null, $newlines = 1, $level = Shell::NORMAL)
*/
public function err($message = null, $newlines = 1)
{
if (is_array($message)) {
foreach ($message as $k => $v) {
$message[$k] = '<error>' . $v . '</error>';
}
} else {
$message = '<error>' . $message . '</error>';
}
$messageType = 'error';
$message = $this->wrapMessageWithType($messageType, $message);

return $this->_io->err($message, $newlines);
}
Expand All @@ -724,13 +719,8 @@ public function err($message = null, $newlines = 1)
*/
public function info($message = null, $newlines = 1, $level = Shell::NORMAL)
{
if (is_array($message)) {
foreach ($message as $k => $v) {
$message[$k] = '<info>' . $v . '</info>';
}
} else {
$message = '<info>' . $message . '</info>';
}
$messageType = 'info';
$message = $this->wrapMessageWithType($messageType, $message);

return $this->out($message, $newlines, $level);
}
Expand All @@ -745,13 +735,8 @@ public function info($message = null, $newlines = 1, $level = Shell::NORMAL)
*/
public function warn($message = null, $newlines = 1)
{
if (is_array($message)) {
foreach ($message as $k => $v) {
$message[$k] = '<warning>' . $v . '</warning>';
}
} else {
$message = '<warning>' . $message . '</warning>';
}
$messageType = 'warning';
$message = $this->wrapMessageWithType($messageType, $message);

return $this->_io->err($message, $newlines);
}
Expand All @@ -766,16 +751,31 @@ public function warn($message = null, $newlines = 1)
* @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out
*/
public function success($message = null, $newlines = 1, $level = Shell::NORMAL)
{
$messageType = 'success';
$message = $this->wrapMessageWithType($messageType, $message);

return $this->out($message, $newlines, $level);
}

/**
* Wraps a message with a given message type, e.g. <warning>
*
* @param string $messageType The message type, e.g. "warning".
* @param string|array $message The message to wrap.
* @return array|string The message wrapped with the given message type.
*/
protected function wrapMessageWithType($messageType, $message)
{
if (is_array($message)) {
foreach ($message as $k => $v) {
$message[$k] = '<success>' . $v . '</success>';
$message[$k] = "<$messageType>" . $v . "</$messageType>";
}
} else {
$message = '<success>' . $message . '</success>';
$message = "<$messageType>" . $message . "</$messageType>";
}

return $this->out($message, $newlines, $level);
return $message;
}

/**
Expand Down
28 changes: 27 additions & 1 deletion src/Database/Dialect/SqlserverDialectTrait.php
Expand Up @@ -14,13 +14,15 @@
*/
namespace Cake\Database\Dialect;

use Cake\Database\ExpressionInterface;
use Cake\Database\Expression\FunctionExpression;
use Cake\Database\Expression\OrderByExpression;
use Cake\Database\Expression\UnaryExpression;
use Cake\Database\Query;
use Cake\Database\Schema\SqlserverSchema;
use Cake\Database\SqlDialectTrait;
use Cake\Database\SqlserverCompiler;
use Cake\Database\ValueBinder;
use PDO;

/**
Expand Down Expand Up @@ -102,7 +104,31 @@ public function _version()
protected function _pagingSubquery($original, $limit, $offset)
{
$field = '_cake_paging_._cake_page_rownum_';
$order = $original->clause('order') ?: new OrderByExpression('(SELECT NULL)');

if ($original->clause('order')) {
// SQL server does not support column aliases in OVER clauses. But
// the only practical way to specify the use of calculated columns
// is with their alias. So substitute the select SQL in place of
// any column aliases for those entries in the order clause.
$select = $original->clause('select');
$order = new OrderByExpression();
$original
->clause('order')
->iterateParts(function ($direction, $orderBy) use ($select, $order) {
$key = $orderBy;
if (isset($select[$orderBy]) &&
$select[$orderBy] instanceof ExpressionInterface
) {
$key = $select[$orderBy]->sql(new ValueBinder());
}
$order->add([$key => $direction]);

// Leave original order clause unchanged.
return $orderBy;
});
} else {
$order = new OrderByExpression('(SELECT NULL)');
}

$query = clone $original;
$query->select([
Expand Down
10 changes: 5 additions & 5 deletions src/Http/ServerRequest.php
Expand Up @@ -638,7 +638,7 @@ public function __get($name)
* @param string $name The property being accessed.
* @return bool Existence
* @deprecated 3.4.0 Accessing routing parameters through __isset will removed in 4.0.0.
* Use param() instead.
* Use getParam() instead.
*/
public function __isset($name)
{
Expand Down Expand Up @@ -895,7 +895,7 @@ public static function addDetector($name, $callable)

/**
* Add parameters to the request's parsed parameter set. This will overwrite any existing parameters.
* This modifies the parameters available through `$request->params`.
* This modifies the parameters available through `$request->getParam()`.
*
* @param array $params Array of parameters to merge in
* @return $this The current object, you can chain this method.
Expand Down Expand Up @@ -2214,7 +2214,7 @@ public function offsetGet($name)
* @param string $name Name of the key being written
* @param mixed $value The value being written.
* @return void
* @deprecated 3.4.0 The ArrayAccess methods will be removed in 4.0.0. Use withParam() or param() instead.
* @deprecated 3.4.0 The ArrayAccess methods will be removed in 4.0.0. Use withParam() instead.
*/
public function offsetSet($name, $value)
{
Expand All @@ -2226,7 +2226,7 @@ public function offsetSet($name, $value)
*
* @param string $name thing to check.
* @return bool
* @deprecated 3.4.0 The ArrayAccess methods will be removed in 4.0.0. Use getParam() or param() instead.
* @deprecated 3.4.0 The ArrayAccess methods will be removed in 4.0.0. Use getParam() instead.
*/
public function offsetExists($name)
{
Expand All @@ -2242,7 +2242,7 @@ public function offsetExists($name)
*
* @param string $name Name to unset.
* @return void
* @deprecated 3.4.0 The ArrayAccess methods will be removed in 4.0.0. Use withParam() or param() instead.
* @deprecated 3.4.0 The ArrayAccess methods will be removed in 4.0.0. Use withParam() instead.
*/
public function offsetUnset($name)
{
Expand Down
2 changes: 1 addition & 1 deletion src/I18n/Translator.php
Expand Up @@ -174,7 +174,7 @@ protected function resolveContext($key, $message, array $vars)
// No or missing context, fallback to the key/first message
if ($context === null) {
if (isset($message['_context'][''])) {
return $message['_context'][''];
return $message['_context'][''] === '' ? $key : $message['_context'][''];
}

return current($message['_context']);
Expand Down
5 changes: 3 additions & 2 deletions src/TestSuite/IntegrationTestCase.php
Expand Up @@ -578,11 +578,12 @@ protected function _buildRequest($url, $method, $data)
list ($url, $query) = $this->_url($url);
$tokenUrl = $url;

parse_str($query, $queryData);

if ($query) {
$tokenUrl .= '?' . $query;
$tokenUrl .= '?' . http_build_query($queryData);
}

parse_str($query, $queryData);
$props = [
'url' => $url,
'post' => $this->_addTokens($tokenUrl, $data),
Expand Down
2 changes: 1 addition & 1 deletion src/Validation/Validator.php
Expand Up @@ -1645,7 +1645,7 @@ public function scalar($field, $message = null, $when = null)
* @param string|null $message The error message when the rule fails.
* @param string|callable|null $when Either 'create' or 'update' or a callable that returns
* true when the validation rule should be applied.
* @see \Cake\Validation\Validation::color()
* @see \Cake\Validation\Validation::hexColor()
* @return $this
*/
public function hexColor($field, $message = null, $when = null)
Expand Down
15 changes: 15 additions & 0 deletions tests/TestCase/Auth/DefaultPasswordHasherTest.php
Expand Up @@ -36,4 +36,19 @@ public function testNeedsRehash()
$password = $hasher->hash('foo');
$this->assertFalse($hasher->needsRehash($password));
}

/**
* Tests that when the hash options change, the password needs
* to be rehashed
*
* @return void
*/
public function testNeedsRehashWithDifferentOptions()
{
$defaultHasher = new DefaultPasswordHasher(['hashType' => PASSWORD_BCRYPT, 'hashOptions' => ['cost' => 10]]);
$updatedHasher = new DefaultPasswordHasher(['hashType' => PASSWORD_BCRYPT, 'hashOptions' => ['cost' => 12]]);
$password = $defaultHasher->hash('foo');

$this->assertTrue($updatedHasher->needsRehash($password));
}
}
30 changes: 30 additions & 0 deletions tests/TestCase/Database/QueryTest.php
Expand Up @@ -2247,6 +2247,36 @@ public function testSelectPage()
$this->assertEquals(25, $query->clause('offset'));
}

/**
* Test selecting rows using the page() method and ordering the results
* by a calculated column.
*
* @return void
*/
public function testSelectPageWithOrder()
{
$this->loadFixtures('Comments');
$query = new Query($this->connection);
$result = $query
->select([
'id',
'ids_added' => $query->newExpr()->add('(user_id + article_id)')
])
->from('comments')
->order(['ids_added' => 'asc'])
->limit(2)
->page(3)
->execute();
$this->assertCount(2, $result);
$this->assertEquals(
[
['id' => '6', 'ids_added' => '4'],
['id' => '2', 'ids_added' => '5']
],
$result->fetchAll('assoc')
);
}

/**
* Tests that Query objects can be included inside the select clause
* and be used as a normal field, including binding any passed parameter
Expand Down
12 changes: 12 additions & 0 deletions tests/TestCase/I18n/I18nTest.php
Expand Up @@ -845,4 +845,16 @@ public function testFallbackTranslatorWithFactory()
$this->assertEquals('Le moo', $translator->translate('Cow'));
$this->assertEquals('Le bark', $translator->translate('Dog'));
}

/**
* Tests the __() function on empty translations
*
* @return void
*/
public function testEmptyTranslationString()
{
I18n::defaultFormatter('sprintf');
$result = __('No translation needed');
$this->assertEquals('No translation needed', $result);
}
}
18 changes: 18 additions & 0 deletions tests/TestCase/TestSuite/IntegrationTestCaseTest.php
Expand Up @@ -574,6 +574,24 @@ public function testPostSecuredFormWithQuery()
$this->assertResponseContains('Request was accepted');
}

/**
* Test posting to a secured form action with a query that has a part that
* will be encoded by the security component
*
* @return void
*/
public function testPostSecuredFormWithUnencodedQuery()
{
$this->enableSecurityToken();
$data = [
'title' => 'Some title',
'body' => 'Some text'
];
$this->post('/posts/securePost?foo=/', $data);
$this->assertResponseOk();
$this->assertResponseContains('Request was accepted');
}

/**
* Test posting to a secured form action action.
*
Expand Down
2 changes: 1 addition & 1 deletion tests/test_app/TestApp/Locale/en/default.po
Expand Up @@ -32,7 +32,7 @@ msgstr "This is a multiline translation\n"
"This is the third line.\n"
"This is the forth line. (translated)"

msgid "No Translation needed"
msgid "No translation needed"
msgstr ""

msgid "test"
Expand Down

0 comments on commit 4253fe7

Please sign in to comment.