Plugin Directory

Changeset 1839780


Ignore:
Timestamp:
03/14/2018 06:55:37 AM (8 years ago)
Author:
pressshack
Message:

Revert 1.10.0

Location:
publishpress/trunk
Files:
5 added
8 deleted
33 edited

Legend:

Unmodified
Added
Removed
  • publishpress/trunk/common/css/pressshack-admin.css

    r1839664 r1839780  
    7979}
    8080
    81 .pressshack-admin-wrapper > header .pressshack-title {
     81.pressshack-admin-wrapper > header h1 {
    8282    margin: .67em 0 15px .15em;
    8383    font-weight: 600;
  • publishpress/trunk/common/php/class-module.php

    r1839664 r1839780  
    161161        public function get_post_types_for_module($module)
    162162        {
    163             return PublishPress\Legacy\Util::get_post_types_for_module($module);
     163            return PublishPress\Util::get_post_types_for_module($module);
    164164        }
    165165
     
    335335        public function get_current_post_type()
    336336        {
    337             return PublishPress\Legacy\Util::get_current_post_type();
     337            return PublishPress\Util::get_current_post_type();
    338338        }
    339339
     
    624624        public function users_select_form($selected = null, $args = null)
    625625        {
    626             global $publishpress;
    627626
    628627            // Set up arguments
     
    650649                $selected = array();
    651650            }
    652 
    653             $roles = get_editable_roles();
    654651            ?>
    655652
    656653            <?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            ?>
    674675            <?php
     676
    675677        }
    676678
     
    684686        {
    685687
    686             PublishPress\Legacy\Util::add_caps_to_role($role, $caps);
     688            PublishPress\Util::add_caps_to_role($role, $caps);
    687689        }
    688690
  • publishpress/trunk/composer.json

    r1839664 r1839780  
    1717    }
    1818  ],
    19   "autoload": {
    20     "psr-4": {
    21       "PublishPress\\Core\\": "core/"
    22     }
    23   },
    2419  "minimum-stability": "stable",
    2520  "require": {
  • publishpress/trunk/includes.php

    r1839670 r1839780  
    2929 */
    3030
    31 use PublishPress\Legacy\Auto_loader;
     31use PublishPress\Auto_loader;
    3232
    33 if (!defined('PP_LOADED')) {
     33if (!defined('PP_LOADED'))
     34{
    3435    $settingsPage = add_query_arg(
    3536        array(
     
    4142
    4243    // Define contants
    43     define('PUBLISHPRESS_VERSION', '1.11.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__));
    4647    define('PUBLISHPRESS_URL', plugins_url('/', __FILE__));
    4748    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');
    5650
    5751    // Define the Priority for the notification/notification_status_change method
    5852    // 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    {
    6055        define('PP_NOTIFICATION_PRIORITY_STATUS_CHANGE', 10);
    6156    }
    6257
    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';
    6659
    6760    // 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';
    7064    }
    7165
    7266    // 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);
    7768
    7869    define('PP_LOADED', 1);
  • publishpress/trunk/includes_notifications.php

    r1839664 r1839780  
    1010 */
    1111
     12use PublishPress\Notifications\Auto_loader;
     13
    1214defined('ABSPATH') or die('No direct script access allowed.');
     15
     16require_once 'vendor/autoload.php';
    1317
    1418if (!defined('PUBLISHPRESS_NOTIF_LOADED'))
    1519{
    1620    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');
    1822    define('PUBLISHPRESS_NOTIF_LOADED', 1);
    1923
  • publishpress/trunk/libraries/Notifications/Workflow/Controller.php

    r1839664 r1839780  
    139139            '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\Author',
    140140            '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\User',
    141             '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\Role',
     141            '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\User_Group',
    142142            '\\PublishPress\\Notifications\\Workflow\\Step\\Receiver\\Follower',
    143143        ];
  • publishpress/trunk/libraries/Notifications/Workflow/Step/Channel/Email.php

    r1839664 r1839780  
    4646        if (empty($receivers)) {
    4747            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);
    5348        }
    5449
  • publishpress/trunk/libraries/Notifications/Workflow/Step/Event/Filter/Base.php

    r1839664 r1839780  
    4141     *
    4242     * @return string
    43      *
    44      * @throws \Exception
    4543     */
    4644    public function render()
  • publishpress/trunk/libraries/Notifications/Workflow/Step/Event/Filter/Post_Status.php

    r1839664 r1839780  
    5050    {
    5151        $statuses = $this->get_post_statuses();
     52        $options  = [];
    5253        $metadata = (array)$this->get_metadata('');
    53         $options  = [];
    54 
    55         if ('from' === $group) {
    56             // Add an status to represent new posts
    57             $options = [
    58                 [
    59                     'value'    => 'auto-draft',
    60                     'label'    => __('"New"', 'publishpress'),
    61                     'selected' => in_array('auto-draft', $metadata[$group]),
    62                 ],
    63             ];
    64         }
    6554
    6655        foreach ($statuses as $status)
  • publishpress/trunk/libraries/Notifications/Workflow/Step/Receiver/Follower.php

    r1839664 r1839780  
    4646        if ($this->is_selected($workflow->ID))
    4747        {
     48
    4849            $post_id = $args['post']->ID;
    4950
     
    5556            $followers = array();
    5657
     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');
    5762
    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);
    6466
    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);
    6770
    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))
    9372                        {
    94                             if (is_user_member_of_blog($user->ID))
    95                             {
    96                                 $followers[] = $user->ID;
    97                             }
     73                            $followers[] = $usergroup_user;
    9874                        }
    9975                    }
     
    10177            }
    10278
    103             // Merge roles' users and users
     79            $users = $publishpress->notifications->get_following_users($post_id, 'object');
     80
     81            // Merge usergroup users and users
    10482            $followers = array_merge($followers, $users);
    10583
    10684            // 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)
    10990                {
    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]);
    12092                }
    12193            }
     
    135107                foreach ($followers as $user)
    136108                {
    137                     if (is_object($user)) {
    138                         $receivers[] = $user->ID;
    139                     } else {
    140                         $receivers[] = $user;
    141                     }
     109                    $receivers[] = $user->ID;
    142110                }
    143111            }
  • publishpress/trunk/libraries/Notifications/Workflow/Step/Receiver/User.php

    r1839664 r1839780  
    112112        $template_context['list_class'] = 'publishpress_notif_user_list';
    113113        $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_';
    115115
    116116        $template_context = parent::filter_workflow_metabox_context($template_context);
     
    137137
    138138            // 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');
    140140            $receivers = array_merge($receivers, $users);
    141141
  • publishpress/trunk/modules/addons/addons.php

    r1839664 r1839780  
    136136        protected function is_plugin_installed($plugin)
    137137        {
    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");
    139139        }
    140140
  • publishpress/trunk/modules/async-notifications/async-notifications.php

    r1839664 r1839780  
    2929 */
    3030
    31 use PublishPress\Legacy\Auto_loader;
     31use PublishPress\Auto_loader;
    3232use PublishPress\Notifications\Traits\Dependency_Injector;
    3333use PublishPress\Notifications\Traits\PublishPress_Module;
     
    8989            $args['default_options'] = apply_filters('publishpress_async_notif_default_options', $args['default_options']);
    9090            $this->module            = $publishpress->register_module(
    91                 PublishPress\Legacy\Util::sanitize_module_name($this->module_name),
     91                PublishPress\Util::sanitize_module_name($this->module_name),
    9292                $args
    9393            );
     
    184184            $receivers    = [$receiver];
    185185
    186             // Decode the content
    187             $content = base64_decode(maybe_unserialize($content));
    188 
    189186            /**
    190187             * Triggers the notification. This can be caught by notification channels.
  • publishpress/trunk/modules/async-notifications/library/Queue/WPCron.php

    r1839664 r1839780  
    5555        if (!empty($receivers))
    5656        {
    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,
    7265            ];
    7366
     
    7568            foreach ($receivers as $receiver)
    7669            {
    77                 // Base data
    78                 $data = $baseData;
    79 
    80                 // Receiver
    81                 $data[] = $receiver;
     70                $data['receiver'] = $receiver;
    8271
    8372                $this->scheduleEvent($data);
  • publishpress/trunk/modules/calendar/calendar.php

    r1839664 r1839780  
    184184            $this->create_post_cap = apply_filters('pp_calendar_create_post_cap', 'edit_posts');
    185185
    186             require_once(PUBLISHPRESS_BASE_PATH . '/common/php/' . 'screen-options.php');
     186            require_once(PUBLISHPRESS_ROOT . '/common/php/' . 'screen-options.php');
    187187
    188188            add_action('admin_init', array($this, 'register_settings'));
  • publishpress/trunk/modules/calendar/lib/calendar.css

    r1839664 r1839780  
    614614    }
    615615}
    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  
    147147        add_action('admin_init', array($this, 'handle_form_date_range_change'));
    148148
    149         include_once PUBLISHPRESS_BASE_PATH . '/common/php/' . 'screen-options.php';
     149        include_once PUBLISHPRESS_ROOT . '/common/php/' . 'screen-options.php';
    150150
    151151        if (function_exists('add_screen_options_panel'))
  • publishpress/trunk/modules/custom-status/custom-status.php

    r1839664 r1839780  
    216216        {
    217217            $default_terms = $this->get_default_terms();
    218             $roles         = ['administrator', 'author', 'editor', 'contributor'];
    219218
    220219            // Okay, now add the default statuses to the db if they don't already exist
     
    224223                {
    225224                    $this->add_custom_status($term['term'], $term['args']);
    226                 }
    227             }
    228 
    229             // Add basic capabilities for each post status
    230             $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                     }
    241225                }
    242226            }
     
    943927            $this->custom_statuses_cache = array();
    944928
    945             // Set permissions for the base roles
    946             $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 
    954929            return $response;
    955930        }
  • publishpress/trunk/modules/dashboard/dashboard.php

    r1839664 r1839780  
    247247            global $publishpress;
    248248
    249             $myposts = $publishpress->notifications->get_user_to_notify_posts();
     249            $myposts = $publishpress->notifications->get_user_following_posts();
    250250
    251251            ?>
  • publishpress/trunk/modules/improved-notifications/assets/css/admin.css

    r1839664 r1839780  
    9393}
    9494
    95 #psppno-workflow-metabox-section-receiver #pp_post_notify_users_box {
     95#psppno-workflow-metabox-section-receiver #pp-post_following_users_box {
    9696    float: none;
    9797    margin-right: 0;
    9898}
    9999
    100 #psppno-workflow-metabox-section-receiver #pp_post_notify_users_box,
     100#psppno-workflow-metabox-section-receiver #pp-post_following_users_box,
    101101#psppno-workflow-metabox-section-receiver #pp-post_following_usergroups_box {
    102102    width: 100%;
     
    112112
    113113#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 {
    115115    margin-bottom: 9px;
    116116}
     
    168168}
    169169
     170/* Branding for pages */
     171body.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
    170192body.post-type-psppnotif_workflow #wpbody-content {
    171193    margin-bottom: 100px;
     
    189211    border-left: 8px solid #f3f3f3;
    190212}
    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  
    4444        setupFieldFilters('event_content_category');
    4545        setupFieldFilters('user');
    46         setupFieldFilters('role');
     46        setupFieldFilters('user_group');
    4747
    4848        // List search
     49        // $('.publishpress-filter-checkbox-list ul').listFilterizer();
    4950        $('.publishpress-filter-checkbox-list select').multipleSelect({
    5051            filter: true
     
    5253
    5354        // Form validation
    54         $('form#post').on('submit', function (event) {
    55             var selected,
    56                 sections = ['event', 'event_content'],
    57                 messages = [];
    5855
    59             /**
    60              * Set the validation status to the given section.
    61              *
    62              * @param section
    63              * @param status
    64              */
    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 sections
    82             $.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() == null
    98                     || $('#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 section
    137             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 section
    168             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         });
    20356    });
    20457})(jQuery);
  • publishpress/trunk/modules/improved-notifications/improved-notifications.php

    r1839664 r1839780  
    103103            $args['default_options'] = apply_filters('publishpress_notif_default_options', $args['default_options']);
    104104            $this->module            = $publishpress->register_module(
    105                 PublishPress\Legacy\Util::sanitize_module_name($this->module_name),
     105                PublishPress\Util::sanitize_module_name($this->module_name),
    106106                $args
    107107            );
     
    362362                }
    363363            }
    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        }
    381365
    382366        /**
     
    467451            if (in_array($hook_suffix, ['post.php', 'post-new.php']))
    468452            {
    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);
    492455            }
    493456        }
     
    563526            $context = [
    564527                'id'     => 'event_content',
    565                 'header' => __('For which content?', 'publishpress'),
     528                'header' => __('Filter the content?', 'publishpress'),
    566529                'html'   => apply_filters('publishpress_notif_render_metabox_section_event_content', ''),
    567530                'class'  => 'pure-u-1-3 pure-u-sm-1 pure-u-md-1-2 pure-u-lg-1-3',
     
    608571            $context = [
    609572                'labels' => [
    610                     'validation_help'  => __('Select at least one option for each section.', 'publishpress'),
    611573                    'pre_text'         => __('You can add dynamic information to the Subject or Body text using the following shortcodes:', 'publishpress'),
    612574                    'content'          => __('Content', 'publishpress'),
     
    635597         * @param int     $id   Unique ID for the post being saved
    636598         * @param WP_Post $post Post object
    637          *
    638          * @return int|null
    639599         */
    640600        public function save_meta_boxes($id, $post)
  • publishpress/trunk/modules/notifications/assets/notifications.css

    r1839664 r1839780  
    77}
    88
    9 .pp_post_notify_list {
     9.pp-post_following_list {
    1010}
    1111
    12 .pp_post_notify_list li {
     12.pp-post_following_list li {
    1313    padding: 10px 5px 5px 5px;
    1414    margin: 0;
     
    1616}
    1717
    18 .pp_post_notify_list li:hover {
     18.pp-post_following_list li:hover {
    1919    background: #EAF2FA;
    2020}
    2121
    22 .pp_post_notify_list li input {
     22.pp-post_following_list li input {
    2323    float: right;
    2424}
    2525
    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 {
    2828    display: block;
    2929    font-size: 14px;
    3030}
    3131
    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 {
    3434    display: block;
    3535    color: #ccc;
     
    3737}
    3838
    39 #pp_post_notify_box {
     39#pp-post_following_box {
    4040    margin: 10px 0;
    4141}
    4242
    43 #pp_post_notify_box h4 {
     43#pp-post_following_box h4 {
    4444    background: #F1F1F1;
    4545    font-weight: bold;
     
    5050}
    5151
    52 #pp_post_notify_box .error {
     52#pp-post_following_box .error {
    5353    color: red;
    5454}
    5555
    56 #pp_post_notify_box label.pp-select_all_box {
     56#pp-post_following_box label.pp-select_all_box {
    5757    float: right;
    5858    margin: -20px 10px;
    5959}
    6060
    61 #pp_post_notify_box label.pp-select_all_box input {
     61#pp-post_following_box label.pp-select_all_box input {
    6262    margin-bottom: 5px;
    6363}
     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%'
     1jQuery(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        });
    440    });
    541});
  • publishpress/trunk/modules/notifications/notifications.php

    r1839664 r1839780  
    4343    {
    4444
    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;
    5050
    5151        public $module;
     
    6464                'title'                 => __('Default Notifications', 'publishpress'),
    6565                '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'),
    6767                'module_url'            => $this->module_url,
    6868                'icon_class'            => 'dashicons dashicons-email',
     
    8383                    'id'      => 'pp-notifications-overview',
    8484                    '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'),
    8686                ),
    8787                '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'),
     
    107107
    108108            // Saving post actions
    109             // self::save_post_subscriptions() is hooked into transition_post_status so we can ensure role data
     109            // self::save_post_subscriptions() is hooked into transition_post_status so we can ensure usergroup data
    110110            // is properly saved before sending notifs
     111            add_action('transition_post_status', array($this, 'save_post_subscriptions'), 0, 3);
    111112            add_action('transition_post_status', array($this, 'notification_status_change'), PP_NOTIFICATION_PRIORITY_STATUS_CHANGE, 3);
    112113            add_action('pp_post_insert_editorial_comment', array($this, 'notification_comment'));
     
    120121            add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_styles'));
    121122
    122             // Add a "Notify" link to posts
    123             if (apply_filters('pp_notifications_show_notify_link', true))
    124             {
    125                 // A little extra JS for the Notify button
    126                 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'));
    127128                // Manage Posts
    128129                add_filter('post_row_actions', array($this, 'filter_post_row_actions'), 10, 2);
     
    136137            add_filter('pp_notification_auto_subscribe_current_user', array($this, 'filter_pp_notification_auto_subscribe_current_user'), 10, 2);
    137138
    138             add_action('save_post', array($this, 'action_save_post'), 10);
    139 
    140139            // Ajax for saving notification updates
     140            add_action('wp_ajax_save_notifications', array($this, 'ajax_save_post_subscriptions'));
    141141            add_action('wp_ajax_pp_notifications_user_post_subscription', array($this, 'handle_user_post_subscription'));
    142142
     
    152152        public function install()
    153153        {
    154             // Considering we could be moving from Edit Flow, we need to migrate the following users.
    155             $this->migrateLegacyFollowingTerms();
     154
    156155        }
    157156
     
    193192                $publishpress->update_module_option($this->module->name, 'loaded_once', true);
    194193            }
    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 Users
    207             $query = "UPDATE {$wpdb->prefix}term_taxonomy SET taxonomy = '{$this->notify_user_taxonomy}' WHERE taxonomy = 'following_users'";
    208             $wpdb->query($query);
    209194        }
    210195
     
    231216            );
    232217
    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);
    235219        }
    236220
     
    246230            if ($this->is_whitelisted_functional_view())
    247231            {
     232                wp_enqueue_script('jquery-listfilterizer');
     233                wp_enqueue_script('jquery-quicksearch');
    248234                wp_enqueue_script(
    249235                    'publishpress-notifications-js',
     
    251237                    array(
    252238                        'jquery',
     239                        'jquery-listfilterizer',
     240                        'jquery-quicksearch',
    253241                    ),
    254242                    PUBLISHPRESS_VERSION,
    255243                    true
    256244                );
    257 
    258                 wp_enqueue_script('publishpress-chosen-js', PUBLISHPRESS_URL . '/common/libs/chosen/chosen.jquery.js',
    259                     ['jquery'], PUBLISHPRESS_VERSION);
    260245            }
    261246        }
     
    279264                    PUBLISHPRESS_VERSION
    280265                );
    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
    289271         *
    290272         * @since 0.8
    291273         */
    292         public function action_admin_head_notify_js()
     274        public function action_admin_head_follow_js()
    293275        {
    294276            ?>
     
    297279                    $(document).ready(function ($) {
    298280                        /**
    299                          * Action to Notify / Stop Notifying posts on the manage posts screen
     281                         * Action to Follow / Unfollow posts on the manage posts screen
    300282                         */
    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) {
    302284
    303285                            e.preventDefault();
     
    327309
    328310        /**
    329          * Add a "Notify" link to supported post types Manage Posts view
     311         * Add a "Follow" link to supported post types Manage Posts view
    330312         *
    331313         * @since 0.8
     
    349331            }
    350332
    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>';
    353335
    354336            return $actions;
     
    356338
    357339        /**
    358          * Get an action parts for a user to set Notify or Stop Notify for a post
     340         * Get an action parts for a user to follow or unfollow a post
    359341         *
    360342         * @since 0.8
    361343         */
    362         private function get_notify_action_parts($post)
     344        private function get_follow_action_parts($post)
    363345        {
    364346            $args = array(
     
    367349            );
    368350
    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';
    374356                $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');
    376358            } else
    377359            {
    378                 $args['method'] = 'start_notifying';
     360                $args['method'] = 'follow';
    379361                $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');
    381363            }
    382364
     
    386368            return array(
    387369                'title' => $title_text,
    388                 'text'  => $link_text,
     370                'text'  => $follow_text,
    389371                'link'  => add_query_arg($args, admin_url('admin-ajax.php')),
    390372            );
     
    401383            }
    402384
    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)
    405387            {
    406388                add_meta_box(
     
    409391                    array($this, 'notifications_meta_box'),
    410392                    $post_type,
    411                     'side',
    412                     'high'
     393                    'advanced'
    413394                );
    414395            }
     
    416397
    417398        /**
    418          * Outputs box used to subscribe users and roles to Posts
     399         * Outputs box used to subscribe users and usergroups to Posts
    419400         *
    420401         * @todo add_cap to set subscribers for posts; default to Admin and editors
     
    425406
    426407            ?>
    427             <div id="pp_post_notify_box">
     408            <div id="pp-post_following_box">
    428409                <a name="subscriptions"></a>
    429410
    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'); ?>
    432412                </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>
    435415                    <?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');
    441417                    $select_form_args = array(
    442                         'list_class' => 'pp_post_notify_list',
     418                        'list_class' => 'pp-post_following_list',
    443419                    );
    444                     $this->users_select_form($selected , $select_form_args);
     420                    $this->users_select_form($followers, $select_form_args);
    445421                    ?>
    446 
    447 
    448422                </div>
    449423
    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; ?>
    453433
    454434                <div class="clear"></div>
    455435
    456                 <input type="hidden" name="pp_save_notify" value="1"/> <?php // Extra protection against autosaves
     436                <input type="hidden" name="pp-save_followers" value="1"/> <?php // Extra protection against autosaves
    457437                ?>
    458438
    459                 <?php wp_nonce_field('save_roles', 'pp_notifications_nonce', false); ?>
     439                <?php wp_nonce_field('save_user_usergroups', 'pp_notifications_nonce', false); ?>
    460440            </div>
    461441
     
    463443        }
    464444
    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);
    478471                    }
    479472                }
    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();
    502475        }
    503476
     
    526499            }
    527500
    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());
    531504            } else
    532505            {
    533                 $retval = $this->post_set_users_stop_notify($post, get_current_user_id());
     506                $retval = $this->unfollow_post_user($post, get_current_user_id());
    534507            }
    535508
     
    539512            }
    540513
    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));
    542515        }
    543516
     
    572545        }
    573546
    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
    576550         *
    577551         * @param int $post ID of the post
    578552         */
    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)
    580575        {
    581576            if (!is_array($users))
     
    584579            }
    585580
    586             // Add current user to notify list
     581            // Add current user to following users
    587582            $user = wp_get_current_user();
    588583            if ($user && apply_filters('pp_notification_auto_subscribe_current_user', true, 'subscription_action'))
     
    591586            }
    592587
    593             // Add post author to notify list
     588            // Add post author to following users
    594589            if (apply_filters('pp_notification_auto_subscribe_post_author', true, 'subscription_action'))
    595590            {
     
    599594            $users = array_unique(array_map('intval', $users));
    600595
    601             $this->post_set_users_to_notify($post, $users, false);
    602         }
    603 
    604         /**
    605          * Sets roles to be notified for the specified post
     596            $follow = $this->follow_post_user($post, $users, false);
     597        }
     598
     599        /**
     600         * Sets usergroups to follow specified post
    606601         *
    607602         * @param int   $post       ID of the post
    608          * @param array $roles   Roles to be notified for posts
    609          */
    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);
    619614        }
    620615
     
    625620        {
    626621            global $publishpress;
    627 
    628622
    629623            // Kill switch for notification
     
    684678            //if( $parent_ID ) $parent = get_comment( $parent_ID );
    685679
    686             // Set user to be notified for a post, but make it filterable
     680            // Set user to follow post, but make it filterable
    687681            if (apply_filters('pp_notification_auto_subscribe_current_user', true, 'comment'))
    688682            {
    689                 $this->post_set_users_to_notify($post, (int )$current_user->ID);
    690             }
    691 
    692             // Set the post author to be notified for the post but make it filterable
     683                $this->follow_post_user($post, (int )$current_user->ID);
     684            }
     685
     686            // Set the post author to follow the post but make it filterable
    693687            if (apply_filters('pp_notification_auto_subscribe_post_author', true, 'comment'))
    694688            {
    695                 $this->post_set_users_to_notify($post, (int )$post->post_author);
     689                $this->follow_post_user($post, (int )$post->post_author);
    696690            }
    697691
     
    813807            $recipients = array();
    814808
    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)
    829818                    {
    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))
    831821                        {
    832                             $role_users[] = $user->user_email;
     822                            $usergroup_users[] = $usergroup_user->user_email;
    833823                        }
    834824                    }
     
    836826            }
    837827
    838             $users = $this->get_users_to_notify($post_id, 'user_email');
     828            $users = $this->get_following_users($post_id, 'user_email');
    839829
    840830            // Merge arrays and filter any duplicates
    841             $recipients = array_merge($authors, $admins, $users, $role_users);
     831            $recipients = array_merge($authors, $admins, $users, $usergroup_users);
    842832            $recipients = array_unique($recipients);
    843833
     
    851841                }
    852842                // Don't send the email to the current user unless we've explicitly indicated they should receive it
    853                 if (false === apply_filters('publishpress_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)
    854844                {
    855845                    unset($recipients[$key]);
     
    871861
    872862        /**
    873          * Set a user or users to be notified for a post
     863         * Set a user or users to follow a post
    874864         *
    875865         * @param int|object   $post   Post object or ID
    876866         * @param string|array $users  User or users to subscribe to post updates
    877          * @param bool         $append Whether users should be added to pp_notify_user list or replace existing list
     867         * @param bool         $append Whether users should be added to following_users list or replace existing list
    878868         *
    879869         * @return true|WP_Error     $response  True on success, WP_Error on failure
    880870         */
    881         public function post_set_users_to_notify($post, $users, $append = true)
     871        public function follow_post_user($post, $users, $append = true)
    882872        {
    883873            $post = get_post($post);
     
    893883
    894884            $user_terms = array();
    895 
    896885            foreach ($users as $user)
    897886            {
     
    912901
    913902                // 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);
    915904
    916905                if (!is_wp_error($term))
     
    919908                }
    920909            }
    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);
    923911
    924912            if (is_wp_error($set))
     
    932920
    933921        /**
    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
    940927         * @return true|WP_Error     $response  True on success, WP_Error on failure
    941928         */
    942         public function post_set_roles_to_notify($post, $roles, $append = true)
     929        public function unfollow_post_user($post, $users)
    943930        {
    944931            $post = get_post($post);
     
    948935            }
    949936
    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))
    962960                {
    963961                    continue;
    964962                }
    965963
    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);
    976971
    977972            if (is_wp_error($set))
     
    985980
    986981        /**
    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
    1052992            $post_id = (is_int($post)) ? $post : $post->ID;
    1053             if (!is_array($roles))
    1054             {
    1055                 $roles = array($roles);
    1056             }
    1057 
    1058             // make sure each role id is an integer and not a number stored as a string
    1059             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);
    10651005
    10661006            return;
     
    10681008
    10691009        /**
    1070          * Removes users that are deleted from receiving future notifications (i.e. makes them out of notify list for posts FOREVER! )
     1010         * Removes users that are deleted from receiving future notifications (i.e. makes them unfollow posts FOREVER! )
    10711011         *
    10721012         * @param $id int ID of the user
     
    10841024            if ($user)
    10851025            {
    1086                 // Delete term from the pp_notify_user taxonomy
    1087                 $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);
    10911031                }
    10921032            }
     
    11151055
    11161056        /**
    1117          * Gets a list of the users to be notified for the specified post
     1057         * Gets a list of the users following the specified post
    11181058         *
    11191059         * @param int    $post_id The ID of the post
    11201060         * @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
    11291070            if (!$users || is_wp_error($users))
    11301071            {
     
    11831124
    11841125        /**
    1185          * Gets a list of the roles that should be notified for the specified post
     1126         * Gets a list of the usergroups that are following specified post
    11861127         *
    11871128         * @param int $post_id
    1188          * @return array $roles All of the role slugs
    1189          */
    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')
    11911132        {
    11921133            global $publishpress;
     
    12011142            }
    12021143
    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));
    12041145
    12051146            if ($return == 'slugs')
    12061147            {
    12071148                $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 notified
     1149                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
    12201161         *
    12211162         * @param string|int $user user_login or id of user
    12221163         * @param array      $args
    1223          * @return array $posts Posts a user is selected to be notified
    1224          */
    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)
    12261167        {
    12271168            if (!$user)
     
    12381179                'tax_query'      => array(
    12391180                    array(
    1240                         'taxonomy' => $this->notify_user_taxonomy,
     1181                        'taxonomy' => $this->following_users_taxonomy,
    12411182                        'field'    => 'slug',
    12421183                        'terms'    => $user,
     
    12481189                'post_status'    => 'any',
    12491190            );
    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);
    12511192            $posts     = get_posts($post_args);
    12521193
     
    15871528        public function send_notification_comment($args)
    15881529        {
     1530
     1531
    15891532            /* translators: 1: blog name, 2: post title */
    15901533            $subject = sprintf(__('[%1$s] New Editorial Comment: "%2$s"', 'publishpress'), $args['blogname'], $args['post_title']);
  • publishpress/trunk/modules/settings/settings.php

    r1839664 r1839780  
    165165            <div class="publishpress-admin pressshack-admin-wrapper wrap">
    166166                <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>
    168172
    169173                    <?php echo !empty($display_text) ? $display_text : ''; ?>
     
    340344
    341345            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 ) );
    343347
    344348                if ($_POST['action'] != 'update'
  • publishpress/trunk/modules/user-groups/lib/user-groups.css

    r1839664 r1839780  
    11/** Post subscriptions **/
    2 .pp_post_notify_list {
     2.pp-post_following_list {
    33}
    44
    5 .pp_post_notify_list li {
     5.pp-post_following_list li {
    66    padding: 10px 5px 5px 5px;
    77    margin: 0;
     
    99}
    1010
    11 .pp_post_notify_list li:hover {
     11.pp-post_following_list li:hover {
    1212    background: #EAF2FA;
    1313}
    1414
    15 .pp_post_notify_list li input {
     15.pp-post_following_list li input {
    1616    float: right;
    1717}
    1818
    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 {
    2121    display: block;
    2222    font-size: 14px;
    2323}
    2424
    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 {
    2727    display: block;
    2828    color: #ccc;
     
    3030}
    3131
    32 #pp_post_notify_box {
     32#pp-post_following_box {
    3333    margin: 10px 0;
    3434}
    3535
    36 #pp_post_notify_box h4 {
     36#pp-post_following_box h4 {
    3737    background: #F1F1F1;
    3838    font-weight: bold;
     
    4343}
    4444
    45 #pp_post_notify_box label.pp-select_all_box {
     45#pp-post_following_box label.pp-select_all_box {
    4646    float: right;
    4747    margin: -20px 10px;
    4848}
    4949
    50 #pp_post_notify_box label.pp-select_all_box input {
     50#pp-post_following_box label.pp-select_all_box input {
    5151    margin-bottom: 5px;
    5252}
    5353
    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 {
    5569    max-height: 500px !important;
    5670    overflow: auto !important;
    5771    margin-bottom: 0;
    5872}
     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  
    3232 * class PP_User_Groups
    3333 *
    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 *
    3539 */
    3640
    3741if (!class_exists('PP_User_Groups'))
    3842{
    39     /**
    40      * Class PP_User_Groups
    41      *
    42      * @deprecated
    43      */
    4443    class PP_User_Groups extends PP_Module
    4544    {
     
    9897                ),
    9998                '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,
    101100            );
    102101            $this->module = PublishPress()->register_module('user_groups', $args);
     
    594593                                <?php
    595594                                $select_form_args = array(
    596                                     'list_class' => 'pp_post_notify_list',
     595                                    'list_class' => 'pp-post_following_list',
    597596                                    'input_id'   => 'usergroup_users',
    598597                                );
     
    883882            // before <tag>, after <tag>, class, id names?
    884883            $defaults = array(
    885                 'list_class' => 'pp_post_notify_list',
     884                'list_class' => 'pp-post_following_list',
    886885                'list_id'    => 'pp-following_usergroups',
    887886                'input_id'   => 'following_usergroups',
     
    949948        public function get_usergroups($args = array())
    950949        {
     950
    951951            // We want empty terms by default
    952952            if (!isset($args['hide_empty']))
     
    12591259                foreach ($all_usergroups as $usergroup)
    12601260                {
    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
    12661262                    if (!in_array($user_id, $usergroup->user_ids))
    12671263                    {
  • publishpress/trunk/publishpress.php

    r1839670 r1839780  
    66 * Author: PublishPress
    77 * Author URI: https://publishpress.com
    8  * Version: 1.11.1
     8 * Version: 1.10.0
    99 * Text Domain: publishpress
    1010 * Domain Path: /languages
     
    137137        foreach ($roles as $role => $caps)
    138138        {
    139             PublishPress\Legacy\Util::add_caps_to_role($role, $caps);
    140         }
    141 
    142         // Additional capabilities
     139            PublishPress\Util::add_caps_to_role($role, $caps);
     140        }
     141
     142        // User groups
    143143        $roles = array(
    144             'administrator' => array(apply_filters('pp_manage_roles_cap', 'pp_manage_roles')),
     144            'administrator' => array('edit_usergroups'),
    145145        );
    146146
    147147        foreach ($roles as $role => $caps)
    148148        {
    149             PublishPress\Legacy\Util::add_caps_to_role($role, $caps);
     149            PublishPress\Util::add_caps_to_role($role, $caps);
    150150        }
    151151    }
     
    222222        if (!class_exists('PP_Module'))
    223223        {
    224             require_once(PUBLISHPRESS_BASE_PATH . '/common/php/class-module.php');
     224            require_once(PUBLISHPRESS_ROOT . '/common/php/class-module.php');
    225225        }
    226226
    227227        // 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/');
    229229        $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,
    240239
    241240            // @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,
    246245        );
    247246
     
    250249
    251250        // Add add-ons as the last tab
    252         $module_dirs['addons'] = PUBLISHPRESS_BASE_PATH;
     251        $module_dirs['addons'] = PUBLISHPRESS_ROOT;
    253252
    254253        $class_names = array();
     
    281280
    282281        // Other utils
    283         require_once(PUBLISHPRESS_BASE_PATH . '/common/php/util.php');
     282        require_once(PUBLISHPRESS_ROOT . '/common/php/util.php');
    284283
    285284        // Instantiate all of our classes onto the PublishPress object
     
    289288            if (class_exists($class_name))
    290289            {
    291                 $slug        = PublishPress\Legacy\Util::sanitize_module_name($slug);
     290                $slug        = PublishPress\Util::sanitize_module_name($slug);
    292291                $this->$slug = new $class_name();
    293292            }
  • publishpress/trunk/readme.txt

    r1839670 r1839780  
    1 === PublishPress helps WordPress teams create great content ===
     1=== PublishPress – WordPress Content Calendar and Notification Workflows ===
    22Contributors: publishpress, andergmartins, stevejburge, pressshack
    33Author: PublishPress, PressShack
    44Author URI: https://publishpress.com
    5 Tags: Content Calendar, Editorial Calendar, workflow, checklist, permissions
     5Tags: Content Calendar, Editorial Calendar, workflow, checklist, pre-publish
    66Requires at least: 4.6
    77Requires PHP: 5.4
    88Tested up to: 4.9.4
    9 Stable tag: 1.11.1
     9Stable tag: 1.10.0
    1010License: GPLv2 or later
    1111License URI: http://www.gnu.org/licenses/gpl-2.0.html
    1212
    13 PublishPress is the plugin for WordPress teams. Your team gets an editorial calendar, flexible permissions and notification workflows.
     13PublishPress is the collaboration tool WordPress teams. You get a beautiful editorial calendar and powerful notification workflows.
    1414
    1515== Description ==
     
    1919PublishPress is the essential plugin for any WordPress site with multiple team members.
    2020
    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
     23PublishPress 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.
    2627* You can add [Metadata](https://publishpress.com/docs/editorial-metadata/) to give your team extra information about each post.
    2728* Create [Custom Statuses](https://publishpress.com/docs/custom-statuses/) so that WordPress matches your team’s workflow.
    2829
    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 
    3530= WHO SHOULD USE PUBLISHPRESS? =
    3631
     
    3934= PREMIUM ADD-ONS FOR PUBLISHPRESS =
    4035
    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 =
    5048
    5149The 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.
     
    9391To 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.
    9492
     93Currently, 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
    9595* [Click here for more on PublishPress User Groups](https://publishpress.com/docs/user-groups/)
    9696
     
    103103= I FOUND A BUG, OR WANT TO CONTRIBUTE CODE =
    104104
    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.
     105Great! 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
     109If 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
     115EmbedPress 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
     123Visit [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)
    106128
    107129== Frequently Asked Questions ==
     
    133155The format is based on [Keep a Changelog](http://keepachangelog.com/)
    134156and 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;
    164157
    165158= [1.10.0] - 2018-02-21 =
  • publishpress/trunk/twig/workflow_help.twig

    r1839664 r1839780  
    1 <p>{{ labels.validation_help }}</p>
    21<h3>Content</h3>
    32<p>{{ labels.pre_text }}</p>
  • publishpress/trunk/twig/workflow_metabox.twig

    r1839664 r1839780  
    11<div id="psppno-workflow-metabox" class="pure-g">
    2 
    3     <!-- Events -->
     2    <!-- Events -->
    43    {{ section_event|raw }}
    54
  • publishpress/trunk/twig/workflow_receiver_user_field.twig

    r1839664 r1839780  
    77
    88    {% 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 }}">
    1010            {% for user in users %}
    1111                <option value="{{ user.ID }}" {{ selected( user.selected, true ) }}>{{ user.display_name }}</option>
Note: See TracChangeset for help on using the changeset viewer.