Changeset 1839780
- Timestamp:
- 03/14/2018 06:55:37 AM (8 years ago)
- Location:
- publishpress/trunk
- Files:
-
- 5 added
- 8 deleted
- 33 edited
-
common/css/pressshack-admin.css (modified) (1 diff)
-
common/libs (deleted)
-
common/php/class-module.php (modified) (5 diffs)
-
composer.json (modified) (1 diff)
-
core (deleted)
-
deprecated.php (deleted)
-
includes.php (modified) (2 diffs)
-
includes_notifications.php (modified) (1 diff)
-
libraries/Auto_loader.php (added)
-
libraries/Legacy (deleted)
-
libraries/Notifications/Workflow/Controller.php (modified) (1 diff)
-
libraries/Notifications/Workflow/Step/Channel/Email.php (modified) (1 diff)
-
libraries/Notifications/Workflow/Step/Event/Filter/Base.php (modified) (1 diff)
-
libraries/Notifications/Workflow/Step/Event/Filter/Post_Status.php (modified) (1 diff)
-
libraries/Notifications/Workflow/Step/Receiver/Follower.php (modified) (4 diffs)
-
libraries/Notifications/Workflow/Step/Receiver/Role.php (deleted)
-
libraries/Notifications/Workflow/Step/Receiver/User.php (modified) (2 diffs)
-
libraries/Notifications/Workflow/Step/Receiver/User_Group.php (added)
-
libraries/Util.php (added)
-
modules/addons/addons.php (modified) (1 diff)
-
modules/async-notifications/async-notifications.php (modified) (3 diffs)
-
modules/async-notifications/library/Queue/WPCron.php (modified) (2 diffs)
-
modules/calendar/calendar.php (modified) (1 diff)
-
modules/calendar/lib/calendar.css (modified) (1 diff)
-
modules/content-overview/content-overview.php (modified) (1 diff)
-
modules/custom-status/custom-status.php (modified) (3 diffs)
-
modules/dashboard/dashboard.php (modified) (1 diff)
-
modules/improved-notifications/assets/css/admin.css (modified) (4 diffs)
-
modules/improved-notifications/assets/js/workflow_form.js (modified) (2 diffs)
-
modules/improved-notifications/improved-notifications.php (modified) (6 diffs)
-
modules/improved-notifications/libs/opentip (deleted)
-
modules/notifications/assets/notifications.css (modified) (4 diffs)
-
modules/notifications/assets/notifications.js (modified) (1 diff)
-
modules/notifications/notifications.php (modified) (49 diffs)
-
modules/roles (deleted)
-
modules/settings/settings.php (modified) (2 diffs)
-
modules/user-groups/lib/user-groups.css (modified) (4 diffs)
-
modules/user-groups/user-groups.php (modified) (6 diffs)
-
package.json (added)
-
publishpress.php (modified) (6 diffs)
-
readme.txt (modified) (6 diffs)
-
twig/workflow_help.twig (modified) (1 diff)
-
twig/workflow_metabox.twig (modified) (1 diff)
-
twig/workflow_receiver_role_field.twig (deleted)
-
twig/workflow_receiver_user_field.twig (modified) (1 diff)
-
twig/workflow_receiver_user_group_field.twig (added)
Legend:
- Unmodified
- Added
- Removed
-
publishpress/trunk/common/css/pressshack-admin.css
r1839664 r1839780 79 79 } 80 80 81 .pressshack-admin-wrapper > header .pressshack-title{81 .pressshack-admin-wrapper > header h1 { 82 82 margin: .67em 0 15px .15em; 83 83 font-weight: 600; -
publishpress/trunk/common/php/class-module.php
r1839664 r1839780 161 161 public function get_post_types_for_module($module) 162 162 { 163 return PublishPress\ Legacy\Util::get_post_types_for_module($module);163 return PublishPress\Util::get_post_types_for_module($module); 164 164 } 165 165 … … 335 335 public function get_current_post_type() 336 336 { 337 return PublishPress\ Legacy\Util::get_current_post_type();337 return PublishPress\Util::get_current_post_type(); 338 338 } 339 339 … … 624 624 public function users_select_form($selected = null, $args = null) 625 625 { 626 global $publishpress;627 626 628 627 // Set up arguments … … 650 649 $selected = array(); 651 650 } 652 653 $roles = get_editable_roles();654 651 ?> 655 652 656 653 <?php if (!empty($users)) : ?> 657 <select class="chosen-select" name="to_notify[]" multiple> 658 <?php if (!empty($roles)) : ?> 659 <optgroup label="<?php echo __('Roles', 'publishpress'); ?>"> 660 <?php foreach ($roles as $role => $data) : ?> 661 <?php $attrSelected = (in_array($role, $selected)) ? 'selected="selected"' : ''; ?> 662 <option value="<?php echo $role; ?>" <?php echo $attrSelected; ?>><?php echo __('Role', 'publishpress'); ?>: <?php echo $data['name']; ?></option> 663 <?php endforeach; ?> 664 </optgroup> 665 <?php endif; ?> 666 <optgroup label="<?php echo __('Users', 'publishpress'); ?>"> 667 <?php foreach ($users as $user) : ?> 668 <?php $attrSelected = (in_array($user->ID, $selected)) ? 'selected="selected"' : ''; ?> 669 <option value="<?php echo $user->ID; ?>" <?php echo $attrSelected; ?>><?php echo $user->display_name; ?></option> 670 <?php endforeach; ?> 671 </optgroup> 672 </select> 673 <?php endif; ?> 654 <ul class="<?php echo esc_attr($list_class) ?>"> 655 <?php foreach ($users as $user) : ?> 656 <?php $checked = (in_array($user->ID, $selected)) ? 'checked="checked"' : ''; 657 ?> 658 <li> 659 <label for="<?php echo esc_attr($input_id . '-' . $user->ID) ?>"> 660 <input type="checkbox" id="<?php echo esc_attr($input_id . '-' . $user->ID) ?>" 661 name="<?php echo esc_attr($input_id) ?>[]" value="<?php echo esc_attr($user->ID); 662 ?>" <?php echo $checked; 663 ?> /> 664 <span class="pp-user_displayname"><?php echo esc_html($user->display_name); 665 ?></span> 666 <span class="pp-user_useremail"><?php echo esc_html($user->user_email); 667 ?></span> 668 </label> 669 </li> 670 <?php endforeach; 671 ?> 672 </ul> 673 <?php endif; 674 ?> 674 675 <?php 676 675 677 } 676 678 … … 684 686 { 685 687 686 PublishPress\ Legacy\Util::add_caps_to_role($role, $caps);688 PublishPress\Util::add_caps_to_role($role, $caps); 687 689 } 688 690 -
publishpress/trunk/composer.json
r1839664 r1839780 17 17 } 18 18 ], 19 "autoload": {20 "psr-4": {21 "PublishPress\\Core\\": "core/"22 }23 },24 19 "minimum-stability": "stable", 25 20 "require": { -
publishpress/trunk/includes.php
r1839670 r1839780 29 29 */ 30 30 31 use PublishPress\ Legacy\Auto_loader;31 use PublishPress\Auto_loader; 32 32 33 if (!defined('PP_LOADED')) { 33 if (!defined('PP_LOADED')) 34 { 34 35 $settingsPage = add_query_arg( 35 36 array( … … 41 42 42 43 // Define contants 43 define('PUBLISHPRESS_VERSION', '1.1 1.1');44 define('PUBLISHPRESS_ BASE_PATH', __DIR__);45 define('PUBLISHPRESS_FILE_PATH', PUBLISHPRESS_ BASE_PATH. '/' . basename(__FILE__));44 define('PUBLISHPRESS_VERSION', '1.10.0'); 45 define('PUBLISHPRESS_ROOT', dirname(__FILE__)); 46 define('PUBLISHPRESS_FILE_PATH', PUBLISHPRESS_ROOT . '/' . basename(__FILE__)); 46 47 define('PUBLISHPRESS_URL', plugins_url('/', __FILE__)); 47 48 define('PUBLISHPRESS_SETTINGS_PAGE', $settingsPage); 48 define('PUBLISHPRESS_LIBRARIES_PATH', PUBLISHPRESS_BASE_PATH . '/libraries'); 49 50 /** 51 * Use PUBLISHPRESS_BASE_PATH instead. 52 * 53 * @deprecated 54 */ 55 define('PUBLISHPRESS_ROOT', PUBLISHPRESS_BASE_PATH); 49 define('PUBLISHPRESS_LIBRARIES_PATH', PUBLISHPRESS_ROOT . '/libraries'); 56 50 57 51 // Define the Priority for the notification/notification_status_change method 58 52 // Added to allow users select a custom priority 59 if (!defined('PP_NOTIFICATION_PRIORITY_STATUS_CHANGE')) { 53 if (!defined('PP_NOTIFICATION_PRIORITY_STATUS_CHANGE')) 54 { 60 55 define('PP_NOTIFICATION_PRIORITY_STATUS_CHANGE', 10); 61 56 } 62 57 63 if (file_exists(PUBLISHPRESS_BASE_PATH . '/vendor/autoload.php')) { 64 require_once PUBLISHPRESS_BASE_PATH . '/vendor/autoload.php'; 65 } 58 require_once PUBLISHPRESS_ROOT . '/vendor/autoload.php'; 66 59 67 60 // Register the autoloader 68 if (!class_exists('\\PublishPress\\Legacy\\Auto_loader')) { 69 require_once PUBLISHPRESS_LIBRARIES_PATH . '/Legacy/Auto_loader.php'; 61 if (!class_exists('\\PublishPress\\Auto_loader')) 62 { 63 require_once PUBLISHPRESS_LIBRARIES_PATH . '/Auto_loader.php'; 70 64 } 71 65 72 66 // Register the library 73 Auto_loader::register('\\PublishPress\\Legacy\\', PUBLISHPRESS_LIBRARIES_PATH . '/Legacy'); 74 Auto_loader::register('\\PublishPress\\Notifications\\', PUBLISHPRESS_LIBRARIES_PATH . '/Notifications'); 75 76 require_once PUBLISHPRESS_BASE_PATH . '/deprecated.php'; 67 Auto_loader::register('\\PublishPress\\', PUBLISHPRESS_LIBRARIES_PATH); 77 68 78 69 define('PP_LOADED', 1); -
publishpress/trunk/includes_notifications.php
r1839664 r1839780 10 10 */ 11 11 12 use PublishPress\Notifications\Auto_loader; 13 12 14 defined('ABSPATH') or die('No direct script access allowed.'); 15 16 require_once 'vendor/autoload.php'; 13 17 14 18 if (!defined('PUBLISHPRESS_NOTIF_LOADED')) 15 19 { 16 20 define('PUBLISHPRESS_NOTIF_MODULE_PATH', __DIR__ . '/modules/improved-notifications'); 17 define('PUBLISHPRESS_NOTIF_TWIG_PATH', PUBLISHPRESS_ BASE_PATH. '/twig');21 define('PUBLISHPRESS_NOTIF_TWIG_PATH', PUBLISHPRESS_ROOT . '/twig'); 18 22 define('PUBLISHPRESS_NOTIF_LOADED', 1); 19 23 -
publishpress/trunk/libraries/Notifications/Workflow/Controller.php
r1839664 r1839780 139 139 '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\Author', 140 140 '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\User', 141 '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\ Role',141 '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\User_Group', 142 142 '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\Follower', 143 143 ]; -
publishpress/trunk/libraries/Notifications/Workflow/Step/Channel/Email.php
r1839664 r1839780 46 46 if (empty($receivers)) { 47 47 return; 48 }49 50 // Make sure we unserialize the content when it comes from async notifications.51 if (is_string($content)) {52 $content = maybe_unserialize($content);53 48 } 54 49 -
publishpress/trunk/libraries/Notifications/Workflow/Step/Event/Filter/Base.php
r1839664 r1839780 41 41 * 42 42 * @return string 43 *44 * @throws \Exception45 43 */ 46 44 public function render() -
publishpress/trunk/libraries/Notifications/Workflow/Step/Event/Filter/Post_Status.php
r1839664 r1839780 50 50 { 51 51 $statuses = $this->get_post_statuses(); 52 $options = []; 52 53 $metadata = (array)$this->get_metadata(''); 53 $options = [];54 55 if ('from' === $group) {56 // Add an status to represent new posts57 $options = [58 [59 'value' => 'auto-draft',60 'label' => __('"New"', 'publishpress'),61 'selected' => in_array('auto-draft', $metadata[$group]),62 ],63 ];64 }65 54 66 55 foreach ($statuses as $status) -
publishpress/trunk/libraries/Notifications/Workflow/Step/Receiver/Follower.php
r1839664 r1839780 46 46 if ($this->is_selected($workflow->ID)) 47 47 { 48 48 49 $post_id = $args['post']->ID; 49 50 … … 55 56 $followers = array(); 56 57 58 if ($publishpress->improved_notifications->module_enabled('user_groups')) 59 { 60 // Get following users and usergroups 61 $usergroups = $publishpress->notifications->get_following_usergroups($post_id, 'ids'); 57 62 58 // Check if we just created the post and the metadata is not saved yet. 59 if ('POST' === $_SERVER['REQUEST_METHOD'] 60 && (isset($_POST['action']) && 'editpost' === $_POST['action']) 61 && (isset($_POST['original_post_status']) && 'auto-draft' === $_POST['original_post_status']) 62 ) { 63 $toNotify = $_POST['to_notify']; 63 foreach ((array)$usergroups as $usergroup_id) 64 { 65 $usergroup = $publishpress->user_groups->get_usergroup_by('id', $usergroup_id); 64 66 65 $roles = array(); 66 $users = array(); 67 foreach ((array)$usergroup->user_ids as $user_id) 68 { 69 $usergroup_user = get_user_by('id', $user_id); 67 70 68 foreach ($toNotify as $item) { 69 if (is_numeric($item)) { 70 $users[] = $item; 71 } else { 72 $roles[] = $item; 73 } 74 } 75 } else { 76 // Get following users and roles 77 $roles = $publishpress->notifications->get_roles_to_notify($post_id, 'slugs'); 78 $users = $publishpress->notifications->get_users_to_notify($post_id, 'id'); 79 } 80 81 // Extract users from roles 82 if (!empty($roles)) { 83 foreach ($roles as $role) 84 { 85 $roleUsers = get_users( 86 [ 87 'role' => $role, 88 ] 89 ); 90 91 if (!empty($roleUsers)) { 92 foreach ($roleUsers as $user) 71 if ($usergroup_user && is_user_member_of_blog($user_id)) 93 72 { 94 if (is_user_member_of_blog($user->ID)) 95 { 96 $followers[] = $user->ID; 97 } 73 $followers[] = $usergroup_user; 98 74 } 99 75 } … … 101 77 } 102 78 103 // Merge roles' users and users 79 $users = $publishpress->notifications->get_following_users($post_id, 'object'); 80 81 // Merge usergroup users and users 104 82 $followers = array_merge($followers, $users); 105 83 106 84 // Process the recipients for this email to be sent 107 if (!empty($followers)) { 108 foreach ($followers as $key => $user) 85 foreach ($followers as $key => $user) 86 { 87 88 // Don't send the email to the current user unless we've explicitly indicated they should receive it 89 if (false === apply_filters('pp_notification_email_current_user', false) && wp_get_current_user()->user_email == $user->user_email) 109 90 { 110 // Make sure we have only user objects in the list 111 if (is_numeric($user)) { 112 $user = get_user_by('ID', $user); 113 } 114 115 // Don't send the email to the current user unless we've explicitly indicated they should receive it 116 if (false === apply_filters('publishpress_notify_current_user', false) && wp_get_current_user()->user_email == $user->user_email) 117 { 118 unset($followers[$key]); 119 } 91 unset($followers[$key]); 120 92 } 121 93 } … … 135 107 foreach ($followers as $user) 136 108 { 137 if (is_object($user)) { 138 $receivers[] = $user->ID; 139 } else { 140 $receivers[] = $user; 141 } 109 $receivers[] = $user->ID; 142 110 } 143 111 } -
publishpress/trunk/libraries/Notifications/Workflow/Step/Receiver/User.php
r1839664 r1839780 112 112 $template_context['list_class'] = 'publishpress_notif_user_list'; 113 113 $template_context['input_name'] = 'publishpress_notif[receiver_user][]'; 114 $template_context['input_id'] = 'publishpress_notif_user_ list';114 $template_context['input_id'] = 'publishpress_notif_user_'; 115 115 116 116 $template_context = parent::filter_workflow_metabox_context($template_context); … … 137 137 138 138 // Get the users following the post 139 $users = $this->get_service('publishpress')->notifications->get_ users_to_notify($args['post']->ID, 'id');139 $users = $this->get_service('publishpress')->notifications->get_following_users($args['post']->ID, 'id'); 140 140 $receivers = array_merge($receivers, $users); 141 141 -
publishpress/trunk/modules/addons/addons.php
r1839664 r1839780 136 136 protected function is_plugin_installed($plugin) 137 137 { 138 return file_exists(plugin_dir_path(PUBLISHPRESS_ BASE_PATH) . "{$plugin}/{$plugin}.php");138 return file_exists(plugin_dir_path(PUBLISHPRESS_ROOT) . "{$plugin}/{$plugin}.php"); 139 139 } 140 140 -
publishpress/trunk/modules/async-notifications/async-notifications.php
r1839664 r1839780 29 29 */ 30 30 31 use PublishPress\ Legacy\Auto_loader;31 use PublishPress\Auto_loader; 32 32 use PublishPress\Notifications\Traits\Dependency_Injector; 33 33 use PublishPress\Notifications\Traits\PublishPress_Module; … … 89 89 $args['default_options'] = apply_filters('publishpress_async_notif_default_options', $args['default_options']); 90 90 $this->module = $publishpress->register_module( 91 PublishPress\ Legacy\Util::sanitize_module_name($this->module_name),91 PublishPress\Util::sanitize_module_name($this->module_name), 92 92 $args 93 93 ); … … 184 184 $receivers = [$receiver]; 185 185 186 // Decode the content187 $content = base64_decode(maybe_unserialize($content));188 189 186 /** 190 187 * Triggers the notification. This can be caught by notification channels. -
publishpress/trunk/modules/async-notifications/library/Queue/WPCron.php
r1839664 r1839780 55 55 if (!empty($receivers)) 56 56 { 57 $baseData = [ 58 // workflow_post_id 59 $workflowPost->ID, 60 // action 61 $actionArgs['action'], 62 // post_id 63 $actionArgs['post']->ID, 64 // content 65 base64_encode(maybe_serialize($content)), 66 // old_status 67 isset($actionArgs['old_status']) ? $actionArgs['old_status'] : null, 68 // new_status 69 isset($actionArgs['new_status']) ? $actionArgs['new_status'] : null, 70 // channel 71 $channel, 57 $data = [ 58 'workflow_post_id' => $workflowPost->ID, 59 'action' => $actionArgs['action'], 60 'post_id' => $actionArgs['post']->ID, 61 'content' => $content, 62 'old_status' => isset($actionArgs['old_status']) ? $actionArgs['old_status'] : null, 63 'new_status' => isset($actionArgs['new_status']) ? $actionArgs['new_status'] : null, 64 'channel' => $channel, 72 65 ]; 73 66 … … 75 68 foreach ($receivers as $receiver) 76 69 { 77 // Base data 78 $data = $baseData; 79 80 // Receiver 81 $data[] = $receiver; 70 $data['receiver'] = $receiver; 82 71 83 72 $this->scheduleEvent($data); -
publishpress/trunk/modules/calendar/calendar.php
r1839664 r1839780 184 184 $this->create_post_cap = apply_filters('pp_calendar_create_post_cap', 'edit_posts'); 185 185 186 require_once(PUBLISHPRESS_ BASE_PATH. '/common/php/' . 'screen-options.php');186 require_once(PUBLISHPRESS_ROOT . '/common/php/' . 'screen-options.php'); 187 187 188 188 add_action('admin_init', array($this, 'register_settings')); -
publishpress/trunk/modules/calendar/lib/calendar.css
r1839664 r1839780 614 614 } 615 615 } 616 617 #publishpress-ics-copy .dashicons,618 #publishpress-ics-download .dashicons {619 margin-top: 4px;620 margin-right: 2px;621 }622 -
publishpress/trunk/modules/content-overview/content-overview.php
r1839664 r1839780 147 147 add_action('admin_init', array($this, 'handle_form_date_range_change')); 148 148 149 include_once PUBLISHPRESS_ BASE_PATH. '/common/php/' . 'screen-options.php';149 include_once PUBLISHPRESS_ROOT . '/common/php/' . 'screen-options.php'; 150 150 151 151 if (function_exists('add_screen_options_panel')) -
publishpress/trunk/modules/custom-status/custom-status.php
r1839664 r1839780 216 216 { 217 217 $default_terms = $this->get_default_terms(); 218 $roles = ['administrator', 'author', 'editor', 'contributor'];219 218 220 219 // Okay, now add the default statuses to the db if they don't already exist … … 224 223 { 225 224 $this->add_custom_status($term['term'], $term['args']); 226 }227 }228 229 // Add basic capabilities for each post status230 $default_terms['publish'] = array();231 foreach ($default_terms as $termSlug => $data)232 {233 foreach ($roles as $roleName) {234 $role = get_role($roleName);235 $role->add_cap('status_change_' . str_replace('-', '_', $termSlug));236 237 if ('publish' === $termSlug) {238 $role->add_cap('status_change_private');239 $role->add_cap('status_change_future');240 }241 225 } 242 226 } … … 943 927 $this->custom_statuses_cache = array(); 944 928 945 // Set permissions for the base roles946 $roles = ['administrator', 'editor', 'author', 'contributor'];947 foreach ($roles as $roleSlug) {948 $role = get_role($roleSlug);949 if (!empty($role)) {950 $role->add_cap('status_change_' . str_replace('-', '_', $slug));951 }952 }953 954 929 return $response; 955 930 } -
publishpress/trunk/modules/dashboard/dashboard.php
r1839664 r1839780 247 247 global $publishpress; 248 248 249 $myposts = $publishpress->notifications->get_user_ to_notify_posts();249 $myposts = $publishpress->notifications->get_user_following_posts(); 250 250 251 251 ?> -
publishpress/trunk/modules/improved-notifications/assets/css/admin.css
r1839664 r1839780 93 93 } 94 94 95 #psppno-workflow-metabox-section-receiver #pp _post_notify_users_box {95 #psppno-workflow-metabox-section-receiver #pp-post_following_users_box { 96 96 float: none; 97 97 margin-right: 0; 98 98 } 99 99 100 #psppno-workflow-metabox-section-receiver #pp _post_notify_users_box,100 #psppno-workflow-metabox-section-receiver #pp-post_following_users_box, 101 101 #psppno-workflow-metabox-section-receiver #pp-post_following_usergroups_box { 102 102 width: 100%; … … 112 112 113 113 #psppno-workflow-metabox-section-receiver .publishpress_notif_user_list, 114 #psppno-workflow-metabox-section-receiver .publishpress_notif_ role_list {114 #psppno-workflow-metabox-section-receiver .publishpress_notif_user_group_list { 115 115 margin-bottom: 9px; 116 116 } … … 168 168 } 169 169 170 /* Branding for pages */ 171 body.post-type-psppnotif_workflow h1.wp-heading-inline:before { 172 display: block; 173 padding: 10px 0 10px 55px; 174 background-image: url(../../../settings/lib/icon-128x128.png); 175 background-size: 45px auto; 176 background-position: left center; 177 background-repeat: no-repeat; 178 background-color: transparent; 179 content: 'PublishPress'; 180 font-weight: bold; 181 font-size: 26px; 182 margin-bottom: 15px; 183 margin-top: 8px; 184 margin-left: 4px; 185 margin-right: 0; 186 padding-bottom: 10px; 187 padding-left: 55px; 188 padding-right: 0px; 189 padding-top: 10px; 190 } 191 170 192 body.post-type-psppnotif_workflow #wpbody-content { 171 193 margin-bottom: 100px; … … 189 211 border-left: 8px solid #f3f3f3; 190 212 } 191 192 193 .psppno_workflow_metabox_section_header.invalid {194 background-color: #ff8585 !important;195 } -
publishpress/trunk/modules/improved-notifications/assets/js/workflow_form.js
r1839664 r1839780 44 44 setupFieldFilters('event_content_category'); 45 45 setupFieldFilters('user'); 46 setupFieldFilters(' role');46 setupFieldFilters('user_group'); 47 47 48 48 // List search 49 // $('.publishpress-filter-checkbox-list ul').listFilterizer(); 49 50 $('.publishpress-filter-checkbox-list select').multipleSelect({ 50 51 filter: true … … 52 53 53 54 // Form validation 54 $('form#post').on('submit', function (event) {55 var selected,56 sections = ['event', 'event_content'],57 messages = [];58 55 59 /**60 * Set the validation status to the given section.61 *62 * @param section63 * @param status64 */65 function set_validation_status(section, status) {66 var selector = '#psppno-workflow-metabox-section-' + section + ' .psppno_workflow_metabox_section_header';67 68 if (status) {69 $(selector).removeClass('invalid');70 } else {71 $(selector).addClass('invalid');72 }73 }74 75 function set_tooltip(section) {76 var selector = '#psppno-workflow-metabox-section-' + section + ' .psppno_workflow_metabox_section_header';77 78 $(selector).tooltip();79 }80 81 // Check the Event and Event Content sections82 $.each(sections, function (index, section) {83 // Check if the "When" and "Which content" filter has at least one selected option.84 selected = $('[name="publishpress_notif[' + section + '][]"]:checked').length;85 86 if (selected === 0) {87 set_validation_status(section, false);88 89 messages.push(workflowFormData.messages['selectAllIn_' + section]);90 } else {91 set_validation_status(section, true);92 }93 });94 95 // Check if any status was selected for "moving to new status"96 if ($('#publishpress_notif_event_post_save:checked').length > 0) {97 if ($('#publishpress_notif_event_post_save_filters_post_status_from').val() == null98 || $('#publishpress_notif_event_post_save_filters_post_status_to').val() == null) {99 100 set_validation_status('event', false);101 102 if ($('#publishpress_notif_event_post_save_filters_post_status_from').val() == null) {103 messages.push(workflowFormData.messages['selectAPreviousStatus']);104 }105 106 if ($('#publishpress_notif_event_post_save_filters_post_status_to').val() == null) {107 messages.push(workflowFormData.messages['selectANewStatus']);108 }109 } else {110 set_validation_status('event', true);111 }112 }113 114 // Check if any post type was selected (if checked)115 if ($('#publishpress_notif_event_content_post_type:checked').length > 0) {116 if ($('#publishpress_notif_event_content_post_type_filters_post_type').val() == null) {117 set_validation_status('event_content', false);118 119 messages.push(workflowFormData.messages['selectPostType']);120 } else {121 set_validation_status('event_content', true);122 }123 }124 125 // Check if any category was selected (if checked)126 if ($('#publishpress_notif_event_content_category:checked').length > 0) {127 if ($('#publishpress_notif_event_content_category_filters_category').val() == null) {128 set_validation_status('event_content', false);129 130 messages.push(workflowFormData.messages['selectCategory']);131 } else {132 set_validation_status('event_content', true);133 }134 }135 136 // Check the Receivers section137 if ($('#psppno-workflow-metabox-section-receiver input[type="checkbox"][name^="publishpress_notif"]:checked').length === 0) {138 set_validation_status('receiver', false);139 140 messages.push(workflowFormData.messages['selectAReceiver']);141 } else {142 set_validation_status('receiver', true);143 }144 145 // Check if any user was selected (if checked)146 if ($('#publishpress_notif_user:checked').length > 0) {147 if ($('#publishpress_notif_user_list').val() == null) {148 set_validation_status('receiver', false);149 150 messages.push(workflowFormData.messages['selectAUser']);151 } else {152 set_validation_status('receiver', true);153 }154 }155 156 // Check if any role was selected (if checked)157 if ($('#publishpress_notif_role:checked').length > 0) {158 if ($('#publishpress_notif_roles').val() == null) {159 set_validation_status('receiver', false);160 161 messages.push(workflowFormData.messages['selectARole']);162 } else {163 set_validation_status('receiver', true);164 }165 }166 167 // Check the Content section168 if ($('#publishpress_notification_content_main_subject').val().trim() == ''169 || tinymce.activeEditor.getContent().trim() === '') {170 set_validation_status('content', false);171 172 if ($('#publishpress_notification_content_main_subject').val().trim() == '') {173 messages.push(workflowFormData.messages['setASubject']);174 }175 176 if (tinymce.activeEditor.getContent().trim() === '') {177 messages.push(workflowFormData.messages['setABody']);178 }179 } else {180 set_validation_status('content', true);181 }182 183 var valid = $('form#post .invalid').length === 0;184 185 if (!valid) {186 if (messages.length > 0) {187 $('#error_messages').remove();188 var $messageBox = $('<div id="error_messages" class="notice notice-error"></div>');189 $('.wp-header-end').after($messageBox);190 191 for (var i = 0; i < messages.length; i++) {192 $element = $('<p>');193 $element.text(messages[i]);194 $messageBox.append($element);195 }196 }197 } else {198 $('#error_messages').remove();199 }200 201 return valid;202 });203 56 }); 204 57 })(jQuery); -
publishpress/trunk/modules/improved-notifications/improved-notifications.php
r1839664 r1839780 103 103 $args['default_options'] = apply_filters('publishpress_notif_default_options', $args['default_options']); 104 104 $this->module = $publishpress->register_module( 105 PublishPress\ Legacy\Util::sanitize_module_name($this->module_name),105 PublishPress\Util::sanitize_module_name($this->module_name), 106 106 $args 107 107 ); … … 362 362 } 363 363 } 364 365 if (version_compare($previous_version, '1.10', '<=')) { 366 $this->migrate_legacy_metadata_for_role(); 367 } 368 } 369 370 protected function migrate_legacy_metadata_for_role() 371 { 372 global $wpdb; 373 374 $query = "UPDATE {$wpdb->prefix}postmeta SET meta_key = '_psppno_torole' WHERE meta_key = '_psppno_togroup'"; 375 $wpdb->query($query); 376 377 $query = "UPDATE {$wpdb->prefix}postmeta SET meta_key = '_psppno_torolelist' WHERE meta_key = '_psppno_togrouplist'"; 378 $wpdb->query($query); 379 } 380 364 } 381 365 382 366 /** … … 467 451 if (in_array($hook_suffix, ['post.php', 'post-new.php'])) 468 452 { 469 wp_enqueue_script('psppno-multiple-select', plugin_dir_url(__FILE__) . 'assets/js/multiple-select.js', ['jquery'], PUBLISHPRESS_VERSION); 470 wp_enqueue_script('psppno-workflow-tooltip', plugin_dir_url(__FILE__) . 'libs/opentip/downloads/opentip-jquery.js', ['jquery'], PUBLISHPRESS_VERSION); 471 wp_enqueue_script('psppno-workflow-form', plugin_dir_url(__FILE__) . 'assets/js/workflow_form.js', ['jquery', 'psppno-workflow-tooltip', 'psppno-multiple-select'], PUBLISHPRESS_VERSION); 472 473 wp_localize_script( 474 'psppno-workflow-form', 475 'workflowFormData', 476 [ 477 'messages' => [ 478 'selectAllIn_event' => 'Select at least one event.', 479 'selectAllIn_event_content' => 'Select at least a filter for the content.', 480 'selectAPreviousStatus' => 'Select at least one previous status.', 481 'selectANewStatus' => 'Select at least one new status.', 482 'selectPostType' => 'Select at least one post type.', 483 'selectCategory' => 'Select at least one category.', 484 'selectAReceiver' => 'Select at least one receiver.', 485 'selectAUser' => 'Select at least one user.', 486 'selectARole' => 'Select at least one role.', 487 'setASubject' => 'Type a subject for the notification.', 488 'setABody' => 'Type a body text for the notification.', 489 ], 490 ] 491 ); 453 wp_enqueue_script('psppno-workflow-form', plugin_dir_url(__FILE__) . 'assets/js/workflow_form.js', [], PUBLISHPRESS_VERSION); 454 wp_enqueue_script('psppno-multiple-select', plugin_dir_url(__FILE__) . 'assets/js/multiple-select.js', [], PUBLISHPRESS_VERSION); 492 455 } 493 456 } … … 563 526 $context = [ 564 527 'id' => 'event_content', 565 'header' => __('F or whichcontent?', 'publishpress'),528 'header' => __('Filter the content?', 'publishpress'), 566 529 'html' => apply_filters('publishpress_notif_render_metabox_section_event_content', ''), 567 530 'class' => 'pure-u-1-3 pure-u-sm-1 pure-u-md-1-2 pure-u-lg-1-3', … … 608 571 $context = [ 609 572 'labels' => [ 610 'validation_help' => __('Select at least one option for each section.', 'publishpress'),611 573 'pre_text' => __('You can add dynamic information to the Subject or Body text using the following shortcodes:', 'publishpress'), 612 574 'content' => __('Content', 'publishpress'), … … 635 597 * @param int $id Unique ID for the post being saved 636 598 * @param WP_Post $post Post object 637 *638 * @return int|null639 599 */ 640 600 public function save_meta_boxes($id, $post) -
publishpress/trunk/modules/notifications/assets/notifications.css
r1839664 r1839780 7 7 } 8 8 9 .pp _post_notify_list {9 .pp-post_following_list { 10 10 } 11 11 12 .pp _post_notify_list li {12 .pp-post_following_list li { 13 13 padding: 10px 5px 5px 5px; 14 14 margin: 0; … … 16 16 } 17 17 18 .pp _post_notify_list li:hover {18 .pp-post_following_list li:hover { 19 19 background: #EAF2FA; 20 20 } 21 21 22 .pp _post_notify_list li input {22 .pp-post_following_list li input { 23 23 float: right; 24 24 } 25 25 26 .pp _post_notify_list .pp-user_displayname,27 .pp _post_notify_list .pp-usergroup_name {26 .pp-post_following_list .pp-user_displayname, 27 .pp-post_following_list .pp-usergroup_name { 28 28 display: block; 29 29 font-size: 14px; 30 30 } 31 31 32 .pp _post_notify_list .pp-user_useremail,33 .pp _post_notify_list .pp-usergroup_description {32 .pp-post_following_list .pp-user_useremail, 33 .pp-post_following_list .pp-usergroup_description { 34 34 display: block; 35 35 color: #ccc; … … 37 37 } 38 38 39 #pp _post_notify_box {39 #pp-post_following_box { 40 40 margin: 10px 0; 41 41 } 42 42 43 #pp _post_notify_box h4 {43 #pp-post_following_box h4 { 44 44 background: #F1F1F1; 45 45 font-weight: bold; … … 50 50 } 51 51 52 #pp _post_notify_box .error {52 #pp-post_following_box .error { 53 53 color: red; 54 54 } 55 55 56 #pp _post_notify_box label.pp-select_all_box {56 #pp-post_following_box label.pp-select_all_box { 57 57 float: right; 58 58 margin: -20px 10px; 59 59 } 60 60 61 #pp _post_notify_box label.pp-select_all_box input {61 #pp-post_following_box label.pp-select_all_box input { 62 62 margin-bottom: 5px; 63 63 } 64 65 #pp-post_following_users_box, 66 #pp-post_following_usergroups_box { 67 width: 49%; 68 } 69 70 #pp-post_following_users_box { 71 float: left; 72 margin-right: 10px; 73 } 74 75 #pp-post_following_usergroups_box { 76 float: right; 77 } 78 79 #pp-post_following_users_box .pp-post_following_list, 80 #pp-post_following_usergroups_box .pp-post_following_list { 81 max-height: 300px !important; 82 overflow: auto !important; 83 } 84 85 #pp-post_following_users_box .list-filterizer-tools, 86 #pp-post_following_usergroups_box .list-filterizer-tools { 87 margin-top: 5px; 88 } 89 90 /** User Groups **/ 91 #profile-page #post_following_usergroups { 92 width: 300px; 93 } 94 95 #pp-usergroup-users form.quicksearch, 96 #pp-post_following_users_box form.quicksearch { 97 display: none; 98 } 99 100 #pp-usergroup-users h4 { 101 margin-top: 0; 102 } -
publishpress/trunk/modules/notifications/assets/notifications.js
r1839664 r1839780 1 jQuery(function ($) { 2 $(".chosen-select").chosen({ 3 'width': '95%' 1 jQuery(document).ready(function ($) { 2 $('#pp-post_following_users_box ul').listFilterizer(); 3 4 var params = { 5 action: 'save_notifications', 6 post_id: $('#post_ID').val(), 7 }; 8 9 $(document).on('click', '.pp-post_following_list li input:checkbox, .pp-following_usergroups li input:checkbox', function () { 10 var user_group_ids = []; 11 var parent_this = $(this); 12 params.pp_notifications_name = $(this).attr('name'); 13 params._nonce = $("#pp_notifications_nonce").val(); 14 15 $(this) 16 .parent() 17 .parent() 18 .parent() 19 .find('input:checked') 20 .map(function () { 21 user_group_ids.push($(this).val()); 22 }) 23 24 params.user_group_ids = user_group_ids; 25 26 $.ajax({ 27 type: 'POST', 28 url: (ajaxurl) ? ajaxurl : wpListL10n.url, 29 data: params, 30 success: function (x) { 31 var backgroundColor = parent_this.css('background-color'); 32 $(parent_this.parent().parent()) 33 .animate({'backgroundColor': '#CCEEBB'}, 200) 34 .animate({'backgroundColor': backgroundColor}, 200); 35 }, 36 error: function (r) { 37 $('#pp-post_following_users_box').prev().append(' <p class="error">There was an error. Please reload the page.</p>'); 38 } 39 }); 4 40 }); 5 41 }); -
publishpress/trunk/modules/notifications/notifications.php
r1839664 r1839780 43 43 { 44 44 45 // Taxonomy name used to store users which will be notified for changes in the posts.46 public $ notify_user_taxonomy = 'pp_notify_user';47 48 // Taxonomy name used to store roles which will be notified for changes in the posts.49 public $ notify_role_taxonomy = 'pp_notify_role';45 // Taxonomy name used to store users following posts 46 public $following_users_taxonomy = 'following_users'; 47 48 // Taxonomy name used to store user groups following posts 49 public $following_usergroups_taxonomy = PP_User_Groups::taxonomy_key; 50 50 51 51 public $module; … … 64 64 'title' => __('Default Notifications', 'publishpress'), 65 65 'short_description' => __('With notifications, you can keep everyone updated about what’s happening with your content.', 'publishpress'), 66 'extended_description' => __('With notifications, you can keep everyone updated about what’s happening with a given content. Each status change or editorial comment sends out a message to users subscribed to a post. Roles can be used to manage who receives notifications on what.', 'publishpress'),66 'extended_description' => __('With notifications, you can keep everyone updated about what’s happening with a given content. Each status change or editorial comment sends out a message to users subscribed to a post. User groups can be used to manage who receives notifications on what.', 'publishpress'), 67 67 'module_url' => $this->module_url, 68 68 'icon_class' => 'dashicons dashicons-email', … … 83 83 'id' => 'pp-notifications-overview', 84 84 'title' => __('Overview', 'publishpress'), 85 'content' => __('<p>Notifications ensure you keep up to date with progress your most important content. Users can be subscribed to notifications on a post one by one or by selecting roles.</p><p>When enabled, notifications can be sent when a post changes status or an editorial comment is left by a writer or an editor.</p>', 'publishpress'),85 'content' => __('<p>Notifications ensure you keep up to date with progress your most important content. Users can be subscribed to notifications on a post one by one or by selecting user groups.</p><p>When enabled, notifications can be sent when a post changes status or an editorial comment is left by a writer or an editor.</p>', 'publishpress'), 86 86 ), 87 87 'settings_help_sidebar' => __('<p><strong>For more information:</strong></p><p><a href="https://publishpress.com/features/notifications/">Notifications Documentation</a></p><p><a href="https://github.com/ostraining/PublishPress">PublishPress on Github</a></p>', 'publishpress'), … … 107 107 108 108 // Saving post actions 109 // self::save_post_subscriptions() is hooked into transition_post_status so we can ensure roledata109 // self::save_post_subscriptions() is hooked into transition_post_status so we can ensure usergroup data 110 110 // is properly saved before sending notifs 111 add_action('transition_post_status', array($this, 'save_post_subscriptions'), 0, 3); 111 112 add_action('transition_post_status', array($this, 'notification_status_change'), PP_NOTIFICATION_PRIORITY_STATUS_CHANGE, 3); 112 113 add_action('pp_post_insert_editorial_comment', array($this, 'notification_comment')); … … 120 121 add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_styles')); 121 122 122 // Add a " Notify" link to posts123 if (apply_filters('pp_notifications_show_ notify_link', true))124 { 125 // A little extra JS for the Notifybutton126 add_action('admin_head', array($this, 'action_admin_head_ notify_js'));123 // Add a "Follow" link to posts 124 if (apply_filters('pp_notifications_show_follow_link', true)) 125 { 126 // A little extra JS for the follow button 127 add_action('admin_head', array($this, 'action_admin_head_follow_js')); 127 128 // Manage Posts 128 129 add_filter('post_row_actions', array($this, 'filter_post_row_actions'), 10, 2); … … 136 137 add_filter('pp_notification_auto_subscribe_current_user', array($this, 'filter_pp_notification_auto_subscribe_current_user'), 10, 2); 137 138 138 add_action('save_post', array($this, 'action_save_post'), 10);139 140 139 // Ajax for saving notification updates 140 add_action('wp_ajax_save_notifications', array($this, 'ajax_save_post_subscriptions')); 141 141 add_action('wp_ajax_pp_notifications_user_post_subscription', array($this, 'handle_user_post_subscription')); 142 142 … … 152 152 public function install() 153 153 { 154 // Considering we could be moving from Edit Flow, we need to migrate the following users. 155 $this->migrateLegacyFollowingTerms(); 154 156 155 } 157 156 … … 193 192 $publishpress->update_module_option($this->module->name, 'loaded_once', true); 194 193 } 195 196 if (version_compare($previous_version, '1.10', '<=')) {197 $this->migrateLegacyFollowingTerms();198 }199 }200 201 202 protected function migrateLegacyFollowingTerms()203 {204 global $wpdb;205 206 // Migrate Following Users207 $query = "UPDATE {$wpdb->prefix}term_taxonomy SET taxonomy = '{$this->notify_user_taxonomy}' WHERE taxonomy = 'following_users'";208 $wpdb->query($query);209 194 } 210 195 … … 231 216 ); 232 217 233 register_taxonomy($this->notify_user_taxonomy, $supported_post_types, $args); 234 register_taxonomy($this->notify_role_taxonomy, $supported_post_types, $args); 218 register_taxonomy($this->following_users_taxonomy, $supported_post_types, $args); 235 219 } 236 220 … … 246 230 if ($this->is_whitelisted_functional_view()) 247 231 { 232 wp_enqueue_script('jquery-listfilterizer'); 233 wp_enqueue_script('jquery-quicksearch'); 248 234 wp_enqueue_script( 249 235 'publishpress-notifications-js', … … 251 237 array( 252 238 'jquery', 239 'jquery-listfilterizer', 240 'jquery-quicksearch', 253 241 ), 254 242 PUBLISHPRESS_VERSION, 255 243 true 256 244 ); 257 258 wp_enqueue_script('publishpress-chosen-js', PUBLISHPRESS_URL . '/common/libs/chosen/chosen.jquery.js',259 ['jquery'], PUBLISHPRESS_VERSION);260 245 } 261 246 } … … 279 264 PUBLISHPRESS_VERSION 280 265 ); 281 282 wp_enqueue_style('publishpress-chosen-css', PUBLISHPRESS_URL . '/common/libs/chosen/chosen.css', false, 283 PUBLISHPRESS_VERSION); 284 } 285 } 286 287 /** 288 * JS required for the Notify link to work 266 } 267 } 268 269 /** 270 * JS required for the Follow link to work 289 271 * 290 272 * @since 0.8 291 273 */ 292 public function action_admin_head_ notify_js()274 public function action_admin_head_follow_js() 293 275 { 294 276 ?> … … 297 279 $(document).ready(function ($) { 298 280 /** 299 * Action to Notify / Stop Notifyingposts on the manage posts screen281 * Action to Follow / Unfollow posts on the manage posts screen 300 282 */ 301 $('.wp-list-table, #pp-calendar-view, #pp-story-budget-wrap').on('click', '.pp_ notify_link a', function (e) {283 $('.wp-list-table, #pp-calendar-view, #pp-story-budget-wrap').on('click', '.pp_follow_link a', function (e) { 302 284 303 285 e.preventDefault(); … … 327 309 328 310 /** 329 * Add a " Notify" link to supported post types Manage Posts view311 * Add a "Follow" link to supported post types Manage Posts view 330 312 * 331 313 * @since 0.8 … … 349 331 } 350 332 351 $parts = $this->get_ notify_action_parts($post);352 $actions['pp_ notify_link'] = '<a title="' . esc_attr($parts['title']) . '" href="' . esc_url($parts['link']) . '">' . $parts['text'] . '</a>';333 $parts = $this->get_follow_action_parts($post); 334 $actions['pp_follow_link'] = '<a title="' . esc_attr($parts['title']) . '" href="' . esc_url($parts['link']) . '">' . $parts['text'] . '</a>'; 353 335 354 336 return $actions; … … 356 338 357 339 /** 358 * Get an action parts for a user to set Notify or Stop Notify fora post340 * Get an action parts for a user to follow or unfollow a post 359 341 * 360 342 * @since 0.8 361 343 */ 362 private function get_ notify_action_parts($post)344 private function get_follow_action_parts($post) 363 345 { 364 346 $args = array( … … 367 349 ); 368 350 369 $ user_to_notify = $this->get_users_to_notify($post->ID);370 371 if (in_array(wp_get_current_user()->user_login, $ user_to_notify))372 { 373 $args['method'] = ' stop_notifying';351 $following_users = $this->get_following_users($post->ID); 352 353 if (in_array(wp_get_current_user()->user_login, $following_users)) 354 { 355 $args['method'] = 'unfollow'; 374 356 $title_text = __('Click to stop being notified on updates for this post', 'publishpress'); 375 $ link_text= __('Stop notifying me', 'publishpress');357 $follow_text = __('Stop notifying me', 'publishpress'); 376 358 } else 377 359 { 378 $args['method'] = ' start_notifying';360 $args['method'] = 'follow'; 379 361 $title_text = __('Click to start being notified on updates for this post', 'publishpress'); 380 $ link_text= __('Notify me', 'publishpress');362 $follow_text = __('Notify me', 'publishpress'); 381 363 } 382 364 … … 386 368 return array( 387 369 'title' => $title_text, 388 'text' => $ link_text,370 'text' => $follow_text, 389 371 'link' => add_query_arg($args, admin_url('admin-ajax.php')), 390 372 ); … … 401 383 } 402 384 403 $ role_post_types = $this->get_post_types_for_module($this->module);404 foreach ($ role_post_types as $post_type)385 $usergroup_post_types = $this->get_post_types_for_module($this->module); 386 foreach ($usergroup_post_types as $post_type) 405 387 { 406 388 add_meta_box( … … 409 391 array($this, 'notifications_meta_box'), 410 392 $post_type, 411 'side', 412 'high' 393 'advanced' 413 394 ); 414 395 } … … 416 397 417 398 /** 418 * Outputs box used to subscribe users and roles to Posts399 * Outputs box used to subscribe users and usergroups to Posts 419 400 * 420 401 * @todo add_cap to set subscribers for posts; default to Admin and editors … … 425 406 426 407 ?> 427 <div id="pp _post_notify_box">408 <div id="pp-post_following_box"> 428 409 <a name="subscriptions"></a> 429 410 430 <p> 431 <?php _e('Select the users and roles that should receive notifications by workflows.', 'publishpress'); ?> 411 <p><?php _e('Select the users and user groups that should receive notifications when the status of this post is updated or when an editorial comment is added.', 'publishpress'); ?> 432 412 </p> 433 434 <div id="pp_post_notify_users_box">413 <div id="pp-post_following_users_box"> 414 <h4><?php _e('Users', 'publishpress'); ?></h4> 435 415 <?php 436 $users_to_notify = $this->get_users_to_notify($post->ID, 'id'); 437 $roles_to_notify = $this->get_roles_to_notify($post->ID, 'slugs'); 438 439 $selected = array_merge($users_to_notify, $roles_to_notify); 440 416 $followers = $this->get_following_users($post->ID, 'id'); 441 417 $select_form_args = array( 442 'list_class' => 'pp _post_notify_list',418 'list_class' => 'pp-post_following_list', 443 419 ); 444 $this->users_select_form($ selected, $select_form_args);420 $this->users_select_form($followers, $select_form_args); 445 421 ?> 446 447 448 422 </div> 449 423 450 <p> 451 <a href="https://publishpress.com/docs/notifications/"><?php _e('Click here to read more about notifications...', 'publishpress'); ?></a> 452 </p> 424 <?php if ($this->module_enabled('user_groups') && in_array($this->get_current_post_type(), $this->get_post_types_for_module($publishpress->user_groups->module))): ?> 425 <div id="pp-post_following_usergroups_box"> 426 <h4><?php _e('User Groups', 'publishpress') ?></h4> 427 <?php 428 $following_usergroups = $this->get_following_usergroups($post->ID, 'ids'); 429 $publishpress->user_groups->usergroups_select_form($following_usergroups); 430 ?> 431 </div> 432 <?php endif; ?> 453 433 454 434 <div class="clear"></div> 455 435 456 <input type="hidden" name="pp _save_notify" value="1"/> <?php // Extra protection against autosaves436 <input type="hidden" name="pp-save_followers" value="1"/> <?php // Extra protection against autosaves 457 437 ?> 458 438 459 <?php wp_nonce_field('save_ roles', 'pp_notifications_nonce', false); ?>439 <?php wp_nonce_field('save_user_usergroups', 'pp_notifications_nonce', false); ?> 460 440 </div> 461 441 … … 463 443 } 464 444 465 public function action_save_post($postId) 466 { 467 if (!isset($_POST['pp_notifications_nonce']) || !wp_verify_nonce($_POST['pp_notifications_nonce'], 'save_roles')) { 468 return; 469 } 470 471 if (isset($_POST['to_notify'])) { 472 // Remove current users 473 $terms = get_the_terms($postId, $this->notify_user_taxonomy); 474 $users = array(); 475 if (!empty($terms)) { 476 foreach ($terms as $term) { 477 $users[] = $term->term_id; 445 /** 446 * Called when a notification editorial metadata checkbox is checked. Handles saving of a user/usergroup to a post. 447 */ 448 public function ajax_save_post_subscriptions() 449 { 450 global $publishpress; 451 452 // Verify nonce 453 if (!wp_verify_nonce($_POST['_nonce'], 'save_user_usergroups')) 454 { 455 die(__("Nonce check failed. Please ensure you can add users or user groups to a post.", 'publishpress')); 456 } 457 458 $post_id = (int )$_POST['post_id']; 459 $post = get_post($post_id); 460 $user_usergroup_ids = array_map('intval', $_POST['user_group_ids']); 461 if ((!wp_is_post_revision($post_id) && !wp_is_post_autosave($post_id)) && current_user_can($this->edit_post_subscriptions_cap)) 462 { 463 if ($_POST['pp_notifications_name'] === 'pp-selected-users[]') 464 { 465 $this->save_post_following_users($post, $user_usergroup_ids); 466 } else if ($_POST['pp_notifications_name'] == 'following_usergroups[]') 467 { 468 if ($this->module_enabled('user_groups') && in_array(get_post_type($post_id), $this->get_post_types_for_module($publishpress->user_groups->module))) 469 { 470 $this->save_post_following_usergroups($post, $user_usergroup_ids); 478 471 } 479 472 } 480 wp_remove_object_terms($postId, $users, $this->notify_user_taxonomy); 481 482 // Remove current roles 483 $terms = get_the_terms($postId, $this->notify_role_taxonomy); 484 $roles = array(); 485 if (!empty($terms)) { 486 foreach ($terms as $term) { 487 $roles[] = $term->term_id; 488 } 489 } 490 wp_remove_object_terms($postId, $roles, $this->notify_role_taxonomy); 491 492 foreach ($_POST['to_notify'] as $id) { 493 if (is_numeric($id)) { 494 // User id 495 $this->post_set_users_to_notify($postId, (int)$id, true); 496 } else { 497 // Role name 498 $this->post_set_roles_to_notify($postId, $id, true); 499 } 500 } 501 } 473 } 474 die(); 502 475 } 503 476 … … 526 499 } 527 500 528 if (' start_notifying' === $_GET['method'])529 { 530 $retval = $this-> post_set_users_to_notify($post, get_current_user_id());501 if ('follow' == $_GET['method']) 502 { 503 $retval = $this->follow_post_user($post, get_current_user_id()); 531 504 } else 532 505 { 533 $retval = $this-> post_set_users_stop_notify($post, get_current_user_id());506 $retval = $this->unfollow_post_user($post, get_current_user_id()); 534 507 } 535 508 … … 539 512 } 540 513 541 $this->print_ajax_response('success', (object )$this->get_ notify_action_parts($post));514 $this->print_ajax_response('success', (object )$this->get_follow_action_parts($post)); 542 515 } 543 516 … … 572 545 } 573 546 574 /** 575 * Sets users to be notified for the specified post 547 548 /** 549 * Called when post is saved. Handles saving of user/usergroup followers 576 550 * 577 551 * @param int $post ID of the post 578 552 */ 579 public function save_post_notify_users($post, $users = null) 553 public function save_post_subscriptions($new_status, $old_status, $post) 554 { 555 global $publishpress; 556 // only if has edit_post_subscriptions cap 557 if ((!wp_is_post_revision($post) && !wp_is_post_autosave($post)) && isset($_POST['pp-save_followers']) && current_user_can($this->edit_post_subscriptions_cap)) 558 { 559 $users = isset($_POST['pp-selected-users']) ? $_POST['pp-selected-users'] : array(); 560 $usergroups = isset($_POST['following_usergroups']) ? $_POST['following_usergroups'] : array(); 561 $this->save_post_following_users($post, $users); 562 if ($this->module_enabled('user_groups') && in_array($this->get_current_post_type(), $this->get_post_types_for_module($publishpress->user_groups->module))) 563 { 564 $this->save_post_following_usergroups($post, $usergroups); 565 } 566 } 567 } 568 569 /** 570 * Sets users to follow specified post 571 * 572 * @param int $post ID of the post 573 */ 574 public function save_post_following_users($post, $users = null) 580 575 { 581 576 if (!is_array($users)) … … 584 579 } 585 580 586 // Add current user to notify list581 // Add current user to following users 587 582 $user = wp_get_current_user(); 588 583 if ($user && apply_filters('pp_notification_auto_subscribe_current_user', true, 'subscription_action')) … … 591 586 } 592 587 593 // Add post author to notify list588 // Add post author to following users 594 589 if (apply_filters('pp_notification_auto_subscribe_post_author', true, 'subscription_action')) 595 590 { … … 599 594 $users = array_unique(array_map('intval', $users)); 600 595 601 $ this->post_set_users_to_notify($post, $users, false);602 } 603 604 /** 605 * Sets roles to be notified for thespecified post596 $follow = $this->follow_post_user($post, $users, false); 597 } 598 599 /** 600 * Sets usergroups to follow specified post 606 601 * 607 602 * @param int $post ID of the post 608 * @param array $ roles Roles to be notified forposts609 */ 610 public function save_post_ notify_roles($post, $roles = null)611 { 612 if (!is_array($ roles))613 { 614 $ roles = array();615 } 616 $ roles = array_map('intval', $roles);617 618 $ this->add_role_to_notify($post, $roles, false);603 * @param array $usergroups Usergroups to follow posts 604 */ 605 public function save_post_following_usergroups($post, $usergroups = null) 606 { 607 if (!is_array($usergroups)) 608 { 609 $usergroups = array(); 610 } 611 $usergroups = array_map('intval', $usergroups); 612 613 $follow = $this->follow_post_usergroups($post, $usergroups, false); 619 614 } 620 615 … … 625 620 { 626 621 global $publishpress; 627 628 622 629 623 // Kill switch for notification … … 684 678 //if( $parent_ID ) $parent = get_comment( $parent_ID ); 685 679 686 // Set user to be notified for apost, but make it filterable680 // Set user to follow post, but make it filterable 687 681 if (apply_filters('pp_notification_auto_subscribe_current_user', true, 'comment')) 688 682 { 689 $this-> post_set_users_to_notify($post, (int )$current_user->ID);690 } 691 692 // Set the post author to be notified forthe post but make it filterable683 $this->follow_post_user($post, (int )$current_user->ID); 684 } 685 686 // Set the post author to follow the post but make it filterable 693 687 if (apply_filters('pp_notification_auto_subscribe_post_author', true, 'comment')) 694 688 { 695 $this-> post_set_users_to_notify($post, (int )$post->post_author);689 $this->follow_post_user($post, (int )$post->post_author); 696 690 } 697 691 … … 813 807 $recipients = array(); 814 808 815 $role_users = array(); 816 817 // Get users and roles to notify 818 $roles = $this->get_roles_to_notify($post_id, 'slugs'); 819 foreach ((array )$roles as $role_id) 820 { 821 $users = get_users( 822 [ 823 'role' => $role_id, 824 ] 825 ); 826 827 if (!empty($users)) { 828 foreach ($users as $user) 809 $usergroup_users = array(); 810 if ($this->module_enabled('user_groups')) 811 { 812 // Get following users and usergroups 813 $usergroups = $this->get_following_usergroups($post_id, 'ids'); 814 foreach ((array )$usergroups as $usergroup_id) 815 { 816 $usergroup = $publishpress->user_groups->get_usergroup_by('id', $usergroup_id); 817 foreach ((array )$usergroup->user_ids as $user_id) 829 818 { 830 if (is_user_member_of_blog($user->ID)) 819 $usergroup_user = get_user_by('id', $user_id); 820 if ($usergroup_user && is_user_member_of_blog($user_id)) 831 821 { 832 $ role_users[] = $user->user_email;822 $usergroup_users[] = $usergroup_user->user_email; 833 823 } 834 824 } … … 836 826 } 837 827 838 $users = $this->get_ users_to_notify($post_id, 'user_email');828 $users = $this->get_following_users($post_id, 'user_email'); 839 829 840 830 // Merge arrays and filter any duplicates 841 $recipients = array_merge($authors, $admins, $users, $ role_users);831 $recipients = array_merge($authors, $admins, $users, $usergroup_users); 842 832 $recipients = array_unique($recipients); 843 833 … … 851 841 } 852 842 // Don't send the email to the current user unless we've explicitly indicated they should receive it 853 if (false === apply_filters('p ublishpress_notify_current_user', false) && wp_get_current_user()->user_email == $user_email)843 if (false === apply_filters('pp_notification_email_current_user', false) && wp_get_current_user()->user_email == $user_email) 854 844 { 855 845 unset($recipients[$key]); … … 871 861 872 862 /** 873 * Set a user or users to be notified fora post863 * Set a user or users to follow a post 874 864 * 875 865 * @param int|object $post Post object or ID 876 866 * @param string|array $users User or users to subscribe to post updates 877 * @param bool $append Whether users should be added to pp_notify_userlist or replace existing list867 * @param bool $append Whether users should be added to following_users list or replace existing list 878 868 * 879 869 * @return true|WP_Error $response True on success, WP_Error on failure 880 870 */ 881 public function post_set_users_to_notify($post, $users, $append = true)871 public function follow_post_user($post, $users, $append = true) 882 872 { 883 873 $post = get_post($post); … … 893 883 894 884 $user_terms = array(); 895 896 885 foreach ($users as $user) 897 886 { … … 912 901 913 902 // Add user as a term if they don't exist 914 $term = $this->add_term_if_not_exists($name, $this-> notify_user_taxonomy);903 $term = $this->add_term_if_not_exists($name, $this->following_users_taxonomy); 915 904 916 905 if (!is_wp_error($term)) … … 919 908 } 920 909 } 921 922 $set = wp_set_object_terms($post->ID, $user_terms, $this->notify_user_taxonomy, $append); 910 $set = wp_set_object_terms($post->ID, $user_terms, $this->following_users_taxonomy, $append); 923 911 924 912 if (is_wp_error($set)) … … 932 920 933 921 /** 934 * Set a role or roles to be notified for a post 935 * 936 * @param int|object $post Post object or ID 937 * @param string|array $roles Role or roles to subscribe to post updates 938 * @param bool $append Whether roles should be added to pp_notify_role list or replace existing list 939 * 922 * Removes user from following_users taxonomy for the given Post, 923 * so they no longer receive future notifications. 924 * 925 * @param object $post Post object or ID 926 * @param int|string|array $users One or more users to unfollow from the post 940 927 * @return true|WP_Error $response True on success, WP_Error on failure 941 928 */ 942 public function post_set_roles_to_notify($post, $roles, $append = true)929 public function unfollow_post_user($post, $users) 943 930 { 944 931 $post = get_post($post); … … 948 935 } 949 936 950 if (!is_array($roles)) 951 { 952 $roles = array($roles); 953 } 954 955 $role_terms = array(); 956 957 foreach ($roles as $role) 958 { 959 $role = get_role($role); 960 961 if (!is_object($role)) 937 if (!is_array($users)) 938 { 939 $users = array($users); 940 } 941 942 $terms = get_the_terms($post->ID, $this->following_users_taxonomy); 943 if (is_wp_error($terms)) 944 { 945 return $terms; 946 } 947 948 $user_terms = wp_list_pluck($terms, 'slug'); 949 foreach ($users as $user) 950 { 951 if (is_int($user)) 952 { 953 $user = get_user_by('id', $user); 954 } else if (is_string($user)) 955 { 956 $user = get_user_by('login', $user); 957 } 958 959 if (!is_object($user)) 962 960 { 963 961 continue; 964 962 } 965 963 966 // Add user as a term if they don't exist 967 $term = $this->add_term_if_not_exists($role->name, $this->notify_role_taxonomy); 968 969 if (!is_wp_error($term)) 970 { 971 $role_terms[] = $role->name; 972 } 973 } 974 975 $set = wp_set_object_terms($post->ID, $role_terms, $this->notify_role_taxonomy, $append); 964 $key = array_search($user->user_login, $user_terms); 965 if (false !== $key) 966 { 967 unset($user_terms[$key]); 968 } 969 } 970 $set = wp_set_object_terms($post->ID, $user_terms, $this->following_users_taxonomy, false); 976 971 977 972 if (is_wp_error($set)) … … 985 980 986 981 /** 987 * Removes user from pp_notify_user taxonomy for the given Post, 988 * so they no longer receive future notifications. 989 * 990 * @param object $post Post object or ID 991 * @param int|string|array $users One or more users to stop being notified for the post 992 * @return true|WP_Error $response True on success, WP_Error on failure 993 */ 994 public function post_set_users_stop_notify($post, $users) 995 { 996 $post = get_post($post); 997 if (!$post) 998 { 999 return new WP_Error('missing-post', $this->module->messages['missing-post']); 1000 } 1001 1002 if (!is_array($users)) 1003 { 1004 $users = array($users); 1005 } 1006 1007 $terms = get_the_terms($post->ID, $this->notify_user_taxonomy); 1008 if (is_wp_error($terms)) 1009 { 1010 return $terms; 1011 } 1012 1013 $user_terms = wp_list_pluck($terms, 'slug'); 1014 foreach ($users as $user) 1015 { 1016 if (is_int($user)) 1017 { 1018 $user = get_user_by('id', $user); 1019 } else if (is_string($user)) 1020 { 1021 $user = get_user_by('login', $user); 1022 } 1023 1024 if (!is_object($user)) 1025 { 1026 continue; 1027 } 1028 1029 $key = array_search($user->user_login, $user_terms); 1030 if (false !== $key) 1031 { 1032 unset($user_terms[$key]); 1033 } 1034 } 1035 $set = wp_set_object_terms($post->ID, $user_terms, $this->notify_user_taxonomy, false); 1036 1037 if (is_wp_error($set)) 1038 { 1039 return $set; 1040 } else 1041 { 1042 return true; 1043 } 1044 } 1045 1046 /** 1047 * add_role_to_notify() 1048 * 1049 */ 1050 public function add_role_to_notify($post, $roles = 0, $append = true) 1051 { 982 * follow_post_usergroups() 983 * 984 */ 985 public function follow_post_usergroups($post, $usergroups = 0, $append = true) 986 { 987 if (!$this->module_enabled('user_groups')) 988 { 989 return; 990 } 991 1052 992 $post_id = (is_int($post)) ? $post : $post->ID; 1053 if (!is_array($ roles))1054 { 1055 $ roles = array($roles);1056 } 1057 1058 // make sure each roleid is an integer and not a number stored as a string1059 foreach ($ roles as $key => $role)1060 { 1061 $ roles[$key] = intval($role);1062 } 1063 1064 wp_set_object_terms($post_id, $ roles, $this->notify_role_taxonomy, $append);993 if (!is_array($usergroups)) 994 { 995 $usergroups = array($usergroups); 996 } 997 998 // make sure each usergroup id is an integer and not a number stored as a string 999 foreach ($usergroups as $key => $usergroup) 1000 { 1001 $usergroups[$key] = intval($usergroup); 1002 } 1003 1004 wp_set_object_terms($post_id, $usergroups, $this->following_usergroups_taxonomy, $append); 1065 1005 1066 1006 return; … … 1068 1008 1069 1009 /** 1070 * Removes users that are deleted from receiving future notifications (i.e. makes them out of notify list forposts FOREVER! )1010 * Removes users that are deleted from receiving future notifications (i.e. makes them unfollow posts FOREVER! ) 1071 1011 * 1072 1012 * @param $id int ID of the user … … 1084 1024 if ($user) 1085 1025 { 1086 // Delete term from the pp_notify_usertaxonomy1087 $ notify_user_term = get_term_by('name', $user->user_login, $this->notify_user_taxonomy);1088 if ($ notify_user_term)1089 { 1090 wp_delete_term($ notify_user_term->term_id, $this->notify_user_taxonomy);1026 // Delete term from the following_users taxonomy 1027 $user_following_term = get_term_by('name', $user->user_login, $this->following_users_taxonomy); 1028 if ($user_following_term) 1029 { 1030 wp_delete_term($user_following_term->term_id, $this->following_users_taxonomy); 1091 1031 } 1092 1032 } … … 1115 1055 1116 1056 /** 1117 * Gets a list of the users to be notified forthe specified post1057 * Gets a list of the users following the specified post 1118 1058 * 1119 1059 * @param int $post_id The ID of the post 1120 1060 * @param string $return The field to return 1121 * @return array $users Users to notify for the specified posts 1122 */ 1123 public function get_users_to_notify($post_id, $return = 'user_login') 1124 { 1125 // Get pp_notify_user terms for the post 1126 $users = wp_get_object_terms($post_id, $this->notify_user_taxonomy, array('fields' => 'names')); 1127 1128 // Don't have any users to notify 1061 * @return array $users Users following the specified posts 1062 */ 1063 public function get_following_users($post_id, $return = 'user_login') 1064 { 1065 1066 // Get following_users terms for the post 1067 $users = wp_get_object_terms($post_id, $this->following_users_taxonomy, array('fields' => 'names')); 1068 1069 // Don't have any following users 1129 1070 if (!$users || is_wp_error($users)) 1130 1071 { … … 1183 1124 1184 1125 /** 1185 * Gets a list of the roles that should be notified for thespecified post1126 * Gets a list of the usergroups that are following specified post 1186 1127 * 1187 1128 * @param int $post_id 1188 * @return array $ roles All of the roleslugs1189 */ 1190 public function get_ roles_to_notify($post_id, $return = 'all')1129 * @return array $usergroups All of the usergroup slugs 1130 */ 1131 public function get_following_usergroups($post_id, $return = 'all') 1191 1132 { 1192 1133 global $publishpress; … … 1201 1142 } 1202 1143 1203 $ roles = wp_get_object_terms($post_id, $this->notify_role_taxonomy, array('fields' => $fields));1144 $usergroups = wp_get_object_terms($post_id, $this->following_usergroups_taxonomy, array('fields' => $fields)); 1204 1145 1205 1146 if ($return == 'slugs') 1206 1147 { 1207 1148 $slugs = array(); 1208 foreach ($ roles as $role)1209 { 1210 $slugs[] = $ role->slug;1211 } 1212 $ roles = $slugs;1213 } 1214 1215 return $ roles;1216 } 1217 1218 /** 1219 * Gets a list of posts that a user is selected to be notified1149 foreach ($usergroups as $usergroup) 1150 { 1151 $slugs[] = $usergroup->slug; 1152 } 1153 $usergroups = $slugs; 1154 } 1155 1156 return $usergroups; 1157 } 1158 1159 /** 1160 * Gets a list of posts that a user is following 1220 1161 * 1221 1162 * @param string|int $user user_login or id of user 1222 1163 * @param array $args 1223 * @return array $posts Posts a user is selected to be notified1224 */ 1225 public function get_user_ to_notify_posts($user = 0, $args = null)1164 * @return array $posts Posts a user is following 1165 */ 1166 public function get_user_following_posts($user = 0, $args = null) 1226 1167 { 1227 1168 if (!$user) … … 1238 1179 'tax_query' => array( 1239 1180 array( 1240 'taxonomy' => $this-> notify_user_taxonomy,1181 'taxonomy' => $this->following_users_taxonomy, 1241 1182 'field' => 'slug', 1242 1183 'terms' => $user, … … 1248 1189 'post_status' => 'any', 1249 1190 ); 1250 $post_args = apply_filters('pp_user_ to_notify_posts_query_args', $post_args);1191 $post_args = apply_filters('pp_user_following_posts_query_args', $post_args); 1251 1192 $posts = get_posts($post_args); 1252 1193 … … 1587 1528 public function send_notification_comment($args) 1588 1529 { 1530 1531 1589 1532 /* translators: 1: blog name, 2: post title */ 1590 1533 $subject = sprintf(__('[%1$s] New Editorial Comment: "%2$s"', 'publishpress'), $args['blogname'], $args['post_title']); -
publishpress/trunk/modules/settings/settings.php
r1839664 r1839780 165 165 <div class="publishpress-admin pressshack-admin-wrapper wrap"> 166 166 <header> 167 <h1 class="wp-heading-inline"><?php echo $current_module->title; ?></h1> 167 <h1 class="pressshack-title"> 168 <a href="//wordpress.org/plugins/publishpress" target="_blank" rel="noopener noreferrer" title="PublishPress"> 169 <?php _e('PublishPress', 'publishpress') ?> 170 </a> 171 </h1> 168 172 169 173 <?php echo !empty($display_text) ? $display_text : ''; ?> … … 340 344 341 345 foreach ($_POST['publishpress_module_name'] as $moduleSlug) { 342 $module_name = sanitize_key( PublishPress\ Legacy\Util::sanitize_module_name( $moduleSlug ) );346 $module_name = sanitize_key( PublishPress\Util::sanitize_module_name( $moduleSlug ) ); 343 347 344 348 if ($_POST['action'] != 'update' -
publishpress/trunk/modules/user-groups/lib/user-groups.css
r1839664 r1839780 1 1 /** Post subscriptions **/ 2 .pp _post_notify_list {2 .pp-post_following_list { 3 3 } 4 4 5 .pp _post_notify_list li {5 .pp-post_following_list li { 6 6 padding: 10px 5px 5px 5px; 7 7 margin: 0; … … 9 9 } 10 10 11 .pp _post_notify_list li:hover {11 .pp-post_following_list li:hover { 12 12 background: #EAF2FA; 13 13 } 14 14 15 .pp _post_notify_list li input {15 .pp-post_following_list li input { 16 16 float: right; 17 17 } 18 18 19 .pp _post_notify_list .pp-user_displayname,20 .pp _post_notify_list .pp-usergroup_name {19 .pp-post_following_list .pp-user_displayname, 20 .pp-post_following_list .pp-usergroup_name { 21 21 display: block; 22 22 font-size: 14px; 23 23 } 24 24 25 .pp _post_notify_list .pp-user_useremail,26 .pp _post_notify_list .pp-usergroup_description {25 .pp-post_following_list .pp-user_useremail, 26 .pp-post_following_list .pp-usergroup_description { 27 27 display: block; 28 28 color: #ccc; … … 30 30 } 31 31 32 #pp _post_notify_box {32 #pp-post_following_box { 33 33 margin: 10px 0; 34 34 } 35 35 36 #pp _post_notify_box h4 {36 #pp-post_following_box h4 { 37 37 background: #F1F1F1; 38 38 font-weight: bold; … … 43 43 } 44 44 45 #pp _post_notify_box label.pp-select_all_box {45 #pp-post_following_box label.pp-select_all_box { 46 46 float: right; 47 47 margin: -20px 10px; 48 48 } 49 49 50 #pp _post_notify_box label.pp-select_all_box input {50 #pp-post_following_box label.pp-select_all_box input { 51 51 margin-bottom: 5px; 52 52 } 53 53 54 .pp_post_notify_list { 54 #pp-post_following_users_box, 55 #pp-post_following_usergroups_box { 56 width: 49%; 57 } 58 59 #pp-post_following_users_box { 60 float: left; 61 margin-right: 2%; 62 } 63 64 #pp-post_following_usergroups_box { 65 float: right; 66 } 67 68 .pp-post_following_list { 55 69 max-height: 500px !important; 56 70 overflow: auto !important; 57 71 margin-bottom: 0; 58 72 } 73 74 #pp-post_following_users_box .list-filterizer-tools, 75 #pp-post_following_usergroups_box .list-filterizer-tools { 76 margin-top: 5px; 77 } 78 79 /** User Groups **/ 80 #profile-page #post_following_usergroups { 81 width: 300px; 82 } 83 84 #pp-usergroup-users form.quicksearch, 85 #pp-post_following_users_box form.quicksearch { 86 display: none; 87 } 88 89 #pp-usergroup-users h4 { 90 margin-top: 0; 91 } 92 93 .list-filterizer-tabs li { 94 color: #655997; 95 } 96 97 .list-filterizer-tabs li.active, 98 .list-filterizer-tabs li:hover { 99 background: #655997; 100 border-color: #655997; 101 color: #fff; 102 } 103 104 @media (max-width: 767px) { 105 106 #pp-post_following_usergroups_box, 107 #pp-post_following_users_box { 108 float: none; 109 width: 100%; 110 } 111 112 #pp-post_following_users_box { 113 margin-right: 0; 114 margin-bottom: 20px; 115 } 116 } -
publishpress/trunk/modules/user-groups/user-groups.php
r1839670 r1839780 32 32 * class PP_User_Groups 33 33 * 34 * @todo Remove this module. It is deprecated. 34 * @todo all of them PHPdocs 35 * @todo Resolve whether the notifications component of this class should be moved to "subscriptions" 36 * @todo Decide whether it's functional to store user_ids in the term description array 37 * - Argument against: it's going to be expensive to look up usergroups for a user 38 * 35 39 */ 36 40 37 41 if (!class_exists('PP_User_Groups')) 38 42 { 39 /**40 * Class PP_User_Groups41 *42 * @deprecated43 */44 43 class PP_User_Groups extends PP_Module 45 44 { … … 98 97 ), 99 98 'settings_help_sidebar' => __('<p><strong>For more information:</strong></p><p><a href="https://publishpress.com/features/user-groups/">User Groups Documentation</a></p><p><a href="https://github.com/ostraining/PublishPress">PublishPress on Github</a></p>', 'publishpress'), 100 //'options_page' => true,99 'options_page' => true, 101 100 ); 102 101 $this->module = PublishPress()->register_module('user_groups', $args); … … 594 593 <?php 595 594 $select_form_args = array( 596 'list_class' => 'pp _post_notify_list',595 'list_class' => 'pp-post_following_list', 597 596 'input_id' => 'usergroup_users', 598 597 ); … … 883 882 // before <tag>, after <tag>, class, id names? 884 883 $defaults = array( 885 'list_class' => 'pp _post_notify_list',884 'list_class' => 'pp-post_following_list', 886 885 'list_id' => 'pp-following_usergroups', 887 886 'input_id' => 'following_usergroups', … … 949 948 public function get_usergroups($args = array()) 950 949 { 950 951 951 // We want empty terms by default 952 952 if (!isset($args['hide_empty'])) … … 1259 1259 foreach ($all_usergroups as $usergroup) 1260 1260 { 1261 // Not in this user group, so keep going 1262 if (!isset($usergroup->user_ids) || empty($usergroup->user_ids || !is_array($usergroup->user_ids))) { 1263 continue; 1264 } 1265 1261 // Not in this usergroup, so keep going 1266 1262 if (!in_array($user_id, $usergroup->user_ids)) 1267 1263 { -
publishpress/trunk/publishpress.php
r1839670 r1839780 6 6 * Author: PublishPress 7 7 * Author URI: https://publishpress.com 8 * Version: 1.1 1.18 * Version: 1.10.0 9 9 * Text Domain: publishpress 10 10 * Domain Path: /languages … … 137 137 foreach ($roles as $role => $caps) 138 138 { 139 PublishPress\ Legacy\Util::add_caps_to_role($role, $caps);140 } 141 142 // Additional capabilities139 PublishPress\Util::add_caps_to_role($role, $caps); 140 } 141 142 // User groups 143 143 $roles = array( 144 'administrator' => array( apply_filters('pp_manage_roles_cap', 'pp_manage_roles')),144 'administrator' => array('edit_usergroups'), 145 145 ); 146 146 147 147 foreach ($roles as $role => $caps) 148 148 { 149 PublishPress\ Legacy\Util::add_caps_to_role($role, $caps);149 PublishPress\Util::add_caps_to_role($role, $caps); 150 150 } 151 151 } … … 222 222 if (!class_exists('PP_Module')) 223 223 { 224 require_once(PUBLISHPRESS_ BASE_PATH. '/common/php/class-module.php');224 require_once(PUBLISHPRESS_ROOT . '/common/php/class-module.php'); 225 225 } 226 226 227 227 // Scan the modules directory and include any modules that exist there 228 // $module_dirs = scandir(PUBLISHPRESS_ BASE_PATH. '/modules/');228 // $module_dirs = scandir(PUBLISHPRESS_ROOT . '/modules/'); 229 229 $default_module_dirs = array( 230 'modules-settings' => PUBLISHPRESS_BASE_PATH, 231 'calendar' => PUBLISHPRESS_BASE_PATH, 232 'editorial-metadata' => PUBLISHPRESS_BASE_PATH, 233 'notifications' => PUBLISHPRESS_BASE_PATH, 234 'content-overview' => PUBLISHPRESS_BASE_PATH, 235 'custom-status' => PUBLISHPRESS_BASE_PATH, 236 'roles' => PUBLISHPRESS_BASE_PATH, 237 'improved-notifications' => PUBLISHPRESS_BASE_PATH, 238 'async-notifications' => PUBLISHPRESS_BASE_PATH, 239 'user-groups' => PUBLISHPRESS_BASE_PATH, 230 'modules-settings' => PUBLISHPRESS_ROOT, 231 'calendar' => PUBLISHPRESS_ROOT, 232 'editorial-metadata' => PUBLISHPRESS_ROOT, 233 'notifications' => PUBLISHPRESS_ROOT, 234 'content-overview' => PUBLISHPRESS_ROOT, 235 'custom-status' => PUBLISHPRESS_ROOT, 236 'user-groups' => PUBLISHPRESS_ROOT, 237 'improved-notifications' => PUBLISHPRESS_ROOT, 238 'async-notifications' => PUBLISHPRESS_ROOT, 240 239 241 240 // @TODO: Move for settings, and remove after cleanup 242 'dashboard' => PUBLISHPRESS_ BASE_PATH,243 'editorial-comments' => PUBLISHPRESS_ BASE_PATH,244 'settings' => PUBLISHPRESS_ BASE_PATH,245 'efmigration' => PUBLISHPRESS_ BASE_PATH,241 'dashboard' => PUBLISHPRESS_ROOT, 242 'editorial-comments' => PUBLISHPRESS_ROOT, 243 'settings' => PUBLISHPRESS_ROOT, 244 'efmigration' => PUBLISHPRESS_ROOT, 246 245 ); 247 246 … … 250 249 251 250 // Add add-ons as the last tab 252 $module_dirs['addons'] = PUBLISHPRESS_ BASE_PATH;251 $module_dirs['addons'] = PUBLISHPRESS_ROOT; 253 252 254 253 $class_names = array(); … … 281 280 282 281 // Other utils 283 require_once(PUBLISHPRESS_ BASE_PATH. '/common/php/util.php');282 require_once(PUBLISHPRESS_ROOT . '/common/php/util.php'); 284 283 285 284 // Instantiate all of our classes onto the PublishPress object … … 289 288 if (class_exists($class_name)) 290 289 { 291 $slug = PublishPress\ Legacy\Util::sanitize_module_name($slug);290 $slug = PublishPress\Util::sanitize_module_name($slug); 292 291 $this->$slug = new $class_name(); 293 292 } -
publishpress/trunk/readme.txt
r1839670 r1839780 1 === PublishPress helps WordPress teams create great content===1 === PublishPress – WordPress Content Calendar and Notification Workflows === 2 2 Contributors: publishpress, andergmartins, stevejburge, pressshack 3 3 Author: PublishPress, PressShack 4 4 Author URI: https://publishpress.com 5 Tags: Content Calendar, Editorial Calendar, workflow, checklist, p ermissions5 Tags: Content Calendar, Editorial Calendar, workflow, checklist, pre-publish 6 6 Requires at least: 4.6 7 7 Requires PHP: 5.4 8 8 Tested up to: 4.9.4 9 Stable tag: 1.1 1.19 Stable tag: 1.10.0 10 10 License: GPLv2 or later 11 11 License URI: http://www.gnu.org/licenses/gpl-2.0.html 12 12 13 PublishPress is the plugin for WordPress teams. Your team gets an editorial calendar, flexible permissions andnotification workflows.13 PublishPress is the collaboration tool WordPress teams. You get a beautiful editorial calendar and powerful notification workflows. 14 14 15 15 == Description == … … 19 19 PublishPress is the essential plugin for any WordPress site with multiple team members. 20 20 21 PublishPress has multiple tools that help your team stay organized when creating content: 22 23 * Use the [Editorial Calendar](https://publishpress.com/docs/calendar/) and [Content Overview](https://publishpress.com/docs/content-overview/) to get a clear picture of all your planned and published content. 24 * You can write [Comments](https://publishpress.com/docs/editorial-comments/) to leave feedback. 25 * Set up [Notification Workflows](https://publishpress.com/docs/notifications/) to keep your team up-to-date with what’s happening. 21 [Click here to try a free demo of PublishPress](http://publishpress.com/demo) 22 23 PublishPress has multiple tools that help your team stay organized: 24 25 * Use the [Editorial Calendar](https://publishpress.com/docs/calendar/) and [Content Overview](https://publishpress.com/docs/calendar/) to get a clear picture of all your planned and published content. 26 * You can create [Comments](https://publishpress.com/docs/editorial-comments/) and [Notifications](https://publishpress.com/docs/notifications/) to leave feedback and keep your team in the loop. 26 27 * You can add [Metadata](https://publishpress.com/docs/editorial-metadata/) to give your team extra information about each post. 27 28 * Create [Custom Statuses](https://publishpress.com/docs/custom-statuses/) so that WordPress matches your team’s workflow. 28 29 29 Interested in finding out more?30 31 [Click here to try a free demo of PublishPress](https://publishpress.com/demo/).32 [Check out premium add-ons](https://publishpress.com/pricing/) for access to all the PublishPress features.33 34 35 30 = WHO SHOULD USE PUBLISHPRESS? = 36 31 … … 39 34 = PREMIUM ADD-ONS FOR PUBLISHPRESS = 40 35 41 * [Content Checklist](https://publishpress.com/addons/content-checklist/): Set high standards for all your published content 42 * [Multiple Authors](https://publishpress.com/addons/multiple-authors-publishpress/): Easily assign multiple authors to one content item 43 * [Permissions](https://publishpress.com/addons/publishpress-permissions/): Control who gets the click the “Publish” button 44 * [WooCommerce Checklist](https://publishpress.com/addons/woocommerce-checklist/): Set high standards for all your WooCommerce products 45 * [Slack Notifications](https://publishpress.com/addons/publishpress-slack/): Get Slack updates for all content changes 46 47 [Check out premium add-ons](https://publishpress.com/pricing/) for access to all the PublishPress features. 48 49 = EDITORIAL CALENDAR = 36 [Content Checklist](https://publishpress.com/addons/content-checklist/): Set high standards for all your published content 37 [Multiple Authors](https://publishpress.com/addons/multiple-authors/): Easily assign multiple authors to one content item 38 [Permissions](https://publishpress.com/addons/publishpress-permissions/): Control who gets the click the “Publish” button 39 [WooCommerce Checklist](https://publishpress.com/addons/woocommerce-checklist/): Set high standards for all your WooCommerce products 40 [Slack Notifications](https://publishpress.com/addons/publishpress-slack/): Get Slack updates for all content changes 41 [YouTube](https://publishpress.com/addons/embedpress-youtube/): More features and design options for your YouTube videos 42 [Wistia](https://publishpress.com/addons/embedpress-wistia/): More features and design options for your Wistia videos 43 [Vimeo](https://publishpress.com/addons/embedpress-vimeo/): More features and design options for your Vimeo videos 44 45 [Check out the PublishPress Everything Club](https://publishpress.com/addons/publishpress-club/) for access to all the PublishPress add-ons. 46 47 = EDITORIAL CONTENT CALENDAR = 50 48 51 49 The calendar gives you a powerful overview of your publishing schedule. Using the Editorial Calendar, you can easily see when content is planned, and when it was published. You can also drag-and-drop content to a new publication date. By default, you see all the WordPress content you have planned for the next six weeks. If you need to drill down, you can filter the calendar by post status, categories, users or post types. … … 93 91 To find the user settings, go to the PublishPress link in your WordPress admin area, and click the “User Groups” tab. By default, PublishPress provides four user groups: Copy Editors, Photographers, Reporters and Section Editors. 94 92 93 Currently, the most important user of user groups is [Email Notifications](http://publishpress.com/docs/notifications/), but we intend to expand the capabilities of user groups in future PublishPress releases. 94 95 95 * [Click here for more on PublishPress User Groups](https://publishpress.com/docs/user-groups/) 96 96 … … 103 103 = I FOUND A BUG, OR WANT TO CONTRIBUTE CODE = 104 104 105 Great! We’d love to hear from you! PublishPress [is available on Github](https://github.com/OSTraining/PublishPress), and we welcome contributions from everyone. 105 Great! PublishPress [is available on Github](https://github.com/OSTraining/PublishPress), and we welcome contributions from everyone. 106 107 = ALSO CHECK OUT THE EMBEDPRESS PLUGIN = 108 109 If you like PublishPress, then consider checking out [EmbedPress](https://publishpress.com/embedpress/). The EmbedPress plugin allows you to embed anything in WordPress. Here are some video examples: 110 111 * [How to embed YouTube Videos in WordPress](http://publishpress.com/embedpress/docs/youtube-wordpress/) 112 * [How to embed Vimeo Videos in WordPress](http://publishpress.com/embedpress/docs/embed-vimeo-video-wordpress/) 113 * [How to embed Wistia videos in WordPress](https://publishpress.com/embedpress/docs/add-wistia-videos-wordpress/) 114 115 EmbedPress also supports all the Google Drive formats, including these: 116 117 * [How to embed Google Docs in WordPress](http://publishpress.com/embedpress/docs/google-docs-embed-wordpress/) 118 * [How to embed Google Maps in WordPress](http://publishpress.com/embedpress/docs/google-maps-embed-wordpress/) 119 * [How to embed Google Sheets in WordPress](http://publishpress.com/embedpress/docs/embed-google-sheets-wordpress/) 120 121 = WORDPRESS TRAINING = 122 123 Visit [OSTraining](https://www.ostraining.com/) to learn from our [WordPress Training](https://www.ostraining.com/wordpress-training/) and read our [best WordPress blog posts](https://www.ostraining.com/blog/wordpress). If you’re interested in a specific WordPress topic, try specific topic areas such as these: 124 125 * [WordPress Development Classes - learn to build plugins](https://www.ostraining.com/classes/wordpress-development) 126 * [WordPress Theme Design Classes - create your first theme](https://www.ostraining.com/classes/wordpress-themes) 127 * [WordPress eCommerce Classes - set up a WordPress store](https://www.ostraining.com/classes/wordpress-ecommerce) 106 128 107 129 == Frequently Asked Questions == … … 133 155 The format is based on [Keep a Changelog](http://keepachangelog.com/) 134 156 and this project adheres to [Semantic Versioning](http://semver.org/). 135 136 = [1.11.1] - 2018-03-13 =137 138 *Fixed:*139 140 * Fixed backward compatibility with legacy PublishPress Permissions;141 142 = [1.11.0] - 2018-03-13 =143 144 *Fixed:*145 146 * Fixed workflows and notifications for new posts;147 * Fixed issue when installed from composer, related to the vendor dir not being found;148 * Fixed style for icons in the buttons of the popup for iCal subscriptions in the calendar;149 * Fixed hidden submenus adding basic capabilities after installing for the first time;150 151 *Changed:*152 153 * Changed the workflow form, adding all fields as required;154 * Removed support for User Groups - they are deprecated in favor of Roles, in PublishPress;155 * Moved Notifications metabox to the sidebar with high priority for posts;156 * Cleaned up UI removing logo from the title in the admin;157 158 *Added:*159 160 * Added new "From" status: New. Allowing to create workflows specifically from new posts;161 * Added new submenu for managing Roles;162 * Added new receiver option for notification workflows to reach Roles;163 * Added support for multiple Roles per user. A new field is displayed in the user's profile allowing to select multiple roles;164 157 165 158 = [1.10.0] - 2018-02-21 = -
publishpress/trunk/twig/workflow_help.twig
r1839664 r1839780 1 <p>{{ labels.validation_help }}</p>2 1 <h3>Content</h3> 3 2 <p>{{ labels.pre_text }}</p> -
publishpress/trunk/twig/workflow_metabox.twig
r1839664 r1839780 1 1 <div id="psppno-workflow-metabox" class="pure-g"> 2 3 <!-- Events --> 2 <!-- Events --> 4 3 {{ section_event|raw }} 5 4 -
publishpress/trunk/twig/workflow_receiver_user_field.twig
r1839664 r1839780 7 7 8 8 {% if users %} 9 <select multiple="multiple" class="{{ list_class }}" name="{{ input_name }}" id="{{ input_id }}">9 <select multiple="multiple" class="{{ list_class }}" name="{{ input_name }}"> 10 10 {% for user in users %} 11 11 <option value="{{ user.ID }}" {{ selected( user.selected, true ) }}>{{ user.display_name }}</option>
Note: See TracChangeset
for help on using the changeset viewer.