workflow.module 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. <?php
  2. /**
  3. * @file
  4. * Support workflows made up of arbitrary states.
  5. */
  6. define('WORKFLOW_CREATION_STATE', 1);
  7. define('WORKFLOW_CREATION_DEFAULT_WEIGHT', -50);
  8. define('WORKFLOW_DELETION', 0);
  9. // Couldn't find a more elegant way to preserve translation.
  10. define('WORKFLOW_CREATION_STATE_NAME', 'creation');
  11. /**
  12. * Role ID for anonymous users.
  13. */
  14. // #2657072 brackets are added later to indicate a special role,
  15. // and distinguish from frequently used 'author' role.
  16. define('WORKFLOW_ROLE_AUTHOR_NAME', 'Author');
  17. define('WORKFLOW_ROLE_AUTHOR_RID', 'workflow_author');
  18. use Drupal\Core\Entity\EntityInterface;
  19. use Drupal\Core\Routing\RouteMatchInterface;
  20. use Drupal\Core\Session\AccountInterface;
  21. use Drupal\Core\Url;
  22. use Drupal\field\Entity\FieldStorageConfig;
  23. use Drupal\user\Entity\User;
  24. use Drupal\workflow\Entity\Workflow;
  25. use Drupal\workflow\Entity\WorkflowManager;
  26. use Drupal\workflow\Entity\WorkflowScheduledTransition;
  27. use Drupal\workflow\Entity\WorkflowState;
  28. use Drupal\workflow\Entity\WorkflowTransition;
  29. use Drupal\workflow\Entity\WorkflowTransitionInterface;
  30. \Drupal::moduleHandler()->loadInclude('workflow', 'inc', 'workflow.form');
  31. \Drupal::moduleHandler()->loadInclude('workflow', 'inc', 'workflow.field');
  32. /**********************************************************************
  33. * Info hooks.
  34. */
  35. /**
  36. * Implements hook_help().
  37. *
  38. * @param string $route_name
  39. * A route.
  40. *
  41. * @return string
  42. * The html output.
  43. */
  44. function workflow_help($route_name) {
  45. $output = '';
  46. switch ($route_name) {
  47. case 'help.page.workflow':
  48. $output .= '<h3>' . t('About') . '</h3>';
  49. $output .= '<p>' . t('The Workflow module adds a field to Entities to
  50. store field values as Workflow states. You can control "state transitions"
  51. and add action to specific transitions.') . '</p>';
  52. }
  53. return $output;
  54. }
  55. /**
  56. * Implements hook_hook_info().
  57. *
  58. * Allow adopters to place their hook implementations in either
  59. * their main module or in a module.workflow.inc file.
  60. */
  61. function workflow_hook_info() {
  62. $hooks['workflow'] = ['group' => 'workflow'];
  63. return $hooks;
  64. }
  65. /**********************************************************************
  66. * CRUD hooks.
  67. */
  68. /**
  69. * Implements hook_user_cancel().
  70. *
  71. * Update tables for deleted account, move account to user 0 (anon.)
  72. * ALERT: This may cause previously non-Anonymous posts to suddenly
  73. * be accessible to Anonymous.
  74. *
  75. * @param $edit
  76. * @param \Drupal\Core\Session\AccountInterface $account
  77. * An account object.
  78. * @param string $method
  79. *
  80. * @see hook_user_cancel()
  81. */
  82. function workflow_user_cancel($edit, AccountInterface $account, $method) {
  83. WorkflowManager::cancelUser($edit, $account, $method);
  84. }
  85. /**
  86. * Implements hook_user_delete().
  87. *
  88. * @param \Drupal\Core\Session\AccountInterface $account
  89. * An account object.
  90. *
  91. * @todo: hook_user_delete does not exist. hook_ENTITY_TYPE_delete?
  92. */
  93. function workflow_user_delete($account) {
  94. WorkflowManager::deleteUser($account);
  95. }
  96. /**
  97. * Implements hook_ENTITY_TYPE_insert().
  98. *
  99. * Is called when adding a new Workflow type.
  100. * The technical name for the Workflow entity is 'workflow_type'.
  101. *
  102. * @param \Drupal\Core\Entity\EntityInterface $entity
  103. * An Entity.
  104. */
  105. function workflow_workflow_type_insert(EntityInterface $entity) {
  106. WorkflowManager::participateUserRoles($entity);
  107. }
  108. /**
  109. * Implements hook_entity_insert().
  110. *
  111. * @param \Drupal\Core\Entity\EntityInterface $entity
  112. * An Entity.
  113. */
  114. function workflow_entity_insert(EntityInterface $entity) {
  115. // Execute updates in hook_presave() to revert executions,
  116. // Execute inserts in hook_insert, to have the Entity ID determined.
  117. _workflow_execute_transitions($entity);
  118. }
  119. /**
  120. * Implements hook_entity_presave().
  121. *
  122. * @param \Drupal\Core\Entity\EntityInterface $entity
  123. * An EntityInterface object.
  124. */
  125. function workflow_entity_presave(EntityInterface $entity) {
  126. if (!$entity->isNew()) {
  127. // Avoid a double call by hook_entity_presave and hook_entity_insert.
  128. _workflow_execute_transitions($entity);
  129. }
  130. }
  131. /**
  132. * Execute transitions. if prohibited, restore original field value.
  133. * - insert: use hook_insert(), to have the Entity ID determined when saving transitions.
  134. * - update: use hook_presave() to revert executions,
  135. * - so, do not use hook_update().
  136. *
  137. * @param \Drupal\Core\Entity\EntityInterface $entity
  138. * An Entity.
  139. */
  140. function _workflow_execute_transitions(EntityInterface $entity) {
  141. // Avoid this hook on workflow objects.
  142. if (WorkflowManager::isWorkflowEntityType($entity->getEntityTypeId())) {
  143. return;
  144. }
  145. // Execute/save the transitions fom the widgets in the entity form.
  146. WorkflowManager::executeTransitionsOfEntity($entity);
  147. }
  148. /**
  149. * Implements hook_entity_delete().
  150. *
  151. * Delete the corresponding workflow table records.
  152. *
  153. * @param \Drupal\Core\Entity\EntityInterface $entity
  154. * An Entity.
  155. */
  156. function workflow_entity_delete(EntityInterface $entity) {
  157. // @todo: test with multiple workflows.
  158. if (get_class($entity) == 'Drupal\field\Entity\FieldConfig'
  159. || get_class($entity) == 'Drupal\field\Entity\FieldStorageConfig') {
  160. // A Workflow Field is removed from an entity.
  161. $field_config = $entity;
  162. /** @var \Drupal\Core\Entity\ContentEntityBase $field_config */
  163. $entity_type = $field_config->get('entity_type');
  164. $field_name = $field_config->get('field_name');
  165. /** @var $transition Drupal\workflow\Entity\WorkflowTransitionInterface */
  166. foreach (WorkflowScheduledTransition::loadMultipleByProperties($entity_type, [], [], $field_name) as $transition) {
  167. $transition->delete();
  168. }
  169. foreach (WorkflowTransition::loadMultipleByProperties($entity_type, [], [], $field_name) as $transition) {
  170. $transition->delete();
  171. }
  172. }
  173. elseif (!WorkflowManager::isWorkflowEntityType($entity->getEntityTypeId())) {
  174. // A 'normal' entity is deleted.
  175. foreach ($fields = _workflow_info_fields($entity) as $field_id => $field_storage) {
  176. $entity_id = $entity->id();
  177. $entity_type = $field_storage->getTargetEntityTypeId();
  178. $field_name = $field_storage->getName();
  179. /** @var $transition Drupal\workflow\Entity\WorkflowTransitionInterface */
  180. foreach (WorkflowScheduledTransition::loadMultipleByProperties($entity_type, [$entity_id], [], $field_name) as $transition) {
  181. $transition->delete();
  182. }
  183. foreach (WorkflowTransition::loadMultipleByProperties($entity_type, [$entity_id], [], $field_name) as $transition) {
  184. $transition->delete();
  185. }
  186. }
  187. }
  188. }
  189. /**
  190. * Implements hook_cron().
  191. *
  192. * Given a time frame, execute all scheduled transitions.
  193. */
  194. function workflow_cron() {
  195. WorkflowManager::executeScheduledTransitionsBetween(0, \Drupal::time()->getRequestTime());
  196. }
  197. /**
  198. * Business related functions, the API.
  199. */
  200. /**
  201. * @param \Drupal\workflow\Entity\WorkflowTransitionInterface $transition
  202. * A WorkflowTransition.
  203. * @param bool $force
  204. * Indicator if the transition must be forces.
  205. *
  206. * @return string
  207. * A string.
  208. */
  209. function workflow_execute_transition(WorkflowTransitionInterface $transition, $force = FALSE) {
  210. // Execute transition and update the attached entity.
  211. return $transition->executeAndUpdateEntity($force);
  212. }
  213. /**
  214. * Functions to get an options list (to show in a Widget).
  215. * To be used in non-OO modules, like workflow_rules, workflow_views.
  216. *
  217. * The naming convention is workflow_get_<entity_type>_names.
  218. * (A bit different from 'user_role_names'.)
  219. * Can be used for hook_allowed_values from list.module:
  220. * - user_role
  221. * - workflow
  222. * - workflow_state
  223. * - sid.
  224. */
  225. /**
  226. * Retrieves the names of roles matching specified conditions.
  227. *
  228. * Deprecated D8: workflow_get_roles --> workflow_get_user_role_names.
  229. *
  230. * Usage:
  231. * D7: $roles = workflow_get_user_role_names('participate in workflow');
  232. * D8: $type_id = $workflow->id();
  233. * D8: $roles = workflow_get_user_role_names("create $type_id workflow_transition");
  234. *
  235. * @param string $permission
  236. * (optional) A string containing a permission. If set, only roles
  237. * containing that permission are returned. Defaults to NULL, which
  238. * returns all roles.
  239. * Normal usage for filtering roles that are enabled in a workflow_type
  240. * would be: $permission = 'create $type_id transition'.
  241. *
  242. * @return array
  243. * Array of role names keyed by role ID, including the 'author' role.
  244. */
  245. function workflow_get_user_role_names($permission) {
  246. static $roles = NULL;
  247. if ($roles[$permission]) {
  248. return $roles[$permission];
  249. }
  250. // Copied from AccountForm::form().
  251. $roles[$permission] = array_map(['\Drupal\Component\Utility\Html', 'escape'],
  252. [WORKFLOW_ROLE_AUTHOR_RID => '(' . t(WORKFLOW_ROLE_AUTHOR_NAME) . ')']
  253. + user_role_names(FALSE, $permission));
  254. return $roles[$permission];
  255. }
  256. /**
  257. * Get an options list for workflow states.
  258. *
  259. * @param mixed $wid
  260. * The Workflow ID.
  261. * @param bool $grouped
  262. * Indicates if the value must be grouped per workflow.
  263. * This influences the rendering of the select_list options.
  264. *
  265. * @return array
  266. * An array of $sid => state->label(), grouped per Workflow.
  267. */
  268. function workflow_get_workflow_state_names($wid = '', $grouped = FALSE) {
  269. $options = [];
  270. // @todo: implement $add parameter.
  271. //
  272. // @todo: follow Options pattern
  273. // @see callback_allowed_values_function()
  274. // @see options_allowed_values()
  275. // Get the (user-dependent) options.
  276. // Since this function is only used in UI, it is save to use the global $user.
  277. $user = workflow_current_user();
  278. /** @var $workflows Workflow[] */
  279. $workflows = Workflow::loadMultiple($wid ? [$wid] : NULL);
  280. // Do not group if only 1 Workflow is configured or selected.
  281. $grouped = count($workflows) == 1 ? FALSE : $grouped;
  282. foreach ($workflows as $wid => $workflow) {
  283. /** @var $state WorkflowState */
  284. $state = WorkflowState::create(['wid' => $wid]);
  285. $workflow_options = $state->getOptions(NULL, '', $user, FALSE);
  286. if (!$grouped) {
  287. $options += $workflow_options;
  288. }
  289. else {
  290. // Make a group for each Workflow.
  291. $options[$workflow->label()] = $workflow_options;
  292. }
  293. }
  294. return $options;
  295. }
  296. /**
  297. * Get an options list for workflows. Include an initial empty value
  298. * if requested. Validate each workflow, and generate a message if not complete.
  299. *
  300. * @param bool $required
  301. * Indicates if the resulting list contains a options value.
  302. *
  303. * @return array
  304. * An array of $wid => workflow->label().
  305. */
  306. function workflow_get_workflow_names($required = TRUE) {
  307. $options = [];
  308. if (!$required) {
  309. $options[''] = t('- Select a value -');
  310. }
  311. foreach (Workflow::loadMultiple() as $wid => $workflow) {
  312. /** @var $workflow Workflow */
  313. if ($workflow->isValid()) {
  314. $options[$wid] = $workflow->label();
  315. }
  316. }
  317. return $options;
  318. }
  319. /**
  320. * Gets an Options list of field names.
  321. *
  322. * @param \Drupal\Core\Entity\EntityInterface $entity
  323. * An entity.
  324. * @param string $entity_type
  325. * An entity_type.
  326. * @param string $entity_bundle
  327. * An entity.
  328. * @param string $field_name
  329. * A field name.
  330. *
  331. * @return array
  332. * An list of field names.
  333. */
  334. function workflow_get_workflow_field_names(EntityInterface $entity = NULL, $entity_type = '', $entity_bundle = '', $field_name = '') {
  335. $result = [];
  336. foreach (_workflow_info_fields($entity, $entity_type, $entity_bundle, $field_name) as $definition) {
  337. $field_name2 = $definition->getName();
  338. $result[$field_name2] = $field_name2;
  339. }
  340. return $result;
  341. }
  342. /**
  343. * Helper function, to get the label of a given State Id.
  344. * deprecated: workflow_get_sid_label() --> workflow_get_sid_name()
  345. *
  346. * @param string $sid
  347. * A State ID.
  348. *
  349. * @return string
  350. * An translated label.
  351. */
  352. function workflow_get_sid_name($sid) {
  353. if (empty($sid)) {
  354. $label = 'No state';
  355. }
  356. /** @noinspection PhpAssignmentInConditionInspection */
  357. elseif ($state = WorkflowState::load($sid)) {
  358. $label = $state->label();
  359. }
  360. else {
  361. $label = 'Unknown state';
  362. }
  363. return t($label);
  364. }
  365. /**
  366. * Determines the Workflow field_name of an entity.
  367. * If an entity has multiple workflows, only returns the first one.
  368. *
  369. * @param \Drupal\Core\Entity\EntityInterface $entity
  370. * The entity at hand.
  371. * @param string $field_name
  372. * The field name. If given, will be passed as return value.
  373. *
  374. * @return string
  375. * The found Field name.
  376. */
  377. function workflow_get_field_name(EntityInterface $entity, $field_name = '') {
  378. if (!$entity) {
  379. // $entity may be empty on Entity Add page.
  380. return '';
  381. }
  382. if ($field_name) {
  383. return $field_name;
  384. }
  385. $fields = workflow_get_workflow_field_names($entity);
  386. $field_name = reset($fields);
  387. return $field_name;
  388. }
  389. /**
  390. * Functions to get the state of an entity.
  391. */
  392. /**
  393. * Wrapper function to get a UserInterface object.
  394. * We use UserInterface to check permissions.
  395. *
  396. * @param \Drupal\Core\Session\AccountInterface|null $account
  397. * An Account.
  398. *
  399. * @return \Drupal\user\UserInterface
  400. * A User.
  401. */
  402. function workflow_current_user(AccountInterface $account = NULL) {
  403. $account = ($account) ? $account : \Drupal::currentUser();
  404. return User::load($account->id());
  405. }
  406. /**
  407. * Gets the current state ID of a given entity.
  408. *
  409. * @param \Drupal\Core\Entity\EntityInterface $entity
  410. * An entity.
  411. * @param string $field_name
  412. * A Field name.
  413. *
  414. * @return string
  415. * The current State ID.
  416. */
  417. function workflow_node_current_state(EntityInterface $entity, $field_name = '') {
  418. return WorkflowManager::getCurrentStateId($entity, $field_name);
  419. }
  420. /**
  421. * Gets the previous state ID of a given entity.
  422. *
  423. * @param \Drupal\Core\Entity\EntityInterface $entity
  424. * An entity.
  425. * @param string $field_name
  426. * A field_name.
  427. *
  428. * @return string
  429. * The previous State ID.
  430. */
  431. function workflow_node_previous_state(EntityInterface $entity, $field_name = '') {
  432. return WorkflowManager::getPreviousStateId($entity, $field_name);
  433. }
  434. /**
  435. * Get a specific workflow, given an entity type.
  436. * Only one workflow is possible per node type.
  437. * Caveat: gives undefined results with multiple workflows per entity.
  438. * @todo: support multiple workflows per entity.
  439. *
  440. * @param string $entity_bundle
  441. * An entity bundle.
  442. * @param string $entity_type
  443. * An entity type. This is passed when also the Field API must be checked.
  444. *
  445. * @return \Drupal\workflow\Entity\Workflow
  446. * A Workflow object, or NULL if no workflow is retrieved.
  447. */
  448. function workflow_get_workflows_by_type($entity_bundle, $entity_type) {
  449. static $map = [];
  450. if (isset($map[$entity_type][$entity_bundle])) {
  451. return $map[$entity_type][$entity_bundle];
  452. }
  453. $wid = FALSE;
  454. if (isset($entity_type)) {
  455. foreach (_workflow_info_fields(NULL, $entity_type, $entity_bundle) as $field_info) {
  456. $wid = $field_info->getSetting('workflow_type');
  457. }
  458. }
  459. // Set the cache with a workflow object.
  460. $map[$entity_type][$entity_bundle] = NULL;
  461. if ($wid) {
  462. $map[$entity_type][$entity_bundle] = Workflow::load($wid);
  463. }
  464. return $map[$entity_type][$entity_bundle];
  465. }
  466. /**
  467. * Finds the Workflow fields on a given Entity type.
  468. *
  469. * @return mixed
  470. *
  471. * @see EntityFieldManager::getFieldMapByFieldType
  472. */
  473. function workflow_get_workflow_fields_by_entity_type() {
  474. return \Drupal::service('entity_field.manager')->getFieldMapByFieldType('workflow');
  475. }
  476. /**
  477. * Gets the workflow field names, if not known already.
  478. *
  479. * @param \Drupal\Core\Entity\EntityInterface $entity
  480. * Object to work with. May be empty, e.g., on menu build.
  481. * @param string $entity_type
  482. * Entity type of object. Optional, but required if $entity provided.
  483. * @param string $entity_bundle
  484. * Bundle of entity. Optional.
  485. * @param string $field_name
  486. * Field name. Optional.
  487. *
  488. * @return Drupal\field\Entity\FieldStorageConfig[]
  489. * An array of FieldStorageConfig objects.
  490. */
  491. function _workflow_info_fields($entity = NULL, $entity_type = '', $entity_bundle = '', $field_name = '') {
  492. $field_info = [];
  493. // Figure out the $entity's bundle and id.
  494. if ($entity) {
  495. $entity_type = $entity->getEntityTypeId();
  496. $entity_bundle = $entity->bundle();
  497. }
  498. else {
  499. // Entity type and bundle should be specified.
  500. }
  501. $field_list = \Drupal::service('entity_field.manager')->getFieldMapByFieldType('workflow');
  502. foreach ($field_list as $e_type => $data) {
  503. if (!$entity_type || ($entity_type == $e_type)) {
  504. foreach ($data as $f_name => $value) {
  505. if (!$entity_bundle || isset($value['bundles'][$entity_bundle])) {
  506. if (!$field_name || ($field_name == $f_name)) {
  507. // Do not use the field_name as ID, but the
  508. // unique <entity_type>.<field_name> since you cannot share the
  509. // same field on multiple entity_types (unlike D7).
  510. $field_config = FieldStorageConfig::loadByName($e_type, $f_name);
  511. if ($field_config) {
  512. $field_info[$field_config->id()] = $field_config;
  513. }
  514. else {
  515. // The field is a base/extra field.
  516. // not a configurable Field via Field UI.
  517. // Re-fetch the field definitions, with extra data.
  518. $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions($e_type, $entity_bundle);
  519. // @todo: ?? Loop over bundles?
  520. /** @var \Drupal\Core\Field\BaseFieldDefinition $field_config */
  521. $field_config = $field_definitions[$f_name];
  522. if ($field_config) {
  523. $field_info[$field_config->getUniqueStorageIdentifier()] = $field_config;
  524. }
  525. else {
  526. // @todo: ?? Loop over bundles?
  527. }
  528. }
  529. }
  530. }
  531. }
  532. }
  533. }
  534. return $field_info;
  535. }
  536. /**
  537. * Helper function to get the entity from a route.
  538. *
  539. * This is a hack. It should be solved by using $route_match.
  540. *
  541. * @param \Drupal\Core\Entity\EntityInterface $entity
  542. * An optional entity.
  543. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  544. * A route.
  545. *
  546. * @return \Drupal\Core\Entity\EntityInterface
  547. * Entity from the route.
  548. */
  549. function workflow_url_get_entity(EntityInterface $entity = NULL, RouteMatchInterface $route_match = NULL) {
  550. if ($entity) {
  551. return $entity;
  552. }
  553. if (!$route_match) {
  554. $route_match = \Drupal::routeMatch();
  555. }
  556. $entities = [];
  557. foreach ($route_match->getParameters() as $param) {
  558. if ($param instanceof EntityInterface) {
  559. $entities[] = $param;
  560. }
  561. }
  562. $value = reset($entities);
  563. if ($value && is_object($value)) {
  564. return $value;
  565. }
  566. if ($value && !is_object($value)) {
  567. // On workflow tab, we'd get an id.
  568. // This is an indicator that the route is mal-configured.
  569. workflow_debug(__FILE__, __FUNCTION__, __LINE__, 'route declaration is not optimal.');
  570. /* Return $entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($value); */
  571. return NULL;
  572. }
  573. return $value;
  574. }
  575. /**
  576. * Helper function to get the field name from a route.
  577. *
  578. * For now only used for ../{entity_id}/workflow history tab.
  579. *
  580. * @return string|null
  581. * Return $field_name
  582. */
  583. function workflow_url_get_field_name() {
  584. return workflow_url_get_parameter('field_name');
  585. }
  586. /**
  587. * Helper function to get the entity from a route.
  588. *
  589. * @return mixed|string
  590. * Return $operation
  591. */
  592. function workflow_url_get_operation() {
  593. $url = Url::fromRoute('<current>');
  594. // The last part of the path is the operation: edit, workflow, devel.
  595. $url_parts = explode('/', $url->toString());
  596. $operation = array_pop($url_parts);
  597. // Except for view pages.
  598. if (is_numeric($operation) || $operation == 'view') {
  599. $operation = '';
  600. }
  601. return $operation;
  602. }
  603. /**
  604. * Helper function to get arbitrary parameter from a route.
  605. *
  606. * @param string $parameter
  607. * The requested parameter.
  608. *
  609. * @return string
  610. * field_name
  611. */
  612. function workflow_url_get_parameter($parameter) {
  613. return \Drupal::routeMatch()->getParameter($parameter);
  614. // Return \Drupal::request()->get($parameter);
  615. }
  616. /**
  617. * Helper function to determine Workflow from Workflow UI URL.
  618. *
  619. * @return \Drupal\workflow\Entity\Workflow
  620. * Workflow Object.
  621. */
  622. function workflow_url_get_workflow() {
  623. /** @var $workflows \Drupal\workflow\Entity\Workflow[] */
  624. static $workflows = [];
  625. $wid = workflow_url_get_parameter('workflow_type');
  626. if (is_object($wid)) {
  627. // $wid is a Workflow object.
  628. return $wid;
  629. }
  630. if (!isset($workflows[$wid])) {
  631. // $wid is a string.
  632. $workflows[$wid] = $wid ? Workflow::load($wid) : NULL;
  633. }
  634. return $workflows[$wid];
  635. }
  636. /**
  637. * Helper function to determine the title of the page.
  638. *
  639. * Used in file workflow_ui.routing.yml.
  640. *
  641. * @return \Drupal\Core\StringTranslation\TranslatableMarkup
  642. * the page title.
  643. */
  644. function workflow_url_get_title() {
  645. $label = '';
  646. // Get the Workflow from the page.
  647. /** @var $workflow \Drupal\workflow\Entity\Workflow */
  648. /** @noinspection PhpAssignmentInConditionInspection */
  649. if ($workflow = workflow_url_get_workflow()) {
  650. $label = $workflow->label();
  651. }
  652. $title = t('Edit @entity %label', ['@entity' => 'Workflow', '%label' => $label]);
  653. return $title;
  654. }
  655. /**
  656. * Helper function to determine Workflow from Workflow UI URL.
  657. *
  658. * @param string $url
  659. * URL.
  660. *
  661. * @return mixed
  662. * the Workflow type.
  663. */
  664. function workflow_url_get_form_type($url = '') {
  665. // For some reason, $_SERVER is not allowed as default.
  666. $url = ($url == '') ? $_SERVER['REQUEST_URI'] : $url;
  667. $base_url = '/config/workflow/workflow/';
  668. $string = substr($url, strpos($url, $base_url) + strlen($base_url));
  669. $type = explode('/', $string)[1];
  670. return $type;
  671. }
  672. /**
  673. * Helper function for D8-port: Get some info on screen.
  674. *
  675. * @param string $class_name
  676. * @param string $function_name
  677. * @param string $line_nr
  678. * @param string $value1
  679. * @param string $value2
  680. *
  681. * @see workflow_devel-module
  682. *
  683. * Usage:
  684. * workflow_debug( __FILE__, __FUNCTION__, __LINE__, '', '');
  685. */
  686. function workflow_debug($class_name, $function_name, $line_nr = '', $value1 = '', $value2 = '') {
  687. $debug_switch = FALSE;
  688. // $debug_switch = TRUE;
  689. if (!$debug_switch) {
  690. return;
  691. }
  692. $class_name_elements = explode("\\", $class_name);
  693. $output = 'Testing... function ' . end($class_name_elements) . '::' . $function_name . '/' . $line_nr;
  694. if ($value1) {
  695. $output .= ' = ' . $value1;
  696. }
  697. if ($value2) {
  698. $output .= ' > ' . $value2;
  699. }
  700. drupal_set_message($output, 'warning', TRUE);
  701. }