RelationFactory::get()   C
last analyzed

Complexity

Conditions 7
Paths 12

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 13.125

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 12
nop 1
dl 0
loc 36
ccs 12
cts 24
cp 0.5
crap 13.125
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
namespace Anavel\Crud\Abstractor\Eloquent;
4
5
use ANavallaSuiza\Laravel\Database\Contracts\Manager\ModelManager;
6
use Anavel\Crud\Abstractor\Exceptions\FactoryException;
7
use Anavel\Crud\Contracts\Abstractor\FieldFactory as FieldFactoryContract;
8
use Anavel\Crud\Contracts\Abstractor\RelationFactory as RelationAbstractorFactoryContract;
9
use Illuminate\Database\Eloquent\Model as EloquentModel;
10
11
class RelationFactory implements RelationAbstractorFactoryContract
12
{
13
    const SELECT = 'select';
14
    const SELECT_MULTIPLE = 'select-multiple';
15
    const SELECT_MULTIPLE_MANY_TO_MANY = 'select-multiple-many-to-many';
16
    const CHECKLIST = 'checklist';
17
    const MINI_CRUD = 'mini-crud';
18
    const MINI_CRUD_SINGLE = 'mini-crud-single';
19
    const MINI_CRUD_POLYMORPHIC = 'mini-crud-polymorphic';
20
    const TRANSLATION = 'translation';
21
22
    protected $eloquentTypeToRelationType = [
23
        'Illuminate\Database\Eloquent\Relations\BelongsTo'     => self::SELECT,
24
        'Illuminate\Database\Eloquent\Relations\BelongsToMany' => self::SELECT_MULTIPLE_MANY_TO_MANY,
25
        'Illuminate\Database\Eloquent\Relations\HasMany'       => self::SELECT_MULTIPLE,
26
        'Illuminate\Database\Eloquent\Relations\HasManyTrough' => self::SELECT_MULTIPLE,
27
        'Illuminate\Database\Eloquent\Relations\HasOne'        => self::SELECT,
28
        'Illuminate\Database\Eloquent\Relations\HasOneOrMany'  => self::SELECT_MULTIPLE,
29
        'Illuminate\Database\Eloquent\Relations\MorphMany'     => self::MINI_CRUD_POLYMORPHIC,
30
        'Illuminate\Database\Eloquent\Relations\MorphOne'      => self::MINI_CRUD_SINGLE,
31
    ];
32
33
    protected $typesMap = [
34
        self::SELECT                       => 'Anavel\Crud\Abstractor\Eloquent\Relation\Select',
35
        self::SELECT_MULTIPLE              => 'Anavel\Crud\Abstractor\Eloquent\Relation\SelectMultiple',
36
        self::SELECT_MULTIPLE_MANY_TO_MANY => 'Anavel\Crud\Abstractor\Eloquent\Relation\SelectMultipleManyToMany',
37
        self::CHECKLIST                    => 'Anavel\Crud\Abstractor\Eloquent\Relation\Checklist',
38
        self::MINI_CRUD                    => 'Anavel\Crud\Abstractor\Eloquent\Relation\MiniCrud',
39
        self::MINI_CRUD_SINGLE             => 'Anavel\Crud\Abstractor\Eloquent\Relation\MiniCrudSingle',
40
        self::MINI_CRUD_POLYMORPHIC        => 'Anavel\Crud\Abstractor\Eloquent\Relation\MiniCrudPolymorphic',
41
        self::TRANSLATION                  => 'Anavel\Crud\Abstractor\Eloquent\Relation\Translation',
42
    ];
43
44
    protected $modelManager;
45
    protected $fieldFactory;
46
47
    /**
48
     * @var EloquentModel
49
     */
50
    protected $model;
51
    protected $config;
52
53 4
    public function __construct(ModelManager $modelManager, FieldFactoryContract $fieldFactory)
54
    {
55 4
        $this->modelManager = $modelManager;
56 4
        $this->fieldFactory = $fieldFactory;
57 4
        $this->config = [];
58 4
    }
59
60 4
    public function setModel($model)
61
    {
62 4
        $this->model = $model;
63
64 4
        return $this;
65
    }
66
67 1
    public function setConfig(array $config)
68
    {
69 1
        $this->config = $config;
70
71 1
        return $this;
72
    }
73
74 2
    public function get($name)
75
    {
76 2
        if (!empty($this->config) && !empty($this->config['name'])) {
77 1
            $name = $this->config['name'];
78 1
        }
79 2
        if (!method_exists($this->model, $name)) {
80 1
            throw new FactoryException('Relation '.$name.' does not exist on '.get_class($this->model));
81
        }
82
83 1
        $relationInstance = $this->model->$name();
84 1
        $relationEloquentType = get_class($relationInstance);
85
86 1
        if (empty($this->config['type'])) {
87
            if (!array_key_exists($relationEloquentType, $this->eloquentTypeToRelationType)) {
88
                throw new FactoryException($relationEloquentType.' relation not supported');
89
            }
90
91
            $type = $this->eloquentTypeToRelationType[$relationEloquentType];
92
        } else {
93 1
            $type = $this->config['type'];
94
        }
95
96 1
        if (!array_key_exists($type, $this->typesMap)) {
97 1
            throw new FactoryException('Unexpected relation type: '.$type);
98
        }
99
100
        $this->config['name'] = $name;
101
102
        return new $this->typesMap[$type](
103
            $this->config,
104
            $this->modelManager,
105
            $this->model,
106
            $relationInstance,
107
            $this->fieldFactory
108
        );
109
    }
110
}
111