/** * Checks access to create an entity of any bundle for the given route. * * @param \Symfony\Component\Routing\Route $route * The route to check against. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The parameterized route. * @param \Drupal\Core\Session\AccountInterface $account * The currently logged in account. * * @return \Drupal\Core\Access\AccessResultInterface * The access result. */ public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) { $entity_type_id = $route->getRequirement($this->requirementsKey); $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type_id); // In case there is no "bundle" entity key, check create access with no // bundle specified. if (!$entity_type->hasKey('bundle')) { return $access_control_handler->createAccess(NULL, $account, [], TRUE); } $access = AccessResult::neutral(); $bundles = array_keys($this->entityTypeBundleInfo->getBundleInfo($entity_type_id)); // Include list cache tag as access might change if more bundles are added. if ($entity_type->getBundleEntityType()) { $access->addCacheTags($this->entityTypeManager->getDefinition($entity_type->getBundleEntityType())->getListCacheTags()); // Check if the user is allowed to create new bundles. If so, allow // access, so the add page can show a link to create one. // @see \Drupal\Core\Entity\Controller\EntityController::addPage() $bundle_access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type->getBundleEntityType()); $access = $access->orIf($bundle_access_control_handler->createAccess(NULL, $account, [], TRUE)); if ($access->isAllowed()) { return $access; } } // Check whether an entity of any bundle may be created. foreach ($bundles as $bundle) { $access = $access->orIf($access_control_handler->createAccess($bundle, $account, [], TRUE)); // In case there is a least one bundle user can create entities for, // access is allowed. if ($access->isAllowed()) { break; } } return $access; }
/** * Sets up the entity type manager to be tested. * * @param \Drupal\Core\Entity\EntityTypeInterface[]|\Prophecy\Prophecy\ProphecyInterface[] $definitions * (optional) An array of entity type definitions. */ protected function setUpEntityTypeDefinitions($definitions = []) { $class = $this->getMockClass(EntityInterface::class); foreach ($definitions as $key => $entity_type) { // \Drupal\Core\Entity\EntityTypeInterface::getLinkTemplates() is called // by \Drupal\Core\Entity\EntityManager::processDefinition() so it must // always be mocked. $entity_type->getLinkTemplates()->willReturn([]); // Give the entity type a legitimate class to return. $entity_type->getClass()->willReturn($class); $definitions[$key] = $entity_type->reveal(); } $this->entityTypeManager->getDefinition(Argument::cetera())->will(function ($args) use($definitions) { $entity_type_id = $args[0]; $exception_on_invalid = $args[1]; if (isset($definitions[$entity_type_id])) { return $definitions[$entity_type_id]; } elseif (!$exception_on_invalid) { return NULL; } else { throw new PluginNotFoundException($entity_type_id); } }); $this->entityTypeManager->getDefinitions()->willReturn($definitions); }
/** * {@inheritdoc} */ public function getFields($entity_type_id) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); if (!$entity_type->isSubclassOf('\\Drupal\\Core\\Entity\\ContentEntityInterface')) { return []; } $map = $this->getAllFields(); return isset($map[$entity_type_id]) ? $map[$entity_type_id] : []; }
/** * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { /** @var ScheduledUpdateTypeInterface $entity */ $row['label'] = $entity->label(); $row['target_type'] = $this->entityTypeManager->getDefinition($entity->getUpdateEntityType())->getLabel(); $row['id'] = $entity->id(); // You probably want a few more properties here... return $row + parent::buildRow($entity); }
/** * {@inheritdoc} */ protected function mapFromStorageRecords(array $records) { $entities = parent::mapFromStorageRecords($records); $prefix = $this->entityTypeManager->getDefinition('moderation_state')->getConfigPrefix(); /* @var \Drupal\workbench_moderation\ModerationStateTransitionInterface $entity */ foreach ($entities as &$entity) { $entity->setModerationStateConfigPrefix($prefix); } reset($entities); return $entities; }
/** * {@inheritdoc} */ public function enhance(array $defaults, Request $request) { // Entity layout forms only need the actual name of the bundle they're dealing // with, not an upcasted entity object, so provide a simple way for them // to get it. $bundle = $this->entityTypeManager->getDefinition($defaults['entity_type_id'])->getBundleEntityType(); if ($bundle && isset($defaults[$bundle])) { $defaults['bundle'] = $defaults['_raw_variables']->get($bundle); } return $defaults; }
/** * {@inheritdoc} */ public function loadEntityByConfigTarget($entity_type_id, $target) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); // For configuration entities, the config target is given by the entity ID. // @todo Consider adding a method to allow entity types to indicate the // target identifier key rather than hard-coding this check. Issue: // https://www.drupal.org/node/2412983. if ($entity_type instanceof ConfigEntityTypeInterface) { $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($target); } else { $entity = $this->loadEntityByUuid($entity_type_id, $target); } return $entity; }
/** * {@inheritdoc} */ public function getValueOptions() { if (!isset($this->valueOptions)) { $entity_type_id = $this->getEntityType(); $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $field_name = $this->getFieldName(); $available_countries = $this->getAvailableCountries($entity_type, $field_name); $countries = $this->countryRepository->getList(); if (!empty($available_countries)) { $countries = array_intersect_key($countries, $available_countries); } $this->valueOptions = $countries; } return $this->valueOptions; }
/** * {@inheritdoc} */ protected function interact(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $config_types = $this->getConfigTypes(); $config_name = $input->getArgument('config-name'); if (!$config_name) { $config_type = $io->choiceNoList($this->trans('commands.config.export.single.questions.config-type'), array_keys($config_types), $this->trans('commands.config.export.single.options.simple-configuration')); $config_names = $this->getConfigNames($config_type); $config_name = $io->choiceNoList($this->trans('commands.config.export.single.questions.config-name'), array_keys($config_names)); if ($config_type !== 'system.simple') { $definition = $this->entityTypeManager->getDefinition($config_type); $config_name = $definition->getConfigPrefix() . '.' . $config_name; } $input->setArgument('config-name', $config_name); } $module = $input->getOption('module'); if ($module) { $optionalConfig = $input->getOption('optional-config'); if (!$optionalConfig) { $optionalConfig = $io->confirm($this->trans('commands.config.export.single.questions.optional-config'), true); $input->setOption('optional-config', $optionalConfig); } } if (!$input->getOption('remove-uuid')) { $removeUuid = $io->confirm($this->trans('commands.config.export.single.questions.remove-uuid'), true); $input->setOption('remove-uuid', $removeUuid); } }
/** * {@inheritDoc} */ public function buildEntity(array $form, FormStateInterface $form_state) { /** @var \Drupal\pathauto\PathautoPatternInterface $entity */ $entity = parent::buildEntity($form, $form_state); $default_weight = 0; $alias_type = $entity->getAliasType(); if ($alias_type->getDerivativeId() && $this->entityTypeManager->hasDefinition($alias_type->getDerivativeId())) { $entity_type = $alias_type->getDerivativeId(); // First, remove bundle and language conditions. foreach ($entity->getSelectionConditions() as $condition_id => $condition) { if (in_array($condition->getPluginId(), ['entity_bundle:' . $entity_type, 'node_type', 'language'])) { $entity->removeSelectionCondition($condition_id); } } if ($bundles = array_filter((array) $form_state->getValue('bundles'))) { $default_weight -= 5; $plugin_id = $entity_type == 'node' ? 'node_type' : 'entity_bundle:' . $entity_type; $entity->addSelectionCondition(['id' => $plugin_id, 'bundles' => $bundles, 'negate' => FALSE, 'context_mapping' => [$entity_type => $entity_type]]); } if ($languages = array_filter((array) $form_state->getValue('languages'))) { $default_weight -= 5; $language_mapping = $entity_type . ':' . $this->entityTypeManager->getDefinition($entity_type)->getKey('langcode') . ':language'; $entity->addSelectionCondition(['id' => 'language', 'langcodes' => array_combine($languages, $languages), 'negate' => FALSE, 'context_mapping' => ['language' => $language_mapping]]); $entity->addRelationship($language_mapping, t('Language')); } } $entity->setWeight($default_weight); return $entity; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $entity_type_id = $form_state->getValue('entity_type_id'); $entity_type_plural = $this->entityTypeManager->getDefinition($entity_type_id)->getPluralLabel(); $batch = ['title' => t('Deleting @entity_type_plural', ['@entity_type_plural' => $entity_type_plural]), 'operations' => [[[__CLASS__, 'deleteContentEntities'], [$entity_type_id]]], 'finished' => [__CLASS__, 'moduleBatchFinished'], 'progress_message' => '']; batch_set($batch); }
/** * {@inheritdoc} */ public function tableFields($bundles) { $info = $this->entityTypeManager->getDefinition($this->entityTypeId()); $definitions = $this->entityFieldManager->getBaseFieldDefinitions($this->entityTypeId()); $label_key = $info->getKey('label'); $label_field_label = t('Label'); if ($label_key && isset($definitions[$label_key])) { $label_field_label = $definitions[$label_key]->getLabel(); } $bundle_key = $info->getKey('bundle'); $bundle_field_label = t('Type'); if ($bundle_key && isset($definitions[$bundle_key])) { $bundle_field_label = $definitions[$bundle_key]->getLabel(); } $fields = []; $fields['label'] = [ 'type' => 'label', 'label' => $label_field_label, 'weight' => 1, ]; if (count($bundles) > 1) { $fields[$bundle_key] = [ 'type' => 'field', 'label' => $bundle_field_label, 'weight' => 2, ]; } return $fields; }
/** * {@inheritdoc} */ public function getSourcePrefix() { if (empty($this->prefix)) { $entity_type = $this->entityTypeManager->getDefinition($this->getEntityTypeId()); $path = $entity_type->getLinkTemplate('canonical'); $this->prefix = substr($path, 0, strpos($path, '{')); } return $this->prefix; }
/** * {@inheritdoc} */ public function getDefaultRevisionId($entity_type_id, $entity_id) { if ($storage = $this->entityTypeManager->getStorage($entity_type_id)) { $revision_ids = $storage->getQuery()->condition($this->entityTypeManager->getDefinition($entity_type_id)->getKey('id'), $entity_id)->sort($this->entityTypeManager->getDefinition($entity_type_id)->getKey('revision'), 'DESC')->range(0, 1)->execute(); if ($revision_ids) { return array_keys($revision_ids)[0]; } } }
/** * Adds an operation on bundles that should have a Moderation form. * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity on which to define an operation. * * @return array * An array of operation definitions. * * @see hook_entity_operation() */ public function entityOperation(EntityInterface $entity) { $operations = []; $type = $entity->getEntityType(); $bundle_of = $type->getBundleOf(); if ($this->currentUser->hasPermission('administer moderation states') && $bundle_of && $this->moderationInfo->canModerateEntitiesOfEntityType($this->entityTypeManager->getDefinition($bundle_of))) { $operations['manage-moderation'] = ['title' => t('Manage moderation'), 'weight' => 27, 'url' => Url::fromRoute("entity.{$type->id()}.moderation", [$entity->getEntityTypeId() => $entity->id()])]; } return $operations; }
/** * {@inheritdoc} */ public function getLatestRevisionId($entity_type_id, $entity_id) { if ($storage = $this->entityTypeManager->getStorage($entity_type_id)) { $revision_ids = $storage->getQuery()->allRevisions()->condition($this->entityTypeManager->getDefinition($entity_type_id)->getKey('id'), $entity_id)->sort($this->entityTypeManager->getDefinition($entity_type_id)->getKey('revision'), 'DESC')->pager(1)->execute(); if ($revision_ids) { $revision_id = array_keys($revision_ids)[0]; return $revision_id; } } }
/** * Load entities based on entity and bundle type. * * @param string $entity_type * The entity type to load entities for. * @param string $bundle_type * The bundle type the load entities for. * * @return ContentEntityInterface[] */ protected function loadEntities($entity_type, $bundle_type) { $definition = $this->entityTypeManager->getDefinition($entity_type); $properties = []; // Get the key used for the bundle on this entity and set it to the query // properties if it exists. if ($bundle_key = $definition->getKey('bundle')) { $properties[$bundle_key] = $bundle_type; } return $this->entityTypeManager->getStorage($entity_type)->loadByProperties($properties); }
/** * @covers ::getAddFormRoute * @dataProvider providerTestGetAddFormRoute */ public function testGetAddFormRoute(Route $expected = NULL, EntityTypeInterface $entity_type, EntityTypeInterface $bundle_entity_type = NULL, FieldStorageDefinitionInterface $field_storage_definition = NULL) { if ($bundle_entity_type) { $this->entityTypeManager->getDefinition('the_bundle_entity_type_id')->willReturn($bundle_entity_type); if ($field_storage_definition) { $this->entityFieldManager->getFieldStorageDefinitions('the_bundle_entity_type_id')->willReturn(['id' => $field_storage_definition]); } } $route = $this->routeProvider->getAddFormRoute($entity_type); $this->assertEquals($expected, $route); }
/** * {@inheritdoc} */ public function calculateDependencies() { $this->addDependencies(parent::calculateDependencies()); $entity_type_id = $this->getConfigurationValue('entity_type'); $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $this->addDependency('module', $entity_type->getProvider()); // Calculate bundle dependencies. foreach ($this->getConfigurationValue('bundles') as $bundle) { $bundle_dependency = $entity_type->getBundleConfigDependency($bundle); $this->addDependency($bundle_dependency['type'], $bundle_dependency['name']); } // Calculate display Entity Embed Display dependencies. foreach ($this->getConfigurationValue('display_plugins') as $display_plugin) { $instance = $this->displayPluginManager->createInstance($display_plugin); $this->calculatePluginDependencies($instance); } return $this->dependencies; }
/** * {@inheritdoc} */ public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entity_type_id) { if ($route_match->getRawParameter($entity_type_id) !== NULL) { $entity = $route_match->getParameter($entity_type_id); } else { $values = []; // If the entity has bundles, fetch it from the route match. $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); if ($bundle_key = $entity_type->getKey('bundle')) { if (($bundle_entity_type_id = $entity_type->getBundleEntityType()) && $route_match->getRawParameter($bundle_entity_type_id)) { $values[$bundle_key] = $route_match->getParameter($bundle_entity_type_id)->id(); } elseif ($route_match->getRawParameter($bundle_key)) { $values[$bundle_key] = $route_match->getParameter($bundle_key); } } $entity = $this->entityTypeManager->getStorage($entity_type_id)->create($values); } return $entity; }
/** * {@inheritdoc} */ public function query() { // The table doesn't exist until a moderated node has been saved at least // once. Just in case, disable this filter until then. Note that this means // the view will still show all revisions, not just latest, but this is // sufficiently edge-case-y that it's probably not worth the time to // handle more robustly. if (!$this->connection->schema()->tableExists('content_revision_tracker')) { return; } $table = $this->ensureMyTable(); /** @var \Drupal\views\Plugin\views\query\Sql $query */ $query = $this->query; $definition = $this->entityTypeManager->getDefinition($this->getEntityType()); $keys = $definition->getKeys(); $definition = ['table' => 'content_revision_tracker', 'type' => 'INNER', 'field' => 'entity_id', 'left_table' => $table, 'left_field' => $keys['id'], 'extra' => [['left_field' => $keys['langcode'], 'field' => 'langcode'], ['left_field' => $keys['revision'], 'field' => 'revision_id'], ['field' => 'entity_type', 'value' => $this->getEntityType()]]]; $join = $this->joinHandler->createInstance('standard', $definition); $query->ensureTable('content_revision_tracker', $this->relationship, $join); }
/** * {@inheritdoc} */ public function importFormFields(array $keyed_fields, array $existing_fields = []) { // Iterate over each FillPdfFormField and override matching PDF keys // (if any current fields have them). $fillpdf_field_type = $this->entityTypeManager->getDefinition('fillpdf_form_field'); $field_fields_to_ignore = array_filter(array_values($fillpdf_field_type->getKeys())); $field_fields_to_ignore[] = 'fillpdf_form'; $existing_fields_by_key = []; foreach ($existing_fields as $existing_field) { $existing_fields_by_key[$existing_field->pdf_key->value] = $existing_field; } $existing_field_pdf_keys = array_keys($existing_fields_by_key); $unmatched_pdf_keys = []; /** * @var string $pdf_key * @var FillPdfFormFieldInterface $keyed_field */ foreach ($keyed_fields as $pdf_key => $keyed_field) { // If the imported field's PDF key matching the PDF key of the // existing field, then copy the constituent entity fields. // I know: they're both called fields. It's confusing as hell. // I am sorry. if (in_array($pdf_key, $existing_field_pdf_keys, TRUE)) { /** @var FillPdfFormFieldInterface $existing_field_by_key */ $existing_field_by_key = $existing_fields_by_key[$pdf_key]; foreach ($keyed_field->getFields() as $keyed_field_name => $keyed_field_data) { if (!in_array($keyed_field_name, $field_fields_to_ignore, TRUE)) { $existing_field_by_key->{$keyed_field_name} = $keyed_field_data; } } $existing_field_by_key->save(); } else { $unmatched_pdf_keys[] = $pdf_key; } } return $unmatched_pdf_keys; }
protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $module = $input->getOption('module'); $viewId = $input->getArgument('view-id'); $optionalConfig = $input->getOption('optional-config'); $includeModuleDependencies = $input->getOption('include-module-dependencies'); $viewTypeDefinition = $this->entityTypeManager->getDefinition('view'); $viewTypeName = $viewTypeDefinition->getConfigPrefix() . '.' . $viewId; $viewNameConfig = $this->getConfiguration($viewTypeName); $this->configExport[$viewTypeName] = array('data' => $viewNameConfig, 'optional' => $optionalConfig); // Include config dependencies in export files if ($dependencies = $this->fetchDependencies($viewNameConfig, 'config')) { $this->resolveDependencies($dependencies, $optionalConfig); } // Include module dependencies in export files if export is not optional if ($includeModuleDependencies) { if ($dependencies = $this->fetchDependencies($viewNameConfig, 'module')) { $this->exportModuleDependencies($io, $module, $dependencies); } } $this->exportConfigToModule($module, $io, $this->trans('commands.views.export.messages.view_exported')); }
/** * Form constructor for the entity selection step. * * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. * * @return array * The form structure. */ public function buildSelectStep(array &$form, FormStateInterface $form_state) { $entity_element = $form_state->get('entity_element'); /** @var \Drupal\embed\EmbedButtonInterface $embed_button */ $embed_button = $form_state->get('embed_button'); $entity = $form_state->get('entity'); $form['attributes']['data-entity-type'] = array('#type' => 'value', '#value' => $entity_element['data-entity-type']); $label = $this->t('Label'); // Attempt to display a better label if we can by getting it from // the label field definition. $entity_type = $this->entityTypeManager->getDefinition($entity_element['data-entity-type']); if ($entity_type->isSubclassOf('\\Drupal\\Core\\Entity\\FieldableEntityInterface') && $entity_type->hasKey('label')) { $field_definitions = $this->entityManager()->getBaseFieldDefinitions($entity_type->id()); if (isset($field_definitions[$entity_type->getKey('label')])) { $label = $field_definitions[$entity_type->getKey('label')]->getLabel(); } } $form['#title'] = $this->t('Select @type to embed', array('@type' => $entity_type->getLowercaseLabel())); if ($this->entityBrowser) { $this->eventDispatcher->addListener(Events::REGISTER_JS_CALLBACKS, [$this, 'registerJSCallback']); $form['attributes']['entity_browser']['#theme_wrappers'] = ['container']; $form['attributes']['entity_browser']['browser'] = $this->entityBrowser->getDisplay()->displayEntityBrowser($form_state); $form['attributes']['entity_browser']['entity-id'] = ['#type' => 'hidden', '#default_value' => $entity ? $entity->id() : '', '#attributes' => ['class' => ['eb-target']]]; $form['#attached']['library'][] = 'entity_browser/common'; $form['#attached']['drupalSettings']['entity_browser'] = [$this->entityBrowser->getDisplay()->getUuid() => ['cardinality' => 1]]; $form['attributes']['data-entity-id'] = array('#type' => 'value', '#title' => $entity_element['data-entity-id']); } else { $form['attributes']['data-entity-id'] = array('#type' => 'entity_autocomplete', '#target_type' => $entity_element['data-entity-type'], '#title' => $label, '#default_value' => $entity, '#required' => TRUE, '#description' => $this->t('Type label and pick the right one from suggestions. Note that the unique ID will be saved.')); if ($bundles = $embed_button->getTypeSetting('bundles')) { $form['attributes']['data-entity-id']['#selection_settings']['target_bundles'] = $bundles; } } $form['attributes']['data-entity-uuid'] = array('#type' => 'value', '#title' => $entity_element['data-entity-uuid']); $form['actions'] = array('#type' => 'actions'); $form['actions']['save_modal'] = array('#type' => 'submit', '#value' => $this->t('Next'), '#button_type' => 'primary', '#submit' => array(), '#ajax' => array('callback' => '::submitSelectStep', 'event' => 'click'), '#attributes' => ['class' => ['js-button-next']]); return $form; }
/** * Builds field storage definitions for an entity type. * * @param string $entity_type_id * The entity type ID. Only entity types that implement * \Drupal\Core\Entity\FieldableEntityInterface are supported * * @return \Drupal\Core\Field\FieldStorageDefinitionInterface[] * An array of field storage definitions, keyed by field name. */ protected function buildFieldStorageDefinitions($entity_type_id) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $field_definitions = []; // Retrieve base field definitions from modules. foreach ($this->moduleHandler->getImplementations('entity_field_storage_info') as $module) { $module_definitions = $this->moduleHandler->invoke($module, 'entity_field_storage_info', [$entity_type]); if (!empty($module_definitions)) { // Ensure the provider key actually matches the name of the provider // defining the field. foreach ($module_definitions as $field_name => $definition) { // @todo Remove this check once FieldDefinitionInterface exposes a // proper provider setter. See https://www.drupal.org/node/2225961. if ($definition instanceof BaseFieldDefinition) { $definition->setProvider($module); } $field_definitions[$field_name] = $definition; } } } // Invoke alter hook. $this->moduleHandler->alter('entity_field_storage_info', $field_definitions, $entity_type); return $field_definitions; }
/** * Constructs a Drupal\rest\Plugin\rest\resource\EntityResource object. * * @param array $configuration * A configuration array containing information about the plugin instance. * @param string $plugin_id * The plugin_id for the plugin instance. * @param mixed $plugin_definition * The plugin implementation definition. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager * @param array $serializer_formats * The available serialization formats. * @param \Psr\Log\LoggerInterface $logger * A logger instance. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, $serializer_formats, LoggerInterface $logger, ConfigFactoryInterface $config_factory) { parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); $this->entityType = $entity_type_manager->getDefinition($plugin_definition['entity_type']); $this->configFactory = $config_factory; }
/** * Creates a new EntityBundle instance. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info * The entity type bundle info service. * @param array $configuration * The plugin configuration, i.e. an array with configuration values keyed * by configuration option name. The special key 'context' may be used to * initialize the defined contexts by setting it to an array of context * values keyed by context names. * @param string $plugin_id * The plugin_id for the plugin instance. * @param mixed $plugin_definition * The plugin implementation definition. */ public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, array $configuration, $plugin_id, $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->entityTypeBundleInfo = $entity_type_bundle_info; $this->bundleOf = $entity_type_manager->getDefinition($this->getDerivativeId()); }
/** * Loads all entities contained in the passed-in $results. *. * If the entity belongs to the base table, then it gets stored in * $result->_entity. Otherwise, it gets stored in * $result->_relationship_entities[$relationship_id]; * * @param \Drupal\views\ResultRow[] $results * The result of the SQL query. */ public function loadEntities(&$results) { $entity_information = $this->getEntityTableInfo(); // No entity tables found, nothing else to do here. if (empty($entity_information)) { return; } // Extract all entity types from entity_information. $entity_types = array(); foreach ($entity_information as $info) { $entity_type = $info['entity_type']; if (!isset($entity_types[$entity_type])) { $entity_types[$entity_type] = $this->entityTypeManager->getDefinition($entity_type); } } // Assemble a list of entities to load. $entity_ids_by_type = []; $revision_ids_by_type = []; foreach ($entity_information as $info) { $relationship_id = $info['relationship_id']; $entity_type = $info['entity_type']; /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_info */ $entity_info = $entity_types[$entity_type]; $revision = $info['revision']; $id_key = !$revision ? $entity_info->getKey('id') : $entity_info->getKey('revision'); $id_alias = $this->getFieldAlias($info['alias'], $id_key); foreach ($results as $index => $result) { // Store the entity id if it was found. if (isset($result->{$id_alias}) && $result->{$id_alias} != '') { if ($revision) { $revision_ids_by_type[$entity_type][$index][$relationship_id] = $result->{$id_alias}; } else { $entity_ids_by_type[$entity_type][$index][$relationship_id] = $result->{$id_alias}; } } } } // Load all entities and assign them to the correct result row. foreach ($entity_ids_by_type as $entity_type => $ids) { $entity_storage = $this->entityTypeManager->getStorage($entity_type); $flat_ids = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($ids)), FALSE); $entities = $entity_storage->loadMultiple(array_unique($flat_ids)); $results = $this->assignEntitiesToResult($ids, $entities, $results); } // Now load all revisions. foreach ($revision_ids_by_type as $entity_type => $revision_ids) { $entity_storage = $this->entityTypeManager->getStorage($entity_type); $entities = []; foreach ($revision_ids as $index => $revision_id_by_relationship) { foreach ($revision_id_by_relationship as $revision => $revision_id) { // Drupal core currently has no way to load multiple revisions. $entity = $entity_storage->loadRevision($revision_id); $entities[$revision_id] = $entity; } } $results = $this->assignEntitiesToResult($revision_ids, $entities, $results); } }
/** * {@inheritdoc} */ public function validate($value, Constraint $constraint) { /** @var \Drupal\Core\Field\FieldItemListInterface $value */ /** @var ValidReferenceConstraint $constraint */ if (!isset($value)) { return; } // Collect new entities and IDs of existing entities across the field items. $new_entities = []; $target_ids = []; foreach ($value as $delta => $item) { $target_id = $item->target_id; // We don't use a regular NotNull constraint for the target_id property as // NULL is allowed if the entity property contains an unsaved entity. // @see \Drupal\Core\TypedData\DataReferenceTargetDefinition::getConstraints() if (!$item->isEmpty() && $target_id === NULL) { if (!$item->entity->isNew()) { $this->context->buildViolation($constraint->nullMessage)->atPath((string) $delta)->addViolation(); return; } $new_entities[$delta] = $item->entity; } // '0' or NULL are considered valid empty references. if (!empty($target_id)) { $target_ids[$delta] = $target_id; } } // Early opt-out if nothing to validate. if (!$new_entities && !$target_ids) { return; } /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface $handler * */ $handler = $this->selectionManager->getSelectionHandler($value->getFieldDefinition()); $target_type_id = $value->getFieldDefinition()->getSetting('target_type'); // Add violations on deltas with a new entity that is not valid. if ($new_entities) { if ($handler instanceof SelectionWithAutocreateInterface) { $valid_new_entities = $handler->validateReferenceableNewEntities($new_entities); $invalid_new_entities = array_diff_key($new_entities, $valid_new_entities); } else { // If the selection handler does not support referencing newly created // entities, all of them should be invalidated. $invalid_new_entities = $new_entities; } foreach ($invalid_new_entities as $delta => $entity) { $this->context->buildViolation($constraint->invalidAutocreateMessage)->setParameter('%type', $target_type_id)->setParameter('%label', $entity->label())->atPath((string) $delta . '.entity')->setInvalidValue($entity)->addViolation(); } } // Add violations on deltas with a target_id that is not valid. if ($target_ids) { $valid_target_ids = $handler->validateReferenceableEntities($target_ids); if ($invalid_target_ids = array_diff($target_ids, $valid_target_ids)) { // For accuracy of the error message, differentiate non-referenceable // and non-existent entities. $target_type = $this->entityTypeManager->getDefinition($target_type_id); $existing_ids = $this->entityTypeManager->getStorage($target_type_id)->getQuery()->condition($target_type->getKey('id'), $invalid_target_ids, 'IN')->execute(); foreach ($invalid_target_ids as $delta => $target_id) { $message = in_array($target_id, $existing_ids) ? $constraint->message : $constraint->nonExistingMessage; $this->context->buildViolation($message)->setParameter('%type', $target_type_id)->setParameter('%id', $target_id)->atPath((string) $delta . '.target_id')->setInvalidValue($target_id)->addViolation(); } } } }
/** * Provides a generic add title callback for an entity type. * * @param string $entity_type_id * The entity type ID. * * @return string * The title for the entity add page. */ public function addTitle($entity_type_id) { $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); return $this->t('Add @entity-type', ['@entity-type' => $entity_type->getLowercaseLabel()]); }