Example #1
0
 /**
  * Ensures correct entity URLs with the method language-content-entity enabled.
  *
  * Test case with the method language-content-entity enabled and configured
  * with higher and also with lower priority than the method language-url.
  */
 public function testEntityUrlLanguageWithLanguageContentEnabled()
 {
     // Define the method language-content-entity with a higher priority than
     // language-url.
     $config = $this->config('language.types');
     $config->set('configurable', [LanguageInterface::TYPE_INTERFACE, LanguageInterface::TYPE_CONTENT]);
     $config->set('negotiation.language_content.enabled', [LanguageNegotiationContentEntity::METHOD_ID => 0, LanguageNegotiationUrl::METHOD_ID => 1]);
     $config->save();
     // Without being on an content entity route the default entity URL tests
     // should still pass.
     $this->testEntityUrlLanguage();
     // Now switching to an entity route, so that the URL links are generated
     // while being on an entity route.
     $this->setCurrentRequestForRoute('/entity_test/{entity_test}', 'entity.entity_test.canonical');
     // The method language-content-entity should run before language-url and
     // append query parameter for the content language and prevent language-url
     // from overwriting the url.
     $this->assertTrue(strpos($this->entity->urlInfo('canonical')->toString(), '/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=en') !== FALSE);
     $this->assertTrue(strpos($this->entity->getTranslation('es')->urlInfo('canonical')->toString(), '/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=es') !== FALSE);
     $this->assertTrue(strpos($this->entity->getTranslation('fr')->urlInfo('canonical')->toString(), '/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=fr') !== FALSE);
     // Define the method language-url with a higher priority than
     // language-content-entity. This configuration should match the default one,
     // where the language-content-entity is turned off.
     $config->set('negotiation.language_content.enabled', [LanguageNegotiationUrl::METHOD_ID => 0, LanguageNegotiationContentEntity::METHOD_ID => 1]);
     $config->save();
     // The default entity URL tests should pass again with the current
     // configuration.
     $this->testEntityUrlLanguage();
 }
Example #2
0
 /**
  * Will test the redirects.
  */
 public function testRedirects()
 {
     // Test alias normalization.
     $this->config->set('normalize_aliases', TRUE)->save();
     $this->assertRedirect('node/' . $this->node->id(), 'test-node');
     $this->assertRedirect('Test-node', 'test-node');
     $this->config->set('normalize_aliases', FALSE)->save();
     $this->assertRedirect('node/' . $this->node->id(), NULL, 'HTTP/1.1 200 OK');
     $this->assertRedirect('Test-node', NULL, 'HTTP/1.1 200 OK');
     // Test deslashing.
     $this->config->set('deslash', TRUE)->save();
     $this->assertRedirect('test-node/', 'test-node');
     $this->config->set('deslash', FALSE)->save();
     $this->assertRedirect('test-node/', NULL, 'HTTP/1.1 200 OK');
     // Test front page redirects.
     $this->config->set('frontpage_redirect', TRUE)->save();
     $this->config('system.site')->set('page.front', '/node')->save();
     $this->assertRedirect('node', '<front>');
     // Test front page redirects with an alias.
     \Drupal::service('path.alias_storage')->save('/node', '/node-alias');
     $this->assertRedirect('node-alias', '<front>');
     $this->config->set('frontpage_redirect', FALSE)->save();
     $this->assertRedirect('node', NULL, 'HTTP/1.1 200 OK');
     $this->assertRedirect('node-alias', NULL, 'HTTP/1.1 200 OK');
     // Test post request.
     $this->config->set('normalize_aliases', TRUE)->save();
     $this->drupalPost('Test-node', 'application/json', array());
     // Does not do a redirect, stays in the same path.
     $this->assertEqual(basename($this->getUrl()), 'Test-node');
     // Test the access checking.
     $this->config->set('normalize_aliases', TRUE)->save();
     $this->config->set('access_check', TRUE)->save();
     $this->assertRedirect('admin/config/system/site-information', NULL, 'HTTP/1.1 403 Forbidden');
     $this->config->set('access_check', FALSE)->save();
     // @todo - here it seems that the access check runs prior to our redirecting
     //   check why so and enable the test.
     //$this->assertRedirect('admin/config/system/site-information', 'site-info');
     // Login as user with admin privileges.
     $this->drupalLogin($this->adminUser);
     // Test ignoring admin paths.
     $this->config->set('ignore_admin_path', FALSE)->save();
     $this->assertRedirect('admin/config/system/site-information', 'site-info');
     $this->config->set('ignore_admin_path', TRUE)->save();
     $this->assertRedirect('admin/config/system/site-information', NULL, 'HTTP/1.1 200 OK');
 }
