/[drupal]/contributions/modules/auditfiles/notindb.admin.inc
ViewVC logotype

Contents of /contributions/modules/auditfiles/notindb.admin.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Wed Jun 3 22:53:23 2009 UTC (5 months, 3 weeks ago) by mikeryan
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +109 -59 lines
File MIME type: text/x-php
#185904 by mikeryan - Add several new features
1 <?php
2 // $Id: notindb.admin.inc,v 1.1 2007/12/05 22:33:19 stuartgreenfield Exp $
3
4 /**
5 * @file
6 * Callback and functions to generate files not in database report
7 */
8
9
10 /**
11 * Menu callback: audit files not in the database.
12 */
13 function auditfiles_notindb() {
14 return drupal_get_form('auditfiles_notindb_form');
15 }
16
17
18 /**
19 * Form definition for audit files not in database
20 */
21 function auditfiles_notindb_form(&$form_state) {
22 if (isset($form_state['storage']['confirm'])) {
23 return auditfiles_notindb_form_confirm($form_state);
24 }
25 // Get the list of files that aren't in the database
26 $filesnotindb = _auditfiles_filesnotindb();
27
28 // Output count of files not in the database
29 if ($filesnotindb) {
30 $form['count'] = array(
31 '#value' => format_plural(count($filesnotindb), '1 file found.', '@count files found.'),
32 );
33 }
34 else {
35 $form['count'] = array(
36 '#value' => t('No files found.'),
37 );
38 }
39
40 // Action button
41 $form['options'] = array(
42 '#type' => 'fieldset',
43 '#title' => t('Action'),
44 '#prefix' => '<div class="container-inline">',
45 '#suffix' => '</div>',
46 );
47
48 $options = array(
49 'donothing' => t('Do nothing'),
50 'delete' => t('Delete checked files'),
51 'add' => t('Add checked files to database'),
52 'addall' => t('Add all files to database'),
53 );
54
55 $form['options']['operation'] = array(
56 '#type' => 'select',
57 '#options' => $options,
58 '#default_value' => 'donothing',
59 );
60
61 $form['options']['submit'] = array(
62 '#type' => 'submit',
63 '#value' => t('Update'),
64 );
65
66
67 // Process each result in turn and build check box list
68 $files_dir = file_directory_path();
69 $files=array();
70 foreach ($filesnotindb as $file) {
71 $files[$file] = '';
72
73 // Can't use file_create_url as the links fail if the site uses private transfers
74 // Force a public url instead
75 $form['file'][$file] = array('#value' => l($file, $GLOBALS['base_url'] .'/'. file_directory_path() .'/'. str_replace('\\', '/', $file)));
76 }
77
78 // Add list of files to checkboxes
79 $form['files'] = array('#type' => 'checkboxes', '#options' => $files);
80
81 // Return form
82 return $form;
83 }
84
85
86 /**
87 * Theme auditfiles_notindb_form
88 */
89 function theme_auditfiles_notindb_form($form) {
90 // Render count
91 $output .= drupal_render($form['count']);
92
93 // If there are files found
94 if (isset($form['file']) && is_array($form['file'])) {
95
96 // Render actions
97 $output .= drupal_render($form['options']);
98
99 // Construct table of files
100 $header = array(
101 t('Select'),
102 t('File'),
103 );
104
105 foreach (element_children($form['file']) as $key) {
106 $row = array();
107 $row[] = drupal_render($form['files'][$key]);
108 $row[] = drupal_render($form['file'][$key]);
109 $rows[] = $row;
110 }
111
112 // Render themed table
113 $output .= theme('table', $header, $rows);
114
115 }
116
117 $output .= drupal_render($form);
118
119 // Return output
120 return $output;
121 }
122
123 function auditfiles_notindb_form_submit($form, &$form_state) {
124 //drupal_set_message("submit form_state: ".dpr($form_state, TRUE));
125 if ($form_state['clicked_button']['#id'] == 'edit-submit' &&
126 $form_state['values']['options']['operation'] <> 'donothing') {
127 $form_state['storage']['confirm'] = TRUE;
128 $form_state['storage']['values'] = $form_state['values'];
129 }
130 }
131
132 function auditfiles_notindb_form_confirm(&$form_state) {
133 $values = $form_state['storage']['values'];
134 //drupal_set_message("form_confirm: values: ".dpr($values, TRUE));
135 $operation = $values['operation'];
136 switch ($operation) {
137 case 'delete':
138 $optype = 'delete';
139 $seltype = 'selected';
140 break;
141 case 'add':
142 $optype = 'add';
143 $seltype = 'selected';
144 break;
145 case 'addall':
146 $optype = 'add';
147 $seltype = 'all';
148 break;
149 case 'donothing':
150 default:
151 return;
152 }
153
154 $form['changelist'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
155
156 foreach ($values['files'] as $file => $selected) {
157 if ($seltype == 'all' || $selected) {
158 if ($optype == 'delete') {
159 $message = "<strong>$file</strong> will be deleted";
160 } else {
161 $message = "<strong>$file</strong> will be added to the database";
162 }
163 $form['changelist'][$file] = array('#type' => 'hidden', '#value' => $file, '#prefix' => '<li>', '#suffix' => $message ."</li>\n");
164 } else {
165 // Unsetting the unprocessed files prevents confirm_submit from dealing with them
166 unset($form_state['storage']['values']['files'][$file]);
167 }
168 }
169
170 $form['operation'] = array('#type' => 'hidden', '#value' => $operation);
171 $form['#submit'][] = 'auditfiles_notindb_form_confirm_submit';
172
173 return confirm_form(
174 $form,
175 t('Are you sure you want to make these changes?'),
176 'admin/reports/auditfiles/notindb',
177 '<strong>'. t('This action cannot be undone.') .'</strong>',
178 t('Process all'),
179 t('Cancel')
180 );
181 }
182
183 function auditfiles_notindb_form_confirm_submit($form, &$form_state) {
184 // drupal_set_message('confirm_submit, form: '.dpr($form, TRUE));
185 // drupal_set_message('confirm_submit, form_state: '.dpr($form_state, TRUE));
186 if ($form_state['values']['confirm']) {
187 $values = $form_state['storage']['values'];
188 $operation = $values['options']['operation'];
189 if ($operation != 'delete') {
190 global $user;
191 if (function_exists('finfo_file')) {
192 $finfo = @finfo_open(FILEINFO_MIME);
193 }
194 }
195 //drupal_set_message("in confirm_submit, values: ".dpr($values,TRUE));
196 foreach ($values['files'] as $filename => $selected) {
197 if ($operation == 'delete') {
198 if (file_delete(file_create_path($filename))) {
199 watchdog('audit', '%file was deleted', array('%file' => $filename));
200 }
201 else {
202 drupal_set_message(t('Failed to delete %file', array('%file' => $filename)));
203 }
204 } else {
205 $fullpath = file_create_path($filename);
206 $file = new stdClass();
207 $file->filename = trim(basename($filename));
208 $file->filepath = trim($fullpath);
209 // Adapted from imce
210 if ($finfo) {
211 $type = finfo_file($finfo, $fullpath);
212 } elseif ($info = @getimagesize($fullpath)) {
213 $type = $info['mime'];
214 } elseif (function_exists('mime_content_type')) {
215 $type = mime_content_type($fullpath);
216 } else {
217 $type = 'application/x-download';
218 }
219 $file->filemime = $type;
220 $file->filesize = filesize($fullpath);
221 $file->uid = $user->uid;
222 $file->status = FILE_STATUS_PERMANENT;
223 $file->timestamp = time();
224 drupal_write_record('files', $file);
225 }
226 }
227 if ($operation == 'delete') {
228 drupal_set_message(t('The files have been deleted.'));
229 } else {
230 drupal_set_message(t('The files have been added to the database.'));
231 }
232 // Clear so our return to the primary form doesn't think we're going to the confirmation form
233 unset($form_state['storage']['confirm']);
234 }
235 }
236
237 /**
238 * Helper function - retrieve sorted list of files that are on the server
239 * but not in the database
240 */
241 function _auditfiles_filesnotindb() {
242
243 // Prepare array to hold results
244 $filesnotindb = array();
245
246 // Get all the files out the {files} table and store as qualified path
247 $result = db_query('SELECT filepath FROM {files} ORDER BY filepath ASC');
248 $filesindb = array();
249 while ($file = db_fetch_object($result)) {
250 $filesindb[] = file_create_path($file->filepath);
251 }
252
253 // Get all the files out of the directory structure
254 $filesonserver = _auditfiles_directorytoarray(realpath(file_create_path()), TRUE);
255
256 // Sort the rows to make it easier to compare to file listing in FTP
257 asort($filesonserver);
258
259 // Get the root path - will need this later
260 $root .= realpath('./');
261
262 // Get the exclusions string
263 $exclusions = _auditfiles_get_exclusions();
264
265 // Process each result in turn
266 foreach ($filesonserver as $file) {
267
268 // Strip out the real path to leave just a drupal path
269 $file = preg_replace('@'.preg_quote($root).'.@', '', $file);
270
271 // Check it isn't a directory - not interested
272 if (!file_check_directory($file)) {
273
274 // Exclude files, paths and extensions according to the retrieved exclusions string
275 if (!preg_match('@'.$exclusions.'@', $file) || !$exclusions) {
276
277 // Check to see if file is NOT in the database
278 if (!in_array($file, $filesindb) ) {
279
280 // If we get here we have a file that isn't in the database
281 $file = preg_replace('@^'.preg_quote(file_directory_path()).'/@', '', $file);
282 $filesnotindb[] = $file;
283 }
284 }
285 }
286 }
287
288 return $filesnotindb;
289 }
290
291
292 /**
293 * Helper function - recurse directories and files in to an array
294 * http://snippets.dzone.com/posts/show/155
295 */
296 function _auditfiles_directorytoarray($directory, $recursive) {
297 $array_items = array();
298 if ($handle = opendir($directory)) {
299 while (false !== ($file = readdir($handle))) {
300 if ($file != "." && $file != "..") {
301 if (is_dir($directory. "/" . $file)) {
302 if($recursive) {
303 $array_items = array_merge($array_items, _auditfiles_directorytoarray($directory. "/" . $file, $recursive));
304 }
305 $file = $directory . "/" . $file;
306 $array_items[] = preg_replace("/\/\//si", "/", $file);
307 }
308 else {
309 $file = $directory . "/" . $file;
310 $array_items[] = preg_replace("/\/\//si", "/", $file);
311 }
312 }
313 }
314 closedir($handle);
315 }
316 return $array_items;
317 }
318
319
320 /**
321 * Helper function: create an exclusion string for the preg
322 */
323 function _auditfiles_get_exclusions() {
324
325 // Get exclusion lists from the variables table
326 $files = trim(variable_get('auditfiles_exclude_files', '.htaccess'));
327 $extensions = trim(variable_get('auditfiles_exclude_extensions', ''));
328 $paths = trim(variable_get('auditfiles_exclude_paths', 'color'));
329
330 // Prepare an empty array
331 $exclusions_array = array();
332
333 // Create file exclusions as required
334 if ($files) {
335 $exclude_files = explode(' ', $files);
336 array_walk($exclude_files, '_auditfiles_make_preg', FALSE);
337 $exclusions_array = array_merge($exclusions_array, $exclude_files);
338 }
339
340 // Create path exclusions as required
341 if ($paths) {
342 $exclude_paths = explode(' ', $paths);
343 array_walk($exclude_paths, '_auditfiles_make_preg', TRUE);
344 $exclusions_array = array_merge($exclusions_array, $exclude_paths);
345 }
346
347 // Create extension exclusions as required (this is a little more complicated)
348 if ($extensions) {
349 // Prepare initial string as for files and paths
350 $exclude_extensions = explode(' ', $extensions);
351 array_walk($exclude_extensions, '_auditfiles_make_preg', FALSE);
352 $extensions = implode('|', $exclude_extensions);
353
354 // Add grouping around string, add end marker, and append to exlusions_array
355 $extensions = '(' . $extensions . ')$';
356 $exclusions_array[] = $extensions;
357
358 }
359
360 // Implode exclusions array to a string
361 $exclusions = implode('|', $exclusions_array);
362
363 // Return prepared exclusion string
364 return $exclusions;
365
366 }
367
368
369 /**
370 * Helper function: walk an array and preg_quote each entry
371 * Pass $makefilepath = TRUE to change elements to file paths at the same time
372 */
373 function _auditfiles_make_preg(&$element, $key, $makefilepath = FALSE) {
374 if ($makefilepath) {
375 $element = file_create_path($element);
376 }
377 $element = preg_quote($element);
378 }

  ViewVC Help
Powered by ViewVC 1.1.2