⚡ NEW: Changeset/ - High Quality

Changeset 1919099


Ignore:
Timestamp:
08/03/2018 12:04:15 AM (7 years ago)
Author:
davejesch
Message:
  • enhancement: updated configuration of allowed Roles for WPSiteSync UI. Can now allow custom Roles. (Thanks Randy K.)
  • enhancement: disable redirect by f(x) Private Site plugin on WPSiteSync API endpoint.
  • enhancement: detect and recover from missing file attachments (Thanks Matt B.)
  • enhancement: adjust file path when working with attachments on MultiSite installs.
Location:
wpsitesynccontent
Files:
49 added
8 edited

Legend:

Unmodified
Added
Removed
  • wpsitesynccontent/trunk/classes/ajax.php

    r1907374 r1919099  
    99    {
    1010        // add user data on a high priority - in case other add-ons want to change/modify it
    11 //      add_filter('spectrom_sync_api_request', array(&$this, 'add_user_info'), 1, 3);
     11//      add_filter('spectrom_sync_api_request', array($this, 'add_user_info'), 1, 3);
    1212    }
    1313
  • wpsitesynccontent/trunk/classes/apimodel.php

    r1907374 r1919099  
    214214            rocket_define_donotasync_css_constant( true );
    215215        }
     216        // unhook f(x) Private Site
     217        if (function_exists('fx_private_site_plugins_loaded'))
     218            add_action('wp_loaded', array($this, 'unhook_fx_private_site'));
    216219
    217220//die('inside ' . __METHOD__. '():' . __LINE__ . ' set=' . var_export($settings, TRUE));
     
    266269        return $value;
    267270    } */
     271    public function unhook_fx_private_site()
     272    {
     273SyncDebug::log(__METHOD__.'():' . __LINE__ . ' unhook "fx_private_site_plugins_loaded()" function');
     274error_log(__METHOD__.'():' . __LINE__ . ' unhook "fx_private_site_plugins_loaded()" function');
     275        remove_action('template_redirect', 'fx_private_site_please_log_in', 0);
     276    }
    268277}
    269278
  • wpsitesynccontent/trunk/classes/apirequest.php

    r1907374 r1919099  
    367367    private function _add_queue($action, $data)
    368368    {
    369 SyncDebug::log(__METHOD__.'() adding "' . $action . '" to queue with ' . var_export($data, TRUE));
     369SyncDebug::log(__METHOD__.'() adding "' . $action . '" to queue'); // with ' . var_export($data, TRUE));
    370370        $this->_queue[] = array('action' => $action, 'data' => $data);
    371371    }
     
    727727        // sometimes the insert media into post doesn't add a space...this will hopefully fix that
    728728        $content = str_replace('alt="', ' alt="', $content);
    729         if (empty($content))
    730             return TRUE;
     729//      if (empty($content))    // need to continue even with empty content. otherwise featured image doesn't get processed
     730//          return TRUE;
    731731
    732732        // TODO: add try..catch
     
    744744        $this->_sent_images = array();          // list of images already sent. Used by _send_image() to not send the same image twice
    745745
    746         // TODO: use PHP_URL_HOST parameter
    747         $url = parse_url(get_bloginfo('url'));
    748         $this->_source_domain = $url['host'];
     746        // set source domain; used to detect media elements to be added to push queue
     747        $this->set_source_domain(site_url('url'));
    749748
    750749        // get all known children of the post
     
    844843
    845844        // handle the featured image
    846         if ('' !== $post_thumbnail_id) {
    847 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' featured image:');
     845        if (0 !== $post_thumbnail_id) {
     846SyncDebug::log(__METHOD__.'():' . __LINE__ . ' featured image: ' . $post_thumbnail_id);
    848847            $img = wp_get_attachment_image_src($post_thumbnail_id, 'full');
    849848if (FALSE === $img) SyncDebug::log(__METHOD__.'():' . __LINE__ . ' wp_get_attachment_image_src() failed');
     
    855854                $att_post = get_post($post_thumbnail_id);
    856855                if (NULL !== $att_post) {
    857 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' post guid: ' . $att_post->guid);
     856SyncDebug::log(__METHOD__.'():' . __LINE__ . ' post guid: ' . $att_post->guid . ' type=' . $att_post->post_type);
    858857                    $img[0] = $att_post->guid;
    859858                }
     
    10061005SyncDebug::log(__METHOD__.'() post_id=' . $post_id . ' path=' . $file_path . ' featured=' . ($featured ? 'TRUE' : 'FALSE') . ' attach_id=' . $attach_id, TRUE);
    10071006
    1008         if (!file_exists($file_path))
    1009             SyncDebug::log(__METHOD__.'():' . __LINE__ . ' file "' . $file_path . '" not found');
     1007        if (!file_exists($file_path) && FALSE !== strpos($file_path, '%')) {
     1008            // TODO: fix url encoding in file path bb#11
     1009        }
     1010           
     1011        if (!file_exists($file_path)) {
     1012            // no image - no need to send update_media API request #167
     1013SyncDebug::log(__METHOD__.'():' . __LINE__ . ' file "' . $file_path . '" not found');
     1014            return;
     1015        }
    10101016        $attach_post = get_post($attach_id, OBJECT);
    10111017        $attach_alt = get_post_meta($attach_id, '_wp_attachment_image_alt', TRUE);
     
    10311037        // allow extensions to include data in upload_media operations
    10321038        $post_fields = apply_filters('spectrom_sync_upload_media_fields', $post_fields);
    1033 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' image post fields: ' . var_export($post_fields, TRUE));
     1039SyncDebug::log(__METHOD__.'():' . __LINE__ . ' image post ' . $post_fields['img_path'] . $post_fields['img_name']);
     1040//var_export($post_fields, TRUE));
    10341041
    10351042//$post_fields['content-len'] = strlen($post_fields['contents']);
     
    10551062    {
    10561063SyncDebug::log(__METHOD__.'():' . __LINE__ . ' path=' . $file_path);
     1064
     1065        // adjust file path if running within multisite #167
     1066        if (is_multisite()) {
     1067            $to_dir = '/wp-content/blogs.dir/' . get_current_blog_id . '/';
     1068            $file_path = str_replace('/wp-content/files/', $to_dir, $file_path);
     1069SyncDebug::log(__METHOD__.'():' . __LINE__ . ' adjusted multisite file path to ' . $file_path);
     1070        }
     1071
     1072        // TODO: rework to use CURLFile class and @filename specifier (for PHP < 5.5) to save memory on large files #165
    10571073
    10581074        // first, try file_get_contents()
  • wpsitesynccontent/trunk/classes/model.php

    r1907374 r1919099  
    121121            $site_key = SyncOptions::get('site_key');
    122122
    123         $where = '';
     123        $join = $where = '';
    124124        if (NULL !== $type) {
    125125            $type = sanitize_key($type);
     
    127127        }
    128128
    129         $join = $where = '';
    130129        if ($assoc) {
    131130            $join = " LEFT JOIN `{$wpdb->posts}` ON `{$wpdb->posts}`.`ID`=`target_content_id` ";
    132             $where = " AND `{$wpdb->posts}`.`ID` IS NOT NULL ";
     131            $where .= " AND `{$wpdb->posts}`.`ID` IS NOT NULL ";
    133132        }
    134133        $query = "SELECT *
  • wpsitesynccontent/trunk/classes/options.php

    r1907374 r1919099  
    1010    private static $_dirty = FALSE;
    1111
     12    private static $_constraints = array(
     13        'match_mode' => array('title', 'slug', 'id'),
     14        'min_role' => array('author', 'editor', 'administrator'),
     15        'roles' => '|author|editor|administrator|',
     16    );
     17    const ROLE_DELIMITER = '|';
     18   
    1219    /*
    1320     * Options are:
     
    2128     * 'strict' = 1 for strict mode; otherwise 0
    2229     * 'salt' = salt value used for authentication
    23      * 'min_role' = minimum role allowed to perform SYNC operations
    2430     * 'remove' = remove settings/tables on plugin deactivation
    2531     * 'match_mode' = method for matching content on Target: 'title', 'slug', 'id'
    2632     * 'min_role' = minimum role required to be able to perform Sync operations #122
     33     * 'roles' = Roles allowed to perform Sync operations
    2734     */
    2835
     
    3239    private static function _load_options()
    3340    {
    34         if (NULL === self::$_options)
    35             self::$_options = get_option(self::OPTION_NAME, array());
     41        if (NULL !== self::$_options)
     42            return;
     43        self::$_options = get_option(self::OPTION_NAME, array());
     44SyncDebug::log(__METHOD__.'():' . __LINE__ . ' options=' . var_export(self::$_options, TRUE));
     45        if (FALSE === self::$_options)
     46            self::$_options = array();
    3647
    3748        // perform fixup / cleanup on option values...migrating from previous configuration settings
     
    4556            'strict' => '1',
    4657            'salt' => '',
    47             'min_role' => '',
    4858            'remove' => '0',
    4959            'match_mode' => 'title',
    5060            'min_role' => 'author',
     61            'roles' => '|author|editor|administrator|',
    5162        );
    5263
    5364        self::$_options = array_merge($defaults, self::$_options);
     65SyncDebug::log(__METHOD__.'():' . __LINE__ . ' options=' . var_export(self::$_options, TRUE));
     66
     67        // adjust settings for roles if missing (newly added setting not configured; use defaults) #166
     68        if (empty(self::$_options['roles']) || empty(self::$_options['min_role'])) {
     69            switch (self::$_options['min_role']) {
     70            case 'author':
     71            default:
     72                self::$_options['roles'] = '|author|editor|administrator|';
     73                break;
     74            case 'editor':
     75                self::$_options['rolse'] = '|editor|administrator|';
     76                break;
     77            case 'admin':
     78                self::$_options['roles'] = '|administrator|';
     79                break;
     80            }
     81SyncDebug::log(__METHOD__.'():' . __LINE__ . ' roles are empty; setting to: ' . self::$_options['roles']);
     82        }
    5483    }
    5584
     
    103132
    104133    /**
     134     * Returns an array describing known good values for each setting name
     135     * @return type
     136     */
     137    public static function get_constraints()
     138    {
     139        return self::$_constraints;
     140    }
     141
     142    /**
    105143     * Checks to see if the site has a valid authentication to a Target site
    106144     * @return boolean TRUE if site is authorized; otherwise FALSE
     
    120158    public static function has_cap()
    121159    {
    122         $min_role = self::get('min_role');
     160        $min_role = self::get('min_role', 'author');
     161        $roles = self::get('roles', '');
     162        if (empty($roles)) {
     163            // if the roles are empty, adjust setting based on default roles from v1.4
     164SyncDebug::log(__METHOD__.'():' . __LINE__ . ' roles are empty; min_role=' . var_export($min_role, TRUE));
     165            switch ($min_role) {
     166                case 'administrator':
     167                default:
     168                    $roles = '|administrator|';
     169                    break;
     170                case 'editor':
     171                    $roles = '|editor|administrator|';
     172                    break;
     173                case 'author':
     174                    $roles = '|author|editor|administrator|';
     175                    break;
     176            }
     177        }
    123178        $current_user = wp_get_current_user();
    124 
     179        // check to see if current user's Role is in list of allowed roles #166
     180SyncDebug::log(__METHOD__.'():' . __LINE__ . ' roles=' . var_export($roles, TRUE));
     181        foreach ($current_user->roles as $role)
     182            if (FALSE !== strpos($roles, self::ROLE_DELIMITER . $role . self::ROLE_DELIMITER)) {
     183SyncDebug::log(__METHOD__.'():' . __LINE__ . ' found matching role "' . $role . '"');
     184                return TRUE;
     185            }
     186        return FALSE;
     187#####
    125188        switch ($min_role) {
    126189        case 'administrator':
     
    141204
    142205    /**
    143      * Updates the local copy of the option data
     206     * Updates the local copy of the option data. Will not update properties that are not already in option array.
    144207     * @param string $name The name of the Sync option to update
    145208     * @param mixed $value The value to store with the name
     
    149212        self::_load_options();
    150213
    151         self::$_options[$name] = $value;
    152         self::$_dirty = TRUE;
     214        // don't allow setting unknown property names
     215        if (isset(self::$_options[$name])) {
     216            if (isset(self::$_constraints[$name]) && !in_array($value, self::$_constraints)) {
     217                // current value is not a known good value for this property; abort
     218                return;
     219            }
     220            self::$_options[$name] = $value;
     221            self::$_dirty = TRUE;
     222        }
    153223    }
    154224
  • wpsitesynccontent/trunk/classes/settings.php

    r1907374 r1919099  
    1919    {
    2020        add_action('admin_menu', array($this, 'add_configuration_page'));
    21         add_action('admin_init', array($this, 'settings_api_init'));
     21        add_action('current_screen'/*'admin_init'*/, array($this, 'settings_api_init'));
    2222        add_action('load-settings_page_sync', array($this, 'contextual_help'));
    2323
     
    6161            'manage_options',                           // capability
    6262            self::SETTINGS_PAGE,                        // menu slug
    63             array(&$this, 'settings_page')              // callback
     63            array($this, 'settings_page')               // callback
    6464        );
    6565        return $slug;
     
    7272    {
    7373//SyncDebug::log(__METHOD__.'() tab=' . $this->_tab);
    74         add_filter('admin_footer_text', array(&$this, 'footer_content'));
     74        add_filter('admin_footer_text', array($this, 'footer_content'));
    7575//      add_action('spectrom_page', array(&$this, 'show_settings_page'));
    7676//      do_action('spectrom_page');
     
    167167    public function settings_api_init()
    168168    {
     169        // don't bother initializing if not on the WPSiteSync settings page
     170//      $screen = get_current_screen();
     171//SyncDebug::log(__METHOD__.'():' . __LINE__ . ' screen=' . var_export($screen, TRUE));
     172//      if (NULL !== $screen && 'settings_page_sync' !== $screen->id)
     173//          return;
     174
    169175        $this->_tab = $this->get('tab', 'general');
    170176//SyncDebug::log(__METHOD__.'() tab=' . $this->_tab);
     
    223229            'sync_options_group',                       // option group, used for settings_fields()
    224230            SyncOptions::OPTION_NAME,                   // option name, used as key in database
    225             array(&$this, 'validate_settings')          // validation callback
     231            array($this, 'validate_settings')           // validation callback
    226232        );
    227233
     
    245251            'host',                                         // field id
    246252            __('Host Name of Target:', 'wpsitesynccontent'),// title
    247             array(&$this, 'render_input_field'),            // callback
     253            array($this, 'render_input_field'),             // callback
    248254            self::SETTINGS_PAGE,                            // page
    249255            $section_id,                                    // section id
     
    253259                'placeholder' => empty($data['host']) ? 'http://' : '',
    254260                'size' => '50',
    255                 'description' => __('http://example.com - This is the URL that your Content will be Pushed to.', 'wpsitesynccontent'),
     261                'description' => __('http://example.com - This is the URL that your Content will be Pushed to. If WordPress is installed in a subdirectory, include the subdirectory.', 'wpsitesynccontent'),
    256262            )
    257263        );
     
    260266            'username',                                     // field id
    261267            __('Username on Target:', 'wpsitesynccontent'), // title
    262             array(&$this, 'render_input_field'),            // callback
     268            array($this, 'render_input_field'),             // callback
    263269            self::SETTINGS_PAGE,                            // page
    264270            $section_id,                                    // section id
     
    281287            'password',                                     // field id
    282288            __('Password on Target:', 'wpsitesynccontent'), // title
    283             array(&$this, 'render_password_field'),         // callback
     289            array($this, 'render_password_field'),          // callback
    284290            self::SETTINGS_PAGE,                            // page
    285291            $section_id,                                    // section
     
    306312            'strict',                                       // field id
    307313            __('Strict Mode:', 'wpsitesynccontent'),        // title
    308             array(&$this, 'render_radio_field'),            // callback
     314            array($this, 'render_radio_field'),             // callback
    309315            self::SETTINGS_PAGE,                            // page
    310316            $section_id,                                    // section id
     
    333339            'match_mode',                                       // field id
    334340            __('Content Match Mode:', 'wpsitesynccontent'),     // title
    335             array($this, 'render_select_field'),            // callback
    336             self::SETTINGS_PAGE,                            // page
    337             $section_id,                                    // section id
    338             array(                                          // args
     341            array($this, 'render_select_field'),                // callback
     342            self::SETTINGS_PAGE,                                // page
     343            $section_id,                                        // section id
     344            array(                                              // args
    339345                'name' => 'match_mode',
    340346                'value' => $match_mode,
     
    351357        $min_role = isset($data['min_role']) ? $data['min_role'] : 'author';
    352358        switch ($min_role) {
     359        case 'author':          $default_role = '|author|editor|administrator|';
    353360        default:
    354         case 'author':          $desc = __('Author - User needs to have Author permissions (Author, Editor, Admin).', 'wpsitesynccontent');
    355             break;
    356         case 'editor':          $desc = __('Editor - User needs to have Editor permissions (Editor, Admin).', 'wpsitesynccontent');
    357             break;
    358         case 'administrator':   $desc = __('Admin - User needs to have Admin permissions (Admins only).', 'wpsitesynccontent');
    359             break;
    360         }
     361            break;
     362        case 'editor':          $default_role = '|editor|administrator|';
     363            break;
     364        case 'admin':           $default_role = '|administrator|';
     365            break;
     366        }
     367        // if not present, default roles based on v1.4 settings values #169
     368        $roles = isset($data['roles']) ? $data['roles'] : $default_role;
    361369
    362370        add_settings_field(
    363             'min_role',                                     // field id
    364             __('Minimum Role to use WPSiteSync:', 'wpsitesynccontent'),     // title
    365             array($this, 'render_select_field'),            // callback
     371            'roles',                                        // field id
     372            __('Roles Allowed to use WPSiteSync:', 'wpsitesynccontent'),        // title
     373            array($this, 'render_roles_field'),             // callback
    366374            self::SETTINGS_PAGE,                            // page
    367375            $section_id,                                    // section id
    368376            array(                                          // args
    369                 'name' => 'min_role',
    370                 'value' => $min_role,
    371                 'options' => array(
     377                'name' => 'roles',
     378                'value' => $roles,
     379/*              'options' => array(
    372380                    'author' => __('Authors, Editors and Admins', 'wpsitesynccontent'),
    373381                    'editor' => __('Editor and Admins', 'wpsitesynccontent'),
    374382                    'administrator' => __('Admins Only', 'wpsitesynccontent'),
    375                 ),
    376                 'description' => $desc,
     383                ), */
     384                'description' => __('Select the Roles you wish to have access to the WPSiteSync User Interface. Only these Roles will be allowed to perform Syncing operations.', 'wpsitesynccontent'),
    377385            )
    378386        );
     
    381389            'salt',                                         // field id
    382390            __('Authentication Salt:', 'wpsitesynccontent'),// title
    383             array(&$this, 'render_input_field'),            // callback
     391            array($this, 'render_input_field'),             // callback
    384392            self::SETTINGS_PAGE,                            // page
    385393            $section_id,                                    // section id
     
    396404            'min_role',                                     // field id
    397405            __('Minimum Role allowed to Sync content:', 'wpsitesynccontent'),   // title
    398             array(&$this, 'render_select_field'),           // callback
     406            array($this, 'render_select_field'),            // callback
    399407            self::SETTINGS_PAGE,                            // page
    400408            $section_id,                                    // section id
     
    412420            'remove',                                       // field id
    413421            __('Optionally remove Settings and Tables on plugin uninstall:', 'wpsitesynccontent'),  // title
    414             array(&$this, 'render_radio_field'),            // callback
     422            array($this, 'render_radio_field'),             // callback
    415423            self::SETTINGS_PAGE,                            // page
    416424            $section_id,                                    // section id
     
    465473        if (!empty($args['description']))
    466474            echo '<p><em>', esc_html($args['description']), '</em></p>';
     475    }
     476
     477    /**
     478     * Renders a list of checkboxes for Role selection
     479     * @param array $args Array of arguments, containser name and options data
     480     */
     481    public function render_roles_field($args)
     482    {
     483        // display list of available Roles #166
     484        $roles = array_reverse(get_editable_roles());
     485        $allowed_roles = $args['value'];
     486        foreach ($roles as $role => $caps) {
     487            if (isset($caps['capabilities']['edit_posts']) && $caps['capabilities']['edit_posts']) {
     488                $checked = (FALSE === strpos($allowed_roles, SyncOptions::ROLE_DELIMITER . $role . SyncOptions::ROLE_DELIMITER)) ? '' : ' checked="checked" ';
     489                $disabled = '';
     490                if ('administrator' === $role) {
     491                    $disabled =  ' disabled="disabled" ';
     492                    $checked = ' checked="checked" ';
     493                }
     494                printf('<input type="checkbox" name="spectrom_sync_settings[%s][%s]" %s %s /> %s<br/>',
     495                    $args['name'], $role, $checked, $disabled, $caps['name']);
     496            }
     497        }
     498        if (!empty($args['description']))
     499            echo '<p>', esc_html($args['description']), '</p>';
     500//      echo '<pre>', var_export($roles, TRUE), '</pre>';
    467501    }
    468502
     
    544578    public function validate_settings($values)
    545579    {
    546 //SyncDebug::log(__METHOD__.'() tab=' . $this->_tab);
     580SyncDebug::log(__METHOD__.'() tab=' . $this->_tab);
     581SyncDebug::log(__METHOD__.'():' . __LINE__ . ' values=' . var_export($values, TRUE));
    547582        if (!current_user_can('manage_options'))
    548583            return array();
     
    558593        $re_auth = FALSE;
    559594
     595        // if no setting found for roles; default to admins only #169
     596        if (!isset($values['roles']))
     597            $values['roles'] = array('administrator' => 'on');
     598
    560599        foreach ($values as $key => $value) {
    561 //SyncDebug::log(" key={$key}  value=[{$value}]");
     600SyncDebug::log(" key={$key}  value=[" . var_export($value, TRUE) . ']');
    562601            if (empty($values[$key]) && 'password' === $key) {
    563602                // ignore this so that passwords are not required on every settings update
    564603            } else {
    565                 if ('password' !== $key)
     604                if ('password' !== $key && !is_array($value))
    566605                    $value = trim($value);          // strip any whitespaces on non-password fields #73
    567606                if ('host' === $key) {
     
    594633                            $out[$key] = $settings['username'];
    595634                    }
     635                } else if ('roles' === $key) {
     636SyncDebug::log(__METHOD__.'():' . __LINE__ . ' POST=' . var_export($_POST, TRUE));
     637                    $roles = array();
     638SyncDebug::log(__METHOD__.'():' . __LINE__ . ' value=' . var_export($value, TRUE));
     639                    foreach ($value as $role => $on) {
     640                        $roles[] = $role;
     641                    }
     642                    if (!in_array('administrator', $roles))
     643                        $roles[] = 'administrator';             // always force administrator access
     644                    $out[$key] = SyncOptions::ROLE_DELIMITER . implode(SyncOptions::ROLE_DELIMITER, $roles) . SyncOptions::ROLE_DELIMITER;
     645SyncDebug::log(__METHOD__.'():' . __LINE__ . ' roles: ' . $out[$key]);
    596646                } else if (0 === strlen(trim($value))) {
    597647                    if (!$missing_error) {
     
    721771                '<p>' . __('<strong>Strict Mode</strong>: Select if WordPress and WPSiteSync for Content should be the same versions on the Source and the Target.', 'wpsitesynccontent') . '</p>' .
    722772                '<p>' . __('<strong>Match Mode</strong>: How WPSiteSync should match posts on the Target. You can select "Post Title" (default), or "Post Slug" to match Content by Title or Slug.', 'wpsitesynccontent') . '</p>' .
    723                 '<p>' . __('<strong>Minimum Role</strong>: The Minimum User Role required in order to use the features of WPSiteSync. Selecting Author means that Authors, Editors and Admins can use WPSiteSync. Selecting Editor means Editors and Admins can use WPSiteSync. Selecting Admin means that only Admins can use WPSiteSync.', 'wpsitesynccontent') . '</p>'
     773                '<p>' . __('<strong>Roles</strong>: The Roles that will be allowed to perform Syncing operations. Only Roles with the "edit_posts" capability will be shown. The "Administrator" Role is always allowed to perform operations.', 'wpsitesynccontent') . '</p>'
    724774//              '<p>' . __('<strong>Authentication Salt:</strong>: Enter a salt to use when Content is sent to current site or leave blank.', 'wpsitesynccontent') . '</p>' .
    725775//              '<p>' . __('<strong>Minimum Role allowed to SYNC Content</strong>: Select minimum role of user who can Sync Content to current site.', 'wpsitesynccontent') . '</p>'
  • wpsitesynccontent/trunk/readme.txt

    r1907374 r1919099  
    112112
    113113== Changelog ==
     114= 1.4.1 - Aug 2, 2018 =
     115* enhancement: updated configuration of allowed Roles for WPSiteSync UI. Can now allow custom Roles. (Thanks Randy K.)
     116* enhancement: disable redirect by f(x) Private Site plugin on WPSiteSync API endpoint.
     117* enhancement: detect and recover from missing file attachments (Thanks Matt B.)
     118* enhancement: adjust file path when working with attachments on MultiSite installs.
     119
    114120= 1.4 - Jul 10, 2018 =
    115121* fix: fix conversion of url to file path when Pushing media content (Thanks Jocelyn M.)
  • wpsitesynccontent/trunk/wpsitesynccontent.php

    r1907374 r1919099  
    66Author: WPSiteSync
    77Author URI: http://wpsitesync.com
    8 Version: 1.4
     8Version: 1.4.1
    99Text Domain: wpsitesynccontent
    1010Domain path: /language
     
    2525    class WPSiteSyncContent
    2626    {
    27         const PLUGIN_VERSION = '1.4';
     27        const PLUGIN_VERSION = '1.4.1';
    2828        const PLUGIN_NAME = 'WPSiteSyncContent';
    2929
     
    5151            add_action('wp_ajax_spectrom_sync', array($this, 'check_ajax_query'));
    5252
    53             add_action('plugins_loaded', array($this, 'plugins_loaded'));
     53            add_action('plugins_loaded', array($this, 'plugins_loaded'), 1);
    5454
    5555            // the following are needed during add-on updates to fix problem with long file names on Windows
     
    203203        public static function check_updates()
    204204        {
     205            // TODO: optimize by doing checks only once every 8 hours
     206
    205207            // load updater class
    206208            if (!class_exists('EDD_SL_Plugin_Updater_Sync', FALSE)) {
Note: See TracChangeset for help on using the changeset viewer.