• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

varhall / dbino / 11102192988

23 Sep 2024 01:08PM UTC coverage: 90.797%. Remained the same
11102192988

push

github

web-flow
Merge pull request #3 from varhall/v2.0

\Nette\Database\Table\Selection readonly properties

10 of 10 new or added lines in 1 file covered. (100.0%)

4 existing lines in 1 file now uncovered.

661 of 728 relevant lines covered (90.8%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/src/collections/ManyToManySelection.php
1
<?php
2

3
namespace Varhall\Dbino\Collections;
4

5

6
use Nette\Database\Table\ActiveRow;
7
use Nette\Database\Table\GroupedSelection;
8
use Nette\NotSupportedException;
9
use Varhall\Dbino\Traits\Events;
10

11
class ManyToManySelection extends GroupedSelection
12
{
13
    use Events;
14

15
    protected string $intermediateTable;
16

17
    protected string $referencedTable;
18

19
    protected string $foreignColumn;
20

21
    protected string $referenceColumn;
22

23
    protected mixed $foreignValue;
24

25

26
    public function __construct(\Nette\Database\Table\GroupedSelection $selection,
1✔
27
                                string $intermediateTable,
28
                                string $referencedTable,
29
                                string $foreignColumn,
30
                                string $referenceColumn,
31
                                mixed $foreignValue)
32
    {
33
        parent::__construct(
1✔
34
            $selection->context,
1✔
35
            $selection->conventions,
1✔
36
            $selection->name,
1✔
37
            $selection->column,
1✔
38
            $selection->refTable,
1✔
39
            $selection->cache?->getStorage()
1✔
40
        );
41

42
        foreach (get_object_vars($selection) as $property => $value) {
1✔
43
            $reflectionProperty = new \ReflectionProperty($this, $property);
1✔
44
            if ($reflectionProperty && !$reflectionProperty->isReadOnly()) {
1✔
45
                $reflectionProperty->setValue($this, $value);
1✔
46
            }
47
        }
48

49

50
        $this->intermediateTable = $intermediateTable;
1✔
51
        $this->referencedTable = $referencedTable;
1✔
52
        $this->foreignColumn = $foreignColumn;
1✔
53
        $this->referenceColumn = $referenceColumn;
1✔
54
        $this->foreignValue = $foreignValue;
1✔
55
    }
1✔
56

57

58
    public function intermediateTable()
59
    {
60
        return $this->context->table($this->intermediateTable)->where($this->foreignColumn, $this->foreignValue);
1✔
61
    }
62

63
    public function attach($values): void
1✔
64
    {
65
        $indb = array_map(
1✔
66
            function($item) { return $item->{$this->referenceColumn}; },
1✔
67
            $this->intermediateTable()->where("{$this->referenceColumn} IN ?", (array) $values)->select($this->referenceColumn)->fetchAll()
1✔
68
        );
69

70
        $values = array_diff((array) $values, $indb);
1✔
71

72
        if (empty($values)) {
1✔
UNCOV
73
            return;
×
74
        }
75

76
        $values = array_map(function($item) {
1✔
77
            return [
78
                $this->foreignColumn    => $this->foreignValue,
1✔
79
                $this->referenceColumn  => $item
1✔
80
            ];
81
        }, $values);
1✔
82

83
        if (count($values) === 1) {
1✔
84
            $values = array_pop($values);
1✔
85
        }
86

87
        $this->intermediateTable()->insert($values);
1✔
88
    }
1✔
89

90
    public function detach($values = null): void
1✔
91
    {
92
        $intermediate = $this->intermediateTable();
1✔
93

94
        if (!empty($values)) {
1✔
95
            $intermediate->where($this->referenceColumn, $values);
1✔
96
        }
97

98
        $intermediate->delete();
1✔
99
    }
1✔
100

101
    public function sync($values, callable $func = null)
1✔
102
    {
103
        if (is_array($values)) {
1✔
104
            $values = array_unique($values);
1✔
105
        }
106

107
        if (!$func) {
1✔
108
            $func = function() use ($values) {
1✔
109
                $this->detach();
1✔
110
                $this->attach($values);
1✔
111
            };
1✔
112
        }
113

114
        // synchronize
115
        $this->raise('beforeSync', $this, $values);
1✔
116
        $func();
1✔
117
        $this->raise('afterSync', $this, $values);
1✔
118
    }
1✔
119

120

121
    /***************************************** METHOD OVERRIDES *******************************************************/
122

123
    public function getSql(): string
124
    {
125
        $sql = parent::getSql();
1✔
126
        $join = "LEFT JOIN {$this->referencedTable} ON {$this->intermediateTable}.{$this->referenceColumn} = {$this->referencedTable}.id";
1✔
127

128
        $sql = preg_replace('/(from [^ ]+)/i', '$1 ' . $join, $sql);
1✔
129

130
        return $sql;
1✔
131
    }
132

133
    public function insert(iterable $data): ActiveRow|array|int|bool
134
    {
UNCOV
135
        throw new NotSupportedException('Collection is readonly');
×
136
    }
137

138

139
    public function update(iterable $data): int
140
    {
UNCOV
141
        throw new NotSupportedException('Collection is readonly');
×
142
    }
143

144

145
    public function delete(): int
146
    {
UNCOV
147
        throw new NotSupportedException('Collection is readonly');
×
148
    }
149
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc