/** * {@inheritdoc} */ public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) { /** @var \Drupal\core\Config\Entity\ConfigEntityInterface $cloned_entity */ $id_key = $this->entityTypeManager->getDefinition($this->entityTypeId)->getKey('id'); $label_key = $this->entityTypeManager->getDefinition($this->entityTypeId)->getKey('label'); // Set new entity properties. if (isset($properties['id'])) { if ($id_key) { $cloned_entity->set($id_key, $properties['id']); } unset($properties['id']); } if (isset($properties['label'])) { if ($label_key) { $cloned_entity->set($label_key, $properties['label']); } unset($properties['label']); } foreach ($properties as $key => $property) { $cloned_entity->set($key, $property); } $cloned_entity->save(); return $cloned_entity; }
/** * {@inheritdoc} */ public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) { /** @var \Drupal\core\Entity\ContentEntityInterface $cloned_entity */ if ($label_key = $this->entityTypeManager->getDefinition($this->entityTypeId)->getKey('label')) { $cloned_entity->set($label_key, $entity->label() . ' - Cloned'); } $cloned_entity->save(); return $cloned_entity; }
/** * {@inheritdoc} */ public function set($property_name, $value, $notify = TRUE) { if (!isset($this->entity)) { throw new MissingDataException("Unable to set property {$property_name} as no entity has been provided."); } if (!$this->entity instanceof FieldableEntityInterface) { // @todo: Add support for config entities in // https://www.drupal.org/node/1818574. throw new \InvalidArgumentException("Unable to set unknown property {$property_name}."); } // This will throw an exception for unknown fields. $this->entity->set($property_name, $value, $notify); return $this; }
/** * Send an invalid UUID to trigger the entity validation. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity we want to check that was inserted correctly. * @param string $entity_type * The type of the entity that should be created. * @param array $context * Options normalizers/encoders have access to. */ public function assertCreateEntityInvalidSerialized(EntityInterface $entity, $entity_type, array $context = array()) { // Add a UUID that is too long. $entity->set('uuid', $this->randomMachineName(129)); $invalid_serialized = $this->serializer->serialize($entity, $this->defaultFormat, $context); $response = $this->httpRequest('entity/' . $entity_type, 'POST', $invalid_serialized, $this->defaultMimeType); // Unprocessable Entity as response. $this->assertResponse(422); // Verify that the text of the response is correct. $error = Json::decode($response); $this->assertEqual($error['error'], "Unprocessable Entity: validation failed.\nuuid.0.value: <em class=\"placeholder\">UUID</em>: may not be longer than 128 characters.\n"); }
/** * Responds to entity PATCH requests. * * @param \Drupal\Core\Entity\EntityInterface $original_entity * The original entity object. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity. * * @return \Drupal\rest\ModifiedResourceResponse * The HTTP response object. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function patch(EntityInterface $original_entity, EntityInterface $entity = NULL) { if ($entity == NULL) { throw new BadRequestHttpException('No entity content received.'); } $definition = $this->getPluginDefinition(); if ($entity->getEntityTypeId() != $definition['entity_type']) { throw new BadRequestHttpException('Invalid entity type'); } if (!$original_entity->access('update')) { throw new AccessDeniedHttpException(); } // Overwrite the received properties. $entity_keys = $entity->getEntityType()->getKeys(); foreach ($entity->_restSubmittedFields as $field_name) { $field = $entity->get($field_name); // Entity key fields need special treatment: together they uniquely // identify the entity. Therefore it does not make sense to modify any of // them. However, rather than throwing an error, we just ignore them as // long as their specified values match their current values. if (in_array($field_name, $entity_keys, TRUE)) { // Unchanged values for entity keys don't need access checking. if ($original_entity->get($field_name)->getValue() === $entity->get($field_name)->getValue()) { continue; } elseif (isset($entity_keys['langcode']) && $field_name === $entity_keys['langcode'] && $field->isEmpty()) { continue; } } if (!$original_entity->get($field_name)->access('edit')) { throw new AccessDeniedHttpException("Access denied on updating field '{$field_name}'."); } $original_entity->set($field_name, $field->getValue()); } // Validate the received data before saving. $this->validate($original_entity); try { $original_entity->save(); $this->logger->notice('Updated entity %type with ID %id.', array('%type' => $original_entity->getEntityTypeId(), '%id' => $original_entity->id())); // Return the updated entity in the response body. return new ModifiedResourceResponse($original_entity, 200); } catch (EntityStorageException $e) { throw new HttpException(500, 'Internal Server Error', $e); } }
/** * Updates a (possible nested) entity property with a value. * * @param \Drupal\Core\Entity\EntityInterface $entity * The config entity. * @param array $parents * The array of parents. * @param string|object $value * The value to update to. */ protected function updateEntityProperty(EntityInterface $entity, array $parents, $value) { $top_key = array_shift($parents); $entity_value = $entity->get($top_key); if (is_array($entity_value)) { NestedArray::setValue($entity_value, $parents, $value); } else { $entity_value = $value; } $entity->set($top_key, $entity_value); }
/** * {@inheritdoc} */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { $langcode = $form_state->getValue('predefined_langcode'); if ($langcode == 'custom') { $langcode = $form_state->getValue('langcode'); $label = $form_state->getValue('label'); $direction = $form_state->getValue('direction'); } else { $standard_languages = LanguageManager::getStandardLanguageList(); $label = $standard_languages[$langcode][0]; $direction = isset($standard_languages[$langcode][2]) ? $standard_languages[$langcode][2] : ConfigurableLanguage::DIRECTION_LTR; } $entity->set('id', $langcode); $entity->set('label', $label); $entity->set('direction', $direction); // There is no weight on the edit form. Fetch all configurable languages // ordered by weight and set the new language to be placed after them. $languages = \Drupal::languageManager()->getLanguages(ConfigurableLanguage::STATE_CONFIGURABLE); $last_language = end($languages); $entity->setWeight($last_language->getWeight() + 1); }
/** * Override this function to let it store the config which would otherwise be * removed for some reason. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity the current form should operate upon. * @param array $form * A nested array of form elements comprising the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { $values = $form_state->getValues(); foreach ($values as $key => $value) { $entity->set($key, $value); } }
/** * Responds to entity PATCH requests. * * @param \Drupal\Core\Entity\EntityInterface $original_entity * The original entity object. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity. * * @return \Drupal\rest\ResourceResponse * The HTTP response object. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function patch(EntityInterface $original_entity, EntityInterface $entity = NULL) { if ($entity == NULL) { throw new BadRequestHttpException(t('No entity content received.')); } $definition = $this->getPluginDefinition(); if ($entity->getEntityTypeId() != $definition['entity_type']) { throw new BadRequestHttpException(t('Invalid entity type')); } if (!$original_entity->access('update')) { throw new AccessDeniedHttpException(); } // Overwrite the received properties. foreach ($entity as $field_name => $field) { if (isset($entity->{$field_name})) { // It is not possible to set the language to NULL as it is automatically // re-initialized. As it must not be empty, skip it if it is. // @todo: Use the langcode entity key when available. See // https://drupal.org/node/2143729. if ($field_name == 'langcode' && $field->isEmpty()) { continue; } if ($field->isEmpty() && !$original_entity->get($field_name)->access('delete')) { throw new AccessDeniedHttpException(t('Access denied on deleting field @field.', array('@field' => $field_name))); } $original_entity->set($field_name, $field->getValue()); if (!$original_entity->get($field_name)->access('update')) { throw new AccessDeniedHttpException(t('Access denied on updating field @field.', array('@field' => $field_name))); } } } // Validate the received data before saving. $this->validate($original_entity); try { $original_entity->save(); $this->logger->notice('Updated entity %type with ID %id.', array('%type' => $entity->getEntityTypeId(), '%id' => $entity->id())); // Update responses have an empty body. return new ResourceResponse(NULL, 204); } catch (EntityStorageException $e) { throw new HttpException(500, t('Internal Server Error'), $e); } }
/** * Responds to entity PATCH requests. * * @param \Drupal\Core\Entity\EntityInterface $original_entity * The original entity object. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity. * * @return \Drupal\rest\ResourceResponse * The HTTP response object. * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function patch(EntityInterface $original_entity, EntityInterface $entity = NULL) { if ($entity == NULL) { throw new BadRequestHttpException('No entity content received.'); } $definition = $this->getPluginDefinition(); if ($entity->getEntityTypeId() != $definition['entity_type']) { throw new BadRequestHttpException('Invalid entity type'); } if (!$original_entity->access('update')) { throw new AccessDeniedHttpException(); } // Overwrite the received properties. $langcode_key = $entity->getEntityType()->getKey('langcode'); foreach ($entity->_restSubmittedFields as $field_name) { $field = $entity->get($field_name); // It is not possible to set the language to NULL as it is automatically // re-initialized. As it must not be empty, skip it if it is. if ($field_name == $langcode_key && $field->isEmpty()) { continue; } if (!$original_entity->get($field_name)->access('edit')) { throw new AccessDeniedHttpException(SafeMarkup::format('Access denied on updating field @field.', array('@field' => $field_name))); } $original_entity->set($field_name, $field->getValue()); } // Validate the received data before saving. $this->validate($original_entity); try { $original_entity->save(); $this->logger->notice('Updated entity %type with ID %id.', array('%type' => $entity->getEntityTypeId(), '%id' => $entity->id())); // Update responses have an empty body. return new ResourceResponse(NULL, 204); } catch (EntityStorageException $e) { throw new HttpException(500, 'Internal Server Error', $e); } }
/** * Sets the target graph to the entity's graph field. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to determine the save graph for. * @param string $graph * The graph id. */ public function setTargetGraphToEntity(EntityInterface $entity, $graph) { $entity->set('graph', $graph); }
/** * {@inheritdoc} */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { $options = array(); $values = $form_state->getValues(); foreach ($values as $key => $value) { if (in_array($key, array('id', 'label'))) { $entity->set($key, $value); } else { $options[$key] = $value; } } $entity->set('options', $options); }
/** * {@inheritdoc} */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { foreach ($form_state->getValues() as $key => $value) { // Do not copy effects here, see self::updateEffectWeights(). if ($key != 'effects') { $entity->set($key, $value); } } }
/** * {@inheritdoc} */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { $langcode = $form_state->getValue('predefined_langcode'); if ($langcode == 'custom') { $langcode = $form_state->getValue('langcode'); $label = $form_state->getValue('label'); $direction = $form_state->getValue('direction'); } else { $standard_languages = LanguageManager::getStandardLanguageList(); $label = $standard_languages[$langcode][0]; $direction = isset($standard_languages[$langcode][2]) ? $standard_languages[$langcode][2] : ConfigurableLanguage::DIRECTION_LTR; } $entity->set('id', $langcode); $entity->set('label', $label); $entity->set('direction', $direction); }
/** * Copies top-level form values to entity properties * * This should not change existing entity properties that are not being edited * by this form. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity the current form should operate upon. * @param array $form * A nested array of form elements comprising the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { $values = $form_state->getValues(); if ($this->entity instanceof EntityWithPluginCollectionInterface) { // Do not manually update values represented by plugin collections. $values = array_diff_key($values, $this->entity->getPluginCollections()); } // @todo: This relies on a method that only exists for config and content // entities, in a different way. Consider moving this logic to a config // entity specific implementation. foreach ($values as $key => $value) { $entity->set($key, $value); } }
/** * {@inheritdoc} */ public function setChangedTime($timestamp) { $field_name = $this->translation->hasField('content_translation_changed') ? 'content_translation_changed' : 'changed'; $this->translation->set($field_name, $timestamp); return $this; }
/** * Updates a field value, only if the field is translatable. * * @param string $field_name * The name of the field. * @param mixed $value * The field value to be set. */ protected function setFieldOnlyIfTranslatable($field_name, $value) { if ($this->translation->getFieldDefinition($field_name)->isTranslatable()) { $this->translation->set($field_name, $value); } }
/** * Copies top-level form values to entity properties * * This should not change existing entity properties that are not being edited * by this form. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity the current form should operate upon. * @param array $form * A nested array of form elements comprising the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) { // @todo: This relies on a method that only exists for config and content // entities, in a different way. Consider moving this logic to a config // entity specific implementation. foreach ($form_state['values'] as $key => $value) { $entity->set($key, $value); } }
/** * {@inheritdoc} */ public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, $properties = []) { /** @var \Drupal\user\UserInterface $cloned_entity */ $cloned_entity->set('name', $cloned_entity->getAccountName() . '_cloned'); return parent::cloneEntity($entity, $cloned_entity, $properties); }