createcontentwithcategory-1.0.0-alpha1/src/Ccwc.php

src/Ccwc.php
<?php

namespace Drupal\createcontentwithcategory;

use Drupal\core\Url;
use Drupal\Core\Template\Attribute;


/**
 * Encapsulates useful methods for creating content with category.
 */
class Ccwc { // implements CcwcInterface {

  /**
   * The identification string for this create content with category object.
   * 
   * @var string
   */
  public $id;

  /**
   * The content (node) type machine name.
   * 
   * @var string
   */
  public $content_type;

  /**
   * The field machine name.
   * 
   * @var string
   */
  public $field_name;

  public function __construct($id) {
    $this->id = $id;
    $parts = explode('__', $id);
    if (count($parts) !== 2) {
      throw new \Exception("Invalid Create Content with Category ID: $id");
    }
    $this->content_type = $parts[0];
    $this->field_name = $parts[1];
  }

  public function label() {
    return t("Create :content_type content with category :field", [':field' => $this->fieldLabel(), ':content_type' => $this->contentTypeLabel()]);
  }

  public function permission() {
    return 'create ' . $this->content_type;
  }

  public function fieldLabel() {
    return $this->getField()->label();
  }

  public function getField() {
    $entity_type = 'node';
    $bundle = $this->content_type;
    $field_name = $this->field_name;
    return \Drupal\field\Entity\FieldConfig::loadByName($entity_type, $bundle, $field_name);
  }

  public function contentTypeLabel() {
    return \Drupal::entityTypeManager()
      ->getStorage('node_type')
      ->load($this->content_type)
      ->label();
  }

  public function build() {
    $build = [];

    $items = $this->buildItems();
    if ($items) {
      // Make sure drupal_render() does not re-order the links.
      $build['#sorted'] = TRUE;
      // Make up a menu name.
      $menu_name = $this->id;
      // Add the theme wrapper for outer markup.
      // Allow menu-specific theme overrides.
      $build['#theme'] = 'menu__' . strtr($menu_name, '-', '_');
      $build['#menu_name'] = $menu_name;
      $build['#items'] = $items;
      // Set cache tag. - this should refresh when the vocabulary terms change, if we have a way to get that in Drupal.  Skipping for now.
      // $build['#cache']['tags'][] = 'config:system.menu.' . $menu_name;
    }

    return $build;
  }

  public function buildItems() {
    $items = [];
    $terms = $this->getTerms();
    foreach ($terms as $id => $term) {
      $element = [];
      $element['attributes'] = new Attribute();
      $element['title'] = $term->getName();
      $element['original_term'] = $term;
      $element['url'] = $this->makeUrl($id);

      $items[$id] = $element;
    }
    return $items;
  }

  public function getTerms() {
    $terms = [];
    $field = $this->getField();
    $vocab_names = $field->getSettings()['handler_settings']['target_bundles'];
    foreach ($vocab_names as $vocab_name) {
      // Preserve numeric keys (why not!) and do the merge in one line, nice.
      $terms += \Drupal::entityTypeManager()->getStorage('taxonomy_term')  ->loadByProperties(['vid' => $vocab_name]);
    }
    return $terms;
  }

  public function makeUrl($term_id) {
    return Url::fromRoute('node.add', [
      'node_type' => $this->content_type,
    ], [
      'query' => [
        $this->prepopulateQueryKey() => $term_id,
      ],
    ]);
  }

  public function prepopulateQueryKey() {
    // The documented approach does not work for select lists
    // "edit[$this->field_name][widget][0][target_id]"
    // Below does work for select lists, though it's not documented.
    // @TODO look up what kind of field we have and produce a working
    // prepopulate link based on trial and error and the 'documentation'
    // https://git.drupalcode.org/project/prepopulate/blob/8.x-2.x/tests/src/Functional/PrepopulateFieldTest.php
    // Again note that what we do here is not in the tests nor documentation.
    return "edit[$this->field_name][widget]";
  }
}

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

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