breadcrumbs_visibility-8.x-1.x-dev/breadcrumbs_visibility.module
breadcrumbs_visibility.module
<?php
/**
* @file
* Contains breadcrumbs_visibility.module.
*/
use Drupal\block\Entity\Block;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
const BREADCRUMBS_VISIBILITY_PERMISSION = 'administer breadcrumbs visibility config';
/**
* Implements hook_help().
*/
function breadcrumbs_visibility_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the breadcrumbs_visibility module.
case 'help.page.breadcrumbs_visibility':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Regulate whether breadcrumbs display on a per-node basis. This provides a new checkbox each node form to "Display breadcrumbs," which, when unchecked, will suppress the display of breadcrumbs only on that node. This assumes that the content type is set to display breadcrumbs in admin/structure/block/manage/breadcrumbs.') . '</p>';
return $output;
default:
}
}
/**
* Implements hook_block_access().
*
* Suppress breadcrumb block display on a per-node setting basis.
*/
function breadcrumbs_visibility_block_access(Block $block, $operation, AccountInterface $account) {
// Only attempt to change visibility on 'breadcrumbs' block.
if ($block->getPluginId() == 'system_breadcrumb_block' && $operation == 'view') {
// This will not affect non node routes (e.g., views, taxonomy, etc.)
// Check first if we can retrieve the node revision.
$node = \Drupal::routeMatch()->getParameter('node_revision');
if (is_string($node)) {
// This conditional will be unnecessary after
// https://www.drupal.org/project/drupal/issues/2730631 .
$node = \Drupal::entityTypeManager()->getStorage('node')->loadRevision($node);
}
if (!$node instanceof NodeInterface) {
$node = \Drupal::routeMatch()->getParameter('node');
}
if ($node instanceof NodeInterface) {
if ($display_breadcrumbs = $node->get('display_breadcrumbs')) {
$display_breadcrumbs = $display_breadcrumbs->value;
// If node has no display_breadcrumbs value, get the content type value.
if ($display_breadcrumbs === NULL) {
$config = \Drupal::config('breadcrumbs_visibility.content_type.' . $node->bundle());
if ($config->get('display_breadcrumbs') !== NULL) {
$display_breadcrumbs = $config->get('display_breadcrumbs');
}
}
return AccessResult::forbiddenIf($display_breadcrumbs == "0")->addCacheableDependency($block);
}
}
}
// Defer access decision to other implementors,
// e.g., /admin/structure/block/manage/breadcrumbs.
return AccessResult::neutral();
}
/**
* Implements hook_entity_base_field_info().
*/
function breadcrumbs_visibility_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = [];
if ($entity_type->id() === 'node') {
$fields['display_breadcrumbs'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Display breadcrumbs'))
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setDisplayOptions('view', [
'region' => 'hidden',
])
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'weight' => 10,
])
->setDefaultValue(TRUE)
->setDisplayConfigurable('form', TRUE);
$account = \Drupal::currentUser();
$element_status = $account->hasPermission(BREADCRUMBS_VISIBILITY_PERMISSION) ? FALSE : TRUE;
$form['display_breadcrumbs']['widget']['#disabled'] = $element_status;
// Update description if user has no permission to change the field value.
if ($element_status) {
$form['display_breadcrumbs']['widget']['value']['#description'] = t('Your account does not have permission to set the breadcrumb visibility.');
}
}
return $fields;
}
/**
* Implements hook_form_BASE_ID_alter().
*
* Display the display breadcrumbs filed on the node edit form.
*
* @note: This won't work where you have Display Suite/REL enabled.
*/
function breadcrumbs_visibility_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (isset($form['display_breadcrumbs'])) {
// Add fieldset for Page display options.
$form['page_display_options'] = [
'#type' => 'details',
'#title' => t('Page display options'),
'#group' => 'advanced',
'#attributes' => [
'class' => ['node-form-page_display_options'],
],
'#attached' => [
'library' => ['node/drupal.node'],
],
'#weight' => 100,
'#optional' => TRUE,
];
$form['display_breadcrumbs']['#group'] = 'page_display_options';
$account = \Drupal::currentUser();
$access_denied = $account->hasPermission(BREADCRUMBS_VISIBILITY_PERMISSION) ? FALSE : TRUE;
$form['display_breadcrumbs']['widget']['#disabled'] = $access_denied;
// Update description if user has no permission to change the field value.
if ($access_denied) {
$form['display_breadcrumbs']['widget']['value']['#description'] = t('Your account does not have permission to set the breadcrumb visibility.');
}
$node = $form_state->getFormObject()->getEntity();
// If new node OR legacy node AND not a cloned node.
if (($node->isNew() || empty($node->get('display_breadcrumbs')->getValue())) && !isset($node->cloned_node)) {
$default_display = \Drupal::config('breadcrumbs_visibility.content_type.' . $node->bundle())->get('display_breadcrumbs');
if ($default_display !== NULL) {
$form['display_breadcrumbs']['widget']['value']['#default_value'] = $default_display;
}
}
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*
* Add a default breadcrumbs display checkbox to content type Edit form.
*/
function breadcrumbs_visibility_form_node_type_edit_form_alter(&$form, FormStateInterface $form_state) {
$node_type = $form_state->getBuildInfo()['callback_object']->getEntity();
$config = \Drupal::config('breadcrumbs_visibility.content_type.' . $node_type->id());
$display_breadcrumbs = 1;
if ($config->get('display_breadcrumbs') !== NULL) {
$display_breadcrumbs = $config->get('display_breadcrumbs');
}
if (!isset($form['page_display_options'])) {
$form['page_display_options'] = [
'#type' => 'details',
'#title' => 'Page display defaults',
'#group' => 'additional_settings',
];
}
$account = \Drupal::currentUser();
$access_denied = $account->hasPermission(BREADCRUMBS_VISIBILITY_PERMISSION) ? FALSE : TRUE;
$form['page_display_options']['display_breadcrumbs'] = [
'#type' => 'checkbox',
'#title' => 'Default to "Display breadcrumbs" on.',
'#disabled' => $access_denied,
'#default_value' => $display_breadcrumbs,
'#description' => 'This value can be overridden on a per-node basis.',
];
// Update description if user has no permission to change the field value.
if ($access_denied) {
$form['page_display_options']['display_breadcrumbs']['#description'] = t('Your account does not have permission to set the breadcrumb visibility.');
}
$form['actions']['submit']['#submit'][] = 'breadcrumbs_visibility_node_type_edit_form_submit';
}
/**
* Submit handler for node type forms.
*/
function breadcrumbs_visibility_node_type_edit_form_submit($form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$node_type = $form_state->getBuildInfo()['callback_object']->getEntity();
$config = \Drupal::service('config.factory')->getEditable('breadcrumbs_visibility.content_type.' . $node_type->id());
if (isset($values['display_breadcrumbs'])) {
$config->set('display_breadcrumbs', $values['display_breadcrumbs']);
$config->save();
}
}
/**
* Implements hook_clone_node_alter().
*
* Match display_breadcrumbs field value with original node when cloned.
*
* @see clone.api.php
*/
function breadcrumbs_visibility_clone_node_alter(&$node, $context) {
$node->cloned_node = TRUE;
}
