Browse Source

Coding standards, and warning of validation issues.

pull/896/head
Adam Vessey 3 years ago
parent
commit
bbb9fc8726
No known key found for this signature in database
GPG Key ID: 89B39535BF6D0D39
  1. 13
      islandora.routing.yml
  2. 2
      src/Form/AddChildrenForm.php
  3. 63
      src/Form/AddChildrenWizard/Access.php
  4. 227
      src/Form/AddChildrenWizard/FileSelectionForm.php
  5. 72
      src/Form/AddChildrenWizard/Form.php
  6. 123
      src/Form/AddChildrenWizard/TypeSelectionForm.php

13
islandora.routing.yml

@ -37,16 +37,6 @@ islandora.add_member_to_node_page:
_entity_create_any_access: 'node' _entity_create_any_access: 'node'
islandora.upload_children: islandora.upload_children:
path: '/node/{node}/members/upload_old'
defaults:
_form: '\Drupal\islandora\Form\AddChildrenForm'
_title: 'Upload Children'
options:
_admin_route: 'TRUE'
requirements:
_custom_access: '\Drupal\islandora\Form\AddChildrenForm::access'
islandora.upload_children_wizard:
path: '/node/{node}/members/upload/{step}' path: '/node/{node}/members/upload/{step}'
defaults: defaults:
_wizard: '\Drupal\islandora\Form\AddChildrenWizard\Form' _wizard: '\Drupal\islandora\Form\AddChildrenWizard\Form'
@ -55,8 +45,7 @@ islandora.upload_children_wizard:
options: options:
_admin_route: 'TRUE' _admin_route: 'TRUE'
requirements: requirements:
#_custom_access: '\Drupal\islandora\Form\AddChildrenWizard\Form::access' _custom_access: '\Drupal\islandora\Form\AddChildrenWizard\Access::checkAccess'
_custom_access: '\Drupal\islandora\Form\AddChildrenForm::access'
islandora.add_media_to_node_page: islandora.add_media_to_node_page:
path: '/node/{node}/media/add' path: '/node/{node}/media/add'

2
src/Form/AddChildrenForm.php

