This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Database driver |
||
4 | * |
||
5 | * @author Matthias Gisder <[email protected]> |
||
6 | * @copyright 2014 inGenerator Ltd |
||
7 | * @licence BSD |
||
8 | */ |
||
9 | |||
10 | namespace Ingenerator\RunSingle; |
||
11 | |||
12 | use \Ingenerator\RunSingle\PdoDatabaseObject; |
||
13 | use \Psr\Log\LoggerInterface; |
||
14 | |||
15 | class DbDriver implements LockDriver |
||
16 | { |
||
17 | |||
18 | const DATE_FORMAT = 'd/m/Y H:i:s'; |
||
19 | /** |
||
20 | * @var \Ingenerator\RunSingle\PdoDatabaseObject |
||
21 | */ |
||
22 | protected $db_object; |
||
23 | |||
24 | /** |
||
25 | * @var callable |
||
26 | */ |
||
27 | protected $timeProvider = 'time'; |
||
28 | |||
29 | /** |
||
30 | * @var \Psr\Log\LoggerInterface |
||
31 | */ |
||
32 | protected $logger; |
||
33 | |||
34 | /** |
||
35 | * @param \Ingenerator\RunSingle\PdoDatabaseObject $db_object |
||
36 | */ |
||
37 | public function __construct(PdoDatabaseObject $db_object) |
||
38 | { |
||
39 | $this->db_object = $db_object; |
||
40 | } |
||
41 | |||
42 | /** |
||
43 | * @param callable $provider |
||
44 | */ |
||
45 | public function set_time_provider($provider) |
||
46 | { |
||
47 | $this->timeProvider = $provider; |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * @return int |
||
52 | */ |
||
53 | protected function get_time() |
||
54 | { |
||
55 | $time = \call_user_func($this->timeProvider); |
||
56 | return $time; |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * @param string $task_name |
||
61 | * @param int $timeout |
||
62 | * @param string $lock_holder |
||
63 | * |
||
64 | * @return false|integer |
||
65 | * @throws \Exception |
||
66 | * @throws \PDOException |
||
67 | */ |
||
68 | public function get_lock($task_name, $timeout, $lock_holder) |
||
69 | { |
||
70 | $timestamp = $this->get_time(); |
||
71 | |||
72 | try { |
||
73 | $this->db_object->execute('INSERT INTO '.$this->db_object->get_db_table_name()." VALUES(:task_name, :timestamp, :timeout, :lock_holder)", array( |
||
74 | ':task_name' => $task_name, |
||
75 | ':timestamp' => $timestamp, |
||
76 | ':timeout' => $timeout, |
||
77 | ':lock_holder' => $lock_holder, |
||
78 | )); |
||
79 | } catch (\PDOException $e) { |
||
80 | if (\substr($e->getMessage(), 0, 69) === 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry') { |
||
81 | return FALSE; |
||
82 | } else { |
||
83 | throw $e; |
||
84 | } |
||
85 | } |
||
86 | |||
87 | return $timestamp; |
||
88 | } |
||
89 | |||
90 | /** |
||
91 | * @param string $task_name |
||
92 | * |
||
93 | * @return void |
||
94 | */ |
||
95 | public function garbage_collect($task_name) |
||
96 | { |
||
97 | $result = $this->db_object->fetch_all('SELECT * FROM '.$this->db_object->get_db_table_name().' WHERE task_name = :task_name AND (lock_timestamp + timeout) < :current_timestamp', array( |
||
98 | ':task_name' => $task_name, |
||
99 | ':current_timestamp' => $this->get_time() |
||
100 | )); |
||
101 | if (!$result) { |
||
0 ignored issues
–
show
|
|||
102 | $this->log('debug', 'no stale locks found for task '.$task_name); |
||
103 | return; |
||
104 | } |
||
105 | |||
106 | $lock = $this->build_lock_object($result[0]); |
||
107 | $this->log('warning', \sprintf('stale locks found for lock:'.PHP_EOL.' %s', $lock)); |
||
108 | $this->release_lock($result[0]['task_name'], $result[0]['lock_timestamp']); |
||
109 | } |
||
110 | |||
111 | /** |
||
112 | * @param string $task_name |
||
113 | * @param int $lock_timestamp |
||
114 | * |
||
115 | * @return void |
||
116 | */ |
||
117 | public function release_lock($task_name, $lock_timestamp) |
||
118 | { |
||
119 | $this->log('debug', 'releasing lock for task '.$task_name); |
||
120 | $this->db_object->execute('DELETE FROM '.$this->db_object->get_db_table_name().' WHERE task_name = :task_name AND lock_timestamp = :lock_timestamp', array( |
||
121 | ':task_name' => $task_name, |
||
122 | ':lock_timestamp' => $lock_timestamp |
||
123 | )); |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * @param LoggerInterface $logger |
||
128 | */ |
||
129 | public function set_logger(LoggerInterface $logger) |
||
130 | { |
||
131 | $this->logger = $logger; |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * Log only if logger is set. |
||
136 | * |
||
137 | * @param $level |
||
138 | * @param $message |
||
139 | */ |
||
140 | protected function log($level, $message) |
||
141 | { |
||
142 | if ($this->logger) { |
||
143 | \call_user_func(array($this->logger, $level), $message); |
||
144 | } |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * @param array $result |
||
149 | * |
||
150 | * @return Lock |
||
151 | */ |
||
152 | protected function build_lock_object($result) |
||
153 | { |
||
154 | $data = array( |
||
155 | 'task_name' => $result['task_name'], |
||
156 | 'lock_id' => $result['lock_timestamp'], |
||
157 | 'timeout' => $result['timeout'], |
||
158 | 'lock_holder' => $result['lock_holder'], |
||
159 | 'expires' => new \DateTime('@'.($result['lock_timestamp'] + $result['timeout'])), |
||
160 | 'locked_at' => new \DateTime('@'.($result['lock_timestamp'])), |
||
161 | ); |
||
162 | $lock_obj = new Lock($data); |
||
163 | |||
164 | return $lock_obj; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * Return a list of locks. |
||
169 | * |
||
170 | * @return array |
||
171 | */ |
||
172 | public function list_locks() |
||
173 | { |
||
174 | $result = $this->db_object->fetch_all('SELECT * FROM '.$this->db_object->get_db_table_name(), array()); |
||
175 | |||
176 | $locks = array(); |
||
177 | if ($result) { |
||
0 ignored issues
–
show
The expression
$result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
178 | foreach ($result as $result_item) { |
||
179 | $locks[] = $this->build_lock_object($result_item); |
||
180 | } |
||
181 | } |
||
182 | |||
183 | return $locks; |
||
184 | } |
||
185 | |||
186 | } |
||
187 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.