Skip to content

Commit

Permalink
[SDPAP-8421]Adds content category terms. (#450)
Browse files Browse the repository at this point in the history
https://digital-vic.atlassian.net/browse/SDPAP-8421

1. adding content category definition and terms.
2. enable term_reference_tree module

add comments

Modifies field_content_category’s help text

update dev-tools

content category helpers for other modules

update _tide_core_adding_default_taxonomy()

Remove fixed patch

restructure helper functions.
  • Loading branch information
vincent-gao authored Apr 8, 2024
1 parent e295654 commit 3a85236
Show file tree
Hide file tree
Showing 11 changed files with 374 additions and 4 deletions.
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

0 comments on commit 3a85236

Please sign in to comment.