@ -12,6 +12,8 @@ use Symfony\Component\HttpKernel\Exception\HttpException;
/** /**
* Form that lets users upload one or more files as children to a resource node. * Form that lets users upload one or more files as children to a resource node.
*
* @deprecated Replaced with the "wizard" appraach.
*/ */
class AddChildrenForm extends AddMediaForm { class AddChildrenForm extends AddMediaForm {

63
src/Form/AddChildrenWizard/Access.php

@ -0,0 +1,63 @@
<?php
namespace Drupal\islandora\Form\AddChildrenWizard;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Routing\RouteMatch;
use Drupal\islandora\IslandoraUtils;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Access checker.
*
* The _wizard/_form route enhancers do not really allow for access checking
* things, so let's roll it separately for now.
*/
class Access implements ContainerInjectionInterface {
/**
* The Islandora utils service.
*
* @var \Drupal\islandora\IslandoraUtils
*/
protected IslandoraUtils $utils;
/**
* Constructor.
*/
public function __construct(IslandoraUtils $utils) {
$this->utils = $utils;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) : self {
return new static(
$container->get('islandora.utils')
);
}
/**
* Check if the user can create any "Islandora" nodes and media.
*
* @param \Drupal\Core\Routing\RouteMatch $route_match
* The current routing match.
*
* @return \Drupal\Core\Access\AccessResultInterface
* Whether we can or cannot show the "thing".
*/
public function checkAccess(RouteMatch $route_match) : AccessResultInterface {
$can_create_media = $this->utils->canCreateIslandoraEntity('media', 'media_type');
$can_create_node = $this->utils->canCreateIslandoraEntity('node', 'node_type');
if ($can_create_media && $can_create_node) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
}

227
src/Form/AddChildrenWizard/FileSelectionForm.php

@ -7,48 +7,66 @@ use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Database\Connection; use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Entity\BaseFieldOverride;
use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemList; use Drupal\Core\Field\FieldItemList;
use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\WidgetInterface; use Drupal\Core\Field\WidgetInterface;
use Drupal\Core\Field\WidgetPluginManager;
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueInterface;
use Drupal\Core\Session\AccountProxyInterface; use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\file\FileInterface;
use Drupal\islandora\IslandoraUtils; use Drupal\islandora\IslandoraUtils;
use Drupal\media\MediaInterface;
use Drupal\media\MediaSourceInterface;
use Drupal\media\MediaTypeInterface; use Drupal\media\MediaTypeInterface;
use Drupal\node\NodeInterface; use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
/**
* Children addition wizard's second step.
*/
class FileSelectionForm extends FormBase { class FileSelectionForm extends FormBase {
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface|null
*/
protected ?EntityTypeManagerInterface $entityTypeManager; protected ?EntityTypeManagerInterface $entityTypeManager;
/** /**
* The widget plugin manager service. * The widget plugin manager service.
* *
* @var WidgetPluginManager * @var \Drupal\Core\Field\WidgetPluginManager|null
*/ */
protected ?PluginManagerInterface $widgetPluginManager; protected ?PluginManagerInterface $widgetPluginManager;
/**
* The entity field manager service.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface|null
*/
protected ?EntityFieldManagerInterface $entityFieldManager; protected ?EntityFieldManagerInterface $entityFieldManager;
/**
* The database connection serivce.
*
* @var \Drupal\Core\Database\Connection|null
*/
protected ?Connection $database; protected ?Connection $database;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface|null
*/
protected ?AccountProxyInterface $currentUser; protected ?AccountProxyInterface $currentUser;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self { public static function create(ContainerInterface $container): self {
$instance = parent::create($container); $instance = parent::create($container);
$instance->entityTypeManager = $container->get('entity_type.manager'); $instance->entityTypeManager = $container->get('entity_type.manager');
$instance->widgetPluginManager = $container->get('plugin.manager.field.widget'); $instance->widgetPluginManager = $container->get('plugin.manager.field.widget');
@ -59,20 +77,57 @@ class FileSelectionForm extends FormBase {
return $instance; return $instance;
} }
/**
* {@inheritdoc}
*/
public function getFormId() { public function getFormId() {
return 'islandora_add_children_wizard_file_selection'; return 'islandora_add_children_wizard_file_selection';
} }
protected function getMediaType(FormStateInterface $form_state) : MediaTypeInterface { /**
* Helper; get the media type, based off discovering from form state.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return \Drupal\media\MediaTypeInterface
* The target media type.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getMediaType(FormStateInterface $form_state): MediaTypeInterface {
return $this->doGetMediaType($form_state->getTemporaryValue('wizard')); return $this->doGetMediaType($form_state->getTemporaryValue('wizard'));
} }
protected function doGetMediaType(array $values) : MediaTypeInterface { /**
/** @var MediaTypeInterface $media_type */ * Helper; get media type, given our required values.
return $this->entityTypeManager->getStorage('media_type')->load($values['media_type']); *
* @param array $values
* An associative array which must contain at least:
* - media_type: The machine name of the media type to load.
*
* @return \Drupal\media\MediaTypeInterface
* The loaded media type.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function doGetMediaType(array $values): MediaTypeInterface {
/** @var \Drupal\media\MediaTypeInterface $media_type */
return $this->entityTypeManager->getStorage('media_type')->load($values['media_type']);
} }
protected function getField(FormStateInterface $form_state) : FieldDefinitionInterface { /**
* Helper; get field instance, based off discovering from form state.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return \Drupal\Core\Field\FieldDefinitionInterface
* The field definition.
*/
protected function getField(FormStateInterface $form_state): FieldDefinitionInterface {
$cached_values = $form_state->getTemporaryValue('wizard'); $cached_values = $form_state->getTemporaryValue('wizard');
$field = $this->doGetField($cached_values); $field = $this->doGetField($cached_values);
@ -81,23 +136,49 @@ class FileSelectionForm extends FormBase {
return $field; return $field;
} }
protected function doGetField(array $values) : FieldDefinitionInterface { /**
* Helper; get field instance, given our required values.
*
* @param array $values
* See ::doGetMediaType() for which values are required.
*
* @return \Drupal\Core\Field\FieldDefinitionInterface
* The target field.
*/
protected function doGetField(array $values): FieldDefinitionInterface {
$media_type = $this->doGetMediaType($values); $media_type = $this->doGetMediaType($values);
$media_source = $media_type->getSource(); $media_source = $media_type->getSource();
$source_field = $media_source->getSourceFieldDefinition($media_type); $source_field = $media_source->getSourceFieldDefinition($media_type);
$fields = $this->entityFieldManager->getFieldDefinitions('media', $media_type->id()); $fields = $this->entityFieldManager->getFieldDefinitions('media', $media_type->id());
return isset($fields[$source_field->getFieldStorageDefinition()->getName()]) ? return $fields[$source_field->getFieldStorageDefinition()->getName()] ??
$fields[$source_field->getFieldStorageDefinition()->getName()] :
$media_source->createSourceField(); $media_source->createSourceField();
} }
protected function getWidget(FormStateInterface $form_state) : WidgetInterface { /**
* Helper; get widget for the field, based on discovering from form state.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return \Drupal\Core\Field\WidgetInterface
* The widget.
*/
protected function getWidget(FormStateInterface $form_state): WidgetInterface {
return $this->doGetWidget($this->getField($form_state)); return $this->doGetWidget($this->getField($form_state));
} }
protected function doGetWidget(FieldDefinitionInterface $field) : WidgetInterface { /**
* Helper; get the base widget for the given field.
*
* @param \Drupal\Core\Field\FieldDefinitionInterface $field
* The field for which get obtain the widget.
*
* @return \Drupal\Core\Field\WidgetInterface
* The widget.
*/
protected function doGetWidget(FieldDefinitionInterface $field): WidgetInterface {
return $this->widgetPluginManager->getInstance([ return $this->widgetPluginManager->getInstance([
'field_definition' => $field, 'field_definition' => $field,
'form_mode' => 'default', 'form_mode' => 'default',
@ -105,11 +186,13 @@ class FileSelectionForm extends FormBase {
]); ]);
} }
public function buildForm(array $form, FormStateInterface $form_state) : array { /**
// TODO: Using the media type selected in the previous step, grab the * {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
// Using the media type selected in the previous step, grab the
// media bundle's "source" field, and create a multi-file upload widget // media bundle's "source" field, and create a multi-file upload widget
// for it, with the same kind of constraints. // for it, with the same kind of constraints.
$field = $this->getField($form_state); $field = $this->getField($form_state);
$items = FieldItemList::createInstance($field, $field->getName(), $this->getMediaType($form_state)->getTypedData()); $items = FieldItemList::createInstance($field, $field->getName(), $this->getMediaType($form_state)->getTypedData());
@ -131,11 +214,6 @@ class FileSelectionForm extends FormBase {
public function submitForm(array &$form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) {
$cached_values = $form_state->getTemporaryValue('wizard'); $cached_values = $form_state->getTemporaryValue('wizard');
dsm($form);
dsm($form_state);
dsm($this->doGetField($cached_values));
dsm($this->doGetField($cached_values)->getName());
$widget = $this->getWidget($form_state); $widget = $this->getWidget($form_state);
$builder = (new BatchBuilder()) $builder = (new BatchBuilder())
->setTitle($this->t('Creating children...')) ->setTitle($this->t('Creating children...'))
@ -143,24 +221,26 @@ class FileSelectionForm extends FormBase {
->setFinishCallback([$this, 'batchProcessFinished']); ->setFinishCallback([$this, 'batchProcessFinished']);
$values = $form_state->getValue($this->doGetField($cached_values)->getName()); $values = $form_state->getValue($this->doGetField($cached_values)->getName());
$massaged_values = $widget->massageFormValues($values, $form, $form_state); $massaged_values = $widget->massageFormValues($values, $form, $form_state);
dsm($values);
dsm($massaged_values);
foreach ($massaged_values as $delta => $file) { foreach ($massaged_values as $delta => $file) {
dsm($file); $builder->addOperation(
$builder->addOperation([$this, 'batchProcess'], [$delta, $file, $form, $form_state, $cached_values]); [$this, 'batchProcess'],
[$delta, $file, $cached_values]
);
} }
batch_set($builder->toArray()); batch_set($builder->toArray());
$form_state->setRedirectUrl(Url::fromUri("internal:/node/{$cached_values['node']}/members")); $form_state->setRedirectUrl(Url::fromUri("internal:/node/{$cached_values['node']}/members"));
} }
public function batchProcess($delta, $info, array $form, FormStateInterface $form_state, array $values, &$context) { /**
$transaction = \Drupal::database()->startTransaction(); * Implements callback_batch_operation() for our child addition batch.
*/
public function batchProcess($delta, $info, array $values, &$context) {
$transaction = $this->database->startTransaction();
try { try {
$taxonomy_term_storage = $this->entityTypeManager->getStorage('taxonomy_term'); $taxonomy_term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
dsm(func_get_args()); /** @var \Drupal\file\FileInterface $file */
/** @var FileInterface $file */
$file = $this->entityTypeManager->getStorage('file')->load($info['target_id']); $file = $this->entityTypeManager->getStorage('file')->load($info['target_id']);
$file->setPermanent(); $file->setPermanent();
if ($file->save() !== SAVED_UPDATED) { if ($file->save() !== SAVED_UPDATED) {
@ -170,36 +250,35 @@ class FileSelectionForm extends FormBase {
$node_storage = $this->entityTypeManager->getStorage('node'); $node_storage = $this->entityTypeManager->getStorage('node');
$parent = $node_storage->load($values['node']); $parent = $node_storage->load($values['node']);
// Create a node (with the filename?) (and also belonging to the target node). // Create a node (with the filename?) (and also belonging to the target
// node).
/** @var \Drupal\node\NodeInterface $node */
$node = $node_storage->create([ $node = $node_storage->create([
'type' => $values['bundle'], 'type' => $values['bundle'],
'title' => $file->getFilename(), 'title' => $file->getFilename(),
IslandoraUtils::MEMBER_OF_FIELD => $parent, IslandoraUtils::MEMBER_OF_FIELD => $parent,
'uid' => $this->currentUser->id(), 'uid' => $this->currentUser->id(),
'status' => NodeInterface::PUBLISHED, 'status' => NodeInterface::PUBLISHED,
IslandoraUtils::MODEL_FIELD => $values['model'] ? IslandoraUtils::MODEL_FIELD => ($values['model'] ?
$taxonomy_term_storage->load($values['model']) : $taxonomy_term_storage->load($values['model']) :
NULL, NULL),
]); ]);
if ($node->save() !== SAVED_NEW) { if ($node->save() !== SAVED_NEW) {
throw new \Exception("Failed to create node for file '{$file->id()}'."); throw new \Exception("Failed to create node for file '{$file->id()}'.");
} }
// Create a media with the file attached and also pointing at the node. // Create a media with the file attached and also pointing at the node.
$field = $this->doGetField($values); $field = $this->doGetField($values);
$widget = $this->doGetWidget($field);
$items = FieldItemList::createInstance($field, $field->getName(), $this->getMediaType($form_state)->getTypedData());
$items->setValue([0 => $info]);
//$items->setValue([$delta => $info]);
$media_values = array_merge( $media_values = array_merge(
[ [
'bundle' => $values['media_type'], 'bundle' => $values['media_type'],
'name' => $file->getFilename(), 'name' => $file->getFilename(),
IslandoraUtils::MEDIA_OF_FIELD => $node, IslandoraUtils::MEDIA_OF_FIELD => $node,
IslandoraUtils::MEDIA_USAGE_FIELD => $values['use'] ? IslandoraUtils::MEDIA_USAGE_FIELD => ($values['use'] ?
$taxonomy_term_storage->loadMultiple($values['use']) : $taxonomy_term_storage->loadMultiple($values['use']) :
NULL, NULL),
'uid' => $this->currentUser->id(), 'uid' => $this->currentUser->id(),
// XXX: Published... no constant? // XXX: Published... no constant?
'status' => 1, 'status' => 1,
@ -210,11 +289,19 @@ class FileSelectionForm extends FormBase {
], ],
] ]
); );
dsm($media_values);
$media = $this->entityTypeManager->getStorage('media')->create($media_values); $media = $this->entityTypeManager->getStorage('media')->create($media_values);
if ($media->save() !== SAVED_NEW) { if ($media->save() !== SAVED_NEW) {
throw new \Exception("Failed to create media for file '{$file->id()}."); throw new \Exception("Failed to create media for file '{$file->id()}.");
} }
$context['results'] = array_merge_recursive($context['results'], [
'validation_violations' => $this->validationClassification([
$file,
$media,
$node,
]),
]);
$context['results']['count'] += 1;
} }
catch (HttpExceptionInterface $e) { catch (HttpExceptionInterface $e) {
$transaction->rollBack(); $transaction->rollBack();
@ -226,8 +313,52 @@ class FileSelectionForm extends FormBase {
} }
} }
public function batchProcessFinished() { /**
// TODO: Dump out status message of some sort? * @param array $entities
*
* @return array
*/
protected function validationClassification(array $entities) {
$violations = [];
foreach ($entities as $entity) {
$entity_violations = $entity->validate();
if ($entity_violations->count() > 0) {
$violations[$entity->getEntityTypeId()][$entity->id()] = $entity_violations->count();
}
}
return $violations;
}
/**
* Implements callback_batch_finished() for our child addition batch.
*/
public function batchProcessFinished($success, $results, $operations): void {
if ($success) {
$this->messenger()->addMessage($this->formatPlural(
$results['count'],
'Added 1 child node.',
'Added @count child nodes.'
));
foreach ($results['validation_violations'] ?? [] as $entity_type => $info) {
foreach ($info as $id => $count) {
$this->messenger()->addWarning($this->formatPlural(
$count,
'1 validation error present in <a href=":uri">bulk created entity of type %type, with ID %id</a>.',
'@count validation errors present in <a href=":uri">bulk created entity of type %type, with ID %id</a>.',
[
'%type' => $entity_type,
':uri' => Url::fromRoute("entity.{$entity_type}.canonical", [$entity_type => $id])->toString(),
'%id' => $id,
]
));
}
}
}
else {
$this->messenger()->addError($this->t('Encountered an error when adding children.'));
}
} }
} }

72
src/Form/AddChildrenWizard/Form.php

@ -5,8 +5,6 @@ namespace Drupal\islandora\Form\AddChildrenWizard;
use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResult;
use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Routing\RouteMatch;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountProxyInterface; use Drupal\Core\Session\AccountProxyInterface;
@ -14,14 +12,38 @@ use Drupal\Core\TempStore\SharedTempStoreFactory;
use Drupal\ctools\Wizard\FormWizardBase; use Drupal\ctools\Wizard\FormWizardBase;
use Drupal\islandora\IslandoraUtils; use Drupal\islandora\IslandoraUtils;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Bulk children addition wizard base form.
*/
class Form extends FormWizardBase { class Form extends FormWizardBase {
/**
* The Islandora Utils service.
*
* @var \Drupal\islandora\IslandoraUtils
*/
protected IslandoraUtils $utils; protected IslandoraUtils $utils;
/**
* The current node ID.
*
* @var string|mixed|null
*/
protected string $nodeId; protected string $nodeId;
/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected RouteMatchInterface $currentRoute; protected RouteMatchInterface $currentRoute;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected AccountProxyInterface $currentUser; protected AccountProxyInterface $currentUser;
/** /**
@ -58,7 +80,6 @@ class Form extends FormWizardBase {
[ [
'utils' => \Drupal::service('islandora.utils'), 'utils' => \Drupal::service('islandora.utils'),
'tempstore_id' => 'islandora.upload_children', 'tempstore_id' => 'islandora.upload_children',
//'machine_name' => 'islandora_add_children_wizard',
'current_route_match' => \Drupal::service('current_route_match'), 'current_route_match' => \Drupal::service('current_route_match'),
'current_user' => \Drupal::service('current_user'), 'current_user' => \Drupal::service('current_user'),
] ]
@ -79,35 +100,38 @@ class Form extends FormWizardBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getOperations($cached_values) { public function getOperations($cached_values) {
return [ $ops = [];
'child_type' => [
'title' => $this->t('Type of children'), $ops['child_type'] = [
'form' => TypeSelectionForm::class, 'title' => $this->t('Type of children'),
'values' => [ 'form' => TypeSelectionForm::class,
'node' => $this->nodeId, 'values' => [
] 'node' => $this->nodeId,
],
];
$ops['child_files'] = [
'title' => $this->t('Files for children'),
'form' => FileSelectionForm::class,
'values' => [
'node' => $this->nodeId,
], ],
'child_files' => [
'title' => $this->t('Files for children'),
'form' => FileSelectionForm::class,
'values' => [
'node' => $this->nodeId,
]
]
]; ];
return $ops;
} }
/**
* {@inheritdoc}
*/
public function getNextParameters($cached_values) { public function getNextParameters($cached_values) {
return parent::getNextParameters($cached_values) + ['node' => $this->nodeId]; return parent::getNextParameters($cached_values) + ['node' => $this->nodeId];
} }
/**
* {@inheritdoc}
*/
public function getPreviousParameters($cached_values) { public function getPreviousParameters($cached_values) {
return parent::getPreviousParameters($cached_values) + ['node' => $this->nodeId]; return parent::getPreviousParameters($cached_values) + ['node' => $this->nodeId];
} }
public function finish(array &$form, FormStateInterface $form_state) {
parent::finish($form, $form_state); // TODO: Change the autogenerated stub
dsm($form_state->getTemporaryValue('wizard'));
}
} }

123
src/Form/AddChildrenWizard/TypeSelectionForm.php

@ -3,25 +3,50 @@
namespace Drupal\islandora\Form\AddChildrenWizard; namespace Drupal\islandora\Form\AddChildrenWizard;
use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\islandora\IslandoraUtils; use Drupal\islandora\IslandoraUtils;
use Drupal\taxonomy\TermInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use function Symfony\Component\DependencyInjection\Loader\Configurator\iterator;
/**
* Children addition wizard's first step.
*/
class TypeSelectionForm extends FormBase { class TypeSelectionForm extends FormBase {
/**
* Cacheable metadata that is instantiated and used internally.
*
* @var \Drupal\Core\Cache\CacheableMetadata|null
*/
protected ?CacheableMetadata $cacheableMetadata = NULL; protected ?CacheableMetadata $cacheableMetadata = NULL;
/**
* The entity type bundle info service.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface|null
*/
protected ?EntityTypeBundleInfoInterface $entityTypeBundleInfo; protected ?EntityTypeBundleInfoInterface $entityTypeBundleInfo;
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface|null
*/
protected ?EntityTypeManagerInterface $entityTypeManager; protected ?EntityTypeManagerInterface $entityTypeManager;
protected ?EntityFieldManagerInterface $entityFieldManager;
/**
* The entity field manager service.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface|null
*/
protected ?EntityFieldManagerInterface $entityFieldManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
$instance = parent::create($container); $instance = parent::create($container);
@ -39,14 +64,33 @@ class TypeSelectionForm extends FormBase {
return 'islandora_add_children_type_selection'; return 'islandora_add_children_type_selection';
} }
/**
* Memoization for ::getNodeBundleOptions().
*
* @var array|null
*/
protected ?array $nodeBundleOptions = NULL; protected ?array $nodeBundleOptions = NULL;
/**
* Indicate presence of model field on node bundles.
*
* Populated as a side effect of ::getNodeBundleOptions().
*
* @var array|null
*/
protected ?array $nodeBundleHasModelField = NULL; protected ?array $nodeBundleHasModelField = NULL;
//protected ?array $nodeBundleHasMemberOfField = NULL;
/**
* Helper; get the node bundle options available to the current user.
*
* @return array
* An associative array mapping node bundle machine names to their human-
* readable labels.
*/
protected function getNodeBundleOptions() : array { protected function getNodeBundleOptions() : array {
if ($this->nodeBundleOptions === NULL) { if ($this->nodeBundleOptions === NULL) {
$this->nodeBundleOptions = []; $this->nodeBundleOptions = [];
$this->nodeBundleHasModelField = []; $this->nodeBundleHasModelField = [];
//$this->nodeBundleHasMemberOfField = [];
$access_handler = $this->entityTypeManager->getAccessControlHandler('node'); $access_handler = $this->entityTypeManager->getAccessControlHandler('node');
foreach ($this->entityTypeBundleInfo->getBundleInfo('node') as $bundle => $info) { foreach ($this->entityTypeBundleInfo->getBundleInfo('node') as $bundle => $info) {
@ -62,7 +106,6 @@ class TypeSelectionForm extends FormBase {
} }
$this->nodeBundleOptions[$bundle] = $info['label']; $this->nodeBundleOptions[$bundle] = $info['label'];
$fields = $this->entityFieldManager->getFieldDefinitions('node', $bundle); $fields = $this->entityFieldManager->getFieldDefinitions('node', $bundle);
//$this->nodeBundleHasMemberOfField[$bundle] = array_key_exists(IslandoraUtils::MEMBER_OF_FIELD, $fields);
$this->nodeBundleHasModelField[$bundle] = array_key_exists(IslandoraUtils::MODEL_FIELD, $fields); $this->nodeBundleHasModelField[$bundle] = array_key_exists(IslandoraUtils::MODEL_FIELD, $fields);
} }
} }
@ -70,7 +113,16 @@ class TypeSelectionForm extends FormBase {
return $this->nodeBundleOptions; return $this->nodeBundleOptions;
} }
protected function getModelOptions() : \Traversable { /**
* Generates a mapping of taxonomy term IDs to their names.
*
* @return \Generator
* The mapping of taxonomy term IDs to their names.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getModelOptions() : \Generator {
$terms = $this->entityTypeManager->getStorage('taxonomy_term') $terms = $this->entityTypeManager->getStorage('taxonomy_term')
->loadTree('islandora_models', 0, NULL, TRUE); ->loadTree('islandora_models', 0, NULL, TRUE);
foreach ($terms as $term) { foreach ($terms as $term) {
@ -78,15 +130,43 @@ class TypeSelectionForm extends FormBase {
} }
} }
protected function mapModelStates() : \Traversable { /**
* Helper; map node bundles supporting the "has model" field, for #states.
*
* @return \Generator
* Yields associative array mapping the string 'value' to the bundles which
* have the given field.
*/
protected function mapModelStates() : \Generator {
$this->getNodeBundleOptions(); $this->getNodeBundleOptions();
foreach (array_keys(array_filter($this->nodeBundleHasModelField)) as $bundle) { foreach (array_keys(array_filter($this->nodeBundleHasModelField)) as $bundle) {
yield ['value' => $bundle]; yield ['value' => $bundle];
} }
} }
/**
* Memoization for ::getMediaBundleOptions().
*
* @var array|null
*/
protected ?array $mediaBundleOptions = NULL; protected ?array $mediaBundleOptions = NULL;
/**
* Indicate presence of usage field on media bundles.
*
* Populated as a side effect in ::getMediaBundleOptions().
*
* @var array|null
*/
protected ?array $mediaBundleUsageField = NULL; protected ?array $mediaBundleUsageField = NULL;
/**
* Helper; get options for media types.
*
* @return array
* An associative array mapping the machine name of the media type to its
* human-readable label.
*/
protected function getMediaBundleOptions() : array { protected function getMediaBundleOptions() : array {
if ($this->mediaBundleOptions === NULL) { if ($this->mediaBundleOptions === NULL) {
$this->mediaBundleOptions = []; $this->mediaBundleOptions = [];
@ -113,16 +193,33 @@ class TypeSelectionForm extends FormBase {
return $this->mediaBundleOptions; return $this->mediaBundleOptions;
} }
/**
* Helper; list the terms of the "islandora_media_use" vocabulary.
*
* @return \Generator
* Generates term IDs as keys mapping to term names.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getMediaUseOptions() { protected function getMediaUseOptions() {
/** @var TermInterface[] $terms */ /** @var \Drupal\taxonomy\TermInterface[] $terms */
$terms = $this->entityTypeManager->getStorage('taxonomy_term') $terms = $this->entityTypeManager->getStorage('taxonomy_term')
->loadTree('islandora_media_use', 0, NULL, TRUE); ->loadTree('islandora_media_use', 0, NULL, TRUE);
foreach ($terms as $term) { foreach ($terms as $term) {
yield $term->id() => $term->getName(); yield $term->id() => $term->getName();
} }
} }
protected function mapUseStates() {
/**
* Helper; map media types supporting the usage field for use with #states.
*
* @return \Generator
* Yields associative array mapping the string 'value' to the bundles which
* have the given field.
*/
protected function mapUseStates(): \Generator {
$this->getMediaBundleOptions(); $this->getMediaBundleOptions();
foreach (array_keys(array_filter($this->mediaBundleUsageField)) as $bundle) { foreach (array_keys(array_filter($this->mediaBundleUsageField)) as $bundle) {
yield ['value' => $bundle]; yield ['value' => $bundle];
@ -165,7 +262,7 @@ class TypeSelectionForm extends FormBase {
'required' => [ 'required' => [
':input[name="bundle"]' => $model_states, ':input[name="bundle"]' => $model_states,
], ],
] ],
]; ];
$form['media_type'] = [ $form['media_type'] = [
'#type' => 'select', '#type' => 'select',

Loading…
Cancel
Save