diff --git a/lib/Notifications/Workflow/Step/Channel/Email.php b/lib/Notifications/Workflow/Step/Channel/Email.php index 4aff9330..2de2f5fe 100644 --- a/lib/Notifications/Workflow/Step/Channel/Email.php +++ b/lib/Notifications/Workflow/Step/Channel/Email.php @@ -76,6 +76,7 @@ public function action_send_notification($workflow, $receiverData, $content, $ch // Send the emails $emailAddress = $this->get_receiver_email($receiverData['receiver']); + $action = 'transition_post_status' === $workflow->event_args['event'] ? 'status-change' : 'comment'; $subject = html_entity_decode($content['subject']); diff --git a/lib/Notifications/Workflow/Step/Event/Filter/Taxonomies.php b/lib/Notifications/Workflow/Step/Event/Filter/Taxonomies.php new file mode 100644 index 00000000..14b2f9b3 --- /dev/null +++ b/lib/Notifications/Workflow/Step/Event/Filter/Taxonomies.php @@ -0,0 +1,116 @@ + + * @copyright Copyright (c) 2022 PublishPress. All rights reserved. + * @license GPLv2 or later + * @since 1.0.0 + */ + +namespace PublishPress\Notifications\Workflow\Step\Event\Filter; + +use PP_Notifications; +use PublishPress\Notifications\Workflow\Step\Event\Post_TaxonomyUpdate; + +class Taxonomies extends Base implements Filter_Interface +{ + const META_KEY_TAXONOMIES_FROM = '_psppno_taxonomiesfrom'; + + /** + * Function to render and returnt the HTML markup for the + * Field in the form. + * + * @return string + */ + public function render() + { + echo $this->get_service('view')->render( + 'workflow_filter_multiple_select', + [ + 'name' => esc_attr("publishpress_notif[{$this->step_name}_filters][taxonomies]"), + 'id' => esc_attr("publishpress_notif_{$this->step_name}_filters_taxonomies"), + 'options' => $this->get_options(), + 'labels' => [ + 'label' => esc_html__('Taxonomies', 'publishpress'), + ], + ] + ); + } + + /** + * Returns a list of taxonomies in the options format + * + * @return array + */ + protected function get_options() + { + + $excluded_taxonomies = []; + if (class_exists('\PP_Notifications')) { + $blacklisted_taxonomies = PP_Notifications::getOption('blacklisted_taxonomies'); + if (!empty($blacklisted_taxonomies)) { + $excluded_taxonomies = array_filter(explode(',', $blacklisted_taxonomies)); + } + } + + $taxonomies = get_taxonomies([], 'objects', 'and'); + $metadata = (array)$this->get_metadata(static::META_KEY_TAXONOMIES_FROM); + $options = []; + + foreach ($taxonomies as $tax) { + if (empty($tax->labels->name) || in_array($tax->labels->name, $excluded_taxonomies)) { + continue; + } + $options[] = [ + 'value' => esc_attr($tax->name), + 'label' => esc_html($tax->labels->name. ' ('.$tax->name.')'), + 'selected' => in_array($tax->name, $metadata), + ]; + } + + return $options; + } + + /** + * Function to save the metadata from the metabox + * + * @param int $id + * @param WP_Post $post + */ + public function save_metabox_data($id, $post) + { + if (!isset($_POST['publishpress_notif']["{$this->step_name}_filters"]['taxonomies'])) { + $values = []; + } else { + $values = array_map( + 'sanitize_key', + (array)$_POST['publishpress_notif']["{$this->step_name}_filters"]['taxonomies'] + ); + } + + $this->update_metadata_array($id, static::META_KEY_TAXONOMIES_FROM, $values); + } + + /** + * Filters and returns the arguments for the query which locates + * workflows that should be executed. + * + * @param array $query_args + * @param array $event_args + * + * @return array + */ + public function get_run_workflow_query_args($query_args, $event_args) + { + // Taxonomy + $query_args['meta_query'][] = [ + [ + 'key' => static::META_KEY_TAXONOMIES_FROM, + 'value' => $event_args['params']['taxonomy'], + 'compare' => '=', + ], + ]; + + return parent::get_run_workflow_query_args($query_args, $event_args); + } +} diff --git a/lib/Notifications/Workflow/Step/Event/Post_TaxonomyUpdate.php b/lib/Notifications/Workflow/Step/Event/Post_TaxonomyUpdate.php new file mode 100644 index 00000000..5a86ed60 --- /dev/null +++ b/lib/Notifications/Workflow/Step/Event/Post_TaxonomyUpdate.php @@ -0,0 +1,116 @@ + + * @copyright Copyright (c) 2022 PublishPress. All rights reserved. + * @license GPLv2 or later + * @since 1.0.0 + */ + +namespace PublishPress\Notifications\Workflow\Step\Event; + +use PublishPress\Notifications\Workflow\Step\Event\Filter; + +class Post_TaxonomyUpdate extends Base +{ + const META_KEY_SELECTED = '_psppno_evttaxonomyupdate'; + + const META_VALUE_SELECTED = 'taxonomy_update'; + + const EVENT_NAME = 'taxonomy_update'; + + /** + * The constructorPost_TaxonomyUpdate' + */ + public function __construct() + { + $this->name = static::META_VALUE_SELECTED; + $this->label = __('When taxonomy is updated', 'publishpress'); + + parent::__construct(); + + // Add filter to return the metakey representing if it is selected or not + add_filter('psppno_events_metakeys', [$this, 'filter_events_metakeys']); + add_filter('publishpress_notifications_workflow_events', [$this, 'filter_workflow_actions']); + add_filter('publishpress_notifications_event_label', [$this, 'filter_event_label'], 10, 2); + } + + /** + * Filters and returns the arguments for the query which locates + * workflows that should be executed. + * + * @param array $query_args + * @param array $event_args + * + * @return array + */ + public function filter_running_workflow_query_args($query_args, $event_args) + { + if ($this->should_ignore_event_on_query($event_args)) { + return $query_args; + } + + if (static::EVENT_NAME === $event_args['event']) { + $query_args['meta_query'][] = [ + 'key' => static::META_KEY_SELECTED, + 'value' => 1, + 'type' => 'BOOL', + 'compare' => '=', + ]; + + // Check the filters + $filters = $this->get_filters(); + + foreach ($filters as $filter) { + $query_args = $filter->get_run_workflow_query_args($query_args, $event_args); + } + } + + return $query_args; + } + + /** + * Method to return a list of fields to display in the filter area + * + * @param array + * + * @return array + */ + protected function get_filters($filters = []) + { + if (!empty($this->cache_filters)) { + return $this->cache_filters; + } + + $step_name = $this->attr_prefix . '_' . $this->name; + + $filters[] = new Filter\Taxonomies($step_name); + + return parent::get_filters($filters); + } + + public function filter_workflow_actions($actions) + { + if (!is_array($actions) || empty($actions)) { + $actions = []; + } + + $actions[] = static::EVENT_NAME; + + return $actions; + } + + /** + * @param string $label + * @param string $event + * @return string|void + */ + public function filter_event_label($label, $event) + { + if ($event === static::EVENT_NAME) { + $label = $this->label; + } + + return $label; + } +} diff --git a/lib/Notifications/Workflow/WorkflowsController.php b/lib/Notifications/Workflow/WorkflowsController.php index e9a21e46..3c6225c5 100644 --- a/lib/Notifications/Workflow/WorkflowsController.php +++ b/lib/Notifications/Workflow/WorkflowsController.php @@ -124,6 +124,7 @@ public function load_workflow_steps() $classes_event = [ '\\PublishPress\\Notifications\\Workflow\\Step\\Event\\Editorial_Comment', '\\PublishPress\\Notifications\\Workflow\\Step\\Event\\Post_Update', + '\\PublishPress\\Notifications\\Workflow\\Step\\Event\\Post_TaxonomyUpdate', '\\PublishPress\\Notifications\\Workflow\\Step\\Event\\Post_StatusTransition', ]; /** diff --git a/modules/improved-notifications/assets/js/workflow_form.js b/modules/improved-notifications/assets/js/workflow_form.js index d45e9bd1..fa1c866b 100644 --- a/modules/improved-notifications/assets/js/workflow_form.js +++ b/modules/improved-notifications/assets/js/workflow_form.js @@ -45,6 +45,7 @@ setupFieldFilters('event_content_post_type'); setupFieldFilters('event_content_category'); setupFieldFilters('event_content_taxonomy'); + setupFieldFilters('event_taxonomy_update'); setupFieldFilters('user'); setupFieldFilters('role'); diff --git a/modules/improved-notifications/improved-notifications.php b/modules/improved-notifications/improved-notifications.php index 7945dea0..564d1f8d 100644 --- a/modules/improved-notifications/improved-notifications.php +++ b/modules/improved-notifications/improved-notifications.php @@ -36,6 +36,7 @@ use PublishPress\Notifications\Workflow\Step\Event\Editorial_Comment as Event_Editorial_Comment; use PublishPress\Notifications\Workflow\Step\Event\Filter\Post_Status as Filter_Post_Status; use PublishPress\Notifications\Workflow\Step\Event\Post_StatusTransition; +use PublishPress\Notifications\Workflow\Step\Event\Post_TaxonomyUpdate; use PublishPress\Notifications\Workflow\Step\Event\Post_Update; use PublishPress\Notifications\Workflow\Step\Event_Content\Filter\Post_Type as Post_Type_Filter; use PublishPress\Notifications\Workflow\Step\Event_Content\Post_Type; @@ -163,6 +164,9 @@ public function init() // Add action to intercep new editorial comments add_action('pp_post_insert_editorial_comment', [$this, 'action_editorial_comment'], 999, 3); + // Add action to intercep taxonomy term update + add_action('set_object_terms', [$this, 'action_post_taxonomy_update'], 999, 4); + add_filter( 'pp_notification_send_email_message_headers', @@ -690,18 +694,37 @@ public function action_update_post($postId, $post, $update, $postBefore) } /** - * @param $post_type + * Action called on taxonomy term update. Used to trigger the + * controller of workflows to filter and execute them. + * + * @param int $object_id + * @param array $terms An array of object term IDs or slugs. + * @param array $tt_ids An array of term taxonomy IDs. + * @param string $taxonomy Taxonomy slug. + * @return void * - * @return bool * @throws Exception */ - private function is_supported_post_type($post_type) + public function action_post_taxonomy_update($object_id, $terms, $tt_ids, $taxonomy) { - $publishpress = $this->get_service('publishpress'); + // Go ahead and do the action to run workflows + $post = get_post($object_id); - $supportedPostTypes = $publishpress->improved_notifications->get_all_post_types(); + if (!is_object($post) || !isset($post->post_type) || ! $this->is_supported_post_type($post->post_type)) { + return; + } - return array_key_exists($post_type, $supportedPostTypes); + $params = [ + 'event' => Post_TaxonomyUpdate::EVENT_NAME, + 'user_id' => get_current_user_id(), + 'params' => [ + 'post_id' => (int)$post->ID, + 'terms' => $terms, + 'taxonomy' => $taxonomy, + ], + ]; + + do_action('publishpress_notifications_trigger_workflows', $params); } /** @@ -733,6 +756,21 @@ public function action_editorial_comment($comment) do_action('publishpress_notifications_trigger_workflows', $params); } + /** + * @param $post_type + * + * @return bool + * @throws Exception + */ + private function is_supported_post_type($post_type) + { + $publishpress = $this->get_service('publishpress'); + + $supportedPostTypes = $publishpress->improved_notifications->get_all_post_types(); + + return array_key_exists($post_type, $supportedPostTypes); + } + /** * Enqueue scripts and stylesheets for the admin pages. * @@ -1176,6 +1214,7 @@ public function get_workflows($meta_query = []) $query = new WP_Query($query_args); $this->workflows[$hash] = $query->posts; + } return $this->workflows[$hash];