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\Support\Collection; |
15
|
|
|
use Tinyissue\Extensions\Auth\LoggedUser; |
16
|
|
|
use Tinyissue\Model; |
17
|
|
|
use Tinyissue\Model\ModelAbstract; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Issue is model class for project issues. |
21
|
|
|
* |
22
|
|
|
* @author Mohamed Alsharaf <[email protected]> |
23
|
|
|
* |
24
|
|
|
* @property int $id |
25
|
|
|
* @property int $created_by |
26
|
|
|
* @property int $project_id |
27
|
|
|
* @property string $title |
28
|
|
|
* @property string $body |
29
|
|
|
* @property int $assigned_to |
30
|
|
|
* @property int $time_quote |
31
|
|
|
* @property bool $lock_quote |
32
|
|
|
* @property int $closed_by |
33
|
|
|
* @property int $closed_at |
34
|
|
|
* @property int status |
35
|
|
|
* @property int $updated_at |
36
|
|
|
* @property int $updated_by |
37
|
|
|
* @property Model\Project $project |
38
|
|
|
* @property Model\User $user |
39
|
|
|
* @property Model\User $assigned |
40
|
|
|
* @property Model\User $closers |
41
|
|
|
* @property Model\User $updatedBy |
42
|
|
|
* @property Collection $attachments |
43
|
|
|
* @property Collection $activities |
44
|
|
|
* @property Collection $generalActivities |
45
|
|
|
* @property Collection $commentActivities |
46
|
|
|
* @property Collection $tags |
47
|
|
|
* @property Collection $comments |
48
|
|
|
* @property Collection $messagesQueue |
49
|
|
|
* |
50
|
|
|
* @method $this getStatusTag() |
51
|
|
|
* @method $this getTypeTag() |
52
|
|
|
* @method $this getResolutionTag() |
53
|
|
|
* @method Collection getGeneralActivities() |
54
|
|
|
* @method Collection getCommentActivities() |
55
|
|
|
* @method int countOpenIssues() |
56
|
|
|
* @method int countClosedIssues() |
57
|
|
|
* @method $this open() |
58
|
|
|
* @method $this closed() |
59
|
|
|
* @method $this status($status = Issue::STATUS_OPEN) |
60
|
|
|
* @method $this assignedOrCreated(Model\User $user = null) |
61
|
|
|
* @method $this assignedTo($user = null) |
62
|
|
|
* @method $this createdBy(Model\User $user = null) |
63
|
|
|
* @method $this limitByCreatedForInternalProject(Model\Project $project, Model\User $user = null) |
64
|
|
|
* @method $this forProject($projectId) |
65
|
|
|
* @method $this searchContent($keyword) |
66
|
|
|
* @method $this whereTags(...$tags) |
67
|
|
|
*/ |
68
|
|
|
class Issue extends ModelAbstract |
69
|
|
|
{ |
70
|
|
|
use IssueRelations, |
71
|
|
|
IssueScopes, |
72
|
|
|
LoggedUser; |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Issue status: Open. |
76
|
|
|
* |
77
|
|
|
* @var int |
78
|
|
|
*/ |
79
|
|
|
const STATUS_OPEN = 1; |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Issue status: Closed. |
83
|
|
|
* |
84
|
|
|
* @var int |
85
|
|
|
*/ |
86
|
|
|
const STATUS_CLOSED = 0; |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Timestamp enabled. |
90
|
|
|
* |
91
|
|
|
* @var bool |
92
|
|
|
*/ |
93
|
|
|
public $timestamps = true; |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Name of database table. |
97
|
|
|
* |
98
|
|
|
* @var string |
99
|
|
|
*/ |
100
|
|
|
protected $table = 'projects_issues'; |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* List of allowed columns to be used in $this->fill(). |
104
|
|
|
* |
105
|
|
|
* @var array |
106
|
|
|
*/ |
107
|
|
|
protected $fillable = ['created_by', 'project_id', 'title', 'body', 'assigned_to', 'time_quote', 'lock_quote']; |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Set attributes default value. |
111
|
|
|
* |
112
|
|
|
* @var array |
113
|
|
|
*/ |
114
|
|
|
protected $attributes = [ |
115
|
|
|
'status' => self::STATUS_OPEN, |
116
|
|
|
]; |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @param User|null $user |
120
|
|
|
* |
121
|
|
|
* @return \Tinyissue\Repository\Project\Issue\Updater |
122
|
|
|
*/ |
123
|
|
|
public function updater(User $user = null) |
124
|
|
|
{ |
125
|
|
|
return parent::updater($user); |
|
|
|
|
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Generate a URL for the active project. |
130
|
|
|
* |
131
|
|
|
* @param string $url |
132
|
|
|
* |
133
|
|
|
* @return string |
134
|
|
|
*/ |
135
|
|
|
public function to($url = '') |
136
|
|
|
{ |
137
|
|
|
return \URL::to('project/' . $this->project_id . '/issue/' . $this->id . (($url) ? '/' . $url : '')); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Convert time quote from an array into seconds. |
142
|
|
|
* |
143
|
|
|
* @param array $value |
144
|
|
|
*/ |
145
|
|
|
public function setTimeQuoteAttribute($value) |
146
|
|
|
{ |
147
|
|
|
$seconds = $value; |
148
|
|
|
if (is_array($value)) { |
149
|
|
|
$seconds = 0; |
150
|
|
|
$seconds += isset($value['m']) ? ($value['m'] * 60) : 0; |
151
|
|
|
$seconds += isset($value['h']) ? ($value['h'] * 60 * 60) : 0; |
152
|
|
|
} |
153
|
|
|
$this->attributes['time_quote'] = (int) $seconds; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Returns the color of tag status. |
158
|
|
|
* |
159
|
|
|
* @return string |
160
|
|
|
*/ |
161
|
|
|
public function getTypeColorAttribute() |
162
|
|
|
{ |
163
|
|
|
$tag = $this->tags->filter(function (Model\Tag $tag) { |
164
|
|
|
return $tag->parent->name === 'type'; |
165
|
|
|
})->first(); |
166
|
|
|
|
167
|
|
|
if ($tag) { |
168
|
|
|
return $tag->bgcolor; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
return null; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Whether or not the issue is new. |
176
|
|
|
* |
177
|
|
|
* @return bool |
178
|
|
|
*/ |
179
|
|
|
public function isNew() |
180
|
|
|
{ |
181
|
|
|
if ($this->status === 0) { |
182
|
|
|
return false; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
return $this->tags->count() === 0; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Whether or not the issue is open or closed. |
190
|
|
|
* |
191
|
|
|
* @return bool |
192
|
|
|
*/ |
193
|
|
|
public function isOpen() |
194
|
|
|
{ |
195
|
|
|
return (boolean) $this->status; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* Check if the issue contains a tag with option to set the issue as readonly to current user. |
200
|
|
|
* |
201
|
|
|
* @param Model\User $user |
202
|
|
|
* |
203
|
|
|
* @return bool |
204
|
|
|
*/ |
205
|
|
|
public function hasReadOnlyTag(Model\User $user) |
206
|
|
|
{ |
207
|
|
|
$hasReadOnly = $this->tags->where('readonly', $user->role_id); |
208
|
|
|
|
209
|
|
|
return !$hasReadOnly->isEmpty(); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Whether or not the issue quote is locked by manager. |
214
|
|
|
* |
215
|
|
|
* @return bool |
216
|
|
|
*/ |
217
|
|
|
public function isQuoteLocked() |
218
|
|
|
{ |
219
|
|
|
return (boolean) $this->lock_quote; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Whether or not a user is the creator of the issue. |
224
|
|
|
* |
225
|
|
|
* @param Model\User $user |
226
|
|
|
* |
227
|
|
|
* @return bool |
228
|
|
|
*/ |
229
|
|
|
public function isCreatedBy(Model\User $user) |
230
|
|
|
{ |
231
|
|
|
return $this->created_by === $user->id; |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.