Commit 82d1beea authored by Thomas Seiber's avatar Thomas Seiber
Browse files

Issue #3221345 by drunken monkey, jan kellermann: Fixed handling of invalid...

Issue #3221345 by drunken monkey, jan kellermann: Fixed handling of invalid date values during indexing.
parent ff45e0d5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
Search API 1.x, dev (xxxx-xx-xx):
---------------------------------
- #3221345 by drunken monkey, jan kellermann: Fixed handling of invalid date
  values during indexing.
- #3220283 by james.williams, drunken monkey: Fixed automatic reindexing of
  related entities with undefined languages.
- #3225675 by mdupont, drunken monkey: Fixed score calculation in DB backend
+26 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@ namespace Drupal\search_api\Plugin\search_api\data_type;
use Drupal\Component\Datetime\DateTimePlus;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\search_api\DataType\DataTypePluginBase;
use Drupal\search_api\LoggerTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a date data type.
@@ -18,6 +20,19 @@ use Drupal\search_api\DataType\DataTypePluginBase;
 */
class DateDataType extends DataTypePluginBase {

  use LoggerTrait;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);

    $plugin->setLogger($container->get('logger.channel.search_api'));

    return $plugin;
  }

  /**
   * {@inheritdoc}
   */
@@ -31,6 +46,17 @@ class DateDataType extends DataTypePluginBase {

    $timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);
    $date = new DateTimePlus($value, $timezone);
    // Check for invalid datetime strings.
    if ($date->hasErrors()) {
      foreach ($date->getErrors() as $error) {
        $args = [
          '@value' => $value,
          '@error' => $error,
        ];
        $this->getLogger()->warning('Error while parsing date/time value "@value": @error.', $args);
      }
      return NULL;
    }
    // Add in time component if this is a date-only field.
    if (strpos($value, ':') === FALSE) {
      $date->setDefaultDateTime();
+18 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ namespace Drupal\Tests\search_api\Unit;

use Drupal\search_api\Plugin\search_api\data_type\DateDataType;
use Drupal\Tests\UnitTestCase;
use Psr\Log\LoggerInterface;

/**
 * Tests functionality of the "Date" data type plugin.
@@ -68,4 +69,21 @@ class DateDataTypeTest extends UnitTestCase {
    ];
  }

  /**
   * Tests that an invalid date value is handled correctly.
   */
  public function testInvalidValue(): void {
    $logger = $this->createMock(LoggerInterface::class);
    $logged = [];
    $callback = function (string $message, array $context = []) use (&$logged) {
      $logged[] = strtr($message, $context);
    };
    $logger->method('warning')->willReturnCallback($callback);
    $this->plugin->setLogger($logger);

    $value = $this->plugin->getValue('foobar');
    $this->assertNull($value);
    $this->assertEquals(['Error while parsing date/time value "foobar": The timezone could not be found in the database.'], $logged);
  }

}