SearchReplace::getTableExcludes()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php namespace SearchReplace;
2
3
use SearchReplace\SearchReplaceDatabase;
4
use SearchReplace\DatabaseTypes\MySQLi;
0 ignored issues
show
Bug introduced by
The type SearchReplace\DatabaseTypes\MySQLi was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
5
use SearchReplace\SearchReplaceException as Exception;
6
7
/**
8
 * Class SearchReplace
9
 *
10
 * @property bool include_all_tables
11
* @package SearchReplace
12
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
13
 * @author Jarrett Barnett <[email protected]>
14
 */
15
class SearchReplace
16
{
17
    // DEFAULTS
18
    const DEFAULT_TABLE_ROW_OFFSET = 0;
19
    const DEFAULT_TABLE_ROW_LIMIT = null;
20
    const DEFAULT_TABLE_ROWS_PER_BATCH = 100;
21
    
22
    /**
23
     * Collection of search/replace properties
24
     */
25
    protected $search_property;
26
    protected $search_regex;
27
    protected $replace_property;
28
    protected $replace_regex;
29
30
    /**
31
     * Collection of tables to execute search on
32
     * @var (array) $tables
33
     */
34
    protected $tables = [];
35
    protected $tables_include_all = false;
36
    protected $tables_include = [];
37
    protected $tables_exclude = [];
38
    protected $table_offset;
39
    protected $table_limit;
40
    protected $table_row_offset = self::DEFAULT_TABLE_ROW_OFFSET;
41
    protected $table_row_limit = self::DEFAULT_TABLE_ROW_LIMIT;
42
    protected $table_rows_per_batch = self::DEFAULT_TABLE_ROWS_PER_BATCH;
43
    
44
    /**
45
     * @var $db
46
     */
0 ignored issues
show
Documentation Bug introduced by
The doc comment $db at position 0 could not be parsed: Unknown type name '$db' at position 0 in $db.
Loading history...
47
    protected $db;
48
49
    /**
50
     * @var bool $exceptions - enable/disable exceptions
51
     */
52
    protected $exceptions = true;
53
54
    /**
55
     * @var array $errors - collection of errors before or during execution
56
     */
57
    protected $errors;
58
59
    /**
60
     * SearchReplace constructor.
61
     * @param $db_resource
62
     */
63
    public function __construct($db_resource = '')
64
    {
65
        if (!empty($db_resource))
66
        {
67
            $this->setDatabase($db_resource);
68
        }
69
    }
70
71
    public function db()
72
    {
73
        return $this->db;
74
    }
75
    
76
    /**
77
     * Search
78
     *
79
     * @param $search
80
     * @param bool $regex
81
     * @return $this
82
     */
83
    public function search($search, $regex = false)
84
    {
85
        $this->search_property = $search;
86
        $this->search_regex = $regex;
87
        return $this;
88
    }
89
    
90
    /**
91
     * Replace
92
     *
93
     * @param $replace
94
     * @param bool $regex
95
     * @return $this
96
     */
97
    public function replace($replace, $regex = false)
98
    {
99
        $this->replace_property = $replace;
100
        $this->replace_regex = $regex;
101
        return $this;
102
    }
103
104
    /**
105
     * Set Database
106
     * @param $resource_or_host
107
     * @param $username
108
     * @param $password
109
     * @param $database
110
     * @return mixed
111
     */
112
    public function setDatabase($resource_or_host = '', $username = '', $password = '', $database = '')
113
    {
114
        if (empty($resource_or_host)) return $this->throwError('setDatabase(): Database resource/hostname cannot be empty');
115
116
        if (is_object($resource_or_host)) {
117
            $this->db = $resource_or_host;
118
119
            return $this;
120
        }
121
122
        if (empty($username)) return $this->throwError('setDatabase(): Username parameter cannot be empty.');
123
        if (empty($database)) return $this->throwError('setDatabase(): Database name parameter cannot be empty.');
124
125
        // empty passwords are allowed
126
        $password = (empty($password)) ? '' : $password;
127
128
        $instance = new SearchReplaceDatabase($resource_or_host, $username, $password, $database);
129
        $this->db = $instance;
130
131
        return $this;
132
    }
133
134
    /**
135
     * Throw Error
136
     * @param $error_message
137
     * @param bool $return_value_if_disabled
138
     * @return bool
139
     * @throws Exception
140
     */
141
    public function throwError($error_message, $return_value_if_disabled = false)
142
    {
143
        if ($this->exceptions)
144
        {
145
            throw new Exception($error_message);
146
        }
147
148
        return $return_value_if_disabled;
149
    }
150
151
    /**
152
     * Enable Exceptions
153
     * @return $this
154
     */
155
    public function enableExceptions()
156
    {
157
        $this->exceptions = true;
158
159
        return $this;
160
    }
161
162
    /**
163
     * Disable Exceptions
164
     * @return $this
165
     */
166
    public function disableExceptions()
167
    {
168
        $this->exceptions = false;
169
170
        return $this;
171
    }
172
173
    /**
174
     * Include All Tables
175
     * @param $bool (bool)
176
     * @return mixed
177
     */
178
    public function includeAllTables($bool = true)
179
    {
180
        if (!is_bool($bool)) return $this->throwError('includeAllTables(): Non-boolean value supplied.');
181
182
        $this->tables_include_all = $bool;
183
184
        return $this;
185
    }
186
187
    /**
188
     * Include Tables
189
     * @param $tables
190
     * @param bool $override
191
     * @return $this
192
     */
193
    public function includeTables($tables, $override = false)
194
    {
195
        if ($override) {
196
            $this->tables_include = $tables;
197
198
            return $this;
199
        }
200
201
        $this->tables_include = array_merge($this->tables_include, $tables);
202
203
        return $this;
204
    }
205
206
    /**
207
     * Exclude Tables
208
     * @param $tables
209
     * @return $this
210
     */
211
    public function excludeTables($tables, $override = false)
212
    {
213
        if ($override) {
214
            $this->tables_exclude = $tables;
215
216
            return $this;
217
        }
218
        
219
        $this->tables_exclude = array_merge($this->tables, $tables);
220
221
        return $this;
222
    }
223
224
    /**
225
     * Get Tables
226
     * @return array
227
     */
228
    public function getTables()
229
    {
230
        $this->prepareTables();
231
        
232
        return $this->tables;
233
    }
234
235
    /**
236
     * Get Table Includes
237
     * @return array
238
     */
239
    public function getTableIncludes()
240
    {
241
        return $this->tables_include;
242
    }
243
244
    /**
245
     * Get Table Excludes
246
     * @return array
247
     */
248
    public function getTableExcludes()
249
    {
250
        return $this->tables_exclude;
251
    }
252
253
    /**
254
     * Reset Tables (Inclusions and Exclusions)
255
     * @return $this
256
     */
257
    public function resetTables()
258
    {
259
        $this->tables_include = [];
260
        $this->tables_exclude = [];
261
262
        return $this;
263
    }
264
265
    /**
266
     * Start table execution at a specific offset
267
     * Useful for executing search in batches
268
     * @param $offset
269
     * @return mixed
270
     */
271
    public function setTableOffset($offset)
272
    {
273
        if (!is_numeric($offset)) return $this->throwError('Table offset must be a number!');
274
275
        $this->table_offset = (int) $offset;
276
277
        return $this;
278
    }
279
    
280
    /**
281
     * Get Table Row Offset
282
     * @return int
283
     */
284
    public function getTableRowOffset()
285
    {
286
        return $this->table_row_offset;
287
    }
288
    
289
    /**
290
     * Get Table Row Limit
291
     * @return int
292
     */
293
    public function getTableRowLimit()
294
    {
295
        return $this->table_row_limit;
296
    }
297
    
298
    /**
299
     * Get Table Offset
300
     * @return int
301
     */
302
    public function getTableOffset()
303
    {
304
        return $this->table_offset;
305
    }
306
307
    /**
308
     * Set limit on table list
309
     * @param $limit
310
     * @return mixed
311
     */
312
    public function setTableLimit($limit)
313
    {
314
        if (!is_numeric($limit)) return $this->throwError('Table limit must be a number!');
315
316
        $this->table_limit = (int) $limit;
317
318
        return $this;
319
    }
320
    
321
    /**
322
     * Get Table Limit
323
     * @return int
324
     */
325
    public function getTableLimit()
326
    {
327
        return $this->table_limit;
328
    }
329
330
    /**
331
     * Set offset and limit on table list
332
     * @param $offset
333
     * @param $limit
334
     * @return $this
335
     */
336
    public function setTableRange($offset, $limit)
337
    {
338
        $this->setTableOffset($offset);
339
        $this->setTableLimit($limit);
340
341
        return $this;
342
    }
343
344
    /**
345
     * Start row search/replace at a specific row offset
346
     * Useful for executing search/replacements on a specific table in batches
347
     * @param $offset
348
     * @return $this
349
     */
350
    public function setTableRowOffset($offset)
351
    {
352
        $this->table_row_offset = (int) $offset;
353
354
        return $this;
355
    }
356
357
    /**
358
     * Limit how many rows are executed per table
359
     * Useful for executing search/replacements on a specific table in batches
360
     * @param $limit
361
     * @return $this
362
     */
363
    public function setTableRowLimit($limit)
364
    {
365
        $this->table_row_limit = (int) $limit;
366
367
        return $this;
368
    }
369
370
    /**
371
     * Set table row range (limit and offset)
372
     * @param $offset
373
     * @param $limit
374
     * @return $this
375
     */
376
    public function setTableRowRange($offset, $limit)
377
    {
378
        $this->setTableRowOffset($offset);
379
        $this->setTableRowLimit($limit);
380
381
        return $this;
382
    }
383
384
    /**
385
     * Set Table Rows Per Batch
386
     * @param $rows_per_batch
387
     * @return $this
388
     */
389
    public function setTableRowsPerBatch($rows_per_batch)
390
    {
391
        if (!is_numeric($rows_per_batch)) {
392
            $this->throwError('setTableRowsPerBatch(): Parameter must be a number');
393
        }
394
        
395
        $this->table_rows_per_batch = (int) $rows_per_batch;
396
        
397
        return $this;
398
    }
399
400
    /**
401
     * Verify Prerequisites
402
     *
403
     * @return array
404
     */
405
    public function verifyPrereqs()
406
    {
407
        if (empty($this->db))
408
        {
409
            $this->errors[] = 'Database connection not provided.';
410
        }
411
412
        return $this->errors;
413
    }
414
415
    /**
416
     * Reset The Request For Another Go-Round'
417
     * @return $this
418
     */
419
    public function reset()
420
    {
421
        $this->tables = [];
422
        $this->tables_include = [];
423
        $this->tables_exclude = [];
424
        $this->table_offset = [];
425
        $this->table_limit = [];
426
        $this->table_row_offset = [];
427
        $this->table_row_limit = [];
428
        
429
        return $this;
430
    }
431
432
    /**
433
     * Reset Errors
434
     * @return $this
435
     */
436
    protected function resetErrors()
437
    {
438
        $this->errors = [];
439
440
        return $this;
441
    }
442
443
    /**
444
     * Append Error
445
     * @param $error
446
     * @return $this
447
     */
448
    protected function appendError($error)
449
    {
450
        $this->errors[] = $error;
451
452
        return $this;
453
    }
454
455
    /**
456
     * Prepare
457
     * @return $this
458
     */
459
    private function prepare()
460
    {
461
        $this->prepareTables();
462
        
463
        return $this;
464
    }
465
466
    /**
467
     * Prepare Tables
468
     * @return $this
469
     */
470
    private function prepareTables()
471
    {
472
        if ($this->tables_include_all === true) {
473
            $this->tables = array_merge($this->tables, $this->db->getAllTables());
474
        }
475
        
476
        if (!empty($this->tables_include)) {
477
            $this->tables = array_merge($this->tables, $this->tables_include);
478
        }
479
        
480
        if (!empty($this->tables_exclude)) {
481
            $this->tables = array_diff($this->tables, $this->tables_exclude);
482
        }
483
        
484
        return $this;
485
    }
486
487
    /**
488
     * Execute!
489
     */
490
    public function execute()
491
    {
492
        $this->verifyPrereqs();
493
        $this->prepare();
494
    }
495
}
496