Skip to content
Snippets Groups Projects
Commit 35a60cac authored by Steve Wirt's avatar Steve Wirt
Browse files

Issue #3334959: Add fieldable documentation entity.

Add related CMdocument entity.  (incomplete #2)

Add intial CMdocument entity 3.  (incomplete)

Add intial CMdocument entity 4. caches clear.  (incomplete)

Fix field list tests.

Correct some errors on CMDocument to remove whitescreen.

Fix Document edit link
parent bcfb0783
No related branches found
No related tags found
No related merge requests found
Showing
with 1230 additions and 3 deletions
......@@ -8,14 +8,20 @@ entities that use them.
* [Help README.md](/admin/help/content_model_documentation)
* [Permissions](/admin/people/permissions/module/content_model_documentation)
* [Content Model Fields](/admin/reports/fields/content-model)
* [Content Model Documentation Settings](/admin/config/system/content_model_documentation)
* [Content Model Documents](/admin/structure/cm_document)
## Features
* [Content Model Fields View](/admin/reports/fields/content-model) -
A list of all fields used in the Drupal instance. Displaying labels,
description, entity types, bundles, and other information. This View, once
the module is installed, can be editied with Views UI to make add or remove
the module is installed, can be edited with Views UI to make add or remove
columns or filters.
* [Content Model Documentation Settings](/admin/config/system/content_model_documentation) -
The settings to control which entity types are documentable.
* [Content Model Documents list](/admin/structure/cm_document) -
The list of Content Model Documents.
## Dependencies
......
cm_document.settings:
type: config_object
label: 'CMDocument settings'
mapping:
show_on_admin:
type: 'integer'
label: 'Show on Administration Pages'
alert_styles:
type: 'string'
label: 'Available alert styles'
name: 'Content Model Documentation'
type: module
description: 'Adds admin displays for the site architecture and history.'
configure: content_model_documentation.content_model_documentation_admin_form
configure: entity.content_model_documentation.config_form
core_version_requirement: ^9.3 || ^10
package: 'Architecture'
dependencies:
......
<?php
// TODO Related to being already installed, then adding an entity type,
// this module can't be uninstalled because drupal is going to try to clean up
// the following tables that likely do not exist
// cm_document (must have columns of id and vid)
// cm_document_field_data any 1 nonsens column will do
// It may be necessary to see if they exist, and if they don't, add them.then re-install.
entity.content_model_documentation.add_form:
route_name: entity.cm_document.add_form
title: 'Add new Content Model Document'
appears_on:
- entity.cm_document.collection
entity.cm_document.collection:
title: 'Content Model Documents'
route_name: entity.cm_document.collection
description: 'List content model documents'
parent: system.admin_structure
weight: 5
entity.content_model_documentation.config_form:
title: 'Content Model Documentation'
route_name: entity.content_model_documentation.config_form
description: 'Manage settings for Content Model Documentation'
parent: system.admin_config_system
content_model_documentation.reports_fields:
title: 'Content Model'
description: 'Display settings for fields in the content model.'
......
content_model_documentation.settings_tab:
route_name: entity.cm_document.config_form
title: 'Settings'
base_route: entity.cm_document.config_form
entity.content_model_documentation.collection:
base_route: system.admin_content
route_name: entity.cm_document.collection
title: 'Content Model Documents'
entity.content_model_documentation.canonical:
route_name: entity.cm_document.canonical
base_route: entity.cm_document.canonical
title: 'View'
entity.content_model_documentation.edit_form:
route_name: entity.cm_document.edit_form
base_route: entity.cm_document.canonical
title: 'Edit'
entity.content_model_documentation.version_history:
route_name: entity.cm_document.version_history
base_route: entity.cm_document.canonical
title: 'Revisions'
entity.content_model_documentation.delete_form:
route_name: entity.cm_document.delete_form
base_route: entity.cm_document.canonical
title: Delete
weight: 10
......@@ -6,6 +6,7 @@
*/
use Drupal\Component\Utility\Html;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
/**
......@@ -55,3 +56,58 @@ function content_model_documentation_help($route_name, RouteMatchInterface $rout
}
return NULL;
}
/**
* Implements hook_theme().
*/
function content_model_documentation_theme() {
return [
'content_model_documentation' => [
'render element' => 'elements',
],
];
}
/**
* Prepares CMDocument variables for twig template.
*/
function template_preprocess_content_model_documentation(&$variables) {
/** @var \Drupal\content_model_documentation\Entity\ContentModelDocumentationInterface $content_model_documentation */
$content_model_documentation = $variables['elements']['#content_model_documentation'];
$variables['content_model_documentation'] = $content_model_documentation;
$variables['view_mode'] = $variables['elements']['#view_mode'];
$variables['label'] = $content_model_documentation->label();
$variables['id'] = $content_model_documentation->id();
$variables['uuid'] = $content_model_documentation->uuid();
$variables['style'] = $content_model_documentation->getStyle();
$variables['style_class'] = $content_model_documentation->getStyleClass();
$variables['attributes']['class'] = [
'sitewide-alert',
'alert',
$content_model_documentation->getStyleClass(),
];
// Helpful $content variable for template.
$variables['content'] = [];
foreach (Element::children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
}
/**
* Implements hook_theme_suggestions_HOOK().
*/
function content_model_documentation_theme_suggestions_content_model_documentation(array $variables) {
$suggestions = [];
/** @var \Drupal\content_model_documentation\Entity\ContentModelDocumentationInterface $content_model_documentation */
$content_model_documentation = $variables['elements']['#content_model_documentation'];
$suggestions[] = 'content_model_documentation__' . $content_model_documentation->getStyle();
return $suggestions;
}
administer content model documentation:
title: 'Administer Content Model Documentation module settings'
view content model documentation:
title: 'View content model documentation'
title: 'View content model documentation reports and Document entities'
description: 'Allows users with this permission to see content model displays
and documentation.'
administer content model document entities:
title: 'Administer Content Model Document entities'
description: 'Allow to access the administration form to configure Content Model Document entities.'
add content model document entities:
title: 'Create new Content Model Document entities'
delete content model document entities:
title: 'Delete Content Model Document entities'
edit content model document entities:
title: 'Edit Content Model Document entities'
view unpublished content model document entities:
title: 'View unpublished Content Model Document entities'
view all content model document revisions:
title: 'View all Content Model Document revisions'
manage all content model document revisions:
title: 'Manage all Content Model Document revisions'
description: 'Role requires permission <em>View all Content Model Document revisions</em> and <em>edit rights</em> for Content Model Document entities in question or <em>Administer Content Model Document entities</em>.'
entity.content_model_documentation.config_form:
path: '/admin/config/system/content_model_documentation'
defaults:
_form: '\Drupal\content_model_documentation\Form\ContentModelDocumentationConfigForm'
_title: 'Content Model Documentation Global Settings'
requirements:
_permission: 'administer content model documentation'
options:
_admin_route: TRUE
entity.content_model_documentation.canonical:
path: '/admin/structure/cm_document/{cm_document}'
defaults:
_entity_form: 'cm_document.edit'
options:
_admin_route: TRUE
requirements:
_entity_access: 'cm_document.update'
block_content: \d+
entity.content_model_documentation.edit_form:
path: '/admin/structure/cm_document/{cm_document}/edit'
defaults:
_entity_form: 'cm_document.edit'
options:
_admin_route: TRUE
requirements:
_entity_access: 'cm_document.update'
block_content: \d+
services:
content_model_documentation.cm_document_manager:
class: Drupal\content_model_documentation\CMDocumentManager
arguments: [ '@entity_type.manager', '@datetime.time' ]
content_model_documentation.documentation_renderer:
class: Drupal\content_model_documentation\CMDocumentRenderer
arguments: [ '@config.factory', '@router.admin_context', '@current_user' ]
<?php
declare(strict_types=1);
namespace Drupal\content_model_documentation;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
/**
* Access controller for the Sitewide Alert entity.
*
* @see \Drupal\content_model_documentation\Entity\CMDocument.
*/
class CMDocumentAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\content_model_documentation\Entity\CMDocumentInterface $entity */
switch ($operation) {
case 'view':
if (!$entity->isPublished()) {
return AccessResult::allowedIfHasPermission($account, 'view unpublished content model document entities');
}
return AccessResult::allowedIfHasPermission($account, 'view content model documentation');
case 'update':
return AccessResult::allowedIfHasPermission($account, 'edit content model document entities');
case 'delete':
return AccessResult::allowedIfHasPermission($account, 'delete content model document entities');
}
// Unknown operation, no opinion.
return AccessResult::neutral();
}
/**
* {@inheritdoc}
*/
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
return AccessResult::allowedIfHasPermission($account, 'add content model document entities');
}
}
<?php
namespace Drupal\content_model_documentation;
use Drupal\content_model_documentation\Form\CMDocumentRevisionDeleteForm;
use Drupal\content_model_documentation\Form\CMDocumentRevisionRevertTranslationForm;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
use Symfony\Component\Routing\Route;
/**
* Provides routes for CMDocument entities.
*
* @see \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider
* @see \Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider
*/
class CMDocumentHtmlRouteProvider extends AdminHtmlRouteProvider {
/**
* {@inheritdoc}
*/
public function getRoutes(EntityTypeInterface $entity_type) {
$collection = parent::getRoutes($entity_type);
$entity_type_id = $entity_type->id();
if ($history_route = $this->getHistoryRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.version_history", $history_route);
}
if ($revision_route = $this->getRevisionRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.revision", $revision_route);
}
if ($revert_route = $this->getRevisionRevertRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.revision_revert", $revert_route);
}
if ($delete_route = $this->getRevisionDeleteRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.revision_delete", $delete_route);
}
if ($translation_route = $this->getRevisionTranslationRevertRoute($entity_type)) {
$collection->add("{$entity_type_id}.revision_revert_translation_confirm", $translation_route);
}
if ($settings_form_route = $this->getSettingsFormRoute($entity_type)) {
$collection->add("$entity_type_id.settings", $settings_form_route);
}
return $collection;
}
/**
* Gets the version history route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getHistoryRoute(EntityTypeInterface $entity_type): ?Route {
if ($entity_type->hasLinkTemplate('version-history')) {
$route = new Route($entity_type->getLinkTemplate('version-history'));
$route
->setDefaults([
'_title' => "{$entity_type->getLabel()} revisions",
'_controller' => '\Drupal\content_model_documentation\Controller\ContentModelDocumentController::revisionOverview',
])
->setRequirement('_permission', 'view all content model document revisions')
->setOption('_admin_route', TRUE);
return $route;
}
return NULL;
}
/**
* Gets the revision route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionRoute(EntityTypeInterface $entity_type): ?Route {
if ($entity_type->hasLinkTemplate('revision')) {
$route = new Route($entity_type->getLinkTemplate('revision'));
$route
->setDefaults([
'_controller' => '\Drupal\content_model_documentation\Controller\ContentModelDocumentController::revisionShow',
'_title_callback' => '\Drupal\content_model_documentation\Controller\ContentModelDocumentController::revisionPageTitle',
])
->setRequirement('_permission', 'view all content model document revisions')
->setOption('_admin_route', TRUE);
return $route;
}
return NULL;
}
/**
* Gets the revision revert route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionRevertRoute(EntityTypeInterface $entity_type): ?Route {
if ($entity_type->hasLinkTemplate('revision_revert')) {
$route = new Route($entity_type->getLinkTemplate('revision_revert'));
$route
->setDefaults([
'_form' => '\Drupal\content_model_document\Form\CMDocumentRevisionRevertForm',
'_title' => 'Revert to earlier revision',
])
->setRequirement('_permission', 'manage all content model document revisions')
->setOption('_admin_route', TRUE);
return $route;
}
return NULL;
}
/**
* Gets the revision delete route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionDeleteRoute(EntityTypeInterface $entity_type): ?Route {
if ($entity_type->hasLinkTemplate('revision_delete')) {
$route = new Route($entity_type->getLinkTemplate('revision_delete'));
$route
->setDefaults([
'_form' => CMDocumentRevisionDeleteForm::class,
'_title' => 'Delete earlier revision',
])
->setRequirement('_permission', 'manage all content model document revisions')
->setOption('_admin_route', TRUE);
return $route;
}
return NULL;
}
/**
* Gets the revision translation revert route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionTranslationRevertRoute(EntityTypeInterface $entity_type): ?Route {
if ($entity_type->hasLinkTemplate('translation_revert')) {
$route = new Route($entity_type->getLinkTemplate('translation_revert'));
$route
->setDefaults([
'_form' => CMDocumentRevisionRevertTranslationForm::class,
'_title' => 'Revert to earlier revision of a translation',
])
->setRequirement('_permission', 'manage all content model document revisions')
->setOption('_admin_route', TRUE);
return $route;
}
return NULL;
}
/**
* Gets the settings form route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getSettingsFormRoute(EntityTypeInterface $entity_type): ?Route {
if (!$entity_type->getBundleEntityType()) {
$route = new Route("/admin/structure/{$entity_type->id()}/settings");
$route
->setDefaults([
'_form' => 'Drupal\content_model_documentation\Form\CMDocumentSettingsForm',
'_title' => "{$entity_type->getLabel()} settings",
])
->setRequirement('_permission', $entity_type->getAdminPermission())
->setOption('_admin_route', TRUE);
return $route;
}
return NULL;
}
}
<?php
namespace Drupal\content_model_documentation;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityListBuilder;
use Drupal\Core\Link;
/**
* Defines a class to build a listing of CMDocument entities.
*
* @ingroup cm_document
*/
class CMDocumentListBuilder extends EntityListBuilder {
/**
* {@inheritdoc}
*/
public function buildHeader(): array {
$header['name'] = $this->t('Name');
$header['style'] = $this->t('Style');
$header['published'] = $this->t('Published');
return $header + parent::buildHeader();
}
/**
* {@inheritdoc}
*/
public function buildRow(EntityInterface $entity): array {
/** @var \Drupal\content_model_documentation\Entity\CMDocument $entity */
$row['name'] = Link::createFromRoute(
$entity->label(),
'entity.cm_document.canonical',
['cm_document' => $entity->id()]
);
$row['active'] = $entity->isPublished() ? '✔' : '✘';
return $row + parent::buildRow($entity);
}
}
<?php
declare(strict_types=1);
namespace Drupal\content_model_documentation;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Manager for working with content model document entities.
*/
class CMDocumentManager {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* Time of current request.
*
* @var \DateTimeInterface
*/
private $requestDateTime;
/**
* Constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time service.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, TimeInterface $time) {
$this->entityTypeManager = $entityTypeManager;
$this->time = $time;
}
/**
* Returns all active Content Model Documents.
*
* @return \Drupal\content_model_documentation\Entity\SitewideAlertInterface[]
* Array of active Content Model Documents indexed by their ids.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function getCmDocuments(): array {
/** @var \Drupal\content_model_documentation\Entity\SitewideAlertInterface[] $cmDocuments */
// TODO this probably is not needed and should be handled with a View.
$cmDocuments = $this->entityTypeManager
->getStorage('cm_document')
->loadByProperties(['status' => 1]);
return $cmDocuments;
}
}
<?php
namespace Drupal\content_model_documentation;
use Drupal\Core\Entity\ContentEntityStorageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\content_model_documentation\Entity\CMDocumentInterface;
/**
* Defines the storage handler class for CMDocument entities.
*
* This extends the base storage class, adding required special handling for
* CMDocument entities.
*
* @ingroup cm_document
*/
interface CMDocumentStorageInterface extends ContentEntityStorageInterface {
/**
* Gets a list of CMDocument revision IDs for a specific CMDocument.
*
* @param \Drupal\content_model_documentation\Entity\CMDocumentInterface $entity
* The Content Model Document entity.
*
* @return int[]
* Content Model Document revision IDs (in ascending order).
*/
public function revisionIds(CMDocumentInterface $entity);
/**
* Gets a list of revision IDs having a given user as CMDocument author.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user entity.
*
* @return int[]
* CMDocument revision IDs (in ascending order).
*/
public function userRevisionIds(AccountInterface $account);
/**
* Counts the number of revisions in the default language.
*
* @param \Drupal\content_model_documentation\Entity\CMDocumentInterface $entity
* The CMDocument entity.
*
* @return int
* The number of revisions in the default language.
*/
public function countDefaultLanguageRevisions(CMDocumentInterface $entity);
/**
* Unsets the language for all CMDocuments with the given language.
*
* @param \Drupal\Core\Language\LanguageInterface $language
* The language object.
*/
public function clearRevisionsLanguage(LanguageInterface $language);
}
<?php
namespace Drupal\content_model_documentation\Controller;
use Drupal\Component\Utility\Xss;
use Drupal\content_model_documentation\Entity\CMDocumentInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Class ContentModelDocumentController.
*
* Returns responses for Content Model Document routes.
*/
class ContentModelDocumentController extends ControllerBase implements ContainerInjectionInterface {
/**
* The renderer.
*
* @var \Drupal\Core\Render\Renderer
*/
protected $renderer;
/**
* Constructs a new ContentModelDocumentationController.
*
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
*/
public function __construct(DateFormatterInterface $date_formatter, RendererInterface $renderer) {
$this->dateFormatter = $date_formatter;
$this->renderer = $renderer;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): ContentModelDocumentController {
return new static(
$container->get('date.formatter'),
$container->get('renderer')
);
}
/**
* Displays a CMDocument revision.
*
* @param int $cm_document_revision
* The CMDocument revision ID.
*
* @return array
* An array suitable for drupal_render().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function revisionShow(int $cm_document_revision): array {
$cm_document = $this->entityTypeManager()->getStorage('cm_document')
->loadRevision($cm_document_revision);
return $this
->entityTypeManager()
->getViewBuilder('cm_document')
->view($cm_document);
}
/**
* Page title callback for a CMDocument revision.
*
* @param int $cm_document_revision
* The CMDocument revision ID.
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup
* The page title.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function revisionPageTitle(int $cm_document_revision): TranslatableMarkup {
$cm_document = $this->entityTypeManager()->getStorage('cm_document')
->loadRevision($cm_document_revision);
return $this->t('Revision of %title from %date', [
'%title' => $cm_document->label(),
'%date' => $this->dateFormatter->format($cm_document->getRevisionCreationTime()),
]);
}
/**
* Generates an overview table of older revisions of a CMDocument.
*
* @param \Drupal\content_model_documentation\Entity\CMDocumentInterface $cm_document
* A CMDocument object.
*
* @return array
* An array as expected by drupal_render().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
public function revisionOverview(CMDocumentInterface $cm_document): array {
$account = $this->currentUser();
$cm_document_storage = $this->entityTypeManager()->getStorage('cm_document');
$langcode = $cm_document->language()->getId();
$langname = $cm_document->language()->getName();
$languages = $cm_document->getTranslationLanguages();
$has_translations = (count($languages) > 1);
$build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $cm_document->label()]) : $this->t('Revisions for %title', ['%title' => $cm_document->label()]);
$header = [$this->t('Revision'), $this->t('Operations')];
$revert_permission = (($account->hasPermission("revert all content model document revisions") || $account->hasPermission('administer content model document entities')));
$delete_permission = (($account->hasPermission("delete all content model document revisions") || $account->hasPermission('administer content model document entities')));
$rows = [];
$vids = array_column($cm_document_storage->getAggregateQuery()
->allRevisions()
->condition('id', $cm_document->id())
->groupBy('vid')
->accessCheck(TRUE)
->execute(), 'vid');
$latest_revision = TRUE;
foreach (array_reverse($vids) as $vid) {
/** @var \Drupal\content_model_documentation\Entity\CMDocumentInterface $revision */
$revision = $cm_document_storage->loadRevision($vid);
// Only show revisions that are affected by the language that is being
// displayed.
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
$username = [
'#theme' => 'username',
'#account' => $revision->getRevisionUser(),
];
$row = [];
$column = [
'data' => [
'#type' => 'inline_template',
'#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
'#context' => [
'date' => Link::fromTextAndUrl(
$this->dateFormatter->format($revision->getRevisionCreationTime(), 'short'),
new Url('entity.cm_document.revision', [
'cm_document' => $cm_document->id(),
'cm_document_revision' => $vid,
])
)->toString(),
'username' => $this->renderer->renderPlain($username),
'message' => [
'#markup' => $revision->getRevisionLogMessage(),
'#allowed_tags' => Xss::getHtmlTagList(),
],
],
],
];
$row[] = $column;
if ($latest_revision) {
$row[] = [
'data' => [
'#prefix' => '<em>',
'#markup' => $this->t('Current revision'),
'#suffix' => '</em>',
],
];
foreach ($row as &$current) {
$current['class'] = ['revision-current'];
}
unset($current);
$latest_revision = FALSE;
}
else {
$links = [];
if ($revert_permission) {
$links['revert'] = [
'title' => $this->t('Revert'),
'url' => $has_translations ?
Url::fromRoute('entity.cm_document.translation_revert', [
'cm_document' => $cm_document->id(),
'cm_document_revision' => $vid,
'langcode' => $langcode,
]) :
Url::fromRoute('entity.cm_document.revision_revert', [
'cm_document' => $cm_document->id(),
'cm_document' => $vid,
]),
];
}
if ($delete_permission) {
$links['delete'] = [
'title' => $this->t('Delete'),
'url' => Url::fromRoute('entity.cm_document.revision_delete', [
'cm_document' => $cm_document->id(),
'cm_document_revision' => $vid,
]),
];
}
$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
}
$rows[] = $row;
}
}
$build['cm_document_revisions_table'] = [
'#theme' => 'table',
'#rows' => $rows,
'#header' => $header,
];
return $build;
}
}
<?php
declare(strict_types=1);
namespace Drupal\content_model_documentation\Entity;
use Drupal\Component\Utility\Html;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EditorialContentEntityBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\RevisionableInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\user\UserInterface;
/**
* Defines the Content Model Document entity.
*
* @ingroup cm_document
*
* @ContentEntityType(
* id = "cm_document",
* label = @Translation("Content Model Document"),
* label_plural = @Translation("Content Model Documents"),
* label_collection = @Translation("Content Model Document"),
* handlers = {
* "storage" = "\Drupal\Core\Entity\Sql\SqlContentEntityStorage",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "list_builder" = "Drupal\content_model_documentation\CMDocumentListBuilder",
* "views_data" = "Drupal\content_model_documentation\Entity\CMDocumentViewsData",
* "form" = {
* "default" = "Drupal\content_model_documentation\Form\CMDocumentForm",
* "add" = "Drupal\content_model_documentation\Form\CMDocumentForm",
* "edit" = "Drupal\content_model_documentation\Form\CMDocumentForm",
* "delete" = "Drupal\content_model_documentation\Form\CMDocumentDeleteForm",
* },
* "route_provider" = {
* "html" = "Drupal\content_model_documentation\CMDocumentHtmlRouteProvider",
* },
* "access" = "Drupal\content_model_documentation\CMDocumentAccessControlHandler",
* },
* base_table = "cm_document",
* data_table = "cm_document_field_data",
* revision_table = "cm_document_revision",
* revision_data_table = "cm_document_field_revision",
* show_revision_ui = TRUE,
* translatable = FALSE,
* admin_permission = "administer content model document entities",
* entity_keys = {
* "id" = "id",
* "revision" = "vid",
* "label" = "name",
* "uuid" = "uuid",
* "uid" = "user_id",
* "langcode" = "langcode",
* "published" = "status",
* },
* revision_metadata_keys = {
* "revision_user" = "revision_user",
* "revision_created" = "revision_created",
* "revision_log_message" = "revision_log_message",
* },
* links = {
* "canonical" = "/admin/structure/cm_document/{cm_document}",
* "add-form" = "/admin/structure/cm_document/add",
* "edit-form" = "/admin/structure/cm_document/{cm_document}/edit",
* "delete-form" = "/admin/structure/cm_document/{cm_document}/delete",
* "version-history" = "/admin/structure/cm_document/{cm_document}/revisions",
* "revision" = "/admin/structure/cm_document/{cm_document}/revisions/{cm_document_revision}/view",
* "revision_revert" = "/admin/structure/cm_document/{cm_document}/revisions/{cm_document_revision}/revert",
* "revision_delete" = "/admin/structure/cm_document/{cm_document}/revisions/{cm_document_revision}/delete",
* "collection" = "/admin/structure/cm_document",
* },
* field_ui_base_route = "entity.cm_document.config_form",
* constraints = {
* }
* )
*/
class CMDocument extends EditorialContentEntityBase implements CMDocumentInterface {
/**
* {@inheritdoc}
*/
public static function preCreate(EntityStorageInterface $storage, array &$values): void {
parent::preCreate($storage, $values);
$values += [
'user_id' => \Drupal::currentUser()->id(),
];
}
/**
* {@inheritdoc}
*/
protected function urlRouteParameters($rel): array {
$uri_route_parameters = parent::urlRouteParameters($rel);
if ($rel === 'revision_revert' && $this instanceof RevisionableInterface) {
$uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
}
elseif ($rel === 'revision_delete' && $this instanceof RevisionableInterface) {
$uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
}
return $uri_route_parameters;
}
/**
* {@inheritdoc}
*/
public function preSave(EntityStorageInterface $storage): void {
parent::preSave($storage);
// If no revision author has been set explicitly,
// make the sitewide_alert owner the revision author.
if (!$this->getRevisionUser()) {
$this->setRevisionUserId($this->getOwnerId());
}
}
/**
* {@inheritdoc}
*/
public function getName(): string {
return $this->get('name')->value;
}
/**
* {@inheritdoc}
*/
public function setName(string $name): CMDocumentInterface {
$this->set('name', $name);
return $this;
}
/**
* {@inheritdoc}
*/
public function getCreatedTime(): int {
return $this->get('created')->value;
}
/**
* {@inheritdoc}
*/
public function setCreatedTime(int $timestamp): CMDocumentInterface {
$this->set('created', $timestamp);
return $this;
}
/**
* {@inheritdoc}
*/
public function getOwner() {
return $this->get('user_id')->entity;
}
/**
* {@inheritdoc}
*/
public function getOwnerId() {
return $this->get('user_id')->target_id;
}
/**
* {@inheritdoc}
*/
public function setOwnerId($uid) {
$this->set('user_id', $uid);
return $this;
}
/**
* {@inheritdoc}
*/
public function setOwner(UserInterface $account) {
$this->set('user_id', $account->id());
return $this;
}
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type): array {
$fields = parent::baseFieldDefinitions($entity_type);
$fields['user_id'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
->setDescription(t('The user ID of author of this Content Model Document.'))
->setRevisionable(TRUE)
->setSetting('target_type', 'user')
->setSetting('handler', 'default')
->setTranslatable(FALSE)
->setDisplayOptions('form', [
'region' => 'hidden',
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'autocomplete_type' => 'tags',
'placeholder' => '',
],
])
->setDisplayOptions('view', [
'region' => 'hidden',
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', FALSE);
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t('A brief description of this Content Model Document. Used for administrative reference only.'))
->setRevisionable(TRUE)
->setSettings([
'max_length' => 50,
'text_processing' => 0,
])
->setDefaultValue('')
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -15,
])
->setDisplayOptions('view', [
'region' => 'hidden',
])
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', FALSE)
->setRequired(TRUE);
$fields['status']
->setLabel(new TranslatableMarkup('Published'))
->setDescription(t('If selected this Content Model Document will show.'))
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'weight' => -1,
]);
$fields['entity'] = BaseFieldDefinition::create('list_string') //or maybe 'entity_reference'
->setLabel(new TranslatableMarkup('Documentation for'))
->setDescription(new TranslatableMarkup('Choose the entity or field that this document applies to.'))
->setSettings([
"smmething" => 'something',
// TODO figure out why this crashes node add. Says it can't be found.
// 'allowed_values_function' => '\Drupal\content_model_documentation\EntityProvider::getDocumentableEntities',
])
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => -14,
])
->setDisplayOptions('view', [
'region' => 'hidden',
])
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', FALSE)
->setRequired(FALSE);
$fields['message'] = BaseFieldDefinition::create('text_long')
->setLabel(t('Notes'))
->setDescription(new TranslatableMarkup("Add freeform notes about the entity."))
->setTranslatable(FALSE)
->setRevisionable(TRUE)
->setDefaultValue('')
->setDisplayOptions('form', [
'type' => 'text_textarea',
'weight' => -13,
'settings' => [
'rows' => 4,
],
])
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'text_default',
'weight' => 0,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE)
->setRequired(FALSE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the Document was created.'));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the Document was last edited.'));
$fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Revision translation affected'))
->setDescription(t('Indicates if the last edit of a translation belongs to current revision.'))
->setReadOnly(TRUE)
->setRevisionable(TRUE)
->setTranslatable(FALSE);
return $fields;
}
}
<?php
namespace Drupal\content_model_documentation\Entity;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\RevisionLogInterface;
use Drupal\user\EntityOwnerInterface;
/**
* Provides an interface for defining Content Model Document entities.
*
* @ingroup cm_document
*/
interface CMDocumentInterface extends ContentEntityInterface, RevisionLogInterface, EntityChangedInterface, EntityPublishedInterface, EntityOwnerInterface {
/**
* Gets the CMDocument name.
*
* @return string
* Name of the CMDocument.
*/
public function getName(): string;
/**
* Sets the CMDocument name.
*
* @param string $name
* The CMDocument name.
*
* @return \Drupal\content_model_documentation\Entity\CMDocumentInterface
* The called CMDocument entity.
*/
public function setName(string $name): CMDocumentInterface;
/**
* Gets the CMDocument creation timestamp.
*
* @return int
* Creation timestamp of the CMDocument.
*/
public function getCreatedTime();
/**
* Sets the CMDocument creation timestamp.
*
* @param int $timestamp
* The CMDocument creation timestamp.
*
* @return \Drupal\content_model_documentation\Entity\CMDocumentInterface
* The called CMDocument entity.
*/
public function setCreatedTime(int $timestamp): CMDocumentInterface;
}
<?php
declare(strict_types=1);
namespace Drupal\content_model_documentation\Entity;
use Drupal\views\EntityViewsData;
/**
* Provides Views data for CMDocument entities.
*/
class CMDocumentViewsData extends EntityViewsData {
/**
* {@inheritdoc}
*/
public function getViewsData(): array {
$data = parent::getViewsData();
// This entire class might not be needed.
return $data;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment