Passed
Pull Request — master (#13)
by Vojta
09:53 queued 03:21
created

Reservation   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 95.24%

Importance

Changes 0
Metric Value
wmc 17
c 0
b 0
f 0
lcom 1
cbo 1
dl 0
loc 161
ccs 40
cts 42
cp 0.9524
rs 10

9 Methods

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