diff --git a/fieldable_panels_panes.install b/fieldable_panels_panes.install index b62bfcf..bebedb3 100644 --- a/fieldable_panels_panes.install +++ b/fieldable_panels_panes.install @@ -32,6 +32,7 @@ function fieldable_panels_panes_uninstall() { // Variables. variable_del('fieldable_panels_panes_skip_default_type'); variable_del('fpp_blocks_expose'); + variable_del('fpp_revision_locking'); // Delete any variables that begin with 'fpp_expose_'. $results = db_query('SELECT name FROM {variable} WHERE name LIKE :var', array(':var' => 'fpp_expose_%'))->fetchCol(); diff --git a/fieldable_panels_panes.module b/fieldable_panels_panes.module index f8aea2a..5f381d7 100644 --- a/fieldable_panels_panes.module +++ b/fieldable_panels_panes.module @@ -1002,8 +1002,12 @@ function fieldable_panels_panes_load_from_subtype($subtype_name) { * Properly load the entity via $subtype_name. * * @param string $subtype_name - * A string combining an indicator of the type of ID, e.g. 'fpid', 'vid' or - * 'vuuid', and an integer ID, separated by a colon; e.g. "fpid:123". + * A string combining an indicator of the type of ID, e.g. 'fpid', 'vid', + * 'uuid', 'vuuid' or 'current, and an integer ID, separated by a colon; e.g. + * "fpid:123". If the type is 'current' the newest revision will be loaded, + * 'fpid' and 'uuid' will load the revision considered best, 'vid' and 'vuuid' + * will load a specific revision. Both 'uuid' and 'vuuid' require the UUID + * module to be present. * * @return object * The requested FPP object. @@ -1022,12 +1026,25 @@ function fieldable_panels_panes_load_from_subtype_force($subtype_name) { } } + // UUID integration for revisions. + elseif ($type == 'vuuid' && module_exists('uuid')) { + $vids = entity_get_id_by_uuid('fieldable_panels_pane', array($id), TRUE); + if ($vids && $content = entity_load('fieldable_panels_pane', FALSE, array('vid' => reset($vids)))) { + $object = reset($content); + } + } // If the type is 'vid' then a specific FPP revision is being requested. elseif ($type == 'vid') { $fpid = db_query('SELECT fpid FROM {fieldable_panels_panes_revision} WHERE vid = :vid', array(':vid' => $id))->fetchField(); $object = fieldable_panels_panes_load($fpid, $id); } + // Load up the current revision. + elseif ($type == 'current') { + $vid = db_query('SELECT MAX(vid) FROM {fieldable_panels_panes_revision} WHERE fpid = :fpid', array(':fpid' => $id))->fetchField(); + $object = fieldable_panels_panes_load($id, $vid); + } + // The remaining scenario is that it's a regular FPP id, i.e. an "fpid", so // just load the object. else { @@ -1526,3 +1543,32 @@ function fieldable_panels_panes_file_download_access($field, $entity_type, $enti return ctools_access($entity->view_access, fieldable_panels_panes_get_base_context($entity)); } } + +/** + * Determine if an FPP's revision should be locked. + * + * @param object $entity + * The FPP object being examined. + * + * @return bool + */ +function fieldable_panels_panes_revision_is_lockable($entity) { + $lock = variable_get('fpp_revision_locking', 'legacy'); + + // Only non-reusable FPPs will be lockable. + if ($lock == 'lock') { + $revision_context_aware = empty($entity->reusable); + } + + // Lock all revisions, even reusable FPPs. + elseif ($lock == 'lock_all') { + $revision_context_aware = TRUE; + } + + // Legacy mode, no revisions handling. + else { + $revision_context_aware = FALSE; + } + + return $revision_context_aware; +} diff --git a/includes/PanelsPaneController.class.php b/includes/PanelsPaneController.class.php index 902dea8..b62a934 100644 --- a/includes/PanelsPaneController.class.php +++ b/includes/PanelsPaneController.class.php @@ -200,7 +200,12 @@ function saveRevision($entity, $uid = NULL) { $entity->uid = $uid; // Update the existing revision if specified. if (!empty($entity->vid)) { - drupal_write_record('fieldable_panels_panes_revision', $entity, 'vid'); + if (module_exists('uuid')) { + drupal_write_record('fieldable_panels_panes_revision', $entity, 'vuuid'); + } + else { + drupal_write_record('fieldable_panels_panes_revision', $entity, 'vid'); + } } else { // Otherwise insert a new revision. This will automatically update $entity diff --git a/includes/admin.inc b/includes/admin.inc index 9625a86..5867cde 100644 --- a/includes/admin.inc +++ b/includes/admin.inc @@ -9,10 +9,20 @@ * Page callback for settings page. */ function fieldable_panels_panes_settings() { - // Get array of all FPP bundles. - $bundles = fieldable_panels_panes_get_bundle_labels(); - $form = array(); + + $form['fpp_revision_locking'] = array( + '#type' => 'radios', + '#title' => t('Should pane changes create new revisions?'), + '#description' => t(''), + '#options' => array( + 'legacy' => t('Ignore, every change saves directly.'), + 'lock' => t('Lock non-resuable FPPs.'), + 'lock_all' => t('Lock non-resuable and reusable FPPs.'), + ), + '#default_value' => variable_get('fpp_revision_locking', 'legacy'), + ); + $form['fpp_blocks_expose'] = array( '#type' => 'checkbox', '#title' => t('Make fieldable panels panes available as blocks'), @@ -33,6 +43,7 @@ function fieldable_panels_panes_settings() { ); // Render checkbox for each FPP bundle if any FPP bundles exist. + $bundles = fieldable_panels_panes_get_bundle_labels(); if (!empty($bundles)) { foreach ($bundles as $bundle => $info) { $form['bundles']['fpp_expose_' . $bundle] = array( diff --git a/plugins/content_types/fieldable_panels_pane.inc b/plugins/content_types/fieldable_panels_pane.inc index aa06879..0a12b36 100644 --- a/plugins/content_types/fieldable_panels_pane.inc +++ b/plugins/content_types/fieldable_panels_pane.inc @@ -255,18 +255,45 @@ function fieldable_panels_panes_fieldable_panels_pane_content_type_edit_form_sub fieldable_panels_panes_entity_edit_form_submit($form, $form_state); - // Sub type is not explicitly set, define it here. - if (module_exists('uuid') && isset($entity->uuid)) { - $entity_id = 'uuid:' . $entity->uuid; + // Determine how to handle revision locking. + $revision_context_aware = fieldable_panels_panes_revision_is_lockable($entity); + + // If this is a new entity entity, or revision locking is enabled, look for a + // specific ID to use. + if (!empty($entity->is_new) || $revision_context_aware) { + // If UUID is available, use it. + if (module_exists('uuid') && isset($entity->uuid)) { + if ($revision_context_aware) { + $subtype = 'vuuid:' . $entity->vuuid; + } + else { + $subtype = 'uuid:' . $entity->uuid; + } + } + + // Otherwise use the native ID values. + else { + if ($revision_context_aware) { + $subtype = 'vid:' . $entity->vid; + } + else { + $subtype = 'fpid:' . $entity->fpid; + } + } } + + // The 'current' key will tell FPP to load up the current revision. This + // bypasses the entity cache on the FPP entity class and loads the revision + // that was just saved instead of the previous revision. This is only really + // relevant in Panels IPE administration or similar circumstances. else { - $entity_id = 'fpid:' . $entity->fpid; + $subtype = 'current:' . $entity->fpid; } // @todo: This won't work if $form_state does not contain 'pane' which could // theoretically happen in a non-Panels use case. Not that anybody uses this // outside of Panels. - $form_state['pane']->subtype = $entity_id; + $form_state['pane']->subtype = $subtype; } /** @@ -319,11 +346,27 @@ function _fieldable_panels_panes_custom_content_type($entity) { 'icon' => 'icon_block_custom.png', ); + // Determine how to handle revision locking. + $revision_context_aware = fieldable_panels_panes_revision_is_lockable($entity); + + // If UUID is available, use it. if (module_exists('uuid') && isset($entity->uuid)) { - $info['name'] = 'uuid:' . $entity->uuid; + if ($revision_context_aware) { + $info['name'] = 'vuuid:' . $entity->vuuid; + } + else { + $info['name'] = 'uuid:' . $entity->uuid; + } } + + // Otherwise use the native ID values. else { - $info['name'] = 'fpid:' . $entity->fpid; + if ($revision_context_aware) { + $info['name'] = 'vid:' . $entity->vid; + } + else { + $info['name'] = 'fpid:' . $entity->fpid; + } } $info['entity_id'] = $info['name'];