Browse Source

Merge branch 'master' into 3.next

Mark Story 8 years ago
parent
commit
45c1015e9c

+ 2 - 0
.mailmap

@@ -111,3 +111,5 @@ antograssiot <antograssiot@free.fr>
 antograssiot <antograssiot@free.fr> <agrassiot@tld-europe.com>
 antograssiot <antograssiot@free.fr> <agrassiot@tld-europe.com>
 Patrick Conroy <patrick.conroy@rockstargames.com>
 Patrick Conroy <patrick.conroy@rockstargames.com>
 Patrick Conroy <patrick.conroy@rockstargames.com> <patrick@rockstargames.com>
 Patrick Conroy <patrick.conroy@rockstargames.com> <patrick@rockstargames.com>
+saeideng <saeideng@yahoo.com>
+saeideng <saeideng@yahoo.com> <saeideng@users.noreply.github.com>

+ 1 - 1
composer.json

@@ -31,7 +31,7 @@
         "php": ">=5.6.0",
         "php": ">=5.6.0",
         "ext-intl": "*",
         "ext-intl": "*",
         "ext-mbstring": "*",
         "ext-mbstring": "*",
-        "cakephp/chronos": "^1.0.0",
+        "cakephp/chronos": "^1.0.1",
         "aura/intl": "^3.0.0",
         "aura/intl": "^3.0.0",
         "psr/log": "^1.0.0",
         "psr/log": "^1.0.0",
         "zendframework/zend-diactoros": "^1.4.0"
         "zendframework/zend-diactoros": "^1.4.0"

+ 1 - 1
src/Cache/Engine/MemcachedEngine.php

@@ -500,7 +500,7 @@ class MemcachedEngine extends CacheEngine
             }
             }
         }
         }
 
 
