Completed
Push — master ( d2c9b2...2cde9b )
by
unknown
08:05 queued 04:31
created

_includeDirectAssociations()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright 2016 - 2017, Cake Development Corporation (http://cakedc.com)
4
 *
5
 * Licensed under The MIT License
6
 * Redistributions of files must retain the above copyright notice.
7
 *
8
 * @copyright Copyright 2016 - 2017, Cake Development Corporation (http://cakedc.com)
9
 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
10
 */
11
12
namespace CakeDC\Api\Service\Action\Extension;
13
14
use CakeDC\Api\Service\Action\Action;
15
use CakeDC\Api\Service\Action\CrudAction;
16
use Cake\Event\Event;
17
use Cake\Event\EventListenerInterface;
18
use Cake\ORM\Query;
19
use Cake\Utility\Inflector;
20
21
/**
22
 * Class CrudRelationsExtension
23
 *
24
 * Allow to include relations for fetched entities to return by index, view or edit crud actions.
25
 * Currently limited only by HasOne and BelongsTo associations.
26
 *
27
 * @package CakeDC\Api\Service\Action\Extension
28
 */
29
class CrudRelationsExtension extends Extension implements EventListenerInterface
30
{
31
32
    /**
33
     * Returns a list of events this object is implementing. When the class is registered
34
     * in an event manager, each individual method will be associated with the respective event.
35
     *
36
     * @return array
37
     */
38 4
    public function implementedEvents()
39
    {
40
        return [
41 4
            'Action.Crud.onFindEntities' => 'findEntities',
42 4
            'Action.Crud.onFindEntity' => 'findEntity',
43 4
        ];
44
    }
45
46
    /**
47
     * On find entity
48
     *
49
     * @param Event $event An Event instance.
50
     * @return \Cake\ORM\Query
51
     */
52 4
    public function findEntity(Event $event)
53
    {
54 4
        return $this->_attachAssociations($event->getSubject(), $event->getData('query'));
55
    }
56
57
    /**
58
     * On find entities.
59
     *
60
     * @param Event $event An Event instance.
61
     * @return \Cake\ORM\Query
62
     */
63
    public function findEntities(Event $event)
64
    {
65
        return $this->_attachAssociations($event->getSubject(), $event->getData('query'));
66
    }
67
68
    /**
69
     * Checks if endpoint returns additional associations.
70
     *
71
     * @param CrudAction $action A CrudAction instance.
72
     * @return array|bool
73
     */
74 4
    protected function _includeAssociations(CrudAction $action)
75
    {
76 4
        $data = $action->data();
77 4
        if (!empty($data['include_associations']) && empty($data['include_relations'])) {
78
            $data['include_relations'] = $data['include_associations'];
79
        }
80 4
        $exists = (is_array($data) && !empty($data['include_relations']));
81 4
        if (!$exists) {
82 3
            return false;
83
        }
84 1
        $associations = $data['include_relations'];
85 1
        if (!is_array($associations)) {
86 1
            return explode(',', $associations);
87
        }
88
        if (is_array($associations) && count($associations) > 0) {
89
            return $associations;
90
        }
91
92
        return false;
93
    }
94
95
    /**
96
     * Checks if endpoint returns direct associations, i.e. all belongsTo and all hasOne.
97
     *
98
     * @param CrudAction $action An CrudAction instance.
99
     * @return bool
100
     */
101 3
    protected function _includeDirectAssociations(CrudAction $action)
102
    {
103 3
        $data = $action->data();
104
105 3
        return (is_array($data) && !empty($data['include_direct']));
106
    }
107
108
    /**
109
     * @param Action $action An Action instance.
110
     * @param Query $query A Query instance.
111
     * @return mixed
112
     */
113 4
    protected function _attachAssociations(CrudAction $action, Query $query)
114
    {
115 4
        $associations = $this->_includeAssociations($action);
116 4
        if (empty($associations) && $this->_includeDirectAssociations($action)) {
117 1
            $relations = $action->getTable()
118 1
                ->associations()
119 1
                ->type(['HasOne', 'BelongsTo']);
120 1
            $associations = collection($relations)
121
                ->map(function ($relation) {
122 1
                    return $relation->target()->table();
123 1
                })
124 1
                ->toArray();
125 1
        }
126 4
        if (empty($associations)) {
127 2
            return $query;
128
        }
129
130 2
        $tables = collection($associations)
131
            ->map(function ($name) {
132 2
                return Inflector::camelize($name);
133 2
            })
134 2
            ->toArray();
135
136 2
        collection($tables)->each(function ($name) use ($query, $action) {
137 2
            $assoc = $action->getTable()->association($name);
138 2
            if ($assoc !== null) {
139 2
                $query->select($assoc);
140 2
            }
141 2
        });
142 2
        $query->select($action->getTable());
143 2
        $query->contain($tables);
144
145 2
        return $query;
146
    }
147
}
148