isLatestRevision example



  /** * Tests that latest revisions are working as expected. * * @covers ::isLatestRevision */
  public function testIsLatestRevision() {
    // Create a basic EntityTestMulRev entity and save it.     $entity = EntityTestMulRev::create();
    $entity->save();
    $this->assertTrue($entity->isLatestRevision());

    // Load the created entity and create a new pending revision.     $pending_revision = EntityTestMulRev::load($entity->id());
    $pending_revision->setNewRevision(TRUE);
    $pending_revision->isDefaultRevision(FALSE);

    // The pending revision should still be marked as the latest one before it     // is saved.     $this->assertTrue($pending_revision->isLatestRevision());
    $pending_revision->save();
    $this->assertTrue($pending_revision->isLatestRevision());

    

  protected function checkRevisionViewAccess(EntityInterface $entity, AccountInterface $account) {
    assert($entity instanceof RevisionableInterface);
    assert(!$entity->isDefaultRevision(), 'It is not necessary to check revision access when the entity is the default revision.');
    $entity_type = $entity->getEntityType();
    $access = $entity->access('view all revisions', $account, TRUE);
    // Apply content_moderation's additional access logic.     // @see \Drupal\content_moderation\Access\LatestRevisionCheck::access()     if ($entity_type->getLinkTemplate('latest-version') && $entity->isLatestRevision() && isset($this->latestRevisionCheck)) {
      // The latest revision access checker only expects to be invoked by the       // routing system, which makes it necessary to fake a route match.       $routes = $this->router->getRouteCollection();
      $resource_type = $this->resourceTypeRepository->get($entity->getEntityTypeId()$entity->bundle());
      $route_name = sprintf('jsonapi.%s.individual', $resource_type->getTypeName());
      $route = $routes->get($route_name);
      $route->setOption('_content_moderation_entity_type', 'entity');
      $route_match = new RouteMatch($route_name$route['entity' => $entity]['entity' => $entity->uuid()]);
      $moderation_access_result = $this->latestRevisionCheck->access($route$route_match$account);
      $access = $access->andIf($moderation_access_result);
    }
    
// If the resource is versionable, the `self` link should be the exact           // link for the represented version. This helps a client track           // revision changes and to disambiguate resource objects with the same           // `type` and `id` in a `version-history` collection.           $self_with_version_url = $self_url->setOption('query', [JsonApiSpec::VERSION_QUERY_PARAMETER => 'id:' . $entity->getRevisionId()]);
          $links = $links->withLink('self', new Link(new CacheableMetadata()$self_with_version_url, 'self'));
        }
        if (!$entity->isDefaultRevision()) {
          $latest_version_url = $self_url->setOption('query', [JsonApiSpec::VERSION_QUERY_PARAMETER => 'rel:' . VersionByRel::LATEST_VERSION]);
          $links = $links->withLink(VersionByRel::LATEST_VERSION, new Link(new CacheableMetadata()$latest_version_url, VersionByRel::LATEST_VERSION));
        }
        if (!$entity->isLatestRevision()) {
          $working_copy_url = $self_url->setOption('query', [JsonApiSpec::VERSION_QUERY_PARAMETER => 'rel:' . VersionByRel::WORKING_COPY]);
          $links = $links->withLink(VersionByRel::WORKING_COPY, new Link(new CacheableMetadata()$working_copy_url, VersionByRel::WORKING_COPY));
        }
      }
      if (!$links->hasLinkWithKey('self')) {
        $links = $links->withLink('self', new Link(new CacheableMetadata()$self_url, 'self'));
      }
    }
    return $links;
  }

  
    // revisions, since the 'name' field can vary by revision.     $labels = explode(',', $entity->label());
    $labels = array_map('trim', $labels);
    if (in_array($operation[
      'view all revisions',
      'view revision',
    ], TRUE)) {
      return AccessResult::allowedIf(in_array($operation$labels, TRUE));
    }
    elseif ($operation === 'revert') {
      // Disallow reverting to latest.       return AccessResult::allowedIf(!$entity->isDefaultRevision() && !$entity->isLatestRevision() && in_array('revert', $labels, TRUE));
    }
    elseif ($operation === 'delete revision') {
      // Disallow deleting latest and current revision.       return AccessResult::allowedIf(!$entity->isLatestRevision() && in_array('delete revision', $labels, TRUE));
    }

    // No opinion.     return AccessResult::neutral();
  }

  /** * {@inheritdoc} */

  public function patchIndividual(ResourceType $resource_type, EntityInterface $entity, Request $request) {
    if ($entity instanceof RevisionableInterface && !($entity->isLatestRevision() && $entity->isDefaultRevision())) {
      throw new BadRequestHttpException('Updating a resource object that has a working copy is not yet supported. See https://www.drupal.org/project/drupal/issues/2795279.');
    }

    $parsed_entity = $this->deserialize($resource_type$request, JsonApiDocumentTopLevel::class);

    $body = Json::decode($request->getContent());
    $data = $body['data'];
    if ($data['id'] != $entity->uuid()) {
      throw new BadRequestHttpException(sprintf(
        'The selected entity (%s) does not match the ID in the payload (%s).',
        $entity->uuid(),
        
'view label',
      'view all revisions',
      'view revision',
    ], TRUE)) {
      return AccessResult::allowedIf(in_array($operation$labels, TRUE));
    }
    elseif ($operation === 'revert') {
      return AccessResult::allowedIf(
        // Allow revert even if latest.         in_array('force allow revert', $labels, TRUE) ||
        // Disallow reverting to latest.         (!$entity->isDefaultRevision() && !$entity->isLatestRevision() && in_array('revert', $labels, TRUE))
      );
    }
    elseif ($operation === 'delete revision') {
      return AccessResult::allowedIf(
        // Allow revision deletion even if latest.         in_array('force allow delete revision', $labels, TRUE) ||
        // Disallow deleting latest and current revision.         (!$entity->isLatestRevision() && in_array('delete revision', $labels, TRUE))
      );
    }

    
$entity_type,
      $container->get('event_dispatcher')
    );
  }

  /** * {@inheritdoc} */
  protected function checkAccess(EntityInterface $entity$operation, AccountInterface $account) {
    assert($entity instanceof BlockContentInterface);
    $bundle = $entity->bundle();
    $forbidIfNotDefaultAndLatest = fn (): AccessResultInterface => AccessResult::forbiddenIf($entity->isDefaultRevision() && $entity->isLatestRevision());
    $forbidIfNotReusable = fn (): AccessResultInterface => AccessResult::forbiddenIf($entity->isReusable() === FALSE, sprintf('Block content must be reusable to use `%s` operation', $operation));
    $access = match ($operation) {
      // Allow view and update access to user with the 'edit any (type) block       // content' permission or the 'administer blocks' permission.       'view' => AccessResult::allowedIf($entity->isPublished())
        ->orIf(AccessResult::allowedIfHasPermissions($account[
          'access block library',
        ]))->orIf(AccessResult::allowedIfHasPermissions($account[
          'administer block content',
        ])),
      'update' => AccessResult::allowedIfHasPermissions($account[
        
$entity->isDefaultRevision(FALSE);
    $entity->setUnpublished();
    $entity->setNewRevision();
    $entity->save();

    // Reload the entity.     /** @var \Drupal\entity_test\Entity\EntityTestRevPub $revision */
    $revision = \Drupal::entityTypeManager()->getStorage('entity_test_revpub')
      ->loadRevision($revisionId);
    // Check default but not latest.     $this->assertTrue($revision->isDefaultRevision());
    $this->assertFalse($revision->isLatestRevision());
    $this->drupalGet($entity->toUrl('revision-delete-form'));
    $this->assertSession()->statusCodeEquals(403);
  }

  /** * Test can delete non-latest revision. * * @covers \Drupal\Core\Entity\EntityAccessControlHandler::checkAccess */
  public function testAccessDeleteNonLatest(): void {
    /** @var \Drupal\entity_test\Entity\EntityTestRev $entity */
    
$result = !$latest_revision->wasDefaultRevision();
      }
    }
    return $result;
  }

  /** * {@inheritdoc} */
  public function isLiveRevision(ContentEntityInterface $entity) {
    $workflow = $this->getWorkflowForEntity($entity);
    return $entity->isLatestRevision()
      && $entity->isDefaultRevision()
      && $entity->moderation_state->value
      && $workflow->getTypePlugin()->getState($entity->moderation_state->value)->isPublishedState();
  }

  /** * {@inheritdoc} */
  public function isDefaultRevisionPublished(ContentEntityInterface $entity) {
    $workflow = $this->getWorkflowForEntity($entity);
    $default_revision = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->load($entity->id());
    

    // If the component is not defined for this display, we have nothing to do.     if (!$display->getComponent('content_moderation_control')) {
      return;
    }
    // The moderation form should be displayed only when viewing the latest     // (translation-affecting) revision, unless it was created as published     // default revision.     if (($entity->isDefaultRevision() || $entity->wasDefaultRevision()) && $this->isPublished($entity)) {
      return;
    }
    if (!$entity->isLatestRevision() && !$entity->isLatestTranslationAffectedRevision()) {
      return;
    }

    $build['content_moderation_control'] = $this->formBuilder->getForm(EntityModerationForm::class$entity);
  }

  /** * Checks if the entity is published. * * This method is optimized to not have to unnecessarily load the moderation * state and workflow if it is not required. * * @param \Drupal\Core\Entity\ContentEntityInterface $entity * The entity to check. * * @return bool * TRUE if the entity is published, FALSE otherwise. */
Home | Imprint | This part of the site doesn't use cookies.