| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 3 4 /** 5 * @file panels_node.module 6 * 7 * This module provides the "panel" node type. 8 * Panel nodes are useful to add additional content to the content area 9 * on a per-node base. 10 */ 11 12 // --------------------------------------------------------------------------- 13 // General Drupal hooks 14 15 /** 16 * Implementation of hook_perm(). 17 */ 18 function panels_node_perm() { 19 return array('create panel-nodes', 'edit any panel-nodes', 'edit own panel-nodes', 'administer panel-nodes', 'delete any panel-nodes', 'delete own panel-nodes'); 20 } 21 22 /** 23 * Implementation of hook_menu(). 24 */ 25 function panels_node_menu() { 26 // Safety: go away if CTools is not at an appropriate version. 27 if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { 28 return array(); 29 } 30 31 $items['admin/build/panels/settings/panel-node'] = array( 32 'title' => 'Panel nodes', 33 'description' => 'Configure which content is available to add to panel node displays.', 34 'access arguments' => array('administer panel-nodes'), 35 'page callback' => 'panels_node_settings', 36 'type' => MENU_LOCAL_TASK, 37 ); 38 39 // Avoid some repetition on these: 40 $base = array( 41 'access callback' => 'panels_node_edit_node', 42 'access arguments' => array(1), 43 'page arguments' => array(1), 44 'type' => MENU_LOCAL_TASK, 45 ); 46 47 $items['node/%node/panel_layout'] = array( 48 'title' => 'Panel layout', 49 'page callback' => 'panels_node_edit_layout', 50 'weight' => 2, 51 ) + $base; 52 53 $items['node/%node/panel_content'] = array( 54 'title' => 'Panel content', 55 'page callback' => 'panels_node_edit_content', 56 'weight' => 3, 57 ) + $base; 58 59 $items['node/add/panel/choose-layout'] = array( 60 'title' => 'Choose layout', 61 'access arguments' => array('create panel-nodes'), 62 'page callback' => 'panels_node_add', 63 'type' => MENU_CALLBACK, 64 ); 65 66 return $items; 67 } 68 69 function panels_node_edit_node($node) { 70 if (!isset($node->panels_node)) { 71 return FALSE; 72 } 73 74 return node_access('update', $node); 75 } 76 77 // --------------------------------------------------------------------------- 78 // Node hooks 79 80 /** 81 * Implementation of hook_node_info(). 82 */ 83 function panels_node_node_info() { 84 // Safety: go away if CTools is not at an appropriate version. 85 if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) { 86 return array(); 87 } 88 89 return array( 90 'panel' => array( 91 'name' => t('Panel'), 92 'module' => 'panels_node', 93 'body_label' => t('Teaser'), 94 'description' => t("A panel layout broken up into rows and columns."), 95 ), 96 ); 97 } 98 99 /** 100 * Implementation of hook_access(). 101 */ 102 function panels_node_access($op, $node, $account) { 103 if (user_access('administer panel-nodes', $account)) { 104 return TRUE; 105 } 106 107 if ($op == 'create' && user_access('create panel-nodes', $account)) { 108 return TRUE; 109 } 110 111 if ($op == 'update' && (user_access('edit any panel-nodes', $account) || $node->uid == $account->uid && user_access('edit own panel-nodes', $account))) { 112 return TRUE; 113 } 114 115 116 if ($op == 'delete' && (user_access('delete any panel-nodes') || $node->uid == $account->uid && user_access('delete own panel-nodes'))) { 117 return TRUE; 118 } 119 } 120 121 function panels_node_add() { 122 $output = ''; 123 124 ctools_include('plugins', 'panels'); 125 ctools_include('common', 'panels'); 126 127 $layouts = panels_common_get_allowed_layouts('panels_node'); 128 return panels_common_print_layout_links($layouts, 'node/add/panel', array('query' => $_GET)); 129 } 130 131 /** 132 * Implementation of hook_form(). 133 */ 134 function panels_node_form(&$node, &$param) { 135 ctools_include('plugins', 'panels'); 136 137 $form['panels_node']['#tree'] = TRUE; 138 if (empty($node->nid) && arg(0) == 'node' && arg(1) == 'add') { 139 // Grab our selected layout from the $node, If it doesn't exist, try arg(3) 140 // and if that doesn't work present them with a list to pick from. 141 $panel_layout = isset($node->panel_layout) ? $node->panel_layout : arg(3); 142 if (empty($panel_layout)) { 143 $opts = $_GET; 144 unset($opts['q']); 145 return drupal_goto('node/add/panel/choose-layout', $opts); 146 } 147 148 $layout = panels_get_layout($panel_layout); 149 if (empty($layout)) { 150 return drupal_not_found(); 151 } 152 $form['panels_node']['layout'] = array( 153 '#type' => 'value', 154 '#value' => $panel_layout, 155 ); 156 } 157 158 $type = node_get_types('type', $node); 159 160 $form['title'] = array( 161 '#type' => 'textfield', 162 '#title' => check_plain($type->title_label), 163 '#required' => TRUE, 164 '#default_value' => $node->title, 165 ); 166 167 if (!empty($type->body_label)) { 168 $form['body_field']['#prefix'] = '<div class="body-field-wrapper">'; 169 $form['body_field']['#suffix'] = '</div>'; 170 $form['body_field']['body'] = array( 171 '#type' => 'textarea', 172 '#title' => check_plain($type->body_label), 173 '#rows' => 10, 174 '#required' => TRUE, 175 '#description' => t('The teaser is a piece of text to describe when the panel is listed (such as when promoted to front page); the actual content will only be displayed on the full node view.'), 176 '#default_value' => $node->body, 177 ); 178 $form['body_field']['format'] = filter_form($node->format); // Now we can set the format! 179 } 180 181 // drupal_set_message('<pre>' . check_plain(var_export($node, true)) . '</pre>'); 182 $css_id = ''; 183 if (!empty($node->panels_node['css_id'])) { 184 $css_id = $node->panels_node['css_id']; 185 } 186 187 $form['panels_node']['css_id'] = array( 188 '#type' => 'textfield', 189 '#title' => t('CSS ID'), 190 '#size' => 30, 191 '#description' => t('An ID that can be used by CSS to style the panel.'), 192 '#default_value' => $css_id, 193 ); 194 195 // Support for different rendering pipelines 196 // Mostly borrowed from panel_context.inc 197 $pipelines = panels_get_renderer_pipelines(); 198 199 // If there are no pipelines, that probably means we're operating in 200 // legacy mode. 201 if (empty($pipelines)) { 202 // We retain the original pipeline so we don't wreck things by installing 203 // old modules. 204 $form['panels_node']['pipeline'] = array( 205 '#type' => 'value', 206 '#value' => $node->panels_node['pipeline'], 207 ); 208 } 209 else { 210 $options = array(); 211 foreach ($pipelines as $name => $pipeline) { 212 $options[$name] = check_plain($pipeline->admin_title) . '<div class="description">' . check_plain($pipeline->admin_description) . '</div>'; 213 } 214 215 $form['panels_node']['pipeline'] = array( 216 '#type' => 'radios', 217 '#options' => $options, 218 '#title' => t('Renderer'), 219 '#default_value' => !empty($node->panels_node['pipeline']) ? $node->panels_node['pipeline'] : 'standard', 220 ); 221 } 222 223 return $form; 224 } 225 226 /** 227 * Implementation of hook_validate(). 228 */ 229 function panels_node_validate($node) { 230 if (!$node->nid && empty($node->panels_node['layout'])) { 231 form_set_error('', t('Please select a layout.')); 232 } 233 } 234 235 /** 236 * Implementation of hook_load(). 237 * 238 * Panels does not use revisions for nodes because that would open us up 239 * to have completely separate displays, and we'd have to copy them, 240 * and that's going to be a LOT of data. 241 */ 242 function panels_node_load($node) { 243 // We shortcut this because only in some really drastic corruption circumstance will this 244 // not work. 245 $additions['panels_node'] = db_fetch_array(db_query("SELECT * FROM {panels_node} WHERE nid = %d", $node->nid)); 246 return $additions; 247 } 248 249 /** 250 * Implementation of hook_insert(). 251 */ 252 function panels_node_insert(&$node) { 253 // Create a new display and record that. 254 $display = panels_new_display(); 255 $display->layout = $node->panels_node['layout']; 256 257 // Special handling for nodes being imported from an export.module data dump. 258 if (!empty($node->export_display)) { 259 // This works by overriding the $display set above 260 eval($node->export_display); 261 unset($node->export_display); 262 } 263 264 panels_save_display($display); 265 $css_id = $node->panels_node['css_id']; 266 267 db_query("INSERT INTO {panels_node} (nid, did, css_id, pipeline) VALUES (%d, %d, '%s', '%s')", $node->nid, $display->did, $node->panels_node['css_id'], $node->panels_node['pipeline']); 268 269 $node->panels_node['did'] = $display->did; 270 } 271 272 /** 273 * Implementation of hook_delete(). 274 */ 275 function panels_node_delete(&$node) { 276 db_query("DELETE FROM {panels_node} WHERE nid = %d", $node->nid); 277 if (!empty($node->panels_node['did'])) { 278 panels_delete_display($node->panels_node['did']); 279 } 280 } 281 282 /** 283 * Implementation of hook_update(). 284 */ 285 function panels_node_update($node) { 286 db_query("UPDATE {panels_node} SET css_id = '%s', pipeline = '%s' WHERE nid = %d", $node->panels_node['css_id'], $node->panels_node['pipeline'], $node->nid); 287 } 288 289 /** 290 * Implementation of hook_view(). 291 */ 292 function panels_node_view($node, $teaser = FALSE, $page = FALSE) { 293 static $rendering = array(); 294 295 // Prevent loops if someone foolishly puts the node inside itself: 296 if (!empty($rendering[$node->nid])) { 297 return $node; 298 } 299 300 $rendering[$node->nid] = TRUE; 301 ctools_include('plugins', 'panels'); 302 if ($teaser) { 303 // Do the standard view for teaser. 304 $node = node_prepare($node, $teaser); 305 // Because our teasier is never the same as our content, *always* provide 306 // the read more flag. 307 $node->readmore = TRUE; 308 } 309 else { 310 if (!empty($node->panels_node['did'])) { 311 $display = panels_load_display($node->panels_node['did']); 312 $display->css_id = $node->panels_node['css_id']; 313 // TODO: Find a way to make sure this can't node_view. 314 $display->context = panels_node_get_context($node); 315 $renderer = panels_get_renderer($node->panels_node['pipeline'], $display); 316 $node->content['body'] = array( 317 '#value' => panels_render_display($display, $renderer), 318 '#weight' => 0, 319 ); 320 } 321 } 322 323 unset($rendering[$node->nid]); 324 return $node; 325 } 326 327 // --------------------------------------------------------------------------- 328 // Administrative pages 329 330 /** 331 * Settings for panel nodes. 332 */ 333 function panels_node_settings() { 334 ctools_include('common', 'panels'); 335 return drupal_get_form('panels_common_settings', 'panels_node'); 336 } 337 338 // --------------------------------------------------------------------------- 339 // Meat of the Panels API; almost completely passing through to panels.module 340 341 /** 342 * Pass through to the panels layout editor. 343 */ 344 function panels_node_edit_layout($node) { 345 // ctools_include('plugins', 'panels'); 346 ctools_include('context'); 347 $display = panels_load_display($node->panels_node['did']); 348 $display->context = panels_node_get_context($node); 349 return panels_edit_layout($display, t('Save'), "node/$node->nid/panel_layout", 'panels_node'); 350 } 351 352 /** 353 * Pass through to the panels content editor. 354 */ 355 function panels_node_edit_content($node) { 356 // ctools_include('plugins', 'panels'); 357 ctools_include('context'); 358 $display = panels_load_display($node->panels_node['did']); 359 $display->context = panels_node_get_context($node); 360 ctools_include('common', 'panels'); 361 $content_types = panels_common_get_allowed_types('panels_node', $display->context); 362 363 // Print this with theme('page') so that blocks are disabled while editing a display. 364 // This is important because negative margins in common block layouts (i.e, Garland) 365 // messes up the drag & drop. 366 print theme('page', panels_edit($display, "node/$node->nid/panel_content", $content_types), FALSE); 367 } 368 369 /** 370 * Build the context to use for a panel node. 371 */ 372 function panels_node_get_context(&$node) { 373 ctools_include('context'); 374 $context = ctools_context_create('node', $node); 375 $context->identifier = t('This node'); 376 $context->keyword = 'node'; 377 return array('panel-node' => $context); 378 } 379 380 /** 381 * Implementation of hook_export_node_alter() 382 * 383 * Integrate with export.module for saving panel_nodes into code. 384 */ 385 function panels_node_export_node_alter(&$node, $original_node, $method) { 386 if ($method == 'export') { 387 $node_export_omitted = variable_get('node_export_omitted', array()); 388 if (variable_get('node_export_method', '') != 'save-edit' && (array_key_exists('panel', $node_export_omitted) && !$node_export_omitted['panel'])) { 389 drupal_set_message(t("NOTE: in order to import panel_nodes you must first set the export.module settings to \"Save as a new node then edit\", otherwise it won't work.")); 390 } 391 $display = panels_load_display($node->panels_node['did']); 392 $export = panels_export_display($display); 393 $node->export_display = $export; 394 } 395 } 396 397 /** 398 * Implementation of hook_panels_dashboard_blocks(). 399 * 400 * Adds panel nodes information to the Panels dashboard. 401 */ 402 function panels_node_panels_dashboard_blocks(&$vars) { 403 $vars['links']['panels_node'] = array( 404 'title' => l(t('Panel node'), 'node/add/panel'), 405 'description' => t('Panel nodes are node content and appear in your searches, but are more limited than panel pages.'), 406 'weight' => -1, 407 ); 408 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |