Created
December 21, 2017 15:34
-
-
Save justinlevi/86f04a4609b92a875ea6f62a97afa255 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\store_graph_upload\Plugin\Deriver; | |
use Drupal\Component\Plugin\Derivative\DeriverBase; | |
use Drupal\Core\Entity\EntityTypeBundleInfoInterface; | |
use Drupal\Core\Entity\EntityTypeManagerInterface; | |
use Drupal\Core\Field\FieldDefinitionInterface; | |
use Drupal\Core\Field\FieldTypePluginManagerInterface; | |
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; | |
use Drupal\Core\Theme\ThemeManagerInterface; | |
use Symfony\Component\DependencyInjection\ContainerInterface; | |
use Drupal\Core\Entity\EntityFieldManagerInterface; | |
/** | |
* Derives EntityFileFieldUpload scalar for each file field instance. | |
*/ | |
class EntityFileFieldUploadDeriver extends DeriverBase implements ContainerDeriverInterface { | |
/** | |
* @var \Drupal\Core\Entity\EntityFieldManagerInterface | |
*/ | |
protected $fieldManager; | |
/** | |
* @var \Drupal\Core\Entity\EntityTypeManagerInterface | |
*/ | |
protected $entityTypeManager; | |
/** | |
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface | |
*/ | |
protected $bundleInfo; | |
/** | |
* @var \Drupal\Core\Field\FieldTypePluginManagerInterface | |
*/ | |
protected $fieldTypeManager; | |
/** | |
* @var \Drupal\Core\Theme\ThemeManagerInterface | |
*/ | |
protected $themeManager; | |
/** | |
* EntityFileFieldUploadDeriver constructor. | |
* | |
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager | |
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager | |
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info | |
* @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager | |
* @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager | |
*/ | |
public function __construct( | |
EntityFieldManagerInterface $field_manager, | |
EntityTypeManagerInterface $entity_manager, | |
EntityTypeBundleInfoInterface $bundle_info, | |
FieldTypePluginManagerInterface $field_type_manager, | |
ThemeManagerInterface $theme_manager | |
) { | |
$this->fieldManager = $field_manager; | |
$this->entityTypeManager = $entity_manager; | |
$this->bundleInfo = $bundle_info; | |
$this->fieldTypeManager = $field_type_manager; | |
$this->themeManager = $theme_manager; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public static function create(ContainerInterface $container, $basePluginId) { | |
return new static( | |
$container->get('entity_field.manager'), | |
$container->get('entity_type.manager'), | |
$container->get('entity_type.bundle.info'), | |
$container->get('plugin.manager.field.field_type'), | |
$container->get('theme.manager') | |
); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getDerivativeDefinitions($basePluginDefinition) { | |
$this->derivatives = []; | |
foreach (store_graph_exposed_content_entities() AS $entity_type_id) { | |
$entity_type = $this->entityTypeManager->getDefinition($entity_type_id); | |
$bundle_entity_type_id = $entity_type->getBundleEntityType(); | |
$bundles = empty($bundle_entity_type_id) ? [$entity_type_id] : array_keys($this->bundleInfo->getBundleInfo($entity_type_id)); | |
foreach ($bundles AS $bundle) { | |
$fields = $this->fieldManager->getFieldDefinitions($entity_type_id, $bundle); | |
foreach ($fields AS $field) { | |
if (in_array($field->getType(), ['file', 'image'])) { | |
$key = $entity_type_id . ':' . $bundle . ':' . $field->getName(); | |
if ($field->getFieldStorageDefinition()->isBaseField()) { | |
$key = $entity_type_id . ':' . $field->getName(); | |
$bundle = $entity_type_id; | |
} | |
if (!isset($this->derivatives[$key])) { | |
$this->derivatives[$key] = $this->buildDefinition($entity_type_id, $bundle, $field) + $basePluginDefinition; | |
} | |
} | |
} | |
} | |
} | |
return parent::getDerivativeDefinitions($basePluginDefinition); | |
} | |
/** | |
* Helper method to create definition of derivative from provided values. | |
* | |
* @param string $entity_type_id | |
* @param string $bundle | |
* @param \Drupal\Core\Field\FieldDefinitionInterface $field | |
* | |
* @return array | |
* | |
* @throws \Drupal\Component\Plugin\Exception\PluginException | |
*/ | |
protected function buildDefinition(string $entity_type_id, string $bundle, FieldDefinitionInterface $field): array { | |
/** @var \Drupal\file\Plugin\Field\FieldType\FileItem $item */ | |
$item = $this->fieldTypeManager->createInstance( | |
$field->getType(), | |
[ | |
'field_definition' => $field, | |
'name' => $field->getName(), | |
'parent' => NULL | |
] | |
); | |
$description = $this->themeManager->render('file_upload_help', [ | |
'description' => store_graph_untranslated_string($field->getDescription()), | |
'upload_validators' => $item->getUploadValidators(), | |
'cardinality' => $field->getFieldStorageDefinition()->getCardinality() | |
]); | |
return [ | |
'name' => store_graph_upload_get_file_field_upload_input_name($entity_type_id, $bundle, $field->getName()), | |
'description' => store_graph_parse_description($description), | |
'file_upload_validators' => $item->getUploadValidators(), | |
'file_upload_destination' => $item->getUploadLocation() | |
]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\store_graph_upload\Plugin\GraphQL\Scalars; | |
/** | |
* @GraphQLScalar( | |
* id = "entity_file_field_upload", | |
* name = "EntityFileFieldUpload", | |
* data_type = "id", | |
* deriver = "\Drupal\store_graph_upload\Plugin\Deriver\EntityFileFieldUploadDeriver" | |
* ) | |
*/ | |
class EntityFileFieldUpload extends FileUpload { | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getFileUploadValidators() { | |
return $this->getPluginDefinition()['file_upload_validators']; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getFileUploadDirectory() { | |
return $this->getPluginDefinition()['file_upload_destination']; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Drupal\store_graph_upload\Plugin\GraphQL\Scalars; | |
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; | |
use Drupal\graphql\Plugin\GraphQL\Scalars\GraphQLString; | |
use Symfony\Component\DependencyInjection\ContainerInterface; | |
use Symfony\Component\HttpFoundation\RequestStack; | |
/** | |
* @GraphQLScalar( | |
* id = "file_upload", | |
* name = "FileUpload", | |
* data_type = "id", | |
* description = @Translation("Name of the key holding the uploaded file data in the $_FILES variable.") | |
* ) | |
*/ | |
class FileUpload extends GraphQLString implements ContainerFactoryPluginInterface { | |
/** | |
* @var \Symfony\Component\HttpFoundation\RequestStack | |
*/ | |
protected $requestStack; | |
/** | |
* {@inheritdoc} | |
*/ | |
public function __construct(array $configuration, $pluginId, $pluginDefinition, RequestStack $request_stack) { | |
$this->requestStack = $request_stack; | |
$this->constructPlugin($configuration, $pluginId, $pluginDefinition); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) { | |
return new static( | |
$configuration, | |
$pluginId, | |
$pluginDefinition, | |
$container->get('request_stack') | |
); | |
} | |
/** | |
* {@inheritdoc} | |
* | |
* @todo remove when https://github.com/drupal-graphql/graphql/issues/420 | |
*/ | |
public function getName() { | |
return $this->getPluginDefinition()['name']; | |
} | |
/** | |
* {@inheritdoc} | |
* | |
* @todo remove when https://github.com/drupal-graphql/graphql/issues/420 | |
*/ | |
public function getDescription() { | |
return $this->getPluginDefinition()['description']; | |
} | |
/** | |
* Helper method to identify the file by its name. | |
* | |
* @param string $file_name | |
* The name of the file to look for. | |
* | |
* @return string|null | |
* The array key in the file bag. | |
*/ | |
protected function findFileIdentifier(string $file_name): ?string { | |
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile[] $all_files */ | |
$all_files = $this->requestStack->getCurrentRequest()->files->all(); | |
foreach ($all_files AS $identifier => $file) { | |
if ($file->getClientOriginalName() === $file_name) { | |
return $identifier; | |
} | |
} | |
return NULL; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function isValidValue($value) { | |
return is_string($value) && strlen($value) !== 0 && $this->findFileIdentifier($value) !== NULL; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function parseValue($value) { | |
// Drupal expects files to reside under 'files' key | |
// so we have to manually move the file to expected location. | |
// @see file_save_upload() | |
// @see \Drupal\file\Element\ManagedFile::processManagedFile() | |
$files_bag = $this->requestStack->getCurrentRequest()->files; | |
$all_files = $files_bag->get('files', []); | |
$identifier = $this->findFileIdentifier($value); | |
$file = $files_bag->get($identifier); | |
// Prevent key collision. | |
if (isset($all_files[$identifier])) { | |
$identifier = uniqid($identifier); | |
} | |
// Move the file. | |
$all_files[$identifier] = $file; | |
$files_bag->set('files', $all_files); | |
// Save the uploaded file as managed file entity. | |
$file = file_save_upload($identifier, $this->getFileUploadValidators(), $this->getFileUploadDirectory(), 0); | |
// Return the file entity id. | |
return parent::parseValue($file ? $file->id() : NULL); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getValidationError($value = null) { | |
return is_string($value) ? sprintf('File "%s" not found in request.', $value) : parent::getValidationError($value); | |
} | |
/** | |
* Helper method that will return file validators. | |
* | |
* @return array | |
*/ | |
public function getFileUploadValidators() { | |
return []; | |
} | |
/** | |
* Helper method that will return the target directory. | |
* | |
* @return string|false | |
*/ | |
public function getFileUploadDirectory() { | |
return FALSE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment