diff --git a/file_entity/file_entity.install b/file_entity/file_entity.install index 9daec77..e8b11a5 100644 --- a/file_entity/file_entity.install +++ b/file_entity/file_entity.install @@ -63,6 +63,38 @@ function file_entity_schema() { ), ), ); + $schema['image_dimensions'] = array( + 'description' => 'Cache images dimensions.', + 'fields' => array( + 'fid' => array( + 'description' => 'File ID.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'height' => array( + 'description' => 'The height of the image in pixels.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'width' => array( + 'description' => 'The width of the image in pixels..', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('fid'), + 'foreign keys' => array( + 'file_managed' => array( + 'table' => 'file_managed', + 'columns' => array('fid' => 'fid'), + ), + ), + ); return $schema; } @@ -211,3 +243,44 @@ function file_entity_update_7002() { */ function file_entity_update_7100() { } + +/** + * Create the {image_dimensions} database table. + */ +function file_entity_update_7101() { + if (!db_table_exists('image_dimensions')){ + $schema['image_dimensions'] = array( + 'description' => 'Cache images dimensions.', + 'fields' => array( + 'fid' => array( + 'description' => 'File ID.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'height' => array( + 'description' => 'The height of the image in pixels.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'width' => array( + 'description' => 'The width of the image in pixels..', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('fid'), + 'foreign keys' => array( + 'file_managed' => array( + 'table' => 'file_managed', + 'columns' => array('fid' => 'fid'), + ), + ), + ); + db_create_table('image_dimensions', $schema['image_dimensions']); + } +} diff --git a/file_entity/file_entity.module b/file_entity/file_entity.module index d652bc3..84e888a 100644 --- a/file_entity/file_entity.module +++ b/file_entity/file_entity.module @@ -192,6 +192,9 @@ function file_entity_file_presave($file) { */ function file_entity_file_insert($file) { field_attach_insert('file', $file); + + // Get and store image dimensions. + file_entity_image_dimensions($file, TRUE); } /** @@ -199,6 +202,9 @@ function file_entity_file_insert($file) { */ function file_entity_file_update($file) { field_attach_update('file', $file); + + // Get and store image dimensions. + file_entity_image_dimensions($file, TRUE); } /** @@ -206,6 +212,85 @@ function file_entity_file_update($file) { */ function file_entity_file_delete($file) { field_attach_delete('file', $file); + + // Delete image dimensions from the {image_dimensions} table + db_query('DELETE FROM {image_dimensions} WHERE fid = :fid', array(':fid' => $file->fid)); +} + +/** + * Implements hook_file_load(). + */ +function file_entity_file_load($files) { + // Load images dimensions already in the {image_dimensions} table. + $result = db_query('SELECT * FROM {image_dimensions} id WHERE id.fid IN (:fids)', array(':fids' => array_keys($files))); + foreach ($result as $record) { + $files[$record->fid]->image_dimensions = array( + 'width' => $record->width, + 'height' => $record->height, + ); + } + // Retrieve any missing images dimensions. + foreach ($files as $file) { + file_entity_image_dimensions($file, FALSE); + } +} + +/** + * Retrieve the dimensions of an image file and store them in the + * {image dimensions} table. + * + * @param $file + * A file object. + * + * @param $force + * TRUE if the image dimensions should always be loaded from the actual file + * even if $file->image_dimensions is already set. + * + * @return + * The image dimensions as an array with the 'width' and 'height' properties. + * The array is also added to $file as its image_dimensions property. If the + * image dimensions cannot be read, the 'width' and 'height' properties will + * be NULL. If $file is either empty or not an image file, FALSE is returned. + */ +function file_entity_image_dimensions($file, $force = FALSE) { + // Prevent PHP notices when trying to read empty files. + // @see http://drupal.org/node/681042 + if (!$file->filesize) { + return; + } + + // Do not bother proceeding if this file does not have an image mime type. + if (strpos($file->filemime, 'image/') !== 0) { + return; + } + + // Return the existing $file->image_dimensions unless a reload is forced. + if (!$force && isset($file->image_dimensions)) { + return $file->image_dimensions; + } + + // We have a non-empty image file. + $image_info = image_get_info($file->uri); + if ($image_info) { + $file->image_dimensions = array( + 'width' => $image_info['width'], + 'height' => $image_info['height'], + ); + db_merge('image_dimensions') + ->key(array('fid' => $file->fid)) + ->fields(array( + 'width' => $file->image_dimensions['width'], + 'height' => $file->image_dimensions['height'], + )) + ->execute(); + } + else { + // Fallback to NULL values. + $file->image_dimensions = array( + 'width' => NULL, + 'height' => NULL, + ); + } } /** @@ -364,22 +449,22 @@ function file_entity_file_formatter_file_image_view($file, $display, $langcode) return; } - if (file_entity_file_is_local($file) && $image = image_load($file->uri)) { + if (file_entity_file_is_local($file) && isset($file->image_dimensions)) { if (!empty($display['settings']['image_style'])) { $element = array( '#theme' => 'image_style', '#style_name' => $display['settings']['image_style'], '#path' => $file->uri, - '#width' => $image->info['width'], - '#height' => $image->info['height'], + '#width' => $file->image_dimensions['width'], + '#height' => $file->image_dimensions['height'], ); } else { $element = array( '#theme' => 'image', '#path' => $file->uri, - '#width' => $image->info['width'], - '#height' => $image->info['height'], + '#width' => $file->image_dimensions['width'], + '#height' => $file->image_dimensions['height'], ); } return $element;