[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |