[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_finder/src/Indexer/ -> Taxonomy.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Administrator
   5   * @subpackage  com_finder
   6   *
   7   * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Component\Finder\Administrator\Indexer;
  12  
  13  use Joomla\CMS\Factory;
  14  use Joomla\CMS\Tree\NodeInterface;
  15  use Joomla\Component\Finder\Administrator\Table\MapTable;
  16  
  17  // phpcs:disable PSR1.Files.SideEffects
  18  \defined('_JEXEC') or die;
  19  // phpcs:enable PSR1.Files.SideEffects
  20  
  21  /**
  22   * Taxonomy base class for the Finder indexer package.
  23   *
  24   * @since  2.5
  25   */
  26  class Taxonomy
  27  {
  28      /**
  29       * An internal cache of taxonomy data.
  30       *
  31       * @var    object[]
  32       * @since  4.0.0
  33       */
  34      public static $taxonomies = array();
  35  
  36      /**
  37       * An internal cache of branch data.
  38       *
  39       * @var    object[]
  40       * @since  4.0.0
  41       */
  42      public static $branches = array();
  43  
  44      /**
  45       * An internal cache of taxonomy node data for inserting it.
  46       *
  47       * @var    object[]
  48       * @since  2.5
  49       */
  50      public static $nodes = array();
  51  
  52      /**
  53       * Method to add a branch to the taxonomy tree.
  54       *
  55       * @param   string   $title   The title of the branch.
  56       * @param   integer  $state   The published state of the branch. [optional]
  57       * @param   integer  $access  The access state of the branch. [optional]
  58       *
  59       * @return  integer  The id of the branch.
  60       *
  61       * @since   2.5
  62       * @throws  \RuntimeException on database error.
  63       */
  64      public static function addBranch($title, $state = 1, $access = 1)
  65      {
  66          $node = new \stdClass();
  67          $node->title = $title;
  68          $node->state = $state;
  69          $node->access = $access;
  70          $node->parent_id = 1;
  71          $node->language = '';
  72  
  73          return self::storeNode($node, 1);
  74      }
  75  
  76      /**
  77       * Method to add a node to the taxonomy tree.
  78       *
  79       * @param   string   $branch    The title of the branch to store the node in.
  80       * @param   string   $title     The title of the node.
  81       * @param   integer  $state     The published state of the node. [optional]
  82       * @param   integer  $access    The access state of the node. [optional]
  83       * @param   string   $language  The language of the node. [optional]
  84       *
  85       * @return  integer  The id of the node.
  86       *
  87       * @since   2.5
  88       * @throws  \RuntimeException on database error.
  89       */
  90      public static function addNode($branch, $title, $state = 1, $access = 1, $language = '')
  91      {
  92          // Get the branch id, insert it if it does not exist.
  93          $branchId = static::addBranch($branch);
  94  
  95          $node = new \stdClass();
  96          $node->title = $title;
  97          $node->state = $state;
  98          $node->access = $access;
  99          $node->parent_id = $branchId;
 100          $node->language = $language;
 101  
 102          return self::storeNode($node, $branchId);
 103      }
 104  
 105      /**
 106       * Method to add a nested node to the taxonomy tree.
 107       *
 108       * @param   string         $branch    The title of the branch to store the node in.
 109       * @param   NodeInterface  $node      The source-node of the taxonomy node.
 110       * @param   integer        $state     The published state of the node. [optional]
 111       * @param   integer        $access    The access state of the node. [optional]
 112       * @param   string         $language  The language of the node. [optional]
 113       * @param   integer        $branchId  ID of a branch if known. [optional]
 114       *
 115       * @return  integer  The id of the node.
 116       *
 117       * @since   4.0.0
 118       */
 119      public static function addNestedNode($branch, NodeInterface $node, $state = 1, $access = 1, $language = '', $branchId = null)
 120      {
 121          if (!$branchId) {
 122              // Get the branch id, insert it if it does not exist.
 123              $branchId = static::addBranch($branch);
 124          }
 125  
 126          $parent = $node->getParent();
 127  
 128          if ($parent && $parent->title != 'ROOT') {
 129              $parentId = self::addNestedNode($branch, $parent, $state, $access, $language, $branchId);
 130          } else {
 131              $parentId = $branchId;
 132          }
 133  
 134          $temp = new \stdClass();
 135          $temp->title = $node->title;
 136          $temp->state = $state;
 137          $temp->access = $access;
 138          $temp->parent_id = $parentId;
 139          $temp->language = $language;
 140  
 141          return self::storeNode($temp, $parentId);
 142      }
 143  
 144      /**
 145       * A helper method to store a node in the taxonomy
 146       *
 147       * @param   object   $node      The node data to include
 148       * @param   integer  $parentId  The parent id of the node to add.
 149       *
 150       * @return  integer  The id of the inserted node.
 151       *
 152       * @since   4.0.0
 153       * @throws  \RuntimeException
 154       */
 155      protected static function storeNode($node, $parentId)
 156      {
 157          // Check to see if the node is in the cache.
 158          if (isset(static::$nodes[$parentId . ':' . $node->title])) {
 159              return static::$nodes[$parentId . ':' . $node->title]->id;
 160          }
 161  
 162          // Check to see if the node is in the table.
 163          $db = Factory::getDbo();
 164          $query = $db->getQuery(true)
 165              ->select('*')
 166              ->from($db->quoteName('#__finder_taxonomy'))
 167              ->where($db->quoteName('parent_id') . ' = ' . $db->quote($parentId))
 168              ->where($db->quoteName('title') . ' = ' . $db->quote($node->title))
 169              ->where($db->quoteName('language') . ' = ' . $db->quote($node->language));
 170  
 171          $db->setQuery($query);
 172  
 173          // Get the result.
 174          $result = $db->loadObject();
 175  
 176          // Check if the database matches the input data.
 177          if ((bool) $result && $result->state == $node->state && $result->access == $node->access) {
 178              // The data matches, add the item to the cache.
 179              static::$nodes[$parentId . ':' . $node->title] = $result;
 180  
 181              return static::$nodes[$parentId . ':' . $node->title]->id;
 182          }
 183  
 184          /*
 185           * The database did not match the input. This could be because the
 186           * state has changed or because the node does not exist. Let's figure
 187           * out which case is true and deal with it.
 188           * @todo: use factory?
 189           */
 190          $nodeTable = new MapTable($db);
 191  
 192          if (empty($result)) {
 193              // Prepare the node object.
 194              $nodeTable->title = $node->title;
 195              $nodeTable->state = (int) $node->state;
 196              $nodeTable->access = (int) $node->access;
 197              $nodeTable->language = $node->language;
 198              $nodeTable->setLocation((int) $parentId, 'last-child');
 199          } else {
 200              // Prepare the node object.
 201              $nodeTable->id = (int) $result->id;
 202              $nodeTable->title = $result->title;
 203              $nodeTable->state = (int) ($node->state > 0 ? $node->state : $result->state);
 204              $nodeTable->access = (int) $result->access;
 205              $nodeTable->language = $node->language;
 206              $nodeTable->setLocation($result->parent_id, 'last-child');
 207          }
 208  
 209          // Check the data.
 210          if (!$nodeTable->check()) {
 211              $error = $nodeTable->getError();
 212  
 213              if ($error instanceof \Exception) {
 214                  // \Joomla\CMS\Table\NestedTable sets errors of exceptions, so in this case we can pass on more
 215                  // information
 216                  throw new \RuntimeException(
 217                      $error->getMessage(),
 218                      $error->getCode(),
 219                      $error
 220                  );
 221              }
 222  
 223              // Standard string returned. Probably from the \Joomla\CMS\Table\Table class
 224              throw new \RuntimeException($error, 500);
 225          }
 226  
 227          // Store the data.
 228          if (!$nodeTable->store()) {
 229              $error = $nodeTable->getError();
 230  
 231              if ($error instanceof \Exception) {
 232                  // \Joomla\CMS\Table\NestedTable sets errors of exceptions, so in this case we can pass on more
 233                  // information
 234                  throw new \RuntimeException(
 235                      $error->getMessage(),
 236                      $error->getCode(),
 237                      $error
 238                  );
 239              }
 240  
 241              // Standard string returned. Probably from the \Joomla\CMS\Table\Table class
 242              throw new \RuntimeException($error, 500);
 243          }
 244  
 245          $nodeTable->rebuildPath($nodeTable->id);
 246  
 247          // Add the node to the cache.
 248          static::$nodes[$parentId . ':' . $nodeTable->title] = (object) $nodeTable->getProperties();
 249  
 250          return static::$nodes[$parentId . ':' . $nodeTable->title]->id;
 251      }
 252  
 253      /**
 254       * Method to add a map entry between a link and a taxonomy node.
 255       *
 256       * @param   integer  $linkId  The link to map to.
 257       * @param   integer  $nodeId  The node to map to.
 258       *
 259       * @return  boolean  True on success.
 260       *
 261       * @since   2.5
 262       * @throws  \RuntimeException on database error.
 263       */
 264      public static function addMap($linkId, $nodeId)
 265      {
 266          // Insert the map.
 267          $db = Factory::getDbo();
 268  
 269          $query = $db->getQuery(true)
 270              ->select($db->quoteName('link_id'))
 271              ->from($db->quoteName('#__finder_taxonomy_map'))
 272              ->where($db->quoteName('link_id') . ' = ' . (int) $linkId)
 273              ->where($db->quoteName('node_id') . ' = ' . (int) $nodeId);
 274          $db->setQuery($query);
 275          $db->execute();
 276          $id = (int) $db->loadResult();
 277  
 278          if (!$id) {
 279              $map = new \stdClass();
 280              $map->link_id = (int) $linkId;
 281              $map->node_id = (int) $nodeId;
 282              $db->insertObject('#__finder_taxonomy_map', $map);
 283          }
 284  
 285          return true;
 286      }
 287  
 288      /**
 289       * Method to get the title of all taxonomy branches.
 290       *
 291       * @return  array  An array of branch titles.
 292       *
 293       * @since   2.5
 294       * @throws  \RuntimeException on database error.
 295       */
 296      public static function getBranchTitles()
 297      {
 298          $db = Factory::getDbo();
 299  
 300          // Set user variables
 301          $groups = implode(',', Factory::getUser()->getAuthorisedViewLevels());
 302  
 303          // Create a query to get the taxonomy branch titles.
 304          $query = $db->getQuery(true)
 305              ->select($db->quoteName('title'))
 306              ->from($db->quoteName('#__finder_taxonomy'))
 307              ->where($db->quoteName('parent_id') . ' = 1')
 308              ->where($db->quoteName('state') . ' = 1')
 309              ->where($db->quoteName('access') . ' IN (' . $groups . ')');
 310  
 311          // Get the branch titles.
 312          $db->setQuery($query);
 313  
 314          return $db->loadColumn();
 315      }
 316  
 317      /**
 318       * Method to find a taxonomy node in a branch.
 319       *
 320       * @param   string  $branch  The branch to search.
 321       * @param   string  $title   The title of the node.
 322       *
 323       * @return  mixed  Integer id on success, null on no match.
 324       *
 325       * @since   2.5
 326       * @throws  \RuntimeException on database error.
 327       */
 328      public static function getNodeByTitle($branch, $title)
 329      {
 330          $db = Factory::getDbo();
 331  
 332          // Set user variables
 333          $groups = implode(',', Factory::getUser()->getAuthorisedViewLevels());
 334  
 335          // Create a query to get the node.
 336          $query = $db->getQuery(true)
 337              ->select('t1.*')
 338              ->from($db->quoteName('#__finder_taxonomy') . ' AS t1')
 339              ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id')
 340              ->where('t1.access IN (' . $groups . ')')
 341              ->where('t1.state = 1')
 342              ->where('t1.title LIKE ' . $db->quote($db->escape($title) . '%'))
 343              ->where('t2.access IN (' . $groups . ')')
 344              ->where('t2.state = 1')
 345              ->where('t2.title = ' . $db->quote($branch));
 346  
 347          // Get the node.
 348          $query->setLimit(1);
 349          $db->setQuery($query);
 350  
 351          return $db->loadObject();
 352      }
 353  
 354      /**
 355       * Method to remove map entries for a link.
 356       *
 357       * @param   integer  $linkId  The link to remove.
 358       *
 359       * @return  boolean  True on success.
 360       *
 361       * @since   2.5
 362       * @throws  \RuntimeException on database error.
 363       */
 364      public static function removeMaps($linkId)
 365      {
 366          // Delete the maps.
 367          $db = Factory::getDbo();
 368          $query = $db->getQuery(true)
 369              ->delete($db->quoteName('#__finder_taxonomy_map'))
 370              ->where($db->quoteName('link_id') . ' = ' . (int) $linkId);
 371          $db->setQuery($query);
 372          $db->execute();
 373  
 374          return true;
 375      }
 376  
 377      /**
 378       * Method to remove orphaned taxonomy maps
 379       *
 380       * @return  integer  The number of deleted rows.
 381       *
 382       * @since   4.2.0
 383       * @throws  \RuntimeException on database error.
 384       */
 385      public static function removeOrphanMaps()
 386      {
 387          // Delete all orphaned maps
 388          $db = Factory::getDbo();
 389          $query2 = $db->getQuery(true)
 390              ->select($db->quoteName('link_id'))
 391              ->from($db->quoteName('#__finder_links'));
 392          $query = $db->getQuery(true)
 393              ->delete($db->quoteName('#__finder_taxonomy_map'))
 394              ->where($db->quoteName('link_id') . ' NOT IN (' . $query2 . ')');
 395          $db->setQuery($query);
 396          $db->execute();
 397          $count = $db->getAffectedRows();
 398  
 399          return $count;
 400      }
 401  
 402      /**
 403       * Method to remove orphaned taxonomy nodes and branches.
 404       *
 405       * @return  integer  The number of deleted rows.
 406       *
 407       * @since   2.5
 408       * @throws  \RuntimeException on database error.
 409       */
 410      public static function removeOrphanNodes()
 411      {
 412          // Delete all orphaned nodes.
 413          $affectedRows = 0;
 414          $db           = Factory::getDbo();
 415          $nodeTable    = new MapTable($db);
 416          $query        = $db->getQuery(true);
 417  
 418          $query->select($db->quoteName('t.id'))
 419              ->from($db->quoteName('#__finder_taxonomy', 't'))
 420              ->join('LEFT', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.node_id') . '=' . $db->quoteName('t.id'))
 421              ->where($db->quoteName('t.parent_id') . ' > 1 ')
 422              ->where('t.lft + 1 = t.rgt')
 423              ->where($db->quoteName('m.link_id') . ' IS NULL');
 424  
 425          do {
 426              $db->setQuery($query);
 427              $nodes = $db->loadColumn();
 428  
 429              foreach ($nodes as $node) {
 430                  $nodeTable->delete($node);
 431                  $affectedRows++;
 432              }
 433          } while ($nodes);
 434  
 435          return $affectedRows;
 436      }
 437  
 438      /**
 439       * Get a taxonomy based on its id or all taxonomies
 440       *
 441       * @param   integer  $id  Id of the taxonomy
 442       *
 443       * @return  object|array  A taxonomy object or an array of all taxonomies
 444       *
 445       * @since   4.0.0
 446       */
 447      public static function getTaxonomy($id = 0)
 448      {
 449          if (!count(self::$taxonomies)) {
 450              $db    = Factory::getDbo();
 451              $query = $db->getQuery(true);
 452  
 453              $query->select(array('id','parent_id','lft','rgt','level','path','title','alias','state','access','language'))
 454                  ->from($db->quoteName('#__finder_taxonomy'))
 455                  ->order($db->quoteName('lft'));
 456  
 457              $db->setQuery($query);
 458              self::$taxonomies = $db->loadObjectList('id');
 459          }
 460  
 461          if ($id == 0) {
 462              return self::$taxonomies;
 463          }
 464  
 465          if (isset(self::$taxonomies[$id])) {
 466              return self::$taxonomies[$id];
 467          }
 468  
 469          return false;
 470      }
 471  
 472      /**
 473       * Get a taxonomy branch object based on its title or all branches
 474       *
 475       * @param   string  $title  Title of the branch
 476       *
 477       * @return  object|array  The object with the branch data or an array of all branches
 478       *
 479       * @since   4.0.0
 480       */
 481      public static function getBranch($title = '')
 482      {
 483          if (!count(self::$branches)) {
 484              $taxonomies = self::getTaxonomy();
 485  
 486              foreach ($taxonomies as $t) {
 487                  if ($t->level == 1) {
 488                      self::$branches[$t->title] = $t;
 489                  }
 490              }
 491          }
 492  
 493          if ($title == '') {
 494              return self::$branches;
 495          }
 496  
 497          if (isset(self::$branches[$title])) {
 498              return self::$branches[$title];
 499          }
 500  
 501          return false;
 502      }
 503  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer