upgrades core to 8.4.2
This commit is contained in:
@@ -3,4 +3,4 @@ description:
|
||||
length: 128
|
||||
icon:
|
||||
directory: 'core/modules/file/icons'
|
||||
|
||||
make_unused_managed_files_temporary: false
|
||||
|
||||
@@ -565,7 +565,7 @@ display:
|
||||
decimal: .
|
||||
separator: ','
|
||||
format_plural: true
|
||||
format_plural_string: "1 place\x03@count places"
|
||||
format_plural_string: !!binary MSBwbGFjZQNAY291bnQgcGxhY2Vz
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
plugin_id: numeric
|
||||
@@ -1007,7 +1007,7 @@ display:
|
||||
decimal: .
|
||||
separator: ','
|
||||
format_plural: false
|
||||
format_plural_string: "1\x03@count"
|
||||
format_plural_string: !!binary MQNAY291bnQ=
|
||||
prefix: ''
|
||||
suffix: ''
|
||||
plugin_id: numeric
|
||||
|
||||
@@ -21,6 +21,9 @@ file.settings:
|
||||
directory:
|
||||
type: path
|
||||
label: 'Directory'
|
||||
make_unused_managed_files_temporary:
|
||||
type: boolean
|
||||
label: 'Controls if unused files should be marked temporary'
|
||||
|
||||
field.storage_settings.file:
|
||||
type: base_entity_reference_field_settings
|
||||
@@ -48,7 +51,7 @@ base_file_field_field_settings:
|
||||
label: 'Reference method'
|
||||
handler_settings:
|
||||
type: entity_reference_selection.[%parent.handler]
|
||||
label: 'Entity reference selection settings'
|
||||
label: 'File selection handler settings'
|
||||
file_directory:
|
||||
type: string
|
||||
label: 'File directory'
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/**
|
||||
* @file
|
||||
* Provides JavaScript additions to the managed file field type.
|
||||
*
|
||||
* This file provides progress bar support (if available), popup windows for
|
||||
* file previews, and disabling of other file fields during Ajax uploads (which
|
||||
* prevents separate file fields from accidentally uploading files).
|
||||
*/
|
||||
|
||||
(function ($, Drupal) {
|
||||
/**
|
||||
* 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(context, settings) {
|
||||
const $context = $(context);
|
||||
let elements;
|
||||
|
||||
function initFileValidation(selector) {
|
||||
$context.find(selector)
|
||||
.once('fileValidate')
|
||||
.on('change.fileValidate', { extensions: elements[selector] }, Drupal.file.validateExtension);
|
||||
}
|
||||
|
||||
if (settings.file && settings.file.elements) {
|
||||
elements = settings.file.elements;
|
||||
Object.keys(elements).forEach(initFileValidation);
|
||||
}
|
||||
},
|
||||
detach(context, settings, trigger) {
|
||||
const $context = $(context);
|
||||
let elements;
|
||||
|
||||
function removeFileValidation(selector) {
|
||||
$context.find(selector)
|
||||
.removeOnce('fileValidate')
|
||||
.off('change.fileValidate', Drupal.file.validateExtension);
|
||||
}
|
||||
|
||||
if (trigger === 'unload' && settings.file && settings.file.elements) {
|
||||
elements = settings.file.elements;
|
||||
Object.keys(elements).forEach(removeFileValidation);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 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(context) {
|
||||
$(context).find('input[type="file"]').once('auto-file-upload').on('change.autoFileUpload', Drupal.file.triggerUploadButton);
|
||||
},
|
||||
detach(context, setting, trigger) {
|
||||
if (trigger === 'unload') {
|
||||
$(context).find('input[type="file"]').removeOnce('auto-file-upload').off('.autoFileUpload');
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 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(context) {
|
||||
const $context = $(context);
|
||||
$context.find('.js-form-submit').on('mousedown', Drupal.file.disableFields);
|
||||
$context.find('.js-form-managed-file .js-form-submit').on('mousedown', Drupal.file.progressBar);
|
||||
},
|
||||
detach(context) {
|
||||
const $context = $(context);
|
||||
$context.find('.js-form-submit').off('mousedown', Drupal.file.disableFields);
|
||||
$context.find('.js-form-managed-file .js-form-submit').off('mousedown', Drupal.file.progressBar);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 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(context) {
|
||||
$(context).find('div.js-form-managed-file .file a').on('click', Drupal.file.openInNewWindow);
|
||||
},
|
||||
detach(context) {
|
||||
$(context).find('div.js-form-managed-file .file a').off('click', Drupal.file.openInNewWindow);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* File upload utility functions.
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
Drupal.file = Drupal.file || {
|
||||
|
||||
/**
|
||||
* Client-side file input validation of file extensions.
|
||||
*
|
||||
* @name Drupal.file.validateExtension
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered. For example `change.fileValidate`.
|
||||
*/
|
||||
validateExtension(event) {
|
||||
event.preventDefault();
|
||||
// Remove any previous errors.
|
||||
$('.file-upload-js-error').remove();
|
||||
|
||||
// Add client side validation for the input[type=file].
|
||||
const extensionPattern = event.data.extensions.replace(/,\s*/g, '|');
|
||||
if (extensionPattern.length > 1 && this.value.length > 0) {
|
||||
const acceptableMatch = new RegExp(`\\.(${extensionPattern})$`, 'gi');
|
||||
if (!acceptableMatch.test(this.value)) {
|
||||
const error = Drupal.t('The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.', {
|
||||
// According to the specifications of HTML5, a file upload control
|
||||
// should not reveal the real local path to the file that a user
|
||||
// has selected. Some web browsers implement this restriction by
|
||||
// replacing the local path with "C:\fakepath\", which can cause
|
||||
// confusion by leaving the user thinking perhaps Drupal could not
|
||||
// find the file because it messed up the file path. To avoid this
|
||||
// confusion, therefore, we strip out the bogus fakepath string.
|
||||
'%filename': this.value.replace('C:\\fakepath\\', ''),
|
||||
'%extensions': extensionPattern.replace(/\|/g, ', '),
|
||||
});
|
||||
$(this).closest('div.js-form-managed-file').prepend(`<div class="messages messages--error file-upload-js-error" aria-live="polite">${error}</div>`);
|
||||
this.value = '';
|
||||
// Cancel all other change event handlers.
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger the upload_button mouse event to auto-upload as a managed file.
|
||||
*
|
||||
* @name Drupal.file.triggerUploadButton
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered. For example `change.autoFileUpload`.
|
||||
*/
|
||||
triggerUploadButton(event) {
|
||||
$(event.target).closest('.js-form-managed-file').find('.js-form-submit').trigger('mousedown');
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevent file uploads when using buttons not intended to upload.
|
||||
*
|
||||
* @name Drupal.file.disableFields
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `mousedown` event.
|
||||
*/
|
||||
disableFields(event) {
|
||||
const $clickedButton = $(this).findOnce('ajax');
|
||||
|
||||
// Only disable upload fields for Ajax buttons.
|
||||
if (!$clickedButton.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we're working with an "Upload" button.
|
||||
let $enabledFields = [];
|
||||
if ($clickedButton.closest('div.js-form-managed-file').length > 0) {
|
||||
$enabledFields = $clickedButton.closest('div.js-form-managed-file').find('input.js-form-file');
|
||||
}
|
||||
|
||||
// Temporarily disable upload fields other than the one we're currently
|
||||
// working with. Filter out fields that are already disabled so that they
|
||||
// do not get enabled when we re-enable these fields at the end of
|
||||
// behavior processing. Re-enable in a setTimeout set to a relatively
|
||||
// short amount of time (1 second). All the other mousedown handlers
|
||||
// (like Drupal's Ajax behaviors) are executed before any timeout
|
||||
// functions are called, so we don't have to worry about the fields being
|
||||
// re-enabled too soon. @todo If the previous sentence is true, why not
|
||||
// set the timeout to 0?
|
||||
const $fieldsToTemporarilyDisable = $('div.js-form-managed-file input.js-form-file').not($enabledFields).not(':disabled');
|
||||
$fieldsToTemporarilyDisable.prop('disabled', true);
|
||||
setTimeout(() => {
|
||||
$fieldsToTemporarilyDisable.prop('disabled', false);
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add progress bar support if possible.
|
||||
*
|
||||
* @name Drupal.file.progressBar
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `mousedown` event.
|
||||
*/
|
||||
progressBar(event) {
|
||||
const $clickedButton = $(this);
|
||||
const $progressId = $clickedButton.closest('div.js-form-managed-file').find('input.file-progress');
|
||||
if ($progressId.length) {
|
||||
const originalName = $progressId.attr('name');
|
||||
|
||||
// Replace the name with the required identifier.
|
||||
$progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]);
|
||||
|
||||
// Restore the original name after the upload begins.
|
||||
setTimeout(() => {
|
||||
$progressId.attr('name', originalName);
|
||||
}, 1000);
|
||||
}
|
||||
// Show the progress bar if the upload takes longer than half a second.
|
||||
setTimeout(() => {
|
||||
$clickedButton.closest('div.js-form-managed-file').find('div.ajax-progress-bar').slideDown();
|
||||
}, 500);
|
||||
},
|
||||
|
||||
/**
|
||||
* Open links to files within forms in a new window.
|
||||
*
|
||||
* @name Drupal.file.openInNewWindow
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `click` event.
|
||||
*/
|
||||
openInNewWindow(event) {
|
||||
event.preventDefault();
|
||||
$(this).attr('target', '_blank');
|
||||
window.open(this.href, 'filePreview', 'toolbar=0,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1,width=500,height=550');
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal));
|
||||
@@ -73,7 +73,7 @@ function template_preprocess_file_widget_multiple(&$variables) {
|
||||
|
||||
// Render everything else together in a column, without the normal wrappers.
|
||||
$widget['#theme_wrappers'] = [];
|
||||
$information = drupal_render($widget);
|
||||
$information = \Drupal::service('renderer')->render($widget);
|
||||
$display = '';
|
||||
if ($element['#display_field']) {
|
||||
unset($widget['display']['#title']);
|
||||
|
||||
@@ -7,8 +7,8 @@ package: Field types
|
||||
dependencies:
|
||||
- field
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -116,3 +116,15 @@ function file_requirements($phase) {
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent unused files from being deleted.
|
||||
*/
|
||||
function file_update_8300() {
|
||||
// Disable deletion of unused permanent files.
|
||||
\Drupal::configFactory()->getEditable('file.settings')
|
||||
->set('make_unused_managed_files_temporary', FALSE)
|
||||
->save();
|
||||
|
||||
return t('Files that have no remaining usages are no longer deleted by default.');
|
||||
}
|
||||
|
||||
+26
-147
@@ -1,35 +1,18 @@
|
||||
/**
|
||||
* @file
|
||||
* Provides JavaScript additions to the managed file field type.
|
||||
*
|
||||
* This file provides progress bar support (if available), popup windows for
|
||||
* file previews, and disabling of other file fields during Ajax uploads (which
|
||||
* prevents separate file fields from accidentally uploading files).
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
attach: function attach(context, settings) {
|
||||
var $context = $(context);
|
||||
var elements;
|
||||
var elements = void 0;
|
||||
|
||||
function initFileValidation(selector) {
|
||||
$context.find(selector)
|
||||
.once('fileValidate')
|
||||
.on('change.fileValidate', {extensions: elements[selector]}, Drupal.file.validateExtension);
|
||||
$context.find(selector).once('fileValidate').on('change.fileValidate', { extensions: elements[selector] }, Drupal.file.validateExtension);
|
||||
}
|
||||
|
||||
if (settings.file && settings.file.elements) {
|
||||
@@ -37,14 +20,12 @@
|
||||
Object.keys(elements).forEach(initFileValidation);
|
||||
}
|
||||
},
|
||||
detach: function (context, settings, trigger) {
|
||||
detach: function detach(context, settings, trigger) {
|
||||
var $context = $(context);
|
||||
var elements;
|
||||
var elements = void 0;
|
||||
|
||||
function removeFileValidation(selector) {
|
||||
$context.find(selector)
|
||||
.removeOnce('fileValidate')
|
||||
.off('change.fileValidate', Drupal.file.validateExtension);
|
||||
$context.find(selector).removeOnce('fileValidate').off('change.fileValidate', Drupal.file.validateExtension);
|
||||
}
|
||||
|
||||
if (trigger === 'unload' && settings.file && settings.file.elements) {
|
||||
@@ -54,204 +35,102 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
attach: function attach(context) {
|
||||
$(context).find('input[type="file"]').once('auto-file-upload').on('change.autoFileUpload', Drupal.file.triggerUploadButton);
|
||||
},
|
||||
detach: function (context, setting, trigger) {
|
||||
detach: function detach(context, setting, trigger) {
|
||||
if (trigger === 'unload') {
|
||||
$(context).find('input[type="file"]').removeOnce('auto-file-upload').off('.autoFileUpload');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
attach: function attach(context) {
|
||||
var $context = $(context);
|
||||
$context.find('.js-form-submit').on('mousedown', Drupal.file.disableFields);
|
||||
$context.find('.js-form-managed-file .js-form-submit').on('mousedown', Drupal.file.progressBar);
|
||||
},
|
||||
detach: function (context) {
|
||||
detach: function detach(context) {
|
||||
var $context = $(context);
|
||||
$context.find('.js-form-submit').off('mousedown', Drupal.file.disableFields);
|
||||
$context.find('.js-form-managed-file .js-form-submit').off('mousedown', Drupal.file.progressBar);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
attach: function attach(context) {
|
||||
$(context).find('div.js-form-managed-file .file a').on('click', Drupal.file.openInNewWindow);
|
||||
},
|
||||
detach: function (context) {
|
||||
detach: function detach(context) {
|
||||
$(context).find('div.js-form-managed-file .file a').off('click', Drupal.file.openInNewWindow);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* File upload utility functions.
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
Drupal.file = Drupal.file || {
|
||||
|
||||
/**
|
||||
* Client-side file input validation of file extensions.
|
||||
*
|
||||
* @name Drupal.file.validateExtension
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered. For example `change.fileValidate`.
|
||||
*/
|
||||
validateExtension: function (event) {
|
||||
validateExtension: function validateExtension(event) {
|
||||
event.preventDefault();
|
||||
// Remove any previous errors.
|
||||
|
||||
$('.file-upload-js-error').remove();
|
||||
|
||||
// Add client side validation for the input[type=file].
|
||||
var extensionPattern = event.data.extensions.replace(/,\s*/g, '|');
|
||||
if (extensionPattern.length > 1 && this.value.length > 0) {
|
||||
var acceptableMatch = new RegExp('\\.(' + extensionPattern + ')$', 'gi');
|
||||
if (!acceptableMatch.test(this.value)) {
|
||||
var error = Drupal.t('The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.', {
|
||||
// According to the specifications of HTML5, a file upload control
|
||||
// should not reveal the real local path to the file that a user
|
||||
// has selected. Some web browsers implement this restriction by
|
||||
// replacing the local path with "C:\fakepath\", which can cause
|
||||
// confusion by leaving the user thinking perhaps Drupal could not
|
||||
// find the file because it messed up the file path. To avoid this
|
||||
// confusion, therefore, we strip out the bogus fakepath string.
|
||||
'%filename': this.value.replace('C:\\fakepath\\', ''),
|
||||
'%extensions': extensionPattern.replace(/\|/g, ', ')
|
||||
});
|
||||
$(this).closest('div.js-form-managed-file').prepend('<div class="messages messages--error file-upload-js-error" aria-live="polite">' + error + '</div>');
|
||||
this.value = '';
|
||||
// Cancel all other change event handlers.
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Trigger the upload_button mouse event to auto-upload as a managed file.
|
||||
*
|
||||
* @name Drupal.file.triggerUploadButton
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered. For example `change.autoFileUpload`.
|
||||
*/
|
||||
triggerUploadButton: function (event) {
|
||||
triggerUploadButton: function triggerUploadButton(event) {
|
||||
$(event.target).closest('.js-form-managed-file').find('.js-form-submit').trigger('mousedown');
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevent file uploads when using buttons not intended to upload.
|
||||
*
|
||||
* @name Drupal.file.disableFields
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `mousedown` event.
|
||||
*/
|
||||
disableFields: function (event) {
|
||||
disableFields: function disableFields(event) {
|
||||
var $clickedButton = $(this).findOnce('ajax');
|
||||
|
||||
// Only disable upload fields for Ajax buttons.
|
||||
if (!$clickedButton.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we're working with an "Upload" button.
|
||||
var $enabledFields = [];
|
||||
if ($clickedButton.closest('div.js-form-managed-file').length > 0) {
|
||||
$enabledFields = $clickedButton.closest('div.js-form-managed-file').find('input.js-form-file');
|
||||
}
|
||||
|
||||
// Temporarily disable upload fields other than the one we're currently
|
||||
// working with. Filter out fields that are already disabled so that they
|
||||
// do not get enabled when we re-enable these fields at the end of
|
||||
// behavior processing. Re-enable in a setTimeout set to a relatively
|
||||
// short amount of time (1 second). All the other mousedown handlers
|
||||
// (like Drupal's Ajax behaviors) are executed before any timeout
|
||||
// functions are called, so we don't have to worry about the fields being
|
||||
// re-enabled too soon. @todo If the previous sentence is true, why not
|
||||
// set the timeout to 0?
|
||||
var $fieldsToTemporarilyDisable = $('div.js-form-managed-file input.js-form-file').not($enabledFields).not(':disabled');
|
||||
$fieldsToTemporarilyDisable.prop('disabled', true);
|
||||
setTimeout(function () {
|
||||
$fieldsToTemporarilyDisable.prop('disabled', false);
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add progress bar support if possible.
|
||||
*
|
||||
* @name Drupal.file.progressBar
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `mousedown` event.
|
||||
*/
|
||||
progressBar: function (event) {
|
||||
progressBar: function progressBar(event) {
|
||||
var $clickedButton = $(this);
|
||||
var $progressId = $clickedButton.closest('div.js-form-managed-file').find('input.file-progress');
|
||||
if ($progressId.length) {
|
||||
var originalName = $progressId.attr('name');
|
||||
|
||||
// Replace the name with the required identifier.
|
||||
$progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]);
|
||||
|
||||
// Restore the original name after the upload begins.
|
||||
setTimeout(function () {
|
||||
$progressId.attr('name', originalName);
|
||||
}, 1000);
|
||||
}
|
||||
// Show the progress bar if the upload takes longer than half a second.
|
||||
|
||||
setTimeout(function () {
|
||||
$clickedButton.closest('div.js-form-managed-file').find('div.ajax-progress-bar').slideDown();
|
||||
}, 500);
|
||||
},
|
||||
|
||||
/**
|
||||
* Open links to files within forms in a new window.
|
||||
*
|
||||
* @name Drupal.file.openInNewWindow
|
||||
*
|
||||
* @param {jQuery.Event} event
|
||||
* The event triggered, most likely a `click` event.
|
||||
*/
|
||||
openInNewWindow: function (event) {
|
||||
openInNewWindow: function openInNewWindow(event) {
|
||||
event.preventDefault();
|
||||
$(this).attr('target', '_blank');
|
||||
window.open(this.href, 'filePreview', 'toolbar=0,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1,width=500,height=550');
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal);
|
||||
})(jQuery, Drupal);
|
||||
@@ -1208,7 +1208,9 @@ function file_managed_file_save_upload($element, FormStateInterface $form_state)
|
||||
|
||||
// Value callback expects FIDs to be keys.
|
||||
$files = array_filter($files);
|
||||
$fids = array_map(function($file) { return $file->id(); }, $files);
|
||||
$fids = array_map(function ($file) {
|
||||
return $file->id();
|
||||
}, $files);
|
||||
|
||||
return empty($files) ? [] : array_combine($fids, $files);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
file.usage:
|
||||
class: Drupal\file\FileUsage\DatabaseFileUsageBackend
|
||||
arguments: ['@database']
|
||||
arguments: ['@database', 'file_usage', '@config.factory']
|
||||
tags:
|
||||
- { name: backend_overridable }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Every migration that references a file by Drupal 6 fid should specify this
|
||||
# migration as an optional dependency.
|
||||
id: d6_file
|
||||
label: Files
|
||||
label: Public files
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
source:
|
||||
|
||||
@@ -9,7 +9,7 @@ process:
|
||||
vid: vid
|
||||
type: type
|
||||
upload:
|
||||
plugin: iterator
|
||||
plugin: sub_process
|
||||
source: upload
|
||||
process:
|
||||
target_id:
|
||||
|
||||
@@ -6,7 +6,7 @@ source:
|
||||
# We do an empty source and a proper destination to have an idmap for
|
||||
# migration_dependencies.
|
||||
plugin: md_empty
|
||||
provider: upload
|
||||
source_module: upload
|
||||
constants:
|
||||
entity_type: node
|
||||
type: file
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Every migration that references a file by Drupal 7 fid should specify this
|
||||
# migration as an optional dependency.
|
||||
id: d7_file
|
||||
label: Files
|
||||
label: Public files
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
source:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
id: d7_file_private
|
||||
label: Files
|
||||
label: Private files
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
source:
|
||||
|
||||
@@ -9,6 +9,7 @@ source:
|
||||
- file_description_type
|
||||
- file_description_length
|
||||
- file_icon_directory
|
||||
source_module: system
|
||||
process:
|
||||
'description/type': file_description_type
|
||||
'description/length': file_description_length
|
||||
|
||||
@@ -398,15 +398,23 @@ class ManagedFile extends FormElement {
|
||||
* Render API callback: Validates the managed_file element.
|
||||
*/
|
||||
public static function validateManagedFile(&$element, FormStateInterface $form_state, &$complete_form) {
|
||||
// If referencing an existing file, only allow if there are existing
|
||||
// references. This prevents unmanaged files from being deleted if this
|
||||
// item were to be deleted.
|
||||
$clicked_button = end($form_state->getTriggeringElement()['#parents']);
|
||||
if ($clicked_button != 'remove_button' && !empty($element['fids']['#value'])) {
|
||||
$fids = $element['fids']['#value'];
|
||||
foreach ($fids as $fid) {
|
||||
if ($file = File::load($fid)) {
|
||||
if ($file->isPermanent()) {
|
||||
// If referencing an existing file, only allow if there are existing
|
||||
// references. This prevents unmanaged files from being deleted if
|
||||
// this item were to be deleted. When files that are no longer in use
|
||||
// are automatically marked as temporary (now disabled by default),
|
||||
// it is not safe to reference a permanent file without usage. Adding
|
||||
// a usage and then later on removing it again would delete the file,
|
||||
// but it is unknown if and where it is currently referenced. However,
|
||||
// when files are not marked temporary (and then removed)
|
||||
// automatically, it is safe to add and remove usages, as it would
|
||||
// simply return to the current state.
|
||||
// @see https://www.drupal.org/node/2891902
|
||||
if ($file->isPermanent() && \Drupal::config('file.settings')->get('make_unused_managed_files_temporary')) {
|
||||
$references = static::fileUsage()->listUsage($file);
|
||||
if (empty($references)) {
|
||||
// We expect the field name placeholder value to be wrapped in t()
|
||||
|
||||
@@ -190,7 +190,10 @@ class File extends ContentEntityBase implements FileInterface {
|
||||
|
||||
// The file itself might not exist or be available right now.
|
||||
$uri = $this->getFileUri();
|
||||
if ($size = @filesize($uri)) {
|
||||
$size = @filesize($uri);
|
||||
|
||||
// Set size unless there was an error.
|
||||
if ($size !== FALSE) {
|
||||
$this->setSize($size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,4 @@ use Drupal\Core\Entity\EntityAccessControlHandlerInterface;
|
||||
*
|
||||
* @see \Drupal\file\Plugin\Field\FieldFormatter\FileFormatterBase::needsAccessCheck()
|
||||
*/
|
||||
interface FileAccessFormatterControlHandlerInterface extends EntityAccessControlHandlerInterface { }
|
||||
interface FileAccessFormatterControlHandlerInterface extends EntityAccessControlHandlerInterface {}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\file\FileUsage;
|
||||
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\file\FileInterface;
|
||||
|
||||
@@ -32,8 +33,11 @@ class DatabaseFileUsageBackend extends FileUsageBase {
|
||||
* information.
|
||||
* @param string $table
|
||||
* (optional) The table to store file usage info. Defaults to 'file_usage'.
|
||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||
* (optional) The config factory.
|
||||
*/
|
||||
public function __construct(Connection $connection, $table = 'file_usage') {
|
||||
public function __construct(Connection $connection, $table = 'file_usage', ConfigFactoryInterface $config_factory = NULL) {
|
||||
parent::__construct($config_factory);
|
||||
$this->connection = $connection;
|
||||
|
||||
$this->tableName = $table;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\file\FileUsage;
|
||||
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\file\FileInterface;
|
||||
|
||||
/**
|
||||
@@ -9,6 +10,27 @@ use Drupal\file\FileInterface;
|
||||
*/
|
||||
abstract class FileUsageBase implements FileUsageInterface {
|
||||
|
||||
/**
|
||||
* The config factory.
|
||||
*
|
||||
* @var \Drupal\Core\Config\ConfigFactoryInterface
|
||||
*/
|
||||
protected $configFactory;
|
||||
|
||||
/**
|
||||
* Creates a FileUsageBase object.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||
* (optional) The config factory. Defaults to NULL and will use
|
||||
* \Drupal::configFactory() instead.
|
||||
*
|
||||
* @deprecated The $config_factory parameter will become required in Drupal
|
||||
* 9.0.0.
|
||||
*/
|
||||
public function __construct(ConfigFactoryInterface $config_factory = NULL) {
|
||||
$this->configFactory = $config_factory ?: \Drupal::configFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -24,6 +46,10 @@ abstract class FileUsageBase implements FileUsageInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete(FileInterface $file, $module, $type = NULL, $id = NULL, $count = 1) {
|
||||
// Do not actually mark files as temporary when the behavior is disabled.
|
||||
if (!$this->configFactory->get('file.settings')->get('make_unused_managed_files_temporary')) {
|
||||
return;
|
||||
}
|
||||
// If there are no more remaining usages of this file, mark it as temporary,
|
||||
// which result in a delete through system_cron().
|
||||
$usage = \Drupal::service('file.usage')->listUsage($file);
|
||||
|
||||
@@ -13,7 +13,7 @@ class FileFieldItemList extends EntityReferenceFieldItemList {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultValuesForm(array &$form, FormStateInterface $form_state) { }
|
||||
public function defaultValuesForm(array &$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
@@ -333,7 +333,7 @@ class FileItem extends EntityReferenceItem {
|
||||
$file = file_save_data($data, $destination, FILE_EXISTS_ERROR);
|
||||
$values = [
|
||||
'target_id' => $file->id(),
|
||||
'display' => (int)$settings['display_default'],
|
||||
'display' => (int) $settings['display_default'],
|
||||
'description' => $random->sentences(10),
|
||||
];
|
||||
return $values;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\cckfield\d6;
|
||||
|
||||
@trigger_error('FileField is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\file\Plugin\migrate\field\d6\FileField instead.', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
||||
@@ -11,6 +13,11 @@ use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
||||
* id = "filefield",
|
||||
* core = {6}
|
||||
* )
|
||||
*
|
||||
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
|
||||
* \Drupal\file\Plugin\migrate\field\d6\FileField instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2751897
|
||||
*/
|
||||
class FileField extends CckFieldPluginBase {
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\cckfield\d7;
|
||||
|
||||
@trigger_error('FileField is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\file\Plugin\migrate\field\d7\FileField instead.', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
||||
@@ -11,6 +13,11 @@ use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
||||
* id = "file",
|
||||
* core = {7}
|
||||
* )
|
||||
*
|
||||
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
|
||||
* \Drupal\file\Plugin\migrate\field\d7\FileField instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2751897
|
||||
*/
|
||||
class FileField extends CckFieldPluginBase {
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\cckfield\d7;
|
||||
|
||||
@trigger_error('ImageField is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.x. Use \Drupal\file\Plugin\migrate\field\d7\ImageField instead.', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
||||
|
||||
@@ -10,16 +12,14 @@ use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
|
||||
* id = "image",
|
||||
* core = {7}
|
||||
* )
|
||||
*
|
||||
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
|
||||
* \Drupal\file\Plugin\migrate\field\d7\ImageField instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2751897
|
||||
*/
|
||||
class ImageField extends CckFieldPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldFormatterMap() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\field\d6;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
|
||||
|
||||
/**
|
||||
* @MigrateField(
|
||||
* id = "filefield",
|
||||
* core = {6}
|
||||
* )
|
||||
*/
|
||||
class FileField extends FieldPluginBase {
|
||||
|
||||
/**
|
||||
* {@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 processFieldValues(MigrationInterface $migration, $field_name, $data) {
|
||||
$process = [
|
||||
'plugin' => 'd6_field_file',
|
||||
'source' => $field_name,
|
||||
];
|
||||
$migration->mergeProcessOfProperty($field_name, $process);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldType(Row $row) {
|
||||
return $row->getSourceProperty('widget_type') == 'imagefield_widget' ? 'image' : 'file';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\field\d7;
|
||||
|
||||
use Drupal\file\Plugin\migrate\field\d6\FileField as D6FileField;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
|
||||
/**
|
||||
* @MigrateField(
|
||||
* id = "file",
|
||||
* core = {7}
|
||||
* )
|
||||
*/
|
||||
class FileField extends D6FileField {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
|
||||
$process = [
|
||||
'plugin' => 'iterator',
|
||||
'source' => $field_name,
|
||||
'process' => [
|
||||
'target_id' => 'fid',
|
||||
'display' => 'display',
|
||||
'description' => 'description',
|
||||
],
|
||||
];
|
||||
$migration->mergeProcessOfProperty($field_name, $process);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\field\d7;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\field\FieldPluginBase;
|
||||
|
||||
/**
|
||||
* @MigrateField(
|
||||
* id = "image",
|
||||
* core = {7}
|
||||
* )
|
||||
*/
|
||||
class ImageField extends FieldPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processFieldValues(MigrationInterface $migration, $field_name, $data) {
|
||||
$process = [
|
||||
'plugin' => 'iterator',
|
||||
'source' => $field_name,
|
||||
'process' => [
|
||||
'target_id' => 'fid',
|
||||
'alt' => 'alt',
|
||||
'title' => 'title',
|
||||
'width' => 'width',
|
||||
'height' => 'height',
|
||||
],
|
||||
];
|
||||
$migration->mergeProcessOfProperty($field_name, $process);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,91 +2,16 @@
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Plugin\MigrateProcessInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@trigger_error('CckFile is deprecated in Drupal 8.3.x and will be be removed before Drupal 9.0.x. Use \Drupal\file\Plugin\migrate\process\d6\FieldFile instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "d6_cck_file"
|
||||
* )
|
||||
*
|
||||
* @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
|
||||
* \Drupal\file\Plugin\migrate\process\d6\FieldFile instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2751897
|
||||
*/
|
||||
class CckFile extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The migration process plugin, configured for lookups in d6_file.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrateProcessInterface
|
||||
*/
|
||||
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\Plugin\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
|
||||
// a d6 file migration.
|
||||
$migration_plugin_configuration = $configuration + [
|
||||
'migration' => 'd6_file',
|
||||
'source' => ['fid'],
|
||||
];
|
||||
|
||||
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.
|
||||
if ($fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property)) {
|
||||
return [
|
||||
'target_id' => $fid,
|
||||
'display' => $value['list'],
|
||||
'description' => isset($options['description']) ? $options['description'] : '',
|
||||
'alt' => isset($options['alt']) ? $options['alt'] : '',
|
||||
'title' => isset($options['title']) ? $options['title'] : '',
|
||||
];
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
class CckFile extends FieldFile {}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\file\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Plugin\MigrateProcessInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "d6_field_file"
|
||||
* )
|
||||
*/
|
||||
class FieldFile extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The migration process plugin, configured for lookups in d6_file.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrateProcessInterface
|
||||
*/
|
||||
protected $migrationPlugin;
|
||||
|
||||
/**
|
||||
* Constructs a FieldFile 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\Plugin\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
|
||||
// a d6 file migration.
|
||||
$migration_plugin_configuration = $configuration + [
|
||||
'migration' => 'd6_file',
|
||||
'source' => ['fid'],
|
||||
];
|
||||
|
||||
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.
|
||||
if ($fid = $this->migrationPlugin->transform($value['fid'], $migrate_executable, $row, $destination_property)) {
|
||||
return [
|
||||
'target_id' => $fid,
|
||||
'display' => $value['list'],
|
||||
'description' => isset($options['description']) ? $options['description'] : '',
|
||||
'alt' => isset($options['alt']) ? $options['alt'] : '',
|
||||
'title' => isset($options['title']) ? $options['title'] : '',
|
||||
];
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* Drupal 6 file source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_file"
|
||||
* id = "d6_file",
|
||||
* source_module = "system"
|
||||
* )
|
||||
*/
|
||||
class File extends DrupalSqlBase {
|
||||
|
||||
@@ -10,7 +10,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_upload",
|
||||
* source_provider = "upload"
|
||||
* source_module = "upload"
|
||||
* )
|
||||
*/
|
||||
class Upload extends DrupalSqlBase {
|
||||
|
||||
@@ -10,7 +10,7 @@ use Drupal\migrate\Plugin\migrate\source\DummyQueryTrait;
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d6_upload_instance",
|
||||
* source_provider = "upload"
|
||||
* source_module = "upload"
|
||||
* )
|
||||
*/
|
||||
class UploadInstance extends DrupalSqlBase {
|
||||
@@ -25,7 +25,9 @@ class UploadInstance extends DrupalSqlBase {
|
||||
->fields('nt', ['type'])
|
||||
->execute()
|
||||
->fetchCol();
|
||||
$variables = array_map(function($type) { return 'upload_' . $type; }, $node_types);
|
||||
$variables = array_map(function ($type) {
|
||||
return 'upload_' . $type;
|
||||
}, $node_types);
|
||||
|
||||
$max_filesize = $this->variableGet('upload_uploadsize_default', 1);
|
||||
$max_filesize = $max_filesize ? $max_filesize . 'MB' : '';
|
||||
|
||||
@@ -10,7 +10,8 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
* Drupal 7 file source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_file"
|
||||
* id = "d7_file",
|
||||
* source_module = "file"
|
||||
* )
|
||||
*/
|
||||
class File extends DrupalSqlBase {
|
||||
|
||||
@@ -91,9 +91,12 @@ class DownloadTest extends FileManagedTestBase {
|
||||
// Tilde (~) is excluded from this test because it is encoded by
|
||||
// rawurlencode() in PHP 5.2 but not in PHP 5.3, as per RFC 3986.
|
||||
// @see http://php.net/manual/function.rawurlencode.php#86506
|
||||
$basename = " -._!$'\"()*@[]?&+%#,;=:\n\x00" . // "Special" ASCII characters.
|
||||
"%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
|
||||
"éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
|
||||
// "Special" ASCII characters.
|
||||
$basename = " -._!$'\"()*@[]?&+%#,;=:\n\x00" .
|
||||
// Characters that look like a percent-escaped string.
|
||||
"%23%25%26%2B%2F%3F" .
|
||||
// Characters from various non-ASCII alphabets.
|
||||
"éøïвβ中國書۞";
|
||||
$basename_encoded = '%20-._%21%24%27%22%28%29%2A%40%5B%5D%3F%26%2B%25%23%2C%3B%3D%3A__' .
|
||||
'%2523%2525%2526%252B%252F%253F' .
|
||||
'%C3%A9%C3%B8%C3%AF%D0%B2%CE%B2%E4%B8%AD%E5%9C%8B%E6%9B%B8%DB%9E';
|
||||
|
||||
@@ -138,7 +138,7 @@ class FileFieldAnonymousSubmissionTest extends FileFieldTestBase {
|
||||
$label = 'Save';
|
||||
}
|
||||
else {
|
||||
$label = 'Save and publish';
|
||||
$label = 'Save';
|
||||
}
|
||||
$this->drupalPostForm(NULL, $edit, $label);
|
||||
$this->assertResponse(200);
|
||||
|
||||
@@ -77,7 +77,7 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
||||
|
||||
// Turn the "display" option off and check that the file is no longer displayed.
|
||||
$edit = [$field_name . '[0][display]' => FALSE];
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
|
||||
|
||||
$this->assertNoRaw($default_output, 'Field is hidden when "display" option is unchecked.');
|
||||
|
||||
@@ -87,7 +87,7 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
||||
$field_name . '[0][description]' => $description,
|
||||
$field_name . '[0][display]' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
|
||||
$this->assertText($description);
|
||||
|
||||
// Ensure the filename in the link's title attribute is escaped.
|
||||
@@ -167,7 +167,7 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
||||
'title[0][value]' => $title,
|
||||
'files[field_' . $field_name . '_0]' => drupal_realpath($file->uri),
|
||||
];
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($title);
|
||||
$this->drupalGet('node/' . $node->id() . '/edit');
|
||||
$this->assertText(t('The description may be used as the label of the link to the file.'));
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\file\Tests;
|
||||
|
||||
|
||||
/**
|
||||
* Tests file formatter access.
|
||||
* @group file
|
||||
|
||||
@@ -22,6 +22,11 @@ class FileFieldRevisionTest extends FileFieldTestBase {
|
||||
* should be deleted also.
|
||||
*/
|
||||
public function testRevisions() {
|
||||
// This test expects unused managed files to be marked as a temporary file
|
||||
// and then deleted up by file_cron().
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
$type_name = 'article';
|
||||
$field_name = strtolower($this->randomMachineName());
|
||||
@@ -63,7 +68,7 @@ class FileFieldRevisionTest extends FileFieldTestBase {
|
||||
|
||||
// Save a new version of the node without any changes.
|
||||
// Check that the file is still the same as the previous revision.
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', ['revision' => '1'], t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', ['revision' => '1'], t('Save'));
|
||||
$node_storage->resetCache([$nid]);
|
||||
$node = $node_storage->load($nid);
|
||||
$node_file_r3 = File::load($node->{$field_name}->target_id);
|
||||
|
||||
@@ -227,7 +227,7 @@ abstract class FileFieldTestBase extends WebTestBase {
|
||||
$edit[$name][] = $file_path;
|
||||
}
|
||||
}
|
||||
$this->drupalPostForm("node/$nid/edit", $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm("node/$nid/edit", $edit, t('Save'));
|
||||
|
||||
return $nid;
|
||||
}
|
||||
@@ -243,7 +243,7 @@ abstract class FileFieldTestBase extends WebTestBase {
|
||||
];
|
||||
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,7 +256,7 @@ abstract class FileFieldTestBase extends WebTestBase {
|
||||
];
|
||||
|
||||
$this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,7 @@ class FileFieldValidateTest extends FileFieldTestBase {
|
||||
// Try to post a new node without uploading a file.
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName();
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
|
||||
$this->assertRaw(t('@title field is required.', ['@title' => $field->getLabel()]), 'Node save failed when required file field was empty.');
|
||||
|
||||
// Create a new node with the uploaded file.
|
||||
@@ -50,7 +50,7 @@ class FileFieldValidateTest extends FileFieldTestBase {
|
||||
// Try to post a new node without uploading a file in the multivalue field.
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName();
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
|
||||
$this->assertRaw(t('@title field is required.', ['@title' => $field->getLabel()]), 'Node save failed when required multiple value file field was empty.');
|
||||
|
||||
// Create a new node with the uploaded file into the multivalue field.
|
||||
@@ -71,8 +71,10 @@ class FileFieldValidateTest extends FileFieldTestBase {
|
||||
$field_name = strtolower($this->randomMachineName());
|
||||
$this->createFileField($field_name, 'node', $type_name, [], ['required' => '1']);
|
||||
|
||||
$small_file = $this->getTestFile('text', 131072); // 128KB.
|
||||
$large_file = $this->getTestFile('text', 1310720); // 1.2MB
|
||||
// 128KB.
|
||||
$small_file = $this->getTestFile('text', 131072);
|
||||
// 1.2MB
|
||||
$large_file = $this->getTestFile('text', 1310720);
|
||||
|
||||
// Test uploading both a large and small file with different increments.
|
||||
$sizes = [
|
||||
|
||||
@@ -121,7 +121,7 @@ class FileFieldWidgetTest extends FileFieldTestBase {
|
||||
$this->assertTrue(isset($label[0]), 'Label for upload found.');
|
||||
|
||||
// Save the node and ensure it does not have the file.
|
||||
$this->drupalPostForm(NULL, [], t('Save and keep published'));
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
$node_storage->resetCache([$nid]);
|
||||
$node = $node_storage->load($nid);
|
||||
$this->assertTrue(empty($node->{$field_name}->target_id), 'File was successfully removed from the node.');
|
||||
@@ -238,8 +238,7 @@ class FileFieldWidgetTest extends FileFieldTestBase {
|
||||
$this->assertNoFieldByXPath('//input[@type="submit"]', t('Remove'), format_string('After removing all files, there is no "Remove" button displayed (JSMode=%type).', ['%type' => $type]));
|
||||
|
||||
// Save the node and ensure it does not have any files.
|
||||
$this->drupalPostForm(NULL, ['title[0][value]' => $this->randomMachineName()], t('Save and publish'));
|
||||
$matches = [];
|
||||
$this->drupalPostForm(NULL, ['title[0][value]' => $this->randomMachineName()], t('Save'));
|
||||
preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
|
||||
$nid = $matches[1];
|
||||
$node_storage->resetCache([$nid]);
|
||||
@@ -368,7 +367,7 @@ class FileFieldWidgetTest extends FileFieldTestBase {
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
|
||||
$this->drupalPostForm('node/add/article', $edit, t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
|
||||
// Add a comment with a file.
|
||||
@@ -402,7 +401,8 @@ class FileFieldWidgetTest extends FileFieldTestBase {
|
||||
|
||||
// Unpublishes node.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and unpublish'));
|
||||
$edit = ['status[value]' => FALSE];
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Ensures normal user can no longer download the file.
|
||||
$this->drupalLogin($user);
|
||||
|
||||
@@ -30,6 +30,11 @@ class FileListingTest extends FileFieldTestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// This test expects unused managed files to be marked as a temporary file.
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
|
||||
$this->adminUser = $this->drupalCreateUser(['access files overview', 'bypass node access']);
|
||||
$this->baseUser = $this->drupalCreateUser();
|
||||
$this->createFileField('file', 'node', 'article', [], ['file_extensions' => 'txt png']);
|
||||
|
||||
@@ -194,4 +194,55 @@ class FileManagedFileElementTest extends FileFieldTestBase {
|
||||
$file->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that unused permanent files can be used.
|
||||
*/
|
||||
public function testUnusedPermanentFileValidation() {
|
||||
|
||||
// Create a permanent file without usages.
|
||||
$file = $this->getTestFile('image');
|
||||
$file->setPermanent();
|
||||
$file->save();
|
||||
|
||||
// By default, unused files are no longer marked temporary, and it must be
|
||||
// allowed to reference an unused file.
|
||||
$this->drupalGet('file/test/1/0/1/' . $file->id());
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
$this->assertNoText('The file used in the Managed file & butter field may not be referenced.');
|
||||
$this->assertText('The file ids are ' . $file->id());
|
||||
|
||||
// Enable marking unused files as tempory, unused permanent files must not
|
||||
// be referenced now.
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
$this->drupalGet('file/test/1/0/1/' . $file->id());
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
$this->assertText('The file used in the Managed file & butter field may not be referenced.');
|
||||
$this->assertNoText('The file ids are ' . $file->id());
|
||||
|
||||
// Make the file temporary, now using it is allowed.
|
||||
$file->setTemporary();
|
||||
$file->save();
|
||||
|
||||
$this->drupalGet('file/test/1/0/1/' . $file->id());
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
$this->assertNoText('The file used in the Managed file & butter field may not be referenced.');
|
||||
$this->assertText('The file ids are ' . $file->id());
|
||||
|
||||
// Make the file permanent again and add a usage from itself, referencing is
|
||||
// still allowed.
|
||||
$file->setPermanent();
|
||||
$file->save();
|
||||
|
||||
/** @var \Drupal\file\FileUsage\FileUsageInterface $file_usage */
|
||||
$file_usage = \Drupal::service('file.usage');
|
||||
$file_usage->add($file, 'file', 'file', $file->id());
|
||||
|
||||
$this->drupalGet('file/test/1/0/1/' . $file->id());
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
$this->assertNoText('The file used in the Managed file & butter field may not be referenced.');
|
||||
$this->assertText('The file ids are ' . $file->id());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ class FileOnTranslatedEntityTest extends FileFieldTestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// This test expects unused managed files to be marked as temporary a file.
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
|
||||
// Create the "Basic page" node type.
|
||||
// @todo Remove the disabling of new revision creation in
|
||||
// https://www.drupal.org/node/1239558.
|
||||
|
||||
@@ -27,6 +27,10 @@ class FilePrivateTest extends FileFieldTestBase {
|
||||
node_access_test_add_field(NodeType::load('article'));
|
||||
node_access_rebuild();
|
||||
\Drupal::state()->set('node_access_test.private', TRUE);
|
||||
// This test expects unused managed files to be marked as a temporary file.
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,10 +77,10 @@ class FilePrivateTest extends FileFieldTestBase {
|
||||
// Attempt to reuse the file when editing a node.
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName();
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
|
||||
$new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$edit[$field_name . '[0][fids]'] = $node_file->id();
|
||||
$this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save'));
|
||||
// Make sure the form submit failed - we stayed on the edit form.
|
||||
$this->assertUrl('node/' . $new_node->id() . '/edit');
|
||||
// Check that we got the expected constraint form error.
|
||||
@@ -87,7 +91,7 @@ class FilePrivateTest extends FileFieldTestBase {
|
||||
$edit = [];
|
||||
$edit['title[0][value]'] = $this->randomMachineName();
|
||||
$edit[$field_name . '[0][fids]'] = $node_file->id();
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
|
||||
$this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
|
||||
$new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
|
||||
$this->assertTrue(empty($new_node), 'Node was not created.');
|
||||
$this->assertUrl('node/add/' . $type_name);
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -8,8 +8,8 @@ dependencies:
|
||||
- file
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -259,7 +259,7 @@ abstract class FileFieldTestBase extends BrowserTestBase {
|
||||
/**
|
||||
* Asserts that a file exists physically on disk.
|
||||
*
|
||||
* Overrides PHPUnit_Framework_Assert::assertFileExists() to also work with
|
||||
* Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with
|
||||
* file entities.
|
||||
*
|
||||
* @param \Drupal\File\FileInterface|string $file
|
||||
@@ -286,7 +286,7 @@ abstract class FileFieldTestBase extends BrowserTestBase {
|
||||
/**
|
||||
* Asserts that a file does not exist on disk.
|
||||
*
|
||||
* Overrides PHPUnit_Framework_Assert::assertFileExists() to also work with
|
||||
* Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with
|
||||
* file entities.
|
||||
*
|
||||
* @param \Drupal\File\FileInterface|string $file
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests the upgrade path for setting the file usage deletion configuration.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2801777
|
||||
*
|
||||
* @group Update
|
||||
*/
|
||||
class FileUsageTemporaryDeletionConfigurationUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['file'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that make_unused_managed_files_temporary conditions are correct.
|
||||
*
|
||||
* Verify that the before and after conditions for the variable are correct.
|
||||
*/
|
||||
public function testUpdateHookN() {
|
||||
$this->assertIdentical($this->config('file.settings')->get('make_unused_managed_files_temporary'), NULL);
|
||||
$this->runUpdates();
|
||||
$this->assertIdentical($this->config('file.settings')->get('make_unused_managed_files_temporary'), FALSE);
|
||||
$this->assertResponse('200');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,6 +28,11 @@ class DeleteTest extends FileManagedUnitTestBase {
|
||||
* Tries deleting a file that is in use.
|
||||
*/
|
||||
public function testInUse() {
|
||||
// This test expects unused managed files to be marked as a temporary file
|
||||
// and then deleted up by file_cron().
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
$file = $this->createFile();
|
||||
$file_usage = $this->container->get('file.usage');
|
||||
$file_usage->add($file, 'testing', 'test', 1);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Core\StreamWrapper\PublicStream;
|
||||
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
|
||||
|
||||
/**
|
||||
* A trait to setup the file migration.
|
||||
*/
|
||||
trait FileMigrationSetupTrait {
|
||||
|
||||
/**
|
||||
* Prepare the file migration for running.
|
||||
*/
|
||||
protected function fileMigrationSetup() {
|
||||
$this->installSchema('file', ['file_usage']);
|
||||
$this->installEntitySchema('file');
|
||||
$this->container->get('stream_wrapper_manager')->registerWrapper('public', PublicStream::class, StreamWrapperInterface::NORMAL);
|
||||
|
||||
$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\Plugin\Migration $migration */
|
||||
$migration = $this->getMigration('d7_file');
|
||||
// Set the source plugin's source_base_path configuration value, which
|
||||
// would normally be set by the user running the migration.
|
||||
$source = $migration->getSourceConfiguration();
|
||||
$source['constants']['source_base_path'] = $fs->realpath('public://');
|
||||
$migration->set('source', $source);
|
||||
$this->executeMigration($migration);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\file\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\file\FileInterface;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
@@ -14,6 +13,8 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
*/
|
||||
class MigrateFileTest extends MigrateDrupal7TestBase {
|
||||
|
||||
use FileMigrationSetupTrait;
|
||||
|
||||
public static $modules = ['file'];
|
||||
|
||||
/**
|
||||
@@ -22,23 +23,7 @@ class MigrateFileTest extends MigrateDrupal7TestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('file');
|
||||
$this->container->get('stream_wrapper_manager')->registerWrapper('public', 'Drupal\Core\StreamWrapper\PublicStream', StreamWrapperInterface::NORMAL);
|
||||
|
||||
$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\Plugin\Migration $migration */
|
||||
$migration = $this->getMigration('d7_file');
|
||||
// Set the source plugin's source_base_path configuration value, which
|
||||
// would normally be set by the user running the migration.
|
||||
$source = $migration->getSourceConfiguration();
|
||||
$source['constants']['source_base_path'] = $fs->realpath('public://');
|
||||
$migration->set('source', $source);
|
||||
$this->executeMigration($migration);
|
||||
$this->fileMigrationSetup();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
|
||||
* @coversDefaultClass \Drupal\file\Plugin\migrate\process\d6\CckFile
|
||||
*
|
||||
* @group file
|
||||
* @group legacy
|
||||
*/
|
||||
class CckFileTest extends MigrateDrupalTestBase {
|
||||
|
||||
|
||||
@@ -81,6 +81,22 @@ class SaveTest extends FileManagedUnitTestBase {
|
||||
$this->assertEqual(1, count($fids));
|
||||
$this->assertEqual([$uppercase_file->id() => $uppercase_file->id()], $fids);
|
||||
|
||||
// Save a file with zero bytes.
|
||||
$file = File::create([
|
||||
'uid' => 1,
|
||||
'filename' => 'no-druplicon.txt',
|
||||
'uri' => 'public://no-druplicon.txt',
|
||||
'filemime' => 'text/plain',
|
||||
'status' => FILE_STATUS_PERMANENT,
|
||||
]);
|
||||
|
||||
file_put_contents($file->getFileUri(), '');
|
||||
|
||||
// Save it, inserting a new record.
|
||||
$file->save();
|
||||
|
||||
// Check the file size was set to zero.
|
||||
$this->assertSame(0, $file->getSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Kernel;
|
||||
|
||||
use Drupal\file\Entity\File;
|
||||
|
||||
/**
|
||||
|
||||
@@ -74,11 +74,34 @@ class UsageTest extends FileManagedUnitTestBase {
|
||||
$this->assertEqual($usage[2]->count, 2, 'Correct count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests file usage deletion when files are made temporary.
|
||||
*/
|
||||
public function testRemoveUsageTemporary() {
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', TRUE)
|
||||
->save();
|
||||
$file = $this->doTestRemoveUsage();
|
||||
$this->assertTrue($file->isTemporary());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests file usage deletion when files are made temporary.
|
||||
*/
|
||||
public function testRemoveUsageNonTemporary() {
|
||||
$this->config('file.settings')
|
||||
->set('make_unused_managed_files_temporary', FALSE)
|
||||
->save();
|
||||
$file = $this->doTestRemoveUsage();
|
||||
$this->assertFalse($file->isTemporary());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests \Drupal\file\FileUsage\DatabaseFileUsageBackend::delete().
|
||||
*/
|
||||
public function testRemoveUsage() {
|
||||
public function doTestRemoveUsage() {
|
||||
$file = $this->createFile();
|
||||
$file->setPermanent();
|
||||
$file_usage = $this->container->get('file.usage');
|
||||
db_insert('file_usage')
|
||||
->fields([
|
||||
@@ -116,6 +139,7 @@ class UsageTest extends FileManagedUnitTestBase {
|
||||
->execute()
|
||||
->fetchField();
|
||||
$this->assertIdentical(FALSE, $count, 'Decrementing non-exist record complete.');
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\file\Kernel;
|
||||
|
||||
|
||||
/**
|
||||
* Tests the file_validate() function.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\cckfield\d6;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\file\Plugin\migrate\cckfield\d6\FileField;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\file\Plugin\migrate\cckfield\d6\FileField
|
||||
* @group file
|
||||
* @group legacy
|
||||
*/
|
||||
class FileCckTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->plugin = new FileField([], 'file', []);
|
||||
|
||||
$migration = $this->prophesize(MigrationInterface::class);
|
||||
|
||||
// The plugin's processFieldValues() method will call
|
||||
// mergeProcessOfProperty() and return nothing. So, in order to examine the
|
||||
// process pipeline created by the plugin, we need to ensure that
|
||||
// getProcess() always returns the last input to mergeProcessOfProperty().
|
||||
$migration->mergeProcessOfProperty(Argument::type('string'), Argument::type('array'))
|
||||
->will(function ($arguments) use ($migration) {
|
||||
$migration->getProcess()->willReturn($arguments[1]);
|
||||
});
|
||||
$this->migration = $migration->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::processCckFieldValues
|
||||
*/
|
||||
public function testProcessCckFieldValues() {
|
||||
$this->plugin->processCckFieldValues($this->migration, 'somefieldname', []);
|
||||
|
||||
$expected = [
|
||||
'plugin' => 'd6_cck_file',
|
||||
'source' => 'somefieldname',
|
||||
];
|
||||
$this->assertSame($expected, $this->migration->getProcess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testGetFieldType().
|
||||
*/
|
||||
public function getFieldTypeProvider() {
|
||||
return [
|
||||
['image', 'imagefield_widget'],
|
||||
['file', 'filefield_widget'],
|
||||
['file', 'x_widget']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getFieldType
|
||||
* @dataProvider getFieldTypeProvider
|
||||
*/
|
||||
public function testGetFieldType($expected_type, $widget_type, array $settings = []) {
|
||||
$row = new Row();
|
||||
$row->setSourceProperty('widget_type', $widget_type);
|
||||
$row->setSourceProperty('global_settings', $settings);
|
||||
$this->assertSame($expected_type, $this->plugin->getFieldType($row));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\cckfield\d7;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\file\Plugin\migrate\cckfield\d7\FileField;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\file\Plugin\migrate\cckfield\d7\FileField
|
||||
* @group file
|
||||
* @group legacy
|
||||
*/
|
||||
class FileCckTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->plugin = new FileField([], 'file', []);
|
||||
|
||||
$migration = $this->prophesize(MigrationInterface::class);
|
||||
|
||||
// The plugin's processFieldValues() method will call
|
||||
// mergeProcessOfProperty() and return nothing. So, in order to examine the
|
||||
// process pipeline created by the plugin, we need to ensure that
|
||||
// getProcess() always returns the last input to mergeProcessOfProperty().
|
||||
$migration->mergeProcessOfProperty(Argument::type('string'), Argument::type('array'))
|
||||
->will(function ($arguments) use ($migration) {
|
||||
$migration->getProcess()->willReturn($arguments[1]);
|
||||
});
|
||||
$this->migration = $migration->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::processCckFieldValues
|
||||
*/
|
||||
public function testProcessCckFieldValues() {
|
||||
$this->plugin->processCckFieldValues($this->migration, 'somefieldname', []);
|
||||
|
||||
$expected = [
|
||||
'plugin' => 'iterator',
|
||||
'source' => 'somefieldname',
|
||||
'process' => [
|
||||
'target_id' => 'fid',
|
||||
'display' => 'display',
|
||||
'description' => 'description',
|
||||
],
|
||||
];
|
||||
$this->assertSame($expected, $this->migration->getProcess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testGetFieldType().
|
||||
*/
|
||||
public function getFieldTypeProvider() {
|
||||
return [
|
||||
['image', 'imagefield_widget'],
|
||||
['file', 'filefield_widget'],
|
||||
['file', 'x_widget']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getFieldType
|
||||
* @dataProvider getFieldTypeProvider
|
||||
*/
|
||||
public function testGetFieldType($expected_type, $widget_type, array $settings = []) {
|
||||
$row = new Row();
|
||||
$row->setSourceProperty('widget_type', $widget_type);
|
||||
$row->setSourceProperty('global_settings', $settings);
|
||||
$this->assertSame($expected_type, $this->plugin->getFieldType($row));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\cckfield\d7;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\file\Plugin\migrate\cckfield\d7\ImageField;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\file\Plugin\migrate\cckfield\d7\ImageField
|
||||
* @group file
|
||||
* @group legacy
|
||||
*/
|
||||
class ImageCckTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate_drupal\Plugin\MigrateCckFieldInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->plugin = new ImageField([], 'image', []);
|
||||
|
||||
$migration = $this->prophesize(MigrationInterface::class);
|
||||
|
||||
// The plugin's processFieldValues() method will call
|
||||
// mergeProcessOfProperty() and return nothing. So, in order to examine the
|
||||
// process pipeline created by the plugin, we need to ensure that
|
||||
// getProcess() always returns the last input to mergeProcessOfProperty().
|
||||
$migration->mergeProcessOfProperty(Argument::type('string'), Argument::type('array'))
|
||||
->will(function ($arguments) use ($migration) {
|
||||
$migration->getProcess()->willReturn($arguments[1]);
|
||||
});
|
||||
$this->migration = $migration->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::processCckFieldValues
|
||||
*/
|
||||
public function testProcessCckFieldValues() {
|
||||
$this->plugin->processCckFieldValues($this->migration, 'somefieldname', []);
|
||||
|
||||
$expected = [
|
||||
'plugin' => 'iterator',
|
||||
'source' => 'somefieldname',
|
||||
'process' => [
|
||||
'target_id' => 'fid',
|
||||
'alt' => 'alt',
|
||||
'title' => 'title',
|
||||
'width' => 'width',
|
||||
'height' => 'height',
|
||||
],
|
||||
];
|
||||
$this->assertSame($expected, $this->migration->getProcess());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\field\d6;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\file\Plugin\migrate\field\d6\FileField;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\file\Plugin\migrate\field\d6\FileField
|
||||
* @group file
|
||||
*/
|
||||
class FileFieldTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->plugin = new FileField([], 'file', []);
|
||||
|
||||
$migration = $this->prophesize(MigrationInterface::class);
|
||||
|
||||
// The plugin's processFieldValues() method will call
|
||||
// mergeProcessOfProperty() and return nothing. So, in order to examine the
|
||||
// process pipeline created by the plugin, we need to ensure that
|
||||
// getProcess() always returns the last input to mergeProcessOfProperty().
|
||||
$migration->mergeProcessOfProperty(Argument::type('string'), Argument::type('array'))
|
||||
->will(function ($arguments) use ($migration) {
|
||||
$migration->getProcess()->willReturn($arguments[1]);
|
||||
});
|
||||
$this->migration = $migration->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::processFieldValues
|
||||
*/
|
||||
public function testProcessFieldValues() {
|
||||
$this->plugin->processFieldValues($this->migration, 'somefieldname', []);
|
||||
|
||||
$expected = [
|
||||
'plugin' => 'd6_field_file',
|
||||
'source' => 'somefieldname',
|
||||
];
|
||||
$this->assertSame($expected, $this->migration->getProcess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testGetFieldType().
|
||||
*/
|
||||
public function getFieldTypeProvider() {
|
||||
return [
|
||||
['image', 'imagefield_widget'],
|
||||
['file', 'filefield_widget'],
|
||||
['file', 'x_widget']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getFieldType
|
||||
* @dataProvider getFieldTypeProvider
|
||||
*/
|
||||
public function testGetFieldType($expected_type, $widget_type, array $settings = []) {
|
||||
$row = new Row();
|
||||
$row->setSourceProperty('widget_type', $widget_type);
|
||||
$row->setSourceProperty('global_settings', $settings);
|
||||
$this->assertSame($expected_type, $this->plugin->getFieldType($row));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\field\d7;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\file\Plugin\migrate\field\d7\FileField;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\file\Plugin\migrate\field\d7\FileField
|
||||
* @group file
|
||||
*/
|
||||
class FileFieldTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->plugin = new FileField([], 'file', []);
|
||||
|
||||
$migration = $this->prophesize(MigrationInterface::class);
|
||||
|
||||
// The plugin's processFieldValues() method will call
|
||||
// mergeProcessOfProperty() and return nothing. So, in order to examine the
|
||||
// process pipeline created by the plugin, we need to ensure that
|
||||
// getProcess() always returns the last input to mergeProcessOfProperty().
|
||||
$migration->mergeProcessOfProperty(Argument::type('string'), Argument::type('array'))
|
||||
->will(function ($arguments) use ($migration) {
|
||||
$migration->getProcess()->willReturn($arguments[1]);
|
||||
});
|
||||
$this->migration = $migration->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::processFieldValues
|
||||
*/
|
||||
public function testProcessFieldValues() {
|
||||
$this->plugin->processFieldValues($this->migration, 'somefieldname', []);
|
||||
|
||||
$expected = [
|
||||
'plugin' => 'iterator',
|
||||
'source' => 'somefieldname',
|
||||
'process' => [
|
||||
'target_id' => 'fid',
|
||||
'display' => 'display',
|
||||
'description' => 'description',
|
||||
],
|
||||
];
|
||||
$this->assertSame($expected, $this->migration->getProcess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testGetFieldType().
|
||||
*/
|
||||
public function getFieldTypeProvider() {
|
||||
return [
|
||||
['image', 'imagefield_widget'],
|
||||
['file', 'filefield_widget'],
|
||||
['file', 'x_widget']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getFieldType
|
||||
* @dataProvider getFieldTypeProvider
|
||||
*/
|
||||
public function testGetFieldType($expected_type, $widget_type, array $settings = []) {
|
||||
$row = new Row();
|
||||
$row->setSourceProperty('widget_type', $widget_type);
|
||||
$row->setSourceProperty('global_settings', $settings);
|
||||
$this->assertSame($expected_type, $this->plugin->getFieldType($row));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\field\d7;
|
||||
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\file\Plugin\migrate\field\d7\ImageField;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\file\Plugin\migrate\field\d7\ImageField
|
||||
* @group file
|
||||
*/
|
||||
class ImageFieldTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate_drupal\Plugin\MigrateFieldInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->plugin = new ImageField([], 'image', []);
|
||||
|
||||
$migration = $this->prophesize(MigrationInterface::class);
|
||||
|
||||
// The plugin's processFieldValues() method will call
|
||||
// mergeProcessOfProperty() and return nothing. So, in order to examine the
|
||||
// process pipeline created by the plugin, we need to ensure that
|
||||
// getProcess() always returns the last input to mergeProcessOfProperty().
|
||||
$migration->mergeProcessOfProperty(Argument::type('string'), Argument::type('array'))
|
||||
->will(function ($arguments) use ($migration) {
|
||||
$migration->getProcess()->willReturn($arguments[1]);
|
||||
});
|
||||
$this->migration = $migration->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::processFieldValues
|
||||
*/
|
||||
public function testProcessFieldValues() {
|
||||
$this->plugin->processFieldValues($this->migration, 'somefieldname', []);
|
||||
|
||||
$expected = [
|
||||
'plugin' => 'iterator',
|
||||
'source' => 'somefieldname',
|
||||
'process' => [
|
||||
'target_id' => 'fid',
|
||||
'alt' => 'alt',
|
||||
'title' => 'title',
|
||||
'width' => 'width',
|
||||
'height' => 'height',
|
||||
],
|
||||
];
|
||||
$this->assertSame($expected, $this->migration->getProcess());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @group file
|
||||
* @group legacy
|
||||
*/
|
||||
class CckFileTest extends UnitTestCase {
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\file\Unit\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\file\Plugin\migrate\process\d6\FieldFile;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Plugin\MigrateProcessInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @group file
|
||||
*/
|
||||
class FieldFileTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Tests that alt and title attributes are included in transformed values.
|
||||
*/
|
||||
public function testTransformAltTitle() {
|
||||
$executable = $this->prophesize(MigrateExecutableInterface::class)->reveal();
|
||||
$row = $this->prophesize(Row::class)->reveal();
|
||||
$migration = $this->prophesize(MigrationInterface::class)->reveal();
|
||||
|
||||
$migration_plugin = $this->prophesize(MigrateProcessInterface::class);
|
||||
$migration_plugin->transform(1, $executable, $row, 'foo')->willReturn(1);
|
||||
|
||||
$plugin = new FieldFile([], 'd6_file', [], $migration, $migration_plugin->reveal());
|
||||
|
||||
$options = [
|
||||
'alt' => 'Foobaz',
|
||||
'title' => 'Wambooli',
|
||||
];
|
||||
$value = [
|
||||
'fid' => 1,
|
||||
'list' => TRUE,
|
||||
'data' => serialize($options),
|
||||
];
|
||||
|
||||
$transformed = $plugin->transform($value, $executable, $row, 'foo');
|
||||
$expected = [
|
||||
'target_id' => 1,
|
||||
'display' => TRUE,
|
||||
'description' => '',
|
||||
'alt' => 'Foobaz',
|
||||
'title' => 'Wambooli',
|
||||
];
|
||||
$this->assertSame($expected, $transformed);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user