[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Administrator 5 * @subpackage com_scheduler 6 * 7 * @copyright (C) 2021 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\Scheduler\Administrator\Table; 12 13 use Joomla\CMS\Event\AbstractEvent; 14 use Joomla\CMS\Factory; 15 use Joomla\CMS\Language\Text; 16 use Joomla\CMS\MVC\Model\AdminModel; 17 use Joomla\CMS\Table\Asset; 18 use Joomla\CMS\Table\Table; 19 use Joomla\Database\DatabaseDriver; 20 use Joomla\Database\Exception\QueryTypeAlreadyDefinedException; 21 22 // phpcs:disable PSR1.Files.SideEffects 23 \defined('_JEXEC') or die; 24 // phpcs:enable PSR1.Files.SideEffects 25 26 /** 27 * Table class for tasks scheduled through `com_scheduler`. 28 * The type alias for Task table entries is `com_scheduler.task`. 29 * 30 * @since 4.1.0 31 */ 32 class TaskTable extends Table 33 { 34 /** 35 * Indicates that columns fully support the NULL value in the database 36 * 37 * @var boolean 38 * @since 4.1.1 39 */ 40 protected $_supportNullValue = true; 41 42 /** 43 * Ensure params are json encoded by the bind method. 44 * 45 * @var string[] 46 * @since 4.1.0 47 */ 48 protected $_jsonEncode = ['params', 'execution_rules', 'cron_rules']; 49 50 /** 51 * The 'created' column. 52 * 53 * @var string 54 * @since 4.1.0 55 */ 56 public $created; 57 58 /** 59 * The 'title' column. 60 * 61 * @var string 62 * @since 4.1.0 63 */ 64 public $title; 65 66 /** 67 * @var string 68 * @since 4.1.0 69 */ 70 public $typeAlias = 'com_scheduler.task'; 71 72 /** 73 * TaskTable constructor override, needed to pass the DB table name and primary key to {@see Table::__construct()}. 74 * 75 * @param DatabaseDriver $db A database connector object. 76 * 77 * @since 4.1.0 78 */ 79 public function __construct(DatabaseDriver $db) 80 { 81 $this->setColumnAlias('published', 'state'); 82 83 parent::__construct('#__scheduler_tasks', 'id', $db); 84 } 85 86 /** 87 * Overloads {@see Table::check()} to perform sanity checks on properties and make sure they're 88 * safe to store. 89 * 90 * @return boolean True if checks pass. 91 * 92 * @since 4.1.0 93 * @throws \Exception 94 */ 95 public function check(): bool 96 { 97 try { 98 parent::check(); 99 } catch (\Exception $e) { 100 Factory::getApplication()->enqueueMessage($e->getMessage()); 101 102 return false; 103 } 104 105 $this->title = htmlspecialchars_decode($this->title, ENT_QUOTES); 106 107 // Set created date if not set. 108 // ? Might not need since the constructor already sets this 109 if (!(int) $this->created) { 110 $this->created = Factory::getDate()->toSql(); 111 } 112 113 // @todo : Add more checks if needed 114 115 return true; 116 } 117 118 /** 119 * Override {@see Table::store()} to update null fields as a default, which is needed when DATETIME 120 * fields need to be updated to NULL. This override is needed because {@see AdminModel::save()} does not 121 * expose an option to pass true to Table::store(). Also ensures the `created` and `created_by` fields are 122 * set. 123 * 124 * @param boolean $updateNulls True to update fields even if they're null. 125 * 126 * @return boolean True if successful. 127 * 128 * @since 4.1.0 129 * @throws \Exception 130 */ 131 public function store($updateNulls = true): bool 132 { 133 $isNew = empty($this->getId()); 134 135 // Set creation date if not set for a new item. 136 if ($isNew && empty($this->created)) { 137 $this->created = Factory::getDate()->toSql(); 138 } 139 140 // Set `created_by` if not set for a new item. 141 if ($isNew && empty($this->created_by)) { 142 $this->created_by = Factory::getApplication()->getIdentity()->id; 143 } 144 145 // @todo : Should we add modified, modified_by fields? [ ] 146 147 return parent::store($updateNulls); 148 } 149 150 /** 151 * Returns the asset name of the entry as it appears in the {@see Asset} table. 152 * 153 * @return string The asset name. 154 * 155 * @since 4.1.0 156 */ 157 protected function _getAssetName(): string 158 { 159 $k = $this->_tbl_key; 160 161 return 'com_scheduler.task.' . (int) $this->$k; 162 } 163 164 /** 165 * Override {@see Table::bind()} to bind some fields even if they're null given they're present in $src. 166 * This override is needed specifically for DATETIME fields, of which the `next_execution` field is updated to 167 * null if a task is configured to execute only on manual trigger. 168 * 169 * @param array|object $src An associative array or object to bind to the Table instance. 170 * @param array|string $ignore An optional array or space separated list of properties to ignore while binding. 171 * 172 * @return boolean 173 * 174 * @since 4.1.0 175 */ 176 public function bind($src, $ignore = array()): bool 177 { 178 $fields = ['next_execution']; 179 180 foreach ($fields as $field) { 181 if (\array_key_exists($field, $src) && \is_null($src[$field])) { 182 $this->$field = $src[$field]; 183 } 184 } 185 186 return parent::bind($src, $ignore); 187 } 188 189 /** 190 * Release pseudo-locks on a set of task records. If an empty set is passed, this method releases lock on its 191 * instance primary key, if available. 192 * 193 * @param integer[] $pks An optional array of primary key values to update. If not set the instance property 194 * value is used. 195 * @param ?int $userId ID of the user unlocking the tasks. 196 * 197 * @return boolean True on success; false if $pks is empty. 198 * 199 * @since 4.1.0 200 * @throws QueryTypeAlreadyDefinedException|\UnexpectedValueException|\BadMethodCallException 201 */ 202 public function unlock(array $pks = [], ?int $userId = null): bool 203 { 204 // Pre-processing by observers 205 $event = AbstractEvent::create( 206 'onTaskBeforeUnlock', 207 [ 208 'subject' => $this, 209 'pks' => $pks, 210 'userId' => $userId, 211 ] 212 ); 213 214 $this->getDispatcher()->dispatch('onTaskBeforeUnlock', $event); 215 216 // Some pre-processing before we can work with the keys. 217 if (!empty($pks)) { 218 foreach ($pks as $key => $pk) { 219 if (!\is_array($pk)) { 220 $pks[$key] = array($this->_tbl_key => $pk); 221 } 222 } 223 } 224 225 // If there are no primary keys set check to see if the instance key is set and use that. 226 if (empty($pks)) { 227 $pk = []; 228 229 foreach ($this->_tbl_keys as $key) { 230 if ($this->$key) { 231 $pk[$key] = $this->$key; 232 } else { 233 // We don't have a full primary key - return false. 234 $this->setError(Text::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); 235 236 return false; 237 } 238 } 239 240 $pks = [$pk]; 241 } 242 243 $lockedField = $this->getColumnAlias('locked'); 244 245 foreach ($pks as $pk) { 246 // Update the publishing state for rows with the given primary keys. 247 $query = $this->_db->getQuery(true) 248 ->update($this->_tbl) 249 ->set($this->_db->quoteName($lockedField) . ' = NULL'); 250 251 // Build the WHERE clause for the primary keys. 252 $this->appendPrimaryKeys($query, $pk); 253 254 $this->_db->setQuery($query); 255 256 try { 257 $this->_db->execute(); 258 } catch (\RuntimeException $e) { 259 $this->setError($e->getMessage()); 260 261 return false; 262 } 263 264 // If the Table instance value is in the list of primary keys that were set, set the instance. 265 $ours = true; 266 267 foreach ($this->_tbl_keys as $key) { 268 if ($this->$key != $pk[$key]) { 269 $ours = false; 270 } 271 } 272 273 if ($ours) { 274 $this->$lockedField = null; 275 } 276 } 277 278 // Pre-processing by observers 279 $event = AbstractEvent::create( 280 'onTaskAfterUnlock', 281 [ 282 'subject' => $this, 283 'pks' => $pks, 284 'userId' => $userId, 285 ] 286 ); 287 288 $this->getDispatcher()->dispatch('onTaskAfterUnlock', $event); 289 290 return true; 291 } 292 }
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 |