Plugin Directory

Changeset 1573030


Ignore:
Timestamp:
01/12/2017 03:44:51 AM (9 years ago)
Author:
davejesch
Message:
  • Fix: add placeholder file to force creation of languages/ directory.
  • Enhancement: Additional changes in preparation for WPSiteSync for BeaverBuilder.
  • Enhancement: Better error messages when empty or missing post content is encountered.
  • Enhancement: Improved Media Library image lookup for use by BeaverBuilder add-on.
  • Enhancement: Added pre processing hook for use by ACF add-on.
Location:
wpsitesynccontent
Files:
45 added
7 edited

Legend:

Unmodified
Added
Removed
  • wpsitesynccontent/trunk/.htaccess

    r1407702 r1573030  
    11<Files *.php>
     2    Order Deny,Allow
     3    deny from all
     4</Files>
     5
     6<Files ~*.txt>
    27    Order Deny,Allow
    38    deny from all
  • wpsitesynccontent/trunk/classes/apicontroller.php

    r1560226 r1573030  
    5555        $this->source_site_key = isset($args['site_key']) ? $args['site_key'] : $this->_get_header(self::HEADER_SITE_KEY);
    5656
    57         $this->source = isset($args['source']) ? $args['source'] : $this->_get_header(self::HEADER_SOURCE);
     57        $this->source = untrailingslashit(isset($args['source']) ? $args['source'] : $this->_get_header(self::HEADER_SOURCE));
    5858SyncDebug::log(__METHOD__.'() action=' . $action . ' source=' . $this->source . ' key=' . $this->source_site_key);
    5959
     
    259259        // Check if a post_id was specified, indicating an update to a previously synced post
    260260        $target_post_id = $this->post_int('target_post_id', 0);
     261
     262        // let add-ons know we're about to process a Push operation
     263        do_action('spectrom_sync_pre_push_content', $post_data, $this->source_post_id, $target_post_id, $response);
    261264
    262265        $post = NULL;
     
    722725    public function upload_media(SyncApiResponse $response)
    723726    {
     727SyncDebug::log(__METHOD__.'():' . __LINE__ . ' max upload size=' . wp_max_upload_size() . ' file size=' . (isset($_FILES['sync_file_upload']['size']) ? $_FILES['sync_file_upload']['size'] : '-'));
    724728        // permissions check - make sure current_user_can('upload_files')
    725729        if (!$this->has_permission('upload_files')) {
     
    736740        if (!isset($_FILES['sync_file_upload'])) {
    737741SyncDebug::log(__METHOD__.'():' . __LINE__ . ' no file upload information provided');
    738             $response->error_code(SyncApiRequest::ERROR_POST_CONTENT_NOT_FOUND);
     742            $response->error_code(SyncApiRequest::ERROR_UPLOAD_NO_CONTENT);
    739743            return;
    740744        }
     
    747751
    748752        // check file type
     753        // TODO: add validating method to SyncAttachModel class
    749754        $img_type = wp_check_filetype($path);
    750755        $mime_type = $img_type['type'];
     
    770775                FROM `{$wpdb->posts}`
    771776                WHERE `post_name`=%s AND `post_type`='attachment'";
    772         $res = $wpdb->get_col($wpdb->prepare($sql, basename($path, '.' . $ext)));
     777        $res = $wpdb->get_col($stmt = $wpdb->prepare($sql, basename($path, '.' . $ext)));
    773778        $attachment_id = 0;
    774779        if (0 != count($res))
    775780            $attachment_id = intval($res[0]);
    776 
     781SyncDebug::log(__METHOD__.'():' . __LINE__ . ' id=' . $attachment_id . ' sql=' . $stmt . ' res=' . var_export($res, TRUE));
    777782        // TODO: need to assume error and only set to success(TRUE) when file successfully processed
    778783        $response->success(TRUE);
  • wpsitesynccontent/trunk/classes/apirequest.php

    r1560226 r1573030  
    3333    const ERROR_CONTENT_UPDATE_FAILED = 26;
    3434    const ERROR_CANNOT_WRITE_TOKEN = 27;
     35    const ERROR_UPLOAD_NO_CONTENT = 28;
    3536
    3637    const NOTICE_FILE_EXISTS = 1;
     
    186187            // examine the Target response's error codes and assign them to the local system's response object
    187188            // TODO: Use SyncResponse::copy() method
    188             if (isset($response->response->error_code))
    189                 $response->error_code($response->response->error_code);
    190             else if (isset($response->response->has_errors) && $response->response->has_errors)
     189            if (isset($response->response->error_code)) {
     190                $msg = NULL;
     191                if (!empty($response->response->error_data))
     192                    $msg = $response->response->error_data;
     193                $response->error_code($response->response->error_code, $msg);
     194            } else if (isset($response->response->has_errors) && $response->response->has_errors)
    191195                $response->error_code($response->response->error_code);
    192196
     
    196200                    $response->notice_code($code);
    197201            }
     202            // if Target reported a problem, make sure we send that back as our API result
     203            if (isset($response->response->has_errors) && $response->response->has_errors)
     204                $response->copy_json($response->response);
    198205
    199206//SyncDebug::log(__METHOD__.'():' . __LINE__ . ' response: ' . var_export($response, TRUE));
     
    299306    {
    300307SyncDebug::log(__METHOD__.'()');
    301         if ($this->_processing || $response->has_errors())
     308        if ($this->_processing || $response->has_errors()) {
     309SyncDebug::log(__METHOD__.'() queue already being processed');
    302310            return;
     311        }
    303312        $this->_processing = TRUE;
    304313
     314SyncDebug::log(__METHOD__.'():' . __LINE__ . ' queue has ' . count($this->_queue) . ' entries');
    305315        foreach ($this->_queue as $queue) {
    306316            $action = $queue['action'];
    307 SyncDebug::log(__METHOD__.'() found action ' . $action);
     317SyncDebug::log(__METHOD__.'():' . __LINE__ . ' found action ' . $action);
    308318            $res = $this->api($action, $queue['data'], $remote_args);
    309319            // exit processing if one of the queued API calls has an error
    310320            if ($res->has_errors()) {
    311                 $response->error_code($res->get_error_code());
     321SyncDebug::log(__METHOD__.'():' . __LINE__ . ' got an error from the Target: ' . var_export($res, TRUE));
     322                $response->error_code($res->get_error_code(), $res->get_error_data());
    312323                break;
    313324            }
     
    323334    private function _add_queue($action, $data)
    324335    {
     336SyncDebug::log(__METHOD__.'() adding "' . $action . '" to queue with ' . var_export($data, TRUE));
    325337        $this->_queue[] = array('action' => $action, 'data' => $data);
    326338    }
     
    465477    private function _auth(&$data)
    466478    {
    467 SyncDebug::log(__METHOD__.'() data: ' . var_export($data, TRUE));
     479//SyncDebug::log(__METHOD__.'() data: ' . var_export($data, TRUE));
    468480        // TODO: indicate error if target system not set up
    469481
    470482        // if no Target credentials provided, get them from the config
    471483        if (!isset($data['username']) /*|| !isset($data['password'])*/ || !isset($data['host'])) {
    472 SyncDebug::log(__METHOD__.'() using credentials from config');
     484//SyncDebug::log(__METHOD__.'() using credentials from config');
    473485            $source_model = new SyncSourcesModel();
    474486            $opts = new SyncOptions();
     
    498510        $auth_cookie = $this->_get_auth_cookie();
    499511        if (is_wp_error($auth_cookie)) {
    500 SyncDebug::log(__METHOD__.'() no authentication cookie data found');
     512//SyncDebug::log(__METHOD__.'() no authentication cookie data found');
    501513            return $auth_cookie;
    502514        }
    503515
    504 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' target data: ' . var_export($this->_target_data, TRUE));
     516//SyncDebug::log(__METHOD__.'():' . __LINE__ . ' target data: ' . var_export($this->_target_data, TRUE));
    505517        // check for site key and credentials
    506518        if (!isset($this->_target_data['site_key'])) {
     
    511523//          return new WP_Error(self::ERROR_MISSING_SITE_KEY);
    512524        }
    513 SyncDebug::log(__METHOD__.'() target username: ' . $this->_target_data['username']);
     525//SyncDebug::log(__METHOD__.'() target username: ' . $this->_target_data['username']);
    514526//SyncDebug::log(__METHOD__.'() target token: ' . (isset($this->_target_data['token']) ? $this->_target_data['token'] : ''));
    515 SyncDebug::log(__METHOD__.'() data token: ' . (isset($data['token']) ? $data['token'] : ''));
     527//SyncDebug::log(__METHOD__.'() data token: ' . (isset($data['token']) ? $data['token'] : ''));
    516528//SyncDebug::log(__METHOD__.'() data password: ' . $data['password']);
    517529        if (empty($this->_target_data['username']) ||
    518530            (empty($this->_target_data['token']) && empty($data['token']) && empty($data['password']))) {
    519 SyncDebug::log(__METHOD__.'() return ERROR_BAD_CREDENTIALS');
     531//SyncDebug::log(__METHOD__.'() return ERROR_BAD_CREDENTIALS');
    520532            return new WP_Error(self::ERROR_BAD_CREDENTIALS);
    521533        }
    522534
    523 SyncDebug::log(' ' . __LINE__ . ' - adding authentication data to array');
     535//SyncDebug::log(' ' . __LINE__ . ' - adding authentication data to array');
    524536        // add authentication to the data array
    525537        $data['auth'] = array(
     
    530542        // if password provided (first time authentication) then encrypt it
    531543        if (!empty($data['password'])) {
    532 SyncDebug::log(__METHOD__.'() encrypting password');
     544//SyncDebug::log(__METHOD__.'() encrypting password');
    533545            $auth = new SyncAuth();
    534546            $data['password'] = $auth->encode_password($data['password'], $data['host']);
    535547        }
    536 SyncDebug::log(__METHOD__.'() data: ' . var_export($data, TRUE));
     548//SyncDebug::log(__METHOD__.'() data: ' . var_export($data, TRUE));
    537549
    538550        return NULL;
    539551    }
    540552
     553    /**
     554     * Constructs the data associated with a post ID in preparation of a Push operation
     555     * @param int $post_id The post ID for the Content to be Pushed
     556     * @param array $data The data array to add Post Content information to
     557     * @return array The updated data array
     558     */
    541559    public function get_push_data($post_id, $data)
    542560    {
    543561        // build array of data that will be sent to Target via the API
    544562        $model = new SyncModel();
    545 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' post id=' . $post_id);
     563//SyncDebug::log(__METHOD__.'():' . __LINE__ . ' post id=' . $post_id);
    546564        $post_data = $model->build_sync_data($post_id);
    547 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' post data: ' . var_export($post_data, TRUE));
     565//SyncDebug::log(__METHOD__.'():' . __LINE__ . ' post data: ' . var_export($post_data, TRUE));
    548566
    549567        // Check if this is an update of a previously sync'd post
    550568        // TODO: use a better variable name than $sync_data
    551569        $sync_data = $model->get_sync_data($post_id, SyncOptions::get('site_key'));
    552 SyncDebug::log(__METHOD__.'() sync data: ' . var_export($sync_data, TRUE));
     570//SyncDebug::log(__METHOD__.'() sync data: ' . var_export($sync_data, TRUE));
    553571
    554572        if (NULL !== $sync_data)
     
    796814
    797815    /**
     816     * Sets the source domain name. Used by add-ons to set the domain used to validate media elements.
     817     * @param string $domain The domain name to set. Use domain only, no protocol or slashes
     818     */
     819    public function set_source_domain($domain)
     820    {
     821        // sanitize value to remove protocol and slashes
     822        $this->_source_domain = parse_url($domain, PHP_URL_HOST);
     823    }
     824
     825    /**
    798826     * Checks that image is unique and sends file information for image to Target
    799827     * @param string $url The full path to the image
     
    811839        }
    812840        $this->_sent_images[] = $url;
     841SyncDebug::log(__METHOD__.'():' . __LINE__ . ' added image #' . count($this->_sent_images) . ': ' . $url);
    813842
    814843        $src_parts = parse_url($url);
     844SyncDebug::log(__METHOD__.'():' . __LINE__ . ' url=' . $url . ' parts=' . var_export($src_parts, TRUE));       
    815845//      $path = substr($src_parts['path'], 1); // remove first "/"
    816846//SyncDebug::log(__METHOD__.'():' . __LINE__ . ' path=' . $path);
     
    821851
    822852        // return data array
    823 SyncDebug::log(__METHOD__.'() sending image ' . $path);
     853SyncDebug::log(__METHOD__.'():' . __LINE__ . ' sending image ' . $path);
     854//SyncDebug::log(__METHOD__.'() src_parts[host]=' . $src_parts['host'] . ' source_domain=' . $this->_source_domain);
    824855        if ($src_parts['host'] === $this->_source_domain &&
    825             is_wp_error($this->upload_media($post_id, $path, NULL, $thumbnail_id == $post_id, $attach_id)))
     856            is_wp_error($this->upload_media($post_id, $path, NULL, $thumbnail_id == $post_id, $attach_id))) {
     857SyncDebug::log(__METHOD__.'():' . __LINE__ . ' returning FALSE');
    826858            return FALSE;
     859        }
    827860
    828861        return TRUE;
     
    910943        case self::ERROR_CONTENT_UPDATE_FAILED: $error = __('Content update on Target failed.', 'wpsitesynccontent'); break;
    911944        case self::ERROR_CANNOT_WRITE_TOKEN:    $error = __('Cannot write authentication token.', 'wpsitesynccontent'); break;
     945        case self::ERROR_UPLOAD_NO_CONTENT:     $error = __('Attachment upload failed. No content found; is there a broken link?', 'wpsitesynccontent'); break;
    912946
    913947        default:
  • wpsitesynccontent/trunk/classes/apiresponse.php

    r1560226 r1573030  
    7272    {
    7373        $this->error_code = $response->error_code;
     74        $this->error_data = $response->error_data;
    7475        $this->notice_codes = $response->notice_codes;
    7576        $this->result_codes = $response->result_codes;
     
    7778        foreach ($response->data as $key => $data) {
    7879            $this->data[$key] = $data;
     80        }
     81    }
     82
     83    /**
     84     * Used to copy the contens of a JSON encoded instance of a response instance into the current instance
     85     * @param object $json_data The JSON object
     86     */
     87    public function copy_json($json_data)
     88    {
     89SyncDebug::log(__METHOD__.'() ' . var_export($json_data, TRUE));
     90        if (isset($json_data->error_code))
     91            $this->error_code = $json_data->error_code;
     92        if (isset($json_data->error_data))
     93            $this->error_data = $json_data->error_data;
     94        if (isset($json_data->notice_codes))
     95            $this->notice_codes = $json_data->notice_codes;
     96        if (isset($json_data->result_codes))
     97            $this->result_codes = $json_data->result_codes;
     98        if (isset($json_data->notices))
     99            $this->notices = $json_data->notices;
     100        if (isset($json_data->data)) {
     101            foreach ($json_data->data as $key => $data) {
     102                $this->data[$key] = $data;
     103            }
    79104        }
    80105    }
     
    143168
    144169    /**
     170     * Gets any error data stored with the error code.
     171     * @return string|NULL The error data or NULL if no data associated with the error code.
     172     */
     173    public function get_error_data()
     174    {
     175        return $this->error_data;
     176    }
     177
     178    /**
    145179     * Adds an notification message to the 'notices.' element
    146180     * @param string $sMsg The notice string to return to the user
     
    161195    }
    162196
     197    /**
     198     * Sets the result code to be returned to the user
     199     * @param int $code The result code to be sent to the user
     200     */
    163201    public function result_code($code)
    164202    {
  • wpsitesynccontent/trunk/classes/attachmodel.php

    r1446190 r1573030  
    33class SyncAttachModel
    44{
    5     public function search_by_guid($guid)
     5    public $_sizes = NULL;
     6
     7    /**
     8     * Searches for attachment resources by GUID
     9     * @param string $guid The GUIS, or URL used to identify the resource
     10     * @param boolean $extended_search Whether or not to perform an extended search
     11     * @return NULL|array The found resource or NULL if no resources found
     12     */
     13    public function search_by_guid($guid, $extended_search = FALSE)
    614    {
    715        global $wpdb;
     
    1422SyncDebug::log(__METHOD__.'() sql=' . $query);
    1523SyncDebug::log(' - res=' . var_export($res, TRUE));
     24
     25        // check if not found and an extended search has been requested
     26        if (0 === count($res) && $extended_search) {
     27SyncDebug::log(__METHOD__.'():' . __LINE__ . ' performing extended search for ' . $guid);
     28            $this->get_image_sizes();
     29SyncDebug::log(' - image sizes: ' . var_export($this->_sizes, TRUE));
     30            foreach ($this->_sizes as $img_size) {
     31                $dims = '-' . $img_size . '.';
     32                // check if there's a known image size suffix in the file name
     33                if (FALSE !== strpos($guid, $dims)) {
     34SyncDebug::log(__METHOD__.'():' . __LINE__ . ' found image match for size ' . $img_size);
     35                    $img_url = str_replace($dims, '.', $guid);
     36SyncDebug::log(__METHOD__.'():' . __LINE__ . ' searching for ' . $img_url);
     37                    $res = $this->search_by_guid($img_url, FALSE);
     38                    if (0 !== count($res)) {
     39                        $res[0]->orig_guid = $guid;
     40SyncDebug::log(__METHOD__.'():' . __LINE__ . ' found a matching image: ' . $img_url);
     41                        return $res;            // set this for the loop below
     42                    }
     43                }
     44            }
     45
     46            // no image found with the known image sizes
     47            $pos = strrpos($guid, '-');
     48            if (FALSE !== $pos) {
     49                $ext = strpos($guid, '.', $pos);
     50                if (FALSE !== $ext) {
     51                    $img_url = substr($guid, 0, $pos) . substr($guid, $ext);
     52SyncDebug::log(__METHOD__.'():' . __LINE__ . ' img=' . $img_url);
     53                    $res = $this->search_by_guid($img_url, FALSE);
     54                    if (0 !== count($res))
     55                        $res[0]->orig_guid = $guid;
     56                }
     57            }
     58        }
    1659        return $res;
     60    }
     61
     62    /**
     63     * Builds a list of all the images sizes known to WP
     64     * @return array The list of registered image sizes in the form {width}x{height}
     65     */
     66    public function get_image_sizes()
     67    {
     68        if (NULL === $this->_sizes) {
     69            $this->_sizes = array();
     70            global $_wp_additional_image_sizes;
     71
     72            // start with the built-in image sizes
     73            $sizes = get_intermediate_image_sizes();
     74            foreach ($sizes as $size) {
     75SyncDebug::log(__METHOD__.'():' . __LINE__ . ' found size: ' . var_export($size, TRUE));
     76                if (in_array($size, array('thumbnail', 'medium', 'medium_large', 'large'))) {
     77                    $wid = get_option("{$size}_size_w");
     78                    $hgt = get_option("{$size}_size_h");
     79                    $this->_sizes[] = $wid . 'x' . $hgt;
     80                } else if (isset($_wp_additional_image_sizes[$size])) {
     81                    continue;           // skip if in the additional size list
     82//                  $sizes[ $_size ] = array(
     83//                      'width'  => $_wp_additional_image_sizes[ $_size ]['width'],
     84//                      'height' => $_wp_additional_image_sizes[ $_size ]['height'],
     85//                      'crop'   => $_wp_additional_image_sizes[ $_size ]['crop'],
     86//                  );
     87                } else {
     88SyncDebug::log(__METHOD__.'():' . __LINE__ . ' unrecognized image size: ' . var_export($size, TRUE));
     89                }
     90            }
     91
     92            // now go through the list of additional image sizes
     93            foreach ($_wp_additional_image_sizes as $img_size) {
     94                $size = $img_size['width'] . 'x' . $img_size['height'];
     95                $this->_sizes[] = $size;
     96            }
     97        }
     98
     99        return $this->_sizes;
     100    }
     101
     102    /**
     103     * Returns a list of all known image types and their sizes
     104     * @return array An associated array in the form [{name}] = ['width'=>150, 'height'=>150, 'crop'=>FALSE]
     105     */
     106    public function get_image_size_data()
     107    {
     108        $ret = array();
     109        global $_wp_additional_image_sizes;
     110
     111        // start with the built-in image sizes
     112        $sizes = get_intermediate_image_sizes();
     113        foreach ($sizes as $size) {
     114SyncDebug::log(__METHOD__.'():' . __LINE__ . ' found size: ' . var_export($size, TRUE));
     115            if (in_array($size, array('thumbnail', 'medium', 'medium_large', 'large'))) {
     116                $wid = get_option("{$size}_size_w");
     117                $hgt = get_option("{$size}_size_h");
     118                $crp = (bool) get_option("{$size}_crop");
     119            } else if (isset($_wp_additional_image_sizes[$size])) {
     120                continue;           // skip if in the additional size list
     121            } else {
     122SyncDebug::log(__METHOD__.'():' . __LINE__ . ' unrecognized image size: ' . var_export($size, TRUE));
     123                continue;
     124            }
     125            $ret[$size] = array(
     126                'width' => $wid,
     127                'height' => $hgt,
     128                'crop' => $crp,
     129            );
     130        }
     131
     132        // now go through the list of additional image sizes
     133        foreach ($_wp_additional_image_sizes as $size => $img_data) {
     134            if (!isset($ret[$size]))
     135                $ret[$size] = $img_data;
     136        }
     137
     138        return $ret;
    17139    }
    18140}
  • wpsitesynccontent/trunk/readme.txt

    r1560226 r1573030  
    111111
    112112== Changelog ==
     113= 1.3.1 - Jan 11, 2017 =
     114* Fix: add placeholder file to force creation of languages/ directory.
     115* Enhancement: Additional changes in preparation for WPSiteSync for BeaverBuilder.
     116* Enhancement: Better error messages when empty or missing post content is encountered.
     117* Enhancement: Improved Media Library image lookup for use by BeaverBuilder add-on.
     118* Enhancement: Added pre processing hook for use by ACF add-on.
     119
    113120= 1.3 - Dec 22, 2016 =
    114121* fix: fix author assigned on revisions when Pushing Content to Target
  • wpsitesynccontent/trunk/wpsitesynccontent.php

    r1560226 r1573030  
    66Author: WPSiteSync
    77Author URI: http://wpsitesync.com
    8 Version: 1.3
     8Version: 1.3.1
    99Text Domain: wpsitesynccontent
    1010Domain path: /language
     
    2525    class WPSiteSyncContent
    2626    {
    27         const PLUGIN_VERSION = '1.3';
     27        const PLUGIN_VERSION = '1.3.1';
    2828        const PLUGIN_NAME = 'WPSiteSyncContent';
    2929
     
    170170        /**
    171171         * Return instance of licensing object
    172          * @return SyncLicensing
     172         * @return SyncLicensing instance of the licensing object
    173173         */
    174174        public function get_license()
    175175        {
     176            // this is just in case somebody calls this before the 'spectrom_sync_init' action is fired
     177            if (NULL === self::$_license)
     178                self::$_license = new SyncLicensing();
    176179            return self::$_license;
    177180        }
Note: See TracChangeset for help on using the changeset viewer.