knowledge-8.x-1.x-dev/src/Entity/Knowledge.php
src/Entity/Knowledge.php
<?php
namespace Drupal\knowledge\Entity;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\EntityPublishedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\RevisionableContentEntityBase;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\knowledge\KnowledgeInterface;
use Drupal\user\Entity\User;
use Drupal\user\EntityOwnerTrait;
/**
* Defines the knowledge entity class.
*
* @ContentEntityType(
* id = "knowledge",
* label = @Translation("Knowledge"),
* label_singular = @Translation("knowledge"),
* label_plural = @Translation("knowledge"),
* label_count = @PluralTranslation(
* singular = "@count knowledge",
* plural = "@count knowledge",
* ),
* bundle_label = @Translation("Knowledge type"),
* handlers = {
* "storage" = "Drupal\knowledge\KnowledgeStorage",
* "storage_schema" = "Drupal\knowledge\KnowledgeStorageSchema",
* "access" = "Drupal\knowledge\KnowledgeAccessControlHandler",
* "list_builder" = "Drupal\Core\Entity\EntityListBuilder",
* "view_builder" = "Drupal\knowledge\KnowledgeViewBuilder",
* "views_data" = "Drupal\knowledge\KnowledgeViewsData",
* "form" = {
* "default" = "Drupal\knowledge\KnowledgeForm",
* "delete" = "Drupal\knowledge\Form\DeleteForm",
* "unlink" = "Drupal\knowledge\Form\UnlinkForm",
* },
* },
* base_table = "knowledge",
* revision_table = "knowledge_revision",
* uri_callback = "knowledge_uri",
* translatable = FALSE,
* entity_keys = {
* "id" = "kid",
* "revision" = "revision_id",
* "bundle" = "knowledge_type",
* "uuid" = "uuid",
* "published" = "status",
* "owner" = "uid",
* },
* revision_metadata_keys = {
* "revision_default" = "revision_default",
* "revision_user" = "revision_user",
* "revision_created" = "revision_created",
* "revision_log_message" = "revision_log_message",
* },
* links = {
* "canonical" = "/knowledge/{knowledge}",
* "delete-form" = "/knowledge/{knowledge}/delete",
* "delete-multiple-form" = "/admin/content/knowledge/delete",
* "edit-form" = "/knowledge/{knowledge}/edit",
* "create" = "/knowledge",
* "unlink-form" = "/knowledge/{knowledge}/unlink",
* },
* bundle_entity_type = "knowledge_type",
* field_ui_base_route = "entity.knowledge_type.edit_form",
* )
*/
class Knowledge extends RevisionableContentEntityBase implements EntityPublishedInterface, KnowledgeInterface {
use EntityChangedTrait;
use EntityOwnerTrait;
use EntityPublishedTrait;
/**
* {@inheritdoc}
*/
public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage);
$entity = $this->getKnowledgeedEntity();
$citation = $entity->getOwnerId() != $this->getOwnerId();
$this->set('citation', (int) $citation);
$entity_revision = $entity->getRevisionId();
$this->set('entity_revision', $entity_revision);
}
/**
* {@inheritdoc}
*/
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
// Always invalidate the cache tag for the linked entity.
if ($linked_entity = $this->getKnowledgeedEntity()) {
Cache::invalidateTags($linked_entity->getCacheTagsToInvalidate());
}
// Update the {knowledge_entity_statistics} table prior to executing
// the hook.
\Drupal::service('knowledge.statistics')->update($this);
if ($this->original) {
$entity_id = $this->getKnowledgeedEntityId();
$entity_type = $this->getKnowledgeedEntityTypeId();
$field_name = $this->getFieldName();
$original_id = $this->original->getKnowledgeedEntityId();
$original_type = $this->original->getKnowledgeedEntityTypeId();
$original_field_name = $this->original->getFieldName();
$diff_id = $entity_id != $original_id;
$diff_type = $entity_type != $original_type;
$diff_field = $field_name != $original_field_name;
$diff = $diff_id || $diff_type || $diff_field;
if ($diff) {
\Drupal::service('knowledge.statistics')->update($this->original);
}
}
}
/**
* {@inheritdoc}
*/
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
foreach ($entities as $entity) {
\Drupal::service('knowledge.statistics')->update($entity);
}
}
/**
* {@inheritdoc}
*/
public function referencedEntities() {
$referenced_entities = parent::referencedEntities();
if ($this->getKnowledgeedEntityId()) {
$referenced_entities[] = $this->getKnowledgeedEntity();
}
return $referenced_entities;
}
/**
* {@inheritdoc}
*/
public function permalink() {
$uri = $this->toUrl();
$uri->setOption('fragment', 'knowledge-' . $this->id());
return $uri;
}
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
$fields = parent::baseFieldDefinitions($entity_type);
$fields += static::publishedBaseFieldDefinitions($entity_type);
$fields += static::ownerBaseFieldDefinitions($entity_type);
$fields['kid']->setLabel(t('Knowledge ID'))
->setDescription(t('The knowledge ID.'));
$fields['uuid']->setDescription(t('The knowledge UUID.'));
$fields['knowledge_type']->setLabel(t('Knowledge Type'))
->setDescription(t('The knowledge type.'));
// Set the default value callback for the status field.
$fields['status']->setDefaultValueCallback('Drupal\knowledge\Entity\Knowledge::getDefaultStatus');
$fields['uid']
->setDescription(t('The user ID of the knowledge author.'));
$fields['field_name'] = BaseFieldDefinition::create('string')
->setLabel(t('Knowledge field name'))
->setRequired(TRUE)
->setDescription(t('The field name through which this knowledge was added.'))
->setSetting('is_ascii', TRUE)
->setSetting('max_length', FieldStorageConfig::NAME_MAX_LENGTH);
$fields['entity_type'] = BaseFieldDefinition::create('string')
->setLabel(t('Entity type'))
->setRequired(TRUE)
->setDescription(t('The entity type to which this knowledge is attached.'))
->setSetting('is_ascii', TRUE)
->setSetting('max_length', EntityTypeInterface::ID_MAX_LENGTH)
->setRevisionable(TRUE);
$fields['entity_id'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Entity ID'))
->setDescription(t('The ID of the entity of which this knowledge is a reply.'))
->setRequired(TRUE)
->setRevisionable(TRUE);
$fields['entity_revision'] = BaseFieldDefinition::create('integer')
->setLabel(t('Entity Revision'))
->setDescription(t('The ID of the entity of which this knowledge is a reply.'))
->setRevisionable(TRUE)
->setSetting('unsigned', TRUE);
$fields['incident_type'] = BaseFieldDefinition::create('string')
->setLabel(t('Incident type'))
->setRequired(TRUE)
->setDescription(t('The entity type to which this knowledge is attached.'))
->setSetting('is_ascii', TRUE)
->setSetting('max_length', EntityTypeInterface::ID_MAX_LENGTH)
->setReadOnly(TRUE);
$fields['incident_id'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Incident Id'))
->setDescription(t('The ID of the support case.'))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE)
->setReadOnly(TRUE)
->setRequired(TRUE);
$fields['citation'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Citation'))
->setDescription(t("The owner linked to another's articled."))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE)
->setRequired(TRUE)
->setRevisionable(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the knowledge was created.'));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the knowledge was last edited.'));
return $fields;
}
/**
* {@inheritdoc}
*/
public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
if ($knowledge_type = KnowledgeType::load($bundle)) {
/** @var \Drupal\Core\Field\BaseFieldDefinition $base_field_definitions['entity_id'] */
$fields['entity_id'] = clone $base_field_definitions['entity_id'];
$fields['entity_id']->setSetting('target_type', $knowledge_type->getTargetEntityTypeId());
/** @var \Drupal\Core\Field\BaseFieldDefinition $base_field_definitions['incident_id'] */
$fields['incident_id'] = clone $base_field_definitions['incident_id'];
$fields['incident_id']->setSetting('target_type', $knowledge_type->getIncidentEntityTypeId());
return $fields;
}
return [];
}
/**
* {@inheritdoc}
*/
public function getKnowledgeedEntity() {
return $this->get('entity_id')->entity;
}
/**
* {@inheritdoc}
*/
public function getKnowledgeedEntityId() {
return $this->get('entity_id')->target_id;
}
/**
* {@inheritdoc}
*/
public function getKnowledgeedEntityTypeId() {
return $this->get('entity_type')->value;
}
/**
* {@inheritdoc}
*/
public function getIncidentEntity() {
return $this->get('incident_id')->entity;
}
/**
* {@inheritdoc}
*/
public function getIncidentEntityId() {
return $this->get('incident_id')->target_id;
}
/**
* {@inheritdoc}
*/
public function getIncidentEntityTypeId() {
return $this->get('incident_type')->value;
}
/**
* {@inheritdoc}
*/
public function setFieldName($field_name) {
$this->set('field_name', $field_name);
return $this;
}
/**
* {@inheritdoc}
*/
public function getFieldName() {
return $this->get('field_name')->value;
}
/**
* {@inheritdoc}
*/
public function getSubject() {
return $this->getIncidentEntity()->label() ?? '(No incident)';
}
/**
* {@inheritdoc}
*/
public function setSubject($subject) {
$this->set('subject', $subject);
return $this;
}
/**
* {@inheritdoc}
*/
public function getAuthorName() {
// If their is a valid user id and the user entity exists return the label.
if ($this->get('uid')->target_id && $this->get('uid')->entity) {
return $this->get('uid')->entity->label();
}
return $this->get('name')->value ?: \Drupal::config('user.settings')->get('anonymous');
}
/**
* {@inheritdoc}
*/
public function getCreatedTime() {
if (isset($this->get('created')->value)) {
return $this->get('created')->value;
}
return NULL;
}
/**
* {@inheritdoc}
*/
public function setCreatedTime($created) {
$this->set('created', $created);
return $this;
}
/**
* {@inheritdoc}
*/
public function getThread() {
$thread = $this->get('thread');
if (!empty($thread->value)) {
return $thread->value;
}
}
/**
* {@inheritdoc}
*/
public function setThread($thread) {
$this->set('thread', $thread);
return $this;
}
/**
* {@inheritdoc}
*/
public static function preCreate(EntityStorageInterface $storage, array &$values) {
if (empty($values['knowledge_type']) && !empty($values['field_name']) && !empty($values['entity_type'])) {
$fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($values['entity_type']);
$values['knowledge_type'] = $fields[$values['field_name']]->getSetting('knowledge_type');
}
}
/**
* {@inheritdoc}
*/
public function getOwner() {
/** @var \Drupal\user\UserInterface $user */
$user = $this->get('uid')->entity;
if (!$user || $user->isAnonymous()) {
$user = User::getAnonymousUser();
$user->name = $this->getAuthorName();
}
return $user;
}
/**
* Get the knowledge type ID for this knowledge.
*
* @return string
* The ID of the knowledge type.
*/
public function getTypeId() {
return $this->bundle();
}
/**
* Default value callback for 'status' base field definition.
*
* @see ::baseFieldDefinitions()
*
* @return bool
* TRUE if the knowledge should be published, FALSE otherwise.
*/
public static function getDefaultStatus() {
return \Drupal::currentUser()->hasPermission('skip knowledge approval') ? KnowledgeInterface::PUBLISHED : KnowledgeInterface::NOT_PUBLISHED;
}
}
