Profile.php 9.74 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\profile\Entity;

5
use Drupal\Core\Entity\EditorialContentEntityBase;
6
use Drupal\Core\Entity\EntityStorageInterface;
7 8
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
9
use Drupal\Core\StringTranslation\StringTranslationTrait;
10
use Drupal\profile\EntityOwnerTrait;
11 12
use Drupal\profile\Event\ProfileEvents;
use Drupal\profile\Event\ProfileLabelEvent;
13 14 15 16 17 18 19

/**
 * Defines the profile entity class.
 *
 * @ContentEntityType(
 *   id = "profile",
 *   label = @Translation("Profile"),
20 21 22 23 24 25 26 27
 *   label_collection = @Translation("Profiles"),
 *   label_singular = @Translation("profile"),
 *   label_plural = @Translation("profiles"),
 *   label_count = @PluralTranslation(
 *     singular = "@count profile",
 *     plural = "@count profiles",
 *   ),
 *   bundle_label = @Translation("Profile type"),
28
 *   handlers = {
29
 *     "storage" = "Drupal\profile\ProfileStorage",
30
 *     "storage_schema" = "Drupal\profile\ProfileStorageSchema",
31
 *     "view_builder" = "Drupal\profile\ProfileViewBuilder",
32
 *     "views_data" = "Drupal\views\EntityViewsData",
33
 *     "access" = "Drupal\profile\ProfileAccessControlHandler",
34
 *     "permission_provider" = "Drupal\entity\UncacheableEntityPermissionProvider",
35
 *     "query_access" = "Drupal\entity\QueryAccess\UncacheableQueryAccessHandler",
36 37
 *     "list_builder" = "Drupal\profile\ProfileListBuilder",
 *     "form" = {
38 39 40
 *       "default" = "Drupal\profile\Form\ProfileForm",
 *       "add" = "Drupal\profile\Form\ProfileForm",
 *       "edit" = "Drupal\profile\Form\ProfileForm",
41
 *       "delete" = "Drupal\profile\Form\ProfileDeleteForm",
42
 *       "delete-multiple-confirm" = "Drupal\Core\Entity\Form\DeleteMultipleForm",
43
 *     },
44
 *     "route_provider" = {
45
 *       "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
46
 *     },
47 48 49
 *   },
 *   bundle_entity_type = "profile_type",
 *   field_ui_base_route = "entity.profile_type.edit_form",
50 51
 *   admin_permission = "administer profile",
 *   permission_granularity = "bundle",
52 53 54
 *   base_table = "profile",
 *   revision_table = "profile_revision",
 *   fieldable = TRUE,
55
 *   show_revision_ui = TRUE,
56
 *   entity_keys = {
cpj's avatar
cpj committed
57 58
 *     "id" = "profile_id",
 *     "revision" = "revision_id",
59
 *     "bundle" = "type",
60
 *     "published" = "status",
61 62
 *     "owner" = "uid",
 *     "uid" = "uid",
63 64
 *     "uuid" = "uuid"
 *   },
65 66 67 68 69
 *   revision_metadata_keys = {
 *     "revision_user" = "revision_user",
 *     "revision_created" = "revision_created",
 *     "revision_log_message" = "revision_log_message"
 *   },
70 71
 *  links = {
 *    "canonical" = "/profile/{profile}",
72
 *    "edit-form" = "/profile/{profile}/edit",
73
 *    "delete-form" = "/profile/{profile}/delete",
74
 *    "delete-multiple-form" = "/admin/content/profile/delete",
75
 *    "collection" = "/admin/people/profiles",
76
 *    "set-default" = "/profile/{profile}/set-default"
77
 *   },
78
 *   common_reference_target = TRUE,
79 80
 * )
 */
81
class Profile extends EditorialContentEntityBase implements ProfileInterface {
82

83
  use EntityOwnerTrait;
84
  use StringTranslationTrait;
vasike's avatar
vasike committed
85

86 87 88 89 90
  /**
   * {@inheritdoc}
   */
  public function label() {
    $profile_type = ProfileType::load($this->bundle());
91 92
    $label = $this->t('@type #@id', [
      '@type' => $profile_type->getDisplayLabel() ?: $profile_type->label(),
93 94 95 96 97 98 99 100 101
      '@id' => $this->id(),
    ]);
    // Allow the label to be overridden.
    $event = new ProfileLabelEvent($this, $label);
    $event_dispatcher = \Drupal::service('event_dispatcher');
    $event_dispatcher->dispatch(ProfileEvents::PROFILE_LABEL, $event);
    $label = $event->getLabel();

    return $label;
102 103 104 105 106
  }

  /**
   * {@inheritdoc}
   */
107
  public function isActive() {
108
    return $this->isPublished();
109 110 111 112 113
  }

  /**
   * {@inheritdoc}
   */
114
  public function setActive($active) {
115 116 117 118 119 120
    if ((bool) $active) {
      $this->setPublished();
    }
    else {
      $this->setUnpublished();
    }
121 122 123 124 125 126
    return $this;
  }

  /**
   * {@inheritdoc}
   */
127 128
  public function isDefault() {
    return (bool) $this->get('is_default')->value;
129 130 131 132 133
  }

  /**
   * {@inheritdoc}
   */
134 135
  public function setDefault($is_default) {
    $this->set('is_default', (bool) $is_default);
136 137 138
    return $this;
  }

139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
  /**
   * {@inheritdoc}
   */
  public function getData($key, $default = NULL) {
    $data = [];
    if (!$this->get('data')->isEmpty()) {
      $data = $this->get('data')->first()->getValue();
    }
    return isset($data[$key]) ? $data[$key] : $default;
  }

  /**
   * {@inheritdoc}
   */
  public function setData($key, $value) {
    $this->get('data')->__set($key, $value);
    return $this;
  }

158 159 160 161 162 163 164 165 166 167 168 169
  /**
   * {@inheritdoc}
   */
  public function unsetData($key) {
    if (!$this->get('data')->isEmpty()) {
      $data = $this->get('data')->first()->getValue();
      unset($data[$key]);
      $this->set('data', $data);
    }
    return $this;
  }

170 171 172
  /**
   * {@inheritdoc}
   */
173 174
  public function getCreatedTime() {
    return $this->get('created')->value;
175 176 177 178 179
  }

  /**
   * {@inheritdoc}
   */
180 181
  public function setCreatedTime($timestamp) {
    $this->set('created', $timestamp);
182 183 184
    return $this;
  }

185 186 187
  /**
   * {@inheritdoc}
   */
188 189
  public function getRevisionAuthor() {
    return $this->get('revision_uid')->entity;
190 191 192 193 194
  }