Example #3
0
 /**
  * {@inheritdoc}
  */
 protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = [])
 {
     // The anonymous user account is saved with the fixed user ID of 0.
     // Therefore we need to check for NULL explicitly.
     if ($entity->id() === NULL) {
         $entity->uid->value = $this->database->nextId($this->database->query('SELECT MAX(uid) FROM {users}')->fetchField());
         $entity->enforceIsNew();
     }
     return parent::doSaveFieldItems($entity, $names);
 }
 protected function getAddLink(ContentEntityInterface $host)
 {
     $link = '';
     if ($host->access('update', \Drupal::currentUser())) {
         $link = '<ul class="action-links action-links-field-collection-add"><li>';
         $link .= \Drupal::l(t('Add'), Url::FromRoute('field_collection_item.add_page', ['field_collection' => $this->fieldDefinition->getName(), 'host_type' => $host->getEntityTypeId(), 'host_id' => $host->id()]));
         $link .= '</li></ul>';
     }
     return $link;
 }
 /**
  * {@inheritdoc}
  */
 public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode, $original_langcode = NULL)
 {
     $translations = $entity->getTranslationLanguages();
     $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
     // If we have no information about what to sync to, if we are creating a new
     // entity, if we have no translations for the current entity and we are not
     // creating one, then there is nothing to synchronize.
     if (empty($sync_langcode) || $entity->isNew() || count($translations) < 2) {
         return;
     }
     // If the entity language is being changed there is nothing to synchronize.
     $entity_type = $entity->getEntityTypeId();
     $entity_unchanged = isset($entity->original) ? $entity->original : $this->entityManager->getStorage($entity_type)->loadUnchanged($entity->id());
     if ($entity->getUntranslated()->language()->getId() != $entity_unchanged->getUntranslated()->language()->getId()) {
         return;
     }
     /** @var \Drupal\Core\Field\FieldItemListInterface $items */
     foreach ($entity as $field_name => $items) {
         $field_definition = $items->getFieldDefinition();
         $field_type_definition = $field_type_manager->getDefinition($field_definition->getType());
         $column_groups = $field_type_definition['column_groups'];
         // Sync if the field is translatable, not empty, and the synchronization
         // setting is enabled.
         if ($field_definition instanceof ThirdPartySettingsInterface && $field_definition->isTranslatable() && !$items->isEmpty() && ($translation_sync = $field_definition->getThirdPartySetting('content_translation', 'translation_sync'))) {
             // Retrieve all the untranslatable column groups and merge them into
             // single list.
             $groups = array_keys(array_diff($translation_sync, array_filter($translation_sync)));
             if (!empty($groups)) {
                 $columns = array();
                 foreach ($groups as $group) {
                     $info = $column_groups[$group];
                     // A missing 'columns' key indicates we have a single-column group.
                     $columns = array_merge($columns, isset($info['columns']) ? $info['columns'] : array($group));
                 }
                 if (!empty($columns)) {
                     $values = array();
                     foreach ($translations as $langcode => $language) {
                         $values[$langcode] = $entity->getTranslation($langcode)->get($field_name)->getValue();
                     }
                     // If a translation is being created, the original values should be
                     // used as the unchanged items. In fact there are no unchanged items
                     // to check against.
                     $langcode = $original_langcode ?: $sync_langcode;
                     $unchanged_items = $entity_unchanged->getTranslation($langcode)->get($field_name)->getValue();
                     $this->synchronizeItems($values, $unchanged_items, $sync_langcode, array_keys($translations), $columns);
                     foreach ($translations as $langcode => $language) {
                         $entity->getTranslation($langcode)->get($field_name)->setValue($values[$langcode]);
                     }
                 }
             }
         }
     }
 }
