Skip to content

Filesystem::joinPaths() #33375

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Symfony/Component/Filesystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ CHANGELOG
-----

* support for passing a `null` value to `Filesystem::isAbsolutePath()` is deprecated and will be removed in 5.0
* `Filesystem::joinPaths()` added

4.3.0
-----
Expand Down
21 changes: 21 additions & 0 deletions src/Symfony/Component/Filesystem/Filesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ class Filesystem
{
private static $lastError;

public static function joinPaths(string ...$pathSegments): string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A description including an example would be helpful

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the docs I've just created help? symfony/symfony-docs#12803

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing but the method itself should have a description in the phpdoc too

{
// remove empty segments
$pathSegments = array_filter($pathSegments);

$potentialDirectorySeparators = '/\\';
// keep leading separator
$first = rtrim(array_shift($pathSegments), $potentialDirectorySeparators);
// keep trailing separator
$last = ltrim(array_pop($pathSegments), $potentialDirectorySeparators);
// trim separators in between
$pathSegments = array_map(function ($item) use ($potentialDirectorySeparators) {
return trim($item, $potentialDirectorySeparators);
}, $pathSegments);

array_push($pathSegments, $last);
array_unshift($pathSegments, $first);

return implode('/', $pathSegments);
}

/**
* Copies a file.
*
Expand Down
38 changes: 38 additions & 0 deletions src/Symfony/Component/Filesystem/Tests/FilesystemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,44 @@ public function testCopyShouldKeepExecutionPermission()
$this->assertFilePermissions(767, $targetFilePath);
}

/**
* @dataProvider providePathSegmentsForJoin
*/
public function testJoinPath(string $expectedJoinedPath, array $pathSegments): void
{
$this->assertSame($expectedJoinedPath, \Symfony\Component\Filesystem\Filesystem::joinPaths(...$pathSegments));
}

public function providePathSegmentsForJoin(): array
{
return [
'simple join' => [
'etc/init.d',
['etc', 'init.d'],
],
'keep heading and trailing separators' => [
'/etc/init.d/',
['/etc', 'init.d/'],
],
'skip empty' => [
'etc/init.d',
['', 'etc', '', '', 'init.d', ''],
],
'does not trim heading and trailing separator if respective segments are empty' => [
'/etc/init.d/',
['', '/etc', '', '', 'init.d/', ''],
],
'trims both types of separators' => [
'etc/some/other',
['etc\\', '\\some\\', '\\other'],
],
'keeps heading and trailing backslashes' => [
'\\etc/init.d\\',
['\\etc', 'init.d\\'],
],
];
}

/**
* Normalize the given path (transform each blackslash into a real directory separator).
*/
Expand Down