Passed
Pull Request — master (#20)
by
unknown
07:25
created

Reservation   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 16
c 3
b 0
f 0
lcom 1
cbo 0
dl 0
loc 169
ccs 42
cts 42
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A beforeCreate() 0 15 2
A isCancelled() 0 9 2
A scopeNotCancelled() 0 8 1
A scopeCurrentDate() 0 4 1
A scopeMachine() 0 8 1
A getDefaultStatus() 0 6 1
A getUniqueHash() 0 9 2
B getUniqueNumber() 0 18 6
1
<?php namespace VojtaSvoboda\Reservations\Models;
2
3
use App;
4
use Carbon\Carbon;
5
use Config;
6
use Model;
7
use October\Rain\Database\Traits\SoftDelete as SoftDeleteTrait;
8
use October\Rain\Database\Traits\Validation as ValidationTrait;
9
use October\Rain\Exception\ApplicationException;
10
use Request;
11
use Str;
12
13
/**
14
 * Reservation class.
15
 *
16
 * @package VojtaSvoboda\Reservations\Models
17
 */
18
class Reservation extends Model
19
{
20
    use SoftDeleteTrait;
21
22
    use ValidationTrait;
23
24
    /** @var string $table The database table used by the model */
25
    public $table = 'vojtasvoboda_reservations_reservations';
26
27
    /** @var array Rules */
28
    public $rules = [
29
        'date' => 'required|date|reservation',
30
        'locale' => 'max:20',
31
        'email' => 'required|email',
32
        'name' => 'required|max:300',
33
        'street' => 'max:300',
34
        'town' => 'max:300',
35
        'zip' => 'numeric',
36
        'phone' => 'required|max:300',
37
        'message' => 'required|max:3000',
38
    ];
39
40
    public $customMessages = [
41
        'reservation' => 'vojtasvoboda.reservations::lang.errors.already_booked',
42
    ];
43
44
    public $fillable = [
45
        'status', 'date', 'locale', 'email', 'name', 'lastname',
46
        'street', 'town', 'zip', 'phone', 'message',
47
    ];
48
49
    public $dates = ['date', 'created_at', 'updated_at', 'deleted_at'];
50
51
    public $belongsTo = [
52
        'status' => 'VojtaSvoboda\Reservations\Models\Status',
53
    ];
54
55
    /**
56
     * Before create reservation.
57
     */
58 11
    public function beforeCreate()
59
    {
60 11
        $this->hash = $this->getUniqueHash();
61 11
        $this->number = $this->getUniqueNumber();
62
63 11
        $this->locale = App::getLocale();
64
65 11
        $this->ip = Request::server('REMOTE_ADDR');
66 11
        $this->ip_forwarded = Request::server('HTTP_X_FORWARDED_FOR');
67 11
        $this->user_agent = Request::server('HTTP_USER_AGENT');
68
69 11
        if ($this->status === null) {
70 5
            $this->status = $this->getDefaultStatus();
71
        }
72 11
    }
73
74
    /**
75
     * If reservation is cancelled.
76
     *
77
     * @param string $statusIdent
78
     *
79
     * @return bool
80
     */
81 3
    public function isCancelled($statusIdent = null)
82
    {
83 3
        if ($statusIdent === null) {
84 1
            $statusIdent = $this->status->ident;
85
        }
86 3
        $cancelledStatuses = Config::get('vojtasvoboda.reservations::config.statuses.cancelled', ['cancelled']);
87
88 3
        return in_array($statusIdent, $cancelledStatuses);
89
    }
90
91
    /**
92
     * Scope for getting non cancelled reservations.
93
     *
94
     * @param $query
95
     *
96
     * @return mixed
97
     */
98 11
    public function scopeNotCancelled($query)
99
    {
100 11
        $cancelledStatuses = Config::get('vojtasvoboda.reservations::config.statuses.cancelled', ['cancelled']);
101
102 11
        return $query->whereHas('status', function($query) use ($cancelledStatuses) {
103 11
            $query->whereNotIn('ident', $cancelledStatuses);
104 11
        });
105
    }
106
107
    /**
108
     * Scope for getting current date reservations.
109
     *
110
     * @param $query
111
     *
112
     * @return mixed
113
     */
114 7
    public function scopeCurrentDate($query)
115
    {
116 7
        return $query->where('date', '>', Carbon::now()->format('Y-m-d H:i:s'));
117 7
    }
118 7
119
    /**
120 7
     * Set machine scope
121
     *
122
     * @param $query
123
     *
124
     * @return mixed
125
     */
126
    public function scopeMachine($query)
127
    {
128 5
        $ip_addr = Request::server('REMOTE_ADDR');
129
        $ip_forwarded = Request::server('HTTP_X_FORWARDED_FOR');
130 5
        $user_agent = Request::server('HTTP_USER_AGENT');
131
132 5
        return $query->whereIp($ip_addr)->whereIpForwarded($ip_forwarded)->whereUserAgent($user_agent);
133
    }
134
135
    /**
136
     * Get default reservation status.
137
     *
138
     * @return Status
139
     */
140 13
    public function getDefaultStatus()
141
    {
142 13
        $statusIdent = Config::get('vojtasvoboda.reservations::config.statuses.received', 'received');
143 13
144 1
        return Status::where('ident', $statusIdent)->first();
145
    }
146
147 12
    /**
148
     * Generate unique hash for each reservation.
149
     *
150
     * @return string|null
151
     */
152
    public function getUniqueHash()
153
    {
154
        $length = Config::get('vojtasvoboda.reservations::config.hash', 32);
155
        if ($length == 0) {
156 13
            return null;
157
        }
158
159 13
        return substr(md5('reservations-' . Str::random($length)), 0, $length);
160 13
    }
161 13
162 1
    /**
163
     * Generate unique number for each reservation. With this hash you can reference
164
     * concrete reservation instead of using internal Reservation ID.
165
     *
166 12
     * @return string|null
167
     */
168 12
    public function getUniqueNumber()
169
    {
170 12
    	// init
171
        $min = Config::get('vojtasvoboda.reservations::config.number.min', 123456);
172 12
        $max = Config::get('vojtasvoboda.reservations::config.number.max', 999999);
173
        if ($min == 0 || $max == 0) {
174
            return null;
175
        }
176
177
        // generate random number
178
        $count = 0;
179
        do {
180
            $number = mt_rand($min, $max);
181
182
        } while ((self::where('number', $number)->count() > 0) && (++$count < 1000));
183
184
        return $count >= 1000 ? null : $number;
185
    }
186
}
187