{"id":18772878,"url":"https://github.com/protonemedia/laravel-mixins","last_synced_at":"2025-05-16T02:07:22.292Z","repository":{"id":39590058,"uuid":"286797745","full_name":"protonemedia/laravel-mixins","owner":"protonemedia","description":"A collection of Laravel goodies. ","archived":false,"fork":false,"pushed_at":"2025-02-21T09:35:52.000Z","size":141,"stargazers_count":149,"open_issues_count":0,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-11T03:07:33.578Z","etag":null,"topics":["laravel","php"],"latest_commit_sha":null,"homepage":"https://protone.media/blog/convert-and-store-base64-encoded-files-in-laravel-use-validation-rules-and-access-the-decoded-files-from-the-request-instance","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/protonemedia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["pascalbaljet"]}},"created_at":"2020-08-11T16:44:41.000Z","updated_at":"2025-03-14T12:46:58.000Z","dependencies_parsed_at":"2024-06-19T15:23:07.878Z","dependency_job_id":"bef78447-a444-4dfb-a959-56832e89a056","html_url":"https://github.com/protonemedia/laravel-mixins","commit_stats":{"total_commits":64,"total_committers":3,"mean_commits":"21.333333333333332","dds":0.046875,"last_synced_commit":"06b672939de9e0258a251ef5850a260a0267377e"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protonemedia%2Flaravel-mixins","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protonemedia%2Flaravel-mixins/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protonemedia%2Flaravel-mixins/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/protonemedia%2Flaravel-mixins/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/protonemedia","download_url":"https://codeload.github.com/protonemedia/laravel-mixins/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453652,"owners_count":22073617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","php"],"created_at":"2024-11-07T19:31:30.562Z","updated_at":"2025-05-16T02:07:22.267Z","avatar_url":"https://github.com/protonemedia.png","language":"PHP","funding_links":["https://github.com/sponsors/pascalbaljet"],"categories":[],"sub_categories":[],"readme":"# Laravel Mixins\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/protonemedia/laravel-mixins.svg?style=flat-square)](https://packagist.org/packages/protonemedia/laravel-mixins)\n[![Total Downloads](https://img.shields.io/packagist/dt/protonemedia/laravel-mixins.svg?style=flat-square)](https://packagist.org/packages/protonemedia/laravel-mixins)\n[![Buy us a tree](https://img.shields.io/badge/Treeware-%F0%9F%8C%B3-lightgreen)](https://plant.treeware.earth/protonemedia/laravel-mixins)\n\n## Sponsor Us\n\n[\u003cimg src=\"https://inertiaui.com/visit-card.jpg\" /\u003e](https://inertiaui.com/inertia-table?utm_source=github\u0026utm_campaign=laravel-mixins)\n\n❤️ We proudly support the community by developing Laravel packages and giving them away for free. If this package saves you time or if you're relying on it professionally, please consider [sponsoring the maintenance and development](https://github.com/sponsors/pascalbaljet) and check out our latest premium package: [Inertia Table](https://inertiaui.com/inertia-table?utm_source=github\u0026utm_campaign=laravel-mixins). Keeping track of issues and pull requests takes time, but we're happy to help!\n\n## Requirements\n\n* PHP 8.2+\n* Laravel 10.0\n\n## Installation\n\nYou can install the package via composer:\n\n```bash\ncomposer require protonemedia/laravel-mixins\n```\n\nThere's no Service Provider or automatic discovery/registration of anything. All features are opt-in.\n\n## Contents\n\n#### Blade Directives\n* [Decimal Money Formatter](#decimal-money-formatter)\n* [Intl Money Formatter](#intl-money-formatter)\n\n#### Console Commands\n* [Generate Sitemap](#generate-sitemap)\n\n#### Validation Rules\n* [Current password](#current-password)\n* [Dimensions With Margin](#dimensions-with-margin)\n* [Host](#host)\n* [In Keys](#in-keys)\n* [Max Words](#max-words)\n* [URL Without Scheme](#url-without-scheme)\n\n#### String Macros\n* [Compact](#compact)\n* [Human Filesize](#human-filesize)\n* [Text](#text)\n* [URL](#url)\n* [Seconds to time](#seconds-to-time)\n\n#### PDF\n* [PDF Regeneration](#pdf-regeneration)\n\n#### Request\n* [Convert Base64 input data to files](#convert-base64-input-data-to-files)\n\n## Blade Directives\n\nYou can register Blade Directives by calling the `directive` method on the class. You can change the name of a directive with the optional first argument.\n\n### Decimal Money Formatter\n\n*Note: This directive requires the `moneyphp/money` package.*\n\nRegister the directive, for example by adding it to your `AppSerivceProvider`:\n\n```php\nProtoneMedia\\LaravelMixins\\Blade\\DecimalMoneyFormatter::directive();\n```\n\nYou can customize the name of the directive and the default currency code:\n\n```php\nProtoneMedia\\LaravelMixins\\Blade\\DecimalMoneyFormatter::directive('decimals', 'EUR');\n```\n\nThe first argument of the directive is the amount in cents. The second optional parameter is the currency.\n\n```blade\n// 0.99\n@decimals(99)\n\n// 1.00\n@decimals(100)\n\n// 100\n@decimals(100, 'XTS')\n```\n\n### Intl Money Formatter\n\n*Note: This directive requires the `moneyphp/money` package.*\n\nRegister the directive, for example by adding it to your `AppSerivceProvider`:\n\n```php\nProtoneMedia\\LaravelMixins\\Blade\\IntlMoneyFormatter::directive();\n```\n\nYou can customize the name of the directive, the default currency code and the locale:\n\n```php\nProtoneMedia\\LaravelMixins\\Blade\\IntlMoneyFormatter::directive('money', 'EUR', 'nl_NL');\n```\n\nThe first argument of the directive is the amount in cents. The optional second parameter is the currency. The optional third parameter is the locale.\n\n```blade\n// € 0,99\n@money(99)\n\n// € 1,00\n@money(100)\n\n// US$ 1,00\n@money(100, 'USD')\n\n// 1 000,00 $US\n@money(100, 'USD', 'fr')\n```\n\n## Commands\n\n### Generate Sitemap\n\n*Note: This command requires the `spatie/laravel-sitemap` package.*\n\nYou can register the command by adding it to your `App\\Console\\Kernel` file, or by calling the `register` method on the class.\n\n```php\nProtoneMedia\\LaravelMixins\\Commands\\GenerateSitemap::register();\n```\n\nYou can also set a custom signature:\n\n```php\nProtoneMedia\\LaravelMixins\\Commands\\GenerateSitemap::register('generate-sitemap');\n```\n\nIt generates a sitemap of your entire site and stores in in the `public` folder as `sitemap.xml`.\n\n```bash\nphp artisan sitemap:generate\n```\n\n## Validation Rules\n\n### Current password\n\nPasses if the value matches the password of the authenticated user.\n\n```php\n$rule = new ProtoneMedia\\LaravelMixins\\Rules\\CurrentPassword;\n```\n\nAs of Laravel 9, this validation rule is [built-in](https://laravel.com/docs/9.x/validation#rule-current-password).\n\n### Dimensions With Margin\n\nExtension of the [Dimensions rule](https://laravel.com/docs/master/validation#rule-dimensions) with a `margin` option. Handy when you're working with ratios with repeating decimals.\n\n```php\nuse ProtoneMedia\\LaravelMixins\\Rules\\DimensionsWithMargin;\n\n$rule = DimensionsWithMargin::make()-\u003eratio(20 / 9)-\u003emargin(1),\n```\n\n### Host\n\nVerifies if the URL matches the given hosts.\n\n```php\nuse ProtoneMedia\\LaravelMixins\\Rules\\Host;\n\n$rule = Host::make(['facebook.com', 'fb.me']);\n```\n\n### In Keys\n\nVerifies if the given key or index exists in the array.\n\n```php\nuse ProtoneMedia\\LaravelMixins\\Rules\\InKeys;\n\n$rule = new InKeys(['laravel' =\u003e 'Laravel Framework', 'tailwindcss' =\u003e 'Tailwind CSS framework']);\n\n// same as\n\nuse Illuminate\\Validation\\Rules\\In;\n\n$rule = new In(['laravel', 'tailwindcss']);\n```\n\n### Max Words\n\nPasses if the values contains no more words than specified.\n\n```php\nuse ProtoneMedia\\LaravelMixins\\Rules\\MaxWords;\n\n$rule = MaxWords::make(250);\n```\n\n### URL Without Scheme\n\nPasses if the URL is valid, even without a scheme.\n\n```php\n$rule = new ProtoneMedia\\LaravelMixins\\Rules\\UrlWithoutScheme;\n```\n\n## String macros\n\nYou can add new method by using the mixins.\n\n### Compact\n\n```php\nStr::mixin(new ProtoneMedia\\LaravelMixins\\String\\Compact);\n\n$string = \"Hoe simpeler hoe beter. Want hoe minder keuze je een speler laat, hoe groter de kans dat hij het juiste doet.\";\n\n// Hoe simpeler hoe beter. Want hoe ... de kans dat hij het juiste doet.\necho Str::compact($string);\n```\n\nIt has an optional second argument to specify the length on each side. With the optional third argument, you can specify the sepeator.\n\n```php\n// Hoe simpeler hoe - het juiste doet.\necho Str::compact($string, 16, ' - ');\n```\n\n### Human Filesize\n\nConverts a filesize into a human-readable version of the string.\n\n```php\nStr::mixin(new ProtoneMedia\\LaravelMixins\\String\\HumanFilesize);\n\n$size = 3456789;\n\n// '3.3 MB'\nStr::humanFilesize($size));\n```\n\n### Text\n\n*Note: This macro requires the `html2text/html2text` package.*\n\nConverts HTML to plain text.\n\n```php\nStr::mixin(new ProtoneMedia\\LaravelMixins\\String\\Text);\n\n$html = \"\u003ch1\u003eProtone Media\u003c/h1\u003e\";\n\n// Protone Media\nStr::text($html);\n```\n\n### URL\n\nPrepends `https://` if the scheme is missing from the given URL.\n\n```php\nStr::mixin(new ProtoneMedia\\LaravelMixins\\String\\Url);\n\n$url = \"protone.media\";\n\n// https://protone.media\nStr::url($url);\n```\n\n### Seconds to time\n\nConverts seconds to a 'mm:ss' / 'hh:mm:ss' format.\n\n```php\nStr::mixin(new ProtoneMedia\\LaravelMixins\\String\\SecondsToTime);\n\nStr::secondsToTime(10); // 00:10\nStr::secondsToTime(580); // 09:40\nStr::secondsToTime(3610); // 01:00:10\n\n// force 'hh:mm:ss' format, even under an hour:\nStr::secondsToTime(580, false); // 00:09:40\n```\n\n## PDF Regeneration\n\n*Note: Requires the `symfony/process` package.*\n\nRegenerates the PDF content with Ghostscript.\n\n```php\n$ghostscript = new ProtoneMedia\\LaravelMixins\\Pdf\\Ghostscript;\n\n$regeneratedPdf = $ghostscript-\u003eregeneratePdf(\n    file_get_contents('/uploads/invoice.pdf')\n);\n```\n\nYou can specify the path of the `ghostscript` binary as well:\n\n```php\n$ghostscript = new Ghostscript('gs-binary');\n```\n\n## Convert Base64 input data to files\n\nAdd the `ConvertsBase64ToFiles` trait and `base64FileKeys` method to your form request.\n\n```php\nuse Illuminate\\Foundation\\Http\\FormRequest;\nuse ProtoneMedia\\LaravelMixins\\Request\\ConvertsBase64ToFiles;\n\nclass ImageRequest extends FormRequest\n{\n    use ConvertsBase64ToFiles;\n\n    protected function base64FileKeys(): array\n    {\n        return [\n            'jpg_image' =\u003e 'Logo.jpg',\n        ];\n    }\n\n    public function rules()\n    {\n        return [\n            'jpg_image' =\u003e ['required', 'file', 'image'],\n        ];\n    }\n}\n```\n\nNow you can get the files like regular uploaded files:\n\n```php\n$jpgFile = $request-\u003efile('jpg_image');\n\n// Logo.jpg\n$jpgFile-\u003egetClientOriginalName();\n```\n\nThis trait supports nested data as well. You can either reference the keys by a nested array, or with a [dotted notation](https://laravel.com/docs/master/helpers#method-array-dot):\n\n```php\nclass ImageRequest extends FormRequest\n{\n    use ConvertsBase64ToFiles;\n\n    protected function base64FileKeys(): array\n    {\n        return [\n            'company.logo' =\u003e 'Logo.jpg',\n            'user' =\u003e [\n                'avatar' =\u003e 'Avatar.jpg',\n            ],\n        ];\n    }\n}\n```\n\nWant to know more about this trait? Check out the [blog post](https://protone.media/blog/convert-and-store-base64-encoded-files-in-laravel-use-validation-rules-and-access-the-decoded-files-from-the-request-instance).\n\n### Testing\n\n``` bash\ncomposer test\n```\n\n### Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Other Laravel packages\n\n* [`Inertia Table`](https://inertiaui.com/inertia-table?utm_source=github\u0026utm_campaign=laravel-mixins): The Ultimate Table for Inertia.js with built-in Query Builder.\n* [`Laravel Blade On Demand`](https://github.com/protonemedia/laravel-blade-on-demand): Laravel package to compile Blade templates in memory.\n* [`Laravel Cross Eloquent Search`](https://github.com/protonemedia/laravel-cross-eloquent-search): Laravel package to search through multiple Eloquent models.\n* [`Laravel Eloquent Scope as Select`](https://github.com/protonemedia/laravel-eloquent-scope-as-select): Stop duplicating your Eloquent query scopes and constraints in PHP. This package lets you re-use your query scopes and constraints by adding them as a subquery.\n* [`Laravel FFMpeg`](https://github.com/protonemedia/laravel-ffmpeg): This package provides an integration with FFmpeg for Laravel. The storage of the files is handled by Laravel's Filesystem.\n* [`Laravel MinIO Testing Tools`](https://github.com/protonemedia/laravel-minio-testing-tools): Run your tests against a MinIO S3 server.\n* [`Laravel Paddle`](https://github.com/protonemedia/laravel-paddle): Paddle.com API integration for Laravel with support for webhooks/events.\n* [`Laravel Task Runner`](https://github.com/protonemedia/laravel-task-runner): Write Shell scripts like Blade Components and run them locally or on a remote server.\n* [`Laravel Verify New Email`](https://github.com/protonemedia/laravel-verify-new-email): This package adds support for verifying new email addresses: when a user updates its email address, it won't replace the old one until the new one is verified.\n* [`Laravel XSS Protection`](https://github.com/protonemedia/laravel-xss-protection): Laravel Middleware to protect your app against Cross-site scripting (XSS). It sanitizes request input, and it can sanatize Blade echo statements.\n\n### Security\n\nIf you discover any security related issues, please email pascal@protone.media instead of using the issue tracker.\n\n## Credits\n\n- [Pascal Baljet](https://github.com/protonemedia)\n- [All Contributors](../../contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n\n## Treeware\n\nThis package is [Treeware](https://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/protonemedia/laravel-mixins) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotonemedia%2Flaravel-mixins","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprotonemedia%2Flaravel-mixins","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotonemedia%2Flaravel-mixins/lists"}