Completed
Push — develop ( 335c93...e4583a )
by Mohamed
12:58
created

Project::setDefaultAssigneeAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
crap 2
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;
13
14
use Illuminate\Database\Eloquent\Model;
15
use URL;
16
17
/**
18
 * Project is model class for projects.
19
 *
20
 * @author Mohamed Alsharaf <[email protected]>
21
 *
22
 * @property int              $id
23
 * @property string           $name
24
 * @property int              $status
25
 * @property int              $default_assignee
26
 * @property int              $private
27
 * @property Project\Issue[]  $issues
28
 * @property int              $openIssuesCount
29
 * @property int              $closedIssuesCount
30
 */
31
class Project extends Model
32
{
33
    use Traits\CountAttributeTrait,
34
        Traits\Project\CountTrait,
35
        Traits\Project\FilterTrait,
36
        Traits\Project\SortTrait,
37
        Traits\Project\RelationTrait,
38
        Traits\Project\CrudTrait,
39
        Traits\Project\QueryTrait;
40
41
    /**
42
     * Project private & user role can see their own issues only.
43
     *
44
     * @var int
45
     */
46
    const INTERNAL_YES = 2;
47
48
    /**
49
     * Project not public to view and create issue.
50
     *
51
     * @var int
52
     */
53
    const PRIVATE_YES = 1;
54
55
    /**
56
     * Project public to view and create issue.
57
     *
58
     * @var int
59
     */
60
    const PRIVATE_NO = 0;
61
62
    /**
63
     * All projects.
64
     *
65
     * @var int
66
     */
67
    const PRIVATE_ALL = -1;
68
69
    /**
70
     * Project status Open.
71
     *
72
     * @var int
73
     */
74
    const STATUS_OPEN = 1;
75
76
    /**
77
     * Project status Archived.
78
     *
79
     * @var int
80
     */
81
    const STATUS_ARCHIVED = 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';
96
97
    /**
98
     * List of allowed columns to be used in $this->fill().
99
     *
100
     * @var array
101
     */
102
    protected $fillable = ['name', 'default_assignee', 'status', 'private'];
103
104
    /**
105
     * List of HTML classes for each status.
106
     *
107
     * @var array
108
     */
109
    protected $attrClassNames = [
110
        self::PRIVATE_NO   => 'note',
111
        self::PRIVATE_YES  => 'info',
112
        self::INTERNAL_YES => 'primary',
113
    ];
114
115
    /**
116
     * List of statuses names.
117
     *
118
     * @var array
119
     */
120
    protected $statusesNames = [
121
        self::PRIVATE_NO   => 'public',
122
        self::PRIVATE_YES  => 'private',
123
        self::INTERNAL_YES => 'internal',
124
    ];
125
126
    /**
127
     * Generate a URL for the active project.
128
     *
129
     * @param string $url
130
     *
131
     * @return string
132
     */
133 38
    public function to($url = '')
134
    {
135 38
        return URL::to('project/' . $this->id . (($url) ? '/' . $url : ''));
136
    }
137
138
    /**
139
     * Returns the aggregate value of number of open issues in the project.
140
     *
141
     * @return int
142
     */
143 4
    public function getOpenIssuesCountAttribute()
144
    {
145 4
        return $this->getCountAttribute('openIssuesCount');
146
    }
147
148
    /**
149
     * Returns the aggregate value of number of closed issues in the project.
150
     *
151
     * @return int
152
     */
153 1
    public function getClosedIssuesCountAttribute()
154
    {
155 1
        return $this->getCountAttribute('closedIssuesCount');
156
    }
157
158
    /**
159
     * Set default assignee attribute.
160
     *
161
     * @param int $value
162
     *
163
     * @return $this
164
     */
165 50
    public function setDefaultAssigneeAttribute($value)
166
    {
167 50
        if (!empty($value)) {
168 30
            $this->attributes['default_assignee'] = (int) $value;
169
        }
170
171 50
        return $this;
172
    }
173
174
    /**
175
     * Returns the aggregate value of number of issues in the project.
176
     *
177
     * @return int
178
     */
179
    public function getIssuesCountAttribute()
180
    {
181
        return $this->getCountAttribute('issuesCount');
182
    }
183
184
    /**
185
     * Get total issues total quote time.
186
     *
187
     * @return int
188
     */
189 3
    public function getTotalQuote()
190
    {
191 3
        $total = 0;
192 3
        foreach ($this->issues as $issue) {
193 3
            $total += $issue->time_quote;
194
        }
195
196 3
        return $total;
197
    }
198
199
    /**
200
     * Calculate the progress (open & closed issues).
201
     *
202
     * @return float|int
203
     */
204 1
    public function getProgress()
205
    {
206 1
        $total       = $this->openIssuesCount + $this->closedIssuesCount;
207 1
        $progress    = 100;
208 1
        if ($total > 0) {
209 1
            $progress = (float) ($this->closedIssuesCount / $total) * 100;
210
        }
211 1
        $progressInt = (int) $progress;
212 1
        if ($progressInt > 0) {
213 1
            $progress = number_format($progress, 2);
214 1
            $fraction = $progress - $progressInt;
215 1
            if ($fraction === 0.0) {
216 1
                $progress = $progressInt;
217
            }
218
        }
219
220 1
        return $progress;
221
    }
222
223
    /**
224
     * Whether or not a user is member of the project.
225
     *
226
     * @param int $userId
227
     *
228
     * @return bool
229
     */
230 8
    public function isMember($userId)
231
    {
232 8
        return $this->user($userId)->count() > 0;
233
    }
234
235
    /**
236
     * Whether or not the project is private.
237
     *
238
     * @return bool
239
     */
240 2
    public function isPrivate()
241
    {
242 2
        return (int) $this->private === self::PRIVATE_YES;
243
    }
244
245
    /**
246
     * Whether or not the project is public.
247
     *
248
     * @return bool
249
     */
250 3
    public function isPublic()
251
    {
252 3
        return (int) $this->private === self::PRIVATE_NO;
253
    }
254
255
    /**
256
     * Whether or not the project is private internal.
257
     *
258
     * @return bool
259
     */
260 24
    public function isPrivateInternal()
261
    {
262 24
        return (int) $this->private === self::INTERNAL_YES;
263
    }
264
265
    /**
266
     * Returns project status as string name.
267
     *
268
     * @return string
269
     */
270 1
    public function getStatusAsName()
271
    {
272 1
        if (array_key_exists((int) $this->private, $this->statusesNames)) {
273 1
            return $this->statusesNames[(int) $this->private];
274
        }
275
276
        return '';
277
    }
278
279
    /**
280
     * Returns the class name to be used for project status.
281
     *
282
     * @return string
283
     */
284 1
    public function getStatusClass()
285
    {
286 1
        if (array_key_exists((int) $this->private, $this->attrClassNames)) {
287 1
            return $this->attrClassNames[(int) $this->private];
288
        }
289
290
        return '';
291
    }
292
293
    /**
294
     * Whether or not a user can access the project.
295
     *
296
     * @param User $user
297
     *
298
     * @return bool
299
     */
300 3
    public function canView(User $user)
301
    {
302
        // Is member of the project
303
        if (
304 3
            ($this->isPublic() && app('tinyissue.settings')->isPublicProjectsEnabled()) ||
305 3
            $this->isMember($user->id)
306
        ) {
307
            return true;
308
        }
309
310 3
        return false;
311
    }
312
}
313