web/drupal/modules/imce/inc/page.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: page.inc,v 1.10.2.21 2009/02/20 00:44:05 ufku Exp $
       
     3 
       
     4 /**
       
     5  * q = imce.
       
     6  */
       
     7 function imce_page() {
       
     8   $jsop = isset($_GET['jsop']) ? $_GET['jsop'] : NULL;
       
     9   print theme('imce_page', imce_content($GLOBALS['user'], $jsop));
       
    10   exit();
       
    11 }
       
    12 
       
    13 /**
       
    14  * q = user/x/imce.
       
    15  */
       
    16 function imce_user_page($account) {
       
    17   drupal_set_title($account->name);
       
    18   $jsop = isset($_GET['jsop']) ? $_GET['jsop'] : NULL;
       
    19   return imce_content($account, $jsop);
       
    20 }
       
    21 
       
    22 /**
       
    23  * Content of the file browser.
       
    24  */
       
    25 function imce_content($user, $jsop = '') {
       
    26 
       
    27   //execute ajax calls.
       
    28   if ($jsop) {
       
    29     return imce_js($user, $jsop);
       
    30   }
       
    31 
       
    32   //initiate configuration profile
       
    33   if (!$imce = imce_initiate_profile($user)) {
       
    34     return '';
       
    35   }
       
    36   imce_process_profile($imce);//get active directory content
       
    37 
       
    38   //Before creating the content let's add main files required for imce to function properly.
       
    39   drupal_add_js('misc/jquery.form.js');
       
    40   drupal_add_js(drupal_get_path('module', 'imce') .'/js/imce.js');
       
    41 
       
    42   //process forms.
       
    43   //reference imce inside an array so it will stay referenced during argument copy of drupal_get_form
       
    44   //when php4-support drops(dr7?), use an object with no reference.
       
    45   $imce_ref = array('imce' => &$imce);
       
    46   $forms = '';
       
    47 
       
    48   if (!$imce['error']) {
       
    49     //process file upload.
       
    50     if (imce_perm_exists($imce, 'upload')) {
       
    51       $forms .= drupal_get_form('imce_upload_form', $imce_ref);
       
    52     }
       
    53     //process file operations.
       
    54     $forms .= drupal_get_form('imce_fileop_form', $imce_ref);
       
    55   }
       
    56 
       
    57   //run custom content functions. possible to insert extra forms. content is invisible when js is enabled.
       
    58   foreach (variable_get('imce_custom_content', array()) as $func => $state) {
       
    59     if ($state && function_exists($func) && $output = $func($imce)) {
       
    60       $forms .= $output;
       
    61     }
       
    62   }
       
    63 
       
    64   $content = theme('imce_content', imce_create_tree($imce), $forms, $imce_ref);
       
    65 
       
    66   //make necessary changes for js conversion
       
    67   $imce['dir'] = str_replace('%2F', '/', rawurlencode($imce['dir']));
       
    68   unset($imce['files'], $imce['name'], $imce['directories'], $imce['subdirectories'], $imce['filesize'], $imce['quota'], $imce['tuquota'], $imce['thumbnails'], $imce['uid']);
       
    69 
       
    70   drupal_add_js($imce_ref, 'setting');
       
    71 
       
    72   return $content;
       
    73 }
       
    74 
       
    75 /**
       
    76  * Ajax operations. q=imce&jsop={op}
       
    77  */
       
    78 function imce_js($user, $jsop = '') {
       
    79   $response = array();
       
    80 
       
    81   //data
       
    82   if ($imce = imce_initiate_profile($user)) {
       
    83     imce_process_profile($imce);
       
    84     if (!$imce['error']) {
       
    85       include_once './'. drupal_get_path('module', 'imce') .'/inc/js.inc';
       
    86       if (function_exists($func = 'imce_js_'. $jsop)) {
       
    87         $response['data'] = $func($imce);
       
    88       }
       
    89     }
       
    90   }
       
    91   //messages
       
    92   $response['messages'] = drupal_get_messages();
       
    93 
       
    94   //for upload we must return plain text header.
       
    95   drupal_set_header('Content-Type: text/'. ($jsop == 'upload' ? 'html' : 'javascript') .'; charset=utf-8');
       
    96   print drupal_to_js($response);
       
    97   exit();
       
    98 }
       
    99 
       
   100 /**
       
   101  * Upload form.
       
   102  */
       
   103 function imce_upload_form(&$form_state, $ref) {
       
   104   $imce =& $ref['imce'];
       
   105   $form['imce'] = array(
       
   106     '#type' => 'file',
       
   107     '#title' => t('File'),
       
   108     '#size' => 30,
       
   109     '#prefix' => '<div class="container-inline">',
       
   110   );
       
   111   $form['upload'] = array(
       
   112     '#type' => 'submit',
       
   113     '#value' => t('Upload'),
       
   114     '#submit' => $imce['perm']['upload'] ? array('imce_upload_submit') : NULL,//permission for submission
       
   115     '#suffix' => '</div>',
       
   116   );
       
   117   if (!empty($imce['thumbnails'])) {
       
   118     $form['thumbnails'] = array(
       
   119       '#type' => 'checkboxes',
       
   120       '#title' => t('Create thumbnails'),
       
   121       '#options' => imce_thumbnail_options($imce['thumbnails']),
       
   122     );
       
   123   }
       
   124   $form = array('fset_upload' => array('#type' => 'fieldset', '#title' => t('Upload file')) + $form);
       
   125   $form['#attributes']['enctype'] = 'multipart/form-data';
       
   126   $form['#action'] = $imce['url'];
       
   127   return $form;
       
   128 }
       
   129 
       
   130 /**
       
   131  * File operations form.
       
   132  */
       
   133 function imce_fileop_form(&$form_state, $ref) {
       
   134   $imce =& $ref['imce'];
       
   135   $form['filenames'] = array(
       
   136     '#type' => 'textfield',
       
   137     '#title' => t('Selected files'),
       
   138     '#maxlength' => $imce['filenum'] ? $imce['filenum']*255 : NULL,
       
   139   );
       
   140 
       
   141   //thumbnail
       
   142   if (!empty($imce['thumbnails']) && imce_perm_exists($imce, 'thumb')) {
       
   143     $form['fset_thumb'] = array(
       
   144       '#type' => 'fieldset',
       
   145       '#title' => t('Thumbnails'),
       
   146     ) + imce_thumb_form($imce);
       
   147   }
       
   148 
       
   149   //delete
       
   150   if (imce_perm_exists($imce, 'delete')) {
       
   151     $form['fset_delete'] = array(
       
   152       '#type' => 'fieldset',
       
   153       '#title' => t('Delete'),
       
   154     ) + imce_delete_form($imce);
       
   155   }
       
   156 
       
   157   //resize
       
   158   if (imce_perm_exists($imce, 'resize')) {
       
   159     $form['fset_resize'] = array(
       
   160       '#type' => 'fieldset',
       
   161       '#title' => t('Resize'),
       
   162     ) + imce_resize_form($imce);
       
   163   }
       
   164  
       
   165   $form['#action'] = $imce['url'];
       
   166   return $form;
       
   167 }
       
   168 
       
   169 /**
       
   170  * Thumbnail form.
       
   171  */
       
   172 function imce_thumb_form(&$imce) {
       
   173   $form['thumbnails'] = array(
       
   174     '#type' => 'checkboxes',
       
   175     '#title' => t('Thumbnails'),
       
   176     '#options' => imce_thumbnail_options($imce['thumbnails']),
       
   177   );
       
   178   $form['thumb'] = array(
       
   179     '#type' => 'submit',
       
   180     '#value' => t('Create thumbnails'),
       
   181     '#submit' => $imce['perm']['thumb'] ? array('imce_thumb_submit') : NULL,//permission for submission
       
   182   );
       
   183   return $form;
       
   184 }
       
   185 
       
   186 /**
       
   187  * Delete form.
       
   188  */
       
   189 function imce_delete_form(&$imce) {
       
   190   $form['delete'] = array(
       
   191     '#type' => 'submit',
       
   192     '#value' => t('Delete'),
       
   193     '#submit' => $imce['perm']['delete'] ? array('imce_delete_submit') : NULL,//permission for submission
       
   194   );
       
   195   return $form;
       
   196 }
       
   197 
       
   198 /**
       
   199  * Resizing form.
       
   200  */
       
   201 function imce_resize_form(&$imce) {
       
   202   $form['width'] = array(
       
   203     '#type' => 'textfield',
       
   204     '#title' => t('Width x Height'),
       
   205     '#size' => 5,
       
   206     '#maxlength' => 4,
       
   207     '#prefix' => '<div class="container-inline">',
       
   208   );
       
   209   $form['height'] = array(
       
   210     '#type' => 'textfield',
       
   211     '#size' => 5,
       
   212     '#maxlength' => 4,
       
   213     '#prefix' => 'x',
       
   214   );
       
   215   $form['resize'] = array(
       
   216     '#type' => 'submit',
       
   217     '#value' => t('Resize'),
       
   218     '#submit' => $imce['perm']['resize'] ? array('imce_resize_submit') : NULL,//permission for submission
       
   219     '#suffix' => '</div>',
       
   220   );
       
   221   $form['copy'] = array(
       
   222     '#type' => 'checkbox',
       
   223     '#title' => t('Create a new image'),
       
   224     '#default_value' => 1,
       
   225   );
       
   226   return $form;
       
   227 }
       
   228 
       
   229 /**
       
   230  * Validate file operations form.
       
   231  */
       
   232 function imce_fileop_form_validate($form, &$form_state) {
       
   233   $imce =& $form['#parameters'][2]['imce'];
       
   234 
       
   235   //check if the filenames is empty
       
   236   if ($form_state['values']['filenames'] == '') {
       
   237     return form_error($form['filenames'], t('Please select a file.'));
       
   238   }
       
   239 
       
   240   //filenames come seperated by colon
       
   241   $filenames = explode(':', $form_state['values']['filenames']);
       
   242   $cnt = count($filenames);
       
   243   //check the number of files.
       
   244   if ($imce['filenum'] && $cnt > $imce['filenum']) {
       
   245     return form_error($form['filenames'], t('You are not allowed to operate on more than %num files.', array('%num' => $imce['filenum'])));
       
   246   }
       
   247 
       
   248   //check if there is any illegal choice
       
   249   for ($i = 0; $i < $cnt; $i++) {
       
   250     $filenames[$i] = $filename = rawurldecode($filenames[$i]);
       
   251     if (!isset($imce['files'][$filename])) {
       
   252       watchdog('imce', 'Illegal choice %choice in !name element.', array('%choice' => $filename, '!name' => t('directory (%dir)', array('%dir' => file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir'])))), WATCHDOG_ERROR);
       
   253       return form_error($form['filenames'], t('An illegal choice has been detected. Please contact the site administrator.'));
       
   254     }
       
   255   }
       
   256 
       
   257   $form_state['values']['filenames'] = $filenames;
       
   258 }
       
   259 
       
   260 /**
       
   261  * Submit upload form.
       
   262  */
       
   263 function imce_upload_submit($form, &$form_state) {
       
   264   $form_state['redirect'] = FALSE;
       
   265   $imce =& $form['#parameters'][2]['imce'];
       
   266   $validators = array('imce_validate_all' => array(&$imce));
       
   267   $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']);
       
   268 
       
   269   //save uploaded file.
       
   270   $replace = variable_get('imce_settings_replace', FILE_EXISTS_RENAME);
       
   271   if ($file = file_save_upload('imce', $validators, $dirpath, $replace)) {
       
   272 
       
   273     //core bug #203204.
       
   274     @chmod($file->filepath, 0664);
       
   275 
       
   276     //core bug #54223.
       
   277     if ($replace == FILE_EXISTS_RENAME) {
       
   278       $name = basename($file->filepath);
       
   279       if ($name != $file->filename) {
       
   280         $file->filename = $name;
       
   281         drupal_set_message(t('The file is renamed to %filename.', array('%filename' => $file->filename)));
       
   282       }
       
   283     }
       
   284     else if ($replace == FILE_EXISTS_REPLACE) {//check duplicates
       
   285       if ($_file = db_fetch_object(db_query("SELECT fid FROM {files} WHERE filepath = '%s' AND fid <> %d", $file->filepath, $file->fid))) {
       
   286         db_query("DELETE FROM {files} WHERE fid = %d", $file->fid);
       
   287         $file->fid = $_file->fid;
       
   288       }
       
   289     }
       
   290 
       
   291     $file->uid = $imce['uid'];//global user may not be the owner.
       
   292     $file->status = FILE_STATUS_PERMANENT;//make permanent
       
   293     drupal_write_record('files', $file, array('fid'));//update
       
   294     drupal_set_message(t('%filename is uploaded.', array('%filename' => $file->filename)));
       
   295 
       
   296     //update file list
       
   297     $img = imce_image_info($file->filepath);
       
   298     $file->width = $img ? $img['width'] : 0;
       
   299     $file->height = $img ? $img['height'] : 0;
       
   300     imce_add_file($file, $imce);
       
   301 
       
   302     //create thumbnails
       
   303     if (isset($form_state['values']['thumbnails']) && $img) {
       
   304       imce_create_thumbnails($file->filename, $imce, $form_state['values']['thumbnails']);
       
   305     }
       
   306   }
       
   307   else {
       
   308     drupal_set_message(t('Upload failed.'), 'error');
       
   309   }
       
   310 }
       
   311 
       
   312 /**
       
   313  * Submit thumbnail form.
       
   314  */
       
   315 function imce_thumb_submit($form, &$form_state) {
       
   316   $form_state['redirect'] = FALSE;
       
   317   $imce =& $form['#parameters'][2]['imce'];
       
   318   //create thumbnails
       
   319   imce_process_files($form_state['values']['filenames'], $imce, 'imce_create_thumbnails', array($form_state['values']['thumbnails']));
       
   320 }
       
   321 
       
   322 /**
       
   323  * Submit delete form.
       
   324  */
       
   325 function imce_delete_submit($form, &$form_state) {
       
   326   $form_state['redirect'] = FALSE;
       
   327   $imce =& $form['#parameters'][2]['imce'];
       
   328 
       
   329   $deleted = imce_process_files($form_state['values']['filenames'], $imce, 'imce_delete_file');
       
   330 
       
   331   if (!empty($deleted)) {
       
   332     drupal_set_message(t('File deletion successful: %files.', array('%files' => utf8_encode(implode(', ', $deleted)))));
       
   333   }
       
   334 
       
   335 }
       
   336 
       
   337 /**
       
   338  * Submit resize form.
       
   339  */
       
   340 function imce_resize_submit($form, &$form_state) {
       
   341   $form_state['redirect'] = FALSE;
       
   342   $imce =& $form['#parameters'][2]['imce'];
       
   343 
       
   344   //check dimensions
       
   345   $width = (int) $form_state['values']['width'];
       
   346   $height = (int) $form_state['values']['height'];
       
   347   list($maxw, $maxh) = explode('x', $imce['dimensions']);
       
   348   if ($width < 1 || $height < 1 || ($maxw && ($width > $maxw || $height > $maxh))) {
       
   349     drupal_set_message(t('Please specify dimensions within the allowed range that is from 1x1 to @dimensions.', array('@dimensions' => $imce['dimensions'] ? $imce['dimensions'] : t('unlimited'))), 'error');
       
   350     return;
       
   351   }
       
   352 
       
   353   $resized = imce_process_files($form_state['values']['filenames'], $imce, 'imce_resize_image', array($width, $height, $form_state['values']['copy']));
       
   354 
       
   355   if (!empty($resized)) {
       
   356     drupal_set_message(t('File resizing successful: %files.', array('%files' => utf8_encode(implode(', ', $resized)))));
       
   357   }
       
   358 
       
   359 }
       
   360 
       
   361 /**
       
   362  * Do batch operations on files.
       
   363  * Used by delete, resize, create thumbnail submissions.
       
   364  */
       
   365 function imce_process_files($filenames, &$imce, $function, $args = array()) {
       
   366   $args = array_merge(array('', &$imce), $args);
       
   367   $processed = array();
       
   368 
       
   369   foreach ($filenames as $filename) {
       
   370     $args[0] = $filename;
       
   371     if (call_user_func_array($function, $args)) {
       
   372       $processed[] = $filename;
       
   373     }
       
   374   }
       
   375 
       
   376   return $processed;
       
   377 }
       
   378 
       
   379 /**
       
   380  * Delete a file in the file list.
       
   381  */
       
   382 function imce_delete_file($filename, &$imce) {
       
   383   $filepath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']) .'/'. $filename;
       
   384   if (!file_delete($filepath)) {
       
   385     return FALSE;
       
   386   }
       
   387   db_query("DELETE FROM {files} WHERE filepath = '%s'", $filepath);
       
   388   imce_remove_file($filename, $imce);
       
   389   return TRUE;
       
   390 }
       
   391 
       
   392 /**
       
   393  * Create all selected thumbnails.
       
   394  */
       
   395 function imce_create_thumbnails($filename, &$imce, $values) {
       
   396   $created = array();
       
   397   foreach ($imce['thumbnails'] as $thumbnail) {
       
   398     if ($values[$thumbnail['name']] && imce_create_thumbnail($filename, $imce, $thumbnail)) {
       
   399       $created[] = $thumbnail['name'];
       
   400     }
       
   401   }
       
   402   if (!empty($created)) {
       
   403   drupal_set_message(t('Thumbnail creation (%thumbnames) successful for %filename.', array('%thumbnames' => implode(', ', $created), '%filename' => utf8_encode($filename))));
       
   404   }
       
   405   return $created;
       
   406 }
       
   407 
       
   408 /**
       
   409  * Create a thumbnail.
       
   410  */
       
   411 function imce_create_thumbnail($filename, &$imce, $thumbnail) {
       
   412   //generate thumbnail name
       
   413   $name = $thumbnail['prefix'];
       
   414   if ($thumbnail['suffix'] != '' && $dot = strrpos($filename, '.')) {
       
   415     $name .= substr($filename, 0, $dot);
       
   416     $name .= $thumbnail['suffix'];
       
   417     $name .= substr($filename, $dot);
       
   418   }
       
   419   else {
       
   420     $name .= $filename;
       
   421   }
       
   422   //scale the image
       
   423   list($width, $height) = explode('x', $thumbnail['dimensions']);
       
   424   return imce_resize_image($filename, $imce, $width, $height, TRUE, $name, variable_get('imce_settings_thumb_method', 'scale_and_crop'));
       
   425 }
       
   426 
       
   427 /**
       
   428  * Resize an image in the file list. Also used for thumbnail creation.
       
   429  */
       
   430 function imce_resize_image($filename, &$imce, $width, $height, $copy = TRUE, $dest = FALSE, $op = 'resize') {
       
   431   $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']);
       
   432   $filepath = $dirpath .'/'. $filename;
       
   433 
       
   434   //check if the file is an image
       
   435   if (!$imce['files'][$filename]['width'] || !$img = imce_image_info($filepath)) {
       
   436     drupal_set_message(t('%filename is not an image.', array('%filename' => utf8_encode($filename))), 'error', FALSE);
       
   437     return FALSE;
       
   438   }
       
   439 
       
   440   if (substr($op, 0, 5) == 'scale' && !($width < $img['width'] || $height < $img['height'])) {
       
   441     drupal_set_message(t('Scaling up is not allowed.'), 'error', FALSE);
       
   442     return FALSE;
       
   443   }
       
   444 
       
   445   //create file object
       
   446   $file = new stdClass();
       
   447   $file->filepath = $dirpath .'/'. $dest;
       
   448   if (!$dest || $dest == $filename) {
       
   449     $file->filepath = $copy ? file_create_filename($filename, $dirpath) : $filepath;
       
   450   }
       
   451   $file->filename = basename($file->filepath);
       
   452 
       
   453   //check if a file having the same properties exists already.
       
   454   if (isset($imce['files'][$file->filename])) {
       
   455     if (($f = $imce['files'][$file->filename]) && $f['width'] == $width && $f['height'] == $height) {
       
   456       drupal_set_message(t('%filename(%dimensions) already exists.', array('%filename' => utf8_encode($file->filename), '%dimensions' => $width .'x'. $height)), 'error');
       
   457       return FALSE;
       
   458     }
       
   459   }
       
   460 
       
   461   //validate file name
       
   462   $errors = file_validate_name_length($file);
       
   463   if (!empty($errors)) {
       
   464     drupal_set_message($errors[0], 'error');
       
   465     return FALSE;
       
   466   }
       
   467 
       
   468   //resize image to a temp file
       
   469   $temp = tempnam(realpath(file_directory_temp()), 'imc');
       
   470   register_shutdown_function('file_delete', $temp);
       
   471   $function = 'image_'. $op;
       
   472   if (!$function($filepath, $temp, $width, $height)) {
       
   473     drupal_set_message(t('%filename cannot be resized to %dimensions', array('%filename' => utf8_encode($filename), '%dimensions' => $width .'x'. $height)), 'error', FALSE);
       
   474     return FALSE;
       
   475   }
       
   476 
       
   477   //validate quota
       
   478   $file->filesize = filesize($temp);
       
   479   $overwrite = $file->filename == $filename;
       
   480   if (!imce_validate_quotas($file, $imce, $overwrite ? -$imce['files'][$filename]['size'] : 0)) {
       
   481     return FALSE;
       
   482   }
       
   483 
       
   484   //copy from temp to filepath
       
   485   if (!@copy($temp, $file->filepath)) {
       
   486     drupal_set_message(t('The selected file %file could not be copied.', array('%file' => utf8_encode($file->filename))), 'error', FALSE);
       
   487     return FALSE;
       
   488   }
       
   489   @chmod($file->filepath, 0664);
       
   490 
       
   491   //build the rest of the file object
       
   492   $file->uid = $imce['uid'];
       
   493   $file->filemime = $img['mime'];
       
   494   $file->status = FILE_STATUS_PERMANENT;
       
   495   $file->timestamp = time();
       
   496 
       
   497   //if we are overwriting the file and it is already in database.
       
   498   $update = array();
       
   499   if ($overwrite && $_file = db_fetch_object(db_query("SELECT f.* FROM {files} f WHERE f.filepath = '%s'", $file->filepath))) {
       
   500     $file->fid = $_file->fid;
       
   501     $file->uid = $_file->uid;
       
   502     $update[] = 'fid';
       
   503   }
       
   504 
       
   505   //save the file
       
   506   drupal_write_record('files', $file, $update);
       
   507 
       
   508   //update file list
       
   509   //if the file was scaled get the new dimensions
       
   510   if ($op == 'scale') {
       
   511     $img = imce_image_info($file->filepath);
       
   512     $width = $img['width'];
       
   513     $height = $img['height'];
       
   514   }
       
   515   $file->width = $width;
       
   516   $file->height = $height;
       
   517   imce_add_file($file, $imce);
       
   518 
       
   519   return $file;
       
   520 }
       
   521 
       
   522 /**
       
   523  * Add a new file to the file list.
       
   524  */
       
   525 function imce_add_file($file, &$imce) {
       
   526   $imce['dirsize'] += $file->filesize;
       
   527   if (isset($imce['files'][$file->filename])) {
       
   528     $imce['dirsize'] -= $imce['files'][$file->filename]['size'];
       
   529   }
       
   530   $imce['files'][$file->filename] = array(
       
   531     'name' => $file->filename,
       
   532     'size' => $file->filesize,
       
   533     'width' => $file->width,
       
   534     'height' => $file->height,
       
   535     'date' => $file->timestamp
       
   536   );
       
   537   if (isset($_GET['jsop'])) {
       
   538     $add = $imce['files'][$file->filename];
       
   539     $add['name'] = rawurlencode($file->filename);
       
   540     $add['fsize'] = format_size($file->filesize);
       
   541     $add['fdate'] = format_date($file->timestamp, 'small');
       
   542     $imce['added'][] = $add;
       
   543   }
       
   544 }
       
   545 
       
   546 /**
       
   547  * Remove a file from the file list.
       
   548  */
       
   549 function imce_remove_file($filename, &$imce) {
       
   550   if (isset($imce['files'][$filename])) {
       
   551     $imce['dirsize'] -= $imce['files'][$filename]['size'];
       
   552     unset($imce['files'][$filename]);
       
   553     if (isset($_GET['jsop'])) {
       
   554       $imce['removed'][] = rawurlencode($filename);
       
   555     }
       
   556   }
       
   557 }
       
   558 
       
   559 /**
       
   560  * Validate uploaded file.
       
   561  */
       
   562 function imce_validate_all(&$file, $imce) {
       
   563 
       
   564   //fix FILE_EXISTS_ERROR bug. core bug #54223.
       
   565   if (!$file->destination && variable_get('imce_settings_replace', FILE_EXISTS_RENAME) == FILE_EXISTS_ERROR) {
       
   566     return array(t('File browser is set to reject the upload of existing files.'));
       
   567   }
       
   568 
       
   569   //validate image resolution only if filesize validation passes.
       
   570   //because user might have uploaded a very big image
       
   571   //and scaling it may exploit system memory.
       
   572   $errors = imce_validate_filesize($file, $imce['filesize']);
       
   573   if (empty($errors)) {//image resolution validation
       
   574     $errors = array_merge($errors, file_validate_image_resolution($file, $imce['dimensions']));
       
   575   }
       
   576   if ($imce['quota']) {//directory quota validation
       
   577     $errors = array_merge($errors, imce_validate_quota($file, $imce['quota'], $imce['dirsize']));
       
   578   }
       
   579   if ($imce['extensions'] != '*' && !preg_match('/\.('. str_replace(' ', '|', $imce['extensions']) .')$/i', $file->filename)) {
       
   580     $errors[] = t('Only files with the following extensions are allowed: %files-allowed.', array('%files-allowed' => $imce['extensions']));
       
   581   }
       
   582   if (empty($errors) && $imce['tuquota']) {//total user quota validation. check everything before hitting the DB
       
   583     $errors = array_merge($errors, imce_validate_quota($file, $imce['tuquota'], file_space_used($imce['uid']), 1));
       
   584   }
       
   585   return $errors;
       
   586 }
       
   587 
       
   588 /**
       
   589  * Validate filesize for maximum allowed file size.
       
   590  */
       
   591 function imce_validate_filesize($file, $maxsize = 0) {
       
   592   $errors = array();
       
   593   if ($maxsize && $file->filesize > $maxsize) {
       
   594     $errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($maxsize)));
       
   595   }
       
   596   return $errors;
       
   597 }
       
   598 
       
   599 /**
       
   600  * Validate filesize for directory and total user quota.
       
   601  */
       
   602 function imce_validate_quota($file, $quota = 0, $current = 0, $type = 0) {
       
   603   $errors = array();
       
   604   if ($quota && ($current + $file->filesize) > $quota) {
       
   605     $qtypes = array('Directory quota', 'Total user quota');
       
   606     $errors[] = t('%filename is %filesize which would exceed your %quota_type. You are currently using %size of %quota.', array('%size' => format_size($current), '%quota' => format_size($quota), '%filesize' => format_size($file->filesize), '%filename' => utf8_encode($file->filename), '%quota_type' => t(isset($qtypes[$type]) ? $qtypes[$type] : 'quota')));
       
   607   }
       
   608   return $errors;
       
   609 }
       
   610 
       
   611 /**
       
   612  * Validate both directory and total user quota. Returns true/false not errors.
       
   613  */
       
   614 function imce_validate_quotas($file, &$imce, $add = 0) {
       
   615   $errors = imce_validate_quota($file, $imce['quota'], $imce['dirsize'] + $add);
       
   616   if (empty($errors) && $imce['tuquota']) {
       
   617     $errors = imce_validate_quota($file, $imce['tuquota'], file_space_used($imce['uid']) + $add, 1);
       
   618   }
       
   619   if (!empty($errors)) {
       
   620     drupal_set_message($errors[0], 'error');
       
   621     return FALSE;
       
   622   }
       
   623   return TRUE;
       
   624 }
       
   625 
       
   626 /**
       
   627  * Check if the file is an image and return info.
       
   628  */
       
   629 function imce_image_info($file) {
       
   630   if (is_file($file) && ($dot = strrpos($file, '.')) && in_array(strtolower(substr($file, $dot+1)), array('jpg', 'jpeg', 'gif', 'png')) && ($info = @getimagesize($file)) && in_array($info[2], array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG)) ) {
       
   631     return array('width' => $info[0], 'height' => $info[1], 'type' => $info[2], 'mime' => $info['mime']);
       
   632   }
       
   633   return FALSE;
       
   634 }
       
   635 
       
   636 /**
       
   637  * Return thumbnails as options to be used in upload form.
       
   638  */
       
   639 function imce_thumbnail_options($thumbs = array()) {
       
   640   $options = array();
       
   641   foreach ($thumbs as $thumb) {
       
   642     $options[$thumb['name']] = $thumb['name'] .' ('. $thumb['dimensions'] .')';
       
   643   }
       
   644   return $options;
       
   645 }
       
   646 
       
   647 /**
       
   648  * Initiate and return configuration profile for the $user.
       
   649  */
       
   650 function imce_initiate_profile($user) {
       
   651 
       
   652   //check user profile and translate tokens in directory paths and evaluate php paths.
       
   653   if ($imce = imce_user_profile($user)) {
       
   654     $imce['directories'] = imce_process_directories($imce['directories'], $user);
       
   655     if (!empty($imce['directories'])) {
       
   656       $imce['uid'] = (int)$user->uid;
       
   657       $imce['url'] = url($_GET['q']);
       
   658       $imce['clean'] = variable_get('clean_url', 0) == 1;
       
   659       $imce['prvt'] = variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE;
       
   660       $imce['furl'] = $imce['prvt'] ? url('system/files') : base_path() . file_directory_path();
       
   661       if (variable_get('imce_settings_absurls', 0)) {
       
   662         $imce['furl'] = $GLOBALS['base_root'] . $imce['furl'];
       
   663       }
       
   664       $imce['filesize'] *= 1048576;//convert from Mb to byte
       
   665       $imce['quota'] *= 1048576;
       
   666       $imce['tuquota'] *= 1048576;
       
   667       $imce['filenum'] = (int) $imce['filenum'];
       
   668       //check and set the active directory
       
   669       if ($info = imce_working_directory($imce)) {
       
   670         $imce['direct'] = isset($imce['directories'][$info['name']]);
       
   671         $imce['directories'][$info['name']] = $info;
       
   672         $imce['dir'] = $info['name'];
       
   673         $imce['perm'] = $info;//copy permissions of the active directory.
       
   674         unset($imce['perm']['name']);
       
   675       }
       
   676       else {
       
   677         drupal_set_message(t('Unable to get a working directory for the file browser!'), 'error');
       
   678         $imce['dir'] = FALSE;
       
   679         $imce['error'] = TRUE;
       
   680       }
       
   681       return $imce;
       
   682     }
       
   683     drupal_set_message(t('There is no valid directory specified for the file browser!'), 'error');
       
   684   }
       
   685   else {
       
   686     drupal_set_message(t('You don\'t have access to any configuration profile to use the file browser!'), 'error');
       
   687   }
       
   688 
       
   689   return FALSE;
       
   690 }
       
   691 
       
   692 /**
       
   693  * Get files and folders of the actve directory. Do custom processing.
       
   694  */
       
   695 function imce_process_profile(&$imce) {
       
   696   //get directory content. do a custom scan if it is set
       
   697   $scan = ($scan = variable_get('imce_custom_scan', '')) && function_exists($scan) ? $scan : 'imce_scan_directory';
       
   698   $imce += $scan($imce['dir'], $imce);
       
   699 
       
   700   //run custom process functions
       
   701   foreach (variable_get('imce_custom_process', array()) as $func => $state) {
       
   702     if ($state && function_exists($func)) {
       
   703       $func($imce);
       
   704     }
       
   705   }
       
   706 
       
   707   //set subdirectories
       
   708   if (!$imce['error'] && !imce_subdirectories_accessible($imce)) {
       
   709     $imce['subdirectories'] = array();
       
   710   }
       
   711 }
       
   712 
       
   713 /**
       
   714  * Translate tokens and evaluate php in directory names.
       
   715  * Return an associative array of directories (dirname => info)
       
   716  */
       
   717 function imce_process_directories($directories, $user) {
       
   718   $paths = array();
       
   719   $translate = array('%uid' => $user->uid);
       
   720 
       
   721   foreach ($directories as $directory) {
       
   722     if (substr($directory['name'], 0, 4) == 'php:') {
       
   723       //not using drupal_eval since we need $user to be accessible as it may be different from $GLOBALS['user']
       
   724       $directory['name'] = eval(substr($directory['name'], 4));
       
   725      //php may return an array of directories
       
   726       if (is_array($directory['name'])) {
       
   727         foreach ($directory['name'] as $name) {
       
   728           $paths[$name] = array('name' => $name) + $directory;
       
   729         }
       
   730         continue;
       
   731       }
       
   732     }
       
   733     else {
       
   734       $directory['name'] = strtr($directory['name'], $translate);
       
   735     }
       
   736     if ($directory['name']) {
       
   737       $paths[$directory['name']] = $directory;
       
   738     }
       
   739   }
       
   740 
       
   741   return $paths;
       
   742 }
       
   743 
       
   744 /**
       
   745  * Return an avaliable directory for the profile.
       
   746  */
       
   747 function imce_working_directory($imce) {
       
   748   //check GET.
       
   749   if (isset($_GET['dir'])) {
       
   750     if ($info = imce_directory_info($_GET['dir'], $imce)) {
       
   751       if (imce_check_directory($_GET['dir'])) {
       
   752         $_SESSION['imce_directory'] = rawurlencode($info['name']);
       
   753       }
       
   754       else {
       
   755         $info = FALSE;
       
   756       }
       
   757     }
       
   758     else {
       
   759       imce_inaccessible_directory($_GET['dir']);
       
   760     }
       
   761     return $info;
       
   762   }
       
   763 
       
   764   //check session
       
   765   if (isset($_SESSION['imce_directory'])) {
       
   766     $dirname = rawurldecode($_SESSION['imce_directory']);
       
   767     if ($info = imce_directory_info($dirname, $imce)) {
       
   768       if (imce_check_directory($dirname)) {
       
   769         return $info;
       
   770       }
       
   771     }
       
   772   }
       
   773 
       
   774   //or the whole list.
       
   775   foreach ($imce['directories'] as $dirname => $info) {
       
   776     if (imce_check_directory($dirname)) {
       
   777       $_SESSION['imce_directory'] = rawurlencode($dirname);
       
   778       return $info;
       
   779     }
       
   780   }
       
   781 
       
   782   return FALSE;
       
   783 }
       
   784 
       
   785 /**
       
   786  * Create a writable directory(any level) under file system directory.
       
   787  */
       
   788 function imce_check_directory($dirname) {
       
   789 
       
   790   $root = file_directory_path();
       
   791   $dirpath = $root .'/'. $dirname;
       
   792 
       
   793   if (!file_check_directory($dirpath)) {//directory does not exist. try to create it.
       
   794     $path = $root;
       
   795     foreach (explode('/', $dirname) as $arg) {
       
   796       $path .= '/'. $arg;
       
   797       if (!file_check_location($path, $root) || !file_check_directory($path, FILE_CREATE_DIRECTORY)) {
       
   798         return imce_inaccessible_directory($dirname);
       
   799       }
       
   800     }
       
   801   }
       
   802   else if (!file_check_location($dirpath, $root)) {//directory exists outside of root.
       
   803     return imce_inaccessible_directory($dirname);
       
   804   }
       
   805 
       
   806   return TRUE;
       
   807 }
       
   808 
       
   809 /**
       
   810  * Generate and log a directory access error.
       
   811  */
       
   812 function imce_inaccessible_directory($dirname) {
       
   813   if (is_string($dirname)) {
       
   814     $msg = 'Directory "%dir" is not accessible under file system!';
       
   815     $token = array('%dir' => utf8_encode($dirname));
       
   816     drupal_set_message(t($msg, $token), 'error');
       
   817     watchdog('imce', $msg, $token, WATCHDOG_ERROR);
       
   818   }
       
   819   return FALSE;
       
   820 }
       
   821 
       
   822 /**
       
   823  * Return the permissions for a directory that is accessed directly or indirectly.
       
   824  * A child of a predefined directory in the directory list takes its parent's properties.
       
   825  * If it has multiple parents, it gets the properties of the latter in the list.
       
   826  */
       
   827 function imce_directory_info($dirname, $imce) {
       
   828 
       
   829   if (isset($imce['directories'][$dirname])) {
       
   830     return $imce['directories'][$dirname];
       
   831   }
       
   832 
       
   833   $info = FALSE;
       
   834   $root = file_directory_path();
       
   835   $dirpath = $root .'/'. $dirname;
       
   836   if (imce_reg_dir($dirname) && file_check_directory($dirpath)) {
       
   837     foreach ($imce['directories'] as $name => $prop) {
       
   838       if ($prop['subnav'] && file_check_location($dirpath, $root .'/'. $name)) {
       
   839         $info = $prop;
       
   840         $info['name'] = $dirname;
       
   841       }
       
   842     }
       
   843   }
       
   844 
       
   845   return $info;
       
   846 }
       
   847 
       
   848 /**
       
   849  * Detect if the subdirectories are accessible through any directory(not just the current one) in the list.
       
   850  */
       
   851 function imce_subdirectories_accessible(&$imce) {
       
   852 
       
   853   if (!empty($imce['subdirectories'])) {
       
   854     $root = file_directory_path() .'/';
       
   855     //checking only the first one is sufficient.
       
   856     $dirname = ($imce['dir'] == '.' ? '' : $imce['dir'] .'/') . $imce['subdirectories'][0];
       
   857     $dirpath = $root . $dirname;
       
   858 
       
   859     //check if any setting is applicable for this subdirectory through any directory in the list.
       
   860     foreach ($imce['directories'] as $name => $info) {
       
   861       if ($info['subnav'] && $dirname != $name && file_check_location($dirpath, $root . $name)) {
       
   862         return TRUE;
       
   863       }
       
   864     }
       
   865   }
       
   866 
       
   867   return FALSE;
       
   868 }
       
   869 
       
   870 /**
       
   871  * Check if a permission is given to at least one directory in the list.
       
   872  */
       
   873 function imce_perm_exists(&$imce, $perm) {
       
   874   static $perms = array();
       
   875 
       
   876   if (isset($perms[$perm])) {
       
   877     return $perms[$perm];
       
   878   }
       
   879 
       
   880   if (isset($imce['perm'][$perm]) && $imce['perm'][$perm]) {
       
   881     return $perms[$perm] = TRUE;
       
   882   }
       
   883 
       
   884   foreach ($imce['directories'] as $name => $info) {
       
   885     if (isset($info[$perm]) && $info[$perm]) {
       
   886       return $perms[$perm] = TRUE;
       
   887     }
       
   888   }
       
   889 
       
   890   return $perms[$perm] = FALSE;
       
   891 }
       
   892 
       
   893 /**
       
   894  * Scan directory and return file list, subdirectories, and total size.
       
   895  */
       
   896 function imce_scan_directory($dirname) {
       
   897 
       
   898   $directory = array('dirsize' => 0, 'files' => array(), 'subdirectories' => array(), 'error' => FALSE);
       
   899   $dirpath = file_directory_path() .'/'. $dirname;
       
   900 
       
   901   if (!is_string($dirname) || $dirname == '' || !$handle = opendir($dirpath)) {
       
   902     imce_inaccessible_directory($dirname);
       
   903     $directory['error'] = TRUE;
       
   904     return $directory;
       
   905   }
       
   906 
       
   907   $exclude = array('.' => 1, '..' => 1, 'CVS' => 1, '.svn' => 1, '.htaccess' => 1);
       
   908   while (($file = readdir($handle)) !== FALSE) {
       
   909     if (isset($exclude[$file])) {
       
   910       continue;
       
   911     }
       
   912 
       
   913     $path = $dirpath .'/'. $file;
       
   914 
       
   915     if (is_dir($path)) {
       
   916       $directory['subdirectories'][] = $file;
       
   917       continue;
       
   918     }
       
   919 
       
   920     $width = $height = 0;
       
   921     if ($img = imce_image_info($path)) {
       
   922       $width = $img['width'];
       
   923       $height = $img['height'];
       
   924     }
       
   925     $size = filesize($path);
       
   926     $date = filemtime($path);
       
   927     $directory['files'][$file] = array(
       
   928       'name' => $file,
       
   929       'size' => $size,
       
   930       'width' => $width,
       
   931       'height' => $height,
       
   932       'date' => $date
       
   933     );
       
   934     $directory['dirsize'] += $size;
       
   935   }
       
   936 
       
   937   closedir($handle);
       
   938   sort($directory['subdirectories']);
       
   939   return $directory;
       
   940 }
       
   941 
       
   942 /**
       
   943  * Create directory tree.
       
   944  */
       
   945 function imce_create_tree(&$imce) {
       
   946   $paths = array();
       
   947   //rearrange paths as arg0=>arg1=>...
       
   948   foreach ($imce['directories'] as $path => $arr) {
       
   949     $tmp =& $paths;
       
   950     if ($path != '.') {
       
   951       $args = explode('/', $path);
       
   952       foreach ($args as $arg) {
       
   953         if (!isset($tmp[$arg])) {
       
   954           $tmp[$arg] = array();
       
   955         }
       
   956         $tmp =& $tmp[$arg];
       
   957       }
       
   958       $tmp[':access:'] = TRUE;
       
   959     }
       
   960     if ("$path" == $imce['dir']) {
       
   961       $tmp[':active:'] = TRUE;
       
   962       foreach ($imce['subdirectories'] as $arg) {
       
   963         $tmp[$arg][':access:'] = TRUE;
       
   964       }
       
   965     }
       
   966   }
       
   967   //set root branch
       
   968   $root = variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE && !user_access('administer site configuration') ? t('Directory root') : file_directory_path();
       
   969   $q = $imce['clean'] ? '?' : '&';
       
   970   if (isset($imce['directories']['.'])) {
       
   971     $root = '<a href="'. $imce['url'] . $q .'dir=." title="." class="folder'. ($imce['dir'] == '.' ? ' active' : '') .'">'. $root .'</a>';
       
   972   }
       
   973   else {
       
   974     $root = '<a title="." class="folder disabled">'. $root .'</a>';
       
   975   }
       
   976 
       
   977   return $root . imce_tree_html($imce, $paths, $q);
       
   978 }
       
   979 
       
   980 /**
       
   981  * Return tree html.
       
   982  * This is not themable because it is complex and needs to be in a proper format for js processing.
       
   983  */
       
   984 function imce_tree_html(&$imce, $paths, $q = '?', $prefix = '', $eprefix = '') {
       
   985   unset($paths[':access:'], $paths[':active:']);
       
   986   $html = '';
       
   987   foreach ($paths as $arg => $children) {
       
   988     $path = $prefix . $arg;
       
   989     $earg = rawurlencode($arg);
       
   990     $epath = $eprefix . $earg;
       
   991     if (isset($children[':access:']) || imce_directory_info($path, $imce)) {
       
   992       $a = '<a href="'. $imce['url'] . $q .'dir='. $epath .'" title="'. $epath .'" class="folder'. (isset($children[':active:']) ? ' active' : '') .'">'. $earg .'</a>';
       
   993     }
       
   994     else {
       
   995       $a = '<a title="'. $epath .'" class="folder disabled">'. $earg .'</a>';
       
   996     }
       
   997     $ul = imce_tree_html($imce, $children, $q, $path .'/', $epath .'/');
       
   998     $html .= '<li class="'. ($ul ? 'expanded' : (isset($children[':active:']) ? 'leaf' : '')) .'">'. $a . $ul .'</li>';
       
   999   }
       
  1000   if ($html) {
       
  1001     $html = '<ul>'. $html .'</ul>';
       
  1002   }
       
  1003   return $html;
       
  1004 }