Use case to test:

1 -> Node with 2 languages
2 -> Both tranlations are published
3 -> Making changes for each tranlsation and put in ready for review state
4 -> Schedule publication and save both
5 -> When cron run only publish the latest saved revision of latest saved translation.

I've tried to remove the unset of the publish_on field, i think the issue there is that this field not have it's own table but this not change anything, i will try to fix by my hand but if some one can help or point me in the right way will be great.

I'm thinking also could be related to the way is keeped latest revision of the node in SchedulerManager.php row 536:

" $node = $node_storage->load($nid);
$revision_ids = $node_storage->revisionIds($node);
$vid = end($revision_ids);
"

Comments

bigbabert created an issue. See original summary.

bigbabert’s picture

bigbabert’s picture

bigbabert’s picture

Assigned: Unassigned » bigbabert
bigbabert’s picture

Below my custom module main functions that solve this issue:

function moderation_scheduler_publishScheduled(){

    $moderation_storage = \Drupal::entityTypeManager()->getStorage('content_moderation_state');
    $moderation_info = \Drupal::service('content_moderation.moderation_information');
    $node_storage = \Drupal::entityManager()->getStorage('node');
    $state = 'published';
    
    // Get a date string suitable for use with entity query.
    $date = new DrupalDateTime();
    $date->setTimezone(new \DateTimezone(DateTimeItemInterface::STORAGE_TIMEZONE));
    $date = $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
    
    $languages = array_keys(\Drupal::languageManager()->getLanguages());
    
    $query = \Drupal::entityQuery('node')
        ->exists('field_scheduled_time')
        ->condition('field_scheduled_time.value', $date, '<=')
        ->latestRevision()
        ->sort('field_scheduled_time')
        ->sort('nid');
      // Disable access checks for this query.
      // @see https://www.drupal.org/node/2700209
      $query->accessCheck(FALSE);
      $nids = $query->execute();
      
      $nodes = moderation_scheduler_loadNodes($nids);

      if($nodes) {
          
        $default_language = \Drupal::languageManager()->getDefaultLanguage()->getId();

        foreach ($nodes as $node) {
            
            
        $d_node_vid = $node_storage->getLatestTranslationAffectedRevisionId($node->id(), $default_language);
        
        $d_node = $node_storage->loadRevision($d_node_vid)->getTranslation($default_language);
        
        $old_state = $d_node->get('moderation_state')->value;
        
        $languages = $node->getTranslationLanguages();
        
        $d_node->set('langcode', $default_language);
          
        $d_node->set('field_scheduled_time', NULL);
        
        $d_node->set('moderation_state', $state);  

        $d_node->setPublished(TRUE);
          
        $d_node->status = "1";
        
        foreach ($languages as $language) {
            $rev_lang = $language->getId();
          if($rev_lang != $default_language) {
              $d_node->removeTranslation($rev_lang);
              $t_node = moderation_scheduler_get_revision_from_field($node->id(), $rev_lang);

              if($t_node) {
                  $t_node->set('field_scheduled_time', NULL);
                  $t_node->set('moderation_state', $state);   
                  $t_node->setPublished(TRUE);  
                  $t_node->status = "1"; 
                  try {
                      // If transition is not valid, throw exception.
                      $translation = $d_node->addTranslation($rev_lang, $t_node->toArray())->save();
                      $t_node->save();
                      
                      $t_title = $t_node->getTitle();

                      $tranlsated = TRUE;
                      $t_lang = $rev_lang;
                      }      
                      catch (\InvalidArgumentException $exception) {
                          try {
                              $t_node->removeTranslation($default_language);
                               // If transition is not valid, throw exception.
                               $translation = $t_node->addTranslation($default_language, $d_node->toArray())->save();

                               $tranlsated = TRUE;
                               $t_lang = $rev_lang;
                               $t_title = $t_node->getTitle();
                              }      
                              catch (\InvalidArgumentException $exception) {
                               $t_title = $t_node->getTitle();
                               $t_node->save();
                              }                            
                      }
              }
          }
        }   
          $d_title = $d_node->getTitle();

          $d_node->save();
          $result[] = [
                          "node id" =>    $node->id(),
                          "old state" => $old_state,
                          "new state" => $state,
                          "lang" => $default_language. " (".$d_title.")",
                          "translation" => isset($translated) ? "default" : isset($t_lang) ? $t_lang. " (".$t_title.")" : "none",
                      ];   
          }          
      }

    if(isset($result)) {
        //moderation_scheduler_clear_scheduled_time_field();
    }
    if(isset($result)) {
        return $result;
    } else {
        return ["no scheduled content"];
    }
}
function moderation_scheduler_get_revision_from_field($nid, $langcode) {
    // Get a date string suitable for use with entity query.
    $node_storage = \Drupal::entityManager()->getStorage('node');
    $date = new DrupalDateTime();
    $date->setTimezone(new \DateTimezone(DateTimeItemInterface::STORAGE_TIMEZONE));
    $date = $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
    $connection = \Drupal::database();
    $query = $connection->query("SELECT revision_id, langcode, field_scheduled_time_value, entity_id FROM {node_revision__field_scheduled_time} WHERE langcode = :langcode", [
  ':langcode' => $langcode,
            ]);

    $revisions = $query->fetchAll();
    if($revisions) {
        $revision = end($revisions);
            //get revision id from the field
            $revision_id = $revision->revision_id;
            $vid = $revision->entity_id;
            $schedule = $revision->field_scheduled_time_value;
            $lang = $revision->langcode;
            if($lang == $langcode && $schedule <= $date) {
                //Load node revision with proper langcode and translation
                $rev = $node_storage->loadRevision($revision_id)->getTranslation($langcode); 
                if($rev) {
                    $rev->set('langcode', $langcode);
                    return $rev;
                }
            }
    }
}
bigbabert’s picture

