rtmatt/abstractresource

This package is abandoned and no longer maintained. No replacement package was suggested.
There is no license information available for the latest version (2.0.0) of this package.

Abstract Resource Manager for Laravel

2.0.0 2016-11-17 17:39 UTC

README

Abstract Resource Management in Laravel.

Latest Version on Packagist Total Downloads

Speed up basic CRUD functionality by configuring resources, rather than repeating the same code over and over and over...

This package currently generates a horizontal form with Bootstrap 3 markup.

Prerequisites

In an ideal world, this would be a fully self-contained package. This isn't an ideal world.

Laravel

You will need an existing install of laravel 5.1. You'll need a database set up and hooked into the application.

Admin Layout

You will need a file in /resources/views/layouts called admin.blade.php At the very least, this file will need a @yield('content) in it.

Install

Via Composer

$ composer require rtmatt/abstractresource

Add to service provider list in config/app.php

RTMatt\AbstractResource\AbstractResourceServiceProvider::class,

This package has a couple dependencies you will need to register with you app if they haven't been already. In your file's config/app.php file, make sure the following is under your 'providers' list:

'Intervention\Image\ImageServiceProvider',
'Collective\Html\HtmlServiceProvider',

In the same file, the following needs to be in your 'aliases' list:

    'Form'  => 'Collective\Html\FormFacade',
    'Image' => 'Intervention\Image\Facades\Image',

For file uploads to work, you will need a folder uploads inside your public directory that is writable by the web server.

If you don't already have one, create a folder Admin in app/Http/Controllers

Usage

Create Model and Migration

$ php artisan make:model [ResourceName] -m

Within the migration file, define your schema. Make sure to define all nullable inputs. Inputs with no values will be set to null on the back end. Run the migration when you're done.

Make Resource Controller

When you make your controller, make sure its name is your Resource Name (pluralized and StudlyCased) + 'Controller'

$ php artisan make:controller Admin/[ResourceNames]Controller --plain

The contents should reflect the following:

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Requests;
use RTMatt\AbstractResource\AbstractResourceController;

class [ResourceNames]Controller extends AbstractResourceController
{

    protected $model = '\App\[ResourceName]';

}

It's important the controller is named just the same as your resource, only pluralized and that it lives in the Admin subdirectory of the controllers directory.
It should extend from RTMatt\AbstractResource\AbstractResourceController and have a namespace of App\Http\Controllers\Admin.

This is all you need for default functionality.

Create Route

Within your routes.php file:

Route::resource('/admin/[resource-names]','Admin\[ResourceNames]Controller');

The URI needs to be a subroute of /admin. The route needs to be a resource route.

Define Model

Define your model as normal. Add your fillable array and any accessors or mutators you will need.

Add the following method:

public static function getResourceControllerConfigs()
{
    return [
        'resourceName'   => 'resource-names',
        'creatable'      => true,
        'deletable'      => true,
        'indexFields'    => [ 'field_1', 'field_2' ],
        'editableFields' => [
            // ...
        ]
    ];
}

This method is where the power lies. We'll discuss it later. Just kidding. We'll discuss it NOW.

Configure Model

Configure your model by changing the array returned by the getResourceControllerConfigs method.

[

    'resourceName'   => 'resource-names',						//this is the lower-case, hyphenated resource name
    'creatable'      => true,    								//whether the resource should be creatable in the admin
    'deletable'      => true,    								//whether the resource should be deletable in the admin
    'indexFields'    => [ 'field__name_1', 'field_name_2' ],    //fields to display on the index view of the resource manager
    'editableFields' => [    									// all the fields that appear on the create and edit forms
        'field_name' => 'field_type'        					// field definition.  make sure each field is fillable

    ]
]

On the generated form, labels will automatically be generated from field names by replacing underscores with spaces and capitalizing the result. Additionally, if the field name ends in "_id," it will be removed.

    'hide_flag'        => "Hide Flag:",
    'property_type_id' => "Property Type:"

Standard Options for field_type

    'field_name' => 'text',        // <input type="text" name="field_name">
    'field_name' => 'tel',         // <input type="tel" name="field_name">
    'field_name' => 'email',       // <input type="email" name="field_name">
    'field_name' => 'textarea',    // <textarea name="field_name"></textarea>
    'field_name' => 'image',       // <input type="file" name="field_name"> - configured for image uploads
    'field_name' => 'file',        // <input type="file" name="field_name"> - configured for file uploads
    'field_name' => 'checkbox',    // single checkbox

Array-based field_type options

Some field types are more complex and defined as arrays :

    'field_name' => [        // Array Field Type
        'type'    => 'radioGroup',  //creates a radio group
        'options' => [              //options are defined as value:key pairs
            'value_1' => 'Display Text for value_1',
            'value_2' => 'Display Text for value_2',
        ]
    ],
    'field_name' => [        // Array Field Type
        'type'    => 'select',      //creates a select input
        'options' => [              //options are defined as value:key pairs
            'value_1' => 'Display Text for value_1',
            'value_2' => 'Display Text for value_2',
        ]
    ],
    'field_name' => [        // Array Field Type
        'type'    => 'checkGroup',  //creates a checkbox group
        'options' => [              //options are defined as value:key pairs
            'value_1' => 'Display Text for value_1',
            'value_2' => 'Display Text for value_2',
        ]
    ],

Note: checkgroup field types require you create accessors and mutators on your model to json_encode the field when storing values and json_decode the field when retrieving them.

Special field_type Options

WYSIWIG
   'field_name' => 'wysi',  //creates a wysi input.   requires additional scripts

This simply creates a textarea input and adds a class of "wysi" to it. You can attach any wysiwig plugin you like to this class.

Date/Datetime
    'field_name' => 'date',  		//creates an input primed for a datepicker.   requires additional scripts
    'field_name' => 'datetime',  	//creates an input primed for a datepicker.   requires additional scripts

The above create inputs of type="text" with the classes "date-picker" and "date-time-picker" respectively. You can use these classes to attach any date/datetime picker plugins you wish.

#####Image with Size Variants This is for images that require automatic saving of various sizes (standard - 320x240, thumbnail - 32x24,etc)

'field_name' => 'varied_image', //creates a image input field  

For the system to create the image variants, you need to add a new index to the array returned by getResourceControllerConfigs():

    'field_name_versions' => [                      	// make sure  `field_name` corresponds to the name you used to create the input
        'name_columns' => [ 'name_field' ],         	// field used to generate file names.  this must be a field from the model
        'versions'     =>                           	// different varients of image to create.  It's important these are in order of descending size
            [
                'field_name'   => [ height, width ], 	// arrays are integers
                'field_name_2' => [ height, width ],
                //...
            ]
    ]

If you would like to see all size variants of the image after it has been saved, add the following to you site's .env file:

DEMO=true

Complete Model Configuration Example

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ResourceName extends Model
{

    protected $fillable = [
        'name',
        'phone_number',
        'email_address',
        'biography',
        'hide_flag',
        'featured_image',
        'resume_file',
        'color',
        'affiliation',
        'skills',
        'custom_content',
        'birthday',
        'hide_until',
        'profile_picture',
        'profile_picture_2x',
        'profile_picture_tile',
        'profile_picture_tile_2x',
    ];


    public static function getResourceControllerConfigs()
    {
        return [
            'resourceName'             => 'resource-names',
            'creatable'                => true,
            'deletable'                => true,
            'indexFields'              => [ 'name', 'phone_number', 'email_address' ],
            'editableFields'           => [
                'name'            => 'text',
                'phone_number'    => 'tel',
                'email_address'   => 'email',
                'biography'       => 'textarea',
                'hide_flag'       => 'checkbox',
                'featured_image'  => 'image',
                'resume_file'     => 'file',
                'color'           => [
                    'type'    => 'radioGroup',
                    'options' => [
                        'red'  => 'Favorite Color - Red',
                        'blue' => 'Favorite Color - Blue',
                    ]
                ],
                'affiliation'     => [
                    'type'    => 'select',
                    'options' => [
                        'rep' => 'Republican',
                        'dem' => 'Democrat',
                        'ind' => 'Independent',
                        'oth' => 'Other',
                    ]
                ],
                'skills'          => [
                    'type'    => 'checkGroup',
                    'options' => [
                        'typing'   => 'Typing',
                        'reading'  => 'Readiing',
                        'knitting' => 'Knitting'
                    ]
                ],
                'custom_content'  => 'wysi',
                'birthday'        => 'date',
                'hide_until'      => 'datetime',
                'profile_picture' => 'varied_image',
            ],
            'profile_picture_versions' => [
                'name_columns' => [ 'name' ],
                'versions'     => [
                    'profile_picture_tile_2x' => [ 80, 80 ],
                    'profile_picture_2x'      => [ 60, 60 ],
                    'profile_picture_tile'    => [ 40, 40 ],
                    'profile_picture'         => [ 30, 30 ],
                ]
            ]
        ];
    }


    public function setSkillsAttribute($value)
    {
        $this->attributes['skills'] = json_encode($value);
    }


    public function getSkillsAttribute($value)
    {
        return json_decode($value, true); //include true arguent to create array instead of std class
    }

}

Overrides

For more complex resources, you will need to override default functionality.

Index Ordering

If you want to change the order of display on the index page, simply give your model a query scope called defaultOrder:

public function scopeDefaultOrder($query){
	return $query->orderBy('name','asc');
}

View Overrides

Overriding the default view for any resource manager screens is easy. All you need to do is create the overridden view, and it will be loaded. If you don't already have one, you will need a resources/views/admin folder.

Within this folder, create a folder for your resource and whichever of the following files you want to override:

resources/views/admin/
   [resource-names]/               //this folder needs to be the pluralized, hyphenated name of your resource
       resource/                   //this folder holds all the necessary resource views
           index.blade.php         
           edit.blade.php
           create.blade.php
           show.blade.php
           partials/
               form.blade.php      //the form for creating/editing your resource.

It's recommended to start with the default views in this package as a starting point when creating an override.

Functionality Overrides

There are some extra functionions outside of typical REST that you can use to add functionality without overriding the REST functions.

Validation
    // define the rules for laravel controller validation for the store request
    protected function getValidationRulesStore()
    {
        return [ ];
    }


    // define custom validation messages for laravel controller validation for the store request
    protected function getValidationMessagesStore()
    {
        return [ ];
    }
Additional Manipulation of Data
	//Allows you do manipulate form input before creting the new resource instance.  if errors are be produced, return $args['errors'] with the error message
    protected function uniqueStoreArgs($args)
    {
        return $args;
    }

All these methods have versions for update requests. Simply replace 'Store' with 'Update' in the function names.

Pre-Destroy Functionality

If you need to do anything prior to deleting a model instance, you can override the following function:

    protected function pre_destroy($id){
        return true;
    }

Change log

Please see CHANGELOG for more information what has changed recently.

License

Exclusive. Please see License File for more information.