Completed
Push — master ( 497d8f...e0d9ca )
by Kanto
13s queued 11s
created

Command::getFromArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 3
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Kore : Simple And Minimal Framework
4
 *
5
 */
6
7
namespace Kore;
8
9
use Kore\Log;
10
11
/**
12
 * Command class
13
 *
14
 */
15
abstract class Command
16
{
17
    /**
18
     * command namespace
19
     *
20
     * @var string
21
     */
22
    protected $command;
23
    /**
24
     * command arguments
25
     *
26
     * @var array<string>
27
     */
28
    protected $args = array();
29
    /**
30
     * command options
31
     *
32
     * @var array<string>
33
     */
34
    protected $opts = array();
35
36
    /**
37
     * Processing Execution
38
     *
39
     * The process is implemented in subclasses.
40
     * @return void
41
     */
42
    abstract protected function exec();
43
    
44
    /**
45
     * Main Processing
46
     *
47
     * @param string $command command namespace
48
     * @param array<string> $args command arguments
49
     * @param array<string> $opts command options
50
     * @return void
51
     */
52
    public function main($command, $args, $opts)
53
    {
54
        $this->command = $command;
55
        $this->args = $args;
56
        $this->opts = $opts;
57
        Log::init($this->commandName(), $this->logLevel());
58
59
        $lockManager = new LockManager($this->commandName(), $this->lockTime());
60
        if ($lockManager->isLock()) {
61
            Log::warn('Process is running!');
62
            return;
63
        }
64
        $lockManager->lock();
65
66
        Log::debug(sprintf('[START]%s', $this->command));
67
        try {
68
            $this->exec();
69
        } catch (\Exception $e) {
70
            $lockManager->unlock();
71
            $this->handleError($e);
72
        }
73
        Log::debug(sprintf('[END]%s', $this->command));
74
75
        $lockManager->unlock();
76
    }
77
78
    /**
79
     * Get the command name
80
     *
81
     * The default is the end of the command namespace.
82
     * If you need to customize, please override it with subclasses.
83
     * @return string command name
84
     */
85
    protected function commandName()
86
    {
87
        $namespace = explode('\\', $this->command);
88
        return $namespace[count($namespace) - 1];
89
    }
90
91
    /**
92
     * Get the log level
93
     *
94
     * The default is Log::LEVEL_DEBUG.
95
     * If you need to customize, please override it with subclasses.
96
     * @return int log level
97
     * @see \Kore\Log
98
     */
99
    protected function logLevel()
100
    {
101
        return Log::LEVEL_DEBUG;
102
    }
103
104
    /**
105
     * Get the lock time
106
     *
107
     * The default is 24 hours.
108
     * If you need to customize, please override it with subclasses.
109
     * @return int lock time
110
     */
111
    protected function lockTime()
112
    {
113
        return 60 * 60 * 24;
114
    }
115
116
    /**
117
     * Handling Errors
118
     *
119
     * If you need to customize the handling of errors, please override it with subclasses.
120
     * @param \Exception $e errors
121
     * @return void
122
     * @throws \Exception
123
     */
124
    protected function handleError($e)
125
    {
126
        Log::error($e->getMessage());
127
        throw $e;
128
    }
129
130
    /**
131
     * Get the command arguments
132
     *
133
     * If no key is specified, all command arguments are returned.
134
     * @param string|null $key command argument key
135
     * @param mixed $default default value if there is no value specified in the key
136
     * @return mixed command arguments
137
     */
138
    protected function getArg($key = null, $default = null)
139
    {
140
        return $this->getFromArray($this->args, $key, $default);
141
    }
142
143
    /**
144
     * Get the command options
145
     *
146
     * If no key is specified, all command options are returned.
147
     * @param string|null $key command option key
148
     * @param mixed $default default value if there is no value specified in the key
149
     * @return mixed command options
150
     */
151
    protected function getOpt($key = null, $default = null)
152
    {
153
        return $this->getFromArray($this->opts, $key, $default);
154
    }
155
156
    /**
157
     * Get from array
158
     *
159
     * If no key is specified, array is returned.
160
     * @param array<mixed> $array array
161
     * @param string|null $key path key
162
     * @param mixed $default default value if there is no value specified in the key
163
     * @return mixed value
164
     */
165
    protected function getFromArray($array, $key, $default)
166
    {
167
        if ($key === null) {
168
            return $array;
169
        }
170
        if (!isset($array[$key])) {
171
            return $default;
172
        }
173
        return $array[$key];
174
    }
175
}
176
177
/**
178
 * Managing Command Lock
179
 *
180
 */
181
class LockManager
182
{
183
    /** @var string process name */
184
    protected $pname;
185
    /** @var int lock time */
186
    protected $lockTime;
187
    /** @var string lock file */
188
    protected $_lockFile;
189
190
    /**
191
     * __construct
192
     * @param string $pname process name
193
     * @param int $lockTime lock time
194
     * @return void
195
     */
196
    public function __construct($pname, $lockTime)
197
    {
198
        $this->pname = $pname;
199
        $this->lockTime = $lockTime;
200
    }
201
202
    /**
203
     * Lock
204
     * @return void
205
     */
206
    public function lock()
207
    {
208
        touch($this->lockFile());
209
    }
210
211
    /**
212
     * Unlock
213
     * @return void
214
     */
215
    public function unlock()
216
    {
217
        if (file_exists($this->lockFile())) {
218
            unlink($this->lockFile());
219
        }
220
    }
221
222
    /**
223
     * Locked or not
224
     * @return boolean locked or not
225
     */
226
    public function isLock()
227
    {
228
        return file_exists($this->lockFile()) && filemtime($this->lockFile()) + $this->lockTime >= time();
229
    }
230
231
    /**
232
     * Get lock file
233
     * @return string lock file
234
     */
235
    protected function lockFile()
236
    {
237
        if (!$this->_lockFile) {
238
            $this->_lockFile = TMP_DIR.'/'.$this->pname.'.lock';
239
        }
240
        return $this->_lockFile;
241
    }
242
}
243