Preferences for Laravel Eloquent models

Overview

Preferences for Laravel Eloquent models

Build Status Latest Stable Version Total Downloads Latest Unstable Version License

Use this library to bind multiple key/value pair preferences to your application's Eloquent models. Preferences are stored in your application's database so they can be easily stored and queried for. This library supports Eloquent 5 through 8 installed either standalone or as a part of the full Laravel framework. Issues and pull requests are welcome! See CONTRIBUTING.md for more information.

Installation

Run composer require klaude/eloquent-preferences to download and install the library.

Configuring In Laravel

  1. Add EloquentPreferencesServiceProvider to config/app.php:
// ...

return [

    // ...

    'providers' => [

        // ...

        KLaude\EloquentPreferences\EloquentPreferencesServiceProvider::class,
    ],

    // ...
];
  1. Install the configuration and database migration files:
$ php artisan vendor:publish
  1. Model preferences are stored in the "model_preferences" database table by default. If you would like to use a different table then edit the "table" entry in config/eloquent-preferences.php.

  2. Install the model preferences database:

$ php artisan migrate

Configuring Without Laravel

  1. Model preferences are stored in the "model_preferences" database table by default. If you would like to use a different table then define the MODEL_PREFERENCE_TABLE constant at your project's point of entry with your preferred table name.

  2. Install the model preferences database. There are a number of ways to do this outside of Laravel. Here's the schema blueprint to apply:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use KLaude\EloquentPreferences\Preference;

// ...

Model::getConnectionResolver()
    ->connection()
    ->getSchemaBuilder()
    ->create((new Preference)->getQualifiedTableName(), function (Blueprint $table) {
        $table->increments('id');
        $table->string('preference');
        $table->string('value');
        $table->morphs('preferable');
        $table->timestamps();
    });

Usage

Add the HasPreferences trait to the Eloquent models that you would like to have related preferences.

use KLaude\EloquentPreferences\HasPreferences;

// ...

class MyModel extends Model
{
    use HasPreferences;

    // ...
}

This builds a polymorphic has-many relationship called "preferences" that you can query on your model like any other Eloquent relationship. Model preferences are modeled in the KLaude\EloquentPreferences\Preference class. A preference object has preference, value, and Eloquent's built-in created_at and updated_at attributes. The HasPreferences trait can be used by any number of model classes in your application.

// Retrieving preferences via Eloquent
/** @var KLaude\EloquentPreferences\Preference $myPreference */
$myPreference = MyModel::find($someId)->preferences()->where('preference', 'my-preference')->get();

// Saving preferences via Eloquent
$preference = new Preference;
$preference->preference = 'some preference';
$preference->value = 'some value';
$myModel->preferences()->save($preference);

Eloquent queries can be run directly on the Preference class as well.

/** @var Illuminate\Database\Eloquent\Collection|KLaude\EloquentPreferences\Preference[] $preferences */
$preferences = Preference::whereIn('preference', ['foo', 'bar'])->orderBy('created_at')->get();

Helper Methods

The HasPreferences trait has a number of helper methods to make preference management a little easier.

Retrieving Preferences

Call the getPreference($preferenceName) or prefers($preferenceName) methods to retrieve that preference's value.

$numberOfFoos = $myModel->getPreference('number-of-foos');

$myModel->prefers('Star Trek over Star Wars') ? liveLongAndProsper() : theForceIsWithYou();

Setting Preferences

Call the setPreference($name, $value) or setPreferences($arrayOfNamesAndValues) methods to set your model's preference values. Setting a preference either creates a new preference row if the preference doesn't exist or updates the existing preference with the new value.

$myModel->setPreference('foo', 'bar');

$myModel->setPreferences([
    'foo' => 'bar',
    'bar' => 'baz',
]);

Removing Preferences

Call the clearPreference($preferenceName), clearPreferences($arrayOfPreferenceNames), or clearAllPreferences() methods to remove one, many, or all preferences from a model. Clearing preferences removes their associated rows from the preferences table.

$myModel->clearPreference('some preference');

$myModel->clearPreferences(['some preference', 'some other preference']);

$myModel->clearAllPreferences();

Default Preference Values

By default, getPreference() and prefers() return null if the preference is not stored in the database. There are two ways to declare default preference values:

  1. Use an optional second parameter to getPreference() and prefers() to define a default value per call. If the preference is not stored in the database then the default value is returned.
// $myPreference = 'some default value'
$myPreference = $myModel->getPreference('unknown preference', 'some default value');
  1. Avoid requiring extra parameters to every getPreference() and prefers() call by declaring a protected $preference_defaults array in your model containing a key/value pair of preference names and their default values. If the preference is not stored in the database but is defined in $preference_defaults then the value in $preference_defaults is returned. If neither of these exist then optional default value parameter or null is returned.
class MyModel extends Model
{
    use HasPreferences;