  /**
   * {@inheritdoc}
   */
195 196
  public function setRevisionAuthorId($uid) {
    $this->set('revision_uid', $uid);
197 198 199
    return $this;
  }

200 201 202
  /**
   * {@inheritdoc}
   */
203 204 205 206 207 208 209
  public function equalToProfile(ProfileInterface $profile, array $field_names = []) {
    // Compare all configurable fields by default.
    $field_names = $field_names ?: $this->getConfigurableFieldNames($profile);
    foreach ($field_names as $field_name) {
      $profile_field_item_list = $profile->get($field_name);
      if (!$this->hasField($field_name) || !$this->get($field_name)->equals($profile_field_item_list)) {
        return FALSE;
210 211
      }
    }
212 213 214 215 216 217 218 219 220 221

    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function populateFromProfile(ProfileInterface $profile, array $field_names = []) {
    // Transfer all configurable fields by default.
    $field_names = $field_names ?: $this->getConfigurableFieldNames($profile);
222 223 224 225
    $profile_values = $profile->toArray();
    foreach ($field_names as $field_name) {
      if (isset($profile_values[$field_name]) && $this->hasField($field_name)) {
        $this->set($field_name, $profile_values[$field_name]);
226 227
      }
    }
228

229 230 231
    return $this;
  }

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
  /**
   * Gets the names of all configurable fields on the given profile.
   *
   * @param \Drupal\profile\Entity\ProfileInterface $profile
   *   The profile.
   *
   * @return string[]
   *   The field names.
   */
  protected function getConfigurableFieldNames(ProfileInterface $profile) {
    $field_names = [];
    foreach ($profile->getFieldDefinitions() as $field_name => $definition) {
      if (!($definition instanceof BaseFieldDefinition)) {
        $field_names[] = $field_name;
      }
    }
    return $field_names;
  }

251 252 253 254 255 256 257
  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage) {
    /** @var \Drupal\profile\ProfileStorage $storage */
    parent::preSave($storage);

258 259 260 261 262 263 264 265 266
    // Only published profiles can be default.
    if (!$this->isPublished()) {
      $this->setDefault(FALSE);
    }
    // Mark the profile as default if there's no other default.
    if ($this->getOwnerId() && $this->isPublished() && !$this->isDefault()) {
      $profile = $storage->loadByUser($this->getOwner(), $this->bundle());
      if (!$profile || !$profile->isDefault()) {
        $this->setDefault(TRUE);
267
      }
268
    }
269 270 271 272 273
    // If no revision author has been set explicitly, make the profile owner
    // the revision author.
    if (!$this->getRevisionUser()) {
      $this->setRevisionUserId($this->getOwnerId());
    }
274 275
  }

276 277 278 279 280 281 282
  /**
   * {@inheritdoc}
   */
  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
    /** @var \Drupal\profile\ProfileStorage $storage */
    parent::postSave($storage, $update);

283 284 285 286 287
    if ($this->getOwnerId()) {
      $default = $this->isDefault();
      $original_default = $this->original ? $this->original->isDefault() : FALSE;
      if ($default && !$original_default) {
        // The profile was set as default, remove the flag from other profiles.
288 289 290 291 292 293
        $profiles = $storage->loadMultipleByUser($this->getOwner(), $this->bundle());
        foreach ($profiles as $profile) {
          if ($profile->id() != $this->id() && $profile->isDefault()) {
            $profile->setDefault(FALSE);
            $profile->save();
          }
294 295
        }
      }
296
    }
297 298
  }

299 300 301 302 303
  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields = parent::baseFieldDefinitions($entity_type);
304
    $fields += static::ownerBaseFieldDefinitions($entity_type);
305

306 307
    $fields['uid']
      ->setRevisionable(TRUE)
308 309
      ->setLabel(t('Owner'))
      ->setDescription(t('The user that owns this profile.'))
310
      ->setSetting('handler', 'default');
311

312
    $fields['status']
313
      ->setLabel(t('Active'))
314 315
      ->setDescription(t('Whether the profile is active.'))
      ->setTranslatable(FALSE);
316 317 318 319

    $fields['is_default'] = BaseFieldDefinition::create('boolean')
      ->setLabel(t('Default'))
      ->setDescription(t('Whether this is the default profile.'))
320
      ->setDefaultValue(FALSE)
321 322
      ->setRevisionable(TRUE)
      ->setDisplayConfigurable('form', TRUE);
323

324 325 326 327 328
    $fields['data'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Data'))
      ->setDescription(t('A serialized array of additional data.'))
      ->setRevisionable(TRUE);

329 330 331 332 333 334 335 336 337 338 339 340 341
    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Created'))
      ->setDescription(t('The time when the profile was created.'))
      ->setRevisionable(TRUE);

    $fields['changed'] = BaseFieldDefinition::create('changed')
      ->setLabel(t('Changed'))
      ->setDescription(t('The time when the profile was last edited.'))
      ->setRevisionable(TRUE);

    return $fields;
  }

342
}