Update to Drupal 8.0-dev-2015-11-17. Commits through da81cd220, Tue Nov 17 15:53:49 2015 +0000, Issue #2617224 by Wim Leers: Move around/fix some documentation.

This commit is contained in:
Pantheon Automation 2015-11-17 13:42:33 -08:00 committed by Greg Anderson
parent 4afb23bbd3
commit 7784f4c23d
929 changed files with 19798 additions and 5304 deletions

View file

@ -27,8 +27,41 @@ class FileSelection extends DefaultSelection {
*/
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
$query = parent::buildEntityQuery($match, $match_operator);
$query->condition('status', FILE_STATUS_PERMANENT);
// Allow referencing :
// - files with status "permanent"
// - or files uploaded by the current user (since newly uploaded files only
// become "permanent" after the containing entity gets validated and
// saved.)
$query->condition($query->orConditionGroup()
->condition('status', FILE_STATUS_PERMANENT)
->condition('uid', $this->currentUser->id()));
return $query;
}
/**
* {@inheritdoc}
*/
public function createNewEntity($entity_type_id, $bundle, $label, $uid) {
$file = parent::createNewEntity($entity_type_id, $bundle, $label, $uid);
// In order to create a referenceable file, it needs to have a "permanent"
// status.
/** @var \Drupal\file\FileInterface $file */
$file->setPermanent();
return $file;
}
/**
* {@inheritdoc}
*/
public function validateReferenceableNewEntities(array $entities) {
$entities = parent::validateReferenceableNewEntities($entities);
$entities = array_filter($entities, function ($file) {
/** @var \Drupal\file\FileInterface $file */
return $file->isPermanent() || $file->getOwnerId() === $this->currentUser->id();
});
return $entities;
}
}

View file

@ -28,7 +28,7 @@ use Drupal\Core\TypedData\DataDefinition;
* default_widget = "file_generic",
* default_formatter = "file_default",
* list_class = "\Drupal\file\Plugin\Field\FieldType\FileFieldItemList",
* constraints = {"ValidReference" = {}, "ReferenceAccess" = {}}
* constraints = {"ReferenceAccess" = {}, "FileValidation" = {}}
* )
*/
class FileItem extends EntityReferenceItem {

View file

@ -18,8 +18,9 @@ use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\file\Element\ManagedFile;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\file\Entity\File;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface;
/**
* Plugin implementation of the 'file_generic' widget.
@ -369,11 +370,6 @@ class FileWidget extends WidgetBase implements ContainerFactoryPluginInterface {
$item = $element['#value'];
$item['fids'] = $element['fids']['#value'];
// Prevent the file widget from overriding the image widget.
if (!isset($element['#theme'])) {
$element['#theme'] = 'file_widget';
}
// Add the display field if enabled.
if ($element['#display_field']) {
$element['display'] = array(
@ -575,4 +571,15 @@ class FileWidget extends WidgetBase implements ContainerFactoryPluginInterface {
static::setWidgetState($parents, $field_name, $form_state, $field_state);
}
/**
* {@inheritdoc}
*/
public function flagErrors(FieldItemListInterface $items, ConstraintViolationListInterface $violations, array $form, FormStateInterface $form_state) {
// Never flag validation errors for the remove button.
$clicked_button = end($form_state->getTriggeringElement()['#parents']);
if ($clicked_button !== 'remove_button') {
parent::flagErrors($items, $violations, $form, $form_state);
}
}
}

View file

@ -0,0 +1,22 @@
<?php
/**
* @file
* Contains \Drupal\file\Plugin\Validation\Constraint\FileValidationConstraint.
*/
namespace Drupal\file\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Validation File constraint.
*
* @Constraint(
* id = "FileValidation",
* label = @Translation("File Validation", context = "Validation")
* )
*/
class FileValidationConstraint extends Constraint {
}

View file

@ -0,0 +1,34 @@
<?php
/**
* @file
* Contains \Drupal\file\Plugin\Validation\Constraint\FileValidationConstraintValidator.
*/
namespace Drupal\file\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Checks that a file referenced in a file field is valid.
*/
class FileValidationConstraintValidator extends ConstraintValidator {
/**
* {@inheritdoc}
*/
public function validate($value, Constraint $constraint) {
// Get the file to execute validators.
$file = $value->get('entity')->getTarget()->getValue();
// Get the validators.
$validators = $value->getUploadValidators();
// Checks that a file meets the criteria specified by the validators.
if ($errors = file_validate($file, $validators)) {
foreach ($errors as $error) {
$this->context->addViolation($error);
}
}
}
}

View file

