Skip to content

Instantly share code, notes, and snippets.

@aknackd
Last active October 28, 2016 16:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aknackd/6021f1d0ff4ef2d5f78fd26a5982ebe9 to your computer and use it in GitHub Desktop.
Save aknackd/6021f1d0ff4ef2d5f78fd26a5982ebe9 to your computer and use it in GitHub Desktop.
Laravel 5.3 helpers
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group(['prefix'=> 'v1', 'namespace' => 'Api'], function () {
Route::group(['prefix' => 'applications'], function () {
Route::get('', 'ApplicationsController@all'); // GET /api/v1/applications
Route::get('{application}', 'ApplicationsController@show'); // GET /api/v1/applications/:id
Route::post('', 'ApplicationsController@store'); // POST /api/v1/applications
Route::put('{application}', 'ApplicationsController@update'); // PUT /api/v1/applications/:id
Route::patch('{application}', 'ApplicationsController@update'); // PATCH /api/v1/applications/:id
Route::delete('{application}', 'ApplicationsController@destroy'); // DELETE /api/v1/applications/:id
});
});
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Traits\HasAppModelTrait;
class Application extends Model
{
use HasAppModelTrait;
protected $fillable = ['name', 'status'];
}
<?php
namespace App\Http\Controllers\Api;
use Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Application;
class ApplicationsController extends Controller
{
/**
* Return all applications, paginated
*/
public function all(Request $request)
{
$this->validateInput(new Application, [
'status' => 'string',
'limit' => 'integer|between:1,1000',
]);
$limit = (int) $request->input('limit') ?: config('app.results_per_page');
$query = Application::query();
// filter by status
if ($request->has('status')) {
$query->where('status', $request->input('status'));
}
return $query->paginate($limit);
}
/**
* Return individual application
*/
public function show(Application $application)
{
return $application;
}
/**
* Create new application
*/
public function store(Request $request)
{
$this->validate($request, [
'name' => 'string|required',
'status' => 'string',
]);
$application = Application::createFromArray($request->input());
$application->save();
return $application;
}
/**
* Update existing application
*/
public function update(Request $request, Application $application)
{
$this->validate($request, [
'name' => 'string',
'status' => 'string',
]);
$application->update($request->input());
return $application;
}
/**
* Delete application
*/
public function destroy(Application $application)
{
$application->destroy($application->id);
return response('', 204);
}
}
<?php
namespace App;
class ApplicationStatus extends AppModel
{
protected $table = 'application_statuses';
}
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.3.*"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~5.0",
"symfony/css-selector": "3.1.*",
"symfony/dom-crawler": "3.1.*"
},
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"classmap": [
"tests/TestCase.php"
]
},
"scripts": {
"post-root-package-install": [
"php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"php artisan key:generate"
],
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan optimize"
]
},
"config": {
"preferred-install": "dist"
}
}
<?php
namespace App\Models\Traits;
use DB;
use Schema;
use Carbon\Carbon;
use InvalidArgumentException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
trait HasAppModelTrait
{
use HasUuidPrimaryKeyTrait;
/**
* Constructor
*
* @param array $attributes Attributes
*/
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
parent::boot();
// Hide fields from responses
array_push($this->hidden, 'pivot');
array_push($this->hidden, 'created_at');
array_push($this->hidden, 'updated_at');
// By default table names are snake case and plural of the model's
// name (ex: Person -> people, AccountStatus -> account_statuses)
$this->table = str_plural(
strtolower(snake_case(class_basename(get_called_class())))
);
}
/**
* Retrieves the traits the model class has. Recursively fetches the Traits
* of parent classes (i.e. if traits have their own traits).
*
* Taken from https://secure.php.net/manual/en/function.class-uses.php#112671
* Retrieved 2016-09-15
*
* @param boolean $autoload Whether to allow loading classes automatically through the __autoload() magic method
* @return array An array of trait classes
*/
protected static function getTraits($autoload = true)
{
$class = get_class();
$traits = [];
do {
$traits = array_merge(class_uses($class, $autoload), $traits);
} while ($class = get_parent_class($class));
$traitsToSearch = $traits;
while (!empty($traitsToSearch)) {
$newTraits = class_uses(array_pop($traitsToSearch), $autoload);
$traits = array_merge($newTraits, $traits);
$traitsToSearch = array_merge($newTraits, $traitsToSearch);
}
foreach ($traits as $trait => $same) {
$traits = array_merge(class_uses($trait, $autoload), $traits);
}
return array_unique(array_keys($traits));
}
/**
* Returns whether or not our model has a particular trait.
*
* @param string $trait Trait class
* @return boolean True or false
*/
protected static function hasTrait($trait)
{
return in_array($trait, self::getTraits());
}
/**
* Retrieve the table name used by the model.
*
* @return string Table name
*/
public static function table()
{
return with(new static)->table;
}
/**
* Find a record by a field. If record annot be found then throw an
* exception.
*
* @param string $field Field
* @param mixed $value Value
* @param array $columns Columns to return in the result
* @return array|mixed Search result
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException If record cannot be found
*/
public static function findByFieldOrFail($field, $value, $columns = ['*'])
{
$instance = new self;
$result = $instance->where($field, $value)
->select($columns)
->get();
if (is_null($result) || $result->count() == 0) {
throw (new ModelNotFoundException)->setModel(get_called_class());
}
return $result;
}
/**
* Creates a new record from a data array. Doesn't insert record into the
* database (must manually be done via `create()`).
*
* @param array $data Data
* @return mixed Instance of model
* @throws \InvalidArgumentException If an invalid field is specified in the data array
*/
public static function createFromArray(array $data)
{
$instance = new self;
$table = $instance::table();
foreach ($data as $field => $value) {
if (!Schema::hasColumn($table, $field)) {
throw new InvalidArgumentException('Invalid field: '.$field);
}
$instance->$field = $value;
}
return $instance;
}
/**
* Inserts a new record given a data array.
*
* @param array $data Data
* @return mixed Instance of newly created model
*/
public static function insertFromArray(array $data)
{
return self::createFromArray($data)->create();
}
/**
* Inserts many records into the database.
*
* @param array $items Items
* @return
*/
public static function insertMany(array $items)
{
$now = Carbon::now();
$table = self::table();
$timestamps = [];
if (Schema::hasColumn($table, 'created_at')) {
$timestamps['created_at'] = $now;
}
if (Schema::hasColumn($table, 'updated_at')) {
$timestamps['updated_at'] = $now;
}
// Inject timestamps if their columns are present in the table schema
if (count($timestamps) > 0) {
$items = collect($items)->map(function ($data) use ($timestamps, $table) {
return array_merge($timestamps, $data);
})->all();
}
// Inject UUIDs since they're only created on `create()`
if ($instance->hasTrait(HasUuidPrimaryKeyTrait::class)) {
$items = collect($items)->map(function ($data) use ($instance) {
return array_merge($data, ['id' => $instance->generateUuid()]);
})->all();
}
return DB::table($table)->insert($items);
}
}
<?php
namespace App\Models\Traits;
use Ramsey\Uuid\Uuid;
trait HasUuidPrimaryKeyTrait
{
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
if ($model->id === null) {
$model->id = self::generateUuid();
}
});
}
protected static function generateUuid()
{
return Uuid::uuid4()->toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment