The Windows Azure Blob module allows for the uploading and storing of files on the Windows Azure storage service. But unfortunately, this module is not compatible with IMCE.
The problem is that with Windows Azure Storage, you don't have direct access to the file system. You have to go through a REST API to get information about stored files. So, PHP methods like opendir
or readdir
can't work in such configuration.
To bypass this problem, the azure_blob module has a class WindowsAzureBlobStreamWrapper
which implements the DrupalStreamWrapperInterface
interface. This interface has several interesting methods, such has dir_opendir
and dir_readdir
, which can be used as replacement for the PHP ones.
So, with this idea, I've made some modifications to IMCE module to avoid direct calls to low-level PHP methods like opendir
or readdir
. Instead, I use the Drupal built-in file stream wrapper mechanism to retrieve the correct implementation class, base on the file scheme.
Here's the patch:
--- a/sites/all/modules/imce/inc/imce.page.inc
+++ b/sites/all/modules/imce/inc/imce.page.inc
@@ -971,13 +971,22 @@ function imce_scan_directory($dirname, $imce) {
$directory = array('dirsize' => 0, 'files' => array(), 'subdirectories' => array(), 'error' => FALSE);
$diruri = imce_dir_uri($imce, $dirname);
- if (!is_string($dirname) || $dirname == '' || !$handle = opendir($diruri)) {
+ // Attempt to retrieve the appropriate wrapper.
+ $fileStreamWrapper = file_stream_wrapper_get_instance_by_uri($diruri);
+ if (!$fileStreamWrapper) {
+ // raise an error if no wrapper was found.
imce_inaccessible_directory($dirname, $imce);
$directory['error'] = TRUE;
return $directory;
}
- while (($file = readdir($handle)) !== FALSE) {
+ if (!is_string($dirname) || $dirname == '' || !$handle = $fileStreamWrapper->dir_opendir($diruri)) {
+ imce_inaccessible_directory($dirname, $imce);
+ $directory['error'] = TRUE;
+ return $directory;
+ }
+
+ while (($file = $fileStreamWrapper->dir_readdir($handle)) !== FALSE) {
// Do not include dot files and folders
if (substr($file, 0, 1) === '.') {
@@ -1008,7 +1017,7 @@ function imce_scan_directory($dirname, $imce) {
$directory['dirsize'] += $size;
}
- closedir($handle);
+ $fileStreamWrapper->dir_closedir($handle);
sort($directory['subdirectories']);
return $directory;
}
This adds a layer of abstraction and add the possibility to have different implementations based on different scheme.
While this patch work in simple situations, this patch is incomplete at the moment. Methods likes is_dir
, filesize
or filemtime
doesn't have any equivalent in DrupalStreamWrapperInterface
. So they can't be ported easily to use this new abstraction layer.
Also, the method imce_image_info
(which is called inside imce_scan_directory
) also uses low-level PHP functions such as is_file
and getimagesize
which may not work in a Windows Azure Storage configuration.
I'm pretty sure a better and more robust patch could be applied for this problem, but this one is a good start.
Also, I've done another patch in azure_blob to avoid another compatibility issue between azure_blob and IMCE Drupal modules: https://www.drupal.org/node/2423001. Hope this helps anyone having the same issue :)
Cheers,
Romain
Comment | File | Size | Author |
---|---|---|---|
0001-imce-use-file_stream_wrapper-to-traverse-directory-c.patch | 1.95 KB | pomeh | |
Comments
Comment #1
ufku CreditAttribution: ufku commentedIMCE works with custom stream wrappers like s3. Azure blob module should be implementing a similar interface.