| Commit | Line | Data |
|---|---|---|
| 9f3609c9 EM |
1 | <?php |
| 2 | // $Id$ | |
| 3 | ||
| 4 | /** | |
| 5 | * Implementation of hook_help() | |
| 6 | */ | |
| 7 | function panels_help($section = '') { | |
| 8 | switch ($section) { | |
| 9 | case 'admin/modules#description': | |
| 10 | return t('The panels module allows the creation of pages with flexible layouts.'); | |
| 11 | case 'admin/panels': | |
| 12 | case 'admin/panels/list': | |
| 13 | return t('<p>You may peruse a list of your current panels layouts and edit them, or click add to create a new page.</p>'); | |
| 14 | case 'admin/panels/add': | |
| 15 | return t('<p>Choose a layout for your new page from the list below.</p>'); | |
| 16 | } | |
| 17 | } | |
| 18 | ||
| 19 | /** | |
| 20 | * Implementation of hook_perm() | |
| 21 | */ | |
| 22 | function panels_perm() { | |
| a2df027f | 23 | return array('create panels'); |
| 9f3609c9 EM |
24 | } |
| 25 | ||
| 26 | /** | |
| 27 | * Implementation of hook_menu() | |
| 28 | */ | |
| 29 | function panels_menu($may_cache) { | |
| 30 | if ($may_cache) { | |
| a2df027f | 31 | $access = user_access('create panels'); |
| 9f3609c9 EM |
32 | $items[] = array( |
| 33 | 'path' => 'admin/panels', | |
| 34 | 'title' => t('panels'), | |
| 35 | 'access' => $access, | |
| 36 | 'callback' => 'panels_list_page', | |
| 37 | ); | |
| 38 | $items[] = array( | |
| 39 | 'path' => 'admin/panels/list', | |
| 40 | 'title' => t('list'), | |
| 41 | 'access' => $access, | |
| 42 | 'callback' => 'panels_list_page', | |
| 43 | 'weight' => -10, | |
| 44 | 'type' => MENU_DEFAULT_LOCAL_TASK, | |
| 45 | ); | |
| 46 | $items[] = array( | |
| 47 | 'path' => 'admin/panels/add', | |
| 48 | 'title' => t('add'), | |
| 49 | 'access' => $access, | |
| 50 | 'callback' => 'panels_add_page', | |
| 51 | 'type' => MENU_LOCAL_TASK, | |
| 52 | ); | |
| 53 | $items[] = array( | |
| 54 | 'path' => 'admin/panels/add/layout', | |
| 55 | 'title' => t('add'), | |
| 56 | 'access' => $access, | |
| 57 | 'callback' => 'panels_add_layout_page', | |
| 58 | 'type' => MENU_LOCAL_TASK, | |
| 59 | ); | |
| 60 | $items[] = array( | |
| 61 | 'path' => 'admin/panels/edit', | |
| 62 | 'title' => t('edit panels'), | |
| 63 | 'access' => $access, | |
| 64 | 'callback' => 'panels_edit_page', | |
| 65 | 'type' => MENU_CALLBACK, | |
| 66 | ); | |
| 67 | $items[] = array( | |
| 68 | 'path' => 'admin/panels/delete', | |
| 69 | 'title' => t('delete panels'), | |
| 70 | 'access' => $access, | |
| 71 | 'callback' => 'panels_delete_page', | |
| 72 | 'type' => MENU_CALLBACK, | |
| 73 | ); | |
| 74 | ||
| 75 | $items[] = array( | |
| 76 | 'path' => 'panels/node/autocomplete', | |
| 77 | 'title' => t('autocomplete node'), | |
| 78 | 'callback' => 'panels_node_autocomplete', | |
| 79 | 'access' => user_access('access content'), | |
| 80 | 'type' => MENU_CALLBACK | |
| 81 | ); | |
| 82 | ||
| a2df027f | 83 | // load panels from database |
| 9f3609c9 EM |
84 | $result = db_query("SELECT * FROM {panels_info}"); |
| 85 | // FIXME: Fow now we're making these all callbacks, but we | |
| 86 | // should steal code from Views so they can be normal, tabs, | |
| 87 | // etc | |
| 88 | while ($panels = db_fetch_object($result)) { | |
| 89 | $items[] = array( | |
| 90 | 'path' => $panels->path, | |
| 91 | 'title' => $panels->title, | |
| 92 | 'access' => panels_access(unserialize($panels->access)), | |
| 93 | 'callback' => 'panels_panels_page', | |
| 94 | 'callback arguments' => array($panels->did), | |
| 95 | 'type' => MENU_CALLBACK | |
| 96 | ); | |
| 97 | } | |
| 98 | } | |
| 99 | return $items; | |
| 100 | } | |
| 101 | ||
| 102 | /** | |
| 103 | * Determine whether or not the current user has access to this | |
| 104 | * panels. | |
| 105 | */ | |
| 106 | function panels_access($access) { | |
| 107 | // for now | |
| 108 | return TRUE; | |
| 109 | } | |
| 110 | ||
| 111 | /** | |
| 112 | * panels path helper function | |
| 113 | */ | |
| 114 | function panels_get_file_path($module, $file, $base_path = true) { | |
| 115 | if ($base_path) { | |
| 116 | $output = base_path(); | |
| 117 | } | |
| 118 | return $output . drupal_get_path('module', $module) . '/' . $file; | |
| 119 | } | |
| 120 | ||
| 121 | // --------------------------------------------------------------------------- | |
| 122 | // panels custom image button | |
| 123 | ||
| 124 | /** | |
| 125 | * Custom form element to do our nice images. | |
| 126 | */ | |
| 127 | function panels_elements() { | |
| 128 | $type['panels_imagebutton'] = array('#input' => TRUE, '#button_type' => 'submit',); | |
| 129 | return $type; | |
| 130 | } | |
| 131 | ||
| 132 | /** | |
| 133 | * Theme our image button. | |
| 134 | */ | |
| 135 | function theme_panels_imagebutton($element) { | |
| 136 | return '<input type="image" class="form-'. $element['#button_type'] .'" name="'. $element['#name'] .'" value="'. check_plain($element['#default_value']) .'" '. drupal_attributes($element['#attributes']) . ' src="' . $element['#image'] . '" alt="' . $element['#title'] . '" title="' . $element['#title'] . "\" />\n"; | |
| 137 | } | |
| 138 | ||
| 139 | function panels_imagebutton_value() { | |
| 140 | // null function guarantees default_value doesn't get moved to #value. | |
| 141 | } | |
| 142 | ||
| 143 | /** | |
| 144 | * Add a single button to a form. | |
| 145 | */ | |
| 146 | function panels_add_button($image, $name, $text) { | |
| 147 | $module_path = base_path() . drupal_get_path('module', 'panels'); | |
| 148 | ||
| 149 | return array( | |
| 150 | '#type' => 'panels_imagebutton', | |
| 151 | '#image' => $module_path . '/images/' . $image, | |
| 152 | '#title' => $text, | |
| 153 | '#default_value' => $name, | |
| 154 | ); | |
| 155 | } | |
| 156 | ||
| 157 | /** | |
| 158 | * Set a button to a blank image -- used for placeholders when buttons are | |
| 159 | * not relevant but just removing it would be visually unappealing. | |
| 160 | */ | |
| 161 | function panels_set_blank(&$form) { | |
| 162 | $form['#type'] = 'markup'; | |
| 163 | $form['#value'] = theme('image', drupal_get_path('module', 'panels') . '/images/blank.gif'); | |
| 164 | } | |
| 165 | ||
| 166 | // --------------------------------------------------------------------------- | |
| 167 | // panels administrative pages | |
| 168 | ||
| 169 | /** | |
| a2df027f | 170 | * Provide a list of panels, with links to edit or delete them. |
| 9f3609c9 EM |
171 | */ |
| 172 | function panels_list_page() { | |
| 173 | $result = db_query("SELECT * FROM {panels_info} ORDER BY title"); | |
| 174 | while ($panels = db_fetch_object($result)) { | |
| 175 | $item = array(); | |
| 176 | $item[] = check_plain($panels->title); | |
| 177 | $item[] = l($panels->path, $panels->path); | |
| 178 | $item[] = implode(' | ', array( | |
| 179 | l('edit', "admin/panels/edit/$panels->did"), | |
| 180 | l('delete', "admin/panels/delete/$panels->did"), | |
| 181 | )); | |
| 182 | $items[] = $item; | |
| 183 | } | |
| 184 | $header = array( | |
| b691d1ca | 185 | t('Panel title'), |
| 9f3609c9 EM |
186 | t('URL'), |
| 187 | t('Operations'), | |
| 188 | ); | |
| 189 | $output = theme('table', $header, $items); | |
| 190 | return $output; | |
| 191 | } | |
| 192 | ||
| 193 | /* | |
| b691d1ca | 194 | * Provide a form to confirm deletion of a panel page. |
| 9f3609c9 EM |
195 | */ |
| 196 | function panels_delete_page($did = '') { | |
| 197 | $panels = panels_load_panels($did); | |
| 198 | ||
| 199 | if (!$panels) { | |
| 200 | return 'admin/panels'; | |
| 201 | } | |
| 202 | ||
| 203 | $form['did'] = array('#type' => 'value', '#value' => $panels->did); | |
| 204 | return confirm_form('panels_delete_confirm', $form, | |
| 205 | t('Are you sure you want to delete %title?', array('%title' => $panels->title)), | |
| 206 | $_GET['destination'] ? $_GET['destination'] : 'admin/panels', | |
| 207 | t('This action cannot be undone.'), | |
| 208 | t('Delete'), t('Cancel') | |
| 209 | ); | |
| 210 | } | |
| 211 | ||
| 212 | /* | |
| b691d1ca | 213 | * Handle the submit button to delete a panel page. |
| 9f3609c9 EM |
214 | */ |
| 215 | function panels_delete_confirm_submit($formid, $form) { | |
| 216 | if ($form['confirm']) { | |
| 217 | panels_delete_panels((object) $form); | |
| 218 | drupal_goto('admin/panels'); | |
| 219 | } | |
| 220 | } | |
| 221 | ||
| 222 | /** | |
| 223 | * Handle the add panels page | |
| 224 | */ | |
| 225 | function panels_add_page($layout = NULL) { | |
| 226 | $layouts = panels_get_layouts(); | |
| 227 | theme_add_style(drupal_get_path('module', 'panels') . '/panels_admin.css'); | |
| 228 | if (!$layout) { | |
| 229 | foreach ($layouts as $id => $layout) { | |
| 230 | if (!$default_id) { | |
| 231 | // grab the first one for our default. | |
| 232 | $default_id = $id; | |
| 233 | } | |
| 234 | $file = panels_get_file_path($layout['module'], $layout['icon'], false); | |
| 235 | $output .= theme('panels_add_image', $layout[title], $id, l(theme('image', $file), $_GET['q'] . '/' . $id, NULL, NULL, NULL, NULL, TRUE)); | |
| 236 | } | |
| 237 | return $output; | |
| 238 | } | |
| 239 | ||
| 240 | if (!$layouts[$layout]) { | |
| 241 | return drupal_not_found(); | |
| 242 | } | |
| 243 | ||
| 244 | $panels->layout = $layout; | |
| 245 | return panels_edit_form($panels); | |
| 246 | } | |
| 247 | ||
| 248 | function theme_panels_add_image($title, $id, $image) { | |
| 249 | $output .= '<div class="layout-link">'; | |
| 250 | $output .= $image; | |
| 251 | $output .= '<div>' . l($title, $_GET['q'] . '/' . $id) . '</div>'; | |
| 252 | $output .= '</div>'; | |
| 253 | return $output; | |
| 254 | } | |
| 255 | // --------------------------------------------------------------------------- | |
| 256 | // panels administrative pages | |
| 257 | ||
| 258 | function panels_edit_page($did = NULL) { | |
| 259 | if (!$did || !($panels = panels_load_panels($did))) { | |
| 260 | return drupal_not_found(); | |
| 261 | } | |
| 262 | return panels_edit_form($panels); | |
| 263 | } | |
| 264 | ||
| 265 | /** | |
| 266 | * shortcut to ease the syntax of the various form builder tricks we use. | |
| 267 | */ | |
| 268 | function panels_form_builder(&$form, $form_id = 'panels_edit_form') { | |
| 269 | $form = form_builder($form_id, $form); | |
| 270 | } | |
| 271 | ||
| 272 | /** | |
| 273 | * Edit an already loaded panels. | |
| 274 | */ | |
| 275 | function panels_edit_form($panels) { | |
| 276 | theme_add_style(drupal_get_path('module', 'panels') . '/panels_admin.css'); | |
| 277 | $layouts = panels_get_layouts(); | |
| 278 | $layout = $layouts[$panels->layout]; | |
| 279 | ||
| 280 | $content_types = panels_get_content_types(); | |
| 281 | ||
| 282 | // Process all our add button stuff first so we can add stuff to the | |
| 283 | // form semi dynamically. | |
| 284 | ||
| 285 | $form['add'] = array( | |
| 286 | '#type' => 'fieldset', | |
| 287 | '#title' => t('Add content'), | |
| 288 | '#collapsible' => false, | |
| 289 | '#description' => t('Select an area to add content to, then select a type of content and click the appropriate button. The content will be added.'), | |
| 290 | ); | |
| 291 | ||
| 292 | $default_radio = array_shift(array_keys($layout['content areas'])); | |
| 293 | $form['add']['area'] = array( | |
| 294 | '#type' => 'radios', | |
| 295 | '#title' => t('Area'), | |
| 296 | '#options' => $layout['content areas'], | |
| 297 | '#prefix' => '<div class="container-inline">', | |
| 298 | '#suffix' => '</div>', | |
| 299 | '#default_value' => $default_radio, | |
| 300 | ); | |
| 301 | foreach ($content_types as $id => $type) { | |
| 302 | $function = $type['admin']; | |
| 303 | if (function_exists($function)) { | |
| 304 | global $form_values; | |
| 305 | $form['add'][$id] = $function('add button', $dummy); | |
| 306 | ||
| 307 | // $dummy needed for cause you can't have default args on a reference. | |
| 308 | $form['add'][$id]['#parents'] = array('add', $id); | |
| 309 | $form['add'][$id]['#tree'] = true; | |
| 310 | panels_form_builder($form['add'][$id]); | |
| 311 | ||
| 312 | if ($conf = $function('add', $form_values['add'][$id])) { | |
| 2b02136c | 313 | $add->configuration = $conf; |
| 9f3609c9 EM |
314 | $add->type = $id; |
| 315 | $form['add']['area']['#parents'] = array('area'); | |
| 316 | panels_form_builder($form['add']['area']); | |
| 317 | $add->area = $form_values['area']; | |
| 318 | } | |
| 319 | } | |
| 320 | } | |
| 321 | ||
| 322 | $form['layout'] = array( | |
| 323 | '#type' => 'value', | |
| 324 | '#value' => $panels->layout | |
| 325 | ); | |
| 326 | ||
| 327 | $form['did'] = array( | |
| 328 | '#type' => 'value', | |
| 329 | '#value' => $panels->did, | |
| 330 | ); | |
| 331 | ||
| 332 | $form['info'] = array( | |
| 333 | '#type' => 'fieldset', | |
| 334 | '#title' => t('General information'), | |
| 335 | '#collapsible' => false, | |
| 336 | ); | |
| 337 | ||
| 338 | $file = panels_get_file_path($layout['module'], $layout['icon'], false); | |
| 339 | $icon .= theme('image', $file); | |
| 340 | $form['info']['layout-icon'] = array( | |
| 341 | '#value' => '<div class="layout-icon">' . $icon . '</div>', | |
| 342 | ); | |
| 343 | ||
| 344 | $form['info']['layout-display'] = array( | |
| 345 | '#value' => '<strong>Layout</strong>: ' . $layout['title'], | |
| 346 | ); | |
| 347 | ||
| 348 | $form['info']['title'] = array( | |
| 349 | '#type' => 'textfield', | |
| 350 | '#default_value' => $panels->title, | |
| 351 | '#title' => t('Page title'), | |
| 352 | '#description' => t('The page title for this panels layout'), | |
| 353 | ); | |
| 354 | ||
| 355 | $form['info']['css_id'] = array( | |
| 356 | '#type' => 'textfield', | |
| 357 | '#default_value' => $panels->css_id, | |
| 358 | '#title' => t('CSS ID'), | |
| 359 | '#description' => t('The CSS ID to apply to this page'), | |
| 360 | ); | |
| 361 | ||
| 362 | $form['info']['path'] = array( | |
| 363 | '#type' => 'textfield', | |
| 364 | '#default_value' => $panels->path, | |
| 365 | '#title' => t('Path'), | |
| 366 | '#description' => t('The URL path to give this page, i.e, path/to/page'), | |
| 367 | '#required' => TRUE, | |
| 368 | ); | |
| 369 | ||
| 370 | $form['content'] = array( | |
| 371 | '#tree' => true, | |
| 372 | ); | |
| 373 | ||
| 374 | // Go through our content areas and display what we have. | |
| 375 | foreach ($layout['content areas'] as $area => $title) { | |
| 376 | $list = array(); | |
| 377 | $form['content'][$area] = array( | |
| 378 | '#tree' => true, | |
| 379 | ); | |
| 380 | ||
| 381 | // Construct the order, feeding it the default order for what | |
| 382 | // we know about. When we pull it back out, it may well be | |
| 383 | // different due to past submits. | |
| 384 | $order = array(); | |
| 385 | if (is_array($panels->content[$area])) { | |
| 386 | $order = array_keys($panels->content[$area]); | |
| 387 | } | |
| 388 | $form['content'][$area]['order'] = array( | |
| 389 | '#type' => 'hidden', | |
| 390 | '#default_value' => serialize($order), | |
| 391 | '#parents' => array('content', $area, 'order'), | |
| 392 | ); | |
| 393 | ||
| 394 | // If an add button has added an item to the area, put it in and update | |
| 395 | // the $order. | |
| 396 | panels_form_builder($form['content'][$area]['order']); | |
| 397 | $order = unserialize($form['content'][$area]['order']['#value']); | |
| 398 | if ($add->area == $area) { | |
| 399 | // say THIS 5 times real fast | |
| 400 | if ($panels->content[$area]) { | |
| 401 | $position = max(max(array_keys($order)), max(array_keys($panels->content[$area]))) + 1; | |
| 402 | } | |
| 403 | else if ($order) { | |
| 404 | $position = max(array_keys($order)) + 1; | |
| 405 | } | |
| 406 | else { | |
| 407 | $position = 0; | |
| 408 | } | |
| 9f3609c9 | 409 | |
| 2b02136c | 410 | $panels->content[$area][$position] = $add; |
| 9f3609c9 EM |
411 | $order[] = $position; |
| 412 | $form['content'][$area]['order']['#value'] = serialize($order); | |
| 413 | } | |
| 414 | ||
| 415 | // Go through each item in the area and render it. | |
| 416 | $count = count($order); | |
| 417 | foreach ($order as $position => $id) { | |
| 418 | // place buttons to re-order content. | |
| 419 | $form['content'][$area][$id]['buttons'] = array( | |
| 420 | '#parents' => array('content', $area, $id, 'buttons'), | |
| 421 | '#tree' => TRUE | |
| 422 | ); | |
| 423 | panels_add_buttons($form['content'][$area][$id]['buttons'], $count, $position); | |
| 424 | ||
| 425 | // figure out if one of those buttons was pressed | |
| 426 | panels_form_builder($form['content'][$area][$id]['buttons']); | |
| 427 | $deleted = false; | |
| 428 | foreach ($GLOBALS['form_values']['content'][$area][$id]['buttons'] as $button => $value) { | |
| 429 | if ($value) { | |
| 430 | $function = 'panels_move_' . $button; | |
| 431 | $function($order, $position); | |
| 432 | $form['content'][$area]['order']['#value'] = serialize($order); | |
| 433 | if ($button == 'delete') | |
| 434 | $deleted = true; | |
| 435 | } | |
| 436 | } | |
| 437 | // If a content item was deleted, it still has buttons. Get rid of them. | |
| 438 | // It had buttons because we needed to give it buttons to see if its | |
| 439 | // buttons were clicked. | |
| 440 | if ($deleted) { | |
| 441 | unset($form['content'][$area][$id]['buttons']); | |
| 442 | } | |
| 443 | else { | |
| 444 | // we finally get to add the conent item's content to the form. | |
| 445 | $area_record = $panels->content[$area][$id]; | |
| 446 | $form['content'][$area][$id]['type'] = array( | |
| 447 | '#type' => 'hidden', | |
| 448 | '#default_value' => $area_record->type, | |
| 449 | '#parents' => array('content', $area, $id, 'type'), | |
| 450 | ); | |
| 451 | // retrieve what was already there -- so we can retain edits and | |
| 452 | // content items that were added. | |
| 453 | panels_form_builder($form['content'][$area][$id]['type']); | |
| 454 | $type = $form['content'][$area][$id]['type']['#value']; | |
| 455 | $function = $content_types[$type]['admin']; | |
| 456 | if (function_exists($function)) { | |
| 457 | $array = array( | |
| 458 | '#tree' => true, | |
| 459 | '#parents' => array('content', $area, $id, 'configuration'), | |
| 460 | ); | |
| 461 | $form['content'][$area][$id]['configuration'] = array_merge($array, $function('edit', $area_record->configuration, array('content', $area, $id, 'configuration'))); | |
| 462 | panels_form_builder($form['content'][$area][$id]['configuration']); | |
| 463 | } | |
| 464 | } | |
| 465 | } | |
| 466 | } | |
| 467 | ||
| 468 | $form['submit'] = array( | |
| 469 | '#type' => 'submit', | |
| 470 | '#value' => t('Save'), | |
| 471 | ); | |
| 472 | ||
| 473 | return drupal_get_form('panels_edit_form', $form); | |
| 474 | } | |
| 475 | ||
| 476 | /** | |
| 477 | * Display the form to edit a panels. | |
| 478 | */ | |
| 479 | function theme_panels_edit_form($form) { | |
| 480 | $layouts = panels_get_layouts(); | |
| 481 | $layout = $layouts[$form['layout']['#value']]; | |
| 482 | ||
| 483 | $content_types = panels_get_content_types(); | |
| 484 | ||
| 485 | $output .= form_render($form['info']); | |
| 486 | foreach ($layout['content areas'] as $area => $title) { | |
| 487 | $order = unserialize($form['content'][$area]['order']['#value']); | |
| 488 | if (!$order) { | |
| 489 | $area_content = t('This area has no content.'); | |
| 490 | } | |
| 491 | else { | |
| 492 | $area_content = ''; | |
| 493 | $count = count($order); | |
| 494 | foreach ($order as $position => $id) { | |
| 495 | if ($count > 1) { | |
| 496 | if ($position == 0 ) { | |
| 497 | panels_set_blank($form['content'][$area][$id]['buttons']['up']); | |
| 498 | } | |
| 499 | else if ($position == ($count - 1)) { | |
| 500 | panels_set_blank($form['content'][$area][$id]['buttons']['down']); | |
| 501 | } | |
| 502 | } | |
| 503 | $type = $form['content'][$area][$id]['type']['#value']; | |
| 504 | $function = $content_types[$type]['admin']; | |
| 505 | if (function_exists($function)) { | |
| 506 | // figure out the actual values; using the global because we need it | |
| 507 | // to be in the same format it'll be in 'submit'. | |
| 508 | global $form_values; | |
| 509 | $conf_form = $form_values['content'][$area][$id]['configuration']; | |
| 510 | $conf = $function('save', $conf_form); | |
| 511 | $fieldset = array( | |
| 512 | '#title' => t('Configure'), | |
| 513 | '#children' => form_render($form['content'][$area][$id]['configuration']), | |
| 514 | '#collapsible' => true, | |
| 515 | '#collapsed' => true | |
| 516 | ); | |
| 517 | $buttons = form_render($form['content'][$area][$id]['buttons']); | |
| 518 | $area_content .= $buttons . ' ' . $function('list', $conf) . | |
| 519 | theme('fieldset', $fieldset) /* . '<br />' */; | |
| 520 | } | |
| 521 | } | |
| 522 | } | |
| 523 | $content[$area] = theme('fieldset', array('#title' => check_plain($title), '#value' => $area_content)); | |
| 524 | } | |
| 525 | ||
| 526 | $output .= panels_get_layout($layout, $content); | |
| 527 | ||
| 528 | $output .= form_render($form); | |
| 529 | return $output; | |
| 530 | } | |
| 531 | ||
| 532 | function panels_edit_form_validate($form_id, $form_values, $form) { | |
| 533 | $content_types = panels_get_content_types(); | |
| 534 | foreach ($form_values['content'] as $area => $content) { | |
| 535 | foreach ($content as $id => $item) { | |
| 536 | if (is_numeric($id)) { | |
| 537 | $function = $content_types[$item['type']]['admin']; | |
| 538 | if (function_exists($function)) { | |
| 539 | $function('validate', $item['configuration'], $form['content'][$area][$id]['configuration']); | |
| 540 | } | |
| 541 | } | |
| 542 | } | |
| 543 | } | |
| 544 | } | |
| 545 | ||
| 546 | function panels_edit_form_submit($form_id, $form_values) { | |
| 547 | $panels = (object) $form_values; | |
| 548 | // be sure we get the order right. | |
| 549 | foreach ($form_values['content'] as $area => $content) { | |
| 550 | $array = array(); | |
| 551 | $order = unserialize($content['order']); | |
| 552 | if (is_array($order)) { | |
| 553 | foreach($order as $id) { | |
| 554 | $array[] = $content[$id]; | |
| 555 | } | |
| 556 | } | |
| 557 | $panels->content[$area] = $array; | |
| 558 | } | |
| 559 | panels_save_panels($panels); | |
| 560 | drupal_set_message(t('The panels has been saved.')); | |
| 561 | return 'admin/panels'; | |
| 562 | } | |
| 563 | ||
| 564 | /** | |
| 565 | * add the buttons to a content item | |
| 566 | */ | |
| 567 | function panels_add_buttons(&$form, $count, $position) { | |
| 568 | $form['delete'] = panels_add_button('user-trash.png', 'delete', t('Delete this item')); | |
| 569 | // Leaving these in but commented out as I'm not convinced we don't want them. | |
| 570 | // if ($count > 2) { | |
| 571 | // $form['top'] = panels_add_button('go-top.png', 'top', t('Move item to top')); | |
| 572 | // } | |
| 573 | if ($count > 1) { | |
| 574 | $form['up'] = panels_add_button('go-up.png', 'up', t('Move item up')); | |
| 575 | $form['down'] = panels_add_button('go-down.png', 'down', t('Move item down')); | |
| 576 | } | |
| 577 | // if ($count > 2) { | |
| 578 | // $form['bottom'] = panels_add_button('go-bottom.png', 'bottom', t('Move item to bottom')); | |
| 579 | // } | |
| 580 | // if ($count > 1) { | |
| 581 | // $form['spacer'] = panels_add_blank(); | |
| 582 | // } | |
| 583 | return $form; | |
| 584 | } | |
| 585 | ||
| 586 | /** | |
| 587 | * move an item in an array to the top | |
| 588 | */ | |
| 589 | function panels_move_top(&$array, &$position) { | |
| 590 | $value = $array[$position]; | |
| 591 | unset($array[$position]); | |
| 592 | array_unshift($array, $value); | |
| 593 | // reindex the array now | |
| 594 | $array = array_values($array); | |
| 595 | } | |
| 596 | ||
| 597 | /** | |
| 598 | * move an item in an array to the bottom | |
| 599 | */ | |
| 600 | function panels_move_bottom(&$array, &$position) { | |
| 601 | $value = $array[$position]; | |
| 602 | unset($array[$position]); | |
| 603 | $array[] = $value; | |
| 604 | // reindex the array now | |
| 605 | $array = array_values($array); | |
| 606 | } | |
| 607 | ||
| 608 | /** | |
| 609 | * move an item in an array up one position | |
| 610 | */ | |
| 611 | function panels_move_up(&$array, &$position) { | |
| 612 | $value = $array[$position]; | |
| 613 | $array[$position] = $array[$position - 1]; | |
| 614 | $array[$position - 1] = $value; | |
| 615 | } | |
| 616 | ||
| 617 | /** | |
| 618 | * move an item in an array up one position | |
| 619 | */ | |
| 620 | function panels_move_down(&$array, &$position) { | |
| 621 | $value = $array[$position]; | |
| 622 | $array[$position] = $array[$position + 1]; | |
| 623 | $array[$position + 1] = $value; | |
| 624 | } | |
| 625 | ||
| 626 | /** | |
| 627 | * Remove an item from an array | |
| 628 | */ | |
| 629 | function panels_move_delete(&$array, &$position) { | |
| 630 | unset($array[$position]); | |
| 631 | // reindex the array now | |
| 632 | $array = array_values($array); | |
| 633 | } | |
| 634 | ||
| 635 | // --------------------------------------------------------------------------- | |
| 636 | // panels database functions | |
| 637 | ||
| 638 | function panels_load_panels($did) { | |
| 639 | $panels = db_fetch_object(db_query("SELECT * FROM {panels_info} WHERE did = %d", $did)); | |
| 640 | if (!$panels) { | |
| 641 | return NULL; | |
| 642 | } | |
| 643 | $result = db_query("SELECT * FROM {panels_area} WHERE did = %d ORDER BY area, position", $did); | |
| 644 | while ($area = db_fetch_object($result)) { | |
| 645 | $area->configuration = unserialize($area->configuration); | |
| 646 | $panels->content[$area->area][] = $area; | |
| 647 | } | |
| 648 | return $panels; | |
| 649 | } | |
| 650 | ||
| 651 | function panels_save_panels($panels) { | |
| 652 | if ($panels->did) { | |
| 653 | db_query("UPDATE {panels_info} SET title = '%s', access = '%s', path = '%s', css_id = '%s', layout = '%s' WHERE did = %d", $panels->title, $panels->access, $panels->path, $panels->css_id, $panels->layout, $panels->did); | |
| 654 | db_query("DELETE FROM {panels_area} WHERE did = %d", $panels->did); | |
| 655 | } | |
| 656 | else { | |
| 657 | $panels->did = db_next_id("{panels_info_id}"); | |
| 658 | db_query("INSERT INTO {panels_info} (did, title, access, path, css_id, layout) VALUES (%d, '%s', '%s', '%s', '%s', '%s')", $panels->did, $panels->title, $panels->access, $panels->path, $panels->css_id, $panels->layout); | |
| 659 | } | |
| 660 | foreach ($panels->content as $area => $info) { | |
| 661 | foreach ($info as $position => $block) { | |
| 662 | if (is_numeric($position)) { // don't save some random form stuff that may've been here. | |
| 663 | $block = (object) $block; | |
| 664 | db_query("INSERT INTO {panels_area} (did, area, type, configuration, position) VALUES(%d, '%s', '%s', '%s', %d)", $panels->did, $area, $block->type, serialize($block->configuration), $position); | |
| 665 | } | |
| 666 | } | |
| 667 | } | |
| 668 | cache_clear_all('menu:', TRUE); | |
| 669 | } | |
| 670 | ||
| 671 | function panels_delete_panels($panels) { | |
| 672 | db_query("DELETE FROM {panels_info} WHERE did = %d", $panels->did); | |
| 673 | db_query("DELETE FROM {panels_area} WHERE did = %d", $panels->did); | |
| 674 | cache_clear_all('menu:', TRUE); | |
| 675 | } | |
| 676 | // --------------------------------------------------------------------------- | |
| 677 | // panels page | |
| 678 | ||
| 679 | function panels_panels_page($did) { | |
| 680 | $panels = panels_load_panels($did); | |
| 681 | if (!$panels) { | |
| 682 | return drupal_not_found(); | |
| 683 | } | |
| 684 | ||
| 685 | $layouts = panels_get_layouts(); | |
| 686 | $layout = $layouts[$panels->layout]; | |
| 687 | ||
| 688 | if (!$layout) { | |
| 689 | watchdog('panels', t('Unable to find requested layout %s', array('%s' => check_plain($panels->layout)))); | |
| 690 | return drupal_not_found(); | |
| 691 | } | |
| 692 | ||
| 693 | $content_types = panels_get_content_types(); | |
| 694 | ||
| 695 | foreach ($panels->content as $location => $list) { | |
| 696 | foreach ($list as $area) { | |
| 697 | $function = $content_types[$area->type]['callback']; | |
| 698 | if (function_exists($function)) { | |
| 699 | $content[$area->area] .= $function($area->configuration); | |
| 700 | } | |
| 701 | } | |
| 702 | } | |
| 703 | $output = panels_get_layout($layout, $content); | |
| 704 | return $output; | |
| 705 | } | |
| 706 | ||
| 707 | function panels_get_layout($layout, $content) { | |
| 708 | $output = theme($layout['theme'], check_plain($layout['css_id']), $content); | |
| 709 | ||
| 710 | if ($output) { | |
| 711 | if (file_exists(path_to_theme() . '/' . $layout['css'])) { | |
| 712 | theme_add_style(path_to_theme() . '/' . $layout['css']); | |
| 713 | } | |
| 714 | else { | |
| 715 | theme_add_style(drupal_get_path('module', $layout['module']) . '/' . $layout['css']); | |
| 716 | } | |
| 717 | } | |
| 718 | return $output; | |
| 719 | } | |
| 720 | ||
| 721 | /** | |
| 722 | * For external use: Given a layout ID and a $content array, return the | |
| 723 | * finished layout. | |
| 724 | */ | |
| 725 | function panels_print_layout($id, $content) { | |
| 726 | $layouts = panels_get_layouts(); | |
| 727 | $layout = $layouts[$id]; | |
| 728 | if (!$layout) { | |
| 729 | return; | |
| 730 | } | |
| 731 | ||
| 732 | return panels_get_layout($layout, $content); | |
| 733 | } | |
| 734 | ||
| 735 | // --------------------------------------------------------------------------- | |
| 736 | // panels data loading | |
| 737 | ||
| 738 | function panels_load_includes($directory, $callback) { | |
| 739 | // Load all our module 'on behalfs'. | |
| 740 | $path = drupal_get_path('module', 'panels') . '/' . $directory; | |
| 741 | $files = system_listing('.inc$', $path, 'name', 0); | |
| 742 | ||
| 743 | foreach($files as $file) { | |
| 744 | require_once($file->filename); | |
| 745 | } | |
| 746 | $output = module_invoke_all($callback); | |
| 747 | foreach ($files as $file) { | |
| 748 | $function = 'panels_' . $file->name . '_' . $callback; | |
| 749 | if (function_exists($function)) { | |
| 750 | $result = $function(); | |
| 751 | if (isset($result) && is_array($result)) { | |
| 752 | $output = array_merge($output, $result); | |
| 753 | } | |
| 754 | } | |
| 755 | } | |
| 756 | return $output; | |
| 757 | } | |
| 758 | ||
| 759 | function panels_get_layouts() { | |
| 760 | static $layout = NULL; | |
| 761 | if (!$layout) { | |
| 762 | $layouts = panels_load_includes('layouts', 'panels_layouts'); | |
| 763 | } | |
| 764 | return $layouts; | |
| 765 | } | |
| 766 | ||
| 767 | function panels_get_content_types() { | |
| 768 | static $layout = NULL; | |
| 769 | if (!$layout) { | |
| 770 | $layouts = panels_load_includes('content_types', 'panels_content_types'); | |
| 771 | } | |
| 772 | return $layouts; | |
| 773 | } | |
| 774 | ||
| 775 | /** | |
| 776 | * Helper function for autocompletion of node titles. | |
| 777 | * This is mostly stolen from clipper. | |
| 778 | */ | |
| 779 | function panels_node_autocomplete($string) { | |
| 780 | if ($string != '') { // if there are node_types passed, we'll use those in a MySQL IN query. | |
| 781 | $result = db_query_range(db_rewrite_sql('SELECT n.title, u.name FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE LOWER(title) LIKE LOWER("%%%s%%")'), $string, 0, 10); | |
| 782 | $prefix = count($array) ? implode(', ', $array) .', ' : ''; | |
| 783 | ||
| 784 | $matches = array(); | |
| 785 | while ($node = db_fetch_object($result)) { | |
| 786 | $n = $node->title; | |
| 787 | // Commas and quotes in terms are special cases, so encode 'em. | |
| 788 | if (preg_match('/,/', $node->title) || preg_match('/"/', $node->title)) { | |
| 789 | $n = '"'. preg_replace('/"/', '""', $node->title) .'"'; | |
| 790 | } | |
| 791 | $matches[$prefix . $n] = '<span class="autocomplete_title">'. check_plain($node->title) .'</span> <span class="autocomplete_user">('. t('by %user', array('%user' => check_plain($node->name))) .')</span>'; | |
| 792 | } | |
| 793 | print drupal_to_js($matches); | |
| 794 | exit(); | |
| 795 | } | |
| 796 | } |