Hook::scopeFindByTokenAndMethod()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 5
nc 1
nop 3
1
<?php namespace Bedard\Webhooks\Models;
2
3
use DB;
4
use Model;
5
use Queue;
6
use Backend;
7
use Carbon\Carbon;
8
use Bedard\Webhooks\Models\Log;
9
use Bedard\Webhooks\Exceptions\ScriptDisabledException;
10
11
/**
12
 * Hook Model
13
 */
14
class Hook extends Model
15
{
16
17
    /**
18
     * @var string The database table used by the model.
19
     */
20
    public $table = 'bedard_webhooks_hooks';
21
22
    /**
23
     * @var array Guarded fields
24
     */
25
    protected $guarded = ['*'];
26
27
    /**
28
     * @var array Fillable fields
29
     */
30
    protected $fillable = [
31
        'name',
32
        'script',
33
        'http_method',
34
        'is_enabled',
35
    ];
36
37
    /**
38
     * @var array Attribute casting
39
     */
40
    protected $casts = [
41
        'is_enabled' => 'boolean',
42
    ];
43
44
    /**
45
     * @var array Datetime fields
46
     */
47
    protected $dates = [
48
        'created_at',
49
        'updated_at',
50
        'executed_at',
51
    ];
52
53
    /**
54
     * @var array Relations
55
     */
56
    public $hasMany = [
57
        'logs' => [
58
            'Bedard\Webhooks\Models\Log',
59
        ],
60
    ];
61
62
    /**
63
     * Generate a unique token
64
     *
65
     * @return void
66
     */
67
    public function beforeCreate()
68
    {
69
        do {
70
            $this->token = str_random(40);
71
        } while (self::where('token', $this->token)->exists());
72
    }
73
74
    /**
75
     * Execute the script and log the output
76
     *
77
     * @return boolean
78
     */
79
    public function queueScript()
80
    {
81
        $id = $this->id;
82
        Queue::push(function() use ($id) { Hook::findAndExecuteScript($id); });
83
    }
84
85
    /**
86
     * Execute the shell script and log the output
87
     *
88
     * @return string
89
     */
90
    public function executeScript()
91
    {
92
        // Make sure the script is enabled
93
        if (!$this->is_enabled) {
94
            throw new ScriptDisabledException();
95
        }
96
97
        // Run the script and log the output
98
        $output = shell_exec($this->script);
99
        Log::create(['hook_id' => $this->id, 'output' => $output]);
100
101
        // Update our executed_at timestamp
102
        $this->executed_at = Carbon::now();
103
        $this->save();
104
    }
105
106
    /**
107
     * Returns the script with normalized line endings
108
     *
109
     * @return void
110
     */
111
    public function getScriptAttribute($script)
112
    {
113
        return preg_replace('/\r\n?/', PHP_EOL, $script);
114
    }
115
116
    /**
117
     * Find a hook by token and HTTP method
118
     *
119
     * @param  \October\Rain\Database\Builder   $query
120
     * @param  string                           $token
121
     * @param  string                           $httpMethod
122
     * @return \October\Rain\Database\Builder
123
     */
124
    public function scopeFindByTokenAndMethod($query, $token, $httpMethod) {
125
        return $query->whereIsEnabled(true)
126
            ->whereHttpMethod($httpMethod)
127
            ->whereToken($token)
128
            ->firstOrFail();
129
    }
130
131
    /**
132
     * Find a hook and execute it's script
133
     *
134
     * @param  \October\Rain\Database\Builder   $query
135
     * @param  integer                          $id
136
     * @return \October\Rain\Database\Builder
137
     */
138
    public function scopeFindAndExecuteScript($query, $id)
139
    {
140
        return $query->find($id)->executeScript();
141
    }
142
143
    /**
144
     * Enables or disables webhooks
145
     *
146
     * @param  \October\Rain\Database\Builder   $query
147
     * @return integer
148
     */
149
    public function scopeSetIsEnabled($query, $isEnabled)
150
    {
151
        return $query->update([
152
            'is_enabled' => $isEnabled,
153
            'updated_at' => Carbon::now(),
154
        ]);
155
    }
156
157
    public function scopeDisable($query)
158
    {
159
        return $query->setIsEnabled(false);
160
    }
161
162
    public function scopeEnable($query)
163
    {
164
        return $query->setIsEnabled(true);
165
    }
166
167
    /**
168
     * Left joins the logs count
169
     *
170
     * @param  \October\Rain\Database\Builder   $query
171
     * @return \October\Rain\Database\Builder
172
     */
173
    public function scopeJoinLogsCount($query)
174
    {
175
        $subquery = Log::select(DB::raw('id, hook_id, COUNT(*) as logs_count'))
176
            ->groupBy('hook_id')
177
            ->getQuery()
178
            ->toSql();
179
180
        return $query
181
            ->addSelect('bedard_webhooks_hooks.*')
182
            ->addSelect('logs.logs_count')
183
            ->leftJoin(DB::raw('(' . $subquery . ') logs'), 'bedard_webhooks_hooks.id', '=', 'logs.hook_id');
184
    }
185
186
    /**
187
     * Helper for snake_case http method
188
     *
189
     * @return string
190
     */
191
    public function getHttpMethodAttribute()
192
    {
193
        return array_key_exists('http_method', $this->attributes)
194
            ? $this->attributes['http_method']
195
            : 'post';
196
    }
197
198
    /**
199
     * Count the number of logs this hook has
200
     *
201
     * @return integer
202
     */
203
    public function getLogsCountAttribute($logs)
204
    {
205
        return array_key_exists('logs_count', $this->attributes)
206
            ? (int) $this->attributes['logs_count']
207
            : 0;
208
    }
209
210
    /**
211
     * Returns a url to this webhook
212
     *
213
     * @return string
214
     */
215
    public function getUrlAttribute()
216
    {
217
        return url('bedard/webhooks', [ 'token' => $this->token ]);
218
    }
219
}
220