diff --git a/composer.json b/composer.json index 7f33acac9b9..dd2d9504b52 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "composer/installers": "^2.2", "guzzlehttp/guzzle": "^7.5.0", "guzzlehttp/psr7": "^2.4.0", - "embed/embed": "^4.4.4", + "embed/embed": "^4.4.7", "league/csv": "^9.8.0", "m1/env": "^2.2.0", "monolog/monolog": "^3.2.0", diff --git a/src/Control/HTTPRequest.php b/src/Control/HTTPRequest.php index 2ceb7e23941..db22f8d4165 100644 --- a/src/Control/HTTPRequest.php +++ b/src/Control/HTTPRequest.php @@ -579,7 +579,7 @@ public function match($pattern, $shiftOnSuccess = false) $shiftCount = sizeof($patternParts ?? []); $remaining = count($this->dirParts ?? []) - $i; for ($j = 1; $j <= $remaining; $j++) { - $arguments["$${j}"] = $this->dirParts[$j + $i - 1]; + $arguments['$' . $j] = $this->dirParts[$j + $i - 1]; } $patternParts = array_merge($patternParts, array_keys($arguments ?? [])); break; diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index a31675502c9..65c63dab5e4 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -161,6 +161,8 @@ abstract class SapphireTest extends TestCase implements TestOnly */ protected static $tempDB = null; + protected FixtureFactory|bool $fixtureFactory; + /** * @return TempDatabase */ diff --git a/src/ORM/Connect/MySQLDatabase.php b/src/ORM/Connect/MySQLDatabase.php index ef7cd1601a5..b80e02054b3 100644 --- a/src/ORM/Connect/MySQLDatabase.php +++ b/src/ORM/Connect/MySQLDatabase.php @@ -65,6 +65,8 @@ class MySQLDatabase extends Database implements TransactionManager */ private $transactionManager = null; + private int $transactionNesting = 0; + /** * Default collation * diff --git a/src/ORM/Connect/MySQLStatement.php b/src/ORM/Connect/MySQLStatement.php index da687898885..81edf8c50fe 100644 --- a/src/ORM/Connect/MySQLStatement.php +++ b/src/ORM/Connect/MySQLStatement.php @@ -73,7 +73,6 @@ public function __construct($statement, $metadata) public function __destruct() { $this->statement->close(); - $this->currentRecord = false; } /** diff --git a/src/View/ViewableData.php b/src/View/ViewableData.php index 2440a5cacf0..28eaa92aeae 100644 --- a/src/View/ViewableData.php +++ b/src/View/ViewableData.php @@ -66,6 +66,8 @@ class ViewableData implements IteratorAggregate */ private static $casting_cache = []; + private array $data = []; + // ----------------------------------------------------------------------------------------------------------------- /** @@ -191,7 +193,7 @@ public function getFailover() */ public function hasField($field) { - return property_exists($this, $field ?? ''); + return isset($this->data[$field]); } /** @@ -202,7 +204,7 @@ public function hasField($field) */ public function getField($field) { - return $this->$field; + return $this->data[$field]; } /** @@ -215,7 +217,7 @@ public function getField($field) public function setField($field, $value) { $this->objCacheClear(); - $this->$field = $value; + $this->data[$field] = $value; return $this; } @@ -509,14 +511,14 @@ public function obj($fieldName, $arguments = [], $cache = false, $cacheName = nu * A simple wrapper around {@link ViewableData::obj()} that automatically caches the result so it can be used again * without re-running the method. * - * @param string $field + * @param string $fieldName * @param array $arguments * @param string $identifier an optional custom cache identifier * @return Object|DBField */ - public function cachedCall($field, $arguments = [], $identifier = null) + public function cachedCall($fieldName, $arguments = [], $identifier = null) { - return $this->obj($field, $arguments, true, $identifier); + return $this->obj($fieldName, $arguments, true, $identifier); } /** diff --git a/src/View/ViewableData_Customised.php b/src/View/ViewableData_Customised.php index 097da478183..a8589bb51a8 100644 --- a/src/View/ViewableData_Customised.php +++ b/src/View/ViewableData_Customised.php @@ -59,19 +59,26 @@ public function hasMethod($method) return $this->customised->hasMethod($method) || $this->original->hasMethod($method); } - public function cachedCall($field, $arguments = null, $identifier = null) + public function cachedCall($fieldName, $arguments = null, $identifier = null) { - if ($this->customised->hasMethod($field) || $this->customised->hasField($field)) { - return $this->customised->cachedCall($field, $arguments, $identifier); + if ($this->customisedHas($fieldName)) { + return $this->customised->cachedCall($fieldName, $arguments, $identifier); } - return $this->original->cachedCall($field, $arguments, $identifier); + return $this->original->cachedCall($fieldName, $arguments, $identifier); } public function obj($fieldName, $arguments = null, $cache = false, $cacheName = null) { - if ($this->customised->hasField($fieldName) || $this->customised->hasMethod($fieldName)) { + if ($this->customisedHas($fieldName)) { return $this->customised->obj($fieldName, $arguments, $cache, $cacheName); } return $this->original->obj($fieldName, $arguments, $cache, $cacheName); } + + private function customisedHas(string $fieldName): bool + { + return property_exists($this->customised, $fieldName) || + $this->customised->hasField($fieldName) || + $this->customised->hasMethod($fieldName); + } } diff --git a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php index 357c9d7657a..1081f90f399 100644 --- a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php +++ b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php @@ -138,18 +138,17 @@ public function testHandleActionReset() public function testGetSearchForm() { $searchForm = $this->component->getSearchForm($this->gridField); - $this->assertTrue($searchForm instanceof Form); - $this->assertEquals('Search__q', $searchForm->fields[0]->Name); - $this->assertEquals('Search__Name', $searchForm->fields[1]->Name); - $this->assertEquals('Search__City', $searchForm->fields[2]->Name); - $this->assertEquals('Search__Cheerleader__Hat__Colour', $searchForm->fields[3]->Name); + $fields = $searchForm->Fields()->toArray(); + $this->assertEquals('Search__q', $fields[0]->Name); + $this->assertEquals('Search__Name', $fields[1]->Name); + $this->assertEquals('Search__City', $fields[2]->Name); + $this->assertEquals('Search__Cheerleader__Hat__Colour', $fields[3]->Name); $this->assertEquals('TeamsSearchForm', $searchForm->Name); - $this->assertEquals('cms-search-form', $searchForm->extraClasses['cms-search-form']); - - foreach ($searchForm->fields as $field) { - $this->assertEquals('stacked', $field->extraClasses['stacked']); - $this->assertEquals('no-change-track', $field->extraClasses['no-change-track']); + $this->assertTrue($searchForm->hasExtraClass('cms-search-form')); + foreach ($fields as $field) { + $this->assertTrue($field->hasExtraClass('stacked')); + $this->assertTrue($field->hasExtraClass('no-change-track')); } } diff --git a/thirdparty/php-peg/Parser.php b/thirdparty/php-peg/Parser.php index 1ce89193e72..bcb57ce06da 100644 --- a/thirdparty/php-peg/Parser.php +++ b/thirdparty/php-peg/Parser.php @@ -9,6 +9,13 @@ * the bracket if a failed match + restore has moved the current position backwards - so we have to check that too. */ class ParserRegexp { + + public $parser; + public $rx; + public $matches; + public $match_pos; + public $check_pos; + function __construct( $parser, $rx ) { $this->parser = $parser ; $this->rx = $rx . 'Sx' ;