Completed
Push — master ( 707c53...e025a0 )
by Vojta
06:37
created

Reservation::getUniqueNumber()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 18
ccs 9
cts 9
cp 1
rs 8.8571
cc 6
eloc 10
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' => 'required|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' => 'Date :reservation is 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
     * Set machine scope
109
     *
110
     * @param $query
111
     *
112
     * @return mixed
113
     */
114 7
    public function scopeMachine($query)
115
    {
116 7
        $ip_addr = Request::server('REMOTE_ADDR');
117 7
        $ip_forwarded = Request::server('HTTP_X_FORWARDED_FOR');
118 7
        $user_agent = Request::server('HTTP_USER_AGENT');
119
120 7
        return $query->whereIp($ip_addr)->whereIpForwarded($ip_forwarded)->whereUserAgent($user_agent);
121
    }
122
123
    /**
124
     * Get default reservation status.
125
     *
126
     * @return Status
127
     */
128 5
    public function getDefaultStatus()
129
    {
130 5
        $statusIdent = Config::get('vojtasvoboda.reservations::config.statuses.received', 'received');
131
132 5
        return Status::where('ident', $statusIdent)->first();
133
    }
134
135
    /**
136
     * Generate unique hash for each reservation.
137
     *
138
     * @return string|null
139
     */
140 13
    public function getUniqueHash()
141
    {
142 13
        $length = Config::get('vojtasvoboda.reservations::config.hash', 32);
143 13
        if ($length == 0) {
144 1
            return null;
145
        }
146
147 12
        return substr(md5('reservations-' . Str::random($length)), 0, $length);
148
    }
149
150
    /**
151
     * Generate unique number for each reservation. With this hash you can reference
152
     * concrete reservation instead of using internal Reservation ID.
153
     *
154
     * @return string|null
155
     */
156 13
    public function getUniqueNumber()
157
    {
158
    	// init
159 13
        $min = Config::get('vojtasvoboda.reservations::config.number.min', 123456);
160 13
        $max = Config::get('vojtasvoboda.reservations::config.number.max', 999999);
161 13
        if ($min == 0 || $max == 0) {
162 1
            return null;
163
        }
164
165
        // generate random number
166 12
        $count = 0;
167
        do {
168 12
            $number = mt_rand($min, $max);
169
170 12
        } while ((self::where('number', $number)->count() > 0) && (++$count < 1000));
171
172 12
        return $count >= 1000 ? null : $number;
173
    }
174
}
175