Merge pull request #7840 from cakephp/2.8-PHP7

2.8 PHP7 compatibility
This commit is contained in:
Larry E. Masters 2015-12-29 00:27:33 -05:00
commit 0aa8847762
20 changed files with 97 additions and 55 deletions

View file

@ -5,6 +5,7 @@ php:
- 5.4 - 5.4
- 5.5 - 5.5
- 5.6 - 5.6
- 7.0
env: env:
- DB=mysql - DB=mysql

View file

@ -275,10 +275,10 @@ class Cache {
* *
* @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default' * @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default'
* @param int $expires [optional] An expires timestamp. Defaults to NULL * @param int $expires [optional] An expires timestamp. Defaults to NULL
* @return void * @return bool
*/ */
public static function gc($config = 'default', $expires = null) { public static function gc($config = 'default', $expires = null) {
static::$_engines[$config]->gc($expires); return static::$_engines[$config]->gc($expires);
} }
/** /**

View file

@ -109,7 +109,7 @@ class FileEngine extends CacheEngine {
* @return bool True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
public function write($key, $data, $duration) { public function write($key, $data, $duration) {
if ($data === '' || !$this->_init) { if (!$this->_init) {
return false; return false;
} }

View file

@ -49,10 +49,10 @@ class ConsoleErrorHandler {
/** /**
* Handle an exception in the console environment. Prints a message to stderr. * Handle an exception in the console environment. Prints a message to stderr.
* *
* @param Exception $exception The exception to handle * @param Exception|ParserError $exception The exception to handle
* @return void * @return void
*/ */
public function handleException(Exception $exception) { public function handleException($exception) {
$stderr = static::getStderr(); $stderr = static::getStderr();
$stderr->write(__d('cake_console', "<error>Error:</error> %s\n%s", $stderr->write(__d('cake_console', "<error>Error:</error> %s\n%s",
$exception->getMessage(), $exception->getMessage(),

View file

@ -109,11 +109,11 @@ class ErrorHandler {
* This will either use custom exception renderer class if configured, * This will either use custom exception renderer class if configured,
* or use the default ExceptionRenderer. * or use the default ExceptionRenderer.
* *
* @param Exception $exception The exception to render. * @param Exception|ParseError $exception The exception to render.
* @return void * @return void
* @see http://php.net/manual/en/function.set-exception-handler.php * @see http://php.net/manual/en/function.set-exception-handler.php
*/ */
public static function handleException(Exception $exception) { public static function handleException($exception) {
$config = Configure::read('Exception'); $config = Configure::read('Exception');
static::_log($exception, $config); static::_log($exception, $config);
@ -169,11 +169,11 @@ class ErrorHandler {
/** /**
* Handles exception logging * Handles exception logging
* *
* @param Exception $exception The exception to render. * @param Exception|ParseError $exception The exception to render.
* @param array $config An array of configuration for logging. * @param array $config An array of configuration for logging.
* @return bool * @return bool
*/ */
protected static function _log(Exception $exception, $config) { protected static function _log($exception, $config) {
if (empty($config['log'])) { if (empty($config['log'])) {
return false; return false;
} }

View file

@ -86,9 +86,9 @@ class ExceptionRenderer {
* If the error is a CakeException it will be converted to either a 400 or a 500 * If the error is a CakeException it will be converted to either a 400 or a 500
* code error depending on the code used to construct the error. * code error depending on the code used to construct the error.
* *
* @param Exception $exception Exception * @param Exception|ParseError $exception Exception
*/ */
public function __construct(Exception $exception) { public function __construct($exception) {
$this->controller = $this->_getController($exception); $this->controller = $this->_getController($exception);
if (method_exists($this->controller, 'appError')) { if (method_exists($this->controller, 'appError')) {

View file

@ -143,7 +143,7 @@ class CakeSession {
public static function init($base = null) { public static function init($base = null) {
static::$time = time(); static::$time = time();
if (env('HTTP_USER_AGENT')) { if (env('HTTP_USER_AGENT') && !static::$_userAgent) {
static::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt')); static::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
} }
@ -202,7 +202,6 @@ class CakeSession {
$id = static::id(); $id = static::id();
static::_startSession(); static::_startSession();
if (!$id && static::started()) { if (!$id && static::started()) {
static::_checkValid(); static::_checkValid();
} }
@ -218,6 +217,9 @@ class CakeSession {
* @return bool True if session has been started. * @return bool True if session has been started.
*/ */
public static function started() { public static function started() {
if (function_exists('session_status')) {
return isset($_SESSION) && (session_status() === PHP_SESSION_ACTIVE);
}
return isset($_SESSION) && session_id(); return isset($_SESSION) && session_id();
} }
@ -461,7 +463,12 @@ class CakeSession {
} }
if (static::started()) { if (static::started()) {
if (session_id() && static::_hasSession()) {
session_write_close();
session_start();
}
session_destroy(); session_destroy();
unset($_COOKIE[static::_cookieName()]);
} }
$_SESSION = null; $_SESSION = null;
@ -584,7 +591,7 @@ class CakeSession {
* @return bool * @return bool
*/ */
protected static function _hasSession() { protected static function _hasSession() {
return static::started() || isset($_COOKIE[static::_cookieName()]); return static::started() || isset($_COOKIE[session_name()]) || (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg');
} }
/** /**
@ -753,7 +760,11 @@ class CakeSession {
if (isset($_COOKIE[session_name()])) { if (isset($_COOKIE[session_name()])) {
setcookie(Configure::read('Session.cookie'), '', time() - 42000, static::$path); setcookie(Configure::read('Session.cookie'), '', time() - 42000, static::$path);
} }
session_regenerate_id(true); if (!headers_sent()) {
session_write_close();
session_start();
session_regenerate_id(true);
}
} }
/** /**

View file

@ -52,7 +52,12 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return mixed The value of the key or false if it does not exist * @return mixed The value of the key or false if it does not exist
*/ */
public function read($id) { public function read($id) {
return Cache::read($id, Configure::read('Session.handler.config')); $data = Cache::read($id, Configure::read('Session.handler.config'));
if (!is_numeric($data) && empty($data)) {
return '';
}
return $data;
} }
/** /**
@ -63,7 +68,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return bool True for successful write, false otherwise. * @return bool True for successful write, false otherwise.
*/ */
public function write($id, $data) { public function write($id, $data) {
return Cache::write($id, $data, Configure::read('Session.handler.config')); return (bool)Cache::write($id, $data, Configure::read('Session.handler.config'));
} }
/** /**
@ -73,7 +78,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return bool True for successful delete, false otherwise. * @return bool True for successful delete, false otherwise.
*/ */
public function destroy($id) { public function destroy($id) {
return Cache::delete($id, Configure::read('Session.handler.config')); return (bool)Cache::delete($id, Configure::read('Session.handler.config'));
} }
/** /**
@ -83,7 +88,7 @@ class CacheSession implements CakeSessionHandlerInterface {
* @return bool Success * @return bool Success
*/ */
public function gc($expires = null) { public function gc($expires = null) {
return Cache::gc(Configure::read('Session.handler.config'), $expires); return (bool)Cache::gc(Configure::read('Session.handler.config'), $expires);
} }
} }

View file

@ -92,11 +92,15 @@ class DatabaseSession implements CakeSessionHandlerInterface {
'conditions' => array($this->_model->alias . '.' . $this->_model->primaryKey => $id) 'conditions' => array($this->_model->alias . '.' . $this->_model->primaryKey => $id)
)); ));
if (empty($row[$this->_model->alias]['data'])) { if (empty($row[$this->_model->alias])) {
return false; return '';
} }
return $row[$this->_model->alias]['data']; if (!is_numeric($row[$this->_model->alias]['data']) && empty($row[$this->_model->alias]['data'])) {
return '';
}
return (string)$row[$this->_model->alias]['data'];
} }
/** /**
@ -123,9 +127,9 @@ class DatabaseSession implements CakeSessionHandlerInterface {
'counterCache' => false 'counterCache' => false
); );
try { try {
return $this->_model->save($record, $options); return (bool)$this->_model->save($record, $options);
} catch (PDOException $e) { } catch (PDOException $e) {
return $this->_model->save($record, $options); return (bool)$this->_model->save($record, $options);
} }
} }
@ -136,7 +140,7 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return bool True for successful delete, false otherwise. * @return bool True for successful delete, false otherwise.
*/ */
public function destroy($id) { public function destroy($id) {
return $this->_model->delete($id); return (bool)$this->_model->delete($id);
} }
/** /**
@ -151,7 +155,8 @@ class DatabaseSession implements CakeSessionHandlerInterface {
} else { } else {
$expires = time() - $expires; $expires = time() - $expires;
} }
return $this->_model->deleteAll(array($this->_model->alias . ".expires <" => $expires), false, false); $this->_model->deleteAll(array($this->_model->alias . ".expires <" => $expires), false, false);
return true;
} }
} }

View file

@ -48,10 +48,15 @@ class ControllerAuthorizeTest extends CakeTestCase {
* testControllerTypeError * testControllerTypeError
* *
* @expectedException PHPUnit_Framework_Error * @expectedException PHPUnit_Framework_Error
* @throws PHPUnit_Framework_Error
* @return void * @return void
*/ */
public function testControllerTypeError() { public function testControllerTypeError() {
$this->auth->controller(new StdClass()); try {
$this->auth->controller(new StdClass());
} catch (Throwable $t) {
throw new PHPUnit_Framework_Error($t);
}
} }
/** /**

View file

@ -202,7 +202,6 @@ class SessionComponentTest extends CakeTestCase {
$this->assertEquals($Session->read('Test'), $array); $this->assertEquals($Session->read('Test'), $array);
$Session->delete('Test'); $Session->delete('Test');
$this->assertTrue($Session->write(array('Test'), 'some value'));
$this->assertTrue($Session->write(array('Test' => 'some value'))); $this->assertTrue($Session->write(array('Test' => 'some value')));
$this->assertEquals('some value', $Session->read('Test')); $this->assertEquals('some value', $Session->read('Test'));
$Session->delete('Test'); $Session->delete('Test');

View file

@ -450,11 +450,17 @@ class ConfigureTest extends CakeTestCase {
* test reader() throwing exceptions on missing interface. * test reader() throwing exceptions on missing interface.
* *
* @expectedException PHPUnit_Framework_Error * @expectedException PHPUnit_Framework_Error
* @throws PHPUnit_Framework_Error
* @return void * @return void
*/ */
public function testReaderExceptionOnIncorrectClass() { public function testReaderExceptionOnIncorrectClass() {
$reader = new StdClass(); $reader = new StdClass();
Configure::config('test', $reader);
try {
Configure::config('test', $reader);
} catch (Throwable $t) {
throw new PHPUnit_Framework_Error($t);
}
} }
/** /**

View file

@ -2909,10 +2909,15 @@ SQL;
* testDropSchemaNoSchema method * testDropSchemaNoSchema method
* *
* @expectedException PHPUnit_Framework_Error * @expectedException PHPUnit_Framework_Error
* @throws PHPUnit_Framework_Error
* @return void * @return void
*/ */
public function testDropSchemaNoSchema() { public function testDropSchemaNoSchema() {
$this->Dbo->dropSchema(null); try {
$this->Dbo->dropSchema(null);
} catch (Throwable $t) {
throw new PHPUnit_Framework_Error($t);
}
} }
/** /**

View file

@ -104,6 +104,8 @@ class CacheSessionTest extends CakeTestCase {
public function testRead() { public function testRead() {
$this->storage->write('test_one', 'Some other value'); $this->storage->write('test_one', 'Some other value');
$this->assertEquals('Some other value', $this->storage->read('test_one'), 'Incorrect value.'); $this->assertEquals('Some other value', $this->storage->read('test_one'), 'Incorrect value.');
$this->storage->write('test_two', 0);
$this->assertEquals(0, $this->storage->read('test_two'));
} }
/** /**

View file

@ -122,19 +122,8 @@ class DatabaseSessionTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testWrite() { public function testWrite() {
$result = $this->storage->write('foo', 'Some value'); $this->storage->write('foo', 'Some value');
$expected = array( $this->assertEquals($this->storage->read('foo'), 'Some value');
'Session' => array(
'id' => 'foo',
'data' => 'Some value',
)
);
$expires = $result['Session']['expires'];
unset($result['Session']['expires']);
$this->assertEquals($expected, $result);
$expected = time() + (Configure::read('Session.timeout') * 60);
$this->assertWithinMargin($expires, $expected, 1);
} }
/** /**
@ -154,13 +143,10 @@ class DatabaseSessionTest extends CakeTestCase {
*/ */
public function testRead() { public function testRead() {
$this->storage->write('foo', 'Some value'); $this->storage->write('foo', 'Some value');
$this->assertEquals($this->storage->read('foo'), 'Some value');
$result = $this->storage->read('foo'); $this->storage->write('bar', 0);
$expected = 'Some value'; $this->assertEquals(0, $this->storage->read('bar'));
$this->assertEquals($expected, $result); $this->assertSame('', $this->storage->read('made up value'));
$result = $this->storage->read('made up value');
$this->assertFalse($result);
} }
/** /**
@ -172,7 +158,7 @@ class DatabaseSessionTest extends CakeTestCase {
$this->storage->write('foo', 'Some value'); $this->storage->write('foo', 'Some value');
$this->assertTrue($this->storage->destroy('foo'), 'Destroy failed'); $this->assertTrue($this->storage->destroy('foo'), 'Destroy failed');
$this->assertFalse($this->storage->read('foo'), 'Value still present.'); $this->assertSame($this->storage->read('foo'), '');
} }
/** /**
@ -189,7 +175,7 @@ class DatabaseSessionTest extends CakeTestCase {
sleep(1); sleep(1);
$storage->gc(); $storage->gc();
$this->assertFalse($storage->read('foo')); $this->assertSame($storage->read('foo'), '');
} }
/** /**

View file

@ -2224,10 +2224,15 @@ class ModelValidationTest extends BaseModelTest {
* Test that type hint exception is thrown * Test that type hint exception is thrown
* *
* @expectedException PHPUnit_Framework_Error * @expectedException PHPUnit_Framework_Error
* @throws PHPUnit_Framework_Error
* @return void * @return void
*/ */
public function testValidatorTypehintException() { public function testValidatorTypehintException() {
new ModelValidator('asdasds'); try {
new ModelValidator('asdasds');
} catch (Throwable $t) {
throw new PHPUnit_Framework_Error($t);
}
} }
/** /**

View file

@ -362,7 +362,9 @@ class JsonViewTest extends CakeTestCase {
$Controller = new Controller($Request, $Response); $Controller = new Controller($Request, $Response);
// non utf-8 stuff // non utf-8 stuff
$data = array('data' => array('foo' => 'bar' . chr('0x97'))); $bar = 'bar';
$bar .= chr(0x97);
$data = array('data' => array('foo' => $bar));
$Controller->set($data); $Controller->set($data);
$Controller->set('_serialize', 'data'); $Controller->set('_serialize', 'data');

View file

@ -12,18 +12,23 @@ class TestAppLibSession implements CakeSessionHandlerInterface {
} }
public function close() { public function close() {
return true;
} }
public function read($id) { public function read($id) {
return '';
} }
public function write($id, $data) { public function write($id, $data) {
return true;
} }
public function destroy($id) { public function destroy($id) {
return true;
} }
public function gc($expires = null) { public function gc($expires = null) {
return true;
} }
} }

View file

@ -12,18 +12,23 @@ class TestPluginSession implements CakeSessionHandlerInterface {
} }
public function close() { public function close() {
return true;
} }
public function read($id) { public function read($id) {
return '';
} }
public function write($id, $data) { public function write($id, $data) {
return true;
} }
public function destroy($id) { public function destroy($id) {
return true;
} }
public function gc($expires = null) { public function gc($expires = null) {
return true;
} }
} }

View file

@ -187,7 +187,7 @@ class Security {
return ''; return '';
} }
srand(Configure::read('Security.cipherSeed')); srand((int)Configure::read('Security.cipherSeed'));
$out = ''; $out = '';
$keyLength = strlen($key); $keyLength = strlen($key);
for ($i = 0, $textLength = strlen($text); $i < $textLength; $i++) { for ($i = 0, $textLength = strlen($text); $i < $textLength; $i++) {