Wednesday, May 16, 2012

Drupal produces warnings with file_check_directory() on low bootstrap levels

I've found interesting issue with file_check_directory() in Drupal. It generates errors like:

Warning: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object in /.../public_html/includes/ on line 245

With back trace like:
30.06424656960 file_check_directory( )../mycustom-script.php:90
40.06434657840 t( )../
50.06434659648 theme( )../
60.06434660552 init_theme( )../
70.06624884760 _init_theme( )../
80.06654901784 call_user_func ( )../
90.06654902024 phptemplate_init( )../
100.06674928608 include_once( 'sites/all/themes/zen/template.php' )../phptemplate.engine:14
110.06674928688 theme_get_setting( )../template.php:15
120.06674929200 theme_get_settings( )../
130.06674932440 module_exists( )../
140.06674932880 array_key_exists (  )../

I'm not sure if this should be reported as a bug for Drupal guys and still do not have a time for experiments and to reproduce it on fresh Drupal installation.

Anyway want to note that I was using the lowest possibly Drupal bootstrap level:

Issue occurs due to message displayed by file_check_directory() function after new directory was created. Message becomes localized with t() function and then themed - which starts theme initialization that results in reading modules related information. As on DRUPAL_BOOTSTRAP_DATABASE level no modules are loaded - uninitialized variable is passed to foreach() loop and then array_key_exists function resulting in such a issue.

it would be better to avoid displaying any output in filesystem related functions.

But to avoid any core hacks - my quick and dirty workaround for this issue was to rise the bootstrap level and load modules right before using the file_check_directory() function, like:

  // trying to bootstrap modules in order to resolve issue with
  //  "file_check_directory()" producing errors when modules are not loaded

  // So we are ready to work with our directories
  $path = file_directory_path();
  file_check_directory($path, FILE_CREATE_DIRECTORY);
  file_check_directory($path . "/test1", FILE_CREATE_DIRECTORY);
  file_check_directory($path . "/test2", FILE_CREATE_DIRECTORY);
  file_check_directory($path . "/test3", FILE_CREATE_DIRECTORY);