Version Description
- Removed: upgrade paths from version 2.4.x
- Removed: support for YOURLS version 1.3
- Removed: support for Twitter Friendly Links (plug-in not updated in 8 years)
- Removed: Ability to enable the Goo.gl URL shortener (see: https://developers.google.com/url-shortener/)
- Removed: fallback functions required for PHP 4 support.
- Add 'show images' as option in feeds.
- Support for alt attributes displayed in Feeds
- Improved URL generation to link to searched Tweets.
- Improve parsing of URLs in Tweets.
- Don't save URLs if no shortener used or shortener returns no value.
- Option to ignore stored URLs when sending Tweets.
- Code now conforms with WordPress PHP standards with the exception of four deprecated functions.
Download this release
Release Info
Developer | joedolson |
Plugin | WP to Twitter |
Version | 3.3.3 |
Comparing to | |
See all releases |
Code changes from version 3.3.2 to 3.3.3
- {tmhOAuth → classes}/cacert.pem +0 -0
- tmhOAuth/tmhOAuth.php → classes/class-tmhoauth.php +121 -105
- WP_OAuth.php → classes/class-wp-oauth.php +572 -237
- classes/class-wpt-latest-tweets-widget.php +186 -0
- classes/class-wpt-normalizer.php +360 -0
- classes/class-wpt-search-tweets-widget.php +174 -0
- wpt-feed.php → classes/class-wpt-twitterfeed.php +141 -49
- classes/class-wpt-twitteroauth.php +420 -0
- css/styles.css +2 -2
- readme.txt +17 -1
- tmhOAuth/LICENSE +0 -202
- tmhOAuth/README.md +0 -211
- tmhOAuth/composer.json +0 -26
- tmhOAuth/tmhUtilities.php +0 -301
- uninstall.php +26 -16
- wp-to-twitter-manager.php +458 -417
- wp-to-twitter-oauth.php +111 -59
- wp-to-twitter-shorteners.php +320 -304
- wp-to-twitter.php +777 -790
- wpt-functions.php +480 -574
- wpt-rate-limiting.php +118 -82
- wpt-truncate.php +251 -170
- wpt-widget.php +208 -540
- wpt_twitter_oauth.php +0 -368
{tmhOAuth → classes}/cacert.pem
RENAMED
File without changes
|
tmhOAuth/tmhOAuth.php → classes/class-tmhoauth.php
RENAMED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
3 |
/**
|
4 |
-
* tmhOAuth
|
5 |
*
|
6 |
* An OAuth 1.0A library written in PHP.
|
7 |
* The library supports file uploading using multipart/form as well as general
|
@@ -9,18 +21,24 @@
|
|
9 |
*
|
10 |
* @author themattharris
|
11 |
* @version 0.7.5
|
|
|
12 |
*
|
13 |
* 20 February 2013
|
14 |
*/
|
15 |
-
class
|
16 |
const VERSION = '0.7.5';
|
17 |
|
|
|
|
|
|
|
|
|
|
|
18 |
var $response = array();
|
19 |
|
20 |
/**
|
21 |
-
* Creates a new
|
22 |
*
|
23 |
-
* @param
|
24 |
*
|
25 |
* @return void
|
26 |
*/
|
@@ -30,13 +48,13 @@ class tmhOAuth {
|
|
30 |
$this->auto_fixed_time = false;
|
31 |
$this->buffer = null;
|
32 |
|
33 |
-
// default configuration options
|
34 |
$this->config = array_merge(
|
35 |
array(
|
36 |
-
// leave 'user_agent' blank for default, otherwise set this to
|
37 |
-
// something that clearly identifies your app
|
38 |
'user_agent' => '',
|
39 |
-
// default timezone for requests
|
40 |
'timezone' => 'UTC',
|
41 |
'use_ssl' => true,
|
42 |
'host' => 'api.twitter.com',
|
@@ -46,41 +64,38 @@ class tmhOAuth {
|
|
46 |
'user_secret' => '',
|
47 |
'force_nonce' => false,
|
48 |
'nonce' => false,
|
49 |
-
// used for checking signatures. leave as false for auto
|
50 |
'force_timestamp' => false,
|
51 |
'timestamp' => false,
|
52 |
-
// used for checking signatures. leave as false for auto
|
53 |
-
|
54 |
-
// oauth signing variables that are not dynamic
|
55 |
'oauth_version' => '1.0',
|
56 |
'oauth_signature_method' => 'HMAC-SHA1',
|
57 |
-
// you probably don't want to change any of these curl values
|
58 |
'curl_connecttimeout' => 30,
|
59 |
'curl_timeout' => 10,
|
60 |
// for security this should always be set to 2.
|
61 |
'curl_ssl_verifyhost' => 2,
|
62 |
// for security this should always be set to true.
|
63 |
'curl_ssl_verifypeer' => true,
|
64 |
-
// you can get the latest cacert.pem from here http://curl.haxx.se/ca/cacert.pem
|
65 |
'curl_cainfo' => dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'cacert.pem',
|
66 |
'curl_capath' => dirname( __FILE__ ),
|
67 |
'curl_followlocation' => false,
|
68 |
-
// whether to follow redirects or not
|
69 |
-
|
70 |
-
// support for proxy servers
|
71 |
'curl_proxy' => false,
|
72 |
-
// really you don't want to use this if you are using streaming
|
73 |
'curl_proxyuserpwd' => false,
|
74 |
-
// format username:password for proxy, if required
|
75 |
'curl_encoding' => '',
|
76 |
-
// leave blank for all supported formats, else use gzip, deflate, identity
|
77 |
-
|
78 |
-
// streaming API
|
79 |
'is_streaming' => false,
|
80 |
'streaming_eol' => "\r\n",
|
81 |
'streaming_metrics_interval' => 60,
|
82 |
// header or querystring. You should always use header!
|
83 |
-
// this is just to help me debug other developers implementations
|
84 |
'as_header' => true,
|
85 |
'debug' => false,
|
86 |
),
|
@@ -116,13 +131,13 @@ class tmhOAuth {
|
|
116 |
* Generates a random OAuth nonce.
|
117 |
* If 'force_nonce' is true a nonce is not generated and the value in the configuration will be retained.
|
118 |
*
|
119 |
-
* @param string $length how many characters the nonce should be before MD5 hashing. default 12
|
120 |
-
* @param string $include_time whether to include time at the beginning of the nonce. default true
|
121 |
*
|
122 |
* @return void value is stored to the config array class variable
|
123 |
*/
|
124 |
private function create_nonce( $length = 12, $include_time = true ) {
|
125 |
-
if ( $this->config['force_nonce']
|
126 |
$sequence = array_merge( range( 0, 9 ), range( 'A', 'Z' ), range( 'a', 'z' ) );
|
127 |
$length = $length > count( $sequence ) ? count( $sequence ) : $length;
|
128 |
shuffle( $sequence );
|
@@ -139,21 +154,21 @@ class tmhOAuth {
|
|
139 |
* @return void value is stored to the config array class variable
|
140 |
*/
|
141 |
private function create_timestamp() {
|
142 |
-
$this->config['timestamp'] = ( $this->config['force_timestamp']
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
* Encodes the string or array passed in a way compatible with OAuth.
|
147 |
* If an array is passed each array value will will be encoded.
|
148 |
*
|
149 |
-
* @param mixed $data the scalar or array to encode
|
150 |
*
|
151 |
* @return $data encoded in a way compatible with OAuth
|
152 |
*/
|
153 |
private function safe_encode( $data ) {
|
154 |
if ( is_array( $data ) ) {
|
155 |
return array_map( array( $this, 'safe_encode' ), $data );
|
156 |
-
}
|
157 |
return str_ireplace(
|
158 |
array( '+', '%7E' ),
|
159 |
array( ' ', '~' ),
|
@@ -168,14 +183,14 @@ class tmhOAuth {
|
|
168 |
* Decodes the string or array from it's URL encoded form
|
169 |
* If an array is passed each array value will will be decoded.
|
170 |
*
|
171 |
-
* @param mixed $data the scalar or array to decode
|
172 |
*
|
173 |
* @return string $data decoded from the URL encoded form
|
174 |
*/
|
175 |
private function safe_decode( $data ) {
|
176 |
if ( is_array( $data ) ) {
|
177 |
return array_map( array( $this, 'safe_decode' ), $data );
|
178 |
-
}
|
179 |
return rawurldecode( $data );
|
180 |
} else {
|
181 |
return '';
|
@@ -196,12 +211,12 @@ class tmhOAuth {
|
|
196 |
'oauth_signature_method' => $this->config['oauth_signature_method'],
|
197 |
);
|
198 |
|
199 |
-
// include the user token if it exists
|
200 |
if ( $this->config['user_token'] ) {
|
201 |
$defaults['oauth_token'] = $this->config['user_token'];
|
202 |
}
|
203 |
|
204 |
-
// safely encode
|
205 |
foreach ( $defaults as $k => $v ) {
|
206 |
$_defaults[ $this->safe_encode( $k ) ] = $this->safe_encode( $v );
|
207 |
}
|
@@ -212,7 +227,7 @@ class tmhOAuth {
|
|
212 |
/**
|
213 |
* Extracts and decodes OAuth parameters from the passed string
|
214 |
*
|
215 |
-
* @param string $body the response body from an OAuth flow method
|
216 |
*
|
217 |
* @return array the response body safely decoded to an array of key => values
|
218 |
*/
|
@@ -233,7 +248,7 @@ class tmhOAuth {
|
|
233 |
* Prepares the HTTP method for use in the base string by converting it to
|
234 |
* uppercase.
|
235 |
*
|
236 |
-
* @param string $method an HTTP method such as GET or POST
|
237 |
*
|
238 |
* @return void value is stored to the class variable 'method'
|
239 |
*/
|
@@ -247,7 +262,7 @@ class tmhOAuth {
|
|
247 |
*
|
248 |
* Ref: 3.4.1.2
|
249 |
*
|
250 |
-
* @param string $url the request URL
|
251 |
*
|
252 |
* @return void value is stored to the class variable 'url'
|
253 |
*/
|
@@ -259,17 +274,17 @@ class tmhOAuth {
|
|
259 |
$host = $parts['host'];
|
260 |
$path = isset( $parts['path'] ) ? $parts['path'] : false;
|
261 |
|
262 |
-
|
|
|
|
|
263 |
|
264 |
-
if ( ( $scheme
|
265 |
-
|| ( $scheme == 'http' && $port != '80' )
|
266 |
-
) {
|
267 |
$host = "$host:$port";
|
268 |
}
|
269 |
|
270 |
-
// the scheme and host MUST be lowercase
|
271 |
$this->url = strtolower( "$scheme://$host" );
|
272 |
-
// but not the path
|
273 |
$this->url .= $path;
|
274 |
}
|
275 |
|
@@ -278,31 +293,31 @@ class tmhOAuth {
|
|
278 |
* Multipart parameters are ignored as they are not defined in the specification,
|
279 |
* all other types of parameter are encoded for compatibility with OAuth.
|
280 |
*
|
281 |
-
* @param array $params the parameters for the request
|
282 |
*
|
283 |
* @return void prepared values are stored in the class variable 'signing_params'
|
284 |
*/
|
285 |
private function prepare_params( $params ) {
|
286 |
-
// do not encode multipart parameters, leave them alone
|
287 |
if ( $this->config['multipart'] ) {
|
288 |
$this->request_params = $params;
|
289 |
$params = array();
|
290 |
}
|
291 |
|
292 |
-
// signing parameters are request parameters + OAuth default parameters
|
293 |
$this->signing_params = array_merge( $this->get_defaults(), (array) $params );
|
294 |
|
295 |
-
// Remove oauth_signature if present
|
296 |
-
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
|
297 |
if ( isset( $this->signing_params['oauth_signature'] ) ) {
|
298 |
unset( $this->signing_params['oauth_signature'] );
|
299 |
}
|
300 |
|
301 |
// Parameters are sorted by name, using lexicographical byte value ordering.
|
302 |
-
// Ref: Spec: 9.1.1 (1)
|
303 |
uksort( $this->signing_params, 'strcmp' );
|
304 |
|
305 |
-
// encode. Also sort the signed parameters from the POST parameters
|
306 |
foreach ( $this->signing_params as $k => $v ) {
|
307 |
$k = $this->safe_encode( $k );
|
308 |
|
@@ -315,7 +330,7 @@ class tmhOAuth {
|
|
315 |
$kv[] = "{$k}={$v}";
|
316 |
}
|
317 |
|
318 |
-
// auth params = the default oauth params which are present in our collection of signing params
|
319 |
$this->auth_params = array_intersect_key( $this->get_defaults(), $_signing_params );
|
320 |
if ( isset( $_signing_params['oauth_callback'] ) ) {
|
321 |
$this->auth_params['oauth_callback'] = $_signing_params['oauth_callback'];
|
@@ -327,12 +342,12 @@ class tmhOAuth {
|
|
327 |
unset( $_signing_params['oauth_verifier'] );
|
328 |
}
|
329 |
|
330 |
-
// request_params is already set if we're doing multipart, if not we need to set them now
|
331 |
if ( ! $this->config['multipart'] ) {
|
332 |
$this->request_params = array_diff_key( $_signing_params, $this->get_defaults() );
|
333 |
}
|
334 |
|
335 |
-
// create the parameter part of the base string
|
336 |
$this->signing_params = implode( '&', $kv );
|
337 |
}
|
338 |
|
@@ -354,9 +369,9 @@ class tmhOAuth {
|
|
354 |
private function prepare_base_string() {
|
355 |
$url = $this->url;
|
356 |
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
if ( ! empty( $this->custom_headers['Host'] ) ) {
|
361 |
$url = str_ireplace(
|
362 |
$this->config['host'],
|
@@ -368,7 +383,7 @@ class tmhOAuth {
|
|
368 |
$base = array(
|
369 |
$this->method,
|
370 |
$url,
|
371 |
-
$this->signing_params
|
372 |
);
|
373 |
$this->base_string = implode( '&', $this->safe_encode( $base ) );
|
374 |
}
|
@@ -399,9 +414,9 @@ class tmhOAuth {
|
|
399 |
* Signs the request and adds the OAuth signature. This runs all the request
|
400 |
* parameter preparation methods.
|
401 |
*
|
402 |
-
* @param string $method the HTTP method being used. e.g. POST, GET, HEAD etc
|
403 |
-
* @param string $url the request URL without query string parameters
|
404 |
-
* @param array
|
405 |
* @param string $useauth whether to use authentication when making the request.
|
406 |
*
|
407 |
* @return void
|
@@ -411,7 +426,7 @@ class tmhOAuth {
|
|
411 |
$this->prepare_url( $url );
|
412 |
$this->prepare_params( $params );
|
413 |
|
414 |
-
// we don't sign anything is we're not using auth
|
415 |
if ( $useauth ) {
|
416 |
$this->prepare_base_string();
|
417 |
$this->prepare_signing_key();
|
@@ -420,7 +435,9 @@ class tmhOAuth {
|
|
420 |
base64_encode(
|
421 |
hash_hmac(
|
422 |
'sha1', $this->base_string, $this->signing_key, true
|
423 |
-
)
|
|
|
|
|
424 |
|
425 |
$this->prepare_auth_header();
|
426 |
}
|
@@ -430,17 +447,17 @@ class tmhOAuth {
|
|
430 |
* Make an HTTP request using this library. This method doesn't return anything.
|
431 |
* Instead the response should be inspected directly.
|
432 |
*
|
433 |
-
* @param string $method the HTTP method being used. e.g. POST, GET, HEAD etc
|
434 |
-
* @param string $url the request URL without query string parameters
|
435 |
-
* @param array
|
436 |
-
* @param string $useauth whether to use authentication when making the request. Default true
|
437 |
-
* @param string $multipart whether this request contains multipart data. Default false
|
438 |
-
* @param array
|
439 |
*
|
440 |
* @return int the http response code for the request. 0 is returned if a connection could not be made
|
441 |
*/
|
442 |
public function request( $method, $url, $params = array(), $useauth = true, $multipart = false, $headers = array() ) {
|
443 |
-
// reset the request headers (we don't want to reuse them)
|
444 |
$this->headers = array();
|
445 |
$this->custom_headers = $headers;
|
446 |
|
@@ -462,15 +479,14 @@ class tmhOAuth {
|
|
462 |
* Make a long poll HTTP request using this library. This method is
|
463 |
* different to the other request methods as it isn't supposed to disconnect
|
464 |
*
|
465 |
-
* Using this method expects a callback which will receive the streaming
|
466 |
-
* responses.
|
467 |
*
|
468 |
-
* @param string $method the HTTP method being used. e.g. POST, GET, HEAD etc
|
469 |
-
* @param string $url the request URL without query string parameters
|
470 |
-
* @param array
|
471 |
* @param string $callback the callback function to stream the buffer to.
|
472 |
*
|
473 |
-
* @return void
|
474 |
*/
|
475 |
public function streaming_request( $method, $url, $params = array(), $callback = '' ) {
|
476 |
if ( ! empty( $callback ) ) {
|
@@ -513,8 +529,8 @@ class tmhOAuth {
|
|
513 |
/**
|
514 |
* Utility function to create the request URL in the requested format
|
515 |
*
|
516 |
-
* @param string $request the API method without extension
|
517 |
-
* @param string $format the format of the response. Default json. Set to an empty string to exclude the format
|
518 |
*
|
519 |
* @return string the concatenation of the host, API version, API method and format
|
520 |
*/
|
@@ -522,7 +538,7 @@ class tmhOAuth {
|
|
522 |
$format = strlen( $format ) > 0 ? ".$format" : '';
|
523 |
$proto = $this->config['use_ssl'] ? 'https:/' : 'http:/';
|
524 |
|
525 |
-
// backwards compatibility with v0.1
|
526 |
if ( isset( $this->config['v'] ) ) {
|
527 |
$this->config['host'] = $this->config['host'] . '/' . $this->config['v'];
|
528 |
}
|
@@ -537,19 +553,19 @@ class tmhOAuth {
|
|
537 |
return implode( '/', array(
|
538 |
$proto,
|
539 |
$this->config['host'],
|
540 |
-
$request . $format
|
541 |
) );
|
542 |
}
|
543 |
|
544 |
/**
|
545 |
* Public access to the private safe decode/encode methods
|
546 |
*
|
547 |
-
* @param string $text the text to transform
|
548 |
-
* @param string $mode the transformation mode. either encode or decode
|
549 |
*
|
550 |
* @return string $text transformed by the given $mode
|
551 |
*/
|
552 |
-
public function
|
553 |
return $this->{"safe_$mode"}( $text );
|
554 |
}
|
555 |
|
@@ -557,12 +573,12 @@ class tmhOAuth {
|
|
557 |
* Utility function to parse the returned curl headers and store them in the
|
558 |
* class array variable.
|
559 |
*
|
560 |
-
* @param object $ch curl handle
|
561 |
-
* @param string $header the response headers
|
562 |
*
|
563 |
* @return string the length of the header
|
564 |
*/
|
565 |
-
private function
|
566 |
$this->response['raw'] .= $header;
|
567 |
|
568 |
list( $key, $value ) = array_pad( explode( ':', $header, 2 ), 2, null );
|
@@ -589,14 +605,14 @@ class tmhOAuth {
|
|
589 |
*
|
590 |
* This function calls the previously defined streaming callback method.
|
591 |
*
|
592 |
-
* @param object $ch curl handle
|
593 |
-
* @param string $data the current curl buffer
|
594 |
*
|
595 |
* @return int the length of the data string processed in this function
|
596 |
*/
|
597 |
-
private function
|
598 |
$l = strlen( $data );
|
599 |
-
if ( strpos( $data, $this->config['streaming_eol'] )
|
600 |
$this->buffer .= $data;
|
601 |
|
602 |
return $l;
|
@@ -631,23 +647,23 @@ class tmhOAuth {
|
|
631 |
* Makes a curl request. Takes no parameters as all should have been prepared
|
632 |
* by the request method
|
633 |
*
|
634 |
-
*
|
635 |
*
|
636 |
* @return int the http response code for the request. 0 is returned if a connection could not be made
|
637 |
*/
|
638 |
private function curlit() {
|
639 |
$this->response['raw'] = '';
|
640 |
|
641 |
-
// method handling
|
642 |
switch ( $this->method ) {
|
643 |
case 'POST':
|
644 |
break;
|
645 |
default:
|
646 |
-
// GET, DELETE request so convert the parameters to a querystring
|
647 |
if ( ! empty( $this->request_params ) ) {
|
648 |
foreach ( $this->request_params as $k => $v ) {
|
649 |
// Multipart params haven't been encoded yet.
|
650 |
-
// Not sure why you would do a multipart GET but anyway, here's the support for it
|
651 |
if ( $this->config['multipart'] ) {
|
652 |
$params[] = $this->safe_encode( $k ) . '=' . $this->safe_encode( $v );
|
653 |
} else {
|
@@ -661,7 +677,7 @@ class tmhOAuth {
|
|
661 |
break;
|
662 |
}
|
663 |
|
664 |
-
// configure curl
|
665 |
$c = curl_init();
|
666 |
curl_setopt_array( $c, array(
|
667 |
CURLOPT_USERAGENT => $this->config['user_agent'],
|
@@ -674,29 +690,29 @@ class tmhOAuth {
|
|
674 |
CURLOPT_PROXY => $this->config['curl_proxy'],
|
675 |
CURLOPT_ENCODING => $this->config['curl_encoding'],
|
676 |
CURLOPT_URL => $this->url,
|
677 |
-
// process the headers
|
678 |
-
CURLOPT_HEADERFUNCTION => array( $this, '
|
679 |
CURLOPT_HEADER => false,
|
680 |
CURLINFO_HEADER_OUT => true,
|
681 |
) );
|
682 |
|
683 |
-
if ( $this->config['curl_cainfo']
|
684 |
curl_setopt( $c, CURLOPT_CAINFO, $this->config['curl_cainfo'] );
|
685 |
}
|
686 |
|
687 |
-
if ( $this->config['curl_capath']
|
688 |
curl_setopt( $c, CURLOPT_CAPATH, $this->config['curl_capath'] );
|
689 |
}
|
690 |
|
691 |
-
if ( $this->config['curl_proxyuserpwd']
|
692 |
curl_setopt( $c, CURLOPT_PROXYUSERPWD, $this->config['curl_proxyuserpwd'] );
|
693 |
}
|
694 |
|
695 |
if ( $this->config['is_streaming'] ) {
|
696 |
-
// process the body
|
697 |
$this->response['content-length'] = 0;
|
698 |
curl_setopt( $c, CURLOPT_TIMEOUT, 0 );
|
699 |
-
curl_setopt( $c, CURLOPT_WRITEFUNCTION, array( $this, '
|
700 |
}
|
701 |
|
702 |
switch ( $this->method ) {
|
@@ -711,7 +727,7 @@ class tmhOAuth {
|
|
711 |
}
|
712 |
|
713 |
if ( ! empty( $this->request_params ) ) {
|
714 |
-
// if not doing multipart we need to implode the parameters
|
715 |
if ( ! $this->config['multipart'] ) {
|
716 |
foreach ( $this->request_params as $k => $v ) {
|
717 |
$ps[] = "{$k}={$v}";
|
@@ -731,8 +747,8 @@ class tmhOAuth {
|
|
731 |
if ( isset( $this->config['prevent_request'] ) && ( true == $this->config['prevent_request'] ) ) {
|
732 |
return 0;
|
733 |
}
|
734 |
-
|
735 |
-
//
|
736 |
$response = curl_exec( $c );
|
737 |
$code = curl_getinfo( $c, CURLINFO_HTTP_CODE );
|
738 |
$info = curl_getinfo( $c );
|
@@ -740,7 +756,7 @@ class tmhOAuth {
|
|
740 |
$errno = curl_errno( $c );
|
741 |
curl_close( $c );
|
742 |
|
743 |
-
// store the response
|
744 |
$this->response['code'] = $code;
|
745 |
$this->response['response'] = $response;
|
746 |
$this->response['info'] = $info;
|
@@ -754,4 +770,4 @@ class tmhOAuth {
|
|
754 |
|
755 |
return $code;
|
756 |
}
|
757 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* TmhOAuth
|
4 |
+
*
|
5 |
+
* @category OAuth
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
/**
|
16 |
+
* OAuth / tmhOAuth
|
17 |
*
|
18 |
* An OAuth 1.0A library written in PHP.
|
19 |
* The library supports file uploading using multipart/form as well as general
|
21 |
*
|
22 |
* @author themattharris
|
23 |
* @version 0.7.5
|
24 |
+
* @link https://github.com/themattharris/tmhOAuth
|
25 |
*
|
26 |
* 20 February 2013
|
27 |
*/
|
28 |
+
class TmhOAuth {
|
29 |
const VERSION = '0.7.5';
|
30 |
|
31 |
+
/**
|
32 |
+
* The response from Twitter.
|
33 |
+
*
|
34 |
+
* @var $response
|
35 |
+
*/
|
36 |
var $response = array();
|
37 |
|
38 |
/**
|
39 |
+
* Creates a new TmhOAuth object
|
40 |
*
|
41 |
+
* @param array $config , the configuration to use for this request.
|
42 |
*
|
43 |
* @return void
|
44 |
*/
|
48 |
$this->auto_fixed_time = false;
|
49 |
$this->buffer = null;
|
50 |
|
51 |
+
// default configuration options.
|
52 |
$this->config = array_merge(
|
53 |
array(
|
54 |
+
// leave 'user_agent' blank for default, otherwise set this to.
|
55 |
+
// something that clearly identifies your app.
|
56 |
'user_agent' => '',
|
57 |
+
// default timezone for requests.
|
58 |
'timezone' => 'UTC',
|
59 |
'use_ssl' => true,
|
60 |
'host' => 'api.twitter.com',
|
64 |
'user_secret' => '',
|
65 |
'force_nonce' => false,
|
66 |
'nonce' => false,
|
67 |
+
// used for checking signatures. leave as false for auto.
|
68 |
'force_timestamp' => false,
|
69 |
'timestamp' => false,
|
70 |
+
// used for checking signatures. leave as false for auto.
|
71 |
+
// oauth signing variables that are not dynamic.
|
|
|
72 |
'oauth_version' => '1.0',
|
73 |
'oauth_signature_method' => 'HMAC-SHA1',
|
74 |
+
// you probably don't want to change any of these curl values.
|
75 |
'curl_connecttimeout' => 30,
|
76 |
'curl_timeout' => 10,
|
77 |
// for security this should always be set to 2.
|
78 |
'curl_ssl_verifyhost' => 2,
|
79 |
// for security this should always be set to true.
|
80 |
'curl_ssl_verifypeer' => true,
|
81 |
+
// you can get the latest cacert.pem from here http://curl.haxx.se/ca/cacert.pem.
|
82 |
'curl_cainfo' => dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'cacert.pem',
|
83 |
'curl_capath' => dirname( __FILE__ ),
|
84 |
'curl_followlocation' => false,
|
85 |
+
// whether to follow redirects or not.
|
86 |
+
// support for proxy servers.
|
|
|
87 |
'curl_proxy' => false,
|
88 |
+
// really you don't want to use this if you are using streaming.
|
89 |
'curl_proxyuserpwd' => false,
|
90 |
+
// format username:password for proxy, if required.
|
91 |
'curl_encoding' => '',
|
92 |
+
// leave blank for all supported formats, else use gzip, deflate, identity.
|
93 |
+
// streaming API.
|
|
|
94 |
'is_streaming' => false,
|
95 |
'streaming_eol' => "\r\n",
|
96 |
'streaming_metrics_interval' => 60,
|
97 |
// header or querystring. You should always use header!
|
98 |
+
// this is just to help me debug other developers implementations.
|
99 |
'as_header' => true,
|
100 |
'debug' => false,
|
101 |
),
|
131 |
* Generates a random OAuth nonce.
|
132 |
* If 'force_nonce' is true a nonce is not generated and the value in the configuration will be retained.
|
133 |
*
|
134 |
+
* @param string $length how many characters the nonce should be before MD5 hashing. default 12.
|
135 |
+
* @param string $include_time whether to include time at the beginning of the nonce. default true.
|
136 |
*
|
137 |
* @return void value is stored to the config array class variable
|
138 |
*/
|
139 |
private function create_nonce( $length = 12, $include_time = true ) {
|
140 |
+
if ( false == $this->config['force_nonce'] ) {
|
141 |
$sequence = array_merge( range( 0, 9 ), range( 'A', 'Z' ), range( 'a', 'z' ) );
|
142 |
$length = $length > count( $sequence ) ? count( $sequence ) : $length;
|
143 |
shuffle( $sequence );
|
154 |
* @return void value is stored to the config array class variable
|
155 |
*/
|
156 |
private function create_timestamp() {
|
157 |
+
$this->config['timestamp'] = ( false == $this->config['force_timestamp'] ? time() : $this->config['timestamp'] );
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
* Encodes the string or array passed in a way compatible with OAuth.
|
162 |
* If an array is passed each array value will will be encoded.
|
163 |
*
|
164 |
+
* @param mixed $data the scalar or array to encode.
|
165 |
*
|
166 |
* @return $data encoded in a way compatible with OAuth
|
167 |
*/
|
168 |
private function safe_encode( $data ) {
|
169 |
if ( is_array( $data ) ) {
|
170 |
return array_map( array( $this, 'safe_encode' ), $data );
|
171 |
+
} elseif ( is_scalar( $data ) ) {
|
172 |
return str_ireplace(
|
173 |
array( '+', '%7E' ),
|
174 |
array( ' ', '~' ),
|
183 |
* Decodes the string or array from it's URL encoded form
|
184 |
* If an array is passed each array value will will be decoded.
|
185 |
*
|
186 |
+
* @param mixed $data the scalar or array to decode.
|
187 |
*
|
188 |
* @return string $data decoded from the URL encoded form
|
189 |
*/
|
190 |
private function safe_decode( $data ) {
|
191 |
if ( is_array( $data ) ) {
|
192 |
return array_map( array( $this, 'safe_decode' ), $data );
|
193 |
+
} elseif ( is_scalar( $data ) ) {
|
194 |
return rawurldecode( $data );
|
195 |
} else {
|
196 |
return '';
|
211 |
'oauth_signature_method' => $this->config['oauth_signature_method'],
|
212 |
);
|
213 |
|
214 |
+
// include the user token if it exists.
|
215 |
if ( $this->config['user_token'] ) {
|
216 |
$defaults['oauth_token'] = $this->config['user_token'];
|
217 |
}
|
218 |
|
219 |
+
// safely encode.
|
220 |
foreach ( $defaults as $k => $v ) {
|
221 |
$_defaults[ $this->safe_encode( $k ) ] = $this->safe_encode( $v );
|
222 |
}
|
227 |
/**
|
228 |
* Extracts and decodes OAuth parameters from the passed string
|
229 |
*
|
230 |
+
* @param string $body the response body from an OAuth flow method.
|
231 |
*
|
232 |
* @return array the response body safely decoded to an array of key => values
|
233 |
*/
|
248 |
* Prepares the HTTP method for use in the base string by converting it to
|
249 |
* uppercase.
|
250 |
*
|
251 |
+
* @param string $method an HTTP method such as GET or POST.
|
252 |
*
|
253 |
* @return void value is stored to the class variable 'method'
|
254 |
*/
|
262 |
*
|
263 |
* Ref: 3.4.1.2
|
264 |
*
|
265 |
+
* @param string $url the request URL.
|
266 |
*
|
267 |
* @return void value is stored to the class variable 'url'
|
268 |
*/
|
274 |
$host = $parts['host'];
|
275 |
$path = isset( $parts['path'] ) ? $parts['path'] : false;
|
276 |
|
277 |
+
if ( ! $port ) {
|
278 |
+
$port = ( 'https' == $scheme ) ? '443' : '80';
|
279 |
+
}
|
280 |
|
281 |
+
if ( ( 'https' == $scheme && '443' != $port ) || ( 'http' == $scheme && '80' != $port ) ) {
|
|
|
|
|
282 |
$host = "$host:$port";
|
283 |
}
|
284 |
|
285 |
+
// the scheme and host MUST be lowercase.
|
286 |
$this->url = strtolower( "$scheme://$host" );
|
287 |
+
// but not the path.
|
288 |
$this->url .= $path;
|
289 |
}
|
290 |
|
293 |
* Multipart parameters are ignored as they are not defined in the specification,
|
294 |
* all other types of parameter are encoded for compatibility with OAuth.
|
295 |
*
|
296 |
+
* @param array $params the parameters for the request.
|
297 |
*
|
298 |
* @return void prepared values are stored in the class variable 'signing_params'
|
299 |
*/
|
300 |
private function prepare_params( $params ) {
|
301 |
+
// do not encode multipart parameters, leave them alone.
|
302 |
if ( $this->config['multipart'] ) {
|
303 |
$this->request_params = $params;
|
304 |
$params = array();
|
305 |
}
|
306 |
|
307 |
+
// signing parameters are request parameters + OAuth default parameters.
|
308 |
$this->signing_params = array_merge( $this->get_defaults(), (array) $params );
|
309 |
|
310 |
+
// Remove oauth_signature if present.
|
311 |
+
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.").
|
312 |
if ( isset( $this->signing_params['oauth_signature'] ) ) {
|
313 |
unset( $this->signing_params['oauth_signature'] );
|
314 |
}
|
315 |
|
316 |
// Parameters are sorted by name, using lexicographical byte value ordering.
|
317 |
+
// Ref: Spec: 9.1.1 (1).
|
318 |
uksort( $this->signing_params, 'strcmp' );
|
319 |
|
320 |
+
// encode. Also sort the signed parameters from the POST parameters.
|
321 |
foreach ( $this->signing_params as $k => $v ) {
|
322 |
$k = $this->safe_encode( $k );
|
323 |
|
330 |
$kv[] = "{$k}={$v}";
|
331 |
}
|
332 |
|
333 |
+
// auth params = the default oauth params which are present in our collection of signing params.
|
334 |
$this->auth_params = array_intersect_key( $this->get_defaults(), $_signing_params );
|
335 |
if ( isset( $_signing_params['oauth_callback'] ) ) {
|
336 |
$this->auth_params['oauth_callback'] = $_signing_params['oauth_callback'];
|
342 |
unset( $_signing_params['oauth_verifier'] );
|
343 |
}
|
344 |
|
345 |
+
// request_params is already set if we're doing multipart, if not we need to set them now.
|
346 |
if ( ! $this->config['multipart'] ) {
|
347 |
$this->request_params = array_diff_key( $_signing_params, $this->get_defaults() );
|
348 |
}
|
349 |
|
350 |
+
// create the parameter part of the base string.
|
351 |
$this->signing_params = implode( '&', $kv );
|
352 |
}
|
353 |
|
369 |
private function prepare_base_string() {
|
370 |
$url = $this->url;
|
371 |
|
372 |
+
// if the host header is set we need to rewrite the basestring to use.
|
373 |
+
// that, instead of the request host. otherwise the signature won't match.
|
374 |
+
// on the server .
|
375 |
if ( ! empty( $this->custom_headers['Host'] ) ) {
|
376 |
$url = str_ireplace(
|
377 |
$this->config['host'],
|
383 |
$base = array(
|
384 |
$this->method,
|
385 |
$url,
|
386 |
+
$this->signing_params,
|
387 |
);
|
388 |
$this->base_string = implode( '&', $this->safe_encode( $base ) );
|
389 |
}
|
414 |
* Signs the request and adds the OAuth signature. This runs all the request
|
415 |
* parameter preparation methods.
|
416 |
*
|
417 |
+
* @param string $method the HTTP method being used. e.g. POST, GET, HEAD etc.
|
418 |
+
* @param string $url the request URL without query string parameters.
|
419 |
+
* @param array $params the request parameters as an array of key=value pairs.
|
420 |
* @param string $useauth whether to use authentication when making the request.
|
421 |
*
|
422 |
* @return void
|
426 |
$this->prepare_url( $url );
|
427 |
$this->prepare_params( $params );
|
428 |
|
429 |
+
// we don't sign anything is we're not using auth.
|
430 |
if ( $useauth ) {
|
431 |
$this->prepare_base_string();
|
432 |
$this->prepare_signing_key();
|
435 |
base64_encode(
|
436 |
hash_hmac(
|
437 |
'sha1', $this->base_string, $this->signing_key, true
|
438 |
+
)
|
439 |
+
)
|
440 |
+
);
|
441 |
|
442 |
$this->prepare_auth_header();
|
443 |
}
|
447 |
* Make an HTTP request using this library. This method doesn't return anything.
|
448 |
* Instead the response should be inspected directly.
|
449 |
*
|
450 |
+
* @param string $method the HTTP method being used. e.g. POST, GET, HEAD etc.
|
451 |
+
* @param string $url the request URL without query string parameters.
|
452 |
+
* @param array $params the request parameters as an array of key=value pairs. Default empty array.
|
453 |
+
* @param string $useauth whether to use authentication when making the request. Default true.
|
454 |
+
* @param string $multipart whether this request contains multipart data. Default false.
|
455 |
+
* @param array $headers any custom headers to send with the request. Default empty array.
|
456 |
*
|
457 |
* @return int the http response code for the request. 0 is returned if a connection could not be made
|
458 |
*/
|
459 |
public function request( $method, $url, $params = array(), $useauth = true, $multipart = false, $headers = array() ) {
|
460 |
+
// reset the request headers (we don't want to reuse them).
|
461 |
$this->headers = array();
|
462 |
$this->custom_headers = $headers;
|
463 |
|
479 |
* Make a long poll HTTP request using this library. This method is
|
480 |
* different to the other request methods as it isn't supposed to disconnect
|
481 |
*
|
482 |
+
* Using this method expects a callback which will receive the streaming responses.
|
|
|
483 |
*
|
484 |
+
* @param string $method the HTTP method being used. e.g. POST, GET, HEAD etc.
|
485 |
+
* @param string $url the request URL without query string parameters.
|
486 |
+
* @param array $params the request parameters as an array of key=value pairs.
|
487 |
* @param string $callback the callback function to stream the buffer to.
|
488 |
*
|
489 |
+
* @return mixed false or void
|
490 |
*/
|
491 |
public function streaming_request( $method, $url, $params = array(), $callback = '' ) {
|
492 |
if ( ! empty( $callback ) ) {
|
529 |
/**
|
530 |
* Utility function to create the request URL in the requested format
|
531 |
*
|
532 |
+
* @param string $request the API method without extension.
|
533 |
+
* @param string $format the format of the response. Default json. Set to an empty string to exclude the format.
|
534 |
*
|
535 |
* @return string the concatenation of the host, API version, API method and format
|
536 |
*/
|
538 |
$format = strlen( $format ) > 0 ? ".$format" : '';
|
539 |
$proto = $this->config['use_ssl'] ? 'https:/' : 'http:/';
|
540 |
|
541 |
+
// backwards compatibility with v0.1.
|
542 |
if ( isset( $this->config['v'] ) ) {
|
543 |
$this->config['host'] = $this->config['host'] . '/' . $this->config['v'];
|
544 |
}
|
553 |
return implode( '/', array(
|
554 |
$proto,
|
555 |
$this->config['host'],
|
556 |
+
$request . $format,
|
557 |
) );
|
558 |
}
|
559 |
|
560 |
/**
|
561 |
* Public access to the private safe decode/encode methods
|
562 |
*
|
563 |
+
* @param string $text the text to transform.
|
564 |
+
* @param string $mode the transformation mode. either encode or decode.
|
565 |
*
|
566 |
* @return string $text transformed by the given $mode
|
567 |
*/
|
568 |
+
public function transform_text( $text, $mode = 'encode' ) {
|
569 |
return $this->{"safe_$mode"}( $text );
|
570 |
}
|
571 |
|
573 |
* Utility function to parse the returned curl headers and store them in the
|
574 |
* class array variable.
|
575 |
*
|
576 |
+
* @param object $ch curl handle.
|
577 |
+
* @param string $header the response headers.
|
578 |
*
|
579 |
* @return string the length of the header
|
580 |
*/
|
581 |
+
private function curl_header( $ch, $header ) {
|
582 |
$this->response['raw'] .= $header;
|
583 |
|
584 |
list( $key, $value ) = array_pad( explode( ':', $header, 2 ), 2, null );
|
605 |
*
|
606 |
* This function calls the previously defined streaming callback method.
|
607 |
*
|
608 |
+
* @param object $ch curl handle.
|
609 |
+
* @param string $data the current curl buffer.
|
610 |
*
|
611 |
* @return int the length of the data string processed in this function
|
612 |
*/
|
613 |
+
private function curl_write( $ch, $data ) {
|
614 |
$l = strlen( $data );
|
615 |
+
if ( false === strpos( $data, $this->config['streaming_eol'] ) ) {
|
616 |
$this->buffer .= $data;
|
617 |
|
618 |
return $l;
|
647 |
* Makes a curl request. Takes no parameters as all should have been prepared
|
648 |
* by the request method
|
649 |
*
|
650 |
+
* The response data is stored in the class variable 'response'
|
651 |
*
|
652 |
* @return int the http response code for the request. 0 is returned if a connection could not be made
|
653 |
*/
|
654 |
private function curlit() {
|
655 |
$this->response['raw'] = '';
|
656 |
|
657 |
+
// method handling.
|
658 |
switch ( $this->method ) {
|
659 |
case 'POST':
|
660 |
break;
|
661 |
default:
|
662 |
+
// GET, DELETE request so convert the parameters to a querystring.
|
663 |
if ( ! empty( $this->request_params ) ) {
|
664 |
foreach ( $this->request_params as $k => $v ) {
|
665 |
// Multipart params haven't been encoded yet.
|
666 |
+
// Not sure why you would do a multipart GET but anyway, here's the support for it.
|
667 |
if ( $this->config['multipart'] ) {
|
668 |
$params[] = $this->safe_encode( $k ) . '=' . $this->safe_encode( $v );
|
669 |
} else {
|
677 |
break;
|
678 |
}
|
679 |
|
680 |
+
// configure curl.
|
681 |
$c = curl_init();
|
682 |
curl_setopt_array( $c, array(
|
683 |
CURLOPT_USERAGENT => $this->config['user_agent'],
|
690 |
CURLOPT_PROXY => $this->config['curl_proxy'],
|
691 |
CURLOPT_ENCODING => $this->config['curl_encoding'],
|
692 |
CURLOPT_URL => $this->url,
|
693 |
+
// process the headers.
|
694 |
+
CURLOPT_HEADERFUNCTION => array( $this, 'curl_header' ),
|
695 |
CURLOPT_HEADER => false,
|
696 |
CURLINFO_HEADER_OUT => true,
|
697 |
) );
|
698 |
|
699 |
+
if ( false !== $this->config['curl_cainfo'] ) {
|
700 |
curl_setopt( $c, CURLOPT_CAINFO, $this->config['curl_cainfo'] );
|
701 |
}
|
702 |
|
703 |
+
if ( false !== $this->config['curl_capath'] ) {
|
704 |
curl_setopt( $c, CURLOPT_CAPATH, $this->config['curl_capath'] );
|
705 |
}
|
706 |
|
707 |
+
if ( false !== $this->config['curl_proxyuserpwd'] ) {
|
708 |
curl_setopt( $c, CURLOPT_PROXYUSERPWD, $this->config['curl_proxyuserpwd'] );
|
709 |
}
|
710 |
|
711 |
if ( $this->config['is_streaming'] ) {
|
712 |
+
// process the body.
|
713 |
$this->response['content-length'] = 0;
|
714 |
curl_setopt( $c, CURLOPT_TIMEOUT, 0 );
|
715 |
+
curl_setopt( $c, CURLOPT_WRITEFUNCTION, array( $this, 'curl_write' ) );
|
716 |
}
|
717 |
|
718 |
switch ( $this->method ) {
|
727 |
}
|
728 |
|
729 |
if ( ! empty( $this->request_params ) ) {
|
730 |
+
// if not doing multipart we need to implode the parameters.
|
731 |
if ( ! $this->config['multipart'] ) {
|
732 |
foreach ( $this->request_params as $k => $v ) {
|
733 |
$ps[] = "{$k}={$v}";
|
747 |
if ( isset( $this->config['prevent_request'] ) && ( true == $this->config['prevent_request'] ) ) {
|
748 |
return 0;
|
749 |
}
|
750 |
+
|
751 |
+
// Run the curl command.
|
752 |
$response = curl_exec( $c );
|
753 |
$code = curl_getinfo( $c, CURLINFO_HTTP_CODE );
|
754 |
$info = curl_getinfo( $c );
|
756 |
$errno = curl_errno( $c );
|
757 |
curl_close( $c );
|
758 |
|
759 |
+
// store the response.
|
760 |
$this->response['code'] = $code;
|
761 |
$this->response['response'] = $response;
|
762 |
$this->response['info'] = $info;
|
770 |
|
771 |
return $code;
|
772 |
}
|
773 |
+
}
|
WP_OAuth.php → classes/class-wp-oauth.php
RENAMED
@@ -1,41 +1,92 @@
|
|
1 |
<?php
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
exit;
|
5 |
-
}
|
6 |
|
7 |
if ( ! class_exists( 'WPOAuthException' ) ) {
|
8 |
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
*/
|
11 |
-
|
12 |
class WPOAuthException extends Exception {
|
13 |
-
// pass
|
14 |
}
|
15 |
|
|
|
|
|
|
|
16 |
class WPOAuthConsumer {
|
|
|
|
|
|
|
|
|
|
|
17 |
public $key;
|
|
|
|
|
|
|
|
|
|
|
18 |
public $secret;
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
function __construct( $key, $secret, $callback_url = null ) {
|
21 |
$this->key = $key;
|
22 |
$this->secret = $secret;
|
23 |
$this->callback_url = $callback_url;
|
24 |
}
|
25 |
|
|
|
|
|
|
|
26 |
function __toString() {
|
27 |
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
|
28 |
}
|
29 |
}
|
30 |
|
|
|
|
|
|
|
31 |
class WPOAuthToken {
|
32 |
-
|
|
|
|
|
|
|
|
|
33 |
public $key;
|
|
|
|
|
|
|
|
|
|
|
34 |
public $secret;
|
35 |
|
36 |
/**
|
37 |
-
*
|
38 |
-
*
|
|
|
|
|
39 |
*/
|
40 |
function __construct( $key, $secret ) {
|
41 |
$this->key = $key;
|
@@ -43,16 +94,18 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
* would respond to request_token and access_token calls with
|
|
|
|
|
48 |
*/
|
49 |
function to_string() {
|
50 |
-
return
|
51 |
-
WPOAuthUtil::urlencode_rfc3986( $this->key ) .
|
52 |
-
"&oauth_token_secret=" .
|
53 |
-
WPOAuthUtil::urlencode_rfc3986( $this->secret );
|
54 |
}
|
55 |
|
|
|
|
|
|
|
56 |
function __toString() {
|
57 |
return $this->to_string();
|
58 |
}
|
@@ -65,6 +118,7 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
65 |
abstract class WPOAuthSignatureMethod {
|
66 |
/**
|
67 |
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
|
|
68 |
* @return string
|
69 |
*/
|
70 |
abstract public function get_name();
|
@@ -75,9 +129,9 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
75 |
* the encoding is handled in OAuthRequest when the final
|
76 |
* request is serialized
|
77 |
*
|
78 |
-
* @param OAuthRequest
|
79 |
-
* @param OAuthConsumer $consumer
|
80 |
-
* @param OAuthToken
|
81 |
*
|
82 |
* @return string
|
83 |
*/
|
@@ -86,10 +140,10 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
86 |
/**
|
87 |
* Verifies that a given signature is correct
|
88 |
*
|
89 |
-
* @param OAuthRequest
|
90 |
-
* @param OAuthConsumer $consumer
|
91 |
-
* @param OAuthToken
|
92 |
-
* @param string
|
93 |
*
|
94 |
* @return bool
|
95 |
*/
|
@@ -105,22 +159,30 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
105 |
* where the Signature Base String is the text and the key is the concatenated values (each first
|
106 |
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
107 |
* character (ASCII code 38) even if empty.
|
108 |
-
*
|
109 |
*/
|
110 |
class WPOAuthSignatureMethod_HMAC_SHA1 extends WPOAuthSignatureMethod {
|
|
|
|
|
|
|
111 |
function get_name() {
|
112 |
-
return
|
113 |
}
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
public function build_signature( $request, $consumer, $token ) {
|
116 |
$base_string = $request->get_signature_base_string();
|
117 |
$request->base_string = $base_string;
|
118 |
|
119 |
-
$key_parts = array(
|
120 |
-
$consumer->secret,
|
121 |
-
( $token ) ? $token->secret : ""
|
122 |
-
);
|
123 |
-
|
124 |
$key_parts = WPOAuthUtil::urlencode_rfc3986( $key_parts );
|
125 |
$key = implode( '&', $key_parts );
|
126 |
|
@@ -134,24 +196,30 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
134 |
* - Chapter 9.4 ("PLAINTEXT")
|
135 |
*/
|
136 |
class WPOAuthSignatureMethod_PLAINTEXT extends WPOAuthSignatureMethod {
|
|
|
|
|
|
|
137 |
public function get_name() {
|
138 |
-
return
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
-
* oauth_signature is set to the concatenated encoded values of the Consumer Secret and
|
143 |
* Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
|
144 |
* empty. The result MUST be encoded again.
|
145 |
* - Chapter 9.4.1 ("Generating Signatures")
|
146 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
148 |
* OAuthRequest handles this!
|
149 |
*/
|
150 |
public function build_signature( $request, $consumer, $token ) {
|
151 |
-
$key_parts = array(
|
152 |
-
$consumer->secret,
|
153 |
-
( $token ) ? $token->secret : ""
|
154 |
-
);
|
155 |
|
156 |
$key_parts = WPOAuthUtil::urlencode_rfc3986( $key_parts );
|
157 |
$key = implode( '&', $key_parts );
|
@@ -167,146 +235,224 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
167 |
* EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
|
168 |
* verified way to the Service Provider, in a manner which is beyond the scope of this
|
169 |
* specification.
|
170 |
-
*
|
171 |
*/
|
172 |
abstract class WPOAuthSignatureMethod_RSA_SHA1 extends WPOAuthSignatureMethod {
|
|
|
|
|
|
|
173 |
public function get_name() {
|
174 |
-
return
|
175 |
}
|
176 |
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
|
|
|
|
|
|
|
|
183 |
protected abstract function fetch_public_cert( &$request );
|
184 |
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
|
|
|
|
|
|
189 |
protected abstract function fetch_private_cert( &$request );
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
public function build_signature( $request, $consumer, $token ) {
|
192 |
$base_string = $request->get_signature_base_string();
|
193 |
$request->base_string = $base_string;
|
194 |
|
195 |
-
// Fetch the private key cert based on the request
|
196 |
$cert = $this->fetch_private_cert( $request );
|
197 |
|
198 |
-
// Pull the private key ID from the certificate
|
199 |
$privatekeyid = openssl_get_privatekey( $cert );
|
200 |
|
201 |
-
// Sign using the key
|
202 |
$ok = openssl_sign( $base_string, $signature, $privatekeyid );
|
203 |
|
204 |
-
// Release the key resource
|
205 |
openssl_free_key( $privatekeyid );
|
206 |
|
207 |
return base64_encode( $signature );
|
208 |
}
|
209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
public function check_signature( $request, $consumer, $token, $signature ) {
|
211 |
$decoded_sig = base64_decode( $signature );
|
212 |
|
213 |
$base_string = $request->get_signature_base_string();
|
214 |
|
215 |
-
// Fetch the public key cert based on the request
|
216 |
$cert = $this->fetch_public_cert( $request );
|
217 |
|
218 |
-
// Pull the public key ID from the certificate
|
219 |
$publickeyid = openssl_get_publickey( $cert );
|
220 |
|
221 |
-
// Check the computed signature against the one passed in the query
|
222 |
$ok = openssl_verify( $base_string, $decoded_sig, $publickeyid );
|
223 |
|
224 |
-
// Release the key resource
|
225 |
openssl_free_key( $publickeyid );
|
226 |
|
227 |
-
return
|
228 |
}
|
229 |
}
|
230 |
|
231 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
private $parameters;
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
private $http_method;
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
private $http_url;
|
235 |
-
|
|
|
|
|
|
|
|
|
|
|
236 |
public $base_string;
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
public static $version = '1.0';
|
238 |
-
public static $POST_INPUT = 'php://input';
|
239 |
|
240 |
-
|
241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
$parameters = array_merge( WPOAuthUtil::parse_parameters( parse_url( $http_url, PHP_URL_QUERY ) ), $parameters );
|
243 |
$this->parameters = $parameters;
|
244 |
$this->http_method = $http_method;
|
245 |
$this->http_url = $http_url;
|
246 |
}
|
247 |
|
248 |
-
|
249 |
/**
|
250 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
*/
|
252 |
public static function from_request( $http_method = null, $http_url = null, $parameters = null ) {
|
253 |
-
$scheme = ( ! isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS']
|
254 |
-
|
255 |
-
: '
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
// We weren't handed any parameters, so let's find the ones relevant to
|
264 |
-
// this request.
|
265 |
-
// If you run XML-RPC or similar you should use this to provide your own
|
266 |
-
// parsed parameter-list
|
267 |
if ( ! $parameters ) {
|
268 |
-
// Find request headers
|
269 |
$request_headers = WPOAuthUtil::get_headers();
|
270 |
|
271 |
-
// Parse the query-string to find GET parameters
|
272 |
$parameters = WPOAuthUtil::parse_parameters( $_SERVER['QUERY_STRING'] );
|
273 |
|
274 |
-
// It's a POST request of the proper content-type, so parse POST
|
275 |
-
// parameters and add those overriding any duplicates from GET
|
276 |
-
|
277 |
-
|
278 |
-
"application/x-www-form-urlencoded" )
|
279 |
-
) {
|
280 |
$post_data = WPOAuthUtil::parse_parameters(
|
281 |
-
file_get_contents( self::$
|
282 |
);
|
283 |
$parameters = array_merge( $parameters, $post_data );
|
284 |
}
|
285 |
|
286 |
-
// We have a Authorization-header with OAuth data. Parse the header
|
287 |
-
// and add those overriding any duplicates from GET or POST
|
288 |
-
|
|
|
289 |
$header_parameters = WPOAuthUtil::split_header(
|
290 |
$request_headers['Authorization']
|
291 |
);
|
292 |
$parameters = array_merge( $parameters, $header_parameters );
|
293 |
}
|
294 |
-
|
295 |
}
|
296 |
-
|
297 |
-
return new WPOAuthRequest( $http_method, $http_url, $parameters );
|
298 |
}
|
299 |
|
300 |
/**
|
301 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
*/
|
303 |
-
public static function from_consumer_and_token( $consumer, $token, $http_method, $http_url, $parameters =
|
304 |
-
@$parameters or $parameters = array();
|
305 |
$defaults = array(
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
);
|
311 |
if ( $token ) {
|
312 |
$defaults['oauth_token'] = $token->key;
|
@@ -314,15 +460,22 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
314 |
|
315 |
$parameters = array_merge( $defaults, $parameters );
|
316 |
|
317 |
-
return new
|
318 |
}
|
319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
public function set_parameter( $name, $value, $allow_duplicates = true ) {
|
321 |
if ( $allow_duplicates && isset( $this->parameters[ $name ] ) ) {
|
322 |
-
// We have already added parameter(s) with this name, so add to the list
|
323 |
if ( is_scalar( $this->parameters[ $name ] ) ) {
|
324 |
-
// This is the first duplicate, so transform scalar (string)
|
325 |
-
// into an array so we can add the duplicates
|
326 |
$this->parameters[ $name ] = array( $this->parameters[ $name ] );
|
327 |
}
|
328 |
|
@@ -332,28 +485,46 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
332 |
}
|
333 |
}
|
334 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
public function get_parameter( $name ) {
|
336 |
return isset( $this->parameters[ $name ] ) ? $this->parameters[ $name ] : null;
|
337 |
}
|
338 |
|
|
|
|
|
|
|
|
|
|
|
339 |
public function get_parameters() {
|
340 |
return $this->parameters;
|
341 |
}
|
342 |
|
|
|
|
|
|
|
|
|
|
|
343 |
public function unset_parameter( $name ) {
|
344 |
unset( $this->parameters[ $name ] );
|
345 |
}
|
346 |
|
347 |
/**
|
348 |
* The request parameters, sorted and concatenated into a normalized string.
|
|
|
349 |
* @return string
|
350 |
*/
|
351 |
public function get_signable_parameters() {
|
352 |
-
// Grab all parameters
|
353 |
$params = $this->parameters;
|
354 |
|
355 |
-
// Remove oauth_signature if present
|
356 |
-
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
|
357 |
if ( isset( $params['oauth_signature'] ) ) {
|
358 |
unset( $params['oauth_signature'] );
|
359 |
}
|
@@ -372,7 +543,7 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
372 |
$parts = array(
|
373 |
$this->get_normalized_http_method(),
|
374 |
$this->get_normalized_http_url(),
|
375 |
-
$this->get_signable_parameters()
|
376 |
);
|
377 |
|
378 |
$parts = WPOAuthUtil::urlencode_rfc3986( $parts );
|
@@ -381,28 +552,29 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
381 |
}
|
382 |
|
383 |
/**
|
384 |
-
*
|
385 |
*/
|
386 |
public function get_normalized_http_method() {
|
387 |
return strtoupper( $this->http_method );
|
388 |
}
|
389 |
|
390 |
/**
|
391 |
-
*
|
392 |
* scheme://host/path
|
393 |
*/
|
394 |
public function get_normalized_http_url() {
|
395 |
$parts = parse_url( $this->http_url );
|
396 |
|
397 |
$port = isset( $parts['port'] ) ? $parts['port'] : false;
|
398 |
-
$scheme =
|
399 |
-
$host =
|
400 |
-
$path =
|
401 |
|
402 |
-
|
|
|
|
|
403 |
|
404 |
-
if ( ( $scheme
|
405 |
-
|| ( $scheme == 'http' && $port != '80' )
|
406 |
) {
|
407 |
$host = "$host:$port";
|
408 |
}
|
@@ -411,7 +583,7 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
411 |
}
|
412 |
|
413 |
/**
|
414 |
-
*
|
415 |
*/
|
416 |
public function to_url() {
|
417 |
$post_data = $this->to_postdata();
|
@@ -424,14 +596,19 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
424 |
}
|
425 |
|
426 |
/**
|
427 |
-
*
|
428 |
*/
|
429 |
public function to_postdata() {
|
430 |
return WPOAuthUtil::build_http_query( $this->parameters );
|
431 |
}
|
432 |
|
433 |
/**
|
434 |
-
*
|
|
|
|
|
|
|
|
|
|
|
435 |
*/
|
436 |
public function to_header( $realm = null ) {
|
437 |
$first = true;
|
@@ -444,38 +621,55 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
444 |
|
445 |
$total = array();
|
446 |
foreach ( $this->parameters as $k => $v ) {
|
447 |
-
if ( substr( $k, 0, 5 )
|
448 |
continue;
|
449 |
}
|
450 |
if ( is_array( $v ) ) {
|
451 |
throw new WPOAuthException( 'Arrays not supported in headers' );
|
452 |
}
|
453 |
-
$out
|
454 |
-
$out
|
455 |
-
'="' .
|
456 |
-
WPOAuthUtil::urlencode_rfc3986( $v ) .
|
457 |
-
'"';
|
458 |
$first = false;
|
459 |
}
|
460 |
|
461 |
return $out;
|
462 |
}
|
463 |
|
|
|
|
|
|
|
|
|
|
|
464 |
public function __toString() {
|
465 |
return $this->to_url();
|
466 |
}
|
467 |
|
468 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
469 |
public function sign_request( $signature_method, $consumer, $token ) {
|
470 |
$this->set_parameter(
|
471 |
-
|
472 |
$signature_method->get_name(),
|
473 |
false
|
474 |
);
|
475 |
$signature = $this->build_signature( $signature_method, $consumer, $token );
|
476 |
-
$this->set_parameter(
|
477 |
}
|
478 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
479 |
public function build_signature( $signature_method, $consumer, $token ) {
|
480 |
$signature = $signature_method->build_signature( $this, $consumer, $token );
|
481 |
|
@@ -483,59 +677,96 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
483 |
}
|
484 |
|
485 |
/**
|
486 |
-
*
|
|
|
|
|
487 |
*/
|
488 |
private static function generate_timestamp() {
|
489 |
-
// make sure that timestamp is in UTC
|
490 |
date_default_timezone_set( 'UTC' );
|
491 |
|
492 |
return time();
|
493 |
}
|
494 |
|
495 |
/**
|
496 |
-
*
|
|
|
|
|
497 |
*/
|
498 |
private static function generate_nonce() {
|
499 |
$mt = microtime();
|
500 |
$rand = mt_rand();
|
501 |
|
502 |
-
return md5( $mt . $rand ); // md5s look nicer than numbers
|
503 |
}
|
504 |
}
|
505 |
|
|
|
|
|
|
|
506 |
class WPOAuthServer {
|
507 |
-
|
508 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
509 |
protected $signature_methods = array();
|
510 |
|
|
|
|
|
|
|
|
|
|
|
511 |
protected $data_store;
|
512 |
|
|
|
|
|
|
|
|
|
|
|
513 |
function __construct( $data_store ) {
|
514 |
$this->data_store = $data_store;
|
515 |
}
|
516 |
|
|
|
|
|
|
|
|
|
|
|
517 |
public function add_signature_method( $signature_method ) {
|
518 |
-
$this->signature_methods[ $signature_method->get_name() ] =
|
519 |
-
$signature_method;
|
520 |
}
|
521 |
|
522 |
-
// high level functions
|
523 |
-
|
524 |
/**
|
525 |
-
*
|
526 |
-
*
|
|
|
|
|
|
|
527 |
*/
|
528 |
public function fetch_request_token( &$request ) {
|
529 |
$this->get_version( $request );
|
530 |
|
531 |
$consumer = $this->get_consumer( $request );
|
532 |
|
533 |
-
// no token required for the initial token request
|
534 |
$token = null;
|
535 |
|
536 |
$this->check_signature( $request, $consumer, $token );
|
537 |
|
538 |
-
// Rev A change
|
539 |
$callback = $request->get_parameter( 'oauth_callback' );
|
540 |
$new_token = $this->data_store->new_request_token( $consumer, $callback );
|
541 |
|
@@ -543,20 +774,23 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
543 |
}
|
544 |
|
545 |
/**
|
546 |
-
*
|
547 |
-
*
|
|
|
|
|
|
|
548 |
*/
|
549 |
public function fetch_access_token( &$request ) {
|
550 |
$this->get_version( $request );
|
551 |
|
552 |
$consumer = $this->get_consumer( $request );
|
553 |
|
554 |
-
// requires authorized request token
|
555 |
-
$token = $this->get_token( $request, $consumer,
|
556 |
|
557 |
$this->check_signature( $request, $consumer, $token );
|
558 |
|
559 |
-
// Rev A change
|
560 |
$verifier = $request->get_parameter( 'oauth_verifier' );
|
561 |
$new_token = $this->data_store->new_access_token( $token, $consumer, $verifier );
|
562 |
|
@@ -564,26 +798,34 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
564 |
}
|
565 |
|
566 |
/**
|
567 |
-
*
|
|
|
|
|
|
|
|
|
568 |
*/
|
569 |
public function verify_request( &$request ) {
|
570 |
$this->get_version( $request );
|
571 |
$consumer = $this->get_consumer( $request );
|
572 |
-
$token = $this->get_token( $request, $consumer,
|
573 |
$this->check_signature( $request, $consumer, $token );
|
574 |
|
575 |
return array( $consumer, $token );
|
576 |
}
|
577 |
|
578 |
-
// Internals from here
|
579 |
/**
|
580 |
-
*
|
|
|
|
|
|
|
|
|
|
|
581 |
*/
|
582 |
private function get_version( &$request ) {
|
583 |
-
$version = $request->get_parameter(
|
584 |
if ( ! $version ) {
|
585 |
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
|
586 |
-
// Chapter 7.0 ("Accessing Protected
|
587 |
$version = '1.0';
|
588 |
}
|
589 |
if ( $version !== $this->version ) {
|
@@ -594,25 +836,27 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
594 |
}
|
595 |
|
596 |
/**
|
597 |
-
*
|
|
|
|
|
|
|
|
|
|
|
598 |
*/
|
599 |
private function get_signature_method( &$request ) {
|
600 |
-
$signature_method =
|
601 |
-
@$request->get_parameter( "oauth_signature_method" );
|
602 |
|
603 |
if ( ! $signature_method ) {
|
604 |
-
// According to chapter 7 ("Accessing Protected
|
605 |
-
// parameter is required, and we can't just fallback to PLAINTEXT
|
606 |
throw new WPOAuthException( 'No signature method parameter. This parameter is required' );
|
607 |
}
|
608 |
|
609 |
-
if ( ! in_array( $signature_method,
|
610 |
-
array_keys( $this->signature_methods ) )
|
611 |
-
) {
|
612 |
throw new WPOAuthException(
|
613 |
"Signature method '$signature_method' not supported " .
|
614 |
-
|
615 |
-
implode(
|
616 |
);
|
617 |
}
|
618 |
|
@@ -620,30 +864,40 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
620 |
}
|
621 |
|
622 |
/**
|
623 |
-
*
|
|
|
|
|
|
|
|
|
|
|
624 |
*/
|
625 |
private function get_consumer( &$request ) {
|
626 |
-
$consumer_key =
|
627 |
if ( ! $consumer_key ) {
|
628 |
-
throw new WPOAuthException(
|
629 |
}
|
630 |
|
631 |
$consumer = $this->data_store->lookup_consumer( $consumer_key );
|
632 |
if ( ! $consumer ) {
|
633 |
-
throw new WPOAuthException(
|
634 |
}
|
635 |
|
636 |
return $consumer;
|
637 |
}
|
638 |
|
639 |
/**
|
640 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
641 |
*/
|
642 |
-
private function get_token( &$request, $consumer, $token_type =
|
643 |
-
$token_field =
|
644 |
-
$token = $this->data_store->lookup_token(
|
645 |
-
$consumer, $token_type, $token_field
|
646 |
-
);
|
647 |
if ( ! $token ) {
|
648 |
throw new WPOAuthException( "Invalid $token_type token: $token_field" );
|
649 |
}
|
@@ -652,13 +906,18 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
652 |
}
|
653 |
|
654 |
/**
|
655 |
-
*
|
656 |
* should guess the signature method appropriately
|
|
|
|
|
|
|
|
|
|
|
657 |
*/
|
658 |
private function check_signature( &$request, $consumer, $token ) {
|
659 |
-
// this should probably be in a different method
|
660 |
-
$timestamp =
|
661 |
-
$nonce =
|
662 |
|
663 |
$this->check_timestamp( $timestamp );
|
664 |
$this->check_nonce( $consumer, $token, $nonce, $timestamp );
|
@@ -674,12 +933,15 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
674 |
);
|
675 |
|
676 |
if ( ! $valid_sig ) {
|
677 |
-
throw new WPOAuthException(
|
678 |
}
|
679 |
}
|
680 |
|
681 |
/**
|
682 |
-
*
|
|
|
|
|
|
|
683 |
*/
|
684 |
private function check_timestamp( $timestamp ) {
|
685 |
if ( ! $timestamp ) {
|
@@ -688,7 +950,7 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
688 |
);
|
689 |
}
|
690 |
|
691 |
-
// verify that timestamp is recentish
|
692 |
$now = time();
|
693 |
if ( abs( $now - $timestamp ) > $this->timestamp_threshold ) {
|
694 |
throw new WPOAuthException(
|
@@ -698,16 +960,20 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
698 |
}
|
699 |
|
700 |
/**
|
701 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
702 |
*/
|
703 |
private function check_nonce( $consumer, $token, $nonce, $timestamp ) {
|
704 |
if ( ! $nonce ) {
|
705 |
-
throw new WPOAuthException(
|
706 |
-
'Missing nonce parameter. The parameter is required'
|
707 |
-
);
|
708 |
}
|
709 |
|
710 |
-
// verify that the nonce is uniqueish
|
711 |
$found = $this->data_store->lookup_nonce(
|
712 |
$consumer,
|
713 |
$token,
|
@@ -721,37 +987,79 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
721 |
|
722 |
}
|
723 |
|
|
|
|
|
|
|
724 |
class WPOAuthDataStore {
|
|
|
|
|
|
|
|
|
|
|
725 |
function lookup_consumer( $consumer_key ) {
|
726 |
-
// implement me
|
727 |
}
|
728 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
729 |
function lookup_token( $consumer, $token_type, $token ) {
|
730 |
-
// implement me
|
731 |
}
|
732 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
733 |
function lookup_nonce( $consumer, $token, $nonce, $timestamp ) {
|
734 |
-
// implement me
|
735 |
}
|
736 |
-
|
|
|
|
|
|
|
|
|
|
|
737 |
function new_request_token( $consumer, $callback = null ) {
|
738 |
-
// return a new token attached to this consumer
|
739 |
}
|
740 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
741 |
function new_access_token( $token, $consumer, $verifier = null ) {
|
742 |
-
// return a new access token attached to this consumer
|
743 |
-
// for the user associated with this token if the request token
|
744 |
-
// is authorized
|
745 |
-
// should also invalidate the request token
|
746 |
}
|
747 |
|
748 |
}
|
749 |
|
|
|
|
|
|
|
750 |
class WPOAuthUtil {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
751 |
public static function urlencode_rfc3986( $input ) {
|
752 |
if ( is_array( $input ) ) {
|
753 |
return array_map( array( 'WPOAuthUtil', 'urlencode_rfc3986' ), $input );
|
754 |
-
}
|
755 |
return str_replace(
|
756 |
'+',
|
757 |
' ',
|
@@ -763,16 +1071,29 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
763 |
}
|
764 |
|
765 |
|
766 |
-
|
767 |
-
|
768 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
769 |
public static function urldecode_rfc3986( $string ) {
|
770 |
return urldecode( $string );
|
771 |
}
|
772 |
|
773 |
-
|
774 |
-
|
775 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
776 |
public static function split_header( $header, $only_allow_oauth_parameters = true ) {
|
777 |
$pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
|
778 |
$offset = 0;
|
@@ -794,29 +1115,32 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
794 |
return $params;
|
795 |
}
|
796 |
|
797 |
-
|
|
|
|
|
|
|
|
|
798 |
public static function get_headers() {
|
799 |
if ( function_exists( 'apache_request_headers' ) ) {
|
800 |
-
// we need this to get the actual Authorization: header
|
801 |
-
// because apache tends to tell us it doesn't exist
|
802 |
$headers = apache_request_headers();
|
803 |
|
804 |
-
// sanitize the output of apache_request_headers because
|
805 |
-
// we always want the keys to be Cased-Like-This and arh()
|
806 |
-
// returns the headers in the same case as they are in the
|
807 |
-
// request
|
808 |
$out = array();
|
809 |
-
foreach ( $headers
|
810 |
$key = str_replace(
|
811 |
-
|
812 |
-
|
813 |
-
ucwords( strtolower( str_replace(
|
814 |
);
|
815 |
$out[ $key ] = $value;
|
816 |
}
|
817 |
} else {
|
818 |
-
// otherwise we don't have apache and are just going to have to hope
|
819 |
-
// that $_SERVER actually contains what we need
|
820 |
$out = array();
|
821 |
if ( isset( $_SERVER['CONTENT_TYPE'] ) ) {
|
822 |
$out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
|
@@ -826,14 +1150,14 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
826 |
}
|
827 |
|
828 |
foreach ( $_SERVER as $key => $value ) {
|
829 |
-
if ( substr( $key, 0, 5 ) ==
|
830 |
-
// this is chaos, basically it is just there to capitalize the first
|
831 |
-
// letter of every word that is not an initial HTTP and strip HTTP
|
832 |
-
// code from przemek
|
833 |
$key = str_replace(
|
834 |
-
|
835 |
-
|
836 |
-
ucwords( strtolower( str_replace(
|
837 |
);
|
838 |
$out[ $key ] = $value;
|
839 |
}
|
@@ -843,9 +1167,15 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
843 |
return $out;
|
844 |
}
|
845 |
|
846 |
-
|
847 |
-
|
848 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
849 |
public static function parse_parameters( $input ) {
|
850 |
if ( ! isset( $input ) || ! $input ) {
|
851 |
return array();
|
@@ -860,12 +1190,11 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
860 |
$value = isset( $split[1] ) ? WPOAuthUtil::urldecode_rfc3986( $split[1] ) : '';
|
861 |
|
862 |
if ( isset( $parsed_parameters[ $parameter ] ) ) {
|
863 |
-
// We have already recieved parameter(s) with this name, so add to the list
|
864 |
-
// of parameters with this name
|
865 |
-
|
866 |
if ( is_scalar( $parsed_parameters[ $parameter ] ) ) {
|
867 |
-
// This is the first duplicate, so transform scalar (string) into an array
|
868 |
-
// so we can add the duplicates
|
869 |
$parsed_parameters[ $parameter ] = array( $parsed_parameters[ $parameter ] );
|
870 |
}
|
871 |
|
@@ -878,25 +1207,32 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
878 |
return $parsed_parameters;
|
879 |
}
|
880 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
881 |
public static function build_http_query( $params ) {
|
882 |
if ( ! $params ) {
|
883 |
return '';
|
884 |
}
|
885 |
|
886 |
-
// Urlencode both keys and values
|
887 |
$keys = WPOAuthUtil::urlencode_rfc3986( array_keys( $params ) );
|
888 |
$values = WPOAuthUtil::urlencode_rfc3986( array_values( $params ) );
|
889 |
$params = array_combine( $keys, $values );
|
890 |
|
891 |
// Parameters are sorted by name, using lexicographical byte value ordering.
|
892 |
-
// Ref: Spec: 9.1.1 (1)
|
893 |
uksort( $params, 'strcmp' );
|
894 |
|
895 |
$pairs = array();
|
896 |
foreach ( $params as $parameter => $value ) {
|
897 |
if ( is_array( $value ) ) {
|
898 |
-
// If two or more parameters share the same name, they are sorted by their value
|
899 |
-
// Ref: Spec: 9.1.1 (1)
|
900 |
natsort( $value );
|
901 |
foreach ( $value as $duplicate_value ) {
|
902 |
$pairs[] = $parameter . '=' . $duplicate_value;
|
@@ -905,10 +1241,9 @@ if ( ! class_exists( 'WPOAuthException' ) ) {
|
|
905 |
$pairs[] = $parameter . '=' . $value;
|
906 |
}
|
907 |
}
|
908 |
-
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
|
909 |
-
// Each name-value pair is separated by an '&' character (ASCII code 38)
|
910 |
return implode( '&', $pairs );
|
911 |
}
|
912 |
}
|
913 |
-
|
914 |
-
} // class_exists check
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP OAuth class adapted from Abraham.
|
4 |
+
*
|
5 |
+
* @package WP to Twitter
|
6 |
+
* @author Joe Dolson
|
7 |
+
* @copyright 2012-2018 Joe Dolson
|
8 |
+
* @license GPL-2.0+
|
9 |
+
*/
|
10 |
+
|
11 |
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
exit;
|
13 |
+
}
|
14 |
|
15 |
if ( ! class_exists( 'WPOAuthException' ) ) {
|
16 |
|
17 |
+
/**
|
18 |
+
* Generic OAuth class
|
19 |
+
*/
|
20 |
+
class WP_OAuth {
|
21 |
+
// Honestly, this is only here so I don't have to rename the file.
|
22 |
+
}
|
23 |
+
/**
|
24 |
+
* Generic exception class
|
25 |
*/
|
|
|
26 |
class WPOAuthException extends Exception {
|
27 |
+
// pass.
|
28 |
}
|
29 |
|
30 |
+
/**
|
31 |
+
* Create Consumer key
|
32 |
+
*/
|
33 |
class WPOAuthConsumer {
|
34 |
+
/**
|
35 |
+
* Contains the user's Consumer key.
|
36 |
+
*
|
37 |
+
* @var consumer key
|
38 |
+
*/
|
39 |
public $key;
|
40 |
+
/**
|
41 |
+
* Contains the user's consumer secret.
|
42 |
+
*
|
43 |
+
* @var secret
|
44 |
+
*/
|
45 |
public $secret;
|
46 |
|
47 |
+
/**
|
48 |
+
* Constructor.
|
49 |
+
*
|
50 |
+
* @param string $key Key.
|
51 |
+
* @param string $secret Secret.
|
52 |
+
* @param string $callback_url Response sent to.
|
53 |
+
*/
|
54 |
function __construct( $key, $secret, $callback_url = null ) {
|
55 |
$this->key = $key;
|
56 |
$this->secret = $secret;
|
57 |
$this->callback_url = $callback_url;
|
58 |
}
|
59 |
|
60 |
+
/**
|
61 |
+
* Generate consumer string.
|
62 |
+
*/
|
63 |
function __toString() {
|
64 |
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
|
65 |
}
|
66 |
}
|
67 |
|
68 |
+
/**
|
69 |
+
* Create consumer token.
|
70 |
+
*/
|
71 |
class WPOAuthToken {
|
72 |
+
/**
|
73 |
+
* Access token
|
74 |
+
*
|
75 |
+
* @var token
|
76 |
+
*/
|
77 |
public $key;
|
78 |
+
/**
|
79 |
+
* Access secret.
|
80 |
+
*
|
81 |
+
* @var secret
|
82 |
+
*/
|
83 |
public $secret;
|
84 |
|
85 |
/**
|
86 |
+
* Construct token.
|
87 |
+
*
|
88 |
+
* @param string $key = the token.
|
89 |
+
* @param string $secret = the token secret.
|
90 |
*/
|
91 |
function __construct( $key, $secret ) {
|
92 |
$this->key = $key;
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
+
* Generates the basic string serialization of a token that a server
|
98 |
* would respond to request_token and access_token calls with
|
99 |
+
*
|
100 |
+
* @return string Oauth serialization.
|
101 |
*/
|
102 |
function to_string() {
|
103 |
+
return 'oauth_token=' . WPOAuthUtil::urlencode_rfc3986( $this->key ) . '&oauth_token_secret=' . WPOAuthUtil::urlencode_rfc3986( $this->secret );
|
|
|
|
|
|
|
104 |
}
|
105 |
|
106 |
+
/**
|
107 |
+
* Return string.
|
108 |
+
*/
|
109 |
function __toString() {
|
110 |
return $this->to_string();
|
111 |
}
|
118 |
abstract class WPOAuthSignatureMethod {
|
119 |
/**
|
120 |
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
121 |
+
*
|
122 |
* @return string
|
123 |
*/
|
124 |
abstract public function get_name();
|
129 |
* the encoding is handled in OAuthRequest when the final
|
130 |
* request is serialized
|
131 |
*
|
132 |
+
* @param OAuthRequest $request OAuth Request object.
|
133 |
+
* @param OAuthConsumer $consumer OAuth Consumer key.
|
134 |
+
* @param OAuthToken $token OAuth Consumer token.
|
135 |
*
|
136 |
* @return string
|
137 |
*/
|
140 |
/**
|
141 |
* Verifies that a given signature is correct
|
142 |
*
|
143 |
+
* @param OAuthRequest $request Request.
|
144 |
+
* @param OAuthConsumer $consumer Consumer key.
|
145 |
+
* @param OAuthToken $token Auth token.
|
146 |
+
* @param string $signature Signature.
|
147 |
*
|
148 |
* @return bool
|
149 |
*/
|
159 |
* where the Signature Base String is the text and the key is the concatenated values (each first
|
160 |
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
161 |
* character (ASCII code 38) even if empty.
|
162 |
+
* - Chapter 9.2 ("HMAC-SHA1")
|
163 |
*/
|
164 |
class WPOAuthSignatureMethod_HMAC_SHA1 extends WPOAuthSignatureMethod {
|
165 |
+
/**
|
166 |
+
* Signature method.
|
167 |
+
*/
|
168 |
function get_name() {
|
169 |
+
return 'HMAC-SHA1';
|
170 |
}
|
171 |
|
172 |
+
/**
|
173 |
+
* Build a signature.
|
174 |
+
*
|
175 |
+
* @param object $request Request object.
|
176 |
+
* @param object $consumer Consumer object.
|
177 |
+
* @param string $token Token.
|
178 |
+
*
|
179 |
+
* @return base 64 signature.
|
180 |
+
*/
|
181 |
public function build_signature( $request, $consumer, $token ) {
|
182 |
$base_string = $request->get_signature_base_string();
|
183 |
$request->base_string = $base_string;
|
184 |
|
185 |
+
$key_parts = array( $consumer->secret, ( $token ) ? $token->secret : '' );
|
|
|
|
|
|
|
|
|
186 |
$key_parts = WPOAuthUtil::urlencode_rfc3986( $key_parts );
|
187 |
$key = implode( '&', $key_parts );
|
188 |
|
196 |
* - Chapter 9.4 ("PLAINTEXT")
|
197 |
*/
|
198 |
class WPOAuthSignatureMethod_PLAINTEXT extends WPOAuthSignatureMethod {
|
199 |
+
/**
|
200 |
+
* Plaintext method.
|
201 |
+
*/
|
202 |
public function get_name() {
|
203 |
+
return 'PLAINTEXT';
|
204 |
}
|
205 |
|
206 |
/**
|
207 |
+
* The oauth_signature is set to the concatenated encoded values of the Consumer Secret and
|
208 |
* Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
|
209 |
* empty. The result MUST be encoded again.
|
210 |
* - Chapter 9.4.1 ("Generating Signatures")
|
211 |
*
|
212 |
+
* @param object $request Request object.
|
213 |
+
* @param object $consumer Consumer object.
|
214 |
+
* @param string $token Token.
|
215 |
+
*
|
216 |
+
* @return signature.
|
217 |
+
*
|
218 |
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
219 |
* OAuthRequest handles this!
|
220 |
*/
|
221 |
public function build_signature( $request, $consumer, $token ) {
|
222 |
+
$key_parts = array( $consumer->secret, ( $token ) ? $token->secret : '' );
|
|
|
|
|
|
|
223 |
|
224 |
$key_parts = WPOAuthUtil::urlencode_rfc3986( $key_parts );
|
225 |
$key = implode( '&', $key_parts );
|
235 |
* EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
|
236 |
* verified way to the Service Provider, in a manner which is beyond the scope of this
|
237 |
* specification.
|
238 |
+
* - Chapter 9.3 ("RSA-SHA1")
|
239 |
*/
|
240 |
abstract class WPOAuthSignatureMethod_RSA_SHA1 extends WPOAuthSignatureMethod {
|
241 |
+
/**
|
242 |
+
* Return method.
|
243 |
+
*/
|
244 |
public function get_name() {
|
245 |
+
return 'RSA-SHA1';
|
246 |
}
|
247 |
|
248 |
+
/**
|
249 |
+
* Up to the SP to implement this lookup of keys. Possible ideas are:
|
250 |
+
* ((1) do a lookup in a table of trusted certs keyed off of consumer.
|
251 |
+
* (2) fetch via http using a url provided by the requester.
|
252 |
+
* (3) some sort of specific discovery code based on request.
|
253 |
+
*
|
254 |
+
* @param Object $request Request.
|
255 |
+
*
|
256 |
+
* Either way should return a string representation of the certificate.
|
257 |
+
*/
|
258 |
protected abstract function fetch_public_cert( &$request );
|
259 |
|
260 |
+
/**
|
261 |
+
* Up to the SP to implement this lookup of keys. Possible ideas are:
|
262 |
+
* (1) do a lookup in a table of trusted certs keyed off of consumer.
|
263 |
+
*
|
264 |
+
* @param Object $request Request.
|
265 |
+
*
|
266 |
+
* @return Either way should return a string representation of the certificate.
|
267 |
+
*/
|
268 |
protected abstract function fetch_private_cert( &$request );
|
269 |
|
270 |
+
/**
|
271 |
+
* Build a signature object.
|
272 |
+
*
|
273 |
+
* @param object $request Request object.
|
274 |
+
* @param object $consumer Consumer object.
|
275 |
+
* @param string $token Token.
|
276 |
+
*
|
277 |
+
* @return Encoded signature.
|
278 |
+
*/
|
279 |
public function build_signature( $request, $consumer, $token ) {
|
280 |
$base_string = $request->get_signature_base_string();
|
281 |
$request->base_string = $base_string;
|
282 |
|
283 |
+
// Fetch the private key cert based on the request.
|
284 |
$cert = $this->fetch_private_cert( $request );
|
285 |
|
286 |
+
// Pull the private key ID from the certificate.
|
287 |
$privatekeyid = openssl_get_privatekey( $cert );
|
288 |
|
289 |
+
// Sign using the key.
|
290 |
$ok = openssl_sign( $base_string, $signature, $privatekeyid );
|
291 |
|
292 |
+
// Release the key resource.
|
293 |
openssl_free_key( $privatekeyid );
|
294 |
|
295 |
return base64_encode( $signature );
|
296 |
}
|
297 |
|
298 |
+
/**
|
299 |
+
* Verify a signature object.
|
300 |
+
*
|
301 |
+
* @param object $request Request object.
|
302 |
+
* @param object $consumer Consumer object.
|
303 |
+
* @param string $token Token.
|
304 |
+
* @param string $signature Signature.
|
305 |
+
*
|
306 |
+
* @return boolean acceptance.
|
307 |
+
*/
|
308 |
public function check_signature( $request, $consumer, $token, $signature ) {
|
309 |
$decoded_sig = base64_decode( $signature );
|
310 |
|
311 |
$base_string = $request->get_signature_base_string();
|
312 |
|
313 |
+
// Fetch the public key cert based on the request.
|
314 |
$cert = $this->fetch_public_cert( $request );
|
315 |
|
316 |
+
// Pull the public key ID from the certificate.
|
317 |
$publickeyid = openssl_get_publickey( $cert );
|
318 |
|
319 |
+
// Check the computed signature against the one passed in the query.
|
320 |
$ok = openssl_verify( $base_string, $decoded_sig, $publickeyid );
|
321 |
|
322 |
+
// Release the key resource.
|
323 |
openssl_free_key( $publickeyid );
|
324 |
|
325 |
+
return 1 == $ok;
|
326 |
}
|
327 |
}
|
328 |
|
329 |
+
/**
|
330 |
+
* Construct and send the OAuth Request to the target URL.
|
331 |
+
*/
|
332 |
+
class WP_Oauth_Request {
|
333 |
+
/**
|
334 |
+
* Query parameters
|
335 |
+
*
|
336 |
+
* @var parameters
|
337 |
+
*/
|
338 |
private $parameters;
|
339 |
+
|
340 |
+
/**
|
341 |
+
* HTTP query method.
|
342 |
+
*
|
343 |
+
* @var http_method
|
344 |
+
*/
|
345 |
private $http_method;
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Target URL
|
349 |
+
*
|
350 |
+
* @var http_url
|
351 |
+
*/
|
352 |
private $http_url;
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Base string - base for signature string.
|
356 |
+
*
|
357 |
+
* @var base_string
|
358 |
+
*/
|
359 |
public $base_string;
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Version.
|
363 |
+
*
|
364 |
+
* @var version
|
365 |
+
*/
|
366 |
public static $version = '1.0';
|
|
|
367 |
|
368 |
+
/**
|
369 |
+
* POST input - source of input.
|
370 |
+
*
|
371 |
+
* @var post_input
|
372 |
+
*/
|
373 |
+
public static $post_input = 'php://input';
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Constructor function. Build properties.
|
377 |
+
*
|
378 |
+
* @param string $http_method Method.
|
379 |
+
* @param string $http_url URL.
|
380 |
+
* @param array $parameters Query parameters; will be combined with POST data.
|
381 |
+
*/
|
382 |
+
function __construct( $http_method, $http_url, $parameters = array() ) {
|
383 |
$parameters = array_merge( WPOAuthUtil::parse_parameters( parse_url( $http_url, PHP_URL_QUERY ) ), $parameters );
|
384 |
$this->parameters = $parameters;
|
385 |
$this->http_method = $http_method;
|
386 |
$this->http_url = $http_url;
|
387 |
}
|
388 |
|
|
|
389 |
/**
|
390 |
+
* Attempt to build up a request from what was passed to the server
|
391 |
+
*
|
392 |
+
* @param string $http_method Method.
|
393 |
+
* @param string $http_url URL.
|
394 |
+
* @param array $parameters Query parameters.
|
395 |
+
*
|
396 |
+
* @return WP_Oauth_Request object.
|
397 |
*/
|
398 |
public static function from_request( $http_method = null, $http_url = null, $parameters = null ) {
|
399 |
+
$scheme = ( ! isset( $_SERVER['HTTPS'] ) || 'on' != $_SERVER['HTTPS'] ) ? 'http' : 'https';
|
400 |
+
if ( null === $http_url ) {
|
401 |
+
$http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
|
402 |
+
}
|
403 |
+
if ( null === $http_method ) {
|
404 |
+
$http_method = $_SERVER['REQUEST_METHOD'];
|
405 |
+
}
|
406 |
+
|
407 |
+
// We weren't handed any parameters, so let's find the ones relevant to this request.
|
408 |
+
// If you run XML-RPC or similar you should use this to provide your own parsed parameter-list.
|
|
|
|
|
|
|
|
|
409 |
if ( ! $parameters ) {
|
410 |
+
// Find request headers.
|
411 |
$request_headers = WPOAuthUtil::get_headers();
|
412 |
|
413 |
+
// Parse the query-string to find GET parameters.
|
414 |
$parameters = WPOAuthUtil::parse_parameters( $_SERVER['QUERY_STRING'] );
|
415 |
|
416 |
+
// It's a POST request of the proper content-type, so parse POST.
|
417 |
+
// parameters and add those overriding any duplicates from GET.
|
418 |
+
$content_type = isset( $request_headers['Content-Type'] ) ? $request_headers['Content-Type'] : '';
|
419 |
+
if ( 'POST' == $http_method && strstr( $content_type, 'application/x-www-form-urlencoded' ) ) {
|
|
|
|
|
420 |
$post_data = WPOAuthUtil::parse_parameters(
|
421 |
+
file_get_contents( self::$post_input )
|
422 |
);
|
423 |
$parameters = array_merge( $parameters, $post_data );
|
424 |
}
|
425 |
|
426 |
+
// We have a Authorization-header with OAuth data. Parse the header.
|
427 |
+
// and add those overriding any duplicates from GET or POST.
|
428 |
+
$authorization = isset( $request_headers['Authorization'] ) ? $request_headers['Authorization'] : '';
|
429 |
+
if ( 'OAuth ' == substr( $authorization, 0, 6 ) ) {
|
430 |
$header_parameters = WPOAuthUtil::split_header(
|
431 |
$request_headers['Authorization']
|
432 |
);
|
433 |
$parameters = array_merge( $parameters, $header_parameters );
|
434 |
}
|
|
|
435 |
}
|
436 |
+
return new WP_Oauth_Request( $http_method, $http_url, $parameters );
|
|
|
437 |
}
|
438 |
|
439 |
/**
|
440 |
+
* Helper function to set up the request
|
441 |
+
*
|
442 |
+
* @param object $consumer Consumer token.
|
443 |
+
* @param object $token API token.
|
444 |
+
* @param string $http_method Method.
|
445 |
+
* @param string $http_url URL.
|
446 |
+
* @param array $parameters Query parameters.
|
447 |
+
*
|
448 |
+
* @return object WP_Oauth_Request object.
|
449 |
*/
|
450 |
+
public static function from_consumer_and_token( $consumer, $token, $http_method, $http_url, $parameters = array() ) {
|
|
|
451 |
$defaults = array(
|
452 |
+
'oauth_version' => WP_Oauth_Request::$version,
|
453 |
+
'oauth_nonce' => WP_Oauth_Request::generate_nonce(),
|
454 |
+
'oauth_timestamp' => WP_Oauth_Request::generate_timestamp(),
|
455 |
+
'oauth_consumer_key' => $consumer->key,
|
456 |
);
|
457 |
if ( $token ) {
|
458 |
$defaults['oauth_token'] = $token->key;
|
460 |
|
461 |
$parameters = array_merge( $defaults, $parameters );
|
462 |
|
463 |
+
return new WP_Oauth_Request( $http_method, $http_url, $parameters );
|
464 |
}
|
465 |
|
466 |
+
/**
|
467 |
+
* Construct parameters for query.
|
468 |
+
*
|
469 |
+
* @param string $name Parameter name string.
|
470 |
+
* @param string $value Parameter value.
|
471 |
+
* @param boolean $allow_duplicates Should we allow duplicate parameter names.
|
472 |
+
*/
|
473 |
public function set_parameter( $name, $value, $allow_duplicates = true ) {
|
474 |
if ( $allow_duplicates && isset( $this->parameters[ $name ] ) ) {
|
475 |
+
// We have already added parameter(s) with this name, so add to the list.
|
476 |
if ( is_scalar( $this->parameters[ $name ] ) ) {
|
477 |
+
// This is the first duplicate, so transform scalar (string).
|
478 |
+
// into an array so we can add the duplicates.
|
479 |
$this->parameters[ $name ] = array( $this->parameters[ $name ] );
|
480 |
}
|
481 |
|
485 |
}
|
486 |
}
|
487 |
|
488 |
+
/**
|
489 |
+
* Get a parameter by name.
|
490 |
+
*
|
491 |
+
* @param string $name Parameter name.
|
492 |
+
*
|
493 |
+
* @return Parameter value.
|
494 |
+
*/
|
495 |
public function get_parameter( $name ) {
|
496 |
return isset( $this->parameters[ $name ] ) ? $this->parameters[ $name ] : null;
|
497 |
}
|
498 |
|
499 |
+
/**
|
500 |
+
* Get all current parameters.
|
501 |
+
*
|
502 |
+
* @return Parameters.
|
503 |
+
*/
|
504 |
public function get_parameters() {
|
505 |
return $this->parameters;
|
506 |
}
|
507 |
|
508 |
+
/**
|
509 |
+
* Remove a parameter.
|
510 |
+
*
|
511 |
+
* @param string $name Parameter name.
|
512 |
+
*/
|
513 |
public function unset_parameter( $name ) {
|
514 |
unset( $this->parameters[ $name ] );
|
515 |
}
|
516 |
|
517 |
/**
|
518 |
* The request parameters, sorted and concatenated into a normalized string.
|
519 |
+
*
|
520 |
* @return string
|
521 |
*/
|
522 |
public function get_signable_parameters() {
|
523 |
+
// Grab all parameters.
|
524 |
$params = $this->parameters;
|
525 |
|
526 |
+
// Remove oauth_signature if present.
|
527 |
+
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.").
|
528 |
if ( isset( $params['oauth_signature'] ) ) {
|
529 |
unset( $params['oauth_signature'] );
|
530 |
}
|
543 |
$parts = array(
|
544 |
$this->get_normalized_http_method(),
|
545 |
$this->get_normalized_http_url(),
|
546 |
+
$this->get_signable_parameters(),
|
547 |
);
|
548 |
|
549 |
$parts = WPOAuthUtil::urlencode_rfc3986( $parts );
|
552 |
}
|
553 |
|
554 |
/**
|
555 |
+
* Just uppercases the http method
|
556 |
*/
|
557 |
public function get_normalized_http_method() {
|
558 |
return strtoupper( $this->http_method );
|
559 |
}
|
560 |
|
561 |
/**
|
562 |
+
* Parses the url and rebuilds it to be
|
563 |
* scheme://host/path
|
564 |
*/
|
565 |
public function get_normalized_http_url() {
|
566 |
$parts = parse_url( $this->http_url );
|
567 |
|
568 |
$port = isset( $parts['port'] ) ? $parts['port'] : false;
|
569 |
+
$scheme = isset( $parts['scheme'] ) ? $parts['scheme'] : '';
|
570 |
+
$host = isset( $parts['host'] ) ? $parts['host'] : '';
|
571 |
+
$path = isset( $parts['path'] ) ? $parts['path'] : '';
|
572 |
|
573 |
+
if ( ! $port ) {
|
574 |
+
$port = ( 'https' == $scheme ) ? '443' : '80';
|
575 |
+
}
|
576 |
|
577 |
+
if ( ( 'https' == $scheme && '443' != $port ) || ( 'http' == $scheme && '80' != $port )
|
|
|
578 |
) {
|
579 |
$host = "$host:$port";
|
580 |
}
|
583 |
}
|
584 |
|
585 |
/**
|
586 |
+
* Builds a url usable for a GET request
|
587 |
*/
|
588 |
public function to_url() {
|
589 |
$post_data = $this->to_postdata();
|
596 |
}
|
597 |
|
598 |
/**
|
599 |
+
* Builds the data one would send in a POST request
|
600 |
*/
|
601 |
public function to_postdata() {
|
602 |
return WPOAuthUtil::build_http_query( $this->parameters );
|
603 |
}
|
604 |
|
605 |
/**
|
606 |
+
* Builds the Authorization: header
|
607 |
+
*
|
608 |
+
* @param string $realm If realm not null.
|
609 |
+
* @throws WPOAuthException Exception message.
|
610 |
+
*
|
611 |
+
* @return Header string.
|
612 |
*/
|
613 |
public function to_header( $realm = null ) {
|
614 |
$first = true;
|
621 |
|
622 |
$total = array();
|
623 |
foreach ( $this->parameters as $k => $v ) {
|
624 |
+
if ( 'oauth' != substr( $k, 0, 5 ) ) {
|
625 |
continue;
|
626 |
}
|
627 |
if ( is_array( $v ) ) {
|
628 |
throw new WPOAuthException( 'Arrays not supported in headers' );
|
629 |
}
|
630 |
+
$out .= ( $first ) ? ' ' : ',';
|
631 |
+
$out .= WPOAuthUtil::urlencode_rfc3986( $k ) . '="' . WPOAuthUtil::urlencode_rfc3986( $v ) . '"';
|
|
|
|
|
|
|
632 |
$first = false;
|
633 |
}
|
634 |
|
635 |
return $out;
|
636 |
}
|
637 |
|
638 |
+
/**
|
639 |
+
* Convert object to URL string.
|
640 |
+
*
|
641 |
+
* @return string URL.
|
642 |
+
*/
|
643 |
public function __toString() {
|
644 |
return $this->to_url();
|
645 |
}
|
646 |
|
647 |
+
/**
|
648 |
+
* Sign the OAuth request.
|
649 |
+
*
|
650 |
+
* @param string $signature_method Method to use to sign.
|
651 |
+
* @param object $consumer Consumer object.
|
652 |
+
* @param object $token Token object.
|
653 |
+
*/
|
654 |
public function sign_request( $signature_method, $consumer, $token ) {
|
655 |
$this->set_parameter(
|
656 |
+
'oauth_signature_method',
|
657 |
$signature_method->get_name(),
|
658 |
false
|
659 |
);
|
660 |
$signature = $this->build_signature( $signature_method, $consumer, $token );
|
661 |
+
$this->set_parameter( 'oauth_signature', $signature, false );
|
662 |
}
|
663 |
|
664 |
+
/**
|
665 |
+
* Create the OAuth signature.
|
666 |
+
*
|
667 |
+
* @param string $signature_method Method to use to sign.
|
668 |
+
* @param object $consumer Consumer object.
|
669 |
+
* @param object $token Token object.
|
670 |
+
*
|
671 |
+
* @return signature.
|
672 |
+
*/
|
673 |
public function build_signature( $signature_method, $consumer, $token ) {
|
674 |
$signature = $signature_method->build_signature( $this, $consumer, $token );
|
675 |
|
677 |
}
|
678 |
|
679 |
/**
|
680 |
+
* Util function: current timestamp
|
681 |
+
*
|
682 |
+
* @return current time.
|
683 |
*/
|
684 |
private static function generate_timestamp() {
|
685 |
+
// make sure that timestamp is in UTC.
|
686 |
date_default_timezone_set( 'UTC' );
|
687 |
|
688 |
return time();
|
689 |
}
|
690 |
|
691 |
/**
|
692 |
+
* Util function: current nonce
|
693 |
+
*
|
694 |
+
* @return md5 string.
|
695 |
*/
|
696 |
private static function generate_nonce() {
|
697 |
$mt = microtime();
|
698 |
$rand = mt_rand();
|
699 |
|
700 |
+
return md5( $mt . $rand ); // md5s look nicer than numbers.
|
701 |
}
|
702 |
}
|
703 |
|
704 |
+
/**
|
705 |
+
* Query to OAuth server.
|
706 |
+
*/
|
707 |
class WPOAuthServer {
|
708 |
+
/**
|
709 |
+
* Limit on timestamp inconsistencies.
|
710 |
+
*
|
711 |
+
* @var $timestamp_threshold
|
712 |
+
*/
|
713 |
+
protected $timestamp_threshold = 300; // in seconds, five minutes.
|
714 |
+
/**
|
715 |
+
* Version
|
716 |
+
*
|
717 |
+
* @var $version
|
718 |
+
*/
|
719 |
+
protected $version = '1.0'; // hi blaine.
|
720 |
+
/**
|
721 |
+
* Array of methods usable.
|
722 |
+
*
|
723 |
+
* @var $signature_methods
|
724 |
+
*/
|
725 |
protected $signature_methods = array();
|
726 |
|
727 |
+
/**
|
728 |
+
* Storage variable.
|
729 |
+
*
|
730 |
+
* @var $data_store
|
731 |
+
*/
|
732 |
protected $data_store;
|
733 |
|
734 |
+
/**
|
735 |
+
* Build data store.
|
736 |
+
*
|
737 |
+
* @param object $data_store Data store.
|
738 |
+
*/
|
739 |
function __construct( $data_store ) {
|
740 |
$this->data_store = $data_store;
|
741 |
}
|
742 |
|
743 |
+
/**
|
744 |
+
* Add a signature method.
|
745 |
+
*
|
746 |
+
* @param object $signature_method Signature method.
|
747 |
+
*/
|
748 |
public function add_signature_method( $signature_method ) {
|
749 |
+
$this->signature_methods[ $signature_method->get_name() ] = $signature_method;
|
|
|
750 |
}
|
751 |
|
|
|
|
|
752 |
/**
|
753 |
+
* Process a request_token request
|
754 |
+
*
|
755 |
+
* @param object $request Request object.
|
756 |
+
*
|
757 |
+
* @return new token.
|
758 |
*/
|
759 |
public function fetch_request_token( &$request ) {
|
760 |
$this->get_version( $request );
|
761 |
|
762 |
$consumer = $this->get_consumer( $request );
|
763 |
|
764 |
+
// no token required for the initial token request.
|
765 |
$token = null;
|
766 |
|
767 |
$this->check_signature( $request, $consumer, $token );
|
768 |
|
769 |
+
// Rev A change.
|
770 |
$callback = $request->get_parameter( 'oauth_callback' );
|
771 |
$new_token = $this->data_store->new_request_token( $consumer, $callback );
|
772 |
|
774 |
}
|
775 |
|
776 |
/**
|
777 |
+
* Process an access_token request
|
778 |
+
*
|
779 |
+
* @param object $request Request object.
|
780 |
+
*
|
781 |
+
* @return new token.
|
782 |
*/
|
783 |
public function fetch_access_token( &$request ) {
|
784 |
$this->get_version( $request );
|
785 |
|
786 |
$consumer = $this->get_consumer( $request );
|
787 |
|
788 |
+
// requires authorized request token.
|
789 |
+
$token = $this->get_token( $request, $consumer, 'request' );
|
790 |
|
791 |
$this->check_signature( $request, $consumer, $token );
|
792 |
|
793 |
+
// Rev A change.
|
794 |
$verifier = $request->get_parameter( 'oauth_verifier' );
|
795 |
$new_token = $this->data_store->new_access_token( $token, $consumer, $verifier );
|
796 |
|
798 |
}
|
799 |
|
800 |
/**
|
801 |
+
* Verify an api call, checks all the parameters
|
802 |
+
*
|
803 |
+
* @param object $request Request object.
|
804 |
+
*
|
805 |
+
* @return consumer & token.
|
806 |
*/
|
807 |
public function verify_request( &$request ) {
|
808 |
$this->get_version( $request );
|
809 |
$consumer = $this->get_consumer( $request );
|
810 |
+
$token = $this->get_token( $request, $consumer, 'access' );
|
811 |
$this->check_signature( $request, $consumer, $token );
|
812 |
|
813 |
return array( $consumer, $token );
|
814 |
}
|
815 |
|
|
|
816 |
/**
|
817 |
+
* Version 1
|
818 |
+
*
|
819 |
+
* @param object $request Request.
|
820 |
+
* @throws WPOAuthException Exception message.
|
821 |
+
*
|
822 |
+
* @return Oauth version.
|
823 |
*/
|
824 |
private function get_version( &$request ) {
|
825 |
+
$version = $request->get_parameter( 'oauth_version' );
|
826 |
if ( ! $version ) {
|
827 |
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
|
828 |
+
// Chapter 7.0 ("Accessing Protected Resources").
|
829 |
$version = '1.0';
|
830 |
}
|
831 |
if ( $version !== $this->version ) {
|
836 |
}
|
837 |
|
838 |
/**
|
839 |
+
* Figure out the signature with some defaults
|
840 |
+
*
|
841 |
+
* @param object $request Request.
|
842 |
+
* @throws WPOAuthException Exception message.
|
843 |
+
*
|
844 |
+
* @return signature methods.
|
845 |
*/
|
846 |
private function get_signature_method( &$request ) {
|
847 |
+
$signature_method = $request->get_parameter( 'oauth_signature_method' );
|
|
|
848 |
|
849 |
if ( ! $signature_method ) {
|
850 |
+
// According to chapter 7 ("Accessing Protected Resources") the signature-method.
|
851 |
+
// parameter is required, and we can't just fallback to PLAINTEXT.
|
852 |
throw new WPOAuthException( 'No signature method parameter. This parameter is required' );
|
853 |
}
|
854 |
|
855 |
+
if ( ! in_array( $signature_method, array_keys( $this->signature_methods ) ) ) {
|
|
|
|
|
856 |
throw new WPOAuthException(
|
857 |
"Signature method '$signature_method' not supported " .
|
858 |
+
'try one of the following: ' .
|
859 |
+
implode( ', ', array_keys( $this->signature_methods ) )
|
860 |
);
|
861 |
}
|
862 |
|
864 |
}
|
865 |
|
866 |
/**
|
867 |
+
* Try to find the consumer for the provided request's consumer key
|
868 |
+
*
|
869 |
+
* @param object $request Request.
|
870 |
+
* @throws WPOAuthException Exception message.
|
871 |
+
*
|
872 |
+
* @return consumer.
|
873 |
*/
|
874 |
private function get_consumer( &$request ) {
|
875 |
+
$consumer_key = $request->get_parameter( 'oauth_consumer_key' );
|
876 |
if ( ! $consumer_key ) {
|
877 |
+
throw new WPOAuthException( 'Invalid consumer key' );
|
878 |
}
|
879 |
|
880 |
$consumer = $this->data_store->lookup_consumer( $consumer_key );
|
881 |
if ( ! $consumer ) {
|
882 |
+
throw new WPOAuthException( 'Invalid consumer' );
|
883 |
}
|
884 |
|
885 |
return $consumer;
|
886 |
}
|
887 |
|
888 |
/**
|
889 |
+
* Try to find the token for the provided request's token key
|
890 |
+
*
|
891 |
+
* @param object $request Request.
|
892 |
+
* @param object $consumer Consumer.
|
893 |
+
* @param string $token_type Type of token being handled.
|
894 |
+
* @throws WPOAuthException Exception message.
|
895 |
+
*
|
896 |
+
* @return Oauth version.
|
897 |
*/
|
898 |
+
private function get_token( &$request, $consumer, $token_type = 'access' ) {
|
899 |
+
$token_field = $request->get_parameter( 'oauth_token' );
|
900 |
+
$token = $this->data_store->lookup_token( $consumer, $token_type, $token_field );
|
|
|
|
|
901 |
if ( ! $token ) {
|
902 |
throw new WPOAuthException( "Invalid $token_type token: $token_field" );
|
903 |
}
|
906 |
}
|
907 |
|
908 |
/**
|
909 |
+
* All-in-one function to check the signature on a request
|
910 |
* should guess the signature method appropriately
|
911 |
+
*
|
912 |
+
* @param object $request Request.
|
913 |
+
* @param object $consumer Consumer.
|
914 |
+
* @param object $token Token.
|
915 |
+
* @throws WPOAuthException Exception message.
|
916 |
*/
|
917 |
private function check_signature( &$request, $consumer, $token ) {
|
918 |
+
// this should probably be in a different method.
|
919 |
+
$timestamp = $request->get_parameter( 'oauth_timestamp' );
|
920 |
+
$nonce = $request->get_parameter( 'oauth_nonce' );
|
921 |
|
922 |
$this->check_timestamp( $timestamp );
|
923 |
$this->check_nonce( $consumer, $token, $nonce, $timestamp );
|
933 |
);
|
934 |
|
935 |
if ( ! $valid_sig ) {
|
936 |
+
throw new WPOAuthException( 'Invalid signature' );
|
937 |
}
|
938 |
}
|
939 |
|
940 |
/**
|
941 |
+
* Check that the timestamp is new enough
|
942 |
+
*
|
943 |
+
* @param string $timestamp Time stamp.
|
944 |
+
* @throws WPOAuthException Exception message.
|
945 |
*/
|
946 |
private function check_timestamp( $timestamp ) {
|
947 |
if ( ! $timestamp ) {
|
950 |
);
|
951 |
}
|
952 |
|
953 |
+
// verify that timestamp is recentish.
|
954 |
$now = time();
|
955 |
if ( abs( $now - $timestamp ) > $this->timestamp_threshold ) {
|
956 |
throw new WPOAuthException(
|
960 |
}
|
961 |
|
962 |
/**
|
963 |
+
* Check that the nonce is not repeated
|
964 |
+
*
|
965 |
+
* @param string $consumer Consumer.
|
966 |
+
* @param string $token Token.
|
967 |
+
* @param string $nonce Nonce.
|
968 |
+
* @param string $timestamp Timestamp.
|
969 |
+
* @throws WPOAuthException Exception message.
|
970 |
*/
|
971 |
private function check_nonce( $consumer, $token, $nonce, $timestamp ) {
|
972 |
if ( ! $nonce ) {
|
973 |
+
throw new WPOAuthException( 'Missing nonce parameter. The parameter is required' );
|
|
|
|
|
974 |
}
|
975 |
|
976 |
+
// verify that the nonce is uniqueish.
|
977 |
$found = $this->data_store->lookup_nonce(
|
978 |
$consumer,
|
979 |
$token,
|
987 |
|
988 |
}
|
989 |
|
990 |
+
/**
|
991 |
+
* Handle data storage.
|
992 |
+
*/
|
993 |
class WPOAuthDataStore {
|
994 |
+
/**
|
995 |
+
* Look up the current consumer.
|
996 |
+
*
|
997 |
+
* @param string $consumer_key Key.
|
998 |
+
*/
|
999 |
function lookup_consumer( $consumer_key ) {
|
1000 |
+
// implement me.
|
1001 |
}
|
1002 |
+
/**
|
1003 |
+
* Look up the current token.
|
1004 |
+
*
|
1005 |
+
* @param object $consumer Consumer object.
|
1006 |
+
* @param string $token_type Token type.
|
1007 |
+
* @param string $token Token.
|
1008 |
+
*/
|
1009 |
function lookup_token( $consumer, $token_type, $token ) {
|
1010 |
+
// implement me.
|
1011 |
}
|
1012 |
+
/**
|
1013 |
+
* Look up the current nonce.
|
1014 |
+
*
|
1015 |
+
* @param object $consumer Consumer object.
|
1016 |
+
* @param object $token Token.
|
1017 |
+
* @param string $nonce None.
|
1018 |
+
* @param string $timestamp Timestamp.
|
1019 |
+
*/
|
1020 |
function lookup_nonce( $consumer, $token, $nonce, $timestamp ) {
|
1021 |
+
// implement me.
|
1022 |
}
|
1023 |
+
/**
|
1024 |
+
* Get a new request token.
|
1025 |
+
*
|
1026 |
+
* @param object $consumer Consumer.
|
1027 |
+
* @param string $callback URL.
|
1028 |
+
*/
|
1029 |
function new_request_token( $consumer, $callback = null ) {
|
1030 |
+
// return a new token attached to this consumer.
|
1031 |
}
|
1032 |
+
/**
|
1033 |
+
* Get a new access token.
|
1034 |
+
*
|
1035 |
+
* @param object $token Token.
|
1036 |
+
* @param object $consumer Consumer.
|
1037 |
+
* @param string $verifier Verifier parameter.
|
1038 |
+
*/
|
1039 |
function new_access_token( $token, $consumer, $verifier = null ) {
|
1040 |
+
// return a new access token attached to this consumer.
|
1041 |
+
// for the user associated with this token if the request token.
|
1042 |
+
// is authorized.
|
1043 |
+
// should also invalidate the request token.
|
1044 |
}
|
1045 |
|
1046 |
}
|
1047 |
|
1048 |
+
/**
|
1049 |
+
* Utility procedures.
|
1050 |
+
*/
|
1051 |
class WPOAuthUtil {
|
1052 |
+
/**
|
1053 |
+
* Encode as rfc3986.
|
1054 |
+
*
|
1055 |
+
* @param string $input Any string input.
|
1056 |
+
*
|
1057 |
+
* @return encoded input.
|
1058 |
+
*/
|
1059 |
public static function urlencode_rfc3986( $input ) {
|
1060 |
if ( is_array( $input ) ) {
|
1061 |
return array_map( array( 'WPOAuthUtil', 'urlencode_rfc3986' ), $input );
|
1062 |
+
} elseif ( is_scalar( $input ) ) {
|
1063 |
return str_replace(
|
1064 |
'+',
|
1065 |
' ',
|
1071 |
}
|
1072 |
|
1073 |
|
1074 |
+
/**
|
1075 |
+
* This decode function isn't taking into consideration the above
|
1076 |
+
* modifications to the encoding process. However, this method doesn't
|
1077 |
+
* seem to be used anywhere so leaving it as is.
|
1078 |
+
*
|
1079 |
+
* @param string $string An encoded string.
|
1080 |
+
*
|
1081 |
+
* @return $string A decoded string.
|
1082 |
+
*/
|
1083 |
public static function urldecode_rfc3986( $string ) {
|
1084 |
return urldecode( $string );
|
1085 |
}
|
1086 |
|
1087 |
+
/**
|
1088 |
+
* Utility function for turning the Authorization: header into.
|
1089 |
+
* parameters, has to do some unescaping.
|
1090 |
+
* Can filter out any non-oauth parameters if needed (default behaviour).
|
1091 |
+
*
|
1092 |
+
* @param string $header Header string.
|
1093 |
+
* @param boolean $only_allow_oauth_parameters Strip off non-oauth params.
|
1094 |
+
*
|
1095 |
+
* @return Return parameters array.
|
1096 |
+
*/
|
1097 |
public static function split_header( $header, $only_allow_oauth_parameters = true ) {
|
1098 |
$pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
|
1099 |
$offset = 0;
|
1115 |
return $params;
|
1116 |
}
|
1117 |
|
1118 |
+
/**
|
1119 |
+
* Helper to try to sort out headers for people who aren't running apache
|
1120 |
+
*
|
1121 |
+
* @return headers
|
1122 |
+
*/
|
1123 |
public static function get_headers() {
|
1124 |
if ( function_exists( 'apache_request_headers' ) ) {
|
1125 |
+
// we need this to get the actual Authorization: header.
|
1126 |
+
// because apache tends to tell us it doesn't exist.
|
1127 |
$headers = apache_request_headers();
|
1128 |
|
1129 |
+
// sanitize the output of apache_request_headers because.
|
1130 |
+
// we always want the keys to be Cased-Like-This and arh().
|
1131 |
+
// returns the headers in the same case as they are in the request.
|
|
|
1132 |
$out = array();
|
1133 |
+
foreach ( $headers as $key => $value ) {
|
1134 |
$key = str_replace(
|
1135 |
+
' ',
|
1136 |
+
'-',
|
1137 |
+
ucwords( strtolower( str_replace( '-', ' ', $key ) ) )
|
1138 |
);
|
1139 |
$out[ $key ] = $value;
|
1140 |
}
|
1141 |
} else {
|
1142 |
+
// otherwise we don't have apache and are just going to have to hope.
|
1143 |
+
// that $_SERVER actually contains what we need.
|
1144 |
$out = array();
|
1145 |
if ( isset( $_SERVER['CONTENT_TYPE'] ) ) {
|
1146 |
$out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
|
1150 |
}
|
1151 |
|
1152 |
foreach ( $_SERVER as $key => $value ) {
|
1153 |
+
if ( substr( $key, 0, 5 ) == 'HTTP_' ) {
|
1154 |
+
// this is chaos, basically it is just there to capitalize the first.
|
1155 |
+
// letter of every word that is not an initial HTTP and strip HTTP.
|
1156 |
+
// code from przemek.
|
1157 |
$key = str_replace(
|
1158 |
+
' ',
|
1159 |
+
'-',
|
1160 |
+
ucwords( strtolower( str_replace( '_', ' ', substr( $key, 5 ) ) ) )
|
1161 |
);
|
1162 |
$out[ $key ] = $value;
|
1163 |
}
|
1167 |
return $out;
|
1168 |
}
|
1169 |
|
1170 |
+
/**
|
1171 |
+
* This function takes a input like a=b&a=c&d=e and returns the parsed
|
1172 |
+
* parameters like this
|
1173 |
+
* array('a' => array('b','c'), 'd' => 'e')
|
1174 |
+
*
|
1175 |
+
* @param string $input URL query string.
|
1176 |
+
*
|
1177 |
+
* @return array of parameters.
|
1178 |
+
*/
|
1179 |
public static function parse_parameters( $input ) {
|
1180 |
if ( ! isset( $input ) || ! $input ) {
|
1181 |
return array();
|
1190 |
$value = isset( $split[1] ) ? WPOAuthUtil::urldecode_rfc3986( $split[1] ) : '';
|
1191 |
|
1192 |
if ( isset( $parsed_parameters[ $parameter ] ) ) {
|
1193 |
+
// We have already recieved parameter(s) with this name, so add to the list.
|
1194 |
+
// of parameters with this name.
|
|
|
1195 |
if ( is_scalar( $parsed_parameters[ $parameter ] ) ) {
|
1196 |
+
// This is the first duplicate, so transform scalar (string) into an array.
|
1197 |
+
// so we can add the duplicates.
|
1198 |
$parsed_parameters[ $parameter ] = array( $parsed_parameters[ $parameter ] );
|
1199 |
}
|
1200 |
|
1207 |
return $parsed_parameters;
|
1208 |
}
|
1209 |
|
1210 |
+
/**
|
1211 |
+
* Built an HTTP query string from parameters.
|
1212 |
+
*
|
1213 |
+
* @param array $params Query parameters.
|
1214 |
+
*
|
1215 |
+
* @return string query string.
|
1216 |
+
*/
|
1217 |
public static function build_http_query( $params ) {
|
1218 |
if ( ! $params ) {
|
1219 |
return '';
|
1220 |
}
|
1221 |
|
1222 |
+
// Urlencode both keys and values.
|
1223 |
$keys = WPOAuthUtil::urlencode_rfc3986( array_keys( $params ) );
|
1224 |
$values = WPOAuthUtil::urlencode_rfc3986( array_values( $params ) );
|
1225 |
$params = array_combine( $keys, $values );
|
1226 |
|
1227 |
// Parameters are sorted by name, using lexicographical byte value ordering.
|
1228 |
+
// Ref: Spec: 9.1.1 (1).
|
1229 |
uksort( $params, 'strcmp' );
|
1230 |
|
1231 |
$pairs = array();
|
1232 |
foreach ( $params as $parameter => $value ) {
|
1233 |
if ( is_array( $value ) ) {
|
1234 |
+
// If two or more parameters share the same name, they are sorted by their value.
|
1235 |
+
// Ref: Spec: 9.1.1 (1).
|
1236 |
natsort( $value );
|
1237 |
foreach ( $value as $duplicate_value ) {
|
1238 |
$pairs[] = $parameter . '=' . $duplicate_value;
|
1241 |
$pairs[] = $parameter . '=' . $value;
|
1242 |
}
|
1243 |
}
|
1244 |
+
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61).
|
1245 |
+
// Each name-value pair is separated by an '&' character (ASCII code 38).
|
1246 |
return implode( '&', $pairs );
|
1247 |
}
|
1248 |
}
|
1249 |
+
} // class_exists check.
|
|
classes/class-wpt-latest-tweets-widget.php
ADDED
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Widget to show latest Tweets.
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* WP to Twitter Latest Tweets widget class.
|
18 |
+
*/
|
19 |
+
class WPT_Latest_Tweets_Widget extends WP_Widget {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Holds widget settings defaults, populated in constructor.
|
23 |
+
*
|
24 |
+
* @var array
|
25 |
+
*/
|
26 |
+
protected $defaults;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Constructor. Set the default widget options and create widget.
|
30 |
+
*
|
31 |
+
* @since 0.1.8
|
32 |
+
*/
|
33 |
+
function __construct() {
|
34 |
+
|
35 |
+
$this->defaults = array(
|
36 |
+
'title' => '',
|
37 |
+
'twitter_id' => '',
|
38 |
+
'twitter_num' => '',
|
39 |
+
'twitter_duration' => '',
|
40 |
+
'twitter_hide_replies' => 0,
|
41 |
+
'twitter_include_rts' => 0,
|
42 |
+
'link_links' => '',
|
43 |
+
'link_mentions' => '',
|
44 |
+
'link_hashtags' => '',
|
45 |
+
'intents' => '',
|
46 |
+
'source' => '',
|
47 |
+
'show_images' => '',
|
48 |
+
'hide_header' => 0,
|
49 |
+
);
|
50 |
+
|
51 |
+
$widget_ops = array(
|
52 |
+
'classname' => 'wpt-latest-tweets',
|
53 |
+
'description' => __( 'Display a list of your latest tweets.', 'wp-to-twitter' ),
|
54 |
+
'customize_selective_refresh' => true,
|
55 |
+
);
|
56 |
+
|
57 |
+
$control_ops = array(
|
58 |
+
'id_base' => 'wpt-latest-tweets',
|
59 |
+
'width' => 200,
|
60 |
+
'height' => 250,
|
61 |
+
);
|
62 |
+
parent::__construct( 'wpt-latest-tweets', __( 'WP to Twitter - Latest Tweets', 'wp-to-twitter' ), $widget_ops, $control_ops );
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Echo the widget content.
|
67 |
+
*
|
68 |
+
* @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
|
69 |
+
* @param array $instance The settings for the particular instance of the widget.
|
70 |
+
*/
|
71 |
+
function widget( $args, $instance ) {
|
72 |
+
$before_widget = $args['before_widget'];
|
73 |
+
$after_widget = $args['after_widget'];
|
74 |
+
$before_title = $args['before_title'];
|
75 |
+
$after_title = $args['after_title'];
|
76 |
+
|
77 |
+
wp_enqueue_script( 'twitter-platform', 'https://platform.twitter.com/widgets.js' );
|
78 |
+
/** Merge with defaults */
|
79 |
+
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
80 |
+
|
81 |
+
echo $before_widget;
|
82 |
+
if ( $instance['title'] ) {
|
83 |
+
echo $before_title . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $after_title;
|
84 |
+
}
|
85 |
+
echo wpt_twitter_feed( $instance );
|
86 |
+
echo $after_widget;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Update a particular instance.
|
91 |
+
*
|
92 |
+
* This function should check that $new_instance is set correctly.
|
93 |
+
* The newly calculated value of $instance should be returned.
|
94 |
+
* If "false" is returned, the instance won't be saved/updated.
|
95 |
+
*
|
96 |
+
* @since 0.1
|
97 |
+
*
|
98 |
+
* @param array $new_instance New settings for this instance as input by the user via form().
|
99 |
+
* @param array $old_instance Old settings for this instance.
|
100 |
+
*
|
101 |
+
* @return array Settings to save or bool false to cancel saving
|
102 |
+
*/
|
103 |
+
function update( $new_instance, $old_instance ) {
|
104 |
+
// Force the cache to refresh.
|
105 |
+
update_option( 'wpt_delete_cache', 'true' );
|
106 |
+
$new_instance['title'] = strip_tags( $new_instance['title'] );
|
107 |
+
|
108 |
+
return $new_instance;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Echo the settings update form.
|
113 |
+
*
|
114 |
+
* @param array $instance Current settings.
|
115 |
+
*/
|
116 |
+
function form( $instance ) {
|
117 |
+
|
118 |
+
// Merge with defaults.
|
119 |
+
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
120 |
+
?>
|
121 |
+
<p>
|
122 |
+
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title', 'wp-to-twitter' ); ?>:</label>
|
123 |
+
<input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $instance['title'] ); ?>" class="widefat"/>
|
124 |
+
</p>
|
125 |
+
|
126 |
+
<p>
|
127 |
+
<label for="<?php echo $this->get_field_id( 'twitter_id' ); ?>"><?php _e( 'Twitter Username', 'wp-to-twitter' ); ?> :</label>
|
128 |
+
<input type="text" id="<?php echo $this->get_field_id( 'twitter_id' ); ?>" name="<?php echo $this->get_field_name( 'twitter_id' ); ?>" value="<?php echo esc_attr( $instance['twitter_id'] ); ?>" class="widefat"/>
|
129 |
+
</p>
|
130 |
+
|
131 |
+
<p>
|
132 |
+
<input id="<?php echo $this->get_field_id( 'hide_header' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'hide_header' ); ?>" value="1" <?php checked( $instance['hide_header'], 1 ); ?>/>
|
133 |
+
<label for="<?php echo $this->get_field_id( 'hide_header' ); ?>"><?php _e( 'Hide Widget Header', 'wp-to-twitter' ); ?></label>
|
134 |
+
</p>
|
135 |
+
|
136 |
+
<p>
|
137 |
+
<label for="<?php echo $this->get_field_id( 'twitter_num' ); ?>"><?php _e( 'Number of Tweets to Show', 'wp-to-twitter' ); ?> :</label>
|
138 |
+
<input type="text" id="<?php echo $this->get_field_id( 'twitter_num' ); ?>" name="<?php echo $this->get_field_name( 'twitter_num' ); ?>" value="<?php echo esc_attr( $instance['twitter_num'] ); ?>" size="3"/>
|
139 |
+
</p>
|
140 |
+
|
141 |
+
<p>
|
142 |
+
<input id="<?php echo $this->get_field_id( 'twitter_hide_replies' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'twitter_hide_replies' ); ?>" value="1" <?php checked( $instance['twitter_hide_replies'], 1 ); ?>/>
|
143 |
+
<label for="<?php echo $this->get_field_id( 'twitter_hide_replies' ); ?>"><?php _e( 'Hide @ Replies', 'wp-to-twitter' ); ?></label>
|
144 |
+
</p>
|
145 |
+
|
146 |
+
<p>
|
147 |
+
<input id="<?php echo $this->get_field_id( 'twitter_include_rts' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'twitter_include_rts' ); ?>" value="1" <?php checked( $instance['twitter_include_rts'], 1 ); ?>/>
|
148 |
+
<label for="<?php echo $this->get_field_id( 'twitter_include_rts' ); ?>"><?php _e( 'Include Retweets', 'wp-to-twitter' ); ?></label>
|
149 |
+
</p>
|
150 |
+
|
151 |
+
<p>
|
152 |
+
<input id="<?php echo $this->get_field_id( 'link_links' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'link_links' ); ?>" value="1" <?php checked( $instance['link_links'], 1 ); ?>/>
|
153 |
+
<label for="<?php echo $this->get_field_id( 'link_links' ); ?>"><?php _e( 'Parse links', 'wp-to-twitter' ); ?></label>
|
154 |
+
</p>
|
155 |
+
|
156 |
+
<p>
|
157 |
+
<input id="<?php echo $this->get_field_id( 'link_mentions' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'link_mentions' ); ?>" value="1" <?php checked( $instance['link_mentions'], 1 ); ?>/>
|
158 |
+
<label for="<?php echo $this->get_field_id( 'link_mentions' ); ?>"><?php _e( 'Parse @mentions', 'wp-to-twitter' ); ?></label>
|
159 |
+
</p>
|
160 |
+
|
161 |
+
<p>
|
162 |
+
<input id="<?php echo $this->get_field_id( 'show_images' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'show_images' ); ?>" value="1" <?php checked( $instance['show_images'], 1 ); ?>/>
|
163 |
+
<label for="<?php echo $this->get_field_id( 'show_images' ); ?>"><?php _e( 'Show Images', 'wp-to-twitter' ); ?></label>
|
164 |
+
</p>
|
165 |
+
|
166 |
+
<p>
|
167 |
+
<input id="<?php echo $this->get_field_id( 'link_hashtags' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'link_hashtags' ); ?>" value="1" <?php checked( $instance['link_hashtags'], 1 ); ?>/>
|
168 |
+
<label for="<?php echo $this->get_field_id( 'link_hashtags' ); ?>"><?php _e( 'Parse #hashtags', 'wp-to-twitter' ); ?></label>
|
169 |
+
</p>
|
170 |
+
|
171 |
+
<p>
|
172 |
+
<input id="<?php echo $this->get_field_id( 'intents' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'intents' ); ?>" value="1" <?php checked( $instance['intents'], 1 ); ?>/>
|
173 |
+
<label for="<?php echo $this->get_field_id( 'intents' ); ?>"><?php _e( 'Include Reply/Retweet/Favorite Links', 'wp-to-twitter' ); ?></label>
|
174 |
+
</p>
|
175 |
+
|
176 |
+
<p>
|
177 |
+
<input id="<?php echo $this->get_field_id( 'source' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'source' ); ?>" value="1" <?php checked( $instance['source'], 1 ); ?>/>
|
178 |
+
<label for="<?php echo $this->get_field_id( 'source' ); ?>"><?php _e( 'Include Tweet source', 'wp-to-twitter' ); ?></label>
|
179 |
+
</p>
|
180 |
+
<p>
|
181 |
+
<input id="<?php echo $this->get_field_id( 'cache' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'cache' ); ?>" value="1" />
|
182 |
+
<label for="<?php echo $this->get_field_id( 'cache' ); ?>"><?php _e( 'Clear cache', 'wp-to-twitter' ); ?></label>
|
183 |
+
</p>
|
184 |
+
<?php
|
185 |
+
}
|
186 |
+
}
|
classes/class-wpt-normalizer.php
ADDED
@@ -0,0 +1,360 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WP to Twitter Normalizer fallback class
|
4 |
+
*
|
5 |
+
* @category Fallbacks
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
|
18 |
+
*
|
19 |
+
* It has been validated with Unicode 6.1 Normalization Conformance Test.
|
20 |
+
* See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
|
21 |
+
*/
|
22 |
+
class WPT_Normalizer {
|
23 |
+
const
|
24 |
+
|
25 |
+
NONE = 1,
|
26 |
+
FORM_D = 2, NFD = 2,
|
27 |
+
FORM_KD = 3, NFKD = 3,
|
28 |
+
FORM_C = 4, NFC = 4,
|
29 |
+
FORM_KC = 5, NFKC = 5;
|
30 |
+
|
31 |
+
protected static
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Character containers.
|
35 |
+
*
|
36 |
+
* @var $c
|
37 |
+
*/
|
38 |
+
$c,
|
39 |
+
/**
|
40 |
+
* Character containers.
|
41 |
+
*
|
42 |
+
* @var $d
|
43 |
+
*/
|
44 |
+
$d,
|
45 |
+
/**
|
46 |
+
* Character containers.
|
47 |
+
*
|
48 |
+
* @var $kd
|
49 |
+
*/
|
50 |
+
$kd,
|
51 |
+
/**
|
52 |
+
* Character containers.
|
53 |
+
*
|
54 |
+
* @var $cc
|
55 |
+
*/
|
56 |
+
$cc,
|
57 |
+
/**
|
58 |
+
* U length mask.
|
59 |
+
*
|
60 |
+
* @var $ulen_mask
|
61 |
+
*/
|
62 |
+
$ulen_mask = array(
|
63 |
+
"\xC0" => 2,
|
64 |
+
"\xD0" => 2,
|
65 |
+
"\xE0" => 3,
|
66 |
+
"\xF0" => 4,
|
67 |
+
),
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Index of ASCII characters.
|
71 |
+
*
|
72 |
+
* @var $ascii
|
73 |
+
*/
|
74 |
+
$ascii = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Check whether is already normalized.
|
78 |
+
*
|
79 |
+
* @param string $s String to check.
|
80 |
+
* @param object $form Self.
|
81 |
+
*
|
82 |
+
* @return boolean
|
83 |
+
*/
|
84 |
+
static function is_normalized( $s, $form = self::NFC ) {
|
85 |
+
if ( strspn( $s, self::$ascii ) === strlen( $s ) ) {
|
86 |
+
return true;
|
87 |
+
}
|
88 |
+
if ( self::NFC === $form && preg_match( '//u', $s ) && ! preg_match( '/[^\x00-\x{2FF}]/u', $s ) ) {
|
89 |
+
return true;
|
90 |
+
}
|
91 |
+
return false; // Pretend false as quick checks implementented in PHP won't be so quick.
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Normalize a string.
|
96 |
+
*
|
97 |
+
* @param string $s String to normalize.
|
98 |
+
* @param object $form Self.
|
99 |
+
*
|
100 |
+
* @return boolean or normalized string.
|
101 |
+
*/
|
102 |
+
static function normalize( $s, $form = self::NFC ) {
|
103 |
+
if ( ! preg_match( '//u', $s ) ) {
|
104 |
+
return false;
|
105 |
+
}
|
106 |
+
|
107 |
+
switch ( $form ) {
|
108 |
+
case self::NONE:
|
109 |
+
return $s;
|
110 |
+
case self::NFC:
|
111 |
+
$c = true;
|
112 |
+
$k = false;
|
113 |
+
break;
|
114 |
+
case self::NFD:
|
115 |
+
$c = false;
|
116 |
+
$k = false;
|
117 |
+
break;
|
118 |
+
case self::NFKC:
|
119 |
+
$c = true;
|
120 |
+
$k = true;
|
121 |
+
break;
|
122 |
+
case self::NFKD:
|
123 |
+
$c = false;
|
124 |
+
$k = true;
|
125 |
+
break;
|
126 |
+
default:
|
127 |
+
return false;
|
128 |
+
}
|
129 |
+
|
130 |
+
if ( ! strlen( $s ) ) {
|
131 |
+
return '';
|
132 |
+
}
|
133 |
+
|
134 |
+
if ( $k && empty( self::$kd ) ) {
|
135 |
+
self::$kd = self::get_data( 'compatibilityDecomposition' );
|
136 |
+
}
|
137 |
+
|
138 |
+
if ( empty( self::$d ) ) {
|
139 |
+
self::$d = self::get_data( 'canonicalDecomposition' );
|
140 |
+
self::$cc = self::get_data( 'combiningClass' );
|
141 |
+
}
|
142 |
+
|
143 |
+
if ( $c ) {
|
144 |
+
if ( empty( self::$c ) ) {
|
145 |
+
self::$c = self::get_data( 'canonicalComposition' );
|
146 |
+
}
|
147 |
+
return self::recompose( self::decompose( $s, $k ) );
|
148 |
+
} else {
|
149 |
+
return self::decompose( $s, $k );
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Recompose a string.
|
155 |
+
*
|
156 |
+
* @param string $s String to check.
|
157 |
+
*
|
158 |
+
* @return string
|
159 |
+
*/
|
160 |
+
protected static function recompose( $s ) {
|
161 |
+
$ascii = self::$ascii;
|
162 |
+
$comp_map = self::$c;
|
163 |
+
$comb_class = self::$cc;
|
164 |
+
$ulen_mask = self::$ulen_mask;
|
165 |
+
|
166 |
+
$result = '';
|
167 |
+
$tail = '';
|
168 |
+
|
169 |
+
$i = $s[0] < "\x80" ? 1 : $ulen_mask[ $s[0] & "\xF0" ];
|
170 |
+
$len = strlen( $s );
|
171 |
+
|
172 |
+
$last_uchr = substr( $s, 0, $i );
|
173 |
+
$last_ucls = isset( $comb_class[ $last_uchr ] ) ? 256 : 0;
|
174 |
+
|
175 |
+
while ( $i < $len ) {
|
176 |
+
if ( $s[ $i ] < "\x80" ) {
|
177 |
+
// ascii chars.
|
178 |
+
if ( $tail ) {
|
179 |
+
$last_uchr .= $tail;
|
180 |
+
$tail = '';
|
181 |
+
}
|
182 |
+
$j = strspn( $s, $ascii, $i + 1 );
|
183 |
+
if ( $j ) {
|
184 |
+
$last_uchr .= substr( $s, $i, $j );
|
185 |
+
$i += $j;
|
186 |
+
}
|
187 |
+
|
188 |
+
$result .= $last_uchr;
|
189 |
+
$last_uchr = $s[ $i ];
|
190 |
+
++$i;
|
191 |
+
} else {
|
192 |
+
$ulen = $ulen_mask[ $s[ $i ] & "\xF0" ];
|
193 |
+
$uchr = substr( $s, $i, $ulen );
|
194 |
+
|
195 |
+
if ( $last_uchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $last_uchr
|
196 |
+
|| $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
|
197 |
+
|| $last_ucls ) {
|
198 |
+
// Table lookup and combining chars composition.
|
199 |
+
$ucls = isset( $comb_class[ $uchr ] ) ? $comb_class[ $uchr ] : 0;
|
200 |
+
|
201 |
+
if ( isset( $comp_map[ $last_uchr . $uchr ] ) && ( ! $last_ucls || $last_ucls < $ucls ) ) {
|
202 |
+
$last_uchr = $comp_map[ $last_uchr . $uchr ];
|
203 |
+
} elseif ( $last_ucls == $ucls ) {
|
204 |
+
$tail .= $uchr;
|
205 |
+
} else {
|
206 |
+
if ( $tail ) {
|
207 |
+
$last_uchr .= $tail;
|
208 |
+
$tail = '';
|
209 |
+
}
|
210 |
+
|
211 |
+
$result .= $last_uchr;
|
212 |
+
$last_uchr = $uchr;
|
213 |
+
}
|
214 |
+
} else {
|
215 |
+
// Hangul chars.
|
216 |
+
$l = ord( $last_uchr[2] ) - 0x80;
|
217 |
+
$v = ord( $uchr[2] ) - 0xA1;
|
218 |
+
$t = 0;
|
219 |
+
|
220 |
+
$uchr = substr( $s, $i + $ulen, 3 );
|
221 |
+
|
222 |
+
if ( "\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82" ) {
|
223 |
+
$t = ord( $uchr[2] ) - 0xA7;
|
224 |
+
0 > $t && $t += 0x40;
|
225 |
+
$ulen += 3;
|
226 |
+
}
|
227 |
+
|
228 |
+
$l = 0xAC00 + ( $l * 21 + $v ) * 28 + $t;
|
229 |
+
$last_uchr = chr( 0xE0 | $l >> 12 ) . chr( 0x80 | $l >> 6 & 0x3F ) . chr( 0x80 | $l & 0x3F );
|
230 |
+
}
|
231 |
+
|
232 |
+
$i += $ulen;
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
return $result . $last_uchr . $tail;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Decompose a string.
|
241 |
+
*
|
242 |
+
* @param string $s String to check.
|
243 |
+
* @param boolean $c use compat map.
|
244 |
+
*
|
245 |
+
* @return string
|
246 |
+
*/
|
247 |
+
protected static function decompose( $s, $c ) {
|
248 |
+
$result = '';
|
249 |
+
|
250 |
+
$ascii = self::$ascii;
|
251 |
+
$decomp_map = self::$d;
|
252 |
+
$comb_class = self::$cc;
|
253 |
+
$ulen_mask = self::$ulen_mask;
|
254 |
+
if ( $c ) {
|
255 |
+
$compat_map = self::$kd;
|
256 |
+
}
|
257 |
+
|
258 |
+
$c = array();
|
259 |
+
$i = 0;
|
260 |
+
$len = strlen( $s );
|
261 |
+
|
262 |
+
while ( $i < $len ) {
|
263 |
+
if ( $s[ $i ] < "\x80" ) {
|
264 |
+
// ascii chars.
|
265 |
+
if ( $c ) {
|
266 |
+
ksort( $c );
|
267 |
+
$result .= implode( '', $c );
|
268 |
+
$c = array();
|
269 |
+
}
|
270 |
+
|
271 |
+
$j = 1 + strspn( $s, $ascii, $i + 1 );
|
272 |
+
$result .= substr( $s, $i, $j );
|
273 |
+
$i += $j;
|
274 |
+
} else {
|
275 |
+
$ulen = $ulen_mask[ $s[ $i ] & "\xF0" ];
|
276 |
+
$uchr = substr( $s, $i, $ulen );
|
277 |
+
$i += $ulen;
|
278 |
+
|
279 |
+
if ( isset( $comb_class[ $uchr ] ) ) {
|
280 |
+
// Combining chars, for sorting.
|
281 |
+
if ( ! isset( $c[ $comb_class[ $uchr ] ] ) ) {
|
282 |
+
$c[ $comb_class[ $uchr ] ] = '';
|
283 |
+
}
|
284 |
+
$c[ $comb_class[ $uchr ] ] .= isset( $compat_map[ $uchr ] ) ? $compat_map[ $uchr ] : ( isset( $decomp_map[ $uchr ] ) ? $decomp_map[ $uchr ] : $uchr );
|
285 |
+
} else {
|
286 |
+
if ( $c ) {
|
287 |
+
ksort( $c );
|
288 |
+
$result .= implode( '', $c );
|
289 |
+
$c = array();
|
290 |
+
}
|
291 |
+
|
292 |
+
if ( $uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr ) {
|
293 |
+
// Table lookup.
|
294 |
+
$j = isset( $compat_map[ $uchr ] ) ? $compat_map[ $uchr ] : ( isset( $decomp_map[ $uchr ] ) ? $decomp_map[ $uchr ] : $uchr );
|
295 |
+
|
296 |
+
if ( $uchr != $j ) {
|
297 |
+
$uchr = $j;
|
298 |
+
|
299 |
+
$j = strlen( $uchr );
|
300 |
+
$ulen = $uchr[0] < "\x80" ? 1 : $ulen_mask[ $uchr[0] & "\xF0" ];
|
301 |
+
|
302 |
+
if ( $ulen != $j ) {
|
303 |
+
// Put trailing chars in $s.
|
304 |
+
$j -= $ulen;
|
305 |
+
$i -= $j;
|
306 |
+
|
307 |
+
if ( 0 > $i ) {
|
308 |
+
$s = str_repeat( ' ', -$i ) . $s;
|
309 |
+
$len -= $i;
|
310 |
+
$i = 0;
|
311 |
+
}
|
312 |
+
|
313 |
+
while ( $j-- ) {
|
314 |
+
$s[ $i + $j ] = $uchr[ $ulen + $j ];
|
315 |
+
}
|
316 |
+
|
317 |
+
$uchr = substr( $uchr, 0, $ulen );
|
318 |
+
}
|
319 |
+
}
|
320 |
+
} else {
|
321 |
+
// Hangul chars.
|
322 |
+
$uchr = unpack( 'C*', $uchr );
|
323 |
+
$j = ( ( $uchr[1] - 224 ) << 12 ) + ( ( $uchr[2] - 128 ) << 6 ) + $uchr[3] - 0xAC80;
|
324 |
+
|
325 |
+
$uchr = "\xE1\x84" . chr( 0x80 + (int) ( $j / 588 ) ) . "\xE1\x85" . chr( 0xA1 + (int) ( ( $j % 588 ) / 28 ) );
|
326 |
+
|
327 |
+
if ( $j %= 28 ) {
|
328 |
+
$uchr .= $j < 25 ? ( "\xE1\x86" . chr( 0xA7 + $j ) ) : ( "\xE1\x87" . chr( 0x67 + $j ) );
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
$result .= $uchr;
|
333 |
+
}
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
if ( $c ) {
|
338 |
+
ksort( $c );
|
339 |
+
$result .= implode( '', $c );
|
340 |
+
}
|
341 |
+
|
342 |
+
return $result;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Data fetcher.
|
347 |
+
*
|
348 |
+
* @param string $file Get data file.
|
349 |
+
*
|
350 |
+
* @return file contents or false.
|
351 |
+
*/
|
352 |
+
protected static function get_data( $file ) {
|
353 |
+
$file = __DIR__ . '/unidata/' . $file . '.ser';
|
354 |
+
if ( file_exists( $file ) ) {
|
355 |
+
return unserialize( file_get_contents( $file ) );
|
356 |
+
} else {
|
357 |
+
return false;
|
358 |
+
}
|
359 |
+
}
|
360 |
+
}
|
classes/class-wpt-search-tweets-widget.php
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Widget to show searched Tweets.
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* WP to Twitter Latest Tweets widget class.
|
18 |
+
*/
|
19 |
+
class WPT_Search_Tweets_Widget extends WP_Widget {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Holds widget settings defaults, populated in constructor.
|
23 |
+
*
|
24 |
+
* @var array
|
25 |
+
*/
|
26 |
+
protected $defaults;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Constructor. Set the default widget options and create widget.
|
30 |
+
*
|
31 |
+
* @since 0.1.8
|
32 |
+
*/
|
33 |
+
function __construct() {
|
34 |
+
|
35 |
+
$this->defaults = array(
|
36 |
+
'title' => '',
|
37 |
+
'twitter_num' => '',
|
38 |
+
'search' => '',
|
39 |
+
'result_type' => 'recent', // mixed, recent, popular.
|
40 |
+
'geocode' => '', // 37.777,-127.98,2km.
|
41 |
+
'link_links' => '',
|
42 |
+
'link_mentions' => '',
|
43 |
+
'show_images' => '',
|
44 |
+
'link_hashtags' => '',
|
45 |
+
'intents' => '',
|
46 |
+
'source' => '',
|
47 |
+
);
|
48 |
+
|
49 |
+
$widget_ops = array(
|
50 |
+
'classname' => 'wpt-search-tweets',
|
51 |
+
'description' => __( 'Display a list of tweets returned by a search.', 'wp-to-twitter' ),
|
52 |
+
'customize_selective_refresh' => true,
|
53 |
+
);
|
54 |
+
|
55 |
+
$control_ops = array(
|
56 |
+
'id_base' => 'wpt-search-tweets',
|
57 |
+
'width' => 200,
|
58 |
+
'height' => 250,
|
59 |
+
);
|
60 |
+
parent::__construct( 'wpt-search-tweets', __( 'WP to Twitter - Searched Tweets', 'wp-to-twitter' ), $widget_ops, $control_ops );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Echo the widget content.
|
65 |
+
*
|
66 |
+
* @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
|
67 |
+
* @param array $instance The settings for the particular instance of the widget.
|
68 |
+
*/
|
69 |
+
function widget( $args, $instance ) {
|
70 |
+
$before_widget = $args['before_widget'];
|
71 |
+
$after_widget = $args['after_widget'];
|
72 |
+
$before_title = $args['before_title'];
|
73 |
+
$after_title = $args['after_title'];
|
74 |
+
|
75 |
+
wp_enqueue_script( 'twitter-platform', 'https://platform.twitter.com/widgets.js' );
|
76 |
+
// Merge with defaults.
|
77 |
+
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
78 |
+
echo $before_widget;
|
79 |
+
if ( $instance['title'] ) {
|
80 |
+
echo $before_title . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $after_title;
|
81 |
+
}
|
82 |
+
echo wpt_twitter_feed( $instance );
|
83 |
+
echo $after_widget;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Update a particular instance.
|
88 |
+
*
|
89 |
+
* This function should check that $new_instance is set correctly.
|
90 |
+
* The newly calculated value of $instance should be returned.
|
91 |
+
* If "false" is returned, the instance won't be saved/updated.
|
92 |
+
*
|
93 |
+
* @since 0.1
|
94 |
+
*
|
95 |
+
* @param array $new_instance New settings for this instance as input by the user via form().
|
96 |
+
* @param array $old_instance Old settings for this instance.
|
97 |
+
*
|
98 |
+
* @return array Settings to save or bool false to cancel saving
|
99 |
+
*/
|
100 |
+
function update( $new_instance, $old_instance ) {
|
101 |
+
// Force the cache to refresh.
|
102 |
+
update_option( 'wpt_delete_cache', 'true' );
|
103 |
+
$new_instance['title'] = strip_tags( $new_instance['title'] );
|
104 |
+
|
105 |
+
return $new_instance;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Echo the settings update form.
|
110 |
+
*
|
111 |
+
* @param array $instance Current settings.
|
112 |
+
*/
|
113 |
+
function form( $instance ) {
|
114 |
+
// Merge with defaults.
|
115 |
+
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
116 |
+
?>
|
117 |
+
<p>
|
118 |
+
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title', 'wp-to-twitter' ); ?>:</label>
|
119 |
+
<input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $instance['title'] ); ?>" class="widefat"/>
|
120 |
+
</p>
|
121 |
+
|
122 |
+
<p>
|
123 |
+
<label for="<?php echo $this->get_field_id( 'search' ); ?>"><?php _e( 'Search String', 'wp-to-twitter' ); ?> :</label>
|
124 |
+
<input type="text" id="<?php echo $this->get_field_id( 'search' ); ?>" name="<?php echo $this->get_field_name( 'search' ); ?>" value="<?php echo esc_attr( $instance['search'] ); ?>" class="widefat"/>
|
125 |
+
</p>
|
126 |
+
|
127 |
+
<p>
|
128 |
+
<label for="<?php echo $this->get_field_id( 'twitter_num' ); ?>"><?php _e( 'Number of Tweets to Show', 'wp-to-twitter' ); ?> :</label>
|
129 |
+
<input type="text" id="<?php echo $this->get_field_id( 'twitter_num' ); ?>" name="<?php echo $this->get_field_name( 'twitter_num' ); ?>" value="<?php echo esc_attr( $instance['twitter_num'] ); ?>" size="3"/>
|
130 |
+
</p>
|
131 |
+
|
132 |
+
<p>
|
133 |
+
<label for="<?php echo $this->get_field_id( 'result_type' ); ?>"><?php _e( 'Type of Results', 'wp-to-twitter' ); ?></label>
|
134 |
+
<select name="<?php echo $this->get_field_name( 'result_type' ); ?>" id="<?php echo $this->get_field_id( 'result_type' ); ?>"> <option value='recent'<?php echo ( 'recent' == $instance['result_type'] ) ? ' selected="selected"' : ''; ?>><?php _e( 'Recent Tweets', 'wp-to-twitter' ); ?></option> <option value='popular'<?php echo ( 'popular' == $instance['result_type'] ) ? ' selected="selected"' : ''; ?>><?php _e( 'Popular Tweets', 'wp-to-twitter' ); ?></option> <option value='mixed'<?php echo ( 'mixed' == $instance['result_type'] ) ? ' selected="selected"' : ''; ?>><?php _e( 'Mixed', 'wp-to-twitter' ); ?></option>
|
135 |
+
</select>
|
136 |
+
</p>
|
137 |
+
|
138 |
+
<p>
|
139 |
+
<label for="<?php echo $this->get_field_id( 'geocode' ); ?>"><?php _e( 'Geocode (Latitude,Longitude,Radius)', 'wp-to-twitter' ); ?> :</label>
|
140 |
+
<input type="text" id="<?php echo $this->get_field_id( 'geocode' ); ?>" class="widefat" name="<?php echo $this->get_field_name( 'geocode' ); ?>" value="<?php echo esc_attr( $instance['geocode'] ); ?>" size="32" placeholder="37.781157,-122.398720,2km"/>
|
141 |
+
</p>
|
142 |
+
|
143 |
+
<p>
|
144 |
+
<input id="<?php echo $this->get_field_id( 'link_links' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'link_links' ); ?>" value="1" <?php checked( $instance['link_links'] ); ?>/>
|
145 |
+
<label for="<?php echo $this->get_field_id( 'link_links' ); ?>"><?php _e( 'Parse links', 'wp-to-twitter' ); ?></label>
|
146 |
+
</p>
|
147 |
+
|
148 |
+
<p>
|
149 |
+
<input id="<?php echo $this->get_field_id( 'link_mentions' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'link_mentions' ); ?>" value="1" <?php checked( $instance['link_mentions'] ); ?>/>
|
150 |
+
<label for="<?php echo $this->get_field_id( 'link_mentions' ); ?>"><?php _e( 'Parse @mentions', 'wp-to-twitter' ); ?></label>
|
151 |
+
</p>
|
152 |
+
|
153 |
+
<p>
|
154 |
+
<input id="<?php echo $this->get_field_id( 'show_images' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'show_images' ); ?>" value="1" <?php checked( $instance['show_images'], 1 ); ?>/>
|
155 |
+
<label for="<?php echo $this->get_field_id( 'show_images' ); ?>"><?php _e( 'Show Images', 'wp-to-twitter' ); ?></label>
|
156 |
+
</p>
|
157 |
+
|
158 |
+
<p>
|
159 |
+
<input id="<?php echo $this->get_field_id( 'link_hashtags' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'link_hashtags' ); ?>" value="1" <?php checked( $instance['link_hashtags'] ); ?>/>
|
160 |
+
<label for="<?php echo $this->get_field_id( 'link_hashtags' ); ?>"><?php _e( 'Parse #hashtags', 'wp-to-twitter' ); ?></label>
|
161 |
+
</p>
|
162 |
+
|
163 |
+
<p>
|
164 |
+
<input id="<?php echo $this->get_field_id( 'intents' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'intents' ); ?>" value="1" <?php checked( $instance['intents'] ); ?>/>
|
165 |
+
<label for="<?php echo $this->get_field_id( 'intents' ); ?>"><?php _e( 'Include Reply/Retweet/Favorite Links', 'wp-to-twitter' ); ?></label>
|
166 |
+
</p>
|
167 |
+
|
168 |
+
<p>
|
169 |
+
<input id="<?php echo $this->get_field_id( 'source' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'source' ); ?>" value="1" <?php checked( $instance['source'] ); ?>/>
|
170 |
+
<label for="<?php echo $this->get_field_id( 'source' ); ?>"><?php _e( 'Include Tweet source', 'wp-to-twitter' ); ?></label>
|
171 |
+
</p>
|
172 |
+
<?php
|
173 |
+
}
|
174 |
+
}
|
wpt-feed.php → classes/class-wpt-twitterfeed.php
RENAMED
@@ -1,18 +1,31 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
exit;
|
4 |
-
}
|
5 |
-
/*
|
6 |
-
* Version 2.0.3, Twitter Feed for Developers by Storm Consultancy (Liam Gladdy)
|
7 |
-
* The base class for the storm twitter feed for developers.
|
8 |
-
*/
|
9 |
-
|
10 |
-
// based on StormTwitter; significantly modified
|
11 |
|
12 |
-
require_once( '
|
13 |
|
|
|
|
|
|
|
|
|
14 |
class WPT_TwitterFeed {
|
15 |
|
|
|
|
|
|
|
|
|
|
|
16 |
private $defaults = array(
|
17 |
'directory' => '',
|
18 |
'key' => '',
|
@@ -20,21 +33,44 @@ class WPT_TwitterFeed {
|
|
20 |
'token' => '',
|
21 |
'token_secret' => '',
|
22 |
'screenname' => false,
|
23 |
-
'cache_expire' => 1800
|
24 |
);
|
25 |
|
|
|
|
|
|
|
|
|
|
|
26 |
public $st_last_error = false;
|
27 |
|
|
|
|
|
|
|
|
|
|
|
28 |
function __construct( $args = array() ) {
|
29 |
$this->defaults = array_merge( $this->defaults, $args );
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
|
|
32 |
function __toString() {
|
33 |
return print_r( $this->defaults, true );
|
34 |
}
|
35 |
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
if ( $count > 20 ) {
|
39 |
/**
|
40 |
* Filters the max feed count. Default is 20, but you can change it.
|
@@ -49,37 +85,49 @@ class WPT_TwitterFeed {
|
|
49 |
$count = 1;
|
50 |
}
|
51 |
|
52 |
-
$default_options = array(
|
|
|
|
|
|
|
|
|
53 |
|
54 |
-
if (
|
55 |
$options = $default_options;
|
56 |
} else {
|
57 |
$options = array_merge( $default_options, $options );
|
58 |
}
|
59 |
|
60 |
-
if ( $screenname
|
61 |
$screenname = get_option( 'wtt_twitter_username' );
|
62 |
}
|
63 |
|
64 |
-
$result = $this->
|
65 |
-
if (
|
66 |
-
return $this->
|
67 |
}
|
68 |
|
69 |
-
//If we're here, we need to load.
|
70 |
-
$result = $this->
|
71 |
|
72 |
if ( is_object( $result ) && isset( $result->error ) ) {
|
73 |
$last_error = $result->error;
|
74 |
|
75 |
return array( 'error' => 'Twitter said: ' . $last_error );
|
76 |
} else {
|
77 |
-
return $this->
|
78 |
}
|
79 |
|
80 |
}
|
81 |
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
if ( is_array( $result ) ) {
|
84 |
return array_slice( $result, 0, $count );
|
85 |
} else {
|
@@ -87,16 +135,32 @@ class WPT_TwitterFeed {
|
|
87 |
}
|
88 |
}
|
89 |
|
90 |
-
|
|
|
|
|
|
|
91 |
return $this->defaults['directory'] . '.tweetcache';
|
92 |
}
|
93 |
|
94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
$hash = md5( serialize( $options ) );
|
96 |
|
97 |
return $hash;
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
private function save_cache( $file, $cache ) {
|
101 |
$is_writable = wpt_is_writable( $file );
|
102 |
if ( $is_writable ) {
|
@@ -106,6 +170,11 @@ class WPT_TwitterFeed {
|
|
106 |
}
|
107 |
}
|
108 |
|
|
|
|
|
|
|
|
|
|
|
109 |
private function delete_cache( $file ) {
|
110 |
$is_writable = wpt_is_writable( $file );
|
111 |
if ( $is_writable ) {
|
@@ -113,20 +182,28 @@ class WPT_TwitterFeed {
|
|
113 |
} else {
|
114 |
delete_transient( 'wpt_cache' );
|
115 |
}
|
116 |
-
}
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
$delete_cache = get_option( 'wpt_delete_cache' );
|
120 |
-
$file
|
121 |
-
|
122 |
-
if (
|
123 |
update_option( 'wpt_delete_cache', 'false' );
|
124 |
$this->delete_cache( $file );
|
125 |
}
|
126 |
-
|
127 |
if ( is_file( $file ) ) {
|
128 |
$cache = file_get_contents( $file );
|
129 |
-
$cache =
|
130 |
if ( ! isset( $cache ) ) {
|
131 |
unlink( $file );
|
132 |
|
@@ -134,14 +211,14 @@ class WPT_TwitterFeed {
|
|
134 |
}
|
135 |
} else {
|
136 |
$cache = get_transient( 'wpt_cache' );
|
137 |
-
$cache =
|
138 |
if ( ! isset( $cache ) ) {
|
139 |
return false;
|
140 |
}
|
141 |
}
|
142 |
-
$cachename = $screenname .
|
143 |
|
144 |
-
//Check if we have a cache for the user.
|
145 |
if ( ! isset( $cache[ $cachename ] ) ) {
|
146 |
return false;
|
147 |
}
|
@@ -154,7 +231,7 @@ class WPT_TwitterFeed {
|
|
154 |
}
|
155 |
|
156 |
if ( $cache[ $cachename ]['time'] < ( time() - $this->defaults['cache_expire'] ) ) {
|
157 |
-
$result = $this->
|
158 |
if ( ! isset( $result->error ) ) {
|
159 |
return $result;
|
160 |
}
|
@@ -163,13 +240,25 @@ class WPT_TwitterFeed {
|
|
163 |
return $cache[ $cachename ]['tweets'];
|
164 |
}
|
165 |
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
$key = $this->defaults['key'];
|
168 |
$secret = $this->defaults['secret'];
|
169 |
$token = $this->defaults['token'];
|
170 |
$token_secret = $this->defaults['token_secret'];
|
171 |
-
$cachename = $screenname .
|
172 |
-
$options = array_merge( $options, array(
|
|
|
|
|
|
|
|
|
173 |
|
174 |
if ( empty( $key ) ) {
|
175 |
return array( 'error' => __( 'Missing Consumer Key - Check settings', 'wp-to-twitter' ) );
|
@@ -190,10 +279,11 @@ class WPT_TwitterFeed {
|
|
190 |
$connection = new wpt_TwitterOAuth( $key, $secret, $token, $token_secret );
|
191 |
|
192 |
if ( isset( $options['search'] ) ) {
|
193 |
-
$args = array(
|
194 |
-
|
|
|
195 |
);
|
196 |
-
if ( $options['geocode']
|
197 |
$args['geocode'] = urlencode( $options['geocode'] );
|
198 |
}
|
199 |
$url = add_query_arg( $args, 'https://api.twitter.com/1.1/search/tweets.json' );
|
@@ -203,28 +293,30 @@ class WPT_TwitterFeed {
|
|
203 |
}
|
204 |
$result = json_decode( $result );
|
205 |
if ( isset( $options['search'] ) ) {
|
206 |
-
if ( !method_exists( $result, 'errors' ) ) {
|
207 |
-
$result = $result->statuses;
|
208 |
} else {
|
209 |
$errors = $result->errors;
|
210 |
$return = '';
|
211 |
foreach ( $errors as $error ) {
|
212 |
$return .= "<li>$error->message</li>";
|
213 |
}
|
214 |
-
echo
|
|
|
215 |
}
|
216 |
}
|
217 |
-
if ( is_file( $this->
|
218 |
-
$cache = json_decode( file_get_contents( $this->
|
219 |
}
|
220 |
|
221 |
if ( ! isset( $result->error ) ) {
|
222 |
$cache[ $cachename ]['time'] = time();
|
223 |
$cache[ $cachename ]['tweets'] = $result;
|
224 |
-
$file = $this->
|
225 |
$this->save_cache( $file, json_encode( $cache ) );
|
226 |
} else {
|
227 |
if ( is_array( $result ) && isset( $result['errors'][0] ) && isset( $result['errors'][0]['message'] ) ) {
|
|
|
228 |
$last_error = '[' . date( 'r' ) . '] ' . sprintf( __( 'Twitter error: %s', 'wp-to-twitter' ), $result['errors'][0]['message'] );
|
229 |
$this->st_last_error = $last_error;
|
230 |
} else {
|
@@ -232,9 +324,9 @@ class WPT_TwitterFeed {
|
|
232 |
$this->st_last_error = $last_error;
|
233 |
}
|
234 |
}
|
235 |
-
// Run an action on the results output from the Twitter widget query
|
236 |
do_action( 'wpt_process_tweets', $result, $screenname, $options );
|
237 |
|
238 |
return $result;
|
239 |
}
|
240 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP to Twitter Twitter Feed Class
|
4 |
+
*
|
5 |
+
* @category Widgets
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
+
require_once( 'class-wpt-twitteroauth.php' );
|
17 |
|
18 |
+
/**
|
19 |
+
* Based on Version 2.0.3, Twitter Feed for Developers by Storm Consultancy (Liam Gladdy)
|
20 |
+
* The base class for the storm twitter feed for developers.
|
21 |
+
*/
|
22 |
class WPT_TwitterFeed {
|
23 |
|
24 |
+
/**
|
25 |
+
* Default feed settings.
|
26 |
+
*
|
27 |
+
* @var $defaults.
|
28 |
+
*/
|
29 |
private $defaults = array(
|
30 |
'directory' => '',
|
31 |
'key' => '',
|
33 |
'token' => '',
|
34 |
'token_secret' => '',
|
35 |
'screenname' => false,
|
36 |
+
'cache_expire' => 1800,
|
37 |
);
|
38 |
|
39 |
+
/**
|
40 |
+
* Last error, if any.
|
41 |
+
*
|
42 |
+
* @var $st_last_error
|
43 |
+
*/
|
44 |
public $st_last_error = false;
|
45 |
|
46 |
+
/**
|
47 |
+
* Constructor.
|
48 |
+
*
|
49 |
+
* @param array $args Arguments; merged with defaults.
|
50 |
+
*/
|
51 |
function __construct( $args = array() ) {
|
52 |
$this->defaults = array_merge( $this->defaults, $args );
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* Convert arguments into a string.
|
57 |
+
*
|
58 |
+
* @return print_r of arguments.
|
59 |
+
*/
|
60 |
function __toString() {
|
61 |
return print_r( $this->defaults, true );
|
62 |
}
|
63 |
|
64 |
+
/**
|
65 |
+
* Get Tweets for a given screen name.
|
66 |
+
*
|
67 |
+
* @param int $count Number of Tweets to fetch.
|
68 |
+
* @param string $screenname Twitter account feed to fetch.
|
69 |
+
* @param array $options Options to apply for display of feed.
|
70 |
+
*
|
71 |
+
* @return Tweets or error message.
|
72 |
+
*/
|
73 |
+
function get_tweets( $count = 20, $screenname = false, $options = false ) {
|
74 |
if ( $count > 20 ) {
|
75 |
/**
|
76 |
* Filters the max feed count. Default is 20, but you can change it.
|
85 |
$count = 1;
|
86 |
}
|
87 |
|
88 |
+
$default_options = array(
|
89 |
+
'trim_user' => true,
|
90 |
+
'exclude_replies' => true,
|
91 |
+
'include_rts' => false,
|
92 |
+
);
|
93 |
|
94 |
+
if ( false === $options || ! is_array( $options ) ) {
|
95 |
$options = $default_options;
|
96 |
} else {
|
97 |
$options = array_merge( $default_options, $options );
|
98 |
}
|
99 |
|
100 |
+
if ( false === $screenname ) {
|
101 |
$screenname = get_option( 'wtt_twitter_username' );
|
102 |
}
|
103 |
|
104 |
+
$result = $this->check_valid_cache( $screenname, $options );
|
105 |
+
if ( false !== $result ) {
|
106 |
+
return $this->crop_tweets( $result, $count );
|
107 |
}
|
108 |
|
109 |
+
// If we're here, we need to load.
|
110 |
+
$result = $this->oauth_get_tweets( $screenname, $options );
|
111 |
|
112 |
if ( is_object( $result ) && isset( $result->error ) ) {
|
113 |
$last_error = $result->error;
|
114 |
|
115 |
return array( 'error' => 'Twitter said: ' . $last_error );
|
116 |
} else {
|
117 |
+
return $this->crop_tweets( $result, $count );
|
118 |
}
|
119 |
|
120 |
}
|
121 |
|
122 |
+
/**
|
123 |
+
* Crop list of Tweets to display correct number of items.
|
124 |
+
*
|
125 |
+
* @param array $result Full query result.
|
126 |
+
* @param int $count Tweets to show.
|
127 |
+
*
|
128 |
+
* @return array
|
129 |
+
*/
|
130 |
+
private function crop_tweets( $result, $count ) {
|
131 |
if ( is_array( $result ) ) {
|
132 |
return array_slice( $result, 0, $count );
|
133 |
} else {
|
135 |
}
|
136 |
}
|
137 |
|
138 |
+
/**
|
139 |
+
* Locate cache.
|
140 |
+
*/
|
141 |
+
private function get_cache_location() {
|
142 |
return $this->defaults['directory'] . '.tweetcache';
|
143 |
}
|
144 |
|
145 |
+
/**
|
146 |
+
* Hash options so cache is unique.
|
147 |
+
*
|
148 |
+
* @param array $options Display options.
|
149 |
+
*
|
150 |
+
* @return md5 hash.
|
151 |
+
*/
|
152 |
+
private function get_options_hash( $options ) {
|
153 |
$hash = md5( serialize( $options ) );
|
154 |
|
155 |
return $hash;
|
156 |
}
|
157 |
|
158 |
+
/**
|
159 |
+
* Save cache to file.
|
160 |
+
*
|
161 |
+
* @param string $file Cache file location.
|
162 |
+
* @param string $cache Data to save.
|
163 |
+
*/
|
164 |
private function save_cache( $file, $cache ) {
|
165 |
$is_writable = wpt_is_writable( $file );
|
166 |
if ( $is_writable ) {
|
170 |
}
|
171 |
}
|
172 |
|
173 |
+
/**
|
174 |
+
* Delete cache.
|
175 |
+
*
|
176 |
+
* @param string $file File name.
|
177 |
+
*/
|
178 |
private function delete_cache( $file ) {
|
179 |
$is_writable = wpt_is_writable( $file );
|
180 |
if ( $is_writable ) {
|
182 |
} else {
|
183 |
delete_transient( 'wpt_cache' );
|
184 |
}
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Fetch and verify cache.
|
189 |
+
*
|
190 |
+
* @param string $screenname Name to get cache for.
|
191 |
+
* @param array $options Options for cache being fetched.
|
192 |
+
*
|
193 |
+
* @return boolean or cache contents.
|
194 |
+
*/
|
195 |
+
private function check_valid_cache( $screenname, $options ) {
|
196 |
$delete_cache = get_option( 'wpt_delete_cache' );
|
197 |
+
$file = $this->get_cache_location();
|
198 |
+
|
199 |
+
if ( 'true' == $delete_cache ) {
|
200 |
update_option( 'wpt_delete_cache', 'false' );
|
201 |
$this->delete_cache( $file );
|
202 |
}
|
203 |
+
|
204 |
if ( is_file( $file ) ) {
|
205 |
$cache = file_get_contents( $file );
|
206 |
+
$cache = json_decode( $cache, true );
|
207 |
if ( ! isset( $cache ) ) {
|
208 |
unlink( $file );
|
209 |
|
211 |
}
|
212 |
} else {
|
213 |
$cache = get_transient( 'wpt_cache' );
|
214 |
+
$cache = json_decode( $cache, true );
|
215 |
if ( ! isset( $cache ) ) {
|
216 |
return false;
|
217 |
}
|
218 |
}
|
219 |
+
$cachename = $screenname . '-' . $this->get_options_hash( $options );
|
220 |
|
221 |
+
// Check if we have a cache for the user.
|
222 |
if ( ! isset( $cache[ $cachename ] ) ) {
|
223 |
return false;
|
224 |
}
|
231 |
}
|
232 |
|
233 |
if ( $cache[ $cachename ]['time'] < ( time() - $this->defaults['cache_expire'] ) ) {
|
234 |
+
$result = $this->oauth_get_tweets( $screenname, $options );
|
235 |
if ( ! isset( $result->error ) ) {
|
236 |
return $result;
|
237 |
}
|
240 |
return $cache[ $cachename ]['tweets'];
|
241 |
}
|
242 |
|
243 |
+
/**
|
244 |
+
* Fetch Tweets from Twitter.
|
245 |
+
*
|
246 |
+
* @param string $screenname Username.
|
247 |
+
* @param array $options Array of display options.
|
248 |
+
*
|
249 |
+
* @return Tweets.
|
250 |
+
*/
|
251 |
+
private function oauth_get_tweets( $screenname, $options ) {
|
252 |
$key = $this->defaults['key'];
|
253 |
$secret = $this->defaults['secret'];
|
254 |
$token = $this->defaults['token'];
|
255 |
$token_secret = $this->defaults['token_secret'];
|
256 |
+
$cachename = $screenname . '-' . $this->get_options_hash( $options );
|
257 |
+
$options = array_merge( $options, array(
|
258 |
+
'screen_name' => $screenname,
|
259 |
+
'count' => 20,
|
260 |
+
'include_ext_alt_text' => 'true',
|
261 |
+
) );
|
262 |
|
263 |
if ( empty( $key ) ) {
|
264 |
return array( 'error' => __( 'Missing Consumer Key - Check settings', 'wp-to-twitter' ) );
|
279 |
$connection = new wpt_TwitterOAuth( $key, $secret, $token, $token_secret );
|
280 |
|
281 |
if ( isset( $options['search'] ) ) {
|
282 |
+
$args = array(
|
283 |
+
'q' => urlencode( $options['search'] ),
|
284 |
+
'result_type' => urlencode( $options['result_type'] ),
|
285 |
);
|
286 |
+
if ( '' != $options['geocode'] ) {
|
287 |
$args['geocode'] = urlencode( $options['geocode'] );
|
288 |
}
|
289 |
$url = add_query_arg( $args, 'https://api.twitter.com/1.1/search/tweets.json' );
|
293 |
}
|
294 |
$result = json_decode( $result );
|
295 |
if ( isset( $options['search'] ) ) {
|
296 |
+
if ( ! method_exists( $result, 'errors' ) ) {
|
297 |
+
$result = ( is_object( $result ) ) ? $result->statuses : '';
|
298 |
} else {
|
299 |
$errors = $result->errors;
|
300 |
$return = '';
|
301 |
foreach ( $errors as $error ) {
|
302 |
$return .= "<li>$error->message</li>";
|
303 |
}
|
304 |
+
echo '<ul>' . $return . '</ul>';
|
305 |
+
return;
|
306 |
}
|
307 |
}
|
308 |
+
if ( is_file( $this->get_cache_location() ) ) {
|
309 |
+
$cache = json_decode( file_get_contents( $this->get_cache_location() ), true );
|
310 |
}
|
311 |
|
312 |
if ( ! isset( $result->error ) ) {
|
313 |
$cache[ $cachename ]['time'] = time();
|
314 |
$cache[ $cachename ]['tweets'] = $result;
|
315 |
+
$file = $this->get_cache_location();
|
316 |
$this->save_cache( $file, json_encode( $cache ) );
|
317 |
} else {
|
318 |
if ( is_array( $result ) && isset( $result['errors'][0] ) && isset( $result['errors'][0]['message'] ) ) {
|
319 |
+
// Translators: Error message.
|
320 |
$last_error = '[' . date( 'r' ) . '] ' . sprintf( __( 'Twitter error: %s', 'wp-to-twitter' ), $result['errors'][0]['message'] );
|
321 |
$this->st_last_error = $last_error;
|
322 |
} else {
|
324 |
$this->st_last_error = $last_error;
|
325 |
}
|
326 |
}
|
327 |
+
// Run an action on the results output from the Twitter widget query.
|
328 |
do_action( 'wpt_process_tweets', $result, $screenname, $options );
|
329 |
|
330 |
return $result;
|
331 |
}
|
332 |
+
}
|
classes/class-wpt-twitteroauth.php
ADDED
@@ -0,0 +1,420 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Abraham Williams (abraham@abrah.am) http://abrah.am
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*
|
11 |
+
* The first PHP Library to support WPOAuth for Twitter's REST API.
|
12 |
+
*/
|
13 |
+
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
|
18 |
+
require_once( 'class-wp-oauth.php' );
|
19 |
+
|
20 |
+
if ( ! class_exists( 'Wpt_TwitterOAuth' ) ) {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Twitter WPOAuth class
|
24 |
+
*/
|
25 |
+
class Wpt_TwitterOAuth {
|
26 |
+
/**
|
27 |
+
* Contains the last HTTP status code returned
|
28 |
+
*
|
29 |
+
* @var status code
|
30 |
+
*/
|
31 |
+
public $http_code;
|
32 |
+
/**
|
33 |
+
* Contains the last API call.
|
34 |
+
*
|
35 |
+
* @var $url
|
36 |
+
*/
|
37 |
+
public $url;
|
38 |
+
/**
|
39 |
+
* Set up the API root URL.
|
40 |
+
*
|
41 |
+
* @var $host
|
42 |
+
*/
|
43 |
+
public $host = 'https://api.twitter.com/1.1/';
|
44 |
+
/**
|
45 |
+
* Set timeout default.
|
46 |
+
*
|
47 |
+
* @var $format
|
48 |
+
*/
|
49 |
+
public $format = 'json';
|
50 |
+
/**
|
51 |
+
* Decode returned json data.
|
52 |
+
*
|
53 |
+
* @var $decode_json
|
54 |
+
*/
|
55 |
+
public $decode_json = false;
|
56 |
+
/**
|
57 |
+
* Contains the last API call
|
58 |
+
*
|
59 |
+
* @var $last_api_call
|
60 |
+
*/
|
61 |
+
private $last_api_call;
|
62 |
+
/**
|
63 |
+
* Contains the header
|
64 |
+
*
|
65 |
+
* @var $http_header
|
66 |
+
*/
|
67 |
+
public $http_header;
|
68 |
+
/**
|
69 |
+
* Contains the body
|
70 |
+
*
|
71 |
+
* @var $body
|
72 |
+
*/
|
73 |
+
public $body;
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Set API URLS
|
77 |
+
*
|
78 |
+
* @return access token endpoint.
|
79 |
+
*/
|
80 |
+
function access_token_url() {
|
81 |
+
return 'https://api.twitter.com/oauth/access_token';
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Set authentication URL.
|
86 |
+
*
|
87 |
+
* @return authentication endpoint.
|
88 |
+
*/
|
89 |
+
function authenticate_url() {
|
90 |
+
return 'https://api.twitter.com/oauth/authenticate';
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Set authorization URL.
|
95 |
+
*
|
96 |
+
* @return authorization endpoint.
|
97 |
+
*/
|
98 |
+
function authorize_url() {
|
99 |
+
return 'https://api.twitter.com/oauth/authorize';
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Set request Token URL.
|
104 |
+
*
|
105 |
+
* @return request token ednpoint.
|
106 |
+
*/
|
107 |
+
function request_token_url() {
|
108 |
+
return 'https://api.twitter.com/oauth/request_token';
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Debug helpers
|
113 |
+
*
|
114 |
+
* @return last query's http code response.
|
115 |
+
*/
|
116 |
+
function last_status_code() {
|
117 |
+
return $this->http_code;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Return last API call.
|
122 |
+
*
|
123 |
+
* @return last query API call.
|
124 |
+
*/
|
125 |
+
function last_api_call() {
|
126 |
+
return $this->last_api_call;
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Construct TwitterWPOAuth object
|
131 |
+
*
|
132 |
+
* @param string $consumer_key Consumer key.
|
133 |
+
* @param string $consumer_secret Consumer secret.
|
134 |
+
* @param string $wp_oauth_token Token.
|
135 |
+
* @param string $wp_oauth_token_secret Token secret.
|
136 |
+
*/
|
137 |
+
function __construct( $consumer_key, $consumer_secret, $wp_oauth_token = null, $wp_oauth_token_secret = null ) {
|
138 |
+
$this->sha1_method = new WPOAuthSignatureMethod_HMAC_SHA1();
|
139 |
+
$this->consumer = new WPOAuthConsumer( $consumer_key, $consumer_secret );
|
140 |
+
if ( ! empty( $wp_oauth_token ) && ! empty( $wp_oauth_token_secret ) ) {
|
141 |
+
$this->token = new WPOAuthConsumer( $wp_oauth_token, $wp_oauth_token_secret );
|
142 |
+
} else {
|
143 |
+
$this->token = null;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Get a request_token from Twitter
|
150 |
+
*
|
151 |
+
* @returns a key/value array containing WPOAuth_token and WPOAuth_token_secret
|
152 |
+
*/
|
153 |
+
function get_request_token() {
|
154 |
+
$r = $this->wp_oauth_request( $this->request_token_url() );
|
155 |
+
$token = $this->wp_oauth_parse_response( $r );
|
156 |
+
$this->token = new WPOAuthConsumer( $token['WPOAuth_token'], $token['WPOAuth_token_secret'] );
|
157 |
+
|
158 |
+
return $token;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Parse a URL-encoded WPOAuth response
|
163 |
+
*
|
164 |
+
* @param string $response_string String from response.
|
165 |
+
*
|
166 |
+
* @return a key/value array
|
167 |
+
*/
|
168 |
+
function wp_oauth_parse_response( $response_string ) {
|
169 |
+
$r = array();
|
170 |
+
foreach ( explode( '&', $response_string ) as $param ) {
|
171 |
+
$pair = explode( '=', $param, 2 );
|
172 |
+
if ( count( $pair ) != 2 ) {
|
173 |
+
continue;
|
174 |
+
}
|
175 |
+
$r[ urldecode( $pair[0] ) ] = urldecode( $pair[1] );
|
176 |
+
}
|
177 |
+
|
178 |
+
return $r;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Get the authorize URL
|
183 |
+
*
|
184 |
+
* @param array $token Token array.
|
185 |
+
*
|
186 |
+
* @returns a string
|
187 |
+
*/
|
188 |
+
function getauthorize_url( $token ) {
|
189 |
+
if ( is_array( $token ) ) {
|
190 |
+
$token = $token['WPOAuth_token'];
|
191 |
+
}
|
192 |
+
|
193 |
+
return $this->authorize_url() . '?WPOAuth_token=' . $token;
|
194 |
+
}
|
195 |
+
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Get the authenticate URL
|
199 |
+
*
|
200 |
+
* @param array $token Token array.
|
201 |
+
*
|
202 |
+
* @returns a string
|
203 |
+
*/
|
204 |
+
function getauthenticate_url( $token ) {
|
205 |
+
if ( is_array( $token ) ) {
|
206 |
+
$token = $token['WPOAuth_token'];
|
207 |
+
}
|
208 |
+
|
209 |
+
return $this->authenticate_url() . '?WPOAuth_token=' . $token;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Exchange the request token and secret for an access token and secret, to sign API calls.
|
214 |
+
*
|
215 |
+
* @param array $token Token array.
|
216 |
+
*
|
217 |
+
* @returns array("WPOAuth_token" => the access token, "WPOAuth_token_secret" => the access secret)
|
218 |
+
*/
|
219 |
+
function get_access_token( $token = null ) {
|
220 |
+
$r = $this->wp_oauth_request( $this->access_token_url() );
|
221 |
+
$token = $this->wp_oauth_parse_response( $r );
|
222 |
+
$this->token = new WPOAuthConsumer( $token['WPOAuth_token'], $token['WPOAuth_token_secret'] );
|
223 |
+
|
224 |
+
return $token;
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Wrapper for POST requests
|
229 |
+
*
|
230 |
+
* @param string $url URL.
|
231 |
+
* @param array $parameters Request params.
|
232 |
+
*
|
233 |
+
* @return decoded response.
|
234 |
+
*/
|
235 |
+
function post( $url, $parameters = array() ) {
|
236 |
+
$response = $this->wp_oauth_request( $url, $parameters, 'POST' );
|
237 |
+
if ( 'json' === $this->format && $this->decode_json ) {
|
238 |
+
return json_decode( $response );
|
239 |
+
}
|
240 |
+
|
241 |
+
return $response;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Wrapper for MEDIA requests
|
246 |
+
*
|
247 |
+
* @param string $url URL.
|
248 |
+
* @param array $parameters Request params.
|
249 |
+
*
|
250 |
+
* @return decoded response.
|
251 |
+
*/
|
252 |
+
function media( $url, $parameters = array() ) {
|
253 |
+
$response = $this->wp_oauth_request( $url, $parameters, 'MEDIA' );
|
254 |
+
if ( 'json' === $this->format && $this->decode_json ) {
|
255 |
+
return json_decode( $response );
|
256 |
+
}
|
257 |
+
|
258 |
+
return $response;
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Wrapper for GET requests
|
263 |
+
*
|
264 |
+
* @param string $url URL.
|
265 |
+
* @param array $parameters Request params.
|
266 |
+
*
|
267 |
+
* @return decoded response.
|
268 |
+
*/
|
269 |
+
function get( $url, $parameters = array() ) {
|
270 |
+
$response = $this->wp_oauth_request( $url, $parameters, 'GET' );
|
271 |
+
if ( 'json' === $this->format && $this->decode_json ) {
|
272 |
+
return json_decode( $response );
|
273 |
+
}
|
274 |
+
|
275 |
+
return $response;
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Handles a status update that includes an image.
|
280 |
+
*
|
281 |
+
* @param string $url Target URL.
|
282 |
+
* @param array $args Array of arguments to send.
|
283 |
+
*
|
284 |
+
* @return boolean
|
285 |
+
*/
|
286 |
+
function handle_media_request( $url, $args = array() ) {
|
287 |
+
// Load tmhOAuth for Media uploads only when needed: https://github.com/themattharris/tmhOAuth.
|
288 |
+
// It's not possible to upload media using WP_HTTP, so this needs to use cURL.
|
289 |
+
if ( ! class_exists( 'tmhOAuth' ) ) {
|
290 |
+
require_once( plugin_dir_path( __FILE__ ) . 'class-tmhoauth.php' );
|
291 |
+
}
|
292 |
+
$auth = $args['auth'];
|
293 |
+
if ( ! $auth ) {
|
294 |
+
$ack = get_option( 'app_consumer_key' );
|
295 |
+
$acs = get_option( 'app_consumer_secret' );
|
296 |
+
$ot = get_option( 'oauth_token' );
|
297 |
+
$ots = get_option( 'oauth_token_secret' );
|
298 |
+
} else {
|
299 |
+
$ack = get_user_meta( $auth, 'app_consumer_key', true );
|
300 |
+
$acs = get_user_meta( $auth, 'app_consumer_secret', true );
|
301 |
+
$ot = get_user_meta( $auth, 'oauth_token', true );
|
302 |
+
$ots = get_user_meta( $auth, 'oauth_token_secret', true );
|
303 |
+
}
|
304 |
+
// when performing as a scheduled action, need to include file.php.
|
305 |
+
if ( ! function_exists( 'get_home_path' ) ) {
|
306 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
307 |
+
}
|
308 |
+
$connect = array(
|
309 |
+
'consumer_key' => $ack,
|
310 |
+
'consumer_secret' => $acs,
|
311 |
+
'user_token' => $ot,
|
312 |
+
'user_secret' => $ots,
|
313 |
+
);
|
314 |
+
$tmh_oauth = new TmhOAuth( $connect );
|
315 |
+
$attachment = $args['media'];
|
316 |
+
|
317 |
+
$image_sizes = get_intermediate_image_sizes();
|
318 |
+
if ( in_array( 'large', $image_sizes ) ) {
|
319 |
+
$size = 'large';
|
320 |
+
} else {
|
321 |
+
$size = array_pop( $image_sizes );
|
322 |
+
}
|
323 |
+
$upload = wp_get_attachment_image_src( $attachment, apply_filters( 'wpt_upload_image_size', $size ) );
|
324 |
+
$image_url = $upload[0];
|
325 |
+
$remote = wp_remote_get( $image_url );
|
326 |
+
if ( is_wp_error( $remote ) ) {
|
327 |
+
$transport = 'curl';
|
328 |
+
$binary = wp_get_curl( $image_url );
|
329 |
+
} else {
|
330 |
+
$transport = 'wp_http';
|
331 |
+
$binary = wp_remote_retrieve_body( $remote );
|
332 |
+
}
|
333 |
+
wpt_mail( 'Media fetched binary', print_r( $remote, 1 ) . "\n\n" . print_r( $binary, 1 ) );
|
334 |
+
if ( ! $binary ) {
|
335 |
+
return;
|
336 |
+
}
|
337 |
+
|
338 |
+
$mime_type = get_post_mime_type( $attachment );
|
339 |
+
if ( ! $mime_type ) {
|
340 |
+
$mime_type = 'image/jpeg';
|
341 |
+
}
|
342 |
+
|
343 |
+
$code = $tmh_oauth->request( 'POST', $url, array( 'media' => "$binary" ), true, true );
|
344 |
+
$response = $tmh_oauth->response['response'];
|
345 |
+
$full = $tmh_oauth->response;
|
346 |
+
wpt_mail( 'Media Posted', "
|
347 |
+
Media ID #$args[media] ($transport)" . "\n\n" .
|
348 |
+
'Twitter Response' . "\n" . print_r( $full, 1 ) . "\n\n" .
|
349 |
+
'Attachment Details' . "\n" . print_r( $upload, 1 ) . "\n\n" .
|
350 |
+
'Img Request Response' . "\n" . print_r( $remote, 1 )
|
351 |
+
);
|
352 |
+
|
353 |
+
if ( is_wp_error( $response ) ) {
|
354 |
+
return '';
|
355 |
+
}
|
356 |
+
|
357 |
+
$this->http_code = $code;
|
358 |
+
$this->last_api_call = $url;
|
359 |
+
$this->format = 'json';
|
360 |
+
$this->http_header = $response;
|
361 |
+
$response = json_decode( $response );
|
362 |
+
$media_id = $response->media_id_string;
|
363 |
+
|
364 |
+
return $media_id;
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Format and sign an WPOAuth / API request
|
369 |
+
*
|
370 |
+
* @param string $url Target URL.
|
371 |
+
* @param array $args Arguments for signing.
|
372 |
+
* @param string $method Method type.
|
373 |
+
*
|
374 |
+
* @return Request.
|
375 |
+
*/
|
376 |
+
function wp_oauth_request( $url, $args = array(), $method = null ) {
|
377 |
+
// Handle media requests using tmhOAuth library.
|
378 |
+
if ( 'MEDIA' == $method ) {
|
379 |
+
return $this->handle_media_request( $url, $args );
|
380 |
+
}
|
381 |
+
|
382 |
+
if ( empty( $method ) ) {
|
383 |
+
$method = empty( $args ) ? 'GET' : 'POST';
|
384 |
+
}
|
385 |
+
$req = WP_Oauth_Request::from_consumer_and_token( $this->consumer, $this->token, $method, $url, $args );
|
386 |
+
$req->sign_request( $this->sha1_method, $this->consumer, $this->token );
|
387 |
+
|
388 |
+
$response = false;
|
389 |
+
$url = null;
|
390 |
+
|
391 |
+
switch ( $method ) {
|
392 |
+
case 'GET':
|
393 |
+
$url = $req->to_url();
|
394 |
+
$response = wp_remote_get( $url );
|
395 |
+
break;
|
396 |
+
case 'POST':
|
397 |
+
// TODO: if JSON, need to authenticate, pass bearer authentication as header in query.
|
398 |
+
// TODO: add content-type when JSON.
|
399 |
+
$url = $req->get_normalized_http_url();
|
400 |
+
$args = wp_parse_args( $req->to_postdata() );
|
401 |
+
$response = wp_remote_post( $url, array(
|
402 |
+
'body' => $args,
|
403 |
+
'timeout' => 30,
|
404 |
+
) );
|
405 |
+
break;
|
406 |
+
}
|
407 |
+
|
408 |
+
if ( is_wp_error( $response ) ) {
|
409 |
+
return false;
|
410 |
+
}
|
411 |
+
$this->http_code = $response['response']['code'];
|
412 |
+
$this->body = json_decode( $response['body'] );
|
413 |
+
$this->last_api_call = $url;
|
414 |
+
$this->format = 'json';
|
415 |
+
$this->http_header = $response['headers'];
|
416 |
+
|
417 |
+
return $response['body'];
|
418 |
+
}
|
419 |
+
}
|
420 |
+
}
|
css/styles.css
CHANGED
@@ -209,12 +209,12 @@ label[for="wpt_license_key"] {
|
|
209 |
}
|
210 |
|
211 |
.tweet {
|
212 |
-
background: #070 url(../images/Ok.png)
|
213 |
color: #fff;
|
214 |
}
|
215 |
|
216 |
.notweet {
|
217 |
-
background: #9d1309 url(../images/Error.png)
|
218 |
color: #fff;
|
219 |
}
|
220 |
|
209 |
}
|
210 |
|
211 |
.tweet {
|
212 |
+
background: #070 url(../images/Ok.png) 99% 50% no-repeat;
|
213 |
color: #fff;
|
214 |
}
|
215 |
|
216 |
.notweet {
|
217 |
+
background: #9d1309 url(../images/Error.png) 99% 50% no-repeat;
|
218 |
color: #fff;
|
219 |
}
|
220 |
|
readme.txt
CHANGED
@@ -4,9 +4,10 @@ Donate link: http://www.joedolson.com/donate/
|
|
4 |
Tags: twitter, microblogging, su.pr, bitly, yourls, redirect, shortener, post, links, social, sharing, media, tweet
|
5 |
Requires at least: 4.4
|
6 |
Tested up to: 4.9
|
|
|
7 |
License: GPLv2 or later
|
8 |
Text Domain: wp-to-twitter
|
9 |
-
Stable tag: 3.3.
|
10 |
|
11 |
Posts a Twitter update when you update your WordPress blog or add a link, with your chosen URL shortening service.
|
12 |
|
@@ -64,6 +65,21 @@ Check out my <a href="https://github.com/joedolson/plugin-extensions/tree/master
|
|
64 |
|
65 |
== Changelog ==
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
= 3.3.2 =
|
68 |
|
69 |
* If short URL already stored, do not execute shortening routine
|
4 |
Tags: twitter, microblogging, su.pr, bitly, yourls, redirect, shortener, post, links, social, sharing, media, tweet
|
5 |
Requires at least: 4.4
|
6 |
Tested up to: 4.9
|
7 |
+
Requires PHP: 5.3
|
8 |
License: GPLv2 or later
|
9 |
Text Domain: wp-to-twitter
|
10 |
+
Stable tag: 3.3.3
|
11 |
|
12 |
Posts a Twitter update when you update your WordPress blog or add a link, with your chosen URL shortening service.
|
13 |
|
65 |
|
66 |
== Changelog ==
|
67 |
|
68 |
+
= 3.3.3 =
|
69 |
+
|
70 |
+
* Removed: upgrade paths from version 2.4.x
|
71 |
+
* Removed: support for YOURLS version 1.3
|
72 |
+
* Removed: support for Twitter Friendly Links (plug-in not updated in 8 years)
|
73 |
+
* Removed: Ability to enable the Goo.gl URL shortener (see: https://developers.google.com/url-shortener/)
|
74 |
+
* Removed: fallback functions required for PHP 4 support.
|
75 |
+
* Add 'show images' as option in feeds.
|
76 |
+
* Support for alt attributes displayed in Feeds
|
77 |
+
* Improved URL generation to link to searched Tweets.
|
78 |
+
* Improve parsing of URLs in Tweets.
|
79 |
+
* Don't save URLs if no shortener used or shortener returns no value.
|
80 |
+
* Option to ignore stored URLs when sending Tweets.
|
81 |
+
* Code now conforms with WordPress PHP standards with the exception of four deprecated functions.
|
82 |
+
|
83 |
= 3.3.2 =
|
84 |
|
85 |
* If short URL already stored, do not execute shortening routine
|
tmhOAuth/LICENSE
DELETED
@@ -1,202 +0,0 @@
|
|
1 |
-
|
2 |
-
Apache License
|
3 |
-
Version 2.0, January 2004
|
4 |
-
http://www.apache.org/licenses/
|
5 |
-
|
6 |
-
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
7 |
-
|
8 |
-
1. Definitions.
|
9 |
-
|
10 |
-
"License" shall mean the terms and conditions for use, reproduction,
|
11 |
-
and distribution as defined by Sections 1 through 9 of this document.
|
12 |
-
|
13 |
-
"Licensor" shall mean the copyright owner or entity authorized by
|
14 |
-
the copyright owner that is granting the License.
|
15 |
-
|
16 |
-
"Legal Entity" shall mean the union of the acting entity and all
|
17 |
-
other entities that control, are controlled by, or are under common
|
18 |
-
control with that entity. For the purposes of this definition,
|
19 |
-
"control" means (i) the power, direct or indirect, to cause the
|
20 |
-
direction or management of such entity, whether by contract or
|
21 |
-
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
22 |
-
outstanding shares, or (iii) beneficial ownership of such entity.
|
23 |
-
|
24 |
-
"You" (or "Your") shall mean an individual or Legal Entity
|
25 |
-
exercising permissions granted by this License.
|
26 |
-
|
27 |
-
"Source" form shall mean the preferred form for making modifications,
|
28 |
-
including but not limited to software source code, documentation
|
29 |
-
source, and configuration files.
|
30 |
-
|
31 |
-
"Object" form shall mean any form resulting from mechanical
|
32 |
-
transformation or translation of a Source form, including but
|
33 |
-
not limited to compiled object code, generated documentation,
|
34 |
-
and conversions to other media types.
|
35 |
-
|
36 |
-
"Work" shall mean the work of authorship, whether in Source or
|
37 |
-
Object form, made available under the License, as indicated by a
|
38 |
-
copyright notice that is included in or attached to the work
|
39 |
-
(an example is provided in the Appendix below).
|
40 |
-
|
41 |
-
"Derivative Works" shall mean any work, whether in Source or Object
|
42 |
-
form, that is based on (or derived from) the Work and for which the
|
43 |
-
editorial revisions, annotations, elaborations, or other modifications
|
44 |
-
represent, as a whole, an original work of authorship. For the purposes
|
45 |
-
of this License, Derivative Works shall not include works that remain
|
46 |
-
separable from, or merely link (or bind by name) to the interfaces of,
|
47 |
-
the Work and Derivative Works thereof.
|
48 |
-
|
49 |
-
"Contribution" shall mean any work of authorship, including
|
50 |
-
the original version of the Work and any modifications or additions
|
51 |
-
to that Work or Derivative Works thereof, that is intentionally
|
52 |
-
submitted to Licensor for inclusion in the Work by the copyright owner
|
53 |
-
or by an individual or Legal Entity authorized to submit on behalf of
|
54 |
-
the copyright owner. For the purposes of this definition, "submitted"
|
55 |
-
means any form of electronic, verbal, or written communication sent
|
56 |
-
to the Licensor or its representatives, including but not limited to
|
57 |
-
communication on electronic mailing lists, source code control systems,
|
58 |
-
and issue tracking systems that are managed by, or on behalf of, the
|
59 |
-
Licensor for the purpose of discussing and improving the Work, but
|
60 |
-
excluding communication that is conspicuously marked or otherwise
|
61 |
-
designated in writing by the copyright owner as "Not a Contribution."
|
62 |
-
|
63 |
-
"Contributor" shall mean Licensor and any individual or Legal Entity
|
64 |
-
on behalf of whom a Contribution has been received by Licensor and
|
65 |
-
subsequently incorporated within the Work.
|
66 |
-
|
67 |
-
2. Grant of Copyright License. Subject to the terms and conditions of
|
68 |
-
this License, each Contributor hereby grants to You a perpetual,
|
69 |
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
70 |
-
copyright license to reproduce, prepare Derivative Works of,
|
71 |
-
publicly display, publicly perform, sublicense, and distribute the
|
72 |
-
Work and such Derivative Works in Source or Object form.
|
73 |
-
|
74 |
-
3. Grant of Patent License. Subject to the terms and conditions of
|
75 |
-
this License, each Contributor hereby grants to You a perpetual,
|
76 |
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
77 |
-
(except as stated in this section) patent license to make, have made,
|
78 |
-
use, offer to sell, sell, import, and otherwise transfer the Work,
|
79 |
-
where such license applies only to those patent claims licensable
|
80 |
-
by such Contributor that are necessarily infringed by their
|
81 |
-
Contribution(s) alone or by combination of their Contribution(s)
|
82 |
-
with the Work to which such Contribution(s) was submitted. If You
|
83 |
-
institute patent litigation against any entity (including a
|
84 |
-
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
85 |
-
or a Contribution incorporated within the Work constitutes direct
|
86 |
-
or contributory patent infringement, then any patent licenses
|
87 |
-
granted to You under this License for that Work shall terminate
|
88 |
-
as of the date such litigation is filed.
|
89 |
-
|
90 |
-
4. Redistribution. You may reproduce and distribute copies of the
|
91 |
-
Work or Derivative Works thereof in any medium, with or without
|
92 |
-
modifications, and in Source or Object form, provided that You
|
93 |
-
meet the following conditions:
|
94 |
-
|
95 |
-
(a) You must give any other recipients of the Work or
|
96 |
-
Derivative Works a copy of this License; and
|
97 |
-
|
98 |
-
(b) You must cause any modified files to carry prominent notices
|
99 |
-
stating that You changed the files; and
|
100 |
-
|
101 |
-
(c) You must retain, in the Source form of any Derivative Works
|
102 |
-
that You distribute, all copyright, patent, trademark, and
|
103 |
-
attribution notices from the Source form of the Work,
|
104 |
-
excluding those notices that do not pertain to any part of
|
105 |
-
the Derivative Works; and
|
106 |
-
|
107 |
-
(d) If the Work includes a "NOTICE" text file as part of its
|
108 |
-
distribution, then any Derivative Works that You distribute must
|
109 |
-
include a readable copy of the attribution notices contained
|
110 |
-
within such NOTICE file, excluding those notices that do not
|
111 |
-
pertain to any part of the Derivative Works, in at least one
|
112 |
-
of the following places: within a NOTICE text file distributed
|
113 |
-
as part of the Derivative Works; within the Source form or
|
114 |
-
documentation, if provided along with the Derivative Works; or,
|
115 |
-
within a display generated by the Derivative Works, if and
|
116 |
-
wherever such third-party notices normally appear. The contents
|
117 |
-
of the NOTICE file are for informational purposes only and
|
118 |
-
do not modify the License. You may add Your own attribution
|
119 |
-
notices within Derivative Works that You distribute, alongside
|
120 |
-
or as an addendum to the NOTICE text from the Work, provided
|
121 |
-
that such additional attribution notices cannot be construed
|
122 |
-
as modifying the License.
|
123 |
-
|
124 |
-
You may add Your own copyright statement to Your modifications and
|
125 |
-
may provide additional or different license terms and conditions
|
126 |
-
for use, reproduction, or distribution of Your modifications, or
|
127 |
-
for any such Derivative Works as a whole, provided Your use,
|
128 |
-
reproduction, and distribution of the Work otherwise complies with
|
129 |
-
the conditions stated in this License.
|
130 |
-
|
131 |
-
5. Submission of Contributions. Unless You explicitly state otherwise,
|
132 |
-
any Contribution intentionally submitted for inclusion in the Work
|
133 |
-
by You to the Licensor shall be under the terms and conditions of
|
134 |
-
this License, without any additional terms or conditions.
|
135 |
-
Notwithstanding the above, nothing herein shall supersede or modify
|
136 |
-
the terms of any separate license agreement you may have executed
|
137 |
-
with Licensor regarding such Contributions.
|
138 |
-
|
139 |
-
6. Trademarks. This License does not grant permission to use the trade
|
140 |
-
names, trademarks, service marks, or product names of the Licensor,
|
141 |
-
except as required for reasonable and customary use in describing the
|
142 |
-
origin of the Work and reproducing the content of the NOTICE file.
|
143 |
-
|
144 |
-
7. Disclaimer of Warranty. Unless required by applicable law or
|
145 |
-
agreed to in writing, Licensor provides the Work (and each
|
146 |
-
Contributor provides its Contributions) on an "AS IS" BASIS,
|
147 |
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
148 |
-
implied, including, without limitation, any warranties or conditions
|
149 |
-
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
150 |
-
PARTICULAR PURPOSE. You are solely responsible for determining the
|
151 |
-
appropriateness of using or redistributing the Work and assume any
|
152 |
-
risks associated with Your exercise of permissions under this License.
|
153 |
-
|
154 |
-
8. Limitation of Liability. In no event and under no legal theory,
|
155 |
-
whether in tort (including negligence), contract, or otherwise,
|
156 |
-
unless required by applicable law (such as deliberate and grossly
|
157 |
-
negligent acts) or agreed to in writing, shall any Contributor be
|
158 |
-
liable to You for damages, including any direct, indirect, special,
|
159 |
-
incidental, or consequential damages of any character arising as a
|
160 |
-
result of this License or out of the use or inability to use the
|
161 |
-
Work (including but not limited to damages for loss of goodwill,
|
162 |
-
work stoppage, computer failure or malfunction, or any and all
|
163 |
-
other commercial damages or losses), even if such Contributor
|
164 |
-
has been advised of the possibility of such damages.
|
165 |
-
|
166 |
-
9. Accepting Warranty or Additional Liability. While redistributing
|
167 |
-
the Work or Derivative Works thereof, You may choose to offer,
|
168 |
-
and charge a fee for, acceptance of support, warranty, indemnity,
|
169 |
-
or other liability obligations and/or rights consistent with this
|
170 |
-
License. However, in accepting such obligations, You may act only
|
171 |
-
on Your own behalf and on Your sole responsibility, not on behalf
|
172 |
-
of any other Contributor, and only if You agree to indemnify,
|
173 |
-
defend, and hold each Contributor harmless for any liability
|
174 |
-
incurred by, or claims asserted against, such Contributor by reason
|
175 |
-
of your accepting any such warranty or additional liability.
|
176 |
-
|
177 |
-
END OF TERMS AND CONDITIONS
|
178 |
-
|
179 |
-
APPENDIX: How to apply the Apache License to your work.
|
180 |
-
|
181 |
-
To apply the Apache License to your work, attach the following
|
182 |
-
boilerplate notice, with the fields enclosed by brackets "[]"
|
183 |
-
replaced with your own identifying information. (Don't include
|
184 |
-
the brackets!) The text should be enclosed in the appropriate
|
185 |
-
comment syntax for the file format. We also recommend that a
|
186 |
-
file or class name and description of purpose be included on the
|
187 |
-
same "printed page" as the copyright notice for easier
|
188 |
-
identification within third-party archives.
|
189 |
-
|
190 |
-
Copyright [yyyy] [name of copyright owner]
|
191 |
-
|
192 |
-
Licensed under the Apache License, Version 2.0 (the "License");
|
193 |
-
you may not use this file except in compliance with the License.
|
194 |
-
You may obtain a copy of the License at
|
195 |
-
|
196 |
-
http://www.apache.org/licenses/LICENSE-2.0
|
197 |
-
|
198 |
-
Unless required by applicable law or agreed to in writing, software
|
199 |
-
distributed under the License is distributed on an "AS IS" BASIS,
|
200 |
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
201 |
-
See the License for the specific language governing permissions and
|
202 |
-
limitations under the License.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tmhOAuth/README.md
DELETED
@@ -1,211 +0,0 @@
|
|
1 |
-
# tmhOAuth
|
2 |
-
|
3 |
-
An OAuth 1.0A library written in PHP by @themattharris, specifically for use
|
4 |
-
with the Twitter API.
|
5 |
-
|
6 |
-
**Disclaimer**: This project is a work in progress. Please use the issue tracker
|
7 |
-
to report any enhancements or issues you encounter.
|
8 |
-
|
9 |
-
## Goals
|
10 |
-
|
11 |
-
- Support OAuth 1.0A
|
12 |
-
- Use Authorisation headers instead of query string or POST parameters
|
13 |
-
- Allow uploading of images
|
14 |
-
- Provide enough information to assist with debugging
|
15 |
-
|
16 |
-
## Dependencies
|
17 |
-
|
18 |
-
The library has been tested with PHP 5.3+ and relies on CURL and hash_hmac. The
|
19 |
-
vast majority of hosting providers include these libraries and run with PHP 5.1+.
|
20 |
-
|
21 |
-
The code makes use of hash_hmac, which was introduced in PHP 5.1.2. If your version
|
22 |
-
of PHP is lower than this you should ask your hosting provider for an update.
|
23 |
-
|
24 |
-
## A note about security and SSL
|
25 |
-
|
26 |
-
Version 0.60 hardened the security of the library and defaulted `curl_ssl_verifypeer` to `true`.
|
27 |
-
As some hosting providers do not provide the most current certificate root file
|
28 |
-
it is now included in this repository. If the version is out of date OR you prefer
|
29 |
-
to download the certificate roots yourself, you can get them
|
30 |
-
from: http://curl.haxx.se/ca/cacert.pem
|
31 |
-
|
32 |
-
Before upgrading the version of tmhOAuth that you use, be sure to verify the SSL
|
33 |
-
handling works on your server by running the `examples/verify_ssl.php` script.
|
34 |
-
|
35 |
-
## Usage
|
36 |
-
|
37 |
-
This will be built out later but for the moment review the examples repository
|
38 |
-
<https://github.com/themattharris/tmhOAuth-examples> for ways the library can be
|
39 |
-
used. Each example contains instructions on how to use it.
|
40 |
-
|
41 |
-
## Notes for users of previous versions
|
42 |
-
|
43 |
-
If you previously used version 0.4 be aware the utility functions
|
44 |
-
have now been broken into their own file. Before you use version 0.5+ in your app
|
45 |
-
test locally to ensure your code doesn't need tmhUtilities included.
|
46 |
-
|
47 |
-
If you used custom HTTP request headers when they were defined as `'key: value'` strings
|
48 |
-
you should now define them as `'key' => 'value'` pairs.
|
49 |
-
|
50 |
-
Versions prior to 0.7.3 collapsed headers with the same value into one
|
51 |
-
$tmhOAuth->response['headers'] key. Since 0.7.3 headers with the same key will use an array
|
52 |
-
to store their values.
|
53 |
-
|
54 |
-
## Change History
|
55 |
-
### 0.7.5 - 20 Februrary 2013
|
56 |
-
- tidying up of composer.json. (Issue #112) Props: ceeram
|
57 |
-
|
58 |
-
### 0.7.4 - 19 Februrary 2013
|
59 |
-
- corrections to composer.json to support packagists requirements. (Issue #110)
|
60 |
-
|
61 |
-
### 0.7.3 - 18 Februrary 2013
|
62 |
-
- add support for making requests with the host header being different to the request host.
|
63 |
-
- ensure headers with the same key do not overwrite each other in $tmhOAuth->response['headers'].
|
64 |
-
- removed examples submodule in favor of examples including tmhOAuth, rather than tmhOAuth including examples
|
65 |
-
- made it so that if param values are sent to $tmhOAuth->request as an array (key -> array()) then $tmhOAuth->prepare_params will now implode them using ','
|
66 |
-
- fixed composer. (Issue #99). Props: rasa
|
67 |
-
- fixed PHPDoc. (Issue #47). Props: trante
|
68 |
-
- instead of void, $tmhOAuth->curlit now returns 0 if 'prevent_request' is set
|
69 |
-
|
70 |
-
### 0.7.2 - 01 November 2012
|
71 |
-
- use DIRECTORY_SEPARATOR for multi-environment support. (Issue #80) Props: whallz
|
72 |
-
- tidied up the curlHeader function to use explode instead of substr and store the keys in the format they are returned from the API
|
73 |
-
- removed content-length hack as it isn't needed if CURLOPT_POSTFIELDS is initialized on all POSTs
|
74 |
-
- removed the expects header hack as Twitter no longer requires it to be there
|
75 |
-
- introduce composer.json. (Issues #39, #77, #85) Props: akandels, conradkleinespel, dguyon, kud, philsturgeon, willdurand
|
76 |
-
- added support for specifying custom headers when using $tmhOAuth->request. (Issue #98)
|
77 |
-
|
78 |
-
### 0.7.1 - 27 October 2012
|
79 |
-
- set content-length to 0 explictly to avoid a bug between libcurl and Twitter. (Issue #94)
|
80 |
-
- allow initialization without a configuration array (default config to array())
|
81 |
-
- prevent ->url allowing double slashes in paths
|
82 |
-
|
83 |
-
### 0.7.0 - 04 September 2012
|
84 |
-
- changed version numbers to x.y.z format
|
85 |
-
- stronger method scoping (public and private)
|
86 |
-
- Typo fix in depenencies. (Issue #42) Props: tantek
|
87 |
-
- Only lowercase the host and scheme, and not path, in prepare_url. (Issue #56) Props: uzyn
|
88 |
-
- Fixed a number of PHP warnings by changing some tmhUtilty methods to static. (Issue #52) Props: DrayChou
|
89 |
-
- Raw headers and response body are now available as `$tmhOAuth->response['raw']`
|
90 |
-
- Moved the examples to their own repository <https://github.com/themattharris/tmhOAuth-examples>
|
91 |
-
- Removed the `noexamples` branch as master does not contain examples anymore
|
92 |
-
- Introduced `$tmhOAuth->config['timezone']` and set `date_default_timezone_set`. (Issue #70) Props: iamctodd
|
93 |
-
|
94 |
-
### 0.621 - 12 March 2012
|
95 |
-
- Ensure `$_SERVER['HTTPS']` isset before checking it's value. Props: kud
|
96 |
-
|
97 |
-
### 0.62 - 01 March 2012
|
98 |
-
- Fix array merging bug. Props: julien-c
|
99 |
-
- use is_callable instead of function_exists: Props: samwierema
|
100 |
-
- Allow options to be specified for the entify function. Props: davidcroda
|
101 |
-
- protocol was not inferred correctly for https when ['HTTPS'] == 'on'. Props: ospector
|
102 |
-
- Switched to https for twitter.com display URLs
|
103 |
-
- Improved the search results example
|
104 |
-
|
105 |
-
### 0.61 - 16 January 2012
|
106 |
-
- Removed trailing ?> from tmhOAuth.php and tmhUtilities.php to meet the Zend Framework's coding practices. Props: reedy
|
107 |
-
- Fixed bug where CURLOPT_SSL_VERIFYHOST was defaulted to true when it should have been defaulted to 2. Props: kevinsmcarthur
|
108 |
-
|
109 |
-
### 0.60 - 29 December 2011
|
110 |
-
- Changed any use of implode to the preferred format of implode($glue, $pieces). Props: reedy
|
111 |
-
- Moved oauth_verifier to the authorization header as shown in example of RFC 5849. Props: spacenick
|
112 |
-
- added curl error and error number values to the $tmhOAuth->response object
|
113 |
-
- added an example script for testing the SSL connection to twitter.com with the new SSL configuration of tmhOAuth
|
114 |
-
- added a function to generate the useragent depending on whether SSL is on or not
|
115 |
-
- defaulted CURLOPT_SSL_VERIFYPEER to true
|
116 |
-
- added CURLOPT_SSL_VERIFYHOST and defaulted it to true
|
117 |
-
- added the most current cacert.pem file from http://curl.haxx.se/ca/cacert.pem and configured curl to use it
|
118 |
-
|
119 |
-
### 0.58 - 29 December 2011
|
120 |
-
- Rearranged some configuration variables around to make commenting easier
|
121 |
-
- Standarised on lowercase booleans
|
122 |
-
|
123 |
-
### 0.57 - 11 December 2011
|
124 |
-
- Fixed prevent_request so OAuth Echo requests work again.
|
125 |
-
- Added a TwitPic OAuth Echo example
|
126 |
-
|
127 |
-
### 0.56 - 29 September 2011
|
128 |
-
- Fixed version reference in the UserAgent
|
129 |
-
- Updated tmhUtilities::entify with support for media
|
130 |
-
- Updated tmhUtilities::entify with support for multibyte characters. Props: andersonshatch
|
131 |
-
|
132 |
-
### 0.55 - 29 September 2011
|
133 |
-
- Added support for content encoding. Defaults to whatever localhost supports. Props: yusuke
|
134 |
-
|
135 |
-
### 0.54 - 29 September 2011
|
136 |
-
- User-Agent is now configurable and includes the current version number of the script
|
137 |
-
- Updated the Streaming examples to use SSL
|
138 |
-
|
139 |
-
### 0.53 - 15 July 2011
|
140 |
-
- Fixed issue where headers were being duplicated if the library was called more than once.
|
141 |
-
- Updated examples to fit the new location of access tokens and secrets on dev.twitter.com
|
142 |
-
- Added Photo Tweet example
|
143 |
-
|
144 |
-
### 0.52 - 06 July 2011
|
145 |
-
- Fixed issue where the preference for include_time in create_nonce was being ignored
|
146 |
-
|
147 |
-
### 0.51 - 06 July 2011
|
148 |
-
- Use isset instead of suppress errors. Props: funkatron
|
149 |
-
- Added example of using the Search API
|
150 |
-
- Added example of using friends/ids and users/lookup to get details of a users friends
|
151 |
-
- Added example of the authorize OAuth webflow
|
152 |
-
|
153 |
-
### 0.5 - 29 March 2011
|
154 |
-
- Moved utility functions out of the main class and into the tmhUtilities class.
|
155 |
-
- Added the ability to send OAuth parameters as part of the querystring or POST body.
|
156 |
-
- Section 3.4.1.2 says the url must be lowercase so prepare URL now does this.
|
157 |
-
- Added a convenience method for accessing the safe_encode/decode transforms.
|
158 |
-
- Updated the examples to use the new utilities library.
|
159 |
-
- Added examples for sitestreams and userstreams.
|
160 |
-
- Added a more advanced streaming API example.
|
161 |
-
|
162 |
-
### 0.4 - 03 March 2011
|
163 |
-
- Fixed handling of parameters when using DELETE. Thanks to yusuke for reporting
|
164 |
-
- Fixed php_self to handle port numbers other than 80/443. Props: yusuke
|
165 |
-
- Updated function pr to use pre only when not running in CLI mode
|
166 |
-
- Add support for proxy servers. Props juanchorossi
|
167 |
-
- Function request now returns the HTTP status code. Props: kronenthaler
|
168 |
-
- Documentation fixes for xAuth. Props: 140dev
|
169 |
-
- Some minor code formatting changes
|
170 |
-
|
171 |
-
### 0.3 - 28 September 2010
|
172 |
-
- Moved entities rendering into the library
|
173 |
-
|
174 |
-
### 0.2 - 17 September 2010
|
175 |
-
- Added support for the Streaming API
|
176 |
-
|
177 |
-
### 0.14 - 17 September 2010
|
178 |
-
- Fixed authorisation header for use with OAuth Echo
|
179 |
-
|
180 |
-
### 0.13 - 17 September 2010
|
181 |
-
- Added use_ssl configuration parameter
|
182 |
-
- Fixed config array typo
|
183 |
-
- Removed v from the config
|
184 |
-
- Remove protocol from the host (configured by use_ssl)
|
185 |
-
- Added include for easier debugging
|
186 |
-
|
187 |
-
### 0.12 - 17 September 2010
|
188 |
-
|
189 |
-
- Moved curl options to config
|
190 |
-
- Added the ability for curl to follow redirects, default false
|
191 |
-
|
192 |
-
### 0.11 - 17 September 2010
|
193 |
-
|
194 |
-
- Fixed a bug in the GET requests
|
195 |
-
|
196 |
-
### 0.1 - 26 August 2010
|
197 |
-
|
198 |
-
- Initial beta version
|
199 |
-
|
200 |
-
## Community
|
201 |
-
|
202 |
-
License: Apache 2 (see [included LICENSE file](https://github.com/themattharris/tmhOAuth/blob/master/LICENSE))
|
203 |
-
|
204 |
-
Follow [@tmhOAuth](https://twitter.com/intent/follow?screen_name=tmhOAuth) to receive updates on releases, or ask for support
|
205 |
-
Follow me on Twitter: [@themattharris](https://twitter.com/intent/follow?screen_name=themattharris)
|
206 |
-
Check out the Twitter Developer Resources: <https://dev.twitter.com>
|
207 |
-
|
208 |
-
## To Do
|
209 |
-
|
210 |
-
- Add good behavior logic to the Streaming API handler - i.e. on disconnect back off
|
211 |
-
- Async Curl support
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tmhOAuth/composer.json
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"name": "themattharris/tmhoauth",
|
3 |
-
"description": "An OAuth 1.0A library written in PHP by @themattharris, specifically for use with the Twitter API",
|
4 |
-
"license": "Apache-2.0",
|
5 |
-
"authors": [
|
6 |
-
{
|
7 |
-
"name": "themattharris",
|
8 |
-
"email": "matt@themattharris.com",
|
9 |
-
"role": "Developer"
|
10 |
-
}
|
11 |
-
],
|
12 |
-
"keywords": [
|
13 |
-
"twitter",
|
14 |
-
"oauth"
|
15 |
-
],
|
16 |
-
"support": {
|
17 |
-
"issues": "https://github.com/themattharris/tmhOAuth/issues"
|
18 |
-
},
|
19 |
-
"require": {
|
20 |
-
"php": ">=5.3.0",
|
21 |
-
"ext-curl": "*"
|
22 |
-
},
|
23 |
-
"autoload": {
|
24 |
-
"psr-0": {"tmhOAuth": ""}
|
25 |
-
}
|
26 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tmhOAuth/tmhUtilities.php
DELETED
@@ -1,301 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* tmhUtilities
|
5 |
-
*
|
6 |
-
* Helpful utility and Twitter formatting functions
|
7 |
-
*
|
8 |
-
* @author themattharris
|
9 |
-
* @version 0.5.0
|
10 |
-
*
|
11 |
-
* 04 September 2012
|
12 |
-
*/
|
13 |
-
class tmhUtilities {
|
14 |
-
const VERSION = '0.5.0';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Entifies the tweet using the given entities element.
|
18 |
-
* Deprecated.
|
19 |
-
* You should instead use entify_with_options.
|
20 |
-
*
|
21 |
-
* @param array $tweet the json converted to normalised array
|
22 |
-
* @param array $replacements if specified, the entities and their replacements will be stored to this variable
|
23 |
-
*
|
24 |
-
* @return the tweet text with entities replaced with hyperlinks
|
25 |
-
*/
|
26 |
-
public static function entify( $tweet, &$replacements = array() ) {
|
27 |
-
return tmhUtilities::entify_with_options( $tweet, array(), $replacements );
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Entifies the tweet using the given entities element, using the provided
|
32 |
-
* options.
|
33 |
-
*
|
34 |
-
* @param array $tweet the json converted to normalised array
|
35 |
-
* @param array $options settings to be used when rendering the entities
|
36 |
-
* @param array $replacements if specified, the entities and their replacements will be stored to this variable
|
37 |
-
*
|
38 |
-
* @return the tweet text with entities replaced with hyperlinks
|
39 |
-
*/
|
40 |
-
public static function entify_with_options( $tweet, $options = array(), &$replacements = array() ) {
|
41 |
-
$default_opts = array(
|
42 |
-
'encoding' => 'UTF-8',
|
43 |
-
'target' => '',
|
44 |
-
);
|
45 |
-
|
46 |
-
$opts = array_merge( $default_opts, $options );
|
47 |
-
|
48 |
-
$encoding = mb_internal_encoding();
|
49 |
-
mb_internal_encoding( $opts['encoding'] );
|
50 |
-
|
51 |
-
$keys = array();
|
52 |
-
$is_retweet = false;
|
53 |
-
|
54 |
-
if ( isset( $tweet['retweeted_status'] ) ) {
|
55 |
-
$tweet = $tweet['retweeted_status'];
|
56 |
-
$is_retweet = true;
|
57 |
-
}
|
58 |
-
|
59 |
-
if ( ! isset( $tweet['entities'] ) ) {
|
60 |
-
return $tweet['text'];
|
61 |
-
}
|
62 |
-
|
63 |
-
$target = ( ! empty( $opts['target'] ) ) ? ' target="' . $opts['target'] . '"' : '';
|
64 |
-
|
65 |
-
// prepare the entities
|
66 |
-
foreach ( $tweet['entities'] as $type => $things ) {
|
67 |
-
foreach ( $things as $entity => $value ) {
|
68 |
-
$tweet_link = "<a href=\"https://twitter.com/{$tweet['user']['screen_name']}/statuses/{$tweet['id']}\"{$target}>{$tweet['created_at']}</a>";
|
69 |
-
|
70 |
-
switch ( $type ) {
|
71 |
-
case 'hashtags':
|
72 |
-
$href = "<a href=\"https://twitter.com/search?q=%23{$value['text']}\"{$target}>#{$value['text']}</a>";
|
73 |
-
break;
|
74 |
-
case 'user_mentions':
|
75 |
-
$href = "@<a href=\"https://twitter.com/{$value['screen_name']}\" title=\"{$value['name']}\"{$target}>{$value['screen_name']}</a>";
|
76 |
-
break;
|
77 |
-
case 'urls':
|
78 |
-
case 'media':
|
79 |
-
$url = empty( $value['expanded_url'] ) ? $value['url'] : $value['expanded_url'];
|
80 |
-
$display = isset( $value['display_url'] ) ? $value['display_url'] : str_replace( 'http://', '', $url );
|
81 |
-
// Not all pages are served in UTF-8 so you may need to do this ...
|
82 |
-
$display = urldecode( str_replace( '%E2%80%A6', '…', urlencode( $display ) ) );
|
83 |
-
$href = "<a href=\"{$value['url']}\"{$target}>{$display}</a>";
|
84 |
-
break;
|
85 |
-
}
|
86 |
-
$keys[ $value['indices']['0'] ] = mb_substr(
|
87 |
-
$tweet['text'],
|
88 |
-
$value['indices']['0'],
|
89 |
-
$value['indices']['1'] - $value['indices']['0']
|
90 |
-
);
|
91 |
-
$replacements[ $value['indices']['0'] ] = $href;
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
ksort( $replacements );
|
96 |
-
$replacements = array_reverse( $replacements, true );
|
97 |
-
$entified_tweet = $tweet['text'];
|
98 |
-
foreach ( $replacements as $k => $v ) {
|
99 |
-
$entified_tweet = mb_substr( $entified_tweet, 0, $k ) . $v . mb_substr( $entified_tweet, $k + strlen( $keys[ $k ] ) );
|
100 |
-
}
|
101 |
-
$replacements = array(
|
102 |
-
'replacements' => $replacements,
|
103 |
-
'keys' => $keys
|
104 |
-
);
|
105 |
-
|
106 |
-
mb_internal_encoding( $encoding );
|
107 |
-
|
108 |
-
return $entified_tweet;
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Returns the current URL. This is instead of PHP_SELF which is unsafe
|
113 |
-
*
|
114 |
-
* @param bool $dropqs whether to drop the querystring or not. Default true
|
115 |
-
*
|
116 |
-
* @return string the current URL
|
117 |
-
*/
|
118 |
-
public static function php_self( $dropqs = true ) {
|
119 |
-
$protocol = 'http';
|
120 |
-
if ( isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) == 'on' ) {
|
121 |
-
$protocol = 'https';
|
122 |
-
} elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( $_SERVER['SERVER_PORT'] == '443' ) ) {
|
123 |
-
$protocol = 'https';
|
124 |
-
}
|
125 |
-
|
126 |
-
$url = sprintf( '%s://%s%s',
|
127 |
-
$protocol,
|
128 |
-
$_SERVER['SERVER_NAME'],
|
129 |
-
$_SERVER['REQUEST_URI']
|
130 |
-
);
|
131 |
-
|
132 |
-
$parts = parse_url( $url );
|
133 |
-
|
134 |
-
$port = $_SERVER['SERVER_PORT'];
|
135 |
-
$scheme = $parts['scheme'];
|
136 |
-
$host = $parts['host'];
|
137 |
-
$path = @$parts['path'];
|
138 |
-
$qs = @$parts['query'];
|
139 |
-
|
140 |
-
$port or $port = ( $scheme == 'https' ) ? '443' : '80';
|
141 |
-
|
142 |
-
if ( ( $scheme == 'https' && $port != '443' )
|
143 |
-
|| ( $scheme == 'http' && $port != '80' )
|
144 |
-
) {
|
145 |
-
$host = "$host:$port";
|
146 |
-
}
|
147 |
-
$url = "$scheme://$host$path";
|
148 |
-
if ( ! $dropqs ) {
|
149 |
-
return "{$url}?{$qs}";
|
150 |
-
} else {
|
151 |
-
return $url;
|
152 |
-
}
|
153 |
-
}
|
154 |
-
|
155 |
-
public static function is_cli() {
|
156 |
-
return ( PHP_SAPI == 'cli' && empty( $_SERVER['REMOTE_ADDR'] ) );
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* Debug function for printing the content of an object
|
161 |
-
*
|
162 |
-
* @param mixes $obj
|
163 |
-
*/
|
164 |
-
public static function pr( $obj ) {
|
165 |
-
|
166 |
-
if ( ! self::is_cli() ) {
|
167 |
-
echo '<pre style="word-wrap: break-word">';
|
168 |
-
}
|
169 |
-
if ( is_object( $obj ) ) {
|
170 |
-
print_r( $obj );
|
171 |
-
} elseif ( is_array( $obj ) ) {
|
172 |
-
print_r( $obj );
|
173 |
-
} else {
|
174 |
-
echo $obj;
|
175 |
-
}
|
176 |
-
if ( ! self::is_cli() ) {
|
177 |
-
echo '</pre>';
|
178 |
-
}
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Make an HTTP request using this library. This method is different to 'request'
|
183 |
-
* because on a 401 error it will retry the request.
|
184 |
-
*
|
185 |
-
* When a 401 error is returned it is possible the timestamp of the client is
|
186 |
-
* too different to that of the API server. In this situation it is recommended
|
187 |
-
* the request is retried with the OAuth timestamp set to the same as the API
|
188 |
-
* server. This method will automatically try that technique.
|
189 |
-
*
|
190 |
-
* This method doesn't return anything. Instead the response should be
|
191 |
-
* inspected directly.
|
192 |
-
*
|
193 |
-
* @param string $method the HTTP method being used. e.g. POST, GET, HEAD etc
|
194 |
-
* @param string $url the request URL without query string parameters
|
195 |
-
* @param array $params the request parameters as an array of key=value pairs
|
196 |
-
* @param string $useauth whether to use authentication when making the request. Default true.
|
197 |
-
* @param string $multipart whether this request contains multipart data. Default false
|
198 |
-
*/
|
199 |
-
public static function auto_fix_time_request( $tmhOAuth, $method, $url, $params = array(), $useauth = true, $multipart = false ) {
|
200 |
-
$tmhOAuth->request( $method, $url, $params, $useauth, $multipart );
|
201 |
-
|
202 |
-
// if we're not doing auth the timestamp isn't important
|
203 |
-
if ( ! $useauth ) {
|
204 |
-
return;
|
205 |
-
}
|
206 |
-
|
207 |
-
// some error that isn't a 401
|
208 |
-
if ( $tmhOAuth->response['code'] != 401 ) {
|
209 |
-
return;
|
210 |
-
}
|
211 |
-
|
212 |
-
// some error that is a 401 but isn't because the OAuth token and signature are incorrect
|
213 |
-
// TODO: this check is horrid but helps avoid requesting twice when the username and password are wrong
|
214 |
-
if ( stripos( $tmhOAuth->response['response'], 'password' ) !== false ) {
|
215 |
-
return;
|
216 |
-
}
|
217 |
-
|
218 |
-
// force the timestamp to be the same as the Twitter servers, and re-request
|
219 |
-
$tmhOAuth->auto_fixed_time = true;
|
220 |
-
$tmhOAuth->config['force_timestamp'] = true;
|
221 |
-
$tmhOAuth->config['timestamp'] = strtotime( $tmhOAuth->response['headers']['date'] );
|
222 |
-
|
223 |
-
return $tmhOAuth->request( $method, $url, $params, $useauth, $multipart );
|
224 |
-
}
|
225 |
-
|
226 |
-
/**
|
227 |
-
* Asks the user for input and returns the line they enter
|
228 |
-
*
|
229 |
-
* @param string $prompt the text to display to the user
|
230 |
-
*
|
231 |
-
* @return the text entered by the user
|
232 |
-
*/
|
233 |
-
public static function read_input( $prompt ) {
|
234 |
-
echo $prompt;
|
235 |
-
$handle = fopen( "php://stdin", "r" );
|
236 |
-
$data = fgets( $handle );
|
237 |
-
|
238 |
-
return trim( $data );
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* Get a password from the shell.
|
243 |
-
*
|
244 |
-
* This function works on *nix systems only and requires shell_exec and stty.
|
245 |
-
*
|
246 |
-
* @param boolean $stars Wether or not to output stars for given characters
|
247 |
-
*
|
248 |
-
* @return string
|
249 |
-
* @url http://www.dasprids.de/blog/2008/08/22/getting-a-password-hidden-from-stdin-with-php-cli
|
250 |
-
*/
|
251 |
-
public static function read_password( $prompt, $stars = false ) {
|
252 |
-
echo $prompt;
|
253 |
-
$style = shell_exec( 'stty -g' );
|
254 |
-
|
255 |
-
if ( $stars === false ) {
|
256 |
-
shell_exec( 'stty -echo' );
|
257 |
-
$password = rtrim( fgets( STDIN ), "\n" );
|
258 |
-
} else {
|
259 |
-
shell_exec( 'stty -icanon -echo min 1 time 0' );
|
260 |
-
$password = '';
|
261 |
-
while ( true ) :
|
262 |
-
$char = fgetc( STDIN );
|
263 |
-
if ( $char === "\n" ) :
|
264 |
-
break;
|
265 |
-
elseif ( ord( $char ) === 127 ) :
|
266 |
-
if ( strlen( $password ) > 0 ) {
|
267 |
-
fwrite( STDOUT, "\x08 \x08" );
|
268 |
-
$password = substr( $password, 0, - 1 );
|
269 |
-
} else {
|
270 |
-
fwrite( STDOUT, "*" );
|
271 |
-
}
|
272 |
-
$password .= $char;
|
273 |
-
endif;
|
274 |
-
endwhile;
|
275 |
-
}
|
276 |
-
|
277 |
-
// Reset
|
278 |
-
shell_exec( 'stty ' . $style );
|
279 |
-
echo PHP_EOL;
|
280 |
-
|
281 |
-
return $password;
|
282 |
-
}
|
283 |
-
|
284 |
-
/**
|
285 |
-
* Check if one string ends with another
|
286 |
-
*
|
287 |
-
* @param string $haystack the string to check inside of
|
288 |
-
* @param string $needle the string to check $haystack ends with
|
289 |
-
*
|
290 |
-
* @return true if $haystack ends with $needle, false otherwise
|
291 |
-
*/
|
292 |
-
public static function endswith( $haystack, $needle ) {
|
293 |
-
$haylen = strlen( $haystack );
|
294 |
-
$needlelen = strlen( $needle );
|
295 |
-
if ( $needlelen > $haylen ) {
|
296 |
-
return false;
|
297 |
-
}
|
298 |
-
|
299 |
-
return substr_compare( $haystack, $needle, - $needlelen ) === 0;
|
300 |
-
}
|
301 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uninstall.php
CHANGED
@@ -1,5 +1,15 @@
|
|
1 |
<?php
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
exit();
|
4 |
} else {
|
5 |
delete_option( 'wpt_post_types' );
|
@@ -10,10 +20,10 @@ if ( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
10 |
delete_option( 'comment-published-text' );
|
11 |
delete_option( 'wpt_status_message_last' );
|
12 |
delete_option( 'wtt_twitter_username' );
|
13 |
-
// Su.pr API
|
14 |
delete_option( 'suprapi' );
|
15 |
|
16 |
-
// Error checking
|
17 |
delete_option( 'jd-functions-checked' );
|
18 |
delete_option( 'wp_twitter_failure' );
|
19 |
delete_option( 'wp_supr_failure' );
|
@@ -21,24 +31,24 @@ if ( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
21 |
delete_option( 'wp_bitly_failure' );
|
22 |
delete_option( 'wpt_curl_error' );
|
23 |
|
24 |
-
// Rate Limiting
|
25 |
delete_option( 'wpt_rate_limits' );
|
26 |
delete_option( 'wpt_default_rate_limit' );
|
27 |
delete_option( 'wpt_rate_limit' );
|
28 |
delete_option( 'wpt_rate_limiting' );
|
29 |
-
|
30 |
-
// Blogroll options
|
31 |
delete_option( 'jd-use-link-title' );
|
32 |
delete_option( 'jd-use-link-description' );
|
33 |
delete_option( 'newlink-published-text' );
|
34 |
delete_option( 'jd_twit_blogroll' );
|
35 |
|
36 |
-
// Default publishing options.
|
37 |
delete_option( 'jd_tweet_default' );
|
38 |
delete_option( 'jd_tweet_default_edit' );
|
39 |
delete_option( 'wpt_inline_edits' );
|
40 |
|
41 |
-
// Note that default options are set.
|
42 |
delete_option( 'twitterInitialised' );
|
43 |
delete_option( 'wpt_twitter_setup' );
|
44 |
delete_option( 'wp_twitter_failure' );
|
@@ -51,7 +61,7 @@ if ( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
51 |
delete_option( 'jd-use-none' );
|
52 |
delete_option( 'jd-use-wp' );
|
53 |
|
54 |
-
// Special Options
|
55 |
delete_option( 'jd_twit_prepend' );
|
56 |
delete_option( 'jd_twit_append' );
|
57 |
delete_option( 'jd_twit_remote' );
|
@@ -65,25 +75,25 @@ if ( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
65 |
delete_option( 'use_tags_as_hashtags' );
|
66 |
delete_option( 'jd_max_tags' );
|
67 |
delete_option( 'jd_max_characters' );
|
68 |
-
// Bitly Settings
|
69 |
delete_option( 'bitlylogin' );
|
70 |
delete_option( 'jd-use-bitly' );
|
71 |
delete_option( 'bitlyapi' );
|
72 |
|
73 |
-
// twitter compatible api
|
74 |
delete_option( 'jd_api_post_status' );
|
75 |
delete_option( 'app_consumer_key' );
|
76 |
delete_option( 'app_consumer_secret' );
|
77 |
delete_option( 'oauth_token' );
|
78 |
delete_option( 'oauth_token_secret' );
|
79 |
|
80 |
-
//dymamic analytics
|
81 |
delete_option( 'jd_dynamic_analytics' );
|
82 |
delete_option( 'use_dynamic_analytics' );
|
83 |
-
//category limits
|
84 |
delete_option( 'limit_categories' );
|
85 |
delete_option( 'tweet_categories' );
|
86 |
-
//yourls installation
|
87 |
delete_option( 'yourlsapi' );
|
88 |
delete_option( 'yourlspath' );
|
89 |
delete_option( 'yourlsurl' );
|
@@ -91,8 +101,8 @@ if ( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
|
91 |
delete_option( 'jd_replace_character' );
|
92 |
delete_option( 'jd_date_format' );
|
93 |
delete_option( 'jd_keyword_format' );
|
94 |
-
//Version
|
95 |
delete_option( 'wp_to_twitter_version' );
|
96 |
delete_option( 'wpt_authentication_missing' );
|
97 |
delete_option( 'wpt_http' );
|
98 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Uninstall WP to Twitter
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
+
if ( ! defined( 'ABSPATH' ) && ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
13 |
exit();
|
14 |
} else {
|
15 |
delete_option( 'wpt_post_types' );
|
20 |
delete_option( 'comment-published-text' );
|
21 |
delete_option( 'wpt_status_message_last' );
|
22 |
delete_option( 'wtt_twitter_username' );
|
23 |
+
// Su.pr API.
|
24 |
delete_option( 'suprapi' );
|
25 |
|
26 |
+
// Error checking.
|
27 |
delete_option( 'jd-functions-checked' );
|
28 |
delete_option( 'wp_twitter_failure' );
|
29 |
delete_option( 'wp_supr_failure' );
|
31 |
delete_option( 'wp_bitly_failure' );
|
32 |
delete_option( 'wpt_curl_error' );
|
33 |
|
34 |
+
// Rate Limiting.
|
35 |
delete_option( 'wpt_rate_limits' );
|
36 |
delete_option( 'wpt_default_rate_limit' );
|
37 |
delete_option( 'wpt_rate_limit' );
|
38 |
delete_option( 'wpt_rate_limiting' );
|
39 |
+
|
40 |
+
// Blogroll options.
|
41 |
delete_option( 'jd-use-link-title' );
|
42 |
delete_option( 'jd-use-link-description' );
|
43 |
delete_option( 'newlink-published-text' );
|
44 |
delete_option( 'jd_twit_blogroll' );
|
45 |
|
46 |
+
// Default publishing options.
|
47 |
delete_option( 'jd_tweet_default' );
|
48 |
delete_option( 'jd_tweet_default_edit' );
|
49 |
delete_option( 'wpt_inline_edits' );
|
50 |
|
51 |
+
// Note that default options are set.
|
52 |
delete_option( 'twitterInitialised' );
|
53 |
delete_option( 'wpt_twitter_setup' );
|
54 |
delete_option( 'wp_twitter_failure' );
|
61 |
delete_option( 'jd-use-none' );
|
62 |
delete_option( 'jd-use-wp' );
|
63 |
|
64 |
+
// Special Options.
|
65 |
delete_option( 'jd_twit_prepend' );
|
66 |
delete_option( 'jd_twit_append' );
|
67 |
delete_option( 'jd_twit_remote' );
|
75 |
delete_option( 'use_tags_as_hashtags' );
|
76 |
delete_option( 'jd_max_tags' );
|
77 |
delete_option( 'jd_max_characters' );
|
78 |
+
// Bitly Settings.
|
79 |
delete_option( 'bitlylogin' );
|
80 |
delete_option( 'jd-use-bitly' );
|
81 |
delete_option( 'bitlyapi' );
|
82 |
|
83 |
+
// twitter compatible api.
|
84 |
delete_option( 'jd_api_post_status' );
|
85 |
delete_option( 'app_consumer_key' );
|
86 |
delete_option( 'app_consumer_secret' );
|
87 |
delete_option( 'oauth_token' );
|
88 |
delete_option( 'oauth_token_secret' );
|
89 |
|
90 |
+
// dymamic analytics.
|
91 |
delete_option( 'jd_dynamic_analytics' );
|
92 |
delete_option( 'use_dynamic_analytics' );
|
93 |
+
// category limits.
|
94 |
delete_option( 'limit_categories' );
|
95 |
delete_option( 'tweet_categories' );
|
96 |
+
// yourls installation.
|
97 |
delete_option( 'yourlsapi' );
|
98 |
delete_option( 'yourlspath' );
|
99 |
delete_option( 'yourlsurl' );
|
101 |
delete_option( 'jd_replace_character' );
|
102 |
delete_option( 'jd_date_format' );
|
103 |
delete_option( 'jd_keyword_format' );
|
104 |
+
// Version.
|
105 |
delete_option( 'wp_to_twitter_version' );
|
106 |
delete_option( 'wpt_authentication_missing' );
|
107 |
delete_option( 'wpt_http' );
|
108 |
+
}
|
wp-to-twitter-manager.php
CHANGED
@@ -1,18 +1,31 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
exit;
|
4 |
-
}
|
5 |
-
|
|
|
|
|
|
|
6 |
function wpt_updated_settings() {
|
7 |
wpt_check_version();
|
8 |
-
|
9 |
if ( empty( $_POST ) ) {
|
10 |
return;
|
11 |
}
|
12 |
-
|
13 |
$nonce = $_REQUEST['_wpnonce'];
|
14 |
if ( ! wp_verify_nonce( $nonce, 'wp-to-twitter-nonce' ) ) {
|
15 |
-
die(
|
16 |
}
|
17 |
|
18 |
if ( isset( $_POST['oauth_settings'] ) ) {
|
@@ -21,11 +34,11 @@ function wpt_updated_settings() {
|
|
21 |
$oauth_message = '';
|
22 |
}
|
23 |
|
24 |
-
$message =
|
25 |
|
26 |
-
// notifications from oauth connection
|
27 |
if ( isset( $_POST['oauth_settings'] ) ) {
|
28 |
-
if (
|
29 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro?tab=basic' );
|
30 |
|
31 |
print( '
|
@@ -33,19 +46,19 @@ function wpt_updated_settings() {
|
|
33 |
<p>' . __( 'WP to Twitter is now connected with Twitter.', 'wp-to-twitter' ) . " <a href='$admin_url'>" . __( 'Configure your Tweet templates', 'wp-to-twitter' ) . '</a></p>
|
34 |
</div>
|
35 |
' );
|
36 |
-
}
|
37 |
print( '
|
38 |
<div id="message" class="error fade">
|
39 |
<p>' . __( 'WP to Twitter failed to connect with Twitter.', 'wp-to-twitter' ) . ' <strong>' . __( 'Error:', 'wp-to-twitter' ) . '</strong> ' . get_option( 'wpt_error' ) . '</p>
|
40 |
</div>
|
41 |
' );
|
42 |
-
}
|
43 |
print( '
|
44 |
<div id="message" class="updated fade">
|
45 |
<p>' . __( 'OAuth Authentication Data Cleared.', 'wp-to-twitter' ) . '</p>
|
46 |
</div>
|
47 |
' );
|
48 |
-
}
|
49 |
print( '
|
50 |
<div id="message" class="error fade">
|
51 |
<p>' . __( 'OAuth Authentication Failed. Your server time is not in sync with the Twitter servers. Talk to your hosting service to see what can be done.', 'wp-to-twitter' ) . '</p>
|
@@ -55,23 +68,23 @@ function wpt_updated_settings() {
|
|
55 |
print( '
|
56 |
<div id="message" class="error fade">
|
57 |
<p>' . __( 'OAuth Authentication response not understood.', 'wp-to-twitter' ) . '</p>
|
58 |
-
</div>
|
59 |
' );
|
60 |
}
|
61 |
}
|
62 |
|
63 |
-
if ( isset( $_POST['submit-type'] ) && $_POST['submit-type']
|
64 |
update_option( 'jd_tweet_default', ( isset( $_POST['jd_tweet_default'] ) ) ? $_POST['jd_tweet_default'] : 0 );
|
65 |
update_option( 'jd_tweet_default_edit', ( isset( $_POST['jd_tweet_default_edit'] ) ) ? $_POST['jd_tweet_default_edit'] : 0 );
|
66 |
-
|
67 |
-
if ( isset( $_POST['wpt_rate_limiting'] ) && get_option( 'wpt_rate_limiting' )
|
68 |
$extend = __( 'Rate Limiting is enabled. Default rate limits are set at 10 posts per category/term per hour. <a href="#special_cases">Edit global default</a> or edit individual terms to customize limits for each category or taxonomy term.', 'wp-to-twitter' );
|
69 |
-
wp_schedule_event( current_time( 'timestamp' )+3600, 'hourly', 'wptratelimits' );
|
70 |
} else {
|
71 |
$extend = '';
|
72 |
wp_clear_scheduled_hook( 'wptratelimits' );
|
73 |
-
}
|
74 |
-
|
75 |
update_option( 'wpt_rate_limiting', ( isset( $_POST['wpt_rate_limiting'] ) ) ? 1 : 0 );
|
76 |
update_option( 'wpt_inline_edits', ( isset( $_POST['wpt_inline_edits'] ) ) ? $_POST['wpt_inline_edits'] : 0 );
|
77 |
update_option( 'jd_twit_remote', ( isset( $_POST['jd_twit_remote'] ) ) ? $_POST['jd_twit_remote'] : 0 );
|
@@ -82,20 +95,20 @@ function wpt_updated_settings() {
|
|
82 |
update_option( 'jd_twit_append', $_POST['jd_twit_append'] );
|
83 |
update_option( 'jd_post_excerpt', $_POST['jd_post_excerpt'] );
|
84 |
update_option( 'jd_max_tags', $_POST['jd_max_tags'] );
|
85 |
-
$use_cats = ( isset( $_POST['wpt_use_cats']
|
86 |
update_option( 'wpt_use_cats', $use_cats );
|
87 |
-
update_option( 'wpt_tag_source', ( ( isset( $_POST['wpt_tag_source'] ) && $_POST['wpt_tag_source']
|
88 |
update_option( 'jd_max_characters', $_POST['jd_max_characters'] );
|
89 |
update_option( 'jd_replace_character', $_POST['jd_replace_character'] );
|
90 |
update_option( 'jd_date_format', $_POST['jd_date_format'] );
|
91 |
update_option( 'jd_dynamic_analytics', $_POST['jd-dynamic-analytics'] );
|
92 |
|
93 |
$twitter_analytics = ( isset( $_POST['twitter-analytics'] ) ) ? $_POST['twitter-analytics'] : 0;
|
94 |
-
if (
|
95 |
update_option( 'use_dynamic_analytics', 0 );
|
96 |
update_option( 'use-twitter-analytics', 1 );
|
97 |
update_option( 'no-analytics', 0 );
|
98 |
-
}
|
99 |
update_option( 'use_dynamic_analytics', 1 );
|
100 |
update_option( 'use-twitter-analytics', 0 );
|
101 |
update_option( 'no-analytics', 0 );
|
@@ -108,16 +121,9 @@ function wpt_updated_settings() {
|
|
108 |
update_option( 'twitter-analytics-campaign', $_POST['twitter-analytics-campaign'] );
|
109 |
update_option( 'jd_individual_twitter_users', ( isset( $_POST['jd_individual_twitter_users'] ) ? $_POST['jd_individual_twitter_users'] : 0 ) );
|
110 |
|
111 |
-
|
112 |
if ( isset( $_POST['wpt_caps'] ) ) {
|
113 |
$perms = $_POST['wpt_caps'];
|
114 |
-
$caps = array(
|
115 |
-
'wpt_twitter_oauth',
|
116 |
-
'wpt_twitter_custom',
|
117 |
-
'wpt_twitter_switch',
|
118 |
-
'wpt_can_tweet',
|
119 |
-
'wpt_tweet_now'
|
120 |
-
);
|
121 |
foreach ( $perms as $key => $value ) {
|
122 |
$role = get_role( $key );
|
123 |
if ( is_object( $role ) ) {
|
@@ -140,44 +146,44 @@ function wpt_updated_settings() {
|
|
140 |
$message .= __( 'WP to Twitter Advanced Options Updated', 'wp-to-twitter' ) . '. ' . $extend;
|
141 |
}
|
142 |
|
143 |
-
if ( isset( $_POST['submit-type'] ) && $_POST['submit-type']
|
144 |
-
// UPDATE OPTIONS
|
145 |
$wpt_settings = get_option( 'wpt_post_types' );
|
146 |
-
if ( !is_array( $wpt_settings ) ) {
|
147 |
$wpt_settings = array();
|
148 |
}
|
149 |
|
150 |
$keys = array();
|
151 |
$values = array();
|
152 |
foreach ( $_POST['wpt_post_types'] as $key => $value ) {
|
153 |
-
// using wp_encode_emoji allows me to save emoji in templates
|
154 |
-
// ...but I haven't found a way to convert the saved emoji *back* to unicode
|
155 |
// sending the HTML entity just yields a broken character on Twitter.
|
156 |
$array = array(
|
157 |
-
'post-published-update' => ( isset( $value[
|
158 |
-
'post-published-text' => $value[
|
159 |
-
'post-edited-update' => ( isset( $value[
|
160 |
-
'post-edited-text' => $value[
|
161 |
);
|
162 |
-
array_push( $keys, $key );
|
163 |
array_push( $values, $array );
|
164 |
}
|
165 |
-
|
166 |
$wpt_settings = array_combine( $keys, $values );
|
167 |
update_option( 'wpt_post_types', $wpt_settings );
|
168 |
update_option( 'newlink-published-text', $_POST['newlink-published-text'] );
|
169 |
-
update_option( 'jd_twit_blogroll', ( isset( $_POST['jd_twit_blogroll'] ) ) ? $_POST['jd_twit_blogroll'] :
|
170 |
$message = wpt_select_shortener( $_POST );
|
171 |
$message .= __( 'WP to Twitter Options Updated', 'wp-to-twitter' );
|
172 |
$message = apply_filters( 'wpt_settings', $message, $_POST );
|
173 |
}
|
174 |
|
175 |
-
if ( isset( $_POST['wpt_shortener_update'] ) && $_POST['wpt_shortener_update']
|
176 |
$message = wpt_shortener_update( $_POST );
|
177 |
}
|
178 |
|
179 |
// Check whether the server has supported for needed functions.
|
180 |
-
if ( isset( $_POST['submit-type'] ) && $_POST['submit-type']
|
181 |
$message = wpt_check_functions();
|
182 |
}
|
183 |
|
@@ -186,44 +192,47 @@ function wpt_updated_settings() {
|
|
186 |
}
|
187 |
}
|
188 |
|
|
|
|
|
|
|
189 |
function wpt_update_settings() {
|
190 |
?>
|
191 |
<div class="wrap" id="wp-to-twitter">
|
192 |
-
<?php
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
?>
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
<?php wpt_max_length(); ?>
|
204 |
-
|
205 |
<div class='nav-tab-wrapper'>
|
206 |
<?php wpt_settings_tabs(); ?>
|
207 |
</div>
|
208 |
<div id="wpt_settings_page" class="postbox-container jcd-wide">
|
209 |
<div class="metabox-holder">
|
210 |
|
211 |
-
<?php
|
212 |
-
$default = ( get_option( 'wtt_twitter_username' )
|
213 |
$current = ( isset( $_GET['tab'] ) ) ? $_GET['tab'] : $default;
|
214 |
-
if (
|
215 |
if ( function_exists( 'wtt_connect_oauth' ) ) {
|
216 |
wtt_connect_oauth();
|
217 |
}
|
218 |
}
|
219 |
-
if (
|
220 |
if ( function_exists( 'wpt_pro_functions' ) ) {
|
221 |
wpt_pro_functions();
|
222 |
if ( function_exists( 'wpt_notes' ) ) {
|
223 |
wpt_notes();
|
224 |
}
|
225 |
} else {
|
226 |
-
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
|
|
227 |
<div class="ui-sortable meta-box-sortables">
|
228 |
<div class="postbox">
|
229 |
<h3 class='wpt-upgrade'><span><strong><?php _e( 'Upgrade Now!', 'wp-to-twitter' ); ?></strong></span></h3>
|
@@ -231,41 +240,49 @@ function wpt_update_settings() {
|
|
231 |
<div class="inside purchase">
|
232 |
<h4><strong><?php _e( 'What can WP Tweets PRO do for you?', 'wp-to-twitter' ); ?></strong></h4>
|
233 |
<p>
|
234 |
-
<?php
|
235 |
-
_e( 'WP Tweets PRO takes the great Tweeting abilities from WP to Twitter and puts them in high gear.', 'wp-to-twitter' );
|
236 |
-
?>
|
237 |
</p>
|
238 |
<ul>
|
239 |
-
<li><?php _e( 'Publish to unique Twitter accounts for each site author.','wp-to-twitter' ); ?></li>
|
240 |
<li><?php _e( 'Schedule up to 3 re-posts of Tweets at an interval of your choice.', 'wp-to-twitter' ); ?></li>
|
241 |
<li><?php _e( 'With a delay between publishing and Tweeting, verify your tweets before you share online.', 'wp-to-twitter' ); ?></li>
|
242 |
<li><?php _e( 'Automatically your great old posts every few hours, days, or weeks!', 'wp-to-twitter' ); ?></li>
|
243 |
<li><?php _e( 'Upload your featured images to Twitter with each Tweet', 'wp-to-twitter' ); ?></li>
|
244 |
-
<li
|
|
|
|
|
|
|
|
|
|
|
245 |
</ul>
|
246 |
<p>
|
247 |
-
<strong><?php _e(
|
248 |
</p>
|
249 |
<p class='wpt-button'>
|
250 |
<strong class='cta'><a href="http://www.wptweetspro.com/wp-tweets-pro"><?php _e( 'Upgrade to <strong>WP Tweets PRO</strong>!', 'wp-to-twitter' ); ?></a></strong>
|
251 |
-
</p>
|
252 |
-
|
253 |
<h4><?php _e( 'What else does WP Tweets PRO do?', 'wp-to-twitter' ); ?></h4>
|
254 |
-
|
255 |
<p>
|
256 |
<?php _e( 'WP Tweets PRO is packed with features to help you increase engagement with your Twitter followers. Upload images, use Twitter Cards, and automated re-posting of your Tweets are just a few of the features available in the premium add-on to WP to Twitter.', 'wp-to-twitter' ); ?>
|
257 |
</p>
|
258 |
<p>
|
259 |
-
<?php
|
|
|
|
|
|
|
260 |
</p>
|
261 |
<p>
|
262 |
-
<?php
|
|
|
|
|
|
|
263 |
</p>
|
264 |
-
|
265 |
<p class='wpt-button'>
|
266 |
<strong class='cta'><a href="http://www.wptweetspro.com/wp-tweets-pro"><?php _e( 'Buy WP Tweets PRO today!', 'wp-to-twitter' ); ?></a></strong>
|
267 |
</p>
|
268 |
-
|
269 |
</div>
|
270 |
</div>
|
271 |
</div>
|
@@ -273,7 +290,7 @@ function wpt_update_settings() {
|
|
273 |
}
|
274 |
}
|
275 |
}
|
276 |
-
if (
|
277 |
?>
|
278 |
<div class="ui-sortable meta-box-sortables">
|
279 |
<div class="postbox">
|
@@ -281,109 +298,101 @@ function wpt_update_settings() {
|
|
281 |
|
282 |
<div class="inside wpt-settings">
|
283 |
<form method="post" action="">
|
284 |
-
<?php
|
285 |
-
|
|
|
|
|
286 |
<div>
|
287 |
-
<?php echo apply_filters( 'wpt_tweet_length', '' ); ?>
|
288 |
-
<?php echo apply_filters( 'wpt_pick_shortener', '' ); ?>
|
289 |
<?php
|
|
|
|
|
290 |
$post_types = get_post_types( array( 'public' => true ), 'objects' );
|
291 |
$wpt_settings = get_option( 'wpt_post_types' );
|
292 |
$tabs = "<ul class='tabs' role='tablist'>";
|
293 |
foreach ( $post_types as $type ) {
|
294 |
-
$name
|
295 |
-
$slug
|
296 |
-
if (
|
297 |
} else {
|
298 |
$tabs .= "<li><a href='#wpt_$slug' role='tab' id='tab_wpt_$slug' aria-controls='wpt_$slug'>$name</a></li>";
|
299 |
}
|
300 |
}
|
301 |
-
$tabs .= "<li><a href='#wpt_links' id='tab_wpt_links' aria-controls='wpt_links'>" . __( 'Links', 'wp-to-twitter' ) .
|
302 |
-
</ul>";
|
303 |
echo $tabs;
|
304 |
foreach ( $post_types as $type ) {
|
305 |
-
$name
|
306 |
-
$
|
307 |
-
$slug
|
308 |
-
if ( $slug == 'attachment' || $slug == 'nav_menu_item' || $slug == 'revision' ) {
|
309 |
continue;
|
310 |
} else {
|
311 |
-
$vowels = array( 'a', 'e', 'i', 'o', 'u' );
|
312 |
-
foreach ( $vowels as $vowel ) {
|
313 |
-
if ( strpos( $name, $vowel ) === 0 ) {
|
314 |
-
$word = 'an';
|
315 |
-
break;
|
316 |
-
} else {
|
317 |
-
$word = 'a';
|
318 |
-
}
|
319 |
-
}
|
320 |
?>
|
321 |
-
|
322 |
<div class='wptab wpt_types wpt_<?php echo $slug; ?>' aria-labelledby='tab_wpt_<?php echo $slug; ?>' role="tabpanel" id='wpt_<?php echo $slug; ?>'>
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
}
|
339 |
-
}
|
340 |
-
echo "</ul>";
|
341 |
-
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
342 |
-
printf( __( '<a href="%s">Upgrade to WP Tweets PRO</a> to filter posts in all custom post types on any taxonomy.', 'wp-to-twitter' ), "http://www.wptweetspro.com/wp-tweets-pro" );
|
343 |
-
} else {
|
344 |
-
_e( 'Updating the WP Tweets PRO taxonomy filters will overwrite your old category filters.', 'wp-to-twitter' );
|
345 |
}
|
346 |
}
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
<
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
</
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
</div>
|
388 |
<?php
|
389 |
}
|
@@ -393,281 +402,255 @@ function wpt_update_settings() {
|
|
393 |
<fieldset>
|
394 |
<legend><span><?php _e( 'Links', 'wp-to-twitter' ); ?></span></legend>
|
395 |
<p>
|
396 |
-
<input type="checkbox" name="jd_twit_blogroll" id="jd_twit_blogroll"
|
397 |
-
|
398 |
-
<label
|
399 |
-
|
400 |
-
<label
|
401 |
-
for="newlink-published-text"><?php _e( "Text for new link updates:", 'wp-to-twitter' ); ?></label>
|
402 |
-
<input aria-describedby="newlink-published-text-label" type="text"
|
403 |
-
class="wpt-template" name="newlink-published-text"
|
404 |
-
id="newlink-published-text" size="60" maxlength="120"
|
405 |
-
value="<?php esc_attr_e( stripslashes( get_option( 'newlink-published-text' ) ) ); ?>"/><br/><span
|
406 |
-
id="newlink-published-text-label"><?php _e( 'Available shortcodes: <code>#url#</code>, <code>#title#</code>, and <code>#description#</code>.', 'wp-to-twitter' ); ?></span>
|
407 |
</p>
|
408 |
</fieldset>
|
409 |
</div>
|
410 |
<div>
|
411 |
<input type="hidden" name="submit-type" value="options" />
|
412 |
</div>
|
413 |
-
<input type="submit" name="submit" value="<?php _e(
|
414 |
</div>
|
415 |
</form>
|
416 |
</div>
|
417 |
</div>
|
418 |
</div>
|
419 |
-
|
420 |
<div class="ui-sortable meta-box-sortables">
|
421 |
<div class="postbox">
|
422 |
<h3><span><?php _e( 'Tweet Template Tags', 'wp-to-twitter' ); ?></span></h3>
|
423 |
-
|
424 |
<div class="inside">
|
425 |
<ul>
|
426 |
-
<li><?php _e(
|
427 |
-
<li><?php _e(
|
428 |
-
<li><?php _e(
|
429 |
-
<li><?php _e(
|
430 |
-
<li><?php _e(
|
431 |
-
<li><?php _e(
|
432 |
-
<li><?php _e(
|
433 |
-
<li><?php _e(
|
434 |
-
<li><?php _e(
|
435 |
-
<li><?php _e(
|
436 |
-
<li><?php _e(
|
437 |
-
<li><?php _e(
|
438 |
-
<li><?php _e(
|
439 |
-
<li><?php _e(
|
440 |
-
<?php
|
441 |
-
|
442 |
-
|
|
|
|
|
|
|
|
|
443 |
</ul>
|
444 |
<p>
|
445 |
-
<?php
|
446 |
-
_e( "Create custom shortcodes and access WordPress custom fields by using square brackets and the name of your custom field.", 'wp-to-twitter' );
|
447 |
-
?>
|
448 |
<br />
|
449 |
-
<?php
|
450 |
-
_e( "<strong>Example:</strong> <code>[[custom_field]]</code>", 'wp-to-twitter' );
|
451 |
-
?>
|
452 |
</p>
|
453 |
<p>
|
454 |
-
<?php
|
455 |
-
_e( "Create custom shortcodes and access the post author's custom user meta fields by using curly brackets and the name of the custom field.", 'wp-to-twitter' );
|
456 |
-
?>
|
457 |
<br />
|
458 |
-
<?php
|
459 |
-
|
460 |
-
?>
|
461 |
-
</p>
|
462 |
</div>
|
463 |
</div>
|
464 |
-
</div>
|
465 |
-
<?php
|
466 |
-
|
467 |
-
|
|
|
468 |
}
|
469 |
-
|
470 |
-
if (
|
471 |
?>
|
|
|
472 |
<div class="ui-sortable meta-box-sortables">
|
473 |
<div class="postbox">
|
474 |
<h3><span><?php _e( 'Advanced Settings', 'wp-to-twitter' ); ?></span></h3>
|
475 |
<div class="inside">
|
476 |
-
<form method="post" action="">
|
477 |
<div>
|
478 |
-
<?php
|
479 |
$nonce = wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false );
|
480 |
-
echo "<div>$nonce</div>";
|
481 |
?>
|
482 |
|
483 |
<fieldset>
|
484 |
-
<legend><?php _e( 'Hashtags', 'wp-to-twitter' ); ?></legend>
|
485 |
<p>
|
486 |
-
<input type="checkbox" name="jd_strip_nonan" id="jd_strip_nonan"
|
487 |
-
value="1" <?php echo jd_checkCheckbox( 'jd_strip_nonan' ); ?> /> <label
|
488 |
-
for="jd_strip_nonan"><?php _e( "Strip nonalphanumeric characters from tags", 'wp-to-twitter' ); ?></label>
|
489 |
</p>
|
490 |
-
|
491 |
<p>
|
492 |
-
<input type="checkbox" name="wpt_tag_source" id="wpt_tag_source"
|
493 |
-
|
494 |
-
<label
|
495 |
-
for="wpt_tag_source"><?php _e( "Use tag slug as hashtag value", 'wp-to-twitter' ); ?></label><br/>
|
496 |
</p>
|
497 |
-
|
498 |
<input type="checkbox" name="wpt_use_cats" id="wpt_use_cats" value="1" <?php checked( get_option( 'wpt_use_cats' ), '1' ); ?> />
|
499 |
-
<label for="wpt_use_cats"><?php _e(
|
500 |
</p>
|
501 |
<p>
|
502 |
-
<label
|
503 |
-
|
504 |
-
<input type="text" name="jd_replace_character" id="jd_replace_character"
|
505 |
-
value="<?php esc_attr_e( get_option( 'jd_replace_character' ) ); ?>"
|
506 |
-
size="3"/>
|
507 |
</p>
|
508 |
|
509 |
<p>
|
510 |
-
<label
|
511 |
-
|
512 |
-
<input aria-describedby="jd_max_characters_label" type="text" name="jd_max_tags"
|
513 |
-
id="jd_max_tags" value="<?php esc_attr_e( get_option( 'jd_max_tags' ) ); ?>"
|
514 |
-
size="3"/>
|
515 |
</p>
|
516 |
<p>
|
517 |
-
<label
|
518 |
-
|
519 |
-
<input type="text" name="jd_max_characters" id="jd_max_characters"
|
520 |
-
value="<?php esc_attr_e( get_option( 'jd_max_characters' ) ); ?>" size="3"/>
|
521 |
</p>
|
522 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
523 |
<fieldset>
|
524 |
-
<legend><?php _e( 'Template Settings', 'wp-to-twitter' ); ?></legend>
|
525 |
<p>
|
526 |
-
<label
|
527 |
-
|
528 |
-
<input type="text" name="jd_post_excerpt" id="jd_post_excerpt" size="3" maxlength="3" value="<?php echo( esc_attr( get_option( 'jd_post_excerpt' ) ) ) ?>"/>
|
529 |
</p>
|
530 |
-
|
531 |
<p>
|
532 |
-
<label
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
|
|
|
|
|
|
541 |
echo date_i18n( get_option( 'jd_date_format' ) );
|
542 |
} else {
|
543 |
-
echo
|
544 |
-
}
|
545 |
-
|
|
|
546 |
</p>
|
547 |
|
548 |
<p>
|
549 |
-
<label for="jd_twit_prepend"><?php _e(
|
550 |
-
<input type="text" name="jd_twit_prepend" id="jd_twit_prepend" size="20"
|
551 |
-
value="<?php esc_attr_e( stripslashes( get_option( 'jd_twit_prepend' ) ) ) ?>"/>
|
552 |
</p>
|
553 |
<p>
|
554 |
-
<label for="jd_twit_append"><?php _e(
|
555 |
-
<input type="text" name="jd_twit_append" id="jd_twit_append" size="20"
|
556 |
-
value="<?php esc_attr_e( stripslashes( get_option( 'jd_twit_append' ) ) ) ?>"/>
|
557 |
</p>
|
558 |
<p>
|
559 |
-
<label for="jd_twit_custom_url"><?php _e(
|
560 |
-
<input type="text" name="jd_twit_custom_url" id="jd_twit_custom_url" size="30" maxlength="120"
|
561 |
-
value="<?php esc_attr_e( stripslashes( get_option( 'jd_twit_custom_url' ) ) ) ?>"/>
|
562 |
</p>
|
563 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
564 |
<fieldset>
|
565 |
-
<legend id="special_cases"><?php _e(
|
566 |
<p>
|
567 |
-
<input type="checkbox" name="jd_tweet_default" id="jd_tweet_default"
|
568 |
-
|
569 |
-
<
|
570 |
-
|
571 |
-
<input type="checkbox" name="
|
572 |
-
|
573 |
-
<
|
574 |
-
|
575 |
-
<input type="checkbox" name="wpt_inline_edits" id="wpt_inline_edits"
|
576 |
-
value="1" <?php echo jd_checkCheckbox( 'wpt_inline_edits' ) ?> />
|
577 |
-
<label
|
578 |
-
for="wpt_inline_edits"><?php _e( "Allow status updates from Quick Edit", 'wp-to-twitter' ); ?></label><br/>
|
579 |
-
<input type="checkbox" name="wpt_rate_limiting" id="wpt_rate_limiting"
|
580 |
-
value="1" <?php echo jd_checkCheckbox( 'wpt_rate_limiting' ) ?> />
|
581 |
-
<label
|
582 |
-
for="wpt_rate_limiting"><?php _e( "Enable Rate Limiting", 'wp-to-twitter' ); ?></label><br/>
|
583 |
<?php
|
584 |
if ( get_option( 'wpt_rate_limiting' ) == 1 ) {
|
585 |
-
|
586 |
-
<input type="number" name="wpt_default_rate_limit" min="1" id="wpt_default_rate_limit"
|
587 |
-
|
588 |
-
|
589 |
-
for="wpt_default_rate_limit"><?php _e( "Default Rate Limit per category per hour", 'wp-to-twitter' ); ?></label><br/>
|
590 |
-
<?php
|
591 |
}
|
592 |
?>
|
593 |
</p>
|
594 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
595 |
<fieldset>
|
596 |
-
<legend><?php _e(
|
597 |
|
598 |
<p>
|
599 |
-
<input type="radio" name="twitter-analytics" id="use-twitter-analytics"
|
600 |
-
|
601 |
-
<label
|
602 |
-
|
603 |
-
<label
|
604 |
-
for="twitter-analytics-campaign"><?php _e( "Static Campaign identifier", 'wp-to-twitter' ); ?></label>
|
605 |
-
<input type="text" name="twitter-analytics-campaign" id="twitter-analytics-campaign"
|
606 |
-
size="40" maxlength="120"
|
607 |
-
value="<?php esc_attr_e( get_option( 'twitter-analytics-campaign' ) ) ?>"/><br/>
|
608 |
</p>
|
609 |
-
|
610 |
<p>
|
611 |
-
<input type="radio" name="twitter-analytics" id="use-dynamic-analytics"
|
612 |
-
|
613 |
-
<label
|
614 |
-
for="use-dynamic-analytics"><?php _e( "Use a dynamic identifier", 'wp-to-twitter' ); ?></label><br/>
|
615 |
-
<label
|
616 |
-
for="jd-dynamic-analytics"><?php _e( "What dynamic identifier would you like to use?", "wp-to-twitter" ); ?></label>
|
617 |
<select name="jd-dynamic-analytics" id="jd-dynamic-analytics">
|
618 |
-
<option
|
619 |
-
|
620 |
-
<option
|
621 |
-
|
622 |
-
<option
|
623 |
-
value="post_title"<?php echo jd_checkSelect( 'jd_dynamic_analytics', 'post_title' ); ?>><?php _e( "Post Title", "wp-to-twitter" ); ?></option>
|
624 |
-
<option
|
625 |
-
value="post_author"<?php echo jd_checkSelect( 'jd_dynamic_analytics', 'post_author' ); ?>><?php _e( "Author", "wp-to-twitter" ); ?></option>
|
626 |
</select><br/>
|
627 |
</p>
|
628 |
<p>
|
629 |
-
<input type="radio" name="twitter-analytics" id="no-analytics"
|
630 |
-
value="3" <?php echo jd_checkCheckbox( 'no-analytics' ); ?> /> <label
|
631 |
-
for="no-analytics"><?php _e( "No Analytics", 'wp-to-twitter' ); ?></label>
|
632 |
</p>
|
633 |
</fieldset>
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
|
|
|
|
|
|
|
|
642 |
|
643 |
-
</fieldset>
|
644 |
<div class='wpt-permissions'>
|
645 |
<fieldset>
|
646 |
<legend><?php _e( 'Permissions', 'wp-to-twitter' ); ?></legend>
|
647 |
<?php
|
648 |
global $wp_roles;
|
649 |
-
$roles
|
650 |
-
$caps
|
651 |
'wpt_can_tweet' => __( 'Can send Tweets', 'wp-to-twitter' ),
|
652 |
'wpt_twitter_custom' => __( 'See Custom Tweet Field when creating a Post', 'wp-to-twitter' ),
|
653 |
'wpt_twitter_switch' => __( 'Toggle the Tweet/Don\'t Tweet option', 'wp-to-twitter' ),
|
654 |
'wpt_tweet_now' => __( 'Can see Tweet Now button', 'wp-to-twitter' ),
|
655 |
-
'wpt_twitter_oauth' => __( 'Allow user to authenticate with Twitter', 'wp-to-twitter' )
|
656 |
);
|
657 |
-
$role_tabs
|
|
|
658 |
foreach ( $roles as $role => $rolename ) {
|
659 |
-
if (
|
660 |
continue;
|
661 |
}
|
662 |
-
$role_tabs
|
663 |
$role_container .= "<div class='wptab wpt_$role' id='wpt_" . sanitize_title( $role ) . "' aria-live='assertive'><fieldset id='wpt_$role' class='roles'><legend>$rolename</legend>";
|
664 |
$role_container .= "<input type='hidden' value='none' name='wpt_caps[" . $role . "][none]' />
|
665 |
-
|
666 |
foreach ( $caps as $cap => $name ) {
|
667 |
$role_container .= wpt_cap_checkbox( $role, $cap, $name );
|
668 |
}
|
669 |
-
$role_container .=
|
670 |
-
</ul></fieldset></div>\n";
|
671 |
}
|
672 |
echo "
|
673 |
<ul class='tabs'>
|
@@ -677,7 +660,14 @@ function wpt_update_settings() {
|
|
677 |
?>
|
678 |
</fieldset>
|
679 |
</div>
|
680 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
681 |
$inputs = '';
|
682 |
$default_order = array(
|
683 |
'excerpt' => 0,
|
@@ -690,7 +680,7 @@ function wpt_update_settings() {
|
|
690 |
'tags' => 7,
|
691 |
'modified' => 8,
|
692 |
'@' => 9,
|
693 |
-
'cat_desc' => 10
|
694 |
);
|
695 |
$preferred_order = get_option( 'wpt_truncation_order' );
|
696 |
if ( ! $preferred_order ) {
|
@@ -702,9 +692,9 @@ function wpt_update_settings() {
|
|
702 |
}
|
703 |
asort( $default_order );
|
704 |
foreach ( $default_order as $k => $v ) {
|
705 |
-
if (
|
706 |
-
$label = '<code>#blog#</code>';
|
707 |
-
}
|
708 |
$label = '<code>#post#</code>';
|
709 |
} else {
|
710 |
$label = '<code>#' . $k . '#</code>';
|
@@ -713,58 +703,76 @@ function wpt_update_settings() {
|
|
713 |
}
|
714 |
?>
|
715 |
<fieldset>
|
716 |
-
<legend><?php _e( 'Template tag priority order', 'wp-to-twitter' ); ?></legend>
|
717 |
-
<p><?php _e( 'The order in which items will be abbreviated or removed from your Tweet if the Tweet is too long to send to Twitter.', 'wp-to-twitter' ); ?> <?php _e( 'Tags with lower values will be modified first.', 'wp-to-twitter' ); ?></p>
|
718 |
<p>
|
719 |
-
|
|
|
|
|
|
|
720 |
</p>
|
721 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
722 |
<fieldset>
|
723 |
-
<legend><?php _e( 'Miscellaneous Settings', 'wp-to-twitter' ); ?></legend>
|
724 |
<ul>
|
725 |
<li>
|
726 |
-
<input type="checkbox" name="wpt_permit_feed_styles" id="wpt_permit_feed_styles" value="1" <?php echo
|
727 |
-
<label for="wpt_permit_feed_styles"><?php _e(
|
728 |
</li>
|
729 |
<li>
|
730 |
-
<input type="checkbox" name="wp_debug_oauth" id="wp_debug_oauth" value="1" <?php echo
|
731 |
</li>
|
732 |
-
<li
|
733 |
-
|
734 |
-
for="jd_donations"><strong><?php _e( "I made a donation, so stop whinging at me, please.", 'wp-to-twitter' ); ?></strong></label>
|
735 |
</li>
|
736 |
</ul>
|
737 |
</fieldset>
|
738 |
<div>
|
739 |
<input type="hidden" name="submit-type" value="advanced"/>
|
740 |
</div>
|
741 |
-
<input type="submit" name="submit"
|
742 |
-
value="<?php _e( "Save Advanced WP to Twitter Options", 'wp-to-twitter' ); ?>"
|
743 |
-
class="button-primary"/>
|
744 |
</div>
|
745 |
</form>
|
746 |
</div>
|
747 |
</div>
|
748 |
</div>
|
749 |
-
<?php
|
750 |
-
|
|
|
751 |
?>
|
752 |
<div class="postbox" id="get-support">
|
753 |
<h3><span><?php _e( 'Get Plug-in Support', 'wp-to-twitter' ); ?></span></h3>
|
754 |
|
755 |
<div class="inside">
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
765 |
</div>
|
766 |
</div>
|
767 |
-
<?php
|
|
|
|
|
768 |
</div>
|
769 |
</div>
|
770 |
<?php wpt_sidebar(); ?>
|
@@ -773,6 +781,9 @@ function wpt_update_settings() {
|
|
773 |
<?php
|
774 |
}
|
775 |
|
|
|
|
|
|
|
776 |
function wpt_sidebar() {
|
777 |
$context = ( ! function_exists( 'wpt_pro_exists' ) ) ? 'free' : 'premium';
|
778 |
?>
|
@@ -780,20 +791,27 @@ function wpt_sidebar() {
|
|
780 |
<div class="metabox-holder">
|
781 |
<div class="ui-sortable meta-box-sortables<?php echo ' ' . $context; ?>">
|
782 |
<div class="postbox">
|
783 |
-
<?php
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
|
|
|
|
|
|
|
|
790 |
<div class="inside resources">
|
791 |
-
<?php
|
792 |
-
|
793 |
-
|
|
|
|
|
|
|
|
|
794 |
<p>
|
795 |
-
<a href="https://twitter.com/intent/follow?screen_name=joedolson" class="twitter-follow-button"
|
796 |
-
data-size="small" data-related="joedolson">Follow @joedolson</a>
|
797 |
<script>!function (d, s, id) {
|
798 |
var js, fjs = d.getElementsByTagName(s)[0];
|
799 |
if (!d.getElementById(id)) {
|
@@ -805,84 +823,102 @@ function wpt_sidebar() {
|
|
805 |
}(document, "script", "twitter-wjs");</script>
|
806 |
</p>
|
807 |
<?php
|
808 |
-
if (
|
809 |
$support_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
810 |
-
$support
|
811 |
} else {
|
812 |
$support_url = false;
|
813 |
-
$support
|
814 |
-
}
|
815 |
echo $support;
|
816 |
?>
|
817 |
<a href="https://www.joedolson.com/wp-content/uploads/wp-tweets-pro-users-guide-current.pdf"><?php _e( 'Read the Manual', 'wp-to-twitter' ); ?></a>
|
818 |
</div>
|
819 |
</div>
|
820 |
</div>
|
821 |
-
|
822 |
<div class="ui-sortable meta-box-sortables">
|
823 |
<div class="postbox">
|
824 |
-
|
|
|
|
|
|
|
|
|
825 |
|
826 |
<div class="inside server">
|
827 |
-
|
828 |
</div>
|
829 |
</div>
|
830 |
</div>
|
831 |
-
|
832 |
<div class="ui-sortable meta-box-sortables">
|
833 |
<div class="postbox">
|
834 |
<h3><?php _e( 'Test WP to Twitter', 'wp-to-twitter' ); ?></h3>
|
835 |
-
|
836 |
<div class="inside test">
|
837 |
<p>
|
838 |
-
|
839 |
</p>
|
840 |
<form method="post" action="">
|
841 |
<input type="hidden" name="submit-type" value="check-support"/>
|
842 |
-
<?php
|
843 |
-
|
|
|
|
|
844 |
<p>
|
845 |
-
<input type="submit" name="submit" value="<?php _e( 'Test WP to Twitter', 'wp-to-twitter' ); ?>" class="button-
|
846 |
</p>
|
847 |
-
</form>
|
848 |
</div>
|
849 |
</div>
|
850 |
</div>
|
851 |
|
852 |
-
<?php
|
|
|
|
|
853 |
<div class="ui-sortable meta-box-sortables">
|
854 |
<div class="postbox">
|
855 |
<h3><?php _e( 'Monitor Rate Limiting', 'wp-to-twitter' ); ?></h3>
|
856 |
|
857 |
-
<div class="inside server">
|
858 |
<?php echo wpt_view_rate_limits(); ?>
|
859 |
</div>
|
860 |
</div>
|
861 |
-
</div>
|
862 |
-
<?php
|
|
|
|
|
863 |
</div>
|
864 |
<?php
|
865 |
}
|
866 |
|
|
|
|
|
|
|
|
|
|
|
867 |
function wpt_do_server_check( $test = false ) {
|
868 |
$wpt_server_string = get_option( 'wpt_server_string' );
|
869 |
-
if (
|
870 |
$server_time = date( DATE_COOKIE );
|
871 |
-
$response = wp_remote_get(
|
872 |
-
|
|
|
|
|
|
|
873 |
if ( is_wp_error( $response ) ) {
|
874 |
$warning = '';
|
875 |
$error = $response->errors;
|
876 |
if ( is_array( $error ) ) {
|
877 |
-
$warning =
|
878 |
foreach ( $error as $k => $e ) {
|
879 |
foreach ( $e as $v ) {
|
880 |
-
$warning .=
|
881 |
}
|
882 |
}
|
883 |
-
$warning .=
|
884 |
}
|
885 |
-
$errors =
|
886 |
} else {
|
887 |
$date = date( DATE_COOKIE, strtotime( $response['headers']['date'] ) );
|
888 |
$errors = '';
|
@@ -896,21 +932,21 @@ function wpt_do_server_check( $test = false ) {
|
|
896 |
}
|
897 |
$diff = "<li>$diff</li>";
|
898 |
} else {
|
899 |
-
$diff =
|
900 |
}
|
901 |
|
902 |
$timezone = '<li>' . __( 'Your server timezone:', 'wp-to-twitter' ) . ' ' . date_default_timezone_get() . '</li>';
|
903 |
|
904 |
-
$search
|
905 |
$replace = array( 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun' );
|
906 |
-
|
907 |
$server_time = str_replace( $search, $replace, $server_time );
|
908 |
-
$date
|
909 |
-
|
910 |
$wpt_server_string =
|
911 |
-
|
912 |
-
<li>
|
913 |
-
|
914 |
$timezone
|
915 |
$diff
|
916 |
$errors
|
@@ -918,26 +954,31 @@ function wpt_do_server_check( $test = false ) {
|
|
918 |
update_option( 'wpt_server_string', $wpt_server_string );
|
919 |
}
|
920 |
echo $wpt_server_string;
|
921 |
-
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro&refresh_wpt_server_string=true' );
|
922 |
-
|
923 |
-
echo "<p><a href='" . $admin_url . "'>" . __( 'Test again', 'wp-to-twitter' ) . "</a></p>";
|
924 |
}
|
925 |
|
926 |
add_filter( 'wpt_tweet_length', 'wpt_tweet_length' );
|
|
|
|
|
|
|
|
|
|
|
927 |
function wpt_tweet_length() {
|
928 |
$tweet_length = intval( ( get_option( 'wpt_tweet_length' ) ) ? get_option( 'wpt_tweet_length' ) : 140 );
|
929 |
-
$control
|
930 |
<label for='wpt_tweet_length'>" . __( 'Tweet Length (max 280 characters)', 'wp-to-twitter' ) . "</label>
|
931 |
-
<input type='number' min='0' max='280' step='1' value='$tweet_length' id='wpt_tweet_length' name='wpt_tweet_length' />
|
932 |
-
<a href='https://www.joedolson.com/2017/11/twitter-expands-280-characters-sort/'>" . __( 'About this setting', 'wp-to-twitter' ) .
|
933 |
-
</p>
|
934 |
-
|
935 |
return $control;
|
936 |
}
|
937 |
|
938 |
add_filter( 'wpt_settings', 'wpt_set_tweet_length' );
|
|
|
|
|
|
|
939 |
function wpt_set_tweet_length() {
|
940 |
if ( isset( $_POST['wpt_tweet_length'] ) ) {
|
941 |
update_option( 'wpt_tweet_length', intval( $_POST['wpt_tweet_length'] ) );
|
942 |
}
|
943 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP to Twitter Settings page
|
4 |
+
*
|
5 |
+
* @category Settings
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Update WP to Twitter settings.
|
18 |
+
*/
|
19 |
function wpt_updated_settings() {
|
20 |
wpt_check_version();
|
21 |
+
|
22 |
if ( empty( $_POST ) ) {
|
23 |
return;
|
24 |
}
|
25 |
+
|
26 |
$nonce = $_REQUEST['_wpnonce'];
|
27 |
if ( ! wp_verify_nonce( $nonce, 'wp-to-twitter-nonce' ) ) {
|
28 |
+
die( 'Security check failed' );
|
29 |
}
|
30 |
|
31 |
if ( isset( $_POST['oauth_settings'] ) ) {
|
34 |
$oauth_message = '';
|
35 |
}
|
36 |
|
37 |
+
$message = '';
|
38 |
|
39 |
+
// notifications from oauth connection.
|
40 |
if ( isset( $_POST['oauth_settings'] ) ) {
|
41 |
+
if ( 'success' == $oauth_message ) {
|
42 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro?tab=basic' );
|
43 |
|
44 |
print( '
|
46 |
<p>' . __( 'WP to Twitter is now connected with Twitter.', 'wp-to-twitter' ) . " <a href='$admin_url'>" . __( 'Configure your Tweet templates', 'wp-to-twitter' ) . '</a></p>
|
47 |
</div>
|
48 |
' );
|
49 |
+
} elseif ( 'failed' == $oauth_message ) {
|
50 |
print( '
|
51 |
<div id="message" class="error fade">
|
52 |
<p>' . __( 'WP to Twitter failed to connect with Twitter.', 'wp-to-twitter' ) . ' <strong>' . __( 'Error:', 'wp-to-twitter' ) . '</strong> ' . get_option( 'wpt_error' ) . '</p>
|
53 |
</div>
|
54 |
' );
|
55 |
+
} elseif ( 'cleared' == $oauth_message ) {
|
56 |
print( '
|
57 |
<div id="message" class="updated fade">
|
58 |
<p>' . __( 'OAuth Authentication Data Cleared.', 'wp-to-twitter' ) . '</p>
|
59 |
</div>
|
60 |
' );
|
61 |
+
} elseif ( 'nosync' == $oauth_message ) {
|
62 |
print( '
|
63 |
<div id="message" class="error fade">
|
64 |
<p>' . __( 'OAuth Authentication Failed. Your server time is not in sync with the Twitter servers. Talk to your hosting service to see what can be done.', 'wp-to-twitter' ) . '</p>
|
68 |
print( '
|
69 |
<div id="message" class="error fade">
|
70 |
<p>' . __( 'OAuth Authentication response not understood.', 'wp-to-twitter' ) . '</p>
|
71 |
+
</div>
|
72 |
' );
|
73 |
}
|
74 |
}
|
75 |
|
76 |
+
if ( isset( $_POST['submit-type'] ) && 'advanced' == $_POST['submit-type'] ) {
|
77 |
update_option( 'jd_tweet_default', ( isset( $_POST['jd_tweet_default'] ) ) ? $_POST['jd_tweet_default'] : 0 );
|
78 |
update_option( 'jd_tweet_default_edit', ( isset( $_POST['jd_tweet_default_edit'] ) ) ? $_POST['jd_tweet_default_edit'] : 0 );
|
79 |
+
|
80 |
+
if ( isset( $_POST['wpt_rate_limiting'] ) && 1 != get_option( 'wpt_rate_limiting' ) ) {
|
81 |
$extend = __( 'Rate Limiting is enabled. Default rate limits are set at 10 posts per category/term per hour. <a href="#special_cases">Edit global default</a> or edit individual terms to customize limits for each category or taxonomy term.', 'wp-to-twitter' );
|
82 |
+
wp_schedule_event( current_time( 'timestamp' ) + 3600, 'hourly', 'wptratelimits' );
|
83 |
} else {
|
84 |
$extend = '';
|
85 |
wp_clear_scheduled_hook( 'wptratelimits' );
|
86 |
+
}
|
87 |
+
|
88 |
update_option( 'wpt_rate_limiting', ( isset( $_POST['wpt_rate_limiting'] ) ) ? 1 : 0 );
|
89 |
update_option( 'wpt_inline_edits', ( isset( $_POST['wpt_inline_edits'] ) ) ? $_POST['wpt_inline_edits'] : 0 );
|
90 |
update_option( 'jd_twit_remote', ( isset( $_POST['jd_twit_remote'] ) ) ? $_POST['jd_twit_remote'] : 0 );
|
95 |
update_option( 'jd_twit_append', $_POST['jd_twit_append'] );
|
96 |
update_option( 'jd_post_excerpt', $_POST['jd_post_excerpt'] );
|
97 |
update_option( 'jd_max_tags', $_POST['jd_max_tags'] );
|
98 |
+
$use_cats = ( isset( $_POST['wpt_use_cats'] ) ) ? $_POST['wpt_use_cats'] : 0;
|
99 |
update_option( 'wpt_use_cats', $use_cats );
|
100 |
+
update_option( 'wpt_tag_source', ( ( isset( $_POST['wpt_tag_source'] ) && 'slug' == $_POST['wpt_tag_source'] ) ? 'slug' : '' ) );
|
101 |
update_option( 'jd_max_characters', $_POST['jd_max_characters'] );
|
102 |
update_option( 'jd_replace_character', $_POST['jd_replace_character'] );
|
103 |
update_option( 'jd_date_format', $_POST['jd_date_format'] );
|
104 |
update_option( 'jd_dynamic_analytics', $_POST['jd-dynamic-analytics'] );
|
105 |
|
106 |
$twitter_analytics = ( isset( $_POST['twitter-analytics'] ) ) ? $_POST['twitter-analytics'] : 0;
|
107 |
+
if ( 1 == $twitter_analytics ) {
|
108 |
update_option( 'use_dynamic_analytics', 0 );
|
109 |
update_option( 'use-twitter-analytics', 1 );
|
110 |
update_option( 'no-analytics', 0 );
|
111 |
+
} elseif ( 2 == $twitter_analytics ) {
|
112 |
update_option( 'use_dynamic_analytics', 1 );
|
113 |
update_option( 'use-twitter-analytics', 0 );
|
114 |
update_option( 'no-analytics', 0 );
|
121 |
update_option( 'twitter-analytics-campaign', $_POST['twitter-analytics-campaign'] );
|
122 |
update_option( 'jd_individual_twitter_users', ( isset( $_POST['jd_individual_twitter_users'] ) ? $_POST['jd_individual_twitter_users'] : 0 ) );
|
123 |
|
|
|
124 |
if ( isset( $_POST['wpt_caps'] ) ) {
|
125 |
$perms = $_POST['wpt_caps'];
|
126 |
+
$caps = array( 'wpt_twitter_oauth', 'wpt_twitter_custom', 'wpt_twitter_switch', 'wpt_can_tweet', 'wpt_tweet_now' );
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
foreach ( $perms as $key => $value ) {
|
128 |
$role = get_role( $key );
|
129 |
if ( is_object( $role ) ) {
|
146 |
$message .= __( 'WP to Twitter Advanced Options Updated', 'wp-to-twitter' ) . '. ' . $extend;
|
147 |
}
|
148 |
|
149 |
+
if ( isset( $_POST['submit-type'] ) && 'options' == $_POST['submit-type'] ) {
|
150 |
+
// UPDATE OPTIONS.
|
151 |
$wpt_settings = get_option( 'wpt_post_types' );
|
152 |
+
if ( ! is_array( $wpt_settings ) ) {
|
153 |
$wpt_settings = array();
|
154 |
}
|
155 |
|
156 |
$keys = array();
|
157 |
$values = array();
|
158 |
foreach ( $_POST['wpt_post_types'] as $key => $value ) {
|
159 |
+
// using wp_encode_emoji allows me to save emoji in templates.
|
160 |
+
// ...but I haven't found a way to convert the saved emoji *back* to unicode.
|
161 |
// sending the HTML entity just yields a broken character on Twitter.
|
162 |
$array = array(
|
163 |
+
'post-published-update' => ( isset( $value['post-published-update'] ) ) ? $value['post-published-update'] : '',
|
164 |
+
'post-published-text' => $value['post-published-text'],
|
165 |
+
'post-edited-update' => ( isset( $value['post-edited-update'] ) ) ? $value['post-edited-update'] : '',
|
166 |
+
'post-edited-text' => $value['post-edited-text'],
|
167 |
);
|
168 |
+
array_push( $keys, $key );
|
169 |
array_push( $values, $array );
|
170 |
}
|
171 |
+
|
172 |
$wpt_settings = array_combine( $keys, $values );
|
173 |
update_option( 'wpt_post_types', $wpt_settings );
|
174 |
update_option( 'newlink-published-text', $_POST['newlink-published-text'] );
|
175 |
+
update_option( 'jd_twit_blogroll', ( isset( $_POST['jd_twit_blogroll'] ) ) ? $_POST['jd_twit_blogroll'] : '' );
|
176 |
$message = wpt_select_shortener( $_POST );
|
177 |
$message .= __( 'WP to Twitter Options Updated', 'wp-to-twitter' );
|
178 |
$message = apply_filters( 'wpt_settings', $message, $_POST );
|
179 |
}
|
180 |
|
181 |
+
if ( isset( $_POST['wpt_shortener_update'] ) && 'true' == $_POST['wpt_shortener_update'] ) {
|
182 |
$message = wpt_shortener_update( $_POST );
|
183 |
}
|
184 |
|
185 |
// Check whether the server has supported for needed functions.
|
186 |
+
if ( isset( $_POST['submit-type'] ) && 'check-support' == $_POST['submit-type'] ) {
|
187 |
$message = wpt_check_functions();
|
188 |
}
|
189 |
|
192 |
}
|
193 |
}
|
194 |
|
195 |
+
/**
|
196 |
+
* Show WP to Twitter settings form.
|
197 |
+
*/
|
198 |
function wpt_update_settings() {
|
199 |
?>
|
200 |
<div class="wrap" id="wp-to-twitter">
|
201 |
+
<?php
|
202 |
+
if ( defined( 'WPT_STAGING_MODE' ) && true == WPT_STAGING_MODE ) {
|
203 |
+
echo "<div class='updated notice'><p>" . __( 'WP to Twitter is in staging mode. Tweets will be reported as if successfully sent to Twitter but will not be sent.', 'wp-to-twitter' ) . '</p></div>';
|
204 |
+
}
|
205 |
+
wpt_updated_settings();
|
206 |
+
wpt_show_last_tweet();
|
207 |
+
wpt_handle_errors();
|
208 |
?>
|
209 |
+
<h1><?php _e( 'WP to Twitter Options', 'wp-to-twitter' ); ?></h1>
|
210 |
+
|
|
|
211 |
<?php wpt_max_length(); ?>
|
212 |
+
|
213 |
<div class='nav-tab-wrapper'>
|
214 |
<?php wpt_settings_tabs(); ?>
|
215 |
</div>
|
216 |
<div id="wpt_settings_page" class="postbox-container jcd-wide">
|
217 |
<div class="metabox-holder">
|
218 |
|
219 |
+
<?php
|
220 |
+
$default = ( '' == get_option( 'wtt_twitter_username' ) ) ? 'connection' : 'basic';
|
221 |
$current = ( isset( $_GET['tab'] ) ) ? $_GET['tab'] : $default;
|
222 |
+
if ( 'connection' == $current ) {
|
223 |
if ( function_exists( 'wtt_connect_oauth' ) ) {
|
224 |
wtt_connect_oauth();
|
225 |
}
|
226 |
}
|
227 |
+
if ( 'pro' == $current ) {
|
228 |
if ( function_exists( 'wpt_pro_functions' ) ) {
|
229 |
wpt_pro_functions();
|
230 |
if ( function_exists( 'wpt_notes' ) ) {
|
231 |
wpt_notes();
|
232 |
}
|
233 |
} else {
|
234 |
+
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
235 |
+
?>
|
236 |
<div class="ui-sortable meta-box-sortables">
|
237 |
<div class="postbox">
|
238 |
<h3 class='wpt-upgrade'><span><strong><?php _e( 'Upgrade Now!', 'wp-to-twitter' ); ?></strong></span></h3>
|
240 |
<div class="inside purchase">
|
241 |
<h4><strong><?php _e( 'What can WP Tweets PRO do for you?', 'wp-to-twitter' ); ?></strong></h4>
|
242 |
<p>
|
243 |
+
<?php _e( 'WP Tweets PRO takes the great Tweeting abilities from WP to Twitter and puts them in high gear.', 'wp-to-twitter' ); ?>
|
|
|
|
|
244 |
</p>
|
245 |
<ul>
|
246 |
+
<li><?php _e( 'Publish to unique Twitter accounts for each site author.', 'wp-to-twitter' ); ?></li>
|
247 |
<li><?php _e( 'Schedule up to 3 re-posts of Tweets at an interval of your choice.', 'wp-to-twitter' ); ?></li>
|
248 |
<li><?php _e( 'With a delay between publishing and Tweeting, verify your tweets before you share online.', 'wp-to-twitter' ); ?></li>
|
249 |
<li><?php _e( 'Automatically your great old posts every few hours, days, or weeks!', 'wp-to-twitter' ); ?></li>
|
250 |
<li><?php _e( 'Upload your featured images to Twitter with each Tweet', 'wp-to-twitter' ); ?></li>
|
251 |
+
<li>
|
252 |
+
<?php
|
253 |
+
// Translators: Link to sales page.
|
254 |
+
printf( __( 'Take a look at the <a href="%s">complete feature list</a>', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro/' );
|
255 |
+
?>
|
256 |
+
</li>
|
257 |
</ul>
|
258 |
<p>
|
259 |
+
<strong><?php _e( 'Use WP Tweets PRO to keep traffic coming for every post.', 'wp-to-twitter' ); ?></strong>
|
260 |
</p>
|
261 |
<p class='wpt-button'>
|
262 |
<strong class='cta'><a href="http://www.wptweetspro.com/wp-tweets-pro"><?php _e( 'Upgrade to <strong>WP Tweets PRO</strong>!', 'wp-to-twitter' ); ?></a></strong>
|
263 |
+
</p>
|
264 |
+
|
265 |
<h4><?php _e( 'What else does WP Tweets PRO do?', 'wp-to-twitter' ); ?></h4>
|
266 |
+
|
267 |
<p>
|
268 |
<?php _e( 'WP Tweets PRO is packed with features to help you increase engagement with your Twitter followers. Upload images, use Twitter Cards, and automated re-posting of your Tweets are just a few of the features available in the premium add-on to WP to Twitter.', 'wp-to-twitter' ); ?>
|
269 |
</p>
|
270 |
<p>
|
271 |
+
<?php
|
272 |
+
// Translators: link to GitHub repo of add-ons.
|
273 |
+
printf( __( 'Is there something that WP Tweets PRO <em>doesn\'t already do for you</em>? No problem! Take a look at the extensive <a href="%s">library of plug-in extensions</a> - you can try out or modify any of these code samples to extend and customize WP Tweets PRO.', 'wp-to-twitter' ), 'https://github.com/joedolson/plugin-extensions/tree/master/wp-to-twitter' );
|
274 |
+
?>
|
275 |
</p>
|
276 |
<p>
|
277 |
+
<?php
|
278 |
+
// Translators: Link to sales page.
|
279 |
+
printf( __( '<a href="%s">Learn more about WP Tweets PRO</a>!', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro?campaign=get-wpt' );
|
280 |
+
?>
|
281 |
</p>
|
282 |
+
|
283 |
<p class='wpt-button'>
|
284 |
<strong class='cta'><a href="http://www.wptweetspro.com/wp-tweets-pro"><?php _e( 'Buy WP Tweets PRO today!', 'wp-to-twitter' ); ?></a></strong>
|
285 |
</p>
|
|
|
286 |
</div>
|
287 |
</div>
|
288 |
</div>
|
290 |
}
|
291 |
}
|
292 |
}
|
293 |
+
if ( 'basic' == $current ) {
|
294 |
?>
|
295 |
<div class="ui-sortable meta-box-sortables">
|
296 |
<div class="postbox">
|
298 |
|
299 |
<div class="inside wpt-settings">
|
300 |
<form method="post" action="">
|
301 |
+
<?php
|
302 |
+
$nonce = wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false );
|
303 |
+
echo "<div>$nonce</div>";
|
304 |
+
?>
|
305 |
<div>
|
|
|
|
|
306 |
<?php
|
307 |
+
echo apply_filters( 'wpt_tweet_length', '' );
|
308 |
+
echo apply_filters( 'wpt_pick_shortener', '' );
|
309 |
$post_types = get_post_types( array( 'public' => true ), 'objects' );
|
310 |
$wpt_settings = get_option( 'wpt_post_types' );
|
311 |
$tabs = "<ul class='tabs' role='tablist'>";
|
312 |
foreach ( $post_types as $type ) {
|
313 |
+
$name = $type->labels->name;
|
314 |
+
$slug = $type->name;
|
315 |
+
if ( 'attachment' == $slug || 'nav_menu_item' == $slug || 'revision' == $slug ) {
|
316 |
} else {
|
317 |
$tabs .= "<li><a href='#wpt_$slug' role='tab' id='tab_wpt_$slug' aria-controls='wpt_$slug'>$name</a></li>";
|
318 |
}
|
319 |
}
|
320 |
+
$tabs .= "<li><a href='#wpt_links' id='tab_wpt_links' aria-controls='wpt_links'>" . __( 'Links', 'wp-to-twitter' ) . '</a></li></ul>';
|
|
|
321 |
echo $tabs;
|
322 |
foreach ( $post_types as $type ) {
|
323 |
+
$name = $type->labels->name;
|
324 |
+
$slug = $type->name;
|
325 |
+
if ( 'attachment' == $slug || 'nav_menu_item' == $slug || 'revision' == $slug ) {
|
|
|
326 |
continue;
|
327 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
?>
|
|
|
329 |
<div class='wptab wpt_types wpt_<?php echo $slug; ?>' aria-labelledby='tab_wpt_<?php echo $slug; ?>' role="tabpanel" id='wpt_<?php echo $slug; ?>'>
|
330 |
+
<?php
|
331 |
+
// share information about any usage of pre 2.8 category filters.
|
332 |
+
if ( '0' != get_option( 'limit_categories' ) && 'post' == $slug ) {
|
333 |
+
$falseness = get_option( 'jd_twit_cats' );
|
334 |
+
$categories = get_option( 'tweet_categories' );
|
335 |
+
if ( 1 == $falseness ) {
|
336 |
+
echo '<p>' . __( 'These categories are currently <strong>excluded</strong> by the deprecated WP to Twitter category filters.', 'wp-to-twitter' ) . '</p>';
|
337 |
+
} else {
|
338 |
+
echo '<p>' . __( 'These categories are currently <strong>allowed</strong> by the deprecated WP to Twitter category filters.', 'wp-to-twitter' ) . '</p>';
|
339 |
+
}
|
340 |
+
echo '<ul>';
|
341 |
+
if ( is_array( $categories ) ) {
|
342 |
+
foreach ( $categories as $cat ) {
|
343 |
+
$category = get_the_category_by_ID( $cat );
|
344 |
+
echo "<li>$category</li>";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
345 |
}
|
346 |
}
|
347 |
+
echo '</ul>';
|
348 |
+
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
349 |
+
// Translators: Link to sales page.
|
350 |
+
printf( __( '<a href="%s">Upgrade to WP Tweets PRO</a> to filter posts in all custom post types on any taxonomy.', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro' );
|
351 |
+
} else {
|
352 |
+
_e( 'Updating the WP Tweets PRO taxonomy filters will overwrite your old category filters.', 'wp-to-twitter' );
|
353 |
+
}
|
354 |
+
}
|
355 |
+
?>
|
356 |
+
<fieldset>
|
357 |
+
<legend><?php _e( 'Tweet Templates', 'wp-to-twitter' ); ?></legend>
|
358 |
+
<p>
|
359 |
+
<input type="checkbox" name="wpt_post_types[<?php echo $slug; ?>][post-published-update]" id="<?php echo $slug; ?>-post-published-update" value="1" <?php echo wpt_checkbox( 'wpt_post_types', $slug, 'post-published-update' ); ?> />
|
360 |
+
<label for="<?php echo $slug; ?>-post-published-update"><strong>
|
361 |
+
<?php
|
362 |
+
// Translators: post type.
|
363 |
+
printf( __( 'Update when %s are published', 'wp-to-twitter' ), $name );
|
364 |
+
?>
|
365 |
+
</strong></label>
|
366 |
+
<label for="<?php echo $slug; ?>-post-published-text"><br/>
|
367 |
+
<?php
|
368 |
+
// Translators: post type.
|
369 |
+
printf( __( 'Template for new %s', 'wp-to-twitter' ), $name );
|
370 |
+
?>
|
371 |
+
</label><br/>
|
372 |
+
<textarea class="wpt-template" name="wpt_post_types[<?php echo $slug; ?>][post-published-text]" id="<?php echo $slug; ?>-post-published-text" cols="60" rows="3"><?php echo ( isset( $wpt_settings[ $slug ] ) ) ? esc_attr( stripslashes( $wpt_settings[ $slug ]['post-published-text'] ) ) : ''; ?></textarea>
|
373 |
+
</p>
|
374 |
+
|
375 |
+
<p>
|
376 |
+
<input type="checkbox" name="wpt_post_types[<?php echo $slug; ?>][post-edited-update]" id="<?php echo $slug; ?>-post-edited-update" value="1" <?php echo wpt_checkbox( 'wpt_post_types', $slug, 'post-edited-update' ); ?> />
|
377 |
+
<label for="<?php echo $slug; ?>-post-edited-update"><strong>
|
378 |
+
<?php
|
379 |
+
// Translators: post type name.
|
380 |
+
printf( __( 'Update when %s are edited', 'wp-to-twitter' ), $name );
|
381 |
+
?>
|
382 |
+
</strong></label><br/><label for="<?php echo $slug; ?>-post-edited-text">
|
383 |
+
<?php
|
384 |
+
// Translators: post type name.
|
385 |
+
printf( __( 'Template for %1$s edits', 'wp-to-twitter' ), $name );
|
386 |
+
?>
|
387 |
+
</label><br/>
|
388 |
+
<textarea class="wpt-template" name="wpt_post_types[<?php echo $slug; ?>][post-edited-text]" id="<?php echo $slug; ?>-post-edited-text" cols="60" rows="3"><?php echo ( isset( $wpt_settings[ $slug ] ) ) ? esc_attr( stripslashes( $wpt_settings[ $slug ]['post-edited-text'] ) ) : ''; ?></textarea>
|
389 |
+
</p>
|
390 |
+
</fieldset>
|
391 |
+
<?php
|
392 |
+
if ( function_exists( 'wpt_list_terms' ) ) {
|
393 |
+
wpt_list_terms( $slug, $name );
|
394 |
+
}
|
395 |
+
?>
|
396 |
</div>
|
397 |
<?php
|
398 |
}
|
402 |
<fieldset>
|
403 |
<legend><span><?php _e( 'Links', 'wp-to-twitter' ); ?></span></legend>
|
404 |
<p>
|
405 |
+
<input type="checkbox" name="jd_twit_blogroll" id="jd_twit_blogroll" value="1" <?php echo wpt_checkbox( 'jd_twit_blogroll' ); ?> />
|
406 |
+
<label for="jd_twit_blogroll"><strong><?php _e( 'Update Twitter when you post a Blogroll link', 'wp-to-twitter' ); ?></strong></label><br/>
|
407 |
+
<label for="newlink-published-text"><?php _e( 'Text for new link updates:', 'wp-to-twitter' ); ?></label>
|
408 |
+
<input aria-describedby="newlink-published-text-label" type="text" class="wpt-template" name="newlink-published-text" id="newlink-published-text" size="60" maxlength="120" value="<?php echo esc_attr( stripslashes( get_option( 'newlink-published-text' ) ) ); ?>"/><br/><span id="newlink-published-text-label"><?php _e( 'Available shortcodes: <code>#url#</code>, <code>#title#</code>, and <code>#description#</code>.', 'wp-to-twitter' ); ?></span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
</p>
|
410 |
</fieldset>
|
411 |
</div>
|
412 |
<div>
|
413 |
<input type="hidden" name="submit-type" value="options" />
|
414 |
</div>
|
415 |
+
<input type="submit" name="submit" value="<?php _e( 'Save WP to Twitter Options', 'wp-to-twitter' ); ?>" class="button-primary" />
|
416 |
</div>
|
417 |
</form>
|
418 |
</div>
|
419 |
</div>
|
420 |
</div>
|
421 |
+
|
422 |
<div class="ui-sortable meta-box-sortables">
|
423 |
<div class="postbox">
|
424 |
<h3><span><?php _e( 'Tweet Template Tags', 'wp-to-twitter' ); ?></span></h3>
|
|
|
425 |
<div class="inside">
|
426 |
<ul>
|
427 |
+
<li><?php _e( '<code>#title#</code>: the title of your blog post', 'wp-to-twitter' ); ?></li>
|
428 |
+
<li><?php _e( '<code>#blog#</code>: the title of your blog', 'wp-to-twitter' ); ?></li>
|
429 |
+
<li><?php _e( '<code>#post#</code>: a short excerpt of the post content', 'wp-to-twitter' ); ?></li>
|
430 |
+
<li><?php _e( '<code>#category#</code>: the first selected category for the post', 'wp-to-twitter' ); ?></li>
|
431 |
+
<li><?php _e( '<code>#cat_desc#</code>: custom value from the category description field', 'wp-to-twitter' ); ?></li>
|
432 |
+
<li><?php _e( '<code>#date#</code>: the post date', 'wp-to-twitter' ); ?></li>
|
433 |
+
<li><?php _e( '<code>#modified#</code>: the post modified date', 'wp-to-twitter' ); ?></li>
|
434 |
+
<li><?php _e( '<code>#url#</code>: the post URL', 'wp-to-twitter' ); ?></li>
|
435 |
+
<li><?php _e( '<code>#longurl#</code>: the unshortened post URL', 'wp-to-twitter' ); ?></li>
|
436 |
+
<li><?php _e( '<code>#author#</code>: the post author (@reference if available, otherwise display name)', 'wp-to-twitter' ); ?></li>
|
437 |
+
<li><?php _e( '<code>#displayname#</code>: post author\'s display name', 'wp-to-twitter' ); ?></li>
|
438 |
+
<li><?php _e( '<code>#account#</code>: the twitter @reference for the account (or the author, if author settings are enabled and set.)', 'wp-to-twitter' ); ?></li>
|
439 |
+
<li><?php _e( '<code>#@#</code>: the twitter @reference for the author or blank, if not set', 'wp-to-twitter' ); ?></li>
|
440 |
+
<li><?php _e( '<code>#tags#</code>: your tags modified into hashtags.', 'wp-to-twitter' ); ?></li>
|
441 |
+
<?php
|
442 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() ) {
|
443 |
+
?>
|
444 |
+
<li><?php _e( '<code>#reference#</code>: Used only in co-tweeting. @reference to main account when posted to author account, @reference to author account in post to main account.', 'wp-to-twitter' ); ?></li>
|
445 |
+
<?php
|
446 |
+
}
|
447 |
+
?>
|
448 |
</ul>
|
449 |
<p>
|
450 |
+
<?php _e( 'Create custom shortcodes and access WordPress custom fields by using square brackets and the name of your custom field.', 'wp-to-twitter' ); ?>
|
|
|
|
|
451 |
<br />
|
452 |
+
<?php _e( '<strong>Example:</strong> <code>[[custom_field]]</code>', 'wp-to-twitter' ); ?>
|
|
|
|
|
453 |
</p>
|
454 |
<p>
|
455 |
+
<?php _e( 'Create custom shortcodes and access the post author\'s custom user meta fields by using curly brackets and the name of the custom field.', 'wp-to-twitter' ); ?>
|
|
|
|
|
456 |
<br />
|
457 |
+
<?php _e( '<strong>Example:</strong> <code>{{user_meta}}</code>', 'wp-to-twitter' ); ?>
|
458 |
+
</p>
|
|
|
|
|
459 |
</div>
|
460 |
</div>
|
461 |
+
</div>
|
462 |
+
<?php
|
463 |
+
}
|
464 |
+
if ( 'shortener' == $current ) {
|
465 |
+
echo apply_filters( 'wpt_shortener_controls', '' );
|
466 |
}
|
467 |
+
|
468 |
+
if ( 'advanced' == $current ) {
|
469 |
?>
|
470 |
+
<form method="post" action="">
|
471 |
<div class="ui-sortable meta-box-sortables">
|
472 |
<div class="postbox">
|
473 |
<h3><span><?php _e( 'Advanced Settings', 'wp-to-twitter' ); ?></span></h3>
|
474 |
<div class="inside">
|
|
|
475 |
<div>
|
476 |
+
<?php
|
477 |
$nonce = wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false );
|
478 |
+
echo "<div>$nonce</div>";
|
479 |
?>
|
480 |
|
481 |
<fieldset>
|
482 |
+
<legend class='screen-reader-text'><?php _e( 'Hashtags', 'wp-to-twitter' ); ?></legend>
|
483 |
<p>
|
484 |
+
<input type="checkbox" name="jd_strip_nonan" id="jd_strip_nonan" value="1" <?php echo checked( get_option( 'jd_strip_nonan' ), 1 ); ?> /> <label for="jd_strip_nonan"><?php _e( 'Strip nonalphanumeric characters from tags', 'wp-to-twitter' ); ?></label>
|
|
|
|
|
485 |
</p>
|
|
|
486 |
<p>
|
487 |
+
<input type="checkbox" name="wpt_tag_source" id="wpt_tag_source" value="slug" <?php checked( get_option( 'wpt_tag_source' ), 'slug' ); ?> />
|
488 |
+
<label for="wpt_tag_source"><?php _e( 'Use tag slug as hashtag value', 'wp-to-twitter' ); ?></label><br/>
|
|
|
|
|
489 |
</p>
|
490 |
+
<p>
|
491 |
<input type="checkbox" name="wpt_use_cats" id="wpt_use_cats" value="1" <?php checked( get_option( 'wpt_use_cats' ), '1' ); ?> />
|
492 |
+
<label for="wpt_use_cats"><?php _e( 'Use categories instead of tags', 'wp-to-twitter' ); ?></label><br/>
|
493 |
</p>
|
494 |
<p>
|
495 |
+
<label for="jd_replace_character"><?php _e( 'Spaces in tags replaced with:', 'wp-to-twitter' ); ?></label>
|
496 |
+
<input type="text" name="jd_replace_character" id="jd_replace_character" value="<?php echo esc_attr( get_option( 'jd_replace_character' ) ); ?>" size="3"/>
|
|
|
|
|
|
|
497 |
</p>
|
498 |
|
499 |
<p>
|
500 |
+
<label for="jd_max_tags"><?php _e( 'Maximum number of tags to include:', 'wp-to-twitter' ); ?></label>
|
501 |
+
<input aria-describedby="jd_max_characters_label" type="text" name="jd_max_tags" id="jd_max_tags" value="<?php echo esc_attr( get_option( 'jd_max_tags' ) ); ?>" size="3"/>
|
|
|
|
|
|
|
502 |
</p>
|
503 |
<p>
|
504 |
+
<label for="jd_max_characters"><?php _e( 'Maximum length in characters for included tags:', 'wp-to-twitter' ); ?></label>
|
505 |
+
<input type="text" name="jd_max_characters" id="jd_max_characters" value="<?php echo esc_attr( get_option( 'jd_max_characters' ) ); ?>" size="3"/>
|
|
|
|
|
506 |
</p>
|
507 |
</fieldset>
|
508 |
+
</div>
|
509 |
+
</div>
|
510 |
+
</div>
|
511 |
+
<div class="ui-sortable meta-box-sortables">
|
512 |
+
<div class="postbox">
|
513 |
+
<h3><span><?php _e( 'Template Settings', 'wp-to-twitter' ); ?></span></h3>
|
514 |
+
<div class="inside">
|
515 |
<fieldset>
|
516 |
+
<legend class='screen-reader-text'><?php _e( 'Template Settings', 'wp-to-twitter' ); ?></legend>
|
517 |
<p>
|
518 |
+
<label for="jd_post_excerpt"><?php _e( 'Post excerpt (#post#) in characters:', 'wp-to-twitter' ); ?></label>
|
519 |
+
<input type="text" name="jd_post_excerpt" id="jd_post_excerpt" size="3" maxlength="3" value="<?php echo( esc_attr( get_option( 'jd_post_excerpt' ) ) ); ?>"/>
|
|
|
520 |
</p>
|
|
|
521 |
<p>
|
522 |
+
<label for="jd_date_format"><?php _e( 'Date Format (#date#):', 'wp-to-twitter' ); ?></label>
|
523 |
+
<input type="text" aria-describedby="date_format_label" name="jd_date_format" id="jd_date_format" size="12" maxlength="12" value="
|
524 |
+
<?php
|
525 |
+
if ( '' == get_option( 'jd_date_format' ) ) {
|
526 |
+
echo( esc_attr( stripslashes( get_option( 'date_format' ) ) ) );
|
527 |
+
} else {
|
528 |
+
echo( esc_attr( get_option( 'jd_date_format' ) ) );
|
529 |
+
}
|
530 |
+
?>
|
531 |
+
"/>
|
532 |
+
<?php
|
533 |
+
if ( '' != get_option( 'jd_date_format' ) ) {
|
534 |
echo date_i18n( get_option( 'jd_date_format' ) );
|
535 |
} else {
|
536 |
+
echo '<em>' . date_i18n( get_option( 'date_format' ) ) . '</em>';
|
537 |
+
}
|
538 |
+
?>
|
539 |
+
(<em id="date_format_label"><a href='http://codex.wordpress.org/Formatting_Date_and_Time'><?php _e( 'Date Formatting', 'wp-to-twitter' ); ?></a></em>)
|
540 |
</p>
|
541 |
|
542 |
<p>
|
543 |
+
<label for="jd_twit_prepend"><?php _e( 'Custom text before Tweets:', 'wp-to-twitter' ); ?></label>
|
544 |
+
<input type="text" name="jd_twit_prepend" id="jd_twit_prepend" size="20" value="<?php echo esc_attr( stripslashes( get_option( 'jd_twit_prepend' ) ) ); ?>"/>
|
|
|
545 |
</p>
|
546 |
<p>
|
547 |
+
<label for="jd_twit_append"><?php _e( 'Custom text after Tweets:', 'wp-to-twitter' ); ?></label>
|
548 |
+
<input type="text" name="jd_twit_append" id="jd_twit_append" size="20" value="<?php echo esc_attr( stripslashes( get_option( 'jd_twit_append' ) ) ); ?>"/>
|
|
|
549 |
</p>
|
550 |
<p>
|
551 |
+
<label for="jd_twit_custom_url"><?php _e( 'Custom field for alternate post URL:', 'wp-to-twitter' ); ?></label>
|
552 |
+
<input type="text" name="jd_twit_custom_url" id="jd_twit_custom_url" size="30" maxlength="120" value="<?php echo esc_attr( stripslashes( get_option( 'jd_twit_custom_url' ) ) ); ?>"/>
|
|
|
553 |
</p>
|
554 |
</fieldset>
|
555 |
+
</div>
|
556 |
+
</div>
|
557 |
+
</div>
|
558 |
+
<div class="ui-sortable meta-box-sortables">
|
559 |
+
<div class="postbox">
|
560 |
+
<h3><span><?php _e( 'Special Cases', 'wp-to-twitter' ); ?></span></h3>
|
561 |
+
<div class="inside">
|
562 |
<fieldset>
|
563 |
+
<legend id="special_cases" class='screen-reader-text'><?php _e( 'Special Cases', 'wp-to-twitter' ); ?></legend>
|
564 |
<p>
|
565 |
+
<input type="checkbox" name="jd_tweet_default" id="jd_tweet_default" value="1" <?php echo wpt_checkbox( 'jd_tweet_default' ); ?> />
|
566 |
+
<label for="jd_tweet_default"><?php _e( 'Do not post Tweets by default', 'wp-to-twitter' ); ?></label><br/>
|
567 |
+
<input type="checkbox" name="jd_tweet_default_edit" id="jd_tweet_default_edit" value="1" <?php echo wpt_checkbox( 'jd_tweet_default_edit' ); ?> />
|
568 |
+
<label for="jd_tweet_default_edit"><?php _e( 'Do not post Tweets by default (editing only)', 'wp-to-twitter' ); ?></label><br/>
|
569 |
+
<input type="checkbox" name="wpt_inline_edits" id="wpt_inline_edits" value="1" <?php echo wpt_checkbox( 'wpt_inline_edits' ); ?> />
|
570 |
+
<label for="wpt_inline_edits"><?php _e( 'Allow status updates from Quick Edit', 'wp-to-twitter' ); ?></label><br/>
|
571 |
+
<input type="checkbox" name="wpt_rate_limiting" id="wpt_rate_limiting" value="1" <?php echo wpt_checkbox( 'wpt_rate_limiting' ); ?> />
|
572 |
+
<label for="wpt_rate_limiting"><?php _e( 'Enable Rate Limiting', 'wp-to-twitter' ); ?></label><br/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
<?php
|
574 |
if ( get_option( 'wpt_rate_limiting' ) == 1 ) {
|
575 |
+
?>
|
576 |
+
<input type="number" name="wpt_default_rate_limit" min="1" id="wpt_default_rate_limit" value="<?php echo wpt_default_rate_limit(); ?>" />
|
577 |
+
<label for="wpt_default_rate_limit"><?php _e( 'Default Rate Limit per category per hour', 'wp-to-twitter' ); ?></label><br/>
|
578 |
+
<?php
|
|
|
|
|
579 |
}
|
580 |
?>
|
581 |
</p>
|
582 |
</fieldset>
|
583 |
+
</div>
|
584 |
+
</div>
|
585 |
+
</div>
|
586 |
+
<div class="ui-sortable meta-box-sortables">
|
587 |
+
<div class="postbox">
|
588 |
+
<h3><span><?php _e( 'Google Analytics Settings', 'wp-to-twitter' ); ?></span></h3>
|
589 |
+
<div class="inside">
|
590 |
<fieldset>
|
591 |
+
<legend class='screen-reader-text'><?php _e( 'Google Analytics Settings', 'wp-to-twitter' ); ?></legend>
|
592 |
|
593 |
<p>
|
594 |
+
<input type="radio" name="twitter-analytics" id="use-twitter-analytics" value="1" <?php echo wpt_checkbox( 'use-twitter-analytics' ); ?> />
|
595 |
+
<label for="use-twitter-analytics"><?php _e( 'Use a Static Identifier', 'wp-to-twitter' ); ?></label><br/>
|
596 |
+
<label for="twitter-analytics-campaign"><?php _e( 'Static Campaign identifier', 'wp-to-twitter' ); ?></label>
|
597 |
+
<input type="text" name="twitter-analytics-campaign" id="twitter-analytics-campaign" size="40" maxlength="120" value="<?php echo esc_attr( get_option( 'twitter-analytics-campaign' ) ); ?>"/><br/>
|
|
|
|
|
|
|
|
|
|
|
598 |
</p>
|
|
|
599 |
<p>
|
600 |
+
<input type="radio" name="twitter-analytics" id="use-dynamic-analytics" value="2" <?php echo wpt_checkbox( 'use_dynamic_analytics' ); ?> />
|
601 |
+
<label for="use-dynamic-analytics"><?php _e( 'Use a dynamic identifier', 'wp-to-twitter' ); ?></label><br/>
|
602 |
+
<label for="jd-dynamic-analytics"><?php _e( 'What dynamic identifier would you like to use?', 'wp-to-twitter' ); ?></label>
|
|
|
|
|
|
|
603 |
<select name="jd-dynamic-analytics" id="jd-dynamic-analytics">
|
604 |
+
<option value="post_category"<?php checked( get_option( 'jd_dynamic_analytics' ), 'post_category' ); ?>><?php _e( 'Category', 'wp-to-twitter' ); ?></option>
|
605 |
+
<option value="post_ID"<?php checked( get_option( 'jd_dynamic_analytics' ), 'post_ID' ); ?>><?php _e( 'Post ID', 'wp-to-twitter' ); ?></option>
|
606 |
+
<option value="post_title"<?php checked( get_option( 'jd_dynamic_analytics' ), 'post_title' ); ?>><?php _e( 'Post Title', 'wp-to-twitter' ); ?></option>
|
607 |
+
<option value="post_author"<?php checked( get_option( 'jd_dynamic_analytics' ), 'post_author' ); ?>><?php _e( 'Author', 'wp-to-twitter' ); ?></option>
|
|
|
|
|
|
|
|
|
608 |
</select><br/>
|
609 |
</p>
|
610 |
<p>
|
611 |
+
<input type="radio" name="twitter-analytics" id="no-analytics" value="3" <?php echo wpt_checkbox( 'no-analytics' ); ?> /> <label for="no-analytics"><?php _e( 'No Analytics', 'wp-to-twitter' ); ?></label>
|
|
|
|
|
612 |
</p>
|
613 |
</fieldset>
|
614 |
+
</div>
|
615 |
+
</div>
|
616 |
+
</div>
|
617 |
+
<div class="ui-sortable meta-box-sortables">
|
618 |
+
<div class="postbox">
|
619 |
+
<h3><span><?php _e( 'Author Settings', 'wp-to-twitter' ); ?></span></h3>
|
620 |
+
<div class="inside">
|
621 |
+
|
622 |
+
<p>
|
623 |
+
<input type="checkbox" name="jd_individual_twitter_users" id="jd_individual_twitter_users" value="1" <?php echo wpt_checkbox( 'jd_individual_twitter_users' ); ?> />
|
624 |
+
<label for="jd_individual_twitter_users"><?php _e( 'Authors have individual Twitter accounts', 'wp-to-twitter' ); ?></label>
|
625 |
+
</p>
|
626 |
|
|
|
627 |
<div class='wpt-permissions'>
|
628 |
<fieldset>
|
629 |
<legend><?php _e( 'Permissions', 'wp-to-twitter' ); ?></legend>
|
630 |
<?php
|
631 |
global $wp_roles;
|
632 |
+
$roles = $wp_roles->get_names();
|
633 |
+
$caps = array(
|
634 |
'wpt_can_tweet' => __( 'Can send Tweets', 'wp-to-twitter' ),
|
635 |
'wpt_twitter_custom' => __( 'See Custom Tweet Field when creating a Post', 'wp-to-twitter' ),
|
636 |
'wpt_twitter_switch' => __( 'Toggle the Tweet/Don\'t Tweet option', 'wp-to-twitter' ),
|
637 |
'wpt_tweet_now' => __( 'Can see Tweet Now button', 'wp-to-twitter' ),
|
638 |
+
'wpt_twitter_oauth' => __( 'Allow user to authenticate with Twitter', 'wp-to-twitter' ),
|
639 |
);
|
640 |
+
$role_tabs = '';
|
641 |
+
$role_container = '';
|
642 |
foreach ( $roles as $role => $rolename ) {
|
643 |
+
if ( 'administrator' == $role ) {
|
644 |
continue;
|
645 |
}
|
646 |
+
$role_tabs .= "<li><a href='#wpt_" . sanitize_title( $role ) . "'>$rolename</a></li>\n";
|
647 |
$role_container .= "<div class='wptab wpt_$role' id='wpt_" . sanitize_title( $role ) . "' aria-live='assertive'><fieldset id='wpt_$role' class='roles'><legend>$rolename</legend>";
|
648 |
$role_container .= "<input type='hidden' value='none' name='wpt_caps[" . $role . "][none]' />
|
649 |
+
<ul class='wpt-settings checkboxes'>";
|
650 |
foreach ( $caps as $cap => $name ) {
|
651 |
$role_container .= wpt_cap_checkbox( $role, $cap, $name );
|
652 |
}
|
653 |
+
$role_container .= '</ul></fieldset></div>';
|
|
|
654 |
}
|
655 |
echo "
|
656 |
<ul class='tabs'>
|
660 |
?>
|
661 |
</fieldset>
|
662 |
</div>
|
663 |
+
</div>
|
664 |
+
</div>
|
665 |
+
</div>
|
666 |
+
<div class="ui-sortable meta-box-sortables">
|
667 |
+
<div class="postbox">
|
668 |
+
<h3><span><?php _e( 'Template tag priority order', 'wp-to-twitter' ); ?></span></h3>
|
669 |
+
<div class="inside">
|
670 |
+
<?php
|
671 |
$inputs = '';
|
672 |
$default_order = array(
|
673 |
'excerpt' => 0,
|
680 |
'tags' => 7,
|
681 |
'modified' => 8,
|
682 |
'@' => 9,
|
683 |
+
'cat_desc' => 10,
|
684 |
);
|
685 |
$preferred_order = get_option( 'wpt_truncation_order' );
|
686 |
if ( ! $preferred_order ) {
|
692 |
}
|
693 |
asort( $default_order );
|
694 |
foreach ( $default_order as $k => $v ) {
|
695 |
+
if ( 'blogname' == $k ) {
|
696 |
+
$label = '<code>#blog#</code>';
|
697 |
+
} elseif ( 'excerpt' == $k ) {
|
698 |
$label = '<code>#post#</code>';
|
699 |
} else {
|
700 |
$label = '<code>#' . $k . '#</code>';
|
703 |
}
|
704 |
?>
|
705 |
<fieldset>
|
706 |
+
<legend class='screen-reader-text'><?php _e( 'Template tag priority order', 'wp-to-twitter' ); ?></legend>
|
|
|
707 |
<p>
|
708 |
+
<?php
|
709 |
+
_e( 'The order in which items will be abbreviated or removed from your Tweet if the Tweet is too long to send to Twitter.', 'wp-to-twitter' );
|
710 |
+
_e( 'Tags with lower values will be modified first.', 'wp-to-twitter' );
|
711 |
+
?>
|
712 |
</p>
|
713 |
+
<p>
|
714 |
+
<?php echo $inputs; ?>
|
715 |
+
</p>
|
716 |
+
</fieldset>
|
717 |
+
</div>
|
718 |
+
</div>
|
719 |
+
</div>
|
720 |
+
<div class="ui-sortable meta-box-sortables">
|
721 |
+
<div class="postbox">
|
722 |
+
<h3><span><?php _e( 'Miscellaneous Settings', 'wp-to-twitter' ); ?></span></h3>
|
723 |
+
<div class="inside">
|
724 |
<fieldset>
|
725 |
+
<legend class='screen-reader-text'><?php _e( 'Miscellaneous Settings', 'wp-to-twitter' ); ?></legend>
|
726 |
<ul>
|
727 |
<li>
|
728 |
+
<input type="checkbox" name="wpt_permit_feed_styles" id="wpt_permit_feed_styles" value="1" <?php echo wpt_checkbox( 'wpt_permit_feed_styles' ); ?> />
|
729 |
+
<label for="wpt_permit_feed_styles"><?php _e( 'Disable Twitter Feed Stylesheet', 'wp-to-twitter' ); ?></label>
|
730 |
</li>
|
731 |
<li>
|
732 |
+
<input type="checkbox" name="wp_debug_oauth" id="wp_debug_oauth" value="1" <?php echo wpt_checkbox( 'wp_debug_oauth' ); ?> /> <label for="wp_debug_oauth"><?php _e( 'Get Debugging Data for OAuth Connection', 'wp-to-twitter' ); ?></label>
|
733 |
</li>
|
734 |
+
<li>
|
735 |
+
<input type="checkbox" name="jd_donations" id="jd_donations" value="1" <?php echo wpt_checkbox( 'jd_donations' ); ?> /> <label for="jd_donations"><strong><?php _e( 'I made a donation, so stop whinging at me, please.', 'wp-to-twitter' ); ?></strong></label>
|
|
|
736 |
</li>
|
737 |
</ul>
|
738 |
</fieldset>
|
739 |
<div>
|
740 |
<input type="hidden" name="submit-type" value="advanced"/>
|
741 |
</div>
|
742 |
+
<input type="submit" name="submit" value="<?php _e( 'Save Advanced WP to Twitter Options', 'wp-to-twitter' ); ?>" class="button-primary"/>
|
|
|
|
|
743 |
</div>
|
744 |
</form>
|
745 |
</div>
|
746 |
</div>
|
747 |
</div>
|
748 |
+
<?php
|
749 |
+
}
|
750 |
+
if ( 'support' == $current ) {
|
751 |
?>
|
752 |
<div class="postbox" id="get-support">
|
753 |
<h3><span><?php _e( 'Get Plug-in Support', 'wp-to-twitter' ); ?></span></h3>
|
754 |
|
755 |
<div class="inside">
|
756 |
+
<?php
|
757 |
+
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
758 |
+
?>
|
759 |
+
<div class='wpt-support-me'>
|
760 |
+
<p>
|
761 |
+
<?php
|
762 |
+
// Translators: Link to sales page.
|
763 |
+
printf( __( 'Please, consider a <a href="%s">purchase</a> to support WP to Twitter!', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro' );
|
764 |
+
?>
|
765 |
+
</p>
|
766 |
+
</div>
|
767 |
+
<?php
|
768 |
+
}
|
769 |
+
wpt_get_support_form();
|
770 |
+
?>
|
771 |
</div>
|
772 |
</div>
|
773 |
+
<?php
|
774 |
+
}
|
775 |
+
?>
|
776 |
</div>
|
777 |
</div>
|
778 |
<?php wpt_sidebar(); ?>
|
781 |
<?php
|
782 |
}
|
783 |
|
784 |
+
/**
|
785 |
+
* Show WP to Twitter sidebar content.
|
786 |
+
*/
|
787 |
function wpt_sidebar() {
|
788 |
$context = ( ! function_exists( 'wpt_pro_exists' ) ) ? 'free' : 'premium';
|
789 |
?>
|
791 |
<div class="metabox-holder">
|
792 |
<div class="ui-sortable meta-box-sortables<?php echo ' ' . $context; ?>">
|
793 |
<div class="postbox">
|
794 |
+
<?php
|
795 |
+
if ( 'free' == $context ) {
|
796 |
+
?>
|
797 |
+
<h3><span><strong><?php _e( 'Support WP to Twitter', 'wp-to-twitter' ); ?></strong></span></h3>
|
798 |
+
<?php
|
799 |
+
} else {
|
800 |
+
?>
|
801 |
+
<h3><span><strong><?php _e( 'WP to Twitter Support', 'wp-to-twitter' ); ?></strong></span></h3>
|
802 |
+
<?php
|
803 |
+
}
|
804 |
+
?>
|
805 |
<div class="inside resources">
|
806 |
+
<?php
|
807 |
+
if ( 1 != get_option( 'jd_donations' ) && ! function_exists( 'wpt_pro_exists' ) ) {
|
808 |
+
?>
|
809 |
+
<p class='cta'><?php _e( '<a href="http://www.wptweetspro.com/wp-tweets-pro">Get WP Tweets Pro</a>', 'wp-to-twitter' ); ?></p>
|
810 |
+
<?php
|
811 |
+
}
|
812 |
+
?>
|
813 |
<p>
|
814 |
+
<a href="https://twitter.com/intent/follow?screen_name=joedolson" class="twitter-follow-button" data-size="small" data-related="joedolson">Follow @joedolson</a>
|
|
|
815 |
<script>!function (d, s, id) {
|
816 |
var js, fjs = d.getElementsByTagName(s)[0];
|
817 |
if (!d.getElementById(id)) {
|
823 |
}(document, "script", "twitter-wjs");</script>
|
824 |
</p>
|
825 |
<?php
|
826 |
+
if ( 'premium' == $context ) {
|
827 |
$support_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
828 |
+
$support = '<a href="' . esc_url( add_query_arg( 'tab', 'support', $support_url ) ) . '#get-support">' . __( 'Get Support', 'wp-to-twitter' ) . '</a> •';
|
829 |
} else {
|
830 |
$support_url = false;
|
831 |
+
$support = '';
|
832 |
+
}
|
833 |
echo $support;
|
834 |
?>
|
835 |
<a href="https://www.joedolson.com/wp-content/uploads/wp-tweets-pro-users-guide-current.pdf"><?php _e( 'Read the Manual', 'wp-to-twitter' ); ?></a>
|
836 |
</div>
|
837 |
</div>
|
838 |
</div>
|
839 |
+
|
840 |
<div class="ui-sortable meta-box-sortables">
|
841 |
<div class="postbox">
|
842 |
+
<?php
|
843 |
+
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro&refresh_wpt_server_string=true' );
|
844 |
+
$link = "<a href='" . $admin_url . "'>" . __( 'Test again', 'wp-to-twitter' ) . '</a>';
|
845 |
+
?>
|
846 |
+
<h3><?php _e( 'Twitter Time Check', 'wp-to-twitter' ); ?> • <?php echo $link; ?></h3>
|
847 |
|
848 |
<div class="inside server">
|
849 |
+
<?php wpt_do_server_check(); ?>
|
850 |
</div>
|
851 |
</div>
|
852 |
</div>
|
853 |
+
|
854 |
<div class="ui-sortable meta-box-sortables">
|
855 |
<div class="postbox">
|
856 |
<h3><?php _e( 'Test WP to Twitter', 'wp-to-twitter' ); ?></h3>
|
857 |
+
|
858 |
<div class="inside test">
|
859 |
<p>
|
860 |
+
<?php _e( 'Check whether WP to Twitter is setup correctly for Twitter and your URL Shortener. The test sends a status update to Twitter and shortens a URL using your chosen shortener.', 'wp-to-twitter' ); ?>
|
861 |
</p>
|
862 |
<form method="post" action="">
|
863 |
<input type="hidden" name="submit-type" value="check-support"/>
|
864 |
+
<?php
|
865 |
+
$nonce = wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false );
|
866 |
+
echo "<div>$nonce</div>";
|
867 |
+
?>
|
868 |
<p>
|
869 |
+
<input type="submit" name="submit" value="<?php _e( 'Test WP to Twitter', 'wp-to-twitter' ); ?>" class="button-secondary" />
|
870 |
</p>
|
871 |
+
</form>
|
872 |
</div>
|
873 |
</div>
|
874 |
</div>
|
875 |
|
876 |
+
<?php
|
877 |
+
if ( 1 == get_option( 'wpt_rate_limiting' ) ) {
|
878 |
+
?>
|
879 |
<div class="ui-sortable meta-box-sortables">
|
880 |
<div class="postbox">
|
881 |
<h3><?php _e( 'Monitor Rate Limiting', 'wp-to-twitter' ); ?></h3>
|
882 |
|
883 |
+
<div class="inside server">
|
884 |
<?php echo wpt_view_rate_limits(); ?>
|
885 |
</div>
|
886 |
</div>
|
887 |
+
</div>
|
888 |
+
<?php
|
889 |
+
}
|
890 |
+
?>
|
891 |
</div>
|
892 |
<?php
|
893 |
}
|
894 |
|
895 |
+
/**
|
896 |
+
* Compare your server time to Twitter's time.
|
897 |
+
*
|
898 |
+
* @param boolean $test Doing a test.
|
899 |
+
*/
|
900 |
function wpt_do_server_check( $test = false ) {
|
901 |
$wpt_server_string = get_option( 'wpt_server_string' );
|
902 |
+
if ( ! $wpt_server_string || isset( $_GET['refresh_wpt_server_string'] ) || true == $test ) {
|
903 |
$server_time = date( DATE_COOKIE );
|
904 |
+
$response = wp_remote_get( 'https://twitter.com/', array(
|
905 |
+
'timeout' => 30,
|
906 |
+
'redirection' => 1,
|
907 |
+
) );
|
908 |
+
|
909 |
if ( is_wp_error( $response ) ) {
|
910 |
$warning = '';
|
911 |
$error = $response->errors;
|
912 |
if ( is_array( $error ) ) {
|
913 |
+
$warning = '<ul>';
|
914 |
foreach ( $error as $k => $e ) {
|
915 |
foreach ( $e as $v ) {
|
916 |
+
$warning .= '<li>' . $v . '</li>';
|
917 |
}
|
918 |
}
|
919 |
+
$warning .= '</ul>';
|
920 |
}
|
921 |
+
$errors = '<li>' . $ssl . $warning . '</li>';
|
922 |
} else {
|
923 |
$date = date( DATE_COOKIE, strtotime( $response['headers']['date'] ) );
|
924 |
$errors = '';
|
932 |
}
|
933 |
$diff = "<li>$diff</li>";
|
934 |
} else {
|
935 |
+
$diff = '<li>' . __( 'WP to Twitter could not contact Twitter\'s remote server.', 'wp-to-twitter' ) . '</li>';
|
936 |
}
|
937 |
|
938 |
$timezone = '<li>' . __( 'Your server timezone:', 'wp-to-twitter' ) . ' ' . date_default_timezone_get() . '</li>';
|
939 |
|
940 |
+
$search = array( 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' );
|
941 |
$replace = array( 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun' );
|
942 |
+
|
943 |
$server_time = str_replace( $search, $replace, $server_time );
|
944 |
+
$date = str_replace( $search, $replace, $date );
|
945 |
+
|
946 |
$wpt_server_string =
|
947 |
+
'<ul>
|
948 |
+
<li>' . __( 'Your server time:', 'wp-to-twitter' ) . '<br /><code>' . $server_time . '</code>' . '</li>' .
|
949 |
+
'<li>' . __( 'Twitter\'s server time: ', 'wp-to-twitter' ) . '<br /><code>' . $date . '</code>' . "</li>
|
950 |
$timezone
|
951 |
$diff
|
952 |
$errors
|
954 |
update_option( 'wpt_server_string', $wpt_server_string );
|
955 |
}
|
956 |
echo $wpt_server_string;
|
|
|
|
|
|
|
957 |
}
|
958 |
|
959 |
add_filter( 'wpt_tweet_length', 'wpt_tweet_length' );
|
960 |
+
/**
|
961 |
+
* Add control to set maximum length for a Tweet.
|
962 |
+
*
|
963 |
+
* @return string HTML control.
|
964 |
+
*/
|
965 |
function wpt_tweet_length() {
|
966 |
$tweet_length = intval( ( get_option( 'wpt_tweet_length' ) ) ? get_option( 'wpt_tweet_length' ) : 140 );
|
967 |
+
$control = "<p class='tweet_length_control'>
|
968 |
<label for='wpt_tweet_length'>" . __( 'Tweet Length (max 280 characters)', 'wp-to-twitter' ) . "</label>
|
969 |
+
<input type='number' min='0' max='280' step='1' value='$tweet_length' id='wpt_tweet_length' name='wpt_tweet_length' />
|
970 |
+
<a href='https://www.joedolson.com/2017/11/twitter-expands-280-characters-sort/'>" . __( 'About this setting', 'wp-to-twitter' ) . '</a>
|
971 |
+
</p>';
|
972 |
+
|
973 |
return $control;
|
974 |
}
|
975 |
|
976 |
add_filter( 'wpt_settings', 'wpt_set_tweet_length' );
|
977 |
+
/**
|
978 |
+
* Set the maximum length for a Tweet.
|
979 |
+
*/
|
980 |
function wpt_set_tweet_length() {
|
981 |
if ( isset( $_POST['wpt_tweet_length'] ) ) {
|
982 |
update_option( 'wpt_tweet_length', intval( $_POST['wpt_tweet_length'] ) );
|
983 |
}
|
984 |
+
}
|
wp-to-twitter-oauth.php
CHANGED
@@ -1,15 +1,32 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
exit;
|
4 |
-
}
|
5 |
|
6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
function wtt_oauth_test( $auth = false, $context = '' ) {
|
8 |
if ( ! $auth ) {
|
9 |
return ( wtt_oauth_credentials_to_hash() == get_option( 'wtt_oauth_hash' ) );
|
10 |
} else {
|
11 |
$return = ( wtt_oauth_credentials_to_hash( $auth ) == wpt_get_user_verification( $auth ) );
|
12 |
-
if ( ! $return &&
|
13 |
return ( wtt_oauth_credentials_to_hash() == get_option( 'wtt_oauth_hash' ) );
|
14 |
} else {
|
15 |
return $return;
|
@@ -17,6 +34,13 @@ function wtt_oauth_test( $auth = false, $context = '' ) {
|
|
17 |
}
|
18 |
}
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
function wpt_get_user_verification( $auth ) {
|
21 |
if ( get_option( 'jd_individual_twitter_users' ) != '1' ) {
|
22 |
return false;
|
@@ -27,8 +51,14 @@ function wpt_get_user_verification( $auth ) {
|
|
27 |
}
|
28 |
}
|
29 |
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
if ( ! $auth ) {
|
33 |
$ack = get_option( 'app_consumer_key' );
|
34 |
$acs = get_option( 'app_consumer_secret' );
|
@@ -41,8 +71,8 @@ function wtt_oauth_connection( $auth = false ) {
|
|
41 |
$ots = get_user_meta( $auth, 'oauth_token_secret', true );
|
42 |
}
|
43 |
if ( ! empty( $ack ) && ! empty( $acs ) && ! empty( $ot ) && ! empty( $ots ) ) {
|
44 |
-
require_once( plugin_dir_path( __FILE__ ) . '
|
45 |
-
$connection = new
|
46 |
$connection->useragent = get_option( 'blogname' ) . ' ' . home_url();
|
47 |
|
48 |
return $connection;
|
@@ -51,7 +81,13 @@ function wtt_oauth_connection( $auth = false ) {
|
|
51 |
}
|
52 |
}
|
53 |
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
function wtt_oauth_credentials_to_hash( $auth = false ) {
|
56 |
if ( ! $auth ) {
|
57 |
$hash = md5( get_option( 'app_consumer_key' ) . get_option( 'app_consumer_secret' ) . get_option( 'oauth_token' ) . get_option( 'oauth_token_secret' ) );
|
@@ -63,13 +99,11 @@ function wtt_oauth_credentials_to_hash( $auth = false ) {
|
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
-
*
|
|
|
|
|
|
|
67 |
*/
|
68 |
-
function jd_update_oauth_settings( $auth = false, $post = false ) {
|
69 |
-
return wpt_update_oauth_settings( $auth, $post );
|
70 |
-
}
|
71 |
-
|
72 |
-
// response to settings updates
|
73 |
function wpt_update_oauth_settings( $auth = false, $post = false ) {
|
74 |
if ( isset( $post['oauth_settings'] ) ) {
|
75 |
switch ( $post['oauth_settings'] ) {
|
@@ -78,9 +112,9 @@ function wpt_update_oauth_settings( $auth = false, $post = false ) {
|
|
78 |
wp_die( 'Oops, please try again.' );
|
79 |
}
|
80 |
if ( ! empty( $post['wtt_app_consumer_key'] )
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
) {
|
85 |
$ack = trim( $post['wtt_app_consumer_key'] );
|
86 |
$acs = trim( $post['wtt_app_consumer_secret'] );
|
@@ -98,17 +132,17 @@ function wpt_update_oauth_settings( $auth = false, $post = false ) {
|
|
98 |
update_user_meta( $auth, 'oauth_token_secret', $ots );
|
99 |
}
|
100 |
$message = 'failed';
|
101 |
-
if (
|
102 |
$data = $connection->get( 'https://api.twitter.com/1.1/account/verify_credentials.json' );
|
103 |
-
if ( $connection->http_code
|
104 |
$data = json_decode( $data );
|
105 |
-
$code = "<a href='https://dev.twitter.com/docs/error-codes-responses'>" . $data->errors[0]->code .
|
106 |
$error = $data->errors[0]->message;
|
107 |
update_option( 'wpt_error', "$code: $error" );
|
108 |
} else {
|
109 |
delete_option( 'wpt_error' );
|
110 |
}
|
111 |
-
if ( $connection->http_code
|
112 |
$error_information = '';
|
113 |
$decode = json_decode( $data );
|
114 |
if ( ! $auth ) {
|
@@ -124,32 +158,33 @@ function wpt_update_oauth_settings( $auth = false, $post = false ) {
|
|
124 |
}
|
125 |
$message = 'success';
|
126 |
delete_option( 'wpt_curl_error' );
|
127 |
-
}
|
128 |
-
$error_information = __(
|
129 |
update_option( 'wpt_curl_error', "$error_information" );
|
130 |
} else {
|
131 |
-
$status
|
132 |
$error_information = array(
|
133 |
-
|
134 |
-
|
135 |
);
|
136 |
-
|
|
|
137 |
update_option( 'wpt_curl_error', $error_code );
|
138 |
}
|
139 |
-
if ( get_option( 'wp_debug_oauth' )
|
140 |
-
echo
|
141 |
print_r( $error_information );
|
142 |
-
echo
|
143 |
print_r( $data );
|
144 |
-
echo
|
145 |
print_r( $connection );
|
146 |
-
echo
|
147 |
}
|
148 |
}
|
149 |
} else {
|
150 |
-
$message =
|
151 |
}
|
152 |
-
if (
|
153 |
$message = 'nosync';
|
154 |
}
|
155 |
|
@@ -172,7 +207,7 @@ function wpt_update_oauth_settings( $auth = false, $post = false ) {
|
|
172 |
delete_user_meta( $auth, 'oauth_token_secret' );
|
173 |
delete_user_meta( $auth, 'wtt_twitter_username' );
|
174 |
}
|
175 |
-
$message =
|
176 |
|
177 |
return $message;
|
178 |
break;
|
@@ -182,7 +217,11 @@ function wpt_update_oauth_settings( $auth = false, $post = false ) {
|
|
182 |
return '';
|
183 |
}
|
184 |
|
185 |
-
|
|
|
|
|
|
|
|
|
186 |
function wtt_connect_oauth( $auth = false ) {
|
187 |
if ( ! $auth ) {
|
188 |
echo '<div class="ui-sortable meta-box-sortables">';
|
@@ -192,7 +231,7 @@ function wtt_connect_oauth( $auth = false ) {
|
|
192 |
if ( $auth ) {
|
193 |
wpt_update_authenticated_users();
|
194 |
}
|
195 |
-
|
196 |
$class = ( $auth ) ? 'wpt-profile' : 'wpt-settings';
|
197 |
$form = ( ! $auth ) ? '<form action="" method="post">' : '';
|
198 |
$nonce = ( ! $auth ) ? wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false ) . '</form>' : '';
|
@@ -202,7 +241,8 @@ function wtt_connect_oauth( $auth = false ) {
|
|
202 |
// show notification to authenticate with OAuth. No longer global; settings only.
|
203 |
if ( ! wpt_check_oauth() ) {
|
204 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
205 |
-
|
|
|
206 |
echo "<div class='error'><p>$message</p></div>";
|
207 |
}
|
208 |
|
@@ -237,7 +277,7 @@ function wtt_connect_oauth( $auth = false ) {
|
|
237 |
<li>' . __( 'Copy your Access token and Access token secret from the "Your Access Token" section.', 'wp-to-twitter' ) . '</li>
|
238 |
</ul>
|
239 |
' . $form . '
|
240 |
-
<fieldset class="options">
|
241 |
<div class="tokens">
|
242 |
<p>
|
243 |
<label for="wtt_app_consumer_key">' . __( 'API Key', 'wp-to-twitter' ) . '</label>
|
@@ -264,21 +304,19 @@ function wtt_connect_oauth( $auth = false ) {
|
|
264 |
' . $submit . '
|
265 |
<input type="hidden" name="oauth_settings" value="wtt_oauth_test" class="hidden" style="display: none;" />
|
266 |
' . $nonce . '
|
267 |
-
</div>
|
268 |
' );
|
269 |
-
}
|
270 |
$ack = ( ! $auth ) ? get_option( 'app_consumer_key' ) : get_user_meta( $auth, 'app_consumer_key', true );
|
271 |
$acs = ( ! $auth ) ? get_option( 'app_consumer_secret' ) : get_user_meta( $auth, 'app_consumer_secret', true );
|
272 |
$ot = ( ! $auth ) ? get_option( 'oauth_token' ) : get_user_meta( $auth, 'oauth_token', true );
|
273 |
$ots = ( ! $auth ) ? get_option( 'oauth_token_secret' ) : get_user_meta( $auth, 'oauth_token_secret', true );
|
274 |
$uname = ( ! $auth ) ? get_option( 'wtt_twitter_username' ) : get_user_meta( $auth, 'wtt_twitter_username', true );
|
275 |
$nonce = ( ! $auth ) ? wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false ) . '</form>' : '';
|
276 |
-
if ( ! $auth ) {
|
277 |
-
$submit = '
|
278 |
-
<input type="
|
279 |
-
|
280 |
-
';
|
281 |
-
} else {
|
282 |
$submit = '<input type="checkbox" name="oauth_settings" value="wtt_twitter_disconnect" id="disconnect" /> <label for="disconnect">' . __( 'Disconnect your WordPress and Twitter Account', 'wp-to-twitter' ) . '</label>';
|
283 |
}
|
284 |
|
@@ -299,30 +337,44 @@ function wtt_connect_oauth( $auth = false ) {
|
|
299 |
<div>
|
300 |
' . $submit . '
|
301 |
</div>
|
302 |
-
</div>
|
303 |
' . $nonce . '
|
304 |
</div>' );
|
305 |
|
306 |
}
|
307 |
if ( ! $auth ) {
|
308 |
-
echo
|
309 |
-
|
310 |
}
|
311 |
}
|
312 |
|
|
|
|
|
|
|
313 |
function wpt_update_authenticated_users() {
|
314 |
-
$args
|
315 |
-
|
316 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
$authorized_users = array();
|
318 |
if ( is_array( $users ) ) {
|
319 |
foreach ( $users as $this_user ) {
|
320 |
-
if ( wtt_oauth_test( $this_user->ID,'verify' ) ) {
|
321 |
-
$twitter
|
322 |
-
$authorized_users[] = array(
|
|
|
|
|
|
|
|
|
323 |
}
|
324 |
}
|
325 |
}
|
326 |
-
|
327 |
-
update_option( 'wpt_authorized_users', $authorized_users );
|
328 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Connect OAuth for WP to Twitter
|
4 |
+
*
|
5 |
+
* @category OAuth
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
|
16 |
+
/**
|
17 |
+
* Function to test validity of credentials
|
18 |
+
*
|
19 |
+
* @param mixed int/boolean $auth Current author.
|
20 |
+
* @param string $context Use context.
|
21 |
+
*
|
22 |
+
* @return Is authenticated.
|
23 |
+
*/
|
24 |
function wtt_oauth_test( $auth = false, $context = '' ) {
|
25 |
if ( ! $auth ) {
|
26 |
return ( wtt_oauth_credentials_to_hash() == get_option( 'wtt_oauth_hash' ) );
|
27 |
} else {
|
28 |
$return = ( wtt_oauth_credentials_to_hash( $auth ) == wpt_get_user_verification( $auth ) );
|
29 |
+
if ( ! $return && 'verify' != $context ) {
|
30 |
return ( wtt_oauth_credentials_to_hash() == get_option( 'wtt_oauth_hash' ) );
|
31 |
} else {
|
32 |
return $return;
|
34 |
}
|
35 |
}
|
36 |
|
37 |
+
/**
|
38 |
+
* Get user verification hash.
|
39 |
+
*
|
40 |
+
* @param mixed int $auth Current author.
|
41 |
+
*
|
42 |
+
* @return author hash.
|
43 |
+
*/
|
44 |
function wpt_get_user_verification( $auth ) {
|
45 |
if ( get_option( 'jd_individual_twitter_users' ) != '1' ) {
|
46 |
return false;
|
51 |
}
|
52 |
}
|
53 |
|
54 |
+
/**
|
55 |
+
* Establish an OAuth connection to Twitter.
|
56 |
+
*
|
57 |
+
* @param mixed int/boolean $auth Current author.
|
58 |
+
*
|
59 |
+
* @return mixed $connection or false
|
60 |
+
*/
|
61 |
+
function wpt_oauth_connection( $auth = false ) {
|
62 |
if ( ! $auth ) {
|
63 |
$ack = get_option( 'app_consumer_key' );
|
64 |
$acs = get_option( 'app_consumer_secret' );
|
71 |
$ots = get_user_meta( $auth, 'oauth_token_secret', true );
|
72 |
}
|
73 |
if ( ! empty( $ack ) && ! empty( $acs ) && ! empty( $ot ) && ! empty( $ots ) ) {
|
74 |
+
require_once( plugin_dir_path( __FILE__ ) . 'classes/class-wpt-twitteroauth.php' );
|
75 |
+
$connection = new Wpt_TwitterOAuth( $ack, $acs, $ot, $ots );
|
76 |
$connection->useragent = get_option( 'blogname' ) . ' ' . home_url();
|
77 |
|
78 |
return $connection;
|
81 |
}
|
82 |
}
|
83 |
|
84 |
+
/**
|
85 |
+
* Convert oauth credentials to hash value for storage.
|
86 |
+
*
|
87 |
+
* @param mixed int/boolean $auth Author.
|
88 |
+
*
|
89 |
+
* @return hash.
|
90 |
+
*/
|
91 |
function wtt_oauth_credentials_to_hash( $auth = false ) {
|
92 |
if ( ! $auth ) {
|
93 |
$hash = md5( get_option( 'app_consumer_key' ) . get_option( 'app_consumer_secret' ) . get_option( 'oauth_token' ) . get_option( 'oauth_token_secret' ) );
|
99 |
}
|
100 |
|
101 |
/**
|
102 |
+
* Update OAuth settings.
|
103 |
+
*
|
104 |
+
* @param mixed int/boolean $auth Author.
|
105 |
+
* @param mixed array/boolean $post POST data.
|
106 |
*/
|
|
|
|
|
|
|
|
|
|
|
107 |
function wpt_update_oauth_settings( $auth = false, $post = false ) {
|
108 |
if ( isset( $post['oauth_settings'] ) ) {
|
109 |
switch ( $post['oauth_settings'] ) {
|
112 |
wp_die( 'Oops, please try again.' );
|
113 |
}
|
114 |
if ( ! empty( $post['wtt_app_consumer_key'] )
|
115 |
+
&& ! empty( $post['wtt_app_consumer_secret'] )
|
116 |
+
&& ! empty( $post['wtt_oauth_token'] )
|
117 |
+
&& ! empty( $post['wtt_oauth_token_secret'] )
|
118 |
) {
|
119 |
$ack = trim( $post['wtt_app_consumer_key'] );
|
120 |
$acs = trim( $post['wtt_app_consumer_secret'] );
|
132 |
update_user_meta( $auth, 'oauth_token_secret', $ots );
|
133 |
}
|
134 |
$message = 'failed';
|
135 |
+
if ( wpt_oauth_connection( $auth ) == $connection ) {
|
136 |
$data = $connection->get( 'https://api.twitter.com/1.1/account/verify_credentials.json' );
|
137 |
+
if ( '200' != $connection->http_code ) {
|
138 |
$data = json_decode( $data );
|
139 |
+
$code = "<a href='https://dev.twitter.com/docs/error-codes-responses'>" . $data->errors[0]->code . '</a>';
|
140 |
$error = $data->errors[0]->message;
|
141 |
update_option( 'wpt_error', "$code: $error" );
|
142 |
} else {
|
143 |
delete_option( 'wpt_error' );
|
144 |
}
|
145 |
+
if ( '200' == $connection->http_code ) {
|
146 |
$error_information = '';
|
147 |
$decode = json_decode( $data );
|
148 |
if ( ! $auth ) {
|
158 |
}
|
159 |
$message = 'success';
|
160 |
delete_option( 'wpt_curl_error' );
|
161 |
+
} elseif ( 0 == $connection->http_code ) {
|
162 |
+
$error_information = __( 'WP to Twitter was unable to establish a connection to Twitter.', 'wp-to-twitter' );
|
163 |
update_option( 'wpt_curl_error', "$error_information" );
|
164 |
} else {
|
165 |
+
$status = ( isset( $connection->http_header['status'] ) ) ? $connection->http_header['status'] : '404';
|
166 |
$error_information = array(
|
167 |
+
'http_code' => $connection->http_code,
|
168 |
+
'status' => $status,
|
169 |
);
|
170 |
+
// Translators: HTTP code & status message from Twitter.
|
171 |
+
$error_code = sprintf( __( 'Twitter response: http_code %s', 'wp-to-twitter' ), "$error_information[http_code] - $error_information[status]" );
|
172 |
update_option( 'wpt_curl_error', $error_code );
|
173 |
}
|
174 |
+
if ( '1' == get_option( 'wp_debug_oauth' ) ) {
|
175 |
+
echo '<pre><strong>Summary Connection Response:</strong><br />';
|
176 |
print_r( $error_information );
|
177 |
+
echo '<br /><strong>Account Verification Data:</strong><br />';
|
178 |
print_r( $data );
|
179 |
+
echo '<br /><strong>Full Connection Response:</strong><br />';
|
180 |
print_r( $connection );
|
181 |
+
echo '</pre>';
|
182 |
}
|
183 |
}
|
184 |
} else {
|
185 |
+
$message = 'nodata';
|
186 |
}
|
187 |
+
if ( 'failed' == $message && ( time() < strtotime( $connection->http_header['date'] ) - 300 || time() > strtotime( $connection->http_header['date'] ) + 300 ) ) {
|
188 |
$message = 'nosync';
|
189 |
}
|
190 |
|
207 |
delete_user_meta( $auth, 'oauth_token_secret' );
|
208 |
delete_user_meta( $auth, 'wtt_twitter_username' );
|
209 |
}
|
210 |
+
$message = 'cleared';
|
211 |
|
212 |
return $message;
|
213 |
break;
|
217 |
return '';
|
218 |
}
|
219 |
|
220 |
+
/**
|
221 |
+
* Connect or disconnect from OAuth form.
|
222 |
+
*
|
223 |
+
* @param mixed int/boolean $auth Current author.
|
224 |
+
*/
|
225 |
function wtt_connect_oauth( $auth = false ) {
|
226 |
if ( ! $auth ) {
|
227 |
echo '<div class="ui-sortable meta-box-sortables">';
|
231 |
if ( $auth ) {
|
232 |
wpt_update_authenticated_users();
|
233 |
}
|
234 |
+
|
235 |
$class = ( $auth ) ? 'wpt-profile' : 'wpt-settings';
|
236 |
$form = ( ! $auth ) ? '<form action="" method="post">' : '';
|
237 |
$nonce = ( ! $auth ) ? wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false ) . '</form>' : '';
|
241 |
// show notification to authenticate with OAuth. No longer global; settings only.
|
242 |
if ( ! wpt_check_oauth() ) {
|
243 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
244 |
+
// Translators: Settings page to authenticate via OAuth.
|
245 |
+
$message = sprintf( __( "Twitter requires authentication by OAuth. You will need to <a href='%s'>update your settings</a> to complete installation of WP to Twitter.", 'wp-to-twitter' ), $admin_url );
|
246 |
echo "<div class='error'><p>$message</p></div>";
|
247 |
}
|
248 |
|
277 |
<li>' . __( 'Copy your Access token and Access token secret from the "Your Access Token" section.', 'wp-to-twitter' ) . '</li>
|
278 |
</ul>
|
279 |
' . $form . '
|
280 |
+
<fieldset class="options">
|
281 |
<div class="tokens">
|
282 |
<p>
|
283 |
<label for="wtt_app_consumer_key">' . __( 'API Key', 'wp-to-twitter' ) . '</label>
|
304 |
' . $submit . '
|
305 |
<input type="hidden" name="oauth_settings" value="wtt_oauth_test" class="hidden" style="display: none;" />
|
306 |
' . $nonce . '
|
307 |
+
</div>
|
308 |
' );
|
309 |
+
} elseif ( wtt_oauth_test( $auth ) ) {
|
310 |
$ack = ( ! $auth ) ? get_option( 'app_consumer_key' ) : get_user_meta( $auth, 'app_consumer_key', true );
|
311 |
$acs = ( ! $auth ) ? get_option( 'app_consumer_secret' ) : get_user_meta( $auth, 'app_consumer_secret', true );
|
312 |
$ot = ( ! $auth ) ? get_option( 'oauth_token' ) : get_user_meta( $auth, 'oauth_token', true );
|
313 |
$ots = ( ! $auth ) ? get_option( 'oauth_token_secret' ) : get_user_meta( $auth, 'oauth_token_secret', true );
|
314 |
$uname = ( ! $auth ) ? get_option( 'wtt_twitter_username' ) : get_user_meta( $auth, 'wtt_twitter_username', true );
|
315 |
$nonce = ( ! $auth ) ? wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false ) . '</form>' : '';
|
316 |
+
if ( ! $auth ) {
|
317 |
+
$submit = '<input type="submit" name="submit" class="button-primary" value="' . __( 'Disconnect your WordPress and Twitter Account', 'wp-to-twitter' ) . '" />
|
318 |
+
<input type="hidden" name="oauth_settings" value="wtt_twitter_disconnect" class="hidden" />';
|
319 |
+
} else {
|
|
|
|
|
320 |
$submit = '<input type="checkbox" name="oauth_settings" value="wtt_twitter_disconnect" id="disconnect" /> <label for="disconnect">' . __( 'Disconnect your WordPress and Twitter Account', 'wp-to-twitter' ) . '</label>';
|
321 |
}
|
322 |
|
337 |
<div>
|
338 |
' . $submit . '
|
339 |
</div>
|
340 |
+
</div>
|
341 |
' . $nonce . '
|
342 |
</div>' );
|
343 |
|
344 |
}
|
345 |
if ( ! $auth ) {
|
346 |
+
echo '</div>
|
347 |
+
</div>';
|
348 |
}
|
349 |
}
|
350 |
|
351 |
+
/**
|
352 |
+
* Update stored set of authenticated users.
|
353 |
+
*/
|
354 |
function wpt_update_authenticated_users() {
|
355 |
+
$args = array(
|
356 |
+
'meta_query' => array(
|
357 |
+
array(
|
358 |
+
'key' => 'wtt_twitter_username',
|
359 |
+
'compare' => 'EXISTS',
|
360 |
+
),
|
361 |
+
),
|
362 |
+
);
|
363 |
+
// get all authorized users.
|
364 |
+
$users = get_users( $args );
|
365 |
$authorized_users = array();
|
366 |
if ( is_array( $users ) ) {
|
367 |
foreach ( $users as $this_user ) {
|
368 |
+
if ( wtt_oauth_test( $this_user->ID, 'verify' ) ) {
|
369 |
+
$twitter = get_user_meta( $this_user->ID, 'wtt_twitter_username', true );
|
370 |
+
$authorized_users[] = array(
|
371 |
+
'ID' => $this_user->ID,
|
372 |
+
'name' => $this_user->display_name,
|
373 |
+
'twitter' => $twitter,
|
374 |
+
);
|
375 |
}
|
376 |
}
|
377 |
}
|
378 |
+
|
379 |
+
update_option( 'wpt_authorized_users', $authorized_users );
|
380 |
+
}
|
wp-to-twitter-shorteners.php
CHANGED
@@ -1,42 +1,63 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
exit;
|
5 |
-
}
|
6 |
|
7 |
-
if ( ! function_exists( 'wpt_shorten_url' ) ) {
|
|
|
8 |
add_filter( 'wptt_shorten_link', 'wpt_shorten_url', 10, 4 );
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
$shortener = get_option( 'jd_shortener' );
|
14 |
-
// if the URL already exists, return it without processing
|
15 |
-
if (
|
16 |
-
$shrink =
|
17 |
-
|
18 |
return $shrink;
|
19 |
}
|
20 |
$url = apply_filters( 'wpt_shorten_link', $url, $shortener, $post_ID );
|
21 |
-
if (
|
22 |
-
if ( get_option( 'use-twitter-analytics' )
|
23 |
-
if ( get_option( 'use_dynamic_analytics' )
|
24 |
$campaign_type = get_option( 'jd_dynamic_analytics' );
|
25 |
-
if (
|
26 |
$category = get_the_category( $post_ID );
|
27 |
$campaign = sanitize_title( $category[0]->cat_name );
|
28 |
-
}
|
29 |
$campaign = $post_ID;
|
30 |
-
}
|
31 |
$post = get_post( $post_ID );
|
32 |
$campaign = sanitize_title( $post->post_title );
|
33 |
} else {
|
34 |
-
if (
|
35 |
$post = get_post( $post_ID );
|
36 |
$post_author = $post->post_author;
|
37 |
$campaign = urlencode( get_the_author_meta( 'user_login', $post_author ) );
|
38 |
} else {
|
39 |
-
$campaign
|
40 |
}
|
41 |
}
|
42 |
} else {
|
@@ -44,37 +65,37 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
44 |
}
|
45 |
$medium = urlencode( trim( apply_filters( 'wpt_utm_medium', 'twitter' ) ) );
|
46 |
$source = urlencode( trim( apply_filters( 'wpt_utm_source', 'twitter' ) ) );
|
47 |
-
$url
|
48 |
-
'utm_campaign' => $campaign,
|
49 |
-
'utm_medium' => $medium,
|
50 |
-
'utm_source' => $source
|
51 |
-
);
|
52 |
}
|
53 |
-
$url = urldecode( trim( $url ) ); // prevent double-encoding
|
54 |
$encoded = urlencode( $url );
|
55 |
} else {
|
56 |
-
$url = urldecode( trim( $url ) ); // prevent double-encoding
|
57 |
$encoded = urlencode( $url );
|
58 |
}
|
59 |
|
60 |
-
// custom word setting
|
61 |
-
$keyword_format = ( get_option( 'jd_keyword_format' )
|
62 |
-
$keyword_format = ( get_option( 'jd_keyword_format' )
|
63 |
-
// Generate and grab the short url
|
64 |
-
$shrink = apply_filters( 'wpt_do_shortening', false, $shortener, $url, $
|
65 |
-
// if an add-on has shortened the link, skip shortening
|
66 |
$error = false;
|
67 |
-
if (
|
68 |
switch ( $shortener ) {
|
69 |
-
case 3: // no shortener
|
70 |
$shrink = $url;
|
71 |
break;
|
72 |
-
case 2: // updated to v3 3/31/2010
|
73 |
$bitlyapi = trim( get_option( 'bitlyapi' ) );
|
74 |
$bitlylogin = trim( strtolower( get_option( 'bitlylogin' ) ) );
|
75 |
-
$decoded = wpt_remote_json(
|
76 |
if ( $decoded && isset( $decoded['status_code'] ) ) {
|
77 |
-
if ( $decoded['status_code']
|
78 |
$shrink = $url;
|
79 |
$error = $decoded['status_txt'];
|
80 |
} else {
|
@@ -90,33 +111,26 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
90 |
case 4:
|
91 |
if ( function_exists( 'wp_get_shortlink' ) ) {
|
92 |
// wp_get_shortlink doesn't natively support custom post types; but don't return an error in that case.
|
93 |
-
$shrink = (
|
94 |
}
|
95 |
if ( ! $shrink ) {
|
96 |
$shrink = $url;
|
97 |
}
|
98 |
-
break;
|
99 |
case 5:
|
100 |
-
// local YOURLS installation
|
101 |
-
|
102 |
-
define( '
|
103 |
-
define( 'YOURLS_FLOOD_DELAY_SECONDS', 0 ); // Disable flood check
|
104 |
$opath = get_option( 'yourlspath' );
|
105 |
$ypath = str_replace( 'user', 'includes', $opath );
|
106 |
-
if ( file_exists( dirname( $ypath ) . '/load-yourls.php' ) ) { // YOURLS 1.4
|
107 |
require_once( dirname( $ypath ) . '/load-yourls.php' );
|
108 |
global $ydb;
|
109 |
if ( function_exists( 'yourls_add_new_link' ) ) {
|
110 |
-
$yourls_result = yourls_add_new_link( $url, $keyword_format, $
|
111 |
} else {
|
112 |
$yourls_result = $url;
|
113 |
}
|
114 |
-
} else { // YOURLS 1.3
|
115 |
-
if ( file_exists( get_option( 'yourslpath' ) ) ) {
|
116 |
-
require_once( get_option( 'yourlspath' ) );
|
117 |
-
$yourls_db = new wpdb( YOURLS_DB_USER, YOURLS_DB_PASS, YOURLS_DB_NAME, YOURLS_DB_HOST );
|
118 |
-
$yourls_result = yourls_add_new_link( $url, $keyword_format, $yourls_db );
|
119 |
-
}
|
120 |
}
|
121 |
if ( $yourls_result ) {
|
122 |
$shrink = $yourls_result['shorturl'];
|
@@ -125,7 +139,7 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
125 |
}
|
126 |
break;
|
127 |
case 6:
|
128 |
-
// remote YOURLS installation
|
129 |
$yourlslogin = trim( get_option( 'yourlslogin' ) );
|
130 |
$yourlsapi = stripcslashes( get_option( 'yourlsapi' ) );
|
131 |
$token = stripcslashes( get_option( 'yourlstoken' ) );
|
@@ -135,8 +149,8 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
135 |
'signature' => $token,
|
136 |
'url' => $encoded,
|
137 |
'action' => 'shorturl',
|
138 |
-
'format' => 'json',
|
139 |
-
'title' => urlencode( $
|
140 |
);
|
141 |
} else {
|
142 |
$args = array(
|
@@ -144,36 +158,36 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
144 |
'password' => $yourlsapi,
|
145 |
'url' => $encoded,
|
146 |
'action' => 'shorturl',
|
147 |
-
'format' => 'json',
|
148 |
-
'title'
|
149 |
);
|
150 |
}
|
151 |
if ( $keyword_format ) {
|
152 |
$args['keyword'] = $keyword_format;
|
153 |
}
|
154 |
-
|
155 |
$api_url = add_query_arg( $args, $yourlsurl );
|
156 |
-
|
157 |
$json = wpt_remote_json( $api_url, false );
|
158 |
-
wpt_mail(
|
159 |
if ( is_object( $json ) ) {
|
160 |
$shrink = $json->shorturl;
|
161 |
} else {
|
162 |
-
$error
|
163 |
$shrink = false;
|
164 |
}
|
165 |
break;
|
166 |
case 7:
|
167 |
$suprapi = trim( get_option( 'suprapi' ) );
|
168 |
$suprlogin = trim( get_option( 'suprlogin' ) );
|
169 |
-
if (
|
170 |
-
$decoded = wpt_remote_json(
|
171 |
} else {
|
172 |
-
$decoded = wpt_remote_json(
|
173 |
}
|
174 |
if ( $decoded && isset( $decoded['statusCode'] ) ) {
|
175 |
-
if ( $decoded['statusCode']
|
176 |
-
$page = str_replace(
|
177 |
$shrink = $decoded['results'][ $page ]['shortUrl'];
|
178 |
$error = $decoded['errorMessage'];
|
179 |
} else {
|
@@ -189,53 +203,47 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
189 |
}
|
190 |
break;
|
191 |
case 8:
|
192 |
-
// Goo.gl
|
193 |
-
$googl_api_key = ( get_option( 'googl_api_key' )
|
194 |
-
$target
|
195 |
-
$body
|
196 |
-
$json
|
197 |
-
$decoded
|
198 |
-
$shrink
|
199 |
if ( ! wpt_is_valid_url( $shrink ) ) {
|
200 |
$shrink = false;
|
201 |
}
|
202 |
break;
|
203 |
case 9:
|
204 |
-
// Twitter Friendly Links
|
205 |
$shrink = $url;
|
206 |
-
if ( function_exists( 'twitter_link' ) ) { // use twitter_link if available
|
207 |
-
$shrink = twitter_link( $post_ID );
|
208 |
-
}
|
209 |
break;
|
210 |
-
case 10:
|
211 |
-
//jotURL, added: 2013-04-10
|
212 |
$joturlapi = trim( get_option( 'joturlapi' ) );
|
213 |
$joturllogin = trim( get_option( 'joturllogin' ) );
|
214 |
$joturl_longurl_params = trim( get_option( 'joturl_longurl_params' ) );
|
215 |
-
if (
|
216 |
-
if ( strpos( $url,
|
217 |
-
$ct =
|
218 |
} else {
|
219 |
-
$ct =
|
220 |
}
|
221 |
-
$url
|
222 |
-
$encoded = urlencode( urldecode( trim( $url ) ) ); // prevent double-encoding
|
223 |
}
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
$shrink = $decoded;
|
228 |
-
//jotURL, added: 2013-04-10
|
229 |
$joturl_shorturl_params = trim( get_option( 'joturl_shorturl_params' ) );
|
230 |
-
if (
|
231 |
-
if ( strpos( $shrink,
|
232 |
-
$ct =
|
233 |
} else {
|
234 |
-
$ct =
|
235 |
}
|
236 |
$shrink .= $ct . $joturl_shorturl_params;
|
237 |
}
|
238 |
-
//\jotURL
|
239 |
} else {
|
240 |
$error = $decoded;
|
241 |
$shrink = false;
|
@@ -244,14 +252,15 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
244 |
$shrink = false;
|
245 |
}
|
246 |
break;
|
247 |
-
default:
|
|
|
248 |
}
|
249 |
}
|
250 |
if ( $error ) {
|
251 |
update_option( 'wpt_shortener_status', "$shrink : $error" );
|
252 |
}
|
253 |
if ( ! $testmode ) {
|
254 |
-
if (
|
255 |
update_option( 'wp_url_failure', '1' );
|
256 |
$shrink = urldecode( $url );
|
257 |
} else {
|
@@ -265,22 +274,21 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
265 |
|
266 |
return $shrink;
|
267 |
}
|
268 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
function wpt_store_url( $post_ID, $url ) {
|
270 |
$store_urls = apply_filters( 'wpt_store_urls', true, $post_ID, $url );
|
271 |
-
if ( function_exists( 'wpt_shorten_url' )
|
272 |
$shortener = get_option( 'jd_shortener' );
|
273 |
-
if (
|
274 |
update_post_meta( $post_ID, '_wpt_short_url', $url );
|
275 |
}
|
276 |
switch ( $shortener ) {
|
277 |
-
case 0:
|
278 |
-
case 1:
|
279 |
-
case 2:
|
280 |
-
case 7:
|
281 |
-
case 8:
|
282 |
-
$target = wpt_expand_url( $url );
|
283 |
-
break;
|
284 |
case 5:
|
285 |
case 6:
|
286 |
$target = wpt_expand_yourl( $url, $shortener );
|
@@ -293,28 +301,21 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
293 |
}
|
294 |
update_post_meta( $post_ID, '_wp_jd_target', $target );
|
295 |
}
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
*
|
|
|
303 |
*/
|
304 |
-
function wpt_expand_url( $short_url ) {
|
305 |
-
return $short_url;
|
306 |
-
}
|
307 |
-
|
308 |
-
function jd_expand_yourl( $short_url, $remote ) {
|
309 |
-
return wpt_expand_yourl( $short_url, $remote );
|
310 |
-
}
|
311 |
-
|
312 |
function wpt_expand_yourl( $short_url, $remote ) {
|
313 |
-
if (
|
314 |
$short_url = urlencode( $short_url );
|
315 |
$yourl_api = get_option( 'yourlsurl' );
|
316 |
$user = get_option( 'yourlslogin' );
|
317 |
-
$pass =
|
318 |
$token = get_option( 'yourlstoken' );
|
319 |
if ( $token ) {
|
320 |
$decoded = wpt_remote_json( $yourl_api . "?action=expand&shorturl=$short_url&format=json&signature=$token&username=$user&password=$pass" );
|
@@ -325,19 +326,12 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
325 |
|
326 |
return $url;
|
327 |
} else {
|
328 |
-
|
329 |
-
define( '
|
330 |
-
|
331 |
-
if ( file_exists( dirname( get_option( 'yourlspath' ) ) . '/load-yourls.php' ) ) { // YOURLS 1.4+
|
332 |
global $ydb;
|
333 |
require_once( dirname( get_option( 'yourlspath' ) ) . '/load-yourls.php' );
|
334 |
$yourls_result = yourls_api_expand( $short_url );
|
335 |
-
} else { // YOURLS 1.3
|
336 |
-
if ( file_exists( get_option( 'yourlspath' ) ) ) {
|
337 |
-
require_once( get_option( 'yourlspath' ) );
|
338 |
-
$yourls_db = new wpdb( YOURLS_DB_USER, YOURLS_DB_PASS, YOURLS_DB_NAME, YOURLS_DB_HOST );
|
339 |
-
$yourls_result = yourls_api_expand( $short_url );
|
340 |
-
}
|
341 |
}
|
342 |
if ( $yourls_result ) {
|
343 |
$url = $yourls_result['longurl'];
|
@@ -349,21 +343,24 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
349 |
}
|
350 |
|
351 |
add_filter( 'wpt_shortener_controls', 'wpt_shortener_controls' );
|
|
|
|
|
|
|
352 |
function wpt_shortener_controls() {
|
353 |
-
$shortener
|
354 |
-
$admin_url
|
355 |
$form_start = '<div class="panel">
|
356 |
<form method="post" action="' . add_query_arg( 'tab', 'shortener', $admin_url ) . '">
|
357 |
<div><input type="hidden" name="wpt_shortener_update" value="true" /></div>
|
358 |
<div>';
|
359 |
-
$nonce
|
360 |
-
$form_end
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
// for the moment, this just displays the fields. Eventually, a real filter.
|
368 |
?>
|
369 |
<div class="ui-sortable meta-box-sortables">
|
@@ -373,168 +370,157 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
373 |
</h3>
|
374 |
|
375 |
<div class="inside">
|
376 |
-
<?php
|
|
|
|
|
377 |
<?php echo $form_start; ?>
|
378 |
<p>
|
379 |
<label
|
380 |
-
for="suprlogin"><?php _e(
|
381 |
-
<input type="text" name="suprlogin" id="suprlogin" size="40"
|
382 |
-
value="<?php esc_attr_e( get_option( 'suprlogin' ) ) ?>"/>
|
383 |
</p>
|
384 |
-
|
385 |
<p>
|
386 |
<label
|
387 |
for="suprapi"><?php _e( "Your Su.pr <abbr title='application programming interface'>API</abbr> Key:", 'wp-to-twitter' ); ?></label>
|
388 |
-
<input type="text" name="suprapi" id="suprapi" size="40"
|
389 |
-
value="<?php esc_attr_e( get_option( 'suprapi' ) ) ?>"/>
|
390 |
</p>
|
391 |
|
392 |
<div>
|
393 |
<input type="hidden" name="submit-type" value="suprapi"/>
|
394 |
</div>
|
395 |
<p><small><?php _e( "Don't have a Su.pr account or API key? <a href='http://su.pr/'>Get one here!</a> You'll need an API key in order to associate the URLs you create with your Su.pr account.", 'wp-to-twitter' ); ?></small></p>
|
396 |
-
<?php echo $form_end; ?>
|
397 |
-
<?php
|
398 |
-
|
|
|
|
|
399 |
<p>
|
400 |
-
<label
|
401 |
-
|
402 |
-
<input type="text" name="bitlylogin" id="bitlylogin"
|
403 |
-
value="<?php esc_attr_e( get_option( 'bitlylogin' ) ) ?>"/>
|
404 |
</p>
|
405 |
<p>
|
406 |
-
<label
|
407 |
-
|
408 |
-
<input type="text" name="bitlyapi" id="bitlyapi" size="40"
|
409 |
-
value="<?php esc_attr_e( get_option( 'bitlyapi' ) ) ?>"/>
|
410 |
</p>
|
411 |
-
|
412 |
<p>
|
413 |
<a href="http://bitly.com/a/your_api_key"><?php _e( 'View your Bit.ly username and API key', 'wp-to-twitter' ); ?></a>
|
414 |
</p>
|
415 |
-
|
416 |
<div>
|
417 |
<input type="hidden" name="submit-type" value="bitlyapi"/>
|
418 |
</div>
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
|
|
|
|
423 |
<p>
|
424 |
-
<label
|
425 |
-
|
426 |
-
type="text" id="yourlspath" name="yourlspath" size="60"
|
427 |
-
value="<?php esc_attr_e( get_option( 'yourlspath' ) ); ?>"/><br/>
|
428 |
<small><?php _e( 'Example:', 'wp-to-twitter' ); ?> <code>/home/username/www/www/yourls/user/config.php</code>
|
429 |
</small>
|
430 |
</p>
|
431 |
-
<?php
|
432 |
-
|
|
|
|
|
433 |
<p>
|
434 |
-
<label
|
435 |
-
|
436 |
-
type="text" id="yourlsurl" name="yourlsurl" size="60"
|
437 |
-
value="<?php esc_attr_e( get_option( 'yourlsurl' ) ); ?>"/><br/>
|
438 |
<small><?php _e( 'Example:', 'wp-to-twitter' ); ?> <code>http://domain.com/yourls-api.php</code>
|
439 |
</small>
|
440 |
</p>
|
441 |
-
<?php
|
|
|
|
|
442 |
<p>
|
443 |
-
<label
|
444 |
-
|
445 |
-
<input type="text" name="yourlstoken" id="yourlstoken" size="30"
|
446 |
-
value="<?php esc_attr_e( get_option( 'yourlstoken' ) ) ?>"/>
|
447 |
</p>
|
448 |
-
<?php
|
|
|
|
|
449 |
<p>
|
450 |
<em><?php _e( 'Your YOURLS username and password are saved. If you add a signature token, that will be used for API calls and your username and password will be deleted from the database.', 'wp-to-twitter' ); ?></em>
|
451 |
</p>
|
452 |
-
<?php
|
|
|
|
|
453 |
<p>
|
454 |
-
<input type="radio" name="jd_keyword_format" id="jd_keyword_id"
|
455 |
-
|
456 |
-
<
|
457 |
-
|
458 |
-
<input type="radio" name="jd_keyword_format" id="
|
459 |
-
|
460 |
-
<label
|
461 |
-
for="jd_keyword"><?php _e( "Custom keyword for YOURLS url slug.", 'wp-to-twitter' ); ?></label><br/>
|
462 |
-
<input type="radio" name="jd_keyword_format" id="jd_keyword_default"
|
463 |
-
value="0" <?php echo jd_checkSelect( 'jd_keyword_format', 0, 'checkbox' ); ?> />
|
464 |
-
<label
|
465 |
-
for="jd_keyword_default"><?php _e( "Default: sequential URL numbering.", 'wp-to-twitter' ); ?></label>
|
466 |
</p>
|
467 |
-
|
468 |
<div>
|
469 |
<input type="hidden" name="submit-type" value="yourlsapi" />
|
470 |
</div>
|
471 |
-
<?php
|
472 |
-
|
473 |
-
|
|
|
|
|
|
|
474 |
<p>
|
475 |
-
<label for="googl_api_key"><?php _e(
|
476 |
-
<input type="text" name="googl_api_key" id="googl_api_key" value="<?php
|
477 |
</p>
|
478 |
-
|
479 |
<div><input type="hidden" name="submit-type" value="googlapi" /></div>
|
480 |
-
<?php
|
481 |
-
|
482 |
-
|
|
|
|
|
483 |
<p>
|
484 |
-
<label
|
485 |
-
|
486 |
-
<input type="text" name="joturllogin" id="joturllogin"
|
487 |
-
value="<?php esc_attr_e( get_option( 'joturllogin' ) ) ?>"/>
|
488 |
</p>
|
489 |
-
|
490 |
<p>
|
491 |
-
<label
|
492 |
-
|
493 |
-
<input type="text" name="joturlapi" id="joturlapi" size="40"
|
494 |
-
value="<?php esc_attr_e( get_option( 'joturlapi' ) ) ?>"/>
|
495 |
</p>
|
496 |
-
|
497 |
<p>
|
498 |
-
<label
|
499 |
-
|
500 |
-
<input type="text" name="joturl_longurl_params" id="joturl_longurl_params"
|
501 |
-
size="40"
|
502 |
-
value="<?php esc_attr_e( get_option( 'joturl_longurl_params' ) ) ?>"/>
|
503 |
</p>
|
504 |
|
505 |
<p>
|
506 |
-
<label
|
507 |
-
|
508 |
-
<input type="text" name="joturl_shorturl_params" id="joturl_shorturl_params"
|
509 |
-
size="40"
|
510 |
-
value="<?php esc_attr_e( get_option( 'joturl_shorturl_params' ) ) ?>"/>
|
511 |
</p>
|
512 |
-
|
513 |
<p>
|
514 |
<a href="https://www.joturl.com/reserved/api.html"><?php _e( 'View your jotURL public and private API key', 'wp-to-twitter' ); ?></a>
|
515 |
</p>
|
516 |
-
|
517 |
<div><input type="hidden" name="submit-type" value="joturlapi"/></div>
|
518 |
-
<?php
|
|
|
519 |
} else {
|
520 |
$form = apply_filters( 'wpt_shortener_settings', '', $shortener );
|
521 |
-
if (
|
522 |
echo $form_start . $form . $form_end;
|
523 |
} else {
|
524 |
_e( 'Your shortener does not require any account settings.', 'wp-to-twitter' );
|
525 |
}
|
526 |
-
}
|
|
|
527 |
</div>
|
528 |
</div>
|
529 |
</div>
|
530 |
<?php
|
531 |
}
|
532 |
|
|
|
|
|
|
|
|
|
|
|
533 |
function wpt_shortener_update( $post ) {
|
534 |
$message = '';
|
535 |
-
if ( isset( $post['submit-type'] ) && $post['submit-type']
|
536 |
$message = '';
|
537 |
-
if ( $post['yourlstoken']
|
538 |
update_option( 'yourlstoken', trim( $post['yourlstoken'] ) );
|
539 |
delete_option( 'yourlsapi' );
|
540 |
delete_option( 'yourlslogin' );
|
@@ -542,22 +528,22 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
542 |
}
|
543 |
update_option( 'yourlsurl', trim( $post['yourlsurl'] ) );
|
544 |
// yourls path is deprecated.
|
545 |
-
if ( isset( $post['yourlspath'] ) && $post['yourlspath']
|
546 |
update_option( 'yourlspath', trim( $post['yourlspath'] ) );
|
547 |
if ( file_exists( $post['yourlspath'] ) ) {
|
548 |
-
$message .= ' ' . __(
|
549 |
} else {
|
550 |
-
$message .= ' ' . __(
|
551 |
}
|
552 |
}
|
553 |
-
if ( $post['jd_keyword_format']
|
554 |
update_option( 'jd_keyword_format', $post['jd_keyword_format'] );
|
555 |
-
if ( $post['jd_keyword_format']
|
556 |
-
$message .= ' ' . __(
|
557 |
-
}
|
558 |
$message .= ' ' . __( 'YOURLS will use default URL structures.', 'wp-to-twitter' );
|
559 |
} else {
|
560 |
-
$message .= ' ' . __(
|
561 |
}
|
562 |
}
|
563 |
if ( isset( $post['clear'] ) ) {
|
@@ -571,145 +557,175 @@ if ( ! function_exists( 'wpt_shorten_url' ) ) { // prep work for future plug-in
|
|
571 |
}
|
572 |
}
|
573 |
|
574 |
-
if ( isset( $post['submit-type'] ) && $post['submit-type']
|
575 |
-
if ( $post['suprapi']
|
576 |
update_option( 'suprapi', trim( $post['suprapi'] ) );
|
577 |
update_option( 'suprlogin', trim( $post['suprlogin'] ) );
|
578 |
-
$message = __(
|
579 |
-
}
|
580 |
update_option( 'suprapi', '' );
|
581 |
update_option( 'suprlogin', '' );
|
582 |
-
$message = __(
|
583 |
} else {
|
584 |
-
$message = __( "Su.pr API Key not added - <a href='http://su.pr/'>get one here</a>!
|
585 |
}
|
586 |
}
|
587 |
-
|
588 |
-
if ( isset( $post['submit-type'] ) && $post['submit-type']
|
589 |
-
if ( $post['bitlyapi']
|
590 |
update_option( 'bitlyapi', trim( $post['bitlyapi'] ) );
|
591 |
-
$message = __(
|
592 |
-
}
|
593 |
update_option( 'bitlyapi', '' );
|
594 |
-
$message = __(
|
595 |
} else {
|
596 |
$message = __( "Bit.ly API Key not added - <a href='http://bit.ly/account/'>get one here</a>! An API key is required to use the Bit.ly URL shortening service.", 'wp-to-twitter' );
|
597 |
}
|
598 |
-
if ( $post['bitlylogin']
|
599 |
update_option( 'bitlylogin', trim( $post['bitlylogin'] ) );
|
600 |
-
$message .= __(
|
601 |
-
}
|
602 |
update_option( 'bitlylogin', '' );
|
603 |
-
$message = __(
|
604 |
} else {
|
605 |
-
$message = __( "Bit.ly Login not added - <a href='http://bit.ly/account/'>get one here</a>!
|
606 |
}
|
607 |
}
|
608 |
-
if ( isset( $post['submit-type'] ) && $post['submit-type']
|
609 |
-
if ( $post['googl_api_key']
|
610 |
update_option( 'googl_api_key', trim( $post['googl_api_key'] ) );
|
611 |
-
$message .= __(
|
612 |
} else {
|
613 |
$message = __( "Goo.gl API Key not added - <a href='https://developers.google.com/url-shortener/v1/getting_started'>get one here</a>! ", 'wp-to-twitter' );
|
614 |
-
}
|
615 |
}
|
616 |
-
|
617 |
-
if ( isset( $post['submit-type'] ) && $post['submit-type']
|
618 |
-
if ( $post['joturlapi']
|
619 |
update_option( 'joturlapi', trim( $post['joturlapi'] ) );
|
620 |
-
$message = __(
|
621 |
-
}
|
622 |
update_option( 'joturlapi', '' );
|
623 |
-
$message = __(
|
624 |
} else {
|
625 |
$message = __( "jotURL private API Key not added - <a href='https://www.joturl.com/reserved/api.html'>get one here</a>! A private API key is required to use the jotURL URL shortening service. ", 'wp-to-twitter' );
|
626 |
}
|
627 |
-
if ( $post['joturllogin']
|
628 |
update_option( 'joturllogin', trim( $post['joturllogin'] ) );
|
629 |
-
$message .= __(
|
630 |
-
}
|
631 |
update_option( 'joturllogin', '' );
|
632 |
-
$message = __(
|
633 |
} else {
|
634 |
$message = __( "jotURL public API Key not added - <a href='https://www.joturl.com/reserved/api.html'>get one here</a>! ", 'wp-to-twitter' );
|
635 |
-
}
|
636 |
-
if ( $post['joturl_longurl_params']
|
637 |
$v = trim( $post['joturl_longurl_params'] );
|
638 |
if ( substr( $v, 0, 1 ) == '&' || substr( $v, 0, 1 ) == '?' ) {
|
639 |
$v = substr( $v, 1 );
|
640 |
}
|
641 |
update_option( 'joturl_longurl_params', $v );
|
642 |
-
$message .= __(
|
643 |
-
}
|
644 |
update_option( 'joturl_longurl_params', '' );
|
645 |
-
$message = __(
|
646 |
}
|
647 |
-
if ( $post['joturl_shorturl_params']
|
648 |
$v = trim( $post['joturl_shorturl_params'] );
|
649 |
if ( substr( $v, 0, 1 ) == '&' || substr( $v, 0, 1 ) == '?' ) {
|
650 |
$v = substr( $v, 1 );
|
651 |
}
|
652 |
update_option( 'joturl_shorturl_params', $v );
|
653 |
-
$message .= __(
|
654 |
-
}
|
655 |
update_option( 'joturl_shorturl_params', '' );
|
656 |
-
$message = __(
|
657 |
}
|
658 |
}
|
659 |
-
|
660 |
$message = apply_filters( 'wpt_save_shortener_settings', $message );
|
661 |
|
662 |
return $message;
|
663 |
}
|
664 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
665 |
function wpt_select_shortener( $post ) {
|
666 |
$message = '';
|
667 |
-
// don't return a message if unchanged
|
668 |
-
|
|
|
|
|
669 |
return;
|
670 |
}
|
671 |
update_option( 'jd_shortener', sanitize_key( $post['jd_shortener'] ) );
|
672 |
-
|
673 |
-
$short = get_option( 'jd_shortener' );
|
674 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
675 |
$admin_url = add_query_arg( 'tab', 'shortener', $admin_url );
|
676 |
-
|
677 |
// these are the URL shorteners which require settings.
|
678 |
-
if (
|
|
|
679 |
$message .= sprintf( __( 'You must <a href="%s">configure your URL shortener settings</a>.', 'wp-to-twitter' ), $admin_url );
|
680 |
}
|
681 |
-
|
682 |
-
if (
|
683 |
-
$message .=
|
684 |
}
|
685 |
-
|
686 |
return $message;
|
687 |
}
|
688 |
|
689 |
add_filter( 'wpt_pick_shortener', 'wpt_pick_shortener' );
|
|
|
|
|
|
|
690 |
function wpt_pick_shortener() {
|
691 |
$shortener = get_option( 'jd_shortener' );
|
|
|
|
|
|
|
692 |
?>
|
693 |
<p>
|
694 |
-
<label for="jd_shortener"><?php _e(
|
695 |
<select name="jd_shortener" id="jd_shortener">
|
696 |
-
<option
|
697 |
-
<option value="4" <?php selected( $shortener, '4' ); ?>>WordPress</option>
|
698 |
-
<option value="2" <?php selected( $shortener, '2' ); ?>>Bit.ly</option>
|
|
|
|
|
|
|
699 |
<option value="8" <?php selected( $shortener, '8' ); ?>>Goo.gl</option>
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
<?php
|
704 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
705 |
<option value="10" <?php selected( $shortener, '10' ); ?>>jotURL</option>
|
706 |
-
<?php
|
707 |
-
|
708 |
-
|
709 |
-
echo apply_filters( 'wpt_choose_shortener', '', $shortener );
|
710 |
?>
|
711 |
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
712 |
</p>
|
713 |
<?php
|
714 |
}
|
715 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* URL Shorteners WP to Twitter
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
|
16 |
+
if ( ! function_exists( 'wpt_shorten_url' ) ) {
|
17 |
+
// prep work for future plug-in replacement.
|
18 |
add_filter( 'wptt_shorten_link', 'wpt_shorten_url', 10, 4 );
|
19 |
|
20 |
+
/**
|
21 |
+
* Given a URL, shorten it.
|
22 |
+
*
|
23 |
+
* @param string $url URL.
|
24 |
+
* @param string $post_title Post Title.
|
25 |
+
* @param int $post_ID Post ID.
|
26 |
+
* @param mixed string/boolean $testmode Testing function.
|
27 |
+
* @param boolean $store_urls Whether to store URL after creating.
|
28 |
+
*
|
29 |
+
* @return shortened URL.
|
30 |
+
*/
|
31 |
+
function wpt_shorten_url( $url, $post_title, $post_ID, $testmode = false, $store_urls = true ) {
|
32 |
+
wpt_mail( 'Initial Link', "$url, $post_title, $post_ID, $testmode" ); // DEBUG.
|
33 |
+
// filter link before sending to shortener or adding analytics.
|
34 |
$shortener = get_option( 'jd_shortener' );
|
35 |
+
// if the URL already exists, return it without processing.
|
36 |
+
if ( wpt_short_url( $post_ID ) ) {
|
37 |
+
$shrink = wpt_short_url( $post_ID );
|
38 |
+
|
39 |
return $shrink;
|
40 |
}
|
41 |
$url = apply_filters( 'wpt_shorten_link', $url, $shortener, $post_ID );
|
42 |
+
if ( false == $testmode ) {
|
43 |
+
if ( 1 == get_option( 'use-twitter-analytics' ) || 1 == get_option( 'use_dynamic_analytics' ) ) {
|
44 |
+
if ( '1' == get_option( 'use_dynamic_analytics' ) ) {
|
45 |
$campaign_type = get_option( 'jd_dynamic_analytics' );
|
46 |
+
if ( 'post_category' == $campaign_type && 'link' != $testmode ) {
|
47 |
$category = get_the_category( $post_ID );
|
48 |
$campaign = sanitize_title( $category[0]->cat_name );
|
49 |
+
} elseif ( 'post_ID' == $campaign_type ) {
|
50 |
$campaign = $post_ID;
|
51 |
+
} elseif ( 'post_title' == $campaign_type && 'link' != $testmode ) {
|
52 |
$post = get_post( $post_ID );
|
53 |
$campaign = sanitize_title( $post->post_title );
|
54 |
} else {
|
55 |
+
if ( 'link' != $testmode ) {
|
56 |
$post = get_post( $post_ID );
|
57 |
$post_author = $post->post_author;
|
58 |
$campaign = urlencode( get_the_author_meta( 'user_login', $post_author ) );
|
59 |
} else {
|
60 |
+
$campaign = '';
|
61 |
}
|
62 |
}
|
63 |
} else {
|
65 |
}
|
66 |
$medium = urlencode( trim( apply_filters( 'wpt_utm_medium', 'twitter' ) ) );
|
67 |
$source = urlencode( trim( apply_filters( 'wpt_utm_source', 'twitter' ) ) );
|
68 |
+
$url = add_query_arg( array(
|
69 |
+
'utm_campaign' => $campaign,
|
70 |
+
'utm_medium' => $medium,
|
71 |
+
'utm_source' => $source,
|
72 |
+
), $url );
|
73 |
}
|
74 |
+
$url = urldecode( trim( $url ) ); // prevent double-encoding.
|
75 |
$encoded = urlencode( $url );
|
76 |
} else {
|
77 |
+
$url = urldecode( trim( $url ) ); // prevent double-encoding.
|
78 |
$encoded = urlencode( $url );
|
79 |
}
|
80 |
|
81 |
+
// custom word setting.
|
82 |
+
$keyword_format = ( '1' == get_option( 'jd_keyword_format' ) ) ? $post_ID : '';
|
83 |
+
$keyword_format = ( '2' == get_option( 'jd_keyword_format' ) ) ? get_post_meta( $post_ID, '_yourls_keyword', true ) : $keyword_format;
|
84 |
+
// Generate and grab the short url.
|
85 |
+
$shrink = apply_filters( 'wpt_do_shortening', false, $shortener, $url, $post_title, $post_ID, $testmode );
|
86 |
+
// if an add-on has shortened the link, skip shortening.
|
87 |
$error = false;
|
88 |
+
if ( ! $shrink ) {
|
89 |
switch ( $shortener ) {
|
90 |
+
case 3: // no shortener.
|
91 |
$shrink = $url;
|
92 |
break;
|
93 |
+
case 2: // updated to v3 3/31/2010.
|
94 |
$bitlyapi = trim( get_option( 'bitlyapi' ) );
|
95 |
$bitlylogin = trim( strtolower( get_option( 'bitlylogin' ) ) );
|
96 |
+
$decoded = wpt_remote_json( 'https://api-ssl.bitly.com/v3/shorten?longUrl=' . $encoded . '&login=' . $bitlylogin . '&apiKey=' . $bitlyapi . '&format=json' );
|
97 |
if ( $decoded && isset( $decoded['status_code'] ) ) {
|
98 |
+
if ( 200 != $decoded['status_code'] ) {
|
99 |
$shrink = $url;
|
100 |
$error = $decoded['status_txt'];
|
101 |
} else {
|
111 |
case 4:
|
112 |
if ( function_exists( 'wp_get_shortlink' ) ) {
|
113 |
// wp_get_shortlink doesn't natively support custom post types; but don't return an error in that case.
|
114 |
+
$shrink = ( false != $post_ID ) ? wp_get_shortlink( $post_ID, 'post' ) : $url;
|
115 |
}
|
116 |
if ( ! $shrink ) {
|
117 |
$shrink = $url;
|
118 |
}
|
119 |
+
break;
|
120 |
case 5:
|
121 |
+
// local YOURLS installation.
|
122 |
+
define( 'YOURLS_INSTALLING', true ); // Pretend we're installing YOURLS to bypass test for install or upgrade.
|
123 |
+
define( 'YOURLS_FLOOD_DELAY_SECONDS', 0 ); // Disable flood check.
|
|
|
124 |
$opath = get_option( 'yourlspath' );
|
125 |
$ypath = str_replace( 'user', 'includes', $opath );
|
126 |
+
if ( file_exists( dirname( $ypath ) . '/load-yourls.php' ) ) { // YOURLS 1.4+.
|
127 |
require_once( dirname( $ypath ) . '/load-yourls.php' );
|
128 |
global $ydb;
|
129 |
if ( function_exists( 'yourls_add_new_link' ) ) {
|
130 |
+
$yourls_result = yourls_add_new_link( $url, $keyword_format, $post_title );
|
131 |
} else {
|
132 |
$yourls_result = $url;
|
133 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
}
|
135 |
if ( $yourls_result ) {
|
136 |
$shrink = $yourls_result['shorturl'];
|
139 |
}
|
140 |
break;
|
141 |
case 6:
|
142 |
+
// remote YOURLS installation.
|
143 |
$yourlslogin = trim( get_option( 'yourlslogin' ) );
|
144 |
$yourlsapi = stripcslashes( get_option( 'yourlsapi' ) );
|
145 |
$token = stripcslashes( get_option( 'yourlstoken' ) );
|
149 |
'signature' => $token,
|
150 |
'url' => $encoded,
|
151 |
'action' => 'shorturl',
|
152 |
+
'format' => 'json',
|
153 |
+
'title' => urlencode( $post_title ),
|
154 |
);
|
155 |
} else {
|
156 |
$args = array(
|
158 |
'password' => $yourlsapi,
|
159 |
'url' => $encoded,
|
160 |
'action' => 'shorturl',
|
161 |
+
'format' => 'json',
|
162 |
+
'title' => urlencode( $post_title ),
|
163 |
);
|
164 |
}
|
165 |
if ( $keyword_format ) {
|
166 |
$args['keyword'] = $keyword_format;
|
167 |
}
|
168 |
+
|
169 |
$api_url = add_query_arg( $args, $yourlsurl );
|
170 |
+
|
171 |
$json = wpt_remote_json( $api_url, false );
|
172 |
+
wpt_mail( 'YOURLS JSON Response', print_r( $json, 1 ) ); // DEBUG YOURLS response.
|
173 |
if ( is_object( $json ) ) {
|
174 |
$shrink = $json->shorturl;
|
175 |
} else {
|
176 |
+
$error = 'Error code: ' . $json->shorturl . ' ' . $json->message;
|
177 |
$shrink = false;
|
178 |
}
|
179 |
break;
|
180 |
case 7:
|
181 |
$suprapi = trim( get_option( 'suprapi' ) );
|
182 |
$suprlogin = trim( get_option( 'suprlogin' ) );
|
183 |
+
if ( '' != $suprapi ) {
|
184 |
+
$decoded = wpt_remote_json( 'http://su.pr/api/shorten?longUrl=' . $encoded . '&login=' . $suprlogin . '&apiKey=' . $suprapi );
|
185 |
} else {
|
186 |
+
$decoded = wpt_remote_json( 'http://su.pr/api/shorten?longUrl=' . $encoded );
|
187 |
}
|
188 |
if ( $decoded && isset( $decoded['statusCode'] ) ) {
|
189 |
+
if ( 'OK' == $decoded['statusCode'] ) {
|
190 |
+
$page = str_replace( '&', '&', urldecode( $url ) );
|
191 |
$shrink = $decoded['results'][ $page ]['shortUrl'];
|
192 |
$error = $decoded['errorMessage'];
|
193 |
} else {
|
203 |
}
|
204 |
break;
|
205 |
case 8:
|
206 |
+
// Goo.gl.
|
207 |
+
$googl_api_key = ( '' == get_option( 'googl_api_key' ) ) ? 'AIzaSyBSnqQOg3vX1gwR7y2l-40yEG9SZiaYPUQ' : get_option( 'googl_api_key' );
|
208 |
+
$target = "https://www.googleapis.com/urlshortener/v1/url?key=$googl_api_key";
|
209 |
+
$body = "{'longUrl':'$url'}";
|
210 |
+
$json = wpt_fetch_url( $target, 'POST', $body, 'Content-Type: application/json' );
|
211 |
+
$decoded = json_decode( $json );
|
212 |
+
$shrink = $decoded->id;
|
213 |
if ( ! wpt_is_valid_url( $shrink ) ) {
|
214 |
$shrink = false;
|
215 |
}
|
216 |
break;
|
217 |
case 9:
|
218 |
+
// Twitter Friendly Links. This plugin not updated in 8 years.
|
219 |
$shrink = $url;
|
|
|
|
|
|
|
220 |
break;
|
221 |
+
case 10:
|
222 |
+
// jotURL, added: 2013-04-10.
|
223 |
$joturlapi = trim( get_option( 'joturlapi' ) );
|
224 |
$joturllogin = trim( get_option( 'joturllogin' ) );
|
225 |
$joturl_longurl_params = trim( get_option( 'joturl_longurl_params' ) );
|
226 |
+
if ( '' != $joturl_longurl_params ) {
|
227 |
+
if ( false === strpos( $url, '%3F' ) && false == strpos( $url, '?' ) ) {
|
228 |
+
$ct = '?';
|
229 |
} else {
|
230 |
+
$ct = '&';
|
231 |
}
|
232 |
+
$url .= $ct . $joturl_longurl_params;
|
233 |
+
$encoded = urlencode( urldecode( trim( $url ) ) ); // prevent double-encoding.
|
234 |
}
|
235 |
+
$decoded = wpt_fetch_url( 'https://api.joturl.com/a/v1/shorten?url=' . $encoded . '&login=' . $joturllogin . '&key=' . $joturlapi . '&format=plain' );
|
236 |
+
if ( false !== $decoded ) {
|
237 |
+
$shrink = $decoded;
|
|
|
|
|
238 |
$joturl_shorturl_params = trim( get_option( 'joturl_shorturl_params' ) );
|
239 |
+
if ( '' != $joturl_shorturl_params ) {
|
240 |
+
if ( false === strpos( $shrink, '%3F' ) && false === strpos( $shrink, '?' ) ) {
|
241 |
+
$ct = '?';
|
242 |
} else {
|
243 |
+
$ct = '&';
|
244 |
}
|
245 |
$shrink .= $ct . $joturl_shorturl_params;
|
246 |
}
|
|
|
247 |
} else {
|
248 |
$error = $decoded;
|
249 |
$shrink = false;
|
252 |
$shrink = false;
|
253 |
}
|
254 |
break;
|
255 |
+
default:
|
256 |
+
$shrink = $url;
|
257 |
}
|
258 |
}
|
259 |
if ( $error ) {
|
260 |
update_option( 'wpt_shortener_status', "$shrink : $error" );
|
261 |
}
|
262 |
if ( ! $testmode ) {
|
263 |
+
if ( false === $shrink || ( false === filter_var( $shrink, FILTER_VALIDATE_URL ) ) ) {
|
264 |
update_option( 'wp_url_failure', '1' );
|
265 |
$shrink = urldecode( $url );
|
266 |
} else {
|
274 |
|
275 |
return $shrink;
|
276 |
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Store shortened URL for re-use.
|
280 |
+
*
|
281 |
+
* @param int $post_ID Post ID.
|
282 |
+
* @param string $url Shortened URL.
|
283 |
+
*/
|
284 |
function wpt_store_url( $post_ID, $url ) {
|
285 |
$store_urls = apply_filters( 'wpt_store_urls', true, $post_ID, $url );
|
286 |
+
if ( function_exists( 'wpt_shorten_url' ) && $store_urls ) {
|
287 |
$shortener = get_option( 'jd_shortener' );
|
288 |
+
if ( wpt_short_url( $post_ID ) != $url && wpt_is_valid_url( $url ) ) {
|
289 |
update_post_meta( $post_ID, '_wpt_short_url', $url );
|
290 |
}
|
291 |
switch ( $shortener ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
292 |
case 5:
|
293 |
case 6:
|
294 |
$target = wpt_expand_yourl( $url, $shortener );
|
301 |
}
|
302 |
update_post_meta( $post_ID, '_wp_jd_target', $target );
|
303 |
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Expand a saved YOURL URl.
|
307 |
+
*
|
308 |
+
* @param string $short_url Shortened URL.
|
309 |
+
* @param int $remote Remote or local install.
|
310 |
+
*
|
311 |
+
* @return long url.
|
312 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
function wpt_expand_yourl( $short_url, $remote ) {
|
314 |
+
if ( 6 == $remote ) {
|
315 |
$short_url = urlencode( $short_url );
|
316 |
$yourl_api = get_option( 'yourlsurl' );
|
317 |
$user = get_option( 'yourlslogin' );
|
318 |
+
$pass = stripslashes( get_option( 'yourlsapi' ) );
|
319 |
$token = get_option( 'yourlstoken' );
|
320 |
if ( $token ) {
|
321 |
$decoded = wpt_remote_json( $yourl_api . "?action=expand&shorturl=$short_url&format=json&signature=$token&username=$user&password=$pass" );
|
326 |
|
327 |
return $url;
|
328 |
} else {
|
329 |
+
define( 'YOURLS_INSTALLING', true ); // Pretend we're installing YOURLS to bypass test for install or upgrade.
|
330 |
+
define( 'YOURLS_FLOOD_DELAY_SECONDS', 0 ); // Disable flood check.
|
331 |
+
if ( file_exists( dirname( get_option( 'yourlspath' ) ) . '/load-yourls.php' ) ) { // YOURLS 1.4+.
|
|
|
332 |
global $ydb;
|
333 |
require_once( dirname( get_option( 'yourlspath' ) ) . '/load-yourls.php' );
|
334 |
$yourls_result = yourls_api_expand( $short_url );
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
}
|
336 |
if ( $yourls_result ) {
|
337 |
$url = $yourls_result['longurl'];
|
343 |
}
|
344 |
|
345 |
add_filter( 'wpt_shortener_controls', 'wpt_shortener_controls' );
|
346 |
+
/**
|
347 |
+
* Controls for adding shortener relevant data.
|
348 |
+
*/
|
349 |
function wpt_shortener_controls() {
|
350 |
+
$shortener = get_option( 'jd_shortener' );
|
351 |
+
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
352 |
$form_start = '<div class="panel">
|
353 |
<form method="post" action="' . add_query_arg( 'tab', 'shortener', $admin_url ) . '">
|
354 |
<div><input type="hidden" name="wpt_shortener_update" value="true" /></div>
|
355 |
<div>';
|
356 |
+
$nonce = wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false );
|
357 |
+
$form_end = '<div>' . $nonce . '</div>
|
358 |
+
<p>
|
359 |
+
<input type="submit" name="submit" value="' . __( 'Save URL Shortener Settings', 'wp-to-twitter' ) . '" class="button-primary" />
|
360 |
+
</p>
|
361 |
+
</div>
|
362 |
+
</form>
|
363 |
+
</div>';
|
364 |
// for the moment, this just displays the fields. Eventually, a real filter.
|
365 |
?>
|
366 |
<div class="ui-sortable meta-box-sortables">
|
370 |
</h3>
|
371 |
|
372 |
<div class="inside">
|
373 |
+
<?php
|
374 |
+
if ( 7 == $shortener ) {
|
375 |
+
?>
|
376 |
<?php echo $form_start; ?>
|
377 |
<p>
|
378 |
<label
|
379 |
+
for="suprlogin"><?php _e( 'Your Su.pr Username:', 'wp-to-twitter' ); ?></label>
|
380 |
+
<input type="text" name="suprlogin" id="suprlogin" size="40" value="<?php echo esc_attr( get_option( 'suprlogin' ) ); ?> "/>
|
|
|
381 |
</p>
|
|
|
382 |
<p>
|
383 |
<label
|
384 |
for="suprapi"><?php _e( "Your Su.pr <abbr title='application programming interface'>API</abbr> Key:", 'wp-to-twitter' ); ?></label>
|
385 |
+
<input type="text" name="suprapi" id="suprapi" size="40" value="<?php echo esc_attr( get_option( 'suprapi' ) ); ?> "/>
|
|
|
386 |
</p>
|
387 |
|
388 |
<div>
|
389 |
<input type="hidden" name="submit-type" value="suprapi"/>
|
390 |
</div>
|
391 |
<p><small><?php _e( "Don't have a Su.pr account or API key? <a href='http://su.pr/'>Get one here!</a> You'll need an API key in order to associate the URLs you create with your Su.pr account.", 'wp-to-twitter' ); ?></small></p>
|
392 |
+
<?php echo $form_end; ?>
|
393 |
+
<?php
|
394 |
+
} elseif ( 2 == $shortener ) {
|
395 |
+
echo $form_start;
|
396 |
+
?>
|
397 |
<p>
|
398 |
+
<label for="bitlylogin"><?php _e( 'Your Bit.ly username:', 'wp-to-twitter' ); ?></label>
|
399 |
+
<input type="text" name="bitlylogin" id="bitlylogin" value="<?php echo esc_attr( get_option( 'bitlylogin' ) ); ?>"/>
|
|
|
|
|
400 |
</p>
|
401 |
<p>
|
402 |
+
<label for="bitlyapi"><?php _e( "Your Bit.ly <abbr title='application programming interface'>API</abbr> Key:", 'wp-to-twitter' ); ?></label>
|
403 |
+
<input type="text" name="bitlyapi" id="bitlyapi" size="40" value="<?php echo esc_attr( get_option( 'bitlyapi' ) ); ?>"/>
|
|
|
|
|
404 |
</p>
|
|
|
405 |
<p>
|
406 |
<a href="http://bitly.com/a/your_api_key"><?php _e( 'View your Bit.ly username and API key', 'wp-to-twitter' ); ?></a>
|
407 |
</p>
|
|
|
408 |
<div>
|
409 |
<input type="hidden" name="submit-type" value="bitlyapi"/>
|
410 |
</div>
|
411 |
+
<?php
|
412 |
+
echo $form_end;
|
413 |
+
} elseif ( 5 == $shortener || 6 == $shortener ) {
|
414 |
+
echo $form_start;
|
415 |
+
if ( 5 == $shortener ) {
|
416 |
+
?>
|
417 |
<p>
|
418 |
+
<label for="yourlspath"><?php _e( 'Path to your YOURLS config file', 'wp-to-twitter' ); ?></label><br/>
|
419 |
+
<input type="text" id="yourlspath" name="yourlspath" size="60" value="<?php echo esc_attr( get_option( 'yourlspath' ) ); ?>"/><br/>
|
|
|
|
|
420 |
<small><?php _e( 'Example:', 'wp-to-twitter' ); ?> <code>/home/username/www/www/yourls/user/config.php</code>
|
421 |
</small>
|
422 |
</p>
|
423 |
+
<?php
|
424 |
+
}
|
425 |
+
if ( 6 == $shortener ) {
|
426 |
+
?>
|
427 |
<p>
|
428 |
+
<label for="yourlsurl"><?php _e( 'URI to the YOURLS API', 'wp-to-twitter' ); ?></label><br/>
|
429 |
+
<input type="text" id="yourlsurl" name="yourlsurl" size="60" value="<?php echo esc_attr( get_option( 'yourlsurl' ) ); ?>"/><br/>
|
|
|
|
|
430 |
<small><?php _e( 'Example:', 'wp-to-twitter' ); ?> <code>http://domain.com/yourls-api.php</code>
|
431 |
</small>
|
432 |
</p>
|
433 |
+
<?php
|
434 |
+
}
|
435 |
+
?>
|
436 |
<p>
|
437 |
+
<label for="yourlstoken"><?php _e( 'YOURLS signature token:', 'wp-to-twitter' ); ?></label>
|
438 |
+
<input type="text" name="yourlstoken" id="yourlstoken" size="30" value="<?php echo esc_attr( get_option( 'yourlstoken' ) ); ?>"/>
|
|
|
|
|
439 |
</p>
|
440 |
+
<?php
|
441 |
+
if ( get_option( 'yourlsapi' ) && get_option( 'yourlslogin' ) ) {
|
442 |
+
?>
|
443 |
<p>
|
444 |
<em><?php _e( 'Your YOURLS username and password are saved. If you add a signature token, that will be used for API calls and your username and password will be deleted from the database.', 'wp-to-twitter' ); ?></em>
|
445 |
</p>
|
446 |
+
<?php
|
447 |
+
}
|
448 |
+
?>
|
449 |
<p>
|
450 |
+
<input type="radio" name="jd_keyword_format" id="jd_keyword_id" value="1" <?php checked( get_option( 'jd_keyword_format' ), 1 ); ?> />
|
451 |
+
<label for="jd_keyword_id"><?php _e( 'Post ID for YOURLS url slug.', 'wp-to-twitter' ); ?></label><br/>
|
452 |
+
<input type="radio" name="jd_keyword_format" id="jd_keyword" value="2" <?php checked( get_option( 'jd_keyword_format' ), 2 ); ?> />
|
453 |
+
<label for="jd_keyword"><?php _e( 'Custom keyword for YOURLS url slug.', 'wp-to-twitter' ); ?></label><br/>
|
454 |
+
<input type="radio" name="jd_keyword_format" id="jd_keyword_default" value="0" <?php checked( get_option( 'jd_keyword_format' ), 0 ); ?> />
|
455 |
+
<label for="jd_keyword_default"><?php _e( 'Default: sequential URL numbering.', 'wp-to-twitter' ); ?></label>
|
|
|
|
|
|
|
|
|
|
|
|
|
456 |
</p>
|
|
|
457 |
<div>
|
458 |
<input type="hidden" name="submit-type" value="yourlsapi" />
|
459 |
</div>
|
460 |
+
<?php
|
461 |
+
echo $form_end;
|
462 |
+
} elseif ( 8 == $shortener ) {
|
463 |
+
echo '<p>' . __( 'The Goo.gl URL shortener will be shut down by Google on March 30th, 2019, and will be removed from WP to Twitter in the near future.', 'wp-to-twitter' ) . '</p>';
|
464 |
+
echo $form_start;
|
465 |
+
?>
|
466 |
<p>
|
467 |
+
<label for="googl_api_key"><?php _e( 'Goo.gl API Key:', 'wp-to-twitter' ); ?></label>
|
468 |
+
<input type="text" name="googl_api_key" id="googl_api_key" value="<?php echo esc_attr( get_option( 'googl_api_key' ) ); ?>"/>
|
469 |
</p>
|
|
|
470 |
<div><input type="hidden" name="submit-type" value="googlapi" /></div>
|
471 |
+
<?php
|
472 |
+
echo $form_end;
|
473 |
+
} elseif ( 10 == $shortener ) {
|
474 |
+
echo $form_start;
|
475 |
+
?>
|
476 |
<p>
|
477 |
+
<label for="joturllogin"><?php _e( "Your jotURL public <abbr title='application programming interface'>API</abbr> key:", 'wp-to-twitter' ); ?></label>
|
478 |
+
<input type="text" name="joturllogin" id="joturllogin" value="<?php echo esc_attr( get_option( 'joturllogin' ) ); ?>"/>
|
|
|
|
|
479 |
</p>
|
|
|
480 |
<p>
|
481 |
+
<label for="joturlapi"><?php _e( "Your jotURL private <abbr title='application programming interface'>API</abbr> key:", 'wp-to-twitter' ); ?></label>
|
482 |
+
<input type="text" name="joturlapi" id="joturlapi" size="40" value="<?php echo esc_attr( get_option( 'joturlapi' ) ); ?>"/>
|
|
|
|
|
483 |
</p>
|
|
|
484 |
<p>
|
485 |
+
<label for="joturl_longurl_params"><?php _e( 'Parameters to add to the long URL (before shortening):', 'wp-to-twitter' ); ?></label>
|
486 |
+
<input type="text" name="joturl_longurl_params" id="joturl_longurl_params" size="40" value="<?php echo esc_attr( get_option( 'joturl_longurl_params' ) ); ?>"/>
|
|
|
|
|
|
|
487 |
</p>
|
488 |
|
489 |
<p>
|
490 |
+
<label for="joturl_shorturl_params"><?php _e( 'Parameters to add to the short URL (after shortening):', 'wp-to-twitter' ); ?></label>
|
491 |
+
<input type="text" name="joturl_shorturl_params" id="joturl_shorturl_params" size="40" value="<?php echo esc_attr( get_option( 'joturl_shorturl_params' ) ); ?>"/>
|
|
|
|
|
|
|
492 |
</p>
|
|
|
493 |
<p>
|
494 |
<a href="https://www.joturl.com/reserved/api.html"><?php _e( 'View your jotURL public and private API key', 'wp-to-twitter' ); ?></a>
|
495 |
</p>
|
|
|
496 |
<div><input type="hidden" name="submit-type" value="joturlapi"/></div>
|
497 |
+
<?php
|
498 |
+
echo $form_end;
|
499 |
} else {
|
500 |
$form = apply_filters( 'wpt_shortener_settings', '', $shortener );
|
501 |
+
if ( '' != $form ) {
|
502 |
echo $form_start . $form . $form_end;
|
503 |
} else {
|
504 |
_e( 'Your shortener does not require any account settings.', 'wp-to-twitter' );
|
505 |
}
|
506 |
+
}
|
507 |
+
?>
|
508 |
</div>
|
509 |
</div>
|
510 |
</div>
|
511 |
<?php
|
512 |
}
|
513 |
|
514 |
+
/**
|
515 |
+
* Update settings for shorteners.
|
516 |
+
*
|
517 |
+
* @param array $post POST data.
|
518 |
+
*/
|
519 |
function wpt_shortener_update( $post ) {
|
520 |
$message = '';
|
521 |
+
if ( isset( $post['submit-type'] ) && 'yourlsapi' == $post['submit-type'] ) {
|
522 |
$message = '';
|
523 |
+
if ( '' != $post['yourlstoken'] && isset( $post['submit'] ) ) {
|
524 |
update_option( 'yourlstoken', trim( $post['yourlstoken'] ) );
|
525 |
delete_option( 'yourlsapi' );
|
526 |
delete_option( 'yourlslogin' );
|
528 |
}
|
529 |
update_option( 'yourlsurl', trim( $post['yourlsurl'] ) );
|
530 |
// yourls path is deprecated.
|
531 |
+
if ( isset( $post['yourlspath'] ) && '' != $post['yourlspath'] ) {
|
532 |
update_option( 'yourlspath', trim( $post['yourlspath'] ) );
|
533 |
if ( file_exists( $post['yourlspath'] ) ) {
|
534 |
+
$message .= ' ' . __( 'YOURLS local server path added. ', 'wp-to-twitter' );
|
535 |
} else {
|
536 |
+
$message .= ' ' . __( 'The path to your YOURLS installation is not correct. ', 'wp-to-twitter' );
|
537 |
}
|
538 |
}
|
539 |
+
if ( '' != $post['jd_keyword_format'] ) {
|
540 |
update_option( 'jd_keyword_format', $post['jd_keyword_format'] );
|
541 |
+
if ( 1 == $post['jd_keyword_format'] ) {
|
542 |
+
$message .= ' ' . __( 'YOURLS will use Post ID for short URL slug.', 'wp-to-twitter' );
|
543 |
+
} elseif ( 0 == $post['jd_keyword_format'] ) {
|
544 |
$message .= ' ' . __( 'YOURLS will use default URL structures.', 'wp-to-twitter' );
|
545 |
} else {
|
546 |
+
$message .= ' ' . __( 'YOURLS will use your custom keyword for short URL slug.', 'wp-to-twitter' );
|
547 |
}
|
548 |
}
|
549 |
if ( isset( $post['clear'] ) ) {
|
557 |
}
|
558 |
}
|
559 |
|
560 |
+
if ( isset( $post['submit-type'] ) && 'suprapi' == $post['submit-type'] ) {
|
561 |
+
if ( '' != $post['suprapi'] && isset( $post['submit'] ) ) {
|
562 |
update_option( 'suprapi', trim( $post['suprapi'] ) );
|
563 |
update_option( 'suprlogin', trim( $post['suprlogin'] ) );
|
564 |
+
$message = __( 'Su.pr API Key and Username Updated', 'wp-to-twitter' );
|
565 |
+
} elseif ( isset( $post['clear'] ) ) {
|
566 |
update_option( 'suprapi', '' );
|
567 |
update_option( 'suprlogin', '' );
|
568 |
+
$message = __( 'Su.pr API Key and username deleted. Su.pr URLs created by WP to Twitter will no longer be associated with your account.', 'wp-to-twitter' );
|
569 |
} else {
|
570 |
+
$message = __( "Su.pr API Key not added - <a href='http://su.pr/'>get one here</a>!", 'wp-to-twitter' );
|
571 |
}
|
572 |
}
|
573 |
+
|
574 |
+
if ( isset( $post['submit-type'] ) && 'bitlyapi' == $post['submit-type'] ) {
|
575 |
+
if ( '' != $post['bitlyapi'] && isset( $post['submit'] ) ) {
|
576 |
update_option( 'bitlyapi', trim( $post['bitlyapi'] ) );
|
577 |
+
$message = __( 'Bit.ly API Key Updated.', 'wp-to-twitter' );
|
578 |
+
} elseif ( isset( $post['clear'] ) ) {
|
579 |
update_option( 'bitlyapi', '' );
|
580 |
+
$message = __( 'Bit.ly API Key deleted. You cannot use the Bit.ly API without an API key.', 'wp-to-twitter' );
|
581 |
} else {
|
582 |
$message = __( "Bit.ly API Key not added - <a href='http://bit.ly/account/'>get one here</a>! An API key is required to use the Bit.ly URL shortening service.", 'wp-to-twitter' );
|
583 |
}
|
584 |
+
if ( '' != $post['bitlylogin'] && isset( $post['submit'] ) ) {
|
585 |
update_option( 'bitlylogin', trim( $post['bitlylogin'] ) );
|
586 |
+
$message .= __( 'Bit.ly User Login Updated.', 'wp-to-twitter' );
|
587 |
+
} elseif ( isset( $post['clear'] ) ) {
|
588 |
update_option( 'bitlylogin', '' );
|
589 |
+
$message = __( 'Bit.ly User Login deleted. You cannot use the Bit.ly API without providing your username.', 'wp-to-twitter' );
|
590 |
} else {
|
591 |
+
$message = __( "Bit.ly Login not added - <a href='http://bit.ly/account/'>get one here</a>!", 'wp-to-twitter' );
|
592 |
}
|
593 |
}
|
594 |
+
if ( isset( $post['submit-type'] ) && 'googlapi' == $post['submit-type'] ) {
|
595 |
+
if ( '' != $post['googl_api_key'] && isset( $post['submit'] ) ) {
|
596 |
update_option( 'googl_api_key', trim( $post['googl_api_key'] ) );
|
597 |
+
$message .= __( 'Goo.gl API Key Updated.', 'wp-to-twitter' );
|
598 |
} else {
|
599 |
$message = __( "Goo.gl API Key not added - <a href='https://developers.google.com/url-shortener/v1/getting_started'>get one here</a>! ", 'wp-to-twitter' );
|
600 |
+
}
|
601 |
}
|
602 |
+
|
603 |
+
if ( isset( $post['submit-type'] ) && 'joturlapi' == $post['submit-type'] ) {
|
604 |
+
if ( '' != $post['joturlapi'] && isset( $post['submit'] ) ) {
|
605 |
update_option( 'joturlapi', trim( $post['joturlapi'] ) );
|
606 |
+
$message = __( 'jotURL private API Key Updated.', 'wp-to-twitter' );
|
607 |
+
} elseif ( isset( $post['clear'] ) ) {
|
608 |
update_option( 'joturlapi', '' );
|
609 |
+
$message = __( 'jotURL private API Key deleted. You cannot use the jotURL API without a private API key.', 'wp-to-twitter' );
|
610 |
} else {
|
611 |
$message = __( "jotURL private API Key not added - <a href='https://www.joturl.com/reserved/api.html'>get one here</a>! A private API key is required to use the jotURL URL shortening service. ", 'wp-to-twitter' );
|
612 |
}
|
613 |
+
if ( '' != $post['joturllogin'] && isset( $post['submit'] ) ) {
|
614 |
update_option( 'joturllogin', trim( $post['joturllogin'] ) );
|
615 |
+
$message .= __( 'jotURL public API Key Updated.', 'wp-to-twitter' );
|
616 |
+
} elseif ( isset( $post['clear'] ) ) {
|
617 |
update_option( 'joturllogin', '' );
|
618 |
+
$message = __( 'jotURL public API Key deleted. You cannot use the jotURL API without providing your public API Key.', 'wp-to-twitter' );
|
619 |
} else {
|
620 |
$message = __( "jotURL public API Key not added - <a href='https://www.joturl.com/reserved/api.html'>get one here</a>! ", 'wp-to-twitter' );
|
621 |
+
}
|
622 |
+
if ( '' != $post['joturl_longurl_params'] && isset( $post['submit'] ) ) {
|
623 |
$v = trim( $post['joturl_longurl_params'] );
|
624 |
if ( substr( $v, 0, 1 ) == '&' || substr( $v, 0, 1 ) == '?' ) {
|
625 |
$v = substr( $v, 1 );
|
626 |
}
|
627 |
update_option( 'joturl_longurl_params', $v );
|
628 |
+
$message .= __( 'Long URL parameters added.', 'wp-to-twitter' );
|
629 |
+
} elseif ( isset( $post['clear'] ) ) {
|
630 |
update_option( 'joturl_longurl_params', '' );
|
631 |
+
$message = __( 'Long URL parameters deleted.', 'wp-to-twitter' );
|
632 |
}
|
633 |
+
if ( '' != $post['joturl_shorturl_params'] && isset( $post['submit'] ) ) {
|
634 |
$v = trim( $post['joturl_shorturl_params'] );
|
635 |
if ( substr( $v, 0, 1 ) == '&' || substr( $v, 0, 1 ) == '?' ) {
|
636 |
$v = substr( $v, 1 );
|
637 |
}
|
638 |
update_option( 'joturl_shorturl_params', $v );
|
639 |
+
$message .= __( 'Short URL parameters added.', 'wp-to-twitter' );
|
640 |
+
} elseif ( isset( $post['clear'] ) ) {
|
641 |
update_option( 'joturl_shorturl_params', '' );
|
642 |
+
$message = __( 'Short URL parameters deleted.', 'wp-to-twitter' );
|
643 |
}
|
644 |
}
|
|
|
645 |
$message = apply_filters( 'wpt_save_shortener_settings', $message );
|
646 |
|
647 |
return $message;
|
648 |
}
|
649 |
|
650 |
+
/**
|
651 |
+
* Select a shortener.
|
652 |
+
*
|
653 |
+
* @param array $post POST data.
|
654 |
+
*
|
655 |
+
* @return message.
|
656 |
+
*/
|
657 |
function wpt_select_shortener( $post ) {
|
658 |
$message = '';
|
659 |
+
// don't return a message if unchanged.
|
660 |
+
$stored = ( isset( $_POST['wpt_use_stored_urls'] ) ) ? 'false' : 'true';
|
661 |
+
update_option( 'wpt_use_stored_urls', $stored );
|
662 |
+
if ( get_option( 'jd_shortener' ) == $post['jd_shortener'] ) {
|
663 |
return;
|
664 |
}
|
665 |
update_option( 'jd_shortener', sanitize_key( $post['jd_shortener'] ) );
|
666 |
+
$short = get_option( 'jd_shortener' );
|
|
|
667 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
668 |
$admin_url = add_query_arg( 'tab', 'shortener', $admin_url );
|
669 |
+
|
670 |
// these are the URL shorteners which require settings.
|
671 |
+
if ( 2 == $short || 10 == $short || 6 == $short ) {
|
672 |
+
// Translators: Settings URL for shortener configuration.
|
673 |
$message .= sprintf( __( 'You must <a href="%s">configure your URL shortener settings</a>.', 'wp-to-twitter' ), $admin_url );
|
674 |
}
|
675 |
+
|
676 |
+
if ( '' != $message ) {
|
677 |
+
$message .= '<br />';
|
678 |
}
|
679 |
+
|
680 |
return $message;
|
681 |
}
|
682 |
|
683 |
add_filter( 'wpt_pick_shortener', 'wpt_pick_shortener' );
|
684 |
+
/**
|
685 |
+
* Form to select your shortener.
|
686 |
+
*/
|
687 |
function wpt_pick_shortener() {
|
688 |
$shortener = get_option( 'jd_shortener' );
|
689 |
+
if ( 8 == $shortener ) {
|
690 |
+
echo '<p>' . __( 'The Goo.gl URL shortener will be shut down by Google on March 30th, 2019, and will be removed from WP to Twitter in the near future.', 'wp-to-twitter' ) . '</p>';
|
691 |
+
}
|
692 |
?>
|
693 |
<p>
|
694 |
+
<label for="jd_shortener"><?php _e( 'Choose a URL shortener', 'wp-to-twitter' ); ?></label>
|
695 |
<select name="jd_shortener" id="jd_shortener">
|
696 |
+
<option value="3" <?php selected( $shortener, '3' ); ?>><?php _e( "Don't shorten URLs.", 'wp-to-twitter' ); ?></option>
|
697 |
+
<option value="4" <?php selected( $shortener, '4' ); ?>>WordPress</option>
|
698 |
+
<option value="2" <?php selected( $shortener, '2' ); ?>>Bit.ly</option>
|
699 |
+
<?php
|
700 |
+
if ( 8 == $shortener ) { // if already selected, leave available.
|
701 |
+
?>
|
702 |
<option value="8" <?php selected( $shortener, '8' ); ?>>Goo.gl</option>
|
703 |
+
<?php
|
704 |
+
}
|
705 |
+
?>
|
706 |
+
<option value="7" <?php selected( $shortener, '7' ); ?>>Su.pr</option>
|
707 |
+
<?php
|
708 |
+
if ( 5 == $shortener ) { // if the user has already selected local server, leave available.
|
709 |
+
?>
|
710 |
+
<option value="5" <?php selected( $shortener, '5' ); ?>><?php _e( 'YOURLS (this server)', 'wp-to-twitter' ); ?></option>
|
711 |
+
<?php
|
712 |
+
}
|
713 |
+
?>
|
714 |
+
<option value="6" <?php selected( $shortener, '6' ); ?>><?php _e( 'YOURLS (remote server)', 'wp-to-twitter' ); ?></option>
|
715 |
<option value="10" <?php selected( $shortener, '10' ); ?>>jotURL</option>
|
716 |
+
<?php
|
717 |
+
// Add a custom shortener.
|
718 |
+
echo apply_filters( 'wpt_choose_shortener', '', $shortener );
|
|
|
719 |
?>
|
720 |
</select>
|
721 |
+
<?php
|
722 |
+
if ( 3 != $shortener ) {
|
723 |
+
?>
|
724 |
+
<input type='checkbox' value='false' name='wpt_use_stored_urls' id='wpt_use_stored_urls' <?php checked( get_option( 'wpt_use_stored_urls' ), 'false' ); ?>> <label for='wpt_use_stored_urls'><?php _e( 'Always request a new short URL for Tweets', 'wp-to-twitter' ); ?></label>
|
725 |
+
<?php
|
726 |
+
}
|
727 |
+
?>
|
728 |
</p>
|
729 |
<?php
|
730 |
}
|
731 |
+
}
|
wp-to-twitter.php
CHANGED
@@ -1,57 +1,87 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/*
|
3 |
-
|
4 |
-
Plugin URI: http://www.joedolson.com/wp-to-twitter/
|
5 |
-
Description: Posts a Tweet when you update your WordPress blog or post a link, using your URL shortening service. Rich in features for customizing and promoting your Tweets.
|
6 |
-
Version: 3.3.2
|
7 |
-
Author: Joseph Dolson
|
8 |
-
Text Domain: wp-to-twitter
|
9 |
-
Author URI: http://www.joedolson.com/
|
10 |
-
*/
|
11 |
-
/* Copyright 2008-2017 Joseph C Dolson (email : plugins@joedolson.com)
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
*/
|
27 |
if ( ! defined( 'ABSPATH' ) ) {
|
28 |
exit;
|
29 |
-
}
|
30 |
|
31 |
-
define( 'WPT_DEBUG', false ); // Debugging only works with WP Tweets PRO.
|
32 |
-
define( 'WPT_DEBUG_BY_EMAIL', false ); // Email debugging no longer default as of 3.3.0
|
33 |
define( 'WPT_DEBUG_ADDRESS', get_option( 'admin_email' ) );
|
34 |
-
define( 'WPT_FROM',
|
35 |
-
|
36 |
-
|
37 |
-
require_once( plugin_dir_path( __FILE__ ) . '
|
38 |
-
require_once( plugin_dir_path( __FILE__ ) . '
|
39 |
-
require_once( plugin_dir_path( __FILE__ ) . '
|
40 |
-
require_once( plugin_dir_path( __FILE__ ) . '
|
41 |
-
require_once( plugin_dir_path( __FILE__ ) . '/wpt-
|
42 |
-
require_once( plugin_dir_path( __FILE__ ) . '
|
43 |
-
require_once( plugin_dir_path( __FILE__ ) . '
|
44 |
-
require_once( plugin_dir_path( __FILE__ ) . '/wpt-rate-limiting.php' );
|
45 |
|
46 |
global $wpt_version;
|
47 |
-
$wpt_version =
|
48 |
|
49 |
add_action( 'init', 'wpt_load_textdomain' );
|
|
|
|
|
|
|
50 |
function wpt_load_textdomain() {
|
51 |
load_plugin_textdomain( 'wp-to-twitter' );
|
52 |
}
|
53 |
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
function wpt_check_oauth( $auth = false ) {
|
56 |
if ( ! function_exists( 'wtt_oauth_test' ) ) {
|
57 |
$oauth = false;
|
@@ -62,31 +92,37 @@ function wpt_check_oauth( $auth = false ) {
|
|
62 |
return $oauth;
|
63 |
}
|
64 |
|
|
|
|
|
|
|
65 |
function wpt_check_version() {
|
66 |
global $wpt_version;
|
67 |
-
$prev_version = ( get_option( 'wp_to_twitter_version' )
|
68 |
-
if ( version_compare( $prev_version, $wpt_version,
|
69 |
wptotwitter_activate();
|
70 |
}
|
71 |
}
|
72 |
|
|
|
|
|
|
|
73 |
function wptotwitter_activate() {
|
74 |
// If this has never run before, do the initial setup.
|
75 |
-
$new_install = ( get_option( 'wpt_twitter_setup' )
|
76 |
if ( $new_install ) {
|
77 |
$initial_settings = array(
|
78 |
'post' => array(
|
79 |
'post-published-update' => 1,
|
80 |
'post-published-text' => 'New post: #title# #url#',
|
81 |
'post-edited-update' => 0,
|
82 |
-
'post-edited-text' => 'Post Edited: #title# #url#'
|
83 |
),
|
84 |
'page' => array(
|
85 |
'post-published-update' => 0,
|
86 |
'post-published-text' => 'New page: #title# #url#',
|
87 |
'post-edited-update' => 0,
|
88 |
-
'post-edited-text' => 'Page edited: #title# #url#'
|
89 |
-
)
|
90 |
);
|
91 |
update_option( 'wpt_post_types', $initial_settings );
|
92 |
update_option( 'jd_twit_blogroll', '1' );
|
@@ -98,7 +134,8 @@ function wptotwitter_activate() {
|
|
98 |
update_option( 'jd_replace_character', '' );
|
99 |
$administrator = get_role( 'administrator' );
|
100 |
if ( is_object( $administrator ) ) {
|
101 |
-
|
|
|
102 |
$administrator->add_cap( 'wpt_twitter_custom' );
|
103 |
$administrator->add_cap( 'wpt_twitter_switch' );
|
104 |
$administrator->add_cap( 'wpt_can_tweet' );
|
@@ -119,15 +156,15 @@ function wptotwitter_activate() {
|
|
119 |
|
120 |
update_option( 'jd_twit_remote', '0' );
|
121 |
update_option( 'jd_post_excerpt', 30 );
|
122 |
-
// Use Google Analytics with Twitter
|
123 |
update_option( 'twitter-analytics-campaign', 'twitter' );
|
124 |
update_option( 'use-twitter-analytics', '0' );
|
125 |
update_option( 'jd_dynamic_analytics', '0' );
|
126 |
update_option( 'no-analytics', 1 );
|
127 |
update_option( 'use_dynamic_analytics', 'category' );
|
128 |
-
// Use custom external URLs to point elsewhere.
|
129 |
update_option( 'jd_twit_custom_url', 'external_link' );
|
130 |
-
// Error checking
|
131 |
update_option( 'wp_url_failure', '0' );
|
132 |
// Default publishing options.
|
133 |
update_option( 'jd_tweet_default', '0' );
|
@@ -135,185 +172,95 @@ function wptotwitter_activate() {
|
|
135 |
update_option( 'wpt_inline_edits', '0' );
|
136 |
// Note that default options are set.
|
137 |
update_option( 'wpt_twitter_setup', '1' );
|
138 |
-
update_option( 'jd_keyword_format', '0' );
|
139 |
}
|
140 |
-
|
141 |
global $wpt_version;
|
142 |
-
$prev_version
|
143 |
-
// this is a switch to plan for future versions
|
144 |
$administrator = get_role( 'administrator' );
|
145 |
-
|
146 |
-
$upgrade = version_compare( $prev_version, "2.4.0", "<" );
|
147 |
-
if ( $upgrade ) {
|
148 |
-
$perms = get_option( 'wtt_user_permissions' );
|
149 |
-
switch ( $perms ) {
|
150 |
-
case 'read':
|
151 |
-
$update = 'subscriber';
|
152 |
-
break;
|
153 |
-
case 'edit_posts':
|
154 |
-
$update = 'contributor';
|
155 |
-
break;
|
156 |
-
case 'publish_posts':
|
157 |
-
$update = 'author';
|
158 |
-
break;
|
159 |
-
case 'moderate_comments':
|
160 |
-
$update = 'editor';
|
161 |
-
break;
|
162 |
-
case 'manage_options':
|
163 |
-
$update = 'administrator';
|
164 |
-
break;
|
165 |
-
default:
|
166 |
-
$update = 'administrator';
|
167 |
-
}
|
168 |
-
update_option( 'wtt_user_permissions', $update );
|
169 |
-
}
|
170 |
-
$upgrade = version_compare( $prev_version, "2.4.1", "<" );
|
171 |
-
if ( $upgrade ) {
|
172 |
-
$subscriber = get_role( 'subscriber' );
|
173 |
-
$contributor = get_role( 'contributor' );
|
174 |
-
$author = get_role( 'author' );
|
175 |
-
$editor = get_role( 'editor' );
|
176 |
-
$administrator->add_cap( 'wpt_twitter_oauth' );
|
177 |
-
$administrator->add_cap( 'wpt_twitter_custom' );
|
178 |
-
$administrator->add_cap( 'wpt_twitter_switch' ); // can toggle tweet/don't tweet
|
179 |
-
switch ( get_option( 'wtt_user_permissions' ) ) { // users that can add twitter information
|
180 |
-
case 'subscriber':
|
181 |
-
$subscriber->add_cap( 'wpt_twitter_oauth' );
|
182 |
-
$contributor->add_cap( 'wpt_twitter_oauth' );
|
183 |
-
$author->add_cap( 'wpt_twitter_oauth' );
|
184 |
-
$editor->add_cap( 'wpt_twitter_oauth' );
|
185 |
-
break;
|
186 |
-
case 'contributor':
|
187 |
-
$contributor->add_cap( 'wpt_twitter_oauth' );
|
188 |
-
$author->add_cap( 'wpt_twitter_oauth' );
|
189 |
-
$editor->add_cap( 'wpt_twitter_oauth' );
|
190 |
-
break;
|
191 |
-
case 'author':
|
192 |
-
$author->add_cap( 'wpt_twitter_oauth' );
|
193 |
-
$editor->add_cap( 'wpt_twitter_oauth' );
|
194 |
-
break;
|
195 |
-
case 'editor':
|
196 |
-
$editor->add_cap( 'wpt_twitter_oauth' );
|
197 |
-
break;
|
198 |
-
case 'administrator':
|
199 |
-
break;
|
200 |
-
default:
|
201 |
-
$role = get_role( get_option( 'wtt_user_permissions' ) );
|
202 |
-
if ( is_object( $role ) ) {
|
203 |
-
$role->add_cap( 'wpt_twitter_oauth' );
|
204 |
-
}
|
205 |
-
break;
|
206 |
-
}
|
207 |
-
switch ( get_option( 'wtt_show_custom_tweet' ) ) { // users that can compose a custom tweet
|
208 |
-
case 'subscriber':
|
209 |
-
$subscriber->add_cap( 'wpt_twitter_custom' );
|
210 |
-
$contributor->add_cap( 'wpt_twitter_custom' );
|
211 |
-
$author->add_cap( 'wpt_twitter_custom' );
|
212 |
-
$editor->add_cap( 'wpt_twitter_custom' );
|
213 |
-
break;
|
214 |
-
case 'contributor':
|
215 |
-
$contributor->add_cap( 'wpt_twitter_custom' );
|
216 |
-
$author->add_cap( 'wpt_twitter_custom' );
|
217 |
-
$editor->add_cap( 'wpt_twitter_custom' );
|
218 |
-
break;
|
219 |
-
case 'author':
|
220 |
-
$author->add_cap( 'wpt_twitter_custom' );
|
221 |
-
$editor->add_cap( 'wpt_twitter_custom' );
|
222 |
-
break;
|
223 |
-
case 'editor':
|
224 |
-
$editor->add_cap( 'wpt_twitter_custom' );
|
225 |
-
break;
|
226 |
-
case 'administrator':
|
227 |
-
break;
|
228 |
-
default:
|
229 |
-
$role = get_role( get_option( 'wtt_show_custom_tweet' ) );
|
230 |
-
if ( is_object( $role ) ) {
|
231 |
-
$role->add_cap( 'wpt_twitter_custom' );
|
232 |
-
}
|
233 |
-
break;
|
234 |
-
}
|
235 |
-
}
|
236 |
-
// version 2.4.13: 10/12/2012
|
237 |
-
$upgrade = version_compare( $prev_version, "2.4.13", "<" );
|
238 |
-
if ( $upgrade ) {
|
239 |
-
$administrator->add_cap( 'wpt_can_tweet' );
|
240 |
-
$editor = get_role( 'editor' );
|
241 |
-
if ( is_object( $editor ) ) {
|
242 |
-
$editor->add_cap( 'wpt_can_tweet' );
|
243 |
-
}
|
244 |
-
$author = get_role( 'author' );
|
245 |
-
if ( is_object( $author ) ) {
|
246 |
-
$author->add_cap( 'wpt_can_tweet' );
|
247 |
-
}
|
248 |
-
$contributor = get_role( 'contributor' );
|
249 |
-
if ( is_object( $contributor ) ) {
|
250 |
-
$contributor->add_cap( 'wpt_can_tweet' );
|
251 |
-
}
|
252 |
-
update_option( 'wpt_can_tweet', 'contributor' );
|
253 |
-
}
|
254 |
-
$upgrade = version_compare( $prev_version, "2.9.0", "<" );
|
255 |
if ( $upgrade ) {
|
256 |
$administrator->add_cap( 'wpt_tweet_now' );
|
257 |
}
|
258 |
-
|
259 |
update_option( 'wp_to_twitter_version', $wpt_version );
|
260 |
}
|
261 |
|
262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
function wpt_link( $post_ID ) {
|
264 |
$ex_link = false;
|
265 |
$external_link = get_option( 'jd_twit_custom_url' );
|
266 |
$permalink = get_permalink( $post_ID );
|
267 |
-
if (
|
268 |
$ex_link = get_post_meta( $post_ID, $external_link, true );
|
269 |
}
|
270 |
|
271 |
return ( $ex_link ) ? $ex_link : $permalink;
|
272 |
}
|
273 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
function wpt_saves_error( $id, $auth, $twit, $error, $http_code, $ts ) {
|
275 |
$http_code = (int) $http_code;
|
276 |
-
if (
|
277 |
add_post_meta( $id, '_wpt_failed', array(
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
} else {
|
285 |
-
if ( get_option( 'wpt_rate_limiting' )
|
286 |
wpt_log_success( $auth, $ts, $id );
|
287 |
}
|
288 |
}
|
289 |
}
|
290 |
|
291 |
|
292 |
-
|
293 |
-
* Checks whether WP to Twitter has sent a tweet on this post to this author within the last 30 seconds and blocks
|
294 |
*
|
295 |
-
*
|
|
|
|
|
|
|
|
|
296 |
*/
|
297 |
function wpt_check_recent_tweet( $id, $auth ) {
|
298 |
if ( ! $id ) {
|
299 |
return false;
|
300 |
} else {
|
301 |
-
if (
|
302 |
$transient = get_transient( "_wpt_most_recent_tweet_$id" );
|
303 |
} else {
|
304 |
-
$transient = get_transient(
|
305 |
}
|
306 |
if ( $transient ) {
|
307 |
return true;
|
308 |
} else {
|
309 |
$expire = apply_filters( 'wpt_recent_tweet_threshold', 30 );
|
310 |
// if expiration is 0, don't set the transient. We don't want permanent transients.
|
311 |
-
if (
|
312 |
-
wpt_mail(
|
313 |
-
if (
|
314 |
set_transient( "_wpt_most_recent_tweet_$id", true, $expire );
|
315 |
} else {
|
316 |
-
set_transient(
|
317 |
}
|
318 |
}
|
319 |
}
|
@@ -324,21 +271,21 @@ function wpt_check_recent_tweet( $id, $auth ) {
|
|
324 |
|
325 |
/**
|
326 |
* Performs the API post to Twitter
|
327 |
-
*
|
328 |
-
* @param string
|
329 |
-
* @param
|
330 |
-
* @param
|
331 |
-
* @param boolean $media Whether to upload media attached to the post specified in $id
|
332 |
-
*
|
333 |
-
* @return boolean Success of query.
|
334 |
*/
|
335 |
function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false ) {
|
336 |
-
$recent
|
337 |
-
$error
|
338 |
-
if ( get_option( 'wpt_rate_limiting' )
|
339 |
// check whether this post needs to be rate limited.
|
340 |
$continue = wpt_test_rate_limit( $id, $auth );
|
341 |
-
if (
|
342 |
return false;
|
343 |
}
|
344 |
}
|
@@ -347,26 +294,26 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
347 |
if ( $recent ) {
|
348 |
return false;
|
349 |
}
|
350 |
-
|
351 |
if ( ! wpt_check_oauth( $auth ) ) {
|
352 |
$error = __( 'This account is not authorized to post to Twitter.', 'wp-to-twitter' );
|
353 |
wpt_saves_error( $id, $auth, $twit, $error, '401', time() );
|
354 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
355 |
|
356 |
return false;
|
357 |
-
} // exit silently if not authorized
|
358 |
|
359 |
-
$check = ( ! $auth ) ? get_option( 'jd_last_tweet' ) : get_user_meta( $auth, 'wpt_last_tweet', true ); // get user's last tweet
|
360 |
-
// prevent duplicate Tweets
|
361 |
if ( $check == $twit ) {
|
362 |
-
wpt_mail(
|
363 |
$error = __( 'This tweet is identical to another Tweet recently sent to this account.', 'wp-to-twitter' ) . ' ' . __( 'Twitter requires all Tweets to be unique.', 'wp-to-twitter' );
|
364 |
wpt_saves_error( $id, $auth, $twit, $error, '403-1', time() );
|
365 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
366 |
|
367 |
return false;
|
368 |
-
}
|
369 |
-
wpt_mail(
|
370 |
$error = __( 'This tweet was blank and could not be sent to Twitter.', 'wp-tweets-pro' );
|
371 |
wpt_saves_error( $id, $auth, $twit, $error, '403-2', time() );
|
372 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
@@ -374,7 +321,7 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
374 |
return false;
|
375 |
} else {
|
376 |
$media_id = false;
|
377 |
-
// must be designated as media and have a valid attachment
|
378 |
$attachment = ( $media ) ? wpt_post_attachment( $id ) : false;
|
379 |
if ( $attachment ) {
|
380 |
wpt_mail( 'Post has upload', "$auth, $attachment" );
|
@@ -384,20 +331,40 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
384 |
$attachment = false;
|
385 |
}
|
386 |
}
|
387 |
-
$api
|
388 |
-
$upload_api
|
389 |
-
$status
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
if ( wtt_oauth_test( $auth )
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
}
|
402 |
}
|
403 |
}
|
@@ -405,20 +372,21 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
405 |
$connection = array( 'connection' => 'undefined' );
|
406 |
} else {
|
407 |
$staging_mode = apply_filters( 'wpt_staging_mode', false, $auth, $id );
|
408 |
-
if ( ( defined( 'WPT_STAGING_MODE' ) &&
|
409 |
// if in staging mode, we'll behave as if the Tweet succeeded, but not send it.
|
410 |
$connection = true;
|
411 |
-
$http_code
|
412 |
-
$notice
|
413 |
} else {
|
414 |
$connection->post( $api, $status );
|
415 |
$http_code = ( $connection ) ? $connection->http_code : 'failed';
|
416 |
-
$notice
|
417 |
-
}
|
418 |
}
|
419 |
wpt_mail( 'Twitter Connection', print_r( $connection, 1 ) . " - $twit, $auth, $id, $media" );
|
420 |
if ( $connection ) {
|
421 |
-
if ( isset( $connection->http_header['x-access-level'] ) && $connection->http_header['x-access-level']
|
|
|
422 |
$supplement = sprintf( __( 'Your Twitter application does not have read and write permissions. Go to <a href="%s">your Twitter apps</a> to modify these settings.', 'wp-to-twitter' ), 'https://dev.twitter.com/apps/' );
|
423 |
} else {
|
424 |
$supplement = '';
|
@@ -426,65 +394,64 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
426 |
$return = false;
|
427 |
switch ( $http_code ) {
|
428 |
case '100':
|
429 |
-
$error = __(
|
430 |
-
break;
|
431 |
case '200':
|
432 |
$return = true;
|
433 |
-
$error = __(
|
434 |
update_option( 'wpt_authentication_missing', false );
|
435 |
break;
|
436 |
case '304':
|
437 |
-
$error = __(
|
438 |
break;
|
439 |
case '400':
|
440 |
-
$error = __(
|
441 |
break;
|
442 |
case '401':
|
443 |
-
$error = __(
|
444 |
update_option( 'wpt_authentication_missing', "$auth" );
|
445 |
break;
|
446 |
case '403':
|
447 |
-
$error = __(
|
448 |
break;
|
449 |
case '404':
|
450 |
-
$error = __(
|
451 |
break;
|
452 |
case '406':
|
453 |
-
$error = __(
|
454 |
break;
|
455 |
case '422':
|
456 |
-
$error = __(
|
457 |
break;
|
458 |
case '429':
|
459 |
-
$error = __(
|
460 |
break;
|
461 |
case '500':
|
462 |
-
$error = __(
|
463 |
break;
|
464 |
case '502':
|
465 |
-
$error = __(
|
466 |
break;
|
467 |
case '503':
|
468 |
-
$error = __(
|
469 |
break;
|
470 |
case '504':
|
471 |
$error = __( "504 Gateway Timeout: The Twitter servers are up, but the request couldn't be serviced due to some failure within our stack. Try again later.", 'wp-to-twitter' );
|
472 |
break;
|
473 |
default:
|
474 |
-
|
|
|
475 |
break;
|
476 |
}
|
477 |
$body = $connection->body;
|
478 |
-
$error_code = (
|
479 |
-
$error_message = (
|
480 |
-
$error_supplement = (
|
481 |
-
$error .= (
|
482 |
$error .= $error_supplement;
|
483 |
-
//
|
484 |
-
|
485 |
-
|
486 |
-
// only save last Tweet if successful
|
487 |
-
if ( $http_code == '200' ) {
|
488 |
if ( ! $auth ) {
|
489 |
update_option( 'jd_last_tweet', $twit );
|
490 |
} else {
|
@@ -492,7 +459,7 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
492 |
}
|
493 |
}
|
494 |
wpt_saves_error( $id, $auth, $twit, $error, $http_code, time() );
|
495 |
-
if (
|
496 |
$jwt = get_post_meta( $id, '_jd_wp_twitter', true );
|
497 |
if ( ! is_array( $jwt ) ) {
|
498 |
$jwt = array();
|
@@ -505,7 +472,7 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
505 |
update_post_meta( $id, '_jd_wp_twitter', $jwt );
|
506 |
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
507 |
// schedule a one-time promotional box for 4 weeks after first successful Tweet.
|
508 |
-
if ( get_option( 'wpt_promotion_scheduled' )
|
509 |
wp_schedule_single_event( time() + ( 60 * 60 * 24 * 7 * 4 ), 'wpt_schedule_promotion_action' );
|
510 |
update_option( 'wpt_promotion_scheduled', 1 );
|
511 |
}
|
@@ -514,7 +481,7 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
514 |
if ( ! $return ) {
|
515 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
516 |
} else {
|
517 |
-
do_action( 'wpt_tweet_posted', $connection, $id );
|
518 |
wpt_set_log( 'wpt_status_message', $id, $notice . __( 'Tweet sent successfully.', 'wp-to-twitter' ) );
|
519 |
}
|
520 |
|
@@ -530,9 +497,9 @@ function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false
|
|
530 |
|
531 |
/**
|
532 |
* For servers without PEAR normalize installed, approximates normalization. With normalizer, executes normalization on string.
|
533 |
-
*
|
534 |
-
* @param string Text to normalize
|
535 |
-
*
|
536 |
* @return string Normalized text.
|
537 |
*/
|
538 |
function wpt_normalize( $string ) {
|
@@ -545,17 +512,17 @@ function wpt_normalize( $string ) {
|
|
545 |
} else {
|
546 |
$normalizer = new WPT_Normalizer();
|
547 |
if ( $normalizer->isNormalized( $string ) ) {
|
548 |
-
|
549 |
}
|
550 |
-
|
551 |
return $normalizer->normalize( $string );
|
552 |
}
|
553 |
}
|
554 |
|
555 |
/**
|
556 |
* Test URL to see if is pointing to https location.
|
557 |
-
*
|
558 |
-
* @param string $url
|
559 |
*
|
560 |
* @return boolean
|
561 |
*/
|
@@ -568,12 +535,17 @@ function wpt_is_ssl( $url ) {
|
|
568 |
}
|
569 |
|
570 |
/**
|
571 |
-
* Deprecated; still used if configured.
|
|
|
|
|
|
|
|
|
|
|
572 |
*/
|
573 |
function wpt_in_allowed_category( $array ) {
|
574 |
$allowed_categories = get_option( 'tweet_categories' );
|
575 |
if ( is_array( $array ) && is_array( $allowed_categories ) ) {
|
576 |
-
$common =
|
577 |
if ( count( $common ) >= 1 ) {
|
578 |
return true;
|
579 |
} else {
|
@@ -586,47 +558,48 @@ function wpt_in_allowed_category( $array ) {
|
|
586 |
|
587 |
/**
|
588 |
* Builds array of post info for use in Tweet functions.
|
589 |
-
*
|
590 |
* @param integer $post_ID Post ID.
|
591 |
*
|
592 |
-
* @return array Post data used in Tweet functions.
|
593 |
*/
|
594 |
function wpt_post_info( $post_ID ) {
|
595 |
$encoding = get_option( 'blog_charset' );
|
596 |
-
if (
|
597 |
$encoding = 'UTF-8';
|
598 |
}
|
599 |
$post = get_post( $post_ID );
|
600 |
$category_ids = false;
|
601 |
$values = array();
|
602 |
$values['id'] = $post_ID;
|
603 |
-
// get post author
|
604 |
$values['postinfo'] = $post;
|
605 |
$values['postContent'] = $post->post_content;
|
606 |
$values['authId'] = $post->post_author;
|
607 |
$postdate = $post->post_date;
|
608 |
-
$
|
609 |
-
$dateformat = ( get_option( 'jd_date_format' ) == '' ) ? get_option( 'date_format' ) : get_option( 'jd_date_format' );
|
610 |
$thisdate = mysql2date( $dateformat, $postdate );
|
611 |
-
$altdate = mysql2date(
|
612 |
$values['_postDate'] = $altdate;
|
613 |
$values['postDate'] = $thisdate;
|
614 |
$moddate = $post->post_modified;
|
615 |
-
$values['_postModified'] = mysql2date(
|
616 |
$values['postModified'] = mysql2date( $dateformat, $moddate );
|
617 |
-
// get first category
|
618 |
-
$category =
|
|
|
619 |
$categories = get_the_category( $post_ID );
|
620 |
-
$cats
|
|
|
621 |
if ( is_array( $categories ) ) {
|
622 |
if ( count( $categories ) > 0 ) {
|
623 |
$category = $categories[0]->cat_name;
|
624 |
$cat_desc = $categories[0]->description;
|
625 |
}
|
626 |
-
foreach ( $categories
|
627 |
$category_ids[] = $cat->term_id;
|
628 |
-
$cats[]
|
629 |
-
$cat_descs[]
|
630 |
}
|
631 |
$cat_names = implode( ' ', apply_filters( 'wpt_twitter_category_names', $cats ) );
|
632 |
$cat_descs = implode( ' ', apply_filters( 'wpt_twitter_category_descs', $cat_descs ) );
|
@@ -641,17 +614,17 @@ function wpt_post_info( $post_ID ) {
|
|
641 |
$values['category'] = html_entity_decode( $category, ENT_COMPAT, $encoding );
|
642 |
$values['cat_desc'] = html_entity_decode( $cat_desc, ENT_COMPAT, $encoding );
|
643 |
$excerpt_length = get_option( 'jd_post_excerpt' );
|
644 |
-
$post_excerpt = ( trim( $post->post_excerpt )
|
645 |
$values['postExcerpt'] = html_entity_decode( $post_excerpt, ENT_COMPAT, $encoding );
|
646 |
$thisposttitle = $post->post_title;
|
647 |
-
if (
|
648 |
$thisposttitle = $_POST['title'];
|
649 |
}
|
650 |
-
$thisposttitle
|
651 |
-
// These are common sequences that may not be fixed by html_entity_decode due to double encoding
|
652 |
$search = array( ''', ''', '"', '"', '&', '&' );
|
653 |
$replace = array( "'", "'", '"', '"', '&', '&' );
|
654 |
-
$thisposttitle = str_replace( $search, $replace, $thisposttitle );
|
655 |
$values['postTitle'] = html_entity_decode( $thisposttitle, ENT_QUOTES, $encoding );
|
656 |
$values['postLink'] = wpt_link( $post_ID );
|
657 |
$values['blogTitle'] = get_bloginfo( 'name' );
|
@@ -660,19 +633,20 @@ function wpt_post_info( $post_ID ) {
|
|
660 |
$values['postType'] = $post->post_type;
|
661 |
/**
|
662 |
* Filters post array to insert custom data that can be used in Tweet process.
|
663 |
-
*
|
664 |
-
* @param array
|
665 |
-
* @param integer $post_ID
|
666 |
-
* @return array
|
667 |
*/
|
668 |
-
$values
|
669 |
|
670 |
return $values;
|
671 |
}
|
672 |
|
673 |
/**
|
674 |
* Retrieve stored short URL.
|
675 |
-
*
|
|
|
676 |
*
|
677 |
* @return mixed
|
678 |
*/
|
@@ -681,25 +655,26 @@ function wpt_short_url( $post_id ) {
|
|
681 |
if ( ! $post_id ) {
|
682 |
$post_id = $post_ID;
|
683 |
}
|
684 |
-
$
|
685 |
-
|
|
|
686 |
return $short;
|
687 |
}
|
688 |
|
689 |
/**
|
690 |
* Identify whether a post should be uploading media. Test settings and verify whether post has images that can be uploaded.
|
691 |
*
|
692 |
-
* @param
|
693 |
-
* @param array $post_info
|
694 |
* @return boolean
|
695 |
-
*/
|
696 |
function wpt_post_with_media( $post_ID, $post_info = array() ) {
|
697 |
$return = false;
|
698 |
-
if ( isset( $post_info['wpt_image'] ) && $post_info['wpt_image']
|
699 |
return $return;
|
700 |
}
|
701 |
|
702 |
-
if ( ! function_exists( 'wpt_pro_exists' ) || get_option( 'wpt_media' )
|
703 |
$return = false;
|
704 |
} else {
|
705 |
if ( has_post_thumbnail( $post_ID ) || wpt_post_attachment( $post_ID ) ) {
|
@@ -711,6 +686,12 @@ function wpt_post_with_media( $post_ID, $post_info = array() ) {
|
|
711 |
}
|
712 |
|
713 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
714 |
* @deprecated
|
715 |
*/
|
716 |
function wpt_category_limit( $post_type, $post_info, $post_ID ) {
|
@@ -718,37 +699,45 @@ function wpt_category_limit( $post_type, $post_info, $post_ID ) {
|
|
718 |
$continue = true;
|
719 |
if ( in_array( 'category', $post_type_cats ) ) {
|
720 |
// 'category' is assigned to this post type, so apply filters.
|
721 |
-
if ( get_option( 'jd_twit_cats' )
|
722 |
$continue = ( ! wpt_in_allowed_category( $post_info['categoryIds'] ) ) ? true : false;
|
723 |
} else {
|
724 |
$continue = ( wpt_in_allowed_category( $post_info['categoryIds'] ) ) ? true : false;
|
725 |
}
|
726 |
}
|
727 |
|
728 |
-
$continue = ( get_option( 'limit_categories' )
|
729 |
-
$args = array(
|
|
|
|
|
|
|
|
|
730 |
|
731 |
return apply_filters( 'wpt_filter_terms', $continue, $args );
|
732 |
}
|
733 |
|
734 |
/**
|
735 |
-
* Set up a Tweet to be sent.
|
736 |
-
*
|
737 |
-
* @param
|
738 |
-
* @param string $type Publishing context (publishing, scheduled, xmlrpc, etc.)
|
739 |
-
*
|
740 |
-
* @return
|
741 |
*/
|
742 |
function wpt_tweet( $post_ID, $type = 'instant' ) {
|
743 |
if ( wp_is_post_autosave( $post_ID ) || wp_is_post_revision( $post_ID ) ) {
|
744 |
return $post_ID;
|
745 |
}
|
746 |
-
|
747 |
wpt_check_version();
|
748 |
-
$tweet_this
|
749 |
-
$newpost
|
750 |
-
$
|
751 |
-
|
|
|
|
|
|
|
|
|
752 |
if ( isset( $_POST['_inline_edit'] ) || isset( $_REQUEST['bulk_edit'] ) ) {
|
753 |
return false;
|
754 |
}
|
@@ -757,109 +746,108 @@ function wpt_tweet( $post_ID, $type = 'instant' ) {
|
|
757 |
$is_inline_edit = true;
|
758 |
}
|
759 |
}
|
760 |
-
if ( get_option( 'jd_tweet_default' )
|
761 |
-
$default = (
|
762 |
} else {
|
763 |
-
$default = (
|
764 |
}
|
765 |
-
wpt_mail(
|
766 |
if ( $default ) { // default switch: depend on default settings.
|
767 |
$post_info = wpt_post_info( $post_ID );
|
768 |
$media = wpt_post_with_media( $post_ID, $post_info );
|
769 |
-
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists()
|
770 |
-
$auth = ( get_option( 'wpt_cotweet_lock' )
|
771 |
} else {
|
772 |
$auth = $post_info['authId'];
|
773 |
}
|
774 |
-
|
775 |
-
|
776 |
-
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists() == true && function_exists( 'wpt_filter_post_info' ) ) {
|
777 |
$filter = wpt_filter_post_info( $post_info );
|
778 |
-
if (
|
779 |
-
wpt_mail(
|
780 |
|
781 |
return false;
|
782 |
}
|
783 |
}
|
784 |
-
|
785 |
$filter = apply_filters( 'wpt_filter_post_data', false, $_POST );
|
786 |
if ( $filter ) {
|
787 |
return false;
|
788 |
}
|
789 |
$post_type = $post_info['postType'];
|
790 |
-
if ( $type
|
791 |
-
$new = 1; // if this is a future action, then it should be published regardless of relationship
|
792 |
-
wpt_mail(
|
793 |
delete_post_meta( $post_ID, 'wpt_publishing' );
|
794 |
} else {
|
795 |
// if the post modified date and the post date are the same, this is new.
|
796 |
-
// true if first date before or equal to last date
|
797 |
$new = wpt_date_compare( $post_info['_postModified'], $post_info['_postDate'] );
|
798 |
}
|
799 |
-
// post is not previously published but has been backdated
|
800 |
-
// (post date is edited, but save option is 'publish')
|
801 |
-
if (
|
802 |
$new = 1;
|
803 |
}
|
804 |
-
// can't catch posts that were set to a past date as a draft, then published.
|
805 |
$post_type_settings = get_option( 'wpt_post_types' );
|
806 |
$post_types = array_keys( $post_type_settings );
|
807 |
if ( in_array( $post_type, $post_types ) ) {
|
808 |
-
// identify whether limited by category/taxonomy
|
809 |
$continue = wpt_category_limit( $post_type, $post_info, $post_ID );
|
810 |
-
if (
|
811 |
return false;
|
812 |
}
|
813 |
-
// create Tweet and ID whether current action is edit or new
|
814 |
-
$
|
815 |
-
if ( isset( $_POST['_jd_twitter'] ) && $_POST['_jd_twitter']
|
816 |
-
$
|
817 |
}
|
818 |
-
$
|
819 |
// if ops is set and equals 'publish', this is being edited. Otherwise, it's a new post.
|
820 |
-
if (
|
821 |
-
// if this is an old post and editing updates are enabled
|
822 |
-
if ( get_option( 'jd_tweet_default_edit' )
|
823 |
$tweet_this = apply_filters( 'wpt_tweet_this_edit', $tweet_this, $_POST );
|
824 |
-
if (
|
825 |
return false;
|
826 |
}
|
827 |
}
|
828 |
-
wpt_mail(
|
829 |
-
if ( $post_type_settings[ $post_type ]['post-edited-update']
|
830 |
$nptext = stripcslashes( $post_type_settings[ $post_type ]['post-edited-text'] );
|
831 |
$oldpost = true;
|
832 |
}
|
833 |
} else {
|
834 |
-
wpt_mail(
|
835 |
-
if ( $post_type_settings[ $post_type ]['post-published-update']
|
836 |
$nptext = stripcslashes( $post_type_settings[ $post_type ]['post-published-text'] );
|
837 |
$newpost = true;
|
838 |
}
|
839 |
}
|
840 |
if ( $newpost || $oldpost ) {
|
841 |
-
$template = (
|
842 |
$sentence = jd_truncate_tweet( $template, $post_info, $post_ID );
|
843 |
-
wpt_mail(
|
844 |
-
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists()
|
845 |
$sentence2 = jd_truncate_tweet( $template, $post_info, $post_ID, false, $auth );
|
846 |
}
|
847 |
}
|
848 |
-
if (
|
849 |
-
// WPT PRO
|
850 |
-
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists()
|
851 |
$wpt_selected_users = $post_info['wpt_authorized_users'];
|
852 |
-
|
853 |
$auth_verified = wtt_oauth_test( $auth, 'verify' );
|
854 |
-
if ( empty( $wpt_selected_users ) && get_option( 'jd_individual_twitter_users' )
|
855 |
$wpt_selected_users = ( $auth_verified ) ? array( $auth ) : array( false );
|
856 |
}
|
857 |
-
if ( $post_info['wpt_cotweet']
|
858 |
$wpt_selected_users['main'] = false;
|
859 |
}
|
860 |
-
// filter selected users before using
|
861 |
$wpt_selected_users = apply_filters( 'wpt_filter_users', $wpt_selected_users, $post_info );
|
862 |
-
if ( $post_info['wpt_delay_tweet']
|
863 |
foreach ( $wpt_selected_users as $acct ) {
|
864 |
if ( wtt_oauth_test( $acct, 'verify' ) ) {
|
865 |
wpt_post_to_twitter( $sentence2, $acct, $post_ID, $media );
|
@@ -867,35 +855,35 @@ function wpt_tweet( $post_ID, $type = 'instant' ) {
|
|
867 |
}
|
868 |
} else {
|
869 |
foreach ( $wpt_selected_users as $acct ) {
|
870 |
-
$acct
|
871 |
$offset = ( $auth != $acct ) ? apply_filters( 'wpt_random_delay', rand( 60, 480 ) ) : 0;
|
872 |
if ( wtt_oauth_test( $acct, 'verify' ) ) {
|
873 |
-
$time
|
874 |
wp_schedule_single_event( time() + $time + $offset, 'wpt_schedule_tweet_action', array(
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
if ( WPT_DEBUG && function_exists( 'wpt_pro_exists' ) ) {
|
881 |
$author_id = ( $acct ) ? "#$acct" : 'Main';
|
882 |
wpt_mail( "7a: Tweet Scheduled for author $author_id", print_r( array(
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
}
|
894 |
}
|
895 |
}
|
896 |
}
|
897 |
-
|
898 |
-
if ( $post_info['wpt_retweet_after']
|
899 |
$repeat = $post_info['wpt_retweet_repeat'];
|
900 |
$first = true;
|
901 |
foreach ( $wpt_selected_users as $acct ) {
|
@@ -905,17 +893,17 @@ function wpt_tweet( $post_ID, $type = 'instant' ) {
|
|
905 |
if ( $continue ) {
|
906 |
$retweet = apply_filters( 'wpt_set_retweet_text', $template, $i );
|
907 |
$retweet = jd_truncate_tweet( $retweet, $post_info, $post_ID, true, $acct );
|
908 |
-
// add original delay to schedule
|
909 |
$delay = ( isset( $post_info['wpt_delay_tweet'] ) ) ? ( (int) $post_info['wpt_delay_tweet'] ) * 60 : 0;
|
910 |
-
|
911 |
-
$offset
|
912 |
-
$time
|
913 |
wp_schedule_single_event( time() + $time + $offset + $delay, 'wpt_schedule_tweet_action', array(
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
if ( WPT_DEBUG && function_exists( 'wpt_pro_exists' ) ) {
|
920 |
if ( $acct ) {
|
921 |
$author_id = "#$acct";
|
@@ -923,19 +911,13 @@ function wpt_tweet( $post_ID, $type = 'instant' ) {
|
|
923 |
$author_id = 'Main';
|
924 |
}
|
925 |
wpt_mail( "7b: Retweet Scheduled for author $author_id", print_r( array(
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
'delay' => $delay,
|
934 |
-
'current_time' => time(),
|
935 |
-
'timezone' => get_option( 'gmt_offset' ),
|
936 |
-
'timestamp_string' => date( 'Y-m-d H:i:s', time() + $time + $offset + $delay ),
|
937 |
-
'current_time_string' => date( 'Y-m-d H:i:s', time() ),
|
938 |
-
), 1 ), true ); // DEBUG
|
939 |
}
|
940 |
$tweet_limit = apply_filters( 'wpt_tweet_repeat_limit', 4, $post_ID );
|
941 |
if ( $i == $tweet_limit ) {
|
@@ -950,11 +932,11 @@ function wpt_tweet( $post_ID, $type = 'instant' ) {
|
|
950 |
} else {
|
951 |
wpt_post_to_twitter( $sentence, false, $post_ID, $media );
|
952 |
}
|
953 |
-
// END WPT PRO
|
954 |
}
|
955 |
} else {
|
956 |
if ( WPT_DEBUG && function_exists( 'wpt_pro_exists' ) ) {
|
957 |
-
wpt_mail(
|
958 |
}
|
959 |
|
960 |
return $post_ID;
|
@@ -966,66 +948,67 @@ function wpt_tweet( $post_ID, $type = 'instant' ) {
|
|
966 |
|
967 |
/**
|
968 |
* Send Tweets on links in link manager. Only active if Link plug-in is installed.
|
969 |
-
*
|
970 |
-
* @param integer $
|
971 |
-
*
|
972 |
* @return mixed boolean/integer link ID if successful, false if failure.
|
973 |
*/
|
974 |
-
function wpt_twit_link( $
|
975 |
wpt_check_version();
|
976 |
$thislinkprivate = $_POST['link_visible'];
|
977 |
-
if (
|
978 |
-
$thislinkname =
|
979 |
$thispostlink = $_POST['link_url'];
|
980 |
$thislinkdescription = stripcslashes( $_POST['link_description'] );
|
981 |
$sentence = stripcslashes( get_option( 'newlink-published-text' ) );
|
982 |
-
$sentence = str_ireplace(
|
983 |
-
$sentence = str_ireplace(
|
984 |
|
985 |
if ( mb_strlen( $sentence ) > 118 ) {
|
986 |
$sentence = mb_substr( $sentence, 0, 114 ) . '...';
|
987 |
}
|
988 |
$shrink = apply_filters( 'wptt_shorten_link', $thispostlink, $thislinkname, false, 'link' );
|
989 |
-
if ( stripos( $sentence,
|
990 |
-
$sentence = $sentence .
|
991 |
} else {
|
992 |
-
$sentence = str_ireplace(
|
993 |
}
|
994 |
-
|
995 |
-
if ( stripos( $sentence,
|
996 |
-
$sentence = $sentence .
|
997 |
} else {
|
998 |
-
$sentence = str_ireplace(
|
999 |
}
|
1000 |
-
|
1001 |
-
if (
|
1002 |
-
wpt_post_to_twitter( $sentence, false, $
|
1003 |
}
|
1004 |
|
1005 |
-
return $
|
1006 |
} else {
|
1007 |
return false;
|
1008 |
}
|
1009 |
}
|
1010 |
|
1011 |
-
/**
|
1012 |
* Generate hash tags from tags set on post.
|
1013 |
-
*
|
1014 |
-
* @param integer $post_ID Post ID.
|
1015 |
*
|
1016 |
-
* @
|
|
|
|
|
1017 |
*/
|
1018 |
function wpt_generate_hash_tags( $post_ID ) {
|
1019 |
$hashtags = '';
|
1020 |
-
$term_meta =
|
|
|
1021 |
$max_tags = get_option( 'jd_max_tags' );
|
1022 |
$max_characters = get_option( 'jd_max_characters' );
|
1023 |
-
$max_characters = (
|
1024 |
-
if (
|
1025 |
$max_tags = 100;
|
1026 |
}
|
1027 |
-
$use_cats = ( get_option( 'wpt_use_cats' )
|
1028 |
-
$tags = (
|
1029 |
$tags = apply_filters( 'wpt_hash_source', $tags, $post_ID );
|
1030 |
if ( $tags && count( $tags ) > 0 ) {
|
1031 |
$i = 1;
|
@@ -1034,25 +1017,34 @@ function wpt_generate_hash_tags( $post_ID ) {
|
|
1034 |
$t_id = $value->term_id;
|
1035 |
$term_meta = get_option( "wpt_taxonomy_$t_id" );
|
1036 |
}
|
1037 |
-
if ( get_option( 'wpt_tag_source' )
|
1038 |
$tag = $value->slug;
|
1039 |
} else {
|
1040 |
$tag = $value->name;
|
1041 |
}
|
1042 |
$strip = get_option( 'jd_strip_nonan' );
|
1043 |
-
$search =
|
1044 |
$replace = get_option( 'jd_replace_character' );
|
1045 |
-
$replace = (
|
1046 |
-
$tag = str_ireplace(
|
1047 |
$tag = preg_replace( '/[\/]/', $replace, $tag ); // remove forward slashes.
|
1048 |
-
$tag = (
|
1049 |
-
|
1050 |
switch ( $term_meta ) {
|
1051 |
-
case 1
|
1052 |
-
|
1053 |
-
|
1054 |
-
case
|
1055 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1056 |
}
|
1057 |
if ( mb_strlen( $newtag ) > 2 && ( mb_strlen( $newtag ) <= $max_characters ) && ( $i <= $max_tags ) ) {
|
1058 |
$hashtags .= "$newtag ";
|
@@ -1062,14 +1054,14 @@ function wpt_generate_hash_tags( $post_ID ) {
|
|
1062 |
}
|
1063 |
$hashtags = trim( $hashtags );
|
1064 |
if ( mb_strlen( $hashtags ) <= 1 ) {
|
1065 |
-
$hashtags =
|
1066 |
}
|
1067 |
|
1068 |
return $hashtags;
|
1069 |
}
|
1070 |
|
1071 |
add_action( 'admin_menu', 'wpt_add_twitter_outer_box' );
|
1072 |
-
/**
|
1073 |
* Set up post meta box.
|
1074 |
*/
|
1075 |
function wpt_add_twitter_outer_box() {
|
@@ -1079,7 +1071,7 @@ function wpt_add_twitter_outer_box() {
|
|
1079 |
if ( function_exists( 'add_meta_box' ) ) {
|
1080 |
if ( is_array( $wpt_post_types ) ) {
|
1081 |
foreach ( $wpt_post_types as $key => $value ) {
|
1082 |
-
if ( $value['post-published-update']
|
1083 |
add_meta_box( 'wp2t', 'WP to Twitter', 'wpt_add_twitter_inner_box', $key, 'side' );
|
1084 |
}
|
1085 |
}
|
@@ -1089,7 +1081,7 @@ function wpt_add_twitter_outer_box() {
|
|
1089 |
|
1090 |
|
1091 |
add_action( 'admin_menu', 'wpt_add_twitter_debug_box' );
|
1092 |
-
/**
|
1093 |
* Set up post meta box.
|
1094 |
*/
|
1095 |
function wpt_add_twitter_debug_box() {
|
@@ -1100,18 +1092,20 @@ function wpt_add_twitter_debug_box() {
|
|
1100 |
if ( function_exists( 'add_meta_box' ) ) {
|
1101 |
if ( is_array( $wpt_post_types ) ) {
|
1102 |
foreach ( $wpt_post_types as $key => $value ) {
|
1103 |
-
if ( $value['post-published-update']
|
1104 |
add_meta_box( 'wp2t-debug', 'WP to Twitter Debugging', 'wpt_show_debug', $key, 'advanced' );
|
1105 |
}
|
1106 |
}
|
1107 |
}
|
1108 |
}
|
1109 |
}
|
1110 |
-
}
|
1111 |
-
|
1112 |
-
|
1113 |
/**
|
1114 |
* Print post meta box
|
|
|
|
|
1115 |
*/
|
1116 |
function wpt_add_twitter_inner_box( $post ) {
|
1117 |
if ( current_user_can( 'wpt_can_tweet' ) ) {
|
@@ -1120,52 +1114,55 @@ function wpt_add_twitter_inner_box( $post ) {
|
|
1120 |
<?php
|
1121 |
$tweet_status = '';
|
1122 |
$options = get_option( 'wpt_post_types' );
|
1123 |
-
$type
|
1124 |
-
$status
|
1125 |
-
$post_id
|
1126 |
-
|
1127 |
-
$tweet_this = get_post_meta( $post_id, '_jd_tweet_this', true );
|
1128 |
if ( ! $tweet_this ) {
|
1129 |
-
$tweet_this = ( get_option( 'jd_tweet_default' )
|
1130 |
}
|
1131 |
-
if ( isset( $_GET['action'] ) && $_GET['action']
|
1132 |
$tweet_this = 'no';
|
1133 |
}
|
1134 |
-
if ( isset( $_REQUEST['message'] ) && $_REQUEST['message']
|
1135 |
-
|
|
|
1136 |
$log = wpt_log( 'wpt_status_message', $post_id );
|
1137 |
-
$class = (
|
1138 |
-
if (
|
1139 |
echo "<div class='$class'><p>$log</p></div>";
|
1140 |
}
|
1141 |
}
|
1142 |
}
|
1143 |
-
$
|
1144 |
-
$
|
1145 |
-
$
|
1146 |
-
$tweet = apply_filters( 'wpt_user_text', $tweet, $status );
|
1147 |
-
$template = ( $status == 'publish' ) ? $options[ $type ]['post-edited-text'] : $options[ $type ]['post-published-text'];
|
1148 |
|
1149 |
-
if (
|
|
|
1150 |
$tweet_status = sprintf( __( '%s will not be Tweeted on update.', 'wp-to-twitter' ), ucfirst( $type ) );
|
1151 |
}
|
1152 |
|
1153 |
-
if (
|
1154 |
?>
|
1155 |
<div class='tweet-buttons'>
|
1156 |
<button type='button' class='tweet button-primary' data-action='tweet'><span class='dashicons dashicons-twitter' aria-hidden='true'></span><?php _e( 'Tweet Now', 'wp-to-twitter' ); ?></button>
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
<?php
|
|
|
|
|
|
|
|
|
1169 |
<div class='wpt_log' aria-live='assertive'></div>
|
1170 |
</div>
|
1171 |
<?php
|
@@ -1173,17 +1170,17 @@ function wpt_add_twitter_inner_box( $post ) {
|
|
1173 |
if ( current_user_can( 'wpt_twitter_custom' ) || current_user_can( 'manage_options' ) ) {
|
1174 |
?>
|
1175 |
<p class='jtw'>
|
1176 |
-
<label for="jtw"><?php _e(
|
1177 |
<textarea class="wpt_tweet_box" name="_jd_twitter" id="jtw" rows="2" cols="60"><?php echo esc_attr( $tweet ); ?></textarea>
|
1178 |
-
<?php echo apply_filters( 'wpt_custom_box', '', $tweet, $post_id ); ?>
|
1179 |
</p>
|
1180 |
<?php
|
1181 |
$expanded = $template;
|
1182 |
-
if ( get_option( 'jd_twit_prepend' )
|
1183 |
-
$expanded = "<span title='" . __( 'Your prepended Tweet text; not part of your template.', 'wp-to-twitter' ) . "'>" . stripslashes( get_option( 'jd_twit_prepend' ) ) .
|
1184 |
}
|
1185 |
-
if ( get_option( 'jd_twit_append' )
|
1186 |
-
$expanded = $expanded . " <span title='" . __( 'Your appended Tweet text; not part of your template.', 'wp-to-twitter' ) . "'>" . stripslashes( get_option( 'jd_twit_append' ) ) .
|
1187 |
}
|
1188 |
?>
|
1189 |
<p class='template'>
|
@@ -1198,186 +1195,201 @@ function wpt_add_twitter_inner_box( $post ) {
|
|
1198 |
echo "<label for='yourls_keyword'>" . __( 'YOURLS Custom Keyword', 'wp-to-twitter' ) . "</label> <input type='text' name='_yourls_keyword' id='yourls_keyword' value='$custom_keyword' />";
|
1199 |
}
|
1200 |
} else {
|
1201 |
-
|
1202 |
-
<input type="hidden" name='_jd_twitter' value='<?php
|
1203 |
<?php
|
1204 |
}
|
1205 |
?>
|
1206 |
<div class='wpt-options'>
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
|
|
|
|
|
|
|
|
|
|
1232 |
} else {
|
1233 |
-
|
1234 |
-
|
1235 |
-
printf( __( 'WP Tweets PRO allows you to select Twitter accounts. <a href="%s">Log in and download now!</a>', 'wp-to-twitter' ), 'http://www.wptweetspro.com/account/' );
|
1236 |
-
} else {
|
1237 |
-
printf( __( 'Upgrade to WP Tweets PRO to select Twitter accounts! <a href="%s">Upgrade now!</a>', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro/' );
|
1238 |
-
}
|
1239 |
-
echo "</p>";
|
1240 |
}
|
1241 |
-
echo
|
1242 |
-
}
|
|
|
1243 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1244 |
?>
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
echo "<p>" . sprintf( __( 'Upgrade to WP Tweets PRO to configure options! <a href="%s">Upgrade now!</a>', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro/' ) . "</p>";
|
1252 |
-
}
|
1253 |
}
|
1254 |
?>
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
do_action( 'wpt_custom_tab', $post_id, 'hidden' );
|
1266 |
-
} ?>
|
1267 |
-
</div>
|
1268 |
-
<?php
|
1269 |
-
}
|
1270 |
-
if ( current_user_can( 'wpt_twitter_custom' ) || current_user_can( 'manage_options' ) ) {
|
1271 |
?>
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
</p>
|
1278 |
-
</div>
|
1279 |
-
<?php
|
1280 |
-
} ?>
|
1281 |
</div>
|
1282 |
<?php
|
1283 |
if ( current_user_can( 'wpt_twitter_switch' ) || current_user_can( 'manage_options' ) ) {
|
1284 |
// "no" means 'Don't Tweet' (is checked)
|
1285 |
-
$nochecked = (
|
1286 |
-
$yeschecked = (
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
<?php
|
1293 |
} else {
|
1294 |
-
|
1295 |
-
|
1296 |
<?php
|
1297 |
}
|
1298 |
-
wpt_show_tweets( $
|
1299 |
?>
|
1300 |
<p class="wpt-support">
|
1301 |
-
|
1302 |
-
|
1303 |
?>
|
1304 |
-
|
1305 |
-
<?php
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
<?php
|
1310 |
-
|
|
|
|
|
|
|
|
|
1311 |
echo "<p class='disabled'>$tweet_status</p>";
|
1312 |
}
|
1313 |
?>
|
1314 |
</div>
|
1315 |
<?php
|
1316 |
-
} else {
|
1317 |
-
|
|
|
|
|
|
|
|
|
1318 |
}
|
1319 |
}
|
1320 |
|
1321 |
/**
|
1322 |
* Format history of Tweets attempted on current post.
|
1323 |
-
*
|
1324 |
-
* @param array $
|
1325 |
-
* @param array $failed_tweets Array of failed Tweets sent on this post.
|
1326 |
-
*
|
1327 |
-
* @return string Formatted list of Tweets.
|
1328 |
*/
|
1329 |
-
function wpt_show_tweets( $
|
1330 |
-
|
|
|
|
|
|
|
1331 |
$previous_tweets = array( 0 => $previous_tweets );
|
1332 |
}
|
1333 |
if ( ! empty( $previous_tweets ) || ! empty( $failed_tweets ) ) {
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
}
|
1352 |
-
}
|
1353 |
-
}
|
1354 |
-
?>
|
1355 |
-
</ul>
|
1356 |
-
<?php
|
1357 |
-
$list = false;
|
1358 |
-
$error_list = '';
|
1359 |
-
if ( is_array( $failed_tweets ) ) {
|
1360 |
-
foreach ( $failed_tweets as $failed_tweet ) {
|
1361 |
-
if ( ! empty( $failed_tweet ) ) {
|
1362 |
-
$ft = $failed_tweet['sentence'];
|
1363 |
-
$reason = $failed_tweet['code'];
|
1364 |
-
$error = $failed_tweet['error'];
|
1365 |
-
$list = true;
|
1366 |
-
$error_list .= "<li> <code>Error: $reason</code> $ft <a href='http://twitter.com/intent/tweet?text=" . urlencode( $ft ) . "'>Tweet this</a><br /><em>$error</em></li>";
|
1367 |
-
}
|
1368 |
}
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1372 |
}
|
1373 |
}
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
}
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
|
|
|
|
|
|
|
|
|
|
1381 |
}
|
1382 |
}
|
1383 |
|
@@ -1387,18 +1399,18 @@ add_action( 'admin_enqueue_scripts', 'wpt_admin_scripts', 10, 1 );
|
|
1387 |
*/
|
1388 |
function wpt_admin_scripts() {
|
1389 |
global $current_screen, $wpt_version;
|
1390 |
-
if (
|
1391 |
wp_enqueue_script( 'charCount', plugins_url( 'wp-to-twitter/js/jquery.charcount.js' ), array( 'jquery' ), $wpt_version );
|
1392 |
}
|
1393 |
-
if ( $current_screen->base
|
1394 |
wp_enqueue_script( 'wpt.ajax', plugins_url( 'js/ajax.js', __FILE__ ), array( 'jquery' ), $wpt_version );
|
1395 |
wp_localize_script( 'wpt.ajax', 'wpt_data', array(
|
1396 |
'post_ID' => (int) $_GET['post'],
|
1397 |
'action' => 'wpt_tweet',
|
1398 |
-
'security' => wp_create_nonce( 'wpt-tweet-nonce' )
|
1399 |
) );
|
1400 |
}
|
1401 |
-
if (
|
1402 |
wp_enqueue_script( 'wpt.tabs', plugins_url( 'js/tabs.js', __FILE__ ), array( 'jquery' ), $wpt_version );
|
1403 |
wp_localize_script( 'wpt.tabs', 'firstItem', 'wpt_post' );
|
1404 |
wp_localize_script( 'wpt.tabs', 'firstPerm', 'wpt_editor' );
|
@@ -1409,21 +1421,20 @@ function wpt_admin_scripts() {
|
|
1409 |
add_action( 'wp_ajax_wpt_tweet', 'wpt_ajax_tweet' );
|
1410 |
/**
|
1411 |
* Handle Tweets sent via Ajax Tweet Now/Schedule Tweet buttons.
|
1412 |
-
*
|
1413 |
-
* @return string Confirmation message indicating success or failure of Tweeting.
|
1414 |
*/
|
1415 |
function wpt_ajax_tweet() {
|
1416 |
if ( ! check_ajax_referer( 'wpt-tweet-nonce', 'security', false ) ) {
|
1417 |
-
echo
|
1418 |
die;
|
1419 |
}
|
1420 |
-
$action
|
1421 |
-
$authors
|
1422 |
-
$upload
|
1423 |
$current_user = wp_get_current_user();
|
1424 |
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists() ) {
|
1425 |
if ( wtt_oauth_test( $current_user->ID, 'verify' ) ) {
|
1426 |
-
$auth
|
|
|
1427 |
} else {
|
1428 |
$auth = false;
|
1429 |
$user_ID = $current_user->ID;
|
@@ -1433,44 +1444,45 @@ function wpt_ajax_tweet() {
|
|
1433 |
$user_ID = $current_user->ID;
|
1434 |
}
|
1435 |
|
1436 |
-
$authors = ( is_array( $authors ) && !empty( $authors ) ) ? $authors : array( $auth );
|
1437 |
-
|
1438 |
if ( current_user_can( 'wpt_can_tweet' ) ) {
|
1439 |
$options = get_option( 'wpt_post_types' );
|
1440 |
$post_ID = intval( $_REQUEST['tweet_post_id'] );
|
1441 |
$type = get_post_type( $post_ID );
|
1442 |
$default = ( isset( $options[ $type ]['post-edited-text'] ) ) ? $options[ $type ]['post-edited-text'] : '';
|
1443 |
-
$sentence = ( isset( $_REQUEST['tweet_text'] ) && trim( $_REQUEST['tweet_text'] )
|
1444 |
$sentence = stripcslashes( trim( $sentence ) );
|
1445 |
-
$post_info = wpt_post_info( $post_ID );
|
1446 |
$sentence = jd_truncate_tweet( $sentence, $post_info, $post_ID, false, $user_ID );
|
1447 |
$schedule = ( isset( $_REQUEST['tweet_schedule'] ) ) ? strtotime( $_REQUEST['tweet_schedule'] ) : rand( 60, 240 );
|
1448 |
$print_schedule = date_i18n( get_option( 'date_format' ) . ' @ ' . get_option( 'time_format' ), $schedule );
|
1449 |
$offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
|
1450 |
$schedule = $schedule - $offset;
|
1451 |
-
$media = (
|
1452 |
-
|
1453 |
-
foreach( $authors as $auth ) {
|
1454 |
-
|
1455 |
-
$auth = (
|
1456 |
-
|
1457 |
switch ( $action ) {
|
1458 |
-
case 'tweet'
|
1459 |
wpt_post_to_twitter( $sentence, $auth, $post_ID, $media );
|
1460 |
break;
|
1461 |
-
case 'schedule'
|
1462 |
wp_schedule_single_event( $schedule, 'wpt_schedule_tweet_action', array(
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
break;
|
1469 |
}
|
1470 |
-
|
|
|
1471 |
echo $return;
|
1472 |
if ( count( $authors ) > 1 ) {
|
1473 |
-
echo
|
1474 |
}
|
1475 |
}
|
1476 |
} else {
|
@@ -1481,23 +1493,23 @@ function wpt_ajax_tweet() {
|
|
1481 |
|
1482 |
add_action( 'admin_head', 'wpt_admin_script' );
|
1483 |
/**
|
1484 |
-
* Print scripts to WP Tweets PRO pages.
|
1485 |
*/
|
1486 |
function wpt_admin_script() {
|
1487 |
global $current_screen;
|
1488 |
-
if (
|
1489 |
wp_register_style( 'wpt-post-styles', plugins_url( 'css/post-styles.css', __FILE__ ) );
|
1490 |
wp_enqueue_style( 'wpt-post-styles' );
|
1491 |
$config = wpt_max_length();
|
1492 |
// add one; character count starts from 1.
|
1493 |
-
if ( $current_screen->base
|
1494 |
$allowed = $config['base_length'] - mb_strlen( stripslashes( get_option( 'jd_twit_prepend' ) . get_option( 'jd_twit_append' ) ) ) + 1;
|
1495 |
} else {
|
1496 |
$allowed = $config['base_length'] + 1;
|
1497 |
}
|
1498 |
-
if ( function_exists( 'wpt_pro_exists' ) && get_option( 'jd_individual_twitter_users' )
|
1499 |
$first = '#authors';
|
1500 |
-
}
|
1501 |
$first = '#custom';
|
1502 |
} else {
|
1503 |
$first = '#notes';
|
@@ -1505,15 +1517,15 @@ function wpt_admin_script() {
|
|
1505 |
wp_register_script( 'wpt-base-js', plugins_url( 'js/base.js', __FILE__ ), array( 'jquery' ) );
|
1506 |
wp_enqueue_script( 'wpt-base-js' );
|
1507 |
wp_localize_script( 'wpt-base-js', 'wptSettings', array(
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
echo "
|
1514 |
<style type='text/css'>
|
1515 |
-
#wp2t h3 span, #wp2t h2 span { padding-left: 30px; background: url(" . plugins_url( 'wp-to-twitter/images/twitter-bird-light-bgs.png' ) .
|
1516 |
-
</style>
|
1517 |
}
|
1518 |
}
|
1519 |
|
@@ -1521,7 +1533,6 @@ function wpt_admin_script() {
|
|
1521 |
* Post the Custom Tweet & custom Tweet data into the post meta table
|
1522 |
*
|
1523 |
* @param integer $id Post ID.
|
1524 |
-
*
|
1525 |
*/
|
1526 |
function wpt_save_post( $id ) {
|
1527 |
if ( empty( $_POST ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || wp_is_post_revision( $id ) || isset( $_POST['_inline_edit'] ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ! wpt_in_post_type( $id ) ) {
|
@@ -1531,88 +1542,86 @@ function wpt_save_post( $id ) {
|
|
1531 |
$yourls = $_POST['_yourls_keyword'];
|
1532 |
$update = update_post_meta( $id, '_yourls_keyword', $yourls );
|
1533 |
}
|
1534 |
-
if ( isset( $_POST['_jd_twitter'] ) && $_POST['_jd_twitter']
|
1535 |
$twitter = $_POST['_jd_twitter'];
|
1536 |
-
$update
|
1537 |
-
}
|
1538 |
delete_post_meta( $id, '_jd_twitter' );
|
1539 |
}
|
1540 |
-
if ( isset( $_POST['_jd_wp_twitter'] ) && $_POST['_jd_wp_twitter']
|
1541 |
$wp_twitter = $_POST['_jd_wp_twitter'];
|
1542 |
-
$update
|
1543 |
}
|
1544 |
if ( isset( $_POST['_jd_tweet_this'] ) ) {
|
1545 |
-
$tweet_this = ( $_POST['_jd_tweet_this']
|
1546 |
-
$update
|
1547 |
} else {
|
1548 |
if ( isset( $_POST['_wpnonce'] ) ) {
|
1549 |
-
$tweet_default = ( get_option( 'jd_tweet_default' )
|
1550 |
-
$update
|
1551 |
}
|
1552 |
}
|
1553 |
-
if ( isset( $_POST['wpt_clear_history'] ) && $_POST['wpt_clear_history']
|
1554 |
delete_post_meta( $id, '_wpt_failed' );
|
1555 |
delete_post_meta( $id, '_jd_wp_twitter' );
|
1556 |
delete_post_meta( $id, '_wpt_short_url' );
|
1557 |
delete_post_meta( $id, '_wp_jd_twitter' );
|
1558 |
}
|
1559 |
-
// WPT PRO
|
1560 |
$update = apply_filters( 'wpt_insert_post', $_POST, $id );
|
1561 |
-
// WPT PRO
|
1562 |
-
// only send debug data if post meta is updated.
|
1563 |
-
if (
|
1564 |
-
wpt_mail(
|
1565 |
}
|
1566 |
-
if ( isset( $_POST['wpt-delete-debug'] ) && $_POST['wpt-delete-debug']
|
1567 |
delete_post_meta( $id, '_wpt_debug_log' );
|
1568 |
}
|
1569 |
-
if ( isset( $_POST['wpt-delete-all-debug'] ) && $_POST['wpt-delete-all-debug']
|
1570 |
delete_post_meta_by_key( '_wpt_debug_log' );
|
1571 |
}
|
1572 |
}
|
1573 |
|
1574 |
/**
|
1575 |
* Show user profile data on Edit User pages.
|
1576 |
-
*
|
1577 |
-
* return @string Configuration forms for WP to Twitter user-specific settings.
|
1578 |
*/
|
1579 |
function wpt_twitter_profile() {
|
1580 |
global $user_ID;
|
1581 |
$current_user = wp_get_current_user();
|
1582 |
-
$user_edit
|
1583 |
|
1584 |
$is_enabled = get_user_meta( $user_edit, 'wp-to-twitter-enable-user', true );
|
1585 |
$twitter_username = get_user_meta( $user_edit, 'wp-to-twitter-user-username', true );
|
1586 |
$wpt_remove = get_user_meta( $user_edit, 'wpt-remove', true );
|
1587 |
-
if ( current_user_can( 'wpt_twitter_oauth' ) || current_user_can( 'manage_options' ) ) {
|
1588 |
?>
|
1589 |
<h3><?php _e( 'WP Tweets User Settings', 'wp-to-twitter' ); ?></h3>
|
1590 |
-
<?php
|
|
|
1591 |
wpt_connect_oauth_message( $user_edit );
|
1592 |
-
}
|
|
|
1593 |
<table class="form-table">
|
1594 |
<tr>
|
1595 |
-
<th scope="row"><?php _e(
|
1596 |
<td>
|
1597 |
-
<input type="radio" name="wp-to-twitter-enable-user" id="wp-to-twitter-enable-user-3" value="mainAtTwitter"<?php checked( $is_enabled, 'mainAtTwitter' ); ?> /> <label for="wp-to-twitter-enable-user-3"><?php _e(
|
1598 |
-
<input type="radio" name="wp-to-twitter-enable-user" id="wp-to-twitter-enable-user-4" value="mainAtTwitterPlus"<?php checked( $is_enabled, 'mainAtTwitterPlus' ); ?> /> <label for="wp-to-twitter-enable-user-4"><?php _e(
|
1599 |
</td>
|
1600 |
</tr>
|
1601 |
<tr>
|
1602 |
-
<th scope="row"
|
1603 |
-
|
1604 |
</th>
|
1605 |
-
<td
|
1606 |
-
|
1607 |
</td>
|
1608 |
</tr>
|
1609 |
<tr>
|
1610 |
-
<th scope="row"
|
1611 |
-
|
1612 |
-
<td
|
1613 |
-
|
1614 |
-
echo ' checked="checked"';
|
1615 |
-
} ?> /> <?php _e( 'Do not display my account in the #account# template tag.', 'wp-to-twitter' ); ?>
|
1616 |
</td>
|
1617 |
</tr>
|
1618 |
<?php echo apply_filters( 'wpt_twitter_user_fields', $user_edit ); ?>
|
@@ -1625,11 +1634,11 @@ function wpt_twitter_profile() {
|
|
1625 |
}
|
1626 |
} else {
|
1627 |
// hidden fields. If function is enabled, but this user does not have privileges to edit.
|
1628 |
-
|
1629 |
-
<input type="hidden" name="wp-to-twitter-enable-user" value="<?php
|
1630 |
-
<input type="hidden" name="wp-to-twitter-user-username" value="<?php
|
1631 |
-
<input type="hidden" name="wpt-remove" value="<?php
|
1632 |
-
|
1633 |
}
|
1634 |
}
|
1635 |
|
@@ -1637,18 +1646,25 @@ function wpt_twitter_profile() {
|
|
1637 |
* This compensates for an old error where the user ID is echoed directly into the page.
|
1638 |
*/
|
1639 |
add_filter( 'wpt_twitter_user_fields', 'wpt_basic_user_fields', 100, 1 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1640 |
function wpt_basic_user_fields( $user_edit ) {
|
1641 |
if ( is_int( $user_edit ) ) {
|
1642 |
return '';
|
1643 |
}
|
1644 |
-
|
1645 |
return $user_edit;
|
1646 |
}
|
1647 |
|
1648 |
-
/**
|
1649 |
-
* Save user profile data
|
1650 |
*/
|
1651 |
-
function wpt_twitter_save_profile() {
|
1652 |
global $user_ID;
|
1653 |
$current_user = wp_get_current_user();
|
1654 |
if ( isset( $_POST['user_id'] ) ) {
|
@@ -1656,7 +1672,7 @@ function wpt_twitter_save_profile() {
|
|
1656 |
} else {
|
1657 |
$edit_id = $user_ID;
|
1658 |
}
|
1659 |
-
if ( current_user_can( 'wpt_twitter_oauth' ) || current_user_can( 'manage_options' ) ) {
|
1660 |
$enable = ( isset( $_POST['wp-to-twitter-enable-user'] ) ) ? $_POST['wp-to-twitter-enable-user'] : '';
|
1661 |
$username = ( isset( $_POST['wp-to-twitter-user-username'] ) ) ? $_POST['wp-to-twitter-user-username'] : '';
|
1662 |
$wpt_remove = ( isset( $_POST['wpt-remove'] ) ) ? 'on' : '';
|
@@ -1664,16 +1680,16 @@ function wpt_twitter_save_profile() {
|
|
1664 |
update_user_meta( $edit_id, 'wp-to-twitter-user-username', $username );
|
1665 |
update_user_meta( $edit_id, 'wpt-remove', $wpt_remove );
|
1666 |
}
|
1667 |
-
//WPT PRO
|
1668 |
apply_filters( 'wpt_save_user', $edit_id, $_POST );
|
1669 |
}
|
1670 |
|
|
|
1671 |
/**
|
1672 |
* Send links to old admin to new admin page
|
1673 |
*/
|
1674 |
-
add_action( 'init', 'wpt_old_admin_redirect' );
|
1675 |
function wpt_old_admin_redirect() {
|
1676 |
-
if ( is_admin() && isset( $_GET['page'] ) &&
|
1677 |
wp_safe_redirect( admin_url( 'admin.php?page=wp-tweets-pro' ) );
|
1678 |
exit;
|
1679 |
}
|
@@ -1686,39 +1702,44 @@ add_action( 'admin_menu', 'wpt_admin_page' );
|
|
1686 |
function wpt_admin_page() {
|
1687 |
if ( function_exists( 'add_menu_page' ) && ! function_exists( 'wpt_pro_functions' ) ) {
|
1688 |
$icon_path = plugins_url( 'images/icon.png', __FILE__ );
|
1689 |
-
$page
|
1690 |
}
|
1691 |
}
|
1692 |
|
1693 |
add_action( 'admin_head', 'wpt_admin_style' );
|
1694 |
-
/**
|
1695 |
* Add stylesheets to WP to Twitter pages.
|
1696 |
*/
|
1697 |
function wpt_admin_style() {
|
1698 |
-
if ( isset( $_GET['page'] ) && (
|
1699 |
wp_enqueue_style( 'wpt-styles', plugins_url( 'css/styles.css', __FILE__ ) );
|
1700 |
}
|
1701 |
}
|
1702 |
|
1703 |
-
/**
|
1704 |
* Add WP to Twitter links to plug-in information.
|
|
|
|
|
|
|
|
|
|
|
1705 |
*/
|
1706 |
function wpt_plugin_action( $links, $file ) {
|
1707 |
-
if (
|
1708 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
1709 |
-
$links[] = "<a href='$admin_url'>" . __( 'WP to Twitter Settings', 'wp-to-twitter'
|
1710 |
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
1711 |
-
$links[] = "<a href='http://www.wptweetspro.com/wp-tweets-pro'>" . __( 'Go Premium', 'wp-to-twitter'
|
1712 |
}
|
1713 |
}
|
1714 |
|
1715 |
return $links;
|
1716 |
}
|
1717 |
|
1718 |
-
//Add Plugin Actions to WordPress
|
1719 |
-
add_filter( 'plugin_action_links', 'wpt_plugin_action',
|
1720 |
|
1721 |
-
if ( get_option( 'jd_individual_twitter_users' )
|
1722 |
add_action( 'show_user_profile', 'wpt_twitter_profile' );
|
1723 |
add_action( 'edit_user_profile', 'wpt_twitter_profile' );
|
1724 |
add_action( 'profile_update', 'wpt_twitter_save_profile' );
|
@@ -1727,8 +1748,6 @@ if ( get_option( 'jd_individual_twitter_users' ) == '1' ) {
|
|
1727 |
add_action( 'in_plugin_update_message-wp-to-twitter/wp-to-twitter.php', 'wpt_plugin_update_message' );
|
1728 |
/**
|
1729 |
* Parse plugin update info to display in update list.
|
1730 |
-
*
|
1731 |
-
* @return string Notice from new version's readme.txt
|
1732 |
*/
|
1733 |
function wpt_plugin_update_message() {
|
1734 |
global $wpt_version;
|
@@ -1738,44 +1757,45 @@ function wpt_plugin_update_message() {
|
|
1738 |
if ( ! is_wp_error( $response ) || is_array( $response ) ) {
|
1739 |
$data = $response['body'];
|
1740 |
$bits = explode( '== Upgrade Notice ==', $data );
|
1741 |
-
$note = '
|
1742 |
}
|
1743 |
-
|
1744 |
echo $note;
|
1745 |
}
|
1746 |
|
1747 |
-
if ( get_option( 'jd_twit_blogroll' )
|
1748 |
add_action( 'add_link', 'wpt_twit_link' );
|
1749 |
}
|
1750 |
|
1751 |
add_action( 'save_post', 'wpt_twit', 15 );
|
1752 |
add_action( 'save_post', 'wpt_save_post', 10 );
|
1753 |
-
|
1754 |
/**
|
1755 |
* Check whether a given post is in an allowed post type and has an update template configured.
|
1756 |
-
*
|
1757 |
* @param integer $id Post ID.
|
1758 |
*
|
1759 |
* @return boolean True if post is allowed, false otherwise.
|
1760 |
*/
|
1761 |
function wpt_in_post_type( $id ) {
|
1762 |
$post_type_settings = get_option( 'wpt_post_types' );
|
1763 |
-
if ( is_array( $post_type_settings ) && !empty( $post_type_settings ) ) {
|
1764 |
-
$post_types
|
1765 |
-
$type
|
1766 |
if ( in_array( $type, $post_types ) ) {
|
1767 |
-
if ( $post_type_settings[ $type ]['post-edited-update']
|
1768 |
return true;
|
1769 |
}
|
1770 |
}
|
1771 |
}
|
1772 |
-
|
1773 |
return false;
|
1774 |
}
|
1775 |
|
1776 |
add_action( 'future_to_publish', 'wpt_future_to_publish', 16 );
|
1777 |
/**
|
1778 |
* Handle Tweeting posts scheduled for the future.
|
|
|
|
|
1779 |
*/
|
1780 |
function wpt_future_to_publish( $post ) {
|
1781 |
$id = $post->ID;
|
@@ -1787,18 +1807,19 @@ function wpt_future_to_publish( $post ) {
|
|
1787 |
|
1788 |
/**
|
1789 |
* Handle Tweeting posts published directly.
|
|
|
|
|
1790 |
*/
|
1791 |
function wpt_twit( $id ) {
|
1792 |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE || wp_is_post_revision( $id ) || ! wpt_in_post_type( $id ) ) {
|
1793 |
return;
|
1794 |
}
|
1795 |
-
$post = get_post( $id );
|
1796 |
-
if ( $post->post_status
|
1797 |
return;
|
1798 |
-
}
|
1799 |
// is there any reason to accept any other status?
|
1800 |
-
|
1801 |
-
// This is an issue only until the release of WP 4.7
|
1802 |
remove_action( 'save_post', 'wpt_twit', 15 );
|
1803 |
wpt_twit_instant( $id );
|
1804 |
add_action( 'save_post', 'wpt_twit', 15 );
|
@@ -1814,13 +1835,13 @@ add_action( 'publish_phone', 'wpt_twit_xmlrpc' );
|
|
1814 |
*/
|
1815 |
function wpt_twit_future( $id ) {
|
1816 |
set_transient( '_wpt_twit_future', $id, 10 );
|
1817 |
-
// instant action has already run for this post. // prevent running actions twice (need both for older WP)
|
1818 |
if ( get_transient( '_wpt_twit_instant' ) && get_transient( '_wpt_twit_instant' ) == $id ) {
|
1819 |
delete_transient( '_wpt_twit_instant' );
|
1820 |
|
1821 |
return;
|
1822 |
}
|
1823 |
-
|
1824 |
wpt_tweet( $id, 'future' );
|
1825 |
}
|
1826 |
|
@@ -1846,8 +1867,12 @@ function wpt_twit_instant( $id ) {
|
|
1846 |
wpt_tweet( $id, 'instant' );
|
1847 |
}
|
1848 |
|
1849 |
-
/**
|
1850 |
* Tweet XMLRPC posts.
|
|
|
|
|
|
|
|
|
1851 |
*/
|
1852 |
function wpt_twit_xmlrpc( $id ) {
|
1853 |
set_transient( '_wpt_twit_xmlrpc', $id, 10 );
|
@@ -1863,7 +1888,7 @@ add_action( 'wpt_schedule_promotion_action', 'wpt_schedule_promotion' );
|
|
1863 |
* Set an option indicating that a job has been scheduled for promoting WP Tweets PRO.
|
1864 |
*/
|
1865 |
function wpt_schedule_promotion() {
|
1866 |
-
if ( ! function_exists( 'wpt_pro_exists' ) && get_option( 'wpt_promotion_scheduled' )
|
1867 |
update_option( 'wpt_promotion_scheduled', 2 );
|
1868 |
}
|
1869 |
}
|
@@ -1872,7 +1897,7 @@ function wpt_schedule_promotion() {
|
|
1872 |
* Dismiss promotion notice.
|
1873 |
*/
|
1874 |
function wpt_dismiss_promotion() {
|
1875 |
-
if ( isset( $_GET['dismiss'] ) && $_GET['dismiss']
|
1876 |
update_option( 'wpt_promotion_scheduled', 3 );
|
1877 |
}
|
1878 |
}
|
@@ -1880,21 +1905,24 @@ function wpt_dismiss_promotion() {
|
|
1880 |
add_action( 'admin_notices', 'wpt_dismiss_promotion', 5 );
|
1881 |
add_action( 'admin_notices', 'wpt_promotion_notice', 10 );
|
1882 |
add_action( 'admin_notices', 'wpt_debugging_enabled', 10 );
|
1883 |
-
|
|
|
|
|
1884 |
function wpt_debugging_enabled() {
|
1885 |
if ( current_user_can( 'manage_options' ) && WPT_DEBUG ) {
|
1886 |
-
echo "<div class='notice error important'><p>" . __(
|
1887 |
-
}
|
1888 |
}
|
1889 |
|
1890 |
/**
|
1891 |
* Display promotion notice to admin users who have not donated or purchased WP Tweets PRO.
|
1892 |
*/
|
1893 |
function wpt_promotion_notice() {
|
1894 |
-
if ( current_user_can( 'activate_plugins' ) && get_option( 'wpt_promotion_scheduled' )
|
1895 |
-
$upgrade =
|
1896 |
$dismiss = admin_url( 'admin.php?page=wp-tweets-pro&dismiss=promotion' );
|
1897 |
-
|
|
|
1898 |
}
|
1899 |
}
|
1900 |
|
@@ -1916,43 +1944,23 @@ add_filter( 'wpt_enqueue_feed_styles', 'wpt_permit_feed_styles' );
|
|
1916 |
* Check whether Twitter Feed styles are enabled.
|
1917 |
*
|
1918 |
* @param boolean $value true if permitted.
|
1919 |
-
*
|
1920 |
* @return boolean $value False if settings disable styles.
|
1921 |
*/
|
1922 |
function wpt_permit_feed_styles( $value ) {
|
1923 |
-
if ( get_option( 'wpt_permit_feed_styles' )
|
1924 |
$value = false;
|
1925 |
}
|
1926 |
|
1927 |
return $value;
|
1928 |
}
|
1929 |
|
1930 |
-
/*
|
1931 |
-
// Add notes about Tweet status to posts admin
|
1932 |
-
function wpt_column($cols) {
|
1933 |
-
$cols['wpt'] = __('Tweet Status','wp-to-twitter');
|
1934 |
-
return $cols;
|
1935 |
-
}
|
1936 |
-
|
1937 |
-
// Echo the ID for the new column
|
1938 |
-
function wpt_value($column_name, $id) {
|
1939 |
-
if ($column_name == 'wpt') {
|
1940 |
-
$marked = ucfirst( ( get_post_meta($id,'_jd_tweet_this',true) ) );
|
1941 |
-
echo $marked;
|
1942 |
-
}
|
1943 |
-
}
|
1944 |
-
|
1945 |
-
function wpt_return_value($value, $column_name, $id) {
|
1946 |
-
if ( $column_name == 'wpt' ) {
|
1947 |
-
$value = $id;
|
1948 |
-
}
|
1949 |
-
return $value;
|
1950 |
-
}
|
1951 |
-
*/
|
1952 |
-
// Output CSS for width of new column
|
1953 |
add_action( 'admin_head', 'wpt_css' );
|
|
|
|
|
|
|
1954 |
function wpt_css() {
|
1955 |
-
|
1956 |
<style type="text/css">
|
1957 |
th#wpt {
|
1958 |
width: 60px;
|
@@ -1967,24 +1975,3 @@ function wpt_css() {
|
|
1967 |
</style>
|
1968 |
<?php
|
1969 |
}
|
1970 |
-
/*
|
1971 |
-
// Actions/Filters for various tables and the css output
|
1972 |
-
add_action('admin_init', 'wpt_add');
|
1973 |
-
function wpt_add() {
|
1974 |
-
$post_type_settings = get_option('wpt_post_types');
|
1975 |
-
$post_types = array_keys($post_type_settings);
|
1976 |
-
|
1977 |
-
add_action('admin_head', 'wpt_css');
|
1978 |
-
if ( !$post_types || in_array( 'post', $post_types ) ) {
|
1979 |
-
add_filter('manage_posts_columns', 'wpt_column');
|
1980 |
-
add_action('manage_posts_custom_column', 'wpt_value', 10, 2);
|
1981 |
-
}
|
1982 |
-
if ( !$post_types || in_array( 'page', $post_types ) ) {
|
1983 |
-
add_filter('manage_pages_columns', 'wpt_column');
|
1984 |
-
add_action('manage_pages_custom_column', 'wpt_value', 10, 2);
|
1985 |
-
}
|
1986 |
-
foreach ( $post_types as $types ) {
|
1987 |
-
add_action("manage_${types}_columns", 'wpt_column');
|
1988 |
-
add_filter("manage_${types}_custom_column", 'wpt_value', 10, 2);
|
1989 |
-
}
|
1990 |
-
} */
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP to Twitter
|
4 |
+
*
|
5 |
+
* @package WP to Twitter
|
6 |
+
* @author Joe Dolson
|
7 |
+
* @copyright 2008-2018 Joe Dolson
|
8 |
+
* @license GPL-2.0+
|
9 |
+
*
|
10 |
+
* @wordpress-plugin
|
11 |
+
* Plugin Name: WP to Twitter
|
12 |
+
* Plugin URI: http://www.joedolson.com/wp-to-twitter/
|
13 |
+
* Description: Posts a Tweet when you update your WordPress blog or post a link, using your URL shortener. Rich options to customize and promote your Tweets.
|
14 |
+
* Author: Joseph C Dolson
|
15 |
+
* Author URI: http://www.joedolson.com
|
16 |
+
* Text Domain: wp-to-twitter
|
17 |
+
* License: GPL-2.0+
|
18 |
+
* License URI: http://www.gnu.org/license/gpl-2.0.txt
|
19 |
+
* Domain Path: lang
|
20 |
+
* Version: 3.3.3
|
21 |
+
*/
|
22 |
+
|
23 |
/*
|
24 |
+
Copyright 2008-2018 Joe Dolson (email : joe@joedolson.com)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
+
This program is free software; you can redistribute it and/or modify
|
27 |
+
it under the terms of the GNU General Public License as published by
|
28 |
+
the Free Software Foundation; either version 2 of the License, or
|
29 |
+
(at your option) any later version.
|
30 |
|
31 |
+
This program is distributed in the hope that it will be useful,
|
32 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
33 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
34 |
+
GNU General Public License for more details.
|
35 |
|
36 |
+
You should have received a copy of the GNU General Public License
|
37 |
+
along with this program; if not, write to the Free Software
|
38 |
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
39 |
*/
|
40 |
if ( ! defined( 'ABSPATH' ) ) {
|
41 |
exit;
|
42 |
+
}
|
43 |
|
44 |
+
define( 'WPT_DEBUG', false ); // Debugging only works with WP Tweets PRO.
|
45 |
+
define( 'WPT_DEBUG_BY_EMAIL', false ); // Email debugging no longer default as of 3.3.0.
|
46 |
define( 'WPT_DEBUG_ADDRESS', get_option( 'admin_email' ) );
|
47 |
+
define( 'WPT_FROM', 'From: \"' . get_option( 'blogname' ) . '\" <' . get_option( 'admin_email' ) . '>' );
|
48 |
+
|
49 |
+
require_once( plugin_dir_path( __FILE__ ) . 'wpt-functions.php' );
|
50 |
+
require_once( plugin_dir_path( __FILE__ ) . 'wp-to-twitter-oauth.php' );
|
51 |
+
require_once( plugin_dir_path( __FILE__ ) . 'wp-to-twitter-shorteners.php' );
|
52 |
+
require_once( plugin_dir_path( __FILE__ ) . 'wp-to-twitter-manager.php' );
|
53 |
+
require_once( plugin_dir_path( __FILE__ ) . 'wpt-truncate.php' );
|
54 |
+
require_once( plugin_dir_path( __FILE__ ) . 'classes/class-wpt-twitterfeed.php' );
|
55 |
+
require_once( plugin_dir_path( __FILE__ ) . 'wpt-widget.php' );
|
56 |
+
require_once( plugin_dir_path( __FILE__ ) . 'wpt-rate-limiting.php' );
|
|
|
57 |
|
58 |
global $wpt_version;
|
59 |
+
$wpt_version = '3.3.3';
|
60 |
|
61 |
add_action( 'init', 'wpt_load_textdomain' );
|
62 |
+
/**
|
63 |
+
* Set up text domain for WP to Twitter.
|
64 |
+
*/
|
65 |
function wpt_load_textdomain() {
|
66 |
load_plugin_textdomain( 'wp-to-twitter' );
|
67 |
}
|
68 |
|
69 |
+
add_action( 'widgets_init', 'wpt_register_widgets' );
|
70 |
+
/**
|
71 |
+
* Register WP to Twitter Widgets
|
72 |
+
*/
|
73 |
+
function wpt_register_widgets() {
|
74 |
+
register_widget( 'WPT_Latest_Tweets_Widget' );
|
75 |
+
register_widget( 'WPT_Search_Tweets_Widget' );
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Check for OAuth configuration
|
80 |
+
*
|
81 |
+
* @param mixed int/boolean $auth Which account to check.
|
82 |
+
*
|
83 |
+
* @return boolean Whether authorized.
|
84 |
+
*/
|
85 |
function wpt_check_oauth( $auth = false ) {
|
86 |
if ( ! function_exists( 'wtt_oauth_test' ) ) {
|
87 |
$oauth = false;
|
92 |
return $oauth;
|
93 |
}
|
94 |
|
95 |
+
/**
|
96 |
+
* Check whether version requires activation.
|
97 |
+
*/
|
98 |
function wpt_check_version() {
|
99 |
global $wpt_version;
|
100 |
+
$prev_version = ( '' != get_option( 'wp_to_twitter_version' ) ) ? get_option( 'wp_to_twitter_version' ) : '1.0.0';
|
101 |
+
if ( version_compare( $prev_version, $wpt_version, '<' ) ) {
|
102 |
wptotwitter_activate();
|
103 |
}
|
104 |
}
|
105 |
|
106 |
+
/**
|
107 |
+
* Activate WP to Twitter.
|
108 |
+
*/
|
109 |
function wptotwitter_activate() {
|
110 |
// If this has never run before, do the initial setup.
|
111 |
+
$new_install = ( 1 == get_option( 'wpt_twitter_setup' ) || 1 == get_option( 'twitterInitialised' ) ) ? false : true;
|
112 |
if ( $new_install ) {
|
113 |
$initial_settings = array(
|
114 |
'post' => array(
|
115 |
'post-published-update' => 1,
|
116 |
'post-published-text' => 'New post: #title# #url#',
|
117 |
'post-edited-update' => 0,
|
118 |
+
'post-edited-text' => 'Post Edited: #title# #url#',
|
119 |
),
|
120 |
'page' => array(
|
121 |
'post-published-update' => 0,
|
122 |
'post-published-text' => 'New page: #title# #url#',
|
123 |
'post-edited-update' => 0,
|
124 |
+
'post-edited-text' => 'Page edited: #title# #url#',
|
125 |
+
),
|
126 |
);
|
127 |
update_option( 'wpt_post_types', $initial_settings );
|
128 |
update_option( 'jd_twit_blogroll', '1' );
|
134 |
update_option( 'jd_replace_character', '' );
|
135 |
$administrator = get_role( 'administrator' );
|
136 |
if ( is_object( $administrator ) ) {
|
137 |
+
// wpt_twitter_oauth is the general permission for editing user accounts.
|
138 |
+
$administrator->add_cap( 'wpt_twitter_oauth' );
|
139 |
$administrator->add_cap( 'wpt_twitter_custom' );
|
140 |
$administrator->add_cap( 'wpt_twitter_switch' );
|
141 |
$administrator->add_cap( 'wpt_can_tweet' );
|
156 |
|
157 |
update_option( 'jd_twit_remote', '0' );
|
158 |
update_option( 'jd_post_excerpt', 30 );
|
159 |
+
// Use Google Analytics with Twitter.
|
160 |
update_option( 'twitter-analytics-campaign', 'twitter' );
|
161 |
update_option( 'use-twitter-analytics', '0' );
|
162 |
update_option( 'jd_dynamic_analytics', '0' );
|
163 |
update_option( 'no-analytics', 1 );
|
164 |
update_option( 'use_dynamic_analytics', 'category' );
|
165 |
+
// Use custom external URLs to point elsewhere.
|
166 |
update_option( 'jd_twit_custom_url', 'external_link' );
|
167 |
+
// Error checking.
|
168 |
update_option( 'wp_url_failure', '0' );
|
169 |
// Default publishing options.
|
170 |
update_option( 'jd_tweet_default', '0' );
|
172 |
update_option( 'wpt_inline_edits', '0' );
|
173 |
// Note that default options are set.
|
174 |
update_option( 'wpt_twitter_setup', '1' );
|
175 |
+
update_option( 'jd_keyword_format', '0' );
|
176 |
}
|
177 |
+
|
178 |
global $wpt_version;
|
179 |
+
$prev_version = get_option( 'wp_to_twitter_version' );
|
|
|
180 |
$administrator = get_role( 'administrator' );
|
181 |
+
$upgrade = version_compare( $prev_version, '2.9.0', '<' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
if ( $upgrade ) {
|
183 |
$administrator->add_cap( 'wpt_tweet_now' );
|
184 |
}
|
185 |
+
|
186 |
update_option( 'wp_to_twitter_version', $wpt_version );
|
187 |
}
|
188 |
|
189 |
+
/**
|
190 |
+
* Function checks for an alternate URL to be Tweeted. Contribution by Bill Berry.
|
191 |
+
*
|
192 |
+
* @param int $post_ID Post ID.
|
193 |
+
*
|
194 |
+
* @return Link to use for this URL.
|
195 |
+
*/
|
196 |
function wpt_link( $post_ID ) {
|
197 |
$ex_link = false;
|
198 |
$external_link = get_option( 'jd_twit_custom_url' );
|
199 |
$permalink = get_permalink( $post_ID );
|
200 |
+
if ( '' != $external_link ) {
|
201 |
$ex_link = get_post_meta( $post_ID, $external_link, true );
|
202 |
}
|
203 |
|
204 |
return ( $ex_link ) ? $ex_link : $permalink;
|
205 |
}
|
206 |
|
207 |
+
/**
|
208 |
+
* Save error messages for Tweets.
|
209 |
+
*
|
210 |
+
* @param int $id Post ID.
|
211 |
+
* @param int $auth Current author.
|
212 |
+
* @param string $twit Tweet text.
|
213 |
+
* @param string $error Error string from Twitter.
|
214 |
+
* @param int $http_code Http code from Tiwtter.
|
215 |
+
* @param string $ts Current timestamp.
|
216 |
+
*/
|
217 |
function wpt_saves_error( $id, $auth, $twit, $error, $http_code, $ts ) {
|
218 |
$http_code = (int) $http_code;
|
219 |
+
if ( 200 != $http_code ) {
|
220 |
add_post_meta( $id, '_wpt_failed', array(
|
221 |
+
'author' => $auth,
|
222 |
+
'sentence' => $twit,
|
223 |
+
'error' => $error,
|
224 |
+
'code' => $http_code,
|
225 |
+
'timestamp' => $ts,
|
226 |
+
) );
|
227 |
} else {
|
228 |
+
if ( 1 == get_option( 'wpt_rate_limiting' ) ) {
|
229 |
wpt_log_success( $auth, $ts, $id );
|
230 |
}
|
231 |
}
|
232 |
}
|
233 |
|
234 |
|
235 |
+
/**
|
236 |
+
* Checks whether WP to Twitter has sent a tweet on this post to this author within the last 30 seconds and blocks duplicates.
|
237 |
*
|
238 |
+
* @param int $id Post ID.
|
239 |
+
* @param int $auth Author.
|
240 |
+
*
|
241 |
+
* @uses filter wpt_recent_tweet_threshold
|
242 |
+
* @return boolean true to send Tweet, false to block.
|
243 |
*/
|
244 |
function wpt_check_recent_tweet( $id, $auth ) {
|
245 |
if ( ! $id ) {
|
246 |
return false;
|
247 |
} else {
|
248 |
+
if ( false == $auth ) {
|
249 |
$transient = get_transient( "_wpt_most_recent_tweet_$id" );
|
250 |
} else {
|
251 |
+
$transient = get_transient( '_wpt_' . $auth . "_most_recent_tweet_$id" );
|
252 |
}
|
253 |
if ( $transient ) {
|
254 |
return true;
|
255 |
} else {
|
256 |
$expire = apply_filters( 'wpt_recent_tweet_threshold', 30 );
|
257 |
// if expiration is 0, don't set the transient. We don't want permanent transients.
|
258 |
+
if ( 0 !== $expire ) {
|
259 |
+
wpt_mail( 'Tweet transient set', "$expire / $auth / $id" );
|
260 |
+
if ( false == $auth ) {
|
261 |
set_transient( "_wpt_most_recent_tweet_$id", true, $expire );
|
262 |
} else {
|
263 |
+
set_transient( '_wpt_' . $auth . "_most_recent_tweet_$id", true, $expire );
|
264 |
}
|
265 |
}
|
266 |
}
|
271 |
|
272 |
/**
|
273 |
* Performs the API post to Twitter
|
274 |
+
*
|
275 |
+
* @param string $twit Text of Tweet to be sent to Twitter.
|
276 |
+
* @param int $auth Author ID.
|
277 |
+
* @param int $id Post ID.
|
278 |
+
* @param boolean $media Whether to upload media attached to the post specified in $id.
|
279 |
+
*
|
280 |
+
* @return boolean Success of query.
|
281 |
*/
|
282 |
function wpt_post_to_twitter( $twit, $auth = false, $id = false, $media = false ) {
|
283 |
+
$recent = wpt_check_recent_tweet( $id, $auth );
|
284 |
+
$error = false;
|
285 |
+
if ( 1 == get_option( 'wpt_rate_limiting' ) ) {
|
286 |
// check whether this post needs to be rate limited.
|
287 |
$continue = wpt_test_rate_limit( $id, $auth );
|
288 |
+
if ( ! $continue ) {
|
289 |
return false;
|
290 |
}
|
291 |
}
|
294 |
if ( $recent ) {
|
295 |
return false;
|
296 |
}
|
297 |
+
|
298 |
if ( ! wpt_check_oauth( $auth ) ) {
|
299 |
$error = __( 'This account is not authorized to post to Twitter.', 'wp-to-twitter' );
|
300 |
wpt_saves_error( $id, $auth, $twit, $error, '401', time() );
|
301 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
302 |
|
303 |
return false;
|
304 |
+
} // exit silently if not authorized.
|
305 |
|
306 |
+
$check = ( ! $auth ) ? get_option( 'jd_last_tweet' ) : get_user_meta( $auth, 'wpt_last_tweet', true ); // get user's last tweet.
|
307 |
+
// prevent duplicate Tweets.
|
308 |
if ( $check == $twit ) {
|
309 |
+
wpt_mail( 'Matched: tweet identical', "This Tweet: $twit; Check Tweet: $check; $auth, $id, $media" ); // DEBUG.
|
310 |
$error = __( 'This tweet is identical to another Tweet recently sent to this account.', 'wp-to-twitter' ) . ' ' . __( 'Twitter requires all Tweets to be unique.', 'wp-to-twitter' );
|
311 |
wpt_saves_error( $id, $auth, $twit, $error, '403-1', time() );
|
312 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
313 |
|
314 |
return false;
|
315 |
+
} elseif ( '' == $twit || ! $twit ) {
|
316 |
+
wpt_mail( 'Tweet check: empty sentence', "$twit, $auth, $id, $media" ); // DEBUG.
|
317 |
$error = __( 'This tweet was blank and could not be sent to Twitter.', 'wp-tweets-pro' );
|
318 |
wpt_saves_error( $id, $auth, $twit, $error, '403-2', time() );
|
319 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
321 |
return false;
|
322 |
} else {
|
323 |
$media_id = false;
|
324 |
+
// must be designated as media and have a valid attachment.
|
325 |
$attachment = ( $media ) ? wpt_post_attachment( $id ) : false;
|
326 |
if ( $attachment ) {
|
327 |
wpt_mail( 'Post has upload', "$auth, $attachment" );
|
331 |
$attachment = false;
|
332 |
}
|
333 |
}
|
334 |
+
$api = 'https://api.twitter.com/1.1/statuses/update.json';
|
335 |
+
$upload_api = 'https://upload.twitter.com/1.1/media/upload.json';
|
336 |
+
$status = array(
|
337 |
+
'status' => $twit,
|
338 |
+
'source' => 'wp-to-twitter',
|
339 |
+
'include_entities' => 'true',
|
340 |
+
);
|
341 |
+
|
342 |
+
if ( wtt_oauth_test( $auth ) ) {
|
343 |
+
$connection = wpt_oauth_connection( $auth );
|
344 |
+
if ( $connection ) {
|
345 |
+
if ( $media && $attachment && ! $media_id ) {
|
346 |
+
$media_id = $connection->media( $upload_api, array(
|
347 |
+
'auth' => $auth,
|
348 |
+
'media' => $attachment,
|
349 |
+
) );
|
350 |
+
wpt_mail( 'Media Uploaded', "$auth, $media_id, $attachment" );
|
351 |
+
if ( $media_id ) {
|
352 |
+
$status['media_ids'] = $media_id;
|
353 |
+
/**
|
354 |
+
* Eventually, use this to add alt text. Not supported at this time.
|
355 |
+
$metadata_api = 'https://upload.twitter.com/1.1/media/metadata/create.json';
|
356 |
+
$alt_text = get_post_meta( $args['media'], '_wp_attachment_image_alt', true );
|
357 |
+
if ( '' != $alt_text ) {
|
358 |
+
$image_alt = json_encode( array(
|
359 |
+
'media_id' => $media_id,
|
360 |
+
'alt_text' => array(
|
361 |
+
'text' => $alt_text,
|
362 |
+
),
|
363 |
+
) );
|
364 |
+
$post_alt = $connection->post( $metadata_api, array( 'auth' => $auth, 'json' => $image_alt ), true );
|
365 |
+
}
|
366 |
+
*/
|
367 |
+
}
|
368 |
}
|
369 |
}
|
370 |
}
|
372 |
$connection = array( 'connection' => 'undefined' );
|
373 |
} else {
|
374 |
$staging_mode = apply_filters( 'wpt_staging_mode', false, $auth, $id );
|
375 |
+
if ( ( defined( 'WPT_STAGING_MODE' ) && true == WPT_STAGING_MODE ) || $staging_mode ) {
|
376 |
// if in staging mode, we'll behave as if the Tweet succeeded, but not send it.
|
377 |
$connection = true;
|
378 |
+
$http_code = 200;
|
379 |
+
$notice = __( 'In Staging Mode:', 'wp-to-twitter' ) . ' ';
|
380 |
} else {
|
381 |
$connection->post( $api, $status );
|
382 |
$http_code = ( $connection ) ? $connection->http_code : 'failed';
|
383 |
+
$notice = '';
|
384 |
+
}
|
385 |
}
|
386 |
wpt_mail( 'Twitter Connection', print_r( $connection, 1 ) . " - $twit, $auth, $id, $media" );
|
387 |
if ( $connection ) {
|
388 |
+
if ( isset( $connection->http_header['x-access-level'] ) && 'read' == $connection->http_header['x-access-level'] ) {
|
389 |
+
// Translators: Twitter App editing URL.
|
390 |
$supplement = sprintf( __( 'Your Twitter application does not have read and write permissions. Go to <a href="%s">your Twitter apps</a> to modify these settings.', 'wp-to-twitter' ), 'https://dev.twitter.com/apps/' );
|
391 |
} else {
|
392 |
$supplement = '';
|
394 |
$return = false;
|
395 |
switch ( $http_code ) {
|
396 |
case '100':
|
397 |
+
$error = __( '100 Continue: Twitter received the header of your submission, but your server did not follow through by sending the body of the data.', 'wp-to-twitter' );
|
398 |
+
break;
|
399 |
case '200':
|
400 |
$return = true;
|
401 |
+
$error = __( '200 OK: Success!', 'wp-to-twitter' );
|
402 |
update_option( 'wpt_authentication_missing', false );
|
403 |
break;
|
404 |
case '304':
|
405 |
+
$error = __( '304 Not Modified: There was no new data to return', 'wp-to-twitter' );
|
406 |
break;
|
407 |
case '400':
|
408 |
+
$error = __( '400 Bad Request: The request was invalid. This is the status code returned during rate limiting.', 'wp-to-twitter' );
|
409 |
break;
|
410 |
case '401':
|
411 |
+
$error = __( '401 Unauthorized: Authentication credentials were missing or incorrect.', 'wp-to-twitter' );
|
412 |
update_option( 'wpt_authentication_missing', "$auth" );
|
413 |
break;
|
414 |
case '403':
|
415 |
+
$error = __( '403 Forbidden: The request is understood, but has been refused by Twitter.', 'wp-to-twitter' );
|
416 |
break;
|
417 |
case '404':
|
418 |
+
$error = __( '404 Not Found: The URI requested is invalid or the resource requested does not exist.', 'wp-to-twitter' );
|
419 |
break;
|
420 |
case '406':
|
421 |
+
$error = __( '406 Not Acceptable: Invalid Format Specified.', 'wp-to-twitter' );
|
422 |
break;
|
423 |
case '422':
|
424 |
+
$error = __( '422 Unprocessable Entity: The image uploaded could not be processed.', 'wp-to-twitter' );
|
425 |
break;
|
426 |
case '429':
|
427 |
+
$error = __( '429 Too Many Requests: You have exceeded your rate limits.', 'wp-to-twitter' );
|
428 |
break;
|
429 |
case '500':
|
430 |
+
$error = __( '500 Internal Server Error: Something is broken at Twitter.', 'wp-to-twitter' );
|
431 |
break;
|
432 |
case '502':
|
433 |
+
$error = __( '502 Bad Gateway: Twitter is down or being upgraded.', 'wp-to-twitter' );
|
434 |
break;
|
435 |
case '503':
|
436 |
+
$error = __( '503 Service Unavailable: The Twitter servers are up, but overloaded with requests - Please try again later.', 'wp-to-twitter' );
|
437 |
break;
|
438 |
case '504':
|
439 |
$error = __( "504 Gateway Timeout: The Twitter servers are up, but the request couldn't be serviced due to some failure within our stack. Try again later.", 'wp-to-twitter' );
|
440 |
break;
|
441 |
default:
|
442 |
+
// Translators: http code.
|
443 |
+
$error = sprintf( __( '<strong>Code %s</strong>: Twitter did not return a recognized response code.', 'wp-to-twitter' ), $http_code );
|
444 |
break;
|
445 |
}
|
446 |
$body = $connection->body;
|
447 |
+
$error_code = ( 200 != $http_code ) ? $body->errors[0]->code : '';
|
448 |
+
$error_message = ( 200 != $http_code ) ? $body->errors[0]->message : '';
|
449 |
+
$error_supplement = ( '' != $error_code ) ? ' (Error Code: ' . $error_code . ': ' . $error_message . ')' : '';
|
450 |
+
$error .= ( '' != $supplement ) ? " $supplement" : '';
|
451 |
$error .= $error_supplement;
|
452 |
+
wpt_mail( "Twitter Response: $http_code", "$error" ); // DEBUG.
|
453 |
+
// only save last Tweet if successful.
|
454 |
+
if ( 200 == $http_code ) {
|
|
|
|
|
455 |
if ( ! $auth ) {
|
456 |
update_option( 'jd_last_tweet', $twit );
|
457 |
} else {
|
459 |
}
|
460 |
}
|
461 |
wpt_saves_error( $id, $auth, $twit, $error, $http_code, time() );
|
462 |
+
if ( 200 == $http_code ) {
|
463 |
$jwt = get_post_meta( $id, '_jd_wp_twitter', true );
|
464 |
if ( ! is_array( $jwt ) ) {
|
465 |
$jwt = array();
|
472 |
update_post_meta( $id, '_jd_wp_twitter', $jwt );
|
473 |
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
474 |
// schedule a one-time promotional box for 4 weeks after first successful Tweet.
|
475 |
+
if ( false == get_option( 'wpt_promotion_scheduled' ) ) {
|
476 |
wp_schedule_single_event( time() + ( 60 * 60 * 24 * 7 * 4 ), 'wpt_schedule_promotion_action' );
|
477 |
update_option( 'wpt_promotion_scheduled', 1 );
|
478 |
}
|
481 |
if ( ! $return ) {
|
482 |
wpt_set_log( 'wpt_status_message', $id, $error );
|
483 |
} else {
|
484 |
+
do_action( 'wpt_tweet_posted', $connection, $id );
|
485 |
wpt_set_log( 'wpt_status_message', $id, $notice . __( 'Tweet sent successfully.', 'wp-to-twitter' ) );
|
486 |
}
|
487 |
|
497 |
|
498 |
/**
|
499 |
* For servers without PEAR normalize installed, approximates normalization. With normalizer, executes normalization on string.
|
500 |
+
*
|
501 |
+
* @param string $string Text to normalize.
|
502 |
+
*
|
503 |
* @return string Normalized text.
|
504 |
*/
|
505 |
function wpt_normalize( $string ) {
|
512 |
} else {
|
513 |
$normalizer = new WPT_Normalizer();
|
514 |
if ( $normalizer->isNormalized( $string ) ) {
|
515 |
+
return $string;
|
516 |
}
|
517 |
+
|
518 |
return $normalizer->normalize( $string );
|
519 |
}
|
520 |
}
|
521 |
|
522 |
/**
|
523 |
* Test URL to see if is pointing to https location.
|
524 |
+
*
|
525 |
+
* @param string $url URL to check for https.
|
526 |
*
|
527 |
* @return boolean
|
528 |
*/
|
535 |
}
|
536 |
|
537 |
/**
|
538 |
+
* Deprecated; still used if configured.
|
539 |
+
* Uses old option 'tweet_categories' and verifies whether category of current post allows it to be Tweeted.
|
540 |
+
*
|
541 |
+
* @param array $array Array of categories for post.
|
542 |
+
*
|
543 |
+
* @return boolean.
|
544 |
*/
|
545 |
function wpt_in_allowed_category( $array ) {
|
546 |
$allowed_categories = get_option( 'tweet_categories' );
|
547 |
if ( is_array( $array ) && is_array( $allowed_categories ) ) {
|
548 |
+
$common = array_intersect( $array, $allowed_categories );
|
549 |
if ( count( $common ) >= 1 ) {
|
550 |
return true;
|
551 |
} else {
|
558 |
|
559 |
/**
|
560 |
* Builds array of post info for use in Tweet functions.
|
561 |
+
*
|
562 |
* @param integer $post_ID Post ID.
|
563 |
*
|
564 |
+
* @return array Post data used in Tweet functions.
|
565 |
*/
|
566 |
function wpt_post_info( $post_ID ) {
|
567 |
$encoding = get_option( 'blog_charset' );
|
568 |
+
if ( '' == $encoding ) {
|
569 |
$encoding = 'UTF-8';
|
570 |
}
|
571 |
$post = get_post( $post_ID );
|
572 |
$category_ids = false;
|
573 |
$values = array();
|
574 |
$values['id'] = $post_ID;
|
575 |
+
// get post author.
|
576 |
$values['postinfo'] = $post;
|
577 |
$values['postContent'] = $post->post_content;
|
578 |
$values['authId'] = $post->post_author;
|
579 |
$postdate = $post->post_date;
|
580 |
+
$dateformat = ( '' == get_option( 'jd_date_format' ) ) ? get_option( 'date_format' ) : get_option( 'jd_date_format' );
|
|
|
581 |
$thisdate = mysql2date( $dateformat, $postdate );
|
582 |
+
$altdate = mysql2date( 'Y-m-d H:i:s', $postdate );
|
583 |
$values['_postDate'] = $altdate;
|
584 |
$values['postDate'] = $thisdate;
|
585 |
$moddate = $post->post_modified;
|
586 |
+
$values['_postModified'] = mysql2date( 'Y-m-d H:i:s', $moddate );
|
587 |
$values['postModified'] = mysql2date( $dateformat, $moddate );
|
588 |
+
// get first category.
|
589 |
+
$category = null;
|
590 |
+
$cat_desc = null;
|
591 |
$categories = get_the_category( $post_ID );
|
592 |
+
$cats = array();
|
593 |
+
$cat_descs = array();
|
594 |
if ( is_array( $categories ) ) {
|
595 |
if ( count( $categories ) > 0 ) {
|
596 |
$category = $categories[0]->cat_name;
|
597 |
$cat_desc = $categories[0]->description;
|
598 |
}
|
599 |
+
foreach ( $categories as $cat ) {
|
600 |
$category_ids[] = $cat->term_id;
|
601 |
+
$cats[] = $cat->cat_name;
|
602 |
+
$cat_descs[] = $cat->description;
|
603 |
}
|
604 |
$cat_names = implode( ' ', apply_filters( 'wpt_twitter_category_names', $cats ) );
|
605 |
$cat_descs = implode( ' ', apply_filters( 'wpt_twitter_category_descs', $cat_descs ) );
|
614 |
$values['category'] = html_entity_decode( $category, ENT_COMPAT, $encoding );
|
615 |
$values['cat_desc'] = html_entity_decode( $cat_desc, ENT_COMPAT, $encoding );
|
616 |
$excerpt_length = get_option( 'jd_post_excerpt' );
|
617 |
+
$post_excerpt = ( '' == trim( $post->post_excerpt ) ) ? mb_substr( strip_tags( strip_shortcodes( $post->post_content ) ), 0, $excerpt_length ) : mb_substr( strip_tags( strip_shortcodes( $post->post_excerpt ) ), 0, $excerpt_length );
|
618 |
$values['postExcerpt'] = html_entity_decode( $post_excerpt, ENT_COMPAT, $encoding );
|
619 |
$thisposttitle = $post->post_title;
|
620 |
+
if ( '' == $thisposttitle && isset( $_POST['title'] ) ) {
|
621 |
$thisposttitle = $_POST['title'];
|
622 |
}
|
623 |
+
$thisposttitle = strip_tags( apply_filters( 'the_title', stripcslashes( $thisposttitle ) ) );
|
624 |
+
// These are common sequences that may not be fixed by html_entity_decode due to double encoding.
|
625 |
$search = array( ''', ''', '"', '"', '&', '&' );
|
626 |
$replace = array( "'", "'", '"', '"', '&', '&' );
|
627 |
+
$thisposttitle = str_replace( $search, $replace, $thisposttitle );
|
628 |
$values['postTitle'] = html_entity_decode( $thisposttitle, ENT_QUOTES, $encoding );
|
629 |
$values['postLink'] = wpt_link( $post_ID );
|
630 |
$values['blogTitle'] = get_bloginfo( 'name' );
|
633 |
$values['postType'] = $post->post_type;
|
634 |
/**
|
635 |
* Filters post array to insert custom data that can be used in Tweet process.
|
636 |
+
*
|
637 |
+
* @param array $values Existing values.
|
638 |
+
* @param integer $post_ID Post ID.
|
639 |
+
* @return array $values
|
640 |
*/
|
641 |
+
$values = apply_filters( 'wpt_post_info', $values, $post_ID );
|
642 |
|
643 |
return $values;
|
644 |
}
|
645 |
|
646 |
/**
|
647 |
* Retrieve stored short URL.
|
648 |
+
*
|
649 |
+
* @param int $post_id Post ID.
|
650 |
*
|
651 |
* @return mixed
|
652 |
*/
|
655 |
if ( ! $post_id ) {
|
656 |
$post_id = $post_ID;
|
657 |
}
|
658 |
+
$use_urls = ( get_option( 'wpt_use_stored_urls' ) == 'false' ) ? false : true;
|
659 |
+
$short = ( $use_url ) ? get_post_meta( $post_id, '_wpt_short_url', true ) : false;
|
660 |
+
|
661 |
return $short;
|
662 |
}
|
663 |
|
664 |
/**
|
665 |
* Identify whether a post should be uploading media. Test settings and verify whether post has images that can be uploaded.
|
666 |
*
|
667 |
+
* @param int $post_ID Post ID.
|
668 |
+
* @param array $post_info Array of post data.
|
669 |
* @return boolean
|
670 |
+
*/
|
671 |
function wpt_post_with_media( $post_ID, $post_info = array() ) {
|
672 |
$return = false;
|
673 |
+
if ( isset( $post_info['wpt_image'] ) && 1 == $post_info['wpt_image'] ) {
|
674 |
return $return;
|
675 |
}
|
676 |
|
677 |
+
if ( ! function_exists( 'wpt_pro_exists' ) || '1' != get_option( 'wpt_media' ) ) {
|
678 |
$return = false;
|
679 |
} else {
|
680 |
if ( has_post_thumbnail( $post_ID ) || wpt_post_attachment( $post_ID ) ) {
|
686 |
}
|
687 |
|
688 |
/**
|
689 |
+
* This function is no longer in use, but the filter within it is.
|
690 |
+
*
|
691 |
+
* @param string $post_type Type of post.
|
692 |
+
* @param array $post_info Post info.
|
693 |
+
* @param int $post_ID Post ID.
|
694 |
+
*
|
695 |
* @deprecated
|
696 |
*/
|
697 |
function wpt_category_limit( $post_type, $post_info, $post_ID ) {
|
699 |
$continue = true;
|
700 |
if ( in_array( 'category', $post_type_cats ) ) {
|
701 |
// 'category' is assigned to this post type, so apply filters.
|
702 |
+
if ( '1' == get_option( 'jd_twit_cats' ) ) {
|
703 |
$continue = ( ! wpt_in_allowed_category( $post_info['categoryIds'] ) ) ? true : false;
|
704 |
} else {
|
705 |
$continue = ( wpt_in_allowed_category( $post_info['categoryIds'] ) ) ? true : false;
|
706 |
}
|
707 |
}
|
708 |
|
709 |
+
$continue = ( '0' == get_option( 'limit_categories' ) ) ? true : $continue;
|
710 |
+
$args = array(
|
711 |
+
'type' => $post_type,
|
712 |
+
'info' => $post_info,
|
713 |
+
'id' => $post_ID,
|
714 |
+
);
|
715 |
|
716 |
return apply_filters( 'wpt_filter_terms', $continue, $args );
|
717 |
}
|
718 |
|
719 |
/**
|
720 |
+
* Set up a Tweet to be sent.
|
721 |
+
*
|
722 |
+
* @param int $post_ID Post ID.
|
723 |
+
* @param string $type Publishing context (publishing, scheduled, xmlrpc, etc.).
|
724 |
+
*
|
725 |
+
* @return int $post_ID
|
726 |
*/
|
727 |
function wpt_tweet( $post_ID, $type = 'instant' ) {
|
728 |
if ( wp_is_post_autosave( $post_ID ) || wp_is_post_revision( $post_ID ) ) {
|
729 |
return $post_ID;
|
730 |
}
|
731 |
+
|
732 |
wpt_check_version();
|
733 |
+
$tweet_this = get_post_meta( $post_ID, '_jd_tweet_this', true );
|
734 |
+
$newpost = false;
|
735 |
+
$oldpost = false;
|
736 |
+
$is_inline_edit = false;
|
737 |
+
$sentence = '';
|
738 |
+
$template = '';
|
739 |
+
$nptext = '';
|
740 |
+
if ( 1 != get_option( 'wpt_inline_edits' ) ) {
|
741 |
if ( isset( $_POST['_inline_edit'] ) || isset( $_REQUEST['bulk_edit'] ) ) {
|
742 |
return false;
|
743 |
}
|
746 |
$is_inline_edit = true;
|
747 |
}
|
748 |
}
|
749 |
+
if ( 0 == get_option( 'jd_tweet_default' ) ) {
|
750 |
+
$default = ( 'no' != $tweet_this ) ? true : false;
|
751 |
} else {
|
752 |
+
$default = ( 'yes' == $tweet_this ) ? true : false;
|
753 |
}
|
754 |
+
wpt_mail( '1: Tweet Template', "$tweet_this / (Original: " . get_option( 'jd_tweet_default' ) . ") / $type" ); // DEBUG.
|
755 |
if ( $default ) { // default switch: depend on default settings.
|
756 |
$post_info = wpt_post_info( $post_ID );
|
757 |
$media = wpt_post_with_media( $post_ID, $post_info );
|
758 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() ) {
|
759 |
+
$auth = ( 'false' == get_option( 'wpt_cotweet_lock' ) || ! get_option( 'wpt_cotweet_lock' ) ) ? $post_info['authId'] : get_option( 'wpt_cotweet_lock' );
|
760 |
} else {
|
761 |
$auth = $post_info['authId'];
|
762 |
}
|
763 |
+
wpt_mail( '2: POST Debug Data', 'Post_Info: ' . print_r( $post_info, 1 ) . " / $type" ); // DEBUG.
|
764 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() && function_exists( 'wpt_filter_post_info' ) ) {
|
|
|
765 |
$filter = wpt_filter_post_info( $post_info );
|
766 |
+
if ( true == $filter ) {
|
767 |
+
wpt_mail( '3: Post caught by wpt_filter_post_info', print_r( $post_info, 1 ) . " / $type" );
|
768 |
|
769 |
return false;
|
770 |
}
|
771 |
}
|
772 |
+
// Filter Tweet based on POST data -- allows custom filtering of unknown plug-ins, etc.
|
773 |
$filter = apply_filters( 'wpt_filter_post_data', false, $_POST );
|
774 |
if ( $filter ) {
|
775 |
return false;
|
776 |
}
|
777 |
$post_type = $post_info['postType'];
|
778 |
+
if ( 'future' == $type || 'future' == get_post_meta( $post_ID, 'wpt_publishing' ) ) {
|
779 |
+
$new = 1; // if this is a future action, then it should be published regardless of relationship.
|
780 |
+
wpt_mail( '4a: Is a future post', print_r( $post_info, 1 ) . " / $type" );
|
781 |
delete_post_meta( $post_ID, 'wpt_publishing' );
|
782 |
} else {
|
783 |
// if the post modified date and the post date are the same, this is new.
|
784 |
+
// true if first date before or equal to last date.
|
785 |
$new = wpt_date_compare( $post_info['_postModified'], $post_info['_postDate'] );
|
786 |
}
|
787 |
+
// post is not previously published but has been backdated.
|
788 |
+
// (post date is edited, but save option is 'publish').
|
789 |
+
if ( 0 == $new && ( isset( $_POST['edit_date'] ) && 1 == $_POST['edit_date'] && ! isset( $_POST['save'] ) ) ) {
|
790 |
$new = 1;
|
791 |
}
|
792 |
+
// can't catch posts that were set to a past date as a draft, then published.
|
793 |
$post_type_settings = get_option( 'wpt_post_types' );
|
794 |
$post_types = array_keys( $post_type_settings );
|
795 |
if ( in_array( $post_type, $post_types ) ) {
|
796 |
+
// identify whether limited by category/taxonomy.
|
797 |
$continue = wpt_category_limit( $post_type, $post_info, $post_ID );
|
798 |
+
if ( false == $continue ) {
|
799 |
return false;
|
800 |
}
|
801 |
+
// create Tweet and ID whether current action is edit or new.
|
802 |
+
$ct = get_post_meta( $post_ID, '_jd_twitter', true );
|
803 |
+
if ( isset( $_POST['_jd_twitter'] ) && '' != $_POST['_jd_twitter'] ) {
|
804 |
+
$ct = $_POST['_jd_twitter'];
|
805 |
}
|
806 |
+
$custom_tweet = ( '' != $ct ) ? stripcslashes( trim( $ct ) ) : '';
|
807 |
// if ops is set and equals 'publish', this is being edited. Otherwise, it's a new post.
|
808 |
+
if ( 0 == $new || true == $is_inline_edit ) {
|
809 |
+
// if this is an old post and editing updates are enabled.
|
810 |
+
if ( 1 == get_option( 'jd_tweet_default_edit' ) ) {
|
811 |
$tweet_this = apply_filters( 'wpt_tweet_this_edit', $tweet_this, $_POST );
|
812 |
+
if ( 'yes' != $tweet_this ) {
|
813 |
return false;
|
814 |
}
|
815 |
}
|
816 |
+
wpt_mail( '4b: Is edited post', 'Tweet this: ' . print_r( $post_info, 1 ) . " / $type" ); // DEBUG.
|
817 |
+
if ( '1' == $post_type_settings[ $post_type ]['post-edited-update'] ) {
|
818 |
$nptext = stripcslashes( $post_type_settings[ $post_type ]['post-edited-text'] );
|
819 |
$oldpost = true;
|
820 |
}
|
821 |
} else {
|
822 |
+
wpt_mail( '4c: Is new post', 'Tweet this: ' . print_r( $post_info, 1 ) . " / $type" ); // DEBUG.
|
823 |
+
if ( '1' == $post_type_settings[ $post_type ]['post-published-update'] ) {
|
824 |
$nptext = stripcslashes( $post_type_settings[ $post_type ]['post-published-text'] );
|
825 |
$newpost = true;
|
826 |
}
|
827 |
}
|
828 |
if ( $newpost || $oldpost ) {
|
829 |
+
$template = ( '' != $custom_tweet ) ? $custom_tweet : $nptext;
|
830 |
$sentence = jd_truncate_tweet( $template, $post_info, $post_ID );
|
831 |
+
wpt_mail( '5: Tweet Truncated', "Truncated Tweet: $sentence / $template / $type" ); // DEBUG.
|
832 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() ) {
|
833 |
$sentence2 = jd_truncate_tweet( $template, $post_info, $post_ID, false, $auth );
|
834 |
}
|
835 |
}
|
836 |
+
if ( '' != $sentence ) {
|
837 |
+
// WPT PRO.
|
838 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() ) {
|
839 |
$wpt_selected_users = $post_info['wpt_authorized_users'];
|
840 |
+
// set up basic author/main account values.
|
841 |
$auth_verified = wtt_oauth_test( $auth, 'verify' );
|
842 |
+
if ( empty( $wpt_selected_users ) && 1 == get_option( 'jd_individual_twitter_users' ) ) {
|
843 |
$wpt_selected_users = ( $auth_verified ) ? array( $auth ) : array( false );
|
844 |
}
|
845 |
+
if ( 1 == $post_info['wpt_cotweet'] || 1 != get_option( 'jd_individual_twitter_users' ) || in_array( 'main', $wpt_selected_users ) ) {
|
846 |
$wpt_selected_users['main'] = false;
|
847 |
}
|
848 |
+
// filter selected users before using.
|
849 |
$wpt_selected_users = apply_filters( 'wpt_filter_users', $wpt_selected_users, $post_info );
|
850 |
+
if ( 0 == $post_info['wpt_delay_tweet'] || '' == $post_info['wpt_delay_tweet'] || 'on' == $post_info['wpt_no_delay'] ) {
|
851 |
foreach ( $wpt_selected_users as $acct ) {
|
852 |
if ( wtt_oauth_test( $acct, 'verify' ) ) {
|
853 |
wpt_post_to_twitter( $sentence2, $acct, $post_ID, $media );
|
855 |
}
|
856 |
} else {
|
857 |
foreach ( $wpt_selected_users as $acct ) {
|
858 |
+
$acct = ( 'main' == $acct ) ? false : $acct;
|
859 |
$offset = ( $auth != $acct ) ? apply_filters( 'wpt_random_delay', rand( 60, 480 ) ) : 0;
|
860 |
if ( wtt_oauth_test( $acct, 'verify' ) ) {
|
861 |
+
$time = apply_filters( 'wpt_schedule_delay', ( (int) $post_info['wpt_delay_tweet'] ) * 60, $acct );
|
862 |
wp_schedule_single_event( time() + $time + $offset, 'wpt_schedule_tweet_action', array(
|
863 |
+
'id' => $acct,
|
864 |
+
'sentence' => $sentence,
|
865 |
+
'rt' => 0,
|
866 |
+
'post_id' => $post_ID,
|
867 |
+
) );
|
868 |
if ( WPT_DEBUG && function_exists( 'wpt_pro_exists' ) ) {
|
869 |
$author_id = ( $acct ) ? "#$acct" : 'Main';
|
870 |
wpt_mail( "7a: Tweet Scheduled for author $author_id", print_r( array(
|
871 |
+
'id' => $acct,
|
872 |
+
'sentence' => $sentence,
|
873 |
+
'rt' => 0,
|
874 |
+
'post_id' => $post_ID,
|
875 |
+
'timestamp' => time() + $time + $offset,
|
876 |
+
'current_time' => time(),
|
877 |
+
'timezone' => get_option( 'gmt_offset' ),
|
878 |
+
'timestamp_string' => date( 'Y-m-d H:i:s', time() + $time + $offset ),
|
879 |
+
'current_ts' => date( 'Y-m-d H:i:s', time() ),
|
880 |
+
), 1 ) ); // DEBUG.
|
881 |
}
|
882 |
}
|
883 |
}
|
884 |
}
|
885 |
+
// This cycle handles scheduling the automatic retweets.
|
886 |
+
if ( 0 != $post_info['wpt_retweet_after'] && 'on' != $post_info['wpt_no_repost'] ) {
|
887 |
$repeat = $post_info['wpt_retweet_repeat'];
|
888 |
$first = true;
|
889 |
foreach ( $wpt_selected_users as $acct ) {
|
893 |
if ( $continue ) {
|
894 |
$retweet = apply_filters( 'wpt_set_retweet_text', $template, $i );
|
895 |
$retweet = jd_truncate_tweet( $retweet, $post_info, $post_ID, true, $acct );
|
896 |
+
// add original delay to schedule.
|
897 |
$delay = ( isset( $post_info['wpt_delay_tweet'] ) ) ? ( (int) $post_info['wpt_delay_tweet'] ) * 60 : 0;
|
898 |
+
// Don't delay the first Tweet of the group.
|
899 |
+
$offset = ( true == $first ) ? 0 : rand( 60, 240 ); // delay each co-tweet by 1-4 minutes.
|
900 |
+
$time = apply_filters( 'wpt_schedule_retweet', ( $post_info['wpt_retweet_after'] ) * ( 60 * 60 ) * $i, $acct, $i, $post_info );
|
901 |
wp_schedule_single_event( time() + $time + $offset + $delay, 'wpt_schedule_tweet_action', array(
|
902 |
+
'id' => $acct,
|
903 |
+
'sentence' => $retweet,
|
904 |
+
'rt' => $i,
|
905 |
+
'post_id' => $post_ID,
|
906 |
+
) );
|
907 |
if ( WPT_DEBUG && function_exists( 'wpt_pro_exists' ) ) {
|
908 |
if ( $acct ) {
|
909 |
$author_id = "#$acct";
|
911 |
$author_id = 'Main';
|
912 |
}
|
913 |
wpt_mail( "7b: Retweet Scheduled for author $author_id", print_r( array(
|
914 |
+
'id' => $acct,
|
915 |
+
'sentence' => array( $retweet, $i, $post_ID ),
|
916 |
+
'timestamp' => time() + $time + $offset + $delay,
|
917 |
+
'time' => array( $time, $offset, $delay, get_option( 'gmt_offset' ), time() ),
|
918 |
+
'timestring' => date( 'Y-m-d H:i:s', time() + $time + $offset + $delay ),
|
919 |
+
'current_ts' => date( 'Y-m-d H:i:s', time() ),
|
920 |
+
), 1 ), true ); // DEBUG.
|
|
|
|
|
|
|
|
|
|
|
|
|
921 |
}
|
922 |
$tweet_limit = apply_filters( 'wpt_tweet_repeat_limit', 4, $post_ID );
|
923 |
if ( $i == $tweet_limit ) {
|
932 |
} else {
|
933 |
wpt_post_to_twitter( $sentence, false, $post_ID, $media );
|
934 |
}
|
935 |
+
// END WPT PRO.
|
936 |
}
|
937 |
} else {
|
938 |
if ( WPT_DEBUG && function_exists( 'wpt_pro_exists' ) ) {
|
939 |
+
wpt_mail( '3c: Not a Tweeted post type', 'Post_Info: ' . print_r( $post_info, 1 ) . " / $type" );
|
940 |
}
|
941 |
|
942 |
return $post_ID;
|
948 |
|
949 |
/**
|
950 |
* Send Tweets on links in link manager. Only active if Link plug-in is installed.
|
951 |
+
*
|
952 |
+
* @param integer $link_id Database ID for link.
|
953 |
+
*
|
954 |
* @return mixed boolean/integer link ID if successful, false if failure.
|
955 |
*/
|
956 |
+
function wpt_twit_link( $link_id ) {
|
957 |
wpt_check_version();
|
958 |
$thislinkprivate = $_POST['link_visible'];
|
959 |
+
if ( 'N' != $thislinkprivate ) {
|
960 |
+
$thislinkname = stripslashes( $_POST['link_name'] );
|
961 |
$thispostlink = $_POST['link_url'];
|
962 |
$thislinkdescription = stripcslashes( $_POST['link_description'] );
|
963 |
$sentence = stripcslashes( get_option( 'newlink-published-text' ) );
|
964 |
+
$sentence = str_ireplace( '#title#', $thislinkname, $sentence );
|
965 |
+
$sentence = str_ireplace( '#description#', $thislinkdescription, $sentence );
|
966 |
|
967 |
if ( mb_strlen( $sentence ) > 118 ) {
|
968 |
$sentence = mb_substr( $sentence, 0, 114 ) . '...';
|
969 |
}
|
970 |
$shrink = apply_filters( 'wptt_shorten_link', $thispostlink, $thislinkname, false, 'link' );
|
971 |
+
if ( false === stripos( $sentence, '#url#' ) ) {
|
972 |
+
$sentence = $sentence . ' ' . $shrink;
|
973 |
} else {
|
974 |
+
$sentence = str_ireplace( '#url#', $shrink, $sentence );
|
975 |
}
|
976 |
+
|
977 |
+
if ( false === stripos( $sentence, '#longurl#' ) ) {
|
978 |
+
$sentence = $sentence . ' ' . $thispostlink;
|
979 |
} else {
|
980 |
+
$sentence = str_ireplace( '#longurl#', $thispostlink, $sentence );
|
981 |
}
|
982 |
+
|
983 |
+
if ( '' != $sentence ) {
|
984 |
+
wpt_post_to_twitter( $sentence, false, $link_id );
|
985 |
}
|
986 |
|
987 |
+
return $link_id;
|
988 |
} else {
|
989 |
return false;
|
990 |
}
|
991 |
}
|
992 |
|
993 |
+
/**
|
994 |
* Generate hash tags from tags set on post.
|
|
|
|
|
995 |
*
|
996 |
+
* @param int $post_ID Post ID.
|
997 |
+
*
|
998 |
+
* @return string $hashtags Hashtags in format needed for Tweet.
|
999 |
*/
|
1000 |
function wpt_generate_hash_tags( $post_ID ) {
|
1001 |
$hashtags = '';
|
1002 |
+
$term_meta = false;
|
1003 |
+
$t_id = false;
|
1004 |
$max_tags = get_option( 'jd_max_tags' );
|
1005 |
$max_characters = get_option( 'jd_max_characters' );
|
1006 |
+
$max_characters = ( 0 == $max_characters || '' == $max_characters ) ? 100 : $max_characters + 1;
|
1007 |
+
if ( 0 == $max_tags || '' == $max_tags ) {
|
1008 |
$max_tags = 100;
|
1009 |
}
|
1010 |
+
$use_cats = ( '1' == get_option( 'wpt_use_cats' ) ) ? true : false;
|
1011 |
+
$tags = ( true == $use_cats ) ? wp_get_post_categories( $post_ID, array( 'fields' => 'all' ) ) : get_the_tags( $post_ID );
|
1012 |
$tags = apply_filters( 'wpt_hash_source', $tags, $post_ID );
|
1013 |
if ( $tags && count( $tags ) > 0 ) {
|
1014 |
$i = 1;
|
1017 |
$t_id = $value->term_id;
|
1018 |
$term_meta = get_option( "wpt_taxonomy_$t_id" );
|
1019 |
}
|
1020 |
+
if ( 'slug' == get_option( 'wpt_tag_source' ) ) {
|
1021 |
$tag = $value->slug;
|
1022 |
} else {
|
1023 |
$tag = $value->name;
|
1024 |
}
|
1025 |
$strip = get_option( 'jd_strip_nonan' );
|
1026 |
+
$search = '/[^\p{L}\p{N}\s]/u';
|
1027 |
$replace = get_option( 'jd_replace_character' );
|
1028 |
+
$replace = ( '[ ]' == $replace || '' == $replace ) ? '' : $replace;
|
1029 |
+
$tag = str_ireplace( ' ', $replace, trim( $tag ) );
|
1030 |
$tag = preg_replace( '/[\/]/', $replace, $tag ); // remove forward slashes.
|
1031 |
+
$tag = ( '1' == $strip ) ? preg_replace( $search, $replace, $tag ) : $tag;
|
1032 |
+
|
1033 |
switch ( $term_meta ) {
|
1034 |
+
case 1:
|
1035 |
+
$newtag = "#$tag";
|
1036 |
+
break;
|
1037 |
+
case 2:
|
1038 |
+
$newtag = "$$tag";
|
1039 |
+
break;
|
1040 |
+
case 3:
|
1041 |
+
$newtag = '';
|
1042 |
+
break;
|
1043 |
+
case 4:
|
1044 |
+
$newtag = $tag;
|
1045 |
+
break;
|
1046 |
+
default:
|
1047 |
+
$newtag = apply_filters( 'wpt_tag_default', '#', $t_id ) . $tag;
|
1048 |
}
|
1049 |
if ( mb_strlen( $newtag ) > 2 && ( mb_strlen( $newtag ) <= $max_characters ) && ( $i <= $max_tags ) ) {
|
1050 |
$hashtags .= "$newtag ";
|
1054 |
}
|
1055 |
$hashtags = trim( $hashtags );
|
1056 |
if ( mb_strlen( $hashtags ) <= 1 ) {
|
1057 |
+
$hashtags = '';
|
1058 |
}
|
1059 |
|
1060 |
return $hashtags;
|
1061 |
}
|
1062 |
|
1063 |
add_action( 'admin_menu', 'wpt_add_twitter_outer_box' );
|
1064 |
+
/**
|
1065 |
* Set up post meta box.
|
1066 |
*/
|
1067 |
function wpt_add_twitter_outer_box() {
|
1071 |
if ( function_exists( 'add_meta_box' ) ) {
|
1072 |
if ( is_array( $wpt_post_types ) ) {
|
1073 |
foreach ( $wpt_post_types as $key => $value ) {
|
1074 |
+
if ( 1 == $value['post-published-update'] || 1 == $value['post-edited-update'] ) {
|
1075 |
add_meta_box( 'wp2t', 'WP to Twitter', 'wpt_add_twitter_inner_box', $key, 'side' );
|
1076 |
}
|
1077 |
}
|
1081 |
|
1082 |
|
1083 |
add_action( 'admin_menu', 'wpt_add_twitter_debug_box' );
|
1084 |
+
/**
|
1085 |
* Set up post meta box.
|
1086 |
*/
|
1087 |
function wpt_add_twitter_debug_box() {
|
1092 |
if ( function_exists( 'add_meta_box' ) ) {
|
1093 |
if ( is_array( $wpt_post_types ) ) {
|
1094 |
foreach ( $wpt_post_types as $key => $value ) {
|
1095 |
+
if ( 1 == $value['post-published-update'] || 1 == $value['post-edited-update'] ) {
|
1096 |
add_meta_box( 'wp2t-debug', 'WP to Twitter Debugging', 'wpt_show_debug', $key, 'advanced' );
|
1097 |
}
|
1098 |
}
|
1099 |
}
|
1100 |
}
|
1101 |
}
|
1102 |
+
}
|
1103 |
+
|
1104 |
+
|
1105 |
/**
|
1106 |
* Print post meta box
|
1107 |
+
*
|
1108 |
+
* @param object $post Post object.
|
1109 |
*/
|
1110 |
function wpt_add_twitter_inner_box( $post ) {
|
1111 |
if ( current_user_can( 'wpt_can_tweet' ) ) {
|
1114 |
<?php
|
1115 |
$tweet_status = '';
|
1116 |
$options = get_option( 'wpt_post_types' );
|
1117 |
+
$type = $post->post_type;
|
1118 |
+
$status = $post->post_status;
|
1119 |
+
$post_id = $post->ID;
|
1120 |
+
$tweet_this = get_post_meta( $post_id, '_jd_tweet_this', true );
|
|
|
1121 |
if ( ! $tweet_this ) {
|
1122 |
+
$tweet_this = ( '1' == get_option( 'jd_tweet_default' ) ) ? 'no' : 'yes';
|
1123 |
}
|
1124 |
+
if ( isset( $_GET['action'] ) && 'edit' == $_GET['action'] && '1' == get_option( 'jd_tweet_default_edit' ) && 'publish' == $status ) {
|
1125 |
$tweet_this = 'no';
|
1126 |
}
|
1127 |
+
if ( isset( $_REQUEST['message'] ) && 10 != $_REQUEST['message'] ) {
|
1128 |
+
// don't display when draft is updated or if no message.
|
1129 |
+
if ( ! ( ( 1 == $_REQUEST['message'] ) && ( 'publish' == $status && 1 != $options[ $type ]['post-edited-update'] ) ) && 'no' != $tweet_this ) {
|
1130 |
$log = wpt_log( 'wpt_status_message', $post_id );
|
1131 |
+
$class = ( __( 'Tweet sent successfully.', 'wp-to-twitter' ) != $log ) ? 'error' : 'updated';
|
1132 |
+
if ( '' != $log ) {
|
1133 |
echo "<div class='$class'><p>$log</p></div>";
|
1134 |
}
|
1135 |
}
|
1136 |
}
|
1137 |
+
$tweet = esc_attr( stripcslashes( get_post_meta( $post_id, '_jd_twitter', true ) ) );
|
1138 |
+
$tweet = apply_filters( 'wpt_user_text', $tweet, $status );
|
1139 |
+
$template = ( 'publish' == $status ) ? $options[ $type ]['post-edited-text'] : $options[ $type ]['post-published-text'];
|
|
|
|
|
1140 |
|
1141 |
+
if ( 'publish' == $status && 1 != $options[ $type ]['post-edited-update'] ) {
|
1142 |
+
// Translators: post type.
|
1143 |
$tweet_status = sprintf( __( '%s will not be Tweeted on update.', 'wp-to-twitter' ), ucfirst( $type ) );
|
1144 |
}
|
1145 |
|
1146 |
+
if ( 'publish' == $status && ( current_user_can( 'wpt_tweet_now' ) || current_user_can( 'manage_options' ) ) ) {
|
1147 |
?>
|
1148 |
<div class='tweet-buttons'>
|
1149 |
<button type='button' class='tweet button-primary' data-action='tweet'><span class='dashicons dashicons-twitter' aria-hidden='true'></span><?php _e( 'Tweet Now', 'wp-to-twitter' ); ?></button>
|
1150 |
+
<?php
|
1151 |
+
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists() ) {
|
1152 |
+
?>
|
1153 |
+
<button type='button' class='tweet schedule button-secondary' data-action='schedule' disabled><?php _e( 'Schedule', 'wp-to-twitter' ); ?></button>
|
1154 |
+
<button type='button' class='time button-secondary'>
|
1155 |
+
<span class="dashicons dashicons-clock" aria-hidden="true"></span><span class="screen-reader-text"><?php _e( 'Set Date/Time', 'wp-to-twitter' ); ?></span>
|
1156 |
+
</button>
|
1157 |
+
<div id="jts">
|
1158 |
+
<label for='wpt_date'><?php _e( 'Date', 'wp-to-twitter' ); ?></label>
|
1159 |
+
<input type='date' value='' class='wpt_date date' name='wpt_datetime' id='wpt_date' data-value='<?php echo date( 'Y-m-d', current_time( 'timestamp' ) ); ?>' /><br/>
|
1160 |
+
<label for='wpt_time'><?php _e( 'Time', 'wp-to-twitter' ); ?></label>
|
1161 |
+
<input type='text' value='<?php echo date_i18n( 'h:s a', current_time( 'timestamp' ) + 3600 ); ?>' class='wpt_time time' name='wpt_datetime' id='wpt_time'/>
|
1162 |
+
</div>
|
1163 |
+
<?php
|
1164 |
+
}
|
1165 |
+
?>
|
1166 |
<div class='wpt_log' aria-live='assertive'></div>
|
1167 |
</div>
|
1168 |
<?php
|
1170 |
if ( current_user_can( 'wpt_twitter_custom' ) || current_user_can( 'manage_options' ) ) {
|
1171 |
?>
|
1172 |
<p class='jtw'>
|
1173 |
+
<label for="jtw"><?php _e( 'Custom Twitter Post', 'wp-to-twitter' ); ?></label><br/>
|
1174 |
<textarea class="wpt_tweet_box" name="_jd_twitter" id="jtw" rows="2" cols="60"><?php echo esc_attr( $tweet ); ?></textarea>
|
1175 |
+
<?php echo apply_filters( 'wpt_custom_box', '', $tweet, $post_id ); ?>
|
1176 |
</p>
|
1177 |
<?php
|
1178 |
$expanded = $template;
|
1179 |
+
if ( '' != get_option( 'jd_twit_prepend' ) ) {
|
1180 |
+
$expanded = "<span title='" . __( 'Your prepended Tweet text; not part of your template.', 'wp-to-twitter' ) . "'>" . stripslashes( get_option( 'jd_twit_prepend' ) ) . '</span> ' . $expanded;
|
1181 |
}
|
1182 |
+
if ( '' != get_option( 'jd_twit_append' ) ) {
|
1183 |
+
$expanded = $expanded . " <span title='" . __( 'Your appended Tweet text; not part of your template.', 'wp-to-twitter' ) . "'>" . stripslashes( get_option( 'jd_twit_append' ) ) . '</span>';
|
1184 |
}
|
1185 |
?>
|
1186 |
<p class='template'>
|
1195 |
echo "<label for='yourls_keyword'>" . __( 'YOURLS Custom Keyword', 'wp-to-twitter' ) . "</label> <input type='text' name='_yourls_keyword' id='yourls_keyword' value='$custom_keyword' />";
|
1196 |
}
|
1197 |
} else {
|
1198 |
+
?>
|
1199 |
+
<input type="hidden" name='_jd_twitter' value='<?php echo esc_attr( $tweet ); ?>'/>
|
1200 |
<?php
|
1201 |
}
|
1202 |
?>
|
1203 |
<div class='wpt-options'>
|
1204 |
+
<?php
|
1205 |
+
if ( 'pro' == $is_pro ) {
|
1206 |
+
$pro_active = " class='active'";
|
1207 |
+
$free_active = '';
|
1208 |
+
} else {
|
1209 |
+
$free_active = " class='active'";
|
1210 |
+
$pro_active = '';
|
1211 |
+
}
|
1212 |
+
?>
|
1213 |
+
<ul class='tabs' role="tablist">
|
1214 |
+
<?php if ( get_option( 'jd_individual_twitter_users' ) == 1 ) { ?>
|
1215 |
+
<li><a href='#authors'<?php echo $pro_active; ?> aria-controls="authors" role="tab" id="tab_authors"><?php _e( 'Tweet to', 'wp-to-twitter' ); ?></a></li>
|
1216 |
+
<?php } ?>
|
1217 |
+
<li><a href='#custom' aria-controls="custom" role="tab" id="tab_custom"><?php _e( 'Options', 'wp-to-twitter' ); ?></a></li>
|
1218 |
+
<li><a href='#notes'<?php echo $free_active; ?> aria-controls="notes" role="tab" id="tab_notes"><?php _e( 'Notes', 'wp-to-twitter' ); ?></a></li>
|
1219 |
+
</ul>
|
1220 |
+
<?php
|
1221 |
+
// WPT PRO OPTIONS.
|
1222 |
+
if ( current_user_can( 'edit_others_posts' ) ) {
|
1223 |
+
if ( 1 == get_option( 'jd_individual_twitter_users' ) ) {
|
1224 |
+
echo "<div class='wptab' id='authors' aria-labelledby='tab_authors' role='tabpanel'>";
|
1225 |
+
$selected = ( get_post_meta( $post_id, '_wpt_authorized_users', true ) ) ? get_post_meta( $post_id, '_wpt_authorized_users', true ) : array();
|
1226 |
+
if ( function_exists( 'wpt_authorized_users' ) ) {
|
1227 |
+
echo wpt_authorized_users( $selected );
|
1228 |
+
do_action( 'wpt_authors_tab', $post_id, $selected );
|
1229 |
+
} else {
|
1230 |
+
echo '<p>';
|
1231 |
+
if ( function_exists( 'wpt_pro_exists' ) ) {
|
1232 |
+
// Translators: URL to account.
|
1233 |
+
printf( __( 'WP Tweets PRO allows you to select Twitter accounts. <a href="%s">Log in and download now!</a>', 'wp-to-twitter' ), 'http://www.wptweetspro.com/account/' );
|
1234 |
} else {
|
1235 |
+
// Translators: URL to buy WP Tweets Pro.
|
1236 |
+
printf( __( 'Upgrade to WP Tweets PRO to select Twitter accounts! <a href="%s">Upgrade now!</a>', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro/' );
|
|
|
|
|
|
|
|
|
|
|
1237 |
}
|
1238 |
+
echo '</p>';
|
1239 |
+
}
|
1240 |
+
echo '</div>';
|
1241 |
}
|
1242 |
+
}
|
1243 |
+
?>
|
1244 |
+
<div class='wptab' id='custom' aria-labelledby='tab_custom' role='tabpanel'>
|
1245 |
+
<?php
|
1246 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() && ( current_user_can( 'wpt_twitter_custom' ) || current_user_can( 'manage_options' ) ) ) {
|
1247 |
+
wpt_schedule_values( $post_id );
|
1248 |
+
do_action( 'wpt_custom_tab', $post_id, 'visible' );
|
1249 |
+
} else {
|
1250 |
+
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
1251 |
+
// Translators: premium sales link.
|
1252 |
+
echo '<p>' . sprintf( __( 'Upgrade to WP Tweets PRO to configure options! <a href="%s">Upgrade now!</a>', 'wp-to-twitter' ), 'http://www.wptweetspro.com/wp-tweets-pro/' ) . '</p>';
|
1253 |
+
}
|
1254 |
+
}
|
1255 |
+
?>
|
1256 |
+
</div>
|
1257 |
+
<?php
|
1258 |
+
// WPT PRO.
|
1259 |
+
if ( ! current_user_can( 'wpt_twitter_custom' ) && ! current_user_can( 'manage_options' ) ) {
|
1260 |
?>
|
1261 |
+
<div class='wptab' id='custom' aria-labelledby='tab_custom' role='tabpanel'>
|
1262 |
+
<p><?php _e( 'Access to customizing WP to Twitter values is not allowed for your user role.', 'wp-to-twitter' ); ?></p>
|
1263 |
+
<?php
|
1264 |
+
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists() == true ) {
|
1265 |
+
wpt_schedule_values( $post_id, 'hidden' );
|
1266 |
+
do_action( 'wpt_custom_tab', $post_id, 'hidden' );
|
|
|
|
|
1267 |
}
|
1268 |
?>
|
1269 |
+
</div>
|
1270 |
+
<?php
|
1271 |
+
}
|
1272 |
+
if ( current_user_can( 'wpt_twitter_custom' ) || current_user_can( 'manage_options' ) ) {
|
1273 |
+
?>
|
1274 |
+
<div class='wptab' id='notes' aria-labelledby='tab_notes' role='tabpanel'>
|
1275 |
+
<p>
|
1276 |
+
<?php
|
1277 |
+
_e( 'Template Tags: <code>#url#</code>, <code>#title#</code>, <code>#post#</code>, <code>#category#</code>, <code>#date#</code>, <code>#modified#</code>, <code>#author#</code>, <code>#account#</code>, <code>#tags#</code>, <code>#blog#</code>, <code>#longurl#</code>.', 'wp-to-twitter' );
|
1278 |
+
do_action( 'wpt_notes_tab', $post_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
1279 |
?>
|
1280 |
+
</p>
|
1281 |
+
</div>
|
1282 |
+
<?php
|
1283 |
+
}
|
1284 |
+
?>
|
|
|
|
|
|
|
|
|
1285 |
</div>
|
1286 |
<?php
|
1287 |
if ( current_user_can( 'wpt_twitter_switch' ) || current_user_can( 'manage_options' ) ) {
|
1288 |
// "no" means 'Don't Tweet' (is checked)
|
1289 |
+
$nochecked = ( 'no' == $tweet_this ) ? ' checked="checked"' : '';
|
1290 |
+
$yeschecked = ( 'yes' == $tweet_this ) ? ' checked="checked"' : '';
|
1291 |
+
?>
|
1292 |
+
<p class='toggle-btn-group'>
|
1293 |
+
<input type="radio" name="_jd_tweet_this" value="no" id="jtn"<?php echo $nochecked; ?> /><label for="jtn"><?php _e( "Don't Tweet", 'wp-to-twitter' ); ?></label>
|
1294 |
+
<input type="radio" name="_jd_tweet_this" value="yes" id="jty"<?php echo $yeschecked; ?> /><label for="jty"><?php _e( 'Tweet', 'wp-to-twitter' ); ?></label>
|
1295 |
+
</p>
|
1296 |
<?php
|
1297 |
} else {
|
1298 |
+
?>
|
1299 |
+
<input type='hidden' name='_jd_tweet_this' value='<?php echo $tweet_this; ?>'/>
|
1300 |
<?php
|
1301 |
}
|
1302 |
+
wpt_show_tweets( $post_id );
|
1303 |
?>
|
1304 |
<p class="wpt-support">
|
1305 |
+
<?php
|
1306 |
+
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
1307 |
?>
|
1308 |
+
<strong><a href="http://www.wptweetspro.com/wp-tweets-pro"><?php _e( 'Go Premium', 'wp-to-twitter' ); ?></a></strong> »
|
1309 |
+
<?php
|
1310 |
+
} else {
|
1311 |
+
?>
|
1312 |
+
<a href="<?php echo esc_url( add_query_arg( 'tab', 'support', admin_url( 'admin.php?page=wp-tweets-pro' ) ) ); ?>#get-support"><?php _e( 'Get Support', 'wp-to-twitter' ); ?></a> »
|
1313 |
+
<?php
|
1314 |
+
}
|
1315 |
+
?>
|
1316 |
+
</p>
|
1317 |
+
<?php
|
1318 |
+
if ( '' != $tweet_status ) {
|
1319 |
echo "<p class='disabled'>$tweet_status</p>";
|
1320 |
}
|
1321 |
?>
|
1322 |
</div>
|
1323 |
<?php
|
1324 |
+
} else {
|
1325 |
+
// permissions: this user isn't allowed to Tweet.
|
1326 |
+
_e( 'Your role does not have the ability to Post Tweets from this site.', 'wp-to-twitter' );
|
1327 |
+
?>
|
1328 |
+
<input type='hidden' name='_jd_tweet_this' value='no'/>
|
1329 |
+
<?php
|
1330 |
}
|
1331 |
}
|
1332 |
|
1333 |
/**
|
1334 |
* Format history of Tweets attempted on current post.
|
1335 |
+
*
|
1336 |
+
* @param array $post_id Post ID to fetch Tweets on.
|
|
|
|
|
|
|
1337 |
*/
|
1338 |
+
function wpt_show_tweets( $post_id ) {
|
1339 |
+
$previous_tweets = get_post_meta( $post_id, '_jd_wp_twitter', true );
|
1340 |
+
$failed_tweets = get_post_meta( $post_id, '_wpt_failed' );
|
1341 |
+
|
1342 |
+
if ( ! is_array( $previous_tweets ) && '' != $previous_tweets ) {
|
1343 |
$previous_tweets = array( 0 => $previous_tweets );
|
1344 |
}
|
1345 |
if ( ! empty( $previous_tweets ) || ! empty( $failed_tweets ) ) {
|
1346 |
+
?>
|
1347 |
+
<hr>
|
1348 |
+
<p class='panel-toggle'>
|
1349 |
+
<a href='#wpt_tweet_history' class='history-toggle'><span class='dashicons dashicons-plus' aria-hidden="true"></span><?php _e( 'View Tweet History', 'wp-to-twitter' ); ?></a>
|
1350 |
+
</p>
|
1351 |
+
<div class='history'>
|
1352 |
+
<p class='error'><em><?php _e( 'Previous Tweets', 'wp-to-twitter' ); ?>:</em></p>
|
1353 |
+
<ul>
|
1354 |
+
<?php
|
1355 |
+
$has_history = false;
|
1356 |
+
$hidden_fields = '';
|
1357 |
+
if ( is_array( $previous_tweets ) ) {
|
1358 |
+
foreach ( $previous_tweets as $previous_tweet ) {
|
1359 |
+
if ( '' != $previous_tweet ) {
|
1360 |
+
$has_history = true;
|
1361 |
+
$hidden_fields .= "<input type='hidden' name='_jd_wp_twitter[]' value='" . esc_attr( $previous_tweet ) . "' />";
|
1362 |
+
echo "<li>$previous_tweet <a href='http://twitter.com/intent/tweet?text=" . urlencode( $previous_tweet ) . "'>Retweet this</a></li>";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1363 |
}
|
1364 |
+
}
|
1365 |
+
}
|
1366 |
+
?>
|
1367 |
+
</ul>
|
1368 |
+
<?php
|
1369 |
+
$list = false;
|
1370 |
+
$error_list = '';
|
1371 |
+
if ( is_array( $failed_tweets ) ) {
|
1372 |
+
foreach ( $failed_tweets as $failed_tweet ) {
|
1373 |
+
if ( ! empty( $failed_tweet ) ) {
|
1374 |
+
$ft = $failed_tweet['sentence'];
|
1375 |
+
$reason = $failed_tweet['code'];
|
1376 |
+
$error = $failed_tweet['error'];
|
1377 |
+
$list = true;
|
1378 |
+
$error_list .= "<li> <code>Error: $reason</code> $ft <a href='http://twitter.com/intent/tweet?text=" . urlencode( $ft ) . "'>Tweet this</a><br /><em>$error</em></li>";
|
1379 |
}
|
1380 |
}
|
1381 |
+
if ( true == $list ) {
|
1382 |
+
echo "<p class='error'><em>" . __( 'Failed Tweets', 'wp-to-twitter' ) . ":</em></p>
|
1383 |
+
<ul>$error_list</ul>";
|
1384 |
}
|
1385 |
+
}
|
1386 |
+
echo '<div>' . $hidden_fields . '</div>';
|
1387 |
+
if ( $has_history || $list ) {
|
1388 |
+
echo "<p><input type='checkbox' name='wpt_clear_history' id='wptch' value='clear' /> <label for='wptch'>" . __( 'Delete Tweet History', 'wp-to-twitter' ) . '</label></p>';
|
1389 |
+
}
|
1390 |
+
?>
|
1391 |
+
</div>
|
1392 |
+
<?php
|
1393 |
}
|
1394 |
}
|
1395 |
|
1399 |
*/
|
1400 |
function wpt_admin_scripts() {
|
1401 |
global $current_screen, $wpt_version;
|
1402 |
+
if ( 'post' == $current_screen->base || 'wp-tweets-pro_page_wp-to-twitter-schedule' == $current_screen->id ) {
|
1403 |
wp_enqueue_script( 'charCount', plugins_url( 'wp-to-twitter/js/jquery.charcount.js' ), array( 'jquery' ), $wpt_version );
|
1404 |
}
|
1405 |
+
if ( 'post' == $current_screen->base && isset( $_GET['post'] ) && ( current_user_can( 'wpt_tweet_now' ) || current_user_can( 'manage_options' ) ) ) {
|
1406 |
wp_enqueue_script( 'wpt.ajax', plugins_url( 'js/ajax.js', __FILE__ ), array( 'jquery' ), $wpt_version );
|
1407 |
wp_localize_script( 'wpt.ajax', 'wpt_data', array(
|
1408 |
'post_ID' => (int) $_GET['post'],
|
1409 |
'action' => 'wpt_tweet',
|
1410 |
+
'security' => wp_create_nonce( 'wpt-tweet-nonce' ),
|
1411 |
) );
|
1412 |
}
|
1413 |
+
if ( 'settings_page_wp-to-twitter/wp-to-twitter' == $current_screen->id || 'toplevel_page_wp-tweets-pro' == $current_screen->id ) {
|
1414 |
wp_enqueue_script( 'wpt.tabs', plugins_url( 'js/tabs.js', __FILE__ ), array( 'jquery' ), $wpt_version );
|
1415 |
wp_localize_script( 'wpt.tabs', 'firstItem', 'wpt_post' );
|
1416 |
wp_localize_script( 'wpt.tabs', 'firstPerm', 'wpt_editor' );
|
1421 |
add_action( 'wp_ajax_wpt_tweet', 'wpt_ajax_tweet' );
|
1422 |
/**
|
1423 |
* Handle Tweets sent via Ajax Tweet Now/Schedule Tweet buttons.
|
|
|
|
|
1424 |
*/
|
1425 |
function wpt_ajax_tweet() {
|
1426 |
if ( ! check_ajax_referer( 'wpt-tweet-nonce', 'security', false ) ) {
|
1427 |
+
echo 'Invalid Security Check';
|
1428 |
die;
|
1429 |
}
|
1430 |
+
$action = ( 'tweet' == $_REQUEST['tweet_action'] ) ? 'tweet' : 'schedule';
|
1431 |
+
$authors = ( isset( $_REQUEST['tweet_auth'] ) && null != $_REQUEST['tweet_auth'] ) ? $_REQUEST['tweet_auth'] : false;
|
1432 |
+
$upload = ( isset( $_REQUEST['tweet_upload'] ) && null != $_REQUEST['tweet_upload'] ) ? $_REQUEST['tweet_upload'] : 1;
|
1433 |
$current_user = wp_get_current_user();
|
1434 |
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists() ) {
|
1435 |
if ( wtt_oauth_test( $current_user->ID, 'verify' ) ) {
|
1436 |
+
$auth = $current_user->ID;
|
1437 |
+
$user_ID = $current_user->ID;
|
1438 |
} else {
|
1439 |
$auth = false;
|
1440 |
$user_ID = $current_user->ID;
|
1444 |
$user_ID = $current_user->ID;
|
1445 |
}
|
1446 |
|
1447 |
+
$authors = ( is_array( $authors ) && ! empty( $authors ) ) ? $authors : array( $auth );
|
1448 |
+
|
1449 |
if ( current_user_can( 'wpt_can_tweet' ) ) {
|
1450 |
$options = get_option( 'wpt_post_types' );
|
1451 |
$post_ID = intval( $_REQUEST['tweet_post_id'] );
|
1452 |
$type = get_post_type( $post_ID );
|
1453 |
$default = ( isset( $options[ $type ]['post-edited-text'] ) ) ? $options[ $type ]['post-edited-text'] : '';
|
1454 |
+
$sentence = ( isset( $_REQUEST['tweet_text'] ) && '' != trim( $_REQUEST['tweet_text'] ) ) ? $_REQUEST['tweet_text'] : $default;
|
1455 |
$sentence = stripcslashes( trim( $sentence ) );
|
1456 |
+
$post_info = wpt_post_info( $post_ID );
|
1457 |
$sentence = jd_truncate_tweet( $sentence, $post_info, $post_ID, false, $user_ID );
|
1458 |
$schedule = ( isset( $_REQUEST['tweet_schedule'] ) ) ? strtotime( $_REQUEST['tweet_schedule'] ) : rand( 60, 240 );
|
1459 |
$print_schedule = date_i18n( get_option( 'date_format' ) . ' @ ' . get_option( 'time_format' ), $schedule );
|
1460 |
$offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
|
1461 |
$schedule = $schedule - $offset;
|
1462 |
+
$media = ( 1 == $upload ) ? false : true; // this is correct; the boolean logic is reversed. Blah.
|
1463 |
+
|
1464 |
+
foreach ( $authors as $auth ) {
|
1465 |
+
|
1466 |
+
$auth = ( 'main' == $auth ) ? false : $auth;
|
1467 |
+
|
1468 |
switch ( $action ) {
|
1469 |
+
case 'tweet':
|
1470 |
wpt_post_to_twitter( $sentence, $auth, $post_ID, $media );
|
1471 |
break;
|
1472 |
+
case 'schedule':
|
1473 |
wp_schedule_single_event( $schedule, 'wpt_schedule_tweet_action', array(
|
1474 |
+
'id' => $auth,
|
1475 |
+
'sentence' => $sentence,
|
1476 |
+
'rt' => 0,
|
1477 |
+
'post_id' => $post_ID,
|
1478 |
+
) );
|
1479 |
break;
|
1480 |
}
|
1481 |
+
// Translators: Full text of Tweet, time scheduled for.
|
1482 |
+
$return = ( 'tweet' == $action ) ? wpt_log( 'wpt_status_message', $post_ID ) : sprintf( __( 'Tweet scheduled: %1$s for %2$s', 'wp-tweets-pro' ), '"' . $sentence . '"', $print_schedule );
|
1483 |
echo $return;
|
1484 |
if ( count( $authors ) > 1 ) {
|
1485 |
+
echo '<br />';
|
1486 |
}
|
1487 |
}
|
1488 |
} else {
|
1493 |
|
1494 |
add_action( 'admin_head', 'wpt_admin_script' );
|
1495 |
/**
|
1496 |
+
* Print scripts to WP Tweets PRO pages.
|
1497 |
*/
|
1498 |
function wpt_admin_script() {
|
1499 |
global $current_screen;
|
1500 |
+
if ( 'post' == $current_screen->base || 'wp-tweets-pro_page_wp-to-twitter-schedule' == $current_screen->id ) {
|
1501 |
wp_register_style( 'wpt-post-styles', plugins_url( 'css/post-styles.css', __FILE__ ) );
|
1502 |
wp_enqueue_style( 'wpt-post-styles' );
|
1503 |
$config = wpt_max_length();
|
1504 |
// add one; character count starts from 1.
|
1505 |
+
if ( 'post' == $current_screen->base ) {
|
1506 |
$allowed = $config['base_length'] - mb_strlen( stripslashes( get_option( 'jd_twit_prepend' ) . get_option( 'jd_twit_append' ) ) ) + 1;
|
1507 |
} else {
|
1508 |
$allowed = $config['base_length'] + 1;
|
1509 |
}
|
1510 |
+
if ( function_exists( 'wpt_pro_exists' ) && 1 == get_option( 'jd_individual_twitter_users' ) ) {
|
1511 |
$first = '#authors';
|
1512 |
+
} elseif ( function_exists( 'wpt_pro_exists' ) ) {
|
1513 |
$first = '#custom';
|
1514 |
} else {
|
1515 |
$first = '#notes';
|
1517 |
wp_register_script( 'wpt-base-js', plugins_url( 'js/base.js', __FILE__ ), array( 'jquery' ) );
|
1518 |
wp_enqueue_script( 'wpt-base-js' );
|
1519 |
wp_localize_script( 'wpt-base-js', 'wptSettings', array(
|
1520 |
+
'allowed' => $allowed,
|
1521 |
+
'first' => $first,
|
1522 |
+
'is_ssl' => ( wpt_is_ssl( home_url() ) ) ? 'true' : 'false',
|
1523 |
+
'text' => __( 'Characters left: ', 'wp-to-twitter' ),
|
1524 |
+
) );
|
1525 |
echo "
|
1526 |
<style type='text/css'>
|
1527 |
+
#wp2t h3 span, #wp2t h2 span { padding-left: 30px; background: url(" . plugins_url( 'wp-to-twitter/images/twitter-bird-light-bgs.png' ) . ') left 50% no-repeat; }
|
1528 |
+
</style>';
|
1529 |
}
|
1530 |
}
|
1531 |
|
1533 |
* Post the Custom Tweet & custom Tweet data into the post meta table
|
1534 |
*
|
1535 |
* @param integer $id Post ID.
|
|
|
1536 |
*/
|
1537 |
function wpt_save_post( $id ) {
|
1538 |
if ( empty( $_POST ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || wp_is_post_revision( $id ) || isset( $_POST['_inline_edit'] ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ! wpt_in_post_type( $id ) ) {
|
1542 |
$yourls = $_POST['_yourls_keyword'];
|
1543 |
$update = update_post_meta( $id, '_yourls_keyword', $yourls );
|
1544 |
}
|
1545 |
+
if ( isset( $_POST['_jd_twitter'] ) && '' != $_POST['_jd_twitter'] ) {
|
1546 |
$twitter = $_POST['_jd_twitter'];
|
1547 |
+
$update = update_post_meta( $id, '_jd_twitter', $twitter );
|
1548 |
+
} elseif ( isset( $_POST['_jd_twitter'] ) && '' == $_POST['_jd_twitter'] ) {
|
1549 |
delete_post_meta( $id, '_jd_twitter' );
|
1550 |
}
|
1551 |
+
if ( isset( $_POST['_jd_wp_twitter'] ) && '' != $_POST['_jd_wp_twitter'] ) {
|
1552 |
$wp_twitter = $_POST['_jd_wp_twitter'];
|
1553 |
+
$update = update_post_meta( $id, '_jd_wp_twitter', $wp_twitter );
|
1554 |
}
|
1555 |
if ( isset( $_POST['_jd_tweet_this'] ) ) {
|
1556 |
+
$tweet_this = ( 'no' == $_POST['_jd_tweet_this'] ) ? 'no' : 'yes';
|
1557 |
+
$update = update_post_meta( $id, '_jd_tweet_this', $tweet_this );
|
1558 |
} else {
|
1559 |
if ( isset( $_POST['_wpnonce'] ) ) {
|
1560 |
+
$tweet_default = ( 1 == get_option( 'jd_tweet_default' ) ) ? 'no' : 'yes';
|
1561 |
+
$update = update_post_meta( $id, '_jd_tweet_this', $tweet_default );
|
1562 |
}
|
1563 |
}
|
1564 |
+
if ( isset( $_POST['wpt_clear_history'] ) && 'clear' == $_POST['wpt_clear_history'] ) {
|
1565 |
delete_post_meta( $id, '_wpt_failed' );
|
1566 |
delete_post_meta( $id, '_jd_wp_twitter' );
|
1567 |
delete_post_meta( $id, '_wpt_short_url' );
|
1568 |
delete_post_meta( $id, '_wp_jd_twitter' );
|
1569 |
}
|
1570 |
+
// WPT PRO.
|
1571 |
$update = apply_filters( 'wpt_insert_post', $_POST, $id );
|
1572 |
+
// WPT PRO.
|
1573 |
+
// only send debug data if post meta is updated.
|
1574 |
+
if ( true == $update || is_int( $update ) ) {
|
1575 |
+
wpt_mail( 'Post Meta Inserted', print_r( $_POST, 1 ) ); // DEBUG.
|
1576 |
}
|
1577 |
+
if ( isset( $_POST['wpt-delete-debug'] ) && 'true' == $_POST['wpt-delete-debug'] ) {
|
1578 |
delete_post_meta( $id, '_wpt_debug_log' );
|
1579 |
}
|
1580 |
+
if ( isset( $_POST['wpt-delete-all-debug'] ) && 'true' == $_POST['wpt-delete-all-debug'] ) {
|
1581 |
delete_post_meta_by_key( '_wpt_debug_log' );
|
1582 |
}
|
1583 |
}
|
1584 |
|
1585 |
/**
|
1586 |
* Show user profile data on Edit User pages.
|
|
|
|
|
1587 |
*/
|
1588 |
function wpt_twitter_profile() {
|
1589 |
global $user_ID;
|
1590 |
$current_user = wp_get_current_user();
|
1591 |
+
$user_edit = ( isset( $_GET['user_id'] ) ) ? (int) $_GET['user_id'] : $user_ID;
|
1592 |
|
1593 |
$is_enabled = get_user_meta( $user_edit, 'wp-to-twitter-enable-user', true );
|
1594 |
$twitter_username = get_user_meta( $user_edit, 'wp-to-twitter-user-username', true );
|
1595 |
$wpt_remove = get_user_meta( $user_edit, 'wpt-remove', true );
|
1596 |
+
if ( current_user_can( 'wpt_twitter_oauth' ) || current_user_can( 'manage_options' ) ) {
|
1597 |
?>
|
1598 |
<h3><?php _e( 'WP Tweets User Settings', 'wp-to-twitter' ); ?></h3>
|
1599 |
+
<?php
|
1600 |
+
if ( function_exists( 'wpt_connect_oauth_message' ) ) {
|
1601 |
wpt_connect_oauth_message( $user_edit );
|
1602 |
+
}
|
1603 |
+
?>
|
1604 |
<table class="form-table">
|
1605 |
<tr>
|
1606 |
+
<th scope="row"><?php _e( 'Use My Twitter Username', 'wp-to-twitter' ); ?></th>
|
1607 |
<td>
|
1608 |
+
<input type="radio" name="wp-to-twitter-enable-user" id="wp-to-twitter-enable-user-3" value="mainAtTwitter"<?php checked( $is_enabled, 'mainAtTwitter' ); ?> /> <label for="wp-to-twitter-enable-user-3"><?php _e( 'Tweet my posts with an @ reference to my username.', 'wp-to-twitter' ); ?></label><br/>
|
1609 |
+
<input type="radio" name="wp-to-twitter-enable-user" id="wp-to-twitter-enable-user-4" value="mainAtTwitterPlus"<?php checked( $is_enabled, 'mainAtTwitterPlus' ); ?> /> <label for="wp-to-twitter-enable-user-4"><?php _e( 'Tweet my posts with an @ reference to both my username and to the main site username.', 'wp-to-twitter' ); ?></label>
|
1610 |
</td>
|
1611 |
</tr>
|
1612 |
<tr>
|
1613 |
+
<th scope="row">
|
1614 |
+
<label for="wp-to-twitter-user-username"><?php _e( 'Your Twitter Username', 'wp-to-twitter' ); ?></label>
|
1615 |
</th>
|
1616 |
+
<td>
|
1617 |
+
<input type="text" name="wp-to-twitter-user-username" id="wp-to-twitter-user-username" value="<?php echo esc_attr( $twitter_username ); ?>"/> <?php _e( 'Enter your own Twitter username.', 'wp-to-twitter' ); ?>
|
1618 |
</td>
|
1619 |
</tr>
|
1620 |
<tr>
|
1621 |
+
<th scope="row">
|
1622 |
+
<label for="wpt-remove"><?php _e( 'Hide account name in Tweets', 'wp-to-twitter' ); ?></label></th>
|
1623 |
+
<td>
|
1624 |
+
<input type="checkbox" name="wpt-remove" id="wpt-remove" value="on"<?php checked( 'on', $wpt_remove ); ?>/> <?php _e( 'Do not display my account in the #account# template tag.', 'wp-to-twitter' ); ?>
|
|
|
|
|
1625 |
</td>
|
1626 |
</tr>
|
1627 |
<?php echo apply_filters( 'wpt_twitter_user_fields', $user_edit ); ?>
|
1634 |
}
|
1635 |
} else {
|
1636 |
// hidden fields. If function is enabled, but this user does not have privileges to edit.
|
1637 |
+
?>
|
1638 |
+
<input type="hidden" name="wp-to-twitter-enable-user" value="<?php echo esc_attr( $is_enabled ); ?>" />
|
1639 |
+
<input type="hidden" name="wp-to-twitter-user-username" value="<?php echo esc_attr( $twitter_username ); ?>" />
|
1640 |
+
<input type="hidden" name="wpt-remove" value="<?php echo esc_attr( $wpt_remove ); ?>" />
|
1641 |
+
<?php
|
1642 |
}
|
1643 |
}
|
1644 |
|
1646 |
* This compensates for an old error where the user ID is echoed directly into the page.
|
1647 |
*/
|
1648 |
add_filter( 'wpt_twitter_user_fields', 'wpt_basic_user_fields', 100, 1 );
|
1649 |
+
/**
|
1650 |
+
* Return empty string if value is an integer.
|
1651 |
+
*
|
1652 |
+
* @param int $user_edit User ID.
|
1653 |
+
*
|
1654 |
+
* @return empty string.
|
1655 |
+
*/
|
1656 |
function wpt_basic_user_fields( $user_edit ) {
|
1657 |
if ( is_int( $user_edit ) ) {
|
1658 |
return '';
|
1659 |
}
|
1660 |
+
|
1661 |
return $user_edit;
|
1662 |
}
|
1663 |
|
1664 |
+
/**
|
1665 |
+
* Save user profile data
|
1666 |
*/
|
1667 |
+
function wpt_twitter_save_profile() {
|
1668 |
global $user_ID;
|
1669 |
$current_user = wp_get_current_user();
|
1670 |
if ( isset( $_POST['user_id'] ) ) {
|
1672 |
} else {
|
1673 |
$edit_id = $user_ID;
|
1674 |
}
|
1675 |
+
if ( current_user_can( 'wpt_twitter_oauth' ) || current_user_can( 'manage_options' ) ) {
|
1676 |
$enable = ( isset( $_POST['wp-to-twitter-enable-user'] ) ) ? $_POST['wp-to-twitter-enable-user'] : '';
|
1677 |
$username = ( isset( $_POST['wp-to-twitter-user-username'] ) ) ? $_POST['wp-to-twitter-user-username'] : '';
|
1678 |
$wpt_remove = ( isset( $_POST['wpt-remove'] ) ) ? 'on' : '';
|
1680 |
update_user_meta( $edit_id, 'wp-to-twitter-user-username', $username );
|
1681 |
update_user_meta( $edit_id, 'wpt-remove', $wpt_remove );
|
1682 |
}
|
1683 |
+
// WPT PRO.
|
1684 |
apply_filters( 'wpt_save_user', $edit_id, $_POST );
|
1685 |
}
|
1686 |
|
1687 |
+
add_action( 'init', 'wpt_old_admin_redirect' );
|
1688 |
/**
|
1689 |
* Send links to old admin to new admin page
|
1690 |
*/
|
|
|
1691 |
function wpt_old_admin_redirect() {
|
1692 |
+
if ( is_admin() && isset( $_GET['page'] ) && 'wp-to-twitter/wp-to-twitter.php' == $_GET['page'] ) {
|
1693 |
wp_safe_redirect( admin_url( 'admin.php?page=wp-tweets-pro' ) );
|
1694 |
exit;
|
1695 |
}
|
1702 |
function wpt_admin_page() {
|
1703 |
if ( function_exists( 'add_menu_page' ) && ! function_exists( 'wpt_pro_functions' ) ) {
|
1704 |
$icon_path = plugins_url( 'images/icon.png', __FILE__ );
|
1705 |
+
$page = add_menu_page( __( 'WP to Twitter', 'wp-to-twitter' ), __( 'WP to Twitter', 'wp-to-twitter' ), 'manage_options', 'wp-tweets-pro', 'wpt_update_settings', $icon_path );
|
1706 |
}
|
1707 |
}
|
1708 |
|
1709 |
add_action( 'admin_head', 'wpt_admin_style' );
|
1710 |
+
/**
|
1711 |
* Add stylesheets to WP to Twitter pages.
|
1712 |
*/
|
1713 |
function wpt_admin_style() {
|
1714 |
+
if ( isset( $_GET['page'] ) && ( 'wp-to-twitter' == $_GET['page'] || 'wp-tweets-pro' == $_GET['page'] || 'wp-to-twitter-schedule' == $_GET['page'] || 'wp-to-twitter-tweets' == $_GET['page'] || 'wp-to-twitter-errors' == $_GET['page'] ) ) {
|
1715 |
wp_enqueue_style( 'wpt-styles', plugins_url( 'css/styles.css', __FILE__ ) );
|
1716 |
}
|
1717 |
}
|
1718 |
|
1719 |
+
/**
|
1720 |
* Add WP to Twitter links to plug-in information.
|
1721 |
+
*
|
1722 |
+
* @param array $links Array of links.
|
1723 |
+
* @param string $file Current file name.
|
1724 |
+
*
|
1725 |
+
* @return link new array.
|
1726 |
*/
|
1727 |
function wpt_plugin_action( $links, $file ) {
|
1728 |
+
if ( plugin_basename( dirname( __FILE__ ) . '/wp-to-twitter.php' ) == $file ) {
|
1729 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
1730 |
+
$links[] = "<a href='$admin_url'>" . __( 'WP to Twitter Settings', 'wp-to-twitter' ) . '</a>';
|
1731 |
if ( ! function_exists( 'wpt_pro_exists' ) ) {
|
1732 |
+
$links[] = "<a href='http://www.wptweetspro.com/wp-tweets-pro'>" . __( 'Go Premium', 'wp-to-twitter' ) . '</a>';
|
1733 |
}
|
1734 |
}
|
1735 |
|
1736 |
return $links;
|
1737 |
}
|
1738 |
|
1739 |
+
// Add Plugin Actions to WordPress.
|
1740 |
+
add_filter( 'plugin_action_links', 'wpt_plugin_action', 10, 2 );
|
1741 |
|
1742 |
+
if ( '1' == get_option( 'jd_individual_twitter_users' ) ) {
|
1743 |
add_action( 'show_user_profile', 'wpt_twitter_profile' );
|
1744 |
add_action( 'edit_user_profile', 'wpt_twitter_profile' );
|
1745 |
add_action( 'profile_update', 'wpt_twitter_save_profile' );
|
1748 |
add_action( 'in_plugin_update_message-wp-to-twitter/wp-to-twitter.php', 'wpt_plugin_update_message' );
|
1749 |
/**
|
1750 |
* Parse plugin update info to display in update list.
|
|
|
|
|
1751 |
*/
|
1752 |
function wpt_plugin_update_message() {
|
1753 |
global $wpt_version;
|
1757 |
if ( ! is_wp_error( $response ) || is_array( $response ) ) {
|
1758 |
$data = $response['body'];
|
1759 |
$bits = explode( '== Upgrade Notice ==', $data );
|
1760 |
+
$note = '</div><div id="wpt-upgrade" class="notice inline notice-warning"><ul><li><strong style="color:#c22;">Upgrade Notes:</strong> ' . str_replace( '* ', '', nl2br( trim( $bits[1] ) ) ) . '</li></ul>';
|
1761 |
}
|
1762 |
+
|
1763 |
echo $note;
|
1764 |
}
|
1765 |
|
1766 |
+
if ( '1' == get_option( 'jd_twit_blogroll' ) ) {
|
1767 |
add_action( 'add_link', 'wpt_twit_link' );
|
1768 |
}
|
1769 |
|
1770 |
add_action( 'save_post', 'wpt_twit', 15 );
|
1771 |
add_action( 'save_post', 'wpt_save_post', 10 );
|
|
|
1772 |
/**
|
1773 |
* Check whether a given post is in an allowed post type and has an update template configured.
|
1774 |
+
*
|
1775 |
* @param integer $id Post ID.
|
1776 |
*
|
1777 |
* @return boolean True if post is allowed, false otherwise.
|
1778 |
*/
|
1779 |
function wpt_in_post_type( $id ) {
|
1780 |
$post_type_settings = get_option( 'wpt_post_types' );
|
1781 |
+
if ( is_array( $post_type_settings ) && ! empty( $post_type_settings ) ) {
|
1782 |
+
$post_types = array_keys( $post_type_settings );
|
1783 |
+
$type = get_post_type( $id );
|
1784 |
if ( in_array( $type, $post_types ) ) {
|
1785 |
+
if ( '1' == $post_type_settings[ $type ]['post-edited-update'] || '1' == $post_type_settings[ $type ]['post-published-update'] ) {
|
1786 |
return true;
|
1787 |
}
|
1788 |
}
|
1789 |
}
|
1790 |
+
|
1791 |
return false;
|
1792 |
}
|
1793 |
|
1794 |
add_action( 'future_to_publish', 'wpt_future_to_publish', 16 );
|
1795 |
/**
|
1796 |
* Handle Tweeting posts scheduled for the future.
|
1797 |
+
*
|
1798 |
+
* @param object $post Post object.
|
1799 |
*/
|
1800 |
function wpt_future_to_publish( $post ) {
|
1801 |
$id = $post->ID;
|
1807 |
|
1808 |
/**
|
1809 |
* Handle Tweeting posts published directly.
|
1810 |
+
*
|
1811 |
+
* @param object $id Post ID.
|
1812 |
*/
|
1813 |
function wpt_twit( $id ) {
|
1814 |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE || wp_is_post_revision( $id ) || ! wpt_in_post_type( $id ) ) {
|
1815 |
return;
|
1816 |
}
|
1817 |
+
$post = get_post( $id );
|
1818 |
+
if ( 'publish' != $post->post_status ) {
|
1819 |
return;
|
1820 |
+
}
|
1821 |
// is there any reason to accept any other status?
|
1822 |
+
// This is an issue only until the release of WP 4.7.
|
|
|
1823 |
remove_action( 'save_post', 'wpt_twit', 15 );
|
1824 |
wpt_twit_instant( $id );
|
1825 |
add_action( 'save_post', 'wpt_twit', 15 );
|
1835 |
*/
|
1836 |
function wpt_twit_future( $id ) {
|
1837 |
set_transient( '_wpt_twit_future', $id, 10 );
|
1838 |
+
// instant action has already run for this post. // prevent running actions twice (need both for older WP).
|
1839 |
if ( get_transient( '_wpt_twit_instant' ) && get_transient( '_wpt_twit_instant' ) == $id ) {
|
1840 |
delete_transient( '_wpt_twit_instant' );
|
1841 |
|
1842 |
return;
|
1843 |
}
|
1844 |
+
|
1845 |
wpt_tweet( $id, 'future' );
|
1846 |
}
|
1847 |
|
1867 |
wpt_tweet( $id, 'instant' );
|
1868 |
}
|
1869 |
|
1870 |
+
/**
|
1871 |
* Tweet XMLRPC posts.
|
1872 |
+
*
|
1873 |
+
* @param integer $id Post ID.
|
1874 |
+
*
|
1875 |
+
* @return post ID.
|
1876 |
*/
|
1877 |
function wpt_twit_xmlrpc( $id ) {
|
1878 |
set_transient( '_wpt_twit_xmlrpc', $id, 10 );
|
1888 |
* Set an option indicating that a job has been scheduled for promoting WP Tweets PRO.
|
1889 |
*/
|
1890 |
function wpt_schedule_promotion() {
|
1891 |
+
if ( ! function_exists( 'wpt_pro_exists' ) && 1 == get_option( 'wpt_promotion_scheduled' ) ) {
|
1892 |
update_option( 'wpt_promotion_scheduled', 2 );
|
1893 |
}
|
1894 |
}
|
1897 |
* Dismiss promotion notice.
|
1898 |
*/
|
1899 |
function wpt_dismiss_promotion() {
|
1900 |
+
if ( isset( $_GET['dismiss'] ) && 'promotion' == $_GET['dismiss'] ) {
|
1901 |
update_option( 'wpt_promotion_scheduled', 3 );
|
1902 |
}
|
1903 |
}
|
1905 |
add_action( 'admin_notices', 'wpt_dismiss_promotion', 5 );
|
1906 |
add_action( 'admin_notices', 'wpt_promotion_notice', 10 );
|
1907 |
add_action( 'admin_notices', 'wpt_debugging_enabled', 10 );
|
1908 |
+
/**
|
1909 |
+
* Show notice is Twitter debugging is enabled.
|
1910 |
+
*/
|
1911 |
function wpt_debugging_enabled() {
|
1912 |
if ( current_user_can( 'manage_options' ) && WPT_DEBUG ) {
|
1913 |
+
echo "<div class='notice error important'><p>" . __( '<strong>WP to Twitter</strong> debugging is enabled. Remember to disable debugging when you are finished.', 'wp-to-twitter' ) . '</p></div>';
|
1914 |
+
}
|
1915 |
}
|
1916 |
|
1917 |
/**
|
1918 |
* Display promotion notice to admin users who have not donated or purchased WP Tweets PRO.
|
1919 |
*/
|
1920 |
function wpt_promotion_notice() {
|
1921 |
+
if ( current_user_can( 'activate_plugins' ) && 2 == get_option( 'wpt_promotion_scheduled' ) && 1 != get_option( 'jd_donations' ) ) {
|
1922 |
+
$upgrade = 'http://www.wptweetspro.com/wp-tweets-pro/';
|
1923 |
$dismiss = admin_url( 'admin.php?page=wp-tweets-pro&dismiss=promotion' );
|
1924 |
+
// Translators: URL to upgrade.
|
1925 |
+
echo "<div class='notice'><p>" . sprintf( __( 'I hope you\'ve enjoyed <strong>WP to Twitter</strong>! Take a look at <a href=\'%1$s\'>upgrading to WP Tweets PRO</a> for advanced Tweeting with WordPress! <a href=\'%2$s\'>Dismiss</a>', 'wp-to-twitter' ), $upgrade, $dismiss ) . '</p></div>';
|
1926 |
}
|
1927 |
}
|
1928 |
|
1944 |
* Check whether Twitter Feed styles are enabled.
|
1945 |
*
|
1946 |
* @param boolean $value true if permitted.
|
1947 |
+
*
|
1948 |
* @return boolean $value False if settings disable styles.
|
1949 |
*/
|
1950 |
function wpt_permit_feed_styles( $value ) {
|
1951 |
+
if ( 1 == get_option( 'wpt_permit_feed_styles' ) ) {
|
1952 |
$value = false;
|
1953 |
}
|
1954 |
|
1955 |
return $value;
|
1956 |
}
|
1957 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1958 |
add_action( 'admin_head', 'wpt_css' );
|
1959 |
+
/**
|
1960 |
+
* Output CSS governing styles for authorized users column.
|
1961 |
+
*/
|
1962 |
function wpt_css() {
|
1963 |
+
?>
|
1964 |
<style type="text/css">
|
1965 |
th#wpt {
|
1966 |
width: 60px;
|
1975 |
</style>
|
1976 |
<?php
|
1977 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wpt-functions.php
CHANGED
@@ -1,38 +1,102 @@
|
|
1 |
<?php
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
exit;
|
6 |
-
}
|
7 |
|
8 |
-
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
if ( $sub1 ) {
|
11 |
$setting = get_option( $field );
|
12 |
if ( isset( $setting[ $sub1 ] ) ) {
|
13 |
-
$value = (
|
14 |
} else {
|
15 |
$value = 0;
|
16 |
}
|
17 |
-
if (
|
18 |
return 'checked="checked"';
|
19 |
}
|
20 |
}
|
21 |
-
if ( get_option( $field )
|
22 |
return 'checked="checked"';
|
23 |
}
|
24 |
return '';
|
25 |
}
|
26 |
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
if ( get_option( $field ) == $value ) {
|
29 |
-
return (
|
30 |
}
|
31 |
return '';
|
32 |
}
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
function wpt_set_log( $data, $id, $message ) {
|
35 |
-
if (
|
36 |
update_option( $data, $message );
|
37 |
} else {
|
38 |
update_post_meta( $id, '_' . $data, $message );
|
@@ -40,10 +104,18 @@ function wpt_set_log( $data, $id, $message ) {
|
|
40 |
update_option( $data . '_last', array( $id, $message ) );
|
41 |
}
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
function wpt_log( $data, $id ) {
|
44 |
-
if (
|
45 |
$log = get_option( $data );
|
46 |
-
}
|
47 |
$log = get_option( $data . '_last' );
|
48 |
} else {
|
49 |
$log = get_post_meta( $id, '_' . $data, true );
|
@@ -52,77 +124,81 @@ function wpt_log( $data, $id ) {
|
|
52 |
return $log;
|
53 |
}
|
54 |
|
|
|
|
|
|
|
55 |
function wpt_check_functions() {
|
56 |
$message = "<div class='update'><ul>";
|
57 |
-
// grab or set necessary variables
|
58 |
-
$testurl
|
59 |
-
$testpost
|
60 |
-
$title
|
61 |
-
$shrink
|
62 |
-
if (
|
63 |
-
$error
|
64 |
-
$message .= __(
|
65 |
-
if (
|
66 |
$message .= "<li><code>$error</code></li>";
|
67 |
} else {
|
68 |
-
$message .=
|
69 |
}
|
70 |
} else {
|
71 |
$message .= __( "<li><strong>WP to Twitter successfully contacted your URL shortening service.</strong> This link should point to your site's homepage:", 'wp-to-twitter' );
|
72 |
$message .= " <a href='$shrink'>$shrink</a></li>";
|
73 |
}
|
74 |
-
//check twitter credentials
|
75 |
if ( wtt_oauth_test() ) {
|
76 |
$rand = rand( 1000000, 9999999 );
|
77 |
$testpost = wpt_post_to_twitter( "This is a test of WP to Twitter. $shrink ($rand)" );
|
78 |
if ( $testpost ) {
|
79 |
-
$message .= __(
|
80 |
} else {
|
81 |
-
$error
|
82 |
-
$message .= __(
|
83 |
-
$message .= "<li class
|
84 |
}
|
85 |
} else {
|
86 |
-
$message .=
|
87 |
}
|
88 |
-
|
89 |
-
if ( $testpost == false && $shrink == false ) {
|
90 |
$message .= __( "<li class=\"error\"><strong>Your server does not appear to support the required methods for WP to Twitter to function.</strong> You can try it anyway - these tests aren't perfect.</li>", 'wp-to-twitter' );
|
91 |
-
} else {
|
92 |
}
|
93 |
if ( $testpost && $shrink ) {
|
94 |
-
$message .= __(
|
95 |
}
|
96 |
-
$message .=
|
97 |
-
</div>
|
98 |
|
99 |
return $message;
|
100 |
}
|
101 |
|
|
|
|
|
|
|
102 |
function wpt_settings_tabs() {
|
103 |
-
$output
|
104 |
-
$default
|
105 |
-
$current
|
106 |
$pro_text = ( function_exists( 'wpt_pro_exists' ) ) ? __( 'Pro Settings', 'wp-to-twitter' ) : __( 'Get WP Tweets PRO', 'wp-to-twitter' );
|
107 |
-
$pages
|
108 |
-
'connection'=> __( 'Twitter Connection', 'wp-to-twitter' ),
|
109 |
-
'basic'=> __( 'Basic Settings', 'wp-to-twitter' ),
|
110 |
-
'shortener'=> __( 'URL Shortener', 'wp-to-twitter' ),
|
111 |
-
'advanced'
|
112 |
-
'support'
|
113 |
-
'pro'
|
114 |
);
|
115 |
-
if ( get_option( 'jd_donations' )
|
116 |
unset( $pages['pro'] );
|
117 |
}
|
118 |
-
|
119 |
-
$pages
|
120 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
121 |
|
122 |
foreach ( $pages as $key => $value ) {
|
123 |
-
$selected = ( $key == $current ) ?
|
124 |
-
$url
|
125 |
-
if (
|
126 |
$output .= "<a class='wpt-pro-tab nav-tab$selected' href='$url'>$value</a>";
|
127 |
} else {
|
128 |
$output .= "<a class='nav-tab$selected' href='$url'>$value</a>";
|
@@ -131,6 +207,9 @@ function wpt_settings_tabs() {
|
|
131 |
echo $output;
|
132 |
}
|
133 |
|
|
|
|
|
|
|
134 |
function wpt_show_last_tweet() {
|
135 |
if ( apply_filters( 'wpt_show_last_tweet', true ) ) {
|
136 |
$log = wpt_log( 'wpt_status_message', 'last' );
|
@@ -140,7 +219,7 @@ function wpt_show_last_tweet() {
|
|
140 |
if ( is_object( $post ) ) {
|
141 |
$title = "<a href='" . get_edit_post_link( $post_ID ) . "'>$post->post_title</a>";
|
142 |
} else {
|
143 |
-
$title = __( 'No post
|
144 |
}
|
145 |
$notice = $log[1];
|
146 |
echo "<div class='updated'><p><strong>" . __( 'Last Tweet', 'wp-to-twitter' ) . "</strong>: $title » $notice</p></div>";
|
@@ -148,20 +227,21 @@ function wpt_show_last_tweet() {
|
|
148 |
}
|
149 |
}
|
150 |
|
151 |
-
|
|
|
|
|
152 |
function wpt_handle_errors() {
|
153 |
-
if ( isset( $_POST['submit-type'] ) && $_POST['submit-type']
|
154 |
delete_option( 'wp_url_failure' );
|
155 |
}
|
156 |
-
if ( get_option( 'wp_url_failure' )
|
157 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
158 |
-
$nonce
|
159 |
-
$error
|
160 |
-
__( "<p>The query to the URL shortener API failed, and your URL was not shrunk. The full post URL was attached to your Tweet. Check with your URL shortening provider to see if there are any known issues.</p>", 'wp-to-twitter' ) .
|
161 |
'<form method="post" action="' . $admin_url . '">
|
162 |
<div>
|
163 |
<input type="hidden" name="submit-type" value="clear-error"/>
|
164 |
-
'. $nonce . '
|
165 |
</div>
|
166 |
<p>
|
167 |
<input type="submit" name="submit" value="' . __( "Clear 'WP to Twitter' Error Messages", 'wp-to-twitter' ) . '" class="button-primary" />
|
@@ -171,7 +251,15 @@ function wpt_handle_errors() {
|
|
171 |
echo $error;
|
172 |
}
|
173 |
}
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
function wpt_check_caps( $role, $cap ) {
|
176 |
$role = get_role( $role );
|
177 |
if ( $role->has_cap( $cap ) ) {
|
@@ -180,13 +268,28 @@ function wpt_check_caps( $role, $cap ) {
|
|
180 |
return '';
|
181 |
}
|
182 |
|
183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
function wpt_cap_checkbox( $role, $cap, $name ) {
|
185 |
return "<li><input type='checkbox' id='wpt_caps_{$role}_$cap' name='wpt_caps[$role][$cap]' value='on'" . wpt_check_caps( $role, $cap ) . " /> <label for='wpt_caps_{$role}_$cap'>$name</label></li>";
|
186 |
}
|
187 |
|
188 |
-
|
189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
if ( WPT_DEBUG_BY_EMAIL ) {
|
191 |
wp_mail( WPT_DEBUG_ADDRESS, $subject, $body, WPT_FROM );
|
192 |
} else {
|
@@ -195,6 +298,12 @@ function wpt_mail( $subject, $body, $override=false ) {
|
|
195 |
}
|
196 |
}
|
197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
function wpt_debug_log( $subject, $body ) {
|
199 |
global $post_ID;
|
200 |
if ( $post_ID ) {
|
@@ -203,17 +312,20 @@ function wpt_debug_log( $subject, $body ) {
|
|
203 |
}
|
204 |
}
|
205 |
|
|
|
|
|
|
|
206 |
function wpt_show_debug() {
|
207 |
global $post_ID;
|
208 |
if ( WPT_DEBUG ) {
|
209 |
-
$records
|
210 |
$debug_log = get_post_meta( $post_ID, '_wpt_debug_log' );
|
211 |
if ( is_array( $debug_log ) ) {
|
212 |
-
foreach( $debug_log as $entry ) {
|
213 |
-
$date
|
214 |
-
$subject
|
215 |
-
$body
|
216 |
-
$records .= "<li><button type='button' class='toggle-debug button-secondary' aria-expanded='false'><strong>$date</strong>:<br />$subject</button><pre class='wpt-debug-details'>" . esc_html( $body ) .
|
217 |
}
|
218 |
}
|
219 |
$script = "
|
@@ -227,7 +339,7 @@ function wpt_show_debug() {
|
|
227 |
$( this ).attr( 'aria-expanded', 'false' );
|
228 |
} else {
|
229 |
$( this ).next( 'pre' ).show();
|
230 |
-
$( this ).attr( 'aria-expanded', 'true' );
|
231 |
}
|
232 |
});
|
233 |
})
|
@@ -235,38 +347,48 @@ function wpt_show_debug() {
|
|
235 |
</script>";
|
236 |
$delete = "<ul>
|
237 |
<li><input type='checkbox' name='wpt-delete-debug' value='true' id='wpt-delete-debug'> <label for='wpt-delete-debug'>" . __( 'Delete debugging logs on this post', 'wp-to-twitter' ) . "</label></li>
|
238 |
-
<li><input type='checkbox' name='wpt-delete-all-debug' value='true' id='wpt-delete-all-debug'> <label for='wpt-delete-all-debug'>" . __( 'Delete debugging logs for all posts', 'wp-to-twitter' ) .
|
239 |
-
</ul>
|
240 |
-
|
241 |
-
echo (
|
242 |
}
|
243 |
}
|
244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
function wpt_remote_json( $url, $array = true, $method = 'GET' ) {
|
246 |
$input = wpt_fetch_url( $url, $method );
|
247 |
wpt_mail( 'Remote JSON input', print_r( $input, 1 ) . "\n\n" . $url );
|
248 |
-
$obj
|
249 |
wpt_mail( 'Remote JSON return value', print_r( $obj, 1 ) . "\n\n" . "$url" );
|
250 |
-
if ( function_exists( 'json_last_error' ) ) { // > PHP 5.3
|
251 |
try {
|
252 |
if ( is_null( $obj ) ) {
|
253 |
switch ( json_last_error() ) {
|
254 |
-
case JSON_ERROR_DEPTH
|
255 |
$msg = ' - Maximum stack depth exceeded';
|
256 |
break;
|
257 |
-
case JSON_ERROR_STATE_MISMATCH
|
258 |
$msg = ' - Underflow or the modes mismatch';
|
259 |
break;
|
260 |
-
case JSON_ERROR_CTRL_CHAR
|
261 |
$msg = ' - Unexpected control character found';
|
262 |
break;
|
263 |
-
case JSON_ERROR_SYNTAX
|
264 |
$msg = ' - Syntax error, malformed JSON';
|
265 |
break;
|
266 |
-
case JSON_ERROR_UTF8
|
267 |
$msg = ' - Malformed UTF-8 characters, possibly incorrectly encoded';
|
268 |
break;
|
269 |
-
default
|
270 |
$msg = ' - Unknown error';
|
271 |
break;
|
272 |
}
|
@@ -280,6 +402,13 @@ function wpt_remote_json( $url, $array = true, $method = 'GET' ) {
|
|
280 |
return $obj;
|
281 |
}
|
282 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
function wpt_is_valid_url( $url ) {
|
284 |
if ( is_string( $url ) ) {
|
285 |
$url = urldecode( $url );
|
@@ -290,19 +419,30 @@ function wpt_is_valid_url( $url ) {
|
|
290 |
}
|
291 |
}
|
292 |
|
293 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
function wpt_fetch_url( $url, $method = 'GET', $body = '', $headers = '', $return = 'body' ) {
|
295 |
$request = new WP_Http;
|
296 |
-
$result = $request->request( $url, array(
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
|
|
303 |
if ( ! is_wp_error( $result ) && isset( $result['body'] ) ) {
|
304 |
-
if ( $result['response']['code']
|
305 |
-
if (
|
306 |
return $result['body'];
|
307 |
} else {
|
308 |
return $result;
|
@@ -310,63 +450,63 @@ function wpt_fetch_url( $url, $method = 'GET', $body = '', $headers = '', $retur
|
|
310 |
} else {
|
311 |
return $result['response']['code'];
|
312 |
}
|
313 |
-
// Failure (server problem...)
|
314 |
} else {
|
315 |
return false;
|
316 |
}
|
317 |
}
|
318 |
|
319 |
if ( ! function_exists( 'mb_substr_split_unicode' ) ) {
|
320 |
-
|
321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
return 0;
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
while ( $charPos++ < $splitPos ) {
|
342 |
-
++$bytePos;
|
343 |
-
// Move past any tail bytes
|
344 |
-
while ( $bytePos < $byteLen && $str[$bytePos] >= "\x80" && $str[$bytePos] < "\xc0" ) {
|
345 |
-
++$bytePos;
|
346 |
-
}
|
347 |
-
}
|
348 |
-
} else {
|
349 |
-
$splitPosX = $splitPos + 1;
|
350 |
-
$charPos = 0; // relative to end of string; we don't care about the actual char position here
|
351 |
-
$bytePos = $byteLen;
|
352 |
-
while ( $bytePos > 0 && $charPos-- >= $splitPosX ) {
|
353 |
-
--$bytePos;
|
354 |
-
// Move past any tail bytes
|
355 |
-
while ( $bytePos > 0 && $str[$bytePos] >= "\x80" && $str[$bytePos] < "\xc0" ) {
|
356 |
-
--$bytePos;
|
357 |
-
}
|
358 |
-
}
|
359 |
-
}
|
360 |
-
|
361 |
-
return $bytePos;
|
362 |
-
}
|
363 |
-
}
|
364 |
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
}
|
371 |
}
|
372 |
|
@@ -374,9 +514,9 @@ if ( ! function_exists( 'mb_strrpos' ) ) {
|
|
374 |
/**
|
375 |
* Fallback implementation of mb_strrpos, hardcoded to UTF-8.
|
376 |
*
|
377 |
-
* @param $haystack String
|
378 |
-
* @param $needle String
|
379 |
-
* @param $offset integer: optional start position
|
380 |
*
|
381 |
* @return int
|
382 |
*/
|
@@ -386,9 +526,7 @@ if ( ! function_exists( 'mb_strrpos' ) ) {
|
|
386 |
$ar = array();
|
387 |
preg_match_all( '/' . $needle . '/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
|
388 |
|
389 |
-
if ( isset( $ar[0] ) && count( $ar[0] ) > 0 &&
|
390 |
-
isset( $ar[0][ count( $ar[0] ) - 1 ][1] )
|
391 |
-
) {
|
392 |
return $ar[0][ count( $ar[0] ) - 1 ][1];
|
393 |
} else {
|
394 |
return false;
|
@@ -396,60 +534,14 @@ if ( ! function_exists( 'mb_strrpos' ) ) {
|
|
396 |
}
|
397 |
}
|
398 |
|
399 |
-
// str_ireplace substitution for PHP4
|
400 |
-
if ( ! function_exists( 'str_ireplace' ) ) {
|
401 |
-
function str_ireplace( $needle, $str, $haystack ) {
|
402 |
-
$needle = preg_quote( $needle, '/' );
|
403 |
-
|
404 |
-
return preg_replace( "/$needle/i", $str, $haystack );
|
405 |
-
}
|
406 |
-
}
|
407 |
-
// str_split substitution for PHP4
|
408 |
-
if ( ! function_exists( 'str_split' ) ) {
|
409 |
-
function str_split( $string, $string_length = 1 ) {
|
410 |
-
if ( strlen( $string ) > $string_length || ! $string_length ) {
|
411 |
-
do {
|
412 |
-
$parts[] = substr( $string, 0, $string_length );
|
413 |
-
$string = substr( $string, $string_length );
|
414 |
-
} while ( $string !== false );
|
415 |
-
} else {
|
416 |
-
$parts = array( $string );
|
417 |
-
}
|
418 |
-
|
419 |
-
return $parts;
|
420 |
-
}
|
421 |
-
}
|
422 |
-
// mb_substr_replace substition for PHP4
|
423 |
-
if ( ! function_exists( 'mb_substr_replace' ) ) {
|
424 |
-
function mb_substr_replace( $string, $replacement, $start, $length = null, $encoding = null ) {
|
425 |
-
if ( extension_loaded( 'mbstring' ) === true ) {
|
426 |
-
$string_length = ( is_null( $encoding ) === true ) ? mb_strlen( $string ) : mb_strlen( $string, $encoding );
|
427 |
-
if ( $start < 0 ) {
|
428 |
-
$start = max( 0, $string_length + $start );
|
429 |
-
} else if ( $start > $string_length ) {
|
430 |
-
$start = $string_length;
|
431 |
-
}
|
432 |
-
if ( $length < 0 ) {
|
433 |
-
$length = max( 0, $string_length - $start + $length );
|
434 |
-
} else if ( ( is_null( $length ) === true ) || ( $length > $string_length ) ) {
|
435 |
-
$length = $string_length;
|
436 |
-
}
|
437 |
-
if ( ( $start + $length ) > $string_length ) {
|
438 |
-
$length = $string_length - $start;
|
439 |
-
}
|
440 |
-
if ( is_null( $encoding ) === true ) {
|
441 |
-
return mb_substr( $string, 0, $start ) . $replacement . mb_substr( $string, $start + $length, $string_length - $start - $length );
|
442 |
-
}
|
443 |
-
|
444 |
-
return mb_substr( $string, 0, $start, $encoding ) . $replacement . mb_substr( $string, $start + $length, $string_length - $start - $length, $encoding );
|
445 |
-
}
|
446 |
-
|
447 |
-
return ( is_null( $length ) === true ) ? substr_replace( $string, $replacement, $start ) : substr_replace( $string, $replacement, $start, $length );
|
448 |
-
}
|
449 |
-
}
|
450 |
-
|
451 |
/**
|
452 |
* This function is obsolete; only exists for people using out of date versions of WP Tweets PRO.
|
|
|
|
|
|
|
|
|
|
|
|
|
453 |
*/
|
454 |
function wtt_option_selected( $field, $value, $type = 'checkbox' ) {
|
455 |
switch ( $type ) {
|
@@ -460,7 +552,8 @@ function wtt_option_selected( $field, $value, $type = 'checkbox' ) {
|
|
460 |
case 'option':
|
461 |
$result = ' selected="selected"';
|
462 |
break;
|
463 |
-
default:
|
|
|
464 |
}
|
465 |
if ( $field == $value ) {
|
466 |
$output = $result;
|
@@ -473,17 +566,17 @@ function wtt_option_selected( $field, $value, $type = 'checkbox' ) {
|
|
473 |
|
474 |
/**
|
475 |
* Compares two dates to identify which is earlier. Used to differentiate between post edits and original publication.
|
476 |
-
*
|
477 |
-
* @param string $modified
|
478 |
-
* @param string $
|
479 |
-
*
|
480 |
* @return integer 1|0
|
481 |
-
*/
|
482 |
function wpt_date_compare( $modified, $postdate ) {
|
483 |
$modifier = apply_filters( 'wpt_edit_sensitivity', 0 ); // alter time in seconds to modified date.
|
484 |
-
$mod_date
|
485 |
-
$post_date
|
486 |
-
if ( $mod_date <= $post_date ) { // if post_modified is before or equal to post_date
|
487 |
return 1;
|
488 |
} else {
|
489 |
return 0;
|
@@ -493,12 +586,12 @@ function wpt_date_compare( $modified, $postdate ) {
|
|
493 |
/**
|
494 |
* Gets the first attachment for the supplied post.
|
495 |
*
|
496 |
-
* @param integer $post_ID The post ID
|
497 |
*
|
498 |
* @return mixed boolean|integer Attachment ID.
|
499 |
*/
|
500 |
function wpt_post_attachment( $post_ID ) {
|
501 |
-
$return
|
502 |
$use_featured_image = apply_filters( 'wpt_use_featured_image', true, $post_ID );
|
503 |
if ( has_post_thumbnail( $post_ID ) && $use_featured_image ) {
|
504 |
$attachment = get_post_thumbnail_id( $post_ID );
|
@@ -511,66 +604,69 @@ function wpt_post_attachment( $post_ID ) {
|
|
511 |
'post_status' => 'published',
|
512 |
'post_parent' => $post_ID,
|
513 |
'post_mime_type' => 'image',
|
514 |
-
'order' => 'ASC'
|
515 |
);
|
516 |
$attachments = get_posts( $args );
|
517 |
if ( $attachments ) {
|
518 |
-
$return = $attachments[0]->ID; //Return the first attachment.
|
519 |
} else {
|
520 |
$return = false;
|
521 |
}
|
522 |
}
|
523 |
-
|
524 |
return apply_filters( 'wpt_post_attachment', $return, $post_ID );
|
525 |
}
|
526 |
|
|
|
|
|
|
|
527 |
function wpt_get_support_form() {
|
528 |
global $current_user, $wpt_version;
|
529 |
-
$current_user
|
530 |
-
$request
|
531 |
$response_email = '';
|
532 |
-
// send fields for WP to Twitter
|
533 |
-
$license = ( get_option( 'wpt_license_key' )
|
534 |
-
if (
|
535 |
-
$valid = ( ( get_option( 'wpt_license_valid' )
|
536 |
} else {
|
537 |
$valid = '';
|
538 |
}
|
539 |
-
$license =
|
540 |
|
541 |
$version = $wpt_version;
|
542 |
$wtt_twitter_username = get_option( 'wtt_twitter_username' );
|
543 |
-
// send fields for all plugins
|
544 |
$wp_version = get_bloginfo( 'version' );
|
545 |
$home_url = home_url();
|
546 |
$wp_url = site_url();
|
547 |
$language = get_bloginfo( 'language' );
|
548 |
$charset = get_bloginfo( 'charset' );
|
549 |
-
// server
|
550 |
$php_version = phpversion();
|
551 |
|
552 |
-
// theme data
|
553 |
$theme = wp_get_theme();
|
554 |
-
$theme_name = $theme->Name;
|
555 |
-
$theme_uri = $theme->ThemeURI;
|
556 |
-
$theme_parent = $theme->Template;
|
557 |
-
$theme_version = $theme->Version;
|
558 |
|
559 |
$admin_email = get_option( 'admin_email' );
|
560 |
-
// plugin data
|
561 |
$plugins = get_plugins();
|
562 |
$plugins_string = '';
|
563 |
foreach ( array_keys( $plugins ) as $key ) {
|
564 |
if ( is_plugin_active( $key ) ) {
|
565 |
-
$plugin
|
566 |
-
$plugin_name
|
567 |
-
$plugin_uri
|
568 |
-
$plugin_version
|
569 |
$plugins_string .= "$plugin_name: $plugin_version; $plugin_uri\n";
|
570 |
}
|
571 |
}
|
572 |
|
573 |
-
$data
|
574 |
================ Installation Data ====================
|
575 |
==WP to Twitter==
|
576 |
Version: $version
|
@@ -603,92 +699,102 @@ $plugins_string
|
|
603 |
if ( isset( $_POST['wpt_support'] ) ) {
|
604 |
$nonce = $_REQUEST['_wpnonce'];
|
605 |
if ( ! wp_verify_nonce( $nonce, 'wp-to-twitter-nonce' ) ) {
|
606 |
-
die(
|
607 |
}
|
608 |
$request = ( ! empty( $_POST['support_request'] ) ) ? stripslashes( $_POST['support_request'] ) : false;
|
609 |
-
$has_donated = ( isset( $_POST['has_donated'] ) ) ?
|
610 |
-
$has_read_faq = ( isset( $_POST['has_read_faq'] ) ) ?
|
611 |
-
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists()
|
612 |
-
$pro =
|
613 |
} else {
|
614 |
$pro = '';
|
615 |
}
|
616 |
$subject = "WP to Twitter$pro support request. $has_donated";
|
617 |
$message = $request . "\n\n" . $data;
|
618 |
-
// Get the site domain and get rid of www. from pluggable.php
|
619 |
$sitename = strtolower( $_SERVER['SERVER_NAME'] );
|
620 |
-
if ( substr( $sitename, 0, 4 )
|
621 |
$sitename = substr( $sitename, 4 );
|
622 |
}
|
623 |
$response_email = ( isset( $_POST['response_email'] ) ) ? $_POST['response_email'] : false;
|
624 |
-
$from_email
|
625 |
-
$from
|
626 |
|
627 |
if ( ! $has_read_faq ) {
|
628 |
-
echo "<div class='notice error'><p>" . __( 'Please read the FAQ and other Help documents before making a support request.', 'wp-to-twitter' ) .
|
629 |
-
}
|
630 |
-
echo "<div class='notice error'><p>" . __( 'Please supply a valid email where you can receive support responses.', 'wp-to-twitter' ) .
|
631 |
-
}
|
632 |
-
echo "<div class='notice error'><p>" . __( 'Please describe your problem. I\'m not psychic.', 'wp-to-twitter' ) .
|
633 |
} else {
|
634 |
-
$sent = wp_mail(
|
635 |
if ( $sent ) {
|
636 |
-
if (
|
637 |
-
|
|
|
638 |
} else {
|
639 |
-
|
|
|
640 |
}
|
641 |
} else {
|
642 |
-
|
|
|
643 |
}
|
644 |
}
|
645 |
}
|
646 |
-
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists()
|
647 |
-
$checked =
|
648 |
} else {
|
649 |
$checked = '';
|
650 |
}
|
651 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
652 |
$admin_url = add_query_arg( 'tab', 'support', $admin_url );
|
653 |
-
|
654 |
echo "
|
655 |
<form method='post' action='$admin_url'>
|
656 |
<div><input type='hidden' name='_wpnonce' value='" . wp_create_nonce( 'wp-to-twitter-nonce' ) . "' /></div>
|
657 |
<div>
|
658 |
-
<p>" .
|
659 |
-
__( "If you're having trouble with WP to Twitter, please try to answer these questions in your message:", 'wp-to-twitter' )
|
660 |
-
. "</p>
|
661 |
<ul>
|
662 |
-
<li>
|
663 |
-
<li>
|
664 |
-
<li>
|
665 |
</ul>
|
666 |
<p>
|
667 |
<label for='response_email'>" . __( 'Your Email', 'wp-to-twitter' ) . "</label><br />
|
668 |
<input type='email' name='response_email' id='response_email' value='$response_email' class='widefat' required='required' aria-required='true' />
|
669 |
</p>
|
670 |
<p>
|
671 |
-
<input type='checkbox' name='has_read_faq' id='has_read_faq' value='on' required='required' aria-required='true' /> <label for='has_read_faq'>"
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
|
|
|
|
678 |
</p>
|
679 |
<p>
|
680 |
<input type='submit' value='" . __( 'Send Support Request', 'wp-to-twitter' ) . "' name='wpt_support' class='button-primary' />
|
681 |
</p>
|
682 |
<p>" .
|
683 |
-
|
684 |
-
|
685 |
<div class='mc_support'>
|
686 |
-
" . wpautop( $data ) .
|
687 |
</div>
|
688 |
</div>
|
689 |
-
</form>
|
690 |
}
|
691 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
692 |
function wpt_is_writable( $file ) {
|
693 |
if ( function_exists( 'wp_is_writable' ) ) {
|
694 |
$is_writable = wp_is_writable( $file );
|
@@ -699,346 +805,78 @@ function wpt_is_writable( $file ) {
|
|
699 |
return $is_writable;
|
700 |
}
|
701 |
|
702 |
-
|
703 |
-
* Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
|
704 |
-
*
|
705 |
-
* It has been validated with Unicode 6.1 Normalization Conformance Test.
|
706 |
-
* See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
|
707 |
-
*/
|
708 |
-
class WPT_Normalizer
|
709 |
-
{
|
710 |
-
const
|
711 |
-
|
712 |
-
NONE = 1,
|
713 |
-
FORM_D = 2, NFD = 2,
|
714 |
-
FORM_KD = 3, NFKD = 3,
|
715 |
-
FORM_C = 4, NFC = 4,
|
716 |
-
FORM_KC = 5, NFKC = 5;
|
717 |
-
|
718 |
-
|
719 |
-
protected static
|
720 |
-
|
721 |
-
$C, $D, $KD, $cC,
|
722 |
-
$ulen_mask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4),
|
723 |
-
$ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
|
724 |
-
|
725 |
-
|
726 |
-
static function isNormalized($s, $form = self::NFC)
|
727 |
-
{
|
728 |
-
if (strspn($s, self::$ASCII) === strlen($s)) return true;
|
729 |
-
if (self::NFC === $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) return true;
|
730 |
-
return false; // Pretend false as quick checks implementented in PHP won't be so quick
|
731 |
-
}
|
732 |
-
|
733 |
-
static function normalize($s, $form = self::NFC)
|
734 |
-
{
|
735 |
-
if (!preg_match('//u', $s)) return false;
|
736 |
-
|
737 |
-
switch ($form)
|
738 |
-
{
|
739 |
-
case self::NONE: return $s;
|
740 |
-
case self::NFC: $C = true; $K = false; break;
|
741 |
-
case self::NFD: $C = false; $K = false; break;
|
742 |
-
case self::NFKC: $C = true; $K = true; break;
|
743 |
-
case self::NFKD: $C = false; $K = true; break;
|
744 |
-
default: return false;
|
745 |
-
}
|
746 |
-
|
747 |
-
if (!strlen($s)) return '';
|
748 |
-
|
749 |
-
if ($K && empty(self::$KD)) self::$KD = self::getData('compatibilityDecomposition');
|
750 |
-
|
751 |
-
if (empty(self::$D))
|
752 |
-
{
|
753 |
-
self::$D = self::getData('canonicalDecomposition');
|
754 |
-
self::$cC = self::getData('combiningClass');
|
755 |
-
}
|
756 |
-
|
757 |
-
if ($C)
|
758 |
-
{
|
759 |
-
if (empty(self::$C)) self::$C = self::getData('canonicalComposition');
|
760 |
-
return self::recompose(self::decompose($s, $K));
|
761 |
-
}
|
762 |
-
else return self::decompose($s, $K);
|
763 |
-
}
|
764 |
-
|
765 |
-
protected static function recompose($s)
|
766 |
-
{
|
767 |
-
$ASCII = self::$ASCII;
|
768 |
-
$compMap = self::$C;
|
769 |
-
$combClass = self::$cC;
|
770 |
-
$ulen_mask = self::$ulen_mask;
|
771 |
-
|
772 |
-
$result = $tail = '';
|
773 |
-
|
774 |
-
$i = $s[0] < "\x80" ? 1 : $ulen_mask[$s[0] & "\xF0"];
|
775 |
-
$len = strlen($s);
|
776 |
-
|
777 |
-
$last_uchr = substr($s, 0, $i);
|
778 |
-
$last_ucls = isset($combClass[$last_uchr]) ? 256 : 0;
|
779 |
-
|
780 |
-
while ($i < $len)
|
781 |
-
{
|
782 |
-
if ($s[$i] < "\x80")
|
783 |
-
{
|
784 |
-
// ASCII chars
|
785 |
-
|
786 |
-
if ($tail)
|
787 |
-
{
|
788 |
-
$last_uchr .= $tail;
|
789 |
-
$tail = '';
|
790 |
-
}
|
791 |
-
|
792 |
-
if ($j = strspn($s, $ASCII, $i+1))
|
793 |
-
{
|
794 |
-
$last_uchr .= substr($s, $i, $j);
|
795 |
-
$i += $j;
|
796 |
-
}
|
797 |
-
|
798 |
-
$result .= $last_uchr;
|
799 |
-
$last_uchr = $s[$i];
|
800 |
-
++$i;
|
801 |
-
}
|
802 |
-
else
|
803 |
-
{
|
804 |
-
$ulen = $ulen_mask[$s[$i] & "\xF0"];
|
805 |
-
$uchr = substr($s, $i, $ulen);
|
806 |
-
|
807 |
-
if ($last_uchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $last_uchr
|
808 |
-
|| $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
|
809 |
-
|| $last_ucls)
|
810 |
-
{
|
811 |
-
// Table lookup and combining chars composition
|
812 |
-
|
813 |
-
$ucls = isset($combClass[$uchr]) ? $combClass[$uchr] : 0;
|
814 |
-
|
815 |
-
if (isset($compMap[$last_uchr . $uchr]) && (!$last_ucls || $last_ucls < $ucls))
|
816 |
-
{
|
817 |
-
$last_uchr = $compMap[$last_uchr . $uchr];
|
818 |
-
}
|
819 |
-
else if ($last_ucls = $ucls) $tail .= $uchr;
|
820 |
-
else
|
821 |
-
{
|
822 |
-
if ($tail)
|
823 |
-
{
|
824 |
-
$last_uchr .= $tail;
|
825 |
-
$tail = '';
|
826 |
-
}
|
827 |
-
|
828 |
-
$result .= $last_uchr;
|
829 |
-
$last_uchr = $uchr;
|
830 |
-
}
|
831 |
-
}
|
832 |
-
else
|
833 |
-
{
|
834 |
-
// Hangul chars
|
835 |
-
|
836 |
-
$L = ord($last_uchr[2]) - 0x80;
|
837 |
-
$V = ord($uchr[2]) - 0xA1;
|
838 |
-
$T = 0;
|
839 |
-
|
840 |
-
$uchr = substr($s, $i + $ulen, 3);
|
841 |
-
|
842 |
-
if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82")
|
843 |
-
{
|
844 |
-
$T = ord($uchr[2]) - 0xA7;
|
845 |
-
0 > $T && $T += 0x40;
|
846 |
-
$ulen += 3;
|
847 |
-
}
|
848 |
-
|
849 |
-
$L = 0xAC00 + ($L * 21 + $V) * 28 + $T;
|
850 |
-
$last_uchr = chr(0xE0 | $L>>12) . chr(0x80 | $L>>6 & 0x3F) . chr(0x80 | $L & 0x3F);
|
851 |
-
}
|
852 |
-
|
853 |
-
$i += $ulen;
|
854 |
-
}
|
855 |
-
}
|
856 |
-
|
857 |
-
return $result . $last_uchr . $tail;
|
858 |
-
}
|
859 |
-
|
860 |
-
protected static function decompose($s, $c)
|
861 |
-
{
|
862 |
-
$result = '';
|
863 |
-
|
864 |
-
$ASCII = self::$ASCII;
|
865 |
-
$decompMap = self::$D;
|
866 |
-
$combClass = self::$cC;
|
867 |
-
$ulen_mask = self::$ulen_mask;
|
868 |
-
if ($c) $compatMap = self::$KD;
|
869 |
-
|
870 |
-
$c = array();
|
871 |
-
$i = 0;
|
872 |
-
$len = strlen($s);
|
873 |
-
|
874 |
-
while ($i < $len) {
|
875 |
-
if ($s[$i] < "\x80") {
|
876 |
-
// ASCII chars
|
877 |
-
|
878 |
-
if ($c) {
|
879 |
-
ksort($c);
|
880 |
-
$result .= implode('', $c);
|
881 |
-
$c = array();
|
882 |
-
}
|
883 |
-
|
884 |
-
$j = 1 + strspn($s, $ASCII, $i+1);
|
885 |
-
$result .= substr($s, $i, $j);
|
886 |
-
$i += $j;
|
887 |
-
} else {
|
888 |
-
$ulen = $ulen_mask[$s[$i] & "\xF0"];
|
889 |
-
$uchr = substr($s, $i, $ulen);
|
890 |
-
$i += $ulen;
|
891 |
-
|
892 |
-
if (isset($combClass[$uchr])) {
|
893 |
-
// Combining chars, for sorting
|
894 |
-
|
895 |
-
isset($c[$combClass[$uchr]]) || $c[$combClass[$uchr]] = '';
|
896 |
-
$c[$combClass[$uchr]] .= isset($compatMap[$uchr]) ? $compatMap[$uchr] : (isset($decompMap[$uchr]) ? $decompMap[$uchr] : $uchr);
|
897 |
-
} else {
|
898 |
-
if ($c) {
|
899 |
-
ksort($c);
|
900 |
-
$result .= implode('', $c);
|
901 |
-
$c = array();
|
902 |
-
}
|
903 |
-
|
904 |
-
if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) {
|
905 |
-
// Table lookup
|
906 |
-
|
907 |
-
$j = isset($compatMap[$uchr]) ? $compatMap[$uchr] : (isset($decompMap[$uchr]) ? $decompMap[$uchr] : $uchr);
|
908 |
-
|
909 |
-
if ($uchr != $j) {
|
910 |
-
$uchr = $j;
|
911 |
-
|
912 |
-
$j = strlen($uchr);
|
913 |
-
$ulen = $uchr[0] < "\x80" ? 1 : $ulen_mask[$uchr[0] & "\xF0"];
|
914 |
-
|
915 |
-
if ($ulen != $j)
|
916 |
-
{
|
917 |
-
// Put trailing chars in $s
|
918 |
-
|
919 |
-
$j -= $ulen;
|
920 |
-
$i -= $j;
|
921 |
-
|
922 |
-
if (0 > $i)
|
923 |
-
{
|
924 |
-
$s = str_repeat(' ', -$i) . $s;
|
925 |
-
$len -= $i;
|
926 |
-
$i = 0;
|
927 |
-
}
|
928 |
-
|
929 |
-
while ($j--) $s[$i+$j] = $uchr[$ulen+$j];
|
930 |
-
|
931 |
-
$uchr = substr($uchr, 0, $ulen);
|
932 |
-
}
|
933 |
-
}
|
934 |
-
} else {
|
935 |
-
// Hangul chars
|
936 |
-
|
937 |
-
$uchr = unpack('C*', $uchr);
|
938 |
-
$j = (($uchr[1]-224) << 12) + (($uchr[2]-128) << 6) + $uchr[3] - 0xAC80;
|
939 |
-
|
940 |
-
$uchr = "\xE1\x84" . chr(0x80 + (int) ($j / 588))
|
941 |
-
. "\xE1\x85" . chr(0xA1 + (int) (($j % 588) / 28));
|
942 |
-
|
943 |
-
if ($j %= 28)
|
944 |
-
{
|
945 |
-
$uchr .= $j < 25
|
946 |
-
? ("\xE1\x86" . chr(0xA7 + $j))
|
947 |
-
: ("\xE1\x87" . chr(0x67 + $j));
|
948 |
-
}
|
949 |
-
}
|
950 |
-
|
951 |
-
$result .= $uchr;
|
952 |
-
}
|
953 |
-
}
|
954 |
-
}
|
955 |
-
|
956 |
-
if ( $c ) {
|
957 |
-
ksort($c);
|
958 |
-
$result .= implode('', $c);
|
959 |
-
}
|
960 |
-
|
961 |
-
return $result;
|
962 |
-
}
|
963 |
-
|
964 |
-
protected static function getData($file) {
|
965 |
-
$file = __DIR__ . '/unidata/' . $file . '.ser';
|
966 |
-
if ( file_exists( $file ) ) {
|
967 |
-
return unserialize( file_get_contents( $file ) );
|
968 |
-
} else {
|
969 |
-
return false;
|
970 |
-
}
|
971 |
-
}
|
972 |
-
}
|
973 |
-
|
974 |
-
|
975 |
/**
|
976 |
* Migrates post meta to new format when post is called in editor.
|
977 |
*/
|
978 |
-
add_action( 'load-post.php', 'wpt_migrate_url_meta' );
|
979 |
function wpt_migrate_url_meta() {
|
980 |
$post_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : false;
|
981 |
-
if (
|
982 |
-
// if this is a new post screen, no migration
|
983 |
return;
|
984 |
}
|
985 |
-
|
986 |
$post = get_post( $post_id );
|
987 |
if ( strtotime( $post->post_date ) > 1449764285 ) {
|
988 |
// if this post was added after the migration function was added, it will not need to be migrated. Guaranteed.
|
989 |
return;
|
990 |
}
|
991 |
-
|
992 |
-
$short =
|
993 |
-
if (
|
994 |
-
return;
|
995 |
}
|
996 |
-
if (
|
997 |
$short = get_post_meta( $post_id, '_wp_jd_goo', true );
|
998 |
delete_post_meta( $post_id, '_wp_jd_goo' );
|
999 |
}
|
1000 |
-
if (
|
1001 |
$short = get_post_meta( $post_id, '_wp_jd_supr', true );
|
1002 |
delete_post_meta( $post_id, '_wp_jd_supr' );
|
1003 |
}
|
1004 |
-
if (
|
1005 |
$short = get_post_meta( $post_id, '_wp_jd_wp', true );
|
1006 |
delete_post_meta( $post_id, '_wp_jd_wp' );
|
1007 |
}
|
1008 |
-
if (
|
1009 |
$short = get_post_meta( $post_id, '_wp_jd_ind', true );
|
1010 |
delete_post_meta( $post_id, '_wp_jd_ind' );
|
1011 |
}
|
1012 |
-
if (
|
1013 |
$short = get_post_meta( $post_id, '_wp_jd_yourls', true );
|
1014 |
delete_post_meta( $post_id, '_wp_jd_yourls' );
|
1015 |
}
|
1016 |
-
if (
|
1017 |
$short = get_post_meta( $post_id, '_wp_jd_url', true );
|
1018 |
delete_post_meta( $post_id, '_wp_jd_url' );
|
1019 |
}
|
1020 |
-
if (
|
1021 |
$short = get_post_meta( $post_id, '_wp_jd_joturl', true );
|
1022 |
delete_post_meta( $post_id, '_wp_jd_joturl' );
|
1023 |
}
|
1024 |
-
if (
|
1025 |
-
// don't delete target link
|
1026 |
$short = get_post_meta( $post_id, '_wp_jd_target', true );
|
1027 |
}
|
1028 |
-
if (
|
1029 |
$short = get_post_meta( $post_id, '_wp_jd_clig', true );
|
1030 |
delete_post_meta( $post_id, '_wp_jd_clig' );
|
1031 |
}
|
1032 |
-
|
1033 |
-
if ( $short
|
1034 |
-
|
1035 |
}
|
1036 |
-
|
1037 |
-
update_post_meta( $post_id, '_wpt_short_url', $short );
|
1038 |
}
|
1039 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1040 |
function wp_get_curl( $url ) {
|
1041 |
-
|
1042 |
$curl = curl_init( $url );
|
1043 |
|
1044 |
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
|
@@ -1049,9 +887,9 @@ function wp_get_curl( $url ) {
|
|
1049 |
curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
|
1050 |
|
1051 |
$response = curl_exec( $curl );
|
1052 |
-
if( 0 !== curl_errno( $curl ) || 200 !== curl_getinfo( $curl, CURLINFO_HTTP_CODE ) ) {
|
1053 |
$response = false;
|
1054 |
-
} // end if
|
1055 |
curl_close( $curl );
|
1056 |
|
1057 |
return $response;
|
@@ -1061,6 +899,9 @@ add_action( 'dp_duplicate_post', 'wpt_delete_copied_meta', 10, 2 );
|
|
1061 |
add_action( 'dp_duplicate_page', 'wpt_delete_copied_meta', 10, 2 );
|
1062 |
/**
|
1063 |
* Prevent 'Duplicate Posts' plug-in from copying WP to Twitter meta data
|
|
|
|
|
|
|
1064 |
*/
|
1065 |
function wpt_delete_copied_meta( $new_id, $post ) {
|
1066 |
$disable = apply_filters( 'wpt_allow_copy_meta', false );
|
@@ -1077,32 +918,97 @@ function wpt_delete_copied_meta( $new_id, $post ) {
|
|
1077 |
}
|
1078 |
|
1079 |
/**
|
1080 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1081 |
*/
|
1082 |
function jd_fetch_url( $url, $method = 'GET', $body = '', $headers = '', $return = 'body' ) {
|
1083 |
return wpt_fetch_url( $url, $method, $body, $headers, $return );
|
1084 |
}
|
1085 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1086 |
function jd_remote_json( $url, $array = true ) {
|
1087 |
return wpt_remote_json( $url, $array );
|
1088 |
}
|
1089 |
|
1090 |
-
|
1091 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1092 |
}
|
1093 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1094 |
function jd_post_info( $post_ID ) {
|
1095 |
return wpt_post_info( $post_ID );
|
1096 |
}
|
1097 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1098 |
function jd_twit( $post_ID, $type = 'instant' ) {
|
1099 |
return wpt_tweet( $post_ID, $type );
|
1100 |
}
|
1101 |
|
|
|
|
|
|
|
1102 |
function jd_addTwitterAdminStyles() {
|
1103 |
return wpt_admin_style();
|
1104 |
}
|
1105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1106 |
function jd_doTwitterAPIPost( $twit, $auth = false, $id = false, $media = false ) {
|
1107 |
return wpt_post_to_twitter( $twit, $auth, $id, $media );
|
1108 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Core support functions WP to Twitter
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
|
16 |
+
include( dirname( __FILE__ ) . '/classes/class-wpt-normalizer.php' );
|
17 |
+
|
18 |
+
/**
|
19 |
+
* See if checkboxes should be checked
|
20 |
+
*
|
21 |
+
* @param string $field Option name to check.
|
22 |
+
* @param string $sub1 Array key if applicable.
|
23 |
+
* @param string $sub2 Array key if applicable.
|
24 |
+
*
|
25 |
+
* @return Checked or unchecked.
|
26 |
+
*/
|
27 |
+
function wpt_checkbox( $field, $sub1 = false, $sub2 = '' ) {
|
28 |
if ( $sub1 ) {
|
29 |
$setting = get_option( $field );
|
30 |
if ( isset( $setting[ $sub1 ] ) ) {
|
31 |
+
$value = ( '' != $sub2 ) ? $setting[ $sub1 ][ $sub2 ] : $setting[ $sub1 ];
|
32 |
} else {
|
33 |
$value = 0;
|
34 |
}
|
35 |
+
if ( 1 == $value ) {
|
36 |
return 'checked="checked"';
|
37 |
}
|
38 |
}
|
39 |
+
if ( '1' == get_option( $field ) ) {
|
40 |
return 'checked="checked"';
|
41 |
}
|
42 |
return '';
|
43 |
}
|
44 |
|
45 |
+
/**
|
46 |
+
* See if checkboxes should be checked - fallback to old function.
|
47 |
+
*
|
48 |
+
* @param string $field Option name to check.
|
49 |
+
* @param string $sub1 Array key if applicable.
|
50 |
+
* @param string $sub2 Array key if applicable.
|
51 |
+
*
|
52 |
+
* @deprecated 3/26/2018
|
53 |
+
*
|
54 |
+
* @return Checked or unchecked.
|
55 |
+
*/
|
56 |
+
function jd_checkCheckbox( $field, $sub1 = false, $sub2 = '' ) {
|
57 |
+
return wpt_checkbox( $field, $sub1, $sub2 );
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* See if options should be selected
|
62 |
+
*
|
63 |
+
* @param string $field Option name to check.
|
64 |
+
* @param string $value Value to verify against.
|
65 |
+
* @param string $type Select or checkbox.
|
66 |
+
*
|
67 |
+
* @return Selected or unselected/ checked or unchecked..
|
68 |
+
*/
|
69 |
+
function wpt_selected( $field, $value, $type = 'select' ) {
|
70 |
if ( get_option( $field ) == $value ) {
|
71 |
+
return ( 'select' == $type ) ? 'selected="selected"' : 'checked="checked"';
|
72 |
}
|
73 |
return '';
|
74 |
}
|
75 |
|
76 |
+
/**
|
77 |
+
* See if options should be selected - fallback function
|
78 |
+
*
|
79 |
+
* @param string $field Option name to check.
|
80 |
+
* @param string $value Value to verify against.
|
81 |
+
* @param string $type Select or checkbox.
|
82 |
+
*
|
83 |
+
* @deprecated 3/26/2018
|
84 |
+
*
|
85 |
+
* @return Selected or unselected/ checked or unchecked..
|
86 |
+
*/
|
87 |
+
function jd_checkSelect( $field, $value, $type = 'select' ) {
|
88 |
+
return wpt_selected( $field, $value, $type );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Insert a Tweet record into logs.
|
93 |
+
*
|
94 |
+
* @param string $data Option key.
|
95 |
+
* @param int $id Post ID.
|
96 |
+
* @param string $message Log message.
|
97 |
+
*/
|
98 |
function wpt_set_log( $data, $id, $message ) {
|
99 |
+
if ( 'test' == $id ) {
|
100 |
update_option( $data, $message );
|
101 |
} else {
|
102 |
update_post_meta( $id, '_' . $data, $message );
|
104 |
update_option( $data . '_last', array( $id, $message ) );
|
105 |
}
|
106 |
|
107 |
+
/**
|
108 |
+
* Get information from Tweet logs.
|
109 |
+
*
|
110 |
+
* @param string $data Option key.
|
111 |
+
* @param int $id Post ID.
|
112 |
+
*
|
113 |
+
* @return stored message.
|
114 |
+
*/
|
115 |
function wpt_log( $data, $id ) {
|
116 |
+
if ( 'test' == $id ) {
|
117 |
$log = get_option( $data );
|
118 |
+
} elseif ( 'last' == $id ) {
|
119 |
$log = get_option( $data . '_last' );
|
120 |
} else {
|
121 |
$log = get_post_meta( $id, '_' . $data, true );
|
124 |
return $log;
|
125 |
}
|
126 |
|
127 |
+
/**
|
128 |
+
* Test function to see whether options are functioning.
|
129 |
+
*/
|
130 |
function wpt_check_functions() {
|
131 |
$message = "<div class='update'><ul>";
|
132 |
+
// grab or set necessary variables.
|
133 |
+
$testurl = get_bloginfo( 'url' );
|
134 |
+
$testpost = false;
|
135 |
+
$title = urlencode( 'Your blog home' );
|
136 |
+
$shrink = apply_filters( 'wptt_shorten_link', $testurl, $title, false, true );
|
137 |
+
if ( false == $shrink ) {
|
138 |
+
$error = htmlentities( get_option( 'wpt_shortener_status' ) );
|
139 |
+
$message .= __( '<li class="error"><strong>WP to Twitter was unable to contact your selected URL shortening service.</strong></li>', 'wp-to-twitter' );
|
140 |
+
if ( '' != $error ) {
|
141 |
$message .= "<li><code>$error</code></li>";
|
142 |
} else {
|
143 |
+
$message .= '<li><code>' . __( 'No error message was returned.', 'wp-to-twitter' ) . '</code></li>';
|
144 |
}
|
145 |
} else {
|
146 |
$message .= __( "<li><strong>WP to Twitter successfully contacted your URL shortening service.</strong> This link should point to your site's homepage:", 'wp-to-twitter' );
|
147 |
$message .= " <a href='$shrink'>$shrink</a></li>";
|
148 |
}
|
149 |
+
// check twitter credentials.
|
150 |
if ( wtt_oauth_test() ) {
|
151 |
$rand = rand( 1000000, 9999999 );
|
152 |
$testpost = wpt_post_to_twitter( "This is a test of WP to Twitter. $shrink ($rand)" );
|
153 |
if ( $testpost ) {
|
154 |
+
$message .= __( '<li><strong>WP to Twitter successfully submitted a status update to Twitter.</strong></li>', 'wp-to-twitter' );
|
155 |
} else {
|
156 |
+
$error = wpt_log( 'wpt_status_message', 'test' );
|
157 |
+
$message .= __( '<li class="error"><strong>WP to Twitter failed to submit an update to Twitter.</strong></li>', 'wp-to-twitter' );
|
158 |
+
$message .= "<li class='error'>$error</li>";
|
159 |
}
|
160 |
} else {
|
161 |
+
$message .= '<strong>' . __( 'You have not connected WordPress to Twitter.', 'wp-to-twitter' ) . '</strong> ';
|
162 |
}
|
163 |
+
if ( false == $testpost && false == $shrink ) {
|
|
|
164 |
$message .= __( "<li class=\"error\"><strong>Your server does not appear to support the required methods for WP to Twitter to function.</strong> You can try it anyway - these tests aren't perfect.</li>", 'wp-to-twitter' );
|
|
|
165 |
}
|
166 |
if ( $testpost && $shrink ) {
|
167 |
+
$message .= __( '<li><strong>Your server should run WP to Twitter successfully.</strong></li>', 'wp-to-twitter' );
|
168 |
}
|
169 |
+
$message .= '</ul>
|
170 |
+
</div>';
|
171 |
|
172 |
return $message;
|
173 |
}
|
174 |
|
175 |
+
/**
|
176 |
+
* Generate Settings links.
|
177 |
+
*/
|
178 |
function wpt_settings_tabs() {
|
179 |
+
$output = '';
|
180 |
+
$default = ( '' == get_option( 'wtt_twitter_username' ) ) ? 'connection' : 'basic';
|
181 |
+
$current = ( isset( $_GET['tab'] ) ) ? $_GET['tab'] : $default;
|
182 |
$pro_text = ( function_exists( 'wpt_pro_exists' ) ) ? __( 'Pro Settings', 'wp-to-twitter' ) : __( 'Get WP Tweets PRO', 'wp-to-twitter' );
|
183 |
+
$pages = array(
|
184 |
+
'connection' => __( 'Twitter Connection', 'wp-to-twitter' ),
|
185 |
+
'basic' => __( 'Basic Settings', 'wp-to-twitter' ),
|
186 |
+
'shortener' => __( 'URL Shortener', 'wp-to-twitter' ),
|
187 |
+
'advanced' => __( 'Advanced Settings', 'wp-to-twitter' ),
|
188 |
+
'support' => __( 'Get Help', 'wp-to-twitter' ),
|
189 |
+
'pro' => $pro_text,
|
190 |
);
|
191 |
+
if ( '1' == get_option( 'jd_donations' ) && ! function_exists( 'wpt_pro_exists' ) ) {
|
192 |
unset( $pages['pro'] );
|
193 |
}
|
194 |
+
|
195 |
+
$pages = apply_filters( 'wpt_settings_tabs_pages', $pages, $current );
|
196 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
197 |
|
198 |
foreach ( $pages as $key => $value ) {
|
199 |
+
$selected = ( $key == $current ) ? ' nav-tab-active' : '';
|
200 |
+
$url = esc_url( add_query_arg( 'tab', $key, $admin_url ) );
|
201 |
+
if ( 'pro' == $key ) {
|
202 |
$output .= "<a class='wpt-pro-tab nav-tab$selected' href='$url'>$value</a>";
|
203 |
} else {
|
204 |
$output .= "<a class='nav-tab$selected' href='$url'>$value</a>";
|
207 |
echo $output;
|
208 |
}
|
209 |
|
210 |
+
/**
|
211 |
+
* Show the last Tweet attempt as admin notice.
|
212 |
+
*/
|
213 |
function wpt_show_last_tweet() {
|
214 |
if ( apply_filters( 'wpt_show_last_tweet', true ) ) {
|
215 |
$log = wpt_log( 'wpt_status_message', 'last' );
|
219 |
if ( is_object( $post ) ) {
|
220 |
$title = "<a href='" . get_edit_post_link( $post_ID ) . "'>$post->post_title</a>";
|
221 |
} else {
|
222 |
+
$title = '(' . __( 'No post', 'wp-to-twitter' ) . ')';
|
223 |
}
|
224 |
$notice = $log[1];
|
225 |
echo "<div class='updated'><p><strong>" . __( 'Last Tweet', 'wp-to-twitter' ) . "</strong>: $title » $notice</p></div>";
|
227 |
}
|
228 |
}
|
229 |
|
230 |
+
/**
|
231 |
+
* Handle Tweet & URL shortener errors.
|
232 |
+
*/
|
233 |
function wpt_handle_errors() {
|
234 |
+
if ( isset( $_POST['submit-type'] ) && 'clear-error' == $_POST['submit-type'] ) {
|
235 |
delete_option( 'wp_url_failure' );
|
236 |
}
|
237 |
+
if ( '1' == get_option( 'wp_url_failure' ) ) {
|
238 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
239 |
+
$nonce = wp_nonce_field( 'wp-to-twitter-nonce', '_wpnonce', true, false ) . wp_referer_field( false );
|
240 |
+
$error = '<div class="error">' . __( '<p>The query to the URL shortener API failed, and your URL was not shrunk. The full post URL was attached to your Tweet. Check with your URL shortening provider to see if there are any known issues.</p>', 'wp-to-twitter' ) .
|
|
|
241 |
'<form method="post" action="' . $admin_url . '">
|
242 |
<div>
|
243 |
<input type="hidden" name="submit-type" value="clear-error"/>
|
244 |
+
' . $nonce . '
|
245 |
</div>
|
246 |
<p>
|
247 |
<input type="submit" name="submit" value="' . __( "Clear 'WP to Twitter' Error Messages", 'wp-to-twitter' ) . '" class="button-primary" />
|
251 |
echo $error;
|
252 |
}
|
253 |
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Verify user capabilities
|
257 |
+
*
|
258 |
+
* @param string $role Role name.
|
259 |
+
* @param string $cap Capability name.
|
260 |
+
*
|
261 |
+
* @return Check if has capability.
|
262 |
+
*/
|
263 |
function wpt_check_caps( $role, $cap ) {
|
264 |
$role = get_role( $role );
|
265 |
if ( $role->has_cap( $cap ) ) {
|
268 |
return '';
|
269 |
}
|
270 |
|
271 |
+
/**
|
272 |
+
* Output checkbox for user capabilities
|
273 |
+
*
|
274 |
+
* @param string $role Role name.
|
275 |
+
* @param string $cap Capability name.
|
276 |
+
* @param string $name Display name for capability.
|
277 |
+
*
|
278 |
+
* @return Checkbox HTML.
|
279 |
+
*/
|
280 |
function wpt_cap_checkbox( $role, $cap, $name ) {
|
281 |
return "<li><input type='checkbox' id='wpt_caps_{$role}_$cap' name='wpt_caps[$role][$cap]' value='on'" . wpt_check_caps( $role, $cap ) . " /> <label for='wpt_caps_{$role}_$cap'>$name</label></li>";
|
282 |
}
|
283 |
|
284 |
+
/**
|
285 |
+
* Send a debug message. (Used email by default until 3.3.)
|
286 |
+
*
|
287 |
+
* @param string $subject Subject of error.
|
288 |
+
* @param string $body Body of error.
|
289 |
+
* @param boolean $override Send message if debug disabled.
|
290 |
+
*/
|
291 |
+
function wpt_mail( $subject, $body, $override = false ) {
|
292 |
+
if ( ( WPT_DEBUG && function_exists( 'wpt_pro_exists' ) ) || true == $override ) {
|
293 |
if ( WPT_DEBUG_BY_EMAIL ) {
|
294 |
wp_mail( WPT_DEBUG_ADDRESS, $subject, $body, WPT_FROM );
|
295 |
} else {
|
298 |
}
|
299 |
}
|
300 |
|
301 |
+
/**
|
302 |
+
* Insert record into debug log.
|
303 |
+
*
|
304 |
+
* @param string $subject Subject of error.
|
305 |
+
* @param string $body Body of error.
|
306 |
+
*/
|
307 |
function wpt_debug_log( $subject, $body ) {
|
308 |
global $post_ID;
|
309 |
if ( $post_ID ) {
|
312 |
}
|
313 |
}
|
314 |
|
315 |
+
/**
|
316 |
+
* Display debug log.
|
317 |
+
*/
|
318 |
function wpt_show_debug() {
|
319 |
global $post_ID;
|
320 |
if ( WPT_DEBUG ) {
|
321 |
+
$records = '';
|
322 |
$debug_log = get_post_meta( $post_ID, '_wpt_debug_log' );
|
323 |
if ( is_array( $debug_log ) ) {
|
324 |
+
foreach ( $debug_log as $entry ) {
|
325 |
+
$date = date_i18n( 'Y-m-d H:i', $entry[0] );
|
326 |
+
$subject = $entry[1];
|
327 |
+
$body = $entry[2];
|
328 |
+
$records .= "<li><button type='button' class='toggle-debug button-secondary' aria-expanded='false'><strong>$date</strong>:<br />$subject</button><pre class='wpt-debug-details'>" . esc_html( $body ) . '</pre></li>';
|
329 |
}
|
330 |
}
|
331 |
$script = "
|
339 |
$( this ).attr( 'aria-expanded', 'false' );
|
340 |
} else {
|
341 |
$( this ).next( 'pre' ).show();
|
342 |
+
$( this ).attr( 'aria-expanded', 'true' );
|
343 |
}
|
344 |
});
|
345 |
})
|
347 |
</script>";
|
348 |
$delete = "<ul>
|
349 |
<li><input type='checkbox' name='wpt-delete-debug' value='true' id='wpt-delete-debug'> <label for='wpt-delete-debug'>" . __( 'Delete debugging logs on this post', 'wp-to-twitter' ) . "</label></li>
|
350 |
+
<li><input type='checkbox' name='wpt-delete-all-debug' value='true' id='wpt-delete-all-debug'> <label for='wpt-delete-all-debug'>" . __( 'Delete debugging logs for all posts', 'wp-to-twitter' ) . '</label></li>
|
351 |
+
</ul>';
|
352 |
+
|
353 |
+
echo ( '' != $records ) ? "$script<div class='wpt-debug-log'><h3>Debugging Log:</h3><ul>$records</ul></div>$delete" : '';
|
354 |
}
|
355 |
}
|
356 |
|
357 |
+
/**
|
358 |
+
* Send a remote query expecting JSON.
|
359 |
+
*
|
360 |
+
* @param string $url Target URL.
|
361 |
+
* @param array $array Arguments if not default.
|
362 |
+
* @param string $method Query method.
|
363 |
+
* @throws Exception JSON error string.
|
364 |
+
*
|
365 |
+
* @return JSON object.
|
366 |
+
*/
|
367 |
function wpt_remote_json( $url, $array = true, $method = 'GET' ) {
|
368 |
$input = wpt_fetch_url( $url, $method );
|
369 |
wpt_mail( 'Remote JSON input', print_r( $input, 1 ) . "\n\n" . $url );
|
370 |
+
$obj = json_decode( $input, $array );
|
371 |
wpt_mail( 'Remote JSON return value', print_r( $obj, 1 ) . "\n\n" . "$url" );
|
372 |
+
if ( function_exists( 'json_last_error' ) ) { // > PHP 5.3.
|
373 |
try {
|
374 |
if ( is_null( $obj ) ) {
|
375 |
switch ( json_last_error() ) {
|
376 |
+
case JSON_ERROR_DEPTH:
|
377 |
$msg = ' - Maximum stack depth exceeded';
|
378 |
break;
|
379 |
+
case JSON_ERROR_STATE_MISMATCH:
|
380 |
$msg = ' - Underflow or the modes mismatch';
|
381 |
break;
|
382 |
+
case JSON_ERROR_CTRL_CHAR:
|
383 |
$msg = ' - Unexpected control character found';
|
384 |
break;
|
385 |
+
case JSON_ERROR_SYNTAX:
|
386 |
$msg = ' - Syntax error, malformed JSON';
|
387 |
break;
|
388 |
+
case JSON_ERROR_UTF8:
|
389 |
$msg = ' - Malformed UTF-8 characters, possibly incorrectly encoded';
|
390 |
break;
|
391 |
+
default:
|
392 |
$msg = ' - Unknown error';
|
393 |
break;
|
394 |
}
|
402 |
return $obj;
|
403 |
}
|
404 |
|
405 |
+
/**
|
406 |
+
* Test whether a URL is valid.
|
407 |
+
*
|
408 |
+
* @param string $url URL.
|
409 |
+
*
|
410 |
+
* @return URL if passes, false otherwise.
|
411 |
+
*/
|
412 |
function wpt_is_valid_url( $url ) {
|
413 |
if ( is_string( $url ) ) {
|
414 |
$url = urldecode( $url );
|
419 |
}
|
420 |
}
|
421 |
|
422 |
+
/**
|
423 |
+
* Fetch a remote page. Input url, return content
|
424 |
+
*
|
425 |
+
* @param string $url URL.
|
426 |
+
* @param string $method Method.
|
427 |
+
* @param string $body Body of query.
|
428 |
+
* @param string $headers Headers to add.
|
429 |
+
* @param string $return Array key from fetched object to return.
|
430 |
+
*
|
431 |
+
* @return value from query.
|
432 |
+
*/
|
433 |
function wpt_fetch_url( $url, $method = 'GET', $body = '', $headers = '', $return = 'body' ) {
|
434 |
$request = new WP_Http;
|
435 |
+
$result = $request->request( $url, array(
|
436 |
+
'method' => $method,
|
437 |
+
'body' => $body,
|
438 |
+
'headers' => $headers,
|
439 |
+
'sslverify' => false,
|
440 |
+
'user-agent' => 'WP to Twitter/http://www.joedolson.com/wp-to-twitter/',
|
441 |
+
) );
|
442 |
+
|
443 |
if ( ! is_wp_error( $result ) && isset( $result['body'] ) ) {
|
444 |
+
if ( 200 == $result['response']['code'] ) {
|
445 |
+
if ( 'body' == $return ) {
|
446 |
return $result['body'];
|
447 |
} else {
|
448 |
return $result;
|
450 |
} else {
|
451 |
return $result['response']['code'];
|
452 |
}
|
453 |
+
// Failure (server problem...).
|
454 |
} else {
|
455 |
return false;
|
456 |
}
|
457 |
}
|
458 |
|
459 |
if ( ! function_exists( 'mb_substr_split_unicode' ) ) {
|
460 |
+
/**
|
461 |
+
* Fall back function for mb_substr_split_unicode if doesn't exist.
|
462 |
+
*
|
463 |
+
* @param string $str String.
|
464 |
+
* @param int $split_pos Position to split on.
|
465 |
+
*
|
466 |
+
* @return split output.
|
467 |
+
*/
|
468 |
+
function mb_substr_split_unicode( $str, $split_pos ) {
|
469 |
+
if ( 0 == $split_pos ) {
|
470 |
return 0;
|
471 |
+
}
|
472 |
+
$byte_len = strlen( $str );
|
473 |
+
|
474 |
+
if ( $split_pos > 0 ) {
|
475 |
+
if ( $split_pos > 256 ) {
|
476 |
+
// Optimize large string offsets by skipping ahead N bytes.
|
477 |
+
// This will cut out most of our slow time on Latin-based text,
|
478 |
+
// and 1/2 to 1/3 on East European and Asian scripts.
|
479 |
+
$byte_pos = $split_pos;
|
480 |
+
while ( $byte_pos < $byte_len && $str[ $byte_pos ] >= "\x80" && $str[ $byte_pos ] < "\xc0" ) {
|
481 |
+
++$byte_pos;
|
482 |
+
}
|
483 |
+
$char_pos = mb_strlen( substr( $str, 0, $byte_pos ) );
|
484 |
+
} else {
|
485 |
+
$char_pos = 0;
|
486 |
+
$byte_pos = 0;
|
487 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
488 |
|
489 |
+
while ( $char_pos++ < $split_pos ) {
|
490 |
+
++$byte_pos;
|
491 |
+
// Move past any tail bytes.
|
492 |
+
while ( $byte_pos < $byte_len && $str[ $byte_pos ] >= "\x80" && $str[ $byte_pos ] < "\xc0" ) {
|
493 |
+
++$byte_pos;
|
494 |
+
}
|
495 |
+
}
|
496 |
+
} else {
|
497 |
+
$split_posx = $split_pos + 1;
|
498 |
+
$char_pos = 0; // relative to end of string; we don't care about the actual char position here.
|
499 |
+
$byte_pos = $byte_len;
|
500 |
+
while ( $byte_pos > 0 && $char_pos-- >= $split_posx ) {
|
501 |
+
--$byte_pos;
|
502 |
+
// Move past any tail bytes.
|
503 |
+
while ( $byte_pos > 0 && $str[ $byte_pos ] >= "\x80" && $str[ $byte_pos ] < "\xc0" ) {
|
504 |
+
--$byte_pos;
|
505 |
+
}
|
506 |
+
}
|
507 |
+
}
|
508 |
+
|
509 |
+
return $byte_pos;
|
510 |
}
|
511 |
}
|
512 |
|
514 |
/**
|
515 |
* Fallback implementation of mb_strrpos, hardcoded to UTF-8.
|
516 |
*
|
517 |
+
* @param string $haystack String.
|
518 |
+
* @param string $needle String.
|
519 |
+
* @param int $offset integer: optional start position.
|
520 |
*
|
521 |
* @return int
|
522 |
*/
|
526 |
$ar = array();
|
527 |
preg_match_all( '/' . $needle . '/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
|
528 |
|
529 |
+
if ( isset( $ar[0] ) && count( $ar[0] ) > 0 && isset( $ar[0][ count( $ar[0] ) - 1 ][1] ) ) {
|
|
|
|
|
530 |
return $ar[0][ count( $ar[0] ) - 1 ][1];
|
531 |
} else {
|
532 |
return false;
|
534 |
}
|
535 |
}
|
536 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
537 |
/**
|
538 |
* This function is obsolete; only exists for people using out of date versions of WP Tweets PRO.
|
539 |
+
*
|
540 |
+
* @param string $field Field to check.
|
541 |
+
* @param string $value Value to check.
|
542 |
+
* @param string $type Type of field.
|
543 |
+
*
|
544 |
+
* @return checked string.
|
545 |
*/
|
546 |
function wtt_option_selected( $field, $value, $type = 'checkbox' ) {
|
547 |
switch ( $type ) {
|
552 |
case 'option':
|
553 |
$result = ' selected="selected"';
|
554 |
break;
|
555 |
+
default:
|
556 |
+
$result = ' selected="selected"';
|
557 |
}
|
558 |
if ( $field == $value ) {
|
559 |
$output = $result;
|
566 |
|
567 |
/**
|
568 |
* Compares two dates to identify which is earlier. Used to differentiate between post edits and original publication.
|
569 |
+
*
|
570 |
+
* @param string $modified Date this post was modified.
|
571 |
+
* @param string $postdate Date this post was published.
|
572 |
+
*
|
573 |
* @return integer 1|0
|
574 |
+
*/
|
575 |
function wpt_date_compare( $modified, $postdate ) {
|
576 |
$modifier = apply_filters( 'wpt_edit_sensitivity', 0 ); // alter time in seconds to modified date.
|
577 |
+
$mod_date = strtotime( $modified );
|
578 |
+
$post_date = strtotime( $postdate ) + $modifier;
|
579 |
+
if ( $mod_date <= $post_date ) { // if post_modified is before or equal to post_date.
|
580 |
return 1;
|
581 |
} else {
|
582 |
return 0;
|
586 |
/**
|
587 |
* Gets the first attachment for the supplied post.
|
588 |
*
|
589 |
+
* @param integer $post_ID The post ID.
|
590 |
*
|
591 |
* @return mixed boolean|integer Attachment ID.
|
592 |
*/
|
593 |
function wpt_post_attachment( $post_ID ) {
|
594 |
+
$return = false;
|
595 |
$use_featured_image = apply_filters( 'wpt_use_featured_image', true, $post_ID );
|
596 |
if ( has_post_thumbnail( $post_ID ) && $use_featured_image ) {
|
597 |
$attachment = get_post_thumbnail_id( $post_ID );
|
604 |
'post_status' => 'published',
|
605 |
'post_parent' => $post_ID,
|
606 |
'post_mime_type' => 'image',
|
607 |
+
'order' => 'ASC',
|
608 |
);
|
609 |
$attachments = get_posts( $args );
|
610 |
if ( $attachments ) {
|
611 |
+
$return = $attachments[0]->ID; // Return the first attachment.
|
612 |
} else {
|
613 |
$return = false;
|
614 |
}
|
615 |
}
|
616 |
+
|
617 |
return apply_filters( 'wpt_post_attachment', $return, $post_ID );
|
618 |
}
|
619 |
|
620 |
+
/**
|
621 |
+
* Show support form. Note: text in the message body should not be translatable.
|
622 |
+
*/
|
623 |
function wpt_get_support_form() {
|
624 |
global $current_user, $wpt_version;
|
625 |
+
$current_user = wp_get_current_user();
|
626 |
+
$request = '';
|
627 |
$response_email = '';
|
628 |
+
// send fields for WP to Twitter.
|
629 |
+
$license = ( '' != get_option( 'wpt_license_key' ) ) ? get_option( 'wpt_license_key' ) : 'none';
|
630 |
+
if ( 'none' != $license ) {
|
631 |
+
$valid = ( ( 'true' == get_option( 'wpt_license_valid' ) ) || ( 'active' == get_option( 'wpt_license_valid' ) ) || ( 'valid' == get_option( 'wpt_license_valid' ) ) ) ? ' (active)' : ' (inactive)';
|
632 |
} else {
|
633 |
$valid = '';
|
634 |
}
|
635 |
+
$license = 'License Key: ' . $license . $valid;
|
636 |
|
637 |
$version = $wpt_version;
|
638 |
$wtt_twitter_username = get_option( 'wtt_twitter_username' );
|
639 |
+
// send fields for all plugins.
|
640 |
$wp_version = get_bloginfo( 'version' );
|
641 |
$home_url = home_url();
|
642 |
$wp_url = site_url();
|
643 |
$language = get_bloginfo( 'language' );
|
644 |
$charset = get_bloginfo( 'charset' );
|
645 |
+
// server.
|
646 |
$php_version = phpversion();
|
647 |
|
648 |
+
// theme data.
|
649 |
$theme = wp_get_theme();
|
650 |
+
$theme_name = $theme->get( 'Name' );
|
651 |
+
$theme_uri = $theme->get( 'ThemeURI' );
|
652 |
+
$theme_parent = $theme->get( 'Template' );
|
653 |
+
$theme_version = $theme->get( 'Version' );
|
654 |
|
655 |
$admin_email = get_option( 'admin_email' );
|
656 |
+
// plugin data.
|
657 |
$plugins = get_plugins();
|
658 |
$plugins_string = '';
|
659 |
foreach ( array_keys( $plugins ) as $key ) {
|
660 |
if ( is_plugin_active( $key ) ) {
|
661 |
+
$plugin =& $plugins[ $key ];
|
662 |
+
$plugin_name = $plugin['Name'];
|
663 |
+
$plugin_uri = $plugin['PluginURI'];
|
664 |
+
$plugin_version = $plugin['Version'];
|
665 |
$plugins_string .= "$plugin_name: $plugin_version; $plugin_uri\n";
|
666 |
}
|
667 |
}
|
668 |
|
669 |
+
$data = "
|
670 |
================ Installation Data ====================
|
671 |
==WP to Twitter==
|
672 |
Version: $version
|
699 |
if ( isset( $_POST['wpt_support'] ) ) {
|
700 |
$nonce = $_REQUEST['_wpnonce'];
|
701 |
if ( ! wp_verify_nonce( $nonce, 'wp-to-twitter-nonce' ) ) {
|
702 |
+
die( 'Security check failed' );
|
703 |
}
|
704 |
$request = ( ! empty( $_POST['support_request'] ) ) ? stripslashes( $_POST['support_request'] ) : false;
|
705 |
+
$has_donated = ( isset( $_POST['has_donated'] ) ) ? 'Donor' : 'No donation';
|
706 |
+
$has_read_faq = ( isset( $_POST['has_read_faq'] ) ) ? 'Read FAQ' : false;
|
707 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() ) {
|
708 |
+
$pro = ' PRO';
|
709 |
} else {
|
710 |
$pro = '';
|
711 |
}
|
712 |
$subject = "WP to Twitter$pro support request. $has_donated";
|
713 |
$message = $request . "\n\n" . $data;
|
714 |
+
// Get the site domain and get rid of www. from pluggable.php.
|
715 |
$sitename = strtolower( $_SERVER['SERVER_NAME'] );
|
716 |
+
if ( 'www.' == substr( $sitename, 0, 4 ) ) {
|
717 |
$sitename = substr( $sitename, 4 );
|
718 |
}
|
719 |
$response_email = ( isset( $_POST['response_email'] ) ) ? $_POST['response_email'] : false;
|
720 |
+
$from_email = 'wordpress@' . $sitename;
|
721 |
+
$from = "From: \"$current_user->display_name\" <$response_email>\r\nReply-to: \"$current_user->display_name\" <$response_email>\r\n";
|
722 |
|
723 |
if ( ! $has_read_faq ) {
|
724 |
+
echo "<div class='notice error'><p>" . __( 'Please read the FAQ and other Help documents before making a support request.', 'wp-to-twitter' ) . '</p></div>';
|
725 |
+
} elseif ( ! $response_email ) {
|
726 |
+
echo "<div class='notice error'><p>" . __( 'Please supply a valid email where you can receive support responses.', 'wp-to-twitter' ) . '</p></div>';
|
727 |
+
} elseif ( ! $request ) {
|
728 |
+
echo "<div class='notice error'><p>" . __( 'Please describe your problem. I\'m not psychic.', 'wp-to-twitter' ) . '</p></div>';
|
729 |
} else {
|
730 |
+
$sent = wp_mail( 'plugins@joedolson.com', $subject, $message, $from );
|
731 |
if ( $sent ) {
|
732 |
+
if ( 'Donor' == $has_donated ) {
|
733 |
+
// Translators: Email address.
|
734 |
+
echo "<div class='notice updated'><p>" . sprintf( __( 'Thank you for supporting WP to Twitter! I\'ll get back to you as soon as I can. Please make sure you can receive email at <code>%s</code>.', 'wp-to-twitter' ), $response_email ) . '</p></div>';
|
735 |
} else {
|
736 |
+
// Translators: Email address.
|
737 |
+
echo "<div class='notice updated'><p>" . sprintf( __( 'Thanks for using WP to Twitter. Please ensure that you can receive email at <code>%s</code>.', 'wp-to-twitter' ), $response_email ) . '</p></div>';
|
738 |
}
|
739 |
} else {
|
740 |
+
// Translators: URL to plugin support form.
|
741 |
+
echo "<div class='notice error'><p>" . __( "Sorry! I couldn't send that message. Here's the text of your request:", 'wp-to-twitter' ) . '</p><p>' . sprintf( __( '<a href="%s">Contact me here</a>, instead.', 'wp-to-twitter' ), 'https://www.joedolson.com/contact/get-support/' ) . "</p><pre>$request</pre></div>";
|
742 |
}
|
743 |
}
|
744 |
}
|
745 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() ) {
|
746 |
+
$checked = 'checked="checked"';
|
747 |
} else {
|
748 |
$checked = '';
|
749 |
}
|
750 |
$admin_url = admin_url( 'admin.php?page=wp-tweets-pro' );
|
751 |
$admin_url = add_query_arg( 'tab', 'support', $admin_url );
|
752 |
+
|
753 |
echo "
|
754 |
<form method='post' action='$admin_url'>
|
755 |
<div><input type='hidden' name='_wpnonce' value='" . wp_create_nonce( 'wp-to-twitter-nonce' ) . "' /></div>
|
756 |
<div>
|
757 |
+
<p>" . __( "If you're having trouble with WP to Twitter, please try to answer these questions in your message:", 'wp-to-twitter' ) . '</p>
|
|
|
|
|
758 |
<ul>
|
759 |
+
<li>' . __( 'What were you doing when the problem occurred?', 'wp-to-twitter' ) . '</li>
|
760 |
+
<li>' . __( 'What did you expect to happen?', 'wp-to-twitter' ) . '</li>
|
761 |
+
<li>' . __( 'What happened instead?', 'wp-to-twitter' ) . "</li>
|
762 |
</ul>
|
763 |
<p>
|
764 |
<label for='response_email'>" . __( 'Your Email', 'wp-to-twitter' ) . "</label><br />
|
765 |
<input type='email' name='response_email' id='response_email' value='$response_email' class='widefat' required='required' aria-required='true' />
|
766 |
</p>
|
767 |
<p>
|
768 |
+
<input type='checkbox' name='has_read_faq' id='has_read_faq' value='on' required='required' aria-required='true' /> <label for='has_read_faq'>";
|
769 |
+
// Translators: Link to plugin FAQ.
|
770 |
+
echo sprintf( __( 'I have read <a href="%1$s">the FAQ for this plug-in</a> <span>(required)</span>', 'wp-to-twitter' ), 'http://www.joedolson.com/wp-to-twitter/support-2/' );
|
771 |
+
echo "</p>
|
772 |
+
<p>
|
773 |
+
<input type='checkbox' name='has_donated' id='has_donated' value='on' $checked /> <label for='has_donated'>" . __( 'I made a donation or purchase to help support this plug-in', 'wp-to-twitter' ) . "</label>
|
774 |
+
</p>
|
775 |
+
<p>
|
776 |
+
<label for='support_request'>" . __( 'Support Request:', 'wp-to-twitter' ) . "</label><br /><textarea class='support-request' name='support_request' id='support_request' cols='80' rows='10' class='widefat'>" . stripslashes( esc_attr( $request ) ) . "</textarea>
|
777 |
</p>
|
778 |
<p>
|
779 |
<input type='submit' value='" . __( 'Send Support Request', 'wp-to-twitter' ) . "' name='wpt_support' class='button-primary' />
|
780 |
</p>
|
781 |
<p>" .
|
782 |
+
__( 'The following additional information will be sent with your support request:', 'wp-to-twitter' )
|
783 |
+
. "</p>
|
784 |
<div class='mc_support'>
|
785 |
+
" . wpautop( $data ) . '
|
786 |
</div>
|
787 |
</div>
|
788 |
+
</form>';
|
789 |
}
|
790 |
|
791 |
+
/**
|
792 |
+
* Check whether a file is writable.
|
793 |
+
*
|
794 |
+
* @param string $file Filename/path.
|
795 |
+
*
|
796 |
+
* @return boolean.
|
797 |
+
*/
|
798 |
function wpt_is_writable( $file ) {
|
799 |
if ( function_exists( 'wp_is_writable' ) ) {
|
800 |
$is_writable = wp_is_writable( $file );
|
805 |
return $is_writable;
|
806 |
}
|
807 |
|
808 |
+
add_action( 'load-post.php', 'wpt_migrate_url_meta' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
809 |
/**
|
810 |
* Migrates post meta to new format when post is called in editor.
|
811 |
*/
|
|
|
812 |
function wpt_migrate_url_meta() {
|
813 |
$post_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : false;
|
814 |
+
if ( ! $post_id ) {
|
815 |
+
// if this is a new post screen, no migration.
|
816 |
return;
|
817 |
}
|
818 |
+
|
819 |
$post = get_post( $post_id );
|
820 |
if ( strtotime( $post->post_date ) > 1449764285 ) {
|
821 |
// if this post was added after the migration function was added, it will not need to be migrated. Guaranteed.
|
822 |
return;
|
823 |
}
|
824 |
+
|
825 |
+
$short = wpt_short_url( $post_id );
|
826 |
+
if ( '' != $short ) {
|
827 |
+
return;
|
828 |
}
|
829 |
+
if ( '' == $short ) {
|
830 |
$short = get_post_meta( $post_id, '_wp_jd_goo', true );
|
831 |
delete_post_meta( $post_id, '_wp_jd_goo' );
|
832 |
}
|
833 |
+
if ( '' == $short ) {
|
834 |
$short = get_post_meta( $post_id, '_wp_jd_supr', true );
|
835 |
delete_post_meta( $post_id, '_wp_jd_supr' );
|
836 |
}
|
837 |
+
if ( '' == $short ) {
|
838 |
$short = get_post_meta( $post_id, '_wp_jd_wp', true );
|
839 |
delete_post_meta( $post_id, '_wp_jd_wp' );
|
840 |
}
|
841 |
+
if ( '' == $short ) {
|
842 |
$short = get_post_meta( $post_id, '_wp_jd_ind', true );
|
843 |
delete_post_meta( $post_id, '_wp_jd_ind' );
|
844 |
}
|
845 |
+
if ( '' == $short ) {
|
846 |
$short = get_post_meta( $post_id, '_wp_jd_yourls', true );
|
847 |
delete_post_meta( $post_id, '_wp_jd_yourls' );
|
848 |
}
|
849 |
+
if ( '' == $short ) {
|
850 |
$short = get_post_meta( $post_id, '_wp_jd_url', true );
|
851 |
delete_post_meta( $post_id, '_wp_jd_url' );
|
852 |
}
|
853 |
+
if ( '' == $short ) {
|
854 |
$short = get_post_meta( $post_id, '_wp_jd_joturl', true );
|
855 |
delete_post_meta( $post_id, '_wp_jd_joturl' );
|
856 |
}
|
857 |
+
if ( '' == $short ) {
|
858 |
+
// don't delete target link.
|
859 |
$short = get_post_meta( $post_id, '_wp_jd_target', true );
|
860 |
}
|
861 |
+
if ( '' == $short ) {
|
862 |
$short = get_post_meta( $post_id, '_wp_jd_clig', true );
|
863 |
delete_post_meta( $post_id, '_wp_jd_clig' );
|
864 |
}
|
865 |
+
|
866 |
+
if ( '' != $short ) {
|
867 |
+
update_post_meta( $post_id, '_wpt_short_url', $short );
|
868 |
}
|
|
|
|
|
869 |
}
|
870 |
|
871 |
+
/**
|
872 |
+
* Make a curl query.
|
873 |
+
*
|
874 |
+
* @param string $url URL to query.
|
875 |
+
*
|
876 |
+
* @return Curl response.
|
877 |
+
*/
|
878 |
function wp_get_curl( $url ) {
|
879 |
+
|
880 |
$curl = curl_init( $url );
|
881 |
|
882 |
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
|
887 |
curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
|
888 |
|
889 |
$response = curl_exec( $curl );
|
890 |
+
if ( 0 !== curl_errno( $curl ) || 200 !== curl_getinfo( $curl, CURLINFO_HTTP_CODE ) ) {
|
891 |
$response = false;
|
892 |
+
} // end if.
|
893 |
curl_close( $curl );
|
894 |
|
895 |
return $response;
|
899 |
add_action( 'dp_duplicate_page', 'wpt_delete_copied_meta', 10, 2 );
|
900 |
/**
|
901 |
* Prevent 'Duplicate Posts' plug-in from copying WP to Twitter meta data
|
902 |
+
*
|
903 |
+
* @param int $new_id New post ID.
|
904 |
+
* @param object $post Old Post.
|
905 |
*/
|
906 |
function wpt_delete_copied_meta( $new_id, $post ) {
|
907 |
$disable = apply_filters( 'wpt_allow_copy_meta', false );
|
918 |
}
|
919 |
|
920 |
/**
|
921 |
+
* Provide aliases for changed function names if plug-ins or themes are calling WP to Twitter functions in custom code.
|
922 |
+
*
|
923 |
+
* @param string $url Query url.
|
924 |
+
* @param string $method Method.
|
925 |
+
* @param string $body Body.
|
926 |
+
* @param string $headers Headers.
|
927 |
+
* @param string $return Return data.
|
928 |
+
*
|
929 |
+
* @return data.
|
930 |
*/
|
931 |
function jd_fetch_url( $url, $method = 'GET', $body = '', $headers = '', $return = 'body' ) {
|
932 |
return wpt_fetch_url( $url, $method, $body, $headers, $return );
|
933 |
}
|
934 |
|
935 |
+
/**
|
936 |
+
* Alias for remote_json.
|
937 |
+
*
|
938 |
+
* @param string $url Query url.
|
939 |
+
* @param array $array Arguments.
|
940 |
+
*
|
941 |
+
* @return remote JSON.
|
942 |
+
*/
|
943 |
function jd_remote_json( $url, $array = true ) {
|
944 |
return wpt_remote_json( $url, $array );
|
945 |
}
|
946 |
|
947 |
+
/**
|
948 |
+
* Send a Tweet for a new link.
|
949 |
+
*
|
950 |
+
* @param int $link_id Link ID.
|
951 |
+
*
|
952 |
+
* @return twit link.
|
953 |
+
*/
|
954 |
+
function jd_twit_link( $link_id ) {
|
955 |
+
return wpt_twit_link( $link_id );
|
956 |
}
|
957 |
|
958 |
+
/**
|
959 |
+
* Get post data.
|
960 |
+
*
|
961 |
+
* @param int $post_ID Post ID.
|
962 |
+
*
|
963 |
+
* @return Array post data.
|
964 |
+
*/
|
965 |
function jd_post_info( $post_ID ) {
|
966 |
return wpt_post_info( $post_ID );
|
967 |
}
|
968 |
|
969 |
+
/**
|
970 |
+
* Sent post tweet.
|
971 |
+
*
|
972 |
+
* @param int $post_ID Post ID.
|
973 |
+
* @param string $type Type of post.
|
974 |
+
*
|
975 |
+
* @return tweet
|
976 |
+
*/
|
977 |
function jd_twit( $post_ID, $type = 'instant' ) {
|
978 |
return wpt_tweet( $post_ID, $type );
|
979 |
}
|
980 |
|
981 |
+
/**
|
982 |
+
* Set up admin styles.
|
983 |
+
*/
|
984 |
function jd_addTwitterAdminStyles() {
|
985 |
return wpt_admin_style();
|
986 |
}
|
987 |
|
988 |
+
/**
|
989 |
+
* Send to Twitter API. Fallback; deprecated.
|
990 |
+
*
|
991 |
+
* @param string $twit Tweet.
|
992 |
+
* @param mixed boolean/int $auth Author ID.
|
993 |
+
* @param int $id Post ID.
|
994 |
+
* @param boolean $media Include media.
|
995 |
+
*
|
996 |
+
* @deprecated 1/19/2017
|
997 |
+
*
|
998 |
+
* @return boolean.
|
999 |
+
*/
|
1000 |
function jd_doTwitterAPIPost( $twit, $auth = false, $id = false, $media = false ) {
|
1001 |
return wpt_post_to_twitter( $twit, $auth, $id, $media );
|
1002 |
+
}
|
1003 |
+
|
1004 |
+
/**
|
1005 |
+
* Update oauth settings.
|
1006 |
+
*
|
1007 |
+
* @param mixed boolean/int $auth Author ID.
|
1008 |
+
* @param mixed boolean/array $post POST data.
|
1009 |
+
*
|
1010 |
+
* @return update.
|
1011 |
+
*/
|
1012 |
+
function jd_update_oauth_settings( $auth = false, $post = false ) {
|
1013 |
+
return wpt_update_oauth_settings( $auth, $post );
|
1014 |
+
}
|
wpt-rate-limiting.php
CHANGED
@@ -1,13 +1,22 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
exit;
|
4 |
-
}
|
5 |
-
|
6 |
|
|
|
7 |
/**
|
8 |
* Hourly cron job to reset rate limits
|
9 |
*/
|
10 |
-
add_action( 'wptratelimits', 'wpt_clear_rate_limits' );
|
11 |
function wpt_clear_rate_limits() {
|
12 |
delete_option( 'wpt_rate_limits' );
|
13 |
}
|
@@ -15,105 +24,112 @@ function wpt_clear_rate_limits() {
|
|
15 |
/**
|
16 |
* Logs successful Tweets for rate limiting.
|
17 |
*
|
18 |
-
* @param $
|
|
|
|
|
19 |
*/
|
20 |
function wpt_log_success( $auth, $ts, $post_ID ) {
|
21 |
-
if (
|
22 |
-
|
23 |
-
|
|
|
|
|
24 |
$rate_limit = get_option( 'wpt_rate_limits' );
|
25 |
if ( ! is_array( $rate_limit ) ) {
|
26 |
$rate_limit = array();
|
27 |
}
|
28 |
-
$post
|
29 |
-
$post_type
|
30 |
$object_taxonomies = get_object_taxonomies( $post_type );
|
31 |
-
$terms
|
32 |
-
|
33 |
-
foreach( $terms as $term ) {
|
34 |
$term_id = $term->term_id;
|
35 |
-
$tax
|
36 |
-
|
37 |
-
$rate_limit[$auth][$term_id.'+'
|
38 |
}
|
39 |
-
|
40 |
update_option( 'wpt_rate_limits', $rate_limit );
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
* Test Tweets against rate limiting rules.
|
45 |
*
|
46 |
-
* @param $post_ID Post ID
|
|
|
47 |
*
|
48 |
* @return boolean True if OK to Tweet.
|
49 |
*/
|
50 |
function wpt_test_rate_limit( $post_ID, $auth ) {
|
51 |
-
// record of recent Tweets
|
52 |
$rate_limit = get_option( 'wpt_rate_limits' );
|
53 |
-
$return
|
54 |
-
if (
|
55 |
return true;
|
56 |
} else {
|
57 |
$post = get_post( $post_ID );
|
58 |
if ( is_object( $post ) ) {
|
59 |
-
$post_type
|
60 |
$object_taxonomies = get_object_taxonomies( $post_type );
|
61 |
-
$terms
|
62 |
-
|
63 |
-
foreach( $terms as $term ) {
|
64 |
$term_id = $term->term_id;
|
65 |
-
$limit
|
66 |
-
$tax
|
67 |
-
$count
|
68 |
if ( $count && $count >= $limit ) {
|
69 |
$return = false;
|
70 |
}
|
71 |
}
|
72 |
} else {
|
73 |
-
// don't rate limit if no post
|
74 |
$return = true;
|
75 |
}
|
76 |
}
|
77 |
-
|
78 |
return $return;
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
* Default rate limiting value. Limit can't be 0.
|
83 |
*
|
84 |
-
* @param $term Term ID
|
85 |
*
|
86 |
* @return integer Default rate limit
|
87 |
*/
|
88 |
function wpt_default_rate_limit( $term = false ) {
|
89 |
-
$limit = ( get_option( 'wpt_default_rate_limit' )
|
90 |
-
$limit = (
|
91 |
-
|
92 |
-
return apply_filters( 'wpt_default_rate_limit', $limit, $term );
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
-
* Get the current rate limit for a given term ID.
|
97 |
*
|
98 |
-
* @param $term Term ID
|
99 |
-
*
|
100 |
* @uses filter wpt_default_rate_limit
|
101 |
*
|
102 |
* @return integer Number of Tweets allowed per hour in this category.
|
103 |
*/
|
104 |
function wpt_get_rate_limit( $term ) {
|
105 |
$limits = get_option( 'wpt_rate_limit' );
|
106 |
-
$limit
|
107 |
-
if ( !is_int( $limit ) ) {
|
108 |
$limit = wpt_default_rate_limit( $term );
|
109 |
}
|
110 |
-
|
111 |
return $limit;
|
112 |
}
|
113 |
|
114 |
add_action( 'init', 'wpt_term_rate_limits' );
|
|
|
|
|
|
|
115 |
function wpt_term_rate_limits() {
|
116 |
-
$args
|
117 |
$taxonomies = get_taxonomies( $args );
|
118 |
if ( ! is_array( $taxonomies ) ) {
|
119 |
$taxonomies = array();
|
@@ -121,76 +137,96 @@ function wpt_term_rate_limits() {
|
|
121 |
foreach ( $taxonomies as $value ) {
|
122 |
add_action( $value . '_add_form_fields', 'wpt_add_term_rate_limit', 10, 1 );
|
123 |
add_action( $value . '_edit_form_fields', 'wpt_edit_term_rate_limit', 10, 2 );
|
124 |
-
add_action( 'edit_'
|
125 |
-
add_action( 'created_'
|
126 |
}
|
127 |
}
|
128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
function wpt_save_term_rate_limit( $term_id, $tax_id ) {
|
130 |
-
$limits
|
131 |
$option_set = isset( $_POST['wpt_rate_limit'] ) ? $_POST['wpt_rate_limit'] : wpt_default_rate_limit( $term_id );
|
132 |
if ( isset( $_POST['taxonomy'] ) ) {
|
133 |
-
if ( isset( $_POST['wpt_rate_limit'] )
|
134 |
-
$limits[$term_id] = $option_set;
|
135 |
update_option( 'wpt_rate_limit', $limits );
|
136 |
-
}
|
137 |
}
|
138 |
}
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
function wpt_edit_term_rate_limit( $term, $taxonomy ) {
|
141 |
-
$t_id
|
142 |
-
$limits
|
143 |
-
$option_set = isset( $limits[$t_id] ) ? $limits[$t_id] : wpt_default_rate_limit( $t_id );
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
}
|
155 |
|
|
|
|
|
|
|
|
|
|
|
156 |
function wpt_add_term_rate_limit( $term ) {
|
157 |
$default = wpt_default_rate_limit();
|
158 |
?>
|
159 |
-
|
160 |
-
<label for="wpt_rate_limit"><?php _e( 'Max Tweets per hour on this term','wp-tweets-pro' ); ?></label> <input type='number' value='<?php echo esc_attr( $default ); ?>' id='wpt_rate_limit' name='wpt_rate_limit' />
|
161 |
</div>
|
162 |
-
|
163 |
}
|
164 |
|
|
|
|
|
|
|
|
|
|
|
165 |
function wpt_view_rate_limits() {
|
166 |
$limits = get_option( 'wpt_rate_limits' );
|
167 |
if ( is_array( $limits ) ) {
|
168 |
-
|
169 |
$output = '<ul>';
|
170 |
-
foreach( $limits as $auth => $term ) {
|
171 |
-
$author
|
172 |
$output .= "<li><h4><a href='https://twitter.com/$author'>@$author</a>:</h4><ul>";
|
173 |
foreach ( $term as $id => $value ) {
|
174 |
-
$count
|
175 |
-
$term_array
|
176 |
-
$t
|
177 |
-
$x
|
178 |
-
$limit
|
179 |
-
$term_object
|
180 |
-
$term_label
|
181 |
$rate_limiting = ( $count >= $limit ) ? 'rate-limited' : 'active';
|
182 |
-
$dashicon
|
183 |
-
$output
|
184 |
-
|
185 |
-
|
186 |
}
|
187 |
-
$output .=
|
188 |
}
|
189 |
-
$output .=
|
190 |
-
|
191 |
} else {
|
192 |
$output = __( 'No Tweets have been sent this hour.', 'wp-to-twitter' );
|
193 |
}
|
194 |
-
|
195 |
return $output;
|
196 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Rate limiting in WP to Twitter
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
|
|
15 |
|
16 |
+
add_action( 'wptratelimits', 'wpt_clear_rate_limits' );
|
17 |
/**
|
18 |
* Hourly cron job to reset rate limits
|
19 |
*/
|
|
|
20 |
function wpt_clear_rate_limits() {
|
21 |
delete_option( 'wpt_rate_limits' );
|
22 |
}
|
24 |
/**
|
25 |
* Logs successful Tweets for rate limiting.
|
26 |
*
|
27 |
+
* @param int $auth Author.
|
28 |
+
* @param string $ts Timestamp.
|
29 |
+
* @param int $post_ID Post ID.
|
30 |
*/
|
31 |
function wpt_log_success( $auth, $ts, $post_ID ) {
|
32 |
+
if ( ! $post_ID ) {
|
33 |
+
return;
|
34 |
+
}
|
35 |
+
|
36 |
+
// get record of recent Tweets.
|
37 |
$rate_limit = get_option( 'wpt_rate_limits' );
|
38 |
if ( ! is_array( $rate_limit ) ) {
|
39 |
$rate_limit = array();
|
40 |
}
|
41 |
+
$post = get_post( $post_ID );
|
42 |
+
$post_type = $post->post_type;
|
43 |
$object_taxonomies = get_object_taxonomies( $post_type );
|
44 |
+
$terms = wp_get_object_terms( $post_ID, $object_taxonomies, array( 'fields' => 'all' ) );
|
45 |
+
|
46 |
+
foreach ( $terms as $term ) {
|
47 |
$term_id = $term->term_id;
|
48 |
+
$tax = $term->taxonomy;
|
49 |
+
|
50 |
+
$rate_limit[ $auth ][ $term_id . '+' . $tax ][] = $post_ID;
|
51 |
}
|
52 |
+
|
53 |
update_option( 'wpt_rate_limits', $rate_limit );
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
* Test Tweets against rate limiting rules.
|
58 |
*
|
59 |
+
* @param int $post_ID Post ID.
|
60 |
+
* @param int $auth Author ID.
|
61 |
*
|
62 |
* @return boolean True if OK to Tweet.
|
63 |
*/
|
64 |
function wpt_test_rate_limit( $post_ID, $auth ) {
|
65 |
+
// record of recent Tweets.
|
66 |
$rate_limit = get_option( 'wpt_rate_limits' );
|
67 |
+
$return = true;
|
68 |
+
if ( ! $rate_limit ) {
|
69 |
return true;
|
70 |
} else {
|
71 |
$post = get_post( $post_ID );
|
72 |
if ( is_object( $post ) ) {
|
73 |
+
$post_type = $post->post_type;
|
74 |
$object_taxonomies = get_object_taxonomies( $post_type );
|
75 |
+
$terms = wp_get_object_terms( $post_ID, $object_taxonomies, array( 'fields' => 'all' ) );
|
76 |
+
|
77 |
+
foreach ( $terms as $term ) {
|
78 |
$term_id = $term->term_id;
|
79 |
+
$limit = wpt_get_rate_limit( $term_id );
|
80 |
+
$tax = $term->taxonomy;
|
81 |
+
$count = ( isset( $rate_limit[ $auth ][ $term_id . '+' . $tax ] ) ) ? count( $rate_limit[ $auth ][ $term_id . '+' . $tax ] ) : false;
|
82 |
if ( $count && $count >= $limit ) {
|
83 |
$return = false;
|
84 |
}
|
85 |
}
|
86 |
} else {
|
87 |
+
// don't rate limit if no post.
|
88 |
$return = true;
|
89 |
}
|
90 |
}
|
91 |
+
|
92 |
return $return;
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
* Default rate limiting value. Limit can't be 0.
|
97 |
*
|
98 |
+
* @param int $term Term ID.
|
99 |
*
|
100 |
* @return integer Default rate limit
|
101 |
*/
|
102 |
function wpt_default_rate_limit( $term = false ) {
|
103 |
+
$limit = ( '' != get_option( 'wpt_default_rate_limit' ) ) ? get_option( 'wpt_default_rate_limit' ) : 10;
|
104 |
+
$limit = ( 0 == $limit ) ? 1 : $limit;
|
105 |
+
|
106 |
+
return apply_filters( 'wpt_default_rate_limit', $limit, $term );
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
+
* Get the current rate limit for a given term ID.
|
111 |
*
|
112 |
+
* @param string $term Term ID.
|
|
|
113 |
* @uses filter wpt_default_rate_limit
|
114 |
*
|
115 |
* @return integer Number of Tweets allowed per hour in this category.
|
116 |
*/
|
117 |
function wpt_get_rate_limit( $term ) {
|
118 |
$limits = get_option( 'wpt_rate_limit' );
|
119 |
+
$limit = isset( $limits[ $term ] ) ? $limits[ $term ] : wpt_default_rate_limit( $term );
|
120 |
+
if ( ! is_int( $limit ) ) {
|
121 |
$limit = wpt_default_rate_limit( $term );
|
122 |
}
|
123 |
+
|
124 |
return $limit;
|
125 |
}
|
126 |
|
127 |
add_action( 'init', 'wpt_term_rate_limits' );
|
128 |
+
/**
|
129 |
+
* Get term-based rate limits.
|
130 |
+
*/
|
131 |
function wpt_term_rate_limits() {
|
132 |
+
$args = apply_filters( 'wpt_rate_limit_taxonomies', array() );
|
133 |
$taxonomies = get_taxonomies( $args );
|
134 |
if ( ! is_array( $taxonomies ) ) {
|
135 |
$taxonomies = array();
|
137 |
foreach ( $taxonomies as $value ) {
|
138 |
add_action( $value . '_add_form_fields', 'wpt_add_term_rate_limit', 10, 1 );
|
139 |
add_action( $value . '_edit_form_fields', 'wpt_edit_term_rate_limit', 10, 2 );
|
140 |
+
add_action( 'edit_' . $value, 'wpt_save_term_rate_limit', 10, 2 );
|
141 |
+
add_action( 'created_' . $value, 'wpt_save_term_rate_limit', 10, 2 );
|
142 |
}
|
143 |
}
|
144 |
|
145 |
+
/**
|
146 |
+
* Save rate limit for a term.
|
147 |
+
*
|
148 |
+
* @param int $term_id Term ID.
|
149 |
+
* @param int $tax_id Taxonomy ID.
|
150 |
+
*/
|
151 |
function wpt_save_term_rate_limit( $term_id, $tax_id ) {
|
152 |
+
$limits = get_option( 'wpt_rate_limit' );
|
153 |
$option_set = isset( $_POST['wpt_rate_limit'] ) ? $_POST['wpt_rate_limit'] : wpt_default_rate_limit( $term_id );
|
154 |
if ( isset( $_POST['taxonomy'] ) ) {
|
155 |
+
if ( isset( $_POST['wpt_rate_limit'] ) ) {
|
156 |
+
$limits[ $term_id ] = $option_set;
|
157 |
update_option( 'wpt_rate_limit', $limits );
|
158 |
+
}
|
159 |
}
|
160 |
}
|
161 |
|
162 |
+
/**
|
163 |
+
* Edit term rate limits.
|
164 |
+
*
|
165 |
+
* @param object $term Term object.
|
166 |
+
* @param object $taxonomy Taxonomy object.
|
167 |
+
*/
|
168 |
function wpt_edit_term_rate_limit( $term, $taxonomy ) {
|
169 |
+
$t_id = $term->term_id;
|
170 |
+
$limits = get_option( 'wpt_rate_limit' );
|
171 |
+
$option_set = isset( $limits[ $t_id ] ) ? $limits[ $t_id ] : wpt_default_rate_limit( $t_id );
|
172 |
+
?>
|
173 |
+
<tr class="form-field">
|
174 |
+
<th valign="top" scope="row">
|
175 |
+
<label for="wpt_rate_limit"><?php _e( 'Max Tweets per hour on this term', 'wp-tweets-pro' ); ?></label>
|
176 |
+
</th>
|
177 |
+
<td>
|
178 |
+
<input type='number' size='4' value='<?php echo esc_attr( $option_set ); ?>' name='wpt_rate_limit' id='wpt_rate_limit' />
|
179 |
+
</td>
|
180 |
+
</tr>
|
181 |
+
<?php
|
182 |
}
|
183 |
|
184 |
+
/**
|
185 |
+
* Add a rate limit for a given term.
|
186 |
+
*
|
187 |
+
* @param object $term Term Object.
|
188 |
+
*/
|
189 |
function wpt_add_term_rate_limit( $term ) {
|
190 |
$default = wpt_default_rate_limit();
|
191 |
?>
|
192 |
+
<div class="form-field">
|
193 |
+
<label for="wpt_rate_limit"><?php _e( 'Max Tweets per hour on this term', 'wp-tweets-pro' ); ?></label> <input type='number' value='<?php echo esc_attr( $default ); ?>' id='wpt_rate_limit' name='wpt_rate_limit' />
|
194 |
</div>
|
195 |
+
<?php
|
196 |
}
|
197 |
|
198 |
+
/**
|
199 |
+
* View rate limit status.
|
200 |
+
*
|
201 |
+
* @return string Rate limit info.
|
202 |
+
*/
|
203 |
function wpt_view_rate_limits() {
|
204 |
$limits = get_option( 'wpt_rate_limits' );
|
205 |
if ( is_array( $limits ) ) {
|
|
|
206 |
$output = '<ul>';
|
207 |
+
foreach ( $limits as $auth => $term ) {
|
208 |
+
$author = ( 0 == $auth ) ? get_option( 'wtt_twitter_username' ) : get_user_meta( $auth, 'wtt_twitter_username', true );
|
209 |
$output .= "<li><h4><a href='https://twitter.com/$author'>@$author</a>:</h4><ul>";
|
210 |
foreach ( $term as $id => $value ) {
|
211 |
+
$count = count( $value );
|
212 |
+
$term_array = explode( '+', $id );
|
213 |
+
$t = $term_array[0];
|
214 |
+
$x = $term_array[1];
|
215 |
+
$limit = wpt_get_rate_limit( $t );
|
216 |
+
$term_object = get_term( $t, $x );
|
217 |
+
$term_label = $term_object->name;
|
218 |
$rate_limiting = ( $count >= $limit ) ? 'rate-limited' : 'active';
|
219 |
+
$dashicon = ( $count >= $limit ) ? "<span class='dashicons dashicons-no' aria-hidden='true'></span>" : "<span class='dashicons dashicons-yes' aria-hidden='true'></span>";
|
220 |
+
$output .= "<li class='$rate_limiting'>$dashicon<strong>$term_label</strong>: ";
|
221 |
+
// Translators: Number of tweets sent, number allowed.
|
222 |
+
$output .= sprintf( _n( '%1$s Tweet sent, %2$s allowed.', '%1$s Tweets sent, %2$s allowed.', $count, 'wp-to-twitter' ), "<strong>$count</strong>", "<strong>$limit</strong>" ) . '</li>';
|
223 |
}
|
224 |
+
$output .= '</ul>';
|
225 |
}
|
226 |
+
$output .= '</ul>';
|
|
|
227 |
} else {
|
228 |
$output = __( 'No Tweets have been sent this hour.', 'wp-to-twitter' );
|
229 |
}
|
230 |
+
|
231 |
return $output;
|
232 |
+
}
|
wpt-truncate.php
CHANGED
@@ -1,58 +1,81 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
exit;
|
4 |
-
}
|
5 |
|
|
|
|
|
|
|
|
|
|
|
6 |
function wpt_max_length() {
|
7 |
-
$config
|
8 |
if ( ! $config ) {
|
9 |
-
$connection =
|
10 |
if ( $connection ) {
|
11 |
-
$config
|
12 |
-
set_transient( 'wpt_twitter_config', $config, 60*60*24 );
|
13 |
} else {
|
14 |
-
$config
|
15 |
-
'http_length'
|
16 |
-
'https_length'
|
17 |
-
'reserved_chars' => 24
|
18 |
) );
|
19 |
}
|
20 |
}
|
21 |
-
|
22 |
$decoded = json_decode( $config );
|
23 |
-
|
24 |
if ( is_object( $decoded ) && isset( $decoded->short_url_length ) ) {
|
25 |
$short_url_length = $decoded->short_url_length;
|
26 |
$short_url_https = $decoded->short_url_length_https;
|
27 |
$reserved_char = $decoded->characters_reserved_per_media;
|
28 |
-
$values
|
29 |
-
'http_length'
|
30 |
-
'https_length'
|
31 |
-
'reserved_chars' => $reserved_char
|
32 |
-
);
|
33 |
-
|
34 |
} else {
|
35 |
-
// if config query is invalid, use default values; these may become invalid
|
36 |
-
$values = array(
|
37 |
-
'http_length'
|
38 |
-
'https_length'
|
39 |
-
'reserved_chars' => 24
|
40 |
-
);
|
41 |
}
|
42 |
-
|
43 |
$values['base_length'] = intval( ( get_option( 'wpt_tweet_length' ) ) ? get_option( 'wpt_tweet_length' ) : 140 ) - 1;
|
44 |
-
|
45 |
-
return apply_filters( 'wpt_max_length', $values );
|
46 |
}
|
47 |
|
48 |
add_filter( 'wpt_tweet_sentence', 'wpt_filter_urls', 10, 2 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
function wpt_filter_urls( $tweet, $post_ID ) {
|
50 |
-
preg_match_all('#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#', $tweet, $match);
|
51 |
$title = get_the_title( $post_ID );
|
52 |
-
|
53 |
-
if ( isset( $match[0] ) && !empty( $match[0] ) ) {
|
54 |
$urls = $match[0];
|
55 |
-
foreach( $urls as $url ) {
|
56 |
if ( esc_url( $url ) ) {
|
57 |
$short = wpt_shorten_url( $url, $title, $post_ID, false, false );
|
58 |
if ( $short ) {
|
@@ -61,85 +84,90 @@ function wpt_filter_urls( $tweet, $post_ID ) {
|
|
61 |
}
|
62 |
}
|
63 |
}
|
64 |
-
|
65 |
return $tweet;
|
66 |
}
|
67 |
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
function jd_truncate_tweet( $tweet, $post, $post_ID, $retweet = false, $ref = false ) {
|
70 |
-
// media file no longer needs accounting in shortening. 9/22/2016
|
71 |
-
$maxlength
|
72 |
-
$length
|
73 |
-
$tweet
|
74 |
-
$tweet
|
75 |
-
$tweet
|
76 |
-
$encoding
|
77 |
-
$diff
|
78 |
-
|
79 |
-
// Add custom append/prepend fields to Tweet text
|
80 |
-
if ( get_option( 'jd_twit_prepend' )
|
81 |
-
$tweet = stripslashes( get_option( 'jd_twit_prepend' ) ) .
|
|
|
|
|
|
|
82 |
}
|
83 |
-
|
84 |
-
$tweet = $tweet . " " . stripslashes( get_option( 'jd_twit_append' ) );
|
85 |
-
}
|
86 |
-
|
87 |
// there are no tags in this Tweet. Truncate and return.
|
88 |
-
if ( !wpt_has_tags( $tweet ) ) {
|
89 |
$post_tweet = mb_substr( $tweet, 0, $length, $encoding );
|
90 |
return apply_filters( 'wpt_custom_truncate', $post_tweet, $tweet, $post_ID, $retweet, 1 );
|
91 |
}
|
92 |
-
|
93 |
-
// create full unconditional post tweet - prior to truncation
|
94 |
// order matters; arrays have to be ordered the same way.
|
95 |
-
$tags
|
96 |
-
$values
|
97 |
-
|
98 |
$post_tweet = str_ireplace( $tags, $values, $tweet );
|
99 |
-
// check total length
|
100 |
$str_length = mb_strlen( urldecode( wpt_normalize( $post_tweet ) ), $encoding );
|
101 |
-
|
102 |
-
|
103 |
-
* Check whether completed replacement is still within allowed length.
|
104 |
-
*
|
105 |
-
* If so, post as is.
|
106 |
-
*/
|
107 |
if ( $str_length < $length + 1 ) {
|
108 |
if ( mb_strlen( wpt_normalize( $post_tweet ) ) > $length + 1 ) {
|
109 |
$post_tweet = mb_substr( $post_tweet, 0, $length, $encoding );
|
110 |
}
|
111 |
|
112 |
-
return apply_filters( 'wpt_custom_truncate', $post_tweet, $tweet, $post_ID, $retweet, 2 ); // return early if all is well
|
113 |
} else {
|
114 |
$has_excerpt_tag = wpt_has( $tweet, '#post#' );
|
115 |
$has_title_tag = wpt_has( $tweet, '#title#' );
|
116 |
$has_short_url = wpt_has( $tweet, '#url#' );
|
117 |
$has_long_url = wpt_has( $tweet, '#longurl#' );
|
118 |
-
|
119 |
-
$url_strlen = mb_strlen( urldecode( wpt_normalize( $values['url'] ) ), $encoding );
|
120 |
-
$longurl_strlen = mb_strlen( urldecode( wpt_normalize( $values['longurl'] ) ), $encoding );
|
121 |
-
|
122 |
-
|
123 |
-
*/
|
124 |
$length_array = wpt_length_array( $values, $encoding );
|
125 |
|
126 |
-
// Twitter's t.co shortener is mandatory. All URLS are max-character value set by Twitter.
|
127 |
$tco = ( wpt_is_ssl( $values['url'] ) ) ? $maxlength['https_length'] : $maxlength['http_length'];
|
128 |
$order = get_option( 'wpt_truncation_order' );
|
129 |
if ( is_array( $order ) ) {
|
130 |
asort( $order );
|
131 |
$preferred = array();
|
132 |
foreach ( $order as $k => $v ) {
|
133 |
-
if (
|
134 |
-
$k
|
135 |
-
$value = $length_array[
|
136 |
-
}
|
137 |
-
$k
|
138 |
-
$value = $length_array[
|
139 |
} else {
|
140 |
$value = $length_array[ $k ];
|
141 |
}
|
142 |
-
|
143 |
$preferred[ $k ] = $value;
|
144 |
}
|
145 |
} else {
|
@@ -147,30 +175,26 @@ function jd_truncate_tweet( $tweet, $post, $post_ID, $retweet = false, $ref = fa
|
|
147 |
}
|
148 |
if ( $has_short_url ) {
|
149 |
$diff = ( ( $url_strlen - $tco ) > 0 ) ? $url_strlen - $tco : 0;
|
150 |
-
}
|
151 |
-
$diff = ( ( $longurl_strlen - $tco ) > 0 ) ? $longurl_strlen - $tco : 0;
|
152 |
}
|
153 |
if ( $str_length > ( $length + 1 + $diff ) ) {
|
154 |
-
foreach ( $preferred
|
155 |
-
// don't truncate content of post excerpt or title if those tags not in use
|
156 |
-
if ( ! (
|
157 |
$str_length = mb_strlen( urldecode( wpt_normalize( trim( $post_tweet ) ) ), $encoding );
|
158 |
if ( $str_length > ( $length + 1 + $diff ) ) {
|
159 |
$trim = $str_length - ( $length + 1 + $diff );
|
160 |
-
$old_value = $values[$key];
|
161 |
-
// prevent URL from being modified
|
162 |
$post_tweet = str_ireplace( array( $values['url'], $values['longurl'] ), array( '#url#', '#longurl#' ), $post_tweet );
|
163 |
|
164 |
-
|
165 |
-
* These tag fields should be removed completely, rather than truncated.
|
166 |
-
*/
|
167 |
if ( wpt_remove_tag( $key ) ) {
|
168 |
$new_value = '';
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
} else if ( $key == 'tags' ) {
|
173 |
-
// remove any stray hash characters due to string truncation
|
174 |
if ( mb_strlen( $old_value ) - $trim <= 2 ) {
|
175 |
$new_value = '';
|
176 |
} else {
|
@@ -179,23 +203,19 @@ function jd_truncate_tweet( $tweet, $post, $post_ID, $retweet = false, $ref = fa
|
|
179 |
$new_value = trim( mb_substr( $new_value, 0, mb_strrpos( $new_value, '#', $encoding ) - 1 ) );
|
180 |
}
|
181 |
}
|
182 |
-
|
183 |
-
* Just flat out truncate everything else cold.
|
184 |
-
*/
|
185 |
} else {
|
186 |
-
// trim letters
|
187 |
$new_value = mb_substr( $old_value, 0, - ( $trim ), $encoding );
|
188 |
-
// trim rest of last word
|
189 |
$last_space = strrpos( $new_value, ' ' );
|
190 |
-
$new_value
|
191 |
-
|
192 |
-
|
193 |
-
*/
|
194 |
-
$new_value = apply_filters( 'wpt_filter_truncated_value', $new_value, $key, $old_value );
|
195 |
}
|
196 |
$post_tweet = str_ireplace( $old_value, $new_value, $post_tweet );
|
197 |
-
// put URL back before checking length
|
198 |
-
$post_tweet = str_ireplace( array( '#url#', '#longurl#' ), array( $values['url'], $values['longurl'] ), $post_tweet );
|
199 |
} else {
|
200 |
if ( mb_strlen( wpt_normalize( $post_tweet ), $encoding ) > ( $length + 1 + $diff ) ) {
|
201 |
$post_tweet = mb_substr( $post_tweet, 0, ( $length + $diff ), $encoding );
|
@@ -204,32 +224,32 @@ function jd_truncate_tweet( $tweet, $post, $post_ID, $retweet = false, $ref = fa
|
|
204 |
}
|
205 |
}
|
206 |
}
|
207 |
-
|
208 |
// this is needed in case a tweet needs to be truncated outright and the truncation values aren't in the above.
|
209 |
-
// 1) removes URL 2) checks length of remainder 3) Replaces URL
|
210 |
if ( mb_strlen( wpt_normalize( $post_tweet ) ) > $length + 1 ) {
|
211 |
$tweet = false;
|
212 |
if ( $has_short_url ) {
|
213 |
$url = $values['url'];
|
214 |
$tag = '#url#';
|
215 |
-
}
|
216 |
$url = $values['longurl'];
|
217 |
$tag = '#longurl#';
|
218 |
} else {
|
219 |
$post_tweet = mb_substr( $post_tweet, 0, ( $length + $diff ), $encoding );
|
220 |
$tweet = true;
|
221 |
}
|
222 |
-
|
223 |
-
if (
|
224 |
$temp = str_ireplace( $url, $tag, $post_tweet );
|
225 |
if ( mb_strlen( wpt_normalize( $temp ) ) > ( ( $length + 1 ) - ( $tco - strlen( $tag ) ) ) && $temp != $post_tweet ) {
|
226 |
-
if ( stripos( $temp, '#url#' )
|
227 |
-
$post_tweet
|
228 |
} else {
|
229 |
-
$post_tweet
|
230 |
}
|
231 |
// it's possible to trim off the #url# part in this process. If that happens, put it back.
|
232 |
-
$sub_sentence = ( !wpt_has( $post_tweet, $tag ) && ( $has_short_url || $has_long_url ) ) ? $post_tweet . ' ' . $tag : $post_tweet;
|
233 |
$post_tweet = str_ireplace( $tag, $url, $sub_sentence );
|
234 |
}
|
235 |
}
|
@@ -239,14 +259,29 @@ function jd_truncate_tweet( $tweet, $post, $post_ID, $retweet = false, $ref = fa
|
|
239 |
return apply_filters( 'wpt_custom_truncate', $post_tweet, $tweet, $post_ID, $retweet, 3 );
|
240 |
}
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
function wpt_has( $string, $tag ) {
|
243 |
if ( strpos( $string, $tag ) === false ) {
|
244 |
return false;
|
245 |
}
|
246 |
-
|
247 |
return true;
|
248 |
}
|
249 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
function wpt_has_tags( $string ) {
|
251 |
$tags = wpt_tags();
|
252 |
foreach ( $tags as $tag ) {
|
@@ -258,33 +293,64 @@ function wpt_has_tags( $string ) {
|
|
258 |
return false;
|
259 |
}
|
260 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
function wpt_remove_tag( $key ) {
|
262 |
-
switch( $key ) {
|
263 |
case 'account':
|
264 |
case 'author':
|
265 |
case 'category':
|
266 |
case 'date':
|
267 |
case 'modified':
|
268 |
case 'reference':
|
269 |
-
case '@':
|
270 |
-
|
|
|
|
|
|
|
271 |
}
|
272 |
-
|
273 |
return $return;
|
274 |
}
|
275 |
|
|
|
|
|
|
|
|
|
|
|
276 |
function wpt_tags() {
|
277 |
return apply_filters( 'wpt_tags', array( 'url', 'title', 'blog', 'post', 'category', 'date', 'author', 'displayname', 'tags', 'modified', 'reference', 'account', '@', 'cat_desc', 'longurl' ) );
|
278 |
}
|
279 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
280 |
function wpt_make_tag( $value ) {
|
281 |
return '#' . $value . '#';
|
282 |
}
|
283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
function wpt_create_values( $post, $post_ID, $ref ) {
|
285 |
-
$shrink
|
286 |
-
// generate template variable values
|
287 |
-
$auth = $post['authId'];
|
288 |
$title = trim( apply_filters( 'wpt_status', $post['postTitle'], $post_ID, 'title' ) );
|
289 |
$blogname = trim( $post['blogTitle'] );
|
290 |
$excerpt = trim( apply_filters( 'wpt_status', $post['postExcerpt'], $post_ID, 'post' ) );
|
@@ -296,108 +362,123 @@ function wpt_create_values( $post, $post_ID, $ref ) {
|
|
296 |
$account = get_option( 'wtt_twitter_username' );
|
297 |
$date = trim( $post['postDate'] );
|
298 |
$modified = trim( $post['postModified'] );
|
299 |
-
if ( get_option( 'jd_individual_twitter_users' )
|
300 |
-
if (
|
301 |
-
if ( get_user_meta( $auth, 'wp-to-twitter-enable-user', true )
|
302 |
-
$
|
303 |
-
|
304 |
-
|
|
|
|
|
305 |
}
|
306 |
} else {
|
307 |
$account = "$user_account";
|
308 |
}
|
309 |
}
|
310 |
$display_name = get_the_author_meta( 'display_name', $auth );
|
311 |
-
$author = (
|
312 |
-
$account = (
|
313 |
-
$uaccount = (
|
314 |
-
// clean up data if extra @ included in user data
|
315 |
-
$account
|
316 |
-
$uaccount
|
317 |
-
$author
|
318 |
-
|
319 |
-
if ( get_user_meta( $auth, 'wpt-remove', true )
|
320 |
$account = '';
|
321 |
}
|
322 |
-
|
323 |
-
if ( function_exists( 'wpt_pro_exists' ) && wpt_pro_exists()
|
324 |
$reference = ( $ref ) ? $account : '@' . get_option( 'wtt_twitter_username' );
|
325 |
} else {
|
326 |
$reference = '';
|
327 |
-
}
|
328 |
-
|
329 |
-
return array(
|
330 |
-
'url'
|
331 |
-
'title'
|
332 |
-
'blog'
|
333 |
-
'post'
|
334 |
-
'category'
|
335 |
-
'date'
|
336 |
-
'author'
|
337 |
'displayname' => $display_name,
|
338 |
-
'tags'
|
339 |
-
'modified'
|
340 |
-
'reference'
|
341 |
-
'account'
|
342 |
-
'@'
|
343 |
-
'cat_desc'
|
344 |
-
'longurl'
|
345 |
);
|
346 |
}
|
347 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
348 |
function wpt_length_array( $values, $encoding ) {
|
349 |
foreach ( $values as $key => $value ) {
|
350 |
-
$array[$key] = mb_strlen( wpt_normalize( $value ), $encoding );
|
351 |
}
|
352 |
|
353 |
return $array;
|
354 |
}
|
355 |
|
356 |
-
|
357 |
/**
|
358 |
-
* Parse custom shortcodes
|
359 |
*
|
360 |
-
* @param string
|
361 |
* @param integer $post_ID Post ID.
|
362 |
*
|
363 |
* @return string $sentence with any custom shortcodes replaced with their appropriate content.
|
364 |
*/
|
365 |
function wpt_custom_shortcodes( $sentence, $post_ID ) {
|
366 |
$pattern = '/([([\[\]?)([A-Za-z0-9-_])*(\]\]]?)+/';
|
367 |
-
$params = array(
|
|
|
|
|
|
|
368 |
preg_match_all( $pattern, $sentence, $matches );
|
369 |
if ( $matches && is_array( $matches[0] ) ) {
|
370 |
foreach ( $matches[0] as $value ) {
|
371 |
$shortcode = "$value";
|
372 |
-
$field = str_replace( $params,
|
373 |
$custom = apply_filters( 'wpt_custom_shortcode', strip_tags( get_post_meta( $post_ID, $field, true ) ), $post_ID, $field );
|
374 |
$sentence = str_replace( $shortcode, $custom, $sentence );
|
375 |
}
|
376 |
}
|
377 |
-
|
378 |
return $sentence;
|
379 |
}
|
380 |
|
381 |
/**
|
382 |
-
* Parse user meta shortcodes
|
383 |
*
|
384 |
-
* @param string
|
385 |
-
* @param integer $
|
386 |
*
|
387 |
* @return string $sentence with any custom shortcodes replaced with their appropriate content.
|
388 |
*/
|
389 |
-
function wpt_user_meta_shortcodes( $sentence, $
|
390 |
$pattern = '/([({\{\}?)([A-Za-z0-9-_])*(\}\}}?)+/';
|
391 |
-
$params = array(
|
|
|
|
|
|
|
392 |
preg_match_all( $pattern, $sentence, $matches );
|
393 |
if ( $matches && is_array( $matches[0] ) ) {
|
394 |
foreach ( $matches[0] as $value ) {
|
395 |
$shortcode = "$value";
|
396 |
-
$field = str_replace( $params,
|
397 |
-
$custom = apply_filters( 'wpt_user_meta_shortcode', strip_tags( get_user_meta( $
|
398 |
$sentence = str_replace( $shortcode, $custom, $sentence );
|
399 |
}
|
400 |
}
|
401 |
-
|
402 |
return $sentence;
|
403 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Construct and check lengths of Tweets - WP to Twitter
|
4 |
+
*
|
5 |
+
* @category Core
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
|
16 |
+
/**
|
17 |
+
* Check the current allowed max lengths.
|
18 |
+
*
|
19 |
+
* @return array of URL lengths and params.
|
20 |
+
*/
|
21 |
function wpt_max_length() {
|
22 |
+
$config = get_transient( 'wpt_twitter_config' );
|
23 |
if ( ! $config ) {
|
24 |
+
$connection = wpt_oauth_connection();
|
25 |
if ( $connection ) {
|
26 |
+
$config = $connection->get( 'https://api.twitter.com/1.1/help/configuration.json' );
|
27 |
+
set_transient( 'wpt_twitter_config', $config, 60 * 60 * 24 );
|
28 |
} else {
|
29 |
+
$config = json_encode( array(
|
30 |
+
'http_length' => 23,
|
31 |
+
'https_length' => 23,
|
32 |
+
'reserved_chars' => 24,
|
33 |
) );
|
34 |
}
|
35 |
}
|
36 |
+
|
37 |
$decoded = json_decode( $config );
|
38 |
+
|
39 |
if ( is_object( $decoded ) && isset( $decoded->short_url_length ) ) {
|
40 |
$short_url_length = $decoded->short_url_length;
|
41 |
$short_url_https = $decoded->short_url_length_https;
|
42 |
$reserved_char = $decoded->characters_reserved_per_media;
|
43 |
+
$values = array(
|
44 |
+
'http_length' => $short_url_length,
|
45 |
+
'https_length' => $short_url_https,
|
46 |
+
'reserved_chars' => $reserved_char,
|
47 |
+
);
|
48 |
+
|
49 |
} else {
|
50 |
+
// if config query is invalid, use default values; these may become invalid.
|
51 |
+
$values = array(
|
52 |
+
'http_length' => 23,
|
53 |
+
'https_length' => 23,
|
54 |
+
'reserved_chars' => 24,
|
55 |
+
);
|
56 |
}
|
57 |
+
|
58 |
$values['base_length'] = intval( ( get_option( 'wpt_tweet_length' ) ) ? get_option( 'wpt_tweet_length' ) : 140 ) - 1;
|
59 |
+
|
60 |
+
return apply_filters( 'wpt_max_length', $values );
|
61 |
}
|
62 |
|
63 |
add_filter( 'wpt_tweet_sentence', 'wpt_filter_urls', 10, 2 );
|
64 |
+
/**
|
65 |
+
* Filter the URLs in a tweet and shorten them.
|
66 |
+
*
|
67 |
+
* @param string $tweet Tweet.
|
68 |
+
* @param int $post_ID Post ID.
|
69 |
+
*
|
70 |
+
* @return string New tweet text.
|
71 |
+
*/
|
72 |
function wpt_filter_urls( $tweet, $post_ID ) {
|
73 |
+
preg_match_all( '#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#', $tweet, $match );
|
74 |
$title = get_the_title( $post_ID );
|
75 |
+
|
76 |
+
if ( isset( $match[0] ) && ! empty( $match[0] ) ) {
|
77 |
$urls = $match[0];
|
78 |
+
foreach ( $urls as $url ) {
|
79 |
if ( esc_url( $url ) ) {
|
80 |
$short = wpt_shorten_url( $url, $title, $post_ID, false, false );
|
81 |
if ( $short ) {
|
84 |
}
|
85 |
}
|
86 |
}
|
87 |
+
|
88 |
return $tweet;
|
89 |
}
|
90 |
|
91 |
+
/**
|
92 |
+
* Parse the text of a Tweet to ensure included tags don't exceed length requirements.
|
93 |
+
*
|
94 |
+
* @param string $tweet Tweet text.
|
95 |
+
* @param array $post Post data.
|
96 |
+
* @param int $post_ID Post ID.
|
97 |
+
* @param boolean $retweet Is this a retweet.
|
98 |
+
* @param boolean $ref Reference.
|
99 |
+
*
|
100 |
+
* @return string New text.
|
101 |
+
*/
|
102 |
function jd_truncate_tweet( $tweet, $post, $post_ID, $retweet = false, $ref = false ) {
|
103 |
+
// media file no longer needs accounting in shortening. 9/22/2016.
|
104 |
+
$maxlength = wpt_max_length();
|
105 |
+
$length = $maxlength['base_length'];
|
106 |
+
$tweet = apply_filters( 'wpt_tweet_sentence', $tweet, $post_ID );
|
107 |
+
$tweet = trim( wpt_custom_shortcodes( $tweet, $post_ID ) );
|
108 |
+
$tweet = trim( wpt_user_meta_shortcodes( $tweet, $post['authId'] ) );
|
109 |
+
$encoding = ( 'UTF-8' != get_option( 'blog_charset' ) && '' != get_option( 'blog_charset' ) ) ? get_option( 'blog_charset' ) : 'UTF-8';
|
110 |
+
$diff = 0;
|
111 |
+
|
112 |
+
// Add custom append/prepend fields to Tweet text.
|
113 |
+
if ( '' != get_option( 'jd_twit_prepend' ) && '' != $tweet ) {
|
114 |
+
$tweet = stripslashes( get_option( 'jd_twit_prepend' ) ) . ' ' . $tweet;
|
115 |
+
}
|
116 |
+
if ( '' != get_option( 'jd_twit_append' ) && '' != $tweet ) {
|
117 |
+
$tweet = $tweet . ' ' . stripslashes( get_option( 'jd_twit_append' ) );
|
118 |
}
|
119 |
+
|
|
|
|
|
|
|
120 |
// there are no tags in this Tweet. Truncate and return.
|
121 |
+
if ( ! wpt_has_tags( $tweet ) ) {
|
122 |
$post_tweet = mb_substr( $tweet, 0, $length, $encoding );
|
123 |
return apply_filters( 'wpt_custom_truncate', $post_tweet, $tweet, $post_ID, $retweet, 1 );
|
124 |
}
|
125 |
+
|
126 |
+
// create full unconditional post tweet - prior to truncation.
|
127 |
// order matters; arrays have to be ordered the same way.
|
128 |
+
$tags = array_map( 'wpt_make_tag', wpt_tags() );
|
129 |
+
$values = wpt_create_values( $post, $post_ID, $ref );
|
130 |
+
|
131 |
$post_tweet = str_ireplace( $tags, $values, $tweet );
|
132 |
+
// check total length.
|
133 |
$str_length = mb_strlen( urldecode( wpt_normalize( $post_tweet ) ), $encoding );
|
134 |
+
|
135 |
+
// Check whether completed replacement is still within allowed length.
|
|
|
|
|
|
|
|
|
136 |
if ( $str_length < $length + 1 ) {
|
137 |
if ( mb_strlen( wpt_normalize( $post_tweet ) ) > $length + 1 ) {
|
138 |
$post_tweet = mb_substr( $post_tweet, 0, $length, $encoding );
|
139 |
}
|
140 |
|
141 |
+
return apply_filters( 'wpt_custom_truncate', $post_tweet, $tweet, $post_ID, $retweet, 2 ); // return early if all is well.
|
142 |
} else {
|
143 |
$has_excerpt_tag = wpt_has( $tweet, '#post#' );
|
144 |
$has_title_tag = wpt_has( $tweet, '#title#' );
|
145 |
$has_short_url = wpt_has( $tweet, '#url#' );
|
146 |
$has_long_url = wpt_has( $tweet, '#longurl#' );
|
147 |
+
|
148 |
+
$url_strlen = mb_strlen( urldecode( wpt_normalize( $values['url'] ) ), $encoding );
|
149 |
+
$longurl_strlen = mb_strlen( urldecode( wpt_normalize( $values['longurl'] ) ), $encoding );
|
150 |
+
|
151 |
+
// Tweet is too long, so we'll have to truncate that sucker.
|
|
|
152 |
$length_array = wpt_length_array( $values, $encoding );
|
153 |
|
154 |
+
// Twitter's t.co shortener is mandatory. All URLS are max-character value set by Twitter.
|
155 |
$tco = ( wpt_is_ssl( $values['url'] ) ) ? $maxlength['https_length'] : $maxlength['http_length'];
|
156 |
$order = get_option( 'wpt_truncation_order' );
|
157 |
if ( is_array( $order ) ) {
|
158 |
asort( $order );
|
159 |
$preferred = array();
|
160 |
foreach ( $order as $k => $v ) {
|
161 |
+
if ( 'excerpt' == $k ) {
|
162 |
+
$k = 'post';
|
163 |
+
$value = $length_array['post'];
|
164 |
+
} elseif ( 'blogname' == $k ) {
|
165 |
+
$k = 'blog';
|
166 |
+
$value = $length_array['blog'];
|
167 |
} else {
|
168 |
$value = $length_array[ $k ];
|
169 |
}
|
170 |
+
|
171 |
$preferred[ $k ] = $value;
|
172 |
}
|
173 |
} else {
|
175 |
}
|
176 |
if ( $has_short_url ) {
|
177 |
$diff = ( ( $url_strlen - $tco ) > 0 ) ? $url_strlen - $tco : 0;
|
178 |
+
} elseif ( $has_long_url ) {
|
179 |
+
$diff = ( ( $longurl_strlen - $tco ) > 0 ) ? $longurl_strlen - $tco : 0;
|
180 |
}
|
181 |
if ( $str_length > ( $length + 1 + $diff ) ) {
|
182 |
+
foreach ( $preferred as $key => $value ) {
|
183 |
+
// don't truncate content of post excerpt or title if those tags not in use.
|
184 |
+
if ( ! ( 'excerpt' == $key && ! $has_excerpt_tag ) && ! ( 'title' == $key && ! $has_title_tag ) ) {
|
185 |
$str_length = mb_strlen( urldecode( wpt_normalize( trim( $post_tweet ) ) ), $encoding );
|
186 |
if ( $str_length > ( $length + 1 + $diff ) ) {
|
187 |
$trim = $str_length - ( $length + 1 + $diff );
|
188 |
+
$old_value = $values[ $key ];
|
189 |
+
// prevent URL from being modified.
|
190 |
$post_tweet = str_ireplace( array( $values['url'], $values['longurl'] ), array( '#url#', '#longurl#' ), $post_tweet );
|
191 |
|
192 |
+
// These tag fields should be removed completely, rather than truncated.
|
|
|
|
|
193 |
if ( wpt_remove_tag( $key ) ) {
|
194 |
$new_value = '';
|
195 |
+
// These tag fields should have stray characters removed on word boundaries.
|
196 |
+
} elseif ( 'tags' == $key ) {
|
197 |
+
// remove any stray hash characters due to string truncation.
|
|
|
|
|
198 |
if ( mb_strlen( $old_value ) - $trim <= 2 ) {
|
199 |
$new_value = '';
|
200 |
} else {
|
203 |
$new_value = trim( mb_substr( $new_value, 0, mb_strrpos( $new_value, '#', $encoding ) - 1 ) );
|
204 |
}
|
205 |
}
|
206 |
+
// Just flat out truncate everything else cold.
|
|
|
|
|
207 |
} else {
|
208 |
+
// trim letters.
|
209 |
$new_value = mb_substr( $old_value, 0, - ( $trim ), $encoding );
|
210 |
+
// trim rest of last word.
|
211 |
$last_space = strrpos( $new_value, ' ' );
|
212 |
+
$new_value = mb_substr( $new_value, 0, $last_space, $encoding );
|
213 |
+
// If you want to add something like an ellipsis after truncation, use this filter.
|
214 |
+
$new_value = apply_filters( 'wpt_filter_truncated_value', $new_value, $key, $old_value );
|
|
|
|
|
215 |
}
|
216 |
$post_tweet = str_ireplace( $old_value, $new_value, $post_tweet );
|
217 |
+
// put URL back before checking length.
|
218 |
+
$post_tweet = str_ireplace( array( '#url#', '#longurl#' ), array( $values['url'], $values['longurl'] ), $post_tweet );
|
219 |
} else {
|
220 |
if ( mb_strlen( wpt_normalize( $post_tweet ), $encoding ) > ( $length + 1 + $diff ) ) {
|
221 |
$post_tweet = mb_substr( $post_tweet, 0, ( $length + $diff ), $encoding );
|
224 |
}
|
225 |
}
|
226 |
}
|
227 |
+
|
228 |
// this is needed in case a tweet needs to be truncated outright and the truncation values aren't in the above.
|
229 |
+
// 1) removes URL 2) checks length of remainder 3) Replaces URL.
|
230 |
if ( mb_strlen( wpt_normalize( $post_tweet ) ) > $length + 1 ) {
|
231 |
$tweet = false;
|
232 |
if ( $has_short_url ) {
|
233 |
$url = $values['url'];
|
234 |
$tag = '#url#';
|
235 |
+
} elseif ( $has_long_url ) {
|
236 |
$url = $values['longurl'];
|
237 |
$tag = '#longurl#';
|
238 |
} else {
|
239 |
$post_tweet = mb_substr( $post_tweet, 0, ( $length + $diff ), $encoding );
|
240 |
$tweet = true;
|
241 |
}
|
242 |
+
|
243 |
+
if ( ! $tweet ) {
|
244 |
$temp = str_ireplace( $url, $tag, $post_tweet );
|
245 |
if ( mb_strlen( wpt_normalize( $temp ) ) > ( ( $length + 1 ) - ( $tco - strlen( $tag ) ) ) && $temp != $post_tweet ) {
|
246 |
+
if ( false === stripos( $temp, '#url#' ) && false === stripos( $temp, '#longurl#' ) ) {
|
247 |
+
$post_tweet = trim( mb_substr( $temp, 0, $length, $encoding ) );
|
248 |
} else {
|
249 |
+
$post_tweet = trim( mb_substr( $temp, 0, ( $length - $tco - 1 ), $encoding ) );
|
250 |
}
|
251 |
// it's possible to trim off the #url# part in this process. If that happens, put it back.
|
252 |
+
$sub_sentence = ( ! wpt_has( $post_tweet, $tag ) && ( $has_short_url || $has_long_url ) ) ? $post_tweet . ' ' . $tag : $post_tweet;
|
253 |
$post_tweet = str_ireplace( $tag, $url, $sub_sentence );
|
254 |
}
|
255 |
}
|
259 |
return apply_filters( 'wpt_custom_truncate', $post_tweet, $tweet, $post_ID, $retweet, 3 );
|
260 |
}
|
261 |
|
262 |
+
/**
|
263 |
+
* Check whether a tag is within the string.
|
264 |
+
*
|
265 |
+
* @param string $string String. Probably a Tweet.
|
266 |
+
* @param string $tag Template tag text.
|
267 |
+
*
|
268 |
+
* @return boolean.
|
269 |
+
*/
|
270 |
function wpt_has( $string, $tag ) {
|
271 |
if ( strpos( $string, $tag ) === false ) {
|
272 |
return false;
|
273 |
}
|
274 |
+
|
275 |
return true;
|
276 |
}
|
277 |
|
278 |
+
/**
|
279 |
+
* Check whether any tags are present.
|
280 |
+
*
|
281 |
+
* @param string $string String. Probably a Tweet.
|
282 |
+
*
|
283 |
+
* @return boolean.
|
284 |
+
*/
|
285 |
function wpt_has_tags( $string ) {
|
286 |
$tags = wpt_tags();
|
287 |
foreach ( $tags as $tag ) {
|
293 |
return false;
|
294 |
}
|
295 |
|
296 |
+
/**
|
297 |
+
* Get a tag to remove.
|
298 |
+
*
|
299 |
+
* @param string $key Template tag.
|
300 |
+
*
|
301 |
+
* @return boolean.
|
302 |
+
*/
|
303 |
function wpt_remove_tag( $key ) {
|
304 |
+
switch ( $key ) {
|
305 |
case 'account':
|
306 |
case 'author':
|
307 |
case 'category':
|
308 |
case 'date':
|
309 |
case 'modified':
|
310 |
case 'reference':
|
311 |
+
case '@':
|
312 |
+
$return = true;
|
313 |
+
break;
|
314 |
+
default:
|
315 |
+
$return = false;
|
316 |
}
|
317 |
+
|
318 |
return $return;
|
319 |
}
|
320 |
|
321 |
+
/**
|
322 |
+
* Get all valid template tags.
|
323 |
+
*
|
324 |
+
* @return array tags.
|
325 |
+
*/
|
326 |
function wpt_tags() {
|
327 |
return apply_filters( 'wpt_tags', array( 'url', 'title', 'blog', 'post', 'category', 'date', 'author', 'displayname', 'tags', 'modified', 'reference', 'account', '@', 'cat_desc', 'longurl' ) );
|
328 |
}
|
329 |
|
330 |
+
/**
|
331 |
+
* Adjust a tag string into its ## usage.
|
332 |
+
*
|
333 |
+
* @param string $value Any text.
|
334 |
+
*
|
335 |
+
* @return string wrapped.
|
336 |
+
*/
|
337 |
function wpt_make_tag( $value ) {
|
338 |
return '#' . $value . '#';
|
339 |
}
|
340 |
|
341 |
+
/**
|
342 |
+
* Create values. Get the value of tags.
|
343 |
+
*
|
344 |
+
* @param array $post Post array.
|
345 |
+
* @param int $post_ID Post ID.
|
346 |
+
* @param boolean $ref Use referential author.
|
347 |
+
*
|
348 |
+
* @return array of values.
|
349 |
+
*/
|
350 |
function wpt_create_values( $post, $post_ID, $ref ) {
|
351 |
+
$shrink = ( '' != $post['shortUrl'] ) ? $post['shortUrl'] : apply_filters( 'wptt_shorten_link', $post['postLink'], $post['postTitle'], $post_ID, false );
|
352 |
+
// generate template variable values.
|
353 |
+
$auth = $post['authId'];
|
354 |
$title = trim( apply_filters( 'wpt_status', $post['postTitle'], $post_ID, 'title' ) );
|
355 |
$blogname = trim( $post['blogTitle'] );
|
356 |
$excerpt = trim( apply_filters( 'wpt_status', $post['postExcerpt'], $post_ID, 'post' ) );
|
362 |
$account = get_option( 'wtt_twitter_username' );
|
363 |
$date = trim( $post['postDate'] );
|
364 |
$modified = trim( $post['postModified'] );
|
365 |
+
if ( 1 == get_option( 'jd_individual_twitter_users' ) ) {
|
366 |
+
if ( '' == $user_account ) {
|
367 |
+
if ( 'mainAtTwitter' == get_user_meta( $auth, 'wp-to-twitter-enable-user', true ) ) {
|
368 |
+
$user_account = stripcslashes( get_user_meta( $auth, 'wp-to-twitter-user-username', true ) );
|
369 |
+
$account = $user_account;
|
370 |
+
} elseif ( 'mainAtTwitterPlus' == get_user_meta( $auth, 'wp-to-twitter-enable-user', true ) ) {
|
371 |
+
$user_account = stripcslashes( get_user_meta( $auth, 'wp-to-twitter-user-username', true ) . ' @' . get_option( 'wtt_twitter_username' ) );
|
372 |
+
$account = $user_account;
|
373 |
}
|
374 |
} else {
|
375 |
$account = "$user_account";
|
376 |
}
|
377 |
}
|
378 |
$display_name = get_the_author_meta( 'display_name', $auth );
|
379 |
+
$author = ( '' != $user_account ) ? "@$user_account" : $display_name; // value of #author#.
|
380 |
+
$account = ( '' != $account ) ? "@$account" : ''; // value of #account#.
|
381 |
+
$uaccount = ( '' != $user_account ) ? "@$user_account" : "$account"; // value of #@#.
|
382 |
+
// clean up data if extra @ included in user data.
|
383 |
+
$account = str_ireplace( '@@', '@', $account );
|
384 |
+
$uaccount = str_ireplace( '@@', '@', $uaccount );
|
385 |
+
$author = str_ireplace( '@@', '@', $author );
|
386 |
+
|
387 |
+
if ( 'on' == get_user_meta( $auth, 'wpt-remove', true ) ) {
|
388 |
$account = '';
|
389 |
}
|
390 |
+
|
391 |
+
if ( function_exists( 'wpt_pro_exists' ) && true == wpt_pro_exists() ) {
|
392 |
$reference = ( $ref ) ? $account : '@' . get_option( 'wtt_twitter_username' );
|
393 |
} else {
|
394 |
$reference = '';
|
395 |
+
}
|
396 |
+
|
397 |
+
return array(
|
398 |
+
'url' => $thisposturl,
|
399 |
+
'title' => $title,
|
400 |
+
'blog' => $blogname,
|
401 |
+
'post' => $excerpt,
|
402 |
+
'category' => $category,
|
403 |
+
'date' => $date,
|
404 |
+
'author' => $author,
|
405 |
'displayname' => $display_name,
|
406 |
+
'tags' => $tags,
|
407 |
+
'modified' => $modified,
|
408 |
+
'reference' => $reference,
|
409 |
+
'account' => $account,
|
410 |
+
'@' => $uaccount,
|
411 |
+
'cat_desc' => $cat_desc,
|
412 |
+
'longurl' => $post['postLink'],
|
413 |
);
|
414 |
}
|
415 |
|
416 |
+
/**
|
417 |
+
* Generate array of length values of every value.
|
418 |
+
*
|
419 |
+
* @param array $values All values.
|
420 |
+
* @param string $encoding Current encoding.
|
421 |
+
*
|
422 |
+
* @return array.
|
423 |
+
*/
|
424 |
function wpt_length_array( $values, $encoding ) {
|
425 |
foreach ( $values as $key => $value ) {
|
426 |
+
$array[ $key ] = mb_strlen( wpt_normalize( $value ), $encoding );
|
427 |
}
|
428 |
|
429 |
return $array;
|
430 |
}
|
431 |
|
|
|
432 |
/**
|
433 |
+
* Parse custom shortcodes
|
434 |
*
|
435 |
+
* @param string $sentence Tweet template.
|
436 |
* @param integer $post_ID Post ID.
|
437 |
*
|
438 |
* @return string $sentence with any custom shortcodes replaced with their appropriate content.
|
439 |
*/
|
440 |
function wpt_custom_shortcodes( $sentence, $post_ID ) {
|
441 |
$pattern = '/([([\[\]?)([A-Za-z0-9-_])*(\]\]]?)+/';
|
442 |
+
$params = array(
|
443 |
+
0 => '[[',
|
444 |
+
1 => ']]',
|
445 |
+
);
|
446 |
preg_match_all( $pattern, $sentence, $matches );
|
447 |
if ( $matches && is_array( $matches[0] ) ) {
|
448 |
foreach ( $matches[0] as $value ) {
|
449 |
$shortcode = "$value";
|
450 |
+
$field = str_replace( $params, '', $shortcode );
|
451 |
$custom = apply_filters( 'wpt_custom_shortcode', strip_tags( get_post_meta( $post_ID, $field, true ) ), $post_ID, $field );
|
452 |
$sentence = str_replace( $shortcode, $custom, $sentence );
|
453 |
}
|
454 |
}
|
455 |
+
|
456 |
return $sentence;
|
457 |
}
|
458 |
|
459 |
/**
|
460 |
+
* Parse user meta shortcodes
|
461 |
*
|
462 |
+
* @param string $sentence Tweet template.
|
463 |
+
* @param integer $auth_id Post Author ID.
|
464 |
*
|
465 |
* @return string $sentence with any custom shortcodes replaced with their appropriate content.
|
466 |
*/
|
467 |
+
function wpt_user_meta_shortcodes( $sentence, $auth_id ) {
|
468 |
$pattern = '/([({\{\}?)([A-Za-z0-9-_])*(\}\}}?)+/';
|
469 |
+
$params = array(
|
470 |
+
0 => '{{',
|
471 |
+
1 => '}}',
|
472 |
+
);
|
473 |
preg_match_all( $pattern, $sentence, $matches );
|
474 |
if ( $matches && is_array( $matches[0] ) ) {
|
475 |
foreach ( $matches[0] as $value ) {
|
476 |
$shortcode = "$value";
|
477 |
+
$field = str_replace( $params, '', $shortcode );
|
478 |
+
$custom = apply_filters( 'wpt_user_meta_shortcode', strip_tags( get_user_meta( $auth_id, $field, true ) ), $auth_id, $field );
|
479 |
$sentence = str_replace( $shortcode, $custom, $sentence );
|
480 |
}
|
481 |
}
|
482 |
+
|
483 |
return $sentence;
|
484 |
+
}
|
wpt-widget.php
CHANGED
@@ -1,24 +1,147 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
exit;
|
4 |
-
}
|
|
|
|
|
|
|
5 |
|
6 |
/**
|
7 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
return;
|
13 |
}
|
14 |
-
$options = array( 'screen_name' => $
|
15 |
$key = get_option( 'app_consumer_key' );
|
16 |
$secret = get_option( 'app_consumer_secret' );
|
17 |
$token = get_option( 'oauth_token' );
|
18 |
$token_secret = get_option( 'oauth_token_secret' );
|
19 |
if ( $key && $secret && $token && $token_secret ) {
|
20 |
-
$connection
|
21 |
-
$result
|
22 |
|
23 |
return json_decode( $result );
|
24 |
} else {
|
@@ -27,71 +150,86 @@ function wpt_get_user( $twitter_ID = false ) {
|
|
27 |
}
|
28 |
|
29 |
add_shortcode( 'get_tweets', 'wpt_get_twitter_feed' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
function wpt_get_twitter_feed( $atts, $content ) {
|
31 |
-
|
32 |
-
'id'
|
33 |
-
'num'
|
34 |
-
'duration'
|
35 |
-
'replies'
|
36 |
-
'rts'
|
37 |
-
'links'
|
38 |
-
'mentions'
|
39 |
-
'hashtags'
|
40 |
-
'intents'
|
41 |
-
'source'
|
42 |
'show_images' => 1,
|
43 |
-
'hide_header' => 0
|
44 |
), $atts, 'get_tweets' ) );
|
45 |
$instance = array(
|
46 |
-
'twitter_id' => $id,
|
47 |
-
'twitter_num' => $num,
|
48 |
-
'twitter_duration' => $duration,
|
49 |
-
'twitter_hide_replies' => $replies,
|
50 |
-
'twitter_include_rts' => $rts,
|
51 |
-
'link_links' => $links,
|
52 |
-
'link_mentions' => $mentions,
|
53 |
-
'link_hashtags' => $hashtags,
|
54 |
-
'intents' => $intents,
|
55 |
-
'source' => $source,
|
56 |
-
'show_images' => $show_images,
|
57 |
-
'hide_header' => $hide_header
|
58 |
);
|
59 |
|
60 |
return wpt_twitter_feed( $instance );
|
61 |
}
|
62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
function wpt_twitter_feed( $instance ) {
|
64 |
$header = '';
|
65 |
if ( ! isset( $instance['search'] ) ) {
|
66 |
-
$
|
67 |
-
$user
|
68 |
if ( empty( $user ) ) {
|
69 |
return __( 'Error: You are not connected to Twitter.', 'wp-to-twitter' );
|
70 |
}
|
71 |
if ( isset( $user->errors ) && $user->errors[0]->message ) {
|
72 |
-
return __(
|
73 |
}
|
74 |
$avatar = $user->profile_image_url_https;
|
75 |
$name = $user->name;
|
76 |
$verified = sanitize_title( $user->verified );
|
77 |
$img_alignment = ( is_rtl() ) ? 'wpt-right' : 'wpt-left';
|
78 |
$follow_alignment = ( is_rtl() ) ? 'wpt-left' : 'wpt-right';
|
79 |
-
$follow_url = esc_url( 'https://twitter.com/' . $
|
80 |
-
$follow_button = apply_filters( 'wpt_follow_button', "<a href='$follow_url' class='twitter-follow-button $follow_alignment' data-width='30px' data-show-screen-name='false' data-size='large' data-show-count='false' data-lang='en'>Follow @" .
|
81 |
-
$header
|
82 |
-
$header
|
83 |
<p>
|
84 |
<img src='$avatar' alt='' class='wpt-twitter-avatar $img_alignment $verified' />
|
85 |
<span class='wpt-twitter-name'>$name</span><br />
|
86 |
-
<span class='wpt-twitter-id'><a href='$follow_url'>@" .
|
87 |
-
</p>
|
88 |
-
$header
|
89 |
} else {
|
90 |
-
$
|
91 |
}
|
92 |
-
|
93 |
-
$hide_header = ( isset( $instance['hide_header'] ) && $instance['hide_header']
|
94 |
-
|
95 |
if ( ! isset( $instance['search'] ) ) {
|
96 |
$options['exclude_replies'] = ( isset( $instance['twitter_hide_replies'] ) ) ? $instance['twitter_hide_replies'] : false;
|
97 |
$options['include_rts'] = $instance['twitter_include_rts'];
|
@@ -100,39 +238,52 @@ function wpt_twitter_feed( $instance ) {
|
|
100 |
$options['geocode'] = $instance['geocode'];
|
101 |
$options['result_type'] = $instance['result_type'];
|
102 |
}
|
103 |
-
|
104 |
if ( $hide_header ) {
|
105 |
-
$header = '';
|
106 |
}
|
107 |
-
|
108 |
-
$return = $header . '<ul>' . "\n";
|
109 |
-
|
110 |
$opts['links'] = $instance['link_links'];
|
111 |
$opts['mentions'] = $instance['link_mentions'];
|
112 |
$opts['hashtags'] = $instance['link_hashtags'];
|
113 |
$opts['show_images'] = isset( $instance['show_images'] ) ? $instance['show_images'] : false;
|
114 |
-
$rawtweets =
|
115 |
|
116 |
if ( isset( $rawtweets['error'] ) ) {
|
117 |
-
$return .=
|
118 |
} else {
|
119 |
-
|
120 |
$tweets = array();
|
121 |
foreach ( $rawtweets as $tweet ) {
|
122 |
|
123 |
if ( is_object( $tweet ) ) {
|
124 |
$tweet = json_decode( json_encode( $tweet ), true );
|
125 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
if ( $instance['source'] ) {
|
127 |
-
$source
|
128 |
-
|
|
|
129 |
} else {
|
130 |
-
|
|
|
131 |
}
|
132 |
$tweet_classes = wpt_generate_classes( $tweet );
|
133 |
|
134 |
$intents = ( $instance['intents'] ) ? "<div class='wpt-intents-border'></div><div class='wpt-intents'><a class='wpt-reply' href='https://twitter.com/intent/tweet?in_reply_to=$tweet[id_str]'><span></span><span class='intent-text reply-text'>Reply</span></a> <a class='wpt-retweet' href='https://twitter.com/intent/retweet?tweet_id=$tweet[id_str]'><span></span><span class='intent-text retweet-text'>Retweet</span></a> <a class='wpt-favorite' href='https://twitter.com/intent/favorite?tweet_id=$tweet[id_str]'><span></span><span class='intent-text favorite-text'>Favorite</span></a></div>" : '';
|
135 |
-
|
136 |
$before_tweet = apply_filters( 'wpt_before_tweet', '', $tweet );
|
137 |
$after_tweet = apply_filters( 'wpt_after_tweet', '', $tweet );
|
138 |
$tweets[] = '<li class="' . $tweet_classes . '">' . $before_tweet . wpt_tweet_linkify( $tweet['text'], $opts, $tweet ) . "<br /><span class='wpt-tweet-time'>$timetweet</span> $intents " . $after_tweet . "</li>\n";
|
@@ -147,486 +298,3 @@ function wpt_twitter_feed( $instance ) {
|
|
147 |
|
148 |
return $return;
|
149 |
}
|
150 |
-
|
151 |
-
|
152 |
-
class WPT_Latest_Tweets_Widget extends WP_Widget {
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Holds widget settings defaults, populated in constructor.
|
156 |
-
*
|
157 |
-
* @var array
|
158 |
-
*/
|
159 |
-
protected $defaults;
|
160 |
-
|
161 |
-
/**
|
162 |
-
* Constructor. Set the default widget options and create widget.
|
163 |
-
*
|
164 |
-
* @since 0.1.8
|
165 |
-
*/
|
166 |
-
function __construct() {
|
167 |
-
|
168 |
-
$this->defaults = array(
|
169 |
-
'title' => '',
|
170 |
-
'twitter_id' => '',
|
171 |
-
'twitter_num' => '',
|
172 |
-
'twitter_duration' => '',
|
173 |
-
'twitter_hide_replies' => 0,
|
174 |
-
'twitter_include_rts' => 0,
|
175 |
-
'link_links' => '',
|
176 |
-
'link_mentions' => '',
|
177 |
-
'link_hashtags' => '',
|
178 |
-
'intents' => '',
|
179 |
-
'source' => '',
|
180 |
-
'show_images' => '',
|
181 |
-
'hide_header' => 0
|
182 |
-
);
|
183 |
-
|
184 |
-
$widget_ops = array(
|
185 |
-
'classname' => 'wpt-latest-tweets',
|
186 |
-
'description' => __( 'Display a list of your latest tweets.', 'wp-to-twitter' ),
|
187 |
-
'customize_selective_refresh' => true
|
188 |
-
);
|
189 |
-
|
190 |
-
$control_ops = array(
|
191 |
-
'id_base' => 'wpt-latest-tweets',
|
192 |
-
'width' => 200,
|
193 |
-
'height' => 250,
|
194 |
-
);
|
195 |
-
parent::__construct( 'wpt-latest-tweets', __( 'WP to Twitter - Latest Tweets', 'wp-to-twitter' ), $widget_ops, $control_ops );
|
196 |
-
}
|
197 |
-
|
198 |
-
/**
|
199 |
-
* Echo the widget content.
|
200 |
-
*
|
201 |
-
* @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
|
202 |
-
* @param array $instance The settings for the particular instance of the widget
|
203 |
-
*/
|
204 |
-
|
205 |
-
function widget( $args, $instance ) {
|
206 |
-
extract( $args );
|
207 |
-
wp_enqueue_script( 'twitter-platform', "https://platform.twitter.com/widgets.js" );
|
208 |
-
/** Merge with defaults */
|
209 |
-
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
210 |
-
|
211 |
-
echo $before_widget;
|
212 |
-
if ( $instance['title'] ) {
|
213 |
-
echo $before_title . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $after_title;
|
214 |
-
}
|
215 |
-
echo wpt_twitter_feed( $instance );
|
216 |
-
echo $after_widget;
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Update a particular instance.
|
221 |
-
*
|
222 |
-
* This function should check that $new_instance is set correctly.
|
223 |
-
* The newly calculated value of $instance should be returned.
|
224 |
-
* If "false" is returned, the instance won't be saved/updated.
|
225 |
-
*
|
226 |
-
* @since 0.1
|
227 |
-
*
|
228 |
-
* @param array $new_instance New settings for this instance as input by the user via form()
|
229 |
-
* @param array $old_instance Old settings for this instance
|
230 |
-
*
|
231 |
-
* @return array Settings to save or bool false to cancel saving
|
232 |
-
*/
|
233 |
-
function update( $new_instance, $old_instance ) {
|
234 |
-
/** Force the cache to refresh */
|
235 |
-
update_option( 'wpt_delete_cache', 'true' );
|
236 |
-
$new_instance['title'] = strip_tags( $new_instance['title'] );
|
237 |
-
|
238 |
-
return $new_instance;
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* Echo the settings update form.
|
243 |
-
*
|
244 |
-
* @param array $instance Current settings
|
245 |
-
*
|
246 |
-
* @return string
|
247 |
-
*/
|
248 |
-
function form( $instance ) {
|
249 |
-
|
250 |
-
/** Merge with defaults */
|
251 |
-
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
252 |
-
?>
|
253 |
-
<p>
|
254 |
-
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title', 'wp-to-twitter' ); ?>:</label>
|
255 |
-
<input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>"
|
256 |
-
name="<?php echo $this->get_field_name( 'title' ); ?>"
|
257 |
-
value="<?php echo esc_attr( $instance['title'] ); ?>" class="widefat"/>
|
258 |
-
</p>
|
259 |
-
|
260 |
-
<p>
|
261 |
-
<label
|
262 |
-
for="<?php echo $this->get_field_id( 'twitter_id' ); ?>"><?php _e( 'Twitter Username', 'wp-to-twitter' ); ?>
|
263 |
-
:</label>
|
264 |
-
<input type="text" id="<?php echo $this->get_field_id( 'twitter_id' ); ?>"
|
265 |
-
name="<?php echo $this->get_field_name( 'twitter_id' ); ?>"
|
266 |
-
value="<?php echo esc_attr( $instance['twitter_id'] ); ?>" class="widefat"/>
|
267 |
-
</p>
|
268 |
-
|
269 |
-
<p>
|
270 |
-
<input id="<?php echo $this->get_field_id( 'hide_header' ); ?>" type="checkbox"
|
271 |
-
name="<?php echo $this->get_field_name( 'hide_header' ); ?>"
|
272 |
-
value="1" <?php checked( $instance['hide_header'], 1 ); ?>/>
|
273 |
-
<label
|
274 |
-
for="<?php echo $this->get_field_id( 'hide_header' ); ?>"><?php _e( 'Hide Widget Header', 'wp-to-twitter' ); ?></label>
|
275 |
-
</p>
|
276 |
-
|
277 |
-
<p>
|
278 |
-
<label
|
279 |
-
for="<?php echo $this->get_field_id( 'twitter_num' ); ?>"><?php _e( 'Number of Tweets to Show', 'wp-to-twitter' ); ?>
|
280 |
-
:</label>
|
281 |
-
<input type="text" id="<?php echo $this->get_field_id( 'twitter_num' ); ?>"
|
282 |
-
name="<?php echo $this->get_field_name( 'twitter_num' ); ?>"
|
283 |
-
value="<?php echo esc_attr( $instance['twitter_num'] ); ?>" size="3"/>
|
284 |
-
</p>
|
285 |
-
|
286 |
-
<p>
|
287 |
-
<input id="<?php echo $this->get_field_id( 'twitter_hide_replies' ); ?>" type="checkbox"
|
288 |
-
name="<?php echo $this->get_field_name( 'twitter_hide_replies' ); ?>"
|
289 |
-
value="1" <?php checked( $instance['twitter_hide_replies'], 1 ); ?>/>
|
290 |
-
<label
|
291 |
-
for="<?php echo $this->get_field_id( 'twitter_hide_replies' ); ?>"><?php _e( 'Hide @ Replies', 'wp-to-twitter' ); ?></label>
|
292 |
-
</p>
|
293 |
-
|
294 |
-
<p>
|
295 |
-
<input id="<?php echo $this->get_field_id( 'twitter_include_rts' ); ?>" type="checkbox"
|
296 |
-
name="<?php echo $this->get_field_name( 'twitter_include_rts' ); ?>"
|
297 |
-
value="1" <?php checked( $instance['twitter_include_rts'], 1 ); ?>/>
|
298 |
-
<label
|
299 |
-
for="<?php echo $this->get_field_id( 'twitter_include_rts' ); ?>"><?php _e( 'Include Retweets', 'wp-to-twitter' ); ?></label>
|
300 |
-
</p>
|
301 |
-
|
302 |
-
<p>
|
303 |
-
<input id="<?php echo $this->get_field_id( 'link_links' ); ?>" type="checkbox"
|
304 |
-
name="<?php echo $this->get_field_name( 'link_links' ); ?>"
|
305 |
-
value="1" <?php checked( $instance['link_links'], 1 ); ?>/>
|
306 |
-
<label
|
307 |
-
for="<?php echo $this->get_field_id( 'link_links' ); ?>"><?php _e( 'Parse links', 'wp-to-twitter' ); ?></label>
|
308 |
-
</p>
|
309 |
-
|
310 |
-
<p>
|
311 |
-
<input id="<?php echo $this->get_field_id( 'link_mentions' ); ?>" type="checkbox"
|
312 |
-
name="<?php echo $this->get_field_name( 'link_mentions' ); ?>"
|
313 |
-
value="1" <?php checked( $instance['link_mentions'], 1 ); ?>/>
|
314 |
-
<label
|
315 |
-
for="<?php echo $this->get_field_id( 'link_mentions' ); ?>"><?php _e( 'Parse @mentions', 'wp-to-twitter' ); ?></label>
|
316 |
-
</p>
|
317 |
-
|
318 |
-
<p>
|
319 |
-
<input id="<?php echo $this->get_field_id( 'show_images' ); ?>" type="checkbox"
|
320 |
-
name="<?php echo $this->get_field_name( 'show_images' ); ?>"
|
321 |
-
value="1" <?php checked( $instance['show_images'], 1 ); ?>/>
|
322 |
-
<label
|
323 |
-
for="<?php echo $this->get_field_id( 'show_images' ); ?>"><?php _e( 'Show Images', 'wp-to-twitter' ); ?></label>
|
324 |
-
</p>
|
325 |
-
|
326 |
-
<p>
|
327 |
-
<input id="<?php echo $this->get_field_id( 'link_hashtags' ); ?>" type="checkbox"
|
328 |
-
name="<?php echo $this->get_field_name( 'link_hashtags' ); ?>"
|
329 |
-
value="1" <?php checked( $instance['link_hashtags'], 1 ); ?>/>
|
330 |
-
<label
|
331 |
-
for="<?php echo $this->get_field_id( 'link_hashtags' ); ?>"><?php _e( 'Parse #hashtags', 'wp-to-twitter' ); ?></label>
|
332 |
-
</p>
|
333 |
-
|
334 |
-
<p>
|
335 |
-
<input id="<?php echo $this->get_field_id( 'intents' ); ?>" type="checkbox"
|
336 |
-
name="<?php echo $this->get_field_name( 'intents' ); ?>"
|
337 |
-
value="1" <?php checked( $instance['intents'], 1 ); ?>/>
|
338 |
-
<label
|
339 |
-
for="<?php echo $this->get_field_id( 'intents' ); ?>"><?php _e( 'Include Reply/Retweet/Favorite Links', 'wp-to-twitter' ); ?></label>
|
340 |
-
</p>
|
341 |
-
|
342 |
-
<p>
|
343 |
-
<input id="<?php echo $this->get_field_id( 'source' ); ?>" type="checkbox"
|
344 |
-
name="<?php echo $this->get_field_name( 'source' ); ?>"
|
345 |
-
value="1" <?php checked( $instance['source'], 1 ); ?>/>
|
346 |
-
<label
|
347 |
-
for="<?php echo $this->get_field_id( 'source' ); ?>"><?php _e( 'Include Tweet source', 'wp-to-twitter' ); ?></label>
|
348 |
-
</p>
|
349 |
-
<p>
|
350 |
-
<input id="<?php echo $this->get_field_id( 'cache' ); ?>" type="checkbox" name="<?php echo $this->get_field_name( 'cache' ); ?>" value="1" />
|
351 |
-
<label for="<?php echo $this->get_field_id( 'cache' ); ?>"><?php _e( 'Clear cache', 'wp-to-twitter' ); ?></label>
|
352 |
-
</p>
|
353 |
-
<?php
|
354 |
-
}
|
355 |
-
}
|
356 |
-
|
357 |
-
add_action( 'widgets_init', 'wpt_register_widgets' );
|
358 |
-
function wpt_register_widgets() {
|
359 |
-
register_widget( 'WPT_Latest_Tweets_Widget' );
|
360 |
-
register_widget( 'WPT_Search_Tweets_Widget' );
|
361 |
-
}
|
362 |
-
|
363 |
-
class WPT_Search_Tweets_Widget extends WP_Widget {
|
364 |
-
|
365 |
-
/**
|
366 |
-
* Holds widget settings defaults, populated in constructor.
|
367 |
-
*
|
368 |
-
* @var array
|
369 |
-
*/
|
370 |
-
protected $defaults;
|
371 |
-
|
372 |
-
/**
|
373 |
-
* Constructor. Set the default widget options and create widget.
|
374 |
-
*
|
375 |
-
* @since 0.1.8
|
376 |
-
*/
|
377 |
-
function __construct() {
|
378 |
-
|
379 |
-
$this->defaults = array(
|
380 |
-
'title' => '',
|
381 |
-
'twitter_num' => '',
|
382 |
-
'search' => '',
|
383 |
-
'result_type' => 'recent', // mixed, recent, popular
|
384 |
-
'geocode' => '', // 37.777,-127.98,2km
|
385 |
-
'link_links' => '',
|
386 |
-
'link_mentions' => '',
|
387 |
-
'link_hashtags' => '',
|
388 |
-
'intents' => '',
|
389 |
-
'source' => ''
|
390 |
-
);
|
391 |
-
|
392 |
-
$widget_ops = array(
|
393 |
-
'classname' => 'wpt-search-tweets',
|
394 |
-
'description' => __( 'Display a list of tweets returned by a search.', 'wp-to-twitter' ),
|
395 |
-
'customize_selective_refresh' => true
|
396 |
-
);
|
397 |
-
|
398 |
-
$control_ops = array(
|
399 |
-
'id_base' => 'wpt-search-tweets',
|
400 |
-
'width' => 200,
|
401 |
-
'height' => 250,
|
402 |
-
);
|
403 |
-
parent::__construct( 'wpt-search-tweets', __( 'WP to Twitter - Searched Tweets', 'wp-to-twitter' ), $widget_ops, $control_ops );
|
404 |
-
}
|
405 |
-
|
406 |
-
/**
|
407 |
-
* Echo the widget content.
|
408 |
-
*
|
409 |
-
* @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
|
410 |
-
* @param array $instance The settings for the particular instance of the widget
|
411 |
-
*/
|
412 |
-
|
413 |
-
function widget( $args, $instance ) {
|
414 |
-
extract( $args );
|
415 |
-
wp_enqueue_script( 'twitter-platform', "https://platform.twitter.com/widgets.js" );
|
416 |
-
/** Merge with defaults */
|
417 |
-
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
418 |
-
echo $before_widget;
|
419 |
-
if ( $instance['title'] ) {
|
420 |
-
echo $before_title . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $after_title;
|
421 |
-
}
|
422 |
-
echo wpt_twitter_feed( $instance );
|
423 |
-
echo $after_widget;
|
424 |
-
}
|
425 |
-
|
426 |
-
/**
|
427 |
-
* Update a particular instance.
|
428 |
-
*
|
429 |
-
* This function should check that $new_instance is set correctly.
|
430 |
-
* The newly calculated value of $instance should be returned.
|
431 |
-
* If "false" is returned, the instance won't be saved/updated.
|
432 |
-
*
|
433 |
-
* @since 0.1
|
434 |
-
*
|
435 |
-
* @param array $new_instance New settings for this instance as input by the user via form()
|
436 |
-
* @param array $old_instance Old settings for this instance
|
437 |
-
*
|
438 |
-
* @return array Settings to save or bool false to cancel saving
|
439 |
-
*/
|
440 |
-
function update( $new_instance, $old_instance ) {
|
441 |
-
/** Force the cache to refresh */
|
442 |
-
update_option( 'wpt_delete_cache', 'true' );
|
443 |
-
$new_instance['title'] = strip_tags( $new_instance['title'] );
|
444 |
-
|
445 |
-
return $new_instance;
|
446 |
-
}
|
447 |
-
|
448 |
-
/**
|
449 |
-
* Echo the settings update form.
|
450 |
-
*
|
451 |
-
* @param array $instance Current settings
|
452 |
-
*/
|
453 |
-
function form( $instance ) {
|
454 |
-
|
455 |
-
/** Merge with defaults */
|
456 |
-
$instance = wp_parse_args( (array) $instance, $this->defaults );
|
457 |
-
|
458 |
-
?>
|
459 |
-
<p>
|
460 |
-
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title', 'wp-to-twitter' ); ?>:</label>
|
461 |
-
<input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>"
|
462 |
-
name="<?php echo $this->get_field_name( 'title' ); ?>"
|
463 |
-
value="<?php echo esc_attr( $instance['title'] ); ?>" class="widefat"/>
|
464 |
-
</p>
|
465 |
-
|
466 |
-
<p>
|
467 |
-
<label for="<?php echo $this->get_field_id( 'search' ); ?>"><?php _e( 'Search String', 'wp-to-twitter' ); ?>
|
468 |
-
:</label>
|
469 |
-
<input type="text" id="<?php echo $this->get_field_id( 'search' ); ?>"
|
470 |
-
name="<?php echo $this->get_field_name( 'search' ); ?>"
|
471 |
-
value="<?php echo esc_attr( $instance['search'] ); ?>" class="widefat"/>
|
472 |
-
</p>
|
473 |
-
|
474 |
-
<p>
|
475 |
-
<label
|
476 |
-
for="<?php echo $this->get_field_id( 'twitter_num' ); ?>"><?php _e( 'Number of Tweets to Show', 'wp-to-twitter' ); ?>
|
477 |
-
:</label>
|
478 |
-
<input type="text" id="<?php echo $this->get_field_id( 'twitter_num' ); ?>"
|
479 |
-
name="<?php echo $this->get_field_name( 'twitter_num' ); ?>"
|
480 |
-
value="<?php echo esc_attr( $instance['twitter_num'] ); ?>" size="3"/>
|
481 |
-
</p>
|
482 |
-
|
483 |
-
<p>
|
484 |
-
<label
|
485 |
-
for="<?php echo $this->get_field_id( 'result_type' ); ?>"><?php _e( 'Type of Results', 'wp-to-twitter' ); ?></label>
|
486 |
-
<select name="<?php echo $this->get_field_name( 'result_type' ); ?>"
|
487 |
-
id="<?php echo $this->get_field_id( 'result_type' ); ?>">
|
488 |
-
<option
|
489 |
-
value='recent'<?php echo ( $instance['result_type'] == 'recent' ) ? ' selected="selected"' : ''; ?>><?php _e( 'Recent Tweets', 'wp-to-twitter' ); ?></option>
|
490 |
-
<option
|
491 |
-
value='popular'<?php echo ( $instance['result_type'] == 'popular' ) ? ' selected="selected"' : ''; ?>><?php _e( 'Popular Tweets', 'wp-to-twitter' ); ?></option>
|
492 |
-
<option
|
493 |
-
value='mixed'<?php echo ( $instance['result_type'] == 'mixed' ) ? ' selected="selected"' : ''; ?>><?php _e( 'Mixed', 'wp-to-twitter' ); ?></option>
|
494 |
-
</select>
|
495 |
-
</p>
|
496 |
-
|
497 |
-
<p>
|
498 |
-
<label
|
499 |
-
for="<?php echo $this->get_field_id( 'geocode' ); ?>"><?php _e( 'Geocode (Latitude,Longitude,Radius)', 'wp-to-twitter' ); ?>
|
500 |
-
:</label>
|
501 |
-
<input type="text" id="<?php echo $this->get_field_id( 'geocode' ); ?>"
|
502 |
-
class="widefat"
|
503 |
-
name="<?php echo $this->get_field_name( 'geocode' ); ?>"
|
504 |
-
value="<?php echo esc_attr( $instance['geocode'] ); ?>" size="32"
|
505 |
-
placeholder="37.781157,-122.398720,2km"/>
|
506 |
-
</p>
|
507 |
-
|
508 |
-
<p>
|
509 |
-
<input id="<?php echo $this->get_field_id( 'link_links' ); ?>" type="checkbox"
|
510 |
-
name="<?php echo $this->get_field_name( 'link_links' ); ?>"
|
511 |
-
value="1" <?php checked( $instance['link_links'] ); ?>/>
|
512 |
-
<label
|
513 |
-
for="<?php echo $this->get_field_id( 'link_links' ); ?>"><?php _e( 'Parse links', 'wp-to-twitter' ); ?></label>
|
514 |
-
</p>
|
515 |
-
|
516 |
-
<p>
|
517 |
-
<input id="<?php echo $this->get_field_id( 'link_mentions' ); ?>" type="checkbox"
|
518 |
-
name="<?php echo $this->get_field_name( 'link_mentions' ); ?>"
|
519 |
-
value="1" <?php checked( $instance['link_mentions'] ); ?>/>
|
520 |
-
<label
|
521 |
-
for="<?php echo $this->get_field_id( 'link_mentions' ); ?>"><?php _e( 'Parse @mentions', 'wp-to-twitter' ); ?></label>
|
522 |
-
</p>
|
523 |
-
|
524 |
-
<p>
|
525 |
-
<input id="<?php echo $this->get_field_id( 'link_hashtags' ); ?>" type="checkbox"
|
526 |
-
name="<?php echo $this->get_field_name( 'link_hashtags' ); ?>"
|
527 |
-
value="1" <?php checked( $instance['link_hashtags'] ); ?>/>
|
528 |
-
<label
|
529 |
-
for="<?php echo $this->get_field_id( 'link_hashtags' ); ?>"><?php _e( 'Parse #hashtags', 'wp-to-twitter' ); ?></label>
|
530 |
-
</p>
|
531 |
-
|
532 |
-
<p>
|
533 |
-
<input id="<?php echo $this->get_field_id( 'intents' ); ?>" type="checkbox"
|
534 |
-
name="<?php echo $this->get_field_name( 'intents' ); ?>"
|
535 |
-
value="1" <?php checked( $instance['intents'] ); ?>/>
|
536 |
-
<label
|
537 |
-
for="<?php echo $this->get_field_id( 'intents' ); ?>"><?php _e( 'Include Reply/Retweet/Favorite Links', 'wp-to-twitter' ); ?></label>
|
538 |
-
</p>
|
539 |
-
|
540 |
-
<p>
|
541 |
-
<input id="<?php echo $this->get_field_id( 'source' ); ?>" type="checkbox"
|
542 |
-
name="<?php echo $this->get_field_name( 'source' ); ?>"
|
543 |
-
value="1" <?php checked( $instance['source'] ); ?>/>
|
544 |
-
<label
|
545 |
-
for="<?php echo $this->get_field_id( 'source' ); ?>"><?php _e( 'Include Tweet source', 'wp-to-twitter' ); ?></label>
|
546 |
-
</p>
|
547 |
-
<?php
|
548 |
-
}
|
549 |
-
}
|
550 |
-
|
551 |
-
/**
|
552 |
-
* Adds links to the contents of a tweet.
|
553 |
-
* Forked from genesis_tweet_linkify, removed target = _blank
|
554 |
-
*
|
555 |
-
* Takes the content of a tweet, detects @replies, #hashtags, and
|
556 |
-
* http:// links, and links them appropriately.
|
557 |
-
*
|
558 |
-
* @since 0.1
|
559 |
-
*
|
560 |
-
* @link http://www.snipe.net/2009/09/php-twitter-clickable-links/
|
561 |
-
*
|
562 |
-
* @param string $text A string representing the content of a tweet
|
563 |
-
*
|
564 |
-
* @return string Linkified tweet content
|
565 |
-
*/
|
566 |
-
function wpt_tweet_linkify( $text, $opts, $tweet ) {
|
567 |
-
if ( $opts['show_images'] == true ) {
|
568 |
-
$media = isset( $tweet['entities']['media'] ) ? $tweet['entities']['media'] : false;
|
569 |
-
if ( $media ) {
|
570 |
-
$media_urls = array();
|
571 |
-
if ( !empty( $media ) ) {
|
572 |
-
foreach ( $media as $key => $image ) {
|
573 |
-
$media_urls[] = $image['url'];
|
574 |
-
// alt attributes are not available on Twitter.
|
575 |
-
$alt = isset( $tweet['extended_entities']['media'][$key]['ext_alt_text'] ) ? $tweet['extended_entities']['media'][$key]['ext_alt_text'] : '';
|
576 |
-
$text .= "<img src='$image[media_url_https]' alt='$alt' class='wpt-twitter-image' />";
|
577 |
-
}
|
578 |
-
}
|
579 |
-
if ( !empty( $media_urls ) ) {
|
580 |
-
foreach ( $media_urls as $media_url ) {
|
581 |
-
$text = str_replace( "$media_url", '', $text );
|
582 |
-
}
|
583 |
-
}
|
584 |
-
}
|
585 |
-
}
|
586 |
-
$text = ( $opts['links'] == true ) ? preg_replace( "#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", '\\1<a href="\\2" rel="nofollow">\\2</a>', $text ) : $text;
|
587 |
-
$text = ( $opts['links'] == true ) ? preg_replace( "#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", '\\1<a href="http://\\2" rel="nofollow">\\2</a>', $text ) : $text;
|
588 |
-
$text = ( $opts['mentions'] == true ) ? preg_replace( '/@(\w+)/', '<a href="https://twitter.com/\\1" rel="nofollow">@\\1</a>', $text ) : $text;
|
589 |
-
$text = ( $opts['hashtags'] == true ) ? preg_replace( '/#(\w+)/', '<a href="https://twitter.com/search?q=%23\\1" rel="nofollow">#\\1</a>', $text ) : $text;
|
590 |
-
$urls = $tweet['entities']['urls'];
|
591 |
-
if ( is_array( $urls ) ) {
|
592 |
-
foreach ( $urls as $url ) {
|
593 |
-
|
594 |
-
$text = str_replace( ">$url[url]<", ">$url[display_url]<", $text );
|
595 |
-
}
|
596 |
-
}
|
597 |
-
|
598 |
-
return $text;
|
599 |
-
}
|
600 |
-
|
601 |
-
/* implement getTweets */
|
602 |
-
function WPT_getTweets( $count = 20, $username = false, $options = false ) {
|
603 |
-
|
604 |
-
$config['key'] = get_option( 'app_consumer_key' );
|
605 |
-
$config['secret'] = get_option( 'app_consumer_secret' );
|
606 |
-
$config['token'] = get_option( 'oauth_token' );
|
607 |
-
$config['token_secret'] = get_option( 'oauth_token_secret' );
|
608 |
-
$config['screenname'] = get_option( 'wtt_twitter_username' );
|
609 |
-
$config['cache_expire'] = intval( apply_filters( 'wpt_cache_expire', 1800 ) );
|
610 |
-
if ( $config['cache_expire'] < 1 ) {
|
611 |
-
$config['cache_expire'] = 1800;
|
612 |
-
}
|
613 |
-
$config['directory'] = plugin_dir_path( __FILE__ );
|
614 |
-
|
615 |
-
$obj = new WPT_TwitterFeed( $config );
|
616 |
-
$res = $obj->getTweets( $count, $username, $options );
|
617 |
-
update_option( 'wpt_tdf_last_error', $obj->st_last_error );
|
618 |
-
|
619 |
-
return $res;
|
620 |
-
|
621 |
-
}
|
622 |
-
|
623 |
-
function wpt_generate_classes( $tweet ) {
|
624 |
-
// take Tweet array and parse selected options into classes.
|
625 |
-
$classes[] = ( $tweet['favorited'] ) ? 'favorited' : '';
|
626 |
-
$clasees[] = ( $tweet['retweeted'] ) ? 'retweeted' : '';
|
627 |
-
$classes[] = ( isset( $tweet['possibly_sensitive'] ) && $tweet['possibly_sensitive'] ) ? 'sensitive' : '';
|
628 |
-
$classes[] = 'lang-' . $tweet['lang'];
|
629 |
-
$class = trim( implode( ' ', $classes ) );
|
630 |
-
|
631 |
-
return $class;
|
632 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP to Twitter Widgets
|
4 |
+
*
|
5 |
+
* @category Widgets
|
6 |
+
* @package WP to Twitter
|
7 |
+
* @author Joe Dolson
|
8 |
+
* @license GPLv2 or later
|
9 |
+
* @link https://www.joedolson.com/wp-to-twitter/
|
10 |
+
*/
|
11 |
+
|
12 |
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
require_once( dirname( __FILE__ ) . '/classes/class-wpt-latest-tweets-widget.php' );
|
17 |
+
require_once( dirname( __FILE__ ) . '/classes/class-wpt-search-tweets-widget.php' );
|
18 |
|
19 |
/**
|
20 |
+
* Adds links to the contents of a tweet.
|
21 |
+
* Forked from genesis_tweet_linkify, removed target = _blank
|
22 |
+
*
|
23 |
+
* Takes the content of a tweet, detects @replies, #hashtags, and
|
24 |
+
* http:// links, and links them appropriately.
|
25 |
+
*
|
26 |
+
* @since 0.1
|
27 |
+
*
|
28 |
+
* @link http://www.snipe.net/2009/09/php-twitter-clickable-links/
|
29 |
+
*
|
30 |
+
* @param string $text A string representing the content of a tweet.
|
31 |
+
* @param array $opts Array of options.
|
32 |
+
* @param array $tweet Array of Tweet information.
|
33 |
+
*
|
34 |
+
* @return string Linkified tweet content
|
35 |
*/
|
36 |
+
function wpt_tweet_linkify( $text, $opts, $tweet ) {
|
37 |
+
if ( true == $opts['show_images'] ) {
|
38 |
+
$media = isset( $tweet['entities']['media'] ) ? $tweet['entities']['media'] : false;
|
39 |
+
if ( $media ) {
|
40 |
+
$media_urls = array();
|
41 |
+
if ( ! empty( $media ) ) {
|
42 |
+
foreach ( $media as $key => $image ) {
|
43 |
+
$media_urls[] = $image['url'];
|
44 |
+
$alt = isset( $tweet['extended_entities']['media'][ $key ]['ext_alt_text'] ) ? $tweet['extended_entities']['media'][ $key ]['ext_alt_text'] : '';
|
45 |
+
$text .= "<img src='$image[media_url_https]' alt='$alt' class='wpt-twitter-image' />";
|
46 |
|
47 |
+
}
|
48 |
+
}
|
49 |
+
if ( ! empty( $media_urls ) ) {
|
50 |
+
foreach ( $media_urls as $media_url ) {
|
51 |
+
$text = str_replace( $media_url, '', $text );
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
$restore = false;
|
57 |
+
if ( false !== strpos( $text, '…' ) ) {
|
58 |
+
$text = str_replace( '…', ' ______ ', $text );
|
59 |
+
$restore = true;
|
60 |
+
}
|
61 |
+
$text = ( true == $opts['links'] ) ? preg_replace( '#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#', '\\1<a href="\\2" rel="nofollow">\\2</a>', $text ) : $text;
|
62 |
+
$text = ( true == $opts['links'] ) ? preg_replace( '#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#', '\\1<a href="http://\\2" rel="nofollow">\\2</a>', $text ) : $text;
|
63 |
+
$text = ( true == $opts['mentions'] ) ? preg_replace( '/@(\w+)/', '<a href="https://twitter.com/\\1" rel="nofollow">@\\1</a>', $text ) : $text;
|
64 |
+
$text = ( true == $opts['hashtags'] ) ? preg_replace( '/#(\w+)/', '<a href="https://twitter.com/search?q=%23\\1" rel="nofollow">#\\1</a>', $text ) : $text;
|
65 |
+
$urls = $tweet['entities']['urls'];
|
66 |
+
if ( is_array( $urls ) ) {
|
67 |
+
foreach ( $urls as $url ) {
|
68 |
+
$text = str_replace( ">$url[url]<", ">$url[display_url]<", $text );
|
69 |
+
}
|
70 |
+
}
|
71 |
+
if ( true == $restore ) {
|
72 |
+
$text = str_replace( ' ______ ', '…', $text );
|
73 |
+
}
|
74 |
+
|
75 |
+
return $text;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Implement get_tweets
|
80 |
+
*
|
81 |
+
* @param int $count How many Tweets.
|
82 |
+
* @param string $username Username passed.
|
83 |
+
* @param array $options Widget options.
|
84 |
+
*
|
85 |
+
* @return Tweets.
|
86 |
+
*/
|
87 |
+
function wpt_get_tweets( $count = 20, $username = false, $options = false ) {
|
88 |
+
|
89 |
+
$config['key'] = get_option( 'app_consumer_key' );
|
90 |
+
$config['secret'] = get_option( 'app_consumer_secret' );
|
91 |
+
$config['token'] = get_option( 'oauth_token' );
|
92 |
+
$config['token_secret'] = get_option( 'oauth_token_secret' );
|
93 |
+
$config['screenname'] = get_option( 'wtt_twitter_username' );
|
94 |
+
$config['cache_expire'] = intval( apply_filters( 'wpt_cache_expire', 1800 ) );
|
95 |
+
if ( $config['cache_expire'] < 1 ) {
|
96 |
+
$config['cache_expire'] = 1800;
|
97 |
+
}
|
98 |
+
$config['directory'] = plugin_dir_path( __FILE__ );
|
99 |
+
|
100 |
+
$obj = new WPT_TwitterFeed( $config );
|
101 |
+
$res = $obj->get_tweets( $count, $username, $options );
|
102 |
+
update_option( 'wpt_tdf_last_error', $obj->st_last_error );
|
103 |
+
|
104 |
+
return $res;
|
105 |
+
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Generate relevant classes for a Tweet.
|
110 |
+
*
|
111 |
+
* @param array $tweet Tweet info.
|
112 |
+
*
|
113 |
+
* @return array classes.
|
114 |
+
*/
|
115 |
+
function wpt_generate_classes( $tweet ) {
|
116 |
+
// take Tweet array and parse selected options into classes.
|
117 |
+
$classes[] = ( $tweet['favorited'] ) ? 'favorited' : '';
|
118 |
+
$clasees[] = ( $tweet['retweeted'] ) ? 'retweeted' : '';
|
119 |
+
$classes[] = ( isset( $tweet['possibly_sensitive'] ) && $tweet['possibly_sensitive'] ) ? 'sensitive' : '';
|
120 |
+
$classes[] = 'lang-' . $tweet['lang'];
|
121 |
+
$class = trim( implode( ' ', $classes ) );
|
122 |
+
|
123 |
+
return $class;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Get information about user.
|
128 |
+
*
|
129 |
+
* @param string $twitter_id Twitter screen name.
|
130 |
+
*
|
131 |
+
* @return array
|
132 |
+
*/
|
133 |
+
function wpt_get_user( $twitter_id = false ) {
|
134 |
+
if ( ! $twitter_id ) {
|
135 |
return;
|
136 |
}
|
137 |
+
$options = array( 'screen_name' => $twitter_id );
|
138 |
$key = get_option( 'app_consumer_key' );
|
139 |
$secret = get_option( 'app_consumer_secret' );
|
140 |
$token = get_option( 'oauth_token' );
|
141 |
$token_secret = get_option( 'oauth_token_secret' );
|
142 |
if ( $key && $secret && $token && $token_secret ) {
|
143 |
+
$connection = new Wpt_TwitterOAuth( $key, $secret, $token, $token_secret );
|
144 |
+
$result = $connection->get( "https://api.twitter.com/1.1/users/show.json?screen_name=$twitter_id&include_ext_alt_text=true", $options );
|
145 |
|
146 |
return json_decode( $result );
|
147 |
} else {
|
150 |
}
|
151 |
|
152 |
add_shortcode( 'get_tweets', 'wpt_get_twitter_feed' );
|
153 |
+
/**
|
154 |
+
* Get a Twitter Feed.
|
155 |
+
*
|
156 |
+
* @param array $atts Display attributes.
|
157 |
+
* @param string $content Fallback content.
|
158 |
+
*
|
159 |
+
* @return Twitter feed.
|
160 |
+
*/
|
161 |
function wpt_get_twitter_feed( $atts, $content ) {
|
162 |
+
$atts = ( shortcode_atts( array(
|
163 |
+
'id' => false,
|
164 |
+
'num' => 10,
|
165 |
+
'duration' => 1800,
|
166 |
+
'replies' => 0,
|
167 |
+
'rts' => 1,
|
168 |
+
'links' => 1,
|
169 |
+
'mentions' => 1,
|
170 |
+
'hashtags' => 0,
|
171 |
+
'intents' => 1,
|
172 |
+
'source' => 0,
|
173 |
'show_images' => 1,
|
174 |
+
'hide_header' => 0,
|
175 |
), $atts, 'get_tweets' ) );
|
176 |
$instance = array(
|
177 |
+
'twitter_id' => $atts['id'],
|
178 |
+
'twitter_num' => $atts['num'],
|
179 |
+
'twitter_duration' => $atts['duration'],
|
180 |
+
'twitter_hide_replies' => $atts['replies'],
|
181 |
+
'twitter_include_rts' => $atts['rts'],
|
182 |
+
'link_links' => $atts['links'],
|
183 |
+
'link_mentions' => $atts['mentions'],
|
184 |
+
'link_hashtags' => $atts['hashtags'],
|
185 |
+
'intents' => $atts['intents'],
|
186 |
+
'source' => $atts['source'],
|
187 |
+
'show_images' => $atts['show_images'],
|
188 |
+
'hide_header' => $atts['hide_header'],
|
189 |
);
|
190 |
|
191 |
return wpt_twitter_feed( $instance );
|
192 |
}
|
193 |
|
194 |
+
/**
|
195 |
+
* Get the twitter feed data.
|
196 |
+
*
|
197 |
+
* @param array $instance Config for this instance.
|
198 |
+
*
|
199 |
+
* @return string.
|
200 |
+
*/
|
201 |
function wpt_twitter_feed( $instance ) {
|
202 |
$header = '';
|
203 |
if ( ! isset( $instance['search'] ) ) {
|
204 |
+
$twitter_id = ( isset( $instance['twitter_id'] ) && '' != $instance['twitter_id'] ) ? $instance['twitter_id'] : get_option( 'wtt_twitter_username' );
|
205 |
+
$user = wpt_get_user( $twitter_id );
|
206 |
if ( empty( $user ) ) {
|
207 |
return __( 'Error: You are not connected to Twitter.', 'wp-to-twitter' );
|
208 |
}
|
209 |
if ( isset( $user->errors ) && $user->errors[0]->message ) {
|
210 |
+
return __( 'Error:', 'wp-to-twitter' ) . ' ' . $user->errors[0]->message;
|
211 |
}
|
212 |
$avatar = $user->profile_image_url_https;
|
213 |
$name = $user->name;
|
214 |
$verified = sanitize_title( $user->verified );
|
215 |
$img_alignment = ( is_rtl() ) ? 'wpt-right' : 'wpt-left';
|
216 |
$follow_alignment = ( is_rtl() ) ? 'wpt-left' : 'wpt-right';
|
217 |
+
$follow_url = esc_url( 'https://twitter.com/' . $twitter_id );
|
218 |
+
$follow_button = apply_filters( 'wpt_follow_button', "<a href='$follow_url' class='twitter-follow-button $follow_alignment' data-width='30px' data-show-screen-name='false' data-size='large' data-show-count='false' data-lang='en'>Follow @" . esc_html( $twitter_id ) . '</a>' );
|
219 |
+
$header .= '<div class="wpt-header">';
|
220 |
+
$header .= "<div class='wpt-follow-button'>$follow_button</div>
|
221 |
<p>
|
222 |
<img src='$avatar' alt='' class='wpt-twitter-avatar $img_alignment $verified' />
|
223 |
<span class='wpt-twitter-name'>$name</span><br />
|
224 |
+
<span class='wpt-twitter-id'><a href='$follow_url'>@" . esc_html( $twitter_id ) . '</a></span>
|
225 |
+
</p>';
|
226 |
+
$header .= '</div>';
|
227 |
} else {
|
228 |
+
$twitter_id = false;
|
229 |
}
|
230 |
+
|
231 |
+
$hide_header = ( isset( $instance['hide_header'] ) && 1 == $instance['hide_header'] ) ? true : false;
|
232 |
+
|
233 |
if ( ! isset( $instance['search'] ) ) {
|
234 |
$options['exclude_replies'] = ( isset( $instance['twitter_hide_replies'] ) ) ? $instance['twitter_hide_replies'] : false;
|
235 |
$options['include_rts'] = $instance['twitter_include_rts'];
|
238 |
$options['geocode'] = $instance['geocode'];
|
239 |
$options['result_type'] = $instance['result_type'];
|
240 |
}
|
241 |
+
|
242 |
if ( $hide_header ) {
|
243 |
+
$header = '';
|
244 |
}
|
245 |
+
|
246 |
+
$return = $header . '<ul>' . "\n";
|
247 |
+
|
248 |
$opts['links'] = $instance['link_links'];
|
249 |
$opts['mentions'] = $instance['link_mentions'];
|
250 |
$opts['hashtags'] = $instance['link_hashtags'];
|
251 |
$opts['show_images'] = isset( $instance['show_images'] ) ? $instance['show_images'] : false;
|
252 |
+
$rawtweets = wpt_get_tweets( $instance['twitter_num'], $twitter_id, $options );
|
253 |
|
254 |
if ( isset( $rawtweets['error'] ) ) {
|
255 |
+
$return .= '<li>' . $rawtweets['error'] . '</li>';
|
256 |
} else {
|
257 |
+
// Build the tweets array.
|
258 |
$tweets = array();
|
259 |
foreach ( $rawtweets as $tweet ) {
|
260 |
|
261 |
if ( is_object( $tweet ) ) {
|
262 |
$tweet = json_decode( json_encode( $tweet ), true );
|
263 |
}
|
264 |
+
|
265 |
+
if ( isset( $tweet['retweeted_status']['user']['id_str'] ) ) {
|
266 |
+
$posted_by = $tweet['retweeted_status']['user']['id_str'];
|
267 |
+
} elseif ( isset( $tweet['in_reply_to_screen_name'] ) ) {
|
268 |
+
$posted_by = $tweet['in_reply_to_screen_name'];
|
269 |
+
} elseif ( isset( $tweet['user']['id_str'] ) ) {
|
270 |
+
$posted_by = $tweet['user']['id_str'];
|
271 |
+
} else {
|
272 |
+
$posted_by = $twitter_id;
|
273 |
+
}
|
274 |
+
|
275 |
if ( $instance['source'] ) {
|
276 |
+
$source = $tweet['source'];
|
277 |
+
// Translators: 1 - time string, 2 - name of Tweet app, 3 - Link to Tweet.
|
278 |
+
$timetweet = sprintf( __( '<a href="%3$s">about %1$s ago</a> via %2$s', 'wp-to-twitter' ), human_time_diff( strtotime( $tweet['created_at'] ) ), $source, 'http://twitter.com/' . $posted_by . "/status/$tweet[id_str]" );
|
279 |
} else {
|
280 |
+
// Translators: 1 - time string; 2 - link to Tweet.
|
281 |
+
$timetweet = sprintf( __( '<a href="%2$s">about %1$s ago</a>', 'wp-to-twitter' ), human_time_diff( strtotime( $tweet['created_at'] ) ), "http://twitter.com/$posted_by/status/$tweet[id_str]" );
|
282 |
}
|
283 |
$tweet_classes = wpt_generate_classes( $tweet );
|
284 |
|
285 |
$intents = ( $instance['intents'] ) ? "<div class='wpt-intents-border'></div><div class='wpt-intents'><a class='wpt-reply' href='https://twitter.com/intent/tweet?in_reply_to=$tweet[id_str]'><span></span><span class='intent-text reply-text'>Reply</span></a> <a class='wpt-retweet' href='https://twitter.com/intent/retweet?tweet_id=$tweet[id_str]'><span></span><span class='intent-text retweet-text'>Retweet</span></a> <a class='wpt-favorite' href='https://twitter.com/intent/favorite?tweet_id=$tweet[id_str]'><span></span><span class='intent-text favorite-text'>Favorite</span></a></div>" : '';
|
286 |
+
// Add tweet to array.
|
287 |
$before_tweet = apply_filters( 'wpt_before_tweet', '', $tweet );
|
288 |
$after_tweet = apply_filters( 'wpt_after_tweet', '', $tweet );
|
289 |
$tweets[] = '<li class="' . $tweet_classes . '">' . $before_tweet . wpt_tweet_linkify( $tweet['text'], $opts, $tweet ) . "<br /><span class='wpt-tweet-time'>$timetweet</span> $intents " . $after_tweet . "</li>\n";
|
298 |
|
299 |
return $return;
|
300 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wpt_twitter_oauth.php
DELETED
@@ -1,368 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
* Abraham Williams (abraham@abrah.am) http://abrah.am
|
4 |
-
*
|
5 |
-
* The first PHP Library to support WPOAuth for Twitter's REST API.
|
6 |
-
*
|
7 |
-
*/
|
8 |
-
|
9 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
-
exit;
|
11 |
-
} // Exit if accessed directly
|
12 |
-
|
13 |
-
require_once( 'WP_OAuth.php' );
|
14 |
-
|
15 |
-
if ( ! class_exists( 'wpt_TwitterOAuth' ) ) {
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Twitter WPOAuth class
|
19 |
-
*/
|
20 |
-
class wpt_TwitterOAuth {
|
21 |
-
/* Contains the last HTTP status code returned */
|
22 |
-
public $http_code;
|
23 |
-
/* Contains the last API call. */
|
24 |
-
public $url;
|
25 |
-
/* Set up the API root URL. */
|
26 |
-
public $host = "https://api.twitter.com/1.1/";
|
27 |
-
/* Set timeout default. */
|
28 |
-
public $format = 'json';
|
29 |
-
/* Decode returned json data. */
|
30 |
-
public $decode_json = false;
|
31 |
-
/* Contains the last API call */
|
32 |
-
private $last_api_call;
|
33 |
-
/* containe the header */
|
34 |
-
public $http_header;
|
35 |
-
/* contains the body */
|
36 |
-
public $body;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Set API URLS
|
40 |
-
*/
|
41 |
-
function accessTokenURL() {
|
42 |
-
return "https://api.twitter.com/oauth/access_token";
|
43 |
-
}
|
44 |
-
|
45 |
-
function authenticateURL() {
|
46 |
-
return "https://api.twitter.com/oauth/authenticate";
|
47 |
-
}
|
48 |
-
|
49 |
-
function authorizeURL() {
|
50 |
-
return "https://api.twitter.com/oauth/authorize";
|
51 |
-
}
|
52 |
-
|
53 |
-
function requestTokenURL() {
|
54 |
-
return "https://api.twitter.com/oauth/request_token";
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Debug helpers
|
59 |
-
*/
|
60 |
-
function lastStatusCode() {
|
61 |
-
return $this->http_code;
|
62 |
-
}
|
63 |
-
|
64 |
-
function lastAPICall() {
|
65 |
-
return $this->last_api_call;
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* construct TwitterWPOAuth object
|
70 |
-
*/
|
71 |
-
function __construct( $consumer_key, $consumer_secret, $WPOAuth_token = null, $WPOAuth_token_secret = null ) {
|
72 |
-
$this->sha1_method = new WPOAuthSignatureMethod_HMAC_SHA1();
|
73 |
-
$this->consumer = new WPOAuthConsumer( $consumer_key, $consumer_secret );
|
74 |
-
if ( ! empty( $WPOAuth_token ) && ! empty( $WPOAuth_token_secret ) ) {
|
75 |
-
$this->token = new WPOAuthConsumer( $WPOAuth_token, $WPOAuth_token_secret );
|
76 |
-
} else {
|
77 |
-
$this->token = null;
|
78 |
-
}
|
79 |
-
}
|
80 |
-
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Get a request_token from Twitter
|
84 |
-
*
|
85 |
-
* @returns a key/value array containing WPOAuth_token and WPOAuth_token_secret
|
86 |
-
*/
|
87 |
-
function getRequestToken() {
|
88 |
-
$r = $this->WPOAuthRequest( $this->requestTokenURL() );
|
89 |
-
$token = $this->WPOAuthParseResponse( $r );
|
90 |
-
$this->token = new WPOAuthConsumer( $token['WPOAuth_token'], $token['WPOAuth_token_secret'] );
|
91 |
-
|
92 |
-
return $token;
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Parse a URL-encoded WPOAuth response
|
97 |
-
*
|
98 |
-
* @return a key/value array
|
99 |
-
*/
|
100 |
-
function WPOAuthParseResponse( $responseString ) {
|
101 |
-
$r = array();
|
102 |
-
foreach ( explode( '&', $responseString ) as $param ) {
|
103 |
-
$pair = explode( '=', $param, 2 );
|
104 |
-
if ( count( $pair ) != 2 ) {
|
105 |
-
continue;
|
106 |
-
}
|
107 |
-
$r[ urldecode( $pair[0] ) ] = urldecode( $pair[1] );
|
108 |
-
}
|
109 |
-
|
110 |
-
return $r;
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Get the authorize URL
|
115 |
-
*
|
116 |
-
* @returns a string
|
117 |
-
*/
|
118 |
-
function getAuthorizeURL( $token ) {
|
119 |
-
if ( is_array( $token ) ) {
|
120 |
-
$token = $token['WPOAuth_token'];
|
121 |
-
}
|
122 |
-
|
123 |
-
return $this->authorizeURL() . '?WPOAuth_token=' . $token;
|
124 |
-
}
|
125 |
-
|
126 |
-
|
127 |
-
/**
|
128 |
-
* Get the authenticate URL
|
129 |
-
*
|
130 |
-
* @returns a string
|
131 |
-
*/
|
132 |
-
function getAuthenticateURL( $token ) {
|
133 |
-
if ( is_array( $token ) ) {
|
134 |
-
$token = $token['WPOAuth_token'];
|
135 |
-
}
|
136 |
-
|
137 |
-
return $this->authenticateURL() . '?WPOAuth_token=' . $token;
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Exchange the request token and secret for an access token and
|
142 |
-
* secret, to sign API calls.
|
143 |
-
*
|
144 |
-
* @returns array("WPOAuth_token" => the access token,
|
145 |
-
* "WPOAuth_token_secret" => the access secret)
|
146 |
-
*/
|
147 |
-
function getAccessToken( $token = null ) {
|
148 |
-
$r = $this->WPOAuthRequest( $this->accessTokenURL() );
|
149 |
-
$token = $this->WPOAuthParseResponse( $r );
|
150 |
-
$this->token = new WPOAuthConsumer( $token['WPOAuth_token'], $token['WPOAuth_token_secret'] );
|
151 |
-
|
152 |
-
return $token;
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Wrapper for POST requests
|
157 |
-
*/
|
158 |
-
function post( $url, $parameters = array() ) {
|
159 |
-
$response = $this->WPOAuthRequest( $url, $parameters, 'POST' );
|
160 |
-
if ( $this->format === 'json' && $this->decode_json ) {
|
161 |
-
return json_decode( $response );
|
162 |
-
}
|
163 |
-
|
164 |
-
return $response;
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Wrapper for MEDIA requests
|
169 |
-
*/
|
170 |
-
function media( $url, $parameters = array() ) {
|
171 |
-
$response = $this->WPOAuthRequest( $url, $parameters, 'MEDIA' );
|
172 |
-
if ( $this->format === 'json' && $this->decode_json ) {
|
173 |
-
return json_decode( $response );
|
174 |
-
}
|
175 |
-
|
176 |
-
return $response;
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Wrapper for GET requests
|
181 |
-
*/
|
182 |
-
function get( $url, $parameters = array() ) {
|
183 |
-
$response = $this->WPOAuthRequest( $url, $parameters, 'GET' );
|
184 |
-
if ( $this->format === 'json' && $this->decode_json ) {
|
185 |
-
return json_decode( $response );
|
186 |
-
}
|
187 |
-
|
188 |
-
return $response;
|
189 |
-
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* Wrapper for metadata requests
|
193 |
-
*/
|
194 |
-
function meta( $url, $parameters = array() ) {
|
195 |
-
$response = $this->WPOAuthRequest( $url, $parameters, 'META' );
|
196 |
-
if ( $this->format === 'json' && $this->decode_json ) {
|
197 |
-
return json_decode( $response );
|
198 |
-
}
|
199 |
-
|
200 |
-
return $response;
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* Handles a status update that includes an image.
|
205 |
-
*
|
206 |
-
* @param type $url
|
207 |
-
* @param type $args
|
208 |
-
*
|
209 |
-
* @return boolean
|
210 |
-
*/
|
211 |
-
function handleMediaRequest( $url, $args = array() ) {
|
212 |
-
/* Load tmhOAuth for Media uploads only when needed: https://github.com/themattharris/tmhOAuth */
|
213 |
-
/* It's not possible to upload media using WP_HTTP, so this needs to use cURL. */
|
214 |
-
if ( ! class_exists( 'tmhOAuth' ) ) {
|
215 |
-
require_once( plugin_dir_path( __FILE__ ) . 'tmhOAuth/tmhOAuth.php' );
|
216 |
-
require_once( plugin_dir_path( __FILE__ ) . 'tmhOAuth/tmhUtilities.php' );
|
217 |
-
}
|
218 |
-
$auth = $args['auth'];
|
219 |
-
if ( ! $auth ) {
|
220 |
-
$ack = get_option( 'app_consumer_key' );
|
221 |
-
$acs = get_option( 'app_consumer_secret' );
|
222 |
-
$ot = get_option( 'oauth_token' );
|
223 |
-
$ots = get_option( 'oauth_token_secret' );
|
224 |
-
} else {
|
225 |
-
$ack = get_user_meta( $auth, 'app_consumer_key', true );
|
226 |
-
$acs = get_user_meta( $auth, 'app_consumer_secret', true );
|
227 |
-
$ot = get_user_meta( $auth, 'oauth_token', true );
|
228 |
-
$ots = get_user_meta( $auth, 'oauth_token_secret', true );
|
229 |
-
}
|
230 |
-
// when performing as a scheduled action, need to include file.php
|
231 |
-
if ( ! function_exists( 'get_home_path' ) ) {
|
232 |
-
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
233 |
-
}
|
234 |
-
$connect = array(
|
235 |
-
'consumer_key' => $ack,
|
236 |
-
'consumer_secret' => $acs,
|
237 |
-
'user_token' => $ot,
|
238 |
-
'user_secret' => $ots
|
239 |
-
);
|
240 |
-
$tmhOAuth = new tmhOAuth( $connect );
|
241 |
-
$attachment = $args['media'];
|
242 |
-
|
243 |
-
$image_sizes = get_intermediate_image_sizes();
|
244 |
-
if ( in_array( 'large', $image_sizes ) ) {
|
245 |
-
$size = 'large';
|
246 |
-
} else {
|
247 |
-
$size = array_pop( $image_sizes );
|
248 |
-
}
|
249 |
-
$upload = wp_get_attachment_image_src( $attachment, apply_filters( 'wpt_upload_image_size', $size ) );
|
250 |
-
$image_url = $upload[0];
|
251 |
-
$remote = wp_remote_get( $image_url );
|
252 |
-
if ( is_wp_error( $remote ) ) {
|
253 |
-
$transport = 'curl';
|
254 |
-
$binary = wp_get_curl( $image_url );
|
255 |
-
} else {
|
256 |
-
$transport = 'wp_http';
|
257 |
-
$binary = wp_remote_retrieve_body( $remote );
|
258 |
-
}
|
259 |
-
wpt_mail( 'Media fetched binary', print_r( $remote, 1 ) . "\n\n" . print_r( $binary, 1 ) );
|
260 |
-
if ( !$binary ) {
|
261 |
-
return;
|
262 |
-
}
|
263 |
-
|
264 |
-
$mime_type = get_post_mime_type( $attachment );
|
265 |
-
if ( ! $mime_type ) {
|
266 |
-
$mime_type = 'image/jpeg';
|
267 |
-
}
|
268 |
-
/* End New */
|
269 |
-
|
270 |
-
$code = $tmhOAuth->request(
|
271 |
-
'POST',
|
272 |
-
$url,
|
273 |
-
array( 'media' => "$binary" ),
|
274 |
-
true, // use auth
|
275 |
-
true // multipart
|
276 |
-
);
|
277 |
-
|
278 |
-
$response = $tmhOAuth->response['response'];
|
279 |
-
$full = $tmhOAuth->response;
|
280 |
-
wpt_mail( "Media Posted", "
|
281 |
-
Media ID #$args[media] ($transport)" . "\n\n" .
|
282 |
-
"Twitter Response" . "\n" . print_r( $full, 1 ) . "\n\n" .
|
283 |
-
"Attachment Details" . "\n" . print_r( $upload, 1 ) . "\n\n" .
|
284 |
-
"Img Request Response" . "\n" . print_r( $remote, 1 )
|
285 |
-
);
|
286 |
-
|
287 |
-
if ( is_wp_error( $response ) ) {
|
288 |
-
return '';
|
289 |
-
}
|
290 |
-
|
291 |
-
$this->http_code = $code;
|
292 |
-
$this->last_api_call = $url;
|
293 |
-
$this->format = 'json';
|
294 |
-
$this->http_header = $response;
|
295 |
-
$response = json_decode( $response );
|
296 |
-
$media_id = $response->media_id_string;
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Eventually, use this to add alt text. Not supported at this time.
|
300 |
-
*
|
301 |
-
$metadata_api = 'https://upload.twitter.com/1.1/media/metadata/create.json';
|
302 |
-
$alt_text = get_post_meta( $args['media'], '_wp_attachment_image_alt', true );
|
303 |
-
if ( $alt_text != '' ) {
|
304 |
-
$image_alt = json_encode( array(
|
305 |
-
'media_id' => $media_id,
|
306 |
-
'alt_text' => array(
|
307 |
-
'text' => $alt_text
|
308 |
-
)
|
309 |
-
) );
|
310 |
-
$post_image = $tmhOAuth->request(
|
311 |
-
'POST',
|
312 |
-
$metadata_api,
|
313 |
-
array( 'body' => $image_alt ),
|
314 |
-
true
|
315 |
-
);
|
316 |
-
|
317 |
-
wpt_debug( 'Test of post image alt', print_r( $post_image, 1 ) );
|
318 |
-
}
|
319 |
-
*/
|
320 |
-
|
321 |
-
return $media_id;
|
322 |
-
}
|
323 |
-
|
324 |
-
/**
|
325 |
-
* Format and sign an WPOAuth / API request
|
326 |
-
*/
|
327 |
-
function WPOAuthRequest( $url, $args = array(), $method = null ) {
|
328 |
-
|
329 |
-
//Handle media requests using tmhOAuth library.
|
330 |
-
if ( $method == 'MEDIA' ) {
|
331 |
-
return $this->handleMediaRequest( $url, $args );
|
332 |
-
}
|
333 |
-
|
334 |
-
if ( empty( $method ) ) {
|
335 |
-
$method = empty( $args ) ? "GET" : "POST";
|
336 |
-
}
|
337 |
-
$req = WPOAuthRequest::from_consumer_and_token( $this->consumer, $this->token, $method, $url, $args );
|
338 |
-
$req->sign_request( $this->sha1_method, $this->consumer, $this->token );
|
339 |
-
|
340 |
-
|
341 |
-
$response = false;
|
342 |
-
$url = null;
|
343 |
-
|
344 |
-
switch ( $method ) {
|
345 |
-
case 'GET':
|
346 |
-
$url = $req->to_url();
|
347 |
-
$response = wp_remote_get( $url );
|
348 |
-
break;
|
349 |
-
case 'POST':
|
350 |
-
$url = $req->get_normalized_http_url();
|
351 |
-
$args = wp_parse_args( $req->to_postdata() );
|
352 |
-
$response = wp_remote_post( $url, array( 'body' => $args, 'timeout' => 30 ) );
|
353 |
-
break;
|
354 |
-
}
|
355 |
-
|
356 |
-
if ( is_wp_error( $response ) ) {
|
357 |
-
return false;
|
358 |
-
}
|
359 |
-
$this->http_code = $response['response']['code'];
|
360 |
-
$this->body = json_decode( $response['body'] );
|
361 |
-
$this->last_api_call = $url;
|
362 |
-
$this->format = 'json';
|
363 |
-
$this->http_header = $response['headers'];
|
364 |
-
|
365 |
-
return $response['body'];
|
366 |
-
}
|
367 |
-
}
|
368 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|