Askedio/laravel-Cruddy

View on GitHub
src/Traits/ModelTrait.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php

namespace Askedio\Laravel5ApiController\Traits;

use Askedio\Laravel5ApiController\Exceptions\BadRequestException;
use Askedio\Laravel5ApiController\Helpers\Api;
use Askedio\Laravel5ApiController\Helpers\ApiObjects;
use DB;

trait ModelTrait
{
    private $objects;

    public function getIncludes()
    {
        return isset($this->includes) ? $this->includes : [];
    }

    public function getObjects()
    {
        if (! $this->objects) {
            $this->objects = new ApiObjects($this);
        }

        return $this->objects;
    }

    /**
     * The validation rules assigned in model.
     *
     * @var string
     *
     * @return array
     */
    public function getRule($rule)
    {
        return isset($this->rules[$rule]) ? $this->rules[$rule] : [];
    }

    /**
     * The id_field defined in the model.
     *
     * @return string
     */
    public function getId()
    {
        return isset($this->primaryKey) ? $this->primaryKey : 'id';
    }

    /**
     * Return if Model has searchable flag.
     *
     * @return bool
     */
    public function isSearchable()
    {
        return isset($this->searchable);
    }

    /**
     * Set order/sort as per json spec.
     * TO-DO: Should go into the ApiValidation class so it can manage relational sorts, ie sort=-profiles.id,users.id.
     *
     * @param string $query
     * @param string $sort
     *
     * @return object
     */
    public function scopesetSort($query, $sort)
    {
        if (empty($sort) || ! is_string($sort) || empty($sorted = explode(',', $sort))) {
            return $query;
        }

        $columns = $this->columns();

        $errors = array_filter(array_diff(array_map(function ($string) {
            return ltrim($string, '-');
        }, $sorted), $columns));

        if (! empty($errors)) {
            throw (new BadRequestException('invalid_sort'))->withDetails([[$this->getTable(), implode(' ', $errors)]]);
        }

        array_map(function ($column) use ($query) {
            return $query->orderBy(ltrim($column, '-'), ('-' === $column[0]) ? 'DESC' : 'ASC');
        }, $sorted);

        return $query;
    }

    /**
     * Filter results based on filter get variable and transform them if enabled.
     *
     * @return array
     */
    public function scopefilterAndTransform()
    {
        $fields = app('api')->fields();

        $key = $this->getTable();

        $results = $this->isTransformable($this) ? $this->transform($this) : $this;

        if ($fields->has($key)) {
            $results = array_diff_key($results, array_flip(array_diff(array_keys($results), $fields->get($key))));
        }

        return $results;
    }

    /**
     * List of columns related to this Model, Cached.
     *
     * @return array
     */
    private $cols;

    public function columns()
    {
        if (! $this->cols) {
            $this->cols = DB::connection()->getSchemaBuilder()->getColumnListing($this->getTable());
        }

        return $this->cols;
    }

    /**
     * Checks whether the object is transformable or not.
     *
     * @param $item
     *
     * @return bool
     */
    private function isTransformable($item)
    {
        return is_object($item) && method_exists($item, 'transform');
    }
}