-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature-rectore-3115670: rule for file_unmanaged_copy #43
base: main
Are you sure you want to change the base?
feature-rectore-3115670: rule for file_unmanaged_copy #43
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work, @mohsin-saeed!
I think you've picked a complicated situation here since the function has an optional $destination
argument, but the service method requires it.
We would need to account for this in our rector rule or at least list it in the "Improvement Opportunities".
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
@trigger_error('file_unmanaged_copy() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::copy(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
try {
$file_system = \Drupal::service('file_system');
// Build a destination URI if necessary.
if (!isset($destination)) {
$destination = file_build_uri($file_system->basename($source));
}
return $file_system->copy($source, $destination, $replace);
}
catch (FileException $e) {
return FALSE;
}
}
In the above example, we would probably need to check if $destination
is not passed as an argument. You can check $node->args
which is an array. If there are at least two arguments, your substitution would work. If not, we should do the more complex replacement as shown above or at least skip over that situation.
Thanks again for the submission. Do you want to make those changes?
function simple_example() { | ||
$source = '/test/directory'; | ||
$destination = '/test/directory_2'; | ||
file_unmanaged_copy($source, $destination,FILE_CREATE_DIRECTORY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mohsin-saeed, it looks like you can actually call file_unmanaged_copy
with just the source
argument.
Can you create an example with that?
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
@trigger_error('file_unmanaged_copy() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::copy(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
try {
$file_system = \Drupal::service('file_system');
// Build a destination URI if necessary.
if (!isset($destination)) {
$destination = file_build_uri($file_system->basename($source));
}
return $file_system->copy($source, $destination, $replace);
}
catch (FileException $e) {
return FALSE;
}
}
/** | ||
* Replaces deprecated file_unmanaged_copy() calls. | ||
* | ||
* See https://api.drupal.org/api/drupal/core%21includes%21file.inc/function/file_unmanaged_copy/8.7.x. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide a link to the change record. This is usually in the function definition comment,
/**
* Copies a file to a new location without database changes or hook invocation.
*
* This is a powerful function that in many ways performs like an advanced
* version of copy().
* - Checks if $source and $destination are valid and readable/writable.
* - If file already exists in $destination either the call will error out,
* replace the file or rename the file based on the $replace parameter.
* - If the $source and $destination are equal, the behavior depends on the
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
* will rename the file until the $destination is unique.
* - Works around a PHP bug where copy() does not properly support streams if
* safe_mode or open_basedir are enabled.
* @see https://bugs.php.net/bug.php?id=60456
*
* @param $source
* A string specifying the filepath or URI of the source file.
* @param $destination
* A URI containing the destination that $source should be copied to. The
* URI may be a bare filepath (without a scheme). If this value is omitted,
* Drupal's default files scheme will be used, usually "public://".
* @param $replace
* Replace behavior when the destination file already exists:
* - FILE_EXISTS_REPLACE - Replace the existing file.
* - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is
* unique.
* - FILE_EXISTS_ERROR - Do nothing and return FALSE.
*
* @return
* The path to the new file, or FALSE in the event of an error.
*
* @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
* Use \Drupal\Core\File\FileSystemInterface::copy().
*
* @see file_copy()
* @see https://www.drupal.org/node/3006851
*/
* - Dependency Injection | ||
*/ | ||
final class FileUnmanagedCopyRector extends AbstractRector { | ||
use TraitsByClassHelperTrait; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless you are looking at traits for classes, you don't need to add this trait to the rector class.
* Improvement opportunities | ||
* - Dependency Injection | ||
*/ | ||
final class FileUnmanagedCopyRector extends AbstractRector { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For simple function to service method calls, we have a class you could extend, FunctionToServiceBase
.
Unfortunately, I think that this rector rule is more complex. I'll add a comment to the overall review.
* @inheritdoc | ||
*/ | ||
public function refactor(Node $node): ?Node { | ||
if ($node->name instanceof Node\Name && 'file_unmanaged_copy' === (string) $node->name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've started to use if ($node->getName($node->name) === 'file_unmanaged_copy') {
in places like this which is easier to read.
Thank you for review @damontgomery. I will make these changes along with your other mentioned changes. |
use PhpParser\Node; | ||
use Rector\Rector\AbstractRector; | ||
use Rector\RectorDefinition\CodeSample; | ||
use Rector\RectorDefinition\RectorDefinition; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mohsin-saeed, with the update to Rector, all of the Rector\
class names need to be changed to Rector\Core\
.
Sorry for moving things from underneath you. :(
file_unmanaged_copy rector