Reservation::getUniqueNumber()   A
last analyzed

Complexity

Conditions 6
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 9
cts 9
cp 1
rs 9.0444
c 0
b 0
f 0
cc 6
nc 3
nop 0
crap 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|nullable',
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 12
    public function beforeCreate()
59
    {
60 12
        $this->hash = $this->getUniqueHash();
61 12
        $this->number = $this->getUniqueNumber();
62
63 12
        $this->locale = App::getLocale();
64
65 12
        $this->ip = Request::server('REMOTE_ADDR');
66 12
        $this->ip_forwarded = Request::server('HTTP_X_FORWARDED_FOR');
67 12
        $this->user_agent = Request::server('HTTP_USER_AGENT');
68
69 12
        if ($this->status === null) {
70 5
            $this->status = $this->getDefaultStatus();
71
        }
72 12
    }
73
74
    /**
75
     * If reservation is cancelled.
76
     *
77
     * @param string $statusIdent
78
     *
79
     * @return bool
80
     */
81 4
    public function isCancelled($statusIdent = null)
82
    {
83 4
        if ($statusIdent === null) {
84 1
            $statusIdent = $this->status->ident;
85
        }
86 4
        $cancelledStatuses = Config::get('vojtasvoboda.reservations::config.statuses.cancelled', ['cancelled']);
87
88 4
        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 12
    public function scopeNotCancelled($query)
99
    {
100 12
        $cancelledStatuses = Config::get('vojtasvoboda.reservations::config.statuses.cancelled', ['cancelled']);
101
102 12
        return $query->whereHas('status', function($query) use ($cancelledStatuses) {
103 12
            $query->whereNotIn('ident', $cancelledStatuses);
104 12
        });
105
    }
106
107
    /**
108
     * Scope for getting current date reservations.
109
     *
110
     * @param $query
111
     *
112
     * @return mixed
113
     */
114 1
    public function scopeCurrentDate($query)
115
    {
116 1
        return $query->where('date', '>', Carbon::now()->format('Y-m-d H:i:s'));
117
    }
118
119
    /**
120
     * Set machine scope
121
     *
122
     * @param $query
123
     *
124
     * @return mixed
125
     */
126 10
    public function scopeMachine($query)
127
    {
128 10
        $ip_addr = Request::server('REMOTE_ADDR');
129 10
        $ip_forwarded = Request::server('HTTP_X_FORWARDED_FOR');
130 10
        $user_agent = Request::server('HTTP_USER_AGENT');
131
132 10
        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 5
    public function getDefaultStatus()
141
    {
142 5
        $statusIdent = Config::get('vojtasvoboda.reservations::config.statuses.received', 'received');
143
144 5
        return Status::where('ident', $statusIdent)->first();
145
    }
146
147
    /**
148
     * Generate unique hash for each reservation.
149
     *
150
     * @return string|null
151
     */
152 14
    public function getUniqueHash()
153
    {
154 14
        $length = Config::get('vojtasvoboda.reservations::config.hash', 32);
155 14
        if ($length == 0) {
156 1
            return null;
157
        }
158
159 13
        return substr(md5('reservations-' . Str::random($length)), 0, $length);
160
    }
161
162
    /**
163
     * Generate unique number for each reservation. With this hash you can reference
164
     * concrete reservation instead of using internal Reservation ID.
165
     *
166
     * @return string|null
167
     */
168 14
    public function getUniqueNumber()
169
    {
170
    	// init
171 14
        $min = Config::get('vojtasvoboda.reservations::config.number.min', 123456);
172 14
        $max = Config::get('vojtasvoboda.reservations::config.number.max', 999999);
173 14
        if ($min == 0 || $max == 0) {
174 1
            return null;
175
        }
176
177
        // generate random number
178 13
        $count = 0;
179
        do {
180 13
            $number = mt_rand($min, $max);
181
182 13
        } while ((self::where('number', $number)->count() > 0) && (++$count < 1000));
183
184 13
        return $count >= 1000 ? null : $number;
185
    }
186
}
187