    // ...

    protected $preference_defaults = [
        'my-default-preference' => 'my-default-value',
    ];
}

// ...

// $myPreference = 'my-default-value'
$myPreference = $myModel->getPreference('my-default-preference');

// $myPreference = 'fallback value'
$myPreference = $myModel->getPreference('my-unstored-preference', 'fallback value');

Please note default preference values only apply when using the getPreference() and prefers() methods. Default values are not honored when retrieving preferences by Eloquent query.

Casting Preference Values

Preferences are stored as strings in the database, but can be cast to different types when retrieved.

Declare a protected $preference_casts array in your model containing a key/value pair of preference names and the types to cast their values to. Preferences are stored and cast according to the same rules as Eloquent's attribute type casts.

class MyModel extends Model
{
    use HasPreferences;

    // ...

    protected $preference_casts = [
        'boolean-preference' => 'boolean',
        'floating-point-preference' => 'float',
        'date-preference' => 'date',
    ];
}

As with default values, casting preferences is only performed when using the getPreference(), prefers(), setPreference(), and setPreferences() helper methods.

Hidden Preference Attributes

By default all preference model attributes are visible when exporting to JSON. However it is possible to declare hidden attributes that act in the same manner as Eloquent's hidden attributes. There are two ways to declare which preference attributes to hide from JSON export:

  1. If this library is being used in a Laravel project then declare hidden attributes in the "hidden-attributes" key in config/eloquent-preferences.php.
return [

    // ...

    'hidden-attributes' => ['created_at', 'updated_at'],

    // ...
];
  1. If this library is being used outside the Laravel framework then define the MODEL_PREFERENCE_HIDDEN_ATTRIBUTES constant at your project's point of entry with a comma-separated list of attributes to hide from JSON export.
const MODEL_PREFERENCE_HIDDEN_ATTRIBUTES = 'created_at,updated_at';
Comments
  • Laravel 8.0 support

    Laravel 8.0 support

    Would be great if you release a tested version for Laravel ^8.0

    I have forked and just bumped the version: https://github.com/sharpstream/eloquent-preferences/blob/laravel8-support/composer.json

    Don't seem to have any issues but of course you may need run phpunit.

    opened by mbalandis 5
  • Preferences hidden option?

    Preferences hidden option?

    Great library here, so easy!

    One suggestions from myself:

    Have a $hidden array as well as the "casts" and "defaults" so we can set it to not return created_at etc. fields? They're adding unnecessary bloat to my returning JSON as I just grab all preferences attached to the user.

    Secondly, and unrelated... is there a way to do a cascading delete? So when I delete my model, all the prefs are deleted as well? So if I have a Department, with a hasMany relationship to Users that have preferences, I could go $department->users()->delete() as I do now, but have the prefs for the users get nuked as well?

    opened by timothyallan 3
  • Add a missing decimal cast feature and perform cleanup

    Add a missing decimal cast feature and perform cleanup

    • Add support for casting preference values to Laravel 5.7+'s decimal
    • Ensure this installs and runs in all Laravel 5 versions and 6.0
    • Perform various PSR12 style fixes and micro optimizations
    • Improve TravisCI build performance by roughly 2x
    • Remove CHANGELOG.md in favor of GitHub release descriptions
    opened by klaude 0
  • Can no longer pass null to strpos

    Can no longer pass null to strpos

    From PHP 8.1 Release notes https://www.php.net/releases/8.1/en.php

    Passing null to non-nullable internal function parameters is deprecated.

    This PR fixes the following error when null is passed to strpos

    Deprecated: strpos(): Passing null to parameter #1 ($haystack)
    
    opened by TheFrankman 0
  • Deprecated: strpos(): Passing null to parameter #1 ($haystack)

    Deprecated: strpos(): Passing null to parameter #1 ($haystack)

    This error for me fires many times when running PHPunit. Not sure what the exact scenario is for recreating it as we run hundreds of tests.

    Deprecated: strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated in /../vendor/klaude/eloquent-preferences/src/HasPreferences.php on line 306
    

    We are running laravel v9 with PHP 8.1

    opened by TheFrankman 5
  • Laravel 9.x Compatibility

    Laravel 9.x Compatibility

    This is an automated pull request from Shift to update your package code and dependencies to be compatible with Laravel 9.x.

    Before merging, you need to:

    • Checkout the l9-compatibility branch
    • Review all comments for additional changes
    • Thoroughly test your package

    If you do find an issue, please report it by commenting on this PR to help improve future automation.

    opened by laravel-shift 2
