Unverified Commit ecf04102 authored by Alex Pott's avatar Alex Pott
Browse files

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
Loading
Loading
Loading
Loading
+9 −13
Original line number Diff line number Diff line
@@ -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);
}

/**
+2 −2
Original line number Diff line number Diff line
@@ -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()) {
+37 −1
Original line number Diff line number Diff line
@@ -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;
  }

}
+26 −0
Original line number Diff line number Diff line
<?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));
  }

}
+118 −0
Original line number Diff line number Diff line
@@ -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;
  }

}