@ -7,8 +7,11 @@
namespace Drupal\file\Plugin\migrate\destination;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\UriItem;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\LocalStream;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
@ -41,7 +44,7 @@ class EntityFile extends EntityContentBase {
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, StreamWrapperManagerInterface $stream_wrappers, FileSystemInterface $file_system) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, StreamWrapperManagerInterface $stream_wrappers, FileSystemInterface $file_system) {
$configuration += array(
'source_base_path' => '',
'source_path_property' => 'filepath',
@ -49,7 +52,7 @@ class EntityFile extends EntityContentBase {
'move' => FALSE,
'urlencode' => FALSE,
);
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager);
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager);
$this->streamWrapperManager = $stream_wrappers;
$this->fileSystem = $file_system;
@ -68,6 +71,7 @@ class EntityFile extends EntityContentBase {
$container->get('entity.manager')->getStorage($entity_type),
array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
$container->get('entity.manager'),
$container->get('plugin.manager.field.field_type'),
$container->get('stream_wrapper_manager'),
$container->get('file_system')
);
@ -77,6 +81,12 @@ class EntityFile extends EntityContentBase {
* {@inheritdoc}
*/
protected function getEntity(Row $row, array $old_destination_id_values) {
// For stub rows, there is no real file to deal with, let the stubbing
// process take its default path.
if ($row->isStub()) {
return parent::getEntity($row, $old_destination_id_values);
}
$destination = $row->getDestinationProperty($this->configuration['destination_path_property']);
$entity = $this->storage->loadByProperties(['uri' => $destination]);
if ($entity) {
@ -91,6 +101,12 @@ class EntityFile extends EntityContentBase {
* {@inheritdoc}
*/
public function import(Row $row, array $old_destination_id_values = array()) {
// For stub rows, there is no real file to deal with, let the stubbing
// process create the stub entity.
if ($row->isStub()) {
return parent::import($row, $old_destination_id_values);
}
$file = $row->getSourceProperty($this->configuration['source_path_property']);
$destination = $row->getDestinationProperty($this->configuration['destination_path_property']);
$source = $this->configuration['source_base_path'] . $file;
@ -256,4 +272,30 @@ class EntityFile extends EntityContentBase {
return $filename;
}
/**
* {@inheritdoc}
*/
protected function processStubRow(Row $row) {
// We stub the uri value ourselves so we can create a real stub file for it.
if (!$row->getDestinationProperty('uri')) {
$field_definitions = $this->entityManager
->getFieldDefinitions($this->storage->getEntityTypeId(),
$this->getKey('bundle'));
$value = UriItem::generateSampleValue($field_definitions['uri']);
if (empty($value)) {
throw new MigrateException('Stubbing failed, unable to generate value for field uri');
}
// generateSampleValue() wraps the value in an array.
$value = reset($value);
// Make it into a proper public file uri, stripping off the existing
// scheme if present.
$value = 'public://' . preg_replace('|^[a-z]+://|i', '', $value);
$value = Unicode::substr($value, 0, $field_definitions['uri']->getSetting('max_length'));
// Create a real file, so File::preSave() can do filesize() on it.
touch($value);
$row->setDestinationProperty('uri', $value);
}
parent::processStubRow($row);
}
}

View file

@ -24,6 +24,11 @@ class FileUri extends ProcessPluginBase {
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
// If we're stubbing a file entity, return a uri of NULL so it will get
// stubbed by the general process.
if ($row->isStub()) {
return NULL;
}
list($filepath, $file_directory_path, $temp_directory_path, $is_public) = $value;
// Specific handling using $temp_directory_path for temporary files.

View file

@ -159,4 +159,35 @@ class FileFieldValidateTest extends FileFieldTestBase {
$this->assertFileEntryExists($node_file, 'File entry exists after uploading a file with extension checking.');
}
/**
* Checks that a file can always be removed if it does not pass validation.
*/
public function testFileRemoval() {
$node_storage = $this->container->get('entity.manager')->getStorage('node');
$type_name = 'article';
$field_name = 'file_test';
$this->createFileField($field_name, 'node', $type_name);
$test_file = $this->getTestFile('image');
// Disable extension checking.
$this->updateFileField($field_name, $type_name, array('file_extensions' => ''));
// Check that the file can be uploaded with no extension checking.
$nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
$node_storage->resetCache(array($nid));
$node = $node_storage->load($nid);
$node_file = File::load($node->{$field_name}->target_id);
$this->assertFileExists($node_file, 'File exists after uploading a file with no extension checking.');
$this->assertFileEntryExists($node_file, 'File entry exists after uploading a file with no extension checking.');
// Enable extension checking for text files.
$this->updateFileField($field_name, $type_name, array('file_extensions' => 'txt'));
// Check that the file can still be removed.
$this->removeNodeFile($nid);
$this->assertNoText('Only files with the following extensions are allowed: txt.');
$this->assertText('Article ' . $node->getTitle() . ' has been updated.');
}
}

View file

@ -0,0 +1,42 @@
<?php
/**
* @file
* Contains \Drupal\file\Tests\Migrate\MigrateFileStubTest.
*/
namespace Drupal\file\Tests\Migrate;
use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase;
use Drupal\migrate_drupal\Tests\StubTestTrait;
/**
* Test stub creation for file entities.
*
* @group file
*/
class MigrateFileStubTest extends MigrateDrupalTestBase {
use StubTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['file'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('file');
}
/**
* Tests creation of file stubs.
*/
public function testStub() {
$this->performStubTest('file');
}
}