Passed
Push — pulls/manymanylist-add-callbac... ( 77b6c5...7684da )
by Ingo
08:25
created

RelationList::setAddCallback()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace SilverStripe\ORM;
4
5
use Exception;
6
7
/**
8
 * A DataList that represents a relation.
9
 *
10
 * Adds the notion of a foreign ID that can be optionally set.
11
 */
12
abstract class RelationList extends DataList implements Relation
13
{
14
15
    /**
16
     * @var bool Hardcoded to false
17
     */
18
    protected $deleteOnRemove = false;
19
20
    /**
21
     * Any number of foreign keys to apply to this list
22
     *
23
     * @return string|array|null
24
     */
25
    public function getForeignID()
26
    {
27
        return $this->dataQuery->getQueryParam('Foreign.ID');
28
    }
29
30
    public function getQueryParams()
31
    {
32
        $params = parent::getQueryParams();
33
34
        // Remove `Foreign.` query parameters for created objects,
35
        // as this would interfere with relations on those objects.
36
        foreach (array_keys($params) as $key) {
37
            if (stripos($key, 'Foreign.') === 0) {
38
                unset($params[$key]);
39
            }
40
        }
41
42
        return $params;
43
    }
44
45
    /**
46
     * Returns a copy of this list with the ManyMany relationship linked to
47
     * the given foreign ID.
48
     *
49
     * @param int|array $id An ID or an array of IDs.
50
     *
51
     * @return static
52
     */
53
    public function forForeignID($id)
54
    {
55
        // Turn a 1-element array into a simple value
56
        if (is_array($id) && sizeof($id) == 1) {
57
            $id = reset($id);
58
        }
59
60
        // Calculate the new filter
61
        $filter = $this->foreignIDFilter($id);
62
63
        $list = $this->alterDataQuery(function (DataQuery $query) use ($id, $filter) {
64
            // Check if there is an existing filter, remove if there is
65
            $currentFilter = $query->getQueryParam('Foreign.Filter');
66
            if ($currentFilter) {
67
                try {
68
                    $query->removeFilterOn($currentFilter);
69
                } catch (Exception $e) {
70
                    /* NOP */
71
                }
72
            }
73
74
            // Add the new filter
75
            $query->setQueryParam('Foreign.ID', $id);
76
            $query->setQueryParam('Foreign.Filter', $filter);
77
            $query->where($filter);
78
        });
79
80
        return $list;
81
    }
82
83
    /**
84
     * Returns a where clause that filters the members of this relationship to
85
     * just the related items.
86
     *
87
     *
88
     * @param array|integer $id (optional) An ID or an array of IDs - if not provided, will use the current ids as
89
     * per getForeignID
90
     * @return array Condition In array(SQL => parameters format)
91
     */
92
    abstract protected function foreignIDFilter($id = null);
93
94
    /**
95
     * Not applicable to relations.
96
     *
97
     * @throws \LogicException
98
     */
99
    public function setDeleteOnRemove(bool $bool): self
100
    {
101
        throw new \LogicException('Not applicable to relations');
102
    }
103
}
104