summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoySegall2013-02-10 13:29:33 (GMT)
committer Roy Segall2013-02-10 13:29:33 (GMT)
commit6b120ae68ac781027e043df4ab4c0fae6f6e4ef5 (patch)
tree758db5e48045330c3fe8f34f88c739bc6d888dac
parent9d20720e00b2b59aaac1b0919933545573f51ef3 (diff)
Issue #1906672 by RoySegall, Amitaibu: Fixed When un-checking content type from a vocab contain with terms the terms still referenced to the node.7.x-1.0
-rw-r--r--includes/og_vocab.og_vocab.inc29
-rw-r--r--og_vocab.module114
-rw-r--r--og_vocab.test113
3 files changed, 256 insertions, 0 deletions
diff --git a/includes/og_vocab.og_vocab.inc b/includes/og_vocab.og_vocab.inc
index 54f06d4..868a222 100644
--- a/includes/og_vocab.og_vocab.inc
+++ b/includes/og_vocab.og_vocab.inc
@@ -205,6 +205,35 @@ class OgVocab extends Entity {
parent::save();
}
+
+ /**
+ * Overrides Entity::delete().
+ */
+ public function delete() {
+ $use_queue = variable_get('og_use_queue', FALSE) && variable_get('og_vocab_use_queue', FALSE) && module_exists('advancedqueue');
+
+ if ($use_queue) {
+ // Add item to the queue.
+ $group = og_vocab_relation_get($this->vid);
+ $task = array(
+ 'vid' => $this->vid,
+ 'entity_type' => $this->entity_type,
+ 'bundle' => $this->bundle,
+ 'field_name' => $this->field_name,
+ 'group_type' => $group->group_type,
+ 'gid' => $group->gid,
+ // The last processed OG-membership ID.
+ 'last_id' => 0,
+ );
+
+ $queue = DrupalQueue::get('og_vocab');
+ $queue->createItem($task);
+ }
+
+ // After defining the item data, if we used queue, delete the entity.
+ parent::delete();
+
+ }
}
/**
diff --git a/og_vocab.module b/og_vocab.module
index 2f21845..56679b6 100644
--- a/og_vocab.module
+++ b/og_vocab.module
@@ -1139,6 +1139,27 @@ function og_vocab_form_alter(&$form, $form_state, $form_id) {
}
/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function og_vocab_form_og_ui_admin_settings_alter(&$form, $form_state) {
+ $form['og_vocab_use_queue'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Delete OG vocab terms reference with the queue'),
+ '#description' => t('Use the advance queue for deleting the OG vocabulary term reference when OG vocabulary is deleted.'),
+ '#default_value' => variable_get('og_vocab_use_queue', FALSE),
+ '#disabled' => !module_exists('advancedqueue'),
+ '#states' => array(
+ 'visible' => array(
+ ':input[name="og_use_queue"]' => array('checked' => TRUE),
+ ),
+ ),
+ '#attributes' => array(
+ 'class' => array('entityreference-settings'),
+ ),
+ );
+}
+
+/**
* After deleting the group vocabulary, redirect to the taxonomy group admin
* page.
*/
@@ -1421,3 +1442,96 @@ function og_vocab_modules_enabled($modules) {
Migration::registerMigration('OgVocabMigrate', 'OgVocabMigrate' . ucfirst($bundle), array('bundle' => $bundle));
}
}
+
+/**
+ * Implements hook_advanced_queue_info().
+ */
+function og_vocab_advanced_queue_info() {
+ $items['og_vocab'] = array(
+ 'worker callback' => 'og_vocab_advancedqueue_worker',
+ // Message-subscribe will deal itself with deleting claimed items.
+ 'delete when completed' => FALSE,
+ );
+ return $items;
+}
+
+/**
+ * Advanced queue worker; Process a queue item.
+ *
+ * The item holds the Message ID, and user ID of the last user the email
+ * was sent to.
+ */
+function og_vocab_advancedqueue_worker($item, $end_time = FALSE) {
+ $queue = DrupalQueue::get('og_vocab');
+ $data = $item->data;
+ extract($data);
+
+ // Get range of the group content.
+ // We don't use entityFieldQuery() as we want to join to the entity base
+ // table, to make sure we process only entities from the correct bundle.
+ $entity_info = entity_get_info($entity_type);
+
+ $query = db_select('og_membership', 'ogm');
+ $query->fields('ogm', array('id', 'entity_type', 'etid'));
+ $query
+ ->condition('ogm.group_type', $group_type)
+ ->condition('ogm.gid', $gid)
+ ->condition('ogm.entity_type', $entity_type)
+ // The last processed OG-membership ID.
+ ->condition('ogm.id', $last_id, '>')
+ ->orderBy('ogm.id');
+
+ $base_table = $entity_info['base table'];
+ $bundle_key = $entity_info['entity keys']['bundle'];
+ $id_key = $entity_info['entity keys']['id'];
+
+ $alias = $query->innerJoin($base_table, NULL, "ogm.etid = $base_table.$id_key");
+ $result = $query
+ ->condition("$alias.$bundle_key", $bundle)
+ ->range(0, 100)
+ ->execute()
+ ->fetchAllAssoc('id');
+
+ if (empty($result)) {
+ // No more group-content for this entity, so we can delete the task item.
+ return $queue->deleteItem($item);
+ }
+
+ foreach ($result as $row) {
+ $last_id = $row->id;
+ $wrapper = entity_metadata_wrapper($row->entity_type, $row->etid);
+ if (!$terms = $wrapper->{$field_name}->value()) {
+ // Field doesn't have any term, so we can skip.
+ continue;
+ }
+
+ // Array with the original and new term IDs.
+ $original_tids = array();
+ $new_tids = array();
+ foreach ($terms as $term) {
+ $original_tids[] = $term->tid;
+
+ if ($term->vid != $vid) {
+ $new_tids[] = $term->tid;
+ }
+ }
+ if ($original_tids != $new_tids) {
+ // Some terms were removed so re-save the entity.
+ $wrapper->{$field_name}->set($new_tids);
+ $wrapper->save();
+ }
+ }
+
+ // Update the item with the last OG-membership ID.
+ $item->data['last_id'] = $last_id;
+ db_update('advancedqueue')
+ ->fields(array(
+ 'data' => serialize($item->data),
+ ))
+ ->condition('item_id', $item->item_id)
+ ->execute();
+
+ // Release the item.
+ $queue->releaseItem($item);
+ return TRUE;
+}
diff --git a/og_vocab.test b/og_vocab.test
index 57041a0..bf3383a 100644
--- a/og_vocab.test
+++ b/og_vocab.test
@@ -478,3 +478,116 @@ class OgVocabApiTestCase extends DrupalWebTestCase {
}
}
+class OgVocabUnbindFromContentType extends DrupalWebTestCase {
+ private $user;
+ private $group;
+ private $first_group_content;
+ private $second_group_content;
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'OG vocabulary removing vocabulary from content type.',
+ 'description' => 'Check the removing of the vocabulary delete the OG vocabulary term reference from nodes.',
+ 'group' => 'Organic groups vocabulary',
+ 'dependencies' => array('advancedqueue'),
+ );
+ }
+
+ public function setup() {
+ parent::setUp('og_vocab', 'advancedqueue');
+
+ // Create group.
+ $group_type = $this->drupalCreateContentType();
+ og_create_field(OG_GROUP_FIELD, 'node', $group_type->type);
+
+ $settings = array();
+ $settings['type'] = $group_type->type;
+ $settings[OG_GROUP_FIELD][LANGUAGE_NONE][0]['value'] = 1;
+ $this->group = $this->drupalCreateNode($settings);
+
+ // Create two groups type.
+ $type = $this->drupalCreateContentType();
+ og_create_field(OG_AUDIENCE_FIELD, 'node', $type->type);
+ $this->first_group_content = $this->drupalCreateNode(array(
+ 'type' => $type->type,
+ ));
+
+ $wrapper = entity_metadata_wrapper('node', $this->first_group_content);
+ $wrapper->{OG_AUDIENCE_FIELD}->set(array($this->group));
+ $wrapper->save();
+
+ $type = $this->drupalCreateContentType();
+ og_create_field(OG_AUDIENCE_FIELD, 'node', $type->type);
+ $this->second_group_content = $this->drupalCreateNode(array(
+ 'type' => $type->type,
+ ));
+
+ $wrapper = entity_metadata_wrapper('node', $this->second_group_content);
+ $wrapper->{OG_AUDIENCE_FIELD}->set(array($this->group));
+ $wrapper->save();
+
+ variable_set('og_use_queue', TRUE);
+ variable_set('og_vocab_use_queue', TRUE);
+ }
+
+ /**
+ * When a vocabulary is related to a bundle and it's term are reference to the
+ * group content, un-bind it from the bundle the terms should not be
+ * reference any more to the node.
+ */
+ public function testUnbindContentType() {
+ $groups_contents = array($this->first_group_content, $this->second_group_content);
+
+ // Create a dummy vocabulary.
+ $vocabulary = new stdClass();
+ $vocabulary->name = "Vocabulary " . $this->group->nid;
+ $vocabulary->machine_name = "vocabulary_" . $this->group->nid;
+ taxonomy_vocabulary_save($vocabulary);
+
+ // Relate vocabulary to group.
+ og_vocab_relation_save($vocabulary->vid, 'node', $this->group->nid);
+
+ // Create the vocabulary.
+ foreach ($groups_contents as $groups_content) {
+ // Create OG vocabulary entity.
+ $og_vocab = og_vocab_create_og_vocab($vocabulary->vid, 'node', $groups_content->type);
+ $og_vocab->save();
+
+ // Create terms in the vocabulary.
+ $terms = array();
+ for ($i = 1; $i < 3; ++$i) {
+ $term = new stdClass();
+ $term->name = "Vocab $vocabulary->vid term $i";
+ $term->vid = $vocabulary->vid;
+ taxonomy_term_save($term);
+ $terms[] = $term->tid;
+ }
+
+ // Reference between the taxonomy terms and the nodes.
+ $wrapper = entity_metadata_wrapper('node', $groups_content);
+ $wrapper->{OG_VOCAB_FIELD}->set($terms);
+ $wrapper->save();
+ }
+
+ // Verify the terms are attached to the nodes.
+ foreach ($groups_contents as $groups_content) {
+ $node = node_load($groups_content->nid);
+ $this->assertTrue(!empty($node->{OG_VOCAB_FIELD}), format_string('Terms are attached to the node @title.', array('@title' => $groups_content->title)));
+ }
+
+ // Delete the last vocabulary.
+ $og_vocab->delete();
+
+ // Execute manually the queue worker.
+ $queue = DrupalQueue::get('og_vocab');
+ $item = $queue->claimItem();
+ og_vocab_advancedqueue_worker($item);
+
+ // Verify the terms are attached to the nodes.
+ $node = node_load($this->first_group_content->nid);
+ $this->assertTrue(!empty($node->{OG_VOCAB_FIELD}), format_string('Terms are attached to the node @title.', array('@title' => $this->first_group_content->title)));
+
+ $node = node_load($this->second_group_content->nid);
+ $this->assertTrue(empty($node->{OG_VOCAB_FIELD}), format_string('There are no terms attached to the node @title.', array('@title' => $this->second_group_content->title)));
+ }
+}