plugin = $plugin; // Register custom post type. add_action( 'init', array( $this, 'register_post_type' ) ); // Add custom post type to menu. add_action( 'wp_stream_admin_menu', array( $this, 'register_menu' ) ); // Add scripts to post screens. add_action( 'admin_enqueue_scripts', array( $this, 'register_scripts', ) ); add_action( 'network_admin_menu', array( $this, 'change_menu_link_url', ), 99 ); add_filter( 'wp_stream_record_inserted', array( $this, 'check_records', ), 10, 2 ); add_action( 'wp_ajax_load_alerts_settings', array( $this, 'load_alerts_settings', ) ); add_action( 'wp_ajax_get_actions', array( $this, 'get_actions' ) ); add_action( 'wp_ajax_save_new_alert', array( $this, 'save_new_alert', ) ); add_action( 'wp_ajax_get_new_alert_triggers_notifications', array( $this, 'get_new_alert_triggers_notifications', ) ); $this->load_alert_types(); $this->load_alert_triggers(); add_filter( 'wp_stream_action_links_posts', array( $this, 'change_alert_action_links', ), 11, 2 ); } /** * Load alert_type classes * * @return void */ public function load_alert_types() { $alert_types = array( 'none', 'highlight', 'email', 'ifttt', 'slack', ); $classes = array(); foreach ( $alert_types as $alert_type ) { $file_location = $this->plugin->locations['dir'] . '/alerts/class-alert-type-' . $alert_type . '.php'; if ( file_exists( $file_location ) ) { include_once $file_location; $class_name = sprintf( '\WP_Stream\Alert_Type_%s', str_replace( '-', '_', $alert_type ) ); if ( ! class_exists( $class_name ) ) { continue; } $class = new $class_name( $this->plugin ); if ( ! property_exists( $class, 'slug' ) ) { continue; } $classes[ $class->slug ] = $class; } } /** * Allows for adding additional alert_types via classes that extend Notifier. * * @param array $classes An array of Notifier objects. In the format alert_type_slug => Notifier_Class() */ $this->alert_types = apply_filters( 'wp_stream_alert_types', $classes ); // Ensure that all alert_types extend Notifier. foreach ( $this->alert_types as $key => $alert_type ) { if ( ! $this->is_valid_alert_type( $alert_type ) ) { unset( $this->alert_types[ $key ] ); } } } /** * Load alert_type classes * * @return void */ public function load_alert_triggers() { $alert_triggers = array( 'author', 'context', 'action', ); $classes = array(); foreach ( $alert_triggers as $alert_trigger ) { $file_location = $this->plugin->locations['dir'] . '/alerts/class-alert-trigger-' . $alert_trigger . '.php'; if ( file_exists( $file_location ) ) { include_once $file_location; $class_name = sprintf( '\WP_Stream\Alert_Trigger_%s', str_replace( '-', '_', $alert_trigger ) ); if ( ! class_exists( $class_name ) ) { continue; } $class = new $class_name( $this->plugin ); if ( ! property_exists( $class, 'slug' ) ) { continue; } $classes[ $class->slug ] = $class; } } /** * Allows for adding additional alert_triggers via classes that extend Notifier. * * @param array $classes An array of Notifier objects. In the format alert_trigger_slug => Notifier_Class() */ $this->alert_triggers = apply_filters( 'wp_stream_alert_triggers', $classes ); // Ensure that all alert_triggers extend Notifier. foreach ( $this->alert_triggers as $key => $alert_trigger ) { if ( ! $this->is_valid_alert_trigger( $alert_trigger ) ) { unset( $this->alert_triggers[ $key ] ); } } } /** * Checks whether a Alert Type class is valid * * @param Alert_Type $alert_type The class to check. * * @return bool */ public function is_valid_alert_type( $alert_type ) { if ( ! is_a( $alert_type, 'WP_Stream\Alert_Type' ) ) { return false; } if ( ! method_exists( $alert_type, 'is_dependency_satisfied' ) || ! $alert_type->is_dependency_satisfied() ) { return false; } return true; } /** * Checks whether a Alert Trigger class is valid * * @param Alert_Trigger $alert_trigger The class to check. * * @return bool */ public function is_valid_alert_trigger( $alert_trigger ) { if ( ! is_a( $alert_trigger, 'WP_Stream\Alert_Trigger' ) ) { return false; } if ( ! method_exists( $alert_trigger, 'is_dependency_satisfied' ) || ! $alert_trigger->is_dependency_satisfied() ) { return false; } return true; } /** * Checks record being processed against active alerts. * * @filter wp_stream_record_inserted * * @param int $record_id The record being processed. * @param array $recordarr Record data. * * @return array */ public function check_records( $record_id, $recordarr ) { $args = array( 'post_type' => self::POST_TYPE, 'post_status' => 'wp_stream_enabled', ); $alerts = new \WP_Query( $args ); foreach ( $alerts->posts as $alert ) { $alert = $this->get_alert( $alert->ID ); $status = $alert->check_record( $record_id, $recordarr ); if ( $status ) { $alert->send_alert( $record_id, $recordarr ); // @todo send_alert expects int, not array. } } return $recordarr; } /** * Register scripts for page load * * @action admin_enqueue_scripts * * @return void */ public function register_scripts() { $screen = get_current_screen(); if ( 'edit-wp_stream_alerts' === $screen->id ) { $min = wp_stream_min_suffix(); wp_register_script( 'wp-stream-alerts', $this->plugin->locations['url'] . 'ui/js/alerts.' . $min . 'js', array( 'wp-stream-select2', 'jquery', 'inline-edit-post', ), $this->plugin->get_version(), false ); wp_localize_script( 'wp-stream-alerts', 'streamAlerts', array( 'any' => __( 'Any', 'stream' ), 'anyContext' => __( 'Any Context', 'stream' ), ) ); wp_enqueue_script( 'wp-stream-alerts' ); wp_enqueue_style( 'wp-stream-select2' ); } } /** * Register custom post type * * @action init * * @return void */ public function register_post_type() { $labels = array( 'name' => _x( 'Alerts', 'post type general name', 'stream' ), 'singular_name' => _x( 'Alert', 'post type singular name', 'stream' ), 'menu_name' => _x( 'Alerts', 'admin menu', 'stream' ), 'name_admin_bar' => _x( 'Alert', 'add new on admin bar', 'stream' ), 'add_new' => _x( 'Add New', 'book', 'stream' ), 'add_new_item' => __( 'Add New Alert', 'stream' ), 'new_item' => __( 'New Alert', 'stream' ), 'edit_item' => __( 'Edit Alert', 'stream' ), 'view_item' => __( 'View Alert', 'stream' ), 'all_items' => __( 'Alerts', 'stream' ), 'search_items' => __( 'Search Alerts', 'stream' ), 'parent_item_colon' => __( 'Parent Alerts:', 'stream' ), 'not_found' => __( 'No alerts found.', 'stream' ), 'not_found_in_trash' => __( 'No alerts found in Trash.', 'stream' ), ); $args = array( 'labels' => $labels, 'description' => __( 'Alerts for Stream.', 'stream' ), 'public' => false, 'publicly_queryable' => false, 'exclude_from_search' => true, 'show_ui' => true, 'show_in_menu' => false, // @see modify_admin_menu 'supports' => false, 'capabilities' => array( 'publish_posts' => 'manage_options', 'edit_others_posts' => 'manage_options', 'delete_posts' => 'manage_options', 'delete_others_posts' => 'manage_options', 'read_private_posts' => 'manage_options', 'edit_post' => 'manage_options', 'delete_post' => 'manage_options', 'read_post' => 'manage_options', ), ); register_post_type( self::POST_TYPE, $args ); $args = array( 'label' => _x( 'Enabled', 'alert', 'stream' ), 'public' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, /* translators: %s: a number of items (e.g. "42") */ 'label_count' => _n_noop( 'Enabled (%s)', 'Enabled (%s)', 'stream' ), ); register_post_status( 'wp_stream_enabled', $args ); $args = array( 'label' => _x( 'Disabled', 'alert', 'stream' ), 'public' => false, 'internal' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, /* translators: %s: a number of items (e.g. "42") */ 'label_count' => _n_noop( 'Disabled (%s)', 'Disabled (%s)', 'stream' ), ); register_post_status( 'wp_stream_disabled', $args ); } /** * Return alert object of the given ID * * @param string $post_id Post ID for the alert. * * @return Alert */ public function get_alert( $post_id = '' ) { if ( ! $post_id ) { $obj = new Alert( null, $this->plugin ); return $obj; } $post = get_post( $post_id ); $alert_type = get_post_meta( $post_id, 'alert_type', true ); $alert_meta = get_post_meta( $post_id, 'alert_meta', true ); $obj = (object) array( 'ID' => $post->ID, 'status' => $post->post_status, 'date' => $post->post_date, 'author' => $post->post_author, 'alert_type' => $alert_type, 'alert_meta' => $alert_meta, ); return new Alert( $obj, $this->plugin ); } /** * Add custom post type to menu * * @action admin_menu * * @return void */ public function register_menu() { add_submenu_page( $this->plugin->admin->records_page_slug, __( 'Alerts', 'stream' ), __( 'Alerts', 'stream' ), 'manage_options', 'edit.php?post_type=wp_stream_alerts' ); } /** * Modify the Stream > Alerts Network Admin Menu link. * * In self::register_menu(), the Alerts submenu item * is essentially set to go to the Site's admin area. * * However, on the Network admin, we need to redirect * it to the first site in the network, as this is * where the true Network Alerts settings page is located. * * @action network_admin_menu * @return bool */ public function change_menu_link_url() { global $submenu; $parent = 'wp_stream'; $page = 'edit.php?post_type=wp_stream_alerts'; // If we're not on the Stream menu item, return. if ( ! isset( $submenu[ $parent ] ) ) { return false; } // Get the first existing Site in the Network. $sites = wp_stream_get_sites( array( 'limit' => 5, // Limit the size of the query. ) ); $site_id = '1'; // Function wp_get_sites() can return an empty array if the network is too large. if ( ! empty( $sites ) && ! empty( $sites[0]->blog_id ) ) { $site_id = $sites[0]->blog_id; } $new_url = get_admin_url( $site_id, $page ); foreach ( $submenu[ $parent ] as $key => $value ) { // Set correct URL for the menu item. if ( $page === $value[2] ) { // This hack is not kosher, see the docblock for an explanation. $submenu[ $parent ][ $key ][2] = $new_url; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited break; } } return true; } /** * Display Alert Type Meta Box * * @param \WP_Post|array $post Post object for current alert. * * @return void */ public function display_notification_box( $post = array() ) { $alert_type = 'none'; if ( is_object( $post ) ) { $alert = $this->get_alert( $post->ID ); $alert_type = $alert->alert_type; } $form = new Form_Generator(); $field_html = $form->render_field( 'select', array( 'id' => 'wp_stream_alert_type', 'name' => 'wp_stream_alert_type', 'value' => $alert_type, 'options' => $this->get_notification_values(), 'placeholder' => __( 'No Alert', 'stream' ), 'title' => 'Alert Type:', ) ); echo ''; echo $field_html; // Xss ok. echo '