diff --git media_gallery.module media_gallery.module index dac5f06..e9b4886 100644 --- media_gallery.module +++ media_gallery.module @@ -226,10 +226,11 @@ function media_gallery_view($node, $view_mode) { // @todo Drupal could really use a theme_menu_local_actions() function... '#prefix' => '', - // Add front-end resources related to this link, only when it is actually - // being rendered. - '#pre_render' => array('media_gallery_add_images_link_pre_render'), ); + // Add front end resources related to this link. + $node->content['add_media_link']['#attached']['js'][] = drupal_get_path('module', 'media_gallery') . '/media_gallery.addimage.js'; + module_load_include('inc', 'media', 'media.browser'); + media_attach_browser_js($node->content['add_media_link']); // These JS settings are used by the "add media" link but are also shared // by the drag-and-drop code below. @@ -353,17 +354,6 @@ function media_gallery_view($node, $view_mode) { } /** - * Prerender function to add front-end resources for the "Add media" link. - */ -function media_gallery_add_images_link_pre_render($elements) { - drupal_add_library('media', 'media_browser'); - module_load_include('inc', 'media', 'media.browser'); - media_include_browser_js(); - drupal_add_js(drupal_get_path('module', 'media_gallery') . '/media_gallery.addimage.js'); - return $elements; -} - -/** * Implements hook_field_extra_fields(). */ function media_gallery_field_extra_fields() { @@ -503,6 +493,29 @@ function media_gallery_update($node) { ->condition('delta', $node->nid) ->execute(); } + // Clear the block cache for this node. + cache_clear_all('media_gallery_block:' . $node->nid, 'cache_block', TRUE); +} + +/** + * Implements hook_media_invalidate_cache(). + */ +function media_gallery_media_invalidate_cache($fid = FALSE) { + // @todo: it may be possible to do an EntityFieldQuery to find all nodes + // that reference the fid if it is passed in. This would allow the cache + // to be cleared by nid instead of all block entries. However this may + // be expensive in itself compared to just rebuilding the cache. + cache_clear_all('media_gallery_block:', 'cache_block', TRUE); +} + +/** + * Implements hook_field_update_instance(). + */ +function media_gallery_field_update_instance($instance, $prior_instance) { + if ($instance['bundle'] == 'media_gallery') { + // Clear the media block cache. + media_gallery_media_invalidate_cache(); + } } /** @@ -546,49 +559,20 @@ function media_gallery_block_view($delta = '') { $block['content'] = t('No content available.'); } else { - // Collect an array of file IDs associated with this gallery. For - // simplicity we will assume (here and below) that this is not a - // multilingual field. Also note that the node may have been loaded and - // viewed elsewhere on the page, in which case the 'media_gallery_media' - // field was modified and does not contain what we want, so we have to go - // back to the original field value set in hook_node_load() instead, and - // also clone the node before changing it so our modifications do not - // affect other places where it might be being viewed. - $node = clone $node; - $node->media_gallery_media = $node->media_gallery_media_original; - $files = &$node->media_gallery_media[LANGUAGE_NONE]; - $gallery_fids = array(); - foreach ($files as $file) { - $gallery_fids[] = _media_gallery_get_media_fid($file); - } - // Construct a list of file IDs that is limited to the specified number of - // items and ordered by most recent; these are the files that will be - // displayed in the block. - $columns = !empty($node->media_gallery_block_columns[LANGUAGE_NONE][0]['value']) ? $node->media_gallery_block_columns[LANGUAGE_NONE][0]['value'] : 1; - $rows = !empty($node->media_gallery_block_rows[LANGUAGE_NONE][0]['value']) ? $node->media_gallery_block_rows[LANGUAGE_NONE][0]['value'] : 1; - $number_to_show = $columns * $rows; - $block_fids = db_select('file_managed', 'f') - ->fields('f', array('fid')) - ->condition('fid', $gallery_fids, 'IN') - ->orderBy('timestamp', 'DESC') - ->range(0, $number_to_show) - ->execute() - ->fetchCol(); - // Before sorting, remove any items that will not display in the block. - $fid_order = array_flip($block_fids); - if ($number_to_show < count($files)) { - foreach ($files as $key => $file) { - if (!isset($fid_order[_media_gallery_get_media_fid($file)])) { - unset($files[$key]); - } - } - } - // Prepare the sorting function with the list of file ID orders. - _media_gallery_sort_by_recent(NULL, NULL, $fid_order); - // Perform the sort. - usort($files, '_media_gallery_sort_by_recent'); - // Display the block. - $block['content'] = node_view($node, 'media_gallery_block'); + $block['content'] = array( + '#node' => $node, + '#pre_render' => array('media_gallery_block_build'), + '#cache' => array( + 'keys' => array( + 'media_gallery_block', + $node->nid, + (int) node_access('update', $node), + (int) $GLOBALS['is_https'], + ), + 'bin' => 'cache_block', + 'expire' => 86400, + ), + ); $block['content']['more_link'] = array( '#theme' => 'more_link', '#url' => 'node/' . $node->nid, @@ -596,11 +580,62 @@ function media_gallery_block_view($delta = '') { '#weight' => 1000, ); } - return $block; } /** + * Build a renderable array for the media gallery block content. + */ +function media_gallery_block_build($elements) { + + // Collect an array of file IDs associated with this gallery. For + // simplicity we will assume (here and below) that this is not a + // multilingual field. Also note that the node may have been loaded and + // viewed elsewhere on the page, in which case the 'media_gallery_media' + // field was modified and does not contain what we want, so we have to go + // back to the original field value set in hook_node_load() instead, and + // also clone the node before changing it so our modifications do not + // affect other places where it might be being viewed. + $node = clone $elements['#node']; + $node->media_gallery_media = $node->media_gallery_media_original; + $files = &$node->media_gallery_media[LANGUAGE_NONE]; + $gallery_fids = array(); + foreach ($files as $file) { + $gallery_fids[] = _media_gallery_get_media_fid($file); + } + // Construct a list of file IDs that is limited to the specified number of + // items and ordered by most recent; these are the files that will be + // displayed in the block. + $columns = !empty($node->media_gallery_block_columns[LANGUAGE_NONE][0]['value']) ? $node->media_gallery_block_columns[LANGUAGE_NONE][0]['value'] : 1; + $rows = !empty($node->media_gallery_block_rows[LANGUAGE_NONE][0]['value']) ? $node->media_gallery_block_rows[LANGUAGE_NONE][0]['value'] : 1; + $number_to_show = $columns * $rows; + $block_fids = db_select('file_managed', 'f') + ->fields('f', array('fid')) + ->condition('fid', $gallery_fids, 'IN') + ->orderBy('timestamp', 'DESC') + ->range(0, $number_to_show) + ->execute() + ->fetchCol(); + // Before sorting, remove any items that will not display in the block. + $fid_order = array_flip($block_fids); + if ($number_to_show < count($files)) { + foreach ($files as $key => $file) { + if (!isset($fid_order[_media_gallery_get_media_fid($file)])) { + unset($files[$key]); + } + } + } + // Prepare the sorting function with the list of file ID orders. + _media_gallery_sort_by_recent(NULL, NULL, $fid_order); + // Perform the sort. + usort($files, '_media_gallery_sort_by_recent'); + // Display the block. + $elements['gallery'] = node_view($node, 'media_gallery_block'); + + return $elements; +} + +/** * Implements hook_block_configure(). */ function media_gallery_block_configure($delta = '') {