[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/components/com_banners/src/Model/ -> BannersModel.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Site
   5   * @subpackage  com_banners
   6   *
   7   * @copyright   (C) 2009 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\Banners\Site\Model;
  12  
  13  use Joomla\CMS\Component\ComponentHelper;
  14  use Joomla\CMS\Factory;
  15  use Joomla\CMS\MVC\Model\ListModel;
  16  use Joomla\Database\DatabaseQuery;
  17  use Joomla\Database\Exception\ExecutionFailureException;
  18  use Joomla\Database\ParameterType;
  19  use Joomla\Registry\Registry;
  20  use Joomla\Utilities\ArrayHelper;
  21  
  22  // phpcs:disable PSR1.Files.SideEffects
  23  \defined('_JEXEC') or die;
  24  // phpcs:enable PSR1.Files.SideEffects
  25  
  26  /**
  27   * Banners model for the Joomla Banners component.
  28   *
  29   * @since  1.6
  30   */
  31  class BannersModel extends ListModel
  32  {
  33      /**
  34       * Method to get a store id based on model configuration state.
  35       *
  36       * This is necessary because the model is used by the component and
  37       * different modules that might need different sets of data or different
  38       * ordering requirements.
  39       *
  40       * @param   string  $id  A prefix for the store id.
  41       *
  42       * @return  string  A store id.
  43       *
  44       * @since   1.6
  45       */
  46      protected function getStoreId($id = '')
  47      {
  48          // Compile the store id.
  49          $id .= ':' . $this->getState('filter.search');
  50          $id .= ':' . $this->getState('filter.tag_search');
  51          $id .= ':' . $this->getState('filter.client_id');
  52          $id .= ':' . serialize($this->getState('filter.category_id'));
  53          $id .= ':' . serialize($this->getState('filter.keywords'));
  54  
  55          return parent::getStoreId($id);
  56      }
  57  
  58      /**
  59       * Method to get a DatabaseQuery object for retrieving the data set from a database.
  60       *
  61       * @return  DatabaseQuery   A DatabaseQuery object to retrieve the data set.
  62       *
  63       * @since   1.6
  64       */
  65      protected function getListQuery()
  66      {
  67          $db         = $this->getDatabase();
  68          $query      = $db->getQuery(true);
  69          $ordering   = $this->getState('filter.ordering');
  70          $tagSearch  = $this->getState('filter.tag_search');
  71          $cid        = (int) $this->getState('filter.client_id');
  72          $categoryId = $this->getState('filter.category_id');
  73          $keywords   = $this->getState('filter.keywords');
  74          $randomise  = ($ordering === 'random');
  75          $nowDate    = Factory::getDate()->toSql();
  76  
  77          $query->select(
  78              [
  79                  $db->quoteName('a.id'),
  80                  $db->quoteName('a.type'),
  81                  $db->quoteName('a.name'),
  82                  $db->quoteName('a.clickurl'),
  83                  $db->quoteName('a.sticky'),
  84                  $db->quoteName('a.cid'),
  85                  $db->quoteName('a.description'),
  86                  $db->quoteName('a.params'),
  87                  $db->quoteName('a.custombannercode'),
  88                  $db->quoteName('a.track_impressions'),
  89                  $db->quoteName('cl.track_impressions', 'client_track_impressions'),
  90              ]
  91          )
  92              ->from($db->quoteName('#__banners', 'a'))
  93              ->join('LEFT', $db->quoteName('#__banner_clients', 'cl'), $db->quoteName('cl.id') . ' = ' . $db->quoteName('a.cid'))
  94              ->where($db->quoteName('a.state') . ' = 1')
  95              ->extendWhere(
  96                  'AND',
  97                  [
  98                      $db->quoteName('a.publish_up') . ' IS NULL',
  99                      $db->quoteName('a.publish_up') . ' <= :nowDate1',
 100                  ],
 101                  'OR'
 102              )
 103              ->extendWhere(
 104                  'AND',
 105                  [
 106                      $db->quoteName('a.publish_down') . ' IS NULL',
 107                      $db->quoteName('a.publish_down') . ' >= :nowDate2',
 108                  ],
 109                  'OR'
 110              )
 111              ->extendWhere(
 112                  'AND',
 113                  [
 114                      $db->quoteName('a.imptotal') . ' = 0',
 115                      $db->quoteName('a.impmade') . ' < ' . $db->quoteName('a.imptotal'),
 116                  ],
 117                  'OR'
 118              )
 119              ->bind([':nowDate1', ':nowDate2'], $nowDate);
 120  
 121          if ($cid) {
 122              $query->where(
 123                  [
 124                      $db->quoteName('a.cid') . ' = :clientId',
 125                      $db->quoteName('cl.state') . ' = 1',
 126                  ]
 127              )
 128                  ->bind(':clientId', $cid, ParameterType::INTEGER);
 129          }
 130  
 131          // Filter by a single or group of categories
 132          if (is_numeric($categoryId)) {
 133              $categoryId = (int) $categoryId;
 134              $type = $this->getState('filter.category_id.include', true) ? ' = ' : ' <> ';
 135  
 136              // Add subcategory check
 137              if ($this->getState('filter.subcategories', false)) {
 138                  $levels = (int) $this->getState('filter.max_category_levels', '1');
 139  
 140                  // Create a subquery for the subcategory list
 141                  $subQuery = $db->getQuery(true);
 142                  $subQuery->select($db->quoteName('sub.id'))
 143                      ->from($db->quoteName('#__categories', 'sub'))
 144                      ->join(
 145                          'INNER',
 146                          $db->quoteName('#__categories', 'this'),
 147                          $db->quoteName('sub.lft') . ' > ' . $db->quoteName('this.lft')
 148                          . ' AND ' . $db->quoteName('sub.rgt') . ' < ' . $db->quoteName('this.rgt')
 149                      )
 150                      ->where(
 151                          [
 152                              $db->quoteName('this.id') . ' = :categoryId1',
 153                              $db->quoteName('sub.level') . ' <= ' . $db->quoteName('this.level') . ' + :levels',
 154                          ]
 155                      );
 156  
 157                  // Add the subquery to the main query
 158                  $query->extendWhere(
 159                      'AND',
 160                      [
 161                          $db->quoteName('a.catid') . $type . ':categoryId2',
 162                          $db->quoteName('a.catid') . ' IN (' . $subQuery . ')',
 163                      ],
 164                      'OR'
 165                  )
 166                      ->bind([':categoryId1', ':categoryId2'], $categoryId, ParameterType::INTEGER)
 167                      ->bind(':levels', $levels, ParameterType::INTEGER);
 168              } else {
 169                  $query->where($db->quoteName('a.catid') . $type . ':categoryId')
 170                      ->bind(':categoryId', $categoryId, ParameterType::INTEGER);
 171              }
 172          } elseif (is_array($categoryId) && (count($categoryId) > 0)) {
 173              $categoryId = ArrayHelper::toInteger($categoryId);
 174  
 175              if ($this->getState('filter.category_id.include', true)) {
 176                  $query->whereIn($db->quoteName('a.catid'), $categoryId);
 177              } else {
 178                  $query->whereNotIn($db->quoteName('a.catid'), $categoryId);
 179              }
 180          }
 181  
 182          if ($tagSearch) {
 183              if (!$keywords) {
 184                  // No keywords, select nothing.
 185                  $query->where('0 != 0');
 186              } else {
 187                  $temp   = array();
 188                  $config = ComponentHelper::getParams('com_banners');
 189                  $prefix = $config->get('metakey_prefix');
 190  
 191                  if ($categoryId) {
 192                      $query->join('LEFT', $db->quoteName('#__categories', 'cat'), $db->quoteName('a.catid') . ' = ' . $db->quoteName('cat.id'));
 193                  }
 194  
 195                  foreach ($keywords as $key => $keyword) {
 196                      $regexp       = '[[:<:]]' . $keyword . '[[:>:]]';
 197                      $valuesToBind = [$keyword, $keyword, $regexp];
 198  
 199                      if ($cid) {
 200                          $valuesToBind[] = $regexp;
 201                      }
 202  
 203                      if ($categoryId) {
 204                          $valuesToBind[] = $regexp;
 205                      }
 206  
 207                      // Because values to $query->bind() are passed by reference, using $query->bindArray() here instead to prevent overwriting.
 208                      $bounded = $query->bindArray($valuesToBind, ParameterType::STRING);
 209  
 210                      $condition1 = $db->quoteName('a.own_prefix') . ' = 1'
 211                          . ' AND ' . $db->quoteName('a.metakey_prefix')
 212                          . ' = SUBSTRING(' . $bounded[0] . ',1,LENGTH(' . $db->quoteName('a.metakey_prefix') . '))'
 213                          . ' OR ' . $db->quoteName('a.own_prefix') . ' = 0'
 214                          . ' AND ' . $db->quoteName('cl.own_prefix') . ' = 1'
 215                          . ' AND ' . $db->quoteName('cl.metakey_prefix')
 216                          . ' = SUBSTRING(' . $bounded[1] . ',1,LENGTH(' . $db->quoteName('cl.metakey_prefix') . '))'
 217                          . ' OR ' . $db->quoteName('a.own_prefix') . ' = 0'
 218                          . ' AND ' . $db->quoteName('cl.own_prefix') . ' = 0'
 219                          . ' AND ' . ($prefix == substr($keyword, 0, strlen($prefix)) ? '0 = 0' : '0 != 0');
 220  
 221                      $condition2 = $db->quoteName('a.metakey') . ' ' . $query->regexp($bounded[2]);
 222  
 223                      if ($cid) {
 224                          $condition2 .= ' OR ' . $db->quoteName('cl.metakey') . ' ' . $query->regexp($bounded[3]) . ' ';
 225                      }
 226  
 227                      if ($categoryId) {
 228                          $condition2 .= ' OR ' . $db->quoteName('cat.metakey') . ' ' . $query->regexp($bounded[4]) . ' ';
 229                      }
 230  
 231                      $temp[] = "($condition1) AND ($condition2)";
 232                  }
 233  
 234                  $query->where('(' . implode(' OR ', $temp) . ')');
 235              }
 236          }
 237  
 238          // Filter by language
 239          if ($this->getState('filter.language')) {
 240              $query->whereIn($db->quoteName('a.language'), [Factory::getLanguage()->getTag(), '*'], ParameterType::STRING);
 241          }
 242  
 243          $query->order($db->quoteName('a.sticky') . ' DESC, ' . ($randomise ? $query->rand() : $db->quoteName('a.ordering')));
 244  
 245          return $query;
 246      }
 247  
 248      /**
 249       * Get a list of banners.
 250       *
 251       * @return  array
 252       *
 253       * @since   1.6
 254       */
 255      public function getItems()
 256      {
 257          if ($this->getState('filter.tag_search')) {
 258              // Filter out empty keywords.
 259              $keywords = array_values(array_filter(array_map('trim', $this->getState('filter.keywords')), 'strlen'));
 260  
 261              // Re-set state before running the query.
 262              $this->setState('filter.keywords', $keywords);
 263  
 264              // If no keywords are provided, avoid running the query.
 265              if (!$keywords) {
 266                  $this->cache['items'] = array();
 267  
 268                  return $this->cache['items'];
 269              }
 270          }
 271  
 272          if (!isset($this->cache['items'])) {
 273              $this->cache['items'] = parent::getItems();
 274  
 275              foreach ($this->cache['items'] as &$item) {
 276                  $item->params = new Registry($item->params);
 277              }
 278          }
 279  
 280          return $this->cache['items'];
 281      }
 282  
 283      /**
 284       * Makes impressions on a list of banners
 285       *
 286       * @return  void
 287       *
 288       * @since   1.6
 289       * @throws  \Exception
 290       */
 291      public function impress()
 292      {
 293          $trackDate = Factory::getDate()->format('Y-m-d H:00:00');
 294          $trackDate = Factory::getDate($trackDate)->toSql();
 295          $items     = $this->getItems();
 296          $db        = $this->getDatabase();
 297          $bid       = [];
 298  
 299          if (!count($items)) {
 300              return;
 301          }
 302  
 303          foreach ($items as $item) {
 304              $bid[] = (int) $item->id;
 305          }
 306  
 307          // Increment impression made
 308          $query = $db->getQuery(true);
 309          $query->update($db->quoteName('#__banners'))
 310              ->set($db->quoteName('impmade') . ' = ' . $db->quoteName('impmade') . ' + 1')
 311              ->whereIn($db->quoteName('id'), $bid);
 312          $db->setQuery($query);
 313  
 314          try {
 315              $db->execute();
 316          } catch (ExecutionFailureException $e) {
 317              throw new \Exception($e->getMessage(), 500);
 318          }
 319  
 320          foreach ($items as $item) {
 321              // Track impressions
 322              $trackImpressions = $item->track_impressions;
 323  
 324              if ($trackImpressions < 0 && $item->cid) {
 325                  $trackImpressions = $item->client_track_impressions;
 326              }
 327  
 328              if ($trackImpressions < 0) {
 329                  $config           = ComponentHelper::getParams('com_banners');
 330                  $trackImpressions = $config->get('track_impressions');
 331              }
 332  
 333              if ($trackImpressions > 0) {
 334                  // Is track already created?
 335                  // Update count
 336                  $query = $db->getQuery(true);
 337                  $query->update($db->quoteName('#__banner_tracks'))
 338                      ->set($db->quoteName('count') . ' = ' . $db->quoteName('count') . ' + 1')
 339                      ->where(
 340                          [
 341                              $db->quoteName('track_type') . ' = 1',
 342                              $db->quoteName('banner_id') . ' = :id',
 343                              $db->quoteName('track_date') . ' = :trackDate',
 344                          ]
 345                      )
 346                      ->bind(':id', $item->id, ParameterType::INTEGER)
 347                      ->bind(':trackDate', $trackDate);
 348  
 349                  $db->setQuery($query);
 350  
 351                  try {
 352                      $db->execute();
 353                  } catch (ExecutionFailureException $e) {
 354                      throw new \Exception($e->getMessage(), 500);
 355                  }
 356  
 357                  if ($db->getAffectedRows() === 0) {
 358                      // Insert new count
 359                      $query = $db->getQuery(true);
 360                      $query->insert($db->quoteName('#__banner_tracks'))
 361                          ->columns(
 362                              [
 363                                  $db->quoteName('count'),
 364                                  $db->quoteName('track_type'),
 365                                  $db->quoteName('banner_id'),
 366                                  $db->quoteName('track_date'),
 367                              ]
 368                          )
 369                          ->values('1, 1, :id, :trackDate')
 370                          ->bind(':id', $item->id, ParameterType::INTEGER)
 371                          ->bind(':trackDate', $trackDate);
 372  
 373                      $db->setQuery($query);
 374  
 375                      try {
 376                          $db->execute();
 377                      } catch (ExecutionFailureException $e) {
 378                          throw new \Exception($e->getMessage(), 500);
 379                      }
 380                  }
 381              }
 382          }
 383      }
 384  }


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