omf /upload/vqmod/install/ugrsr.class.php

Language PHP Lines 494
MD5 Hash b4eb6b608c5b14e1234d9e3e91f9d5f2 Estimated Cost $5,668 (why?)
Repository https://bitbucket.org/elena_dyavolova/omf.git View Raw File View Project SPDX
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
<?php

/**
 * UGRSR
 * 
 * @package Universal Global RegEx Search/Replace
 * @author Qphoria - http://theqdomain.com/ & Jay Gilford - http://jaygilford.com/
 * @copyright Qphoria & Jay Gilford 2011
 * @version 0.2
 * @access public
 * 
 * @information
 * This class will perform mass search and replace actions
 * based on regex pattern matching. It recursively grabs all files
 * below it's given path and applies the specified change(s)
 * 
 * @license
 * Permission is hereby granted, free of charge, to any person to
 * use, copy, modify, distribute, sublicense, and/or sell copies
 * of the Software, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software
 * 
 * @warning
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESSED OR IMPLIED.
 *  
 */
class UGRSR {
	
	public $debug = false;				// Show debug messages switch
	public $flags = 0;					// Flags for the file recursive glob
	public $pattern = '*.php';			// File pattern to match with glob
	public $recursive = true;			// Recursion into subdirectories switch
	public $test_mode = false;			// Test mode only switch
	public $file_search = true;			// Search for files switch
	
	
	private $_regexes = array();		// Array for regex patterns and replaces
	private $_path = '';				// Path to directory to work with
	private $_protected = array();		// Array of protected files
	private $_files = array();			// Array of manually added file locations
	
	/**
	 * UGRSR::__construct()
	 * 
	 * @param string $path
	 * @return null
	 */
	function __construct($path = '') {
		
		// Use current working directory if none given as a parameter
		if(empty($path)) {
			$path = getcwd();
		}
		
		// Apply path to var
		$this->setPath($path);
		
		// Check to make sure the script calling the class is set to be protected
		if(!isset($_SERVER['SCRIPT_FILENAME'])) {
			DIE('SCRIPT FILENAME COULD NOT BE DETERMINED');
		}
		
		// Set default file protections
		$this->resetProtected();
	}
	
	/**
	 * UGRSR::addPattern()
	 * 
	 * @param string $pattern
	 * @param string $replace
	 * @return bool
	 */
	public function addPattern($pattern, $replace) {
		
		// If pattern is empty throw error
		if(empty($pattern)) {
			$this->_dbg('PATTERN EMPTY');
			return false;
		}
		
		// Add regex pattern and replace vars to _regexes array
		$this->_regexes[] = array(
			'pattern'		=> $pattern,
			'replace'		=> $replace
		);
		
		return true;
	}
	
	/**
	 * UGRSR::mergePatterns()
	 * 
	 * @param array $pattern_array
	 * @return bool
	 */
	public function mergePatterns($pattern_array) {
		
		// If the param is not an array throw error
		if(!is_array($pattern_array)) {
			$this->_dbg('PARAM IS NOT AN ARRAY');
			return false;
		}
		
		//Loop through pattern array
		foreach($pattern_array as $data) {
			
			// If pattern or replace keys not set throw error and continue loop
			if(!isset($data['pattern']) || !isset($data['replace'])) {
				$this->_dbg('ARRAY KEYS NOT SET');
				continue;
			}
			
			// Add regex and replace
			$this->addPattern($data['pattern'], $data['replace']);
		}
		
		return true;
	}
	
	/**
	 * UGRSR::clearPatterns()
	 * 
	 * @return null
	 */
	public function clearPatterns() {
		
		// Set regexes var to empty array
		$this->_regexes = array();
	}
	
	/**
	 * UGRSR::addFile()
	 * 
	 * @param string $filename
	 * @param bool 
	 * @return bool
	 */
	public function addFile($filename, $omit_path = false) {
		
		$file = $omit_path ? $filename : $this->_path . $filename;
		
		// If the protection isnt for a file throw an error
		if(!is_file($file)) {
			$this->_dbg('FILE [' . $file . '] IS NOT A FILE');
			return false;
		}
		
		// Get real full path to file
		$real_filename = realpath($file);
		
		// If real path for file can't be found throw error
		if(!$real_filename) {
			$this->_dbg('FILE [' . $file . '] IS NOT A FILE');
			return false;
		}
		
		// Don't add file if it's already in the file list
		if(in_array($real_filename, $this->_files)) {
			$this->_dbg('FILE [' . $file . '] ALREADY IN FILE LIST');
			return false;
		}
		
		// Add filename to file list
		$this->_dbg('FILE [' . $real_filename . '] ADDED TO FILE LIST');
		$this->_files[] = $real_filename;
		
		return true;
	}
	
