Update to Drupal 8.0.0-beta15. For more information, see: https://www.drupal.org/node/2563023
This commit is contained in:
parent
2720a9ec4b
commit
f3791f1da3
1898 changed files with 54300 additions and 11481 deletions
|
@ -448,10 +448,12 @@ display:
|
|||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
date_format: medium
|
||||
custom_date_format: ''
|
||||
timezone: ''
|
||||
plugin_id: date
|
||||
type: timestamp
|
||||
settings:
|
||||
date_format: medium
|
||||
custom_date_format: ''
|
||||
timezone: ''
|
||||
plugin_id: field
|
||||
entity_type: file
|
||||
entity_field: created
|
||||
changed:
|
||||
|
@ -502,10 +504,12 @@ display:
|
|||
hide_empty: false
|
||||
empty_zero: false
|
||||
hide_alter_empty: true
|
||||
date_format: medium
|
||||
custom_date_format: ''
|
||||
timezone: ''
|
||||
plugin_id: date
|
||||
type: timestamp
|
||||
settings:
|
||||
date_format: medium
|
||||
custom_date_format: ''
|
||||
timezone: ''
|
||||
plugin_id: field
|
||||
entity_type: file
|
||||
entity_field: changed
|
||||
count:
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
migrate.destination.entity:file:
|
||||
type: migrate_destination
|
||||
label: 'File'
|
||||
mapping:
|
||||
source_path_property:
|
||||
type: string
|
||||
label: 'Source path'
|
|
@ -121,3 +121,11 @@ field.formatter.settings.file_extension:
|
|||
extension_detect_tar:
|
||||
type: boolean
|
||||
label: 'Detect tar'
|
||||
|
||||
migrate.source.d6_upload_instance:
|
||||
type: migrate_source_sql
|
||||
label: 'Drupal 6 upload form display'
|
||||
mapping:
|
||||
constants:
|
||||
type: migrate_entity_constant
|
||||
label: 'Constants'
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldFilteredString;
|
||||
use Drupal\Core\Render\Element;
|
||||
|
||||
/**
|
||||
|
@ -96,13 +96,6 @@ function template_preprocess_file_widget_multiple(&$variables) {
|
|||
// Render everything else together in a column, without the normal wrappers.
|
||||
$widget['#theme_wrappers'] = array();
|
||||
$information = drupal_render($widget);
|
||||
|
||||
// Render the previously hidden elements, using render() instead of
|
||||
// drupal_render(), to undo the earlier hide().
|
||||
$operations = '';
|
||||
foreach ($operations_elements as $operation_element) {
|
||||
$operations .= render($operation_element);
|
||||
}
|
||||
$display = '';
|
||||
if ($element['#display_field']) {
|
||||
unset($widget['display']['#title']);
|
||||
|
@ -121,7 +114,15 @@ function template_preprocess_file_widget_multiple(&$variables) {
|
|||
$row[] = $display;
|
||||
}
|
||||
$row[] = $weight;
|
||||
$row[] = SafeMarkup::set($operations);
|
||||
|
||||
// Show the buttons that had previously been marked as hidden in this
|
||||
// preprocess function. We use show() to undo the earlier hide().
|
||||
foreach (Element::children($operations_elements) as $key) {
|
||||
show($operations_elements[$key]);
|
||||
}
|
||||
$row[] = array(
|
||||
'data' => $operations_elements,
|
||||
);
|
||||
$rows[] = array(
|
||||
'data' => $row,
|
||||
'class' => isset($widget['#attributes']['class']) ? array_merge($widget['#attributes']['class'], array('draggable')) : array('draggable'),
|
||||
|
@ -142,6 +143,7 @@ function template_preprocess_file_widget_multiple(&$variables) {
|
|||
'group' => $weight_class,
|
||||
),
|
||||
),
|
||||
'#access' => !empty($rows),
|
||||
);
|
||||
|
||||
$variables['element'] = $element;
|
||||
|
@ -167,7 +169,7 @@ function template_preprocess_file_upload_help(&$variables) {
|
|||
$descriptions = array();
|
||||
|
||||
if (!empty($description)) {
|
||||
$descriptions[] = Html::normalize($description);
|
||||
$descriptions[] = FieldFilteredString::create($description);
|
||||
}
|
||||
if (isset($cardinality)) {
|
||||
if ($cardinality == -1) {
|
||||
|
|
|
@ -12,9 +12,14 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Attach behaviors to managed file element upload fields.
|
||||
* Attach behaviors to the file fields passed in the settings.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches validation for file extensions.
|
||||
* @prop {Drupal~behaviorDetach} detach
|
||||
* Detaches validation for file extensions.
|
||||
*/
|
||||
Drupal.behaviors.fileValidateAutoAttach = {
|
||||
attach: function (context, settings) {
|
||||
|
@ -50,9 +55,14 @@
|
|||
};
|
||||
|
||||
/**
|
||||
* Attach behaviors to managed file element upload fields.
|
||||
* Attach behaviors to file element auto upload.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches triggers for the upload button.
|
||||
* @prop {Drupal~behaviorDetach} detach
|
||||
* Detaches auto file upload trigger.
|
||||
*/
|
||||
Drupal.behaviors.fileAutoUpload = {
|
||||
attach: function (context) {
|
||||
|
@ -69,6 +79,11 @@
|
|||
* Attach behaviors to the file upload and remove buttons.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches form submit events.
|
||||
* @prop {Drupal~behaviorDetach} detach
|
||||
* Detaches form submit events.
|
||||
*/
|
||||
Drupal.behaviors.fileButtons = {
|
||||
attach: function (context) {
|
||||
|
@ -84,9 +99,14 @@
|
|||
};
|
||||
|
||||
/**
|
||||
* Attach behaviors to links within managed file elements.
|
||||
* Attach behaviors to links within managed file elements for preview windows.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches triggers.
|
||||
* @prop {Drupal~behaviorDetach} detach
|
||||
* Detaches triggers.
|
||||
*/
|
||||
Drupal.behaviors.filePreviewLinks = {
|
||||
attach: function (context) {
|
||||
|
@ -110,6 +130,7 @@
|
|||
* @name Drupal.file.validateExtension
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered. For example `change.fileValidate`.
|
||||
*/
|
||||
validateExtension: function (event) {
|
||||
event.preventDefault();
|
||||
|
@ -146,6 +167,7 @@
|
|||
* @name Drupal.file.triggerUploadButton
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered. For example `change.autoFileUpload`.
|
||||
*/
|
||||
triggerUploadButton: function (event) {
|
||||
$(event.target).closest('.js-form-managed-file').find('.js-form-submit').trigger('mousedown');
|
||||
|
@ -157,6 +179,7 @@
|
|||
* @name Drupal.file.disableFields
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `mousedown` event.
|
||||
*/
|
||||
disableFields: function (event) {
|
||||
var $clickedButton = $(this).findOnce('ajax');
|
||||
|
@ -194,6 +217,7 @@
|
|||
* @name Drupal.file.progressBar
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `mousedown` event.
|
||||
*/
|
||||
progressBar: function (event) {
|
||||
var $clickedButton = $(this);
|
||||
|
@ -221,6 +245,7 @@
|
|||
* @name Drupal.file.openInNewWindow
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `click` event.
|
||||
*/
|
||||
openInNewWindow: function (event) {
|
||||
event.preventDefault();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Defines a "managed_file" Form API field and a "file" field for Field module.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Datetime\Entity\DateFormat;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
@ -629,7 +629,7 @@ function file_file_download($uri) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements file_cron()
|
||||
* Implements hook_cron().
|
||||
*/
|
||||
function file_cron() {
|
||||
$age = \Drupal::config('system.file')->get('temporary_maximum_age');
|
||||
|
@ -968,15 +968,15 @@ function file_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
|
||||
// Essential file data
|
||||
case 'name':
|
||||
$replacements[$original] = $sanitize ? SafeMarkup::checkPlain($file->getFilename()) : $file->getFilename();
|
||||
$replacements[$original] = $sanitize ? Html::escape($file->getFilename()) : $file->getFilename();
|
||||
break;
|
||||
|
||||
case 'path':
|
||||
$replacements[$original] = $sanitize ? SafeMarkup::checkPlain($file->getFileUri()) : $file->getFileUri();
|
||||
$replacements[$original] = $sanitize ? Html::escape($file->getFileUri()) : $file->getFileUri();
|
||||
break;
|
||||
|
||||
case 'mime':
|
||||
$replacements[$original] = $sanitize ? SafeMarkup::checkPlain($file->getMimeType()) : $file->getMimeType();
|
||||
$replacements[$original] = $sanitize ? Html::escape($file->getMimeType()) : $file->getMimeType();
|
||||
break;
|
||||
|
||||
case 'size':
|
||||
|
@ -984,7 +984,7 @@ function file_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
break;
|
||||
|
||||
case 'url':
|
||||
$replacements[$original] = $sanitize ? SafeMarkup::checkPlain(file_create_url($file->getFileUri())) : file_create_url($file->getFileUri());
|
||||
$replacements[$original] = $sanitize ? Html::escape(file_create_url($file->getFileUri())) : file_create_url($file->getFileUri());
|
||||
break;
|
||||
|
||||
// These tokens are default variations on the chained tokens handled below.
|
||||
|
@ -1004,7 +1004,7 @@ function file_tokens($type, $tokens, array $data, array $options, BubbleableMeta
|
|||
$owner = $file->getOwner();
|
||||
$bubbleable_metadata->addCacheableDependency($owner);
|
||||
$name = $owner->label();
|
||||
$replacements[$original] = $sanitize ? SafeMarkup::checkPlain($name) : $name;
|
||||
$replacements[$original] = $sanitize ? Html::escape($name) : $name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1248,7 +1248,7 @@ function template_preprocess_file_link(&$variables) {
|
|||
}
|
||||
else {
|
||||
$link_text = $variables['description'];
|
||||
$options['attributes']['title'] = SafeMarkup::checkPlain($file_entity->getFilename());
|
||||
$options['attributes']['title'] = $file_entity->getFilename();
|
||||
}
|
||||
|
||||
// Classes to add to the file field for icons.
|
||||
|
@ -1274,7 +1274,7 @@ function template_preprocess_file_link(&$variables) {
|
|||
* A MIME type.
|
||||
*
|
||||
* @return string
|
||||
* A class associated to the file.
|
||||
* A class associated with the file.
|
||||
*/
|
||||
function file_icon_class($mime_type) {
|
||||
// Search for a group with the files MIME type.
|
||||
|
|
25
core/modules/file/migration_templates/d6_file.yml
Normal file
25
core/modules/file/migration_templates/d6_file.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Every migration that saves into {file_managed} must have the d6_file
|
||||
# migration as an optional dependency to ensure d6_file runs first.
|
||||
id: d6_file
|
||||
label: Drupal 6 files
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: d6_file
|
||||
process:
|
||||
fid: fid
|
||||
filename: filename
|
||||
uri:
|
||||
plugin: file_uri
|
||||
source:
|
||||
- filepath
|
||||
- file_directory_path
|
||||
- temp_directory_path
|
||||
- is_public
|
||||
filemime: filemime
|
||||
filesize: filesize
|
||||
status: status
|
||||
changed: timestamp
|
||||
uid: uid
|
||||
destination:
|
||||
plugin: entity:file
|
17
core/modules/file/migration_templates/d6_file_settings.yml
Normal file
17
core/modules/file/migration_templates/d6_file_settings.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
id: d6_file_settings
|
||||
label: Drupal 6 file configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: variable
|
||||
variables:
|
||||
- file_description_type
|
||||
- file_description_length
|
||||
- file_icon_directory
|
||||
process:
|
||||
'description/type': file_description_type
|
||||
'description/length': file_description_length
|
||||
'icon/directory': file_icon_directory
|
||||
destination:
|
||||
plugin: config
|
||||
config_name: file.settings
|
27
core/modules/file/migration_templates/d6_upload.yml
Normal file
27
core/modules/file/migration_templates/d6_upload.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
id: d6_upload
|
||||
label: Drupal 6 file uploads
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: d6_upload
|
||||
process:
|
||||
nid: nid
|
||||
vid: vid
|
||||
type: type
|
||||
upload:
|
||||
plugin: iterator
|
||||
source: upload
|
||||
process:
|
||||
target_id:
|
||||
plugin: migration
|
||||
migration: d6_file
|
||||
source: fid
|
||||
display: list
|
||||
description: description
|
||||
destination:
|
||||
plugin: entity:node
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_file
|
||||
- d6_node:*
|
||||
- d6_upload_field_instance
|
|
@ -0,0 +1,27 @@
|
|||
id: d6_upload_entity_display
|
||||
label: Drupal 6 upload display configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: d6_upload_instance
|
||||
constants:
|
||||
entity_type: node
|
||||
view_mode: default
|
||||
name: upload
|
||||
type: file_default
|
||||
options:
|
||||
label: hidden
|
||||
settings: {}
|
||||
process:
|
||||
entity_type: 'constants/entity_type'
|
||||
bundle: node_type
|
||||
view_mode: 'constants/view_mode'
|
||||
field_name: 'constants/name'
|
||||
type: 'constants/type'
|
||||
options: 'constants/options'
|
||||
'options/type': @type
|
||||
destination:
|
||||
plugin: component_entity_display
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_upload_field_instance
|
|
@ -0,0 +1,28 @@
|
|||
id: d6_upload_entity_form_display
|
||||
label: Drupal 6 upload form display configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: d6_upload_instance
|
||||
constants:
|
||||
empty: {}
|
||||
entity_type: node
|
||||
form_mode: default
|
||||
name: upload
|
||||
type: file_generic
|
||||
options:
|
||||
settings:
|
||||
progress_indicator: throbber
|
||||
process:
|
||||
entity_type: 'constants/entity_type'
|
||||
bundle: node_type
|
||||
field_name: 'constants/name'
|
||||
form_mode: 'constants/form_mode'
|
||||
type: 'constants/type'
|
||||
options: 'constants/options'
|
||||
'options/type': @type
|
||||
destination:
|
||||
plugin: component_entity_form_display
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_upload_field_instance
|
23
core/modules/file/migration_templates/d6_upload_field.yml
Normal file
23
core/modules/file/migration_templates/d6_upload_field.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
id: d6_upload_field
|
||||
label: Drupal 6 upload field configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
# We do an empty source and a proper destination to have an idmap for
|
||||
# migration_dependencies.
|
||||
plugin: md_empty
|
||||
provider: upload
|
||||
constants:
|
||||
entity_type: node
|
||||
type: file
|
||||
name: upload
|
||||
cardinality: -1
|
||||
display_field: true
|
||||
process:
|
||||
entity_type: 'constants/entity_type'
|
||||
field_name: 'constants/name'
|
||||
type: 'constants/type'
|
||||
cardinality: 'constants/cardinality'
|
||||
'settings/display_field': 'constants/display_field'
|
||||
destination:
|
||||
plugin: md_entity:field_storage_config
|
|
@ -0,0 +1,24 @@
|
|||
id: d6_upload_field_instance
|
||||
label: Drupal 6 upload field instance configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
plugin: d6_upload_instance
|
||||
constants:
|
||||
entity_type: node
|
||||
name: upload
|
||||
settings:
|
||||
description_field: 1
|
||||
process:
|
||||
entity_type: 'constants/entity_type'
|
||||
bundle: node_type
|
||||
field_name: 'constants/name'
|
||||
settings: 'constants/settings'
|
||||
'settings/file_extensions': file_extensions
|
||||
'settings/max_filesize': max_filesize
|
||||
destination:
|
||||
plugin: entity:field_config
|
||||
migration_dependencies:
|
||||
required:
|
||||
- d6_upload_field
|
||||
- d6_node_type
|
25
core/modules/file/migration_templates/d7_file.yml
Normal file
25
core/modules/file/migration_templates/d7_file.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Every migration that references a file by fid should specify this migration
|
||||
# as an optional dependency.
|
||||
id: d7_file
|
||||
label: Drupal 7 files
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
source:
|
||||
plugin: d7_file
|
||||
process:
|
||||
fid: fid
|
||||
filename: filename
|
||||
uri: uri
|
||||
filemime: filemime
|
||||
# filesize is dynamically computed when file entities are saved, so there is
|
||||
# no point in migrating it.
|
||||
# filesize: filesize
|
||||
status: status
|
||||
# Drupal 7 didn't keep track of the file's creation or update time -- all it
|
||||
# had was the vague "timestamp" column. So we'll use it for both.
|
||||
created: timestamp
|
||||
changed: timestamp
|
||||
uid: uid
|
||||
destination:
|
||||
plugin: entity:file
|
||||
source_path_property: filepath
|
|
@ -22,10 +22,13 @@ class FileAccessControlHandler extends EntityAccessControlHandler {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
|
||||
|
||||
/** @var \Drupal\file\FileInterface $entity */
|
||||
if ($operation == 'download' || $operation == 'view') {
|
||||
$references = $this->getFileReferences($entity);
|
||||
if ($references) {
|
||||
if (\Drupal::service('file_system')->uriScheme($entity->getFileUri()) === 'public') {
|
||||
// Always allow access to file in public file system.
|
||||
return AccessResult::allowed();
|
||||
}
|
||||
elseif ($references = $this->getFileReferences($entity)) {
|
||||
foreach ($references as $field_name => $entity_map) {
|
||||
foreach ($entity_map as $referencing_entity_type => $referencing_entities) {
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $referencing_entity */
|
||||
|
|
|
@ -56,17 +56,17 @@ abstract class BaseFieldFileFormatterBase extends FormatterBase {
|
|||
}
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
$string = $this->viewValue($item);
|
||||
$view_value = $this->viewValue($item);
|
||||
|
||||
if ($url) {
|
||||
$elements[$delta] = [
|
||||
'#type' => 'link',
|
||||
'#title' => $string,
|
||||
'#title' => $view_value,
|
||||
'#url' => Url::fromUri($url),
|
||||
];
|
||||
}
|
||||
else {
|
||||
$elements[$delta] = is_array($string) ? $string : ['#markup' => $string];
|
||||
$elements[$delta] = is_array($view_value) ? $view_value : ['#markup' => $view_value];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
namespace Drupal\file\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldFilteredString;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Field\WidgetBase;
|
||||
|
@ -118,8 +118,8 @@ class FileWidget extends WidgetBase implements ContainerFactoryPluginInterface {
|
|||
break;
|
||||
}
|
||||
|
||||
$title = SafeMarkup::checkPlain($this->fieldDefinition->getLabel());
|
||||
$description = $this->fieldFilterXss($this->fieldDefinition->getDescription());
|
||||
$title = $this->fieldDefinition->getLabel();
|
||||
$description = FieldFilteredString::create($this->fieldDefinition->getDescription());
|
||||
|
||||
$elements = array();
|
||||
|
||||
|
|
52
core/modules/file/src/Plugin/migrate/cckfield/FileField.php
Normal file
52
core/modules/file/src/Plugin/migrate/cckfield/FileField.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\migrate\cckfield\FileField.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\cckfield;
|
||||
|
||||
use Drupal\migrate\Entity\MigrationInterface;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
||||
|
||||
/**
|
||||
* @PluginID("filefield")
|
||||
*/
|
||||
class FileField extends CckFieldPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldWidgetMap() {
|
||||
return [
|
||||
'filefield_widget' => 'file_generic',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldFormatterMap() {
|
||||
return [
|
||||
'default' => 'file_default',
|
||||
'url_plain' => 'file_url_plain',
|
||||
'path_plain' => 'file_url_plain',
|
||||
'image_plain' => 'image',
|
||||
'image_nodelink' => 'image',
|
||||
'image_imagelink' => 'image',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) {
|
||||
$process = [
|
||||
'plugin' => 'd6_cck_file',
|
||||
'source' => $field_name,
|
||||
];
|
||||
$migration->mergeProcessOfProperty($field_name, $process);
|
||||
}
|
||||
|
||||
}
|
245
core/modules/file/src/Plugin/migrate/destination/EntityFile.php
Normal file
245
core/modules/file/src/Plugin/migrate/destination/EntityFile.php
Normal file
|
@ -0,0 +1,245 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\migrate\Plugin\migrate\destination\EntityFile.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\File\FileSystemInterface;
|
||||
use Drupal\Core\StreamWrapper\LocalStream;
|
||||
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
|
||||
use Drupal\migrate\Entity\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Every migration that uses this destination must have an optional
|
||||
* dependency on the d6_file migration to ensure it runs first.
|
||||
*
|
||||
* @MigrateDestination(
|
||||
* id = "entity:file"
|
||||
* )
|
||||
*/
|
||||
class EntityFile extends EntityContentBase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
|
||||
*/
|
||||
protected $streamWrapperManager;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\File\FileSystemInterface
|
||||
*/
|
||||
protected $fileSystem;
|
||||
|
||||
/**
|
||||
* {@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) {
|
||||
$configuration += array(
|
||||
'source_base_path' => '',
|
||||
'source_path_property' => 'filepath',
|
||||
'destination_path_property' => 'uri',
|
||||
'move' => FALSE,
|
||||
'urlencode' => FALSE,
|
||||
);
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager);
|
||||
|
||||
$this->streamWrapperManager = $stream_wrappers;
|
||||
$this->fileSystem = $file_system;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
|
||||
$entity_type = static::getEntityTypeId($plugin_id);
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$migration,
|
||||
$container->get('entity.manager')->getStorage($entity_type),
|
||||
array_keys($container->get('entity.manager')->getBundleInfo($entity_type)),
|
||||
$container->get('entity.manager'),
|
||||
$container->get('stream_wrapper_manager'),
|
||||
$container->get('file_system')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function import(Row $row, array $old_destination_id_values = array()) {
|
||||
$file = $row->getSourceProperty($this->configuration['source_path_property']);
|
||||
$destination = $row->getDestinationProperty($this->configuration['destination_path_property']);
|
||||
$source = $this->configuration['source_base_path'] . $file;
|
||||
|
||||
// Ensure the source file exists, if it's a local URI or path.
|
||||
if ($this->isLocalUri($source) && !file_exists($source)) {
|
||||
throw new MigrateException("File '$source' does not exist.");
|
||||
}
|
||||
|
||||
// If the start and end file is exactly the same, there is nothing to do.
|
||||
if ($this->isLocationUnchanged($source, $destination)) {
|
||||
return parent::import($row, $old_destination_id_values);
|
||||
}
|
||||
|
||||
$replace = $this->getOverwriteMode($row);
|
||||
$success = $this->writeFile($source, $destination, $replace);
|
||||
if (!$success) {
|
||||
$dir = $this->getDirectory($destination);
|
||||
if (file_prepare_directory($dir, FILE_CREATE_DIRECTORY)) {
|
||||
$success = $this->writeFile($source, $destination, $replace);
|
||||
}
|
||||
else {
|
||||
throw new MigrateException("Could not create directory '$dir'");
|
||||
}
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
return parent::import($row, $old_destination_id_values);
|
||||
}
|
||||
else {
|
||||
throw new MigrateException("File $source could not be copied to $destination.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to move or copy a file.
|
||||
*
|
||||
* @param string $source
|
||||
* The source path or URI.
|
||||
* @param string $destination
|
||||
* The destination path or URI.
|
||||
* @param integer $replace
|
||||
* FILE_EXISTS_REPLACE (default) or FILE_EXISTS_RENAME.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE on success, FALSE on failure.
|
||||
*/
|
||||
protected function writeFile($source, $destination, $replace = FILE_EXISTS_REPLACE) {
|
||||
if ($this->configuration['move']) {
|
||||
return (boolean) file_unmanaged_move($source, $destination, $replace);
|
||||
}
|
||||
else {
|
||||
$destination = file_destination($destination, $replace);
|
||||
$source = $this->urlencode($source);
|
||||
return @copy($source, $destination);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines how to handle file conflicts.
|
||||
*
|
||||
* @param \Drupal\migrate\Row $row
|
||||
*
|
||||
* @return integer
|
||||
* Either FILE_EXISTS_REPLACE (default) or FILE_EXISTS_RENAME, depending
|
||||
* on the current configuration.
|
||||
*/
|
||||
protected function getOverwriteMode(Row $row) {
|
||||
if (!empty($this->configuration['rename'])) {
|
||||
$entity_id = $row->getDestinationProperty($this->getKey('id'));
|
||||
if ($entity_id && ($entity = $this->storage->load($entity_id))) {
|
||||
return FILE_EXISTS_RENAME;
|
||||
}
|
||||
}
|
||||
return FILE_EXISTS_REPLACE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory component of a URI or path.
|
||||
*
|
||||
* For URIs like public://foo.txt, the full physical path of public://
|
||||
* will be returned, since a scheme by itself will trip up certain file
|
||||
* API functions (such as file_prepare_directory()).
|
||||
*
|
||||
* @param string $uri
|
||||
* The URI or path.
|
||||
*
|
||||
* @return string|false
|
||||
* The directory component of the path or URI, or FALSE if it could not
|
||||
* be determined.
|
||||
*/
|
||||
protected function getDirectory($uri) {
|
||||
$dir = $this->fileSystem->dirname($uri);
|
||||
if (substr($dir, -3) == '://') {
|
||||
return $this->fileSystem->realpath($dir);
|
||||
}
|
||||
else {
|
||||
return $dir;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the source and destination URIs represent identical paths.
|
||||
* If either URI is a remote stream, will return FALSE.
|
||||
*
|
||||
* @param string $source
|
||||
* The source URI.
|
||||
* @param string $destination
|
||||
* The destination URI.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the source and destination URIs refer to the same physical path,
|
||||
* otherwise FALSE.
|
||||
*/
|
||||
protected function isLocationUnchanged($source, $destination) {
|
||||
if ($this->isLocalUri($source) && $this->isLocalUri($destination)) {
|
||||
return $this->fileSystem->realpath($source) === $this->fileSystem->realpath($destination);
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given URI or path is considered local.
|
||||
*
|
||||
* A URI or path is considered local if it either has no scheme component,
|
||||
* or the scheme is implemented by a stream wrapper which extends
|
||||
* \Drupal\Core\StreamWrapper\LocalStream.
|
||||
*
|
||||
* @param string $uri
|
||||
* The URI or path to test.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLocalUri($uri) {
|
||||
$scheme = $this->fileSystem->uriScheme($uri);
|
||||
return $scheme === FALSE || $this->streamWrapperManager->getViaScheme($scheme) instanceof LocalStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Urlencode all the components of a remote filename.
|
||||
*
|
||||
* @param string $filename
|
||||
* The filename of the file to be urlencoded.
|
||||
*
|
||||
* @return string
|
||||
* The urlencoded filename.
|
||||
*/
|
||||
protected function urlencode($filename) {
|
||||
// Only apply to a full URL
|
||||
if ($this->configuration['urlencode'] && strpos($filename, '://')) {
|
||||
$components = explode('/', $filename);
|
||||
foreach ($components as $key => $component) {
|
||||
$components[$key] = rawurlencode($component);
|
||||
}
|
||||
$filename = implode('/', $components);
|
||||
// Actually, we don't want certain characters encoded
|
||||
$filename = str_replace('%3A', ':', $filename);
|
||||
$filename = str_replace('%3F', '?', $filename);
|
||||
$filename = str_replace('%26', '&', $filename);
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
|
||||
}
|
102
core/modules/file/src/Plugin/migrate/process/d6/CckFile.php
Normal file
102
core/modules/file/src/Plugin/migrate/process/d6/CckFile.php
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\migrate\process\d6\CckFile.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\Entity\MigrationInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\MigrateSkipRowException;
|
||||
use Drupal\migrate\Plugin\MigrateProcessInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "d6_cck_file"
|
||||
* )
|
||||
*/
|
||||
class CckFile extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
protected $migrationPlugin;
|
||||
|
||||
/**
|
||||
* Constructs a CckFile plugin instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin definition.
|
||||
* @param \Drupal\migrate\Entity\MigrationInterface $migration
|
||||
* The current migration.
|
||||
* @param \Drupal\migrate\Plugin\MigrateProcessInterface $migration_plugin
|
||||
* An instance of the 'migration' process plugin.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrateProcessInterface $migration_plugin) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->migration = $migration;
|
||||
$this->migrationPlugin = $migration_plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
|
||||
// Configure the migration process plugin to look up migrated IDs from
|
||||
// the d6_file migration.
|
||||
$migration_plugin_configuration = [
|
||||
'source' => ['fid'],
|
||||
'migration' => 'd6_file',
|
||||
];
|
||||
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$migration,
|
||||
$container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_plugin_configuration, $migration)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$options = unserialize($value['data']);
|
||||
|
||||
// Try to look up the ID of the migrated file. If one cannot be found, it
|
||||
// means the file referenced by the current field item did not migrate for
|
||||
// some reason -- file migration is notoriously brittle -- and we do NOT
|
||||
// want to send invalid file references into the field system (it causes
|
||||
// fatals), so return an empty item instead.
|
||||
try {
|
||||
$fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property);
|
||||
}
|
||||
// If the migration plugin completely fails its lookup process, it will
|
||||
// throw a MigrateSkipRowException. It shouldn't, but that is being dealt
|
||||
// with at https://www.drupal.org/node/2487568. Until that lands, return
|
||||
// an empty item.
|
||||
catch (MigrateSkipRowException $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($fid) {
|
||||
return [
|
||||
'target_id' => $fid,
|
||||
'display' => $value['list'],
|
||||
'description' => isset($options['description']) ? $options['description'] : '',
|
||||
];
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
43
core/modules/file/src/Plugin/migrate/process/d6/FileUri.php
Normal file
43
core/modules/file/src/Plugin/migrate/process/d6/FileUri.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\migrate\process\d6\FileUri.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* Process the file url into a D8 compatible URL.
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "file_uri"
|
||||
* )
|
||||
*/
|
||||
class FileUri extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
|
||||
list($filepath, $file_directory_path, $temp_directory_path, $is_public) = $value;
|
||||
|
||||
// Specific handling using $temp_directory_path for temporary files.
|
||||
if (substr($filepath, 0, strlen($temp_directory_path)) === $temp_directory_path) {
|
||||
$uri = preg_replace('/^' . preg_quote($temp_directory_path, '/') . '/', '', $filepath);
|
||||
return "temporary://$uri";
|
||||
}
|
||||
|
||||
// Strip the files path from the uri instead of using basename
|
||||
// so any additional folders in the path are preserved.
|
||||
$uri = preg_replace('/^' . preg_quote($file_directory_path, '/') . '/', '', $filepath);
|
||||
|
||||
return $is_public ? "public://$uri" : "private://$uri";
|
||||
}
|
||||
|
||||
}
|
108
core/modules/file/src/Plugin/migrate/source/d6/File.php
Normal file
108
core/modules/file/src/Plugin/migrate/source/d6/File.php
Normal file
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\migrate\source\d6\File.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 6 file source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_file"
|
||||
* )
|
||||
*/
|
||||
class File extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* The file directory path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filePath;
|
||||
|
||||
/**
|
||||
* The temporary file path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tempFilePath;
|
||||
|
||||
/**
|
||||
* Flag for private or public file storage.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isPublic;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('files', 'f')->fields('f', array(
|
||||
'fid',
|
||||
'uid',
|
||||
'filename',
|
||||
'filepath',
|
||||
'filemime',
|
||||
'filesize',
|
||||
'status',
|
||||
'timestamp',
|
||||
));
|
||||
$query->orderBy('timestamp');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initializeIterator() {
|
||||
$site_path = isset($this->configuration['site_path']) ? $this->configuration['site_path'] : 'sites/default';
|
||||
$this->filePath = $this->variableGet('file_directory_path', $site_path . '/files') . '/';
|
||||
$this->tempFilePath = $this->variableGet('file_directory_temp', '/tmp') . '/';
|
||||
|
||||
// FILE_DOWNLOADS_PUBLIC == 1 and FILE_DOWNLOADS_PRIVATE == 2.
|
||||
$this->isPublic = $this->variableGet('file_downloads', 1) == 1;
|
||||
return parent::initializeIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$row->setSourceProperty('file_directory_path', $this->filePath);
|
||||
$row->setSourceProperty('temp_directory_path', $this->tempFilePath);
|
||||
$row->setSourceProperty('is_public', $this->isPublic);
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'fid' => $this->t('File ID'),
|
||||
'uid' => $this->t('The {users}.uid who added the file. If set to 0, this file was added by an anonymous user.'),
|
||||
'filename' => $this->t('File name'),
|
||||
'filepath' => $this->t('File path'),
|
||||
'filemime' => $this->t('File Mime Type'),
|
||||
'status' => $this->t('The published status of a file.'),
|
||||
'timestamp' => $this->t('The time that the file was added.'),
|
||||
'file_directory_path' => $this->t('The Drupal files path.'),
|
||||
'is_public' => $this->t('TRUE if the files directory is public otherwise FALSE.'),
|
||||
);
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['fid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
77
core/modules/file/src/Plugin/migrate/source/d6/Upload.php
Normal file
77
core/modules/file/src/Plugin/migrate/source/d6/Upload.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\migrate\source\d6\Upload.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 6 upload source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_upload",
|
||||
* source_provider = "upload"
|
||||
* )
|
||||
*/
|
||||
class Upload extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* The join options between the node and the upload table.
|
||||
*/
|
||||
const JOIN = 'n.nid = u.nid AND n.vid = u.vid';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('upload', 'u')
|
||||
->distinct()
|
||||
->fields('u', array('nid', 'vid'));
|
||||
$query->innerJoin('node', 'n', static::JOIN);
|
||||
$query->addField('n', 'type');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$query = $this->select('upload', 'u')
|
||||
->fields('u', array('fid', 'description', 'list'))
|
||||
->condition('u.nid', $row->getSourceProperty('nid'))
|
||||
->orderBy('u.weight');
|
||||
$query->innerJoin('node', 'n', static::JOIN);
|
||||
$row->setSourceProperty('upload', $query->execute()->fetchAll());
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'fid' => $this->t('The file Id.'),
|
||||
'nid' => $this->t('The node Id.'),
|
||||
'vid' => $this->t('The version Id.'),
|
||||
'type' => $this->t('The node type'),
|
||||
'description' => $this->t('The file description.'),
|
||||
'list' => $this->t('Whether the list should be visible on the node page.'),
|
||||
'weight' => $this->t('The file weight.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['vid']['type'] = 'integer';
|
||||
$ids['vid']['alias'] = 'u';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\migrate\source\d6\UploadInstance.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
use Drupal\migrate\Plugin\migrate\source\DummyQueryTrait;
|
||||
|
||||
/**
|
||||
* Drupal 6 upload instance source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_upload_instance",
|
||||
* source_provider = "upload"
|
||||
* )
|
||||
*/
|
||||
class UploadInstance extends DrupalSqlBase {
|
||||
|
||||
use DummyQueryTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initializeIterator() {
|
||||
$prefix = 'upload';
|
||||
$node_types = $this->getDatabase()->query('SELECT type FROM {node_type}')->fetchCol();
|
||||
foreach ($node_types as $node_type) {
|
||||
$variables[] = $prefix . '_' . $node_type;
|
||||
}
|
||||
|
||||
$max_filesize = $this->variableGet('upload_uploadsize_default', 1);
|
||||
$max_filesize = $max_filesize ? $max_filesize . 'MB' : '';
|
||||
$file_extensions = $this->variableGet('upload_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp');
|
||||
$return = array();
|
||||
$values = $this->getDatabase()->query('SELECT name, value FROM {variable} WHERE name IN ( :name[] )', array(':name[]' => $variables))->fetchAllKeyed();
|
||||
foreach ($node_types as $node_type) {
|
||||
$name = $prefix . '_' . $node_type;
|
||||
if (isset($values[$name])) {
|
||||
$enabled = unserialize($values[$name]);
|
||||
if ($enabled) {
|
||||
$return[$node_type]['node_type'] = $node_type;
|
||||
$return[$node_type]['max_filesize'] = $max_filesize;
|
||||
$return[$node_type]['file_extensions'] = $file_extensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new \ArrayIterator($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return array(
|
||||
'node_type' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'node_type' => $this->t('Node type'),
|
||||
'max_filesize' => $this->t('Max filesize'),
|
||||
'file_extensions' => $this->t('File extensions'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->initializeIterator());
|
||||
}
|
||||
|
||||
}
|
100
core/modules/file/src/Plugin/migrate/source/d7/File.php
Normal file
100
core/modules/file/src/Plugin/migrate/source/d7/File.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Plugin\migrate\source\d7\File.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 7 file source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_file"
|
||||
* )
|
||||
*/
|
||||
class File extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* The public file directory path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $publicPath;
|
||||
|
||||
/**
|
||||
* The private file directory path, if any.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $privatePath;
|
||||
|
||||
/**
|
||||
* The temporary file directory path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $temporaryPath;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('file_managed', 'f')
|
||||
->fields('f')
|
||||
->orderBy('timestamp');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initializeIterator() {
|
||||
$this->publicPath = $this->variableGet('file_public_path', 'sites/default/files');
|
||||
$this->privatePath = $this->variableGet('file_private_path', NULL);
|
||||
$this->temporaryPath = $this->variableGet('file_temporary_path', '/tmp');
|
||||
return parent::initializeIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
// Compute the filepath property, which is a physical representation of
|
||||
// the URI relative to the Drupal root.
|
||||
$path = str_replace(['public:/', 'private:/', 'temporary:/'], [$this->publicPath, $this->privatePath, $this->temporaryPath], $row->getSourceProperty('uri'));
|
||||
// At this point, $path could be an absolute path or a relative path,
|
||||
// depending on how the scheme's variable was set. So we need to shear out
|
||||
// the source_base_path in order to make them all relative.
|
||||
$path = str_replace($this->migration->get('destination.source_base_path'), NULL, $path);
|
||||
$row->setSourceProperty('filepath', $path);
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'fid' => $this->t('File ID'),
|
||||
'uid' => $this->t('The {users}.uid who added the file. If set to 0, this file was added by an anonymous user.'),
|
||||
'filename' => $this->t('File name'),
|
||||
'filepath' => $this->t('File path'),
|
||||
'filemime' => $this->t('File Mime Type'),
|
||||
'status' => $this->t('The published status of a file.'),
|
||||
'timestamp' => $this->t('The time that the file was added.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['fid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,6 @@ namespace Drupal\file\Plugin\views\argument;
|
|||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\Query\QueryFactory;
|
||||
use Drupal\views\Plugin\views\argument\NumericArgument;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
|
@ -81,7 +80,7 @@ class Fid extends NumericArgument implements ContainerFactoryPluginInterface {
|
|||
$files = $controller->loadMultiple($fids);
|
||||
$titles = array();
|
||||
foreach ($files as $file) {
|
||||
$titles[] = SafeMarkup::checkPlain($file->getFilename());
|
||||
$titles[] = $file->getFilename();
|
||||
}
|
||||
return $titles;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,12 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
|||
}
|
||||
|
||||
$test_file = $this->getTestFile('text');
|
||||
simpletest_generate_file('escaped-&-text', 64, 10, 'text');
|
||||
$test_file = File::create([
|
||||
'uri' => 'public://escaped-&-text.txt',
|
||||
'name' => 'escaped-&-text',
|
||||
'filesize' => filesize('public://escaped-&-text.txt'),
|
||||
]);
|
||||
|
||||
// Create a new node with the uploaded file.
|
||||
$nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
|
||||
|
@ -81,6 +87,9 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
|||
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
|
||||
$this->assertText($description);
|
||||
|
||||
// Ensure the filename in the link's title attribute is escaped.
|
||||
$this->assertRaw('title="escaped-&-text.txt"');
|
||||
|
||||
// Test that fields appear as expected after during the preview.
|
||||
// Add a second file.
|
||||
$name = 'files[' . $field_name . '_1][]';
|
||||
|
|
|
@ -35,7 +35,7 @@ class FileFieldValidateTest extends FileFieldTestBase {
|
|||
$edit = array();
|
||||
$edit['title[0][value]'] = $this->randomMachineName();
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
|
||||
$this->assertText('1 error has been found: ' . $field->label(), 'Node save failed when required file field was empty.');
|
||||
$this->assertText('1 error has been found: ' . $field->label(), 'Node save failed when required file field was empty.');
|
||||
$this->assertIdentical(1, count($this->xpath('//div[contains(concat(" ", normalize-space(@class), " "), :class)]//a', [':class' => ' messages--error '])), 'There is one link in the error message.');
|
||||
|
||||
// Create a new node with the uploaded file.
|
||||
|
@ -57,7 +57,7 @@ class FileFieldValidateTest extends FileFieldTestBase {
|
|||
$edit = array();
|
||||
$edit['title[0][value]'] = $this->randomMachineName();
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
|
||||
$this->assertText('1 error has been found: ' . $field->label(), 'Node save failed when required multiple value file field was empty.');
|
||||
$this->assertText('1 error has been found: ' . $field->label(), 'Node save failed when required multiple value file field was empty.');
|
||||
$this->assertIdentical(1, count($this->xpath('//div[contains(concat(" ", normalize-space(@class), " "), :class)]//a', [':class' => ' messages--error '])), 'There is one link in the error message.');
|
||||
|
||||
// Create a new node with the uploaded file into the multivalue field.
|
||||
|
|
|
@ -9,7 +9,9 @@ namespace Drupal\file\Tests;
|
|||
|
||||
use Drupal\comment\Entity\Comment;
|
||||
use Drupal\comment\Tests\CommentTestTrait;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field_ui\Tests\FieldUiTestTrait;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Drupal\file\Entity\File;
|
||||
|
@ -419,4 +421,32 @@ class FileFieldWidgetTest extends FileFieldTestBase {
|
|||
$this->assertNoRaw($error_message, t('Validation error removed when file with correct extension uploaded (JSMode=%type).', array('%type' => $type)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests file widget element.
|
||||
*/
|
||||
public function testWidgetElement() {
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$html_name = str_replace('_', '-', $field_name);
|
||||
$this->createFileField($field_name, 'node', 'article', ['cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED]);
|
||||
$file = $this->getTestFile('text');
|
||||
$xpath = "//details[@data-drupal-selector='edit-$html_name']/div[@class='details-wrapper']/table";
|
||||
|
||||
$this->drupalGet('node/add/article');
|
||||
|
||||
$elements = $this->xpath($xpath);
|
||||
|
||||
// If the field has no item, the table should not be visible.
|
||||
$this->assertIdentical(count($elements), 0);
|
||||
|
||||
// Upload a file.
|
||||
$edit['files[' . $field_name . '_0][]'] = $this->container->get('file_system')->realpath($file->getFileUri());
|
||||
$this->drupalPostAjaxForm(NULL, $edit, "{$field_name}_0_upload_button");
|
||||
|
||||
$elements = $this->xpath($xpath);
|
||||
|
||||
// If the field has at least a item, the table should be visible.
|
||||
$this->assertIdentical(count($elements), 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
73
core/modules/file/src/Tests/FileManagedAccessTest.php
Normal file
73
core/modules/file/src/Tests/FileManagedAccessTest.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\FileManagedAccessTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests;
|
||||
|
||||
use Drupal\file\Entity\File;
|
||||
|
||||
/**
|
||||
* Tests access to managed files.
|
||||
*
|
||||
* @group file
|
||||
*/
|
||||
class FileManagedAccessTest extends FileManagedTestBase {
|
||||
|
||||
/**
|
||||
* Tests if public file is always accessible.
|
||||
*/
|
||||
function testFileAccess() {
|
||||
// Create a new file entity.
|
||||
$file = File::create(array(
|
||||
'uid' => 1,
|
||||
'filename' => 'drupal.txt',
|
||||
'uri' => 'public://drupal.txt',
|
||||
'filemime' => 'text/plain',
|
||||
'status' => FILE_STATUS_PERMANENT,
|
||||
));
|
||||
file_put_contents($file->getFileUri(), 'hello world');
|
||||
|
||||
// Save it, inserting a new record.
|
||||
$file->save();
|
||||
|
||||
// Create authenticated user to check file access.
|
||||
$account = $this->createUser(array('access site reports'));
|
||||
|
||||
$this->assertTrue($file->access('view', $account), 'Public file is viewable to authenticated user');
|
||||
$this->assertTrue($file->access('download', $account), 'Public file is downloadable to authenticated user');
|
||||
|
||||
// Create anonymous user to check file access.
|
||||
$account = $this->createUser()->getAnonymousUser();
|
||||
|
||||
$this->assertTrue($file->access('view', $account), 'Public file is viewable to anonymous user');
|
||||
$this->assertTrue($file->access('download', $account), 'Public file is downloadable to anonymous user');
|
||||
|
||||
// Create a new file entity.
|
||||
$file = File::create(array(
|
||||
'uid' => 1,
|
||||
'filename' => 'drupal.txt',
|
||||
'uri' => 'private://drupal.txt',
|
||||
'filemime' => 'text/plain',
|
||||
'status' => FILE_STATUS_PERMANENT,
|
||||
));
|
||||
file_put_contents($file->getFileUri(), 'hello world');
|
||||
|
||||
// Save it, inserting a new record.
|
||||
$file->save();
|
||||
|
||||
// Create authenticated user to check file access.
|
||||
$account = $this->createUser(array('access site reports'));
|
||||
|
||||
$this->assertFalse($file->access('view', $account), 'Private file is not viewable to authenticated user');
|
||||
$this->assertFalse($file->access('download', $account), 'Private file is not downloadable to authenticated user');
|
||||
|
||||
// Create anonymous user to check file access.
|
||||
$account = $this->createUser()->getAnonymousUser();
|
||||
|
||||
$this->assertFalse($file->access('view', $account), 'Private file is not viewable to anonymous user');
|
||||
$this->assertFalse($file->access('download', $account), 'Private file is not downloadable to anonymous user');
|
||||
}
|
||||
}
|
|
@ -37,6 +37,18 @@ class FileManagedFileElementTest extends FileFieldTestBase {
|
|||
$this->drupalPostForm($path, array(), t('Save'));
|
||||
$this->assertRaw(t('The file ids are %fids.', array('%fids' => implode(',', array()))), 'Submitted without a file.');
|
||||
|
||||
// Submit with a file, but with an invalid form token. Ensure the file
|
||||
// was not saved.
|
||||
$last_fid_prior = $this->getLastFileId();
|
||||
$edit = [
|
||||
$file_field_name => drupal_realpath($test_file->getFileUri()),
|
||||
'form_token' => 'invalid token',
|
||||
];
|
||||
$this->drupalPostForm($path, $edit, t('Save'));
|
||||
$this->assertText('The form has become outdated. Copy any unsaved work in the form below');
|
||||
$last_fid = $this->getLastFileId();
|
||||
$this->assertEqual($last_fid_prior, $last_fid, 'File was not saved when uploaded with an invalid form token.');
|
||||
|
||||
// Submit a new file, without using the Upload button.
|
||||
$last_fid_prior = $this->getLastFileId();
|
||||
$edit = array($file_field_name => drupal_realpath($test_file->getFileUri()));
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\file\Tests;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Drupal\file\Entity\File;
|
||||
|
||||
|
@ -47,16 +47,16 @@ class FileTokenReplaceTest extends FileFieldTestBase {
|
|||
// Generate and test sanitized tokens.
|
||||
$tests = array();
|
||||
$tests['[file:fid]'] = $file->id();
|
||||
$tests['[file:name]'] = SafeMarkup::checkPlain($file->getFilename());
|
||||
$tests['[file:path]'] = SafeMarkup::checkPlain($file->getFileUri());
|
||||
$tests['[file:mime]'] = SafeMarkup::checkPlain($file->getMimeType());
|
||||
$tests['[file:name]'] = Html::escape($file->getFilename());
|
||||
$tests['[file:path]'] = Html::escape($file->getFileUri());
|
||||
$tests['[file:mime]'] = Html::escape($file->getMimeType());
|
||||
$tests['[file:size]'] = format_size($file->getSize());
|
||||
$tests['[file:url]'] = SafeMarkup::checkPlain(file_create_url($file->getFileUri()));
|
||||
$tests['[file:url]'] = Html::escape(file_create_url($file->getFileUri()));
|
||||
$tests['[file:created]'] = format_date($file->getCreatedTime(), 'medium', '', NULL, $language_interface->getId());
|
||||
$tests['[file:created:short]'] = format_date($file->getCreatedTime(), 'short', '', NULL, $language_interface->getId());
|
||||
$tests['[file:changed]'] = format_date($file->getChangedTime(), 'medium', '', NULL, $language_interface->getId());
|
||||
$tests['[file:changed:short]'] = format_date($file->getChangedTime(), 'short', '', NULL, $language_interface->getId());
|
||||
$tests['[file:owner]'] = SafeMarkup::checkPlain(user_format_name($this->adminUser));
|
||||
$tests['[file:owner]'] = Html::escape(user_format_name($this->adminUser));
|
||||
$tests['[file:owner:uid]'] = $file->getOwnerId();
|
||||
|
||||
$base_bubbleable_metadata = BubbleableMetadata::createFromObject($file);
|
||||
|
|
295
core/modules/file/src/Tests/Migrate/EntityFileTest.php
Normal file
295
core/modules/file/src/Tests/Migrate/EntityFileTest.php
Normal file
|
@ -0,0 +1,295 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\EntityFileTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate;
|
||||
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\file\Plugin\migrate\destination\EntityFile;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the entity file destination plugin.
|
||||
*
|
||||
* @group file
|
||||
*/
|
||||
class EntityFileTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system', 'entity_test', 'user', 'file');
|
||||
|
||||
/**
|
||||
* @var \Drupal\file\Tests\Migrate\TestEntityFile $destination
|
||||
*/
|
||||
protected $destination;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->destination = new TestEntityFile([]);
|
||||
$this->destination->streamWrapperManager = \Drupal::getContainer()->get('stream_wrapper_manager');
|
||||
$this->destination->fileSystem = \Drupal::getContainer()->get('file_system');
|
||||
$this->installEntitySchema('file');
|
||||
|
||||
file_put_contents('/tmp/test-file.jpg', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test successful imports/copies.
|
||||
*/
|
||||
public function testSuccessfulCopies() {
|
||||
foreach ($this->localFileDataProvider() as $data) {
|
||||
list($row_values, $destination_path, $expected, $source_base_path) = $data;
|
||||
|
||||
$this->doImport($row_values, $destination_path, $source_base_path);
|
||||
$message = $expected ? sprintf('File %s exists', $destination_path) : sprintf('File %s does not exist', $destination_path);
|
||||
$this->assertIdentical($expected, is_file($destination_path), $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The data provider for testing the file destination.
|
||||
*
|
||||
* @return array
|
||||
* An array of file permutations to test.
|
||||
*/
|
||||
protected function localFileDataProvider() {
|
||||
global $base_url;
|
||||
return [
|
||||
// Test a local to local copy.
|
||||
[['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://file1.jpg', TRUE, DRUPAL_ROOT . '/'],
|
||||
// Test a temporary file using an absolute path.
|
||||
[['filepath' => '/tmp/test-file.jpg'], 'temporary://test.jpg', TRUE, ''],
|
||||
// Test a temporary file using a relative path.
|
||||
[['filepath' => 'test-file.jpg'], 'temporary://core/modules/simpletest/files/test.jpg', TRUE, '/tmp/'],
|
||||
// Test a remote path to local.
|
||||
[['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://remote-file.jpg', TRUE, $base_url . '/'],
|
||||
// Test a remote path to local inside a folder that doesn't exist.
|
||||
[['filepath' => 'core/modules/simpletest/files/image-test.jpg'], 'public://folder/remote-file.jpg', TRUE, DRUPAL_ROOT . '/'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that non-existent files throw an exception.
|
||||
*/
|
||||
public function testNonExistentSourceFile() {
|
||||
$destination = '/non/existent/file';
|
||||
try {
|
||||
// If this test passes, doImport() will raise a MigrateException and
|
||||
// we'll never reach fail().
|
||||
$this->doImport(['filepath' => $destination], 'public://wontmatter.jpg');
|
||||
$this->fail('Expected Drupal\migrate\MigrateException when importing ' . $destination);
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
$this->assertIdentical($e->getMessage(), "File '$destination' does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests various invocations of the writeFile() method.
|
||||
*/
|
||||
public function testWriteFile() {
|
||||
$plugin = $this->destination;
|
||||
$method = new \ReflectionMethod($plugin, 'writeFile');
|
||||
$method->setAccessible(TRUE);
|
||||
|
||||
touch('temporary://baz.txt');
|
||||
|
||||
// Moving an actual file should return TRUE.
|
||||
$plugin->configuration['move'] = TRUE;
|
||||
$this->assertTrue($method->invoke($plugin, 'temporary://baz.txt', 'public://foo.txt'));
|
||||
|
||||
// Trying to move a non-existent file should return FALSE.
|
||||
$this->assertFalse($method->invoke($plugin, 'temporary://invalid.txt', 'public://invalid.txt'));
|
||||
|
||||
// Copying over a file that already exists should replace the existing file.
|
||||
$plugin->configuration['move'] = FALSE;
|
||||
touch('temporary://baz.txt');
|
||||
$this->assertTrue($method->invoke($plugin, 'temporary://baz.txt', 'public://foo.txt'));
|
||||
// Copying over a file that already exists should rename the resulting file
|
||||
// if FILE_EXISTS_RENAME is specified.
|
||||
$method->invoke($plugin, 'temporary://baz.txt', 'public://foo.txt', FILE_EXISTS_RENAME);
|
||||
$this->assertTrue(file_exists('public://foo_0.txt'));
|
||||
|
||||
// Trying to copy a non-existent file should return FALSE.
|
||||
$this->assertFalse($method->invoke($plugin, 'temporary://invalid.txt', 'public://invalid.txt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests various invocations of the getOverwriteMode() method.
|
||||
*/
|
||||
public function testGetOverwriteMode() {
|
||||
$plugin = $this->destination;
|
||||
$method = new \ReflectionMethod($plugin, 'getOverwriteMode');
|
||||
$method->setAccessible(TRUE);
|
||||
|
||||
$row = new Row([], []);
|
||||
// If the plugin is not configured to rename the destination file, we should
|
||||
// always get FILE_EXISTS_REPLACE.
|
||||
$this->assertIdentical(FILE_EXISTS_REPLACE, $method->invoke($plugin, $row));
|
||||
|
||||
// When the plugin IS configured to rename the destination file, it should
|
||||
// return FILE_EXISTS_RENAME if the destination entity already exists,
|
||||
// and FILE_EXISTS_REPLACE otherwise.
|
||||
$plugin->configuration['rename'] = TRUE;
|
||||
$plugin->storage = \Drupal::entityManager()->getStorage('file');
|
||||
/** @var \Drupal\file\FileInterface $file */
|
||||
$file = $plugin->storage->create();
|
||||
touch('public://foo.txt');
|
||||
$file->setFileUri('public://foo.txt');
|
||||
$file->save();
|
||||
$row->setDestinationProperty($plugin->storage->getEntityType()->getKey('id'), $file->id());
|
||||
$this->assertIdentical(FILE_EXISTS_RENAME, $method->invoke($plugin, $row));
|
||||
unlink('public://foo.txt');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests various invocations of the getDirectory() method.
|
||||
*/
|
||||
public function testGetDirectory() {
|
||||
$plugin = $this->destination;
|
||||
$method = new \ReflectionMethod($plugin, 'getDirectory');
|
||||
$method->setAccessible(TRUE);
|
||||
|
||||
$this->assertEqual('public://foo', $method->invoke($plugin, 'public://foo/baz.txt'));
|
||||
$this->assertEqual('/path/to', $method->invoke($plugin, '/path/to/foo.txt'));
|
||||
// A directory like public:// (no path) needs to resolve to a physical path.
|
||||
$fs = \Drupal::getContainer()->get('file_system');
|
||||
$this->assertEqual($fs->realpath(Settings::get('file_public_path')), $method->invoke($plugin, 'public://foo.txt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests various invocations of the isLocationUnchanged() method.
|
||||
*/
|
||||
public function testIsLocationUnchanged() {
|
||||
$plugin = $this->destination;
|
||||
$method = new \ReflectionMethod($plugin, 'isLocationUnchanged');
|
||||
$method->setAccessible(TRUE);
|
||||
|
||||
$public_dir = Settings::get('file_public_path');
|
||||
|
||||
// Due to the limitations of realpath(), the source file must exist.
|
||||
touch('public://foo.txt');
|
||||
$this->assertTrue($method->invoke($plugin, $public_dir . '/foo.txt', 'public://foo.txt'));
|
||||
unlink('public://foo.txt');
|
||||
|
||||
$temporary_file = '/tmp/foo.txt';
|
||||
touch($temporary_file);
|
||||
$this->assertTrue($method->invoke($plugin, $temporary_file, 'temporary://foo.txt'));
|
||||
unlink($temporary_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests various invocations of the isLocalUri() method.
|
||||
*/
|
||||
public function testIsLocalUri() {
|
||||
$plugin = $this->destination;
|
||||
$method = new \ReflectionMethod($plugin, 'isLocalUri');
|
||||
$method->setAccessible(TRUE);
|
||||
|
||||
$this->assertTrue($method->invoke($plugin, 'public://foo.txt'));
|
||||
$this->assertTrue($method->invoke($plugin, 'public://path/to/foo.txt'));
|
||||
$this->assertTrue($method->invoke($plugin, 'temporary://foo.txt'));
|
||||
$this->assertTrue($method->invoke($plugin, 'temporary://path/to/foo.txt'));
|
||||
$this->assertTrue($method->invoke($plugin, 'foo.txt'));
|
||||
$this->assertTrue($method->invoke($plugin, '/path/to/files/foo.txt'));
|
||||
$this->assertTrue($method->invoke($plugin, 'relative/path/to/foo.txt'));
|
||||
$this->assertFalse($method->invoke($plugin, 'http://www.example.com/foo.txt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Do an import using the destination.
|
||||
*
|
||||
* @param array $row_values
|
||||
* An array of row values.
|
||||
* @param string $destination_path
|
||||
* The destination path to copy to.
|
||||
* @param string $source_base_path
|
||||
* The source base path.
|
||||
* @return array
|
||||
* An array of saved entities ids.
|
||||
*
|
||||
* @throws \Drupal\migrate\MigrateException
|
||||
*/
|
||||
protected function doImport($row_values, $destination_path, $source_base_path = '') {
|
||||
$row = new Row($row_values, []);
|
||||
$row->setDestinationProperty('uri', $destination_path);
|
||||
$this->destination->configuration['source_base_path'] = $source_base_path;
|
||||
|
||||
// Importing asserts there are no errors, then we just check the file has
|
||||
// been copied into place.
|
||||
return $this->destination->import($row, array());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestEntityFile extends EntityFile {
|
||||
|
||||
/**
|
||||
* This is needed to be passed to $this->save().
|
||||
*
|
||||
* @var \Drupal\Core\Entity\ContentEntityInterface
|
||||
*/
|
||||
public $mockEntity;
|
||||
|
||||
/**
|
||||
* Make this public for easy writing during tests.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $configuration;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||
*/
|
||||
public $storage;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
|
||||
*/
|
||||
public $streamWrapperManager;
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\File\FileSystemInterface
|
||||
*/
|
||||
public $fileSystem;
|
||||
|
||||
public function __construct($configuration) {
|
||||
$configuration += array(
|
||||
'source_base_path' => '',
|
||||
'source_path_property' => 'filepath',
|
||||
'destination_path_property' => 'uri',
|
||||
'move' => FALSE,
|
||||
'urlencode' => FALSE,
|
||||
);
|
||||
$this->configuration = $configuration;
|
||||
// We need a mock entity to be passed to save to prevent strict exceptions.
|
||||
$this->mockEntity = EntityTest::create();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getEntity(Row $row, array $old_destination_id_values) {
|
||||
return $this->mockEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) {}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateFileConfigsTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upgrade variables to file.settings.yml.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFileConfigsTest extends MigrateDrupal6TestBase {
|
||||
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('file');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_file_settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of file variables to file.settings.yml.
|
||||
*/
|
||||
public function testFileSettings() {
|
||||
$config = $this->config('file.settings');
|
||||
$this->assertIdentical('textfield', $config->get('description.type'));
|
||||
$this->assertIdentical(128, $config->get('description.length'));
|
||||
$this->assertIdentical('sites/default/files/icons', $config->get('icon.directory'));
|
||||
$this->assertConfigSchema(\Drupal::service('config.typed'), 'file.settings', $config->get());
|
||||
}
|
||||
|
||||
}
|
130
core/modules/file/src/Tests/Migrate/d6/MigrateFileTest.php
Normal file
130
core/modules/file/src/Tests/Migrate/d6/MigrateFileTest.php
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateFileTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\Component\Utility\Random;
|
||||
use Drupal\migrate\Tests\MigrateDumpAlterInterface;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
use Drupal\simpletest\TestBase;
|
||||
use Drupal\file\Entity\File;
|
||||
|
||||
/**
|
||||
* file migration.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFileTest extends MigrateDrupal6TestBase implements MigrateDumpAlterInterface {
|
||||
|
||||
/**
|
||||
* The filename of a file used to test temporary file migration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $tempFilename;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('file');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('file');
|
||||
$this->installConfig(['file']);
|
||||
|
||||
/** @var \Drupal\migrate\Entity\MigrationInterface $migration */
|
||||
$migration = entity_load('migration', 'd6_file');
|
||||
$source = $migration->get('source');
|
||||
$source['site_path'] = 'core/modules/simpletest';
|
||||
$migration->set('source', $source);
|
||||
$this->executeMigration($migration);
|
||||
$this->standalone = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 files to Drupal 8 migration.
|
||||
*/
|
||||
public function testFiles() {
|
||||
/** @var \Drupal\file\FileInterface $file */
|
||||
$file = File::load(1);
|
||||
$this->assertIdentical('Image1.png', $file->getFilename());
|
||||
$this->assertIdentical('39325', $file->getSize());
|
||||
$this->assertIdentical('public://image-1.png', $file->getFileUri());
|
||||
$this->assertIdentical('image/png', $file->getMimeType());
|
||||
$this->assertIdentical("1", $file->getOwnerId());
|
||||
|
||||
// It is pointless to run the second half from MigrateDrupal6Test.
|
||||
if (empty($this->standalone)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test that we can re-import and also test with file_directory_path set.
|
||||
db_truncate(entity_load('migration', 'd6_file')->getIdMap()->mapTableName())->execute();
|
||||
|
||||
// Update the file_directory_path.
|
||||
Database::getConnection('default', 'migrate')
|
||||
->update('variable')
|
||||
->fields(array('value' => serialize('files/test')))
|
||||
->condition('name', 'file_directory_path')
|
||||
->execute();
|
||||
Database::getConnection('default', 'migrate')
|
||||
->update('variable')
|
||||
->fields(array('value' => serialize($this->getTempFilesDirectory())))
|
||||
->condition('name', 'file_directory_temp')
|
||||
->execute();
|
||||
|
||||
$migration = entity_load_unchanged('migration', 'd6_file');
|
||||
$this->executeMigration($migration);
|
||||
|
||||
$file = File::load(2);
|
||||
$this->assertIdentical('public://core/modules/simpletest/files/image-2.jpg', $file->getFileUri());
|
||||
|
||||
// Ensure that a temporary file has been migrated.
|
||||
$file = File::load(6);
|
||||
$this->assertIdentical('temporary://' . static::getUniqueFilename(), $file->getFileUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* A filename based upon the test.
|
||||
*/
|
||||
public static function getUniqueFilename() {
|
||||
return static::$tempFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function migrateDumpAlter(TestBase $test) {
|
||||
// Creates a random filename and updates the source database.
|
||||
$random = new Random();
|
||||
$temp_directory = $test->getTempFilesDirectory();
|
||||
file_prepare_directory($temp_directory, FILE_CREATE_DIRECTORY);
|
||||
static::$tempFilename = $test->getDatabasePrefix() . $random->name() . '.jpg';
|
||||
$file_path = $temp_directory . '/' . static::$tempFilename;
|
||||
file_put_contents($file_path, '');
|
||||
Database::getConnection('default', 'migrate')
|
||||
->update('files')
|
||||
->condition('fid', 6)
|
||||
->fields(array(
|
||||
'filename' => static::$tempFilename,
|
||||
'filepath' => $file_path,
|
||||
))
|
||||
->execute();
|
||||
|
||||
return static::$tempFilename;
|
||||
}
|
||||
|
||||
}
|
100
core/modules/file/src/Tests/Migrate/d6/MigrateUploadBase.php
Normal file
100
core/modules/file/src/Tests/Migrate/d6/MigrateUploadBase.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateUploadBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Base class for file/upload migration tests.
|
||||
*/
|
||||
abstract class MigrateUploadBase extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static $modules = array('file', 'node');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('file');
|
||||
$this->installEntitySchema('node');
|
||||
$this->installSchema('file', ['file_usage']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
|
||||
// Create new file entities.
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$file = entity_create('file', array(
|
||||
'fid' => $i,
|
||||
'uid' => 1,
|
||||
'filename' => 'druplicon.txt',
|
||||
'uri' => "public://druplicon-$i.txt",
|
||||
'filemime' => 'text/plain',
|
||||
'created' => 1,
|
||||
'changed' => 1,
|
||||
'status' => FILE_STATUS_PERMANENT,
|
||||
));
|
||||
$file->enforceIsNew();
|
||||
file_put_contents($file->getFileUri(), 'hello world');
|
||||
|
||||
// Save it, inserting a new record.
|
||||
$file->save();
|
||||
$id_mappings['d6_file'][] = array(array($i), array($i));
|
||||
}
|
||||
|
||||
// Add a node type.
|
||||
$node_type = entity_create('node_type', array('type' => 'story'));
|
||||
$node_type->save();
|
||||
|
||||
// Add a file field.
|
||||
entity_create('field_storage_config', array(
|
||||
'field_name' => 'upload',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'file',
|
||||
'cardinality' => -1,
|
||||
'settings' => array(
|
||||
'display_field' => TRUE,
|
||||
),
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
'field_name' => 'upload',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'story',
|
||||
))->save();
|
||||
$id_mappings['d6_node'] = array(
|
||||
array(array(1), array(1)),
|
||||
array(array(2), array(2)),
|
||||
);
|
||||
$id_mappings['d6_upload_field_instance'] = [
|
||||
[['story'], ['node', 'story', 'upload']],
|
||||
];
|
||||
|
||||
$this->prepareMigrations($id_mappings);
|
||||
$vids = array(1, 2, 3);
|
||||
for ($i = 1; $i <= 2; $i++) {
|
||||
$node = entity_create('node', array(
|
||||
'type' => 'story',
|
||||
'nid' => $i,
|
||||
'vid' => array_shift($vids),
|
||||
'title' => $this->randomString(),
|
||||
));
|
||||
$node->enforceIsNew();
|
||||
$node->save();
|
||||
if ($i == 1) {
|
||||
$node->vid->value = array_shift($vids);
|
||||
$node->enforceIsNew(FALSE);
|
||||
$node->isDefaultRevision(FALSE);
|
||||
$node->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateUploadEntityDisplayTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upload entity display.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateUploadEntityDisplayTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* The modules to be enabled during the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $modules = array('node', 'file');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
entity_create('node_type', array('type' => 'article'))->save();
|
||||
entity_create('node_type', array('type' => 'story'))->save();
|
||||
entity_create('node_type', array('type' => 'page'))->save();
|
||||
|
||||
$id_mappings = array(
|
||||
'd6_upload_field_instance' => array(
|
||||
array(array(1), array('node', 'page', 'upload')),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
$this->executeMigration('d6_upload_entity_display');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 upload settings to Drupal 8 entity display migration.
|
||||
*/
|
||||
public function testUploadEntityDisplay() {
|
||||
$display = entity_get_display('node', 'page', 'default');
|
||||
$component = $display->getComponent('upload');
|
||||
$this->assertIdentical('file_default', $component['type']);
|
||||
|
||||
$display = entity_get_display('node', 'story', 'default');
|
||||
$component = $display->getComponent('upload');
|
||||
$this->assertIdentical('file_default', $component['type']);
|
||||
|
||||
// Assure this doesn't exist.
|
||||
$display = entity_get_display('node', 'article', 'default');
|
||||
$component = $display->getComponent('upload');
|
||||
$this->assertTrue(is_null($component));
|
||||
|
||||
$this->assertIdentical(array('node', 'page', 'default', 'upload'), entity_load('migration', 'd6_upload_entity_display')->getIdMap()->lookupDestinationID(array('page')));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateUploadEntityFormDisplayTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upload form entity display.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateUploadEntityFormDisplayTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* The modules to be enabled during the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $modules = array('file', 'node');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
entity_create('node_type', array('type' => 'article'))->save();
|
||||
entity_create('node_type', array('type' => 'story'))->save();
|
||||
entity_create('node_type', array('type' => 'page'))->save();
|
||||
|
||||
$id_mappings = array(
|
||||
'd6_upload_field_instance' => array(
|
||||
array(array(1), array('node', 'page', 'upload')),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
$this->executeMigration('d6_upload_entity_form_display');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 upload settings to Drupal 8 entity form display migration.
|
||||
*/
|
||||
public function testUploadEntityFormDisplay() {
|
||||
$display = entity_get_form_display('node', 'page', 'default');
|
||||
$component = $display->getComponent('upload');
|
||||
$this->assertIdentical('file_generic', $component['type']);
|
||||
|
||||
$display = entity_get_form_display('node', 'story', 'default');
|
||||
$component = $display->getComponent('upload');
|
||||
$this->assertIdentical('file_generic', $component['type']);
|
||||
|
||||
// Assure this doesn't exist.
|
||||
$display = entity_get_form_display('node', 'article', 'default');
|
||||
$component = $display->getComponent('upload');
|
||||
$this->assertTrue(is_null($component));
|
||||
|
||||
$this->assertIdentical(array('node', 'page', 'default', 'upload'), entity_load('migration', 'd6_upload_entity_form_display')->getIdMap()->lookupDestinationID(array('page')));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateUploadFieldTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Uploads migration.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateUploadFieldTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* The modules to be enabled during the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $modules = array('file', 'node');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigration('d6_upload_field');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 upload settings to Drupal 8 field migration.
|
||||
*/
|
||||
public function testUpload() {
|
||||
$field_storage = FieldStorageConfig::load('node.upload');
|
||||
$this->assertIdentical('node.upload', $field_storage->id());
|
||||
$this->assertIdentical(array('node', 'upload'), entity_load('migration', 'd6_upload_field')->getIdMap()->lookupDestinationID(array('')));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateUploadInstanceTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Upload field instance migration.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateUploadInstanceTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* The modules to be enabled during the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $modules = array('file', 'node');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Add some node mappings to get past checkRequirements().
|
||||
$id_mappings = array(
|
||||
'd6_upload_field' => array(
|
||||
array(array(1), array('node', 'upload')),
|
||||
),
|
||||
'd6_node_type' => array(
|
||||
array(array('page'), array('page')),
|
||||
array(array('story'), array('story')),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
|
||||
foreach (array('page', 'story') as $type) {
|
||||
entity_create('node_type', array('type' => $type))->save();
|
||||
}
|
||||
entity_create('field_storage_config', array(
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'upload',
|
||||
'type' => 'file',
|
||||
'translatable' => '0',
|
||||
))->save();
|
||||
|
||||
$this->executeMigration('d6_upload_field_instance');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 upload settings to Drupal 8 field instance migration.
|
||||
*/
|
||||
public function testUploadFieldInstance() {
|
||||
$field = FieldConfig::load('node.page.upload');
|
||||
$settings = $field->getSettings();
|
||||
$this->assertIdentical('node.page.upload', $field->id());
|
||||
$this->assertIdentical('jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp', $settings['file_extensions']);
|
||||
$this->assertIdentical('1MB', $settings['max_filesize']);
|
||||
$this->assertIdentical(TRUE, $settings['description_field']);
|
||||
|
||||
$field = FieldConfig::load('node.story.upload');
|
||||
$this->assertIdentical('node.story.upload', $field->id());
|
||||
|
||||
// Shouldn't exist.
|
||||
$field = FieldConfig::load('node.article.upload');
|
||||
$this->assertTrue(is_null($field));
|
||||
|
||||
$this->assertIdentical(array('node', 'page', 'upload'), entity_load('migration', 'd6_upload_field_instance')->getIdMap()->lookupDestinationID(array('page')));
|
||||
}
|
||||
|
||||
}
|
59
core/modules/file/src/Tests/Migrate/d6/MigrateUploadTest.php
Normal file
59
core/modules/file/src/Tests/Migrate/d6/MigrateUploadTest.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d6\MigrateUploadTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d6;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Migrate association data between nodes and files.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateUploadTest extends MigrateUploadBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$id_mappings = array(
|
||||
'd6_node:*' => array(
|
||||
array(
|
||||
array(0),
|
||||
array(0),
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->prepareMigrations($id_mappings);
|
||||
$this->executeMigration('d6_upload');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test upload migration from Drupal 6 to Drupal 8.
|
||||
*/
|
||||
function testUpload() {
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
$node_storage->resetCache(array(1, 2));
|
||||
$nodes = Node::loadMultiple(array(1, 2));
|
||||
$node = $nodes[1];
|
||||
$this->assertIdentical(1, count($node->upload));
|
||||
$this->assertIdentical('1', $node->upload[0]->target_id);
|
||||
$this->assertIdentical('file 1-1-1', $node->upload[0]->description);
|
||||
$this->assertIdentical(FALSE, $node->upload[0]->isDisplayed());
|
||||
|
||||
$node = $nodes[2];
|
||||
$this->assertIdentical(2, count($node->upload));
|
||||
$this->assertIdentical('3', $node->upload[0]->target_id);
|
||||
$this->assertIdentical('file 2-3-3', $node->upload[0]->description);
|
||||
$this->assertIdentical(FALSE, $node->upload[0]->isDisplayed());
|
||||
$this->assertIdentical('2', $node->upload[1]->target_id);
|
||||
$this->assertIdentical(TRUE, $node->upload[1]->isDisplayed());
|
||||
$this->assertIdentical('file 2-3-2', $node->upload[1]->description);
|
||||
}
|
||||
|
||||
}
|
96
core/modules/file/src/Tests/Migrate/d7/MigrateFileTest.php
Normal file
96
core/modules/file/src/Tests/Migrate/d7/MigrateFileTest.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\file\Tests\Migrate\d7\MigrateFileTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\file\Tests\Migrate\d7;
|
||||
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\file\FileInterface;
|
||||
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
|
||||
|
||||
/**
|
||||
* Migrates all files in the file_managed table.
|
||||
*
|
||||
* @group file
|
||||
*/
|
||||
class MigrateFileTest extends MigrateDrupal7TestBase {
|
||||
|
||||
static $modules = ['file'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('file');
|
||||
|
||||
$fs = \Drupal::service('file_system');
|
||||
// The public file directory active during the test will serve as the
|
||||
// root of the fictional Drupal 7 site we're migrating.
|
||||
$fs->mkdir('public://sites/default/files', NULL, TRUE);
|
||||
file_put_contents('public://sites/default/files/cube.jpeg', str_repeat('*', 3620));
|
||||
|
||||
/** @var \Drupal\migrate\Entity\MigrationInterface $migration */
|
||||
$migration = entity_load('migration', 'd7_file');
|
||||
// Set the destination plugin's source_base_path configuration value, which
|
||||
// would normally be set by the user running the migration.
|
||||
$migration->set('destination', [
|
||||
'plugin' => 'entity:file',
|
||||
// Note that source_base_path must include a trailing slash because it's
|
||||
// prepended directly to the value of the source path property.
|
||||
'source_base_path' => $fs->realpath($this->publicFilesDirectory) . '/',
|
||||
// This is set in the migration's YAML file, but we need to repeat it
|
||||
// here because all the destination configuration must be set at once.
|
||||
'source_path_property' => 'filepath',
|
||||
]);
|
||||
$this->executeMigration($migration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a single file entity.
|
||||
*
|
||||
* @param integer $id
|
||||
* The file ID.
|
||||
* @param string $name
|
||||
* The expected file name.
|
||||
* @param string $uri
|
||||
* The expected URI.
|
||||
* @param string $mime
|
||||
* The expected MIME type.
|
||||
* @param integer $size
|
||||
* The expected file size.
|
||||
* @param integer $created
|
||||
* The expected creation time.
|
||||
* @param integer $changed
|
||||
* The expected modification time.
|
||||
* @param integer $uid
|
||||
* The expected owner ID.
|
||||
*/
|
||||
protected function assertEntity($id, $name, $uri, $mime, $size, $created, $changed, $uid) {
|
||||
/** @var \Drupal\file\FileInterface $file */
|
||||
$file = File::load($id);
|
||||
$this->assertTrue($file instanceof FileInterface);
|
||||
$this->assertIdentical($name, $file->getFilename());
|
||||
$this->assertIdentical($uri, $file->getFileUri());
|
||||
$this->assertTrue(file_exists($uri));
|
||||
$this->assertIdentical($mime, $file->getMimeType());
|
||||
$this->assertIdentical($size, $file->getSize());
|
||||
// isPermanent(), isTemporary(), etc. are determined by the status column.
|
||||
$this->assertTrue($file->isPermanent());
|
||||
$this->assertIdentical($created, $file->getCreatedTime());
|
||||
$this->assertIdentical($changed, $file->getChangedTime());
|
||||
$this->assertIdentical($uid, $file->getOwnerId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that all expected files are migrated.
|
||||
*/
|
||||
public function testFileMigration() {
|
||||
$this->assertEntity(1, 'cube.jpeg', 'public://cube.jpeg', 'image/jpeg', '3620', '1421727515', '1421727515', '1');
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,7 @@ namespace Drupal\file\Tests\Views;
|
|||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ use Drupal\views\Tests\ViewTestData;
|
|||
*
|
||||
* @group file
|
||||
*/
|
||||
class ExtensionViewsFieldTest extends ViewUnitTestBase {
|
||||
class ExtensionViewsFieldTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\file\Tests\Views;
|
|||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\views\Tests\ViewUnitTestBase;
|
||||
use Drupal\views\Tests\ViewKernelTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ use Drupal\views\Views;
|
|||
*
|
||||
* @group file
|
||||
*/
|
||||
class FileViewsDataTest extends ViewUnitTestBase {
|
||||
class FileViewsDataTest extends ViewKernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\file\Unit\Plugin\migrate\source\d6\FileTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
|
||||
|
||||
/**
|
||||
* Tests D6 file source plugin.
|
||||
*
|
||||
* @group file
|
||||
*/
|
||||
class FileTest extends MigrateSqlSourceTestCase {
|
||||
|
||||
const PLUGIN_CLASS = 'Drupal\file\Plugin\migrate\source\d6\File';
|
||||
|
||||
// The fake Migration configuration entity.
|
||||
protected $migrationConfiguration = array(
|
||||
// The ID of the entity, can be any string.
|
||||
'id' => 'test',
|
||||
'source' => array(
|
||||
'plugin' => 'd6_file',
|
||||
),
|
||||
);
|
||||
|
||||
protected $expectedResults = array(
|
||||
array(
|
||||
'fid' => 1,
|
||||
'uid' => 1,
|
||||
'filename' => 'migrate-test-file-1.pdf',
|
||||
'filepath' => 'sites/default/files/migrate-test-file-1.pdf',
|
||||
'filemime' => 'application/pdf',
|
||||
'filesize' => 890404,
|
||||
'status' => 1,
|
||||
'timestamp' => 1382255613,
|
||||
),
|
||||
array(
|
||||
'fid' => 2,
|
||||
'uid' => 1,
|
||||
'filename' => 'migrate-test-file-2.pdf',
|
||||
'filepath' => 'sites/default/files/migrate-test-file-2.pdf',
|
||||
'filemime' => 'application/pdf',
|
||||
'filesize' => 204124,
|
||||
'status' => 1,
|
||||
'timestamp' => 1382255662,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->databaseContents['files'] = $this->expectedResults;
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\file\Unit\Plugin\migrate\source\d7\FileTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\file\Plugin\migrate\source\d7\File;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
|
||||
|
||||
/**
|
||||
* Tests D7 file source plugin.
|
||||
*
|
||||
* @group file
|
||||
*/
|
||||
class FileTest extends MigrateSqlSourceTestCase {
|
||||
|
||||
const PLUGIN_CLASS = 'Drupal\Tests\file\Unit\Plugin\migrate\source\d7\TestFile';
|
||||
|
||||
// The fake Migration configuration entity.
|
||||
protected $migrationConfiguration = array(
|
||||
// The ID of the entity, can be any string.
|
||||
'id' => 'test',
|
||||
'source' => array(
|
||||
'plugin' => 'd7_file',
|
||||
),
|
||||
);
|
||||
|
||||
protected $expectedResults = [
|
||||
[
|
||||
'fid' => '1',
|
||||
'uid' => '1',
|
||||
'filename' => 'cube.jpeg',
|
||||
'uri' => 'public://cube.jpeg',
|
||||
'filemime' => 'image/jpeg',
|
||||
'filesize' => '3620',
|
||||
'status' => '1',
|
||||
'timestamp' => '1421727515',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->databaseContents['file_managed'] = $this->expectedResults;
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that public file URIs are properly transformed by prepareRow().
|
||||
*/
|
||||
public function testPublicUri() {
|
||||
$this->source->publicPath = 'sites/default/files';
|
||||
$row = new Row(['uri' => 'public://foo.png'], ['uri' => []]);
|
||||
$this->source->prepareRow($row);
|
||||
$this->assertEquals('sites/default/files/foo.png',
|
||||
$row->getSourceProperty('filepath'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that private file URIs are properly transformed by prepareRow().
|
||||
*/
|
||||
public function testPrivateUri() {
|
||||
$this->source->privatePath = '/path/to/private/files';
|
||||
$row = new Row(['uri' => 'private://baz.jpeg'], ['uri' => []]);
|
||||
$this->source->prepareRow($row);
|
||||
$this->assertEquals('/path/to/private/files/baz.jpeg',
|
||||
$row->getSourceProperty('filepath'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that temporary file URIs are property transformed by prepareRow().
|
||||
*/
|
||||
public function testTemporaryUri() {
|
||||
$this->source->temporaryPath = '/tmp';
|
||||
$row = new Row(['uri' => 'temporary://camelot/lancelot.gif'],
|
||||
['uri' => []]);
|
||||
$this->source->prepareRow($row);
|
||||
$this->assertEquals('/tmp/camelot/lancelot.gif',
|
||||
$row->getSourceProperty('filepath'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing version of \Drupal\file\Plugin\migrate\source\d7\File.
|
||||
*
|
||||
* Exposes inaccessible properties.
|
||||
*/
|
||||
class TestFile extends File {
|
||||
|
||||
/**
|
||||
* The public file directory path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $publicPath;
|
||||
|
||||
/**
|
||||
* The private file directory path, if any.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $privatePath;
|
||||
|
||||
/**
|
||||
* The temporary file directory path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $temporaryPath;
|
||||
|
||||
}
|
Reference in a new issue