Example #6
0
 /**
  * {@inheritdoc}
  */
 protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array())
 {
     // Do not overwrite the root account password.
     if ($entity->id() != 1) {
         // Set the pre_hashed password so that the PasswordItem field does not hash
         // already hashed passwords. If the md5_passwords configuration option is
         // set we need to rehash the password and prefix with a U.
         // @see \Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem::preSave()
         $entity->pass->pre_hashed = TRUE;
         if (isset($this->configuration['md5_passwords'])) {
             $entity->pass->value = 'U' . $this->password->hash($entity->pass->value);
         }
     }
     return parent::save($entity, $old_destination_id_values);
 }
 /**
  * Checks whether field languages are correctly stored for the given entity.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The entity fields are attached to.
  * @param string $message
  *   (optional) A message to display with the assertion.
  */
 protected function assertFieldStorageLangcode(ContentEntityInterface $entity, $message = '')
 {
     $status = TRUE;
     $entity_type = $entity->getEntityTypeId();
     $id = $entity->id();
     $langcode = $entity->getUntranslated()->language()->id;
     $fields = array($this->field_name, $this->untranslatable_field_name);
     foreach ($fields as $field_name) {
         $field_storage = FieldStorageConfig::loadByName($entity_type, $field_name);
         $tables = array(ContentEntityDatabaseStorage::_fieldTableName($field_storage), ContentEntityDatabaseStorage::_fieldRevisionTableName($field_storage));
         foreach ($tables as $table) {
             $record = \Drupal::database()->select($table, 'f')->fields('f')->condition('f.entity_id', $id)->condition('f.revision_id', $id)->execute()->fetchObject();
             if ($record->langcode != $langcode) {
                 $status = FALSE;
                 break;
             }
         }
     }
     return $this->assertTrue($status, $message);
 }
 /**
  * Getter for the entity id.
  *
  * @return int mixed
  *   The entity id.
  */
 public function getEntityId() {
   return $this->entity->id();
 }
Example #9
0
 protected function sortById(ContentEntityInterface $leftEntity, ContentEntityInterface $rightEntity)
 {
     $leftId = (int) $leftEntity->id();
     $rightId = (int) $rightEntity->id();
     return $leftId < $rightId ? -1 : 1;
 }
 /**
  * Check if the supplied entity layout has any content blocks.
  *
  * @param EntityLayoutInterface $entity_layout
  *   The entity layout to check content blocks for.
  *
  * @return bool
  */
 public function hasContentBlocks(EntityLayoutInterface $entity_layout, ContentEntityInterface $entity)
 {
     return (bool) $this->entityTypeManager->getStorage('entity_layout_block')->getQuery()->condition('entity_id', $entity->id())->condition('layout', $entity_layout->id())->count()->execute();
 }
 /**
  * {@inheritdoc}
  */
 public function create(ContentEntityInterface $entity, $fields)
 {
     $query = $this->database->insert('comment_entity_statistics')->fields(array('entity_id', 'entity_type', 'field_name', 'cid', 'last_comment_timestamp', 'last_comment_name', 'last_comment_uid', 'comment_count'));
     foreach ($fields as $field_name => $detail) {
         // Skip fields that entity does not have.
         if (!$entity->hasField($field_name)) {
             continue;
         }
         // Get the user ID from the entity if it's set, or default to the
         // currently logged in user.
         $last_comment_uid = 0;
         if ($entity instanceof EntityOwnerInterface) {
             $last_comment_uid = $entity->getOwnerId();
         }
         if (!isset($last_comment_uid)) {
             // Default to current user when entity does not implement
             // EntityOwnerInterface or author is not set.
             $last_comment_uid = $this->currentUser->id();
         }
         // Default to REQUEST_TIME when entity does not have a changed property.
         $last_comment_timestamp = REQUEST_TIME;
         if ($entity instanceof EntityChangedInterface) {
             $last_comment_timestamp = $entity->getChangedTime();
         }
         $query->values(array('entity_id' => $entity->id(), 'entity_type' => $entity->getEntityTypeId(), 'field_name' => $field_name, 'cid' => 0, 'last_comment_timestamp' => $last_comment_timestamp, 'last_comment_name' => NULL, 'last_comment_uid' => $last_comment_uid, 'comment_count' => 0));
     }
     $query->execute();
 }