	/**
	 * UGRSR::resetFileList()
	 * 
	 * @return true
	 */
	public function resetFileList() {
		// Clear file list
		$this->_files = array();
		
		$this->_dbg('FILE LIST RESET');
		
		return true;
	}
	
	/**
	 * UGRSR::addProtected()
	 * 
	 * @param string $filename
	 * @return bool
	 */
	public function addProtected($filename) {
		
		// If the protection isnt for a file throw an error
		if(!is_file($filename)) {
			$this->_dbg('FILE [' . $filename . '] IS NOT A FILE');
			return false;
		}
		
		// Get real full path to file
		$real_filename = realpath($filename);
		
		// If real path for file can't be found throw error
		if(!$real_filename) {
			$this->_dbg('FILE [' . $filename . '] IS NOT A FILE');
			return false;
		}
		
		// Add filename to protected list
		$this->_dbg('FILE [' . $filename . '] ADDED TO PROTECTED LIST');
		$this->_protected[] = $real_filename;
		
		return true;
	}
	
	/**
	 * UGRSR::resetProtected()
	 * 
	 * @return true
	 */
	public function resetProtected() {
		// Clear protected list
		$this->_protected = array();
		
		$this->_dbg('PROTECTED FILES RESET');
		//Add this class to protected list
		$this->_protected[] = realpath(__FILE__);
		
		// Add script that called the class to protected list
		$this->_protected[] = realpath($_SERVER['SCRIPT_FILENAME']);
		
		return true;
	}
	
	/**
	 * UGRSR::setPath()
	 * 
	 * @param string $path
	 * @return bool
	 */
	public function setPath($path) {
		
		// Get full real path to given path
		$realpath = realpath($path);
		
		// If path can't be found or isn't a directory throw an error
		if(!$realpath || !is_dir($realpath)) {
			$this->_dbg('INVALID PATH [' . $realpath . ']');
			return false;
		}
		
		// Add trailing slash to path name
		$realpath .= '/';
		
		// Set path to new value
		$this->_dbg('NEW PATH SET [' . $realpath . ']');
		$this->_path = $realpath;
		
		return true;
	}
	
	/**
	 * UGRSR::run()
	 * 
	 * @return bool
	 */
	public function run() {
		
		// If regexes array is empty throw an error
		if(empty($this->_regexes)) {
			$this->_dbg('REGEX LIST IS EMPTY');
			return false;
		}
		
		$this->_dbg('STARTING RUN');
		$this->_dbg();
		
		// Set files to list of manually added files
		$files = $this->_files;

		// Check if file searching is enabled
		if($this->file_search) {
			$this->_dbg('GETTING FILE LIST');
			
			// Get a list of files under defined path
			$found = array_merge($this->_rglob());
	
			$this->_dbg(count($found) . ' FILES FOUND');
			$this->_dbg();
			
			// merge list of files with manually added file list
			$files = array_merge($files, $found);
		}
		
		// Check files found or throw error and return
		if(count($files) == 0) {
			$this->_dbg('NO FILES TO BE PROCESSED');
			return false;
		}
		
		$this->_dbg('STARTING FILE PROCESSING');
		
		// Var for total regex matches throughout files
		$global_change_count = 0;
		
		// Var to hold 
		$global_write_count = 0;
		
		// Var to hold number of bytes saved
		$bytes_saved = 0;
		
		// Loop through files one at a time
		foreach($files as $filename) {
			
			// Var for total regex matches in current file
			$file_change_count = 0;
			
			// Load file contents
			$content = $original_content = file_get_contents($filename);
			
			// If content couldn't be loaded throw error
			if($content === FALSE) {
				$this->_dbg('COULD NOT OPEN [' . $filename . ']');
				continue;
			}
			
			// If file length is 0 throw error
			if(strlen($content) == 0) {
				$this->_dbg('EMPTY FILE SKIPPED [' . $filename . ']');
				continue;
			}
			
			// Loop through _regexes array applying changes to content
			foreach($this->_regexes as $regex) {
				
				// Var for total regex matches for individual pattern
				$change_count = 0;
				
				// Try replacing content
				$content = preg_replace($regex['pattern'], $regex['replace'], $content, -1, $change_count);
				
				// If regex operation fails throw error and abort all operations
				if($content === NULL) {
					$this->_dbg('REGEX PATTERN ERROR <strong>' . $regex['pattern'] . '</strong>');
					$this->_dbg('ABORTING ALL OPERATIONS');
					break 2;
				}
				
				// Add individual pattern change count to file change count
				$file_change_count += $change_count;
				$this->_dbg('REGEX <strong>' . $regex['pattern'] . '</strong> FOUND ' . ($change_count ? $change_count : 'NO') . ' MATCHES IN [' . $filename . ']');
				
			}
			
			// If not in test mode and content has changed attempt to write back to file			
			if($content !== $original_content && !$this->test_mode) {
				$this->_dbg('ATTEMPTING TO WRITE TO FILE [' . $filename . ']');
				
				// If file isn't writeable throw error
				if(!is_writeable($filename)) {
					$this->_dbg('CANNOT WRITE TO [' . $filename . ']');
				} else {
					
					// Write file data back to file and show result
					$result = file_put_contents($filename, $content);
					if($result) {
						$this->_dbg('SUCCESSFULLY WROTE ' . $result . ' BYTES  TO [' . $filename . ']');
						$global_write_count++;
					} else {
						$this->_dbg('WRITE OPERATION FAILED IN [' . $filename . ']');
					}
				}
			}
			
			// Add byte difference to $bytes_saved
			$bytes_saved += (strlen($original_content) - strlen($content));
			
			// Add total file changes count to global file changes count 
			$global_change_count += $file_change_count;
			
			$this->_dbg('TOTAL NUMBER OF FILE CHANGES: ' . $file_change_count);
			$this->_dbg();
		}
		
		$this->_dbg();
		$this->_dbg('FINISHED FILE PROCESSING');
		$this->_dbg('TOTAL CHANGES APPLIED ACROSS ALL FILES: <strong>' . $global_change_count . '</strong>');
		$this->_dbg('TOTAL BYTES SAVED ACROSS ALL FILES: <strong>' . $bytes_saved . '</strong>');
		$this->_dbg();
		
		$this->_dbg('FINISHED RUN');
		$this->_dbg();
		
		// Pass back the number of changes and writes matched
		return array(
			'changes' => $global_change_count,
			'writes' => $global_write_count
		);
	}
	
	/**
	 * UGRSR::_dbg()
	 * 
	 * @param string $message
	 * @return NULL;
	 */
	private function _dbg($message = '') {
		
		// If in debug mode show output
		if($this->debug) {
			
			// Set mode type
			$mode = $this->test_mode ? 'TEST MODE' : 'LIVE MODE';
			
			// If there's a message echo that otherwise echo some whitespace for formatting
			if(!empty($message)) {
				echo $mode . ': *** ' . $message . " ***<br />\r\n";
			} else {
				echo str_repeat("<br />\r\n", 2);
			}
		}
	}
	
	/**
	 * UGRSR::_rglob()
	 * 
	 * @param string $path
	 * @return array
	 */
	private function _rglob($path = NULL) {
		
		// If the path isn't supplied use the one stored in _path
		if($path === NULL) $path = $this->_path;
		$this->_dbg('SEARCHING PATH [' . $path .']');
		
		// Get list of files under current directory
		$files = glob($path . $this->pattern, $this->flags);
		
		// Loop through all files
		foreach($files as $key => &$file) {
			// Flag to allow file to be kept in file array
			$remove_file = false;
			
			// Get full path of file
			$realfile = realpath($file);
			
			// Report if file path can't be resolved
			if($realfile === FALSE) {
				$this->_dbg('REAL PATH OF FILE [' . $file . '] COULD NOT BE RESOLVED');
				$remove_file = true;
			}
			
			// Report if file path is in the protected list
			if($realfile && in_array($realfile, $this->_protected)) {
				$this->_dbg('PROTECTED FILE [' . $realfile . '] REMOVED FROM FILES LIST');
				$remove_file = true;
			}
			
			// Report if file path is in the protected list
			if($realfile && in_array($realfile, $this->_files)) {
				$this->_dbg('FILE [' . $realfile . '] SKIPPED. ALREADY IN FILE LIST');
				$remove_file = true;
			}
			
			// Report if write access cannot be granted for file
			if($realfile && !is_writeable($realfile)) {
				$this->_dbg('FILE [' . $file . '] SKIPPED AS CANNOT WRITE TO IT');
				$remove_file = true;
			}
			
			// Remove from file list if any issues
			if($remove_file) {
				unset($files[$key]);
			}
		}
		
		// If recursion is set get files in subdirectories
		if($this->recursive) {
		
			// Get list of directories under current path
			$paths = glob($path . '*', GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT);
			
			// Loop through subdirectories and merge files into directory list
			foreach($paths as $p) {
				$files = array_merge($files, $this->_rglob($p));
			}
		}
		
		// Pass file array back		
		return $files;
	}
}
Back to Top