Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDPAP-8421]Adds content category terms. #450

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
"respect/validation": "2.3.1",
"giggsey/libphonenumber-for-php": "^8.13",
"drupal/site_alert": "^1.3",
"lcobucci/clock": "3.0.0"
"lcobucci/clock": "3.0.0",
"drupal/term_reference_tree": "^2.0"
},
"repositories": {
"drupal": {
Expand Down
23 changes: 23 additions & 0 deletions config/install/field.storage.node.field_content_category.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
langcode: en
status: true
dependencies:
module:
- field_permissions
- node
- taxonomy
third_party_settings:
field_permissions:
permission_type: public
id: node.field_content_category
field_name: field_content_category
entity_type: node
type: entity_reference
settings:
target_type: taxonomy_term
module: core
locked: false
cardinality: -1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
7 changes: 7 additions & 0 deletions config/install/taxonomy.vocabulary.content_category.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
langcode: en
status: true
dependencies: { }
name: 'Content category'
vid: content_category
description: 'Categories assigned to all content to assist with filtering in content collection and search'
weight: 0
3 changes: 3 additions & 0 deletions css/pseudo_required_field.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.pseudo-required-field {
color: #dc2323;
}
187 changes: 187 additions & 0 deletions includes/helpers.inc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use Drupal\Core\Config\FileStorage;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Site\Settings;
use Drupal\paragraphs\Entity\ParagraphsType;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;

/**
* Helper to read configuration from provided locations.
Expand Down Expand Up @@ -199,3 +201,188 @@ function _tide_extract_id_for_storage_usage($target, $config, $include) {
}
return $matches;
}

/**
* Adds taxonomy with nested terms up to a specified depth and order.
*
* @param array $terms
* An associative array of terms where keys are term names and values are
* either arrays of child term names or associative arrays with nested terms.
* Example structure for $terms:
* $terms = [
* 'Events' => [
* 'Events',
* ],
* 'Policy and legislation' => [
* 'Legislation',
* 'Regulation' => [
* 'hello' => [
* 'world',
* 'new' => [
* 'era',
* ],
* ],
* ],
* ],
* ];
* This represents a hierarchy with 'Events' and 'Policy and legislation'
* as top-level terms, and nested children underneath them.
* @param array $vocabulary_details
* An associative array with vocabulary details. Example:
* $vocabulary_details = [
* 'vid' => 'content_category',
* 'description' => 'Categories for content filtering and search',
* 'name' => 'Content category',
* ];.
* @param int $max_depth
* The maximum hierarchy depth to create, defaulting to 4. Deeper nested
* terms beyond this depth will be ignored.
*/
function _tide_core_adding_default_taxonomy(array $terms, array $vocabulary_details, $max_depth = 4) {
$vocabulary_id = $vocabulary_details['vid'];
// Load or create the vocabulary.
$vocabulary = Vocabulary::load($vocabulary_id);
if (!$vocabulary) {
$vocabulary = Vocabulary::create($vocabulary_details);
$vocabulary->save();
}

// Function to recursively add terms to the vocabulary.
$add_terms_recursively = function ($parent_tid, array $terms, $weight, $depth) use (&$add_terms_recursively, $vocabulary_id, $max_depth) {
if ($depth > $max_depth) {
return;
}

foreach ($terms as $term_name => $child_terms) {
if (is_array($child_terms)) {
$parent_term = _create_or_load_term($vocabulary_id, $term_name, $parent_tid, $weight++);
$add_terms_recursively($parent_term->id(), $child_terms, 0, $depth + 1);
}
else {
_create_or_load_term($vocabulary_id, $child_terms, $parent_tid, $weight++);
}
}
};

$add_terms_recursively(0, $terms, 0, 1);
}

/**
* Create or retrieve a Term.
*
* This function checks if a taxonomy term already exists within a specified
* vocabulary. If the term exists, it is returned. If not, a new term is created
* with the given details and then returned.
*
* @param string $vocabulary_id
* The machine name of the vocabulary.
* @param string $term_name
* The name of the term to be created or retrieved.
* @param int $parent_tid
* The term ID of the parent term. If set to 0, it has no parent.
* @param int $weight
* The weight of the term, used for sorting purposes.
*
* @return \Drupal\taxonomy\Entity\Term
* The taxonomy term object.
*/
function _create_or_load_term($vocabulary_id, $term_name, $parent_tid = 0, $weight = 0) {
// If a parent term is specified, search for a term with the same name
// and parent.
if ($parent_tid != 0) {
$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties([
'name' => $term_name,
'vid' => $vocabulary_id,
'parent' => $parent_tid,
]);
}
// If no parent is specified, search for a term with the same name in
// the vocabulary.
else {
$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties([
'name' => $term_name,
'vid' => $vocabulary_id,
]);
}
// If the term exists, return it.
$term = reset($terms);
if ($term) {
return $term;
}
// If the term does not exist, create a new one with the specified details.
$term = Term::create([
'vid' => $vocabulary_id,
'name' => $term_name,
'parent' => [$parent_tid],
'weight' => $weight,
]);
// Save the newly created term.
$term->save();
// Return the new term.
return $term;
}

/**
* Returns predefined content_category terms for tide_core module.
*/
function _content_category_terms() {
return [
'Events' => [
'Event',
],
'Grants' => [
'Grant',
],
'Other' => [
'Other',
],
'News and media' => [
'News article',
'Media release',
],
'Policy and legislation' => [
'Legislation',
'Regulation',
'Policy',
'Ministerial order',
'Notice',
'Briefing',
],
'Profiles' => [
'Individual profile',
'Organisation profile',
],
'Programs and reports' => [
'Report',
'Program',
'Initiative',
'Campaign',
'Inquiry',
'Strategy',
],
'Resources and guidance' => [
'Guide',
'Handbook',
'Manual',
'Fact sheet',
'Brochure',
'Map',
'Framework',
'Poster',
'Specification',
'Plan',
],
'Tools and templates' => [
'Tool',
'Quote template',
'Template',
'Calculator',
'Contract template',
'Worksheet',
'Form',
'Letter',
'Checklist',
'Memo',
],
];
}
76 changes: 76 additions & 0 deletions includes/updates.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

/**
* @file
* This file supports other modules in their hook_update_N.
*/

use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\field\Entity\FieldConfig;
use Drupal\taxonomy\Entity\Term;

/**
* Set default values for the field_content_category field.
*
* @param string $bundle
* The bundle of the entity.
* @param mixed $term_names
* A single term name or an array of term names to set as default values.
*/
function _tide_core_field_content_category_default_value(string $bundle, $term_names) {
// Ensure $term_names is always an array.
if (!is_array($term_names)) {
$term_names = [$term_names];
}

$default_values = [];

foreach ($term_names as $term_name) {
$query = \Drupal::entityQuery('taxonomy_term')
->condition('name', $term_name)
->condition('vid', 'content_category')
->condition('parent', 0, '<>')
->accessCheck(TRUE);

$results = $query->execute();
if (!empty($results)) {
$tid = reset($results);
$uuid = Term::load($tid)->uuid();
if (!empty($uuid)) {
$default_values[] = ['target_uuid' => $uuid];
}
}
}

if (!empty($default_values)) {
/** @var \Drupal\field\Entity\FieldConfig $config */
$config = FieldConfig::loadByName('node', $bundle, 'field_content_category');
$config->set('default_value', $default_values)->save();
}
}

/**
* Set form display for field_content_category field.
*/
function _tide_core_content_category_form_display(string $bundle) {
$entity_form_display = EntityFormDisplay::load('node.' . $bundle . '.default');
$detail = $entity_form_display->getComponent('field_tags');
$weight = $detail['weight'];
$content = [
"type" => "term_reference_tree",
"weight" => $weight + 1,
"region" => "content",
"settings" => [
"start_minimized" => TRUE,
"leaves_only" => TRUE,
"select_parents" => FALSE,
"cascading_selection" => 0,
"max_depth" => 0,
],
"third_party_settings" => [],
];
$field_content_category_component = $entity_form_display->getComponent('field_content_category');
if ($field_content_category_component === NULL) {
$entity_form_display->setComponent('field_content_category', $content)->save();
}
}
13 changes: 13 additions & 0 deletions src/TideCoreOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,17 @@ public function chagneDiffSettings() {
}
}

/**
* Creates terms for content_category vocabulary.
*/
public function addContentCategoryVocabulary() {
$vocabulary_details = [
'vid' => 'content_category',
'description' => 'Categories assigned to all content to assist with filtering in content collection and search',
'name' => 'Content category',
];
\Drupal::moduleHandler()->loadInclude('tide_core', 'inc', 'includes/helpers');
_tide_core_adding_default_taxonomy(_content_category_terms(), $vocabulary_details);
}

}
1 change: 1 addition & 0 deletions tide_core.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ dependencies:
- field_permissions:field_permissions
- content_lock:content_lock
- ckeditor_templates:ckeditor_templates
- term_reference_tree:term_reference_tree
themes:
- claro
config_devel:
Expand Down
34 changes: 33 additions & 1 deletion tide_core.install
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ function tide_core_install() {
// Creates terms for Topic vocabulary.
$tideCoreOperation->createTopicTermsVocabulary();

// Creates terms for content_category vocabulary.
$tideCoreOperation->addContentCategoryVocabulary();

// Update default Editorial workflow of Content Moderation.
$tideCoreOperation->updateEditorialWorkflow();

Expand Down Expand Up @@ -144,9 +147,38 @@ function tide_core_update_10004() {
}

/**
* Fixes dialog can no longer use custom data- attributes in CKEditor 5.
* Run _add_default_content_category_taxonomy().
*/
function tide_core_update_10005() {
\Drupal::moduleHandler()->loadInclude('tide_core', 'inc', 'includes/helpers');
$config_location = [\Drupal::service('extension.list.module')->getPath('tide_core') . '/config/install'];
$config_read = _tide_read_config('field.storage.node.field_content_category', $config_location, TRUE);
$storage = \Drupal::entityTypeManager()->getStorage('field_storage_config');
if ($storage->load('node.field_content_category') === NULL) {
$config_entity = $storage->createFromStorageRecord($config_read);
$config_entity->save();
}
if (\Drupal::moduleHandler()->moduleExists('term_reference_tree') === FALSE) {
\Drupal::service('module_installer')->install(['term_reference_tree']);
}
$config_read = _tide_read_config('taxonomy.vocabulary.content_category', $config_location, TRUE);
$storage = \Drupal::entityTypeManager()->getStorage('taxonomy_vocabulary');
if ($storage->load('content_category') === NULL) {
$config_entity = $storage->createFromStorageRecord($config_read);
$config_entity->save();
}
$vocabulary_details = [
'vid' => 'content_category',
'description' => 'Categories assigned to all content to assist with filtering in content collection and search',
'name' => 'Content category',
];
_tide_core_adding_default_taxonomy(_content_category_terms(), $vocabulary_details);
}

/**
* Fixes dialog can no longer use custom data- attributes in CKEditor 5.
*/
function tide_core_update_10006() {
$config_factory = \Drupal::configFactory();
$filter_ids = [
'filter.format.admin_text',
Expand Down
Loading
Loading