Example #12
0
 /**
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  * @return array
  */
 protected function buildRecord(ContentEntityInterface $entity)
 {
     return array('entity_type_id' => $entity->getEntityTypeId(), 'entity_id' => $entity->id(), 'entity_uuid' => $entity->uuid(), 'revision_id' => $entity->getRevisionId(), 'deleted' => $entity->_deleted->value, 'rev' => $entity->_rev->value, 'seq' => $this->multiversionManager->newSequenceId(), 'local' => (bool) $entity->getEntityType()->get('local'), 'is_stub' => (bool) $entity->_rev->is_stub);
 }
Example #13
0
 /**
  * Check an entity value after reload.
  *
  * @param $entity_type_id
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  * @param $field
  * @param $value
  */
 protected function checkEntityValue($entity_type_id, ContentEntityInterface $entity, $field, $value) {
   $storage = \Drupal::entityTypeManager()->getStorage($entity_type_id);
   $storage->resetCache([$entity->id()]);
   $updated_entity = $storage->load($entity->id());
   $this->assertEqual($updated_entity->get($field)->value, 1, $entity->label() . " $field = $value");
 }
Example #14
0
 /**
  * Detect whether an entity is already reference within an ancestry ER array.
  *
  * @var \Drupal\Core\Entity\ContentEntityInterface $discussion
  *    A discussion node entity.
  * @var array $ancestry
  *    A discussion node entity, coming from field_ancestry->getValue().
  */
 protected function withinAncestry(ContentEntityInterface $entity, $ancestry)
 {
     $detected = FALSE;
     foreach ($ancestry as $ancestor) {
         if ($entity->id() == $ancestor['target_id']) {
             $detected = TRUE;
         }
     }
     return $detected;
 }
 /**
  * Counts the number of revisions in the default language.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The entity.
  * @param \Drupal\Core\Entity\EntityStorageInterface $entity_storage
  *   The entity storage.
  *
  * @return int
  *   The number of revisions in the default language.
  */
 protected function countDefaultLanguageRevisions(ContentEntityInterface $entity, EntityStorageInterface $entity_storage)
 {
     $entity_type = $entity->getEntityType();
     $count = $entity_storage->getQuery()->allRevisions()->condition($entity_type->getKey('id'), $entity->id())->condition($entity_type->getKey('default_langcode'), 1)->count()->execute();
     return $count;
 }
 /**
  * Generate the HTML for our entity.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The entity we're rendering.
  * @param bool $use_default_css
  *   TRUE if we should inject our default CSS otherwise FALSE.
  * @param bool $optimize_css
  *   TRUE if we should compress the CSS otherwise FALSE.
  *
  * @return string
  *   The generated HTML.
  *
  * @throws \Exception
  */
 protected function getHtml(ContentEntityInterface $entity, $use_default_css, $optimize_css)
 {
     $render_controller = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
     $render = ['#theme' => 'entity_print__' . $entity->getEntityTypeId() . '__' . $entity->id(), '#entity' => $entity, '#entity_array' => $render_controller->view($entity, 'pdf'), '#attached' => []];
     // Inject some generic CSS across all templates.
     if ($use_default_css) {
         $render['#attached']['library'][] = 'entity_print/default';
     }
     // Allow other modules to add their own CSS.
     $this->moduleHandler->alter('entity_print_css', $render, $entity);
     // Inject CSS from the theme info files and then render the CSS.
     $render = $this->addCss($render, $entity);
     $css_assets = $this->assetResolver->getCssAssets(AttachedAssets::createFromRenderArray($render), $optimize_css);
     $rendered_css = $this->cssRenderer->render($css_assets);
     $render['#entity_print_css'] = $this->renderer->render($rendered_css);
     return $this->renderer->render($render);
 }
 /**
  * Builds a table row for overview form.
  *
  * @param array ContentEntityInterface $entity
  *   Data needed to build the list row.
  * @param array $bundles
  *   The array of bundles.
  *
  * @return array
  */
 public function overviewRow(ContentEntityInterface $entity, array $bundles)
 {
     $label = $entity->label() ?: $this->t('@type: @id', array('@type' => $entity->getEntityTypeId(), '@id' => $entity->id()));
     // Get existing translations and current job items for the entity
     // to determine translation statuses
     $translations = $entity->getTranslationLanguages();
     $source_lang = $entity->language()->getId();
     $current_job_items = tmgmt_job_item_load_latest('content', $entity->getEntityTypeId(), $entity->id(), $source_lang);
     $row = array('id' => $entity->id(), 'title' => $entity->hasLinkTemplate('canonical') ? $entity->toLink($label, 'canonical')->toString() : ($entity->label() ?: $entity->id()));
     if (count($bundles) > 1) {
         $row['bundle'] = isset($bundles[$entity->bundle()]) ? $bundles[$entity->bundle()] : t('Unknown');
     }
     // Load entity translation specific data.
     $manager = \Drupal::service('content_translation.manager');
     foreach (\Drupal::languageManager()->getLanguages() as $langcode => $language) {
         $translation_status = 'current';
         if ($langcode == $source_lang) {
             $translation_status = 'original';
         } elseif (!isset($translations[$langcode])) {
             $translation_status = 'missing';
         } elseif ($translation = $entity->getTranslation($langcode)) {
             $metadata = $manager->getTranslationMetadata($translation);
             if ($metadata->isOutdated()) {
                 $translation_status = 'outofdate';
             }
         }
         $build = $this->buildTranslationStatus($translation_status, isset($current_job_items[$langcode]) ? $current_job_items[$langcode] : NULL);
         $row['langcode-' . $langcode] = ['data' => \Drupal::service('renderer')->render($build), 'class' => array('langstatus-' . $langcode)];
     }
     return $row;
 }
 /**
  * {@inheritdoc}
  */
 public function isLatestRevision(ContentEntityInterface $entity)
 {
     return $entity->getRevisionId() == $this->getLatestRevisionId($entity->getEntityTypeId(), $entity->id());
 }
 /**
  * Save the entity.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The content entity.
  * @param array $old_destination_id_values
  *   An array of destination id values.
  *
  * @return array
  *   An array containing the entity id.
  */
 protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array())
 {
     $entity->save();
     return array($entity->id());
 }
 /**
  * Get all previous revisions that have updates of the attached type.
  *
  * This function would be easier and more performant if this core issue with
  * Entity Query was fixed: https://www.drupal.org/node/2649268 Without this
  * fix can't filter query on type of update and whether they are active. So
  * therefore all previous revisions have to be loaded.
  *
  * @todo Help get that core issue fixed or rewrite this function query table
  *       fields directly.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *
  * @return \Drupal\Core\Entity\ContentEntityInterface[]
  */
 protected function getPreviousRevisionsWithUpdates(ContentEntityInterface $entity)
 {
     /** @var ContentEntityInterface[] $revisions */
     $revisions = [];
     $type = $entity->getEntityType();
     $query = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->getQuery();
     $query->allRevisions()->condition($type->getKey('id'), $entity->id())->condition($type->getKey('revision'), $entity->getRevisionId(), '<')->sort($type->getKey('revision'), 'DESC');
     if ($revision_ids = $query->execute()) {
         $revision_ids = array_keys($revision_ids);
         $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId());
         foreach ($revision_ids as $revision_id) {
             /** @var ContentEntityInterface $revision */
             $revision = $storage->loadRevision($revision_id);
             if ($update_ids = $this->getUpdateIdsOnEntity($revision)) {
                 $revisions[$revision_id] = $revision;
             }
         }
     }
     return $revisions;
 }
 /**
  * Build the render array for the block library.
  *
  * @param EntityLayoutInterface $entity_layout
  *   The entity layout to show allowed blocks for.
  * @param ContentEntityInterface $content_entity
  *   The content entity the block is being added to.
  *
  * @return array
  *   The render array.
  */
 protected function buildBlockLibrary(EntityLayoutInterface $entity_layout, ContentEntityInterface $content_entity = NULL)
 {
     $build['filter'] = ['#type' => 'search', '#title' => $this->t('Filter'), '#title_display' => 'invisible', '#size' => 30, '#placeholder' => $this->t('Filter by block name'), '#attributes' => ['class' => ['context-table-filter'], 'data-element' => '.block-add-table', 'title' => $this->t('Enter a part of the block name to filter by.')]];
     $headers = [$this->t('Block'), $this->t('Category'), $this->t('Operations')];
     $build['blocks'] = ['#type' => 'table', '#header' => $headers, '#rows' => [], '#empty' => $this->t('No blocks available for placement.'), '#attributes' => ['class' => ['block-add-table']]];
     $blocks = $this->entityLayoutService->getSystemBlocks();
     // Add each block definition to the table.
     foreach ($blocks as $block_id => $block) {
         if (!$entity_layout->blockIsAllowed($block_id)) {
             continue;
         }
         $bundle_entity_type = $this->entityLayoutService->getTargetBundleEntityType($entity_layout);
         // Use different routes depending on what kind of entity were adding
         // blocks for.
         if ($content_entity) {
             $entity_type_id = $content_entity->getEntityTypeId();
             $block_add_url = Url::fromRoute("entity_layout.{$entity_type_id}.content.block.add", ['block_id' => $block_id, $entity_type_id => $content_entity->id()]);
         } else {
             $entity_type_id = $entity_layout->getTargetEntityType();
             $block_add_url = Url::fromRoute("entity_layout.{$entity_type_id}.block.add", ['block_id' => $block_id, $bundle_entity_type => $entity_layout->getTargetBundle()]);
         }
         $links = ['add' => ['title' => $this->t('Place block'), 'url' => $block_add_url, 'attributes' => ['class' => ['use-ajax'], 'data-dialog-type' => 'modal', 'data-dialog-options' => Json::encode(['width' => 700])]]];
         $build['blocks']['#rows'][] = ['title' => ['data' => ['#type' => 'inline_template', '#template' => '<div class="context-table-filter-text-source">{{ label }}</div>', '#context' => ['label' => $block['admin_label']]]], 'category' => ['data' => $block['category']], 'operations' => ['data' => ['#type' => 'operations', '#links' => $links]]];
     }
     // @todo Create a filter behaviour for the table.
     //$build['#attached']['library'][] = 'context_ui/admin';
     return $build;
 }
 /**
  * Loads all revision IDs of an entity sorted by revision ID descending.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The entity.
  *
  * @return mixed[]
  */
 protected function revisionIds(ContentEntityInterface $entity)
 {
     $entity_type = $entity->getEntityType();
     $result = $this->entityTypeManager()->getStorage($entity_type->id())->getQuery()->allRevisions()->condition($entity_type->getKey('id'), $entity->id())->sort($entity_type->getKey('revision'), 'DESC')->execute();
     return array_keys($result);
 }
Example #23
0
 /**
  * Get the directly previous revision.
  *
  * $entity->original will not ALWAYS be the previous revision.
  *
  * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *
  * @return \Drupal\Core\Entity\EntityInterface|null
  */
 public function getPreviousRevision(ContentEntityInterface $entity) {
   $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId());
   $query = $storage->getQuery();
   $type = $entity->getEntityType();
   $query->allRevisions()
     ->condition($type->getKey('id'), $entity->id())
     ->condition($type->getKey('revision'), $entity->getRevisionId(), '<')
     ->sort($type->getKey('revision'), 'DESC')
     ->pager(1);
   $revision_ids = $query->execute();
   if ($revision_ids) {
     $revision_id = array_keys($revision_ids)[0];
     return $storage->loadRevision($revision_id);
   }
   return NULL;
 }
 /**
  * {@inheritdoc}
  */
 protected function purgeFieldItems(ContentEntityInterface $entity, FieldDefinitionInterface $field_definition)
 {
     $storage_definition = $field_definition->getFieldStorageDefinition();
     $is_deleted = $this->storageDefinitionIsDeleted($storage_definition);
     $table_mapping = $this->getTableMapping();
     $table_name = $table_mapping->getDedicatedDataTableName($storage_definition, $is_deleted);
     $revision_name = $table_mapping->getDedicatedRevisionTableName($storage_definition, $is_deleted);
     $revision_id = $this->entityType->isRevisionable() ? $entity->getRevisionId() : $entity->id();
     $this->database->delete($table_name)->condition('revision_id', $revision_id)->execute();
     if ($this->entityType->isRevisionable()) {
         $this->database->delete($revision_name)->condition('revision_id', $revision_id)->execute();
     }
 }
Example #25
0
 /**
  * {@inheritdoc}
  */
 public function getNewCommentPageNumber($total_comments, $new_comments, ContentEntityInterface $entity, $field_name = 'comment')
 {
     $instance = $entity->getFieldDefinition($field_name);
     $comments_per_page = $instance->getSetting('per_page');
     if ($total_comments <= $comments_per_page) {
         // Only one page of comments.
         $count = 0;
     } elseif ($instance->getSetting('default_mode') == CommentManagerInterface::COMMENT_MODE_FLAT) {
         // Flat comments.
         $count = $total_comments - $new_comments;
     } else {
         // Threaded comments.
         // 1. Find all the threads with a new comment.
         $unread_threads_query = $this->database->select('comment_field_data', 'comment')->fields('comment', array('thread'))->condition('entity_id', $entity->id())->condition('entity_type', $entity->getEntityTypeId())->condition('field_name', $field_name)->condition('status', CommentInterface::PUBLISHED)->condition('default_langcode', 1)->orderBy('created', 'DESC')->orderBy('cid', 'DESC')->range(0, $new_comments);
         // 2. Find the first thread.
         $first_thread_query = $this->database->select($unread_threads_query, 'thread');
         $first_thread_query->addExpression('SUBSTRING(thread, 1, (LENGTH(thread) - 1))', 'torder');
         $first_thread = $first_thread_query->fields('thread', array('thread'))->orderBy('torder')->range(0, 1)->execute()->fetchField();
         // Remove the final '/'.
         $first_thread = substr($first_thread, 0, -1);
         // Find the number of the first comment of the first unread thread.
         $count = $this->database->query('SELECT COUNT(*) FROM {comment_field_data} WHERE entity_id = :entity_id
                     AND entity_type = :entity_type
                     AND field_name = :field_name
                     AND status = :status
                     AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread
                     AND default_langcode = 1', array(':status' => CommentInterface::PUBLISHED, ':entity_id' => $entity->id(), ':field_name' => $field_name, ':entity_type' => $entity->getEntityTypeId(), ':thread' => $first_thread))->fetchField();
     }
     return $comments_per_page > 0 ? (int) ($count / $comments_per_page) : 0;
 }