betasite-1.0.4/src/BetaAliasStorage.php
src/BetaAliasStorage.php
<?php namespace Drupal\betasite; use Drupal\Core\Cache\CacheTagsInvalidatorInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; use Drupal\path_alias\AliasRepository; /** * CRUD for beta site aliases. * * Usage: * $beta_links = \Drupal::service('betasite.beta_alias_storage'); * * Get beta alias by nid: * $beta_links->getAlias('12345'); * Get beta alias by canonical alias: * $beta_links->getAlias('/some/normal/alias'); * Check if a beta alias already exists. * $beta_links->aliasExists('/possible/beta/alias'); * Save a new beta alias with nid: (Can be used to both create and update). * $beta_links->saveAlias('12345', '/beta/alias'); * Remove a beta alias with nid: * $beta_links->deleteAlias('12345'); */ class BetaAliasStorage { /** * The database connection. * * @var \Drupal\Core\Database\Connection */ protected $database; /** * A logger instance. * * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface */ protected $logger; /** * The repository for searching canonical aliases. * * @var \Drupal\path_alias\AliasRepository */ protected $pathAliasRepository; /** * The entity type manager for creating PathAlias entities. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The service to invalidate the custom cache tag. * * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface */ protected CacheTagsInvalidatorInterface $cacheTagsInvalidator; /** * Inject everything. * * @param \Drupal\Core\Database\Connection $database * The database connection. * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $factory * A logger instance. * @param \Drupal\path_alias\AliasRepository $path_alias_repository * The repository for searching canonical aliases. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entityTypeManager for creating PathAlias entities. * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tags_invalidator * The service for invalidating cache tags. */ public function __construct( Connection $database, LoggerChannelFactoryInterface $factory, AliasRepository $path_alias_repository, EntityTypeManagerInterface $entity_type_manager, CacheTagsInvalidatorInterface $cache_tags_invalidator, ) { $this->database = $database; $this->logger = $factory->get('betasite'); $this->pathAliasRepository = $path_alias_repository; $this->entityTypeManager = $entity_type_manager; $this->cacheTagsInvalidator = $cache_tags_invalidator; } /** * Retrieves an alias from its nid or canonical alias. * * @param string $nid_or_alias * Either the node id or the canonical alias. * * @return string|bool * The beta alias or FALSE if no beta alias found. */ public function getAlias($nid_or_alias) { if (substr($nid_or_alias, 0, 1) === '/') { $result = $this->database->query( 'SELECT beta_alias FROM {path_alias} WHERE alias = :alias AND langcode = :lang', [':alias' => $nid_or_alias, ':lang' => 'en']); } else { $path = "/node/" . $nid_or_alias; $result = $this->database->query( 'SELECT beta_alias FROM {path_alias} WHERE path = :path AND langcode = :lang', [':path' => $path, ':lang' => 'en']); } return $result->fetchField(0); } /** * Attempts to save a beta alias. * * @param string $nid * The node id. * @param string $alias * The beta alias to be saved. * * @return bool * Indicates if the operation was successful. */ public function saveAlias($nid, $alias) { if (!$this->validateAlias($alias)) { return FALSE; } $path = '/node/' . $nid; if ($this->pathObjMissing($path)) { $this->createPathObj($path); } $this->cacheTagsInvalidator->invalidateTags(['beta_alias:' . $nid]); return $this->updateTable($path, $alias); } /** * Deletes an alias. * * @param string $nid * The node id. * * @return bool * Indicates if the operation was successful. */ public function deleteAlias($nid) { $this->cacheTagsInvalidator->invalidateTags(['beta_alias:' . $nid]); return $this->updateTable("/node/" . $nid, NULL); } /** * Checks for the existence of a beta alias. * * @param string $alias * The beta alias that may or may not exist. */ public function aliasExists($alias) { $result = $this->database->query( 'SELECT beta_alias FROM {path_alias} WHERE beta_alias = :alias AND langcode = :lang', [':alias' => $alias, ':lang' => 'en']); return $result->fetchField(0) !== FALSE; } /** * Updates the path_alias table. * * @param string $path * The /node/*** path of the entity. * @param string $alias * The beta alias to be saved. * * @return bool * Indicates if the operation was successful. */ private function updateTable($path, $alias) { $result = $this->database->update('path_alias') ->fields(['beta_alias' => $alias]) ->condition('path', $path) ->condition('langcode', 'en') ->execute(); if ($result === 0) { $this->logger->warning('Could not find ' . $path . ' in path_alias table.'); // phpcs:ignore return FALSE; } return TRUE; } /** * Validate that an alias is a string and starts with /. * * @param string $alias * The beta alias to be validated. * * @return bool * Indicates if the alias is valid. */ private function validateAlias($alias) { if (gettype($alias) !== 'string' || substr($alias, 0, 1) !== '/' || strpos($alias, ' ') !== FALSE ) { $this->logger->warning($alias . ' is not a valid url alias. It must be a string that starts with /.'); // phpcs:ignore return FALSE; } return TRUE; } /** * Checks if a PathAlias entity exists for the node. * * @param string $path * The system path of the node. */ private function pathObjMissing($path) { return $this->pathAliasRepository->lookupBySystemPath($path, 'en') === NULL; } /** * Creates a new PathAlias entity for the node. * * @param string $path * The system path of the node. */ private function createPathObj($path) { $this->entityTypeManager->getStorage('path_alias')->create([ 'path' => $path, 'langcode' => 'en', 'alias' => NULL, ])->save(); } }