Merge pull request #6771 from kinglozzer/php7-ss3

PHP 7 compatibility
This commit is contained in:
Damian Mooyman 2017-04-05 13:37:13 +12:00 committed by GitHub
commit b1dc2cc9f9
40 changed files with 238 additions and 142 deletions

View File

@ -17,11 +17,15 @@ matrix:
env: DB=SQLITE
- php: 5.6
env: DB=MYSQL PDO=1
- php: 7.0
env: DB=MYSQL
- php: 7.1
env: DB=MYSQL PDO=1
- php: 5.6
env: DB=MYSQL BEHAT_TEST=1
- php: 5.6
- php: 7.0
env: DB=MYSQL CMS_TEST=1
- php: 5.6
- php: 7.0
env: DB=MYSQL BEHAT_TEST=1 CMS_TEST=1
before_script:

View File

@ -20,3 +20,7 @@ Injector:
PDOConnector:
class: 'PDOConnector'
type: prototype
Int:
class: DBInt
Float:
class: DBFloat

View File

@ -16,7 +16,7 @@
}
],
"require": {
"php": ">=5.3.3,<7",
"php": ">= 5.3.3, <7.2",
"composer/installers": "~1.0"
},
"require-dev": {

View File

@ -704,8 +704,8 @@ class Config_LRU {
public function __construct() {
Deprecation::notice('4.0', 'Please use Config_MemCache instead', Deprecation::SCOPE_CLASS);
if (version_compare(PHP_VERSION, '5.3.7', '<')) {
// SplFixedArray causes seg faults before PHP 5.3.7
if (version_compare(PHP_VERSION, '5.3.7', '<') || version_compare(PHP_VERSION, '6.99.99', '>')) {
// SplFixedArray causes seg faults before PHP 5.3.7, and also in 7.0.0-RC1
$this->cache = array();
}
else {

View File

@ -112,6 +112,9 @@ if(file_exists(BASE_PATH . '/vendor/autoload.php')) {
require_once BASE_PATH . '/vendor/autoload.php';
}
// Int/Float autoloader for PHP5.6 backwards-compatability
require_once(BASE_PATH . '/framework/model/fieldtypes/compat/autoload.php');
// Now that the class manifest is up, load the static configuration
$configManifest = new SS_ConfigStaticManifest(BASE_PATH, false, $flush);
Config::inst()->pushConfigStaticManifest($configManifest);

View File

@ -14,12 +14,7 @@
// You may copy this code freely under the conditions of the GPL.
//
// FIXME: possibly remove assert()'s for production version?
// PHP3 does not have assert()
/**
*/
define('USE_ASSERTS', function_exists('assert'));
define('USE_ASSERTS', true);
/**
* @package framework
@ -52,7 +47,7 @@ class _DiffOp {
class _DiffOp_Copy extends _DiffOp {
var $type = 'copy';
public function _DiffOp_Copy ($orig, $final = false) {
public function __construct ($orig, $final = false) {
if (!is_array($final))
$final = $orig;
$this->orig = $orig;
@ -72,7 +67,7 @@ class _DiffOp_Copy extends _DiffOp {
class _DiffOp_Delete extends _DiffOp {
var $type = 'delete';
public function _DiffOp_Delete ($lines) {
public function __construct ($lines) {
$this->orig = $lines;
$this->final = false;
}
@ -90,7 +85,7 @@ class _DiffOp_Delete extends _DiffOp {
class _DiffOp_Add extends _DiffOp {
var $type = 'add';
public function _DiffOp_Add ($lines) {
public function __construct ($lines) {
$this->final = $lines;
$this->orig = false;
}
@ -108,7 +103,7 @@ class _DiffOp_Add extends _DiffOp {
class _DiffOp_Change extends _DiffOp {
var $type = 'change';
public function _DiffOp_Change ($orig, $final) {
public function __construct ($orig, $final) {
$this->orig = $orig;
$this->final = $final;
}
@ -541,7 +536,7 @@ class Diff
* (Typically these are lines from a file.)
* @param $to_lines array An array of strings.
*/
public function Diff($from_lines, $to_lines) {
public function __construct($from_lines, $to_lines) {
$eng = new _DiffEngine;
$this->edits = $eng->diff($from_lines, $to_lines);
//$this->_check($from_lines, $to_lines);
@ -853,13 +848,13 @@ extends Diff
* @param $mapped_to_lines array This array should
* have the same number of elements as $to_lines.
*/
public function MappedDiff($from_lines, $to_lines,
public function __construct($from_lines, $to_lines,
$mapped_from_lines, $mapped_to_lines) {
assert(sizeof($from_lines) == sizeof($mapped_from_lines));
assert(sizeof($to_lines) == sizeof($mapped_to_lines));
$this->Diff($mapped_from_lines, $mapped_to_lines);
parent::__construct($mapped_from_lines, $mapped_to_lines);
$xi = $yi = 0;
// Optimizing loop invariants:

View File

@ -8,7 +8,7 @@ Our web-based [PHP installer](installation/) can check if you meet the requireme
## Web server software requirements
* PHP 5.3.3+, <7
* PHP 5.3.3+, <7.2
* We recommend using a PHP accelerator or opcode cache, such as [xcache](http://xcache.lighttpd.net/) or [WinCache](http://www.iis.net/download/wincacheforphp).
* Allocate at least 48MB of memory to each PHP process. (SilverStripe can be resource hungry for some intensive operations.)
* Required modules: dom, gd2, fileinfo, hash, iconv, mbstring, mysqli (or other database driver), session, simplexml, tokenizer, xml.
@ -34,10 +34,9 @@ Our web-based [PHP installer](installation/) can check if you meet the requireme
* Microsoft Windows XP SP3, Vista, Windows 7, Server 2008, Server 2008 R2
* Mac OS X 10.4+
### Why doesn't SilverStripe 3 work with PHP 7?
Unfortunately, SilverStripe has classes named the same as PHP reserved words, such as "Int" and "Float". This means that
we are unable to make SilverStripe 3 support PHP 7 without breaking backward compatibility. SilverStripe 4 will work
with PHP 7 and will be released in 2016. Until then, we recommend that you use PHP 5.6.
### Does SilverStripe 3 work with PHP 7?
SilverStripe 3.6 or greater will work with PHP 7.0 and 7.1. SilverStripe 3.5 or lower will only work with PHP
5.3 - 5.6.
## Web server hardware requirements

View File

@ -883,19 +883,28 @@ class File extends DataObject {
/**
* Convert a php.ini value (eg: 512M) to bytes
*
* @param string $phpIniValue
* @param string $iniValue
* @return int
*/
public static function ini2bytes($PHPiniValue) {
switch(strtolower(substr(trim($PHPiniValue), -1))) {
public static function ini2bytes($iniValue) {
$iniValues = str_split(trim($iniValue));
$unit = strtolower(array_pop($iniValues));
$quantity = (int) implode($iniValues);
switch ($unit) {
case 'g':
$PHPiniValue *= 1024;
$quantity *= 1024;
// deliberate no break
case 'm':
$PHPiniValue *= 1024;
$quantity *= 1024;
// deliberate no break
case 'k':
$PHPiniValue *= 1024;
$quantity *= 1024;
// deliberate no break
default:
// no-op: pre-existing behaviour
break;
}
return $PHPiniValue;
return $quantity;
}
/**

View File

@ -220,6 +220,8 @@ class GDBackend extends Object implements Image_Backend {
* @todo This method isn't very efficent
*/
public function fittedResize($width, $height) {
$width = intval($width);
$height = intval($height);
$gd = $this->resizeByHeight($height);
if($gd->width > $width) $gd = $gd->resizeByWidth($width);
return $gd;
@ -354,6 +356,11 @@ class GDBackend extends Object implements Image_Backend {
*/
public function crop($top, $left, $width, $height) {
$top = intval($top);
$left = intval($left);
$width = intval($width);
$height = intval($height);
$newGD = imagecreatetruecolor($width, $height);
// Preserve alpha channel between images
@ -390,6 +397,7 @@ class GDBackend extends Object implements Image_Backend {
* Resize an image by width. Preserves aspect ratio.
*/
public function resizeByWidth( $width ) {
$width = intval($width);
$heightScale = $width / $this->width;
return $this->resize( $width, $heightScale * $this->height );
}
@ -398,6 +406,7 @@ class GDBackend extends Object implements Image_Backend {
* Resize an image by height. Preserves aspect ratio
*/
public function resizeByHeight( $height ) {
$height = intval($height);
$scale = $height / $this->height;
return $this->resize( $scale * $this->width, $height );
}
@ -407,6 +416,8 @@ class GDBackend extends Object implements Image_Backend {
* and maxHeight. Passing useAsMinimum will make the smaller dimension equal to the maximum corresponding dimension
*/
public function resizeRatio( $maxWidth, $maxHeight, $useAsMinimum = false ) {
$maxWidth = intval($maxWidth);
$maxHeight = intval($maxHeight);
$widthRatio = $maxWidth / $this->width;
$heightRatio = $maxHeight / $this->height;

View File

@ -148,6 +148,9 @@ class ImagickBackend extends Imagick implements Image_Backend {
public function resizeRatio($maxWidth, $maxHeight, $useAsMinimum = false) {
if(!$this->valid()) return;
$maxWidth = intval($maxWidth);
$maxHeight = intval($maxHeight);
$geometry = $this->getImageGeometry();
$widthRatio = $maxWidth / $geometry["width"];
@ -168,6 +171,8 @@ class ImagickBackend extends Imagick implements Image_Backend {
public function resizeByWidth($width) {
if(!$this->valid()) return;
$width = intval($width);
$geometry = $this->getImageGeometry();
$heightScale = $width / $geometry["width"];
@ -183,6 +188,8 @@ class ImagickBackend extends Imagick implements Image_Backend {
public function resizeByHeight($height) {
if(!$this->valid()) return;
$height = intval($height);
$geometry = $this->getImageGeometry();
$scale = $height / $geometry["height"];
@ -198,6 +205,9 @@ class ImagickBackend extends Imagick implements Image_Backend {
* @return Image_Backend
*/
public function paddedResize($width, $height, $backgroundColor = "FFFFFF", $transparencyPercent = 0) {
$width = intval($width);
$height = intval($height);
//keep the % within bounds of 0-100
$transparencyPercent = min(100, max(0, $transparencyPercent));
$new = $this->resizeRatio($width, $height);
@ -265,7 +275,7 @@ class ImagickBackend extends Imagick implements Image_Backend {
$new->ThumbnailImage($width,$height,true);
return $new;
}
/**
* Crop's part of image.
* @param int $top y position of left upper corner of crop rectangle
@ -275,9 +285,14 @@ class ImagickBackend extends Imagick implements Image_Backend {
* @return Image_Backend
*/
public function crop($top, $left, $width, $height) {
$top = intval($top);
$left = intval($left);
$width = intval($width);
$height = intval($height);
$new = clone $this;
$new->cropImage($width, $height, $left, $top);
return $new;
}

View File

@ -27,6 +27,8 @@
*/
class TabSet extends CompositeField {
protected $tabSet;
/**
* @param string $name Identifier
* @param string $title (Optional) Natural language title of the tabset

View File

@ -578,7 +578,7 @@ abstract class DBSchemaManager {
$spec['parts']['name'] = $field;
$spec_orig['parts']['name'] = $field;
//Convert the $spec array into a database-specific string
$spec = $this->$spec['type']($spec['parts'], true);
$spec = $this->{$spec['type']}($spec['parts'], true);
}
// Collations didn't come in until MySQL 4.1. Anything earlier will throw a syntax error if you try and use
@ -615,7 +615,7 @@ abstract class DBSchemaManager {
// Get the version of the field as we would create it. This is used for comparison purposes to see if the
// existing field is different to what we now want
if (is_array($spec_orig)) {
$spec_orig = $this->$spec_orig['type']($spec_orig['parts']);
$spec_orig = $this->{$spec_orig['type']}($spec_orig['parts']);
}
if ($newTable || $fieldValue == '') {

View File

@ -8,7 +8,7 @@
* @subpackage model
* @see Int
*/
class BigInt extends Int {
class BigInt extends DBInt {
public function requireField() {
$parts = array(

View File

@ -5,7 +5,7 @@
* @package framework
* @subpackage model
*/
class Float extends DBField {
class DBFloat extends DBField {
public function __construct($name = null, $defaultVal = 0) {
$this->defaultVal = is_float($defaultVal) ? $defaultVal : (float) 0;

View File

@ -5,7 +5,7 @@
* @package framework
* @subpackage model
*/
class Int extends DBField {
class DBInt extends DBField {
public function __construct($name = null, $defaultVal = 0) {
$this->defaultVal = is_int($defaultVal) ? $defaultVal : 0;
@ -63,4 +63,3 @@ class Int extends DBField {
}
}

View File

@ -4,7 +4,7 @@
* @package framework
* @subpackage model
*/
class Double extends Float {
class Double extends DBFloat {
public function requireField() {
// HACK: MSSQL does not support double so we're using float instead

View File

@ -12,7 +12,7 @@
* @package framework
* @subpackage model
*/
class ForeignKey extends Int {
class ForeignKey extends DBInt {
/**
* @var DataObject

View File

@ -7,7 +7,7 @@
* @package framework
* @subpackage model
*/
class PrimaryKey extends Int {
class PrimaryKey extends DBInt {
/**
* @var DataObject
*/

View File

@ -0,0 +1,6 @@
<?php
class Float extends DBFloat
{
}

View File

@ -0,0 +1,6 @@
<?php
class Int extends DBInt
{
}

View File

@ -0,0 +1,17 @@
<?php
if (PHP_MAJOR_VERSION < 7) {
spl_autoload_register('php5_compat_autoloader');
}
function php5_compat_autoloader($classname) {
$classMap = array(
"int" => "/framework/model/fieldtypes/compat/Int.php",
"float" => "/framework/model/fieldtypes/compat/Float.php",
);
$classname = strtolower($classname);
if(isset($classMap[$classname])) {
require_once BASE_PATH . $classMap[$classname];
}
}

View File

@ -17,6 +17,10 @@ class RandomGenerator {
* @return string Returns a random series of bytes
*/
public function generateEntropy() {
if (function_exists('random_bytes')) {
return bin2hex(random_bytes(32));
}
$isWin = preg_match('/WIN/', PHP_OS);
// TODO Fails with "Could not gather sufficient random data" on IIS, temporarily disabled on windows

View File

@ -229,6 +229,25 @@ class DBFieldTest extends SapphireTest {
$this->assertEquals('åäö', DBField::create_field('Text', 'ÅÄÖ')->LowerCase());
}
public function testIntFloatPhp5Behaviour() {
if (PHP_MAJOR_VERSION < 7) {
// PHP 5 - Int class exists and is an instance of DBInt
// Can't use the reserved words for these classes or we'll get a compile error on PHP7
$classname = "int";
$obj = new $classname();
$this->assertInstanceOf('DBInt', $obj);
$classname = "float";
$obj = new $classname();
$this->assertInstanceOf('DBFloat', $obj);
} else {
// PHP 7 - classes don't exist
$this->assertFalse(class_exists("Int"));
$this->assertFalse(class_exists("Float"));
}
}
}

View File

@ -180,11 +180,11 @@ class VersionedTest extends SapphireTest {
public function testVersionedFieldsAdded() {
$obj = new VersionedTest_DataObject();
// Check that the Version column is added as a full-fledged column
$this->assertInstanceOf('Int', $obj->dbObject('Version'));
$this->assertInstanceOf('DBInt', $obj->dbObject('Version'));
$obj2 = new VersionedTest_Subclass();
// Check that the Version column is added as a full-fledged column
$this->assertInstanceOf('Int', $obj2->dbObject('Version'));
$this->assertInstanceOf('DBInt', $obj2->dbObject('Version'));
}
public function testVersionedFieldsNotInCMS() {

View File

@ -252,7 +252,7 @@ class ShortcodeParserTest extends SapphireTest {
$this->parser->parse('<script>[2]</script>')
);
$this->parser->register('2', function($attributes, $content, $this, $tag, $extra) {
$this->parser->register('2', function($attributes, $content, $parser, $tag, $extra) {
return 'this is 2';
});

View File

@ -1491,7 +1491,7 @@ EOC;
$parser = new SSTemplateParser();
$parser->addClosedBlock(
'test',
function (&$res) use (&$count) {
function ($res) use (&$count) {
$count++;
}
);
@ -1507,7 +1507,7 @@ EOC;
$parser = new SSTemplateParser();
$parser->addOpenBlock(
'test',
function (&$res) use (&$count) {
function ($res) use (&$count) {
$count++;
}
);

View File

@ -36,7 +36,7 @@ class SimpleCookie {
* @param string $expiry Expiry date as string.
* @param boolean $is_secure Currently ignored.
*/
function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
function __construct($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
$this->_host = false;
$this->_name = $name;
$this->_value = $value;
@ -232,7 +232,7 @@ class SimpleCookieJar {
* Constructor. Jar starts empty.
* @access public
*/
function SimpleCookieJar() {
function __construct() {
$this->_cookies = array();
}

View File

@ -26,7 +26,7 @@ class SimpleEncodedPair {
* @param string $key Form element name.
* @param string $value Data to send.
*/
function SimpleEncodedPair($key, $value) {
function __construct($key, $value) {
$this->_key = $key;
$this->_value = $value;
}
@ -97,7 +97,7 @@ class SimpleAttachment {
* @param string $content Raw data.
* @param hash $filename Original filename.
*/
function SimpleAttachment($key, $content, $filename) {
function __construct($key, $content, $filename) {
$this->_key = $key;
$this->_content = $content;
$this->_filename = $filename;
@ -198,7 +198,7 @@ class SimpleEncoding {
* as lists on a single key.
* @access public
*/
function SimpleEncoding($query = false) {
function __construct($query = false) {
if (! $query) {
$query = array();
}
@ -328,17 +328,6 @@ class SimpleEncoding {
*/
class SimpleGetEncoding extends SimpleEncoding {
/**
* Starts empty.
* @param array $query Hash of parameters.
* Multiple values are
* as lists on a single key.
* @access public
*/
function SimpleGetEncoding($query = false) {
$this->SimpleEncoding($query);
}
/**
* HTTP request method.
* @return string Always GET.
@ -390,8 +379,8 @@ class SimpleHeadEncoding extends SimpleGetEncoding {
* as lists on a single key.
* @access public
*/
function SimpleHeadEncoding($query = false) {
$this->SimpleGetEncoding($query);
function __construct($query = false) {
parent::__construct($query);
}
/**
@ -419,11 +408,11 @@ class SimplePostEncoding extends SimpleEncoding {
* as lists on a single key.
* @access public
*/
function SimplePostEncoding($query = false) {
function __construct($query = false) {
if (is_array($query) and $this->hasMoreThanOneLevel($query)) {
$query = $this->rewriteArrayWithMultipleLevels($query);
}
$this->SimpleEncoding($query);
parent::__construct($query);
}
function hasMoreThanOneLevel($query) {
@ -509,8 +498,8 @@ class SimpleMultipartEncoding extends SimplePostEncoding {
* as lists on a single key.
* @access public
*/
function SimpleMultipartEncoding($query = false, $boundary = false) {
$this->SimplePostEncoding($query);
function __construct($query = false, $boundary = false) {
parent::__construct($query);
$this->_boundary = ($boundary === false ? uniqid('st') : $boundary);
}

View File

@ -36,7 +36,7 @@ class SimpleForm {
* @param SimpleTag $tag Form tag to read.
* @param SimplePage $page Holding page.
*/
function SimpleForm($tag, &$page) {
function __construct($tag, &$page) {
$this->_method = $tag->getAttribute('method');
$this->_action = $this->_createAction($tag->getAttribute('action'), $page);
$this->_encoding = $this->_setEncodingClass($tag);

View File

@ -28,7 +28,7 @@ class SimpleRoute {
* @param SimpleUrl $url URL as object.
* @access public
*/
function SimpleRoute($url) {
function __construct($url) {
$this->_url = $url;
}
@ -125,8 +125,8 @@ class SimpleProxyRoute extends SimpleRoute {
* @param string $password Password for autentication.
* @access public
*/
function SimpleProxyRoute($url, $proxy, $username = false, $password = false) {
$this->SimpleRoute($url);
function __construct($url, $proxy, $username = false, $password = false) {
parent::__construct($url);
$this->_proxy = $proxy;
$this->_username = $username;
$this->_password = $password;
@ -208,7 +208,7 @@ class SimpleHttpRequest {
* request.
* @access public
*/
function SimpleHttpRequest(&$route, $encoding) {
function __construct(&$route, $encoding) {
$this->_route = &$route;
$this->_encoding = $encoding;
$this->_headers = array();
@ -307,7 +307,7 @@ class SimpleHttpHeaders {
* @param string $headers Header block.
* @access public
*/
function SimpleHttpHeaders($headers) {
function __construct($headers) {
$this->_raw_headers = $headers;
$this->_response_code = false;
$this->_http_version = false;
@ -494,8 +494,8 @@ class SimpleHttpResponse extends SimpleStickyError {
* @param mixed $encoding Record of content sent.
* @access public
*/
function SimpleHttpResponse(&$socket, $url, $encoding) {
$this->SimpleStickyError();
function __construct(&$socket, $url, $encoding) {
parent::__construct();
$this->_url = $url;
$this->_encoding = $encoding;
$this->_sent = $socket->getSent();

View File

@ -127,10 +127,9 @@ class SimplePageBuilder extends SimpleSaxListener {
* Sets the builder up empty.
* @access public
*/
function SimplePageBuilder() {
$this->SimpleSaxListener();
function __construct() {
parent::__construct();
}
/**
* Frees up any references so as to allow the PHP garbage
* collection from unset() to work.
@ -358,7 +357,7 @@ class SimplePage {
* @param SimpleHttpResponse $response Result of HTTP fetch.
* @access public
*/
function SimplePage($response = false) {
function __construct($response = false) {
$this->_links = array();
$this->_title = false;
$this->_left_over_labels = array();

View File

@ -37,7 +37,7 @@ class ParallelRegex {
* for insensitive.
* @access public
*/
function ParallelRegex($case) {
function __construct($case) {
$this->_case = $case;
$this->_patterns = array();
$this->_labels = array();
@ -129,7 +129,7 @@ class SimpleStateStack {
* @param string $start Starting state name.
* @access public
*/
function SimpleStateStack($start) {
function __construct($start) {
$this->_stack = array($start);
}
@ -193,7 +193,7 @@ class SimpleLexer {
* @param boolean $case True for case sensitive.
* @access public
*/
function SimpleLexer(&$parser, $start = "accept", $case = false) {
function __construct(&$parser, $start = "accept", $case = false) {
$this->_case = $case;
$this->_regexes = array();
$this->_parser = &$parser;
@ -456,8 +456,8 @@ class SimpleHtmlLexer extends SimpleLexer {
* reference.
* @access public
*/
function SimpleHtmlLexer(&$parser) {
$this->SimpleLexer($parser, 'text');
function __construct(&$parser) {
parent::__construct($parser, 'text');
$this->mapHandler('text', 'acceptTextToken');
$this->_addSkipping();
foreach ($this->_getParsedTags() as $tag) {
@ -552,7 +552,7 @@ class SimpleHtmlSaxParser {
* @param SimpleSaxListener $listener SAX event handler.
* @access public
*/
function SimpleHtmlSaxParser(&$listener) {
function __construct(&$listener) {
$this->_listener = &$listener;
$this->_lexer = &$this->createLexer($this);
$this->_tag = '';
@ -728,7 +728,7 @@ class SimpleSaxListener {
* Sets the document to write to.
* @access public
*/
function SimpleSaxListener() {
function __construct() {
}
/**

View File

@ -26,7 +26,7 @@ class SimpleByName {
* Stashes the name for later comparison.
* @param string $name Name attribute to match.
*/
function SimpleByName($name) {
function __construct($name) {
$this->_name = $name;
}
@ -57,7 +57,7 @@ class SimpleByLabel {
* Stashes the name for later comparison.
* @param string $label Visible text to match.
*/
function SimpleByLabel($label) {
function __construct($label) {
$this->_label = $label;
}
@ -88,7 +88,7 @@ class SimpleById {
* Stashes the name for later comparison.
* @param string $id ID atribute to match.
*/
function SimpleById($id) {
function __construct($id) {
$this->_id = $id;
}
@ -115,7 +115,7 @@ class SimpleByLabelOrName {
* Stashes the name/label for later comparison.
* @param string $label Visible text to match.
*/
function SimpleByLabelOrName($label) {
function __construct($label) {
$this->_label = $label;
}

View File

@ -25,7 +25,7 @@ class SimpleStickyError {
* Sets the error to empty.
* @access public
*/
function SimpleStickyError() {
function __construct() {
$this->_clearError();
}
@ -85,8 +85,8 @@ class SimpleSocket extends SimpleStickyError {
* @param integer $block_size Size of chunk to read.
* @access public
*/
function SimpleSocket($host, $port, $timeout, $block_size = 255) {
$this->SimpleStickyError();
function __construct($host, $port, $timeout, $block_size = 255) {
parent::__construct();
if (! ($this->_handle = $this->_openSocket($host, $port, $error_number, $error, $timeout))) {
$this->_setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds");
return;
@ -196,8 +196,8 @@ class SimpleSecureSocket extends SimpleSocket {
* @param integer $timeout Connection timeout in seconds.
* @access public
*/
function SimpleSecureSocket($host, $port, $timeout) {
$this->SimpleSocket($host, $port, $timeout);
function __construct($host, $port, $timeout) {
parent::__construct($host, $port, $timeout);
}
/**

View File

@ -31,7 +31,7 @@ class SimpleTag {
* the keys must have been
* converted to lower case.
*/
function SimpleTag($name, $attributes) {
function __construct($name, $attributes) {
$this->_name = strtolower(trim($name));
$this->_attributes = $attributes;
$this->_content = '';
@ -162,8 +162,8 @@ class SimpleBaseTag extends SimpleTag {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleBaseTag($attributes) {
$this->SimpleTag('base', $attributes);
function __construct($attributes) {
parent::__construct('base', $attributes);
}
/**
@ -188,8 +188,8 @@ class SimpleTitleTag extends SimpleTag {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleTitleTag($attributes) {
$this->SimpleTag('title', $attributes);
function __construct($attributes) {
parent::__construct('title', $attributes);
}
}
@ -205,8 +205,8 @@ class SimpleAnchorTag extends SimpleTag {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleAnchorTag($attributes) {
$this->SimpleTag('a', $attributes);
function __construct($attributes) {
parent::__construct('a', $attributes);
}
/**
@ -239,8 +239,8 @@ class SimpleWidget extends SimpleTag {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleWidget($name, $attributes) {
$this->SimpleTag($name, $attributes);
function __construct($name, $attributes) {
parent::__construct($name, $attributes);
$this->_value = false;
$this->_label = false;
$this->_is_set = false;
@ -344,8 +344,8 @@ class SimpleTextTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleTextTag($attributes) {
$this->SimpleWidget('input', $attributes);
function __construct($attributes) {
parent::__construct('input', $attributes);
if ($this->getAttribute('value') === false) {
$this->_setAttribute('value', '');
}
@ -387,8 +387,8 @@ class SimpleSubmitTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleSubmitTag($attributes) {
$this->SimpleWidget('input', $attributes);
function __construct($attributes) {
parent::__construct('input', $attributes);
if ($this->getAttribute('value') === false) {
$this->_setAttribute('value', 'Submit');
}
@ -445,10 +445,9 @@ class SimpleImageSubmitTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleImageSubmitTag($attributes) {
$this->SimpleWidget('input', $attributes);
function __construct($attributes) {
parent::__construct('input', $attributes);
}
/**
* Tag contains no end element.
* @return boolean False.
@ -521,8 +520,8 @@ class SimpleButtonTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleButtonTag($attributes) {
$this->SimpleWidget('button', $attributes);
function __construct($attributes) {
parent::__construct('button', $attributes);
}
/**
@ -577,8 +576,8 @@ class SimpleTextAreaTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleTextAreaTag($attributes) {
$this->SimpleWidget('textarea', $attributes);
function __construct($attributes) {
parent::__construct('textarea', $attributes);
}
/**
@ -662,8 +661,8 @@ class SimpleUploadTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleUploadTag($attributes) {
$this->SimpleWidget('input', $attributes);
function __construct($attributes) {
parent::__construct('input', $attributes);
}
/**
@ -705,8 +704,8 @@ class SimpleSelectionTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleSelectionTag($attributes) {
$this->SimpleWidget('select', $attributes);
function __construct($attributes) {
parent::__construct('select', $attributes);
$this->_options = array();
$this->_choice = false;
}
@ -792,8 +791,8 @@ class MultipleSelectionTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function MultipleSelectionTag($attributes) {
$this->SimpleWidget('select', $attributes);
function __construct($attributes) {
parent::__construct('select', $attributes);
$this->_options = array();
$this->_values = false;
}
@ -883,8 +882,8 @@ class SimpleOptionTag extends SimpleWidget {
/**
* Stashes the attributes.
*/
function SimpleOptionTag($attributes) {
$this->SimpleWidget('option', $attributes);
function __construct($attributes) {
parent::__construct('option', $attributes);
}
/**
@ -945,8 +944,8 @@ class SimpleRadioButtonTag extends SimpleWidget {
* Stashes the attributes.
* @param array $attributes Hash of attributes.
*/
function SimpleRadioButtonTag($attributes) {
$this->SimpleWidget('input', $attributes);
function __construct($attributes) {
parent::__construct('input', $attributes);
if ($this->getAttribute('value') === false) {
$this->_setAttribute('value', 'on');
}
@ -1003,8 +1002,8 @@ class SimpleCheckboxTag extends SimpleWidget {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleCheckboxTag($attributes) {
$this->SimpleWidget('input', $attributes);
function __construct($attributes) {
parent::__construct('input', $attributes);
if ($this->getAttribute('value') === false) {
$this->_setAttribute('value', 'on');
}
@ -1359,8 +1358,8 @@ class SimpleLabelTag extends SimpleTag {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleLabelTag($attributes) {
$this->SimpleTag('label', $attributes);
function __construct($attributes) {
parent::__construct('label', $attributes);
}
/**
@ -1385,8 +1384,8 @@ class SimpleFormTag extends SimpleTag {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleFormTag($attributes) {
$this->SimpleTag('form', $attributes);
function __construct($attributes) {
parent::__construct('form', $attributes);
}
}
@ -1402,8 +1401,8 @@ class SimpleFrameTag extends SimpleTag {
* @param hash $attributes Attribute names and
* string values.
*/
function SimpleFrameTag($attributes) {
$this->SimpleTag('frame', $attributes);
function __construct($attributes) {
parent::__construct('frame', $attributes);
}
/**

View File

@ -41,7 +41,7 @@ class SimpleUrl {
* @param string $url Incoming URL.
* @access public
*/
function SimpleUrl($url = '') {
function __construct($url = '') {
list($x, $y) = $this->_chompCoordinates($url);
$this->setCoordinates($x, $y);
$this->_scheme = $this->_chompScheme($url);

View File

@ -769,7 +769,8 @@ class Spyc {
$_arr = array_merge ($_arr, $value);
} else if ($key || $key === '') {
$_arr[$key] = $value;
if (!is_array ($_arr)) { $_arr = array ($key=>$value); }
else { $_arr[$key] = $value; }
} else {
if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }

View File

@ -536,7 +536,7 @@ class SSViewer_DataPresenter extends SSViewer_Scope {
// If not provided, use default
if (!$casting) $casting = Config::inst()->get('ViewableData', 'default_cast', Config::FIRST_SET);
$obj = new $casting($property);
$obj = Injector::inst()->create($casting, false, array($property));
$obj->setValue($res['value']);
$res['obj'] = $obj;

View File

@ -93,7 +93,18 @@ class ViewableData extends Object implements IteratorAggregate {
* @return bool
*/
public function __isset($property) {
return $this->hasField($property) || ($this->failover && $this->failover->hasField($property));
// getField() isn't a field-specific getter and shouldn't be treated as such
if (strtolower($property) !== 'field' && $this->hasMethod($method = "get$property")) {
return true;
} elseif ($this->hasField($property)) {
return true;
} elseif ($this->failover) {
return isset($this->failover->$property);
}
return false;
}
/**
@ -104,13 +115,17 @@ class ViewableData extends Object implements IteratorAggregate {
* @return mixed
*/
public function __get($property) {
if($this->hasMethod($method = "get$property")) {
// getField() isn't a field-specific getter and shouldn't be treated as such
if (strtolower($property) !== 'field' && $this->hasMethod($method = "get$property")) {
return $this->$method();
} elseif($this->hasField($property)) {
} elseif ($this->hasField($property)) {
return $this->getField($property);
} elseif($this->failover) {
} elseif ($this->failover) {
return $this->failover->$property;
}
return null;
}
/**
@ -331,7 +346,7 @@ class ViewableData extends Object implements IteratorAggregate {
public function escapeTypeForField($field) {
$class = $this->castingClass($field) ?: $this->config()->default_cast;
return Config::inst()->get($class, 'escape_type', Config::FIRST_SET);
return Injector::inst()->get($class, true)->config()->escape_type;
}
/**