PHPackages                             custom-d/laravel-helpers - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. custom-d/laravel-helpers

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

custom-d/laravel-helpers
========================

A laravel helpers

v5.6.2(1y ago)011.4k↑225%MITPHPPHP ^8.2

Since Jun 24Pushed 1y ago6 watchersCompare

[ Source](https://github.com/customd/Laravel-Helpers)[ Packagist](https://packagist.org/packages/custom-d/laravel-helpers)[ RSS](/packages/custom-d-laravel-helpers/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (83)Used By (0)

[![Latest Release](https://camo.githubusercontent.com/1ac59dcd5f5c07b1277b962c0764b3d7d613c27d88917cb29d50c72e0250606f/68747470733a2f2f6769742e637573746f6d642e636f6d2f636f6d706f7365722f4c61726176656c2d48656c706572732f2d2f6261646765732f72656c656173652e737667)](https://git.customd.com/composer/Laravel-Helpers/-/releases)[![coverage report](https://camo.githubusercontent.com/cc8bc9d8ac4e7f37648d501b50467846d68e76bc7a6366de1511d6403cb2d706/68747470733a2f2f6769742e637573746f6d642e636f6d2f636f6d706f7365722f4c61726176656c2d48656c706572732f6261646765732f6d61737465722f636f7665726167652e737667)](https://git.customd.com/composer/Laravel-Helpers/-/commits/master)[![Github Issues](https://camo.githubusercontent.com/b10b374bd000df00e34ab78ea523d44ad2272df19454a492aa406a894d9a3977/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f637573746f6d642f6c61726176656c2d68656c70657273)](https://github.com/customd/Laravel-Helpers/issue)[![For Laravel 5](https://camo.githubusercontent.com/9a2355d1426923632b618f75ebc11f7a91c3c9d605f08bacc34cb8ad62a4fe0b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d382532302f253230392d7265642e737667)](https://github.com/phpsa/laravel-api-controller/issues)[![Total Downloads](https://camo.githubusercontent.com/4c1e68ac974f239ee7372c78c54145d46e1f25b77310b5d10d32870779904c4a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f637573746f6d2d642f6c61726176656c2d68656c70657273)](https://packagist.org/packages/custom-d/laravel-helpers)[![Latest Stable Version](https://camo.githubusercontent.com/118ff3141b54dd24096f2da9bf394ef8a4c5265904437cc6bec40b2388ef76ee/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f637573746f6d2d642f6c61726176656c2d68656c70657273)](https://packagist.org/packages/custom-d/laravel-helpers)[![License](https://camo.githubusercontent.com/d8ae915363441b554f098f831ddcf1664015d2525248d1177538f5b28d4fcb0d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f637573746f6d2d642f6c61726176656c2d68656c70657273)](https://packagist.org/packages/custom-d/laravel-helpers)

Laravel Helpers
================

[](#laravel-helpers-)

Collection of helpers for re-use accross a few of our projects

- [Laravel Helpers ](#laravel-helpers-)
    - [Installation](#installation)
    - [Upgrade V2 to V3](#upgrade-v2-to-v3)
    - [Crud Policy Trait](#crud-policy-trait)
        - [Permission naming.](#permission-naming)
    - [Crud Access Permission Global Trait &amp; Scope for Model](#crud-access-permission-global-trait--scope-for-model)
    - [Helpers](#helpers)
    - [DB Macros](#db-macros)
        - [Null Or Empty](#null-or-empty)
        - [Case insensitive statments](#case-insensitive-statments)
        - [Enforced Non Nullable Relations (orFail chain)](#enforced-non-nullable-relations-orfail-chain)
    - [DB Repositories](#db-repositories)
    - [Observerable trait (Deprecated)](#observerable-trait-deprecated)
    - [Record or Fake HTTP Calls](#record-or-fake-http-calls)
    - [Date Manipulation](#date-manipulation)
        - [Date(Carbon) Helpers attached to above:](#datecarbon-helpers-attached-to-above)
    - [Value Objects](#value-objects)
    - [Larastan Stubs](#larastan-stubs)
    - [Filament Plugin](#filament-plugin)
    - [Credits](#credits)

Installation
------------

[](#installation)

Install via composer

```
composer require custom-d/laravel-helpers
```

Upgrade V2 to V3
----------------

[](#upgrade-v2-to-v3)

- ViewAny plicy now checks for a viewAny permission and not list for the viewAny permission check
- Dropped support for php 7.3 &amp; 7.2
- Dropped support for Laravel 6 &amp; 7
- marked execute helper as deprecated
- fixed Model::orWhereNotNullOrEmpty method to do correct query

Crud Policy Trait
-----------------

[](#crud-policy-trait)

By using the `CustomD\LaravelHelpers\Models\Policies\CrudPermissions` trait in your model policy alongside `Spatie role permissions` you can avoid having to write lots of boilerplate methods in your policy file.

Instead of a Policy like this

```
class UserPolicy
{
    public function viewAny(Authenticatable $user): Response
    {
        return $user->can('users.viewAny');
    }

    public function view(Authenticatable $user, User $targetUser): Response
    {
        return $user->can('users.view');
    }
    ...
```

it would now look as follows:

```
namespace App\Models\Policies;

use App\Models\Policies\Traits\CrudPermissions;

class UserPolicy
{
    use CrudPermissions;
}
```

and it will automatically check for the following permissions which you would have seeded / set up in Spatie's package.

- users.viewAny
- users.view
- users.create
- users.update
- users.delete
- users.forceDelete
- users.restore

Additionally if using the `PermissionBasedAccess` trait on your model, the following extra ones are taken into account

- users.viewOwn (as long as you own the record)
- users.updateOwn
- users.deleteOwn

If the `user_id` column is not `user_id`, set that in the `getOwnerKeyColumn` method documented below in the Crud Access for Model section.

viewAny, create, restore &amp; forceDelete will use the base versions only, and you would need to customise if needed yourself by setting up the permission or policy method to deal with it based on your business logic. Create and viewAny do not have Ownership within a default policy, and the restore / forceDelete are mainly only an administrative functionality.

### Permission naming.

[](#permission-naming)

The permission naming will by default use a plural of the model name: ie `User` becomes `users` / `BlogPost` becomes `blog_posts`

Crud Access Permission Global Trait &amp; Scope for Model
---------------------------------------------------------

[](#crud-access-permission-global-trait--scope-for-model)

If you use the `CustomD\LaravelHelpers\Traits\PermissionBasedAccess` trait on your model it will look for the following Spatie permissions by default:

`xxx.view`, `xxx.viewOwn`

This works as follows:

- if `viewOwn` is true, then it will call `scopeCanRetrieveOwnRecord` scope
- else if `view` is true, then it will call `scopeCanRetrieveAnyRecord` scope
- else it will fallback to `scopeCannotRetrieveAnyRecord` scope

To modify the user column, add this to the model.

```
    public function getOwnerKeyColumn(): ?string
    {
        return 'custom_id';
    }

```

to call without the scopes: use the `withoutPermissionCheck` modifier: eg `Model::withoutPermissionCheck()->get()`

Helpers
-------

[](#helpers)

**execute** - this helper runs an execute action on an action file with dependancy injection on the contructor

```
execute(Action::class, $param, $param2);
execute(Action::class);

//resolves as
$app->make(Action::class)->execute(...)

```

If you discover any security related issues, please email instead of using the issue tracker.

String Helpers
--------------

[](#string-helpers)

**isEmail** -- usage `Str::isEmail('xxx')` or `str('xxx')->isEmail()` -- will return boolean.

Array Helpers
-------------

[](#array-helpers)

**pushBefore** - will push one or more items before the specified key, or append to the end of the array if the key does not exist: **PushAfter** will push one or more items after the specified key

```
$arr = [
  'one' => 'two',
  'three' => 'four',
  'ten' => 'eleven',
];

$missing = [
  'four' => 'five',
  'six' => 'seven',
  'eight' => 'nine'
];

$new = Arr::pushBefore($arr, 'eight', $missing);
// or
$new = Arr::pushAfter($arr, 'three', $missing);
```

Collection Helpers
------------------

[](#collection-helpers)

**pushBefore** - will push one or more items before the specified key, or append to the end of the array if the key does not exist: **PushAfter** will push one or more items after the specified key

```
$collection = collect([
  'one' => 'two',
  'three' => 'four',
  'ten' => 'eleven',
]);

$missing = [
  'four' => 'five',
  'six' => 'seven',
  'eight' => 'nine'
];

$collection->pushBefore('eight', $missing);
// or
$collection->pushAfter('three', $missing);
```

DB Macros
---------

[](#db-macros)

### Null Or Empty

[](#null-or-empty)

when dealing with some of our legacy databases we have some columns where the entry is either null or empty and these macros allow you to query this without the double entries:

```
Model::whereNullOrEmpty('column_name'); //generates select * where 1=1 and (column_name is null or column_name = '')
Model::orWhereNullOrEmpty('column_name'); //generates select * where 1=1 or (column_name is null or column_name = '')
Model::whereNotNullOrEmpty('column_name'); //generates select * where 1=1 and (column_name is not null and column_name != '')
Model::orWhereNotNullOrEmpty('column_name'); //generates select * where 1=1 or (column_name is not null and column_name != '')
Model::whereNullOrValue('column_name', [$operator],$value, [$boolean]); to check if column null or specific value (follows laravel where specification where operator is optional)
```

### Case insensitive statments

[](#case-insensitive-statments)

```
Model::iWhere('col',$value);
Model::iWhere('col',$operator,$value);
Model::iWhere(['col' => $value]);
```

### Enforced Non Nullable Relations (orFail chain)

[](#enforced-non-nullable-relations-orfail-chain)

```
function related(){
  return $this->hasOne()->orFail();
}
```

DB Repositories
---------------

[](#db-repositories)

use of repositories via extending the `CustomD\LaravelHelpers\Repository\BaseRepository` abstract example in the [UserRepository.stub.php](https://git.customd.com/composer/Laravel-Helpers/-/blob/master/src/Repository/UserRepository.php.stub) file

Observerable trait (Deprecated)
-------------------------------

[](#observerable-trait-deprecated)

adding this trait to your models will automatically look for an observer in the app/Observers folder with the convension {model}Observer as the classname,

you can additionally/optionally add

```
protected static $observers = [ ...arrayOfObservers]
```

to add a additional ones if

Replace this with

```
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use App\Observers\UserObserver;

#[ObservedBy(UserObserver::class)]
#[ObservedBy(AnotherUserObserver::class)]
class User extends Model
{
    //
}

```

Record or Fake HTTP Calls
-------------------------

[](#record-or-fake-http-calls)

The `RecordsOrFakesHttpCalls` trait will allow you to record or fake http calls in your tests. This is useful for testing external api calls without actually calling them.

Add the trait to your PHPUnit test file, ensure the `tests/stubs/` directory exists, and then wrap your test code in a callable:

```
  public function test_external_api()
  {
      // $this->record = true; // Toggle to create recorded files
      $this->processRecordedTest(
          'test_external_api',
          function () {
              // Any HTTP calls made by MyServiceClass will be recorded or returned from recorded responses, depending on `$this->record` above.
              $result = resolve(MyServiceClass::class)->execute('foo');
              $this->assertEquals('bar', $result->value);
          },
          'json'
      );
  }
```

Date Manipulation
-----------------

[](#date-manipulation)

You can set user timezones via the following options:

1. optionally create a migration with:

```
Schema::table('users', function (Blueprint $table) {
            $table->string('timezone', 40)->nullable();
        });

```

2. in user model:

```
pubic function timezone(): Attribute
{
  return Attribute::get(fn($value) => $value ?? config('app.user_timezone'));
}

```

Additionally you can set defaults on the timezone via the attributes method or a setter or even in the migration.

3. in your app config file add the `user_timezone` parameter.
4. add the UserTimeZone middleware to your api middleware list.

You can now access the current requests timezone via `config('request.user.timezone')`

### Date(Carbon) Helpers attached to above:

[](#datecarbon-helpers-attached-to-above)

methods available:

- `setUserTimezone(string $timezone) : Static` - sets the users timezone (default set by helper)
- `getUserTimezone() : string` - gets current users timezone
- `setSystemTimezone(string $timezone) : Static` - sets system timezone (Default app.timezone)
- `getSystemTimezone(): string` - gets teh current timezone
- `toUsersTimezone(): Static` - returns carbon instance set to users timezone
- `toSystemTimezone(): Static` - returns carbon instance set to system timezone
- `usersStartOfDay(): Static` - returns carbon instance set to start of users day (converts to users timezone =&gt; start of day =&gt; to systemtime)
- `usersEndOfDay(): Static` - users end of day
- `usersStartOfWeek(): Static`
- `usersEndOfWeek(): Static`
- `usersStartOfMonth(): Static`
- `usersEndOfMonth(): Static`
- `usersStartOfQuarter(): Static`
- `usersEndOfQuarter(): Static`
- `usersStartOfYear(): Static`
- `usersEndOfYear(): Static`
- `parseWithTz(string $time): Static` - parses the time passed using the users timezone unless the timezone is in the timestamp
- `hasISOFormat(string $date): bool` - checks if the date is in iso format.

You can also use the CDCarbonDate to create a few different date objects.

Value Objects
-------------

[](#value-objects)

Example:

```
