This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the Tinyissue package. |
||
5 | * |
||
6 | * (c) Mohamed Alsharaf <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Tinyissue\Model\Project; |
||
13 | |||
14 | use Illuminate\Database\Eloquent\Model as BaseModel; |
||
15 | use Illuminate\Support\Collection; |
||
16 | use Tinyissue\Contracts\Model\AccessControl; |
||
17 | use Tinyissue\Extensions\Auth\LoggedUser; |
||
18 | use Tinyissue\Model; |
||
19 | use Tinyissue\Model\Traits\CountAttributeTrait; |
||
20 | use Tinyissue\Model\Traits\Project\Issue\CountTrait; |
||
21 | use Tinyissue\Model\Traits\Project\Issue\CrudTagTrait; |
||
22 | use Tinyissue\Model\Traits\Project\Issue\CrudTrait; |
||
23 | use Tinyissue\Model\Traits\Project\Issue\QueryTrait; |
||
24 | use Tinyissue\Model\Traits\Project\Issue\QueueTrait; |
||
25 | use Tinyissue\Model\Traits\Project\Issue\RelationTrait; |
||
26 | |||
27 | /** |
||
28 | * Issue is model class for project issues. |
||
29 | * |
||
30 | * @author Mohamed Alsharaf <[email protected]> |
||
31 | * |
||
32 | * @property int $id |
||
33 | * @property int $created_by |
||
34 | * @property int $project_id |
||
35 | * @property string $title |
||
36 | * @property string $body |
||
37 | * @property int $assigned_to |
||
38 | * @property int $time_quote |
||
39 | * @property bool $lock_quote |
||
40 | * @property int $closed_by |
||
41 | * @property int $closed_at |
||
42 | * @property int status |
||
43 | * @property int $updated_at |
||
44 | * @property int $updated_by |
||
45 | * @property Model\Project $project |
||
46 | * @property Model\User $user |
||
47 | * @property Model\User $assigned |
||
48 | * @property Model\User $closers |
||
49 | * @property Model\User $updatedBy |
||
50 | * @property Collection $attachments |
||
51 | * @property Collection $activities |
||
52 | * @property Collection $generalActivities |
||
53 | * @property Collection $commentActivities |
||
54 | * @property Collection $tags |
||
55 | * @property Collection $comments |
||
56 | * @property Collection $messagesQueue |
||
57 | */ |
||
58 | class Issue extends BaseModel implements AccessControl |
||
59 | { |
||
60 | use CountAttributeTrait, |
||
61 | CountTrait, |
||
62 | CrudTrait, |
||
63 | CrudTagTrait, |
||
64 | RelationTrait, |
||
65 | QueryTrait, |
||
66 | QueueTrait, |
||
67 | LoggedUser; |
||
68 | |||
69 | /** |
||
70 | * Issue status: Open. |
||
71 | * |
||
72 | * @var int |
||
73 | */ |
||
74 | const STATUS_OPEN = 1; |
||
75 | |||
76 | /** |
||
77 | * Issue status: Closed. |
||
78 | * |
||
79 | * @var int |
||
80 | */ |
||
81 | const STATUS_CLOSED = 0; |
||
82 | |||
83 | /** |
||
84 | * Timestamp enabled. |
||
85 | * |
||
86 | * @var bool |
||
87 | */ |
||
88 | public $timestamps = true; |
||
89 | |||
90 | /** |
||
91 | * Name of database table. |
||
92 | * |
||
93 | * @var string |
||
94 | */ |
||
95 | protected $table = 'projects_issues'; |
||
96 | |||
97 | /** |
||
98 | * List of allowed columns to be used in $this->fill(). |
||
99 | * |
||
100 | * @var array |
||
101 | */ |
||
102 | protected $fillable = ['created_by', 'project_id', 'title', 'body', 'assigned_to', 'time_quote', 'lock_quote']; |
||
103 | |||
104 | /** |
||
105 | * Set attributes default value. |
||
106 | * |
||
107 | * @var array |
||
108 | */ |
||
109 | protected $attributes = [ |
||
110 | 'status' => self::STATUS_OPEN, |
||
111 | ]; |
||
112 | |||
113 | /** |
||
114 | * Returns the aggregate value of number of comments in an issue. |
||
115 | * |
||
116 | * @return int |
||
117 | */ |
||
118 | 6 | public function getCountCommentsAttribute() |
|
119 | { |
||
120 | 6 | return $this->getCountAttribute('countComments'); |
|
121 | } |
||
122 | |||
123 | /** |
||
124 | * Generate a URL for the active project. |
||
125 | * |
||
126 | * @param string $url |
||
127 | * |
||
128 | * @return string |
||
129 | */ |
||
130 | 30 | public function to($url = '') |
|
131 | { |
||
132 | 30 | return \URL::to('project/' . $this->project_id . '/issue/' . $this->id . (($url) ? '/' . $url : '')); |
|
133 | } |
||
134 | |||
135 | /** |
||
136 | * Convert time quote from an array into seconds. |
||
137 | * |
||
138 | * @param array $value |
||
139 | */ |
||
140 | 36 | public function setTimeQuoteAttribute($value) |
|
141 | { |
||
142 | 36 | $seconds = $value; |
|
143 | 36 | if (is_array($value)) { |
|
144 | 35 | $seconds = 0; |
|
145 | 35 | $seconds += isset($value['m']) ? ($value['m'] * 60) : 0; |
|
146 | 35 | $seconds += isset($value['h']) ? ($value['h'] * 60 * 60) : 0; |
|
147 | } |
||
148 | 36 | $this->attributes['time_quote'] = (int) $seconds; |
|
149 | 36 | } |
|
150 | |||
151 | /** |
||
152 | * Returns the color of tag status. |
||
153 | * |
||
154 | * @return string |
||
155 | */ |
||
156 | public function getTypeColorAttribute() |
||
157 | { |
||
158 | 1 | $tag = $this->tags->filter(function (Model\Tag $tag) { |
|
159 | 1 | return $tag->parent->name === 'type'; |
|
160 | 1 | })->first(); |
|
161 | |||
162 | 1 | if ($tag) { |
|
163 | return $tag->bgcolor; |
||
164 | } |
||
165 | |||
166 | 1 | return null; |
|
167 | } |
||
168 | |||
169 | /** |
||
170 | * Whether or not the issue is new. |
||
171 | * |
||
172 | * @return bool |
||
173 | */ |
||
174 | public function isNew() |
||
175 | { |
||
176 | if ($this->status === 0) { |
||
177 | return false; |
||
178 | } |
||
179 | |||
180 | return $this->tags->count() === 0; |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Whether or not the issue is open or closed. |
||
185 | * |
||
186 | * @return bool |
||
187 | */ |
||
188 | 27 | public function isOpen() |
|
189 | { |
||
190 | 27 | return (boolean) $this->status; |
|
191 | } |
||
192 | |||
193 | /** |
||
194 | * Check if the issue contains a tag with option to set the issue as readonly to current user. |
||
195 | * |
||
196 | * @param Model\User $user |
||
197 | * |
||
198 | * @return bool |
||
199 | */ |
||
200 | 14 | public function hasReadOnlyTag(Model\User $user) |
|
201 | { |
||
202 | 14 | $hasReadOnly = $this->tags->where('readonly', $user->role_id, false); |
|
203 | |||
204 | 14 | return !$hasReadOnly->isEmpty(); |
|
205 | } |
||
206 | |||
207 | /** |
||
208 | * Whether or not the issue quote is locked by manager. |
||
209 | * |
||
210 | * @return bool |
||
211 | */ |
||
212 | 11 | public function isQuoteLocked() |
|
213 | { |
||
214 | 11 | return (boolean) $this->lock_quote; |
|
215 | } |
||
216 | |||
217 | /** |
||
218 | * Check if a user is allowed to see the issue quote. |
||
219 | * |
||
220 | * @param Model\User $user |
||
221 | * |
||
222 | * @return bool |
||
223 | */ |
||
224 | 23 | public function canUserViewQuote(Model\User $user = null) |
|
225 | { |
||
226 | 23 | if ($user && $this->time_quote > 0 && |
|
227 | 23 | (!$this->isQuoteLocked() || $user->permission(Model\Permission::PERM_ISSUE_VIEW_LOCKED_QUOTE)) |
|
228 | ) { |
||
229 | 5 | return true; |
|
230 | } |
||
231 | |||
232 | 23 | return false; |
|
233 | } |
||
234 | |||
235 | /** |
||
236 | * Whether or not a user is the creator of the issue. |
||
237 | * |
||
238 | * @param Model\User $user |
||
239 | * |
||
240 | * @return bool |
||
241 | */ |
||
242 | 17 | public function isCreatedBy(Model\User $user) |
|
243 | { |
||
244 | 17 | return $this->created_by === $user->id; |
|
245 | } |
||
246 | |||
247 | /** |
||
248 | * Whether a user can view the issue. |
||
249 | * |
||
250 | * @param Model\User $user |
||
251 | * |
||
252 | * @return bool |
||
253 | */ |
||
254 | 9 | public function canView(Model\User $user) |
|
255 | { |
||
256 | // not access if issue limited to developers and managers, or user is not member of the project |
||
257 | if ( |
||
258 | 9 | ($this->project->isPrivateInternal() && $user->isUser() && !$this->isCreatedBy($user)) || |
|
259 | 9 | !$this->project->isMember($user->id) |
|
260 | ) { |
||
261 | 2 | return false; |
|
262 | } |
||
263 | |||
264 | 9 | return true; |
|
265 | } |
||
266 | |||
267 | /** |
||
268 | * Whether a user can edit the issue. |
||
269 | * |
||
270 | * @param Model\User $user |
||
271 | * |
||
272 | * @return bool |
||
273 | */ |
||
274 | 17 | public function canEdit(Model\User $user) |
|
275 | { |
||
276 | // If you have permission to modify issue or a creator and current tag is not read only. |
||
277 | 17 | return ($this->isCreatedBy($user) && !$this->hasReadOnlyTag($user)) || ($this->canView($user) && $user->permission(Model\Permission::PERM_ISSUE_MODIFY)); |
|
278 | } |
||
279 | |||
280 | /** |
||
281 | * @param string $permission |
||
282 | * @param Model\User $user |
||
283 | * |
||
284 | * @return bool |
||
285 | */ |
||
286 | 9 | View Code Duplication | public function can($permission, Model\User $user) |
0 ignored issues
–
show
|
|||
287 | { |
||
288 | $editPermissions = [ |
||
289 | 9 | Model\Permission::PERM_ISSUE_COMMENT, |
|
290 | 9 | Model\Permission::PERM_ISSUE_MODIFY, |
|
291 | 9 | Model\Permission::PERM_ISSUE_LOCK_QUOTE, |
|
292 | ]; |
||
293 | |||
294 | 9 | if (in_array($permission, $editPermissions)) { |
|
295 | 4 | return $this->canEdit($user); |
|
296 | } |
||
297 | |||
298 | 8 | return $this->canView($user); |
|
299 | } |
||
300 | } |
||
301 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.