Completed
Push — develop ( fed724...263ba5 )
by Schlaefer
03:00 queued 11s
created

UserPostingTrait   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 155
rs 10
c 0
b 0
f 0
wmc 23
lcom 1
cbo 4

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getCurrentUser() 0 4 1
A setCurrentUser() 0 4 1
A isAnsweringForbidden() 0 9 2
A isBookmarked() 0 4 1
A isEditingAsCurrentUserForbidden() 0 4 1
A isEditingWithRoleUserForbidden() 0 7 1
B _isEditingForbidden() 0 32 10
A isIgnored() 0 4 1
A isUnread() 0 11 2
A hasNewAnswers() 0 15 3
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\UserPosting;
14
15
use Cake\Core\Configure;
16
use Saito\Posting\PostingInterface;
17
use Saito\User\CurrentUser\CurrentUserInterface;
18
19
/**
20
 * Implements UserPostingInterface
21
 */
22
trait UserPostingTrait
23
{
24
    /**
25
     * @var array
26
     */
27
    protected $_cache = [];
28
29
    /**
30
     * @var CurrentUserInterface
31
     */
32
    protected $_CurrentUser;
33
34
    /**
35
     * Get current-user.
36
     *
37
     * @return CurrentUserInterface
38
     */
39
    public function getCurrentUser()
40
    {
41
        return $this->_CurrentUser;
42
    }
43
44
    /**
45
     * Set current user.
46
     *
47
     * @param CurrentUserInterface $CurrentUser  current user
48
     * @return void
49
     */
50
    public function setCurrentUser($CurrentUser)
51
    {
52
        $this->_CurrentUser = $CurrentUser;
53
    }
54
55
    /**
56
     * {@inheritDoc}
57
     */
58
    public function isAnsweringForbidden()
59
    {
60
        if ($this->isLocked()) {
0 ignored issues
show
Bug introduced by
It seems like isLocked() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
61
            return 'locked';
62
        }
63
        $permission = $this->_CurrentUser->getCategories()->permission('answer', $this->get('category'));
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
64
65
        return !$permission;
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71
    public function isBookmarked(): bool
72
    {
73
        return $this->_CurrentUser->hasBookmarked($this->get('id'));
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79
    public function isEditingAsCurrentUserForbidden()
80
    {
81
        return $this->_isEditingForbidden($this, $this->_CurrentUser);
82
    }
83
84
    /**
85
     * {@inheritDoc}
86
     */
87
    public function isEditingWithRoleUserForbidden()
88
    {
89
        $MockedUser = clone $this->_CurrentUser;
90
        $MockedUser->set('user_type', 'user');
91
92
        return $this->_isEditingForbidden($this, $MockedUser);
93
    }
94
95
    /**
96
     * Check if editing on the posting is forbidden.
97
     *
98
     * @param PostingInterface $posting The posting.
99
     * @param CurrentUserInterface $User The user.
100
     * @return bool|string string if a reason is available.
101
     */
102
    protected function _isEditingForbidden(PostingInterface $posting, CurrentUserInterface $User)
103
    {
104
        if ($User->isLoggedIn() !== true) {
105
            return true;
106
        } elseif ($User->permission('saito.core.posting.edit.unrestricted')) {
107
            return false;
108
        }
109
110
        $editPeriod = Configure::read('Saito.Settings.edit_period') * 60;
111
        $timeLimit = $editPeriod + ($posting->get('time')->format('U'));
112
        $isOverTime = time() > $timeLimit;
113
114
        $isOwn = $User->getId() === $posting->get('user_id');
115
116
        if ($User->permission('saito.core.posting.edit.restricted')) {
117
            if ($isOwn && $isOverTime && !$posting->isPinned()) {
118
                return 'time';
119
            } else {
120
                return false;
121
            }
122
        }
123
124
        if (!$isOwn) {
125
            return 'user';
126
        } elseif ($isOverTime) {
127
            return 'time';
128
        } elseif ($this->isLocked()) {
0 ignored issues
show
Bug introduced by
It seems like isLocked() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
129
            return 'locked';
130
        }
131
132
        return false;
133
    }
134
135
    /**
136
     * {@inheritDoc}
137
     */
138
    public function isIgnored(): bool
139
    {
140
        return $this->_CurrentUser->ignores($this->get('user_id'));
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146
    public function isUnread(): bool
147
    {
148
        if (!isset($this->_cache['isUnread'])) {
149
            $id = $this->get('id');
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
150
            $time = $this->get('time');
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
151
            $this->_cache['isUnread'] = !$this->getCurrentUser()
152
                ->getReadPostings()->isRead($id, $time);
153
        }
154
155
        return $this->_cache['isUnread'];
156
    }
157
158
    /**
159
     * {@inheritDoc}
160
     */
161
    public function hasNewAnswers(): bool
162
    {
163
        if (!$this->isRoot()) {
0 ignored issues
show
Bug introduced by
It seems like isRoot() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
164
            throw new \RuntimeException(
165
                'Posting with id ' . $this->get('id') . ' is no root posting.'
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
166
            );
167
        }
168
        if (!$this->_CurrentUser->get('last_refresh')) {
169
            return false;
170
        }
171
172
        return $this->_CurrentUser->get('last_refresh_unix') < strtotime(
173
            $this->get('last_answer')
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
174
        );
175
    }
176
}
177