{"id":35159591,"url":"https://github.com/lyhty/macros","last_synced_at":"2026-04-26T17:31:47.756Z","repository":{"id":55826407,"uuid":"514416534","full_name":"lyhty/macros","owner":"lyhty","description":"A set of convenient macros for you to use in your Laravel project.","archived":false,"fork":false,"pushed_at":"2025-04-27T20:55:39.000Z","size":73,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-11T16:35:53.384Z","etag":null,"topics":["collection","eloquent","laravel","macroable","macros"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/lyhty/macros","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/lyhty.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2022-07-15T22:05:40.000Z","updated_at":"2025-04-22T12:04:03.000Z","dependencies_parsed_at":"2025-04-22T13:23:04.996Z","dependency_job_id":"39764136-5a47-41dc-861d-14b11d96c789","html_url":"https://github.com/lyhty/macros","commit_stats":{"total_commits":36,"total_committers":2,"mean_commits":18.0,"dds":"0.16666666666666663","last_synced_commit":"b46682587bd81ec2ca94afe91a81fcc3beaed47e"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/lyhty/macros","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyhty%2Fmacros","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyhty%2Fmacros/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyhty%2Fmacros/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyhty%2Fmacros/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lyhty","download_url":"https://codeload.github.com/lyhty/macros/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyhty%2Fmacros/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32307010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T17:23:19.671Z","status":"ssl_error","status_checked_at":"2026-04-26T17:23:19.195Z","response_time":129,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["collection","eloquent","laravel","macroable","macros"],"created_at":"2025-12-28T17:56:36.582Z","updated_at":"2026-04-26T17:31:47.748Z","avatar_url":"https://github.com/lyhty.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp\u003e\n  \u003cimg src=\"https://matti.suoraniemi.com/storage/lyhty-macros.png\" width=\"400\"\u003e\n\u003c/p\u003e\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/lyhty/macros.svg?label=\u0026logo=packagist\u0026logoColor=white\u0026style=flat-square)](https://packagist.org/packages/lyhty/macros)\n[![PHP](https://img.shields.io/packagist/php-v/lyhty/macros?label=\u0026logo=php\u0026logoColor=white\u0026style=flat-square)](https://packagist.org/packages/lyhty/macros)\n[![Laravel](https://img.shields.io/static/v1?label=\u0026message=^11%20|%20^12\u0026color=red\u0026style=flat-square\u0026logo=laravel\u0026logoColor=white)](https://packagist.org/packages/lyhty/macros)\n[![Total Downloads](https://img.shields.io/packagist/dt/lyhty/macros.svg?style=flat-square)](https://packagist.org/packages/lyhty/macros)\n[![StyleCI](https://github.styleci.io/repos/514416534/shield)](https://github.styleci.io/repos/514416534)\n[![License](https://img.shields.io/packagist/l/lyhty/macros.svg?style=flat-square)](https://packagist.org/packages/lyhty/macros)\n\n\u003c!-- CUTOFF --\u003e\n\nThis package provides some additional, convenient macros for you to use with your Laravel project.\n\n## Installation\n\nInstall the package with Composer:\n\n    composer require lyhty/macros\n\nThe package registers itself automatically.\n\n## Macros\n\nHere's a brief documentation on the macros the package provides.\n\n- [`Illuminate\\Database\\Eloquent\\Builder`](#illuminatedatabaseeloquentbuilder)\n  - [`selectKey`](#builderselectkey)\n  - [`whereLike` \u0026 `orWhereLike`](#builderwherelike--orwherelike)\n- [`Illuminate\\Database\\Query\\Builder`](#illuminatedatabasequerybuilder)\n  - [`selectRawArr`](#builderselectrawarr)\n- [`Illuminate\\Support\\Collection`](#illuminatesupportcollection)\n  - [`mergeMany`](#collectionmergemany)\n  - [`pick` (was `pluckMany`)](#collectionpick-was-pluckmany)\n  - [`whereExtends`](#collectionwhereextends)\n  - [`whereImplements`](#collectionwhereimplements)\n  - [`whereUses`](#collectionwhereuses)\n- [`Illuminate\\Support\\Arr`](#illuminatesupportarr)\n  - [`associate`](#arrassociate)\n  - [`combine`](#arrcombine)\n  - [`fillKeys`](#arrfillkeys)\n  - [`implode`](#arrimplode)\n  - [`join`](#arrjoin)\n  - [`zip`](#arrzip)\n  - [`unzip`](#arrunzip)\n- [`Illuminate\\Support\\Str`](#illuminatesupportstr)\n  - [`explodeReverse`](#strexplodereverse)\n  - [`wrapWith`](#strwrapwith)\n- [`Illuminate\\Support\\Stringable`](#illuminatesupportstringable)\n  - [`explodeReverse`](#stringableexplodereverse)\n  - [`wrapWith`](#stringablewrapwith)\n- [`Carbon\\CarbonPeriod`](#carboncarbonperiod)\n  - [`collect`](#carbonperiodcollect)\n\n### `Illuminate\\Database\\Eloquent\\Builder`\n\n#### `Builder::selectKey`\n\nSelect the key of the model in the query (uses Model's `getKey` method).\n\n```php\n$query = User::query()-\u003eselectKey();\n\n$query-\u003etoSql(); // \"select `id` from `users`\"\n```\n\n### `Illuminate\\Database\\Query\\Builder`\n\n#### `Builder::whereLike` \u0026 `orWhereLike`\n\n\u003e ⚠️ This macro relies on `Str::explodeReverse` macro. If you want to disable the latter macro, this macro will no longer function.\n\n\u003e ⚠️ The `Builder::orWhereLike` macro relies on `Builder::whereLike` macro. If you want to disable the `whereLike` macro, be sure to disable the `orWhereLike` macro as well.\n\n```php\n$query = User::query()\n    -\u003ewhereLike('name', 'Matti Suo', 'right')\n    -\u003eorWhereLike('name', 'ranie')\n    -\u003eorWhereLike('name', 'mi', 'left');\n\n$query-\u003etoSql();\n// \"select * from `users` where (`users`.`name` LIKE ?) or (`users`.`name` LIKE ?) or (`users`.`name` LIKE ?)\"\n// First ? being \"Matti Suo%\", second \"%ranie%\" and third \"%mi\"\n\n$query = User::query()-\u003ewhereLike('games.name', 'Apex Leg', 'right');\n\n$query-\u003etoSql();\n// select * from `users` where (exists\n//   (select * from `games` where `users`.`id` = `games`.`user_id` and `games`.`name` LIKE ?)\n// )\n// ? being \"Apex Leg%\"\n\n$query = User::query()-\u003ewhereLike(['games.console.name', 'games.platforms.name'], 'Xbox');\n\n$query-\u003etoSql();\n// select * from `users` where (exists (select * from `games` where `users`.`id` = `games`.`user_id` and (exists\n// (select * from `consoles` where `games`.`console_id` = `consoles`.`id` and (`consoles`.`name` LIKE ?)) or exists\n// (select * from `platforms` inner join `platform_game` on `platforms`.`id` = `platform_game`.`platform_id` where\n// `games`.`id` = `platform_game`.`game_id` and (`platforms`.`name` LIKE ?)))))\n// ? being \"Xbox\"\n```\n\n#### `Builder::selectRawArr`\n\nAdd raw select statements as an array, instead of as a one ugly string (`selectRaw`).\n\n```php\n$query = User::query()-\u003eselectRawArr([\n    'concat(`id`, \"-\", `name`) as id_name',\n    'concat(`email`, \"-\", `name`) as email_name'\n]);\n// 🤩\n\n$query-\u003efirst()-\u003etoArray(); // [\"id_name\" =\u003e \"1-Matti\", \"email_name\" =\u003e \"matti@suoraniemi.com-Matti\"]\n\n// Instead of:\n$query = User::query()-\u003eselectRaw('concat(`id`, \"-\", `name`) as id_name, concat(`email`, \"-\", `name`) as email_name');\n// 🤢\n```\n\n### `Illuminate\\Support\\Collection`\n\n#### `Collection::mergeMany`\n\nMerge multiple arrays/collections to the collection in one go.\n\n```php\n$data = new Collection([1,2,3]);\n\n$data-\u003emergeMany([4], [5], [6]); // [1, 2, 3, 4, 5, 6]\n```\n\n#### `Collection::pick` (was `pluckMany`)\n\nPick several keys from the collection items. The first value should be an array of keys\nyou want to pick up from the collection items. The second value determines whether keys\nwill be preserved and in which format:\n\n- `PICK_WITH_FULL_KEYS (\u003e= 2)`:\n  - Keeps even the possibly nested values in their original depths.\n- `PICK_WITH_PARTIAL_KEYS (1)`:\n  - Flattens the results while keeping the keys.\n- `PICK_WITHOUT_KEYS (0)`:\n  - No keys will be preserved\n\n```php\n$data = User::query()-\u003eget();\n\n$data-\u003epick(['id', 'name', 'metadata.loggedIn'])-\u003etoArray();\n// [[1, \"Matti Suoraniemi\", true], [2, \"Foo Bar\", false]]\n\n$data-\u003epick(['id', 'name', 'metadata.loggedIn'], 1)-\u003etoArray();\n// [\n//   [\"id\" =\u003e 1, \"name\" =\u003e \"Matti Suoraniemi\", \"loggedIn\" =\u003e true],\n//   [\"id\" =\u003e 2, \"name\" =\u003e \"Foo Bar\", \"loggedIn\" =\u003e false]\n// ]\n\n$data-\u003epick(['id', 'name', 'metadata.loggedIn'], 2)-\u003etoArray();\n// [\n//   [\"id\" =\u003e 1, \"name\" =\u003e \"Matti Suoraniemi\", \"metadata\" =\u003e [\"loggedIn\" =\u003e true]],\n//   [\"id\" =\u003e 2, \"name\" =\u003e \"Foo Bar\", \"metadata\" =\u003e [\"loggedIn\" =\u003e false]]\n// ]\n```\n\n#### `Collection::whereExtends`\n\nFilter classes and/or objects that extend the given class.\n\n```php\nuse Illuminate\\Database\\Eloquent\\Model;\n\n$data = new Collection([\n    \\App\\Models\\User::class,\n    \\App\\Models\\Game::class,\n    \\App\\Models\\Console::class,\n    \\App\\Models\\Hobby::class,\n]);\n\n$data-\u003ewhereExtends(Model::class)-\u003ecount(); // 4\n```\n\n#### `Collection::whereImplements`\n\nFilter classes and/or objects that implement the given interface.\n\n```php\nuse App\\Contracts\\PlayableOnConsole;\n\n$data = new Collection([\n    \\App\\Models\\User::class,\n    \\App\\Models\\Game::class,\n    \\App\\Models\\Console::class,\n    \\App\\Models\\Hobby::class,\n]);\n\n$data-\u003ewhereImplements(PlayableOnConsole::class)-\u003etoArray(); // [\"App\\Models\\Game\"]\n```\n\n#### `Collection::whereUses`\n\nFilter classes and/or objects that use the given trait.\n\n```php\nuse Illuminate\\Notifications\\Notifiable;\n\n$data = new Collection([\n    \\App\\Models\\User::class,\n    \\App\\Models\\Game::class,\n    \\App\\Models\\Console::class,\n    \\App\\Models\\Hobby::class,\n]);\n\n$data-\u003ewhereUses(Notifiable::class)-\u003etoArray(); // [\"App\\Models\\User\"]\n```\n\n### `Illuminate\\Support\\Arr`\n\n#### `Arr::associate`\n\nConverts an array into a fully associative array by converting any values with an integer key\nto the value being the key filled with the given fill value. Values that have a string key already\nwon't be touched.\n\n```php\nArr::associate(['foo']); // [\"foo\" =\u003e null]\nArr::associate(['foo', 'bar' =\u003e []], []); // [\"foo\" =\u003e [], \"bar\" =\u003e []]\nArr::associate(['foo', 'bar' =\u003e []], fn () =\u003e Arr::random(['foo', 'bar'])); // [\"foo\" =\u003e \"foo\", \"bar\" =\u003e []]\nArr::associate([fn () =\u003e Str::reverse('foo'), 'bar' =\u003e []]); // [\"oof\" =\u003e null, \"bar\" =\u003e []]\n```\n\n#### `Arr::combine`\n\nSimilar to `array_combine`, but allows to have more keys than values. Keys without value will be set\nas null.\n\n```php\nArr::combine(['foo', 'zoo'], [\"bar\", \"gar\"]); // [\"foo\" =\u003e \"bar\", \"zoo\" =\u003e \"gar\"]\nArr::combine(['foo', 'zoo'], [\"bar\"]); // [\"foo\" =\u003e \"bar\", \"zoo\" =\u003e null]\n```\n\n#### `Arr::fillKeys`\n\nFills given keys with given value. You can also set that only keys that already exist in the array\ncan become filled. In other words, if the key `foo` is to be filled with value `bar`, but the key\n`foo` doesn't already exist in the array, the array will remain unchanged.\n\n```php\n$array = ['foo' =\u003e 'bar', 'zoo' =\u003e 'gar'];\n\nArr::fillKeys($array, ['foo', 'zoo'], null); // [\"foo\" =\u003e null, \"zoo\" =\u003e null]\nArr::fillKeys($array, ['foo', 'zoo', 'boo'], null); // [\"foo\" =\u003e null, \"zoo\" =\u003e null, \"boo\" =\u003e null]\nArr::fillKeys($array, ['foo', 'zoo', 'boo'], null, true); // [\"foo\" =\u003e null, \"zoo\" =\u003e null]\n```\n\n#### `Arr::implode`\n\nImplodes given array with given separator to a `\\Illuminate\\Support\\Stringable` instance.\n\n```php\n$array = ['foo', 'bar'];\n\n(string) Arr::implode($array, ' ')-\u003eupper(); // \"FOO BAR\"\n```\n\n#### `Arr::join`\n\nCollection's nice join method brought to Arr.\n\n```php\nArr::join(['foo', 'bar', 'zoo'], ', ', ' and '); // \"foo, bar and zoo\"\n```\n\n#### `Arr::zip`\n\nZips the key and value together with the given zipper.\n\n```php\nArr::zip(['foo' =\u003e 'bar', 'zoo' =\u003e 'gar'], ':'); // [\"foo:bar\", \"zoo:gar\"]\n```\n\n#### `Arr::unzip`\n\nUnzips keys to key and value with the given zipper.\n\n```php\nArr::unzip(['foo:bar', 'zoo:gar'], ':'); // [\"foo\" =\u003e \"bar\", \"zoo\" =\u003e \"gar\"]\n```\n\n#### `Str::explodeReverse`\n\nExplodes the given string from the end instead of the start and returns it as\na `Illuminate\\Support\\Collection` class instance.\n\n```php\nStr::explodeReverse('games.platforms.name', '.', 2)-\u003etoArray(); // ['games.platforms', 'name']\n\n// Whereas normal explode function would do:\nexplode('.', 'games.platforms.name', 2); // ['games', 'platforms.name']\n```\n\n### `Illuminate\\Support\\Str`\n\n#### `Str::wrapWith`\n\nWraps the string with given character(s).\n\n```php\nStr::wrapWith('foo', ':'); // \":foo:\"\nStr::wrapWith('bar', '\u003c', '\u003e'); // \"\u003cbar\u003e\"\nStr::wrapWith('!zoo', '!'); // \"!zoo!\"\n```\n\n\u003e ⚠️ As Laravel 9 introduced `Str::wrap` macro, as of v4.0 this macro is now called `Str::wrapWith` to avoid conflicts.\n\u003e Note: the behavior between these two macros is different:\n\n```php\nStr::wrapWith(':foo', ':'); // \":foo:\"\nStr::wrap(':foo', ':'); // \"::foo:\"\n```\n\n### `Illuminate\\Support\\Stringable`\n\n#### `Stringable::explodeReverse`\n\n\u003e ⚠️ This macro relies on `Str::explodeReverse` macro. If you want to disable that macro, this macro will no longer function.\n\nSee [Illuminate\\Support\\Str::explodeReverse](#illuminatesupportstrexplodereverse)\n\n```php\nStr::of('games.platforms.name')-\u003eexplodeReverse('.', 2)-\u003etoArray(); // ['games.platforms', 'name']\n\n// Whereas normal explode function would do:\nStr::of('games.platforms.name')-\u003eexplode('.', 2)-\u003etoArray(); // ['games', 'platforms.name']\n```\n\n#### `Stringable::wrapWith`\n\n\u003e ⚠️ As Laravel 9 introduced `Str::wrap` macro, as of v4.0 this macro is now called `Str::wrapWith` to avoid conflicts.\n\n\u003e ⚠️ This macro relies on `Str::wrapWith` macro. If you want to disable that macro, this macro will no longer function.\n\nSee [Illuminate\\Support\\Str::wrapWith](#strwrapwith)\n\n```php\n(string) Str::of('foo')-\u003eupper()-\u003ewrapWith(':'); // \":FOO:\"\n(string) Str::of('bar')-\u003eupper()-\u003ewrapWith('\u003c', '\u003e'); // \"\u003cBAR\u003e\"\n(string) Str::of('!zoo')-\u003eupper()-\u003ewrapWith('!'); // \"!ZOO!\"\n```\n\n### `Carbon\\CarbonPeriod`\n\n#### `CarbonPeriod::collect`\n\n```php\n$dates = CarbonPeriod::between('yesterday', 'today')-\u003ecollect();\n\n$dates-\u003efirst()-\u003etoDateTimeString(); // \"2022-06-14 00:00:00\"\n```\n\n## License\n\nLyhty Macros is open-sourced software licensed under the [MIT license](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyhty%2Fmacros","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flyhty%2Fmacros","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyhty%2Fmacros/lists"}