PasswordItem.php 2.6 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\Core\Field\Plugin\Field\FieldType;

5 6
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
7
use Drupal\Core\StringTranslation\TranslatableMarkup;
8 9
use Drupal\Core\TypedData\DataDefinition;

10 11 12 13 14 15 16 17 18 19
/**
 * Defines the 'password' entity field type.
 *
 * @FieldType(
 *   id = "password",
 *   label = @Translation("Password"),
 *   description = @Translation("An entity field containing a password value."),
 *   no_ui = TRUE,
 * )
 */
20 21 22 23 24 25 26
class PasswordItem extends StringItem {

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['value'] = DataDefinition::create('string')
27
      ->setLabel(new TranslatableMarkup('The hashed password'))
28 29
      ->setSetting('case_sensitive', TRUE);
    $properties['existing'] = DataDefinition::create('string')
30
      ->setLabel(new TranslatableMarkup('Existing password'));
31 32
    $properties['pre_hashed'] = DataDefinition::create('boolean')
      ->setLabel(new TranslatableMarkup('Determines if a password needs hashing'));
33 34 35 36 37 38 39 40 41 42 43 44

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function preSave() {
    parent::preSave();

    $entity = $this->getEntity();

45 46 47 48 49
    if ($this->pre_hashed) {
      // Reset the pre_hashed value since it has now been used.
      $this->pre_hashed = FALSE;
    }
    elseif ($entity->isNew() || (strlen(trim($this->value)) > 0 && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
      // Allow alternate password hashing schemes.
      $this->value = \Drupal::service('password')->hash(trim($this->value));
      // Abort if the hashing failed and returned FALSE.
      if (!$this->value) {
        throw new EntityMalformedException('The entity does not have a password.');
      }
    }

    if (!$entity->isNew()) {
      // If the password is empty, that means it was not changed, so use the
      // original password.
      if (empty($this->value)) {
        $this->value = $entity->original->{$this->getFieldDefinition()->getName()}->value;
      }
    }
65 66 67
    // Ensure that the existing password is unset to minimise risks of it
    // getting serialized and stored somewhere.
    $this->existing = NULL;
68
  }
69 70 71 72 73 74 75 76 77 78 79 80

  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    // We cannot use the parent implementation from StringItem as it does not
    // consider the additional 'existing' property that PasswordItem contains.
    $value = $this->get('value')->getValue();
    $existing = $this->get('existing')->getValue();
    return $value === NULL && $existing === NULL;
  }

81
}