panels_mini.module

Go to the documentation of this file.
00001 <?php
00002 // $Id: panels_mini.module,v 1.1.2.37 2008/10/05 23:28:40 sdboyer Exp $
00003 
00004 /**
00005  * @file panels_mini.module
00006  *
00007  * This module provides mini panels which are basically panels that can be
00008  * used within blocks or other panels.
00009  */
00010 
00011 /**
00012  * Implementation of hook_help().
00013  */
00014 function panels_mini_help($section = '') {
00015   switch ($section) {
00016     case 'admin/panels/panel-mini':
00017     case 'admin/panels/panel-mini/list':
00018       $output = '<p>';
00019       $output .= t('You can edit existing mini panels, or click add to create a new one.');
00020       $output .= '</p>';
00021       break;
00022 
00023     case 'admin/panels/panel-mini/add':
00024       $output = '<p>';
00025       $output .= t('Mini panels are the small variants of panel pages. Instead of pages, they define blocks.');
00026       $output .= '</p>';
00027       break;
00028   }
00029   return $output;
00030 }
00031 
00032 /**
00033  * Implementation of hook_perm().
00034  */
00035 function panels_mini_perm() {
00036   return array('create mini panels', 'administer mini panels');
00037 }
00038 
00039 /**
00040  * Implementation of hook_menu().
00041  */
00042 function panels_mini_menu($may_cache) {
00043   if ($may_cache) {
00044     $access = user_access('create mini panels');
00045 
00046     $items[] = array(
00047       'path' => 'admin/panels/panel-mini',
00048       'title' => t('Mini panels'),
00049       'access' => $access,
00050       'callback' => 'panels_mini_list_page',
00051       'description' => t('Create and administer mini panels (panels exposed as blocks).'),
00052     );
00053     $items[] = array(
00054       'path' => 'admin/panels/panel-mini/list',
00055       'title' => t('List'),
00056       'access' => $access,
00057       'callback' => 'panels_mini_list_page',
00058       'weight' => -10,
00059       'type' => MENU_DEFAULT_LOCAL_TASK,
00060     );
00061     $items[] = array(
00062       'path' => 'admin/panels/panel-mini/add',
00063       'title' => t('Add'),
00064       'access' => $access,
00065       'callback' => 'panels_mini_add_page',
00066       'type' => MENU_LOCAL_TASK,
00067     );
00068     $items[] = array(
00069       'path' => 'admin/panels/panel-mini/import',
00070       'title' => t('Import'),
00071       'access' => $access,
00072       'callback' => 'panels_mini_import_mini',
00073       'type' => MENU_LOCAL_TASK,
00074     );
00075     $items[] = array(
00076       'path' => 'admin/panels/panel-mini/settings',
00077       'title' => t('Settings'),
00078       'access' => $access,
00079       'callback' => 'panels_mini_settings',
00080       'type' => MENU_LOCAL_TASK,
00081     );
00082     $items[] = array(
00083       'path' => 'admin/panels/panel-mini/disable',
00084       'access' => $access,
00085       'callback' => 'panels_mini_disable_page',
00086       'weight' => -1,
00087       'type' => MENU_CALLBACK,
00088     );
00089     $items[] = array(
00090       'path' => 'admin/panels/panel-mini/enable',
00091       'access' => $access,
00092       'callback' => 'panels_mini_enable_page',
00093       'weight' => -1,
00094       'type' => MENU_CALLBACK,
00095     );
00096   }
00097   else {
00098     if (arg(0) == 'admin' && arg(1) == 'panels' && arg(2) == 'panel-mini') {
00099       $mini = panels_mini_load(arg(3));
00100       if ($mini && empty($mini->disabled)) {
00101         $items = array();
00102         panels_mini_menu_items($items, "admin/panels/panel-mini/$mini->name", $mini);
00103       }
00104     }
00105   }
00106   return $items;
00107 }
00108 
00109 function panels_mini_menu_items(&$items, $base, $panel_mini) {
00110   $access = user_access('administer mini panels');
00111 
00112   if ($access) {
00113     $items[] = array(
00114       'path' => $base,
00115       'title' => t('Preview'),
00116       'access' => $access,
00117       'callback' => 'panels_mini_preview_panel',
00118       'callback arguments' => array($panel_mini),
00119       'weight' => -10,
00120       'type' => MENU_CALLBACK,
00121     );
00122     $items[] = array(
00123       'path' => $base . '/preview',
00124       'title' => t('Preview'),
00125       'access' => $access,
00126       'callback' => 'panels_mini_preview_panel',
00127       'callback arguments' => array($panel_mini),
00128       'weight' => -10,
00129       'type' => MENU_DEFAULT_LOCAL_TASK,
00130     );
00131     $items[] = array(
00132       'path' => $base .'/edit/layout',
00133       'title' => t('Layout'),
00134       'access' => $access,
00135       'callback' => 'panels_mini_edit_layout',
00136       'callback arguments' => array($panel_mini),
00137       'weight' => -9,
00138       'type' => MENU_LOCAL_TASK,
00139     );
00140     $items[] = array(
00141       'path' => $base .'/edit/general',
00142       'title' => t('Settings'),
00143       'access' => $access,
00144       'callback' => 'panels_mini_edit',
00145       'callback arguments' => array($panel_mini),
00146       'weight' => -5,
00147       'type' => MENU_LOCAL_TASK,
00148     );
00149     $items[] = array(
00150       'path' => $base .'/edit/settings',
00151       'title' => t('Layout settings'),
00152       'access' => $access,
00153       'callback' => 'panels_mini_edit_layout_settings',
00154       'callback arguments' => array($panel_mini),
00155       'weight' => -3,
00156       'type' => MENU_LOCAL_TASK,
00157     );
00158 
00159     $items[] = array(
00160       'path' => $base . '/edit/context',
00161       'title' => t('Context'),
00162       'access' => $access,
00163       'callback' => 'panels_mini_edit_context',
00164       'callback arguments' => array($panel_mini),
00165       'weight' => -2,
00166       'type' => MENU_LOCAL_TASK,
00167     );
00168 
00169     $items[] = array(
00170       'path' => $base .'/edit/content',
00171       'title' => t('Content'),
00172       'access' => $access,
00173       'callback' => 'panels_mini_edit_content',
00174       'callback arguments' => array($panel_mini),
00175       'weight' => -1,
00176       'type' => MENU_LOCAL_TASK,
00177     );
00178     $items[] = array(
00179       'path' => $base . '/export',
00180       'title' => t('Export'),
00181       'access' => $access,
00182       'callback' => 'drupal_get_form',
00183       'callback arguments' => array('panels_mini_edit_export', $panel_mini),
00184       'weight' => 0,
00185       'type' => MENU_LOCAL_TASK,
00186     );
00187     $items[] = array(
00188       'path' => $base .'/delete',
00189       'title' => t('Delete mini panel'),
00190       'access' => user_access('create mini panels'),
00191       'callback' => 'drupal_get_form',
00192       'callback arguments' => array('panels_mini_delete_confirm', $panel_mini),
00193       'type' => MENU_CALLBACK,
00194     );
00195   }
00196 }
00197 
00198 // ---------------------------------------------------------------------------
00199 // Mini panel administrative pages.
00200 
00201 /**
00202  * Settings for mini panels.
00203  */
00204 function panels_mini_settings() {
00205   panels_load_include('common');
00206   return drupal_get_form('panels_common_settings', 'panels_mini');
00207 }
00208 
00209 /**
00210  * Provide a list of mini panels, with links to edit or delete them.
00211  */
00212 function panels_mini_list_page() {
00213   panels_load_include('plugins');
00214   $layouts = panels_get_layouts();
00215   $items = array();
00216   $sorts = array();
00217 
00218   $header = array(
00219     array('data' => t('Title'), 'field' => 'title'),
00220     array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'),
00221     array('data' => t('Type'), 'field' => 'type'),
00222     t('Layout'),
00223     t('Operations'),
00224   );
00225 
00226   // Load all mini panels and their displays.
00227   $panel_minis = panels_mini_load_all();
00228   $dids = array();
00229   foreach ($panel_minis as $panel_mini) {
00230     if (empty($panel_mini->display)) {
00231       $dids[] = $panel_mini->did;
00232     }
00233   }
00234   $displays = panels_load_displays($dids);
00235 
00236   foreach ($panel_minis as $panel_mini) {
00237     $ops = array();
00238     if (empty($panel_mini->disabled)) {
00239       $ops[] = l(t('Edit'), "admin/panels/panel-mini/$panel_mini->name/edit/general");
00240       $ops[] = l(t('Export'), "admin/panels/panel-mini/$panel_mini->name/export");
00241     }
00242     if ($panel_mini->type != t('Default')) {
00243       $text = ($panel_mini->type == t('Overridden')) ? t('Revert') : t('Delete');
00244       $ops[] = l($text, "admin/panels/panel-mini/$panel_mini->name/delete");
00245     }
00246     else {
00247       if (empty($panel_mini->disabled)) {
00248         $ops[] = l(t('Disable'), "admin/panels/panel-mini/disable/$panel_mini->name", NULL, drupal_get_destination());
00249       }
00250       else {
00251         $ops[] = l(t('Enable'), "admin/panels/panel-mini/enable/$panel_mini->name", NULL, drupal_get_destination());
00252       }
00253     }
00254 
00255     $item = array();
00256     $item[] = check_plain($panel_mini->title);
00257     $item[] = check_plain($panel_mini->name);
00258     // this is safe as it's always programmatic
00259     $item[] = $panel_mini->type;
00260 
00261     if (empty($panel_mini->display)) {
00262       $panel_mini->display = $displays[$panel_mini->did];
00263     }
00264 
00265     $item[] = check_plain($layouts[$panel_mini->display->layout]['title']);
00266     $item[] = implode(' | ', $ops);
00267     $items[] = $item;
00268     $ts = tablesort_init($header);
00269     switch ($ts['sql']) {
00270       case 'title':
00271         $sorts[] = $item[0];
00272         break;
00273 
00274       case 'name':
00275       default:
00276         $sorts[] = $item[1];
00277         break;
00278 
00279       case 'type':
00280         $sorts[] = $panel_mini->type . $item[0];
00281         break;
00282     }
00283   }
00284 
00285   if (drupal_strtolower($ts['sort']) == 'desc') {
00286     arsort($sorts);
00287   }
00288   else {
00289     asort($sorts);
00290   }
00291 
00292   $i = array();
00293   foreach ($sorts as $id => $title) {
00294     $i[] = $items[$id];
00295   }
00296 
00297   $output = theme('table', $header, $i);
00298   return $output;
00299 }
00300 
00301 /**
00302  * Provide a form to confirm deletion of a mini panel.
00303  */
00304 function panels_mini_delete_confirm($panel_mini) {
00305   if (!is_object($panel_mini)) {
00306     $panel_mini = panels_mini_load($panel_mini);
00307   }
00308   $form['pid'] = array('#type' => 'value', '#value' => $panel_mini->pid);
00309   $form['did'] = array('#type' => 'value', '#value' => $panel_mini->did);
00310   return confirm_form($form,
00311     t('Are you sure you want to delete the mini panel "@title"?', array('@title' => $panel_mini->title)),
00312     $_GET['destination'] ? $_GET['destination'] : 'admin/panels/panel-mini',
00313     t('This action cannot be undone.'),
00314     t('Delete'), t('Cancel')
00315   );
00316 }
00317 
00318 /**
00319  * Handle the submit button to delete a mini panel.
00320  */
00321 function panels_mini_delete_confirm_submit($form_id, $form) {
00322   if ($form['confirm']) {
00323     panels_mini_delete((object) $form);
00324     return 'admin/panels/panel-mini';
00325   }
00326 }
00327 
00328 /**
00329  * Provide an administrative preview of a mini panel.
00330  */
00331 function panels_mini_preview_panel($mini) {
00332   $mini->display->args = array();
00333   $mini->display->css_id = panels_mini_get_id($mini->name);
00334 
00335   panels_load_include('plugins');
00336   $mini->context = $mini->display->context = panels_context_load_contexts($mini);
00337 
00338   drupal_set_title(filter_xss_admin($mini->title));
00339   return panels_render_display($mini->display);
00340 }
00341 
00342 /**
00343  * Page callback to export a mini panel to PHP code.
00344  */
00345 function panels_mini_edit_export($panel_mini) {
00346   if (!is_object($panel_mini)) {
00347     $panel_mini = panels_mini_load($panel_mini);
00348   }
00349   drupal_set_title(check_plain($panel_mini->title));
00350   $code = panels_mini_export($panel_mini);
00351 
00352   $lines = substr_count($code, "\n");
00353   $form['code'] = array(
00354     '#type' => 'textarea',
00355     '#title' => $panel_mini->title,
00356     '#default_value' => $code,
00357     '#rows' => $lines,
00358   );
00359   return $form;
00360 }
00361 
00362 /**
00363  * Page callback to import a mini panel from PHP code.
00364  */
00365 function panels_mini_import_mini() {
00366   if ($_POST['form_id'] == 'panels_mini_edit_form') {
00367     $panel_mini = unserialize($_SESSION['pm_import']);
00368     drupal_set_title(t('Import panel mini "@s"', array('@s' => $panel_mini->title)));
00369     return drupal_get_form('panels_mini_edit_form', $panel_mini);
00370   }
00371 
00372   return drupal_get_form('panels_mini_import_form');
00373 }
00374 
00375 /**
00376  * Form for the mini panel import.
00377  */
00378 function panels_mini_import_form() {
00379   $form['panel_mini'] = array(
00380     '#type' => 'textarea',
00381     '#title' => t('Panel mini code'),
00382     '#cols' => 60,
00383     '#rows' => 15,
00384     '#description' => t('Cut and paste the results of an exported mini panel here.'),
00385   );
00386 
00387   $form['submit'] = array(
00388     '#type' => 'submit',
00389     '#value' => t('Import'),
00390   );
00391 
00392   $form['#redirect'] = NULL;
00393   return $form;
00394 }
00395 
00396 /**
00397  * Handle the submit button on importing a mini panel.
00398  */
00399 function panels_mini_import_form_submit($form_id, $form) {
00400   ob_start();
00401   eval($form['panel_mini']);
00402   ob_end_clean();
00403 
00404   if (isset($mini)) {
00405     drupal_set_title(t('Import mini panel "@s"', array('@s' => $mini->title)));
00406     // As $mini contains non-stdClass objects,
00407     // it needs to be serialized before being stored in the session variable.
00408     $_SESSION['pm_import'] = serialize($mini);
00409     $output = drupal_get_form('panels_mini_edit_form', $mini);
00410     print theme('page', $output);
00411     exit;
00412   }
00413   else {
00414     drupal_set_message(t('Unable to get a mini panel out of that.'));
00415   }
00416 }
00417 
00418 /**
00419  * Handle the add mini panel page.
00420  */
00421 function panels_mini_add_page($layout = NULL) {
00422   panels_load_include('plugins');
00423   $layouts = panels_get_layouts();
00424 
00425   if ($layout === NULL) {
00426     foreach ($layouts as $id => $layout) {
00427       $output .= panels_print_layout_link($id, $layout, $_GET['q'] .'/'. $id);
00428     }
00429     return $output;
00430   }
00431 
00432   if (!$layouts[$layout]) {
00433     return drupal_not_found();
00434   }
00435 
00436   $panel_mini = new stdClass();
00437   $panel_mini->display = panels_new_display();
00438   $panel_mini->display->layout = $layout;
00439   $panel_mini->pid = 'new';
00440   $panel_mini->did = 'new';
00441   return panels_mini_edit($panel_mini);
00442 }
00443 
00444 /**
00445  * Edit a mini panel.
00446  *
00447  * Called from both the add and edit points to provide for common flow.
00448  */
00449 function panels_mini_edit($panel_mini) {
00450   if (!is_object($panel_mini)) {
00451     $panel_mini = panels_mini_load($panel_mini);
00452   }
00453   drupal_set_title(check_plain($panel_mini->title));
00454   return drupal_get_form('panels_mini_edit_form', $panel_mini);
00455 }
00456 
00457 /**
00458  * Form to edit the settings of a mini panel.
00459  */
00460 function panels_mini_edit_form($panel_mini) {
00461   panels_load_include('common');
00462   drupal_add_css(panels_get_path('css/panels_admin.css'));
00463 
00464   $form['pid'] = array(
00465     '#type' => 'value',
00466     '#value' => $panel_mini->pid,
00467   );
00468   $form['panel_mini'] = array(
00469     '#type' => 'value',
00470     '#value' => $panel_mini,
00471   );
00472 
00473   $form['right'] = array(
00474     '#prefix' => '<div class="layout-container">',
00475     '#suffix' => '</div>',
00476   );
00477   $form['left'] = array(
00478     '#prefix' => '<div class="info-container">',
00479     '#suffix' => '</div>',
00480   );
00481 
00482   $form['left']['settings'] = array(
00483     '#type' => 'fieldset',
00484     '#title' => t('Settings'),
00485   );
00486   $form['left']['settings']['title'] = array(
00487     '#type' => 'textfield',
00488     '#size' => 24,
00489     '#default_value' => $panel_mini->title,
00490     '#title' => t('Mini panel title'),
00491     '#description' => t('The title for this mini panel. It can be overridden in the block configuration.'),
00492   );
00493 
00494   $form['left']['settings']['name'] = array(
00495     '#type' => 'textfield',
00496     '#size' => 24,
00497     '#default_value' => $panel_mini->name,
00498     '#title' => t('Mini panel name'),
00499     '#description' => t('A unique name used to identify this panel page internally. It must be only be alpha characters and underscores. No spaces, numbers or uppercase characters.'),
00500   );
00501 
00502   $form['left']['settings']['category'] = array(
00503     '#type' => 'textfield',
00504     '#size' => 24,
00505     '#default_value' => $panel_mini->category,
00506     '#title' => t('Mini panel category'),
00507     '#description' => t("The category that this mini-panel will be grouped into on the Add Content form. Only upper and lower-case alphanumeric characters are allowed. If left blank, defaults to 'Mini panels'."),
00508   );
00509 
00510   panels_load_include('plugins');
00511   $panel_mini->context = $panel_mini->display->context = panels_context_load_contexts($panel_mini);
00512 
00513   $form['right']['layout'] = array(
00514     '#type' => 'fieldset',
00515     '#title' => t('Layout'),
00516   );
00517 
00518   $layout = panels_get_layout($panel_mini->display->layout);
00519 
00520   $form['right']['layout']['layout-icon'] = array(
00521     '#value' => panels_print_layout_icon($panel_mini->display->layout, $layout),
00522   );
00523 
00524   $form['right']['layout']['layout-display'] = array(
00525     '#value' => check_plain($layout['title']),
00526   );
00527   $form['right']['layout']['layout-content'] = array(
00528     '#value' => theme('panels_common_content_list', $panel_mini->display),
00529   );
00530 
00531   $contexts = theme('panels_common_context_list', $panel_mini);
00532   if ($contexts) {
00533     $form['right']['context'] = array(
00534       '#type' => 'fieldset',
00535       '#title' => t('Contexts'),
00536     );
00537 
00538     $form['right']['context']['context'] = array(
00539       '#value' => $contexts,
00540     );
00541   }
00542 
00543   $label = ($panel_mini->pid == 'new') ? t('Save and proceed') : t('Save');
00544   $form['submit'] = array(
00545     '#type' => 'submit',
00546     '#value' => $label,
00547   );
00548 
00549   return $form;
00550 }
00551 
00552 /**
00553  * Validate submission of the mini panel edit form.
00554  */
00555 function panels_mini_edit_form_validate($form_id, $form_values, $form) {
00556   // Test uniqueness of name:
00557   if (!$form_values['name']) {
00558     form_error($form['left']['settings']['name'], t('Panel mini name is required.'));
00559   }
00560   else if (preg_match("/[^A-Za-z0-9_]/", $form_values['name'])) {
00561     form_error($form['left']['settings']['name'], t('Name must be alphanumeric or underscores only.'));
00562   }
00563   else if (preg_match("/[^A-Za-z0-9 ]/", $form_values['category'])) {
00564     form_error($form['left']['settings']['category'], t('Categories may contain only alphanumerics or spaces.'));
00565   }
00566   else {
00567     $query = "SELECT pid FROM {panels_mini} WHERE name = '%s'";
00568     if (!empty($form_values['pid']) && is_numeric($form_values['pid'])) {
00569       $query .= " AND pid != $form_values[pid]";
00570     }
00571     if (db_result(db_query($query, $form_values['name']))) {
00572       form_error($form['left']['settings']['name'], t('Panel name must be unique.'));
00573     }
00574   }
00575 }
00576 
00577 /**
00578  * Process submission of the mini panel edit form.
00579  */
00580 function panels_mini_edit_form_submit($form_id, $form_values) {
00581   $panel_mini = $form_values['panel_mini'];
00582   if ($panel_mini->pid != 'new' && $panel_mini->name != $form_values['name']) {
00583     // update all existing mini panels to point to this one appropriately.
00584     db_query("UPDATE {blocks} b SET delta = '%s' WHERE b.module = 'panels_mini' AND b.delta = '%s'", $form_values['name'], $panel_mini->name);
00585 
00586     // Above was blocks; these are actual panel panes.
00587     $result = db_query("SELECT * FROM {panels_pane} WHERE type = 'panels_mini' and subtype = '%s'", $panel_mini->name);
00588     while ($pane = db_fetch_object($result)) {
00589       $conf = unserialize($pane->configuration);
00590       $conf['name'] = $form_values['name'];
00591       db_query("UPDATE {panels_pane} SET configuration = '%s', subtype = '%s' WHERE pid = %d", serialize($conf), $conf['name'], $pane->pid);
00592     }
00593   }
00594 
00595   $panel_mini->title = $form_values['title'];
00596   $panel_mini->name = $form_values['name'];
00597   $panel_mini->category = empty($form_values['category']) ? '' : $form_values['category'];
00598 
00599   if ($panel_mini->pid == 'new') {
00600     unset($_SESSION['pm_import']);
00601     drupal_set_message(t('Your new mini panel %title has been saved.', array('%title' => $panel_mini->title)));
00602     panels_mini_save($panel_mini);
00603     $GLOBALS['form_values']['pid'] = $panel_mini->pid;
00604 
00605     $layout = panels_get_layout($panel_mini->display->layout);
00606 
00607     if ($layout['settings form']) {
00608       return "admin/panels/panel-mini/$panel_mini->name/edit/settings/next";
00609     }
00610     return "admin/panels/panel-mini/$panel_mini->name/edit/context/next";
00611   }
00612   else {
00613     drupal_set_message(t('Your changes have been saved.'));
00614     panels_mini_save($panel_mini);
00615   }
00616 }
00617 
00618 /**
00619  * Form to edit context features of a mini panel.
00620  */
00621 function panels_mini_edit_context($panel_mini, $next = NULL) {
00622   if (!empty($_POST)) {
00623     $panel_mini = panels_common_cache_get('panel_object:panel_mini', $panel_mini->name);
00624   }
00625   else {
00626     panels_common_cache_set('panel_object:panel_mini', $panel_mini->name, $panel_mini);
00627   }
00628 
00629   drupal_set_title(check_plain($panel_mini->title));
00630   return drupal_get_form('panels_mini_context_form', $panel_mini, $next);
00631 }
00632 
00633 /**
00634  * Form to edit the context settings of a mini panel.
00635  */
00636 function panels_mini_context_form($panel_mini, $next = NULL) {
00637   drupal_add_css(panels_get_path('css/panels_admin.css'));
00638   panels_load_include('plugins');
00639   $layout = panels_get_layout($panel_mini->display->layout);
00640 
00641   $form['pid'] = array(
00642     '#type' => 'value',
00643     '#value' => $panel_mini->pid,
00644   );
00645 
00646   $form['panel_mini'] = array(
00647     '#type' => 'value',
00648     '#value' => $panel_mini,
00649   );
00650 
00651   $form['right'] = array(
00652     '#prefix' => '<div class="right-container">',
00653     '#suffix' => '</div>',
00654   );
00655 
00656   $form['left'] = array(
00657     '#prefix' => '<div class="left-container">',
00658     '#suffix' => '</div>',
00659   );
00660 
00661   panels_load_include('common');
00662 
00663   $settings = panels_common_add_context_form('panel_mini', $form, $form['right']['contexts_table'], $panel_mini);
00664   $settings += panels_common_add_required_context_form('panel_mini', $form, $form['left']['required_contexts_table'], $panel_mini);
00665   $settings += panels_common_add_relationship_form('panel_mini', $form, $form['right']['relationships_table'], $panel_mini);
00666   panels_common_add_context_js($settings);
00667 
00668   $label = $next ? t('Save and proceed') : t('Save');
00669   $form['submit'] = array(
00670     '#type' => 'submit',
00671     '#value' => $label,
00672   );
00673 
00674   return $form;
00675 }
00676 
00677 /**
00678  * Process submission of the mini panel edit form.
00679  */
00680 function panels_mini_context_form_submit($form_id, $form_values) {
00681   $panel_mini = $form_values['panel_mini'];
00682 
00683   // Organize these from the common form.
00684   panels_common_save_context('context', $panel_mini->contexts, $form_values);
00685   panels_common_save_context('requiredcontext', $panel_mini->requiredcontexts, $form_values);
00686   panels_common_save_context('relationship', $panel_mini->relationships, $form_values);
00687 
00688   drupal_set_message(t('Your changes have been saved.'));
00689   panels_mini_save($panel_mini);
00690   panels_common_cache_clear('panel_object:panel_mini', $panel_mini->name);
00691   if ($form_values['submit'] == t('Save and proceed')) {
00692     return "admin/panels/panel-mini/$panel_mini->name/edit/content";
00693   }
00694 }
00695 
00696 /**
00697  * Enable a default mini panel.
00698  */
00699 function panels_mini_enable_page($name = NULL) {
00700   $defaults = panels_mini_default_panels();
00701   if (isset($defaults[$name])) {
00702     $status = variable_get('panel_mini_defaults', array());
00703     $status[$name] = FALSE;
00704     variable_set('panel_mini_defaults', $status);
00705     drupal_set_message(t('Panel mini enabled'));
00706   }
00707   drupal_goto();
00708 }
00709 
00710 /**
00711  * Disable a default mini panel.
00712  */
00713 function panels_mini_disable_page($name = NULL) {
00714   $defaults = panels_mini_default_panels();
00715   if (isset($defaults[$name])) {
00716     $status = variable_get('panel_mini_defaults', array());
00717     $status[$name] = TRUE;
00718     variable_set('panel_mini_defaults', $status);
00719     drupal_set_message(t('Panel mini disabled'));
00720   }
00721   drupal_goto();
00722 }
00723 
00724 /**
00725  * Pass through to the panels content editor.
00726  */
00727 function panels_mini_edit_content($panel_mini) {
00728   if (!is_object($panel_mini)) {
00729     $panel_mini = panels_mini_load($panel_mini);
00730   }
00731   panels_load_include('plugins');
00732   // Collect a list of contexts required by the arguments on this page.
00733   $panel_mini->display->context = $contexts = panels_context_load_contexts($panel_mini);
00734 
00735   panels_load_include('common');
00736   $content_types = panels_common_get_allowed_types('panels_mini', $contexts);
00737 
00738   $output = panels_edit($panel_mini->display, NULL, $content_types);
00739   if (is_object($output)) {
00740     $panel_mini->display = $output;
00741     $panel_mini->did = $output->did;
00742     panels_mini_save($panel_mini);
00743     drupal_goto("admin/panels/panel-mini/$panel_mini->name/edit/content");
00744   }
00745   // Print this with theme('page') so that blocks are disabled while editing a display.
00746   // This is important because negative margins in common block layouts (i.e, Garland)
00747   // messes up the drag & drop.
00748   drupal_set_title(check_plain($panel_mini->title));
00749   print theme('page', $output, FALSE);
00750 }
00751 
00752 /**
00753  * Pass through to the panels layout editor.
00754  */
00755 function panels_mini_edit_layout($panel_mini) {
00756   if (!is_object($panel_mini)) {
00757     $panel_mini = panels_mini_load($panel_mini);
00758   }
00759 
00760   $output = panels_edit_layout($panel_mini->display, t('Save'));
00761   if (is_object($output)) {
00762     $panel_mini->display = $output;
00763     $panel_mini->did = $output->did;
00764     panels_mini_save($panel_mini);
00765     drupal_goto("admin/panels/panel-mini/$panel_mini->name/edit/layout");
00766   }
00767 
00768   drupal_set_title(check_plain($panel_mini->title));
00769   return $output;
00770 }
00771 
00772 /**
00773  * Pass through to the panels layout settings editor.
00774  */
00775 function panels_mini_edit_layout_settings($panel_mini, $next = NULL) {
00776   if (!is_object($panel_mini)) {
00777     $panel_mini = panels_mini_load($panel_mini);
00778   }
00779   if (empty($next)) {
00780     $button = t('Save');
00781     $dest = "admin/panels/panel-mini/$panel_mini->name/edit/settings";
00782   }
00783   else {
00784     $button = t('Save and proceed');
00785     $dest = "admin/panels/panel-mini/$panel_mini->name/edit/context/next";
00786   }
00787 
00788   $output = panels_edit_layout_settings($panel_mini->display, $button, NULL, $panel_mini->title);
00789   if (is_object($output)) {
00790     $panel_mini->display = $output;
00791     $panel_mini->did = $output->did;
00792     panels_mini_save($panel_mini);
00793     drupal_goto($dest);
00794   }
00795 
00796   drupal_set_title(check_plain($panel_mini->title));
00797   return $output;
00798 }
00799 
00800 // ---------------------------------------------------------------------------
00801 // Allow the rest of the system access to mini panels
00802 
00803 /**
00804  * Implementation of hook_block().
00805  *
00806  * Expose qualifying mini panels to Drupal's block system.
00807  */
00808 function panels_mini_block($op = 'list', $delta = 0, $edit = array()) {
00809   if ($op == 'list') {
00810     $blocks = array();
00811 
00812     $minis = panels_mini_load_all();
00813     foreach ($minis as $panel_mini) {
00814       if (empty($panel_mini->disabled) && empty($panel_mini->requiredcontext)) {
00815         $title = $panel_mini->hide_title ? t('Mini panel: %title (Title will be hidden)', array('%title' => $panel_mini->title)) : t('Mini panel: %title', array('%title' => $panel_mini->title));
00816         $blocks[$panel_mini->pid] = array(
00817           'info' => $title,
00818         );
00819       }
00820     }
00821 
00822     return $blocks;
00823   }
00824   elseif ($op == 'view') {
00825     $panel_mini = panels_mini_load($delta);
00826     panels_load_include('plugins');
00827     $panel_mini->context = $panel_mini->display->context = panels_context_load_contexts($panel_mini);
00828     $panel_mini->display->css_id = panels_mini_get_id($panel_mini->name);
00829 
00830     $block = array(
00831       'subject' => $panel_mini->hide_title ? '' : check_plain($panel_mini->title),
00832       'content' => panels_render_display($panel_mini->display),
00833     );
00834     return $block;
00835   }
00836 }
00837 
00838 /**
00839  * Expose all mini panels to our own system.
00840  */
00841 function panels_mini_panels_content_types() {
00842   $items['panels_mini'] = array(
00843     'title' => t('Mini panels'),
00844     'content_types' => 'panels_mini_content_types',
00845     'render callback' => 'panels_mini_content',
00846     'add callback' => 'panels_mini_add_mini_panel',
00847     'edit callback' => 'panels_mini_edit_mini_panel',
00848     'title callback' => 'panels_mini_title_mini_panel',
00849   );
00850   return $items;
00851 }
00852 
00853 /**
00854  * Return each available mini panel available as a subtype.
00855  */
00856 function panels_mini_content_types() {
00857   $types = array();
00858   foreach (panels_mini_load_all() as $mini) {
00859     if (!empty($mini->disabled)) {
00860       continue;
00861     }
00862 
00863     $types[$mini->name] = array(
00864       'title' => filter_xss_admin($mini->title),
00865       // For now mini panels will just use the contrib block icon.
00866       'icon' => 'icon_contrib_block.png',
00867       'path' => panels_get_path("content_types/block"),
00868       'description' => filter_xss_admin($mini->title),
00869       'category' => array(!empty($mini->category) ? filter_xss_admin($mini->category) : t('Mini panel'), -8),
00870     );
00871     if (!empty($mini->requiredcontexts)) {
00872       $types[$mini->name]['required context'] = array();
00873       foreach ($mini->requiredcontexts as $context) {
00874         $info = panels_get_context($context['name']);
00875         // TODO: allow an optional setting
00876         $types[$mini->name]['required context'][] = new panels_required_context($context['identifier'], $info['context name']);
00877       }
00878     }
00879   }
00880   return $types;
00881 }
00882 
00883 /**
00884  * Statically store all used IDs to ensure all mini panels get a unique id.
00885  */
00886 function panels_mini_get_id($name) {
00887   static $id_cache = array();
00888 
00889   $id = 'mini-panel-' . $name;
00890   if (!empty($id_cache[$name])) {
00891     $id .= "-" . $id_cache[$name]++;
00892   }
00893   else {
00894     $id_cache[$name] = 1;
00895   }
00896 
00897   return $id;
00898 }
00899 
00900 /**
00901  * Render a mini panel called from a panels display.
00902  */
00903 function panels_mini_content($conf, $panel_args, &$contexts) {
00904   $mini = panels_mini_load($conf['name']);
00905   if (!$mini) {
00906     return FALSE;
00907   }
00908 
00909   panels_load_include('plugins');
00910 
00911   // Load up any contexts we might be using.
00912   $context = panels_context_match_required_contexts($mini->requiredcontexts, $contexts);
00913   $mini->context = $mini->display->context = panels_context_load_contexts($mini, FALSE, $context);
00914 
00915   if (empty($mini) || !empty($mini->disabled)) {
00916     return;
00917   }
00918 
00919   $mini->display->args      = $panel_args;
00920   $mini->display->css_id    = panels_mini_get_id($conf['name']);
00921   $mini->display->owner     = $mini;
00922   // unique ID of this mini.
00923   $mini->display->owner->id = $mini->name;
00924 
00925   $block          = new stdClass();
00926   $block->module    = 'panels_mini';
00927   $block->delta     = $conf['name'];
00928   $block->content   = panels_render_display($mini->display);
00929   if (!$mini->hide_title) {
00930     $block->subject = filter_xss_admin($mini->title);
00931   }
00932   return $block;
00933 }
00934 
00935 /**
00936  * Form to add a mini panel to a panel.
00937  */
00938 function panels_mini_add_mini_panel($id, $parents, $conf = array()) {
00939   $conf['name'] = $id;
00940   return panels_mini_edit_mini_panel($id, $parents, $conf);
00941 }
00942 
00943 /**
00944  * Returns an edit form for the mini panel.
00945  *
00946  * There isn't much here as most of this is set up at mini panel creation time.
00947  */
00948 function panels_mini_edit_mini_panel($id, $parents, $conf) {
00949   $form['name'] = array(
00950     '#type' => 'value',
00951     '#value' => $conf['name'],
00952   );
00953 
00954   return $form;
00955 }
00956 
00957 function panels_mini_title_mini_panel($conf) {
00958   $mini = panels_mini_load($conf['name']);
00959   if (!$mini) {
00960     return t('Deleted/missing mini panel @name', array('@name' => $conf['name']));
00961   }
00962 
00963   $title = filter_xss_admin($mini->title);
00964   if (empty($title)) {
00965     $title = t('Untitled mini panel');
00966   }
00967   return $title;
00968 }
00969 
00970 // ---------------------------------------------------------------------------
00971 // Database functions.
00972 
00973 /**
00974  * A list of the fields used in the panel_mini table.
00975  */
00976 function panels_mini_fields() {
00977   return array(
00978     'name' => "'%s'",
00979     'category' => "'%s'",
00980     'title' => "'%s'",
00981     'contexts' => "'%s'",
00982     'requiredcontexts' => "'%s'",
00983     'relationships' => "'%s'",
00984   );
00985 }
00986 
00987 
00988 /**
00989  * Sanitize a mini panel, to guarantee certain data is as we believe it will be.
00990  */
00991 function panels_mini_sanitize($panel_mini) {
00992   foreach (array('contexts', 'relationships', 'requiredcontexts') as $id) {
00993     if (!is_array($panel_mini->$id)) {
00994       $panel_mini->$id = array();
00995     }
00996   }
00997 
00998   return $panel_mini;
00999 }
01000 
01001 /**
01002  * Fetch all mini panels in the system.
01003  *
01004  * This function does not cache.
01005  */
01006 function panels_mini_load_all($page_size = 0) {
01007   static $results = array();
01008 
01009   if (array_key_exists($page_size, $results)) {
01010     return $results[$page_size];
01011   }
01012 
01013   $panels = $dids = array();
01014   $query = "SELECT * FROM {panels_mini}";
01015   if ($page_size) {
01016     $result = pager_query($query, $page_size);
01017   }
01018   else {
01019     $result = db_query($query);
01020   }
01021 
01022   while ($panel_mini = db_fetch_object($result)) {
01023     $panel_mini->contexts = (!empty($panel_mini->contexts)) ? unserialize($panel_mini->contexts) : array();
01024     $panel_mini->requiredcontexts = (!empty($panel_mini->requiredcontexts)) ? unserialize($panel_mini->requiredcontexts) : array();
01025     $panel_mini->relationships = (!empty($panel_mini->relationships)) ? unserialize($panel_mini->relationships) : array();
01026     $panel_mini->category = (!empty($panel_mini->category)) ? $panel_mini->category : 'Mini panels';
01027     $panel_mini->hide_title = ((bool) db_result(db_query('SELECT hide_title FROM {panels_display} WHERE did = %d', $panel_mini->did)));
01028 
01029     $panel_mini->type = t('Local');
01030     $panels[$panel_mini->name] = panels_mini_sanitize($panel_mini);
01031   }
01032 
01033   $status = variable_get('panel_mini_defaults', array());
01034   foreach (panels_mini_default_panels() as $panel_mini) {
01035     // Determine if default panel is enabled or disabled.
01036     if (isset($status[$panel_mini->name])) {
01037       $panel_mini->disabled = $status[$panel_mini->name];
01038     }
01039 
01040     if (!empty($panels[$panel_mini->name])) {
01041       $panels[$panel_mini->name]->type = t('Overridden');
01042     }
01043     else {
01044       $panel_mini->type = t('Default');
01045       $panels[$panel_mini->name] = $panel_mini;
01046     }
01047   }
01048   $results[$page_size] = $panels;
01049 
01050   return $results[$page_size];
01051 }
01052 
01053 /**
01054  * Load a mini panel.
01055  */
01056 function panels_mini_load($pid) {
01057   static $cache = array();
01058 
01059   if (array_key_exists($pid, $cache)) {
01060     return $cache[$pid];
01061   }
01062 
01063   if (!is_numeric($pid)) {
01064     $where = "name = '%s'";
01065   }
01066   else {
01067     $where = 'pid = %d';
01068   }
01069   $panel_mini = db_fetch_object(db_query("SELECT m.*, d.hide_title FROM {panels_mini} AS m INNER JOIN {panels_display} AS d ON m.did = d.did WHERE $where", $pid));
01070   if (!$panel_mini) {
01071     $defaults = panels_mini_default_panels();
01072     if (isset($defaults[$pid])) {
01073       $panel_mini = $defaults[$pid];
01074       $status = variable_get('panel_mini_defaults', array());
01075       // Determine if default panel is enabled or disabled.
01076       if (isset($status[$panel_mini->name])) {
01077         $panel_mini->disabled = $status[$panel_mini->name];
01078       }
01079       $cache[$pid] = $panel_mini;
01080       return $panel_mini;
01081     }
01082     return;
01083   }
01084 
01085   $panel_mini->contexts = (!empty($panel_mini->contexts)) ? unserialize($panel_mini->contexts) : array();
01086   $panel_mini->requiredcontexts = (!empty($panel_mini->requiredcontexts)) ? unserialize($panel_mini->requiredcontexts) : array();
01087   $panel_mini->relationships = (!empty($panel_mini->relationships)) ? unserialize($panel_mini->relationships) : array();
01088   // $panel_mini->hide_title = ((bool) db_result(db_query('SELECT hide_title FROM {panels_display} WHERE did = %d', $panel_mini->did)));
01089 
01090   $cache[$pid] = panels_mini_sanitize($panel_mini);
01091   $cache[$pid]->display = panels_load_display($cache[$pid]->did);
01092 
01093   return $cache[$pid];
01094 }
01095 
01096 /**
01097  * Save a mini panel.
01098  */
01099 function panels_mini_save(&$panel_mini) {
01100   $fields = $types = $values = $pairs = array();
01101   // Save the display if one was given to us.
01102   if (!empty($panel_mini->display)) {
01103     $display = panels_save_display($panel_mini->display);
01104   }
01105 
01106   // Ensure empty values get translated correctly.
01107   // Also make sure we don't mess up the original.
01108   $mini_clone = drupal_clone(panels_mini_sanitize($panel_mini));
01109 
01110   // If pid is set to our "magic value", this is an insert, otherwise an update.
01111   $insert = $mini_clone->pid && $mini_clone->pid == 'new';
01112 
01113   // Build arrays of fields and types (resp. pairs of both) and of values.
01114   foreach (panels_mini_fields() as $field => $type) {
01115     // Skip empty values.
01116     if (isset($mini_clone->$field)) {
01117       if ($insert) {
01118         $fields[] = $field;
01119         $types[] = $type;
01120       }
01121       else {
01122         $pairs[] = "$field = $type";
01123       }
01124       // Build the $values array, serializing some fields.
01125       $serialize = in_array($field, array('contexts', 'requiredcontexts', 'relationships'));
01126       $values[] = $serialize ? serialize($mini_clone->$field) : $mini_clone->$field;
01127     }
01128   }
01129 
01130   if ($insert) {
01131     // Determine the new primary key.
01132     $mini_clone->pid = db_next_id('{panels_mini}_pid');
01133     // Build the query adding the new primary key and the did.
01134     $sql = 'INSERT INTO {panels_mini} (' . implode(', ', $fields) . ', did, pid) VALUES (' . implode(', ', $types) . ', %d, %d)';
01135     $values[] = $display->did;
01136   }
01137   else {
01138     // Build the query filtering by the primary key.
01139     $sql = 'UPDATE {panels_mini} SET ' . implode(', ', $pairs) . ' WHERE pid = %d';
01140   }
01141   $values[] = $mini_clone->pid;
01142 
01143   db_query($sql, $values);
01144   return $mini_clone->pid;
01145 }
01146 
01147 /**
01148  * Delete a mini panel.
01149  */
01150 function panels_mini_delete($panel_mini) {
01151   db_query("DELETE FROM {panels_mini} WHERE pid = %d", $panel_mini->pid);
01152   db_query("DELETE FROM {blocks} WHERE module = 'panels_mini' AND delta = %d", $panel_mini->pid);
01153   return panels_delete_display($panel_mini->did);
01154 }
01155 
01156 /**
01157  * Export a mini panel into PHP code for use in import.
01158  *
01159  * The code returned from can be used directly in panels_mini_save().
01160  */
01161 function panels_mini_export($panel_mini, $prefix = '') {
01162   $output = '';
01163   $fields = panels_mini_fields();
01164   $output .= $prefix . '$mini = new stdClass()' . ";\n";
01165   $output .= $prefix . '$mini->pid = \'new\'' . ";\n";
01166   foreach ($fields as $field => $sub) {
01167     $output .= $prefix . '  $mini->' . $field . ' = ' . panels_var_export($panel_mini->$field, '  ') . ";\n";
01168   }
01169   // Export the primary display
01170   $display = !empty($panel_mini->display) ? $panel_mini->display : panels_load_display($panel_mini->did);
01171   $output .= panels_export_display($display, $prefix);
01172   $output .= $prefix . '$mini->display = $display' . ";\n";
01173 
01174   return $output;
01175 }
01176 
01177 /**
01178  * Get all 'default' mini panels.
01179  *
01180  * @ingroup HookInvokers
01181  */
01182 function panels_mini_default_panels() {
01183   $panels = module_invoke_all('default_panel_minis');
01184   if (!is_array($panels)) {
01185     $panels = array();
01186   }
01187 
01188   return $panels;
01189 }
01190 
01191 /**
01192  * Remove the block version of mini panels from being available content types.
01193  */
01194 function panels_mini_panels_block_info($module, $delta, &$info) {
01195   $info = NULL;
01196 }
01197 
01198 /**
01199  * Implementation of hook_panels_exportables().
01200  */
01201 function panels_mini_panels_exportables($op = 'list', $panels = NULL, $name = 'foo') {
01202   static $all_panels = NULL;
01203   if ($op == 'list') {
01204     if (empty($all_panels)) {
01205       $all_panels = panels_mini_load_all();
01206     }
01207 
01208     foreach ($all_panels as $name => $panel) {
01209       $return[$name] = check_plain($name) . ' (' . check_plain($panel->title) . ')';
01210     }
01211     return $return;
01212   }
01213 
01214   if ($op == 'export') {
01215     $code = "/**\n";
01216     $code .= " * Implementation of hook_default_panel_minis()\n";
01217     $code .= " */\n";
01218     $code .= "function " . $name . "_default_panel_minis() {\n";
01219     foreach ($panels as $panel => $truth) {
01220       $code .= panels_mini_export($all_panels[$panel], '  ');
01221       $code .= '  $minis[\'' . check_plain($panel) . '\'] = $mini;' . "\n\n\n";
01222     }
01223     $code .= "  return \$minis;\n";
01224     $code .= "}\n";
01225     return $code;
01226   }
01227 }

Generated on Thu Jul 29 05:00:15 2010 for Panels 2 by  doxygen 1.5.6