Eloquent model-caching made easy.

Overview

Model Caching for Laravel

Laravel Package Scrutinizer BCH Compliance Coveralls GitHub (pre-)release Packagist GitHub license

Model Caching for Laravel masthead image

Supporting This Package

This is an MIT-licensed open source project with its ongoing development made possible by the support of the community. If you'd like to support this, and our other packages, please consider becoming a sponsor.

Impetus

I created this package in response to a client project that had complex, nested forms with many <select>'s that resulted in over 700 database queries on one page. I needed a package that abstracted the caching process out of the model for me, and one that would let me cache custom queries, as well as cache model relationships. This package is an attempt to address those requirements.

Features

  • automatic, self-invalidating relationship (only eager-loading) caching.
  • automatic, self-invalidating model query caching.
  • automatic use of cache tags for cache providers that support them (will flush entire cache for providers that don't).

Cache Drivers

This package is best suited for taggable cache drivers:

+ Redis
+ MemCached
+ APC
+ Array

It will not work with non-taggable drivers:

- Database
- File
- DynamoDB

Requirements

  • PHP 7.3+
  • Laravel 8.0+
    - Please note that prior Laravel versions are not supported and the package
    - versions that are compatible with prior versions of Laravel contain bugs.
    - Please only use with the versions of Laravel noted above to be compatible.

Possible Package Conflicts

Any packages that override newEloquentModel() from the Model class will likely conflict with this package. Of course, any packages that implement their own Querybuilder class effectively circumvent this package, rendering them incompatible.

The following are packages we have identified as conflicting:

Things That Don't Work Currently

The following items currently do no work with this package:

- caching of lazy-loaded relationships, see #127. Currently lazy-loaded belongs-to relationships are cached. Caching of other relationships is in the works.
- using select() clauses in Eloquent queries, see #238 (work-around discussed in the issue)
- using transactions. If you are using transactions, you will likely have to manually flush the cache, see [issue #305](https://github.com/GeneaLabs/laravel-model-caching/issues/305).

installation guide cover

Installation

Be sure to not require a specific version of this package when requiring it:

composer require genealabs/laravel-model-caching

Gotchas If Using With Lumen

The following steps need to be figured out by you and implemented in your Lumen app. Googling for ways to do this provided various approaches to this.

  1. Register the package to load in Lumen:
    $app->register(GeneaLabs\LaravelModelCaching\Providers\Service::class);
  2. Make sure your Lumen app can load config files.
  3. Publish this package's config file to the location your app loads config files from.

Upgrade Notes

0.6.0

The environment and config variables for disabling this package have changed.

  • If you have previously published the config file, publish it again, and adjust as necessary:

    php artisan modelCache:publish --config
  • If you have disabled the package in your .env file, change the entry from MODEL_CACHE_DISABLED=true to MODEL_CACHE_ENABLED=false.

0.5.0

The following implementations have changed (see the respective sections below):

  • model-specific cache prefix

Configuration

Recommended (Optional) Custom Cache Store

If you would like to use a different cache store than the default one used by your Laravel application, you may do so by setting the MODEL_CACHE_STORE environment variable in your .env file to the name of a cache store configured in config/cache.php (you can define any custom cache store based on your specific needs there). For example:

MODEL_CACHE_STORE=redis2

Usage

For best performance a taggable cache provider is recommended (redis, memcached). While this is optional, using a non-taggable cache provider will mean that the entire cache is cleared each time a model is created, saved, updated, or deleted.

For ease of maintenance, I would recommend adding a BaseModel model that uses Cachable, from which all your other models are extended. If you don't want to do that, simply extend your models directly from CachedModel.

Here's an example BaseModel class:

<?php namespace App;

use GeneaLabs\LaravelModelCaching\Traits\Cachable;

abstract class BaseModel
{
    use Cachable;
    //
}

Multiple Database Connections

Thanks to @dtvmedia for suggestion this feature. This is actually a more robust solution than cache-prefixes.

Keeping keys separate for multiple database connections is automatically handled. This is especially important for multi-tenant applications, and of course any application using multiple database connections.

Optional Cache Key Prefix

Thanks to @lucian-dragomir for suggesting this feature! You can use cache key prefixing to keep cache entries separate for multi-tenant applications. For this it is recommended to add the Cachable trait to a base model, then set the cache key prefix config value there.

Here's is an example:

<?php namespace GeneaLabs\LaravelModelCaching\Tests\Fixtures;

use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class BaseModel extends Model
{
    use Cachable;

    protected $cachePrefix = "test-prefix";
}

The cache prefix can also be set in the configuration to prefix all cached models across the board:

    'cache-prefix' => 'test-prefix',

Exception: User Model

I would not recommend caching the user model, as it is a special case, since it extends Illuminate\Foundation\Auth\User. Overriding that would break functionality. Not only that, but it probably isn't a good idea to cache the user model anyway, since you always want to pull the most up-to-date info on it.

Experimental: Cache Cool-down In Specific Models

In some instances, you may want to add a cache invalidation cool-down period. For example you might have a busy site where comments are submitted at a high rate, and you don't want every comment submission to invalidate the cache. While I don't necessarily recommend this, you might experiment it's effectiveness.

To use it, it must be enabled in the model (or base model if you want to use it on multiple or all models):

class MyModel extends Model
{
    use Cachable;

    protected $cacheCooldownSeconds = 300; // 5 minutes

    // ...
}

After that it can be implemented in queries:

(new Comment)
    ->withCacheCooldownSeconds(30) // override default cooldown seconds in model
    ->get();

or:

(new Comment)
    ->withCacheCooldownSeconds() // use default cooldown seconds in model
    ->get();

Disabling Caching of Queries

There are two methods by which model-caching can be disabled:

  1. Use ->disableCache() in a query-by-query instance.
  2. Set MODEL_CACHE_ENABLED=false in your .env file.
  3. If you only need to disable the cache for a block of code, or for non- eloquent queries, this is probably the better option:
    $result = app("model-cache")->runDisabled(function () {
        return (new MyModel)->get(); // or any other stuff you need to run with model-caching disabled
    });

Recommendation: use option #1 in all your seeder queries to avoid pulling in cached information when reseeding multiple times. You can disable a given query by using disableCache() anywhere in the query chain. For example:

$results = $myModel->disableCache()->where('field', $value)->get();

Manual Flushing of Specific Model

You can flush the cache of a specific model using the following artisan command:

php artisan modelCache:clear --model=App\Model

This comes in handy when manually making updates to the database. You could also trigger this after making updates to the database from sources outside your Laravel app.

Summary

That's all you need to do. All model queries and relationships are now cached!

In testing this has optimized performance on some pages up to 900%! Most often you should see somewhere around 100% performance increase.

Commitment to Quality

During package development I try as best as possible to embrace good design and development practices, to help ensure that this package is as good as it can be. My checklist for package development includes:

  • Achieve as close to 100% code coverage as possible using unit tests.
  • Eliminate any issues identified by SensioLabs Insight and Scrutinizer.
  • Be fully PSR1, PSR2, and PSR4 compliant.
  • Include comprehensive documentation in README.md.
  • Provide an up-to-date CHANGELOG.md which adheres to the format outlined at https://keepachangelog.com.
  • Have no PHPMD or PHPCS warnings throughout all code.

Contributing

Please observe and respect all aspects of the included Code of Conduct https://github.com/GeneaLabs/laravel-model-caching/blob/master/CODE_OF_CONDUCT.md.

Reporting Issues

When reporting issues, please fill out the included template as completely as possible. Incomplete issues may be ignored or closed if there is not enough information included to be actionable.

Submitting Pull Requests

Please review the Contribution Guidelines https://github.com/GeneaLabs/laravel-model-caching/blob/master/CONTRIBUTING.md. Only PRs that meet all criterium will be accepted.

If you ❤️ open-source software, give the repos you use a ⭐️ .

We have included the awesome symfony/thanks composer package as a dev dependency. Let your OS package maintainers know you appreciate them by starring the packages you use. Simply run composer thanks after installing this package. (And not to worry, since it's a dev-dependency it won't be installed in your live environment.)

Comments
  • Undefined offset in conjunction with yajra/laravel-datatables

    Undefined offset in conjunction with yajra/laravel-datatables

    Issue

    This issue prevents searching on the laravel datatables plugin due to some type of issue with the laravel datatables usage of whereRaw.

    Possibly related to: https://github.com/GeneaLabs/laravel-model-caching/issues/111

    Possible clue:

    DataTables::of(User::query()) -> Error
    DataTables::of(\DB::table('users')) -> Works
    

    Environment

    Laravel Version: 5.6.24 Laravel Model Caching Package Version: 0.2.62 PHP Version: 7.2 Homestead Version: 6 Operating System & Version: MacOS 10.13.5

    Stack Trace

    [2018-06-03 19:34:22] local.ERROR: ErrorException: Undefined offset: 3 in /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php:235
    Stack trace:
    #0 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php(235): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8, 'Undefined offse...', '/home/vagrant/C...', 235, Array)
    #1 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php(152): GeneaLabs\LaravelModelCaching\CacheKey->getRawClauses(Array)
    #2 [internal function]: GeneaLabs\LaravelModelCaching\CacheKey->GeneaLabs\LaravelModelCaching\{closure}('-_or_LOWER(`pra...', Array)
    #3 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Support/Collection.php(1313): array_reduce(Array, Object(Closure), NULL)
    #4 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php(158): Illuminate\Support\Collection->reduce(Object(Closure))
    #5 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php(169): GeneaLabs\LaravelModelCaching\CacheKey->getWhereClauses(Array)
    #6 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php(150): GeneaLabs\LaravelModelCaching\CacheKey->getNestedClauses(Array)
    #7 [internal function]: GeneaLabs\LaravelModelCaching\CacheKey->GeneaLabs\LaravelModelCaching\{closure}(NULL, Array)
    #8 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Support/Collection.php(1313): array_reduce(Array, Object(Closure), NULL)
    #9 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php(158): Illuminate\Support\Collection->reduce(Object(Closure))
    #10 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CacheKey.php(36): GeneaLabs\LaravelModelCaching\CacheKey->getWhereClauses()
    #11 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/Traits/Caching.php(76): GeneaLabs\LaravelModelCaching\CacheKey->make(Array, NULL, '')
    #12 /PROJECT_PATH/vendor/genealabs/laravel-model-caching/src/CachedBuilder.php(78): GeneaLabs\LaravelModelCaching\CachedBuilder->makeCacheKey(Array)
    #13 /PROJECT_PATH/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php(186): GeneaLabs\LaravelModelCaching\CachedBuilder->get()
    #14 /PROJECT_PATH/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php(86): Yajra\DataTables\QueryDataTable->results()
    #15 /PROJECT_PATH/app/Http/Controllers/Backend/Organization/Practice/PracticeController.php(65): Yajra\DataTables\QueryDataTable->make(true)
    #16 [internal function]: App\Http\Controllers\Backend\Organization\Practice\PracticeController->get(Object(App\Http\Requests\Backend\Organization\Practice\ManagePracticeRequest))
    #17 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
    #18 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\Routing\Controller->callAction('get', Array)
    #19 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(App\Http\Controllers\Backend\Organization\Practice\PracticeController), 'get')
    #20 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Route.php(169): Illuminate\Routing\Route->runController()
    #21 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Router.php(665): Illuminate\Routing\Route->run()
    #22 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #23 /PROJECT_PATH/app/Http/Middleware/RouteNeedsRole.php(35): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #24 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\RouteNeedsRole->handle(Object(Illuminate\Http\Request), Object(Closure), '1')
    #25 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #26 /PROJECT_PATH/app/Http/Middleware/OrganizationMiddleware.php(31): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #27 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\OrganizationMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure))
    #28 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #29 /PROJECT_PATH/app/Http/Middleware/PasswordExpires.php(34): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #30 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\PasswordExpires->handle(Object(Illuminate\Http\Request), Object(Closure))
    #31 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #32 /PROJECT_PATH/app/Http/Middleware/NeedsPracticeCreation.php(34): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #33 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\NeedsPracticeCreation->handle(Object(Illuminate\Http\Request), Object(Closure))
    #34 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #35 /PROJECT_PATH/app/Http/Middleware/NeedsPasswordChange.php(34): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #36 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\NeedsPasswordChange->handle(Object(Illuminate\Http\Request), Object(Closure))
    #37 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #38 /PROJECT_PATH/app/Http/Middleware/PortalMiddleware.php(71): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #39 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\PortalMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure))
    #40 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #41 /PROJECT_PATH/app/Http/Middleware/IsUserMiddleware.php(25): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #42 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\IsUserMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure))
    #43 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #44 /PROJECT_PATH/app/Http/Middleware/RefreshSessionObjects.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #45 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): App\Http\Middleware\RefreshSessionObjects->handle(Object(Illuminate\Http\Request), Object(Closure))
    #46 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #47 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #48 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
    #49 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #50 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(43): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #51 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Auth\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure))
    #52 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #53 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(67): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #54 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
    #55 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #56 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #57 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
    #58 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #59 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #60 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
    #61 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #62 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(59): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #63 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
    #64 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #65 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #66 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Router.php(667): Illuminate\Pipeline\Pipeline->then(Object(Closure))
    #67 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Router.php(642): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
    #68 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Router.php(608): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route))
    #69 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Router.php(597): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
    #70 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
    #71 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
    #72 /PROJECT_PATH/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(58): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #73 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Barryvdh\Debugbar\Middleware\InjectDebugbar->handle(Object(Illuminate\Http\Request), Object(Closure))
    #74 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #75 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(63): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #76 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
    #77 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #78 /PROJECT_PATH/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #79 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Fideloper\Proxy\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure))
    #80 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #81 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(31): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #82 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
    #83 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #84 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(31): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #85 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
    #86 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #87 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #88 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure))
    #89 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #90 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(51): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #91 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(151): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
    #92 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
    #93 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
    #94 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\Pipeline\Pipeline->then(Object(Closure))
    #95 /PROJECT_PATH/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
    #96 /PROJECT_PATH/public/index.php(55): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
    #97 {main}  
    
    Unconfirmed Bug 
    opened by rappasoft 43
  • Inavalidation Problems since last version

    Inavalidation Problems since last version

    I just updated to the latest version and now i have strange errors - maybe something todo with invalidation. (or not invalidating)

    Example: In my SalesController i prepare to add another product to the basket. $saleItem = SaleItem::where('id','=',$request->get('id'))->first(); $product = Product::where('id',$request->get('product_id'))->first(); $saleItem->product_id = $product->id; Now sometimes - mostly when more than one product is in the basket i get this error: Property [id] does not exist on this collection instance. (Regarding the line $product->id) If i disable the cache everything is ok. Before i updated to the current version everything was fine, too.

    What could be the problem over here. I have the same error on different Controllers - not only regarding products.. I disabled the whole cache now - because i'm getting many errors like these...

    PHP 7.1 Laravel 5.5 latest package version

    follow-up required 
    opened by jetwes 32
  • Caching of LazyLoaded Relationships

    Caching of LazyLoaded Relationships

    Issue

    From the README and video I am trying to cache a belongsToMany relationship but it doesn't seem to be working. In my set up caching other relationships does work such as hasOne, hasMany and belongsTo but the many-to-many case does not.

    I have had a brief look through the code but I am not following where either it or I could be going wrong. The documentation states that adding the Cachable trait just works including relationships.

    I do note however, that the test for relationships only seems to test a single type (many-to-one).

    Also note that eagerly loading a relationship does appear to work (ie. using with()) whereas lazy loading does not.

    I would appreciate any help. Let me know if you need more info.

    PS. This is an awesome library!

    Environment

    Laravel Version: 5.6.* Laravel Model Caching Package Version: 0.2.57 PHP Version: 7.2 Homestead Version: N/A Operating System & Version: ArchLinux

    Stack Trace

    N/A

    enhancement help wanted 
    opened by jradtilbrook 28
  • vsprintf(): Too few arguments

    vsprintf(): Too few arguments

    Describe the bug Exception occurs when using eagerLoadRelation on Model with Cachable trait.

    Eloquent Query

    $parents = Category::where('category_id', Category::encodeUuid($uuid))->with('word')->with('posts')->withCount('posts')->get();
    

    Stack Trace vsprintf(): Too few arguments

    protected function getInAndNotInClauses(array $where) : string
    {
        if (! in_array($where["type"], ["In", "NotIn", "InRaw"])) {
            return "";
        }
    
        $type = strtolower($where["type"]);
        $subquery = $this->getValuesFromWhere($where);
        $values = collect($this->query->bindings["where"][$this->currentBinding] ?? []);
        $this->currentBinding += count($where["values"]);
        $subquery = collect(**vsprintf**(str_replace("?", "%s", $subquery), $values->toArray()));
        $values = $this->recursiveImplode($subquery->toArray(), "_");
    
        return "-{$where["column"]}_{$type}{$values}";
    }
    

    Environment

    • PHP: [ 7.3.0]
    • OS: [ Ubuntu 18.04]
    • Laravel: [e.g. 5.8.]
    • Model Caching: [ 0.7] (*)

    Model uses \Ramsey\Uuid\Uuid for primary keys

    bug 
    opened by rajnishmishra20 23
  • Pagination count query wont get cached

    Pagination count query wont get cached

    Environment

    Laravel Version: 5.6.3 Laravel Model Caching Package Version: 0.2.33 PHP Version: 7.2.0 Homestead Version: - Operating System & Version: macOs High Sierra 10.13.3

    Stack Trace

    When using the paginate query there is a count query that not get cached

    $articles = Article::paginate(30);
    

    In the debug bar you see this query:

    select count(*) as aggregate from articles
    
    Unconfirmed Bug follow-up required 
    opened by jurrid 22
  • Global Scopes Possibly Not Working Again?

    Global Scopes Possibly Not Working Again?

    Describe the bug SQL queries cached, but always return first cached query. The SQL queries make a package, namely a generateQuery method

    Help me, please. It's very important problem. I don't know what I need to do to worked it

    SQL Query First SQL query

    select articles.*, (SELECT `string` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='uk' AND `key`='name') as `name`, (SELECT `text` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='uk' AND `key`='short_description') as `short_description`, (SELECT `text` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='uk' AND `key`='text') as `text`, (SELECT `string` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='uk' AND `key`='meta_title') as `meta_title`, (SELECT `text` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='uk' AND `key`='meta_description') as `meta_description` from `articles` where `slug` = 'ivanchenko-bogdan-yosipovich' and `active` = 1 limit 1
    

    Second SQL query

    select articles.*, (SELECT `string` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='en' AND `key`='name') as `name`, (SELECT `text` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='en' AND `key`='short_description') as `short_description`, (SELECT `text` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='en' AND `key`='text') as `text`, (SELECT `string` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='en' AND `key`='meta_title') as `meta_title`, (SELECT `text` FROM `translations` WHERE `translation_id`=`articles`.`id` AND `translation_type`='articles' AND `lang`='en' AND `key`='meta_description') as `meta_description` from `articles` where `slug` = 'ivanchenko-bogdan-yosipovich' and `active` = 1 limit 1
    

    This queries are different by lang key in subquery

    Environment

    • PHP: 7.2.17
    • OS: Ubuntu 18.04.1
    • Laravel: 5.8.18
    • Model Caching: 0.5.3
    bug 
    opened by kolirt 21
  • not taking param into consideration?

    not taking param into consideration?

    So I have a query such as this. and i have an api endpoint categories/id/products..

    $collection = ProductVariant::with( 'product.owner' )->whereHas( 'product', function( $q ) use ( $categoryId )
                {
                    $q->whereCategoryId($categoryId)->live();
                } )->inRandomOrder()->live(1)
    

    but when i change the id to say 2 or 3.. I get same products.. is this something I have to take care of? or am i doing something wrong?

    Environment

    Laravel Version: 5.6.2 Laravel Model Caching Package Version: ^0.2.22 PHP Version: * 7.1.6 * Homestead Version: N/A (using Valet) Operating System & Version: *Mac OS - El captain - 10.11.6 *

    Unconfirmed Bug follow-up required 
    opened by shez1983 20
  • Caching Performance Is Slow

    Caching Performance Is Slow

    @howya wrote:

    Hi Mike,

    I've put together a very simple example at:

    https://github.com/howya/laravel_builder_cache

    Just clone it, composer install, then setup the phpunit.xml environment variables to point at your MySQL server and Redis server.

    Once setup you can run 'composer test' to run a simple performance test. The performance test runs a 1000 iteration loop of query calls (I chose these queries as they are similar to what I require in a project I'm working on). The loop is replicated 3 times:

    • Once for queries against Non-Cached 'standard' models
    • Once for queries against Builder-Cached models - this is an experimental cache that I'm playing with
    • Once for queries against Model-Cached models - this is your package

    The test is trivial and does not reflect real world usage as it does not bust the cache and the query domain space is very small i.e. MySql is probably hitting its own cache 100% of the time.

    The results I get are:

    "Non-Cached time taken: 25.299576044083" "Builder-Cached time taken: 24.184181928635" "Model-Cached time taken: 35.246420145035"

    I would have assumed that our caching strategies would have been the same or slightly slower than 'Non-Cached' in this test as MySql is probably hitting its own cache 100% of the time. I'm not sure why yours is approx 50% slower. Have I made an error when implementing your caching package?

    question follow-up required 
    opened by mikebronner 18
  • composer require genealabs/laravel-model-caching ^0.4.7

    composer require genealabs/laravel-model-caching ^0.4.7

    Describe the bug Using version ^0.4.7 for genealabs/laravel-model-caching

    ./composer.json has been updated
    Loading composer repositories with package information
    Updating dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    
      Problem 1
        - Installation request for genealabs/laravel-model-caching ^0.4.7 -> satisfiable by genealabs/laravel-model-caching[0.4.7].
        - genealabs/laravel-model-caching 0.4.7 requires mikebronner/laravel-pivot dev-master@dev -> no matching package found.
    
    Potential causes:
     - A typo in the package name
     - The package is not available in a stable-enough version according to your minimum-stability setting
       see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
     - It's a private package and you forgot to add a custom repository to find it
    
    Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
    
    Installation failed, reverting ./composer.json to its original content.
    

    Environment

    • PHP: 7.1.23
    • OS: mac os 10.13.6
    • Laravel: 5.8.*
    • Model Caching: ^0.4.7
    Unconfirmed Bug 
    opened by sgssxf 17
  • Same results for different queries using whereRaw with added bindings

    Same results for different queries using whereRaw with added bindings

    Issue

    I get the same results for different queries using whereRaw with added bindings when called on the same column. For example:

    SomeModel::whereRaw('somecolumn = ?', ['somevalue'])->get();
    SomeModel::whereRaw('somecolumn = ?', ['anothervalue'])->get();
    SomeModel::whereRaw('somecolumn = ?', ['yetanothervalue'])->get();
    

    The second and third query always returns the result of the first query.

    I did dug around in the code. I noticed that CacheKey does not include the value of the binding given to the whereRaw method. This results in a string that is the same for these three queries, thus causing trouble.

    I guess adding a $this->getValuesClause($where) to https://github.com/GeneaLabs/laravel-model-caching/blob/master/src/CacheKey.php#L172 should fix the problem? Haven't been able to spend much time on it so please correct me if I'm wrong or if this will break stuff. I am willing to create a PR to fix this!

    Environment

    Laravel Version: 5.6.16 Laravel Model Caching Package Version: 0.2.52 PHP Version: 7.2.2 Homestead Version: n/a Operating System & Version: Debian 9.3

    Unconfirmed Bug follow-up required 
    opened by emielmolenaar 16
  • Global Scopes Not Being Busted Based On Called Context

    Global Scopes Not Being Busted Based On Called Context

    Describe the bug When calling Model::all() - the global scope is not being applied. I am getting an instance of the first cached result, not the updated one when the Auth::user() changed in the global scope.

    In my model I attach a global scope on boot which is a class implementing scope:

    static::addGlobalScope(new SameCompanyScope);
    

    However when I run the below Eloquent query, it always returns the cached results instead of updating the results when the scope changes due to a different user being logged in.

    Eloquent Query Please provide the complete eloquent query that caused the bug, for example:

    Model::all();
    

    Stack Trace There is no stack trace, because nothing "breaks" it just returns the incorrect information.

    Is this expected behaviour?

    The workarounds I have identified include using the get() method on the model instead of all, but this does not feel correct as the global scope should be applied to all.

    The other is modifying ModelCaching.php trait like:

    if (!$instance->isCachable() || $instance->getGlobalScopes()) {
       return parent::all($columns);
    }
    

    To disable the caching when a global scope are being applied, but this still feels wrong. Any thoughts or tips would be appreciated.

    Environment

    • PHP: 7.3.5
    • OS: Windows 10 - Wamp
    • Laravel: 6.15.1
    • Model Caching: 0.7.4
    bug 
    opened by Drewdan 15
  • Saving not working with eloquent strict mode

    Saving not working with eloquent strict mode

    When using in app service provider

    Model::shouldBeStrict(!$this->app->isProduction());
    

    saving model not working with exception Illuminate \ Database \ Eloquent \ MissingAttributeException The attribute [query] either does not exist or was not retrieved for model [app\Models\MyModel].

    Eloquent Query Please provide the complete eloquent query that caused the bug, for example:

    $record = MyModel::find($id);
    $record->field = 'foo';
    $record->save();
    

    Stack Trace Illuminate \ Database \ Eloquent \ MissingAttributeException The attribute [query] either does not exist or was not retrieved for model [app\Models\MyModel].

    Environment PHP 8.1.6 Laravel 9.36.3 Model Caching: 0.12.5

    ** work around ** add to model

    protected $query = null; // required property for Cachable trait
    

    I think you should add this in trait

    opened by jamesRUS52 0
  • Only flush cache when delete() returns a count

    Only flush cache when delete() returns a count

    The two methods delete and forceDelete in Buildable trait should imho only flush the cache, if the parent methods return an int > 0. Right now, the cache is flushed every time, even when the query did not actually deleted records from the database.

    public function delete()
    {
        $result = parent::delete();
    
        if ($result) {
            $this->cache($this->makeCacheTags())->flush();
        }
    
        return $result;
    }
    
    opened by m-lotze 0
  • GeneaLabs\LaravelModelCaching\CacheKey::processEnum()

    GeneaLabs\LaravelModelCaching\CacheKey::processEnum()

    I'm facing this issues in a couple of situations like deleting a model: but in both situations the whole function is almost the same. It's a try/catch with the delete method of a model inside.

    try {
                $article->delete();
    
                return redirect(request()->header('Referer'));
            } catch (Exception $e) {
                return redirect(request()->header('Referer'))
                    ->with([
                            'errormsg' => session()->flash('errorMessage', $e),
                        ]);
            }
    

    Here is the full stack error: https://flareapp.io/share/VP6AGVam#F71

    • PHP: 8.1
    • Laravel: 9.x
    opened by Musamba24 2
  • Cache Not Clearing With morphTo/morphedByMany

    Cache Not Clearing With morphTo/morphedByMany

    I have Project, Service, User and Bookmark models. A user can bookmark a project, a service or another user.

    Project, Service, Bookmark and User models are cachable.

    User model:

    public function bookmarkedProjects()
    	{
    		return $this->morphedByMany(Project::class, 'bookmarkable', 'bookmarks');
    	}
    
    public function bookmarkedUsers()
    	{
    		return $this->morphedByMany(User::class, 'bookmarkable', 'bookmarks');
    	}
    
    public function bookmarkedServices()
    	{
    		return $this->morphedByMany(Service::class, 'bookmarkable', 'bookmarks');
    	}
    

    Bookmark model:

    public function bookmarkable()
    	{
    		return $this->morphTo();
    	}
    

    The problem is, when user deleted a bookmark, database record deleting but cache not flushing and there is no error. I have to use modelCache:clear. And if I remove Cachable from models there is no problem.

    Delete function (Other functions are same. Except bookmarkable_type):

    public function removeBookmarkedService(string $id)
    	{
    		Bookmark::where('bookmarkable_type', 'App\Models\Service')->where('user_id', Auth::user()->id)->where('bookmarkable_id', $id)->delete();
    
    		$this->emit('refreshPage');
    	}
    

    Environment

    • PHP: [8.1.3]
    • OS: [Windows 10]
    • Laravel: [9.18]
    • Model Caching: [0.12.4]
    opened by reasecret 0
  • Pagination links are incorrectly cached when the website has multiple domains

    Pagination links are incorrectly cached when the website has multiple domains

    Describe the bug

    If you have a website which has multiple domains, and subsequently multiple sessions, you might visit a page showing paginated resources, and the class which has the pagination data, such as the path for the links is cached. This means the baseURL for the pagination links is also cached, and won't change when the URL of the website changes.

    For example: go to mywebsite.com - and load a page with paginated data - the links will show with the correct URL process to mywebsite.app - and loads the same page with paginated data - the links will show with the previous URL, not the current one.

    Eloquent Query Please provide the complete eloquent query that caused the bug, for example:

    User::paginate();
    

    Stack Trace N.A

    Environment

    • PHP: 7.4
    • OS: Windows 10, Ubuntu 20.04 (WSL) and AWS Llambdas
    • Laravel: 8.36.2
    • Model Caching 0.11.1

    Additional context

    This behaviour is not too unpleasant and quite edge casey, however, it does get confusing when a pagination link changes your domain from one to another, and then you lose your session.

    I have a fix in mind, and the PR will follow.

    opened by Drewdan 0
  • lockForUpdate() method does not work.

    lockForUpdate() method does not work.

    Describe the bug It seems the lockForUpdate() method available for laravel queries does not work when caching has been enabled and there is a cache hit. I have not had time to look further into this but I was having problems with a query not locking when it should have, and I found adding ->disableCache() to the query instantly fixed the issue. I believe if the cache gets a hit it returns the record and ignores the lockForUpdate() part of the query.

    I think the proper behaviour when lockForUpdate() is encountered is to possibly automatically disable cache or use cache key locking if the cache provider implements Illuminate\Contracts\Cache\LockProvider contract.

    Eloquent Query An example of how to reproduce is below. In two different terminal sessions run artisan tinker, in one session run the instance1 code, then in the other session while instance1 code is sleeping run instance2 code. When instance2 encounters the lock it should block until the lock is released, the issue I am seeing is that instance2 returns straight away rather than blocking.

    function instance1() {
        DB::transaction(function () {
            SomeModel::where('id', 1)->lockForUpdate()->get();
            echo 'sleeping ';
            sleep(20);
        }, 2);
        echo time();
    }
    
    function instance2() {
        DB::transaction(function () {
            echo 'blocking ';
            SomeModel::where('id', 1)->lockForUpdate()->get();
        }, 2);
        echo time();
    }
    

    Environment

    • PHP: 7.2
    • Laravel: 7
    • Model Caching: 0.10.1
    opened by saernz 1
Releases(0.12.5)
Owner
GeneaLabs, LLC
GeneaLabs, LLC
A laravel package to generate model hashid based on model id column.

Laravel Model Hashid A package to generate model hash id from the model auto increment id for laravel models Installation Require the package using co

Touhidur Rahman 13 Jan 20, 2022
A package to filter laravel model based on query params or retrieved model collection

Laravel Filterable A package to filter laravel model based on query params or retrived model collection. Installation Require/Install the package usin

Touhidur Rahman 17 Jan 20, 2022
Laravel-model-mapper - Map your model attributes to class properties with ease.

Laravel Model-Property Mapper This package provides functionality to map your model attributes to local class properties with the same names. The pack

Michael Rubel 15 Oct 29, 2022
Turn any Eloquent model into a list!

Listify Turn any Eloquent model into a list! Description Listify provides the capabilities for sorting and reordering a number of objects in a list. T

Travis Vignon 138 Nov 28, 2022
Collection of the Laravel/Eloquent Model classes that allows you to get data directly from a Magento 2 database.

Laragento LAravel MAgento Micro services Magento 2 has legacy code based on abandoned Zend Framework 1 with really ugly ORM on top of outdated Zend_DB

Egor Shitikov 87 Nov 26, 2022
Laravel Quran is static Eloquent model for Quran.

Laravel Quran بِسْمِ ٱللّٰهِ الرَّحْمٰنِ الرَّحِيْمِ Laravel Quran is static Eloquent model for Quran. The Quran has never changed and never will, bec

Devtical 13 Aug 17, 2022
A package for Laravel One Time Password (OTP) generator and validation without Eloquent Model, since it done by Cache.

Laravel OTP Introduction A package for Laravel One Time Password (OTP) generator and validation without Eloquent Model, since it done by Cache. The ca

Lim Teck Wei 52 Sep 6, 2022
This package provides a trait that will generate a unique uuid when saving any Eloquent model.

Generate slugs when saving Eloquent models This package provides a trait that will generate a unique uuid when saving any Eloquent model. $model = new

Abdul Kudus 2 Oct 14, 2021
🔥 Fire events on attribute changes of your Eloquent model

class Order extends Model { protected $dispatchesEvents = [ 'status:shipped' => OrderShipped::class, 'note:*' => OrderNoteChanged:

Jan-Paul Kleemans 252 Dec 7, 2022
Cast your Eloquent model attributes to Value Objects with ease.

Laravel Value Objects Cast your Eloquent model attributes to value objects with ease! Requirements This package requires PHP >= 5.4. Using the latest

Red Crystal Code 23 Dec 30, 2022
Add eloquent model events fired after a transaction is committed or rolled back

Laravel Transactional Model Events Add transactional events to your eloquent models. Will automatically detect changes in your models within a transac

Mark van Duijker 62 Dec 22, 2022
A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)

Laravel MongoDB This package adds functionalities to the Eloquent model and Query builder for MongoDB, using the original Laravel API. This library ex

Jens Segers 6.3k Jan 7, 2023
Generate UUID for a Laravel Eloquent model attribute

Generate a UUIDv4 for the primary key or any other attribute on an Eloquent model.

Alex Bouma 4 Mar 1, 2022
Laravel comments - This package enables to easily associate comments to any Eloquent model in your Laravel application

Laravel comments - This package enables to easily associate comments to any Eloquent model in your Laravel application

Rubik 4 May 12, 2022
This Laravel package merges staudenmeir/eloquent-param-limit-fix and staudenmeir/laravel-adjacency-list to allow them being used in the same model.

This Laravel package merges staudenmeir/eloquent-param-limit-fix and staudenmeir/laravel-adjacency-list to allow them being used in the same model.

Jonas Staudenmeir 5 Jan 6, 2023
A DynamoDB based Eloquent model and Query builder for Laravel.

Laravel DynamoDB A DynamoDB based Eloquent model and Query builder for Laravel. You can find an example implementation in kitar/simplechat. Motivation

Satoshi Kita 146 Jan 2, 2023
Laravel package to create autonumber for Eloquent model

Laravel AutoNumber Laravel package to create autonumber for Eloquent model Installation You can install the package via composer: composer require gid

null 2 Jul 10, 2022
🐍 Web application made in PHP with Laravel where you can interact via API with my Snake game which is made in Python

Snake web application Project of the web application where you can interact via API with Snake game which is available to download on it. Application

Maciek Iwaniuk 1 Nov 26, 2022
Observe (and react to) attribute changes made on Eloquent models.

Laravel Attribute Observer Requirements PHP: 7.4+ Laravel: 7+ Installation You can install the package via composer: composer require alexstewartja/la

Alex Stewart 55 Jan 4, 2023