[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE 8 */ 9 10 namespace Joomla\CMS\MVC\Model; 11 12 use Joomla\CMS\Component\ComponentHelper; 13 use Joomla\CMS\Factory; 14 use Joomla\CMS\Filesystem\Path; 15 use Joomla\CMS\Form\Form; 16 use Joomla\CMS\Language\Text; 17 use Joomla\CMS\Plugin\PluginHelper; 18 use Joomla\CMS\Workflow\Workflow; 19 20 // phpcs:disable PSR1.Files.SideEffects 21 \defined('JPATH_PLATFORM') or die; 22 // phpcs:enable PSR1.Files.SideEffects 23 24 /** 25 * Trait which supports state behavior 26 * 27 * @since 4.0.0 28 */ 29 trait WorkflowBehaviorTrait 30 { 31 /** 32 * The name of the component. 33 * 34 * @var string 35 * @since 4.0.0 36 */ 37 protected $extension = null; 38 39 /** 40 * The section of the component. 41 * 42 * @var string 43 * @since 4.0.0 44 */ 45 protected $section = ''; 46 47 /** 48 * Is workflow for this component enabled? 49 * 50 * @var boolean 51 * @since 4.0.0 52 */ 53 protected $workflowEnabled = false; 54 55 /** 56 * The workflow object 57 * 58 * @var Workflow 59 * @since 4.0.0 60 */ 61 protected $workflow; 62 63 /** 64 * Set Up the workflow 65 * 66 * @param string $extension The option and section separated by. 67 * 68 * @return void 69 * 70 * @since 4.0.0 71 */ 72 public function setUpWorkflow($extension) 73 { 74 $parts = explode('.', $extension); 75 76 $this->extension = array_shift($parts); 77 78 if (count($parts)) { 79 $this->section = array_shift($parts); 80 } 81 82 $this->workflow = new Workflow($extension); 83 84 $params = ComponentHelper::getParams($this->extension); 85 86 $this->workflowEnabled = $params->get('workflow_enabled'); 87 88 $this->enableWorkflowBatch(); 89 } 90 91 /** 92 * Add the workflow batch to the command list. Can be overwritten bei the child class 93 * 94 * @return void 95 * 96 * @since 4.0.0 97 */ 98 protected function enableWorkflowBatch() 99 { 100 // Enable batch 101 if ($this->workflowEnabled && property_exists($this, 'batch_commands')) { 102 $this->batch_commands['workflowstage_id'] = 'batchWorkflowStage'; 103 } 104 } 105 106 /** 107 * Method to allow derived classes to preprocess the form. 108 * 109 * @param Form $form A Form object. 110 * @param mixed $data The data expected for the form. 111 * 112 * @return void 113 * 114 * @since 4.0.0 115 * @see FormField 116 */ 117 public function workflowPreprocessForm(Form $form, $data) 118 { 119 $this->addTransitionField($form, $data); 120 121 if (!$this->workflowEnabled) { 122 return; 123 } 124 125 // Import the workflow plugin group to allow form manipulation. 126 $this->importWorkflowPlugins(); 127 } 128 129 /** 130 * Let plugins access stage change events 131 * 132 * @return void 133 * 134 * @since 4.0.0 135 */ 136 public function workflowBeforeStageChange() 137 { 138 if (!$this->workflowEnabled) { 139 return; 140 } 141 142 $this->importWorkflowPlugins(); 143 } 144 145 /** 146 * Preparation of workflow data/plugins 147 * 148 * @return void 149 * 150 * @since 4.0.0 151 */ 152 public function workflowBeforeSave() 153 { 154 if (!$this->workflowEnabled) { 155 return; 156 } 157 158 $this->importWorkflowPlugins(); 159 } 160 161 /** 162 * Executing of relevant workflow methods 163 * 164 * @return void 165 * 166 * @since 4.0.0 167 */ 168 public function workflowAfterSave($data) 169 { 170 // Regardless if workflow is active or not, we have to set the default stage 171 // So we can work with the workflow, when the user activates it later 172 $id = $this->getState($this->getName() . '.id'); 173 $isNew = $this->getState($this->getName() . '.new'); 174 175 // We save the first stage 176 if ($isNew) { 177 // We have to add the paths, because it could be called outside of the extension context 178 $path = JPATH_BASE . '/components/' . $this->extension; 179 180 $path = Path::check($path); 181 182 Form::addFormPath($path . '/forms'); 183 Form::addFormPath($path . '/models/forms'); 184 Form::addFieldPath($path . '/models/fields'); 185 Form::addFormPath($path . '/model/form'); 186 Form::addFieldPath($path . '/model/field'); 187 188 $form = $this->getForm(); 189 190 $stage_id = $this->getStageForNewItem($form, $data); 191 192 $this->workflow->createAssociation($id, $stage_id); 193 } 194 195 if (!$this->workflowEnabled) { 196 return; 197 } 198 199 // Execute transition 200 if (!empty($data['transition'])) { 201 $this->executeTransition([$id], $data['transition']); 202 } 203 } 204 205 /** 206 * Batch change workflow stage or current. 207 * 208 * @param integer $value The workflow stage ID. 209 * @param array $pks An array of row IDs. 210 * @param array $contexts An array of item contexts. 211 * 212 * @return mixed An array of new IDs on success, boolean false on failure. 213 * 214 * @since 4.0.0 215 */ 216 public function batchWorkflowStage(int $value, array $pks, array $contexts) 217 { 218 $user = Factory::getApplication()->getIdentity(); 219 220 $workflow = Factory::getApplication()->bootComponent('com_workflow'); 221 222 if (!$user->authorise('core.admin', $this->option)) { 223 $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EXECUTE_TRANSITION')); 224 } 225 226 // Get workflow stage information 227 $stage = $workflow->getMVCFactory()->createTable('Stage', 'Administrator'); 228 229 if (empty($value) || !$stage->load($value)) { 230 Factory::getApplication()->enqueueMessage(Text::sprintf('JGLOBAL_BATCH_WORKFLOW_STAGE_ROW_NOT_FOUND'), 'error'); 231 232 return false; 233 } 234 235 if (empty($pks)) { 236 Factory::getApplication()->enqueueMessage(Text::sprintf('JGLOBAL_BATCH_WORKFLOW_STAGE_ROW_NOT_FOUND'), 'error'); 237 238 return false; 239 } 240 241 // Update workflow associations 242 return $this->workflow->updateAssociations($pks, $value); 243 } 244 245 /** 246 * Batch change workflow stage or current. 247 * 248 * @param integer $oldId The ID of the item copied from 249 * @param integer $newId The ID of the new item 250 * 251 * @return null 252 * 253 * @since 4.0.0 254 */ 255 public function workflowCleanupBatchMove($oldId, $newId) 256 { 257 // Trigger workflow plugins only if enable (will be triggered from parent class) 258 if ($this->workflowEnabled) { 259 $this->importWorkflowPlugins(); 260 } 261 262 // We always need an association, so create one 263 $table = $this->getTable(); 264 265 $table->load($newId); 266 267 $catKey = $table->getColumnAlias('catid'); 268 269 $stage_id = $this->workflow->getDefaultStageByCategory($table->$catKey); 270 271 if (empty($stage_id)) { 272 return; 273 } 274 275 $this->workflow->createAssociation((int) $newId, (int) $stage_id); 276 } 277 278 /** 279 * Runs transition for item. 280 * 281 * @param array $pks Id of items to execute the transition 282 * @param integer $transitionId Id of transition 283 * 284 * @return boolean 285 * 286 * @since 4.0.0 287 */ 288 public function executeTransition(array $pks, int $transitionId) 289 { 290 $result = $this->workflow->executeTransition($pks, $transitionId); 291 292 if (!$result) { 293 $app = Factory::getApplication(); 294 295 $app->enqueueMessage(Text::_('COM_CONTENT_ERROR_UPDATE_STAGE', $app::MSG_WARNING)); 296 297 return false; 298 } 299 300 return true; 301 } 302 303 /** 304 * Import the Workflow plugins. 305 * 306 * @param Form $form A Form object. 307 * @param mixed $data The data expected for the form. 308 * 309 * @return void 310 */ 311 protected function importWorkflowPlugins() 312 { 313 PluginHelper::importPlugin('workflow'); 314 } 315 316 /** 317 * Adds a transition field to the form. Can be overwritten by the child class if not needed 318 * 319 * @param Form $form A Form object. 320 * @param mixed $data The data expected for the form. 321 * 322 * @return void 323 * @since 4.0.0 324 */ 325 protected function addTransitionField(Form $form, $data) 326 { 327 $extension = $this->extension . ($this->section ? '.' . $this->section : ''); 328 329 $field = new \SimpleXMLElement('<field></field>'); 330 331 $field->addAttribute('name', 'transition'); 332 $field->addAttribute('type', $this->workflowEnabled ? 'transition' : 'hidden'); 333 $field->addAttribute('label', 'COM_CONTENT_WORKFLOW'); 334 $field->addAttribute('extension', $extension); 335 336 $form->setField($field); 337 338 $table = $this->getTable(); 339 340 $key = $table->getKeyName(); 341 342 $id = isset($data->$key) ? $data->$key : $form->getValue($key); 343 344 if ($id) { 345 // Transition field 346 $assoc = $this->workflow->getAssociation($id); 347 348 if (!empty($assoc->stage_id)) { 349 $form->setFieldAttribute('transition', 'workflow_stage', (int) $assoc->stage_id); 350 } 351 } else { 352 $stage_id = $this->getStageForNewItem($form, $data); 353 354 if (!empty($stage_id)) { 355 $form->setFieldAttribute('transition', 'workflow_stage', (int) $stage_id); 356 } 357 } 358 } 359 360 /** 361 * Try to load a workflow stage for newly created items 362 * which does not have a workflow assigned yet. If the category is not the 363 * carrier, overwrite it on your model and deliver your own carrier. 364 * 365 * @param Form $form A Form object. 366 * @param mixed $data The data expected for the form. 367 * 368 * @return boolean|integer An integer, holding the stage ID or false 369 * @since 4.0.0 370 */ 371 protected function getStageForNewItem(Form $form, $data) 372 { 373 $table = $this->getTable(); 374 375 $hasKey = $table->hasField('catid'); 376 377 if (!$hasKey) { 378 return false; 379 } 380 381 $catKey = $table->getColumnAlias('catid'); 382 383 $field = $form->getField($catKey); 384 385 if (!$field) { 386 return false; 387 } 388 389 $catId = isset(((object) $data)->$catKey) ? ((object) $data)->$catKey : $form->getValue($catKey); 390 391 // Try to get the category from the html code of the field 392 if (empty($catId)) { 393 $catId = $field->getAttribute('default', null); 394 395 if (!$catId) { 396 // Choose the first category available 397 $catOptions = $field->options; 398 399 if ($catOptions && !empty($catOptions[0]->value)) { 400 $catId = (int) $catOptions[0]->value; 401 } 402 } 403 } 404 405 if (empty($catId)) { 406 return false; 407 } 408 409 return $this->workflow->getDefaultStageByCategory($catId); 410 } 411 }
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 |