Skip to content
Snippets Groups Projects
Commit de72b76d authored by Lily Yan's avatar Lily Yan
Browse files

Merge branch 'feature/ISTWCMS-7142-ibiki-term_depth_update' into '1.0.x'

Feature/istwcms 7142 ibiki term depth update

See merge request !61
parents 90c17b22 c776b438
No related branches found
No related tags found
1 merge request!61Feature/istwcms 7142 ibiki term depth update
<?php
namespace Drupal\uw_ct_service\Plugin\QueueWorker;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueWorkerBase;
use Drupal\taxonomy\TermStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Updates taxonomy term depth from uw_ct_service module.
*
* @QueueWorker(
* id = "uw_ct_service_queue_worker",
* title = @Translation("UW Taxonomy term depth update"),
* cron = {"time" = 300}
* )
*/
class UWServiceUpdateDepth extends QueueWorkerBase implements ContainerFactoryPluginInterface {
/**
* Database.
*
* @var \Drupal\Core\Database\Connection
*/
protected Connection $database;
/**
* Entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* Term storage.
*
* @var \Drupal\taxonomy\TermStorageInterface
*/
protected TermStorageInterface $termStorage;
/**
* Constructs a new LocaleTranslation object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param array $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Database\Connection $database
* Database.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, Connection $database, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->database = $database;
$this->entityTypeManager = $entity_type_manager;
$this->termStorage = $this->entityTypeManager->getStorage('taxonomy_term');
}
/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('database'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritDoc}
*/
public function processItem($data) {
if (($vid = $data['vid']) && (is_array($data['tids']) && $tids = $data['tids'])) {
foreach ($tids as $tid) {
$depth = count($this->termStorage->loadAllParents($tid));
$this->database->update('taxonomy_term_field_data')->fields([
'depth_level' => $depth,
])->condition('vid', $vid)->condition('tid', $tid)->execute();
}
}
}
}
<?php
namespace Drupal\uw_ct_service\QueueManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueInterface;
use Drupal\Core\Queue\QueueWorkerManager;
use Drupal\Core\Queue\SuspendQueueException;
use Drupal\taxonomy\VocabularyInterface;
/**
* UW Queue Manager class.
*/
class UWQueueManager {
public const QUEUE_ID = 'uw_ct_service_queue';
public const BATCH_SIZE = 10;
/**
* Vocabulary.
*
* @var \Drupal\taxonomy\VocabularyInterface|null
*/
protected ?VocabularyInterface $vocabulary = NULL;
/**
* Vocabulary id.
*
* @var string|null
*/
protected ?string $vid = NULL;
/**
* Queue.
*
* @var \Drupal\Core\Queue\QueueInterface|null
*/
protected ?QueueInterface $queue = NULL;
/**
* Default constructor.
*
* @param \Drupal\Core\Queue\QueueFactory $queue_factory
* Queue.
* @param \Drupal\Core\Queue\QueueWorkerManager $queue_worker_manager
* Queue worker manager.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager service.
*/
public function __construct(
QueueFactory $queue_factory,
protected QueueWorkerManager $queue_worker_manager,
protected EntityTypeManagerInterface $entity_type_manager,
) {
$this->queue = $queue_factory->get(self::QUEUE_ID);
$this->vocabulary = NULL;
$this->vid = NULL;
}
/**
* Deletes queue.
*/
public function deleteQueue(): void {
$this->queue->deleteQueue();
}
/**
* Creates queue.
*/
public function createQueue(): void {
$this->deleteQueue();
/** @var \Drupal\taxonomy\TermStorageInterface $term_storage */
$term_storage = $this->entity_type_manager->getStorage('taxonomy_term');
$all_terms = $term_storage->loadByProperties([
'vid' => $this->vid,
]);
$tids = [];
foreach ($all_terms as $term) {
if (count($tids) >= self::BATCH_SIZE) {
$this->queue->createItem([
'vid' => $this->vid,
'tids' => $tids,
]);
$tids = [];
}
$tids[] = $term->id();
}
// Last batch which may be less than the limit.
$this->queue->createItem([
'vid' => $this->vid,
'tids' => $tids,
]);
}
/**
* Process queued items.
*/
public function processQueue(): void {
if ($this->queue->numberOfItems() === 0) {
$this->createQueue();
}
$worker = $this->queue_worker_manager->createInstance('uw_ct_service_queue_worker');
while ($item = $this->queue->claimItem()) {
try {
$worker->processItem($item->data);
$this->queue->deleteItem($item);
}
catch (SuspendQueueException $e) {
$this->queue->releaseItem($item);
break;
}
catch (\Exception $e) {
$this->queue->deleteItem($item);
}
}
}
/**
* Set vocabulary.
*
* @param \Drupal\taxonomy\VocabularyInterface $vocabulary
* Vocabulary.
*/
public function setVocabulary(VocabularyInterface $vocabulary): self {
// Check if vocabulary has nesting allowed.
// When max_depth is set to zero, there isn't any save handler on the form.
// So maybe checking this out is not necessary.
$max_depth = $vocabulary?->getThirdPartySetting('taxonomy_max_depth', 'max_depth');
if ($max_depth > 1) {
$this->vocabulary = $vocabulary;
$this->vid = $vocabulary->id();
}
return $this;
}
}
......@@ -5,8 +5,8 @@
* Provides configuration and settings for services.
*/
use Drupal\Core\Link;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\taxonomy\Entity\Term;
use Drupal\views\Plugin\views\query\QueryPluginBase;
......@@ -55,7 +55,7 @@ function _uw_ct_service_load_locations(): array {
$locations = [];
foreach ($locations_file as $file_location) {
// Parse name into code and name.
list($location_code, $location_name) = explode('-', $file_location['name'], 2);
[$location_code, $location_name] = explode('-', $file_location['name'], 2);
$location_code = trim($location_code);
// Create array for this location.
$location = [
......@@ -238,7 +238,7 @@ function uw_ct_service_preprocess_views_view(&$variables) {
*/
function uw_ct_service_views_query_alter(
ViewExecutable $view,
QueryPluginBase $query
QueryPluginBase $query,
) {
if ($view->id() === 'uw_view_services') {
......@@ -483,3 +483,40 @@ function _uw_ct_service_get_child_terms_with_grandchild(): array {
}
return $tids_for_child_with_grandchild;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function uw_ct_service_form_taxonomy_overview_terms_alter(array &$form, FormStateInterface $form_state, $form_id) {
// Add the submission handler to update depths of vocabularies.
$form['#submit'][] = '_uw_ct_service_form_taxonomy_overview_terms_submit';
}
/**
* Additional form submit handler.
*
* @param array $form
* Term overview form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*/
function _uw_ct_service_form_taxonomy_overview_terms_submit(array $form, FormStateInterface $form_state) {
/** @var \Drupal\taxonomy\VocabularyInterface $vocabulary */
$vocabulary = \Drupal::routeMatch()->getParameter('taxonomy_vocabulary');
if (!$vocabulary) {
return;
}
// Once issue with calculating depth_level is fixed in a contrib module
// taxonomy_term_depth this should be removed. What this code does is
// check if vocabulary has set depth limit, and recalculate depth for
// each term and the used database query to update depth_level to the
// correct value. Avoiding entity update, so that no update hook is fired.
// see: https://uwaterloo.atlassian.net/browse/ISTWCMS-7142
/** @var \Drupal\uw_ct_service\QueueManager\UWQueueManager $qm */
$qm = \Drupal::service('uw_ct_service.queue_manager');
$qm->setVocabulary($vocabulary)->processQueue();
}
services:
uw_ct_service.queue_manager:
class: Drupal\uw_ct_service\QueueManager\UWQueueManager
arguments: ['@queue', '@plugin.manager.queue_worker', '@entity_type.manager']
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment