Pathologic was missing because of a .git folder inside.
[yaffs-website] / web / modules / contrib / hacked / hacked.module
1 <?php
2
3 /**
4  * @file
5  * The Hacked! module, shows which project have been changed since download.
6  *
7  * We download the original project file, and hash all the files contained
8  * within, then we hash our local copies and compare.
9  * This module should never be used on a production server.
10  */
11
12 define('HACKED_CACHE_TABLE', 'hacked');
13
14 define('HACKED_STATUS_UNCHECKED', 1);
15 define('HACKED_STATUS_PERMISSION_DENIED', 2);
16 define('HACKED_STATUS_HACKED', 3);
17 define('HACKED_STATUS_DELETED', 4);
18 define('HACKED_STATUS_UNHACKED', 5);
19
20 define('HACKED_DEFAULT_FILE_HASHER', 'hacked_ignore_line_endings');
21
22 /**
23  * Implementation of the hook_theme() registry.
24  */
25 function hacked_theme() {
26   return [
27     'hacked_report'          => [
28       'variables' => ['data' => NULL],
29       'file'      => 'hacked.report.inc',
30     ],
31     'hacked_project_summary' => [
32       'variables' => ['project' => NULL],
33       'file'      => 'hacked.report.inc',
34     ],
35     'hacked_detailed_report' => [
36       'variables' => ['project' => NULL],
37       'file'      => 'hacked.details.inc',
38     ],
39     'hacked_file_status'     => [
40       'variables' => ['file' => NULL],
41       'file'      => 'hacked.details.inc',
42     ],
43   ];
44 }
45
46 /**
47  * Sort callback for sorting the projects in the report.
48  */
49 function _hacked_project_report_sort_by_status($a, $b) {
50   if ($a['status'] == $b['status']) {
51     return strcmp($a['name'], $b['name']);
52   }
53   else {
54     return $a['status'] - $b['status'];
55   }
56 }
57
58 /**
59  * Determine if a file is a binary file.
60  *
61  * Taken from: http://www.ultrashock.com/forums/server-side/checking-if-a-file-is-binary-98391.html
62  * and then tweaked in: http://drupal.org/node/760362.
63  */
64 function hacked_file_is_binary($file) {
65   if (file_exists($file)) {
66     if (!is_file($file)) {
67       return 0;
68     }
69     if (!is_readable($file)) {
70       return 1;
71     }
72
73     $fh = fopen($file, "r");
74     $blk = fread($fh, 512);
75     fclose($fh);
76     clearstatcache();
77
78     return (
79       0 or substr_count($blk, "^\r\n") / 512 > 0.3
80       or substr_count($blk, "^ -~") / 512 > 0.3
81       or substr_count($blk, "\x00") > 0
82     );
83   }
84   return 0;
85 }
86
87 /**
88  * Hacked! version of the core function, can return hidden files too.
89  *
90  * @param           $dir
91  * @param           $mask
92  * @param array     $nomask
93  * @param int       $callback
94  * @param bool|TRUE $recurse
95  * @param string    $key
96  * @param int       $min_depth
97  * @param int       $depth
98  * @return array
99  *
100  * @see file_scan_directory().
101  */
102 function hacked_file_scan_directory($dir, $mask, $nomask = ['.', '..', 'CVS'], $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0) {
103   $key = (in_array($key, ['filename', 'basename', 'name']) ? $key : 'filename');
104   $files = [];
105
106   if (is_dir($dir) && $handle = opendir($dir)) {
107     while (FALSE !== ($file = readdir($handle))) {
108       if (!in_array($file, $nomask)) {
109         if (is_dir("$dir/$file") && $recurse) {
110           // Give priority to files in this folder by merging them in after any subdirectory files.
111           $files = array_merge(hacked_file_scan_directory("$dir/$file", $mask, $nomask, $callback, $recurse, $key, $min_depth, $depth + 1), $files);
112         }
113         elseif ($depth >= $min_depth && preg_match($mask, $file)) {
114           // Always use this match over anything already set in $files with the same $$key.
115           $filename = "$dir/$file";
116           $basename = basename($file);
117           $name = substr($basename, 0, strrpos($basename, '.'));
118           $files[$$key] = new stdClass();
119           $files[$$key]->filename = $filename;
120           $files[$$key]->basename = $basename;
121           $files[$$key]->name = $name;
122           if (is_callable($callback)) {
123             $callback($filename);
124           }
125         }
126       }
127     }
128
129     closedir($handle);
130   }
131
132   return $files;
133 }
134
135 /**
136  * Return the file hasher that is currently selected by the user.
137  */
138 function hacked_get_file_hasher($name = NULL) {
139   if (is_null($name)) {
140     $name = \Drupal::config('hacked.settings')->get('selected_file_hasher');
141   }
142   $hashers = hacked_get_file_hashers();
143   $class_name = $hashers[$name]['class'];
144   return new $class_name;
145 }
146
147 /**
148  * Gets all the file hashers defined.
149  */
150 function hacked_get_file_hashers() {
151   $hashers = &drupal_static(__FUNCTION__);
152   if (is_null($hashers)) {
153     $hashers = \Drupal::moduleHandler()->invokeAll('hacked_file_hashers_info');
154     \Drupal::moduleHandler()->alter('hacked_file_hashers_info', $hashers);
155   }
156   return $hashers;
157 }
158
159 /**
160  * Implements hook_hacked_file_hashers_info().
161  */
162 function hacked_hacked_file_hashers_info() {
163   $hashers = [];
164
165   $hashers['hacked_ignore_line_endings'] = [
166     'class'       => '\Drupal\hacked\hackedFileIgnoreEndingsHasher',
167     'name'        => t('Ignore line endings'),
168     'description' => t('When hashing files differences in line endings will be ignored. This might be useful if projects have been edited on a different platform than of the original author\'s. E.g. if a file has been opened and saved on Windows.'),
169   ];
170
171   $hashers['hacked_include_line_endings'] = [
172     'class'       => '\Drupal\hacked\hackedFileIncludeEndingsHasher',
173     'name'        => t('Include line endings'),
174     'description' => t('When hashing files differences in line endings will be included.'),
175   ];
176
177   return $hashers;
178 }