Releases(v0.5.0)
  • v0.5.0(Oct 25, 2020)

  • v0.4.0(May 13, 2020)

  • v0.3.0(Sep 5, 2019)

    • Add support for casting preference values to Laravel 5.7+'s decimal
    • Ensure this installs and runs in all Laravel 5 versions and 6.0
    • Perform various PSR12 style fixes and micro optimizations
    • Improve TravisCI build performance by roughly 2x
    • Remove CHANGELOG.md in favor of GitHub release descriptions
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Sep 5, 2019)

  • v0.1.1(Sep 5, 2019)

    Originally released 23 February, 2016

    • Fix a typo in an internal method name (#1) - Thanks, @timothyallan!
    • Replace a deprecated PHPUnit configuration option
    • Add contributing guidelines and a change log
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Sep 5, 2019)

    Originally released 27 December, 2015

    • Initial release
    • Basic support for preference retrieval, creation, updating, and deletion
    • Support for preference value type casting
    • Support for default preference values
    Source code(tar.gz)
    Source code(zip)
Owner
Kevin Laude
Kevin Laude
Easy creation of slugs for your Eloquent models in Laravel

Eloquent-Sluggable Easy creation of slugs for your Eloquent models in Laravel. NOTE: These instructions are for the latest version of Laravel. If you

Colin Viebrock 3.6k Dec 30, 2022
Automatically validating Eloquent models for Laravel

Validating, a validation trait for Laravel Validating is a trait for Laravel Eloquent models which ensures that models meet their validation criteria

Dwight Watson 955 Dec 25, 2022
Laravel Ban simplify blocking and banning Eloquent models.

Laravel Ban Introduction Laravel Ban simplify management of Eloquent model's ban. Make any model bannable in a minutes! Use case is not limited to Use

cybercog 879 Dec 30, 2022
cybercog 996 Dec 28, 2022
Tag support for Laravel Eloquent models - Taggable Trait

Laravel Taggable Trait This package is not meant to handle javascript or html in any way. This package handles database storage and read/writes only.

Rob 859 Dec 11, 2022
Laravel package to search through multiple Eloquent models.

Laravel package to search through multiple Eloquent models. Supports sorting, pagination, scoped queries, eager load relationships and searching through single or multiple columns.

Protone Media 845 Jan 1, 2023
Automatic human timestamps for Laravel Eloquent models.

Automatic human timestamp properties in Laravel This package provides a trait you can add to an Eloquent model that will automatically create human-re

Christopher Di Carlo 25 Jul 17, 2022
An Eloquent Way To Filter Laravel Models And Their Relationships

Eloquent Filter An Eloquent way to filter Eloquent Models and their relationships Introduction Lets say we want to return a list of users filtered by

Eric Tucker 1.5k Dec 30, 2022
🕵️ Inspect Laravel Eloquent models to collect properties, relationships and more.

??️ Eloquent Inspector Inspect Laravel Eloquent models to collect properties, relationships and more. Install Via Composer composer require cerbero/el

Andrea Marco Sartori 111 Nov 4, 2022
Laravel Nova Ban simplify blocking and banning Eloquent models.

Laravel Nova Ban Introduction Behind the scenes cybercog/laravel-ban is used. Contents Installation Usage Prepare bannable model Prepare bannable mode

cybercog 39 Sep 29, 2022
Package with small support traits and classes for the Laravel Eloquent models

Contains a set of traits for the eloquent model. In future can contain more set of classes/traits for the eloquent database.

Martin Kluska 3 Feb 10, 2022
Sortable behaviour for Eloquent models

Sortable behaviour for Eloquent models This package provides a trait that adds sortable behaviour to an Eloquent model. The value of the order column

Spatie 1.2k Dec 22, 2022
This package gives Eloquent models the ability to manage their friendships.

Laravel 5 Friendships This package gives Eloquent models the ability to manage their friendships. You can easily design a Facebook like Friend System.

Alex Kyriakidis 690 Nov 27, 2022
Create presenters for Eloquent Models

Laravel Presentable This package allows the information to be presented in a different way by means of methods that can be defined in the model's pres

The Hive Team 67 Dec 7, 2022
A small package for adding UUIDs to Eloquent models.

A small package for adding UUIDs to Eloquent models. Installation You can install the package via composer: composer require ryangjchandler/laravel-uu

Ryan Chandler 40 Jun 5, 2022
Use auto generated UUID slugs to identify and retrieve your Eloquent models.

Laravel Eloquent UUID slug Summary About Features Requirements Installation Examples Compatibility table Alternatives Tests About By default, when get

Khalyomede 25 Dec 14, 2022
Record created by, updated by and deleted by on Eloquent models automatically.

quarks/laravel-auditors Record created by, updated by and deleted by (if SoftDeletes added) on Eloquent models automatically. Installation composer re

Quarks 3 Jun 13, 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
Eloquent Befriended brings social media-like features like following, blocking and filtering content based on following or blocked models.

Laravel Befriended Eloquent Befriended brings social media-like features like following, blocking and filtering content based on following or blocked

Renoki Co. 720 Jan 3, 2023