Status: Active » Needs review
bigbabert’s picture

Assigned: bigbabert » Unassigned
Status: Needs review » Needs work
Raman Starshykh’s picture

Issue tags: +epam-contrib-2019.03
jonathan1055’s picture

Title: Transleted node is not scheduled » Translated node is not scheduled
Issue summary: View changes

In between step 4 and 5 above, are both of the translated nodes showing as scheduled on the admin/content/scheduled tab?

bigbabert’s picture

Hi nope in admin/scheduled/tab was only the latest saved translation, the node is only one but with 2 tranlsations.

My suggestion is to get the revision id from the field u create for scheduling and then load Revision by field revision id.

To fix my use case i develop my own module so we can use with composer dependency, if can help have a look:

https://www.drupal.org/project/moderation_scheduler

Regards

rodman1980’s picture

Issue tags: -epam-contrib-2019.03
avpaderno’s picture

Status: Needs work » Active
Issue tags: -not scheduled
idflood’s picture

This issue is still present with the latest version of the modules.

I'm still not sure where exactly is the problem but in the node_field_revision table the data looks ok, but it seems that once the first translated version is published the data in node_field_data is changed for both languages. So even if the unpublished version has still the correct information in node_field_revision it doesn't get picked by the query at the beginning of the scheduler/src/SchedulerManager->publish method, and later on it will be discarded by the "publish_on" check which return null.

edit:
- may be related to https://www.drupal.org/project/drupal/issues/3088341
- this post also highlight one issue we have here I think: https://www.drupal.org/project/drupal/issues/2815779#comment-13365758 "what I'm really trying to figure out is why there's a new english revision when I only updated the translation"
- the way the last revision is loaded in scheduler was added here https://www.drupal.org/project/scheduler/issues/3049070

idflood’s picture

Looks like this issue is being taken care in https://www.drupal.org/project/scheduler/issues/3080979

avpaderno’s picture

@idflood if the other issue contains a patch that fixes the issue reported here, this issue can be closed as duplicate. May you confirm that the patch in the other issue would eventually fix the issue reported here?

eric_a’s picture

smustgrave’s picture

Status: Active » Postponed (maintainer needs more info)

Can you try on 2.x branch

smustgrave’s picture

Version: 8.x-1.x-dev » 2.x-dev
Status: Postponed (maintainer needs more info) » Closed (outdated)

If still experiencing this issue with 2.x branch or 3.0.x when I release that soon please reopen.