diff --git a/file_entity.module b/file_entity.module index 27de900..48dd107 100644 --- a/file_entity.module +++ b/file_entity.module @@ -1036,10 +1036,9 @@ function file_entity_metadata_form_file($file) { /** * Implements hook_ctools_plugin_directory(). */ - -function file_entity_ctools_plugin_directory($module, $type) { - if ($module == 'ctools' && $type == 'content_types') { - return 'plugins/' . $type; +function file_entity_ctools_plugin_directory($module, $plugin) { + if (in_array($module, array('panelizer', 'ctools', 'page_manager'))) { + return 'plugins/' . $plugin; } } @@ -1556,11 +1555,11 @@ function file_entity_stream_wrappers_alter(&$wrappers) { /** * Implements hook_ctools_plugin_api(). */ -function file_entity_ctools_plugin_api($owner, $api) { - if ($owner == 'file_entity' && $api == 'file_type') { +function file_entity_ctools_plugin_api($module, $api) { + if (($module == 'file_entity' && $api == 'file_type') || ($module == 'page_manager' && $api == 'pages_default') || $module == 'panelizer') { return array('version' => 1); } - if ($owner == 'file_entity' && $api == 'file_default_displays') { + if ($module == 'file_entity' && $api == 'file_default_displays') { return array('version' => 1); } } diff --git a/plugins/entity/PanelizerEntityFile.class.php b/plugins/entity/PanelizerEntityFile.class.php new file mode 100644 index 0000000..f753d3c --- /dev/null +++ b/plugins/entity/PanelizerEntityFile.class.php @@ -0,0 +1,123 @@ +plugin['bundles'] as $info) { + if (!empty($info['status'])) { + $warn = TRUE; + break; + } + } + + if ($warn) { + $task = page_manager_get_task('file_view'); + if (!empty($task['disabled'])) { + drupal_set_message('The file template page is currently not enabled in page manager. You must enable this for Panelizer to be able to panelize files.', 'warning'); + } + + $handler = page_manager_load_task_handler($task, '', 'file_view_panelizer'); + if (!empty($handler->disabled)) { + drupal_set_message('The panelizer variant on the file template page is currently not enabled in page manager. You must enable this for Panelizer to be able to panelize files.', 'warning'); + } + } + } + + public function entity_identifier($entity) { + return t('This file'); + } + + public function entity_bundle_label() { + return t('File type'); + } + + function get_default_display($bundle, $view_mode) { + // For now we just go with the empty display. + // @todo come up with a better default display. + return parent::get_default_display($bundle, $view_mode); + } + + /** + * Implements a delegated hook_page_manager_handlers(). + * + * This makes sure that all panelized entities have the proper entry + * in page manager for rendering. + */ + public function hook_default_page_manager_handlers(&$handlers) { + page_manager_get_task('file_view'); + + $handler = new stdClass; + $handler->disabled = FALSE; /* Edit this to true to make a default handler disabled initially */ + $handler->api_version = 1; + $handler->name = 'file_view_panelizer'; + $handler->task = 'file_view'; + $handler->subtask = ''; + $handler->handler = 'panelizer_file'; + $handler->weight = -100; + $handler->conf = array( + 'title' => t('File panelizer'), + 'context' => 'argument_entity_id:file_1', + 'access' => array(), + ); + $handlers['file_view_panelizer'] = $handler; + + return $handlers; + } + + /** + * Implements a delegated hook_form_alter. + * + * We want to add Panelizer settings for the bundle to the file type form. + */ + public function hook_form_alter(&$form, &$form_state, $form_id) { + if ($form_id == 'file_entity_file_type_form') { + if (isset($form['#file_type'])) { + $bundle = $form['#file_type']->type; + $this->add_bundle_setting_form($form, $form_state, $bundle, array('machine_name')); + } + } + } + + public function hook_page_alter(&$page) { + + } + + public function hook_views_plugins_alter(&$plugins) { + + } + +} diff --git a/plugins/entity/file.inc b/plugins/entity/file.inc new file mode 100644 index 0000000..fd58231 --- /dev/null +++ b/plugins/entity/file.inc @@ -0,0 +1,22 @@ + 'PanelizerEntityFile', + 'entity path' => 'file/%file', + 'uses page manager' => TRUE, + 'hooks' => array( + 'menu' => TRUE, + 'admin_paths' => TRUE, + 'permission' => TRUE, + 'panelizer_defaults' => TRUE, + 'default_page_manager_handlers' => TRUE, + 'form_alter' => TRUE, + 'page_alter' => TRUE, + 'views_data_alter' => TRUE, + 'views_plugins_alter' => TRUE, + ), +); diff --git a/plugins/tasks/file_view.inc b/plugins/tasks/file_view.inc new file mode 100644 index 0000000..5b82375 --- /dev/null +++ b/plugins/tasks/file_view.inc @@ -0,0 +1,164 @@ + 'page', + 'title' => t('File template'), + 'admin title' => t('File template'), + 'admin description' => t('When enabled, this overrides the default Drupal behavior for displaying files at file/%file. If you add variants, you may use selection criteria such as file types or user access to provide different views of files. If no variant is selected, the default Drupal file view will be used. This page only affects files viewed as pages, it will not affect files viewed in lists or at other locations. Also please note that if you are using Pathauto, aliases may make a file to be available somewhere else, but as far as Drupal is concerned, they are still at file/%file.'), + 'admin path' => 'file/%file', + + // Menu hooks so that we can alter the file/%file menu entry to point to us. + 'hook menu' => 'file_entity_file_view_menu', + 'hook menu alter' => 'file_entity_file_view_menu_alter', + + // This is task uses 'context' handlers and must implement these to give the + // handler data it needs. + 'handler type' => 'context', + 'get arguments' => 'file_entity_file_view_get_arguments', + 'get context placeholders' => 'file_entity_file_view_get_contexts', + + // Allow this to be enabled or disabled: + 'disabled' => variable_get('file_entity_file_view_disabled', TRUE), + 'enable callback' => 'file_entity_file_view_enable', + 'access callback' => 'file_entity_file_view_access_check', + ); +} + +/** + * Callback defined by page_manager_file_view_page_manager_tasks(). + * + * Alter the file view input so that file view comes to us rather than the + * normal file view process. + */ +function file_entity_file_view_menu_alter(&$items, $task) { + if (variable_get('file_entity_file_view_disabled', TRUE)) { + return; + } + + // Override the node view handler for our purpose. + $callback = $items['file/%file']['page callback']; + if ($callback == 'file_entity_view_page' || variable_get('page_manager_override_anyway', FALSE)) { + $items['file/%file']['page callback'] = 'file_entity_file_view_page'; + $items['file/%file']['file path'] = $task['path']; + $items['file/%file']['file'] = $task['file']; + } + else { + // automatically disable this task if it cannot be enabled. + variable_set('file_entity_file_view_disabled', TRUE); + if (!empty($GLOBALS['page_manager_enabling_file_view'])) { + drupal_set_message(t('Page manager module is unable to enable file/%file because some other module already has overridden with %callback.', array('%callback' => $callback)), 'error'); + } + } +} + +/** + * Entry point for our overridden file view. + * + * This function asks its assigned handlers who, if anyone, would like + * to run with it. If no one does, it passes through to File entity's + * file view, which is file_entity_view_page(). + */ +function file_entity_file_view_page($file) { + // Load my task plugin: + $task = page_manager_get_task('file_view'); + + // Load the account into a context. + ctools_include('context'); + ctools_include('context-task-handler'); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($file)); + + // We need to mimic Drupal's behavior of setting the file title here. + drupal_set_title($file->filename); + $uri = entity_uri('file', $file); + // Set the file path as the canonical URL to prevent duplicate content. + drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url($uri['path'], $uri['options'])), TRUE); + // Set the non-aliased path as a default shortlink. + drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE)))), TRUE); + $contexts = ctools_context_handler_get_task_contexts($task, '', array($file)); + + $output = ctools_context_handler_render($task, '', $contexts, array($file->fid)); + if ($output != FALSE) { + return $output; + } + + $function = 'file_entity_view_page'; + foreach (module_implements('page_manager_override') as $module) { + $call = $module . '_page_manager_override'; + if (($rc = $call('file_view')) && function_exists($rc)) { + $function = $rc; + break; + } + } + + // Otherwise, fall back. + return $function($file); +} + +/** + * Callback to get arguments provided by this task handler. + * + * Since this is the file view and there is no UI on the arguments, we + * create dummy arguments that contain the needed data. + */ +function file_entity_file_view_get_arguments($task, $subtask_id) { + return array( + array( + 'keyword' => 'file', + 'identifier' => t('File being viewed'), + 'id' => 1, + 'name' => 'entity_id:file', + 'settings' => array(), + ), + ); +} + +/** + * Callback to get context placeholders provided by this handler. + */ +function file_entity_file_view_get_contexts($task, $subtask_id) { + return ctools_context_get_placeholders_from_argument(page_manager_file_view_get_arguments($task, $subtask_id)); +} + +/** + * Callback to enable/disable the page from the UI. + */ +function file_entity_file_view_enable($cache, $status) { + variable_set('file_entity_file_view_disabled', $status); + + // Set a global flag so that the menu routine knows it needs + // to set a message if enabling cannot be done. + if (!$status) { + $GLOBALS['page_manager_enabling_file_view'] = TRUE; + } +} + +/** + * Callback to determine if a page is accessible. + * + * @param $task + * The task plugin. + * @param $subtask_id + * The subtask id + * @param $contexts + * The contexts loaded for the task. + * @return + * TRUE if the current user can access the page. + */ +function page_manager_file_view_access_check($task, $subtask_id, $contexts) { + $context = reset($contexts); + return file_entity_access('view'); +}