-        $groups = $this->_Memcached->getMulti($this->_compiledGroupNames);
+        $groups = $this->_Memcached->getMulti($this->_compiledGroupNames) ?: [];
         if (count($groups) !== count($this->_config['groups'])) {
         if (count($groups) !== count($this->_config['groups'])) {
             foreach ($this->_compiledGroupNames as $group) {
             foreach ($this->_compiledGroupNames as $group) {
                 if (!isset($groups[$group])) {
                 if (!isset($groups[$group])) {

+ 5 - 4
src/Controller/Component/RequestHandlerComponent.php

@@ -233,12 +233,13 @@ class RequestHandlerComponent extends Component
     public function convertXml($xml)
     public function convertXml($xml)
     {
     {
         try {
         try {
-            $xml = Xml::build($xml, ['readFile' => false]);
-            if (isset($xml->data)) {
-                return Xml::toArray($xml->data);
+            $xml = Xml::build($xml, ['return' => 'domdocument', 'readFile' => false]);
+            // We might not get child nodes if there are nested inline entities.
+            if ($xml->childNodes->length > 0) {
+                return Xml::toArray($xml);
             }
             }
 
 
-            return Xml::toArray($xml);
+            return [];
         } catch (XmlException $e) {
         } catch (XmlException $e) {
             return [];
             return [];
         }
         }

+ 21 - 21
src/Database/Schema/MysqlSchema.php

@@ -130,7 +130,7 @@ class MysqlSchema extends BaseSchema
         }
         }
         if (strpos($col, 'text') !== false) {
         if (strpos($col, 'text') !== false) {
             $lengthName = substr($col, 0, -4);
             $lengthName = substr($col, 0, -4);
-            $length = isset(Table::$columnLengths[$lengthName]) ? Table::$columnLengths[$lengthName] : null;
+            $length = isset(TableSchema::$columnLengths[$lengthName]) ? TableSchema::$columnLengths[$lengthName] : null;
 
 
             return ['type' => TableSchema::TYPE_TEXT, 'length' => $length];
             return ['type' => TableSchema::TYPE_TEXT, 'length' => $length];
         }
         }
@@ -139,7 +139,7 @@ class MysqlSchema extends BaseSchema
         }
         }
         if (strpos($col, 'blob') !== false || $col === 'binary') {
         if (strpos($col, 'blob') !== false || $col === 'binary') {
             $lengthName = substr($col, 0, -4);
             $lengthName = substr($col, 0, -4);
-            $length = isset(Table::$columnLengths[$lengthName]) ? Table::$columnLengths[$lengthName] : null;
+            $length = isset(TableSchema::$columnLengths[$lengthName]) ? TableSchema::$columnLengths[$lengthName] : null;
 
 
             return ['type' => TableSchema::TYPE_BINARY, 'length' => $length];
             return ['type' => TableSchema::TYPE_BINARY, 'length' => $length];
         }
         }
@@ -195,25 +195,25 @@ class MysqlSchema extends BaseSchema
 
 
         $name = $row['Key_name'];
         $name = $row['Key_name'];
         if ($name === 'PRIMARY') {
         if ($name === 'PRIMARY') {
-            $name = $type = Table::CONSTRAINT_PRIMARY;
+            $name = $type = TableSchema::CONSTRAINT_PRIMARY;
         }
         }
 
 
         $columns[] = $row['Column_name'];
         $columns[] = $row['Column_name'];
 
 
         if ($row['Index_type'] === 'FULLTEXT') {
         if ($row['Index_type'] === 'FULLTEXT') {
-            $type = Table::INDEX_FULLTEXT;
+            $type = TableSchema::INDEX_FULLTEXT;
         } elseif ($row['Non_unique'] == 0 && $type !== 'primary') {
         } elseif ($row['Non_unique'] == 0 && $type !== 'primary') {
-            $type = Table::CONSTRAINT_UNIQUE;
+            $type = TableSchema::CONSTRAINT_UNIQUE;
         } elseif ($type !== 'primary') {
         } elseif ($type !== 'primary') {
-            $type = Table::INDEX_INDEX;
+            $type = TableSchema::INDEX_INDEX;
         }
         }
 
 
         if (!empty($row['Sub_part'])) {
         if (!empty($row['Sub_part'])) {
             $length[$row['Column_name']] = $row['Sub_part'];
             $length[$row['Column_name']] = $row['Sub_part'];
         }
         }
         $isIndex = (
         $isIndex = (
-            $type === Table::INDEX_INDEX ||
-            $type === Table::INDEX_FULLTEXT
+            $type === TableSchema::INDEX_INDEX ||
+            $type === TableSchema::INDEX_FULLTEXT
         );
         );
         if ($isIndex) {
         if ($isIndex) {
             $existing = $schema->getIndex($name);
             $existing = $schema->getIndex($name);
@@ -263,7 +263,7 @@ class MysqlSchema extends BaseSchema
     public function convertForeignKeyDescription(TableSchema $schema, $row)
     public function convertForeignKeyDescription(TableSchema $schema, $row)
     {
     {
         $data = [
         $data = [
-            'type' => Table::CONSTRAINT_FOREIGN,
+            'type' => TableSchema::CONSTRAINT_FOREIGN,
             'columns' => [$row['COLUMN_NAME']],
             'columns' => [$row['COLUMN_NAME']],
             'references' => [$row['REFERENCED_TABLE_NAME'], $row['REFERENCED_COLUMN_NAME']],
             'references' => [$row['REFERENCED_TABLE_NAME'], $row['REFERENCED_COLUMN_NAME']],
             'update' => $this->_convertOnClause($row['UPDATE_RULE']),
             'update' => $this->_convertOnClause($row['UPDATE_RULE']),
@@ -345,27 +345,27 @@ class MysqlSchema extends BaseSchema
                     }
                     }
                     break;
                     break;
                 case TableSchema::TYPE_TEXT:
                 case TableSchema::TYPE_TEXT:
-                    $isKnownLength = in_array($data['length'], Table::$columnLengths);
+                    $isKnownLength = in_array($data['length'], TableSchema::$columnLengths);
                     if (empty($data['length']) || !$isKnownLength) {
                     if (empty($data['length']) || !$isKnownLength) {
                         $out .= ' TEXT';
                         $out .= ' TEXT';
                         break;
                         break;
                     }
                     }
 
 
                     if ($isKnownLength) {
                     if ($isKnownLength) {
-                        $length = array_search($data['length'], Table::$columnLengths);
+                        $length = array_search($data['length'], TableSchema::$columnLengths);
                         $out .= ' ' . strtoupper($length) . 'TEXT';
                         $out .= ' ' . strtoupper($length) . 'TEXT';
                     }
                     }
 
 
                     break;
                     break;
                 case TableSchema::TYPE_BINARY:
                 case TableSchema::TYPE_BINARY:
-                    $isKnownLength = in_array($data['length'], Table::$columnLengths);
+                    $isKnownLength = in_array($data['length'], TableSchema::$columnLengths);
                     if (empty($data['length']) || !$isKnownLength) {
                     if (empty($data['length']) || !$isKnownLength) {
                         $out .= ' BLOB';
                         $out .= ' BLOB';
                         break;
                         break;
                     }
                     }
 
 
                     if ($isKnownLength) {
                     if ($isKnownLength) {
-                        $length = array_search($data['length'], Table::$columnLengths);
+                        $length = array_search($data['length'], TableSchema::$columnLengths);
                         $out .= ' ' . strtoupper($length) . 'BLOB';
                         $out .= ' ' . strtoupper($length) . 'BLOB';
                     }
                     }
 
 
@@ -452,7 +452,7 @@ class MysqlSchema extends BaseSchema
     public function constraintSql(TableSchema $schema, $name)
     public function constraintSql(TableSchema $schema, $name)
     {
     {
         $data = $schema->getConstraint($name);
         $data = $schema->getConstraint($name);
-        if ($data['type'] === Table::CONSTRAINT_PRIMARY) {
+        if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) {
             $columns = array_map(
             $columns = array_map(
                 [$this->_driver, 'quoteIdentifier'],
                 [$this->_driver, 'quoteIdentifier'],
                 $data['columns']
                 $data['columns']
@@ -462,10 +462,10 @@ class MysqlSchema extends BaseSchema
         }
         }
 
 
         $out = '';
         $out = '';
-        if ($data['type'] === Table::CONSTRAINT_UNIQUE) {
+        if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) {
             $out = 'UNIQUE KEY ';
             $out = 'UNIQUE KEY ';
         }
         }
-        if ($data['type'] === Table::CONSTRAINT_FOREIGN) {
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
             $out = 'CONSTRAINT ';
             $out = 'CONSTRAINT ';
         }
         }
         $out .= $this->_driver->quoteIdentifier($name);
         $out .= $this->_driver->quoteIdentifier($name);
@@ -483,7 +483,7 @@ class MysqlSchema extends BaseSchema
 
 
         foreach ($schema->constraints() as $name) {
         foreach ($schema->constraints() as $name) {
             $constraint = $schema->getConstraint($name);
             $constraint = $schema->getConstraint($name);
-            if ($constraint['type'] === Table::CONSTRAINT_FOREIGN) {
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name));
                 $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name));
             }
             }
@@ -502,7 +502,7 @@ class MysqlSchema extends BaseSchema
 
 
         foreach ($schema->constraints() as $name) {
         foreach ($schema->constraints() as $name) {
             $constraint = $schema->getConstraint($name);
             $constraint = $schema->getConstraint($name);
-            if ($constraint['type'] === Table::CONSTRAINT_FOREIGN) {
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $constraintName = $this->_driver->quoteIdentifier($name);
                 $constraintName = $this->_driver->quoteIdentifier($name);
                 $sql[] = sprintf($sqlPattern, $tableName, $constraintName);
                 $sql[] = sprintf($sqlPattern, $tableName, $constraintName);
@@ -519,10 +519,10 @@ class MysqlSchema extends BaseSchema
     {
     {
         $data = $schema->getIndex($name);
         $data = $schema->getIndex($name);
         $out = '';
         $out = '';
-        if ($data['type'] === Table::INDEX_INDEX) {
+        if ($data['type'] === TableSchema::INDEX_INDEX) {
             $out = 'KEY ';
             $out = 'KEY ';
         }
         }
-        if ($data['type'] === Table::INDEX_FULLTEXT) {
+        if ($data['type'] === TableSchema::INDEX_FULLTEXT) {
             $out = 'FULLTEXT KEY ';
             $out = 'FULLTEXT KEY ';
         }
         }
         $out .= $this->_driver->quoteIdentifier($name);
         $out .= $this->_driver->quoteIdentifier($name);
@@ -548,7 +548,7 @@ class MysqlSchema extends BaseSchema
                 $columns[$i] .= sprintf('(%d)', $data['length'][$column]);
                 $columns[$i] .= sprintf('(%d)', $data['length'][$column]);
             }
             }
         }
         }
-        if ($data['type'] === Table::CONSTRAINT_FOREIGN) {
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
             return $prefix . sprintf(
             return $prefix . sprintf(
                 ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
                 ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
                 implode(', ', $columns),
                 implode(', ', $columns),

+ 22 - 22
src/Database/Schema/SqlserverSchema.php

@@ -230,16 +230,16 @@ class SqlserverSchema extends BaseSchema
      */
      */
     public function convertIndexDescription(TableSchema $schema, $row)
     public function convertIndexDescription(TableSchema $schema, $row)
     {
     {
-        $type = Table::INDEX_INDEX;
+        $type = TableSchema::INDEX_INDEX;
         $name = $row['index_name'];
         $name = $row['index_name'];
         if ($row['is_primary_key']) {
         if ($row['is_primary_key']) {
-            $name = $type = Table::CONSTRAINT_PRIMARY;
+            $name = $type = TableSchema::CONSTRAINT_PRIMARY;
         }
         }
-        if ($row['is_unique_constraint'] && $type === Table::INDEX_INDEX) {
-            $type = Table::CONSTRAINT_UNIQUE;
+        if ($row['is_unique_constraint'] && $type === TableSchema::INDEX_INDEX) {
+            $type = TableSchema::CONSTRAINT_UNIQUE;
         }
         }
 
 
-        if ($type === Table::INDEX_INDEX) {
+        if ($type === TableSchema::INDEX_INDEX) {
             $existing = $schema->getIndex($name);
             $existing = $schema->getIndex($name);
         } else {
         } else {
             $existing = $schema->getConstraint($name);
             $existing = $schema->getConstraint($name);
@@ -250,7 +250,7 @@ class SqlserverSchema extends BaseSchema
             $columns = array_merge($existing['columns'], $columns);
             $columns = array_merge($existing['columns'], $columns);
         }
         }
 
 
-        if ($type === Table::CONSTRAINT_PRIMARY || $type === Table::CONSTRAINT_UNIQUE) {
+        if ($type === TableSchema::CONSTRAINT_PRIMARY || $type === TableSchema::CONSTRAINT_UNIQUE) {
             $schema->addConstraint($name, [
             $schema->addConstraint($name, [
                 'type' => $type,
                 'type' => $type,
                 'columns' => $columns
                 'columns' => $columns
@@ -292,7 +292,7 @@ class SqlserverSchema extends BaseSchema
     public function convertForeignKeyDescription(TableSchema $schema, $row)
     public function convertForeignKeyDescription(TableSchema $schema, $row)
     {
     {
         $data = [
         $data = [
-            'type' => Table::CONSTRAINT_FOREIGN,
+            'type' => TableSchema::CONSTRAINT_FOREIGN,
             'columns' => [$row['column']],
             'columns' => [$row['column']],
             'references' => [$row['reference_table'], $row['reference_column']],
             'references' => [$row['reference_table'], $row['reference_column']],
             'update' => $this->_convertOnClause($row['update_type']),
             'update' => $this->_convertOnClause($row['update_type']),
@@ -309,7 +309,7 @@ class SqlserverSchema extends BaseSchema
     {
     {
         $parent = parent::_foreignOnClause($on);
         $parent = parent::_foreignOnClause($on);
 
 
-        return $parent === 'RESTRICT' ? parent::_foreignOnClause(Table::ACTION_SET_NULL) : $parent;
+        return $parent === 'RESTRICT' ? parent::_foreignOnClause(TableSchema::ACTION_SET_NULL) : $parent;
     }
     }
 
 
     /**
     /**
@@ -319,16 +319,16 @@ class SqlserverSchema extends BaseSchema
     {
     {
         switch ($clause) {
         switch ($clause) {
             case 'NO_ACTION':
             case 'NO_ACTION':
-                return Table::ACTION_NO_ACTION;
+                return TableSchema::ACTION_NO_ACTION;
             case 'CASCADE':
             case 'CASCADE':
-                return Table::ACTION_CASCADE;
+                return TableSchema::ACTION_CASCADE;
             case 'SET_NULL':
             case 'SET_NULL':
-                return Table::ACTION_SET_NULL;
+                return TableSchema::ACTION_SET_NULL;
             case 'SET_DEFAULT':
             case 'SET_DEFAULT':
-                return Table::ACTION_SET_DEFAULT;
+                return TableSchema::ACTION_SET_DEFAULT;
         }
         }
 
 
-        return Table::ACTION_SET_NULL;
+        return TableSchema::ACTION_SET_NULL;
     }
     }
 
 
     /**
     /**
@@ -366,22 +366,22 @@ class SqlserverSchema extends BaseSchema
             }
             }
         }
         }
 
 
-        if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== Table::LENGTH_TINY) {
+        if ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] !== TableSchema::LENGTH_TINY) {
             $out .= ' NVARCHAR(MAX)';
             $out .= ' NVARCHAR(MAX)';
         }
         }
 
 
         if ($data['type'] === TableSchema::TYPE_BINARY) {
         if ($data['type'] === TableSchema::TYPE_BINARY) {
             $out .= ' VARBINARY';
             $out .= ' VARBINARY';
 
 
-            if ($data['length'] !== Table::LENGTH_TINY) {
+            if ($data['length'] !== TableSchema::LENGTH_TINY) {
                 $out .= '(MAX)';
                 $out .= '(MAX)';
             } else {
             } else {
-                $out .= sprintf('(%s)', Table::LENGTH_TINY);
+                $out .= sprintf('(%s)', TableSchema::LENGTH_TINY);
             }
             }
         }
         }
 
 
         if ($data['type'] === TableSchema::TYPE_STRING ||
         if ($data['type'] === TableSchema::TYPE_STRING ||
-            ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] === Table::LENGTH_TINY)
+            ($data['type'] === TableSchema::TYPE_TEXT && $data['length'] === TableSchema::LENGTH_TINY)
         ) {
         ) {
             $type = ' NVARCHAR';
             $type = ' NVARCHAR';
 
 
@@ -440,7 +440,7 @@ class SqlserverSchema extends BaseSchema
 
 
         foreach ($schema->constraints() as $name) {
         foreach ($schema->constraints() as $name) {
             $constraint = $schema->getConstraint($name);
             $constraint = $schema->getConstraint($name);
-            if ($constraint['type'] === Table::CONSTRAINT_FOREIGN) {
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name));
                 $sql[] = sprintf($sqlPattern, $tableName, $this->constraintSql($schema, $name));
             }
             }
@@ -459,7 +459,7 @@ class SqlserverSchema extends BaseSchema
 
 
         foreach ($schema->constraints() as $name) {
         foreach ($schema->constraints() as $name) {
             $constraint = $schema->getConstraint($name);
             $constraint = $schema->getConstraint($name);
-            if ($constraint['type'] === Table::CONSTRAINT_FOREIGN) {
+            if ($constraint['type'] === TableSchema::CONSTRAINT_FOREIGN) {
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $tableName = $this->_driver->quoteIdentifier($schema->name());
                 $constraintName = $this->_driver->quoteIdentifier($name);
                 $constraintName = $this->_driver->quoteIdentifier($name);
                 $sql[] = sprintf($sqlPattern, $tableName, $constraintName);
                 $sql[] = sprintf($sqlPattern, $tableName, $constraintName);
@@ -495,10 +495,10 @@ class SqlserverSchema extends BaseSchema
     {
     {
         $data = $schema->getConstraint($name);
         $data = $schema->getConstraint($name);
         $out = 'CONSTRAINT ' . $this->_driver->quoteIdentifier($name);
         $out = 'CONSTRAINT ' . $this->_driver->quoteIdentifier($name);
-        if ($data['type'] === Table::CONSTRAINT_PRIMARY) {
+        if ($data['type'] === TableSchema::CONSTRAINT_PRIMARY) {
             $out = 'PRIMARY KEY';
             $out = 'PRIMARY KEY';
         }
         }
-        if ($data['type'] === Table::CONSTRAINT_UNIQUE) {
+        if ($data['type'] === TableSchema::CONSTRAINT_UNIQUE) {
             $out .= ' UNIQUE';
             $out .= ' UNIQUE';
         }
         }
 
 
@@ -518,7 +518,7 @@ class SqlserverSchema extends BaseSchema
             [$this->_driver, 'quoteIdentifier'],
             [$this->_driver, 'quoteIdentifier'],
             $data['columns']
             $data['columns']
         );
         );
-        if ($data['type'] === Table::CONSTRAINT_FOREIGN) {
+        if ($data['type'] === TableSchema::CONSTRAINT_FOREIGN) {
             return $prefix . sprintf(
             return $prefix . sprintf(
                 ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
                 ' FOREIGN KEY (%s) REFERENCES %s (%s) ON UPDATE %s ON DELETE %s',
                 implode(', ', $columns),
                 implode(', ', $columns),

+ 1 - 1
src/Datasource/EntityTrait.php

@@ -825,7 +825,7 @@ trait EntityTrait
     /**
     /**
      * Checks if the entity is dirty or if a single property of it is dirty.
      * Checks if the entity is dirty or if a single property of it is dirty.
      *
      *
-     * @param string $property the field to check the status for
+     * @param string|null $property The field to check the status for. Null for the whole entity.
      * @return bool Whether the property was changed or not
      * @return bool Whether the property was changed or not
      */
      */
     public function isDirty($property = null)
     public function isDirty($property = null)

+ 1 - 1
src/I18n/Parser/PoFileParser.php

@@ -98,7 +98,7 @@ class PoFileParser
             } elseif (substr($line, 0, 9) === 'msgctxt "') {
             } elseif (substr($line, 0, 9) === 'msgctxt "') {
                 $item['context'] = substr($line, 9, -1);
                 $item['context'] = substr($line, 9, -1);
             } elseif ($line[0] === '"') {
             } elseif ($line[0] === '"') {
-                $continues = isset($item['translated']) ? 'translated' : 'ids';
+                $continues = isset($item['context']) ? 'context' : (isset($item['translated']) ? 'translated' : 'ids');
 
 
                 if (is_array($item[$continues])) {
                 if (is_array($item[$continues])) {
                     end($item[$continues]);
                     end($item[$continues]);

+ 2 - 2
src/ORM/Table.php

@@ -2189,9 +2189,9 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
      * any one of the records fails to save due to failed validation or database
      * any one of the records fails to save due to failed validation or database
      * error.
      * error.
      *
      *
-     * @param array|\Cake\ORM\ResultSet $entities Entities to save.
+     * @param \Cake\Datasource\EntityInterface[]|\Cake\ORM\ResultSet $entities Entities to save.
      * @param array|\ArrayAccess $options Options used when calling Table::save() for each entity.
      * @param array|\ArrayAccess $options Options used when calling Table::save() for each entity.
-     * @return bool|array|\Cake\ORM\ResultSet False on failure, entities list on success.
+     * @return bool|\Cake\Datasource\EntityInterface[]|\Cake\ORM\ResultSet False on failure, entities list on success.
      */
      */
     public function saveMany($entities, $options = [])
     public function saveMany($entities, $options = [])
     {
     {

+ 3 - 2
src/Utility/Xml.php

@@ -145,16 +145,17 @@ class Xml
         if ($hasDisable && !$options['loadEntities']) {
         if ($hasDisable && !$options['loadEntities']) {
             libxml_disable_entity_loader(true);
             libxml_disable_entity_loader(true);
         }
         }
-        $flags = LIBXML_NOCDATA;
+        $flags = 0;
         if (!empty($options['parseHuge'])) {
         if (!empty($options['parseHuge'])) {
             $flags |= LIBXML_PARSEHUGE;
             $flags |= LIBXML_PARSEHUGE;
         }
         }
         try {
         try {
             if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
             if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
+                $flags |= LIBXML_NOCDATA;
                 $xml = new SimpleXMLElement($input, $flags);
                 $xml = new SimpleXMLElement($input, $flags);
             } else {
             } else {
                 $xml = new DOMDocument();
                 $xml = new DOMDocument();
-                $xml->loadXML($input);
+                $xml->loadXML($input, $flags);
             }
             }
         } catch (Exception $e) {
         } catch (Exception $e) {
             $xml = null;
             $xml = null;

+ 0 - 1
tests/TestCase/Cache/Engine/RedisEngineTest.php

@@ -33,7 +33,6 @@ class RedisEngineTest extends TestCase
     {
     {
         parent::setUp();
         parent::setUp();
         $this->skipIf(!class_exists('Redis'), 'Redis extension is not installed or configured properly.');
         $this->skipIf(!class_exists('Redis'), 'Redis extension is not installed or configured properly.');
-        $this->skipIf(version_compare(PHP_VERSION, '7.2.0dev', '>='), 'Redis is misbehaving in PHP7.2');
 
 
         // @codingStandardsIgnoreStart
         // @codingStandardsIgnoreStart
         $socket = @fsockopen('127.0.0.1', 6379, $errno, $errstr, 1);
         $socket = @fsockopen('127.0.0.1', 6379, $errno, $errstr, 1);

+ 92 - 0
tests/TestCase/Controller/Component/RequestHandlerComponentTest.php

@@ -611,6 +611,98 @@ class RequestHandlerComponentTest extends TestCase
     }
     }
 
 
     /**
     /**
+     * Test that input xml is parsed
+     *
+     * @return void
+     */
+    public function testStartupConvertXmlDataWrapper()
+    {
+        $xml = <<<XML
+<?xml version="1.0" encoding="utf-8"?>
+<data>
+<article id="1" title="first"></article>
+</data>
+XML;
+        $this->Controller->request = new ServerRequest(['input' => $xml]);
+        $this->Controller->request->env('REQUEST_METHOD', 'POST');
+        $this->Controller->request->env('CONTENT_TYPE', 'application/xml');
+
+        $event = new Event('Controller.startup', $this->Controller);
+        $this->RequestHandler->startup($event);
+        $expected = [
+            'data' => [
+                'article' => [
+                    '@id' => 1,
+                    '@title' => 'first'
+                ]
+            ]
+        ];
+        $this->assertEquals($expected, $this->Controller->request->data);
+    }
+
+    /**
+     * Test that input xml is parsed
+     *
+     * @return void
+     */
+    public function testStartupConvertXmlElements()
+    {
+        $xml = <<<XML
+<?xml version="1.0" encoding="utf-8"?>
+<article>
+    <id>1</id>
+    <title><![CDATA[first]]></title>
+</article>
+XML;
+        $this->Controller->request = new ServerRequest(['input' => $xml]);
+        $this->Controller->request->env('REQUEST_METHOD', 'POST');
+        $this->Controller->request->env('CONTENT_TYPE', 'application/xml');
+
+        $event = new Event('Controller.startup', $this->Controller);
+        $this->RequestHandler->startup($event);
+        $expected = [
+            'article' => [
+                'id' => 1,
+                'title' => 'first'
+            ]
+        ];
+        $this->assertEquals($expected, $this->Controller->request->data);
+    }
+
+    /**
+     * Test that input xml is parsed
+     *
+     * @return void
+     */
+    public function testStartupConvertXmlIgnoreEntities()
+    {
+        $xml = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE item [
+  <!ENTITY item "item">
+  <!ENTITY item1 "&item;&item;&item;&item;&item;&item;">
+  <!ENTITY item2 "&item1;&item1;&item1;&item1;&item1;&item1;&item1;&item1;&item1;">
+  <!ENTITY item3 "&item2;&item2;&item2;&item2;&item2;&item2;&item2;&item2;&item2;">
+  <!ENTITY item4 "&item3;&item3;&item3;&item3;&item3;&item3;&item3;&item3;&item3;">
+  <!ENTITY item5 "&item4;&item4;&item4;&item4;&item4;&item4;&item4;&item4;&item4;">
+  <!ENTITY item6 "&item5;&item5;&item5;&item5;&item5;&item5;&item5;&item5;&item5;">
+  <!ENTITY item7 "&item6;&item6;&item6;&item6;&item6;&item6;&item6;&item6;&item6;">
+  <!ENTITY item8 "&item7;&item7;&item7;&item7;&item7;&item7;&item7;&item7;&item7;">
+]>
+<item>
+  <description>&item8;</description>
+</item>
+XML;
+        $this->Controller->request = new ServerRequest(['input' => $xml]);
+        $this->Controller->request->env('REQUEST_METHOD', 'POST');
+        $this->Controller->request->env('CONTENT_TYPE', 'application/xml');
+
+        $event = new Event('Controller.startup', $this->Controller);
+        $this->RequestHandler->startup($event);
+        $this->assertEquals([], $this->Controller->request->data);
+    }
+
+    /**
      * Test mapping a new type and having startup process it.
      * Test mapping a new type and having startup process it.
      *
      *
      * @group deprecated
      * @group deprecated

+ 2 - 1
tests/test_app/TestApp/Locale/rule_1_po/default.po

@@ -15,7 +15,8 @@ msgstr ""
 msgid "Plural Rule 1"
 msgid "Plural Rule 1"
 msgstr "Plural Rule 1 (translated)"
 msgstr "Plural Rule 1 (translated)"
 
 
-msgctxt "This is the context"
+msgctxt ""
+"This is the context"
 msgid "%d = 1"
 msgid "%d = 1"
 msgstr "First Context trasnlation"
 msgstr "First Context trasnlation"