Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Path Converter Laravel Package

matthiasmullie/path-converter

Convert relative paths between source and target locations. Given a file currently relative to one path (e.g., an import), it returns the equivalent relative path from another path—useful for moving/minifying assets while keeping URLs correct.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package via Composer:

composer require matthiasmullie/path-converter

First Use Case: Convert relative paths in CSS/JS files when moving them to a new directory structure.

use MatthiasMullie\PathConverter\Converter;

// Define source and target paths
$from = '/resources/css/styles.css';
$to = '/public/dist/styles.css';

// Create converter instance
$converter = new Converter($from, $to);

// Convert a relative path
$originalPath = '../../images/logo.png';
$convertedPath = $converter->convert($originalPath);
// $convertedPath now contains '../images/logo.png'

Where to Look First:

  • The README.md for basic usage
  • The Converter class for implementation details
  • Laravel's storage_path() and public_path() helpers for common path resolutions

Implementation Patterns

Core Workflow

  1. Path Resolution: Convert Laravel's absolute paths to relative paths before passing to the converter

    $from = str_replace(base_path(), '', storage_path('app/css/main.css'));
    $to = str_replace(base_path(), '', public_path('dist/css/main.css'));
    
  2. Asset Pipeline Integration: Use in Laravel Mix or custom build scripts

    // mix.js
    const converter = new Converter('/resources/css', '/public/dist/css');
    
  3. Service Layer Pattern: Create a dedicated service class

    class PathConverterService {
        protected $converter;
    
        public function __construct() {
            $this->converter = new Converter(
                $this->getSourcePath(),
                $this->getTargetPath()
            );
        }
    
        public function convertPath(string $path): string {
            return $this->converter->convert($path);
        }
    }
    

Common Integration Patterns

1. Blade Template Processing

@php
    $converter = new Converter(
        str_replace(base_path(), '', storage_path('app/views/partials/header.blade.php')),
        str_replace(base_path(), '', public_path('cached/views/header.blade.php'))
    );
@endphp

<img src="{{ $converter->convert('images/logo.png') }}">

2. File Migration Utility

class FileMigrator {
    public function migrate(string $sourceDir, string $targetDir): void {
        $converter = new Converter($sourceDir, $targetDir);

        foreach (glob($sourceDir . '/**/*') as $file) {
            $relativePath = $converter->convert(str_replace($sourceDir, '', $file));
            // Process migrated file with new path
        }
    }
}

3. Dynamic Path Conversion Middleware

public function handle($request, Closure $next) {
    $converter = app()->make(Converter::class);

    if ($request->has('asset_path')) {
        $request->merge([
            'converted_path' => $converter->convert($request->input('asset_path'))
        ]);
    }

    return $next($request);
}

4. Testing Helper

class PathConverterTestCase extends TestCase {
    protected function convertPath(string $from, string $to, string $path): string {
        return (new Converter($from, $to))->convert($path);
    }
}

Laravel-Specific Patterns

1. Configuration-Based Conversion

// config/path-converter.php
return [
    'default' => [
        'from' => env('PATH_CONVERTER_FROM', 'resources'),
        'to' => env('PATH_CONVERTER_TO', 'public/dist'),
    ],
    'custom' => [
        'from' => 'storage/app',
        'to' => 'public/uploads',
    ],
];

// Usage
$converter = new Converter(
    config('path-converter.default.from'),
    config('path-converter.default.to')
);

2. Facade Implementation

// app/Facades/PathConverter.php
namespace App\Facades;

use Illuminate\Support\Facades\Facade;
use MatthiasMullie\PathConverter\Converter;

class PathConverter extends Facade {
    protected static function getFacadeAccessor() {
        return 'path.converter';
    }
}

// app/Providers/AppServiceProvider.php
public function register() {
    $this->app->singleton('path.converter', function() {
        return new Converter(
            config('path-converter.default.from'),
            config('path-converter.default.to')
        );
    });
}

// Usage
use App\Facades\PathConverter;

$converted = PathConverter::convert('../../images/banner.jpg');

3. Artisan Command for Bulk Conversion

class ConvertPathsCommand extends Command {
    protected $signature = 'paths:convert
        {source : Source directory path}
        {target : Target directory path}
        {--file= : Specific file to convert}';

    public function handle() {
        $converter = new Converter($this->argument('source'), $this->argument('target'));

        if ($file = $this->option('file')) {
            $this->convertSingleFile($file, $converter);
        } else {
            $this->convertDirectory($this->argument('source'), $converter);
        }
    }

    protected function convertSingleFile(string $file, Converter $converter) {
        $content = file_get_contents($file);
        $converted = preg_replace_callback(
            '/url\(([\'"])(.*?)\1\)/',
            fn($matches) => 'url('.$matches[1].$converter->convert($matches[2]).$matches[1].')',
            $content
        );

        file_put_contents($file, $converted);
        $this->info("Converted paths in {$file}");
    }
}

Gotchas and Tips

Common Pitfalls

1. Absolute Path Handling

// ❌ Problem: Absolute paths will break conversion
$converter = new Converter('/var/www/project/resources', '/var/www/project/public');
$result = $converter->convert('/var/www/project/images/logo.png');
// Returns '/var/www/project/public/var/www/project/images/logo.png'

// ✅ Solution: Use relative paths
$converter = new Converter('resources', 'public');
$result = $converter->convert('../images/logo.png');
// Returns '../images/logo.png'

2. Windows Path Separators

// ❌ Problem: Windows paths with backslashes
$converter = new Converter('C:\\project\\resources', 'C:\\project\\public');
$result = $converter->convert('..\\images\\logo.png');
// May not convert correctly

// ✅ Solution: Normalize paths
$converter = new Converter(
    str_replace('\\', '/', 'C:/project/resources'),
    str_replace('\\', '/', 'C:/project/public')
);
$result = $converter->convert('../images/logo.png');
// Returns '../images/logo.png'

3. Deep Directory Traversal

// ❌ Problem: Complex path with many ../
$converter = new Converter('resources/css', 'public/dist/css');
$result = $converter->convert('../../../../images/logo.png');
// May not resolve as expected

// ✅ Solution: Test thoroughly with edge cases

4. Case Sensitivity

// ❌ Problem: Case-sensitive filesystem
$converter = new Converter('Resources', 'Public');
$result = $converter->convert('../images/Logo.PNG');
// May not match actual filesystem paths

// ✅ Solution: Use consistent casing

Debugging Tips

1. Verify Path Structures

$from = realpath('resources/css');
$to = realpath('public/dist/css');
$converter = new Converter($from, $to);

2. Log Conversion Results

$original = 'some/relative/path';
$converted = $converter->convert($original);

Log::debug("Path conversion", [
    'original' => $original,
    'converted' => $converted,
    'from' => $converter->getFrom(),
    'to' => $converter->getTo()
]);

3. Test with Boundary Cases

$testCases = [
    'file.txt',
    './file.txt',
    '../file.txt',
    '../../file.txt',
    '/absolute/path/file.txt',
    'file.txt/../file2.txt',
    'file.txt/./file2.txt',
];

foreach ($testCases as $path) {
    $result = $converter->convert($path);
    // Verify results match expectations
}

Performance Considerations

1. Caching Converter Instances

// In service provider
$this->app->singleton(Converter::class, function() {
    return new Converter(
        config('path-converter.from'),
        config('path-converter.to')
    );
});

// Usage
$converter = app(Converter::class);

2. Batch Processing Optimization

public function convertMultiple(array $paths, Converter $converter): array {
    return array_map(fn($path) => $converter->convert($path), $paths);
}

Extension Points

1. Custom Path Normalization

class CustomConverter extends Converter {
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor