Elgg  Version 1.11
CodeStyle.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Project;
4 
13 class CodeStyle {
14 
15  const KEY_NEW_CONTENT = 'new_content';
16  const KEY_REMAINING = 'remaining';
17  const KEY_CORRECTIONS = 'corrections';
18 
22  protected $file_pattern = '~\.(?:php|js|css|xml|json|yml|txt|rst|md|gitignore|htaccess|mailmap|sh)$~';
23 
29  protected $substr_start;
30 
38  public function fixDirectory($root, $dry_run = false) {
39  $return = array();
40 
41  $this->substr_start = strlen($this->normalizePath($root)) + 1;
42 
43  $files = $this->findFilesToAnalyze($root);
44 
45  foreach ($files as $file) {
46  $report = $this->analyzeFile($file);
47  $key = substr($file, $this->substr_start);
48 
49  if ($dry_run) {
50  $errors = $report[self::KEY_REMAINING];
51  array_splice($errors, count($errors), 0, $report[self::KEY_CORRECTIONS]);
52  if ($errors) {
53  $return[$key] = $errors;
54  }
55  } else {
56  if ($report[self::KEY_NEW_CONTENT] !== null) {
57  file_put_contents($file, $report[self::KEY_NEW_CONTENT]);
58  }
59  if ($report[self::KEY_REMAINING]) {
60  $return[$key][self::KEY_REMAINING] = $report[self::KEY_REMAINING];
61  }
62  if ($report[self::KEY_CORRECTIONS]) {
63  $return[$key][self::KEY_CORRECTIONS] = $report[self::KEY_CORRECTIONS];
64  }
65  }
66  }
67 
68  return $return;
69  }
70 
77  public function findFilesToAnalyze($root) {
78  $files = array();
79  $this->substr_start = strlen($this->normalizePath($root)) + 1;
80  $this->findFiles(rtrim($root, '/\\'), $files);
81  return $files;
82  }
83 
96  public function analyzeFile($filepath, $content = null) {
97  if (!is_string($content)) {
98  $content = file_get_contents($filepath);
99  }
100  $old = $content;
101  unset($content);
102 
103  $return = array(
104  self::KEY_REMAINING => array(),
105  self::KEY_CORRECTIONS => array(),
106  self::KEY_NEW_CONTENT => null,
107  );
108 
109  // remove WS after non-WS
110  $new = preg_replace('~(\S)[ \t]+(\r?\n)~', '$1$2', $old, -1, $count);
111  if ($count) {
112  $return[self::KEY_CORRECTIONS][] = "line(s) with trailing whitespace ($count)";
113  }
114 
115  // don't risk breaking code blocks
116  if (!preg_match('~\.(?:rst|md)$~', $filepath)) {
117  // remove WS from empty lines
118  $new = preg_replace('~^[ \t]+$~m', '', $new, -1, $count);
119  if ($count) {
120  $return[self::KEY_CORRECTIONS][] = "empty line(s) with whitespace ($count)";
121  }
122  }
123 
124  if (pathinfo($filepath, PATHINFO_EXTENSION) === 'php') {
125  // remove close PHP tag at file end
126  $new = preg_replace('~\?>\s*$~', '', $new, -1, $count);
127  if ($count) {
128  $return[self::KEY_CORRECTIONS][] = 'unnecessary close PHP tag';
129  }
130  }
131 
132  if ($new !== $old) {
133  $return[self::KEY_NEW_CONTENT] = $new;
134  }
135 
136  return $return;
137  }
138 
147  protected function findFiles($dir, &$files) {
148  $d = dir($dir);
149 
150  while (false !== ($entry = $d->read())) {
151  if ($entry === '.' || $entry === '..') {
152  continue;
153  }
154 
155  $full = $this->normalizePath("{$d->path}/$entry");
156  $relative_path = substr($full, $this->substr_start);
157 
158  if (is_dir($full)) {
159  if ($entry[0] === '.' || preg_match('~(?:/vendors?|/zaudio/audioplayer)$~', $full)) {
160  // special case
161  if ($entry !== '.scripts') {
162  continue;
163  }
164  }
165 
166  if (in_array($relative_path, array('node_modules', 'docs/_build'))) {
167  continue;
168  }
169 
170  $this->findFiles($full, $files);
171  } else {
172  // file
173 
174  if (basename($dir) === 'languages' && $entry !== 'en.php') {
175  continue;
176  }
177 
178  if ($relative_path === 'install/config/htaccess.dist' || preg_match($this->file_pattern, $entry)) {
179  $files[] = $full;
180  continue;
181  }
182  }
183  }
184  $d->close();
185  }
186 
194  protected function normalizePath($path) {
195  return str_replace('\\', '/', rtrim($path, '/\\'));
196  }
197 }
$files
Definition: crop.php:36
$return
Definition: opendd.php:15
$report
findFilesToAnalyze($root)
Find files which can be analyzed/fixed by this component.
Definition: CodeStyle.php:77
analyzeFile($filepath, $content=null)
Analyze a file for problems and return a report.
Definition: CodeStyle.php:96
$key
Definition: summary.php:34
if(is_array($custom_items)) $new
Definition: save.php:85
normalizePath($path)
Normalize a path.
Definition: CodeStyle.php:194
$content
Set robots.txt action.
Definition: set_robots.php:6
findFiles($dir, &$files)
Find files within a directory (recurse for subdirectories)
Definition: CodeStyle.php:147
fixDirectory($root, $dry_run=false)
Fix problems in a directory of files and return a report.
Definition: CodeStyle.php:38
if(elgg_in_context('widget')) $count
Definition: pagination.php:20
$path
Definition: invalid.php:17