Commit ecf04102 authored by alexpott's avatar alexpott

Issue #3051981 by andypost, alexpott, amateescu, kim.pepper, Berdir, voleger,...

Issue #3051981 by andypost, alexpott, amateescu, kim.pepper, Berdir, voleger, larowlan, claudiu.cristea, martin107: Deprecate drupal_schema_get_field_value()
parent d9e8e19c
......@@ -5,6 +5,8 @@
* Schema API handling functions.
*/
use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;
/**
* @addtogroup schemaapi
* @{
......@@ -215,21 +217,15 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
*
* @return mixed
* The converted value.
*
* @deprecated in drupal:8.8.0 and will be removed from drupal:9.0.0. Use
* \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::castValue() instead.
*
* @see https://www.drupal.org/node/3051983
*/
function drupal_schema_get_field_value(array $info, $value) {
// Preserve legal NULL values.
if (isset($value) || !empty($info['not null'])) {
if ($info['type'] == 'int' || $info['type'] == 'serial') {
$value = (int) $value;
}
elseif ($info['type'] == 'float') {
$value = (float) $value;
}
elseif (!is_array($value)) {
$value = (string) $value;
}
}
return $value;
@trigger_error('drupal_schema_get_field_value() is deprecated in drupal:8.8.0. It will be removed from drupal:9.0.0. Use \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::castValue($info, $value) instead. See https://www.drupal.org/node/3051983', E_USER_DEPRECATED);
return SqlContentEntityStorageSchema::castValue($info, $value);
}
/**
......
......@@ -1097,7 +1097,7 @@ protected function mapToStorageRecord(ContentEntityInterface $entity, $table_nam
// Do not set serial fields if we do not have a value. This supports all
// SQL database drivers.
// @see https://www.drupal.org/node/2279395
$value = drupal_schema_get_field_value($definition->getSchema()['columns'][$column_name], $value);
$value = SqlContentEntityStorageSchema::castValue($definition->getSchema()['columns'][$column_name], $value);
if (!(empty($value) && $this->isColumnSerial($table_name, $schema_name))) {
$record->$schema_name = $value;
}
......@@ -1398,7 +1398,7 @@ protected function saveToDedicatedTables(ContentEntityInterface $entity, $update
if (!empty($attributes['serialize'])) {
$value = serialize($value);
}
$record[$column_name] = drupal_schema_get_field_value($attributes, $value);
$record[$column_name] = SqlContentEntityStorageSchema::castValue($attributes, $value);
}
$query->values($record);
if ($this->entityType->isRevisionable()) {
......
......@@ -2099,7 +2099,7 @@ protected function getSharedTableFieldSchema(FieldStorageDefinitionInterface $st
// Use the initial value of the field storage, if available.
if ($initial_value && isset($initial_value[$field_column_name])) {
$schema['fields'][$schema_field_name]['initial'] = drupal_schema_get_field_value($column_schema, $initial_value[$field_column_name]);
$schema['fields'][$schema_field_name]['initial'] = SqlContentEntityStorageSchema::castValue($column_schema, $initial_value[$field_column_name]);
}
if (!empty($initial_value_from_field)) {
$schema['fields'][$schema_field_name]['initial_from_field'] = $initial_value_from_field[$field_column_name];
......@@ -2506,4 +2506,40 @@ protected function addUniqueKey($table, $name, array $specifier) {
$schema_handler->addUniqueKey($table, $name, $specifier);
}
/**
* Typecasts values to proper datatypes.
*
* MySQL PDO silently casts, e.g. FALSE and '' to 0, when inserting the value
* into an integer column, but PostgreSQL PDO does not. Use the schema
* information to correctly typecast the value.
*
* @param array $info
* An array describing the schema field info. See hook_schema() and
* https://www.drupal.org/node/146843 for details.
* @param mixed $value
* The value to be converted.
*
* @return mixed
* The converted value.
*
* @internal
*
* @see hook_schema()
* @see https://www.drupal.org/node/146843
*/
public static function castValue(array $info, $value) {
// Preserve legal NULL values.
if (isset($value) || !empty($info['not null'])) {
if ($info['type'] === 'int' || $info['type'] === 'serial') {
return (int) $value;
}
elseif ($info['type'] === 'float') {
return (float) $value;
}
return (string) $value;
}
return $value;
}
}
<?php
namespace Drupal\KernelTests\Core\Database;
use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;
use Drupal\KernelTests\KernelTestBase;
/**
* Deprecation tests cases for the schema API.
*
* @group legacy
*/
class SchemaLegacyTest extends KernelTestBase {
/**
* Tests deprecation of the drupal_schema_get_field_value() function.
*
* @expectedDeprecation drupal_schema_get_field_value() is deprecated in drupal:8.8.0. It will be removed from drupal:9.0.0. Use \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::castValue($info, $value) instead. See https://www.drupal.org/node/3051983
*/
public function testSchemaGetFieldValue() {
$info = ['type' => 'int'];
$value = 1.1;
$this->assertEquals(SqlContentEntityStorageSchema::castValue($info, $value), drupal_schema_get_field_value($info, $value));
}
}
......@@ -8,6 +8,7 @@
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\Sql\DefaultTableMapping;
use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;
use Drupal\Tests\UnitTestCase;
/**
......@@ -1562,4 +1563,121 @@ public function testonEntityTypeUpdateWithNewIndex() {
);
}
/**
* Tests various value casts depending on column schema.
*
* @param mixed $expected
* The expected value.
* @param mixed $value
* The tested value.
* @param array $schema
* The schema for the table column.
*
* @dataProvider providerSchemaCastValue
* @covers ::castValue
*/
public function testCastValue($expected, $value, array $schema) {
$this->assertSame($expected, SqlContentEntityStorageSchema::castValue($schema, $value));
}
/**
* Provides data for testCastValue().
*/
public function providerSchemaCastValue() {
$cases = [];
// Tests NULL values.
$cases[] = [
NULL,
NULL,
[
'not null' => FALSE,
],
];
$cases[] = [
0,
NULL,
[
'not null' => TRUE,
'type' => 'int',
],
];
$cases[] = [
0,
NULL,
[
'not null' => TRUE,
'type' => 'serial',
],
];
$cases[] = [
0.0,
NULL,
[
'not null' => TRUE,
'type' => 'float',
],
];
$cases[] = [
'',
NULL,
[
'not null' => TRUE,
'type' => 'varchar',
],
];
// Tests cast to int and serial.
$cases[] = [
1,
'1.001',
[
'type' => 'int',
],
];
$cases[] = [
2,
2.6,
[
'type' => 'int',
],
];
$cases[] = [
3,
'3.6',
[
'type' => 'serial',
],
];
// Tests float.
$cases[] = [
1.001,
'1.001',
[
'type' => 'float',
],
];
$cases[] = [
2.6,
2.6,
[
'type' => 'float',
],
];
// Tests other column types casts to string.
$cases[] = [
'1',
1,
[
'type' => 'varchar',
],
];
$cases[] = [
'2',
'2',
[
'type' => 'varchar',
],
];
return $cases;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment