knowledge-8.x-1.x-dev/src/KnowledgeLazyBuilders.php
src/KnowledgeLazyBuilders.php
<?php
namespace Drupal\knowledge;
use Drupal\Core\Entity\EntityFormBuilderInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\Element\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Core\Url;
use Drupal\knowledge\Plugin\Field\FieldType\KnowledgeItemInterface;
/**
* Defines a service for knowledge #lazy_builder callbacks.
*/
class KnowledgeLazyBuilders implements TrustedCallbackInterface {
use StringTranslationTrait;
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity form builder service.
*
* @var \Drupal\Core\Entity\EntityFormBuilderInterface
*/
protected $entityFormBuilder;
/**
* Knowledge manager service.
*
* @var \Drupal\knowledge\KnowledgeManagerInterface
*/
protected $knowledgeManager;
/**
* Current logged in user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Constructs a new KnowledgeLazyBuilders object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Core\Entity\EntityFormBuilderInterface $entity_form_builder
* The entity form builder service.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current logged in user.
* @param \Drupal\knowledge\KnowledgeManagerInterface $knowledge_manager
* The knowledge manager service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The sting translation service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFormBuilderInterface $entity_form_builder, AccountInterface $current_user, KnowledgeManagerInterface $knowledge_manager, ModuleHandlerInterface $module_handler, RendererInterface $renderer, TranslationInterface $string_translation) {
$this->entityTypeManager = $entity_type_manager;
$this->entityFormBuilder = $entity_form_builder;
$this->currentUser = $current_user;
$this->knowledgeManager = $knowledge_manager;
$this->moduleHandler = $module_handler;
$this->renderer = $renderer;
$this->stringTranslation = $string_translation;
}
/**
* The #lazy_builder callback; builds the knowledge form.
*
* @param string $knowledge_entity_type_id
* The linked entity type ID.
* @param string $linked_entity_id
* The linked entity ID.
* @param string $field_name
* The knowledge field name.
* @param string $knowledge_type_id
* The knowledge type ID.
*
* @return array
* A renderable array containing the knowledge form.
*/
public function renderForm($knowledge_entity_type_id, $linked_entity_id, $field_name, $knowledge_type_id) {
/** @var \Drupal\knowledge\KnowledgeInterface $entity */
$entity = $this->entityTypeManager->getStorage($knowledge_entity_type_id)->load($linked_entity_id);
if (!$entity || !$entity->get('status')->value) {
return [
'#markup' => $this->t('Only active content may be linked.'),
];
}
$field = $entity->get($field_name);
if ($field[0]->get('status')->getValue() == 1) {
return [
'#markup' => $this->t('Linking is disabled for this content.'),
];
}
$values = [
'entity_type' => $knowledge_entity_type_id,
'entity_id' => $linked_entity_id,
'field_name' => $field_name,
'knowledge_type' => $knowledge_type_id,
];
$knowledge = $this->entityTypeManager->getStorage('knowledge')->create($values);
return $this->entityFormBuilder->getForm($knowledge);
}
/**
* The #lazy_builder callback; builds a knowledge's links.
*
* @param string $knowledge_entity_id
* The knowledge entity ID.
* @param string $view_mode
* The view mode in which the knowledge entity is being viewed.
* @param string $langcode
* The language in which the knowledge entity is being viewed.
* @param bool $is_in_preview
* Whether the knowledge is currently being previewed.
*
* @return array
* A renderable array representing the knowledge links.
*/
public function renderLinks($knowledge_entity_id, $view_mode, $langcode, $is_in_preview) {
$links = [
'#theme' => 'links__knowledge',
'#pre_render' => [[Link::class, 'preRenderLinks']],
'#attributes' => ['class' => ['links', 'inline']],
];
if (!$is_in_preview) {
/** @var \Drupal\knowledge\KnowledgeInterface $entity */
$entity = $this->entityTypeManager->getStorage('knowledge')->load($knowledge_entity_id);
if ($linked_entity = $entity->getKnowledgeedEntity()) {
$links['knowledge'] = $this->buildLinks($entity, $linked_entity);
}
// Allow other modules to alter the knowledge links.
$hook_context = [
'view_mode' => $view_mode,
'langcode' => $langcode,
'linked_entity' => $linked_entity,
];
$this->moduleHandler->alter('knowledge_links', $links, $entity, $hook_context);
}
return $links;
}
/**
* The #lazy_builder callback; builds the knowledge form.
*
* @param string $entity_type_id
* The linked entity type ID.
* @param int $entity_id
* The linked entity ID.
* @param int $entity_vid
* The knowledge field name.
* @param int $user_id
* The user the KnowledgeQuality is reviewing.
*
* @return array
* A renderable array containing the knowledge form.
*/
public function renderQualityForm(string $entity_type_id, int $entity_id, int $entity_vid, int $user_id) {
$build = [];
$quality_storage = $this->entityTypeManager->getStorage('knowledge_quality');
$query = $this->entityTypeManager
->getStorage('knowledge_quality')
->getQuery();
$quality_id = $query
->condition('entity_type', $entity_type_id)
->condition('entity_id', $entity_id)
->accessCheck(FALSE)
->execute();
if ($this->currentUser->hasPermission('add quality entities')) {
if (empty($quality_id)) {
$values = [
'entity_type' => $entity_type_id,
'entity_id' => $entity_id,
'entity_vid' => $entity_vid,
'user_id' => $user_id,
];
/** @var \Drupal\knowledge\Entity\KnowledgeQualityInterface $quality */
$quality = $quality_storage->create($values);
}
else {
/** @var \Drupal\knowledge\Entity\KnowledgeQualityInterface $quality */
$quality = $quality_storage->load(current($quality_id));
$quality->set('entity_vid', $entity_vid);
}
$build = $this->entityFormBuilder->getForm($quality);
}
elseif ($this->currentUser->hasPermission('view published quality entities')) {
$build['no_entity']['#markup'] = $this->t('Not yet scored.');
if (!empty($quality_id)) {
$quality = $quality_storage->load(current($quality_id));
$view_builder = $this->entityTypeManager
->getViewBuilder('knowledge_quality');
// You can omit the language ID, by default the current content language
// will be used. If no translation is available for the current
// language, fallback rules will be used.
$build = $view_builder->view($quality, 'default');
}
}
return $build;
}
/**
* Build the default links (reply, edit, delete …) for a knowledge.
*
* @param \Drupal\knowledge\KnowledgeInterface $entity
* The knowledge object.
* @param \Drupal\Core\Entity\FieldableEntityInterface $linked_entity
* The entity to which the knowledge is attached.
*
* @return array
* An array that can be processed by drupal_pre_render_links().
*/
protected function buildLinks(KnowledgeInterface $entity, FieldableEntityInterface $linked_entity) {
$links = [];
$status = $linked_entity->get($entity->getFieldName())->status;
if ($status == KnowledgeItemInterface::OPEN) {
if ($entity->access('update')) {
if ($entity->isPublished()) {
$links['knowledge-unlink'] = [
'title' => $this->t('Unlink'),
'url' => $entity->toUrl('unlink-form'),
];
}
}
if (!$entity->isPublished() && $entity->access('approve')) {
$links['knowledge-approve'] = [
'title' => $this->t('Approve'),
'url' => Url::fromRoute('knowledge.approve', ['knowledge' => $entity->id()]),
];
}
if (empty($links) && $this->currentUser->isAnonymous()) {
$links['knowledge-forbidden']['title'] = $this->knowledgeManager->forbiddenMessage($linked_entity, $entity->getFieldName());
}
}
// Add translations link for translation-enabled knowledge bundles.
if ($this->moduleHandler->moduleExists('content_translation') && $this->access($entity)->isAllowed()) {
$links['knowledge-translations'] = [
'title' => $this->t('Translate'),
'url' => $entity->toUrl('drupal:content-translation-overview'),
];
}
return [
'#theme' => 'links__knowledge__knowledge',
// The "entity" property is specified to be present, so no need to check.
'#links' => $links,
'#attributes' => ['class' => ['links', 'inline']],
];
}
/**
* Wraps content_translation_translate_access.
*/
protected function access(EntityInterface $entity) {
return content_translation_translate_access($entity);
}
/**
* {@inheritdoc}
*/
public static function trustedCallbacks() {
return ['renderLinks', 'renderForm', 'renderQualityForm'];
}
}
