Browse Source

Decent progress... getting things actually rendering...

... bit of refactoring stuff making a mess.
pull/896/head
Adam Vessey 3 years ago
parent
commit
593f175ac3
No known key found for this signature in database
GPG Key ID: 89B39535BF6D0D39
  1. 14
      islandora.routing.yml
  2. 2
      src/Form/AddChildrenForm.php
  3. 180
      src/Form/AddChildrenWizard/FileSelectionForm.php
  4. 84
      src/Form/AddChildrenWizard/Form.php
  5. 27
      src/Form/AddChildrenWizard/TypeSelectionForm.php

14
islandora.routing.yml

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

2
src/Form/AddChildrenForm.php

@ -229,7 +229,7 @@ class AddChildrenForm extends AddMediaForm {
* @param \Drupal\Core\Routing\RouteMatch $route_match
* The current routing match.
*
* @return \Drupal\Core\Access\AccessResultAllowed|\Drupal\Core\Access\AccessResultForbidden
* @return \Drupal\Core\Access\AccessResultInterface
* Whether we can or can't show the "thing".
*/
public function access(RouteMatch $route_match) {

180
src/Form/AddChildrenWizard/FileSelectionForm.php

@ -2,24 +2,198 @@
namespace Drupal\islandora\Form\AddChildrenWizard;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Entity\BaseFieldOverride;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\WidgetInterface;
use Drupal\Core\Field\WidgetPluginManager;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\file\FileInterface;
use Drupal\islandora\IslandoraUtils;
use Drupal\media\MediaSourceInterface;
use Drupal\media\MediaTypeInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class FileSelectionForm extends FormBase {
protected ?EntityTypeManagerInterface $entityTypeManager;
/**
* The widget plugin manager service.
*
* @var WidgetPluginManager
*/
protected ?PluginManagerInterface $widgetPluginManager;
protected ?EntityFieldManagerInterface $entityFieldManager;
protected ?Connection $database;
protected ?AccountProxyInterface $currentUser;
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->entityTypeManager = $container->get('entity_type.manager');
$instance->widgetPluginManager = $container->get('plugin.manager.field.widget');
$instance->entityFieldManager = $container->get('entity_field.manager');
$instance->database = $container->get('database');
$instance->currentUser = $container->get('current_user');
return $instance;
}
public function getFormId() {
return 'islandora_add_children_wizard_file_selection';
}
public function buildForm(array $form, FormStateInterface $form_state) {
protected function getMediaType(FormStateInterface $form_state) : MediaTypeInterface {
return $this->doGetMediaType($form_state->getTemporaryValue('wizard'));
}
protected function doGetMediaType(array $values) : MediaTypeInterface {
/** @var MediaTypeInterface $media_type */
return $this->entityTypeManager->getStorage('media_type')->load($values['media_type']);
}
protected function getField(FormStateInterface $form_state) : FieldDefinitionInterface {
$cached_values = $form_state->getTemporaryValue('wizard');
$field = $this->doGetField($cached_values);
$field->getFieldStorageDefinition()->set('cardinality', FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
return $field;
}
protected function doGetField(array $values) : FieldDefinitionInterface {
$media_type = $this->doGetMediaType($values);
$media_source = $media_type->getSource();
$source_field = $media_source->getSourceFieldDefinition($media_type);
$fields = $this->entityFieldManager->getFieldDefinitions('media', $media_type->id());
return isset($fields[$source_field->getFieldStorageDefinition()->getName()]) ?
$fields[$source_field->getFieldStorageDefinition()->getName()] :
$media_source->createSourceField();
}
protected function getWidget(FormStateInterface $form_state) : WidgetInterface {
return $this->widgetPluginManager->getInstance([
'field_definition' => $this->getField($form_state),
'form_mode' => 'default',
'prepare' => TRUE,
]);
}
public function buildForm(array $form, FormStateInterface $form_state) : array {
// TODO: Using the media type selected in the previous step, grab the
// media bundle's "source" field, and create a multi-file upload widget
// for it, with the same kind of constraints.
$field = $this->getField($form_state);
$items = FieldItemList::createInstance($field, $field->getName(), $this->getMediaType($form_state)->getTypedData());
$form['#tree'] = TRUE;
$form['#parents'] = [];
$widget = $this->getWidget($form_state);
$form['files'] = $widget->form(
$items,
$form,
$form_state
);
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// TODO: Implement submitForm() method.
$form_state->setError($form, 'Oh no!');
$cached_values = $form_state->getTemporaryValue('wizard');
dsm($form_state);
$builder = (new BatchBuilder())
->setTitle($this->t('Creating children...'))
->setInitMessage($this->t('Initializing...'))
->setFinishCallback([$this, 'batchProcessFinished']);
foreach ($form_state->getValue($this->doGetField($cached_values)->getName()) as $file) {
$builder->addOperation([$this, 'batchProcess'], [$file, $cached_values]);
}
batch_set($builder->toArray());
}
public function batchProcess($fid, array $values, &$context) {
$transaction = \Drupal::database()->startTransaction();
try {
$taxonomy_term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
/** @var FileInterface $file */
$file = $this->entityTypeManager->getStorage('file')->load($fid);
$file->setPermanent();
if ($file->save() !== SAVED_UPDATED) {
throw new \Exception("Failed to update file '{$file->id()}' to be permanent.");
}
$node_storage = $this->entityTypeManager->getStorage('node');
$parent = $node_storage->load($values['node']);
// Create a node (with the filename?) (and also belonging to the target node).
$node = $node_storage->create([
'type' => $values['bundle'],
'title' => $file->getFilename(),
IslandoraUtils::MEMBER_OF_FIELD => $parent,
'uid' => $this->currentUser->id(),
'status' => NodeInterface::PUBLISHED,
IslandoraUtils::MODEL_FIELD => $values['model'] ?
$taxonomy_term_storage->load($values['model']) :
NULL,
]);
if ($node->save() !== SAVED_NEW) {
throw new \Exception("Failed to create node for file '{$file->id()}'.");
}
// Create a media with the file attached and also pointing at the node.
$media = $this->entityTypeManager->getStorage('media')->create([
'bundle' => $values['media_type'],
'name' => $file->getFilename(),
IslandoraUtils::MEDIA_OF_FIELD => $node,
IslandoraUtils::MEDIA_USAGE_FIELD => $values['use'] ?
$taxonomy_term_storage->loadMultiple($values['use']) :
NULL,
$this->doGetField($values)->getName() => $file->id(),
]);
if ($media->save() !== SAVED_NEW) {
throw new \Exception("Failed to create media for file '{$file->id()}.");
}
}
catch (HttpExceptionInterface $e) {
$transaction->rollBack();
throw $e;
}
catch (\Exception $e) {
$transaction->rollBack();
throw new HttpException(500, $e->getMessage(), $e);
}
}
public function batchProcessFinished() {
// TODO: Dump out status message of some sort?
}
}

84
src/Form/AddChildrenWizard/Form.php

@ -2,15 +2,83 @@
namespace Drupal\islandora\Form\AddChildrenWizard;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteMatch;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\TempStore\SharedTempStoreFactory;
use Drupal\ctools\Wizard\FormWizardBase;
use Drupal\islandora\IslandoraUtils;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
class Form extends FormWizardBase {
protected IslandoraUtils $utils;
protected string $nodeId;
protected RouteMatchInterface $currentRoute;
protected AccountProxyInterface $currentUser;
/**
* Constructor.
*/
public function __construct(
SharedTempStoreFactory $tempstore,
FormBuilderInterface $builder,
ClassResolverInterface $class_resolver,
EventDispatcherInterface $event_dispatcher,
RouteMatchInterface $route_match,
$tempstore_id,
IslandoraUtils $utils,
RouteMatchInterface $current_route_match,
AccountProxyInterface $current_user,
$machine_name = NULL,
$step = NULL
) {
parent::__construct($tempstore, $builder, $class_resolver, $event_dispatcher, $route_match, $tempstore_id,
$machine_name, $step);
$this->utils = $utils;
$this->currentRoute = $current_route_match;
$this->nodeId = $this->currentRoute->getParameter('node');
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function getParameters() : array {
return array_merge(
parent::getParameters(),
[
'utils' => \Drupal::service('islandora.utils'),
'tempstore_id' => 'islandora.upload_children',
//'machine_name' => 'islandora_add_children_wizard',
'current_route_match' => \Drupal::service('current_route_match'),
'current_user' => \Drupal::service('current_user'),
]
);
}
/**
* {@inheritdoc}
*/
public function getMachineName() {
return strtr("islandora_add_children_wizard__{userid}__{nodeid}", [
'{userid}' => $this->currentUser->id(),
'{nodeid}' => $this->nodeId,
]);
}
/**
* {@inheritdoc}
*/
public function getOperations($cached_values) {
// TODO: Implement getOperations() method.
return [
'child_type' => [
'title' => $this->t('Type of children'),
@ -22,4 +90,18 @@ class Form extends FormWizardBase {
]
];
}
public function getNextParameters($cached_values) {
return parent::getNextParameters($cached_values) + ['node' => $this->nodeId];
}
public function getPreviousParameters($cached_values) {
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'));
}
}

27
src/Form/AddChildrenWizard/TypeSelectionForm.php

@ -133,12 +133,19 @@ class TypeSelectionForm extends FormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$this->cacheableMetadata = CacheableMetadata::createFromRenderArray($form);
$this->cacheableMetadata = CacheableMetadata::createFromRenderArray($form)
->addCacheContexts([
'url',
'url.query_args',
]);
$cached_values = $form_state->getTemporaryValue('wizard');
$form['bundle'] = [
'#type' => 'select',
'#title' => $this->t('Content Type'),
'#description' => $this->t('Each child created will have this content type.'),
'#empty_value' => '',
'#default_value' => $cached_values['bundle'] ?? '',
'#options' => $this->getNodeBundleOptions(),
'#required' => TRUE,
];
@ -149,6 +156,8 @@ class TypeSelectionForm extends FormBase {
'#title' => $this->t('Model'),
'#description' => $this->t('Each child will be tagged with this model.'),
'#options' => iterator_to_array($this->getModelOptions()),
'#empty_value' => '',
'#default_value' => $cached_values['model'] ?? '',
'#states' => [
'visible' => [
':input[name="bundle"]' => $model_states,
@ -162,6 +171,8 @@ class TypeSelectionForm extends FormBase {
'#type' => 'select',
'#title' => $this->t('Media Type'),
'#description' => $this->t('Each media created will have this type.'),
'#empty_value' => '',
'#default_value' => $cached_values['media_type'] ?? '',
'#options' => $this->getMediaBundleOptions(),
'#required' => TRUE,
];
@ -173,6 +184,7 @@ class TypeSelectionForm extends FormBase {
':url' => 'https://pcdm.org/2015/05/12/use',
]),
'#options' => iterator_to_array($this->getMediaUseOptions()),
'#default_value' => $cached_values['use'] ?? [],
'#states' => [
'visible' => [
':input[name="media_type"]' => $use_states,
@ -191,6 +203,17 @@ class TypeSelectionForm extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// TODO: Implement submitForm() method.
$keys = [
'bundle',
'model',
'media_type',
'use',
];
$cached_values = $form_state->getTemporaryValue('wizard');
foreach ($keys as $key) {
$cached_values[$key] = $form_state->getValue($key);
}
$form_state->setTemporaryValue('wizard', $cached_values);
}
}

Loading…
Cancel
Save