[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_finder/src/Model/ -> IndexModel.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\Model;
  12  
  13  use Joomla\CMS\Component\ComponentHelper;
  14  use Joomla\CMS\Factory;
  15  use Joomla\CMS\Language\Text;
  16  use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
  17  use Joomla\CMS\MVC\Model\ListModel;
  18  use Joomla\CMS\Plugin\PluginHelper;
  19  
  20  // phpcs:disable PSR1.Files.SideEffects
  21  \defined('_JEXEC') or die;
  22  // phpcs:enable PSR1.Files.SideEffects
  23  
  24  /**
  25   * Index model class for Finder.
  26   *
  27   * @since  2.5
  28   */
  29  class IndexModel extends ListModel
  30  {
  31      /**
  32       * The event to trigger after deleting the data.
  33       *
  34       * @var    string
  35       * @since  2.5
  36       */
  37      protected $event_after_delete = 'onContentAfterDelete';
  38  
  39      /**
  40       * The event to trigger before deleting the data.
  41       *
  42       * @var    string
  43       * @since  2.5
  44       */
  45      protected $event_before_delete = 'onContentBeforeDelete';
  46  
  47      /**
  48       * The event to trigger after purging the data.
  49       *
  50       * @var    string
  51       * @since  4.0.0
  52       */
  53      protected $event_after_purge = 'onFinderIndexAfterPurge';
  54  
  55      /**
  56       * Constructor.
  57       *
  58       * @param   array                $config   An optional associative array of configuration settings.
  59       * @param   MVCFactoryInterface  $factory  The factory.
  60       *
  61       * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel
  62       * @since   3.7
  63       */
  64      public function __construct($config = array(), MVCFactoryInterface $factory = null)
  65      {
  66          if (empty($config['filter_fields'])) {
  67              $config['filter_fields'] = array(
  68                  'state', 'published', 'l.published',
  69                  'title', 'l.title',
  70                  'type', 'type_id', 'l.type_id',
  71                  't.title', 't_title',
  72                  'url', 'l.url',
  73                  'language', 'l.language',
  74                  'indexdate', 'l.indexdate',
  75                  'content_map',
  76              );
  77          }
  78  
  79          parent::__construct($config, $factory);
  80      }
  81  
  82      /**
  83       * Method to test whether a record can be deleted.
  84       *
  85       * @param   object  $record  A record object.
  86       *
  87       * @return  boolean  True if allowed to delete the record. Defaults to the permission for the component.
  88       *
  89       * @since   2.5
  90       */
  91      protected function canDelete($record)
  92      {
  93          return Factory::getUser()->authorise('core.delete', $this->option);
  94      }
  95  
  96      /**
  97       * Method to test whether a record can have its state changed.
  98       *
  99       * @param   object  $record  A record object.
 100       *
 101       * @return  boolean  True if allowed to change the state of the record. Defaults to the permission for the component.
 102       *
 103       * @since   2.5
 104       */
 105      protected function canEditState($record)
 106      {
 107          return Factory::getUser()->authorise('core.edit.state', $this->option);
 108      }
 109  
 110      /**
 111       * Method to delete one or more records.
 112       *
 113       * @param   array  $pks  An array of record primary keys.
 114       *
 115       * @return  boolean  True if successful, false if an error occurs.
 116       *
 117       * @since   2.5
 118       */
 119      public function delete(&$pks)
 120      {
 121          $pks = (array) $pks;
 122          $table = $this->getTable();
 123  
 124          // Include the content plugins for the on delete events.
 125          PluginHelper::importPlugin('content');
 126  
 127          // Iterate the items to delete each one.
 128          foreach ($pks as $i => $pk) {
 129              if ($table->load($pk)) {
 130                  if ($this->canDelete($table)) {
 131                      $context = $this->option . '.' . $this->name;
 132  
 133                      // Trigger the onContentBeforeDelete event.
 134                      $result = Factory::getApplication()->triggerEvent($this->event_before_delete, array($context, $table));
 135  
 136                      if (in_array(false, $result, true)) {
 137                          $this->setError($table->getError());
 138  
 139                          return false;
 140                      }
 141  
 142                      if (!$table->delete($pk)) {
 143                          $this->setError($table->getError());
 144  
 145                          return false;
 146                      }
 147  
 148                      // Trigger the onContentAfterDelete event.
 149                      Factory::getApplication()->triggerEvent($this->event_after_delete, array($context, $table));
 150                  } else {
 151                      // Prune items that you can't change.
 152                      unset($pks[$i]);
 153                      $error = $this->getError();
 154  
 155                      if ($error) {
 156                          $this->setError($error);
 157                      } else {
 158                          $this->setError(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'));
 159                      }
 160                  }
 161              } else {
 162                  $this->setError($table->getError());
 163  
 164                  return false;
 165              }
 166          }
 167  
 168          // Clear the component's cache
 169          $this->cleanCache();
 170  
 171          return true;
 172      }
 173  
 174      /**
 175       * Build an SQL query to load the list data.
 176       *
 177       * @return  \Joomla\Database\DatabaseQuery
 178       *
 179       * @since   2.5
 180       */
 181      protected function getListQuery()
 182      {
 183          $db = $this->getDatabase();
 184          $query = $db->getQuery(true)
 185              ->select('l.*')
 186              ->select($db->quoteName('t.title', 't_title'))
 187              ->from($db->quoteName('#__finder_links', 'l'))
 188              ->join('INNER', $db->quoteName('#__finder_types', 't') . ' ON ' . $db->quoteName('t.id') . ' = ' . $db->quoteName('l.type_id'));
 189  
 190          // Check the type filter.
 191          $type = $this->getState('filter.type');
 192  
 193          // Join over the language
 194          $query->select('la.title AS language_title, la.image AS language_image')
 195              ->join('LEFT', $db->quoteName('#__languages') . ' AS la ON la.lang_code = l.language');
 196  
 197          if (is_numeric($type)) {
 198              $query->where($db->quoteName('l.type_id') . ' = ' . (int) $type);
 199          }
 200  
 201          // Check the map filter.
 202          $contentMapId = $this->getState('filter.content_map');
 203  
 204          if (is_numeric($contentMapId)) {
 205              $query->join('INNER', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.link_id') . ' = ' . $db->quoteName('l.link_id'))
 206                  ->where($db->quoteName('m.node_id') . ' = ' . (int) $contentMapId);
 207          }
 208  
 209          // Check for state filter.
 210          $state = $this->getState('filter.state');
 211  
 212          if (is_numeric($state)) {
 213              $query->where($db->quoteName('l.published') . ' = ' . (int) $state);
 214          }
 215  
 216          // Filter on the language.
 217          if ($language = $this->getState('filter.language')) {
 218              $query->where($db->quoteName('l.language') . ' = ' . $db->quote($language));
 219          }
 220  
 221          // Check the search phrase.
 222          $search = $this->getState('filter.search');
 223  
 224          if (!empty($search)) {
 225              $search      = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%'));
 226              $orSearchSql = $db->quoteName('l.title') . ' LIKE ' . $search . ' OR ' . $db->quoteName('l.url') . ' LIKE ' . $search;
 227  
 228              // Filter by indexdate only if $search doesn't contains non-ascii characters
 229              if (!preg_match('/[^\x00-\x7F]/', $search)) {
 230                  $orSearchSql .= ' OR ' . $query->castAsChar($db->quoteName('l.indexdate')) . ' LIKE ' . $search;
 231              }
 232  
 233              $query->where('(' . $orSearchSql . ')');
 234          }
 235  
 236          // Handle the list ordering.
 237          $listOrder = $this->getState('list.ordering', 'l.title');
 238          $listDir   = $this->getState('list.direction', 'ASC');
 239  
 240          if ($listOrder === 't.title') {
 241              $ordering = $db->quoteName('t.title') . ' ' . $db->escape($listDir) . ', ' . $db->quoteName('l.title') . ' ' . $db->escape($listDir);
 242          } else {
 243              $ordering = $db->escape($listOrder) . ' ' . $db->escape($listDir);
 244          }
 245  
 246          $query->order($ordering);
 247  
 248          return $query;
 249      }
 250  
 251      /**
 252       * Method to get the state of the Smart Search Plugins.
 253       *
 254       * @return  array  Array of relevant plugins and whether they are enabled or not.
 255       *
 256       * @since   2.5
 257       */
 258      public function getPluginState()
 259      {
 260          $db = $this->getDatabase();
 261          $query = $db->getQuery(true)
 262              ->select('name, enabled')
 263              ->from($db->quoteName('#__extensions'))
 264              ->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
 265              ->where($db->quoteName('folder') . ' IN (' . $db->quote('system') . ',' . $db->quote('content') . ')')
 266              ->where($db->quoteName('element') . ' = ' . $db->quote('finder'));
 267          $db->setQuery($query);
 268  
 269          return $db->loadObjectList('name');
 270      }
 271  
 272      /**
 273       * Method to get a store id based on model configuration state.
 274       *
 275       * This is necessary because the model is used by the component and
 276       * different modules that might need different sets of data or different
 277       * ordering requirements.
 278       *
 279       * @param   string  $id  A prefix for the store id. [optional]
 280       *
 281       * @return  string  A store id.
 282       *
 283       * @since   2.5
 284       */
 285      protected function getStoreId($id = '')
 286      {
 287          // Compile the store id.
 288          $id .= ':' . $this->getState('filter.search');
 289          $id .= ':' . $this->getState('filter.state');
 290          $id .= ':' . $this->getState('filter.type');
 291          $id .= ':' . $this->getState('filter.content_map');
 292  
 293          return parent::getStoreId($id);
 294      }
 295  
 296      /**
 297       * Gets the total of indexed items.
 298       *
 299       * @return  integer  The total of indexed items.
 300       *
 301       * @since   3.6.0
 302       */
 303      public function getTotalIndexed()
 304      {
 305          $db = $this->getDatabase();
 306          $query = $db->getQuery(true)
 307              ->select('COUNT(link_id)')
 308              ->from($db->quoteName('#__finder_links'));
 309          $db->setQuery($query);
 310  
 311          return (int) $db->loadResult();
 312      }
 313  
 314      /**
 315       * Returns a Table object, always creating it.
 316       *
 317       * @param   string  $type    The table type to instantiate. [optional]
 318       * @param   string  $prefix  A prefix for the table class name. [optional]
 319       * @param   array   $config  Configuration array for model. [optional]
 320       *
 321       * @return  \Joomla\CMS\Table\Table  A database object
 322       *
 323       * @since   2.5
 324       */
 325      public function getTable($type = 'Link', $prefix = 'Administrator', $config = array())
 326      {
 327          return parent::getTable($type, $prefix, $config);
 328      }
 329  
 330      /**
 331       * Method to purge the index, deleting all links.
 332       *
 333       * @return  boolean  True on success, false on failure.
 334       *
 335       * @since   2.5
 336       * @throws  \Exception on database error
 337       */
 338      public function purge()
 339      {
 340          $db = $this->getDatabase();
 341  
 342          // Truncate the links table.
 343          $db->truncateTable('#__finder_links');
 344  
 345          // Truncate the links terms tables.
 346          $db->truncateTable('#__finder_links_terms');
 347  
 348          // Truncate the terms table.
 349          $db->truncateTable('#__finder_terms');
 350  
 351          // Truncate the taxonomy map table.
 352          $db->truncateTable('#__finder_taxonomy_map');
 353  
 354          // Truncate the taxonomy table and insert the root node.
 355          $db->truncateTable('#__finder_taxonomy');
 356          $root = (object) array(
 357              'id' => 1,
 358              'parent_id' => 0,
 359              'lft' => 0,
 360              'rgt' => 1,
 361              'level' => 0,
 362              'path' => '',
 363              'title' => 'ROOT',
 364              'alias' => 'root',
 365              'state' => 1,
 366              'access' => 1,
 367              'language' => '*'
 368          );
 369          $db->insertObject('#__finder_taxonomy', $root);
 370  
 371          // Truncate the tokens tables.
 372          $db->truncateTable('#__finder_tokens');
 373  
 374          // Truncate the tokens aggregate table.
 375          $db->truncateTable('#__finder_tokens_aggregate');
 376  
 377          // Include the finder plugins for the on purge events.
 378          PluginHelper::importPlugin('finder');
 379          Factory::getApplication()->triggerEvent($this->event_after_purge);
 380  
 381          return true;
 382      }
 383  
 384      /**
 385       * Method to auto-populate the model state.  Calling getState in this method will result in recursion.
 386       *
 387       * @param   string  $ordering   An optional ordering field. [optional]
 388       * @param   string  $direction  An optional direction. [optional]
 389       *
 390       * @return  void
 391       *
 392       * @since   2.5
 393       */
 394      protected function populateState($ordering = 'l.title', $direction = 'asc')
 395      {
 396          // Load the filter state.
 397          $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string'));
 398          $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd'));
 399          $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'cmd'));
 400          $this->setState('filter.content_map', $this->getUserStateFromRequest($this->context . '.filter.content_map', 'filter_content_map', '', 'cmd'));
 401          $this->setState('filter.language', $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''));
 402  
 403          // Load the parameters.
 404          $params = ComponentHelper::getParams('com_finder');
 405          $this->setState('params', $params);
 406  
 407          // List state information.
 408          parent::populateState($ordering, $direction);
 409      }
 410  
 411      /**
 412       * Method to change the published state of one or more records.
 413       *
 414       * @param   array    $pks    A list of the primary keys to change.
 415       * @param   integer  $value  The value of the published state. [optional]
 416       *
 417       * @return  boolean  True on success.
 418       *
 419       * @since   2.5
 420       */
 421      public function publish(&$pks, $value = 1)
 422      {
 423          $user = Factory::getUser();
 424          $table = $this->getTable();
 425          $pks = (array) $pks;
 426  
 427          // Include the content plugins for the change of state event.
 428          PluginHelper::importPlugin('content');
 429  
 430          // Access checks.
 431          foreach ($pks as $i => $pk) {
 432              $table->reset();
 433  
 434              if ($table->load($pk) && !$this->canEditState($table)) {
 435                  // Prune items that you can't change.
 436                  unset($pks[$i]);
 437                  $this->setError(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
 438  
 439                  return false;
 440              }
 441          }
 442  
 443          // Attempt to change the state of the records.
 444          if (!$table->publish($pks, $value, $user->get('id'))) {
 445              $this->setError($table->getError());
 446  
 447              return false;
 448          }
 449  
 450          $context = $this->option . '.' . $this->name;
 451  
 452          // Trigger the onContentChangeState event.
 453          $result = Factory::getApplication()->triggerEvent('onContentChangeState', array($context, $pks, $value));
 454  
 455          if (in_array(false, $result, true)) {
 456              $this->setError($table->getError());
 457  
 458              return false;
 459          }
 460  
 461          // Clear the component's cache
 462          $this->cleanCache();
 463  
 464          return true;
 465      }
 466  }


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