onlyone-8.x-1.x-dev/onlyone.module

onlyone.module
<?php

/**
 * @file
 * Contains onlyone.module.
 */

use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\Markup;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * Implements hook_help().
 */
function onlyone_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    // Main module help.
    case 'help.page.onlyone':

      // The route onlyone.add_page exists or not?
      if (\Drupal::service('config.factory')->get('onlyone.settings')->get('onlyone_new_menu_entry')) {
        // Creating the link.
        $onlyone_add_page_link = Link::fromTextAndUrl(t('Add content (Only One)'), Url::fromRoute('onlyone.add_page'))->toString();
        $onlyone_add_page = t('@link page', ['@link' => $onlyone_add_page_link]);
      }
      else {
        // As the route doesn't exists we use a string.
        $onlyone_add_page = t('<em>Add content (Only One)</em> page (onlyone/add)');
      }

      // Array with routes to replace.
      $routes = [
        ':settings-page' => Url::fromRoute('onlyone.admin_settings')->toString(),
        ':content' => Url::fromRoute('system.admin_content')->toString(),
        '@onlyone_add_page' => $onlyone_add_page,
        ':add-content' => Url::fromRoute('node.add_page')->toString(),
      ];

      // Getting the help link for the admin_toolbar module.
      $admin_toolbar_page = \Drupal::service('onlyone.module_handler')->getModuleHelpPageLink('admin_toolbar', 'Admin Toolbar', TRUE);
      // Getting the help link for the admin_toolbar_tools module.
      $admin_toolbar_tools_page = \Drupal::service('onlyone.module_handler')->getModuleHelpPageLink('admin_toolbar_tools', 'Admin Toolbar Extra Tools', TRUE);
      // Getting the help link for the onlyone_admin_toolbar module.
      $onlyone_admin_toolbar = \Drupal::service('onlyone.module_handler')->getModuleHelpPageLink('onlyone_admin_toolbar', 'Allow a content type only once (Only One) for Admin Toolbar');

      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('The Allow a content type only once (Only One) module allows the creation of Only One content per language in the selected content types for this configuration.') . '</p>';
      $output .= '<h3>' . t('Uses') . '</h3>';
      $output .= '<dl>';
      $output .= '<dt>' . t('Configuring content types') . '</dt>';
      $output .= '<dd>' . t('To configure the content types to allow for Only One content per language, visit the <a href=":config-page">Only One</a> page, in the <em>Available content types for Only One</em> section and <em>check</em> the content types that should have Only One content per language. For this you need the <em>Administer Only One</em> permission.', [':config-page' => Url::fromRoute('onlyone.config_content_types')->toString()]) . '</dd>';
      $output .= '<dt>' . t('Configuring module settings') . '</dt>';
      $output .= '<dd>' . t('To configure the module settings visit the <a href=":settings-page">Settings</a> page, if you want to have the configured content types in a new menu entry named <em>Add content (Only One)</em> you must check the option <em>Show configured content types in a new menu entry</em>, the new menu link will be available in the <a href=":content">Content</a> page as an action link to the @onlyone_add_page, then the <a href=":add-content">Add content</a> page will show the not configured content types. For this you need the <em>Administer Only One</em> permission.', $routes) . '</dd>';
      $output .= '<dt>' . t('Creating content') . '</dt>';
      $output .= '<dd>' . t('Once you try to <a href=":add-content">Add content</a>, if the chosen content type is configured to have Only One content and it already has one content created in the actual language, you will be redirected to <em>edit</em> the content, otherwise, you will go to create a new one.', [':add-content' => Url::fromRoute('node.add_page')->toString()]) . '</dd>';
      $output .= '</dl>';
      $output .= '<h3>' . t('Aditionals modules') . '</h3>';
      $output .= '<dl>';
      $output .= '<dt>' . $onlyone_admin_toolbar . '</dt>';
      $output .= '<dd>' . t(
      'Very useful if you use the @admin_toolbar_page module as it handles modifications to the @admin_toolbar_tools_page module menu entries related to the configured content types.',
      [
        '@admin_toolbar_page' => $admin_toolbar_page,
        '@admin_toolbar_tools_page' => $admin_toolbar_tools_page,
      ]
      ) . '</dd>';
      $output .= '</dl>';

      return $output;
  }
}

/**
 * Implements hook_menu_local_actions_alter().
 */
function onlyone_menu_local_actions_alter(&$local_actions) {
  // Adding the local actions if the new menu entry option is active.
  if (\Drupal::config('onlyone.settings')->get('onlyone_new_menu_entry')) {
    $local_actions['onlyone.add_page'] = [
      'title' => t('Add content (Only One)'),
      'weight' => -1,
      'route_name' => 'onlyone.add_page',
      'options' => [],
      'appears_on' => [
        'system.admin_content',
      ],
      'class' => 'Drupal\Core\Menu\LocalActionDefault',
    ];
  }
}

/**
 * Implements hook_menu_links_discovered_alter().
 */
function onlyone_menu_links_discovered_alter(&$links) {
  // Adding the menu link if the new menu entry option is active.
  if (\Drupal::config('onlyone.settings')->get('onlyone_new_menu_entry')) {
    $links['onlyone.add_page'] = [
      'title' => t('Add content (Only One)'),
      'route_name' => 'onlyone.add_page',
      'menu_name' => 'admin',
      'parent' => 'system.admin_content',
      'description' => t('Add content page for content types configured to have Only One node per language.'),
    ];
  }
}

/**
 * Implements hook_preprocess_HOOK() for block content add list templates.
 */
function onlyone_preprocess_node_add_list(&$variables) {
  // Getting the route.
  $route = \Drupal::request()->attributes->get('_route');

  // Getting variable to know if we should show the configured content type
  // in a new page.
  $onlyone_new_menu_entry = \Drupal::config('onlyone.settings')->get('onlyone_new_menu_entry');

  // Leaving this code here until this issue will be resolved:
  // https://www.drupal.org/project/drupal/issues/2965718
  // @see https://www.drupal.org/project/onlyone/issues/3029598
  // Creating the message variable.
  if ($route == 'onlyone.add_page') {
    $variables['message'] = t('You have not configured any content type yet, go to the <a href=":config-content-types">Only One page</a> to configure the content types.', [':config-content-types' => Url::fromRoute('onlyone.config_content_types')->toString()]);
  }
  else {
    if ($onlyone_new_menu_entry) {
      $variables['message'] = t('All the content types are configured to have Only One node. Go to the <a href=":add-onlyone-content-type">Add content (Only One)</a> page to create or edit content.', [':add-onlyone-content-type' => Url::fromRoute('onlyone.add_page')->toString()]);
    }
    else {
      $variables['message'] = t('You have not created any content types yet. Go to the <a href=":add-content-type">Add content type</a> page to create content types.', [':add-content-type' => Url::fromRoute('node.type_add')->toString()]);
    }
  }

  // Getting the configured content types.
  $onlyone_content_types = \Drupal::config('onlyone.settings')->get('onlyone_node_types');

  // Modifying the contet types information if needed.
  foreach ($onlyone_content_types as $content_type_machine_name) {
    // If the user don't have permission to create the content type even if it
    // is configured to have only one node the content type will not exists
    // in the render array.
    // See: https://www.drupal.org/project/onlyone/issues/3028525 .
    if (empty($variables['content'][$content_type_machine_name])) {
      continue;
    }

    // Getting help from the community to solve this part, see:
    // https://drupal.stackexchange.com/q/244030/28275 .
    // We need to modify the links?
    if (!($onlyone_new_menu_entry xor $route == 'onlyone.add_page')) {
      // Getting the content type.
      $content_type = $variables['content'][$content_type_machine_name];

      // Checking if exists nodes created for the content type.
      if (\Drupal::service('onlyone')->existsNodesContentType($content_type_machine_name)) {
        // Assigning the new name.
        $new_name = t('@content_type_name (Edit)', ['@content_type_name' => $content_type->get('name')]);

        $variables['content'][$content_type_machine_name]->set('name', $new_name);
        // Changing the value in the original template, because all the themes
        // dont' use the same variables, see the seven theme as example.
        // @see template_preprocess_block_content_add_list().
        $variables['types'][$content_type_machine_name]['title'] = $new_name;
      }
      $original_description = empty($content_type->getDescription()) ? '' : rtrim($content_type->getDescription(), '.') . '.';
      $original_description_markup = Markup::create($original_description);
      $description = t('@description <strong>Only a single node can be created and edited</strong>.', ['@description' => $original_description_markup]);
      // Changing the value in the content type.
      $variables['content'][$content_type_machine_name]->set('description', $description);
      // Changing the value in the original template, because all the themes
      // dont' use the same variables, see the seven theme as example.
      // @see template_preprocess_block_content_add_list().
      $variables['types'][$content_type_machine_name]['description'] = $description;
    }
    else {
      // We need to delete the links.
      unset($variables['content'][$content_type_machine_name]);
      unset($variables['types'][$content_type_machine_name]);
    }
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter() for node_form.
 */
function onlyone_form_node_form_alter(&$form, FormStateInterface &$form_state, $form_id) {
  // Getting the configured content types.
  $onlyone_content_types = \Drupal::config('onlyone.settings')->get('onlyone_node_types');
  $onlyone_redirect = \Drupal::config('onlyone.settings')->get('onlyone_redirect');
  // Getting the node.
  $form_object = $form_state->getFormObject();
  if ($form_object instanceof EntityFormInterface) {
    /** @var \Drupal\node\NodeInterface $node */
    $node = $form_object->getEntity();

    // Verifying if the new node should by onlyone and if  trying to create
    // a new node.
    if (isset($onlyone_content_types) && in_array($node->getType(), $onlyone_content_types) && $node->isNew()) {
      // If we have one node, then redirect to the edit page.
      $nid = \Drupal::service('onlyone')->existsNodesContentType($node->getType());
      if ($nid) {
        // Creating the url.
        if ($onlyone_redirect) {
          $route = 'entity.node.edit_form';
        }
        else {
          $route = 'entity.node.canonical';
        }
        $url = Url::fromRoute($route, ['node' => $nid])->toString();
        // Redirecting to edit the only one node for this content type.
        $response = new RedirectResponse($url);
        $response->send();
      }
    }
  }
}

/**
 * Implements hook_node_type_delete().
 */
function onlyone_node_type_delete(EntityInterface $node) {
  // Getting the content type machine name.
  $content_type = $node->id();
  // Deleting the value from the config.
  \Drupal::service('onlyone')->deleteContentTypeConfig($content_type);
}

/**
 * Implements hook_entity_type_alter().
 */
function onlyone_entity_type_alter(array &$entity_types) {
  // Adding the constraint. Here is not possible to check specific content type.
  // @see https://drupal.stackexchange.com/q/208283/28275
  if (isset($entity_types['node'])) {
    $entity_types['node']->addConstraint('OnlyOne');
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc