Completed
Branch feature/currentUserRefactoring (e6f778)
by Schlaefer
02:47
created

Posting::withCurrentUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace Saito\Posting;
14
15
use Saito\Posting\Basic\BasicPostingTrait;
16
use Saito\Posting\PostingInterface;
17
use Saito\Posting\UserPosting\UserPostingTrait;
18
use Saito\Thread\Thread;
19
use Saito\User\CurrentUser\CurrentUserInterface;
20
use Saito\User\RemovedSaitoUser;
21
use Saito\User\SaitoUser;
22
23
class Posting implements PostingInterface
24
{
25
26
    use BasicPostingTrait;
27
    use UserPostingTrait;
28
29
    protected $_children = [];
30
31
    /**
32
     * Distance to root in tree
33
     *
34
     * @var int
35
     */
36
    protected $_level;
37
38
    protected $_rawData;
39
40
    protected $_Thread;
41
42
    /**
43
     * Constructor.
44
     *
45
     * @param array $rawData raw posting data
46
     * @param array $options options
47
     * @param null|Thread $tree thread
48
     */
49
    public function __construct(
50
        $rawData,
51
        array $options = [],
52
        Thread $tree = null
53
    ) {
54
        $this->_rawData = $rawData;
55
56
        if (empty($this->_rawData['user'])) {
57
            $this->_rawData['user'] = new RemovedSaitoUser();
58
        } else {
59
            $this->_rawData['user'] = new SaitoUser($this->_rawData['user']);
60
        }
61
62
        $options += ['level' => 0];
63
        $this->_level = $options['level'];
64
65
        if (!$tree) {
66
            $tree = new Thread;
67
        }
68
        $this->_Thread = $tree;
69
        $this->_Thread->add($this);
70
71
        $this->_attachChildren();
72
    }
73
74
    /**
75
     * {@inheritDoc}
76
     */
77
    public function get($var)
78
    {
79
        switch (true) {
80
            case (isset($this->_rawData[$var])):
81
                return $this->_rawData[$var];
82
            case (array_key_exists($var, $this->_rawData)):
83
                // key is set but null
84
                return $this->_rawData[$var];
85
            default:
86
                $message = "Attribute '$var' not found in class Posting.";
87
                throw new \InvalidArgumentException($message);
88
        }
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     */
94
    public function withCurrentUser(CurrentUserInterface $CU): self
95
    {
96
        $this->setCurrentUser($CU);
97
        $this->map(function ($node) use ($CU) {
98
            $node->setCurrentUser($CU);
99
        });
100
101
        return $this;
102
    }
103
104
    /**
105
     * {@inheritDoc}
106
     */
107
    public function getLevel(): int
108
    {
109
        return $this->_level;
110
    }
111
112
    /**
113
     * {@inheritDoc}
114
     */
115
    public function getChildren()
116
    {
117
        return $this->_children;
118
    }
119
120
    /**
121
     * {@inheritDoc}
122
     */
123
    public function getAllChildren()
124
    {
125
        $postings = [];
126
        $this->map(
127
            function ($node) use (&$postings) {
128
                $postings[$node->get('id')] = $node;
129
            },
130
            false
131
        );
132
133
        return $postings;
134
    }
135
136
    /**
137
     * {@inheritDoc}
138
     */
139
    public function toArray()
140
    {
141
        return $this->_rawData;
142
    }
143
144
    /**
145
     * {@inheritDoc}
146
     */
147
    public function getThread()
148
    {
149
        return $this->_Thread;
150
    }
151
152
    /**
153
     * {@inheritDoc}
154
     */
155
    public function hasAnswers()
156
    {
157
        return count($this->_children) > 0;
158
    }
159
160
    /**
161
     * {@inheritDoc}
162
     */
163
    public function map(callable $callback, bool $mapSelf = true, $node = null): void
164
    {
165
        if ($node === null) {
166
            $node = $this;
167
        }
168
        if ($mapSelf) {
169
            $callback($node);
170
        }
171
        foreach ($node->getChildren() as $child) {
172
            $this->map($callback, true, $child);
173
        }
174
    }
175
176
    /**
177
     * {@inheritDoc}
178
     */
179
    public function addDecorator(callable $fct)
180
    {
181
        foreach ($this->_children as $key => $child) {
182
            $newChild = $fct($child);
183
            $newChild->addDecorator($fct);
184
            $this->_children[$key] = $newChild;
185
        }
186
        $new = $fct($this);
187
        // replace decorated object in Thread collection
188
        $this->_Thread->add($new);
189
190
        return $new;
191
    }
192
193
    /**
194
     * Attach all children recursively
195
     *
196
     * @return void
197
     */
198
    protected function _attachChildren()
199
    {
200
        if (isset($this->_rawData['_children'])) {
201
            foreach ($this->_rawData['_children'] as $child) {
202
                $this->_children[] = new Posting(
203
                    $child,
204
                    ['level' => $this->_level + 1],
205
                    $this->_Thread
206
                );
207
            }
208
        }
209
        unset($this->_rawData['_children']);
210
    }
211
}
212