Changeset 1492115
- Timestamp:
- 09/08/2016 12:17:51 AM (9 years ago)
- Location:
- wpsitesynccontent/trunk
- Files:
-
- 5 deleted
- 18 edited
-
assets/css/font-awesome.min.css (deleted)
-
assets/css/sync-admin.css (modified) (2 diffs)
-
assets/imgs/screenshot-sync.png (deleted)
-
assets/imgs/spectrom.png (deleted)
-
assets/imgs/spectrom_logo_plain.png (deleted)
-
assets/imgs/spectrom_small.png (deleted)
-
classes/admin.php (modified) (4 diffs)
-
classes/ajax.php (modified) (4 diffs)
-
classes/apicontroller.php (modified) (8 diffs)
-
classes/apimodel.php (modified) (6 diffs)
-
classes/apirequest.php (modified) (4 diffs)
-
classes/apiresponse.php (modified) (3 diffs)
-
classes/auth.php (modified) (1 diff)
-
classes/extensionsettings.php (modified) (1 diff)
-
classes/logmodel.php (modified) (1 diff)
-
classes/model.php (modified) (2 diffs)
-
classes/settings.php (modified) (15 diffs)
-
classes/sourcesmodel.php (modified) (9 diffs)
-
install/activate.php (modified) (1 diff)
-
install/deactivate.php (modified) (3 diffs)
-
readme.txt (modified) (2 diffs)
-
views/content_details.php (modified) (1 diff)
-
wpsitesynccontent.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wpsitesynccontent/trunk/assets/css/sync-admin.css
r1451657 r1492115 16 16 background-size: contain; /* 100px 82px; */ 17 17 vertical-align: top; 18 } 19 .notice #sync-logo { 20 margin-top: .5rem; 18 21 } 19 22 #spectrom_sync { … … 164 167 margin: 0 .7rem; 165 168 } 166 /* TODO: can be removed?? */167 /*.spectrom-sync-settings div.spectrom-mkt-right {168 float: right;169 display: inline-block;170 width: 300px;171 padding: 0 5px;172 margin: 25px 0 0 0;173 height: 100%;174 min-height: 100px;175 }176 .spectrom-sync-settings div.spectrom-mkt-right div.spectrom-logo {177 width: 100%;178 width: 260px;179 height: 150px;180 background-image: url('../imgs/spectrom.png');181 background-repeat: no-repeat;182 background-size: contain;183 background-position: center;184 } */185 169 186 170 .spectrom-sync-settings div.spectrom-page { -
wpsitesynccontent/trunk/classes/admin.php
r1451657 r1492115 59 59 60 60 wp_register_style('sync-admin', WPSiteSyncContent::get_asset('css/sync-admin.css'), array(), WPSiteSyncContent::PLUGIN_VERSION, 'all'); 61 wp_register_style('font-awesome', WPSiteSyncContent::get_asset('css/font-awesome.min.css'), array(), WPSiteSyncContent::PLUGIN_VERSION, 'all');62 61 63 62 $screen = get_current_screen(); … … 69 68 wp_enqueue_script('sync'); 70 69 71 $option_data = array('site_key' => WPSiteSyncContent::get_option('site_key'));70 $option_data = array('site_key' => SyncOptions::get('site_key')); 72 71 wp_localize_script('sync-settings', 'syncdata', $option_data); 73 72 … … 123 122 echo '<span>', __('Push content to Target: ', 'wpsitesynccontent'), '<br/>', 124 123 sprintf('<span title="%2$s"><b>%1$s</b></span>', 125 WPSiteSyncContent::get_option('host'),124 SyncOptions::get('host'), 126 125 esc_attr(__('The "Target" is the WordPress install that the Content will be pushed to.', 'wpsitesynccontent'))), 127 126 '</span>'; … … 263 262 } else if (0 !== $response_body->error_code) { 264 263 $msg = $api->error_code_to_string($response_body->error_code); 265 echo '<p>', sprintf(__('Error #%1$d: %2$s', 'wpsitesync -pull'), $response_body->error_code, $msg), '</p>';264 echo '<p>', sprintf(__('Error #%1$d: %2$s', 'wpsitesynccontent'), $response_body->error_code, $msg), '</p>'; 266 265 $pull_active = FALSE; 267 266 } -
wpsitesynccontent/trunk/classes/ajax.php
r1451657 r1492115 24 24 // also include the user name of the user on the Source site that is Pushing the Content 25 25 $current_user = wp_get_current_user(); 26 if (0 !== $current_user->ID) { 26 //SyncDebug::log(__METHOD__.'() current user=' . var_export($current_user, TRUE)); 27 if (NULL !== $current_user && 0 !== $current_user->ID) { 27 28 $data['username'] = $current_user->user_login; 28 29 $data['user_id'] = $current_user->ID; … … 36 37 public function dispatch() 37 38 { 38 // TODO: add authentication checking: must be logged in, an 'Author' role or higher, check nonce39 40 39 $operation = $this->post('operation'); 41 40 SyncDebug::log(__METHOD__."('{$operation}')"); 42 $response = new SyncApiResponse(); 41 $response = new SyncApiResponse(TRUE); 42 43 // perform authentication checking: must be logged in, an 'Author' role or higher 44 if (!is_user_logged_in()) { 45 $response->error_code(SyncApiRequest::ERROR_SESSION_EXPIRED, $operation); 46 $response->send(); 47 } 48 if (!current_user_can('publish_posts')) { 49 $response->error_code(SyncApiRequest::ERROR_NO_PERMISSION, $operation); 50 $response->send(); 51 } 52 // TODO: check nonce 43 53 44 54 switch ($operation) { … … 74 84 if (FALSE === apply_filters('spectrom_sync_ajax_operation', FALSE, $operation, $response)) { 75 85 // No method found, fallback to error message. 76 $response->success(FALSE);86 // $response->success(FALSE); 77 87 $response->error_code(SyncApiRequest::ERROR_EXTENSION_MISSING, $operation); 78 88 // TODO: error_code() data parameter … … 95 105 $input = new SyncInput(); 96 106 $settings = array_merge( 97 get_option(SyncOptions::OPTION_NAME),107 SyncOptions::get_all(), // get_option(SyncOptions::OPTION_NAME), 98 108 $input->post(SyncOptions::OPTION_NAME) 99 109 ); -
wpsitesynccontent/trunk/classes/apicontroller.php
r1451657 r1492115 36 36 public function __construct($args) 37 37 { 38 //SyncDebug::log(__METHOD__.'() args=' . var_export($args, TRUE)); 38 39 self::$_instance = $this; 39 40 $this->args = $args; … … 47 48 $response = $args['response']; 48 49 else 49 $response = new SyncApiResponse( );50 $response = new SyncApiResponse(TRUE); 50 51 51 52 if (isset($args['site_key'])) … … 171 172 if (NULL === $this->_headers) { 172 173 if (!function_exists('apache_request_headers')) { 173 $this->_headers = $this->_get_request_headers(); 174 //SyncDebug::log(__METHOD__.'() using _get_request_headers()'); 175 $hdrs = $this->_get_request_headers(); 174 176 } else { 175 $this->_headers = apache_request_headers(); 176 } 177 SyncDebug::log(__METHOD__.'() read request headers: ' . var_export($this->_headers, TRUE)); 177 //SyncDebug::log(__METHOD__.'() using apache_request_headers()'); 178 $hdrs = apache_request_headers(); 179 } 180 $this->_headers = array(); 181 foreach ($hdrs as $key => $value) { 182 $this->_headers[strtolower($key)] = $value; 183 } 184 //SyncDebug::log(__METHOD__.'() read request headers: ' . var_export($this->_headers, TRUE)); 178 185 } 179 186 … … 212 219 } 213 220 } 221 //SyncDebug::log(__METHOD__.'() headers: ' . var_export($arh, TRUE)); 214 222 return $arh; 215 223 } … … 223 231 SyncDebug::log(__METHOD__.'()'); 224 232 SyncDebug::log(' post data: ' . var_export($_POST, TRUE)); 225 SyncDebug::log(' request data: ' . var_export($_REQUEST, TRUE));233 //SyncDebug::log(' request data: ' . var_export($_REQUEST, TRUE)); 226 234 // TODO: need to assume failure, not success - then set to success when successful 227 235 $response->success(TRUE); … … 235 243 //SyncDebug::log(__METHOD__.'():' . __LINE__ . ' - post_data=' . var_export($post_data, TRUE)); 236 244 237 $this->source_post_id = intval($post_data['ID']); 245 $this->source_post_id = abs($post_data['ID']); 246 // if (0 === $this->source_post_id && isset($post_data['post_id'])) 247 // $this->source_post_id = abs($post_data['post_id']); 238 248 SyncDebug::log('- syncing post data Source ID#'. $this->source_post_id . ' - "' . $post_data['post_title'] . '"'); 239 249 … … 313 323 wp_update_post($post_data); // ;here; 314 324 } else { 315 $response->error_code(SyncApiRe sponse::ERROR_NO_PERMISSION);325 $response->error_code(SyncApiRequest::ERROR_NO_PERMISSION); 316 326 $response->send(); 317 327 } … … 324 334 $target_post_id = wp_insert_post($new_post_data); // ;here; 325 335 } else { 326 $response->error_code(SyncApiRe sponse::ERROR_NO_PERMISSION);336 $response->error_code(SyncApiRequest::ERROR_NO_PERMISSION); 327 337 $response->send(); 328 338 } 329 339 } 330 340 $this->post_id = $target_post_id; 341 SyncDebug::log(__METHOD__ . '():' . __LINE__. ' performing sync'); 331 342 332 343 // save the source and target post information for later reference -
wpsitesynccontent/trunk/classes/apimodel.php
r1399948 r1492115 28 28 return; 29 29 30 SyncDebug::log(__METHOD__.'() request uri=' . $_SERVER['REQUEST_URI']);30 //SyncDebug::log(__METHOD__.'() request uri=' . $_SERVER['REQUEST_URI']); 31 31 add_filter('request', array(&$this, 'set_query_var')); 32 32 // hook in late to allow other plugins to operate earlier … … 76 76 public function set_query_var(array $vars) 77 77 { 78 //SyncDebug::log(__METHOD__.'() vars=' . var_export($vars, TRUE)); 78 79 if (!empty($vars[$this->options['name']])) 79 80 return $vars; … … 104 105 105 106 $parts = explode('/', $api); 106 SyncDebug::log(__METHOD__.'() parts=' . var_export($parts, TRUE));107 //SyncDebug::log(__METHOD__.'() parts=' . var_export($parts, TRUE)); 107 108 108 109 // spectrom - using json only for now … … 113 114 // TODO: this can be simplified. assume only Sync callback are made, which will always be array type 114 115 if (is_string($callback)) { 116 //SyncDebug::log(__METHOD__.'() string callback'); 115 117 call_user_func($callback, $values); 116 118 } else if (is_array($callback)) { 119 //SyncDebug::log(__METHOD__.'() array callback'); 117 120 if ('__construct' === $callback[1]) 118 121 new $callback[0]($values); … … 120 123 call_user_func($callback, $values); 121 124 } else { 125 //SyncDebug::log(__METHOD__.'() no callback'); 122 126 // TODO: use exception 123 127 trigger_error( … … 128 132 129 133 // WP will render main page if we leave this out 134 // TODO: shouldn't be needed. SyncApiController calls die() when sending results 130 135 exit; 131 136 } -
wpsitesynccontent/trunk/classes/apirequest.php
r1451657 r1492115 138 138 $remote_args['headers'][self::HEADER_WP_VERSION] = $wp_version; 139 139 $remote_args['headers'][self::HEADER_SOURCE] = site_url(); 140 $remote_args['headers'][self::HEADER_SITE_KEY] = WPSiteSyncContent::get_option('site_key'); // $model->generate_site_key(); 140 // $remote_args['headers'][self::HEADER_SITE_KEY] = WPSiteSyncContent::get_option('site_key'); // $model->generate_site_key(); 141 $remote_args['headers'][self::HEADER_SITE_KEY] = SyncOptions::get('site_key'); // $model->generate_site_key(); 142 //SyncDebug::log(__METHOD__.'() plugin sitekey=' . WPSiteSyncContent::get_option('site_key') . ' // option sitekey=' . SyncOptions::get('site_key')); 141 143 142 144 // send data where it's going 143 $url = $this->host . '/' . WPSiteSyncContent::API_ENDPOINT . '?action=' . $action; 145 // $url = $this->host . '/' . WPSiteSyncContent::API_ENDPOINT . '?action=' . $action; 146 $url = $this->host . '?pagename=' . WPSiteSyncContent::API_ENDPOINT . '&action=' . $action; 144 147 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' sending API request to ' . $url, TRUE); 145 148 SyncDebug::log(' sending data array: ' . SyncDebug::arr_dump($remote_args)); 146 149 150 $remote_args = apply_filters('spectrom_sync_api_arguments', $remote_args, $action); 151 147 152 $request = wp_remote_post($url, $remote_args); 148 153 if (is_wp_error($request)) { 149 //SyncDebug::log(__METHOD__.'():' . __LINE__ . ' error in wp_remote_post(): ' . var_export($request, TRUE));154 SyncDebug::log(__METHOD__.'():' . __LINE__ . ' error in wp_remote_post(): ' . var_export($request, TRUE)); 150 155 // handle error 151 156 $response->error_code(self::ERROR_REMOTE_REQUEST_FAILED, $request->get_error_message()); … … 214 219 update_user_meta($this->_user_id, 'spectrom_site_target_uid', $response->response->data->user_id); 215 220 216 SyncDebug::log(__METHOD__.'() saving auth token ' . var_export($response, TRUE));221 SyncDebug::log(__METHOD__.'() saving auth token'); 217 222 // store the returned token for later authentication uses 218 223 $sources_model = new SyncSourcesModel(); … … 396 401 // the success or error message will be returned as part of the response for the AJAX request and displayed just 397 402 // underneath the ( Sync ) button within the MetaBox. 398 $response = new SyncApiResponse();403 // $response = new SyncApiResponse(); 399 404 if (!is_wp_error($result)) { 400 405 // PARSE IMAGES FROM SOURCE ONLY … … 402 407 $response->success(TRUE); 403 408 $response->notice_code(SyncApiRequest::NOTICE_CONTENT_SYNCD); 404 // $response->notice(__('Content SYNCd.', 'wpsitesynccontent'));405 409 $response->set('post_id', $result->data->post_id); 406 410 -
wpsitesynccontent/trunk/classes/apiresponse.php
r1451657 r1492115 28 28 public $data = array(); 29 29 30 private $_headers_sent = FALSE; // TRUE when headers are sent on instantiation 31 private $_capture = FALSE; // TRUE when capturing output 32 30 33 // constructor 31 public function __construct() 32 { 34 public function __construct($send_headers = FALSE) 35 { 36 if ($send_headers) { 37 $this->_send_headers(TRUE); 38 } 39 33 40 if (!is_user_logged_in()) 34 41 $this->session_timeout = 1; … … 170 177 return; 171 178 172 global $wp_version; 173 header(self::HEADER_SYNC_VERSION . ': ' . WPSiteSyncContent::PLUGIN_VERSION); // send this header so sources will know that they're talking to SYNC 174 header(self::HEADER_WP_VERSION . ': ' . $wp_version); // send this header so sources will know that they're talking to WP 175 header('Content-Type: application/json'); 179 $this->_send_headers(); 176 180 177 181 if ($this->has_errors()) { … … 185 189 if ($exit) 186 190 exit(0); // stop script 191 } 192 193 /** 194 * Send the HTTP headers for the JSON response 195 */ 196 private function _send_headers($capture = FALSE) 197 { 198 if (!$this->_headers_sent) { 199 global $wp_version; 200 201 header(self::HEADER_SYNC_VERSION . ': ' . WPSiteSyncContent::PLUGIN_VERSION); // send this header so sources will know that they're talking to SYNC 202 header(self::HEADER_WP_VERSION . ': ' . $wp_version); // send this header so sources will know that they're talking to WP 203 header('Content-Type: application/json'); 204 $this->_headers_sent = TRUE; 205 206 if ($this->_capture) { 207 // headers have already been sent and ob_start() has been called. 208 // clear the output buffer so our JSON data can be sent 209 ob_get_clean(); 210 } 211 if ($capture) { 212 ob_start(); 213 $this->_capture = TRUE; 214 } 215 } 187 216 } 188 217 -
wpsitesynccontent/trunk/classes/auth.php
r1451657 r1492115 36 36 //SyncDebug::log(__METHOD__.'() authenticating via token'); 37 37 //SyncDebug::log(' - source: ' . $source . ' site_key: ' . $site_key . ' user: ' . $username . ' token: ' . $token); 38 ### $site_key = ''; ###39 38 $user_signon = $source_model->check_auth($source, $site_key, $username, $token); 40 39 //SyncDebug::log(__METHOD__.'() source->check_auth() returned ' . var_export($user_signon, TRUE)); -
wpsitesynccontent/trunk/classes/extensionsettings.php
r1451657 r1492115 4 4 { 5 5 const FEED_URL = 'https://wpsitesync.com/downloads/feed/'; 6 const TRANSIENT_KEY = 'wpsitesync_extension_list'; 7 const TRANSIENT_TTL = 86400; // 24 hours 8 9 private static $_instance = NULL; 10 11 private function __construct() 12 { 13 } 14 15 public static function get_instance() 16 { 17 if (NULL === self::$_instance) 18 self::$_instance = new self(); 19 return self::$_instance; 20 } 6 21 7 22 public function init_settings() 8 23 { 24 // no settings fields to display so nothing to initialize 25 } 26 27 public function show_settings() 28 { 29 echo '<h3>Available Extensions:</h3>'; 30 31 $extens = $this->_get_extension_data(); 32 if (FALSE === $extens) { 33 echo '<p><b>Error:</b> Temporarily unable to read data from https://wpsitesync.com</p>'; 34 } else { 35 $count = 0; 36 foreach ($extens as $ext_info) { 37 // image is 491x309 38 echo '<div class="sync-extension">'; 39 echo '<h3>', esc_html($ext_info['title']), ' ', $ext_info['price'], '</h3>'; 40 echo '</div>'; 41 ++$count; 42 } 43 echo '<p>', sprintf(__('%1$d extensions found.', 'wpsitesynccontent')), '</p>'; 44 } 45 } 46 47 private function _get_extension_data() 48 { 49 $data = get_transient(self::TRANSIENT_KEY); 50 if (FALSE === $data) { 51 $url = self::FEED_URL; 52 $url = 'http://wpsitesync.dev/downloadfeed/'; 53 $response = wp_remote_get($url); 54 //echo 'reading data from ', $url, '<br/>'; 55 if (is_wp_error($response)) { 56 return FALSE; 57 die('error'); 58 } else { 59 $data = wp_remote_retrieve_body($response); 60 } 61 // set_transient(self::TRANSIENT_KEY, $data, self::TRANSIENT_TTL); 62 } 63 64 //echo '<pre>', $data, '</pre>'; 65 //echo 'read ', strlen($data), ' bytes of data<br/>'; 66 67 $ret = array(); 68 $info = array(); 69 70 $xmldoc = simplexml_load_string($data); 71 //echo 'found ', count($xmldoc->channel->item), ' items<br/>'; 72 foreach ($xmldoc->channel->item as $item) { 73 //echo 'title=', $item->title, '<br/>'; 74 $info = array( 75 'title' => $item->title, 76 'link' => $item->link, 77 'price' => $item->price, 78 'saleprice' => isset($item->saleprice) ? $item->saleprice : '', 79 'image' => isset($item->image) ? $item->image : '', 80 ); 81 $ret[] = $info; 82 } 83 //echo '<pre>', var_export($xmldoc, TRUE), '</pre>'; 84 return $ret; 85 #### 86 $parser = xml_parser_create(); 87 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 88 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 89 xml_parse_into_struct($parser, $data, $values, $tags); 90 xml_parser_free($parser); 91 92 foreach ($tags as $key => $val) { 93 echo $key, ' = ', esc_html($val), '<br/>'; 94 if ('item' === $key) { 95 echo var_export($val, TRUE), '<br/>'; 96 foreach ($val as $idx) { 97 echo 'value=', var_export($values[$idx], TRUE), '<br/>'; 98 } 99 } 100 } 101 102 return $ret; 103 #### 104 105 106 // parse the XML data 107 $xml = new DOMDocument(); 108 $xml->loadHTML($data); 109 $items = $xml->getElementsByTagName('item'); 110 111 // loop through each <item> tag and return them 112 $nodes = $xml->documentElement; 113 $count = 0; 114 foreach ($nodes->childNodes as $item) { 115 echo $item->nodeName, ' = ', esc_html($item->nodeValue), '<br/>'; 116 ++$count; 117 } 118 echo '<p>found ', $count, ' nodes<br/>'; 119 120 /* for ($i = $items->length - 1; $i >= 0; $i--) { 121 $node = $items->item($i); 122 $title = $node->get('title'); 123 echo $title, '<br/>'; 124 if (FALSE !== stripos($title, 'wpsitesync')) { 125 $ret[] = array( 126 'title' => $title, 127 ); 128 } 129 } */ 130 131 return $ret; 9 132 } 10 133 } -
wpsitesynccontent/trunk/classes/logmodel.php
r1421284 r1492115 40 40 if (!isset($data['source_user'])) 41 41 $data['source_user'] = 0; 42 if (!isset($data['post_title'])) 43 $data['post_title'] = ''; 42 44 43 45 return $wpdb->insert($this->_log_table, $data); -
wpsitesynccontent/trunk/classes/model.php
r1446190 r1492115 182 182 'p' => $post_id, 183 183 'post_type' => apply_filters('spectrom_sync_allowed_post_types', array('post', 'page')), 184 'post_status' => array('publish', 'pending', 'draft', 'future', 'private', 'trash'), 184 185 'posts_per_page' => 1, 185 186 ); … … 188 189 // TODO: add failure checking 189 190 SyncDebug::log(__METHOD__.'() post id=' . $post_id); 191 192 if (0 === $query->found_posts) 193 return $push_data; 190 194 191 195 $push_data['post_data'] = (array) $query->posts[0]; -
wpsitesynccontent/trunk/classes/settings.php
r1451657 r1492115 11 11 private static $_instance = NULL; 12 12 13 private $_options = array();13 // private $_options = array(); 14 14 private $_tab = ''; 15 15 … … 22 22 add_action('load-settings_page_sync', array(&$this, 'contextual_help')); 23 23 24 $this->_options = SyncOptions::get_all();24 // $this->_options = SyncOptions::get_all(); 25 25 } 26 26 … … 41 41 * @param string $default (optional) The default value to be returned 42 42 * @return mixed The value if it exists, else $default 43 */ 44 public function get_option($option, $default = NULL) 45 { 43 * @deprecated 44 */ 45 /* public function get_option($option, $default = NULL) 46 { 47 // TODO: remove this method 46 48 return isset($this->_options[$option]) ? $this->_options[$option] : $default; 47 } 49 } */ 48 50 49 51 /** … … 83 85 //SyncDebug::log(__METHOD__.'() tab=' . $this->_tab); 84 86 wp_enqueue_script('sync-settings'); 85 wp_enqueue_style('font-awesome');86 87 87 88 do_action('spectrom_sync_before_render_settings'); … … 138 139 139 140 case 'extensions': 141 // $ext = SyncExtensionSettings::get_instance(); 142 // $ext->show_settings(); 140 143 break; 141 144 … … 154 157 submit_button(); 155 158 echo '</form>'; 156 echo '<p>', __('WPSiteSync for Content Site key: ', 'wpsitesynccontent'), '<b>', $this->get_option('site_key'), '</b></p>';159 echo '<p>', __('WPSiteSync for Content Site key: ', 'wpsitesynccontent'), '<b>', SyncOptions::get('site_key'), '</b></p>'; 157 160 echo '</div><!-- #tab_container -->'; 158 161 } … … 174 177 break; 175 178 case 'extensions': 179 // $ext = SyncExtensionSettings::get_instance(); 180 // $ext->init_settings(); 176 181 break; 177 182 case 'license': … … 192 197 { 193 198 //SyncDebug::log(__METHOD__.'() tab=' . $this->_tab); 194 $option_values = $this->_options;199 $option_values = SyncOptions::get_all(); // $this->_options; 195 200 196 201 $default_values = apply_filters('spectrom_sync_default_settings', … … 251 256 'size' => '50', 252 257 'value' => $data['username'], 253 'description' => __('Username on Target to authenticate API calls with. Must be able to create Content with this username.', 'wpsitesynccontent'),258 'description' => __('Username on Target for authentication. Must be able to create Content with this username.', 'wpsitesynccontent'), 254 259 ) 255 260 ); … … 459 464 460 465 //SyncDebug::log(__METHOD__.'() values=' . var_export($values, TRUE)); 461 $settings = $this->_options;466 $settings = SyncOptions::get_all(); // $this->_options; 462 467 //SyncDebug::log(__METHOD__.'() settings: ' . var_export($settings, TRUE)); 463 468 … … 466 471 467 472 $missing_error = FALSE; 473 $re_auth = FALSE; 468 474 foreach ($values as $key => $value) { 469 475 //SyncDebug::log(" key={$key} value=[{$value}]"); 470 476 if (empty($values[$key]) && 'password' === $key) { 471 477 // ignore this so that passwords are not required on every settings update 472 // $out[$key] = $settings[$key];473 478 } else { 474 if ('host' === $key && FALSE === filter_var($value, FILTER_VALIDATE_URL)) { 475 add_settings_error('sync_options_group', 'invalid-url', __('Invalid URL.', 'wpsitesynccontent')); 476 $out[$key] = $settings[$key]; 479 if ('host' === $key) { 480 if (FALSE === $this->_is_valid_url($value)) { 481 add_settings_error('sync_options_group', 'invalid-url', __('Invalid URL.', 'wpsitesynccontent')); 482 $out[$key] = $settings[$key]; 483 } else { 484 $out[$key] = $value; 485 if ($out[$key] !== $settings[$key]) 486 $re_auth = TRUE; 487 } 477 488 } else if (0 === strlen(trim($value))) { 478 489 if (!$missing_error) { … … 487 498 } else { 488 499 $out[$key] = $value; 500 if ('username' === $key && $out[$key] !== $settings[$key]) 501 $re_auth = TRUE; 489 502 } 490 503 } … … 492 505 //SyncDebug::log(__METHOD__.'() output array: ' . var_export($out, TRUE)); 493 506 494 // authenticate if there was a password provided 495 if (!empty($out['password'])) { 507 // authenticate if there was a password provided or the host/username are different 508 if ($re_auth && empty($out['password'])) { 509 add_settings_error('sync_options_group', 'no-password', __('Changed Host Name of Target or Username but did not provide password.', 'wpsitesynccontent')); 510 $re_auth = FALSE; 511 } 512 if (!empty($out['password']) || $re_auth) { 496 513 $out['auth'] = 0; 497 514 … … 524 541 525 542 /** 543 * Performs validation on URL. Note: filter_var() checks for schema but does not validate it. Also allows trailing '.' characters 544 * @param string $url The URL to validate 545 * @return boolean TRUE on successful validation; FALSE on failure 546 */ 547 private function _is_valid_url($url) 548 { 549 $res = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED); 550 if (FALSE === $res) 551 return FALSE; 552 553 if (0 !== stripos($url, 'http://') && 0 !== stripos($url, 'https://')) 554 return FALSE; 555 else if ('.' === substr($url, -1)) 556 return FALSE; 557 558 return TRUE; 559 } 560 561 /** 526 562 * Callback for adding contextual help to Sync Settings page 527 563 */ … … 535 571 '<p><strong>' . __('For more information:', 'wpsitesynccontent') . '</strong></p>' . 536 572 '<p>' . sprintf(__('Visit the <a href="%s" target="_blank">documentation</a> on the WPSiteSync for Content website.', 'wpsitesynccontent'), 537 esc_url('http s://wpsitesync.com/documentation/')) . '</p>' .573 esc_url('http://wpsitesync.com/knowledgebase/use-wpsitesync-content/')) . '</p>' . 538 574 '<p>' . sprintf( 539 575 __('<a href="%s" target="_blank">Post an issue</a> on <a href="%s" target="_blank">GitHub</a>.', 'wpsitesynccontent'), 540 esc_url('https://github.com/ServerPress/ sync/issues'),541 esc_url('https://github.com/ServerPress/ sync/')) .576 esc_url('https://github.com/ServerPress/wpsitesync/issues'), 577 esc_url('https://github.com/ServerPress/wpsitesync')) . 542 578 '</p>' 543 579 ); -
wpsitesynccontent/trunk/classes/sourcesmodel.php
r1457902 r1492115 36 36 * @param string $name The username to authenticate 37 37 * @param string $token The user's Token to authenticate against 38 * @return object The found row if the user is authenticated; otherwise NULL38 * @return WP_User|WP_Error The user associated with the found row if the user is authenticated; otherwise WP_Error 39 39 */ 40 40 public function check_auth($source, $site_key, $name, $token) … … 69 69 * @return object The Source site's information that matches the $domain and $site_key; or NULL if not found 70 70 */ 71 public function find_source($source, $site_key )71 public function find_source($source, $site_key, $auth_name = NULL) 72 72 { 73 73 global $wpdb; 74 74 $source = $this->_fix_domain($source); 75 76 if (NULL !== $auth_name) { 77 $sql = "SELECT * 78 FROM `{$this->_sources_table}` 79 WHERE `site_key`=%s AND `domain`=%s AND `auth_name`=%s"; 80 $res = $wpdb->get_row($exec = $wpdb->prepare($sql, $site_key, $source, $auth_name)); 81 //SyncDebug::log(__METHOD__.'():' . __LINE__ . ' sql=' . $exec . ' res=' . var_export($res, TRUE)); 82 if (NULL !== $res) 83 return $res; 84 } 75 85 76 86 $sql = "SELECT * … … 90 100 { 91 101 global $wpdb; 92 //SyncDebug::log(__METHOD__.'() data=' . var_export($data, TRUE) );102 //SyncDebug::log(__METHOD__.'() data=' . var_export($data, TRUE), TRUE); 93 103 $token = ''; 94 104 $data['domain'] = $this->_fix_domain($data['domain']); … … 111 121 //SyncDebug::log(__METHOD__.'() - existing'); 112 122 // update existing source token 123 if (empty($data['token'])) 124 $data['token'] = $this->_make_token(); 113 125 if ($row->token !== $data['token']) 114 126 $wpdb->update($this->_sources_table, array('token' => $data['token']), array('id' => $row->id)); 115 $token = $data['token ;']; // $row->token127 $token = $data['token']; // $row->token 116 128 } 117 129 } else { … … 119 131 //SyncDebug::log(__METHOD__.'() - adding source'); 120 132 // first, check to see if the domain already exists 121 $row = $this->find_source($data['domain'], $data['site_key'] );122 if (NULL === $row ) {133 $row = $this->find_source($data['domain'], $data['site_key'], $data['auth_name']); 134 if (NULL === $row || $row->auth_name !== $data['auth_name']) { 123 135 //SyncDebug::log(__METHOD__.'() - adding ' . __LINE__); 124 136 // no record found, add it … … 128 140 // update existing source 129 141 //SyncDebug::log(__METHOD__.'() updating id ' . $row->id . ' with token '); // . $data['token']); 130 if ($row->token !== $data['token']) 142 if (empty($data['token']) || $row->token !== $data['token']) { 143 // TODO: ensure no duplicate tokens 144 $data['token'] = $this->_make_token(); 131 145 $wpdb->update($this->_sources_table, array('token' => $data['token']), array('id' => $row->id)); 146 } 132 147 $token = $data['token']; // $row->token 133 148 } 134 149 } 150 //$this->_show_sources(); 135 151 //SyncDebug::log(__METHOD__.'() last query: ' . $wpdb->last_query); 136 152 //SyncDebug::log(__METHOD__.'() returning token ' . $token); … … 139 155 140 156 /** 157 * Method used for debugging 158 */ 159 /* private function _show_sources() 160 { 161 global $wpdb; 162 163 $sql = "SELECT * 164 FROM `{$this->_sources_table}`"; 165 $res = $wpdb->get_results($sql, ARRAY_A); 166 if (NULL !== $res) { 167 SyncDebug::log(__METHOD__.'()'); 168 foreach ($res as $row) { 169 $vals = array_values($row); 170 SyncDebug::log(' ' . implode(', ', $vals)); 171 } 172 SyncDebug::log(' ' . count($res) . ' rows'); 173 } 174 } */ 175 176 /** 141 177 * Inserts a new record into the sources table, creating a unique token 142 178 * @param array $data The data to add … … 151 187 if (empty($data['token'])) { 152 188 do { 153 $token = wp_generate_password(48, FALSE);189 $token = $this->_make_token(); 154 190 //SyncDebug::log(__METHOD__ . '() looking for token ' . $token); 155 191 // this finds a match, regardless of the value of `allowed` … … 218 254 $wpdb->update($this->_sources, array('allowed' => 1), array('site_key' => $site_key, 'auth_name' => $user)); 219 255 } 256 257 private function _make_token() 258 { 259 return wp_generate_password(48, FALSE); 260 } 220 261 } -
wpsitesynccontent/trunk/install/activate.php
r1446190 r1492115 127 127 if (!empty($wpdb->charset)) 128 128 $charset_collate = " DEFAULT CHARACTER SET {$wpdb->charset} "; 129 if (!empty($wpdb->collate)) 130 $charset_collate .= " COLLATE {$wpdb->collate} "; 129 130 // determine default collation for tables being created 131 $collate = NULL; 132 if (defined('DB_COLLATE')) 133 $collate = DB_COLLATE; // if the constant is declared, use it 134 if (empty($collate) && !empty($wpdb->collate)) // otherwise allow wpdb class to specify 135 $collate = $wpdb->collate; 136 if (!empty($collate)) 137 $charset_collate .= " COLLATE {$collate} "; 131 138 132 139 $aTables = $this->get_table_data(); -
wpsitesynccontent/trunk/install/deactivate.php
r1451657 r1492115 19 19 $this->remove_database_tables(); 20 20 $this->remove_options(); 21 $this->remove_transients(); 21 22 } 22 23 … … 34 35 'sync_log', 35 36 'sync', 36 's ources',37 'sync_sources', 37 38 'sync_media', 38 39 ); … … 54 55 foreach ($options as $option) 55 56 delete_option($option); 57 } 58 59 /** 60 * Removes all transients 61 */ 62 protected function remove_transients() 63 { 64 $trans_keys = array( 65 'wpsitesync_extension_list', 66 ); 67 68 foreach ($trans_keys as $trans_key) { 69 delete_transient($trans_key); 70 } 56 71 } 57 72 -
wpsitesynccontent/trunk/readme.txt
r1457902 r1492115 4 4 Tags: attachments, content, content sync, data migration, desktopserver, export, import, migrate content, moving data, staging, synchronization, taxonomies 5 5 Requires at least: 3.5 6 Tested up to: 4. 56 Tested up to: 4.6 7 7 Stable tag: trunk 8 8 License: GPLv2 or later … … 107 107 108 108 == Changelog == 109 = 1.2 - Sep 7, 2016 = 110 * Fix: Changes to resolve authentication issues. (thanks to Craig S., Cathy E., Josh C. and Jason H.) 111 * Enhancement: Some optimizations and code cleanup. 112 * Enhancement: Updates in the Settings page for validating URLs. (thanks to Craig S.) 113 * Fix: Fixing a table name reference when removing tables on uninstall. 114 * Enhancement: Code to protect JSON data being returned via API calls when third-party plugins throw runtime errors. 115 * Fix: Fix URL references in the Help text. (thanks to Pedro M.) 116 * Fix: Fix text domain reference. (thanks to Pedro M.) 117 * Fix: authentication token save. (thanks to Jeff C.) 118 * Enhancement: Changes to allow new features in upcoming add-ons. 119 * Enhancement: Change API code to work with any Permalink setting on Target site. 120 109 121 = 1.1.1 - Jul 20, 2016 = 110 122 * Fix for authentication issues that sometimes occur after initial credentials are entered. -
wpsitesynccontent/trunk/views/content_details.php
r1446190 r1492115 1 1 <div id="sync-details-container"> 2 <p><b><?php _e('Content Details:', 'wpsitesync -pull'); ?></b></p>2 <p><b><?php _e('Content Details:', 'wpsitesynccontent'); ?></b></p> 3 3 <ul style="border:1px solid gray; padding:.2rem; margin: -4px"> 4 <li><?php printf(__('Target Content Id: %d', 'wpsitesync -pull'), $data['target_post_id']); ?></li>5 <li><?php printf(__('Content Title: %s', 'wpsitesync -pull'), $data['post_title']); ?></li>6 <li><?php printf(__('Content Author: %s', 'wpsitesync -pull'), $data['post_author']); ?></li>7 <li><?php printf(__('Last Modified: %s', 'wpsitesync -pull'),4 <li><?php printf(__('Target Content Id: %d', 'wpsitesynccontent'), $data['target_post_id']); ?></li> 5 <li><?php printf(__('Content Title: %s', 'wpsitesynccontent'), $data['post_title']); ?></li> 6 <li><?php printf(__('Content Author: %s', 'wpsitesynccontent'), $data['post_author']); ?></li> 7 <li><?php printf(__('Last Modified: %s', 'wpsitesynccontent'), 8 8 date(get_option('date_format') . ' ' . get_option('time_format'), strtotime($data['modified'])) ); ?></li> 9 <li><?php printf(__('Content: %s', 'wpsitesync -pull'), $data['content']); ?></li>9 <li><?php printf(__('Content: %s', 'wpsitesynccontent'), $data['content']); ?></li> 10 10 <?php do_action('spectrom_sync_details_view', $data); ?> 11 11 </ul> 12 <p><?php _e('Note: Syncing this Content will overwrite data.', 'wpsitesync -pull'); ?></p>12 <p><?php _e('Note: Syncing this Content will overwrite data.', 'wpsitesynccontent'); ?></p> 13 13 </div> -
wpsitesynccontent/trunk/wpsitesynccontent.php
r1457902 r1492115 6 6 Author: WPSiteSync 7 7 Author URI: http://wpsitesync.com 8 Version: 1. 1.18 Version: 1.2 9 9 Text Domain: wpsitesynccontent 10 10 Domain path: /language … … 25 25 class WPSiteSyncContent 26 26 { 27 const PLUGIN_VERSION = '1. 1.1';27 const PLUGIN_VERSION = '1.2'; 28 28 const PLUGIN_NAME = 'WPSiteSyncContent'; 29 29 … … 128 128 129 129 /* 130 * return option values131 * @param string $name name of the option value being requested132 * @param string $default default value to return if nothing found133 * @return multi the stored option value134 */135 public static function get_option($name, $default = NULL)136 {137 // TODO: deprecated138 if (NULL === self::$_config)139 self::$_config = SyncSettings::get_instance();140 return self::$_config->get_option($name, $default);141 }142 143 /*144 130 * return reference to asset, relative to the base plugin's /assets/ directory 145 131 * @param string $ref asset name to reference
Note: See TracChangeset
for help on using the changeset viewer.