diff --git a/metatag.install b/metatag.install index ae3f390..29f8059 100644 --- a/metatag.install +++ b/metatag.install @@ -922,3 +922,166 @@ function metatag_update_7015() { drupal_set_message(t('Added the {metatag}.revision_id field.')); } + +/** + * This was removed. + */ +function metatag_update_7016() { + // Do nothing. +} + +/** + * Update the revision ID for each record. This may take some time. + */ +function metatag_update_7017(&$sandbox) { + // Process records in small groups. + // When a group is processed, the batch update engine determines whether it + // should continue processing in the same request or provide progress + // feedback to the user and wait for the next request. + $limit = 10; + + // Use the sandbox at your convenience to store the information needed + // to track progression between successive calls to the function. + if (!isset($sandbox['progress'])) { + // The count of records visited so far. + $sandbox['progress'] = 0; + + // Get a list of all records affected. + $sandbox['records'] = db_query("SELECT entity_type, entity_id, language + FROM {metatag} + WHERE revision_id = 0") + ->fetchAll(); + + // If there's no data, don't bother with the extra work. + if (empty($sandbox['records'])) { + watchdog('metatag', 'Update 7017: No {metatag} records needed to have the revision_id value fixed.', array(), WATCHDOG_INFO); + if (drupal_is_cli()) { + drupal_set_message(t('Update 7017: No {metatag} records needed to have the revision_id value fixed.')); + } + return t('No {metatag} records needed to have the revision_id value fixed.'); + } + + // Total records that must be visited. + $sandbox['max'] = count($sandbox['records']); + + // A place to store messages during the run. + $sandbox['messages'] = array(); + + // An initial record of the number of records to be updated. + watchdog('metatag', 'Update 7017: !count records to update.', array('!count' => $sandbox['max']), WATCHDOG_INFO); + if (drupal_is_cli()) { + drupal_set_message(t('Update 7017: !count records to update.', array('!count' => $sandbox['max']))); + } + + // Last record processed. + $sandbox['current_record'] = -1; + + // Because a lot of other processing happens on the first iteration, just do + // one. + $limit = 1; + } + + // The for loop will run as normal when ran via update.php, but when ran via + // Drush it'll just run 'til it's finished. + $increment = 1; + if (drupal_is_cli()) { + $increment = 0; + } + + // Set default values. + for ($ctr = 0; $ctr < $limit; $ctr += $increment) { + $sandbox['current_record']++; + if (empty($sandbox['records'][$sandbox['current_record']])) { + break; + } + + // Shortcuts for later. + $entity_type = $sandbox['records'][$sandbox['current_record']]->entity_type; + $entity_id = $sandbox['records'][$sandbox['current_record']]->entity_id; + // Make sure to load the correct language record. + $language = $sandbox['records'][$sandbox['current_record']]->language; + $conditions = array( + 'language' => $language, + ); + $records = entity_load($entity_type, array($entity_id), $conditions); + + // Fix this record. + if (!empty($records)) { + $entity = reset($records); + list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity); + db_update('metatag') + ->fields(array('revision_id' => $revision_id)) + ->condition('entity_type', $entity_type) + ->condition('entity_id', $entity_id) + ->condition('revision_id', 0) + ->condition('language', $language) + ->execute(); + + // Check for additional revision records. + // if ($entity_type != 'node') { + // $info = entity_get_info($entity_type); + // if (!empty($info['revision table'])) { + // $revisions = db_query("SELECT {$info['entity keys']['revision']} + // FROM {$info['revision table']} + // WHERE {$info['entity keys']['id']} = :entity_id + // AND {$info['entity keys']['revision']} <> :revision_id", + // array(':entity_id' => $entity_id, ':revision_id' => $revision_id)); + // foreach ($revisions as $rev) { + // } + // } + // } + + // Nodes can have multiple revisions. + if ($entity_type == 'node') { + $revs = node_revision_list($entity); + if (count($revs) > 1) { + $data = db_query("SELECT data + FROM {metatag} + WHERE entity_type = :entity_type + AND entity_id = :entity_id + AND language = :language", + array( + ':entity_type' => $entity_type, + ':entity_id' => $entity_id, + ':language' => $language, + ))->execute(); + foreach ($x as $vid -> $rev) { + if ($vid != $revision_id) { + $node = node_load($entity_id, $vid); + $record = new StdClass(); + $record->entity_type = 'node'; + $record->entity_id = $node->nid; + $record->revision_id = $node->vid; + $record->language = $node->language; + $record->data = $metatag->data; + drupal_write_record('metatag', $record); + } + } + } + } + } + + // Update our progress information. + $sandbox['progress']++; + } + + // Set the "finished" status, to tell batch engine whether this function + // needs to run again. If you set a float, this will indicate the progress of + // the batch so the progress bar will update. + $sandbox['#finished'] = ($sandbox['progress'] >= $sandbox['max']) ? TRUE : ($sandbox['progress'] / $sandbox['max']); + + if ($sandbox['#finished']) { + // Clear all caches so the fixed data will be reloaded. + cache_clear_all('*', 'cache_metatag', TRUE); + + // A final log of the number of records that were converted. + watchdog('metatag', 'Update 7017: !count records were updated in total.', array('!count' => $sandbox['progress']), WATCHDOG_INFO); + if (drupal_is_cli()) { + drupal_set_message(t('Update 7017: !count records were updated.', array('!count' => $sandbox['progress']))); + } + + // hook_update_N() may optionally return a string which will be displayed + // to the user. + return t('Fixed the revision_id values for @count {metatag} records.', array('!count' => $sandbox['progress'])); + } +} diff --git a/metatag.module b/metatag.module index 9402d30..f84c25f 100644 --- a/metatag.module +++ b/metatag.module @@ -368,17 +368,16 @@ function metatag_metatags_load_multiple($entity_type, array $entity_ids, array $ } // Get all translations of tag data for this entity. - $result = db_query("SELECT entity_id, data, language FROM {metatag} WHERE (entity_type = :type) AND (entity_id IN (:ids)) AND (revision_id IN (:vids))", array( + $result = db_query("SELECT entity_id, revision_id, language, data FROM {metatag} WHERE (entity_type = :type) AND (entity_id IN (:ids)) ORDER BY entity_id, revision_id", array( ':type' => $entity_type, ':ids' => $entity_ids, - ':vids' => $revision_ids, )); // Marshal it into an array keyed by entity ID. Each value is an array of // translations keyed by language code. $metatags = array(); while ($record = $result->fetchObject()) { - $metatags[$record->entity_id][$record->language] = unserialize($record->data); + $metatags[$record->entity_id][intval($record->revision_id)][$record->language] = unserialize($record->data); } return $metatags; @@ -547,23 +546,28 @@ function metatag_metatags_cache_clear($entity_type, $entity_id = NULL) { * Implements hook_entity_load(). */ function metatag_entity_load($entities, $entity_type) { - // get the revision_ids + // Get the revision_ids. $revision_ids = array(); - //since some entities do not have revisions, set the vid to the id + + // Since some entities do not have revisions, set the vid to the id. foreach ($entities as $key => $entity) { list($entity_id, $revision_id) = entity_extract_ids($entity_type, $entity); - if (!$revision_id) { - $revision_id = $entity_id; + if (!empty($revision_id)) { + $revision_ids[] = $revision_id; } - $revision_ids[] = $revision_id; } + // Wrap this in a try-catch block to work around occasions when the schema // hasn't been updated yet. try { if (metatag_entity_supports_metatags($entity_type)) { $metatags = metatag_metatags_load_multiple($entity_type, array_keys($entities), $revision_ids); - foreach ($entities as $entity_id => $entity) { - $entities[$entity_id]->metatags = isset($metatags[$entity_id]) ? $metatags[$entity_id] : array(); + + // Assign the metatag records for the correct revision ID. + foreach ($entities as $entity_id => $records) { + list($entity_id, $revision_id) = entity_extract_ids($entity_type, $entity); + $revision_id = intval($revision_id); + $entities[$entity_id]->metatags = isset($metatags[$entity_id][$revision_id]) ? $metatags[$entity_id][$revision_id] : array(); } } } @@ -611,6 +615,7 @@ function metatag_entity_update($entity, $entity_type) { } list($entity_id, $revision_id) = entity_extract_ids($entity_type, $entity); + $revision_id = intval($revision_id); if (isset($entity->metatags)) { // Determine the entity's language. @@ -627,6 +632,7 @@ function metatag_entity_update($entity, $entity_type) { db_delete('metatag') ->condition('entity_type', $entity_type) ->condition('entity_id', $entity_id) + ->condition('revision_id', $revision_id) ->condition('language', $old_language) ->execute(); } @@ -725,6 +731,7 @@ function metatag_entity_view($entity, $entity_type, $view_mode, $langcode, $forc 'entity_type' => $entity_type, 'bundle' => $bundle, 'entity_id' => $entity_id, + 'revision_id' => $revision_id, 'view_mode' => $view_mode, 'langcode' => $langcode, 'url' => $GLOBALS['base_url'] . base_path() . current_path(),