Project::isPublic()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

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.

Loading history...
341
    {
342
        $editPermissions = [
343 4
            Permission::PERM_PROJECT_CREATE,
344 4
            Permission::PERM_PROJECT_MODIFY,
345
        ];
346
347 4
        if (in_array($permission, $editPermissions)) {
348 1
            return $this->canEdit($user);
349
        }
350
351 3
        return $this->canView($user);
352
    }
353
}
354