From b8e8cc8ceea5eba6f09082d04edbbb0ff89e80ea Mon Sep 17 00:00:00 2001 From: Bachir Soussi Chiadmi Date: Wed, 12 Sep 2018 14:51:18 +0200 Subject: [PATCH] updated contrib modules : translation_views, views_bulk_edit, views_bulk_operations, workflow, addtoany, redis, url_to_video_filter --- .../config/schema/workflow.schema.yml | 10 - .../workflow_access/workflow_access.info.yml | 6 +- .../workflow_access/workflow_access.module | 9 +- .../workflow_cleanup.info.yml | 6 +- .../workflow_devel/workflow_devel.info.yml | 6 +- .../workflow_field/workflowfield.info.yml | 6 +- .../workflow_operations.info.yml | 6 +- .../Controller/WorkflowStateListBuilder.php | 6 +- .../Form/WorkflowConfigTransitionRoleForm.php | 39 +- .../modules/workflow_ui/workflow_ui.info.yml | 6 +- .../modules/workflow_ui/workflow_ui.module | 6 +- .../workflow_ui/workflow_ui.routing.yml | 13 +- .../src/Access/WorkflowHistoryAccess.php | 79 ++ .../WorkflowTransitionListController.php | 79 +- .../src/Element/WorkflowTransitionElement.php | 31 +- .../admin/workflow/src/Entity/Workflow.php | 12 +- .../src/Entity/WorkflowConfigTransition.php | 62 +- .../WorkflowConfigTransitionInterface.php | 11 +- .../workflow/src/Entity/WorkflowInterface.php | 2 +- .../workflow/src/Entity/WorkflowManager.php | 18 +- .../src/Entity/WorkflowManagerInterface.php | 4 +- .../Entity/WorkflowScheduledTransition.php | 17 +- .../workflow/src/Entity/WorkflowState.php | 73 +- .../src/Entity/WorkflowTransition.php | 76 +- .../src/Form/WorkflowTransitionForm.php | 4 +- .../Action/WorkflowNodeGivenStateAction.php | 2 +- .../Plugin/Action/WorkflowStateActionBase.php | 13 +- .../Plugin/Derivative/WorkflowLocalTask.php | 75 ++ .../Plugin/Field/FieldType/WorkflowItem.php | 1 - .../FieldWidget/WorkflowDefaultWidget.php | 2 +- .../WorkflowFieldConstraintValidator.php | 5 +- .../workflow/src/Routing/RouteSubscriber.php | 136 +++ .../src/WorkflowTransitionListBuilder.php | 7 +- .../src/WorkflowTypeAttributeTrait.php | 103 ++ .../contrib/admin/workflow/workflow.field.inc | 16 + .../contrib/admin/workflow/workflow.form.inc | 2 +- .../contrib/admin/workflow/workflow.info.yml | 6 +- .../contrib/admin/workflow/workflow.install | 7 - .../admin/workflow/workflow.links.task.yml | 15 +- .../contrib/admin/workflow/workflow.module | 122 ++- .../admin/workflow/workflow.routing.yml | 33 - .../admin/workflow/workflow.services.yml | 10 +- .../all/modules/contrib/dev/redis/.travis.yml | 5 +- .../modules/contrib/dev/redis/redis.info.yml | 6 +- .../contrib/dev/redis/src/Cache/CacheBase.php | 3 +- .../contrib/dev/redis/src/Lock/Predis.php | 4 +- .../dev/redis/src/PersistentLock/Predis.php | 26 + .../Lock/RedisLockFunctionalTest.php | 2 +- .../redis/tests/src/Functional/WebTest.php | 9 +- .../redis/tests/src/Kernel/RedisQueueTest.php | 6 +- .../contrib/fields/addtoany/addtoany.info.yml | 6 +- .../contrib/fields/addtoany/addtoany.module | 58 +- .../config/install/addtoany.settings.yml | 4 + .../fields/addtoany/css/addtoany.admin.css | 9 + .../src/Form/AddToAnySettingsForm.php | 93 +- .../css/url_to_video_embed.scss | 2 +- .../url_to_video_filter/js/vimeo_embed.js | 157 ++- .../url_to_video_filter/js/youtube_embed.js | 135 ++- .../src/Plugin/Filter/FilterUrlToVideo.php | 224 ++-- .../src/Service/UrlToVideoFilterService.php | 262 ++--- .../UrlToVideoFilterServiceInterface.php | 60 +- .../url_to_video_filter.info.yml | 8 +- .../url_to_video_filter.libraries.yml | 3 + .../contrib/views/translation_views/README.md | 37 +- .../views.view.content_translations.yml | 15 +- .../schema/translation_views.views.schema.yml | 44 + .../views/field/TranslationCountField.php | 7 + ...onSourceLangcodeEqualsRowLangcodeField.php | 2 +- .../Plugin/views/field/TranslationStatus.php | 2 +- .../views/filter/TranslationCountFilter.php | 7 + ...nSourceLangcodeEqualsRowLangcodeFilter.php | 2 +- .../views/join/TranslationLanguageJoin.php | 16 +- .../src/TranslationCountTrait.php | 8 +- .../views.view.comment_translation.yml | 996 ++++++++++++++++++ ...anslation_views_all_filters_and_fields.yml | 924 ++++++++++++++++ .../translation_views_test_views.info.yml | 17 + .../CommentFullViewFiltersFieldsTest.php | 491 +++++++++ .../ContentFullViewFiltersFieldsTest.php | 471 +++++++++ .../ContentTranslationJobsViewTest.php | 223 ++++ .../translation_views.info.yml | 6 +- .../translation_views.module | 25 + .../translation_views.views.inc | 31 +- .../contrib/views/views_bulk_edit/README.txt | 6 + .../views/views_bulk_edit/css/edit_form.css | 4 +- .../src/Plugin/Action/ModifyEntityValues.php | 49 +- .../views_bulk_edit/views_bulk_edit.info.yml | 6 +- .../views/views_bulk_operations/js/frontUi.js | 5 +- .../actions_permissions.info.yml | 6 +- .../views_bulk_operations_example.info.yml | 6 +- .../src/Form/ConfigureAction.php | 4 +- .../src/Form/ConfirmAction.php | 7 +- .../src/Form/ViewsBulkOperationsFormTrait.php | 32 + .../field/ViewsBulkOperationsBulkForm.php | 17 +- .../Service/ViewsBulkOperationsViewData.php | 4 +- .../ViewsBulkOperationsBulkFormTest.php | 2 +- .../ViewsBulkOperationsKernelTestBase.php | 5 +- .../src/Unit/ViewsBulkOperationsBatchTest.php | 3 - .../views_bulk_operations_test.info.yml | 6 +- .../views_bulk_operations.info.yml | 6 +- 99 files changed, 4762 insertions(+), 954 deletions(-) create mode 100644 sites/all/modules/contrib/admin/workflow/src/Access/WorkflowHistoryAccess.php create mode 100644 sites/all/modules/contrib/admin/workflow/src/Plugin/Derivative/WorkflowLocalTask.php create mode 100644 sites/all/modules/contrib/admin/workflow/src/Routing/RouteSubscriber.php create mode 100644 sites/all/modules/contrib/admin/workflow/src/WorkflowTypeAttributeTrait.php create mode 100644 sites/all/modules/contrib/dev/redis/src/PersistentLock/Predis.php rename sites/all/modules/contrib/views/translation_views/config/{install => optional}/views.view.content_translations.yml (99%) mode change 100644 => 100755 sites/all/modules/contrib/views/translation_views/src/Plugin/views/join/TranslationLanguageJoin.php create mode 100644 sites/all/modules/contrib/views/translation_views/tests/modules/translation_views_test_views/test_views/views.view.comment_translation.yml create mode 100644 sites/all/modules/contrib/views/translation_views/tests/modules/translation_views_test_views/test_views/views.view.translation_views_all_filters_and_fields.yml create mode 100644 sites/all/modules/contrib/views/translation_views/tests/modules/translation_views_test_views/translation_views_test_views.info.yml create mode 100644 sites/all/modules/contrib/views/translation_views/tests/src/Functional/CommentFullViewFiltersFieldsTest.php create mode 100644 sites/all/modules/contrib/views/translation_views/tests/src/Functional/ContentFullViewFiltersFieldsTest.php create mode 100644 sites/all/modules/contrib/views/translation_views/tests/src/Functional/ContentTranslationJobsViewTest.php mode change 100644 => 100755 sites/all/modules/contrib/views/translation_views/translation_views.views.inc diff --git a/sites/all/modules/contrib/admin/workflow/config/schema/workflow.schema.yml b/sites/all/modules/contrib/admin/workflow/config/schema/workflow.schema.yml index a14ae7ef1..35ff20cb3 100644 --- a/sites/all/modules/contrib/admin/workflow/config/schema/workflow.schema.yml +++ b/sites/all/modules/contrib/admin/workflow/config/schema/workflow.schema.yml @@ -66,17 +66,7 @@ field.storage_settings.workflow: label: type: label label: 'Label' - allowed_values_function: - type: string - label: 'Allowed values function' field.field_settings.workflow: type: mapping label: 'Workflow settings' - -workflow.settings: - type: config_object - mapping: - workflow_states_per_page: - type: integer - label: 'Number of workflow states displayed per page.' diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.info.yml b/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.info.yml index 0d3367ddc..e09ace788 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.info.yml +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.info.yml @@ -6,8 +6,8 @@ package: Workflow # core: 8.x type: module -# Information added by Drupal.org packaging script on 2017-12-17 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-04-29 +version: '8.x-1.1' core: '8.x' project: 'workflow' -datestamp: 1513552400 +datestamp: 1525039388 diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.module b/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.module index ae82ed9a1..15f4d14c0 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.module +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_access/workflow_access.module @@ -66,7 +66,7 @@ function workflow_access_workflow_operations($op, EntityInterface $entity = NULL } /** - * Implements hook_entity_insert(). + * Implements hook_ENTITY_TYPE_insert(). * * We use the Role weight as an id. * In contrary to content_access module, that uses a 'content_access_roles_gids' @@ -78,11 +78,11 @@ function workflow_access_user_role_insert(EntityInterface $entity) { // Attend user to Rebuild data, because the weight of a role // is the key for workflow_Access. /** @var $entity \Drupal\user\RoleInterface */ - node_access_needs_rebuild(TRUE); + node_access_needs_rebuild(TRUE); } /** - * Implements hook_access_entity_update(). + * Implements hook_access_ENTITY_TYPE_update(). * * @param EntityInterface $entity */ @@ -167,8 +167,7 @@ function workflow_access_node_access_records(\Drupal\node\NodeInterface $node) { // - when rebuilding permissions via batch for Workflow Fields. // In that case, we need to create the workflow_transitions ourselves to // calculate the grants. - foreach (_workflow_info_fields($node, $entity_type) as $field) { - $field_name = $field->getName(); // Do not use id(). + foreach (workflow_get_workflow_field_names($node, $entity_type) as $field_name) { $old_sid = $new_sid = $node->$field_name->value; // Create a dummy transition, just to set $node->workflow_transitions. diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_cleanup/workflow_cleanup.info.yml b/sites/all/modules/contrib/admin/workflow/modules/workflow_cleanup/workflow_cleanup.info.yml index d88ca0eb1..84361d145 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_cleanup/workflow_cleanup.info.yml +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_cleanup/workflow_cleanup.info.yml @@ -6,8 +6,8 @@ package: Workflow dependencies: - workflow configure: workflow.cleanup.settings -# Information added by Drupal.org packaging script on 2017-12-17 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-04-29 +version: '8.x-1.1' core: '8.x' project: 'workflow' -datestamp: 1513552400 +datestamp: 1525039388 diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_devel/workflow_devel.info.yml b/sites/all/modules/contrib/admin/workflow/modules/workflow_devel/workflow_devel.info.yml index d3fcae967..d89202171 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_devel/workflow_devel.info.yml +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_devel/workflow_devel.info.yml @@ -7,8 +7,8 @@ type: module dependencies: - workflow -# Information added by Drupal.org packaging script on 2017-12-17 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-04-29 +version: '8.x-1.1' core: '8.x' project: 'workflow' -datestamp: 1513552400 +datestamp: 1525039388 diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_field/workflowfield.info.yml b/sites/all/modules/contrib/admin/workflow/modules/workflow_field/workflowfield.info.yml index 9a818e8b5..35d450099 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_field/workflowfield.info.yml +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_field/workflowfield.info.yml @@ -5,8 +5,8 @@ type: module # core: 8.x hidden: TRUE -# Information added by Drupal.org packaging script on 2017-12-17 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-04-29 +version: '8.x-1.1' core: '8.x' project: 'workflow' -datestamp: 1513552400 +datestamp: 1525039388 diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_operations/workflow_operations.info.yml b/sites/all/modules/contrib/admin/workflow/modules/workflow_operations/workflow_operations.info.yml index 3b0623fec..dd3282296 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_operations/workflow_operations.info.yml +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_operations/workflow_operations.info.yml @@ -7,8 +7,8 @@ type: module dependencies: - workflow -# Information added by Drupal.org packaging script on 2017-12-17 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-04-29 +version: '8.x-1.1' core: '8.x' project: 'workflow' -datestamp: 1513552400 +datestamp: 1525039388 diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Controller/WorkflowStateListBuilder.php b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Controller/WorkflowStateListBuilder.php index c8f044403..14eadde74 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Controller/WorkflowStateListBuilder.php +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Controller/WorkflowStateListBuilder.php @@ -24,16 +24,16 @@ class WorkflowStateListBuilder extends DraggableListBuilder { $entities = []; // Get the Workflow from the page. - /** @var $workflow \Drupal\workflow\Entity\Workflow */ if (!$workflow = workflow_url_get_workflow()) { // @todo: Generate error message. return $entities; } - $wid = $url_wid = $workflow->id(); + $wid = $workflow->id(); + /** @var WorkflowState[] $entities */ $entities = parent::load(); foreach ($entities as $key => $entity) { - if (!isset($entity->wid) || $entity->wid != $wid) { + if ($entity->getWorkflowId() != $wid) { unset($entities[$key]); } } diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Form/WorkflowConfigTransitionRoleForm.php b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Form/WorkflowConfigTransitionRoleForm.php index 19377ad87..cb38b898f 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Form/WorkflowConfigTransitionRoleForm.php +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/src/Form/WorkflowConfigTransitionRoleForm.php @@ -99,20 +99,19 @@ class WorkflowConfigTransitionRoleForm extends WorkflowConfigTransitionFormBase continue; } $to_sid = $to_state->id(); - $stay_on_this_state = ($to_sid == $from_sid); // Load existing config_transitions. Create if not found. $config_transitions = $workflow->getTransitionsByStateId($from_sid, $to_sid); if (!$config_transition = reset($config_transitions)) { $config_transition = $workflow->createTransition($from_sid, $to_sid); } + $stay_on_this_state = !$config_transition->hasStateChange(); - $row[$to_sid]['workflow_config_transition'] = ['#type' => 'value', '#value' => $config_transition, ]; + $row[$to_sid]['workflow_config_transition'] = ['#type' => 'value', '#value' => $config_transition,]; $row[$to_sid]['roles'] = [ - '#type' => $stay_on_this_state ? 'checkboxes' : 'checkboxes', + '#type' => 'checkboxes', '#options' => $stay_on_this_state ? [] : $roles, '#disabled' => $stay_on_this_state, - // When $stay_on_this_state, allow all roles. '#default_value' => $stay_on_this_state ? $allow_all_roles : $config_transition->roles, ]; } @@ -127,24 +126,30 @@ class WorkflowConfigTransitionRoleForm extends WorkflowConfigTransitionFormBase */ public function validateForm(array &$form, FormStateInterface $form_state) { $workflow = $this->workflow; + + // If only the 'Creation' state is available, + if (count($form_state->getValue($this->entitiesKey)) < 2) { + $form_state->setErrorByName('id', t('Please create at least one other state.', + [])); + } + // Make sure 'author' is checked for (creation) -> [something]. $creation_state = $workflow->getCreationState(); + $creation_state_id = $workflow->getCreationState()->id(); + $author_has_permission = FALSE; + foreach ($form_state->getValue($this->entitiesKey) as $from_sid => $to_data) { + foreach ($to_data as $to_sid => $transition_data) { - if (empty($form_state->getValue($this->entitiesKey))) { - $author_has_permission = TRUE; - } - else { - $author_has_permission = FALSE; - foreach ($form_state->getValue($this->entitiesKey) as $from_sid => $to_data) { - foreach ($to_data as $to_sid => $transition_data) { - if ($from_sid == $to_sid) { - // Same-state-transition do not count. - } - elseif (!empty($transition_data['roles'][WORKFLOW_ROLE_AUTHOR_RID])) { - $author_has_permission = TRUE; + if ($from_sid == $creation_state_id) { + // Same-state-transitions do not count. + if ($from_sid != $to_sid) { + if (!empty($transition_data['roles'][WORKFLOW_ROLE_AUTHOR_RID])) { + $author_has_permission = TRUE; + } break; } } + } } if (!$author_has_permission) { @@ -152,7 +157,7 @@ class WorkflowConfigTransitionRoleForm extends WorkflowConfigTransitionFormBase ['%creation' => $creation_state->label()])); } - return; + parent::validateForm($form, $form_state); } /** diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.info.yml b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.info.yml index 8bf924186..44e89fd65 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.info.yml +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.info.yml @@ -10,8 +10,8 @@ configure: entity.workflow_type.collection dependencies: - workflow -# Information added by Drupal.org packaging script on 2017-12-17 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-04-29 +version: '8.x-1.1' core: '8.x' project: 'workflow' -datestamp: 1513552400 +datestamp: 1525039388 diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.module b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.module index bfce24235..867a54af9 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.module +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.module @@ -70,8 +70,8 @@ function workflow_ui_help($route_name, RouteMatchInterface $route_match) { * * @deprecated : @see workflow_url_get_workflow . */ -function workflow_ui_url_get_workflow($url = '' ) { - return workflow_url_get_workflow($url); +function workflow_ui_url_get_workflow() { + return workflow_url_get_workflow(); } /** @@ -88,6 +88,6 @@ function workflow_ui_url_get_title() { * * @deprecated : @see workflow_url_get_form_type . */ -function workflow_ui_url_get_form_type($url = '' ) { +function workflow_ui_url_get_form_type($url = '') { return workflow_url_get_form_type($url); } diff --git a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.routing.yml b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.routing.yml index 93c16fc6b..34dae7099 100644 --- a/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.routing.yml +++ b/sites/all/modules/contrib/admin/workflow/modules/workflow_ui/workflow_ui.routing.yml @@ -23,7 +23,10 @@ entity.workflow_state.collection: _title_callback: 'workflow_url_get_title' requirements: _permission: 'administer workflow' - + options: + parameters: + workflow_type: + type: entity:workflow_type ### Workflow Transitions entity.workflow_transition.collection: @@ -34,6 +37,10 @@ entity.workflow_transition.collection: _title_callback: 'workflow_url_get_title' requirements: _permission: 'administer workflow' + options: + parameters: + workflow_type: + type: entity:workflow_type ### Workflow Labels entity.workflow_label.collection: @@ -44,3 +51,7 @@ entity.workflow_label.collection: _title_callback: 'workflow_url_get_title' requirements: _permission: 'administer workflow' + options: + parameters: + workflow_type: + type: entity:workflow_type diff --git a/sites/all/modules/contrib/admin/workflow/src/Access/WorkflowHistoryAccess.php b/sites/all/modules/contrib/admin/workflow/src/Access/WorkflowHistoryAccess.php new file mode 100644 index 000000000..36dbdacd4 --- /dev/null +++ b/sites/all/modules/contrib/admin/workflow/src/Access/WorkflowHistoryAccess.php @@ -0,0 +1,79 @@ +id() : -1; + + $entity = workflow_url_get_entity(); + $entity_id = $entity->id(); + $entity_type = $entity->getEntityTypeId(); + $entity_bundle = $entity->bundle(); + $field_name = workflow_url_get_parameter('field_name'); // @todo: this doesn't work. + + if (isset($access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'])) { + return $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field']; + } + + $access_result = AccessResult::forbidden(); + + // When having multiple workflows per bundle, use Views display + // 'Workflow history per entity' instead! + $fields = _workflow_info_fields($entity, $entity_type, $entity_bundle, $field_name); + if (!$fields) { + return AccessResult::forbidden(); + } + + // @todo: Keep below code aligned between WorkflowState, ~Transition, ~TransitionListController + // Determine if user is owner of the entity. + $is_owner = WorkflowManager::isOwner($account, $entity); + + /* + * Determine if user has Access. Fill the cache. + */ + // @todo: what to do with multiple workflow_fields per bundle? Use Views instead! Or introduce a setting. + // @todo D8-port: workflow_tab_access: use proper 'WORKFLOW_TYPE' permissions + foreach ($fields as $definition) { + $type_id = $definition->getSetting('workflow_type'); + if ($account->hasPermission("access any $type_id workflow_transion overview")) { + $access_result = AccessResult::allowed(); + } + elseif ($is_owner && $account->hasPermission("access own $type_id workflow_transion overview")) { + $access_result = AccessResult::allowed(); + } + elseif ($account->hasPermission('administer nodes')) { + $access_result = AccessResult::allowed(); + } + $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'] = $access_result; + } + + return $access_result; + } +} \ No newline at end of file diff --git a/sites/all/modules/contrib/admin/workflow/src/Controller/WorkflowTransitionListController.php b/sites/all/modules/contrib/admin/workflow/src/Controller/WorkflowTransitionListController.php index 0329b8ac3..1cfbb5dea 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Controller/WorkflowTransitionListController.php +++ b/sites/all/modules/contrib/admin/workflow/src/Controller/WorkflowTransitionListController.php @@ -58,7 +58,7 @@ class WorkflowTransitionListController extends EntityListController implements C /** * Generates an overview table of older revisions of a node, - * but only if this::historyAccess() allows it. + * but only if WorkflowHistoryAccess::access() allows it. * * @param EntityInterface $node * A node object. @@ -137,81 +137,4 @@ class WorkflowTransitionListController extends EntityListController implements C return $form; } - /** - * Menu access control callback. Checks access to Workflow tab. - * - * This used to be D7-function workflow_tab_access($user, $entity). - * - * The History tab should not be used with multiple workflows per entity. - * Use the dedicated view for this use case. - * @todo D8: remove this in favour of View 'Workflow history per entity'. - * @todo D8-port: make this workflow for non-Node entity types. - * - * @param \Drupal\Core\Session\AccountInterface $account - * Run access checks for this account. - * - * @return \Drupal\Core\Access\AccessResult - */ - public function historyAccess(AccountInterface $account) { - static $access = []; - - $uid = ($account) ? $account->id() : -1; - - // @todo D8-port: make Workflow History tab happen for every entity_type. - // @see workflow.routing.yml, workflow.links.task.yml, WorkflowTransitionListController. - // ATM it only works for Nodes and Terms. - // This is a hack. The Route should always pass an object. - // On view tab, $entity is object, - // On workflow tab, $entity is id(). - // Get the entity for this form. - $entity = workflow_url_get_entity(); - - /* @var $entity EntityInterface */ - // Figure out the $entity's bundle and id. - $entity_type = $entity->getEntityTypeId(); - $entity_bundle = $entity->bundle(); - $entity_id = ($entity) ? $entity->id() : ''; - $field_name = workflow_url_get_field_name(); - - if (isset($access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'])) { - return $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field']; - } - - $access_result = AccessResult::forbidden(); - - // When having multiple workflows per bundle, use Views display - // 'Workflow history per entity' instead! - $fields = _workflow_info_fields($entity, $entity_type, $entity_bundle, $field_name); - if (!$fields) { - return AccessResult::forbidden(); - } - else { - // @todo: Keep below code aligned between WorkflowState, ~Transition, ~TransitionListController - $uid = ($account) ? $account->id() : -1; - $entity_id = ($entity) ? $entity->id() : ''; - // Determine if user is owner of the entity. - $is_owner = WorkflowManager::isOwner($account, $entity); - - /** - * Determine if user has Access. Fill the cache. - */ - // @todo: what to do with multiple workflow_fields per bundle? Use Views instead! Or introduce a setting. - // @todo D8-port: workflow_tab_access: use proper 'WORKFLOW_TYPE' permissions - foreach ($fields as $definition) { - $type_id = $definition->getSetting('workflow_type'); - if ($account->hasPermission("access any $type_id workflow_transion overview")) { - $access_result = AccessResult::allowed(); - } - elseif ($is_owner && $account->hasPermission("access own $type_id workflow_transion overview")) { - $access_result = AccessResult::allowed(); - } - elseif ($account->hasPermission('administer nodes')) { - $access_result = AccessResult::allowed(); - } - $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'] = $access_result; - } - } - return $access_result; - } - } diff --git a/sites/all/modules/contrib/admin/workflow/src/Element/WorkflowTransitionElement.php b/sites/all/modules/contrib/admin/workflow/src/Element/WorkflowTransitionElement.php index 3c25ddbe9..9751a1ae7 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Element/WorkflowTransitionElement.php +++ b/sites/all/modules/contrib/admin/workflow/src/Element/WorkflowTransitionElement.php @@ -41,7 +41,7 @@ class WorkflowTransitionElement extends FormElement { * @param array $complete_form */ public static function validateTransition(&$element, FormStateInterface $form_state, &$complete_form) { - workflow_debug( __FILE__, __FUNCTION__, __LINE__); // @todo D8-port: still test this snippet. + workflow_debug(__FILE__, __FUNCTION__, __LINE__); // @todo D8-port: still test this snippet. } /** @@ -57,7 +57,7 @@ class WorkflowTransitionElement extends FormElement { * The Workflow element */ public static function processTransition(&$element, FormStateInterface $form_state, &$complete_form) { - workflow_debug( __FILE__, __FUNCTION__, __LINE__); // @todo D8-port: still test this snippet. + workflow_debug(__FILE__, __FUNCTION__, __LINE__); // @todo D8-port: still test this snippet. return self::transitionElement($element, $form_state, $complete_form); } @@ -159,13 +159,6 @@ class WorkflowTransitionElement extends FormElement { $default_value = FALSE; } - // Fetch the form ID. This is unique for each entity, to allow multiple form per page (Views, etc.). - // Make it uniquer by adding the field name, or else the scheduling of - // multiple workflow_fields is not independent of each other. - // If we are indeed on a Transition form (so, not a Node Form with widget) - // then change the form id, too. - $form_id = self::getFormId(); - /* * Output: generate the element. */ @@ -230,7 +223,7 @@ class WorkflowTransitionElement extends FormElement { // Add a state formatter before the rest of the form, // when transition is scheduled or widget is hidden. - if ( (!$show_widget) || $transition_is_scheduled || $transition->isExecuted()) { + if ((!$show_widget) || $transition_is_scheduled || $transition->isExecuted()) { $element['workflow_current_state'] = workflow_state_formatter($entity, $field_name, $current_sid); // Set a proper weight, which works for Workflow Options in select list AND action buttons. $element['workflow_current_state']['#weight'] = -0.005; @@ -316,6 +309,14 @@ class WorkflowTransitionElement extends FormElement { '#type' => 'container', '#tree' => TRUE, ]; + // Define class for '#states' behaviour. + // Fetch the form ID. This is unique for each entity, to allow multiple form per page (Views, etc.). + // Make it uniquer by adding the field name, or else the scheduling of + // multiple workflow_fields is not independent of each other. + // If we are indeed on a Transition form (so, not a Node Form with widget) + // then change the form id, too. + $form_id = $form_state->getBuildInfo()['form_id']; + $class_identifier = Html::getClass('scheduled_' . Html::getUniqueId($form_id).'-'.$field_name); $element['workflow_scheduling']['scheduled'] = [ '#type' => 'radios', '#title' => t('Schedule'), @@ -326,7 +327,7 @@ class WorkflowTransitionElement extends FormElement { '#default_value' => $transition_is_scheduled ? '1' : '0', '#attributes' => [ // 'id' => 'scheduled_' . $form_id, - 'class' => [Html::getClass('scheduled_' . $form_id)], + 'class' => [$class_identifier], ], ]; $element['workflow_scheduling']['date_time'] = [ @@ -337,18 +338,18 @@ class WorkflowTransitionElement extends FormElement { '#suffix' => '', '#states' => [ //'visible' => array(':input[id="' . 'scheduled_' . $form_id . '"]' => array('value' => '1')), - 'visible' => ['input.' . Html::getClass('scheduled_' . $form_id) => ['value' => '1']], + 'visible' => ['input.' . $class_identifier => ['value' => '1']], ], ]; $element['workflow_scheduling']['date_time']['workflow_scheduled_date'] = [ '#type' => 'date', '#prefix' => t('At'), - '#default_value' => implode( '-', [ + '#default_value' => implode('-', [ 'year' => date('Y', $timestamp), 'month' => date('m', $timestamp), 'day' => date('d', $timestamp), ] - ) + ), ]; $element['workflow_scheduling']['date_time']['workflow_scheduled_hour'] = [ '#type' => 'textfield', @@ -419,7 +420,7 @@ class WorkflowTransitionElement extends FormElement { return 'workflow_transition_form'; //@todo D8-port: add $form_id for widget and History tab. } - /** + /** * Implements ContentEntityForm::copyFormValuesToEntity(), and is called from: * - WorkflowTransitionForm::copyFormValuesToEntity() * - WorkflowDefaultWidget diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/Workflow.php b/sites/all/modules/contrib/admin/workflow/src/Entity/Workflow.php index 701920feb..685f27a4b 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/Workflow.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/Workflow.php @@ -84,6 +84,13 @@ class Workflow extends ConfigEntityBase implements WorkflowInterface { public $states = []; public $transitions = []; + /** + * The module implementing this object, for config_export. + * + * @var string + */ + protected $module = 'workflow'; + /** * CRUD functions. */ @@ -135,7 +142,10 @@ class Workflow extends ConfigEntityBase implements WorkflowInterface { */ public function delete() { if (!$this->isDeletable()) { - // @todo: throw error if not workflow->isDeletable(). + $message = t('Workflow %workflow is not Deletable. Please delete the field where this workflow type is reffered', + ['%workflow' => $this->label()]); + drupal_set_message($message, 'error'); + return; } else { // Delete associated state (also deletes any associated transitions). diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransition.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransition.php index 7e25f7fc2..f42e124d3 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransition.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransition.php @@ -5,6 +5,7 @@ namespace Drupal\workflow\Entity; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\user\UserInterface; +use Drupal\workflow\WorkflowTypeAttributeTrait; /** * Workflow configuration entity to persistently store configuration. @@ -45,6 +46,10 @@ use Drupal\user\UserInterface; * ) */ class WorkflowConfigTransition extends ConfigEntityBase implements WorkflowConfigTransitionInterface { + /* + * Add variables and get/set methods for Workflow property. + */ + use WorkflowTypeAttributeTrait; // Transition data. public $id; @@ -52,11 +57,12 @@ class WorkflowConfigTransition extends ConfigEntityBase implements WorkflowConfi public $to_sid; public $roles = []; - // Extra fields. - protected $wid; - // The following must explicitly defined, and not be public, to avoid errors - // when exporting with json_encode(). - protected $workflow = NULL; + /** + * The module implementing this object, for config_export. + * + * @var string + */ + protected $module = 'workflow'; /* * Entity class functions. @@ -67,7 +73,11 @@ class WorkflowConfigTransition extends ConfigEntityBase implements WorkflowConfi */ public function __construct(array $values = [], $entityType = NULL) { // Please be aware that $entity_type and $entityType are different things! - return parent::__construct($values, $entity_type = 'workflow_config_transition'); + parent::__construct($values, $entity_type = 'workflow_config_transition'); + $state = WorkflowState::load($this->to_sid ? $this->to_sid : $this->from_sid); + if($state) { + $this->setWorkflow($state->getWorkflow()); + } } /** @@ -76,8 +86,10 @@ class WorkflowConfigTransition extends ConfigEntityBase implements WorkflowConfi * @param $to_sid */ public function setValues($from_sid, $to_sid) { - $this->from_sid = $from_sid; - $this->to_sid = $to_sid; + $state = WorkflowState::load($this->to_sid ? $this->to_sid : $this->from_sid); + if($state) { + $this->setWorkflow($state->getWorkflow()); + } } /** @@ -148,29 +160,6 @@ class WorkflowConfigTransition extends ConfigEntityBase implements WorkflowConfi * Property functions. */ - /** - * {@inheritdoc} - */ - public function getWorkflow() { - if (!$this->workflow && $wid = $this->getWorkflowId()) { - $this->workflow = Workflow::load($wid); - } - return $this->workflow; - } - - /** - * {@inheritdoc} - */ - public function getWorkflowId() { - if (!$this->wid) { - $from_sid = $this->getFromSid(); - $to_sid = $this->getToSid(); - $state = WorkflowState::load($to_sid ? $to_sid : $from_sid); - $this->wid = $state->getWorkflowId(); - } - return $this->wid; - } - /** * {@inheritdoc} */ @@ -219,4 +208,15 @@ class WorkflowConfigTransition extends ConfigEntityBase implements WorkflowConfi return TRUE == array_intersect($user->getRoles(), $this->roles); } + /** + * Determines if the State changes by this Transition. + * @return bool + */ + public function hasStateChange() { + if ($this->from_sid == $this->to_sid) { + return FALSE; + } + return TRUE; + } + } diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransitionInterface.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransitionInterface.php index b0a254600..7e923b0fc 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransitionInterface.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowConfigTransitionInterface.php @@ -31,7 +31,7 @@ interface WorkflowConfigTransitionInterface { public function isAllowed(UserInterface $user, $force = FALSE); /** - * Returns the Workflow object of this State. + * Returns the Workflow object of this object. * * @return Workflow * Workflow object. @@ -39,10 +39,10 @@ interface WorkflowConfigTransitionInterface { public function getWorkflow(); /** - * Returns the Workflow ID of this Transition + * Returns the Workflow ID of this object. * * @return string - * Workflow Id. + * Workflow ID. */ public function getWorkflowId(); @@ -66,4 +66,9 @@ interface WorkflowConfigTransitionInterface { */ public function getToSid(); + /** + * Determines if the State changes by this Transition. + * @return bool + */ + public function hasStateChange(); } diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowInterface.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowInterface.php index 284778537..be9859fda 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowInterface.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowInterface.php @@ -130,7 +130,7 @@ interface WorkflowInterface { * @param string $to_sid * @param array $values * - * @return mixed|null|static + * @return WorkflowConfigTransitionInterface */ public function createTransition($from_sid, $to_sid, $values = []); diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManager.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManager.php index 720c8f0a9..8d27ce18a 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManager.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManager.php @@ -140,21 +140,13 @@ class WorkflowManager implements WorkflowManagerInterface { public static function executeTransitionsOfEntity(EntityInterface $entity) { // Avoid this hook on workflow objects. - if (in_array($entity->getEntityTypeId(), [ - 'workflow_type', - 'workflow_state', - 'workflow_config_transition', - 'workflow_transition', - 'workflow_scheduled_transition', - ])) { + if (WorkflowManager::isWorkflowEntityType($entity->getEntityTypeId())) { return; } $user = workflow_current_user(); - foreach (_workflow_info_fields($entity) as $field_info) { - $field_name = $field_info->getName(); - + foreach (workflow_get_workflow_field_names($entity) as $field_name) { // Transition is created in widget or WorkflowTransitionForm. /** @var $transition WorkflowTransitionInterface */ $transition = $entity->$field_name->__get('workflow_transition'); @@ -345,7 +337,7 @@ class WorkflowManager implements WorkflowManagerInterface { /** * {@inheritdoc} */ - public static function getWorkflowTransitionForm(EntityInterface $entity, string $field_name) { + public static function getWorkflowTransitionForm(EntityInterface $entity, $field_name, array $form_state_additions = []) { // Create a transition, to pass to the form. No need to use setValues(). $current_sid = workflow_node_current_state($entity, $field_name); $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]); @@ -353,7 +345,7 @@ class WorkflowManager implements WorkflowManagerInterface { // Create the WorkflowTransitionForm. /** @var \Drupal\Core\Entity\EntityFormBuilder $entity_form_builder */ $entity_form_builder = \Drupal::getContainer()->get('entity.form_builder'); - $form = $entity_form_builder->getForm($transition, 'add'); + $form = $entity_form_builder->getForm($transition, 'add', $form_state_additions); return $form; } @@ -455,7 +447,7 @@ class WorkflowManager implements WorkflowManagerInterface { /** * {@inheritdoc} */ - public static function isWorkflowEntityType(string $entity_type_id) { + public static function isWorkflowEntityType($entity_type_id) { return in_array($entity_type_id, [ 'workflow_type', 'workflow_state', diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManagerInterface.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManagerInterface.php index a39f62e7b..9889877d7 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManagerInterface.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowManagerInterface.php @@ -108,7 +108,7 @@ interface WorkflowManagerInterface { * * @return */ - public static function getWorkflowTransitionForm(EntityInterface $entity, string $field_name); + public static function getWorkflowTransitionForm(EntityInterface $entity, $field_name, array $form_state_additions = []); /** * Returns the attached fields (via Field UI) @@ -168,6 +168,6 @@ interface WorkflowManagerInterface { * * @return bool */ - public static function isWorkflowEntityType(string $entity_type_id); + public static function isWorkflowEntityType($entity_type_id); } diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowScheduledTransition.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowScheduledTransition.php index b84474e97..0f70a2500 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowScheduledTransition.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowScheduledTransition.php @@ -47,7 +47,7 @@ use Drupal\Core\Field\BaseFieldDefinition; class WorkflowScheduledTransition extends WorkflowTransition { /** - * Constructor. + * @inheritdoc. */ public function __construct(array $values = [], $entityType = 'workflow_scheduled_transition', $bundle = FALSE, $translations = []) { // Please be aware that $entity_type and $entityType are different things! @@ -70,7 +70,7 @@ class WorkflowScheduledTransition extends WorkflowTransition { * {@inheritdoc} * * This is a hack to avoid the following error, because ScheduledTransition is not a bundle of Workflow: - * Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:workflow_scheduled_transition:eerste" plugin does not exist. in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 60 of core\lib\Drupal\Component\Plugin\Discovery\DiscoveryTrait.php). + * Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:workflow_scheduled_transition:first" plugin does not exist. in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 60 of core\lib\Drupal\Component\Plugin\Discovery\DiscoveryTrait.php). */ function validate() { // Since this function generates an error in one use case (using WorkflowTransitionForm) @@ -176,11 +176,13 @@ class WorkflowScheduledTransition extends WorkflowTransition { * * @param int $start * @param int $end + * @param string $from_sid + * @param string $to_sid * * @return WorkflowScheduledTransition[] * An array of transitions. */ - public static function loadBetween($start = 0, $end = 0) { + public static function loadBetween($start = 0, $end = 0, $from_sid = '', $to_sid = '') { $transition_type = 'workflow_scheduled_transition'; // @todo: get this from annotation. /* @var $query \Drupal\Core\Entity\Query\QueryInterface */ @@ -193,6 +195,12 @@ class WorkflowScheduledTransition extends WorkflowTransition { if ($end) { $query->condition('timestamp', $end, '<'); } + if ($from_sid) { + $query->condition('from_sid', $from_sid, '='); + } + if ($to_sid) { + $query->condition('to_sid', $from_sid, '='); + } $ids = $query->execute(); $transitions = self::loadMultiple($ids); @@ -233,7 +241,8 @@ class WorkflowScheduledTransition extends WorkflowTransition { $fields['timestamp'] = BaseFieldDefinition::create('created') ->setLabel(t('Scheduled')) ->setDescription(t('The date+time this transition is scheduled for.')) - ->setQueryable(FALSE) +// ->setQueryable(FALSE) +// ->setCustomStorage(FALSE) // ->setTranslatable(TRUE) // ->setDisplayOptions('view', array( // 'label' => 'hidden', diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowState.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowState.php index 682736e5a..a4be81d00 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowState.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowState.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\Entity; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Language\LanguageInterface; +use Drupal\workflow\WorkflowTypeAttributeTrait; /** * Workflow configuration entity to persistently store configuration. @@ -54,6 +55,11 @@ use Drupal\Core\Language\LanguageInterface; */ class WorkflowState extends ConfigEntityBase { + /* + * Add variables and get/set methods for Workflow property. + */ + use WorkflowTypeAttributeTrait; + /** * The machine name. * @@ -68,13 +74,6 @@ class WorkflowState extends ConfigEntityBase { */ public $label; - /** - * The machine_name of the attached Workflow. - * - * @var string - */ - public $wid; - /** * The weight of this Workflow state. * @@ -89,11 +88,11 @@ class WorkflowState extends ConfigEntityBase { public $status = 1; /** - * The attached Workflow. + * The module implementing this object, for config_export. * - * @var Workflow + * @var string */ - protected $workflow; + protected $module = 'workflow'; /** * CRUD functions. @@ -133,7 +132,7 @@ class WorkflowState extends ConfigEntityBase { // Create the machine_name for new states. // N.B.: Keep machine_name in WorkflowState and ~ListBuilder aligned. $sid = $this->id(); - $wid = $this->wid; + $wid = $this->getWorkflowId(); $label = $this->label(); // Set the workflow-including machine_name. @@ -185,7 +184,7 @@ class WorkflowState extends ConfigEntityBase { $result = []; foreach ($states as $state) { /** @var WorkflowState $state */ - if ((!$wid) || ($wid == $state->wid)) { + if ((!$wid) || ($wid == $state->getWorkflowId())) { $result[$state->id()] = $state; } } @@ -198,8 +197,8 @@ class WorkflowState extends ConfigEntityBase { public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) { /** @var WorkflowState $a */ /** @var WorkflowState $b */ - $a_wid = $a->wid; - $b_wid = $b->wid; + $a_wid = $a->getWorkflowId(); + $b_wid = $b->getWorkflowId(); if ($a_wid == $b_wid) { $a_weight = $a->getWeight(); $b_weight = $b->getWeight(); @@ -263,7 +262,7 @@ class WorkflowState extends ConfigEntityBase { } // Delete the transitions this state is involved in. - $workflow = Workflow::load($this->wid); + $workflow = Workflow::load($this->getWorkflowId()); /** @var WorkflowInterface $workflow */ /** @var WorkflowTransitionInterface $transition */ foreach ($workflow->getTransitionsByStateId($current_sid, '') as $transition) { @@ -295,39 +294,6 @@ class WorkflowState extends ConfigEntityBase { return $this->weight; } - /** - * Returns the Workflow ID of this State. - * - * @return string - * Workflow Id. - */ - public function getWorkflowId() { - return $this->wid; - } - - /** - * Returns the Workflow object of this State. - * - * @return Workflow - * Workflow object. - */ - public function getWorkflow() { - if (!isset($this->workflow)) { - $this->workflow = Workflow::load($this->wid); - } - return $this->workflow; - } - - /** - * @param Workflow $workflow - */ - public function setWorkflow(Workflow $workflow) { - workflow_debug(__FILE__, __FUNCTION__, __LINE__); // @todo D8-port: still test this snippet. - - $this->wid = $workflow->id(); - $this->workflow = $workflow; - } - /** * Returns the Workflow object of this State. * @@ -396,15 +362,16 @@ class WorkflowState extends ConfigEntityBase { // No workflow, no options ;-) return $transitions; } + // Load a User object, since we cannot add Roles to AccountInterface. + if (!$user = workflow_current_user($account)) { + // In some edge cases, no user is provided. + return $transitions; + } // @todo: Keep below code aligned between WorkflowState, ~Transition, ~TransitionListController - /** * Get permissions of user, adding a Role to user, depending on situation. */ - // Load a User object, since we cannot add Roles to AccountInterface. - /** @var \Drupal\user\UserInterface $user */ - $user = workflow_current_user($account); // Determine if user is owner of the entity. $is_owner = WorkflowManager::isOwner($user, $entity); @@ -423,6 +390,7 @@ class WorkflowState extends ConfigEntityBase { * Get the object and its permissions. */ /** @var WorkflowConfigTransition[] $transitions */ + /** @var Workflow $workflow */ $transitions = $workflow->getTransitionsByStateId($this->id(), ''); /** @@ -518,6 +486,7 @@ class WorkflowState extends ConfigEntityBase { // We cannot use getTransitions, since there are no ConfigTransitions // from State with ID 0, and we do not want to repeat States. /** @var WorkflowState $state */ + /** @var Workflow $workflow */ foreach ($workflow->getStates() as $state) { $options[$state->id()] = html_entity_decode(t('@label', ['@label' => $state->label()])); } diff --git a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowTransition.php b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowTransition.php index 9e5f7990a..2563d6f4c 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowTransition.php +++ b/sites/all/modules/contrib/admin/workflow/src/Entity/WorkflowTransition.php @@ -8,6 +8,7 @@ use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Language\Language; use Drupal\user\Entity\User; use Drupal\user\UserInterface; +use Drupal\workflow\WorkflowTypeAttributeTrait; /** * Implements an actual, executed, Transition. @@ -57,6 +58,11 @@ use Drupal\user\UserInterface; */ class WorkflowTransition extends ContentEntityBase implements WorkflowTransitionInterface { + /* + * Add variables and get/set methods for Workflow property. + */ + use WorkflowTypeAttributeTrait; + /* * Transition data: are provided via baseFieldDefinitions(). */ @@ -64,7 +70,6 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition /* * Cache data. */ - protected $workflow; // Use WorkflowTransition->getWorkflow() to fetch this. protected $entity = NULL; // Use WorkflowTransition->getTargetEntity() to fetch this. protected $user = NULL; // Use WorkflowTransition->getOwner() to fetch this. @@ -116,17 +121,15 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition public static function create(array $values = []) { if (is_array($values) && isset($values[0])) { $value = $values[0]; - $values['wid'] = ''; - $values['from_sid'] = ''; - if (is_string($value) && $state = WorkflowState::load($value)) { - $values['wid'] = $state->getWorkflowId(); - $values['from_sid'] = $state->id(); + $state = NULL; + if (is_string($value)) { + $state = WorkflowState::load($value); } elseif (is_object($value) && $value instanceof WorkflowState) { $state = $value; - $values['wid'] = $state->getWorkflowId(); - $values['from_sid'] = $state->id(); } + $values['wid'] = $state ? $state->getWorkflowId() : ''; + $values['from_sid'] = $state ? $state->id() : ''; } // Add default values. @@ -185,6 +188,10 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition public function save() { // return parent::save(); + // Set Target Entity to be used by Rules. + $reference = $this->get('entity_id')->first(); + $reference->set('entity', $this->getTargetEntity()); + // Avoid custom actions for subclass WorkflowScheduledTransition. if ($this->isScheduled()) { return parent::save(); @@ -257,7 +264,7 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition /** @var $query \Drupal\Core\Entity\Query\QueryInterface */ $query = \Drupal::entityQuery($transition_type) ->condition('entity_type', $entity_type) - ->sort('timestamp', $sort) // 'DESC' || 'ASC' + ->sort('timestamp', $sort)// 'DESC' || 'ASC' ->addTag($transition_type); if (!empty($entity_ids)) { $query->condition('entity_id', $entity_ids, 'IN'); @@ -387,6 +394,17 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition return $result; } + /** + * Determines if the State changes by this Transition. + * @return bool + */ + public function hasStateChange() { + if ($this->from_sid->target_id == $this->to_sid->target_id) { + return FALSE; + } + return TRUE; + } + /** * {@inheritdoc} */ @@ -409,7 +427,7 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition static $static_info = NULL; - if (isset($static_info[$entity_id][$field_name][$label])) { + if (isset($static_info[$entity_id][$field_name][$label]) && !$this->isEmpty()) { // Error: this Transition is already executed. // On the development machine, execute() is called twice, when // on an Edit Page, the entity has a scheduled transition, and @@ -451,8 +469,7 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition // @todo: move below code to $this->isAllowed(). // If the state has changed, check the permissions. // No need to check if Comments or attached fields are filled. - $state_changed = ($from_sid != $to_sid); - if ($state_changed) { + if ($this->hasStateChange()) { // Make sure this transition is allowed by workflow module Admin UI. if (!$force) { $user->addRole(WORKFLOW_ROLE_AUTHOR_RID); @@ -503,7 +520,7 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition $this->save(); // Register state change with watchdog. - if ($state_changed && !empty($this->getWorkflow()->options['watchdog_log'])) { + if ($this->hasStateChange() && !empty($this->getWorkflow()->options['watchdog_log'])) { if ($this->getEntityTypeId() == 'workflow_scheduled_transition') { $message = 'Scheduled state change of @entity_type_label %entity_label to %sid2 executed'; } @@ -597,31 +614,6 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition } } - /** - * {@inheritdoc} - */ - public function getWorkflow() { - if (!$this->workflow && $wid = $this->getWorkflowId()) { - $this->workflow = Workflow::load($wid); - } - return $this->workflow; - } - - /** - * {@inheritdoc} - */ - public function getWorkflowId() { - - if (!$this->wid->target_id && $state = $this->getFromState()) { - // Fallback. - $state = ($state) ? $state : $this->getToState(); - $wid = ($state) ? $state->getWorkflowId() : ''; - - $this->set('wid', $wid); - } - return $this->wid->target_id; - } - /** * {@inheritdoc} */ @@ -1074,12 +1066,14 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition $user = $transition->getOwner(); $user_name = ($user) ? $user->getAccountName() : 'unknown username'; $t_string = $this->getEntityTypeId() . ' ' . $this->id() . ' for workflow_type ' . $this->getWorkflowId() . ' ' . ($function ? ("in function '$function'") : ''); - $output[] = 'Entity = ' . $this->getTargetEntityTypeId() . '/' . (($entity) ? ($entity->bundle() . '/' . $entity->id()) : '___/0') ; + $output[] = 'Entity = ' . $this->getTargetEntityTypeId() . '/' . (($entity) ? ($entity->bundle() . '/' . $entity->id()) : '___/0'); $output[] = 'Field = ' . $transition->getFieldName(); $output[] = 'From/To = ' . $transition->getFromSid() . ' > ' . $transition->getToSid() . ' @ ' . $time; $output[] = 'Comment = ' . $user_name . ' says: ' . $transition->getComment(); - $output[] = 'Forced = ' . ($transition->isForced() ? 'yes' : 'no') .'; ' . 'Scheduled = ' . ($transition->isScheduled() ? 'yes' : 'no'); - if (function_exists('dpm')) { dpm($output, $t_string); } + $output[] = 'Forced = ' . ($transition->isForced() ? 'yes' : 'no') . '; ' . 'Scheduled = ' . ($transition->isScheduled() ? 'yes' : 'no'); + if (function_exists('dpm')) { // in Workflow->dpm(). + dpm($output, $t_string); // in Workflow->dpm(). + } // in Workflow->dpm(). } } diff --git a/sites/all/modules/contrib/admin/workflow/src/Form/WorkflowTransitionForm.php b/sites/all/modules/contrib/admin/workflow/src/Form/WorkflowTransitionForm.php index 680d1b54a..d63cb79b4 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Form/WorkflowTransitionForm.php +++ b/sites/all/modules/contrib/admin/workflow/src/Form/WorkflowTransitionForm.php @@ -45,13 +45,11 @@ class WorkflowTransitionForm extends ContentEntityForm { // $entity_type = $transition->getTargetEntityTypeId(); // $entity_id = $transition->getTargetEntityId();; + $suffix = 'form'; // Emulate nodeForm convention. if ($transition->id()) { $suffix = 'edit_form'; } - else { - $suffix = 'form'; - } $form_id = implode('_', ['workflow_transition', $field_name, $suffix]); $form_id = Html::getUniqueId($form_id); diff --git a/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowNodeGivenStateAction.php b/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowNodeGivenStateAction.php index b12bbcfa7..1950817af 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowNodeGivenStateAction.php +++ b/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowNodeGivenStateAction.php @@ -73,7 +73,7 @@ class WorkflowNodeGivenStateAction extends WorkflowStateActionBase { } // Fire the transition. - workflow_execute_transition($transition, $force); + workflow_execute_transition($transition, $force = FALSE); } } diff --git a/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowStateActionBase.php b/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowStateActionBase.php index 83c0b27e2..44dfb53cf 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowStateActionBase.php +++ b/sites/all/modules/contrib/admin/workflow/src/Plugin/Action/WorkflowStateActionBase.php @@ -109,7 +109,6 @@ abstract class WorkflowStateActionBase extends ConfigurableActionBase implements * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $form = []; // If we are on admin/config/system/actions and use CREATE AN ADVANCED ACTION // Then $context only contains: @@ -126,18 +125,18 @@ abstract class WorkflowStateActionBase extends ConfigurableActionBase implements $wids = workflow_get_workflow_names(); if (empty($field_name) && count($wids) > 1) { - drupal_set_message('You have more then one workflow in the system. Please first select the field name + drupal_set_message('You have multiple workflows in the system. Please first select the field name and save the form. Then, revisit the form to set the correct state value.', 'warning'); } - if (empty($field_name)) { - $wid = count($wids) ? array_keys($wids)[0] : ''; - } - else { + + $wid = count($wids) ? array_keys($wids)[0] : ''; + if (!empty($field_name)) { $fields = _workflow_info_fields($entity = NULL, $entity_type = '', $entity_bundle = '', $field_name); $wid = count($fields) ? reset($fields)->getSetting('workflow_type') : ''; } // Get the common Workflow, or create a dummy Workflow. + /** @var Workflow $workflow */ $workflow = $wid ? Workflow::load($wid) : Workflow::create(['id' => 'dummy_action', 'label' => 'dummy_action']); $current_state = $workflow->getCreationState(); @@ -183,7 +182,7 @@ abstract class WorkflowStateActionBase extends ConfigurableActionBase implements \Drupal::time()->getRequestTime(), $comment = $config['comment'], $force = $config['force'] - ); + ); // Add the WorkflowTransitionForm to the page. @todo diff --git a/sites/all/modules/contrib/admin/workflow/src/Plugin/Derivative/WorkflowLocalTask.php b/sites/all/modules/contrib/admin/workflow/src/Plugin/Derivative/WorkflowLocalTask.php new file mode 100644 index 000000000..b33817a73 --- /dev/null +++ b/sites/all/modules/contrib/admin/workflow/src/Plugin/Derivative/WorkflowLocalTask.php @@ -0,0 +1,75 @@ +entityTypeManager = $entity_type_manager; + $this->stringTranslation = $string_translation; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('entity_type.manager'), + $container->get('string_translation') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions($base_plugin_definition) { + $this->derivatives = []; + + $field_list = workflow_get_workflow_fields_by_entity_type(); + foreach ($field_list as $entity_type_id => $fields) { + $this->derivatives["entity.$entity_type_id.workflow_history"] = [ + 'route_name' => "entity.$entity_type_id.workflow_history", + 'title' => $this->t('Workflow'), + 'base_route' => "entity.$entity_type_id.canonical", + 'weight' => 100, + ]; + } + + foreach ($this->derivatives as &$entry) { + $entry += $base_plugin_definition; + } + + return $this->derivatives; + } + +} \ No newline at end of file diff --git a/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldType/WorkflowItem.php b/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldType/WorkflowItem.php index b07bea12f..46cead80a 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldType/WorkflowItem.php +++ b/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldType/WorkflowItem.php @@ -156,7 +156,6 @@ class WorkflowItem extends ListItemBase { return [ 'workflow_type' => '', - 'allowed_values_function' => 'workflow_state_allowed_values', ] + parent::defaultStorageSettings(); } diff --git a/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php b/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php index 3f13f5b71..f8268bb5a 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php +++ b/sites/all/modules/contrib/admin/workflow/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php @@ -78,7 +78,7 @@ class WorkflowDefaultWidget extends WidgetBase { $field_storage = $field_config->getFieldStorageDefinition(); $entity = $item->getEntity(); - $field_name = $field_storage->get('field_name'); + $field_name = $field_storage->getName(); // Create a transition, to pass to the form. No need to use setValues(). $from_sid = workflow_node_current_state($entity, $field_name); diff --git a/sites/all/modules/contrib/admin/workflow/src/Plugin/Validation/Constraint/WorkflowFieldConstraintValidator.php b/sites/all/modules/contrib/admin/workflow/src/Plugin/Validation/Constraint/WorkflowFieldConstraintValidator.php index a3917fbe2..37c105ccf 100644 --- a/sites/all/modules/contrib/admin/workflow/src/Plugin/Validation/Constraint/WorkflowFieldConstraintValidator.php +++ b/sites/all/modules/contrib/admin/workflow/src/Plugin/Validation/Constraint/WorkflowFieldConstraintValidator.php @@ -3,10 +3,8 @@ namespace Drupal\workflow\Plugin\Validation\Constraint; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; -use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\field\Entity\FieldStorageConfig; use Drupal\user\UserStorageInterface; -use Drupal\workflow\Entity\WorkflowTransitionInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; @@ -54,6 +52,7 @@ class WorkflowFieldConstraintValidator extends ConstraintValidator implements Co */ public function validate($entity, Constraint $constraint) { // Workflow field name on CommentForm has special requirements. + /** @var FieldStorageConfig $field_storage */ $field_storage = $entity->getFieldDefinition()->getFieldStorageDefinition(); if ($field_storage->getTargetEntityTypeId() == 'comment') { if (!$this->isValidFieldname($field_storage)) { @@ -76,7 +75,7 @@ class WorkflowFieldConstraintValidator extends ConstraintValidator implements Co return TRUE; } - $field_name = $field_storage->get('field_name'); + $field_name = $field_storage->getName(); // Check if the 'comment' field name exists on the 'commented' entity type. // @todo: Still not waterproof. You could have a field on a non-relevant entity_type. diff --git a/sites/all/modules/contrib/admin/workflow/src/Routing/RouteSubscriber.php b/sites/all/modules/contrib/admin/workflow/src/Routing/RouteSubscriber.php new file mode 100644 index 000000000..66e5b254e --- /dev/null +++ b/sites/all/modules/contrib/admin/workflow/src/Routing/RouteSubscriber.php @@ -0,0 +1,136 @@ +entityTypeManager = $entity_manager; + } + + /** + * {@inheritdoc} + */ + protected function alterRoutes(RouteCollection $collection) { + + $field_list = workflow_get_workflow_fields_by_entity_type(); + foreach ($field_list as $entityTypeId => $fields) { + + /* + * @todo Create a Entity workflow field list page and a route + * that redirect to the page when a entity have more than + * one workflow fields. + */ + + // Only 1 field. Workflow is redirect to workflow/{field_name}. + if (count($fields) < 2) { + $path = "/$entityTypeId/{{$entityTypeId}}/workflow"; + $route = $this->getEntityLoadRoute($entityTypeId, $path); + $collection->add("entity.$entityTypeId.workflow_history", $route); + } + + // Generate one route for each workflow field. + foreach ($fields as $field_name => $field) { + $path = "/$entityTypeId/{{$entityTypeId}}/workflow/$field_name"; + $route = $this->getEntityLoadRoute($entityTypeId, $path); + $collection->add("entity.$entityTypeId.workflow_history.$field_name", $route); + } + } + } + + /** + * Gets the entity load route. + * + * @param string $entityTypeId + * The entity type id. + * @param string $path + * The Path of the route. + * + * @return \Symfony\Component\Routing\Route|null + * The generated route, if available. + */ + protected function getEntityLoadRoute($entityTypeId, $path) { + + /* + * @todo Create the Route for taxonomy term like + * '/taxonomy/term/{taxonomy_term}/workflow/{field_name}' + * + */ + $route = new Route( + $path, + [ + '_controller' => '\Drupal\workflow\Controller\WorkflowTransitionListController::historyOverview', + '_title' => 'Workflow history', + ], + [ + '_custom_access' => '\Drupal\workflow\Access\WorkflowHistoryAccess::access', + ], + [ + '_admin_route' => TRUE, + '_workflow_entity_type_id' => $entityTypeId, // @todo: remove + 'parameters' => [ + $entityTypeId => ['type' => 'entity:' . $entityTypeId], + ], + ] + ); + + return $route; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events = parent::getSubscribedEvents(); + $events[RoutingEvents::ALTER] = ['onAlterRoutes', 100]; + return $events; + } + + /** + * Get all field of type workflow. + * + * @return array + * Return all workflow fields. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + */ + public function listWorkflowFields() { + $fieldType = 'workflow'; + $fieldStorageConfigs = $this->entityTypeManager->getStorage('field_storage_config')->loadByProperties(['type' => $fieldType]); + if (!$fieldStorageConfigs) { + return []; + } + + $availableItems = []; + foreach ($fieldStorageConfigs as $fieldStorage) { + $availableItems[] = $fieldStorage; + } + + return $availableItems; + } + +} \ No newline at end of file diff --git a/sites/all/modules/contrib/admin/workflow/src/WorkflowTransitionListBuilder.php b/sites/all/modules/contrib/admin/workflow/src/WorkflowTransitionListBuilder.php index 5368b20ca..8d6c46c11 100644 --- a/sites/all/modules/contrib/admin/workflow/src/WorkflowTransitionListBuilder.php +++ b/sites/all/modules/contrib/admin/workflow/src/WorkflowTransitionListBuilder.php @@ -3,8 +3,8 @@ namespace Drupal\workflow; use Drupal\Component\Utility\Html; -use Drupal\Core\Entity\EntityListBuilder; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityListBuilder; use Drupal\workflow\Entity\WorkflowTransition; /** @@ -55,6 +55,7 @@ class WorkflowTransitionListBuilder extends EntityListBuilder { $field_name = workflow_url_get_field_name(); // @todo D8-port: document $limit. Should be used in pager, not in load(). + // N.B. Using the provided default History view is recommended. $this->limit = \Drupal::config('workflow.settings')->get('workflow_states_per_page'); $limit = $this->limit; // Get Transitions with highest timestamp first. @@ -202,7 +203,7 @@ class WorkflowTransitionListBuilder extends EntityListBuilder { 'class' => ['footer-class'], 'data' => [ [ - 'data' => WORKFLOW_MARK_STATE_IS_DELETED . ' ' . t('State is no longer available.'), + 'data' => self::WORKFLOW_MARK_STATE_IS_DELETED . ' ' . t('State is no longer available.'), 'colspan' => count($build['table']['#header']), ], ], @@ -210,7 +211,7 @@ class WorkflowTransitionListBuilder extends EntityListBuilder { ]; */ $build['workflow_footer'] = [ - '#markup' => WORKFLOW_MARK_STATE_IS_DELETED . ' ' . t('State is no longer available.'), + '#markup' => self::WORKFLOW_MARK_STATE_IS_DELETED . ' ' . t('State is no longer available.'), '#weight' => 500, // @todo Make this better. ]; } diff --git a/sites/all/modules/contrib/admin/workflow/src/WorkflowTypeAttributeTrait.php b/sites/all/modules/contrib/admin/workflow/src/WorkflowTypeAttributeTrait.php new file mode 100644 index 000000000..05d929f67 --- /dev/null +++ b/sites/all/modules/contrib/admin/workflow/src/WorkflowTypeAttributeTrait.php @@ -0,0 +1,103 @@ +wid = ''; + $this->workflow = NULL; + if ($workflow) { + $this->wid = $workflow->id(); + $this->workflow = $workflow; + } + } + + /** + * Returns the Workflow object of this object. + * + * @return Workflow + * Workflow object. + */ + public function getWorkflow() { + if (!empty($this->workflow)) { + return $this->workflow; + } + + /** @noinspection PhpAssignmentInConditionInspection */ + if ($wid = $this->getWorkflowId()) { + $this->workflow = Workflow::load($wid); + } + return $this->workflow; + } + + /** + * Sets the Workflow ID of this object. + * + * @return object + */ + public function setWorkflowId($wid) { + $this->wid = $wid; + $this->workflow = NULL; + return $this; + } + + /** + * Returns the Workflow ID of this object. + * + * @return string + * Workflow Id. + */ + public function getWorkflowId() { + /** @var ContentEntityBase $this */ + if (!empty($this->wid)) { + return $this->wid; + } + + $value = $this->get('wid'); + if (is_string($value)) { + $this->wid = $value; + } + elseif (is_object($value)) { + $wid = isset($value->getValue()[0]['target_id']) ? $value->getValue()[0]['target_id'] : ''; + // or: $this->set('wid', $wid); + $this->wid = $wid; // in WorkflowTransition. + } + else { + workflow_debug(__FILE__, __FUNCTION__, __LINE__, '', ''); + } + + return $this->wid; + } + +} diff --git a/sites/all/modules/contrib/admin/workflow/workflow.field.inc b/sites/all/modules/contrib/admin/workflow/workflow.field.inc index 95e89fabb..872d85f04 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.field.inc +++ b/sites/all/modules/contrib/admin/workflow/workflow.field.inc @@ -95,6 +95,7 @@ function workflow_state_formatter($entity, $field_name, $current_sid = '') { // If user creates a node, and only 1 option is available, the formatter // is shown with key, not value, because creation state does not count. // In this case, hide the formatter. + /** @var \Drupal\workflow\Entity\WorkflowState $state */ $state = \Drupal\workflow\Entity\WorkflowState::load($current_sid); if ($state->isCreationState()) { return $element; @@ -117,3 +118,18 @@ function workflow_state_formatter($entity, $field_name, $current_sid = '') { return $element; } + +/** + * This function is a residue for installations that have v8.x-1.0 + * The setting for options_allowed_values is still in the Field confuguration + * Saving the field data again does not remove the settings. + * So, we copy code from options_allowed_values(). + * + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition + * + * @return mixed + */ +function workflow_state_allowed_values(\Drupal\Core\Field\FieldStorageDefinitionInterface $definition) { + $values = $definition->getSetting('allowed_values'); + return $values; +} diff --git a/sites/all/modules/contrib/admin/workflow/workflow.form.inc b/sites/all/modules/contrib/admin/workflow/workflow.form.inc index a26ed430c..384ae9bea 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.form.inc +++ b/sites/all/modules/contrib/admin/workflow/workflow.form.inc @@ -190,7 +190,7 @@ function _workflow_transition_form_get_action_buttons(array $form, array $workfl if (isset($form['#form_id']) && substr($form['#form_id'], 0, 24) == 'workflow_transition_form') { // Hide same-state-button on the transition-form (that is: // view page or workflow history tab) if there is nothing to do. - // However, a Transition may be fieldable. + // However, a Transition may be fieldable (have attached fields). if ($form['comment']['#access'] == FALSE) { $workflow_submit_action['#access'] = FALSE; } diff --git a/sites/all/modules/contrib/admin/workflow/workflow.info.yml b/sites/all/modules/contrib/admin/workflow/workflow.info.yml index 0056bdfb2..8c065af53 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.info.yml +++ b/sites/all/modules/contrib/admin/workflow/workflow.info.yml @@ -10,8 +10,8 @@ dependencies: - options - user -# Information added by Drupal.org packaging script on 2017-12-17 -version: '8.x-1.0' +# Information added by Drupal.org packaging script on 2018-04-29 +version: '8.x-1.1' core: '8.x' project: 'workflow' -datestamp: 1513552400 +datestamp: 1525039388 diff --git a/sites/all/modules/contrib/admin/workflow/workflow.install b/sites/all/modules/contrib/admin/workflow/workflow.install index 0f1a48971..19b8b360f 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.install +++ b/sites/all/modules/contrib/admin/workflow/workflow.install @@ -18,13 +18,6 @@ function workflow_install() { drupal_set_message($message); } -/** - * Implements hook_uninstall(). - */ -function workflow_uninstall() { -// \Drupal::config('workflow.settings')->clear('workflow_states_per_page')->save(); // @FIXME -} - /** * Implements hook_requirements(). * diff --git a/sites/all/modules/contrib/admin/workflow/workflow.links.task.yml b/sites/all/modules/contrib/admin/workflow/workflow.links.task.yml index 46ea56155..0b5c25633 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.links.task.yml +++ b/sites/all/modules/contrib/admin/workflow/workflow.links.task.yml @@ -18,15 +18,6 @@ entity.workflow_type.delete_form: title: 'Delete' weight: 10 -# @todo D8-port: make Workflow History tab happen for every entity_type. -# @see workflow.routing.yml, workflow.links.task.yml, WorkflowTransitionListController. -entity.node.workflow_history: - route_name: entity.node.workflow_history - base_route: entity.node.canonical - title: 'Workflow' - weight: 30 -entity.taxonomy_term.edit_form: - route_name: entity.taxonomy_term.workflow_history - base_route: entity.taxonomy_term.canonical - title: 'Workflow' - weight: 30 +workflow.entities: + deriver: 'Drupal\workflow\Plugin\Derivative\WorkflowLocalTask' + weight: 100 diff --git a/sites/all/modules/contrib/admin/workflow/workflow.module b/sites/all/modules/contrib/admin/workflow/workflow.module index 8e8ab2bc0..66dfc404f 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.module +++ b/sites/all/modules/contrib/admin/workflow/workflow.module @@ -176,9 +176,9 @@ function workflow_entity_delete(\Drupal\Core\Entity\EntityInterface $entity) { elseif (!WorkflowManager::isWorkflowEntityType($entity->getEntityTypeId())) { // A 'normal' entity is deleted. foreach ($fields = _workflow_info_fields($entity) as $field_id => $field_storage) { - $entity_type = $field_storage->getTargetEntityTypeId(); $entity_id = $entity->id(); - $field_name = $field_storage->get('field_name'); + $entity_type = $field_storage->getTargetEntityTypeId(); + $field_name = $field_storage->getName(); /** @var $transition Drupal\workflow\Entity\WorkflowTransitionInterface */ foreach (WorkflowScheduledTransition::loadMultipleByProperties($entity_type, [$entity_id], [], $field_name) as $transition) { $transition->delete(); @@ -347,8 +347,8 @@ function workflow_get_workflow_names($required = TRUE) { function workflow_get_workflow_field_names($entity = NULL, $entity_type = '', $entity_bundle = '', $field_name = '') { $result = []; foreach (_workflow_info_fields($entity, $entity_type, $entity_bundle, $field_name) as $definition) { - $field_name = $definition->getName(); - $result[$field_name] = $definition->getName(); + $field_name2 = $definition->getName(); + $result[$field_name2] = $field_name2; } return $result; } @@ -397,10 +397,8 @@ function workflow_get_field_name(\Drupal\Core\Entity\EntityInterface $entity, $f if ($field_name) { return $field_name; } - - $fields = _workflow_info_fields($entity); - $field = reset($fields); - $field_name = $field->getName(); + $fields = workflow_get_workflow_field_names($entity); + $field_name = reset($fields); return $field_name; } @@ -428,8 +426,6 @@ function workflow_current_user(\Drupal\Core\Session\AccountInterface $account = * @param string $field_name * * @return string $current_sid - * - * @deprecated : use WorkflowManager::getCurrentStateId() */ function workflow_node_current_state(\Drupal\Core\Entity\EntityInterface $entity, $field_name = '') { return WorkflowManager::getCurrentStateId($entity, $field_name); @@ -442,8 +438,6 @@ function workflow_node_current_state(\Drupal\Core\Entity\EntityInterface $entity * @param string $field_name * * @return string $previous_sid - * - * @deprecated : use WorkflowManager::getPreviousStateId() */ function workflow_node_previous_state(\Drupal\Core\Entity\EntityInterface $entity, $field_name = '') { return WorkflowManager::getPreviousStateId($entity, $field_name); @@ -486,6 +480,10 @@ function workflow_get_workflows_by_type($entity_bundle, $entity_type) { return $map[$entity_type][$entity_bundle]; } +function workflow_get_workflow_fields_by_entity_type() { + return \Drupal::service('entity_field.manager')->getFieldMapByFieldType('workflow'); +} + /** * Gets the workflow field names, if not known already. * @@ -522,7 +520,24 @@ function _workflow_info_fields($entity = NULL, $entity_type = '', $entity_bundle // Do not use the field_name as ID, but the unique . // since you cannot share the same field on multiple entity_types (unlike D7). $field_config = \Drupal\field\Entity\FieldStorageConfig::loadByName($e_type, $f_name); - $field_info[$field_config->id()] = $field_config; + if ($field_config) { + $field_info[$field_config->id()] = $field_config; + } + else { + // The field is a base/extra field not a configurable Field via Field UI. + + // Refetch the field definitions, with extra data. + $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions($e_type, $entity_bundle); + // @todo ?? Loop over bundles? + /** @var \Drupal\Core\Field\BaseFieldDefinition $field_config */ + $field_config = $field_definitions[$f_name]; + if ($field_config) { + $field_info[$field_config->getUniqueStorageIdentifier()] = $field_config; + } + else { + // @todo ?? Loop over bundles? + } + } } } } @@ -545,36 +560,27 @@ function workflow_url_get_entity(\Drupal\Core\Entity\EntityInterface $entity = N return $entity; } - $route_match = \Drupal::routeMatch(); - - // @todo: get entity for any route. - // On node pages, we'd get an object. - $entity = $route_match->getParameter('node'); - if ($entity && is_object($entity)) { - return $entity; + $entities = []; + foreach (\Drupal::routeMatch()->getParameters() as $param) { + if ($param instanceof \Drupal\Core\Entity\EntityInterface) { + $entities[] = $param; + } } - if ($entity && !is_object($entity)) { + $value = reset($entities); + + if ($value && is_object($value)) { + return $value; + } + + if ($value && !is_object($value)) { // On workflow tab, we'd get an id. - $entity = \Drupal\node\Entity\Node::load($entity); + // This is an indicator that the route is mal-configured. + workflow_debug(__FILE__, __FUNCTION__, __LINE__, 'route declaration is not optimal.'); + $entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($value); return $entity; } - // It was not a Node, try a Term. - // On term pages, we get objects, or id's. - $entity = $route_match->getParameter('taxonomy_term'); - if ($entity && is_object($entity)) { - return $entity; - } - elseif ($entity && !is_object($entity)) { - $entity = \Drupal\taxonomy\Entity\Term::load($entity); - return $entity; - } - - if (!$entity) { - // We may be on a entity add page/ - // Or we may be on a page of some unknown entity. - } - return $entity; + return $value; } /** @@ -585,10 +591,7 @@ function workflow_url_get_entity(\Drupal\Core\Entity\EntityInterface $entity = N * @return string|null $field_name */ function workflow_url_get_field_name() { - /** @var $route_match \Drupal\Core\Routing\RouteMatchInterface */ - $route_match = \Drupal::routeMatch(); - $field_name = $route_match->getParameter('field_name'); - return $field_name; + return workflow_url_get_parameter('field_name'); } /** @@ -609,32 +612,37 @@ function workflow_url_get_operation() { } /** - * Helper function to determine Workflow from Workflow UI URL. + * Helper function to get arbitrary parameter from a route. * - * @param string $url + * @param $parameter + * The requested parameter. + * @return string $field_name + */ +function workflow_url_get_parameter($parameter) { + return \Drupal::routeMatch()->getParameter($parameter); + // return \Drupal::request()->get($parameter); +} + +/** + * Helper function to determine Workflow from Workflow UI URL. * @return Workflow */ -function workflow_url_get_workflow($url = '' ) { +function workflow_url_get_workflow() { /** @var $workflows \Drupal\workflow\Entity\Workflow[] */ static $workflows = []; - // For some reason, $_SERVER is not allowed as default. - $url = ($url == '') ? $_SERVER['REQUEST_URI'] : $url; - - // The URL may have prefixes: / - // ex.1: /en/admin/config/workflow/workflow/MY_WORKFLOW/states - // ex.2: /admin/config/workflow/workflow/MY_WORKFLOW/states - $base_url = '/config/workflow/workflow/'; - $string = substr($url, strpos($url, $base_url) + strlen($base_url)); - $wid = explode('/', $string)[0]; - if (!isset($workflows[$wid])) { - $workflows[$wid] = Workflow::load($wid); + $wid = workflow_url_get_parameter('workflow_type'); + if (is_object($wid)) { // $wid is a Workflow object. + return $wid; } + // $wid is a string + if (!isset($workflows[$wid])) { + $workflows[$wid] = $wid ? Workflow::load($wid) : NULL; + } return $workflows[$wid]; } - /** * Helper function to determine the title of the page. * diff --git a/sites/all/modules/contrib/admin/workflow/workflow.routing.yml b/sites/all/modules/contrib/admin/workflow/workflow.routing.yml index 2e124652f..1ff93ad75 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.routing.yml +++ b/sites/all/modules/contrib/admin/workflow/workflow.routing.yml @@ -109,36 +109,3 @@ entity.workflow_scheduled_transition.delete_form: _admin_route: TRUE requirements: _entity_access: 'workflow_transition.delete' - -### The Workflow Transition History List (Tab) -# @todo D8-port: make Workflow History tab happen for every entity_type. -# @see workflow.routing.yml, workflow.links.task.yml, WorkflowTransitionListController. -# A route for showing the Workflow history tab. -entity.node.workflow_history: - path: '/node/{node}/workflow/{field_name}' - defaults: - _title: 'Workflow history' - _controller: '\Drupal\workflow\Controller\WorkflowTransitionListController::historyOverview' - field_name: ~ - requirements: - _custom_access: '\Drupal\workflow\Controller\WorkflowTransitionListController::historyAccess' - _module_dependencies: 'node' - options: - _admin_route: TRUE - parameters: - entity: - type: entity:{entity_type} - -entity.taxonomy_term.workflow_history: - path: '/taxonomy/term/{taxonomy_term}/workflow/{field_name}' - defaults: - _title: 'Workflow history' - _controller: '\Drupal\workflow\Controller\WorkflowTransitionListController::historyOverview' - field_name: ~ - requirements: - _custom_access: '\Drupal\workflow\Controller\WorkflowTransitionListController::historyAccess' - _module_dependencies: 'taxonomy' - options: - parameters: - entity: - type: entity:{entity_type} diff --git a/sites/all/modules/contrib/admin/workflow/workflow.services.yml b/sites/all/modules/contrib/admin/workflow/workflow.services.yml index 11489db5b..ca424d1ae 100644 --- a/sites/all/modules/contrib/admin/workflow/workflow.services.yml +++ b/sites/all/modules/contrib/admin/workflow/workflow.services.yml @@ -3,8 +3,8 @@ services: class: Drupal\workflow\Entity\WorkflowManager arguments: ['@entity_type.manager', '@entity.query', '@config.factory', '@string_translation', '@module_handler', '@current_user'] -# workflow.route_subscriber: -# class: Drupal\workflow\Routing\RouteSubscriber -# arguments: ['@entity.manager'] -# tags: -# - { name: event_subscriber } + workflow.route_subscriber: + class: Drupal\workflow\Routing\RouteSubscriber + arguments: ['@entity.manager'] + tags: + - { name: event_subscriber } diff --git a/sites/all/modules/contrib/dev/redis/.travis.yml b/sites/all/modules/contrib/dev/redis/.travis.yml index 30bba24e7..400d14326 100644 --- a/sites/all/modules/contrib/dev/redis/.travis.yml +++ b/sites/all/modules/contrib/dev/redis/.travis.yml @@ -12,12 +12,9 @@ php: - 5.5 - 5.6 - 7 - - hhvm matrix: fast_finish: true - allow_failures: - - php: hhvm env: global: @@ -63,7 +60,7 @@ env: - DRUPAL_TI_BEHAT_BROWSER="firefox" # Use Drupal 8.3.x to run tests. - - DRUPAL_TI_CORE_BRANCH="8.3.x" + - DRUPAL_TI_CORE_BRANCH="8.5.x" # PHPUnit specific commandline arguments. - DRUPAL_TI_PHPUNIT_ARGS="--verbose --debug" diff --git a/sites/all/modules/contrib/dev/redis/redis.info.yml b/sites/all/modules/contrib/dev/redis/redis.info.yml index cc9f23548..06a5bbcb6 100644 --- a/sites/all/modules/contrib/dev/redis/redis.info.yml +++ b/sites/all/modules/contrib/dev/redis/redis.info.yml @@ -5,8 +5,8 @@ type: module # core: 8.x configure: redis.admin_display -# Information added by Drupal.org packaging script on 2017-09-14 -version: '8.x-1.0-rc2' +# Information added by Drupal.org packaging script on 2018-05-30 +version: '8.x-1.0' core: '8.x' project: 'redis' -datestamp: 1505390051 +datestamp: 1527699489 diff --git a/sites/all/modules/contrib/dev/redis/src/Cache/CacheBase.php b/sites/all/modules/contrib/dev/redis/src/Cache/CacheBase.php index 4fe8e5dce..6daf590ac 100644 --- a/sites/all/modules/contrib/dev/redis/src/Cache/CacheBase.php +++ b/sites/all/modules/contrib/dev/redis/src/Cache/CacheBase.php @@ -3,6 +3,7 @@ namespace Drupal\redis\Cache; use \DateInterval; +use Drupal\Component\Assertion\Inspector; use Drupal\Component\Serialization\SerializationInterface; use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheBackendInterface; @@ -297,7 +298,7 @@ abstract class CacheBase implements CacheBackendInterface { // Always add a cache tag for the current bin, so that we can use that for // invalidateAll(). $tags[] = $this->getTagForBin(); - assert('\Drupal\Component\Assertion\Inspector::assertAllStrings($tags)', 'Cache Tags must be strings.'); + assert(Inspector::assertAllStrings($tags), 'Cache Tags must be strings.'); $hash = [ 'cid' => $cid, 'created' => round(microtime(TRUE), 3), diff --git a/sites/all/modules/contrib/dev/redis/src/Lock/Predis.php b/sites/all/modules/contrib/dev/redis/src/Lock/Predis.php index bede5d97b..aa67ca143 100644 --- a/sites/all/modules/contrib/dev/redis/src/Lock/Predis.php +++ b/sites/all/modules/contrib/dev/redis/src/Lock/Predis.php @@ -84,8 +84,8 @@ class Predis extends LockBackendAbstract { // succeed if the key does not exist yet. $result = $this->client->set($key, $id, 'nx', 'px', (int) ($timeout * 1000)); - // If the result is FALSE, we failed to acquire the lock. - if (FALSE === $result) { + // If the result is FALSE or NULL, we failed to acquire the lock. + if (FALSE === $result || NULL === $result) { return FALSE; } diff --git a/sites/all/modules/contrib/dev/redis/src/PersistentLock/Predis.php b/sites/all/modules/contrib/dev/redis/src/PersistentLock/Predis.php new file mode 100644 index 000000000..79252e77e --- /dev/null +++ b/sites/all/modules/contrib/dev/redis/src/PersistentLock/Predis.php @@ -0,0 +1,26 @@ +client = $factory->getClient(); + // Set the lockId to a fixed string to make the lock ID the same across + // multiple requests. The lock ID is used as a page token to relate all the + // locks set during a request to each other. + // @see \Drupal\Core\Lock\LockBackendInterface::getLockId() + $this->lockId = 'persistent'; + } + +} diff --git a/sites/all/modules/contrib/dev/redis/tests/src/Functional/Lock/RedisLockFunctionalTest.php b/sites/all/modules/contrib/dev/redis/tests/src/Functional/Lock/RedisLockFunctionalTest.php index fbf4b0461..d74a05ee2 100644 --- a/sites/all/modules/contrib/dev/redis/tests/src/Functional/Lock/RedisLockFunctionalTest.php +++ b/sites/all/modules/contrib/dev/redis/tests/src/Functional/Lock/RedisLockFunctionalTest.php @@ -41,7 +41,7 @@ class RedisLockFunctionalTest extends LockFunctionalTest { file_put_contents($filename, $contents); $settings = Settings::getAll(); $settings['container_yamls'][] = 'modules/redis/example.services.yml'; - $settings['redis.connection']['interface'] = '\'' . $redis_interface . '\''; + $settings['redis.connection']['interface'] = $redis_interface; new Settings($settings); OpCodeCache::invalidate(DRUPAL_ROOT . '/' . $filename); diff --git a/sites/all/modules/contrib/dev/redis/tests/src/Functional/WebTest.php b/sites/all/modules/contrib/dev/redis/tests/src/Functional/WebTest.php index d5cfcb22d..e49dfa347 100644 --- a/sites/all/modules/contrib/dev/redis/tests/src/Functional/WebTest.php +++ b/sites/all/modules/contrib/dev/redis/tests/src/Functional/WebTest.php @@ -3,7 +3,6 @@ namespace Drupal\Tests\redis\Functional; use Drupal\Component\Utility\OpCodeCache; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Database\Database; use Drupal\Core\Site\Settings; use Drupal\field_ui\Tests\FieldUiTestTrait; @@ -142,10 +141,10 @@ class WebTest extends BrowserTestBase { // Create a node type with a field. $edit = [ 'name' => $this->randomString(), - 'type' => $node_type = Unicode::strtolower($this->randomMachineName()), + 'type' => $node_type = mb_strtolower($this->randomMachineName()), ]; $this->drupalPostForm('admin/structure/types/add', $edit, t('Save and manage fields')); - $field_name = Unicode::strtolower($this->randomMachineName()); + $field_name = mb_strtolower($this->randomMachineName()); $this->fieldUIAddNewField('admin/structure/types/manage/' . $node_type, $field_name, NULL, 'text'); // Create a node, check display, edit, verify that it has been updated. @@ -154,7 +153,7 @@ class WebTest extends BrowserTestBase { 'body[0][value]' => $this->randomMachineName(), 'field_' . $field_name . '[0][value]' => $this->randomMachineName(), ]; - $this->drupalPostForm('node/add/' . $node_type, $edit, t('Save and publish')); + $this->drupalPostForm('node/add/' . $node_type, $edit, t('Save')); // Test the output as anonymous user. $this->drupalLogout(); @@ -169,7 +168,7 @@ class WebTest extends BrowserTestBase { $update = [ 'title[0][value]' => $this->randomMachineName(), ]; - $this->drupalPostForm(NULL, $update, t('Save and keep published')); + $this->drupalPostForm(NULL, $update, t('Save')); $this->assertSession()->responseContains($update['title[0][value]']); $this->drupalGet('node'); $this->assertSession()->responseContains($update['title[0][value]']); diff --git a/sites/all/modules/contrib/dev/redis/tests/src/Kernel/RedisQueueTest.php b/sites/all/modules/contrib/dev/redis/tests/src/Kernel/RedisQueueTest.php index 137cb9821..78110049a 100644 --- a/sites/all/modules/contrib/dev/redis/tests/src/Kernel/RedisQueueTest.php +++ b/sites/all/modules/contrib/dev/redis/tests/src/Kernel/RedisQueueTest.php @@ -39,7 +39,7 @@ class RedisQueueTest extends CoreQueueTest { $queue2 = new $class_name($this->randomMachineName(), $settings, $client_factory->getClient()); $queue2->createQueue(); - $this->queueTest($queue1, $queue2); + $this->runQueueTest($queue1, $queue2); $queue1->deleteQueue(); $queue2->deleteQueue(); @@ -53,7 +53,7 @@ class RedisQueueTest extends CoreQueueTest { $queue2 = new $class_name($this->randomMachineName(), $settings, $client_factory->getClient()); $queue2->createQueue(); - $this->queueTest($queue1, $queue2); + $this->runQueueTest($queue1, $queue2); } /** @@ -74,7 +74,7 @@ class RedisQueueTest extends CoreQueueTest { $queue2 = new $class_name($this->randomMachineName(), $settings, $client_factory->getClient()); $queue2->createQueue(); - $this->queueTest($queue1, $queue2); + $this->runQueueTest($queue1, $queue2); } /** diff --git a/sites/all/modules/contrib/fields/addtoany/addtoany.info.yml b/sites/all/modules/contrib/fields/addtoany/addtoany.info.yml index ad3948b42..ee1c75004 100644 --- a/sites/all/modules/contrib/fields/addtoany/addtoany.info.yml +++ b/sites/all/modules/contrib/fields/addtoany/addtoany.info.yml @@ -7,8 +7,8 @@ dependencies: - drupal:node configure: addtoany.admin_settings -# Information added by Drupal.org packaging script on 2018-03-07 -version: '8.x-1.9' +# Information added by Drupal.org packaging script on 2018-07-03 +version: '8.x-1.10' core: '8.x' project: 'addtoany' -datestamp: 1520385667 +datestamp: 1530656924 diff --git a/sites/all/modules/contrib/fields/addtoany/addtoany.module b/sites/all/modules/contrib/fields/addtoany/addtoany.module index 65677ed32..da490ea64 100644 --- a/sites/all/modules/contrib/fields/addtoany/addtoany.module +++ b/sites/all/modules/contrib/fields/addtoany/addtoany.module @@ -11,6 +11,7 @@ use Drupal\Core\Render\Markup; use Drupal\Core\Url; use Drupal\Component\Utility\UrlHelper; use Drupal\node\Entity\Node; +use Drupal\addtoany\Form\AddToAnySettingsForm; /** * Implements hook_theme(). @@ -58,20 +59,25 @@ function addtoany_theme_suggestions_addtoany_standard(array $variables) { */ function addtoany_entity_extra_field_info() { $extra = []; - $types = ['node', 'comment', 'media']; + $entityTypes = AddToAnySettingsForm::getContentEntities(); + $config = Drupal::config('addtoany.settings'); // Allow modules to alter the entity types. - \Drupal::moduleHandler()->alter('addtoany_entity_types', $types); + \Drupal::moduleHandler()->alter('addtoany_entity_types', $entityTypes); - foreach ($types as $type) { - $bundles = Drupal::service('entity_type.bundle.info')->getBundleInfo($type); - foreach ($bundles as $bundle => $bundle_data) { - $extra[$type][$bundle]['display']['addtoany'] = [ - 'label' => t('AddToAny'), - 'description' => t('Share buttons by AddToAny'), - 'weight' => 5, - 'visible' => FALSE, - ]; + foreach ($entityTypes as $type) { + $entityTypeId = $type->id(); + $isAllowed = $config->get("entities.{$entityTypeId}"); + if ($isAllowed) { + $bundles = Drupal::service('entity_type.bundle.info')->getBundleInfo($entityTypeId); + foreach ($bundles as $bundle => $bundle_data) { + $extra[$entityTypeId][$bundle]['display']['addtoany'] = [ + 'label' => t('AddToAny'), + 'description' => t('Share buttons by AddToAny'), + 'weight' => 5, + 'visible' => FALSE, + ]; + } } } @@ -83,19 +89,23 @@ function addtoany_entity_extra_field_info() { */ function addtoany_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { if ($display->getComponent('addtoany')) { - $data = addtoany_create_entity_data($entity); - $build['addtoany'] = [ - '#addtoany_html' => \Drupal::token()->replace($data['addtoany_html'], ['node' => $entity]), - '#link_url' => $data['link_url'], - '#link_title' => $data['link_title'], - '#button_setting' => $data['button_setting'], - '#button_image' => $data['button_image'], - '#universal_button_placement' => $data['universal_button_placement'], - '#buttons_size' => $data['buttons_size'], - '#entity_type' => $entity->getEntityType()->id(), - '#bundle' => $entity->bundle(), - '#theme' => 'addtoany_standard', - ]; + $config = Drupal::config('addtoany.settings'); + $isAllowed = $config->get("entities.{$entity->getEntityTypeId()}"); + if ($isAllowed) { + $data = addtoany_create_entity_data($entity); + $build['addtoany'] = [ + '#addtoany_html' => \Drupal::token()->replace($data['addtoany_html'], ['node' => $entity]), + '#link_url' => $data['link_url'], + '#link_title' => $data['link_title'], + '#button_setting' => $data['button_setting'], + '#button_image' => $data['button_image'], + '#universal_button_placement' => $data['universal_button_placement'], + '#buttons_size' => $data['buttons_size'], + '#entity_type' => $entity->getEntityType()->id(), + '#bundle' => $entity->bundle(), + '#theme' => 'addtoany_standard', + ]; + } } } diff --git a/sites/all/modules/contrib/fields/addtoany/config/install/addtoany.settings.yml b/sites/all/modules/contrib/fields/addtoany/config/install/addtoany.settings.yml index a66611b94..d44f24b51 100644 --- a/sites/all/modules/contrib/fields/addtoany/config/install/addtoany.settings.yml +++ b/sites/all/modules/contrib/fields/addtoany/config/install/addtoany.settings.yml @@ -9,3 +9,7 @@ universal_button: default custom_universal_button: '' universal_button_placement: before no_3p: false +entities: + media: 1 + node: 1 + comment: 1 diff --git a/sites/all/modules/contrib/fields/addtoany/css/addtoany.admin.css b/sites/all/modules/contrib/fields/addtoany/css/addtoany.admin.css index e96227ffd..63952bf67 100644 --- a/sites/all/modules/contrib/fields/addtoany/css/addtoany.admin.css +++ b/sites/all/modules/contrib/fields/addtoany/css/addtoany.admin.css @@ -1,3 +1,12 @@ +.addtoany-entity-checkbox ~ .description { + display: inline; +} + +.addtoany-entity-checkbox ~ .description a { + margin: 0 3px; + white-space: nowrap; +} + .addtoany-round-icon { border-radius: 14%; } diff --git a/sites/all/modules/contrib/fields/addtoany/src/Form/AddToAnySettingsForm.php b/sites/all/modules/contrib/fields/addtoany/src/Form/AddToAnySettingsForm.php index 41af77765..dd4c95fc9 100644 --- a/sites/all/modules/contrib/fields/addtoany/src/Form/AddToAnySettingsForm.php +++ b/sites/all/modules/contrib/fields/addtoany/src/Form/AddToAnySettingsForm.php @@ -5,7 +5,10 @@ namespace Drupal\addtoany\Form; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Extension\ModuleHandler; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Entity\ContentEntityType; +use Drupal\Core\Link; /** * Configure AddToAny settings for this site. @@ -191,6 +194,69 @@ class AddToAnySettingsForm extends ConfigFormBase { ]; } + $form['addtoany_entity_settings'] = [ + '#type' => 'details', + '#title' => $this->t('Entities'), + ]; + + $form['addtoany_entity_settings']['addtoany_entity_tip_1'] = [ + '#type' => 'html_tag', + '#tag' => 'p', + '#value' => $this + ->t('AddToAny is available on the "Manage display" pages of enabled entities, e.g. Structure > Content types > Article > Manage display.'), + ]; + + $entities = self::getContentEntities(); + + // Allow modules to alter the entity types. + \Drupal::moduleHandler()->alter('addtoany_entity_types', $entities); + + // Whitelist the entity IDs that let us link to each bundle's Manage Display page. + $linkableEntities = [ + 'block_content', 'comment', 'commerce_product', 'commerce_store', + 'contact_message', 'media', 'node', 'paragraph', + ]; + + foreach ($entities as $entity) { + $entityId = $entity->id(); + $entityType = $entity->getBundleEntityType(); + // Get all available bundles for the current entity. + $bundles = \Drupal::service('entity.manager')->getBundleInfo($entityId); + $links = []; + + foreach($bundles as $machine_name => $bundle) { + $label = $bundle['label']; + + // Some labels are TranslatableMarkup objects (such as the File entity). + if ($label instanceof TranslatableMarkup) { + $label = $label->render(); + } + + // Link to the bundle's Manage Display page if the entity ID supports the route pattern. + if (in_array($entityId, $linkableEntities) && $entityType) { + $links[] = Link::createFromRoute(t($label), "entity.entity_view_display.{$entityId}.default", [ + $entityType => $machine_name, + ])->toString(); + } + } + + $description = empty($links) ? '' : '( ' . implode(' | ', $links) . ' )'; + + $form['addtoany_entity_settings'][$entityId] = [ + '#type' => 'checkbox', + '#title' => $this->t('@entity', ['@entity' => $entity->getLabel()]), + '#default_value' => $addtoany_settings->get("entities.{$entityId}"), + '#description' => $description, + '#attributes' => ['class' => ['addtoany-entity-checkbox']] + ]; + } + + $form['addtoany_entity_settings']['addtoany_entity_tip_2'] = [ + '#type' => 'html_tag', + '#tag' => 'p', + '#value' => $this->t('A cache rebuild may be required before changes take effect.'), + ]; + return parent::buildForm($form, $form_state); } @@ -207,10 +273,33 @@ class AddToAnySettingsForm extends ConfigFormBase { ->set('custom_universal_button', $values['addtoany_custom_universal_button']) ->set('universal_button', $values['addtoany_universal_button']) ->set('universal_button_placement', $values['addtoany_universal_button_placement']) - ->set('no_3p', $values['addtoany_no_3p']) - ->save(); + ->set('no_3p', $values['addtoany_no_3p']); + + foreach(self::getContentEntities() as $entity) { + $entityId = $entity->id(); + $this->config('addtoany.settings') + ->set("entities.{$entityId}", $values[$entityId]); + } + + $this->config('addtoany.settings')->save(); parent::submitForm($form, $form_state); } + /** + * Get all available content entities in the environment. + * @return array + */ + public static function getContentEntities() { + $content_entity_types = []; + $entity_type_definitions = \Drupal::entityTypeManager()->getDefinitions(); + /* @var $definition EntityTypeInterface */ + foreach ($entity_type_definitions as $definition) { + if ($definition instanceof ContentEntityType) { + $content_entity_types[] = $definition; + } + } + + return $content_entity_types; + } } diff --git a/sites/all/modules/contrib/filters/url_to_video_filter/css/url_to_video_embed.scss b/sites/all/modules/contrib/filters/url_to_video_filter/css/url_to_video_embed.scss index 482a94814..cdfed8362 100644 --- a/sites/all/modules/contrib/filters/url_to_video_filter/css/url_to_video_embed.scss +++ b/sites/all/modules/contrib/filters/url_to_video_filter/css/url_to_video_embed.scss @@ -69,4 +69,4 @@ top:0; left:0; } -} +} \ No newline at end of file diff --git a/sites/all/modules/contrib/filters/url_to_video_filter/js/vimeo_embed.js b/sites/all/modules/contrib/filters/url_to_video_filter/js/vimeo_embed.js index b896b8ef9..13a979361 100644 --- a/sites/all/modules/contrib/filters/url_to_video_filter/js/vimeo_embed.js +++ b/sites/all/modules/contrib/filters/url_to_video_filter/js/vimeo_embed.js @@ -1,66 +1,113 @@ +/** + * @file + * Converts Vimeo placeholders to embedded vimeo videos. + */ + /*global jQuery, Drupal, drupalSettings*/ -/*jslint white:true, multivar, this, browser:true*/ +/*jslint white:true, this, browser:true*/ -(function($, Drupal, drupalSettings) -{ - "use strict"; +(function ($, Drupal, drupalSettings) { + "use strict"; - function vimeoVideoEnable(context) - { - $(context).find(".vimeo-player").once("vimeo-video-enable").each(function() - { - var vimeoID = $(this).attr("data-vimeo-id"); + function vimeoVideoEnable(context) { - $(this).parent().removeClass("no-js"); + $(context).find(".vimeo-player").once("vimeo-video-enable").each(function () { + var IDParts, vimeoID, queryString; - if(drupalSettings.urlToVideoFilter.autoload) - { - $(this).empty().append($("