Version Description
Adds embedded Tweets grid template, Vine embeds, and Periscope On Air buttons.
Download this release
Release Info
Developer | niallkennedy |
Plugin | |
Version | 1.3.0 |
Comparing to | |
See all releases |
Code changes from version 1.2.0 to 1.3.0
- readme.txt +67 -19
- src/Twitter/Helpers/Validators/PeriscopeUsername.php +35 -0
- src/Twitter/Widgets/Language.php +3 -1
- src/Twitter/Widgets/PeriscopeOnAir.php +226 -0
- src/Twitter/WordPress/Admin/Post/MetaBox.php +13 -3
- src/Twitter/WordPress/Admin/Profile/PeriscopeUser.php +120 -0
- src/Twitter/WordPress/Admin/Settings/SinglePage.php +29 -1
- src/Twitter/WordPress/Features.php +207 -0
- src/Twitter/WordPress/Helpers/VineOEmbed.php +43 -0
- src/Twitter/WordPress/JavaScriptLoaders/AsyncJavaScript.php +239 -0
- src/Twitter/WordPress/JavaScriptLoaders/VineEmbed.php +65 -0
- src/Twitter/WordPress/JavaScriptLoaders/Widgets.php +8 -147
- src/Twitter/WordPress/PluginLoader.php +99 -64
- src/Twitter/WordPress/Shortcodes/EmbeddedTweet.php +30 -88
- src/Twitter/WordPress/Shortcodes/EmbeddedTweetVideo.php +7 -9
- src/Twitter/WordPress/Shortcodes/Follow.php +14 -16
- src/Twitter/WordPress/Shortcodes/Moment.php +9 -247
- src/Twitter/WordPress/Shortcodes/OEmbedTrait.php +132 -0
- src/Twitter/WordPress/Shortcodes/PeriscopeOnAir.php +281 -0
- src/Twitter/WordPress/Shortcodes/Share.php +14 -16
- src/Twitter/WordPress/Shortcodes/ShortcodeInterface.php +66 -0
- src/Twitter/WordPress/Shortcodes/Tracking.php +10 -12
- src/Twitter/WordPress/Shortcodes/TweetGrid.php +292 -0
- src/Twitter/WordPress/Shortcodes/Vine.php +295 -0
- src/Twitter/WordPress/User/Meta.php +37 -9
- src/Twitter/WordPress/Widgets/PeriscopeOnAir.php +176 -0
- twitter.php +3 -3
- uninstall.php +10 -8
readme.txt
CHANGED
@@ -1,33 +1,75 @@
|
|
1 |
=== Plugin Name ===
|
2 |
Contributors: Twitter, niallkennedy
|
3 |
-
Tags: twitter, embedded tweet, twitter moment, twitter video, twitter cards, tweet button, follow button, twitter analytics, twitter ads
|
4 |
Requires at least: 3.9
|
5 |
-
Tested up to: 4.
|
6 |
-
Stable tag: 1.
|
7 |
License: MIT
|
8 |
License URI: http://opensource.org/licenses/MIT
|
9 |
|
10 |
-
Official Twitter plugin for WordPress. Embed
|
11 |
|
12 |
== Description ==
|
13 |
|
14 |
-
The Twitter plugin for WordPress
|
|
|
|
|
15 |
|
16 |
Requires PHP version 5.4 or greater.
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
== Upgrade Notice ==
|
30 |
|
|
|
|
|
|
|
31 |
= 1.2.0 =
|
32 |
Support Twitter Moment embeds.
|
33 |
|
@@ -39,6 +81,12 @@ Display admin notice if current PHP version does not meet minimum requirements.
|
|
39 |
|
40 |
== Changelog ==
|
41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
= 1.2.0 =
|
43 |
* Embed a Twitter Moment by simply pasting a URL
|
44 |
* Always load Twitter ads conversion tracking JavaScript over HTTPS
|
@@ -56,12 +104,12 @@ Display admin notice if current PHP version does not meet minimum requirements.
|
|
56 |
* Fix: save Follow button widget with no overrides
|
57 |
|
58 |
= 1.0.0 =
|
59 |
-
* Embedded
|
60 |
-
* Embedded video
|
61 |
* Tweet button
|
62 |
* Twitter Cards
|
63 |
* Follow button
|
64 |
-
* Advertising tracker
|
65 |
|
66 |
== Frequently Asked Questions ==
|
67 |
|
@@ -71,9 +119,9 @@ The Twitter plugin for WordPress includes a settings page with options to custom
|
|
71 |
|
72 |
= How do I include an embedded timeline in my page? =
|
73 |
|
74 |
-
|
75 |
|
76 |
-
Copy-and-paste the HTML generated by the Twitter widgets configuration tool into a new [WordPress text widget](http://codex.wordpress.org/WordPress_Widgets#Using_Text_Widgets).
|
77 |
|
78 |
= My custom link color and border color do not appear in embedded Tweets or timelines =
|
79 |
|
1 |
=== Plugin Name ===
|
2 |
Contributors: Twitter, niallkennedy
|
3 |
+
Tags: twitter, embedded tweet, twitter moment, twitter video, twitter grid, vine, periscope, periscope on air, twitter cards, tweet button, follow button, twitter analytics, twitter ads
|
4 |
Requires at least: 3.9
|
5 |
+
Tested up to: 4.4
|
6 |
+
Stable tag: 1.3.0
|
7 |
License: MIT
|
8 |
License URI: http://opensource.org/licenses/MIT
|
9 |
|
10 |
+
Official Twitter, Vine, and Periscope plugin for WordPress. Embed content and grow your audience. Requires PHP 5.4 or greater.
|
11 |
|
12 |
== Description ==
|
13 |
|
14 |
+
The Twitter plugin for WordPress makes it easy to embed single Tweets, multiple Tweets, a Moment, or a Vine on your website. Improve the reach of your content with the Tweet button and populate rich link previews on Twitter with automatically-generated Twitter Card markup. Help your audience follow your latest updates with the Twitter follow button and Periscope On Air button.
|
15 |
+
|
16 |
+
All features are deeply integrated with WordPress APIs to make building your webpages and administrative features as easy as possible with the extensibility you expect from WordPress. The plugin is multisite-aware, supports post meta customizations through the WordPress REST API, and shortcode customizations through shortcode UI.
|
17 |
|
18 |
Requires PHP version 5.4 or greater.
|
19 |
|
20 |
+
= Embed Twitter content =
|
21 |
+
|
22 |
+
Embed a [single Tweet](https://dev.twitter.com/web/embedded-tweets), [single Tweet with video template](https://dev.twitter.com/web/embedded-video), [Moment](https://dev.twitter.com/web/embedded-moments "Twitter Moment"), or [Twitter collection](https://dev.twitter.com/web/embedded-timelines/collection) grid template by pasting a URL into your article content. Customize advanced options using a shortcode.
|
23 |
+
|
24 |
+
Choose a light or dark theme, customize link and border colors, and configure other widget template options through your site's WordPress administrative interface.
|
25 |
+
|
26 |
+
The plugin automatically customizes embed HTML to match the locale or your site, optimally enqueues Twitter's widgets JavaScript for fast loading and extensibility, and handles advanced cases such as articles loaded asynchronously via the WordPress API.
|
27 |
+
|
28 |
+
= Embed a Vine =
|
29 |
+
|
30 |
+
Embed a Vine by pasting a URL into your article content. Customize advanced options using a shortcode.
|
31 |
+
|
32 |
+
The plugin optimally enqueues Vine's embed JavaScript to handle unpausing and unmuting videos as they become visible on the page.
|
33 |
+
|
34 |
+
= Add a Tweet button to public posts =
|
35 |
+
|
36 |
+
Add a Tweet button to public posts to encourage your visitors to share your content on Twitter. The Tweet button automatically constructs share text, URLs, and shares your site's Twitter account in the Tweet. Visitors may see recommended accounts to follow after posting your content, including your site's specified accounts.
|
37 |
+
|
38 |
+
Customize the pre-populated share text and hashtags shown in a Tweet composer for each post from your site's post editor.
|
39 |
+
|
40 |
+
= Enable link previews and Twitter bylines with Twitter Cards =
|
41 |
+
|
42 |
+
The plugin automatically generates [Twitter Card](https://dev.twitter.com/cards/overview) markup to populate link previews on Twitter and attribute articles to a site and author Twitter account. Increase engagement with your content and related Twitter accounts.
|
43 |
|
44 |
+
Twitter Cards with site attribution provides access to [Twitter Analytics](https://analytics.twitter.com/) for detailed information about your site's Twitter audience including top sharers and engagement data.
|
45 |
+
|
46 |
+
Provide a custom link preview title and description for each post from your site's post editor.
|
47 |
+
|
48 |
+
= Twitter follow button =
|
49 |
+
|
50 |
+
Add a [Twitter follow button](https://dev.twitter.com/web/follow-button) with a WordPress widget or shortcode.
|
51 |
+
|
52 |
+
= Periscope On Air button =
|
53 |
+
|
54 |
+
Display a [Periscope On Air button](https://www.periscope.tv/embed) by pasting a Periscope profile URL into article content. Customize advanced options using a shortcode.
|
55 |
+
|
56 |
+
= Associate WordPress accounts with Twitter and Periscope identities =
|
57 |
+
|
58 |
+
Add a Twitter or Periscope username to a WordPress profile page for easy reference to your authors' external accounts. The plugin includes author attribution for posts and can dynamically include Twitter follow or Periscope On Air buttons through a shortcode when account information exists.
|
59 |
+
|
60 |
+
= Add an advertising pixel with a shortcode =
|
61 |
+
|
62 |
+
Add a Twitter audience pixel or [track advertising conversions](https://support.twitter.com/articles/20170807-conversion-tracking-for-websites "Twitter advertising conversion tracking") by adding an advertising pixel through a simple shortcode.
|
63 |
+
|
64 |
+
> <strong>Docs and active development</strong><br>
|
65 |
+
>Contribute to the plugin, submit pull requests, or run test suites through the [Twitter plugin for WordPress GitHub repository](https://github.com/twitter/wordpress).
|
66 |
+
> View [Twitter for WordPress documentation](https://dev.twitter.com/web/wordpress) to learn more about customization through WordPress filters.
|
67 |
|
68 |
== Upgrade Notice ==
|
69 |
|
70 |
+
= 1.3.0 =
|
71 |
+
Adds embedded Tweets grid template, Vine embeds, and Periscope On Air buttons.
|
72 |
+
|
73 |
= 1.2.0 =
|
74 |
Support Twitter Moment embeds.
|
75 |
|
81 |
|
82 |
== Changelog ==
|
83 |
|
84 |
+
= 1.3.0 =
|
85 |
+
* Display multiple Tweets in a [media-rich responsive grid template](https://dev.twitter.com/web/embedded-timelines/collection#template-grid) by pasting a Twitter collection URL
|
86 |
+
* Add a [Periscope On Air button](https://www.periscope.tv/embed) through a widget, shortcode, or as an embed handler for a Periscope profile URL
|
87 |
+
* Add a Vine through a URL or shortcode
|
88 |
+
* Shortcode UI integration now uses the `register_shortcode_ui` action introduced in Shortcake 0.5.0
|
89 |
+
|
90 |
= 1.2.0 =
|
91 |
* Embed a Twitter Moment by simply pasting a URL
|
92 |
* Always load Twitter ads conversion tracking JavaScript over HTTPS
|
104 |
* Fix: save Follow button widget with no overrides
|
105 |
|
106 |
= 1.0.0 =
|
107 |
+
* Embedded Tweet
|
108 |
+
* Embedded Tweet with video template
|
109 |
* Tweet button
|
110 |
* Twitter Cards
|
111 |
* Follow button
|
112 |
+
* Advertising tracker for Twitter custom audiences and ad conversion
|
113 |
|
114 |
== Frequently Asked Questions ==
|
115 |
|
119 |
|
120 |
= How do I include an embedded timeline in my page? =
|
121 |
|
122 |
+
Paste a Twitter collection URL into your post content to see a media-rich grid display on your website.
|
123 |
|
124 |
+
Log in to Twitter.com and visit the [Twitter widgets settings page](https://twitter.com/settings/widgets) to create and manage user, list, and search [embedded timeline](https://dev.twitter.com/web/embedded-timelines) widgets for your account. Widget settings are saved to a widget identifier for the logged in account; you may want to create a widget from your site's account, not your personal account, for continuity and general organization. Copy-and-paste the HTML generated by the Twitter widgets configuration tool into a new [WordPress text widget](http://codex.wordpress.org/WordPress_Widgets#Using_Text_Widgets).
|
125 |
|
126 |
= My custom link color and border color do not appear in embedded Tweets or timelines =
|
127 |
|
src/Twitter/Helpers/Validators/PeriscopeUsername.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\Helpers\Validators;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Test for Periscope username validity
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class PeriscopeUsername extends ScreenName
|
34 |
+
{
|
35 |
+
}
|
src/Twitter/Widgets/Language.php
CHANGED
@@ -47,9 +47,10 @@ class Language
|
|
47 |
'cs' => 'Czech',
|
48 |
'da' => 'Danish',
|
49 |
'de' => 'German',
|
|
|
50 |
'en' => 'English',
|
51 |
'es' => 'Spanish',
|
52 |
-
'fa' => '
|
53 |
'fi' => 'Finnish',
|
54 |
'fil' => 'Filipino',
|
55 |
'fr' => 'French',
|
@@ -70,6 +71,7 @@ class Language
|
|
70 |
'sv' => 'Swedish',
|
71 |
'th' => 'Thai',
|
72 |
'tr' => 'Turkish',
|
|
|
73 |
'ur' => 'Urdu',
|
74 |
'vi' => 'Vietnamese',
|
75 |
'zh-cn' => 'Simplified Chinese',
|
47 |
'cs' => 'Czech',
|
48 |
'da' => 'Danish',
|
49 |
'de' => 'German',
|
50 |
+
'el' => 'Greek',
|
51 |
'en' => 'English',
|
52 |
'es' => 'Spanish',
|
53 |
+
'fa' => 'Persian',
|
54 |
'fi' => 'Finnish',
|
55 |
'fil' => 'Filipino',
|
56 |
'fr' => 'French',
|
71 |
'sv' => 'Swedish',
|
72 |
'th' => 'Thai',
|
73 |
'tr' => 'Turkish',
|
74 |
+
'uk' => 'Ukrainian',
|
75 |
'ur' => 'Urdu',
|
76 |
'vi' => 'Vietnamese',
|
77 |
'zh-cn' => 'Simplified Chinese',
|
src/Twitter/Widgets/PeriscopeOnAir.php
ADDED
@@ -0,0 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\Widgets;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Periscope profile button with on-air status display
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class PeriscopeOnAir extends BaseWidget
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* HTML class expected by the Periscope widget JS
|
37 |
+
*
|
38 |
+
* @since 1.3.0
|
39 |
+
*
|
40 |
+
* @type string
|
41 |
+
*/
|
42 |
+
const HTML_CLASS = 'periscope-on-air';
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Default button size
|
47 |
+
*
|
48 |
+
* @since 1.3.0
|
49 |
+
*
|
50 |
+
* @type string
|
51 |
+
*/
|
52 |
+
const DEFAULT_SIZE = 'small';
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Periscope web profile base URL
|
56 |
+
*
|
57 |
+
* @since 1.3.0
|
58 |
+
*
|
59 |
+
* @type string
|
60 |
+
*/
|
61 |
+
const BASE_URL = 'https://periscope.tv/';
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Periscope username
|
65 |
+
*
|
66 |
+
* @since 1.3.0
|
67 |
+
*
|
68 |
+
* @type string
|
69 |
+
*/
|
70 |
+
protected $username;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Allowed values for the size property
|
74 |
+
*
|
75 |
+
* @since 1.3.0
|
76 |
+
*
|
77 |
+
* @type array allowed sizes {
|
78 |
+
* @type string size
|
79 |
+
* @type bool exists
|
80 |
+
* }
|
81 |
+
*/
|
82 |
+
public static $ALLOWED_SIZES = array( 'small' => true, 'large' => true );
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Size of the button
|
86 |
+
*
|
87 |
+
* @since 1.3.0
|
88 |
+
*
|
89 |
+
* @type string
|
90 |
+
*/
|
91 |
+
protected $size;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Require username
|
95 |
+
*
|
96 |
+
* @since 1.3.0
|
97 |
+
*/
|
98 |
+
public function __construct($username, $validate = true)
|
99 |
+
{
|
100 |
+
$username = \Twitter\Helpers\Validators\PeriscopeUsername::trim($username);
|
101 |
+
if (false === $validate || \Twitter\Helpers\Validators\PeriscopeUsername::isValid($username)) {
|
102 |
+
$this->username = $username;
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Retrieve the stored Periscope username
|
108 |
+
*
|
109 |
+
* @since 1.3.0
|
110 |
+
*
|
111 |
+
* @return string Periscope username or empty string if username not set
|
112 |
+
*/
|
113 |
+
public function getUsername()
|
114 |
+
{
|
115 |
+
return $this->username ?: '';
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Build a Periscope web profile URL
|
120 |
+
*
|
121 |
+
* @since 1.3.0
|
122 |
+
*
|
123 |
+
* @return Periscope web profile URL or empty string if username not set
|
124 |
+
*/
|
125 |
+
public function getWebProfileURL()
|
126 |
+
{
|
127 |
+
return $this->username ? static::BASE_URL . $this->username : '';
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Set the desired size of the On Air button
|
132 |
+
*
|
133 |
+
* @since 1.3.0
|
134 |
+
*
|
135 |
+
* @param string $size button size
|
136 |
+
*
|
137 |
+
* @return __CLASS__ support chaining
|
138 |
+
*/
|
139 |
+
public function setSize($size)
|
140 |
+
{
|
141 |
+
if ($size && isset(static::$ALLOWED_SIZES[$size])) {
|
142 |
+
$this->size = $size;
|
143 |
+
}
|
144 |
+
return $this;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Build a Periscope On Air object from an associative array
|
149 |
+
*
|
150 |
+
* @since 1.3.0
|
151 |
+
*
|
152 |
+
* @param array $options associative array of options {
|
153 |
+
* @type string option name
|
154 |
+
* @type string option value
|
155 |
+
* }
|
156 |
+
*
|
157 |
+
* @return __CLASS__ support chaining
|
158 |
+
*/
|
159 |
+
public static function fromArray($options)
|
160 |
+
{
|
161 |
+
if (! isset( $options['username'] ) && $options['username']) {
|
162 |
+
return;
|
163 |
+
}
|
164 |
+
|
165 |
+
$class = __CLASS__;
|
166 |
+
$on_air = new $class( $options['username'] );
|
167 |
+
unset( $class );
|
168 |
+
|
169 |
+
$on_air->setBaseOptions($options);
|
170 |
+
|
171 |
+
if (isset( $options['size'] ) && static::DEFAULT_SIZE !== $options['size']) {
|
172 |
+
$on_air->setSize($options['size']);
|
173 |
+
}
|
174 |
+
|
175 |
+
return $on_air;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Convert the class object into an array, removing default field values
|
180 |
+
*
|
181 |
+
* @since 1.3.0
|
182 |
+
*
|
183 |
+
* @return array properties as associative array
|
184 |
+
*/
|
185 |
+
public function toArray()
|
186 |
+
{
|
187 |
+
$data = parent::toArray();
|
188 |
+
|
189 |
+
if ($this->size && static::DEFAULT_SIZE !== $this->size) {
|
190 |
+
$data['size'] = $this->size;
|
191 |
+
}
|
192 |
+
|
193 |
+
return $data;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Generate a link to a Periscope web profile configured for enhancement by the Twitter for Websites JavaScript
|
198 |
+
*
|
199 |
+
* @since 1.3.0
|
200 |
+
*
|
201 |
+
* @param string $html_builder_class callable HTML builder with a static anchorElement class
|
202 |
+
*
|
203 |
+
* @return string HTML markup or empty string if minimum requirements not met
|
204 |
+
*/
|
205 |
+
public function toHTML($html_builder_class = '\Twitter\Helpers\HTMLBuilder')
|
206 |
+
{
|
207 |
+
// test for invalid passed class
|
208 |
+
if (! ( class_exists($html_builder_class) && method_exists($html_builder_class, 'anchorElement') )) {
|
209 |
+
return '';
|
210 |
+
}
|
211 |
+
|
212 |
+
$web_profile_url = $this->getWebProfileURL();
|
213 |
+
if (! $web_profile_url) {
|
214 |
+
return '';
|
215 |
+
}
|
216 |
+
|
217 |
+
return $html_builder_class::anchorElement(
|
218 |
+
$web_profile_url,
|
219 |
+
'@' . $this->getUsername(),
|
220 |
+
array(
|
221 |
+
'class' => static::HTML_CLASS,
|
222 |
+
),
|
223 |
+
$this->toArray()
|
224 |
+
);
|
225 |
+
}
|
226 |
+
}
|
src/Twitter/WordPress/Admin/Post/MetaBox.php
CHANGED
@@ -66,9 +66,13 @@ class MetaBox
|
|
66 |
*/
|
67 |
public static function load()
|
68 |
{
|
69 |
-
add_action( 'wp', array( '\Twitter\WordPress\Admin\Post\TweetIntent', 'registerPostMeta' ), 10, 0 );
|
70 |
add_action( 'add_meta_boxes', array( __CLASS__, 'addMetaBox' ), 1, 0 );
|
71 |
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueueScripts' ) );
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
73 |
|
74 |
/**
|
@@ -163,8 +167,14 @@ class MetaBox
|
|
163 |
// Use nonce for verification
|
164 |
wp_nonce_field( plugin_basename( __FILE__ ), self::NONCE_NAME );
|
165 |
|
166 |
-
\Twitter\WordPress\
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
169 |
|
170 |
/**
|
66 |
*/
|
67 |
public static function load()
|
68 |
{
|
|
|
69 |
add_action( 'add_meta_boxes', array( __CLASS__, 'addMetaBox' ), 1, 0 );
|
70 |
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueueScripts' ) );
|
71 |
+
|
72 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
73 |
+
if ( isset( $features[ \Twitter\WordPress\Features::TWEET_BUTTON ] ) ) {
|
74 |
+
add_action( 'wp', array( '\Twitter\WordPress\Admin\Post\TweetIntent', 'registerPostMeta' ), 10, 0 );
|
75 |
+
}
|
76 |
}
|
77 |
|
78 |
/**
|
167 |
// Use nonce for verification
|
168 |
wp_nonce_field( plugin_basename( __FILE__ ), self::NONCE_NAME );
|
169 |
|
170 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
171 |
+
|
172 |
+
if ( isset( $features[ \Twitter\WordPress\Features::TWEET_BUTTON ] ) ) {
|
173 |
+
\Twitter\WordPress\Admin\Post\TweetIntent::metaBoxContent();
|
174 |
+
}
|
175 |
+
if ( isset( $features[ \Twitter\WordPress\Features::CARDS ] ) ) {
|
176 |
+
\Twitter\WordPress\Admin\Post\TwitterCard::metaBoxContent();
|
177 |
+
}
|
178 |
}
|
179 |
|
180 |
/**
|
src/Twitter/WordPress/Admin/Profile/PeriscopeUser.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Admin\Profile;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Associate a WordPress account with a Periscope account
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class PeriscopeUser
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Conditionally load features on the edit profile page.
|
37 |
+
*
|
38 |
+
* @since 1.3.0
|
39 |
+
*
|
40 |
+
* @return void
|
41 |
+
*/
|
42 |
+
public static function init()
|
43 |
+
{
|
44 |
+
// only show to authors
|
45 |
+
if ( ! current_user_can( 'edit_posts' ) ) {
|
46 |
+
return;
|
47 |
+
}
|
48 |
+
|
49 |
+
// add Twitter after website
|
50 |
+
add_filter( 'user_contactmethods', array( __CLASS__, 'addContactMethod' ), 1, 2 );
|
51 |
+
// provide additional hints in label text
|
52 |
+
add_filter( 'user_periscope_label', array( __CLASS__, 'contactMethodLabel' ), 10, 1 );
|
53 |
+
// clean up user input
|
54 |
+
add_filter( 'sanitize_user_meta_periscope', array( __CLASS__, 'sanitize' ), 10, 1 );
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Add Periscope as a contact method in the Contact Info profile section
|
59 |
+
*
|
60 |
+
* @since 1.3.0
|
61 |
+
*
|
62 |
+
* @see wp_get_user_contact_methods()
|
63 |
+
*
|
64 |
+
* @param array $methods contact methods and their labels {
|
65 |
+
* @type string contact method
|
66 |
+
* @type string label
|
67 |
+
* }
|
68 |
+
* @param WP_User $user WP_User object.
|
69 |
+
*
|
70 |
+
* @return array contact methods and their labels {
|
71 |
+
* @type string contact method
|
72 |
+
* @type string label
|
73 |
+
* }
|
74 |
+
*/
|
75 |
+
public static function addContactMethod( $methods, $user )
|
76 |
+
{
|
77 |
+
$methods['periscope'] = 'Periscope';
|
78 |
+
return $methods;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Customize HTML display label for contact method
|
83 |
+
*
|
84 |
+
* @since 1.3.0
|
85 |
+
*
|
86 |
+
* @param string $label HTML label
|
87 |
+
*
|
88 |
+
* @return string HTML label
|
89 |
+
*/
|
90 |
+
public static function contactMethodLabel( $label = '' )
|
91 |
+
{
|
92 |
+
return _x( 'Periscope username', 'Prompt requesting entry of a Periscope username', 'twitter' );
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Clean up user inputted Periscope username value before saving the option
|
97 |
+
*
|
98 |
+
* @since 1.3.0
|
99 |
+
*
|
100 |
+
* @param string $username inputted Periscope username value
|
101 |
+
*
|
102 |
+
* @return string sanitized Periscope username value
|
103 |
+
*/
|
104 |
+
public static function sanitize( $username )
|
105 |
+
{
|
106 |
+
if ( ! is_string( $username ) ) {
|
107 |
+
return '';
|
108 |
+
}
|
109 |
+
$username = trim( $username );
|
110 |
+
if ( ! $username ) {
|
111 |
+
return '';
|
112 |
+
}
|
113 |
+
$username = sanitize_text_field( $username );
|
114 |
+
if ( ! $username ) {
|
115 |
+
return '';
|
116 |
+
}
|
117 |
+
|
118 |
+
return \Twitter\Helpers\Validators\PeriscopeUsername::sanitize( $username );
|
119 |
+
}
|
120 |
+
}
|
src/Twitter/WordPress/Admin/Settings/SinglePage.php
CHANGED
@@ -75,6 +75,32 @@ class SinglePage
|
|
75 |
return __( 'Twitter settings', 'twitter' );
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
/**
|
79 |
* Add a submenu item to WordPress admin.
|
80 |
*
|
@@ -101,8 +127,10 @@ class SinglePage
|
|
101 |
}
|
102 |
$settings->hook_suffix = $hook_suffix;
|
103 |
|
|
|
|
|
104 |
// add each settings component to the single page settings page
|
105 |
-
foreach (
|
106 |
$settings_component::addToSettingsPage( $hook_suffix );
|
107 |
}
|
108 |
|
75 |
return __( 'Twitter settings', 'twitter' );
|
76 |
}
|
77 |
|
78 |
+
/**
|
79 |
+
* Do not display a settings section if the related feature has been disabled by the site
|
80 |
+
*
|
81 |
+
* @since 1.3.0
|
82 |
+
*
|
83 |
+
* @return array {
|
84 |
+
* Settings component full qualified class names
|
85 |
+
|
86 |
+
* @type string fully qualified class name
|
87 |
+
* }
|
88 |
+
*/
|
89 |
+
public static function getSettingsComponentsForEnabledFeatures() {
|
90 |
+
$components = static::$SETTINGS_COMPONENTS;
|
91 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
92 |
+
|
93 |
+
if ( ! isset( $features[ \Twitter\WordPress\Features::EMBED_TWEET ] ) ) {
|
94 |
+
unset( $components['\Twitter\WordPress\Admin\Settings\Theme'] );
|
95 |
+
}
|
96 |
+
|
97 |
+
if ( ! isset( $features[ \Twitter\WordPress\Features::TWEET_BUTTON ] ) ) {
|
98 |
+
unset( $components['\Twitter\WordPress\Admin\Settings\TweetButton'] );
|
99 |
+
}
|
100 |
+
|
101 |
+
return $components;
|
102 |
+
}
|
103 |
+
|
104 |
/**
|
105 |
* Add a submenu item to WordPress admin.
|
106 |
*
|
127 |
}
|
128 |
$settings->hook_suffix = $hook_suffix;
|
129 |
|
130 |
+
$settings_components = static::getSettingsComponentsForEnabledFeatures();
|
131 |
+
|
132 |
// add each settings component to the single page settings page
|
133 |
+
foreach ( $settings_components as $settings_component ) {
|
134 |
$settings_component::addToSettingsPage( $hook_suffix );
|
135 |
}
|
136 |
|
src/Twitter/WordPress/Features.php
ADDED
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Customize available features
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class Features
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Describe webpage content to Twitter
|
37 |
+
*
|
38 |
+
* Twitter Cards describes a webpage using Twitter-specific HTML meta elements. Populate a link preview for URLs shared on Twitter, attribute content to a site and author Twitter account, and deeplink into the equivalent view in your iOS or Android apps.
|
39 |
+
*
|
40 |
+
* @since 1.3.0
|
41 |
+
*
|
42 |
+
* @link https://dev.twitter.com/cards/overview Twitter Cards
|
43 |
+
*
|
44 |
+
* @type string
|
45 |
+
*/
|
46 |
+
const CARDS = 'cards';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Embed a single Tweet by URL or shortcode
|
50 |
+
*
|
51 |
+
* @since 1.3.0
|
52 |
+
*
|
53 |
+
* @link https://dev.twitter.com/web/embedded-tweets Embedded Tweet
|
54 |
+
*
|
55 |
+
* @type string
|
56 |
+
*/
|
57 |
+
const EMBED_TWEET = 'embed-tweet';
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Embed a single Tweet with a video template using a shortcode
|
61 |
+
*
|
62 |
+
* @since 1.3.0
|
63 |
+
*
|
64 |
+
* @link https://dev.twitter.com/web/embedded-video Embedded Video
|
65 |
+
*
|
66 |
+
* @type string
|
67 |
+
*/
|
68 |
+
const EMBED_TWEET_VIDEO = 'embed-tweet-video';
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Embed a single Vine
|
72 |
+
*
|
73 |
+
* @since 1.3.0
|
74 |
+
*
|
75 |
+
* @link https://dev.twitter.com/web/vine Vine Embed
|
76 |
+
*
|
77 |
+
* @type string
|
78 |
+
*/
|
79 |
+
const EMBED_VINE = 'embed-vine';
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Embed a Twitter Moment by URL or shortcode
|
83 |
+
*
|
84 |
+
* @since 1.3.0
|
85 |
+
*
|
86 |
+
* @link https://twitter.com/i/moments Twitter Moments
|
87 |
+
*
|
88 |
+
* @type string
|
89 |
+
*/
|
90 |
+
const EMBED_MOMENT = 'embed-moment';
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Embed multiple Tweets in a responsive grid format by URL or shortcode
|
94 |
+
*
|
95 |
+
* @since 1.3.0
|
96 |
+
*
|
97 |
+
* @type string
|
98 |
+
*/
|
99 |
+
const EMBED_TWEETS_GRID = 'embed-tweets-grid';
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Display a Twitter follow button using a shortcode
|
103 |
+
*
|
104 |
+
* @since 1.3.0
|
105 |
+
*
|
106 |
+
* @link https://dev.twitter.com/web/follow-button Follow Button
|
107 |
+
*
|
108 |
+
* @type string
|
109 |
+
*/
|
110 |
+
const FOLLOW_BUTTON = 'follow';
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Display a Tweet button using a shortcode
|
114 |
+
*
|
115 |
+
* @since 1.3.0
|
116 |
+
*
|
117 |
+
* @link https://dev.twitter.com/web/tweet-button Tweet Button
|
118 |
+
*
|
119 |
+
* @type string
|
120 |
+
*/
|
121 |
+
const TWEET_BUTTON = 'share';
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Display a Periscope On Air button using a shortcode
|
125 |
+
*
|
126 |
+
* @since 1.3.0
|
127 |
+
*
|
128 |
+
* @link https://www.periscope.tv/embed Periscope On Air embed
|
129 |
+
*
|
130 |
+
* @type string
|
131 |
+
*/
|
132 |
+
const PERISCOPE_ON_AIR = 'periscope-on-air';
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Audience conversion pixel
|
136 |
+
*
|
137 |
+
* Track your website's audience for retargeting on Twitter
|
138 |
+
* Track the result of a Twitter targeted user visiting your webpage
|
139 |
+
*
|
140 |
+
* @since 1.3.0
|
141 |
+
*
|
142 |
+
* @link https://business.twitter.com/help/website-tag-for-remarketing Twitter website tag for remarketing
|
143 |
+
* @link https://business.twitter.com/help/conversion-tracking-for-websites Twitter conversion tracking for websites
|
144 |
+
*
|
145 |
+
* @type string
|
146 |
+
*/
|
147 |
+
const TRACKING_PIXEL = 'ad-pixel';
|
148 |
+
|
149 |
+
/**
|
150 |
+
* All available features
|
151 |
+
*
|
152 |
+
* Allows a publisher to filter features available on the site
|
153 |
+
*
|
154 |
+
* @since 1.3.0
|
155 |
+
*
|
156 |
+
* @type array
|
157 |
+
*/
|
158 |
+
public static $features = array(
|
159 |
+
self::CARDS => true, // Twitter Cards
|
160 |
+
self::EMBED_MOMENT => true, // Twitter Moment
|
161 |
+
self::EMBED_TWEET => true, // single Tweet
|
162 |
+
self::EMBED_TWEET_VIDEO => true, // single Tweet with video-specific display template
|
163 |
+
self::EMBED_VINE => true, // single Vine
|
164 |
+
self::EMBED_TWEETS_GRID => true, // multiple Tweets displayed in a grid layout
|
165 |
+
self::FOLLOW_BUTTON => true, // Twitter Follow button
|
166 |
+
self::TWEET_BUTTON => true, // Tweet button
|
167 |
+
self::PERISCOPE_ON_AIR => true, // Periscope On Air button
|
168 |
+
self::TRACKING_PIXEL => true, // audience and conversion pixel
|
169 |
+
);
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Get a list of features enabled for the current site
|
173 |
+
*
|
174 |
+
* Allows a site owner to install the plugin but limit its features
|
175 |
+
*
|
176 |
+
* @since 1.3.0
|
177 |
+
*
|
178 |
+
* @return array list of features {
|
179 |
+
* List of features
|
180 |
+
*
|
181 |
+
* @type string $key feature name
|
182 |
+
* @type bool $value true
|
183 |
+
* }
|
184 |
+
*/
|
185 |
+
public static function getEnabledFeatures()
|
186 |
+
{
|
187 |
+
/**
|
188 |
+
* Limit the features available in the Twitter plugin for WordPress
|
189 |
+
*
|
190 |
+
* Disable specific features of the Twitter plugin for WordPress
|
191 |
+
*
|
192 |
+
* @since 1.3.0
|
193 |
+
*
|
194 |
+
* @param array $features {
|
195 |
+
*
|
196 |
+
* @type string $feature feature toggle. if present, the feature is active.
|
197 |
+
* @type bool $exists used to form an associative array. a false value has no effect
|
198 |
+
* }
|
199 |
+
*/
|
200 |
+
$features = apply_filters( 'twitter_features', static::$features );
|
201 |
+
if ( ! is_array( $features ) ) {
|
202 |
+
$features = array();
|
203 |
+
}
|
204 |
+
|
205 |
+
return $features;
|
206 |
+
}
|
207 |
+
}
|
src/Twitter/WordPress/Helpers/VineOEmbed.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Helpers;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Request oEmbeds from Twitter's publisher endpoints
|
30 |
+
*
|
31 |
+
* @since 1.2.0
|
32 |
+
*/
|
33 |
+
class VineOEmbed extends TwitterOEmbed
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Vine oEmbed host FQDN
|
37 |
+
*
|
38 |
+
* @since 1.3.0
|
39 |
+
*
|
40 |
+
* @type string
|
41 |
+
*/
|
42 |
+
const HOST = 'vine.co';
|
43 |
+
}
|
src/Twitter/WordPress/JavaScriptLoaders/AsyncJavaScript.php
ADDED
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\JavaScriptLoaders;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Improve BackPress JavaScript handlers for asynchronous use
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
abstract class AsyncJavaScript
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Proactively resolve FQDN asynchronously before later use
|
37 |
+
*
|
38 |
+
* @since 1.3.0
|
39 |
+
*
|
40 |
+
* @link https://dev.chromium.org/developers/design-documents/dns-prefetching Chromium prefetch behavior
|
41 |
+
* @link https://developer.mozilla.org/en-US/docs/Controlling_DNS_prefetching Firefox prefetch behavior
|
42 |
+
*
|
43 |
+
* @return void
|
44 |
+
*/
|
45 |
+
public static function dnsPrefetch()
|
46 |
+
{
|
47 |
+
if ( ! ( defined( get_called_class() . '::FQDN' ) && static::FQDN ) ) {
|
48 |
+
return;
|
49 |
+
}
|
50 |
+
|
51 |
+
echo '<link rel="dns-prefetch" href="//' . esc_attr( static::FQDN ) . '"' . \Twitter\WordPress\Helpers\HTMLBuilder::closeVoidHTMLElement() . '>' . "\n";
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Register JavaScript to be later referenced by queue handle
|
56 |
+
*
|
57 |
+
* Set up related inline JavaScript to be loaded if SCRIPT_EXTRA exists.
|
58 |
+
*
|
59 |
+
* @since 1.3.0
|
60 |
+
*
|
61 |
+
* @return bool true on a successful wp_register_script response
|
62 |
+
*/
|
63 |
+
public static function register()
|
64 |
+
{
|
65 |
+
global $wp_scripts;
|
66 |
+
|
67 |
+
$classname = get_called_class();
|
68 |
+
if ( ! ( defined( $classname . '::QUEUE_HANDLE' ) && static::QUEUE_HANDLE && defined( $classname . '::URI' ) && static::URI ) ) {
|
69 |
+
return false;
|
70 |
+
}
|
71 |
+
|
72 |
+
$registered = wp_register_script(
|
73 |
+
static::QUEUE_HANDLE,
|
74 |
+
static::URI, // should be overridden during queue output by asyncScriptLoaderSrc
|
75 |
+
array(), // no dependencies
|
76 |
+
null, // do not add extra query parameters for cache busting
|
77 |
+
true // in footer
|
78 |
+
);
|
79 |
+
|
80 |
+
// treat null response as true
|
81 |
+
if ( ! is_bool( $registered ) ) {
|
82 |
+
$registered = true;
|
83 |
+
}
|
84 |
+
|
85 |
+
// replace standard script element with async script element
|
86 |
+
add_filter( 'script_loader_src', array( get_called_class(), 'asyncScriptLoaderSrc' ), 1, 2 );
|
87 |
+
|
88 |
+
if ( defined( $classname . '::SCRIPT_EXTRA' ) && is_string( static::SCRIPT_EXTRA ) && static::SCRIPT_EXTRA ) {
|
89 |
+
$script = static::SCRIPT_EXTRA;
|
90 |
+
$data = $wp_scripts->get_data( static::QUEUE_HANDLE, 'data' );
|
91 |
+
if ( $data ) {
|
92 |
+
// WP 4.3+
|
93 |
+
// do not add script data if data was possibly previously added
|
94 |
+
if ( $registered ) {
|
95 |
+
$script = $data . "\n" . $script;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
$wp_scripts->add_data( static::QUEUE_HANDLE, 'data', $script );
|
99 |
+
}
|
100 |
+
|
101 |
+
return $registered;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Enqueue the JavaScript
|
106 |
+
*
|
107 |
+
* @since 1.3.0
|
108 |
+
*
|
109 |
+
* @uses wp_enqueue_script()
|
110 |
+
*
|
111 |
+
* @return string async JavaScript loading snippet if script queue may not be supported. empty string if enqueued
|
112 |
+
*/
|
113 |
+
public static function enqueue()
|
114 |
+
{
|
115 |
+
if ( ! ( defined( get_called_class() . '::QUEUE_HANDLE' ) && static::QUEUE_HANDLE ) ) {
|
116 |
+
return '';
|
117 |
+
}
|
118 |
+
|
119 |
+
if ( ! wp_script_is( static::QUEUE_HANDLE, 'registered' ) ) {
|
120 |
+
if ( ! static::register() ) {
|
121 |
+
return '';
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
126 |
+
return static::asyncScriptLoaderInline();
|
127 |
+
}
|
128 |
+
|
129 |
+
wp_enqueue_script( static::QUEUE_HANDLE );
|
130 |
+
|
131 |
+
return '';
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Get the script element HTML markup used to load JavaScript in a browser
|
136 |
+
*
|
137 |
+
* @since 1.3.0
|
138 |
+
*
|
139 |
+
* @return string HTML <script> element
|
140 |
+
*/
|
141 |
+
public static function getScriptElement()
|
142 |
+
{
|
143 |
+
$classname = get_called_class();
|
144 |
+
if ( ! ( defined( $classname . '::QUEUE_HANDLE' ) && static::QUEUE_HANDLE && defined( $classname . '::URI' ) && static::URI ) ) {
|
145 |
+
return false;
|
146 |
+
}
|
147 |
+
|
148 |
+
// type = text/javascript to match default WP_Scripts output
|
149 |
+
// id to match on DOM getElementByID in async inline loading snippet
|
150 |
+
// async property to unlock page load, preload scanner discoverable in modern browsers
|
151 |
+
// defer property for IE 9 and older
|
152 |
+
return '<script type="text/javascript" id="' . esc_attr( static::QUEUE_HANDLE ) . '" async defer src="' . esc_url( static::URI, array( 'http', 'https' ) ) . '" charset="utf-8"></script>' . "\n";
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Create our own script element markup, replacing WordPress default with async loading
|
157 |
+
*
|
158 |
+
* Can be used with `script_loader_tag` filter in WordPress 4.1+.
|
159 |
+
*
|
160 |
+
* @since 1.3.0
|
161 |
+
*
|
162 |
+
* @param string $tag The `<script>` tag for the enqueued script
|
163 |
+
* @param string $handle The script's registered handle
|
164 |
+
* @param string $src The script's source URL
|
165 |
+
*
|
166 |
+
* @return string The `<script>` tag for the enqueued script
|
167 |
+
*/
|
168 |
+
public static function scriptLoaderTag( $tag, $handle, $src = '' )
|
169 |
+
{
|
170 |
+
if ( ! ( defined( get_called_class() . '::QUEUE_HANDLE' ) && static::QUEUE_HANDLE ) ) {
|
171 |
+
return '';
|
172 |
+
}
|
173 |
+
|
174 |
+
if ( ! ( is_string( $handle ) && $handle === static::QUEUE_HANDLE ) ) {
|
175 |
+
return $tag;
|
176 |
+
}
|
177 |
+
|
178 |
+
return static::getScriptElement();
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Load enqueued JavaScript using async deferred JavaScript properties
|
183 |
+
*
|
184 |
+
* Called from `script_loader_src` filter.
|
185 |
+
*
|
186 |
+
* @since 1.3.0
|
187 |
+
*
|
188 |
+
* @param string $src script URL
|
189 |
+
* @param string $handle WordPress registered script handle
|
190 |
+
* @global WP_Scripts $wp_scripts match concatenation preferences
|
191 |
+
*
|
192 |
+
* @return string empty string if our queue handle requested, else give back the src variable
|
193 |
+
*/
|
194 |
+
public static function asyncScriptLoaderSrc( $src, $handle )
|
195 |
+
{
|
196 |
+
global $wp_scripts;
|
197 |
+
|
198 |
+
if ( ! ( is_string( $handle ) && defined( get_called_class() . '::QUEUE_HANDLE' ) && $handle === static::QUEUE_HANDLE ) ) {
|
199 |
+
return $src;
|
200 |
+
}
|
201 |
+
|
202 |
+
$html = static::getScriptElement();
|
203 |
+
|
204 |
+
if ( isset( $wp_scripts ) && $wp_scripts->do_concat ) {
|
205 |
+
$wp_scripts->print_html .= $html;
|
206 |
+
} else {
|
207 |
+
echo $html;
|
208 |
+
}
|
209 |
+
|
210 |
+
// empty out the src response to avoid extra <script>
|
211 |
+
return '';
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Load JavaScript using an inline script block
|
216 |
+
*
|
217 |
+
* Suitable for unknown render environments where a script block may not be included in a standard enqueue output such as the wp_print_footer_scripts action. Dynamically-inserted JavaScript src is async by default.
|
218 |
+
*
|
219 |
+
* @since 1.3.0
|
220 |
+
*
|
221 |
+
* @param bool $include_script_element_wrapper wrap the returned JavaScript string in a script element wrapper
|
222 |
+
*
|
223 |
+
* @return string HTML script element containing loader script
|
224 |
+
*/
|
225 |
+
public static function asyncScriptLoaderInline( $include_script_element_wrapper = true )
|
226 |
+
{
|
227 |
+
$classname = get_called_class();
|
228 |
+
if ( ! ( defined( $classname . '::QUEUE_HANDLE' ) && static::QUEUE_HANDLE && defined( $classname . '::URI' ) && static::URI ) ) {
|
229 |
+
return '';
|
230 |
+
}
|
231 |
+
|
232 |
+
$script = '(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(d.getElementById(id))return;js=d.createElement(s);js.id=id;js.src=' . json_encode( static::URI ) . ';fjs.parentNode.insertBefore(js,fjs);}(document,"script",' . json_encode( static::QUEUE_HANDLE ) . '));';
|
233 |
+
|
234 |
+
if ( $include_script_element_wrapper ) {
|
235 |
+
return '<script>' . $script . '</script>';
|
236 |
+
}
|
237 |
+
return $script;
|
238 |
+
}
|
239 |
+
}
|
src/Twitter/WordPress/JavaScriptLoaders/VineEmbed.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\JavaScriptLoaders;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Load the remotely hosted Vine embed JavaScript
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class VineEmbed extends AsyncJavaScript
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Vine embed JavaScript handle
|
37 |
+
*
|
38 |
+
* Used in WordPress JavaScript queue
|
39 |
+
*
|
40 |
+
* @since 1.3.0
|
41 |
+
*
|
42 |
+
* @type string
|
43 |
+
*/
|
44 |
+
const QUEUE_HANDLE = 'vine-embed-js';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Vine embed JavaScript fully-qualified domain name
|
48 |
+
*
|
49 |
+
* Used to prefetch DNS lookup
|
50 |
+
*
|
51 |
+
* @since 1.3.0
|
52 |
+
*
|
53 |
+
* @type string
|
54 |
+
*/
|
55 |
+
const FQDN = 'platform.vine.co';
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Vine embed JavaScript absolute URI
|
59 |
+
*
|
60 |
+
* @since 1.3.0
|
61 |
+
*
|
62 |
+
* @type string
|
63 |
+
*/
|
64 |
+
const URI = 'https://platform.vine.co/static/scripts/embed.js';
|
65 |
+
}
|
src/Twitter/WordPress/JavaScriptLoaders/Widgets.php
CHANGED
@@ -30,7 +30,7 @@ namespace Twitter\WordPress\JavaScriptLoaders;
|
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
-
class Widgets
|
34 |
{
|
35 |
/**
|
36 |
* Twitter widget JavaScript handle
|
@@ -64,157 +64,18 @@ class Widgets
|
|
64 |
const URI = 'https://platform.twitter.com/widgets.js';
|
65 |
|
66 |
/**
|
67 |
-
*
|
68 |
*
|
69 |
-
*
|
70 |
-
*
|
71 |
-
* @link http://dev.chromium.org/developers/design-documents/dns-prefetching Chromium prefetch behavior
|
72 |
-
* @link https://developer.mozilla.org/en-US/docs/Controlling_DNS_prefetching Firefox prefetch behavior
|
73 |
-
*
|
74 |
-
* @return void
|
75 |
-
*/
|
76 |
-
public static function dnsPrefetch()
|
77 |
-
{
|
78 |
-
echo '<link rel="dns-prefetch" href="//' . esc_attr( self::FQDN ) . '"';
|
79 |
-
echo \Twitter\WordPress\Helpers\HTMLBuilder::closeVoidHTMLElement();
|
80 |
-
echo '>' . "\n";
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Register Twitter widget JavaScript
|
85 |
-
*
|
86 |
-
* @since 1.0.0
|
87 |
-
*
|
88 |
-
* @return bool true on a successful wp_register_script response
|
89 |
-
*/
|
90 |
-
public static function register()
|
91 |
-
{
|
92 |
-
global $wp_scripts;
|
93 |
-
|
94 |
-
$registered = wp_register_script(
|
95 |
-
self::QUEUE_HANDLE,
|
96 |
-
self::URI, // should be overridden during queue output by asyncScriptLoaderSrc
|
97 |
-
array(), // no dependencies
|
98 |
-
null, // no not add extra query parameters for cache busting
|
99 |
-
true // in footer
|
100 |
-
);
|
101 |
-
|
102 |
-
// treat null response as true
|
103 |
-
if ( ! is_bool( $registered ) ) {
|
104 |
-
$registered = true;
|
105 |
-
}
|
106 |
-
|
107 |
-
// replace standard script element with async script element
|
108 |
-
add_filter( 'script_loader_src', array( __CLASS__, 'asyncScriptLoaderSrc' ), 1, 2 );
|
109 |
-
|
110 |
-
// initialize the twttr variable to attach ready events before JS loaded
|
111 |
-
$script = 'window.twttr=(function(w){t=w.twttr||{};t._e=[];t.ready=function(f){t._e.push(f);};return t;}(window));';
|
112 |
-
$data = $wp_scripts->get_data( self::QUEUE_HANDLE, 'data' );
|
113 |
-
if ( $data ) {
|
114 |
-
// WP 4.3+
|
115 |
-
// do not add script data if data was possibly previously added
|
116 |
-
if ( $registered ) {
|
117 |
-
$script = $data . "\n" . $script;
|
118 |
-
}
|
119 |
-
}
|
120 |
-
$wp_scripts->add_data( self::QUEUE_HANDLE, 'data', $script );
|
121 |
-
|
122 |
-
return $registered;
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Enqueue the widgets JavaScript
|
127 |
-
*
|
128 |
-
* @since 1.0.0
|
129 |
-
*
|
130 |
-
* @uses wp_enqueue_script()
|
131 |
-
*
|
132 |
-
* @return string async JavaScript loading snippet if script queue may not be supported. empty string if enqueued
|
133 |
-
*/
|
134 |
-
public static function enqueue()
|
135 |
-
{
|
136 |
-
if ( ! wp_script_is( self::QUEUE_HANDLE, 'registered' ) ) {
|
137 |
-
static::register();
|
138 |
-
}
|
139 |
-
|
140 |
-
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
141 |
-
return static::asyncScriptLoaderInline();
|
142 |
-
}
|
143 |
-
|
144 |
-
wp_enqueue_script( self::QUEUE_HANDLE );
|
145 |
-
|
146 |
-
return '';
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Get the script element HTML markup used to load widgets.js in a browser
|
151 |
-
*
|
152 |
-
* @since 1.0.0
|
153 |
-
*
|
154 |
-
* @return string HTML <script> element
|
155 |
-
*/
|
156 |
-
public static function getScriptElement()
|
157 |
-
{
|
158 |
-
// type = text/javascript to match default WP_Scripts output
|
159 |
-
// async property to unlock page load, preload scanner discoverable in modern browsers
|
160 |
-
// defer property for IE 9 and older
|
161 |
-
return '<script type="text/javascript" id="' . esc_attr( self::QUEUE_HANDLE ) . '" async defer src="' . esc_url( self::URI, array( 'http', 'https' ) ) . '" charset="utf-8"></script>' . "\n";
|
162 |
-
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* Create our own script element markup, replacing WordPress default with async loading
|
166 |
*
|
167 |
-
*
|
168 |
-
*
|
169 |
-
* @since 1.0.0
|
170 |
*
|
171 |
-
* @
|
172 |
-
* @param string $handle The script's registered handle.
|
173 |
-
* @param string $src The script's source URL.
|
174 |
*
|
175 |
-
* @
|
176 |
-
*/
|
177 |
-
public static function scriptLoaderTag( $tag, $handle, $src = '' )
|
178 |
-
{
|
179 |
-
if ( ! ( is_string( $handle ) && $handle === static::QUEUE_HANDLE ) ) {
|
180 |
-
return $tag;
|
181 |
-
}
|
182 |
-
|
183 |
-
return static::getScriptElement();
|
184 |
-
}
|
185 |
-
|
186 |
-
/**
|
187 |
-
* Load Twitter widget JS using async deferred JavaScript properties
|
188 |
-
*
|
189 |
-
* Called from `script_loader_src` filter.
|
190 |
-
*
|
191 |
-
* @since 1.0.0
|
192 |
-
*
|
193 |
-
* @param string $src script URL
|
194 |
-
* @param string $handle WordPress registered script handle
|
195 |
-
* @global WP_Scripts $wp_scripts match concatenation preferences
|
196 |
-
*
|
197 |
-
* @return string empty string if Twitter widget JS, else give back the src variable
|
198 |
*/
|
199 |
-
|
200 |
-
{
|
201 |
-
global $wp_scripts;
|
202 |
-
|
203 |
-
if ( ! ( is_string( $handle ) && $handle === self::QUEUE_HANDLE ) ) {
|
204 |
-
return $src;
|
205 |
-
}
|
206 |
-
|
207 |
-
$html = static::getScriptElement();
|
208 |
-
|
209 |
-
if ( isset( $wp_scripts ) && $wp_scripts->do_concat ) {
|
210 |
-
$wp_scripts->print_html .= $html;
|
211 |
-
} else {
|
212 |
-
echo $html;
|
213 |
-
}
|
214 |
-
|
215 |
-
// empty out the src response to avoid extra <script>
|
216 |
-
return '';
|
217 |
-
}
|
218 |
|
219 |
/**
|
220 |
* Load Twitter widget JS using an inline script block
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
+
class Widgets extends AsyncJavaScript
|
34 |
{
|
35 |
/**
|
36 |
* Twitter widget JavaScript handle
|
64 |
const URI = 'https://platform.twitter.com/widgets.js';
|
65 |
|
66 |
/**
|
67 |
+
* Extra JavaScript to be loaded with external JS
|
68 |
*
|
69 |
+
* Initialize the twttr variable to attach ready events before JS loaded
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
*
|
71 |
+
* @see WP_Scripts::print_extra_script()
|
72 |
+
* @link https://dev.twitter.com/web/javascript/loading Twitter Widgets JS async loading snippet
|
|
|
73 |
*
|
74 |
+
* @since 1.3.0
|
|
|
|
|
75 |
*
|
76 |
+
* @type string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
*/
|
78 |
+
const SCRIPT_EXTRA = 'window.twttr=(function(w){t=w.twttr||{};t._e=[];t.ready=function(f){t._e.push(f);};return t;}(window));';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
/**
|
81 |
* Load Twitter widget JS using an inline script block
|
src/Twitter/WordPress/PluginLoader.php
CHANGED
@@ -41,7 +41,7 @@ class PluginLoader
|
|
41 |
*
|
42 |
* @type string
|
43 |
*/
|
44 |
-
const VERSION = '1.
|
45 |
|
46 |
/**
|
47 |
* Unique domain of the plugin's translated text
|
@@ -61,25 +61,27 @@ class PluginLoader
|
|
61 |
*/
|
62 |
public static function init()
|
63 |
{
|
|
|
|
|
64 |
// load translated text
|
65 |
-
add_action( 'init', array(
|
66 |
|
67 |
// compatibility wrappers to coexist with other popular plugins
|
68 |
-
add_action( 'plugins_loaded', array(
|
69 |
|
70 |
// make widgets available on front and back end
|
71 |
-
add_action( 'widgets_init', array(
|
72 |
|
73 |
// register Twitter JavaScript to eligible for later enqueueing
|
74 |
-
add_action( 'wp_enqueue_scripts', array(
|
75 |
|
76 |
if ( is_admin() ) {
|
77 |
// admin-specific functionality
|
78 |
-
add_action( 'init', array(
|
79 |
} else {
|
80 |
// hooks to be executed on general execution of WordPress such as public pageviews
|
81 |
-
add_action( 'init', array(
|
82 |
-
add_action( 'wp_head', array(
|
83 |
}
|
84 |
|
85 |
// shortcodes
|
@@ -135,7 +137,15 @@ class PluginLoader
|
|
135 |
*/
|
136 |
public static function widgetsInit()
|
137 |
{
|
138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
}
|
140 |
|
141 |
/**
|
@@ -147,14 +157,22 @@ class PluginLoader
|
|
147 |
*/
|
148 |
public static function adminInit()
|
149 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
// Twitter settings menu
|
151 |
\Twitter\WordPress\Admin\Settings\Loader::init();
|
152 |
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
|
|
|
|
158 |
}
|
159 |
|
160 |
/**
|
@@ -171,10 +189,16 @@ class PluginLoader
|
|
171 |
return;
|
172 |
}
|
173 |
|
|
|
|
|
174 |
// load widgets JS if a Twitter widget is active
|
175 |
-
if (
|
|
|
|
|
|
|
176 |
// enqueue after the script is registered in wp_enqueue_scripts action priority 1
|
177 |
add_action( 'wp_enqueue_scripts', array( '\Twitter\WordPress\JavaScriptLoaders\Widgets', 'enqueue' ) );
|
|
|
178 |
}
|
179 |
|
180 |
// do not add content filters to HTTP 404 response
|
@@ -182,6 +206,10 @@ class PluginLoader
|
|
182 |
return;
|
183 |
}
|
184 |
|
|
|
|
|
|
|
|
|
185 |
/**
|
186 |
* Set the priority to apply to Twitter elements automatically added to the_content
|
187 |
*
|
@@ -210,56 +238,53 @@ class PluginLoader
|
|
210 |
*/
|
211 |
public static function registerShortcodeHandlers()
|
212 |
{
|
|
|
|
|
|
|
213 |
// features requiring HTTPS remote requests
|
214 |
if ( wp_http_supports( array( 'ssl' => true ) ) ) {
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
|
|
|
|
|
|
|
|
|
|
230 |
|
231 |
-
// Twitter Moment
|
232 |
add_action(
|
233 |
'plugins_loaded',
|
234 |
-
array(
|
235 |
5,
|
236 |
0
|
237 |
);
|
238 |
}
|
239 |
-
|
240 |
-
// Follow button
|
241 |
-
add_action(
|
242 |
-
'plugins_loaded',
|
243 |
-
array( '\Twitter\WordPress\Shortcodes\Follow', 'init' ),
|
244 |
-
5,
|
245 |
-
0
|
246 |
-
);
|
247 |
-
|
248 |
-
// Tweet button
|
249 |
-
add_action(
|
250 |
-
'plugins_loaded',
|
251 |
-
array( '\Twitter\WordPress\Shortcodes\Share', 'init' ),
|
252 |
-
5,
|
253 |
-
0
|
254 |
-
);
|
255 |
-
|
256 |
-
// Ad conversion and audience tracking
|
257 |
-
add_action(
|
258 |
-
'plugins_loaded',
|
259 |
-
array( '\Twitter\WordPress\Shortcodes\Tracking', 'init' ),
|
260 |
-
5,
|
261 |
-
0
|
262 |
-
);
|
263 |
}
|
264 |
|
265 |
/**
|
@@ -271,13 +296,17 @@ class PluginLoader
|
|
271 |
*/
|
272 |
public static function wpHead()
|
273 |
{
|
|
|
|
|
274 |
// Twitter Cards markup
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
|
|
|
|
281 |
|
282 |
// page-level customizations referenced by Twitter JavaScript
|
283 |
add_action(
|
@@ -307,10 +336,13 @@ class PluginLoader
|
|
307 |
*/
|
308 |
public static function registerScripts()
|
309 |
{
|
310 |
-
// widgets
|
311 |
\Twitter\WordPress\JavaScriptLoaders\Widgets::register();
|
312 |
|
313 |
-
//
|
|
|
|
|
|
|
314 |
\Twitter\WordPress\JavaScriptLoaders\Tracking::register();
|
315 |
}
|
316 |
|
@@ -323,6 +355,9 @@ class PluginLoader
|
|
323 |
*/
|
324 |
public static function compatibility()
|
325 |
{
|
326 |
-
\Twitter\WordPress\
|
|
|
|
|
|
|
327 |
}
|
328 |
}
|
41 |
*
|
42 |
* @type string
|
43 |
*/
|
44 |
+
const VERSION = '1.3.0';
|
45 |
|
46 |
/**
|
47 |
* Unique domain of the plugin's translated text
|
61 |
*/
|
62 |
public static function init()
|
63 |
{
|
64 |
+
$classname = get_called_class();
|
65 |
+
|
66 |
// load translated text
|
67 |
+
add_action( 'init', array( $classname, 'loadTranslatedText' ) );
|
68 |
|
69 |
// compatibility wrappers to coexist with other popular plugins
|
70 |
+
add_action( 'plugins_loaded', array( $classname, 'compatibility' ) );
|
71 |
|
72 |
// make widgets available on front and back end
|
73 |
+
add_action( 'widgets_init', array( $classname, 'widgetsInit' ) );
|
74 |
|
75 |
// register Twitter JavaScript to eligible for later enqueueing
|
76 |
+
add_action( 'wp_enqueue_scripts', array( $classname, 'registerScripts' ), 1, 0 );
|
77 |
|
78 |
if ( is_admin() ) {
|
79 |
// admin-specific functionality
|
80 |
+
add_action( 'init', array( $classname, 'adminInit' ) );
|
81 |
} else {
|
82 |
// hooks to be executed on general execution of WordPress such as public pageviews
|
83 |
+
add_action( 'init', array( $classname, 'publicInit' ) );
|
84 |
+
add_action( 'wp_head', array( $classname, 'wpHead' ), 1, 0 );
|
85 |
}
|
86 |
|
87 |
// shortcodes
|
137 |
*/
|
138 |
public static function widgetsInit()
|
139 |
{
|
140 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
141 |
+
|
142 |
+
if ( isset( $features[ \Twitter\WordPress\Features::FOLLOW_BUTTON ] ) ) {
|
143 |
+
register_widget( '\Twitter\WordPress\Widgets\Follow' );
|
144 |
+
}
|
145 |
+
|
146 |
+
if ( isset( $features[ \Twitter\WordPress\Features::PERISCOPE_ON_AIR ] ) ) {
|
147 |
+
register_widget( '\Twitter\WordPress\Widgets\PeriscopeOnAir' );
|
148 |
+
}
|
149 |
}
|
150 |
|
151 |
/**
|
157 |
*/
|
158 |
public static function adminInit()
|
159 |
{
|
160 |
+
// User profile fields
|
161 |
+
add_action( 'admin_init', array( '\Twitter\WordPress\Admin\Profile\User', 'init' ) );
|
162 |
+
add_action( 'admin_init', array( '\Twitter\WordPress\Admin\Profile\PeriscopeUser', 'init' ) );
|
163 |
+
|
164 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
165 |
+
|
166 |
// Twitter settings menu
|
167 |
\Twitter\WordPress\Admin\Settings\Loader::init();
|
168 |
|
169 |
+
if (
|
170 |
+
isset( $features[ \Twitter\WordPress\Features::CARDS ] ) ||
|
171 |
+
isset( $features[ \Twitter\WordPress\Features::TWEET_BUTTON ] )
|
172 |
+
) {
|
173 |
+
// Edit post meta box
|
174 |
+
add_action( 'admin_init', array( '\Twitter\WordPress\Admin\Post\MetaBox', 'init' ) );
|
175 |
+
}
|
176 |
}
|
177 |
|
178 |
/**
|
189 |
return;
|
190 |
}
|
191 |
|
192 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
193 |
+
|
194 |
// load widgets JS if a Twitter widget is active
|
195 |
+
if (
|
196 |
+
( isset( $features[ \Twitter\WordPress\Features::FOLLOW_BUTTON ] ) && is_active_widget( false, false, \Twitter\WordPress\Widgets\Follow::BASE_ID, true ) ) ||
|
197 |
+
( isset( $features[ \Twitter\WordPress\Features::PERISCOPE_ON_AIR ] ) && is_active_widget( false, false, \Twitter\WordPress\Widgets\PeriscopeOnAir::BASE_ID, true ) )
|
198 |
+
) {
|
199 |
// enqueue after the script is registered in wp_enqueue_scripts action priority 1
|
200 |
add_action( 'wp_enqueue_scripts', array( '\Twitter\WordPress\JavaScriptLoaders\Widgets', 'enqueue' ) );
|
201 |
+
add_action( 'wp_head', array( '\Twitter\WordPress\JavaScriptLoaders\Widgets', 'dnsPrefetch' ) );
|
202 |
}
|
203 |
|
204 |
// do not add content filters to HTTP 404 response
|
206 |
return;
|
207 |
}
|
208 |
|
209 |
+
if ( ! isset( $features[ \Twitter\WordPress\Features::TWEET_BUTTON ] ) ) {
|
210 |
+
return;
|
211 |
+
}
|
212 |
+
|
213 |
/**
|
214 |
* Set the priority to apply to Twitter elements automatically added to the_content
|
215 |
*
|
238 |
*/
|
239 |
public static function registerShortcodeHandlers()
|
240 |
{
|
241 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
242 |
+
$shortcode_namespace = '\\Twitter\\WordPress\\Shortcodes\\';
|
243 |
+
|
244 |
// features requiring HTTPS remote requests
|
245 |
if ( wp_http_supports( array( 'ssl' => true ) ) ) {
|
246 |
+
foreach (
|
247 |
+
array(
|
248 |
+
\Twitter\WordPress\Features::EMBED_TWEET => 'EmbeddedTweet',
|
249 |
+
\Twitter\WordPress\Features::EMBED_TWEET_VIDEO => 'EmbeddedTweetVideo',
|
250 |
+
\Twitter\WordPress\Features::EMBED_VINE => 'Vine',
|
251 |
+
\Twitter\WordPress\Features::EMBED_TWEETS_GRID => 'TweetGrid',
|
252 |
+
\Twitter\WordPress\Features::EMBED_MOMENT => 'Moment',
|
253 |
+
) as $feature => $shortcode_class
|
254 |
+
) {
|
255 |
+
if ( ! isset( $features[ $feature ] ) ) {
|
256 |
+
continue;
|
257 |
+
}
|
258 |
+
|
259 |
+
add_action(
|
260 |
+
'plugins_loaded',
|
261 |
+
array( $shortcode_namespace . $shortcode_class, 'init' ),
|
262 |
+
5,
|
263 |
+
0
|
264 |
+
);
|
265 |
+
}
|
266 |
+
}
|
267 |
|
268 |
+
// initialize buttons and ad pixel if not disabled
|
269 |
+
foreach (
|
270 |
+
array(
|
271 |
+
\Twitter\WordPress\Features::FOLLOW_BUTTON => 'Follow',
|
272 |
+
\Twitter\WordPress\Features::TWEET_BUTTON => 'Share',
|
273 |
+
\Twitter\WordPress\Features::PERISCOPE_ON_AIR => 'PeriscopeOnAir',
|
274 |
+
\Twitter\WordPress\Features::TRACKING_PIXEL => 'Tracking',
|
275 |
+
) as $feature => $shortcode_class
|
276 |
+
) {
|
277 |
+
if ( ! isset( $features[ $feature ] ) ) {
|
278 |
+
continue;
|
279 |
+
}
|
280 |
|
|
|
281 |
add_action(
|
282 |
'plugins_loaded',
|
283 |
+
array( $shortcode_namespace . $shortcode_class, 'init' ),
|
284 |
5,
|
285 |
0
|
286 |
);
|
287 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
}
|
289 |
|
290 |
/**
|
296 |
*/
|
297 |
public static function wpHead()
|
298 |
{
|
299 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
300 |
+
|
301 |
// Twitter Cards markup
|
302 |
+
if ( isset( $features[ \Twitter\WordPress\Features::CARDS ] ) ) {
|
303 |
+
add_action(
|
304 |
+
'wp_head',
|
305 |
+
array( '\Twitter\WordPress\Head\CardsMetaElements', 'outputMetaElements' ),
|
306 |
+
99, // late priority to override if multiple values provided
|
307 |
+
0 // expects no arguments
|
308 |
+
);
|
309 |
+
}
|
310 |
|
311 |
// page-level customizations referenced by Twitter JavaScript
|
312 |
add_action(
|
336 |
*/
|
337 |
public static function registerScripts()
|
338 |
{
|
339 |
+
// Twitter widgets
|
340 |
\Twitter\WordPress\JavaScriptLoaders\Widgets::register();
|
341 |
|
342 |
+
// Vine embed
|
343 |
+
\Twitter\WordPress\JavaScriptLoaders\VineEmbed::register();
|
344 |
+
|
345 |
+
// Twitter audience tracker and conversion
|
346 |
\Twitter\WordPress\JavaScriptLoaders\Tracking::register();
|
347 |
}
|
348 |
|
355 |
*/
|
356 |
public static function compatibility()
|
357 |
{
|
358 |
+
$features = \Twitter\WordPress\Features::getEnabledFeatures();
|
359 |
+
if ( isset( $features[ \Twitter\WordPress\Features::CARDS ] ) ) {
|
360 |
+
\Twitter\WordPress\Cards\Compatibility::init();
|
361 |
+
}
|
362 |
}
|
363 |
}
|
src/Twitter/WordPress/Shortcodes/EmbeddedTweet.php
CHANGED
@@ -30,8 +30,9 @@ namespace Twitter\WordPress\Shortcodes;
|
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
-
class EmbeddedTweet
|
34 |
{
|
|
|
35 |
|
36 |
/**
|
37 |
* Shortcode tag to be matched
|
@@ -42,6 +43,15 @@ class EmbeddedTweet
|
|
42 |
*/
|
43 |
const SHORTCODE_TAG = 'tweet';
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
/**
|
46 |
* Relative path for the oEmbed API relative to Twitter API base path
|
47 |
*
|
@@ -71,6 +81,15 @@ class EmbeddedTweet
|
|
71 |
*/
|
72 |
const TWEET_URL_REGEX = '#^https?://(www\.)?twitter\.com/.+?/status(es)?/([0-9]+)#i';
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
/**
|
75 |
* Accepted values for the align parameter
|
76 |
*
|
@@ -101,17 +120,15 @@ class EmbeddedTweet
|
|
101 |
// register our shortcode and its handler
|
102 |
add_shortcode( self::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
}
|
114 |
-
} else {
|
115 |
// unhook the WordPress Core oEmbed handler
|
116 |
wp_oembed_remove_provider( static::OEMBED_CORE_REGEX );
|
117 |
// pass a Tweet detail URL through the Tweet shortcode handler
|
@@ -145,7 +162,7 @@ class EmbeddedTweet
|
|
145 |
shortcode_ui_register_for_shortcode(
|
146 |
self::SHORTCODE_TAG,
|
147 |
array(
|
148 |
-
'label' => __( 'Embedded Tweet', 'twitter' ),
|
149 |
'listItemImage' => 'dashicons-twitter',
|
150 |
'attrs' => array(
|
151 |
array(
|
@@ -334,40 +351,6 @@ class EmbeddedTweet
|
|
334 |
return $html;
|
335 |
}
|
336 |
|
337 |
-
/**
|
338 |
-
* Get the base set of oEmbed params before applying shortcode customizations
|
339 |
-
*
|
340 |
-
* @since 1.0.0
|
341 |
-
*
|
342 |
-
* @param string $tweet_id Tweet identifier
|
343 |
-
*
|
344 |
-
* @return array associative array of query parameters ready for http_build_query {
|
345 |
-
* @type string query parameter name
|
346 |
-
* @type string|bool query parameter value
|
347 |
-
* }
|
348 |
-
*/
|
349 |
-
public static function getBaseOEmbedParams( $tweet_id )
|
350 |
-
{
|
351 |
-
$tweet_id = trim( $tweet_id );
|
352 |
-
if ( ! $tweet_id ) {
|
353 |
-
return array();
|
354 |
-
}
|
355 |
-
|
356 |
-
// omit JavaScript. enqueue separately
|
357 |
-
$query_parameters = array(
|
358 |
-
'id' => $tweet_id,
|
359 |
-
'omit_script' => true,
|
360 |
-
);
|
361 |
-
|
362 |
-
// attempt to customize text for site language
|
363 |
-
$lang = \Twitter\WordPress\Language::localeToTwitterLang();
|
364 |
-
if ( $lang ) {
|
365 |
-
$query_parameters['lang'] = $lang;
|
366 |
-
}
|
367 |
-
|
368 |
-
return $query_parameters;
|
369 |
-
}
|
370 |
-
|
371 |
/**
|
372 |
* Convert shortcode parameters into query parameters supported by the Twitter oEmbed endpoint
|
373 |
*
|
@@ -464,45 +447,4 @@ class EmbeddedTweet
|
|
464 |
|
465 |
return implode( '_', $key_pieces );
|
466 |
}
|
467 |
-
|
468 |
-
/**
|
469 |
-
* Request and parse oEmbed markup from Twitter's API servers
|
470 |
-
*
|
471 |
-
* @since 1.0.0
|
472 |
-
*
|
473 |
-
* @param array $query_parameters request parameters
|
474 |
-
*
|
475 |
-
* @return string HTML markup returned by the oEmbed endpoint
|
476 |
-
*/
|
477 |
-
public static function getOEmbedMarkup( array $query_parameters )
|
478 |
-
{
|
479 |
-
$cache_key = static::oEmbedCacheKey( $query_parameters );
|
480 |
-
if ( ! $cache_key ) {
|
481 |
-
return '';
|
482 |
-
}
|
483 |
-
|
484 |
-
// check for cached result
|
485 |
-
$html = get_transient( $cache_key );
|
486 |
-
if ( $html ) {
|
487 |
-
return $html;
|
488 |
-
}
|
489 |
-
|
490 |
-
$ttl = DAY_IN_SECONDS;
|
491 |
-
|
492 |
-
$oembed_response = \Twitter\WordPress\Helpers\TwitterAPI::getJSON( self::OEMBED_API_ENDPOINT, $query_parameters );
|
493 |
-
if ( ! $oembed_response || ! isset( $oembed_response->type ) || 'rich' !== $oembed_response->type || ! ( isset( $oembed_response->html ) && $oembed_response->html ) ) {
|
494 |
-
// do not rerequest errors with every page request
|
495 |
-
set_transient( $cache_key, ' ', $ttl );
|
496 |
-
return '';
|
497 |
-
}
|
498 |
-
|
499 |
-
$html = $oembed_response->html;
|
500 |
-
|
501 |
-
if ( isset( $oembed_response->cache_age ) ) {
|
502 |
-
$ttl = absint( $oembed_response->cache_age );
|
503 |
-
}
|
504 |
-
set_transient( $cache_key, $html, $ttl );
|
505 |
-
|
506 |
-
return $html;
|
507 |
-
}
|
508 |
}
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
+
class EmbeddedTweet implements ShortcodeInterface
|
34 |
{
|
35 |
+
use OEmbedTrait;
|
36 |
|
37 |
/**
|
38 |
* Shortcode tag to be matched
|
43 |
*/
|
44 |
const SHORTCODE_TAG = 'tweet';
|
45 |
|
46 |
+
/**
|
47 |
+
* PHP class to use for fetching oEmbed data
|
48 |
+
*
|
49 |
+
* @since 1.3.0
|
50 |
+
*
|
51 |
+
* @type string
|
52 |
+
*/
|
53 |
+
const OEMBED_API_CLASS = '\Twitter\WordPress\Helpers\TwitterAPI';
|
54 |
+
|
55 |
/**
|
56 |
* Relative path for the oEmbed API relative to Twitter API base path
|
57 |
*
|
81 |
*/
|
82 |
const TWEET_URL_REGEX = '#^https?://(www\.)?twitter\.com/.+?/status(es)?/([0-9]+)#i';
|
83 |
|
84 |
+
/**
|
85 |
+
* Base URL used to reconstruct a Tweet URL
|
86 |
+
*
|
87 |
+
* @since 1.3.0
|
88 |
+
*
|
89 |
+
* @type string
|
90 |
+
*/
|
91 |
+
const BASE_URL = 'https://twitter.com/_/status/';
|
92 |
+
|
93 |
/**
|
94 |
* Accepted values for the align parameter
|
95 |
*
|
120 |
// register our shortcode and its handler
|
121 |
add_shortcode( self::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
122 |
|
123 |
+
// Shortcode UI, if supported
|
124 |
+
add_action(
|
125 |
+
'register_shortcode_ui',
|
126 |
+
array( __CLASS__, 'shortcodeUI' ),
|
127 |
+
5,
|
128 |
+
0
|
129 |
+
);
|
130 |
+
|
131 |
+
if ( ! is_admin() ) {
|
|
|
|
|
132 |
// unhook the WordPress Core oEmbed handler
|
133 |
wp_oembed_remove_provider( static::OEMBED_CORE_REGEX );
|
134 |
// pass a Tweet detail URL through the Tweet shortcode handler
|
162 |
shortcode_ui_register_for_shortcode(
|
163 |
self::SHORTCODE_TAG,
|
164 |
array(
|
165 |
+
'label' => esc_html( __( 'Embedded Tweet', 'twitter' ) ),
|
166 |
'listItemImage' => 'dashicons-twitter',
|
167 |
'attrs' => array(
|
168 |
array(
|
351 |
return $html;
|
352 |
}
|
353 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
/**
|
355 |
* Convert shortcode parameters into query parameters supported by the Twitter oEmbed endpoint
|
356 |
*
|
447 |
|
448 |
return implode( '_', $key_pieces );
|
449 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
}
|
src/Twitter/WordPress/Shortcodes/EmbeddedTweetVideo.php
CHANGED
@@ -63,15 +63,13 @@ class EmbeddedTweetVideo extends EmbeddedTweet
|
|
63 |
// register our shortcode and its handler
|
64 |
add_shortcode( self::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
65 |
|
66 |
-
//
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
);
|
74 |
-
}
|
75 |
}
|
76 |
|
77 |
/**
|
63 |
// register our shortcode and its handler
|
64 |
add_shortcode( self::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
65 |
|
66 |
+
// Shortcode UI, if supported
|
67 |
+
add_action(
|
68 |
+
'register_shortcode_ui',
|
69 |
+
array( __CLASS__, 'shortcodeUI' ),
|
70 |
+
5,
|
71 |
+
0
|
72 |
+
);
|
|
|
|
|
73 |
}
|
74 |
|
75 |
/**
|
src/Twitter/WordPress/Shortcodes/Follow.php
CHANGED
@@ -30,7 +30,7 @@ namespace Twitter\WordPress\Shortcodes;
|
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
-
class Follow
|
34 |
{
|
35 |
|
36 |
/**
|
@@ -62,15 +62,13 @@ class Follow
|
|
62 |
{
|
63 |
add_shortcode( static::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
64 |
|
65 |
-
//
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
);
|
73 |
-
}
|
74 |
}
|
75 |
|
76 |
/**
|
@@ -92,12 +90,12 @@ class Follow
|
|
92 |
shortcode_ui_register_for_shortcode(
|
93 |
static::SHORTCODE_TAG,
|
94 |
array(
|
95 |
-
'label' => __( 'Follow Button', 'twitter' ),
|
96 |
'listItemImage' => 'dashicons-twitter',
|
97 |
'attrs' => array(
|
98 |
array(
|
99 |
'attr' => 'screen_name',
|
100 |
-
'label' => __( 'Twitter @username', 'twitter' ),
|
101 |
'type' => 'text',
|
102 |
'meta' => array(
|
103 |
'placeholder' => 'WordPress',
|
@@ -106,12 +104,12 @@ class Follow
|
|
106 |
),
|
107 |
array(
|
108 |
'attr' => 'size',
|
109 |
-
'label' => __( 'Button size:', 'twitter' ),
|
110 |
'type' => 'radio',
|
111 |
-
'value' => '
|
112 |
'options' => array(
|
113 |
-
'' => _x( 'medium', 'medium size button', 'twitter' ),
|
114 |
-
'large' => _x( 'large', 'large size button', 'twitter' ),
|
115 |
),
|
116 |
),
|
117 |
),
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
+
class Follow implements ShortcodeInterface
|
34 |
{
|
35 |
|
36 |
/**
|
62 |
{
|
63 |
add_shortcode( static::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
64 |
|
65 |
+
// Shortcode UI, if supported
|
66 |
+
add_action(
|
67 |
+
'register_shortcode_ui',
|
68 |
+
array( __CLASS__, 'shortcodeUI' ),
|
69 |
+
5,
|
70 |
+
0
|
71 |
+
);
|
|
|
|
|
72 |
}
|
73 |
|
74 |
/**
|
90 |
shortcode_ui_register_for_shortcode(
|
91 |
static::SHORTCODE_TAG,
|
92 |
array(
|
93 |
+
'label' => esc_html( __( 'Follow Button', 'twitter' ) ),
|
94 |
'listItemImage' => 'dashicons-twitter',
|
95 |
'attrs' => array(
|
96 |
array(
|
97 |
'attr' => 'screen_name',
|
98 |
+
'label' => esc_html( __( 'Twitter @username', 'twitter' ) ),
|
99 |
'type' => 'text',
|
100 |
'meta' => array(
|
101 |
'placeholder' => 'WordPress',
|
104 |
),
|
105 |
array(
|
106 |
'attr' => 'size',
|
107 |
+
'label' => esc_html( __( 'Button size:', 'twitter' ) ),
|
108 |
'type' => 'radio',
|
109 |
+
'value' => '',
|
110 |
'options' => array(
|
111 |
+
'' => esc_html( _x( 'medium', 'medium size button', 'twitter' ) ),
|
112 |
+
'large' => esc_html( _x( 'large', 'large size button', 'twitter' ) ),
|
113 |
),
|
114 |
),
|
115 |
),
|
src/Twitter/WordPress/Shortcodes/Moment.php
CHANGED
@@ -30,7 +30,7 @@ namespace Twitter\WordPress\Shortcodes;
|
|
30 |
*
|
31 |
* @since 1.2.0
|
32 |
*/
|
33 |
-
class Moment
|
34 |
{
|
35 |
|
36 |
/**
|
@@ -43,13 +43,13 @@ class Moment
|
|
43 |
const SHORTCODE_TAG = 'twitter_moment';
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
*
|
48 |
-
* @since 1.
|
49 |
*
|
50 |
* @type string
|
51 |
*/
|
52 |
-
const
|
53 |
|
54 |
/**
|
55 |
* Regex used to match a Moment in text
|
@@ -70,252 +70,14 @@ class Moment
|
|
70 |
const BASE_URL = 'https://twitter.com/i/moments/';
|
71 |
|
72 |
/**
|
73 |
-
*
|
74 |
-
*
|
75 |
-
* @since 1.2.0
|
76 |
-
*
|
77 |
-
* @type array
|
78 |
-
*/
|
79 |
-
public static $SHORTCODE_DEFAULTS = array( 'id' => '' );
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Attach handlers for Twitter Moment
|
83 |
-
*
|
84 |
-
* @since 1.2.0
|
85 |
-
*
|
86 |
-
* @return void
|
87 |
-
*/
|
88 |
-
public static function init()
|
89 |
-
{
|
90 |
-
// register our shortcode and its handler
|
91 |
-
add_shortcode( self::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
92 |
-
|
93 |
-
wp_embed_register_handler(
|
94 |
-
self::SHORTCODE_TAG,
|
95 |
-
static::URL_REGEX,
|
96 |
-
array( __CLASS__, 'linkHandler' ),
|
97 |
-
1
|
98 |
-
);
|
99 |
-
|
100 |
-
if ( is_admin() ) {
|
101 |
-
// Shortcake UI
|
102 |
-
if ( function_exists( 'shortcode_ui_register_for_shortcode' ) ) {
|
103 |
-
add_action(
|
104 |
-
'admin_init',
|
105 |
-
array( __CLASS__, 'shortcodeUI' ),
|
106 |
-
5,
|
107 |
-
0
|
108 |
-
);
|
109 |
-
}
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Describe shortcode for Shortcake UI
|
115 |
-
*
|
116 |
-
* @since 1.2.0
|
117 |
-
*
|
118 |
-
* @link https://github.com/fusioneng/Shortcake Shortcake UI
|
119 |
-
*
|
120 |
-
* @return void
|
121 |
-
*/
|
122 |
-
public static function shortcodeUI()
|
123 |
-
{
|
124 |
-
// Shortcake required
|
125 |
-
if ( ! function_exists( 'shortcode_ui_register_for_shortcode' ) ) {
|
126 |
-
return;
|
127 |
-
}
|
128 |
-
|
129 |
-
shortcode_ui_register_for_shortcode(
|
130 |
-
self::SHORTCODE_TAG,
|
131 |
-
array(
|
132 |
-
'label' => __( 'Twitter Moment', 'twitter' ),
|
133 |
-
'listItemImage' => 'dashicons-twitter',
|
134 |
-
'attrs' => array(
|
135 |
-
array(
|
136 |
-
'attr' => 'id',
|
137 |
-
'label' => 'ID',
|
138 |
-
'type' => 'text',
|
139 |
-
'meta' => array(
|
140 |
-
'required' => true,
|
141 |
-
'pattern' => '[0-9]+',
|
142 |
-
),
|
143 |
-
),
|
144 |
-
),
|
145 |
-
)
|
146 |
-
);
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Handle a URL matched by a Moment embed handler
|
151 |
-
*
|
152 |
-
* @since 1.2.0
|
153 |
-
*
|
154 |
-
* @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
|
155 |
-
* @param array $attr Embed attributes. Not used.
|
156 |
-
* @param string $url The original URL that was matched by the regex. Not used.
|
157 |
-
* @param array $rawattr The original unmodified attributes. Not used.
|
158 |
-
*
|
159 |
-
* @return string HTML markup for the Tweet or an empty string if requirements not met
|
160 |
-
*/
|
161 |
-
public static function linkHandler( $matches, $attr, $url, $rawattr )
|
162 |
-
{
|
163 |
-
if ( ! ( is_array( $matches ) && isset( $matches[1] ) && $matches[1] ) ) {
|
164 |
-
return '';
|
165 |
-
}
|
166 |
-
|
167 |
-
return static::shortcodeHandler( array( 'id' => $matches[1] ) );
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* Handle shortcode macro
|
172 |
-
*
|
173 |
-
* @since 1.2.0
|
174 |
-
*
|
175 |
-
* @param array $attributes set of shortcode attribute-value pairs or positional content matching the WordPress shortcode regex {
|
176 |
-
* @type string|int attribute name or positional int
|
177 |
-
* @type mixed shortcode value
|
178 |
-
* }
|
179 |
-
* @param string $content content inside a shortcode macro. no effect on this shortcode
|
180 |
-
*
|
181 |
-
* @return string HTML markup. empty string if parameter requirement not met or no Moment info found
|
182 |
-
*/
|
183 |
-
public static function shortcodeHandler( $attributes, $content = '' )
|
184 |
-
{
|
185 |
-
$options = shortcode_atts(
|
186 |
-
static::$SHORTCODE_DEFAULTS,
|
187 |
-
$attributes,
|
188 |
-
static::SHORTCODE_TAG
|
189 |
-
);
|
190 |
-
|
191 |
-
$moment_id = trim( $options['id'] );
|
192 |
-
if ( ! $moment_id ) {
|
193 |
-
return '';
|
194 |
-
}
|
195 |
-
$query_parameters = static::getBaseOEmbedParams( $moment_id );
|
196 |
-
|
197 |
-
// fetch HTML markup from Twitter oEmbed endpoint for the given parameters
|
198 |
-
$html = trim( static::getOEmbedMarkup( $query_parameters ) );
|
199 |
-
if ( ! $html ) {
|
200 |
-
return '';
|
201 |
-
}
|
202 |
-
|
203 |
-
$html = '<div class="twitter-moment">' . $html . '</div>';
|
204 |
-
|
205 |
-
$inline_js = \Twitter\WordPress\JavaScriptLoaders\Widgets::enqueue();
|
206 |
-
if ( $inline_js ) {
|
207 |
-
return $html . $inline_js;
|
208 |
-
}
|
209 |
-
|
210 |
-
return $html;
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* Get the base set of oEmbed params before applying shortcode customizations
|
215 |
-
*
|
216 |
-
* @since 1.2.0
|
217 |
-
*
|
218 |
-
* @param string $moment_id Moment identifier
|
219 |
-
*
|
220 |
-
* @return array associative array of query parameters ready for http_build_query {
|
221 |
-
* @type string query parameter name
|
222 |
-
* @type string|bool query parameter value
|
223 |
-
* }
|
224 |
-
*/
|
225 |
-
public static function getBaseOEmbedParams( $moment_id )
|
226 |
-
{
|
227 |
-
$moment_id = trim( $moment_id );
|
228 |
-
if ( ! $moment_id ) {
|
229 |
-
return array();
|
230 |
-
}
|
231 |
-
|
232 |
-
// omit JavaScript. enqueue separately
|
233 |
-
$query_parameters = array(
|
234 |
-
'id' => $moment_id,
|
235 |
-
'omit_script' => true,
|
236 |
-
);
|
237 |
-
|
238 |
-
// attempt to customize text for site language
|
239 |
-
$lang = \Twitter\WordPress\Language::localeToTwitterLang();
|
240 |
-
if ( $lang ) {
|
241 |
-
$query_parameters['lang'] = $lang;
|
242 |
-
}
|
243 |
-
|
244 |
-
return $query_parameters;
|
245 |
-
}
|
246 |
-
|
247 |
-
/**
|
248 |
-
* Construct a cache key for the oEmbed response. Account for query parameters needing to bust cache
|
249 |
*
|
250 |
-
* @since 1.
|
251 |
-
*
|
252 |
-
* @param array $query_parameters oEmbed API query parameters
|
253 |
*
|
254 |
-
* @return string
|
255 |
*/
|
256 |
-
public static function
|
257 |
{
|
258 |
-
|
259 |
-
return '';
|
260 |
-
}
|
261 |
-
|
262 |
-
$key_pieces = array( self::SHORTCODE_TAG, $query_parameters['id'] );
|
263 |
-
|
264 |
-
// separate cache for each explicitly-defined display language
|
265 |
-
if ( isset( $query_parameters['lang'] ) && $query_parameters['lang'] ) {
|
266 |
-
$key_pieces[] = $query_parameters['lang'];
|
267 |
-
}
|
268 |
-
|
269 |
-
return implode( '_', $key_pieces );
|
270 |
-
}
|
271 |
-
|
272 |
-
/**
|
273 |
-
* Request and parse Moment oEmbed markup from Twitter's servers
|
274 |
-
*
|
275 |
-
* @since 1.2.0
|
276 |
-
*
|
277 |
-
* @param string $moment_id Moment identifier
|
278 |
-
*
|
279 |
-
* @todo make this not mocked
|
280 |
-
* @return string HTML markup returned by the oEmbed endpoint
|
281 |
-
*/
|
282 |
-
public static function getOEmbedMarkup( $query_parameters ) {
|
283 |
-
$cache_key = static::oEmbedCacheKey( $query_parameters );
|
284 |
-
if ( ! $cache_key ) {
|
285 |
-
return '';
|
286 |
-
}
|
287 |
-
|
288 |
-
$cache_key = static::oEmbedCacheKey( $query_parameters );
|
289 |
-
if ( ! $cache_key ) {
|
290 |
-
return '';
|
291 |
-
}
|
292 |
-
|
293 |
-
// check for cached result
|
294 |
-
$html = get_transient( $cache_key );
|
295 |
-
if ( $html ) {
|
296 |
-
return $html;
|
297 |
-
}
|
298 |
-
|
299 |
-
$ttl = DAY_IN_SECONDS;
|
300 |
-
|
301 |
-
// convert ID to full URL to allow more flexibility for oEmbed endpoint as embed types expand
|
302 |
-
$query_parameters['url'] = self::BASE_URL . $query_parameters['id'];
|
303 |
-
unset( $query_parameters['id'] );
|
304 |
-
|
305 |
-
$oembed_response = \Twitter\WordPress\Helpers\TwitterOEmbed::getJSON( self::OEMBED_API_ENDPOINT, $query_parameters );
|
306 |
-
if ( ! $oembed_response || ! isset( $oembed_response->type ) || 'rich' !== $oembed_response->type || ! ( isset( $oembed_response->html ) && $oembed_response->html ) ) {
|
307 |
-
// do not rerequest errors with every page request
|
308 |
-
set_transient( $cache_key, ' ', $ttl );
|
309 |
-
return '';
|
310 |
-
}
|
311 |
-
|
312 |
-
$html = $oembed_response->html;
|
313 |
-
|
314 |
-
if ( isset( $oembed_response->cache_age ) ) {
|
315 |
-
$ttl = absint( $oembed_response->cache_age );
|
316 |
-
}
|
317 |
-
set_transient( $cache_key, $html, $ttl );
|
318 |
-
|
319 |
-
return $html;
|
320 |
}
|
321 |
}
|
30 |
*
|
31 |
* @since 1.2.0
|
32 |
*/
|
33 |
+
class Moment extends TweetGrid
|
34 |
{
|
35 |
|
36 |
/**
|
43 |
const SHORTCODE_TAG = 'twitter_moment';
|
44 |
|
45 |
/**
|
46 |
+
* HTML class to be used in div wrapper
|
47 |
*
|
48 |
+
* @since 1.3.0
|
49 |
*
|
50 |
* @type string
|
51 |
*/
|
52 |
+
const HTML_CLASS = 'twitter-moment';
|
53 |
|
54 |
/**
|
55 |
* Regex used to match a Moment in text
|
70 |
const BASE_URL = 'https://twitter.com/i/moments/';
|
71 |
|
72 |
/**
|
73 |
+
* Reference the feature by name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
*
|
75 |
+
* @since 1.3.0
|
|
|
|
|
76 |
*
|
77 |
+
* @return string translated feature name
|
78 |
*/
|
79 |
+
public static function featureName()
|
80 |
{
|
81 |
+
return __( 'Twitter Moment', 'twitter' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
83 |
}
|
src/Twitter/WordPress/Shortcodes/OEmbedTrait.php
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Shortcodes;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Set up and fetch a Twitter oEmbed capable object
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
trait OEmbedTrait
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Get the base set of oEmbed params before applying shortcode customizations
|
37 |
+
*
|
38 |
+
* @since 1.3.0
|
39 |
+
*
|
40 |
+
* @param string $snowflake_id object identifier
|
41 |
+
*
|
42 |
+
* @return array associative array of query parameters ready for http_build_query {
|
43 |
+
* @type string query parameter name
|
44 |
+
* @type string|bool query parameter value
|
45 |
+
* }
|
46 |
+
*/
|
47 |
+
public static function getBaseOEmbedParams( $snowflake_id )
|
48 |
+
{
|
49 |
+
$snowflake_id = trim( $snowflake_id );
|
50 |
+
if ( ! $snowflake_id ) {
|
51 |
+
return array();
|
52 |
+
}
|
53 |
+
|
54 |
+
// omit JavaScript. enqueue separately
|
55 |
+
$query_parameters = array(
|
56 |
+
'id' => $snowflake_id,
|
57 |
+
'omit_script' => true,
|
58 |
+
);
|
59 |
+
|
60 |
+
// attempt to customize text for site language
|
61 |
+
$lang = \Twitter\WordPress\Language::localeToTwitterLang();
|
62 |
+
if ( $lang ) {
|
63 |
+
$query_parameters['lang'] = $lang;
|
64 |
+
}
|
65 |
+
|
66 |
+
return $query_parameters;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Request and parse oEmbed markup from Twitter's servers
|
71 |
+
*
|
72 |
+
* @since 1.3.0
|
73 |
+
*
|
74 |
+
* @param array $query_parameters query parameters to be passed to the oEmbed endpoint
|
75 |
+
*
|
76 |
+
* @todo make this not mocked
|
77 |
+
* @return string HTML markup returned by the oEmbed endpoint
|
78 |
+
*/
|
79 |
+
public static function getOEmbedMarkup( $query_parameters )
|
80 |
+
{
|
81 |
+
$cache_key = static::oEmbedCacheKey( $query_parameters );
|
82 |
+
if ( ! $cache_key ) {
|
83 |
+
return '';
|
84 |
+
}
|
85 |
+
|
86 |
+
// check for cached result
|
87 |
+
$html = get_transient( $cache_key );
|
88 |
+
if ( $html ) {
|
89 |
+
return $html;
|
90 |
+
}
|
91 |
+
|
92 |
+
$classname = get_called_class();
|
93 |
+
if ( ! ( defined( $classname . '::OEMBED_API_CLASS' ) && static::OEMBED_API_CLASS ) ) {
|
94 |
+
return '';
|
95 |
+
}
|
96 |
+
$oembed_api_class = static::OEMBED_API_CLASS;
|
97 |
+
if ( ! ( class_exists( $oembed_api_class ) && method_exists( $oembed_api_class, 'getJSON' ) ) ) {
|
98 |
+
return '';
|
99 |
+
}
|
100 |
+
|
101 |
+
if ( defined( $classname . '::BASE_URL' ) ) {
|
102 |
+
// convert ID to full URL to allow more flexibility for oEmbed endpoint
|
103 |
+
$query_parameters['url'] = static::BASE_URL . $query_parameters['id'];
|
104 |
+
unset( $query_parameters['id'] );
|
105 |
+
}
|
106 |
+
|
107 |
+
$allowed_resource_types = array( 'rich' => true, 'video' => true );
|
108 |
+
$ttl = DAY_IN_SECONDS;
|
109 |
+
|
110 |
+
$oembed_response = $oembed_api_class::getJSON( static::OEMBED_API_ENDPOINT, $query_parameters );
|
111 |
+
if ( ! (
|
112 |
+
$oembed_response &&
|
113 |
+
isset( $oembed_response->type ) &&
|
114 |
+
isset( $allowed_resource_types[ $oembed_response->type ] ) &&
|
115 |
+
isset( $oembed_response->html ) &&
|
116 |
+
$oembed_response->html
|
117 |
+
) ) {
|
118 |
+
// do not rerequest errors with every page request
|
119 |
+
set_transient( $cache_key, ' ', $ttl );
|
120 |
+
return '';
|
121 |
+
}
|
122 |
+
|
123 |
+
$html = $oembed_response->html;
|
124 |
+
|
125 |
+
if ( isset( $oembed_response->cache_age ) ) {
|
126 |
+
$ttl = absint( $oembed_response->cache_age );
|
127 |
+
}
|
128 |
+
set_transient( $cache_key, $html, $ttl );
|
129 |
+
|
130 |
+
return $html;
|
131 |
+
}
|
132 |
+
}
|
src/Twitter/WordPress/Shortcodes/PeriscopeOnAir.php
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Shortcodes;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Display a Periscope On Air button
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class PeriscopeOnAir implements ShortcodeInterface
|
34 |
+
{
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Shortcode tag to be matched
|
38 |
+
*
|
39 |
+
* @since 1.3.0
|
40 |
+
*
|
41 |
+
* @type string
|
42 |
+
*/
|
43 |
+
const SHORTCODE_TAG = 'periscope_on_air';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Regex used to match a Periscope profile URL in text
|
47 |
+
*
|
48 |
+
* @since 1.3.0
|
49 |
+
*
|
50 |
+
* @type string
|
51 |
+
*/
|
52 |
+
const PERISCOPE_PROFILE_URL_REGEX = '#^https://(www\.)?periscope\.tv/([a-z0-9_]{1,20})#i';
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Accepted shortcode attributes and their default values
|
56 |
+
*
|
57 |
+
* @since 1.3.0
|
58 |
+
*
|
59 |
+
* @type array
|
60 |
+
*/
|
61 |
+
public static $SHORTCODE_DEFAULTS = array( 'username' => '', 'size' => 'small' );
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Register shortcode macro and handler
|
65 |
+
*
|
66 |
+
* @since 1.3.0
|
67 |
+
*
|
68 |
+
* @return void
|
69 |
+
*/
|
70 |
+
public static function init()
|
71 |
+
{
|
72 |
+
add_shortcode( static::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
73 |
+
|
74 |
+
// pass a Periscope profile URL through the Periscope On Air shortcode handler
|
75 |
+
wp_embed_register_handler(
|
76 |
+
self::SHORTCODE_TAG,
|
77 |
+
static::PERISCOPE_PROFILE_URL_REGEX,
|
78 |
+
array( __CLASS__, 'linkHandler' ),
|
79 |
+
1
|
80 |
+
);
|
81 |
+
|
82 |
+
// Shortcode UI, if supported
|
83 |
+
add_action(
|
84 |
+
'register_shortcode_ui',
|
85 |
+
array( __CLASS__, 'shortcodeUI' ),
|
86 |
+
5,
|
87 |
+
0
|
88 |
+
);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Describe shortcode for Shortcake UI
|
93 |
+
*
|
94 |
+
* @since 1.3.0
|
95 |
+
*
|
96 |
+
* @link https://github.com/fusioneng/Shortcake Shortcake UI
|
97 |
+
*
|
98 |
+
* @return void
|
99 |
+
*/
|
100 |
+
public static function shortcodeUI()
|
101 |
+
{
|
102 |
+
// Shortcake required
|
103 |
+
if ( ! function_exists( 'shortcode_ui_register_for_shortcode' ) ) {
|
104 |
+
return;
|
105 |
+
}
|
106 |
+
|
107 |
+
shortcode_ui_register_for_shortcode(
|
108 |
+
static::SHORTCODE_TAG,
|
109 |
+
array(
|
110 |
+
'label' => esc_html( __( 'Periscope On Air', 'twitter' ) ),
|
111 |
+
'listItemImage' => 'dashicons-video-alt',
|
112 |
+
'attrs' => array(
|
113 |
+
array(
|
114 |
+
'attr' => 'username',
|
115 |
+
'label' => esc_html( __( 'Periscope username', 'twitter' ) ),
|
116 |
+
'type' => 'text',
|
117 |
+
'meta' => array(
|
118 |
+
'placeholder' => 'photomatt',
|
119 |
+
'pattern' => '[A-Za-z0-9_]{1,20}',
|
120 |
+
),
|
121 |
+
),
|
122 |
+
array(
|
123 |
+
'attr' => 'size',
|
124 |
+
'label' => esc_html( __( 'Button size:', 'twitter' ) ),
|
125 |
+
'type' => 'radio',
|
126 |
+
'value' => '',
|
127 |
+
'options' => array(
|
128 |
+
'' => esc_html( _x( 'small', 'small size button', 'twitter' ) ),
|
129 |
+
'large' => esc_html( _x( 'large', 'large size button', 'twitter' ) ),
|
130 |
+
),
|
131 |
+
),
|
132 |
+
),
|
133 |
+
)
|
134 |
+
);
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Handle a URL matched by an embed handler
|
139 |
+
*
|
140 |
+
* @since 1.3.0
|
141 |
+
*
|
142 |
+
* @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
|
143 |
+
* @param array $attr Embed attributes. Not used.
|
144 |
+
* @param string $url The original URL that was matched by the regex. Not used.
|
145 |
+
* @param array $rawattr The original unmodified attributes. Not used.
|
146 |
+
*
|
147 |
+
* @return string HTML markup for the Tweet or an empty string if requirements not met
|
148 |
+
*/
|
149 |
+
public static function linkHandler( $matches, $attr, $url, $rawattr )
|
150 |
+
{
|
151 |
+
if ( ! ( is_array( $matches ) && isset( $matches[2] ) && $matches[2] ) ) {
|
152 |
+
return '';
|
153 |
+
}
|
154 |
+
|
155 |
+
return static::shortcodeHandler( array( 'username' => $matches[2] ) );
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Clean up provided shortcode values
|
160 |
+
*
|
161 |
+
* @since 1.3.0
|
162 |
+
*
|
163 |
+
* @param array $attributes provided shortcode attributes {
|
164 |
+
* @type string shortcode attribute name
|
165 |
+
* @type mixed shortcode attribute value
|
166 |
+
* }
|
167 |
+
*
|
168 |
+
* @return array simplified shortcode values with defaults removed {
|
169 |
+
* @type string shortcode attribute name
|
170 |
+
* @type bool|string shortcode attribute value
|
171 |
+
* }
|
172 |
+
*/
|
173 |
+
public static function sanitizeShortcodeParameters( $attributes = array() )
|
174 |
+
{
|
175 |
+
if ( ! is_array( $attributes ) ) {
|
176 |
+
return array();
|
177 |
+
}
|
178 |
+
|
179 |
+
$options = array();
|
180 |
+
|
181 |
+
if ( isset( $attributes['username'] ) ) {
|
182 |
+
$username = \Twitter\Helpers\Validators\PeriscopeUsername::trim( $attributes['username'] );
|
183 |
+
if ( $username ) {
|
184 |
+
$options['username'] = $username;
|
185 |
+
}
|
186 |
+
unset( $username );
|
187 |
+
}
|
188 |
+
|
189 |
+
// large is the only option
|
190 |
+
if ( isset( $attributes['size'] ) ) {
|
191 |
+
if ( is_string( $attributes['size'] ) && in_array( strtolower( $attributes['size'] ), array( 'large', 'l' ) ) ) {
|
192 |
+
$options['size'] = 'large';
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
return $options;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Get the Periscope username of the author of the current post
|
201 |
+
*
|
202 |
+
* @since 1.3.0
|
203 |
+
*
|
204 |
+
* @return string Periscope username or empty if no screen name stored
|
205 |
+
*/
|
206 |
+
public static function getUsername()
|
207 |
+
{
|
208 |
+
if ( ! in_the_loop() ) {
|
209 |
+
return '';
|
210 |
+
}
|
211 |
+
|
212 |
+
$username = \Twitter\WordPress\User\Meta::getPeriscopeUsername( get_the_author_meta( 'ID' ) );
|
213 |
+
if ( ! $username ) {
|
214 |
+
return '';
|
215 |
+
}
|
216 |
+
|
217 |
+
return $username;
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Handle shortcode macro
|
222 |
+
*
|
223 |
+
* @since 1.3.0
|
224 |
+
*
|
225 |
+
* @param array $attributes shortcode attributes
|
226 |
+
* @param string $content shortcode content. no effect
|
227 |
+
*
|
228 |
+
* @return string Periscope On Air button HTML or empty string
|
229 |
+
*/
|
230 |
+
public static function shortcodeHandler( $attributes, $content = '' )
|
231 |
+
{
|
232 |
+
// clean up attribute to shortcode option mappings before passing to filter
|
233 |
+
// apply the same filter as shortcode_atts
|
234 |
+
/** This filter is documented in wp-includes/shortcodes.php */
|
235 |
+
$options = apply_filters(
|
236 |
+
'shortcode_atts_' . self::SHORTCODE_TAG,
|
237 |
+
array_merge(
|
238 |
+
static::$SHORTCODE_DEFAULTS,
|
239 |
+
static::sanitizeShortcodeParameters( (array) $attributes )
|
240 |
+
),
|
241 |
+
static::$SHORTCODE_DEFAULTS,
|
242 |
+
$attributes
|
243 |
+
);
|
244 |
+
|
245 |
+
$username = '';
|
246 |
+
if ( isset( $options['username'] ) ) {
|
247 |
+
$username = $options['username'];
|
248 |
+
unset( $options['username'] );
|
249 |
+
}
|
250 |
+
if ( ! $username ) {
|
251 |
+
$username = static::getUsername();
|
252 |
+
// user target required
|
253 |
+
if ( ! $username ) {
|
254 |
+
return '';
|
255 |
+
}
|
256 |
+
}
|
257 |
+
|
258 |
+
// update the options array with the Periscope username
|
259 |
+
$options['username'] = $username;
|
260 |
+
unset( $username );
|
261 |
+
|
262 |
+
$on_air = \Twitter\Widgets\PeriscopeOnAir::fromArray( $options );
|
263 |
+
if ( ! $on_air ) {
|
264 |
+
return '';
|
265 |
+
}
|
266 |
+
|
267 |
+
$html = $on_air->toHTML( '\Twitter\WordPress\Helpers\HTMLBuilder' );
|
268 |
+
if ( ! $html ) {
|
269 |
+
return '';
|
270 |
+
}
|
271 |
+
|
272 |
+
$html = '<div class="periscope-on-air">' . $html . '</div>';
|
273 |
+
|
274 |
+
$inline_js = \Twitter\WordPress\JavaScriptLoaders\Widgets::enqueue();
|
275 |
+
if ( $inline_js ) {
|
276 |
+
return $html . $inline_js;
|
277 |
+
}
|
278 |
+
|
279 |
+
return $html;
|
280 |
+
}
|
281 |
+
}
|
src/Twitter/WordPress/Shortcodes/Share.php
CHANGED
@@ -30,7 +30,7 @@ namespace Twitter\WordPress\Shortcodes;
|
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
-
class Share
|
34 |
{
|
35 |
|
36 |
/**
|
@@ -62,15 +62,13 @@ class Share
|
|
62 |
{
|
63 |
add_shortcode( static::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
64 |
|
65 |
-
//
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
);
|
73 |
-
}
|
74 |
}
|
75 |
|
76 |
/**
|
@@ -92,12 +90,12 @@ class Share
|
|
92 |
shortcode_ui_register_for_shortcode(
|
93 |
static::SHORTCODE_TAG,
|
94 |
array(
|
95 |
-
'label' => __( 'Tweet Button', 'twitter' ),
|
96 |
'listItemImage' => 'dashicons-twitter',
|
97 |
'attrs' => array(
|
98 |
array(
|
99 |
'attr' => 'text',
|
100 |
-
'label' => _x( 'Text', 'Share / Tweet text', 'twitter' ),
|
101 |
'type' => 'text',
|
102 |
),
|
103 |
array(
|
@@ -107,12 +105,12 @@ class Share
|
|
107 |
),
|
108 |
array(
|
109 |
'attr' => 'size',
|
110 |
-
'label' => __( 'Button size:', 'twitter' ),
|
111 |
'type' => 'radio',
|
112 |
-
'value' => '
|
113 |
'options' => array(
|
114 |
-
'' => _x( 'medium', 'medium size button', 'twitter' ),
|
115 |
-
'large' => _x( 'large', 'large size button', 'twitter' ),
|
116 |
),
|
117 |
),
|
118 |
),
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
+
class Share implements ShortcodeInterface
|
34 |
{
|
35 |
|
36 |
/**
|
62 |
{
|
63 |
add_shortcode( static::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
64 |
|
65 |
+
// Shortcode UI, if supported
|
66 |
+
add_action(
|
67 |
+
'register_shortcode_ui',
|
68 |
+
array( __CLASS__, 'shortcodeUI' ),
|
69 |
+
5,
|
70 |
+
0
|
71 |
+
);
|
|
|
|
|
72 |
}
|
73 |
|
74 |
/**
|
90 |
shortcode_ui_register_for_shortcode(
|
91 |
static::SHORTCODE_TAG,
|
92 |
array(
|
93 |
+
'label' => esc_html( __( 'Tweet Button', 'twitter' ) ),
|
94 |
'listItemImage' => 'dashicons-twitter',
|
95 |
'attrs' => array(
|
96 |
array(
|
97 |
'attr' => 'text',
|
98 |
+
'label' => esc_html( _x( 'Text', 'Share / Tweet text', 'twitter' ) ),
|
99 |
'type' => 'text',
|
100 |
),
|
101 |
array(
|
105 |
),
|
106 |
array(
|
107 |
'attr' => 'size',
|
108 |
+
'label' => esc_html( __( 'Button size:', 'twitter' ) ),
|
109 |
'type' => 'radio',
|
110 |
+
'value' => '',
|
111 |
'options' => array(
|
112 |
+
'' => esc_html( _x( 'medium', 'medium size button', 'twitter' ) ),
|
113 |
+
'large' => esc_html( _x( 'large', 'large size button', 'twitter' ) ),
|
114 |
),
|
115 |
),
|
116 |
),
|
src/Twitter/WordPress/Shortcodes/ShortcodeInterface.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Shortcodes;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Common methods expected to exist in each shortcode handler
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
interface ShortcodeInterface
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Register shortcode macro and handler
|
37 |
+
*
|
38 |
+
* @since 1.3.0
|
39 |
+
*
|
40 |
+
* @return void
|
41 |
+
*/
|
42 |
+
public static function init();
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Describe shortcode for Shortcake UI
|
46 |
+
*
|
47 |
+
* @since 1.3.0
|
48 |
+
*
|
49 |
+
* @link https://github.com/fusioneng/Shortcake Shortcake UI
|
50 |
+
*
|
51 |
+
* @return void
|
52 |
+
*/
|
53 |
+
public static function shortcodeUI();
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Handle shortcode macro
|
57 |
+
*
|
58 |
+
* @since 1.3.0
|
59 |
+
*
|
60 |
+
* @param array $attributes shortcode attributes
|
61 |
+
* @param string $content shortcode content. no effect
|
62 |
+
*
|
63 |
+
* @return string HTML result or empty string. JavaScript dependencies should be enqueued or loaded in the returned HTML
|
64 |
+
*/
|
65 |
+
public static function shortcodeHandler( $attributes, $content );
|
66 |
+
}
|
src/Twitter/WordPress/Shortcodes/Tracking.php
CHANGED
@@ -30,7 +30,7 @@ namespace Twitter\WordPress\Shortcodes;
|
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
-
class Tracking
|
34 |
{
|
35 |
|
36 |
/**
|
@@ -71,15 +71,13 @@ class Tracking
|
|
71 |
{
|
72 |
add_shortcode( static::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
73 |
|
74 |
-
//
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
);
|
82 |
-
}
|
83 |
}
|
84 |
|
85 |
/**
|
@@ -101,13 +99,13 @@ class Tracking
|
|
101 |
shortcode_ui_register_for_shortcode(
|
102 |
static::SHORTCODE_TAG,
|
103 |
array(
|
104 |
-
'label' => __( 'Twitter Advertising Tracker', 'twitter' ),
|
105 |
'listItemImage' => 'dashicons-twitter',
|
106 |
'attrs' => array(
|
107 |
array(
|
108 |
'attr' => 'id',
|
109 |
'label' => 'ID',
|
110 |
-
'description' => __( 'Twitter conversion or remarketing audience tracking identifier', 'twitter' ),
|
111 |
'type' => 'text',
|
112 |
'meta' => array(
|
113 |
'required' => true,
|
30 |
*
|
31 |
* @since 1.0.0
|
32 |
*/
|
33 |
+
class Tracking implements ShortcodeInterface
|
34 |
{
|
35 |
|
36 |
/**
|
71 |
{
|
72 |
add_shortcode( static::SHORTCODE_TAG, array( __CLASS__, 'shortcodeHandler' ) );
|
73 |
|
74 |
+
// Shortcode UI, if supported
|
75 |
+
add_action(
|
76 |
+
'register_shortcode_ui',
|
77 |
+
array( __CLASS__, 'shortcodeUI' ),
|
78 |
+
5,
|
79 |
+
0
|
80 |
+
);
|
|
|
|
|
81 |
}
|
82 |
|
83 |
/**
|
99 |
shortcode_ui_register_for_shortcode(
|
100 |
static::SHORTCODE_TAG,
|
101 |
array(
|
102 |
+
'label' => esc_html( __( 'Twitter Advertising Tracker', 'twitter' ) ),
|
103 |
'listItemImage' => 'dashicons-twitter',
|
104 |
'attrs' => array(
|
105 |
array(
|
106 |
'attr' => 'id',
|
107 |
'label' => 'ID',
|
108 |
+
'description' => esc_html( __( 'Twitter conversion or remarketing audience tracking identifier', 'twitter' ) ),
|
109 |
'type' => 'text',
|
110 |
'meta' => array(
|
111 |
'required' => true,
|
src/Twitter/WordPress/Shortcodes/TweetGrid.php
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Shortcodes;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Display a grid of Tweets
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class TweetGrid implements ShortcodeInterface
|
34 |
+
{
|
35 |
+
use OEmbedTrait;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Shortcode tag to be matched
|
39 |
+
*
|
40 |
+
* @since 1.3.0
|
41 |
+
*
|
42 |
+
* @type string
|
43 |
+
*/
|
44 |
+
const SHORTCODE_TAG = 'twitter_grid';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* HTML class to be used in div wrapper
|
48 |
+
*
|
49 |
+
* @since 1.3.0
|
50 |
+
*
|
51 |
+
* @type string
|
52 |
+
*/
|
53 |
+
const HTML_CLASS = 'twitter-grid';
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Regex used to match a Collection in text
|
57 |
+
*
|
58 |
+
* @since 1.3.0
|
59 |
+
*
|
60 |
+
* @type string
|
61 |
+
*/
|
62 |
+
const URL_REGEX = '#^https://twitter\.com/.+?/timelines/([0-9]+)#i';
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Base URL used to reconstruct a Collection URL
|
66 |
+
*
|
67 |
+
* @since 1.3.0
|
68 |
+
*
|
69 |
+
* @type string
|
70 |
+
*/
|
71 |
+
const BASE_URL = 'https://twitter.com/_/timelines/';
|
72 |
+
|
73 |
+
/**
|
74 |
+
* PHP class to use for fetching oEmbed data
|
75 |
+
*
|
76 |
+
* @since 1.3.0
|
77 |
+
*
|
78 |
+
* @type string
|
79 |
+
*/
|
80 |
+
const OEMBED_API_CLASS = '\Twitter\WordPress\Helpers\TwitterOEmbed';
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Relative path for the oEmbed API relative to Twitter publishers base path
|
84 |
+
*
|
85 |
+
* @since 1.3.0
|
86 |
+
*
|
87 |
+
* @type string
|
88 |
+
*/
|
89 |
+
const OEMBED_API_ENDPOINT = 'oembed';
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Accepted shortcode attributes and their default values
|
93 |
+
*
|
94 |
+
* @since 1.3.0
|
95 |
+
*
|
96 |
+
* @type array
|
97 |
+
*/
|
98 |
+
public static $SHORTCODE_DEFAULTS = array( 'id' => '', 'limit' => 20 );
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Attach handlers for Twitter Grid
|
102 |
+
*
|
103 |
+
* @since 1.3.0
|
104 |
+
*
|
105 |
+
* @return void
|
106 |
+
*/
|
107 |
+
public static function init()
|
108 |
+
{
|
109 |
+
$classname = get_called_class();
|
110 |
+
|
111 |
+
// register our shortcode and its handler
|
112 |
+
add_shortcode( static::SHORTCODE_TAG, array( $classname, 'shortcodeHandler' ) );
|
113 |
+
|
114 |
+
// convert a URL into the shortcode equivalent
|
115 |
+
wp_embed_register_handler(
|
116 |
+
static::SHORTCODE_TAG,
|
117 |
+
static::URL_REGEX,
|
118 |
+
array( $classname, 'linkHandler' ),
|
119 |
+
1
|
120 |
+
);
|
121 |
+
|
122 |
+
// Shortcode UI, if supported
|
123 |
+
add_action(
|
124 |
+
'register_shortcode_ui',
|
125 |
+
array( $classname, 'shortcodeUI' ),
|
126 |
+
5,
|
127 |
+
0
|
128 |
+
);
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Reference the feature by name
|
133 |
+
*
|
134 |
+
* @since 1.3.0
|
135 |
+
*
|
136 |
+
* @return string translated feature name
|
137 |
+
*/
|
138 |
+
public static function featureName()
|
139 |
+
{
|
140 |
+
return __( 'Tweet Grid', 'twitter' );
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Describe shortcode for Shortcake UI
|
145 |
+
*
|
146 |
+
* @since 1.3.0
|
147 |
+
*
|
148 |
+
* @link https://github.com/fusioneng/Shortcake Shortcake UI
|
149 |
+
*
|
150 |
+
* @return void
|
151 |
+
*/
|
152 |
+
public static function shortcodeUI()
|
153 |
+
{
|
154 |
+
// Shortcake required
|
155 |
+
if ( ! function_exists( 'shortcode_ui_register_for_shortcode' ) ) {
|
156 |
+
return;
|
157 |
+
}
|
158 |
+
|
159 |
+
shortcode_ui_register_for_shortcode(
|
160 |
+
static::SHORTCODE_TAG,
|
161 |
+
array(
|
162 |
+
'label' => esc_html( static::featureName() ),
|
163 |
+
'listItemImage' => 'dashicons-twitter',
|
164 |
+
'attrs' => array(
|
165 |
+
array(
|
166 |
+
'attr' => 'id',
|
167 |
+
'label' => 'ID',
|
168 |
+
'type' => 'text',
|
169 |
+
'meta' => array(
|
170 |
+
'required' => true,
|
171 |
+
'pattern' => '[0-9]+',
|
172 |
+
),
|
173 |
+
),
|
174 |
+
array(
|
175 |
+
'attr' => 'limit',
|
176 |
+
'label' => _x( 'Limit', 'Maximum number of items to include', 'twitter' ),
|
177 |
+
'type' => 'number',
|
178 |
+
'value' => static::$SHORTCODE_DEFAULTS['limit'],
|
179 |
+
'meta' => array(
|
180 |
+
'min' => 1,
|
181 |
+
'max' => 20,
|
182 |
+
'step' => 1,
|
183 |
+
),
|
184 |
+
),
|
185 |
+
),
|
186 |
+
)
|
187 |
+
);
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Handle a URL matched by a embed handler
|
192 |
+
*
|
193 |
+
* @since 1.3.0
|
194 |
+
*
|
195 |
+
* @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
|
196 |
+
* @param array $attr Embed attributes. Not used.
|
197 |
+
* @param string $url The original URL that was matched by the regex. Not used.
|
198 |
+
* @param array $rawattr The original unmodified attributes. Not used.
|
199 |
+
*
|
200 |
+
* @return string HTML markup for the Tweet or an empty string if requirements not met
|
201 |
+
*/
|
202 |
+
public static function linkHandler( $matches, $attr, $url, $rawattr )
|
203 |
+
{
|
204 |
+
if ( ! ( is_array( $matches ) && isset( $matches[1] ) && $matches[1] ) ) {
|
205 |
+
return '';
|
206 |
+
}
|
207 |
+
|
208 |
+
return static::shortcodeHandler( array( 'id' => $matches[1] ) );
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Handle shortcode macro
|
213 |
+
*
|
214 |
+
* @since 1.3.0
|
215 |
+
*
|
216 |
+
* @param array $attributes set of shortcode attribute-value pairs or positional content matching the WordPress shortcode regex {
|
217 |
+
* @type string|int attribute name or positional int
|
218 |
+
* @type mixed shortcode value
|
219 |
+
* }
|
220 |
+
* @param string $content content inside a shortcode macro. no effect on this shortcode
|
221 |
+
*
|
222 |
+
* @return string HTML markup. empty string if parameter requirement not met or no collection info found
|
223 |
+
*/
|
224 |
+
public static function shortcodeHandler( $attributes, $content = '' )
|
225 |
+
{
|
226 |
+
$options = shortcode_atts(
|
227 |
+
static::$SHORTCODE_DEFAULTS,
|
228 |
+
$attributes,
|
229 |
+
static::SHORTCODE_TAG
|
230 |
+
);
|
231 |
+
|
232 |
+
$snowflake_id = trim( $options['id'] );
|
233 |
+
if ( ! $snowflake_id ) {
|
234 |
+
return '';
|
235 |
+
}
|
236 |
+
|
237 |
+
$query_parameters = static::getBaseOEmbedParams( $snowflake_id );
|
238 |
+
if ( isset( $options['limit'] ) ) {
|
239 |
+
$limit = 0;
|
240 |
+
try {
|
241 |
+
$limit = intval( trim( $options['limit'] ), 10 );
|
242 |
+
} catch( Exception $e ) {}
|
243 |
+
if ( $limit > 0 && $limit < 20 ) {
|
244 |
+
$query_parameters['limit'] = $limit;
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
// fetch HTML markup from Twitter oEmbed endpoint for the given parameters
|
249 |
+
$html = trim( static::getOEmbedMarkup( $query_parameters ) );
|
250 |
+
if ( ! $html ) {
|
251 |
+
return '';
|
252 |
+
}
|
253 |
+
|
254 |
+
$html = '<div class="' . sanitize_html_class( static::HTML_CLASS ) . '">' . $html . '</div>';
|
255 |
+
|
256 |
+
$inline_js = \Twitter\WordPress\JavaScriptLoaders\Widgets::enqueue();
|
257 |
+
if ( $inline_js ) {
|
258 |
+
return $html . $inline_js;
|
259 |
+
}
|
260 |
+
|
261 |
+
return $html;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Construct a cache key for the oEmbed response. Account for query parameters needing to bust cache
|
266 |
+
*
|
267 |
+
* @since 1.3.0
|
268 |
+
*
|
269 |
+
* @param array $query_parameters oEmbed API query parameters
|
270 |
+
*
|
271 |
+
* @return string cache key
|
272 |
+
*/
|
273 |
+
public static function oEmbedCacheKey( array $query_parameters )
|
274 |
+
{
|
275 |
+
if ( ! ( isset( $query_parameters['id'] ) && $query_parameters['id'] ) ) {
|
276 |
+
return '';
|
277 |
+
}
|
278 |
+
|
279 |
+
$key_pieces = array( static::SHORTCODE_TAG, $query_parameters['id'] );
|
280 |
+
|
281 |
+
// separate cache for each explicitly-defined display language
|
282 |
+
if ( isset( $query_parameters['lang'] ) && $query_parameters['lang'] ) {
|
283 |
+
$key_pieces[] = $query_parameters['lang'];
|
284 |
+
}
|
285 |
+
|
286 |
+
if ( isset( $query_parameters['limit'] ) && $query_parameters['limit'] ) {
|
287 |
+
$key_pieces[] = $query_parameters['limit'];
|
288 |
+
}
|
289 |
+
|
290 |
+
return implode( '_', $key_pieces );
|
291 |
+
}
|
292 |
+
}
|
src/Twitter/WordPress/Shortcodes/Vine.php
ADDED
@@ -0,0 +1,295 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Shortcodes;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Display a Vine
|
30 |
+
*
|
31 |
+
* @since 1.3.0
|
32 |
+
*/
|
33 |
+
class Vine implements ShortcodeInterface
|
34 |
+
{
|
35 |
+
use OEmbedTrait;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Shortcode tag to be matched
|
39 |
+
*
|
40 |
+
* @since 1.3.0
|
41 |
+
*
|
42 |
+
* @type string
|
43 |
+
*/
|
44 |
+
const SHORTCODE_TAG = 'vine';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* HTML class to be used in div wrapper
|
48 |
+
*
|
49 |
+
* @since 1.3.0
|
50 |
+
*
|
51 |
+
* @type string
|
52 |
+
*/
|
53 |
+
const HTML_CLASS = 'vine-embed';
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Regex used to match a Vine in text
|
57 |
+
*
|
58 |
+
* @since 1.3.0
|
59 |
+
*
|
60 |
+
* @type string
|
61 |
+
*/
|
62 |
+
const URL_REGEX = '#https?://vine\.co/v/([a-z0-9]+)\/?#i';
|
63 |
+
|
64 |
+
/**
|
65 |
+
* oEmbed regex registered by WordPress Core since 4.1
|
66 |
+
*
|
67 |
+
* @since 1.3.0
|
68 |
+
*
|
69 |
+
* @type string
|
70 |
+
*/
|
71 |
+
const OEMBED_CORE_REGEX = '#https?://vine.co/v/.*#i';
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Base URL used to reconstruct a Vine URL
|
75 |
+
*
|
76 |
+
* @since 1.3.0
|
77 |
+
*
|
78 |
+
* @type string
|
79 |
+
*/
|
80 |
+
const BASE_URL = 'https://vine.co/v/';
|
81 |
+
|
82 |
+
/**
|
83 |
+
* PHP class to use for fetching oEmbed data
|
84 |
+
*
|
85 |
+
* @since 1.3.0
|
86 |
+
*
|
87 |
+
* @type string
|
88 |
+
*/
|
89 |
+
const OEMBED_API_CLASS = '\Twitter\WordPress\Helpers\VineOEmbed';
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Relative path for the oEmbed API relative to Vine base path
|
93 |
+
*
|
94 |
+
* @since 1.3.0
|
95 |
+
*
|
96 |
+
* @type string
|
97 |
+
*/
|
98 |
+
const OEMBED_API_ENDPOINT = 'oembed';
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Accepted shortcode attributes and their default values
|
102 |
+
*
|
103 |
+
* @since 1.3.0
|
104 |
+
*
|
105 |
+
* @type array
|
106 |
+
*/
|
107 |
+
public static $SHORTCODE_DEFAULTS = array( 'id' => '', 'width' => 0 );
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Attach handlers for Vine
|
111 |
+
*
|
112 |
+
* @since 1.3.0
|
113 |
+
*
|
114 |
+
* @return void
|
115 |
+
*/
|
116 |
+
public static function init()
|
117 |
+
{
|
118 |
+
$classname = get_called_class();
|
119 |
+
|
120 |
+
// register our shortcode and its handler
|
121 |
+
add_shortcode( static::SHORTCODE_TAG, array( $classname, 'shortcodeHandler' ) );
|
122 |
+
|
123 |
+
// unhook the WordPress Core oEmbed handler
|
124 |
+
wp_oembed_remove_provider( static::OEMBED_CORE_REGEX );
|
125 |
+
|
126 |
+
// convert a URL into the shortcode equivalent
|
127 |
+
wp_embed_register_handler(
|
128 |
+
static::SHORTCODE_TAG,
|
129 |
+
static::URL_REGEX,
|
130 |
+
array( $classname, 'linkHandler' ),
|
131 |
+
1
|
132 |
+
);
|
133 |
+
|
134 |
+
// Shortcode UI, if supported
|
135 |
+
add_action(
|
136 |
+
'register_shortcode_ui',
|
137 |
+
array( $classname, 'shortcodeUI' ),
|
138 |
+
5,
|
139 |
+
0
|
140 |
+
);
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Reference the feature by name
|
145 |
+
*
|
146 |
+
* @since 1.3.0
|
147 |
+
*
|
148 |
+
* @return string translated feature name
|
149 |
+
*/
|
150 |
+
public static function featureName()
|
151 |
+
{
|
152 |
+
return 'Vine';
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Describe shortcode for Shortcake UI
|
157 |
+
*
|
158 |
+
* @since 1.3.0
|
159 |
+
*
|
160 |
+
* @link https://github.com/fusioneng/Shortcake Shortcake UI
|
161 |
+
*
|
162 |
+
* @return void
|
163 |
+
*/
|
164 |
+
public static function shortcodeUI()
|
165 |
+
{
|
166 |
+
// Shortcake required
|
167 |
+
if ( ! function_exists( 'shortcode_ui_register_for_shortcode' ) ) {
|
168 |
+
return;
|
169 |
+
}
|
170 |
+
|
171 |
+
shortcode_ui_register_for_shortcode(
|
172 |
+
static::SHORTCODE_TAG,
|
173 |
+
array(
|
174 |
+
'label' => esc_html( static::featureName() ),
|
175 |
+
'listItemImage' => 'dashicons-video-alt3',
|
176 |
+
'attrs' => array(
|
177 |
+
array(
|
178 |
+
'attr' => 'id',
|
179 |
+
'label' => 'ID',
|
180 |
+
'type' => 'text',
|
181 |
+
'meta' => array(
|
182 |
+
'required' => true,
|
183 |
+
'pattern' => '[A-Za-z0-9]+',
|
184 |
+
),
|
185 |
+
),
|
186 |
+
),
|
187 |
+
)
|
188 |
+
);
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Handle a URL matched by a embed handler
|
193 |
+
*
|
194 |
+
* @since 1.3.0
|
195 |
+
*
|
196 |
+
* @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
|
197 |
+
* @param array $attr Embed attributes. Not used.
|
198 |
+
* @param string $url The original URL that was matched by the regex. Not used.
|
199 |
+
* @param array $rawattr The original unmodified attributes. Not used.
|
200 |
+
*
|
201 |
+
* @return string HTML markup for the Tweet or an empty string if requirements not met
|
202 |
+
*/
|
203 |
+
public static function linkHandler( $matches, $attr, $url, $rawattr )
|
204 |
+
{
|
205 |
+
if ( ! ( is_array( $matches ) && isset( $matches[1] ) && $matches[1] ) ) {
|
206 |
+
return '';
|
207 |
+
}
|
208 |
+
|
209 |
+
return static::shortcodeHandler( array( 'id' => $matches[1] ) );
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Handle shortcode macro
|
214 |
+
*
|
215 |
+
* @since 1.3.0
|
216 |
+
*
|
217 |
+
* @param array $attributes set of shortcode attribute-value pairs or positional content matching the WordPress shortcode regex {
|
218 |
+
* @type string|int attribute name or positional int
|
219 |
+
* @type mixed shortcode value
|
220 |
+
* }
|
221 |
+
* @param string $content content inside a shortcode macro. no effect on this shortcode
|
222 |
+
*
|
223 |
+
* @return string HTML markup. empty string if parameter requirement not met or no collection info found
|
224 |
+
*/
|
225 |
+
public static function shortcodeHandler( $attributes, $content = '' )
|
226 |
+
{
|
227 |
+
global $content_width;
|
228 |
+
|
229 |
+
$options = shortcode_atts(
|
230 |
+
static::$SHORTCODE_DEFAULTS,
|
231 |
+
$attributes,
|
232 |
+
static::SHORTCODE_TAG
|
233 |
+
);
|
234 |
+
|
235 |
+
$vine_id = trim( $options['id'] );
|
236 |
+
if ( ! $vine_id ) {
|
237 |
+
return '';
|
238 |
+
}
|
239 |
+
|
240 |
+
$query_parameters = static::getBaseOEmbedParams( $vine_id );
|
241 |
+
unset( $query_parameters['lang'] );
|
242 |
+
|
243 |
+
$width = absint( $options['width'] );
|
244 |
+
if ( $width < 100 && isset( $content_width ) ) {
|
245 |
+
$width = absint( $content_width );
|
246 |
+
}
|
247 |
+
if ( $width > 100 ) {
|
248 |
+
// reset max_width to max value supported by Vine
|
249 |
+
// collapses cache hits
|
250 |
+
if ( $width > 600 ) {
|
251 |
+
$width = 600;
|
252 |
+
}
|
253 |
+
$query_parameters['maxwidth'] = $width;
|
254 |
+
}
|
255 |
+
|
256 |
+
// fetch HTML markup from Vine oEmbed endpoint for the given parameters
|
257 |
+
$html = trim( static::getOEmbedMarkup( $query_parameters ) );
|
258 |
+
if ( ! $html ) {
|
259 |
+
return '';
|
260 |
+
}
|
261 |
+
|
262 |
+
$html = '<div class="' . sanitize_html_class( static::HTML_CLASS ) . '">' . $html . '</div>';
|
263 |
+
|
264 |
+
$inline_js = \Twitter\WordPress\JavaScriptLoaders\VineEmbed::enqueue();
|
265 |
+
if ( $inline_js ) {
|
266 |
+
return $html . $inline_js;
|
267 |
+
}
|
268 |
+
|
269 |
+
return $html;
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Construct a cache key for the oEmbed response. Account for query parameters needing to bust cache
|
274 |
+
*
|
275 |
+
* @since 1.3.0
|
276 |
+
*
|
277 |
+
* @param array $query_parameters oEmbed API query parameters
|
278 |
+
*
|
279 |
+
* @return string cache key
|
280 |
+
*/
|
281 |
+
public static function oEmbedCacheKey( array $query_parameters )
|
282 |
+
{
|
283 |
+
if ( ! ( isset( $query_parameters['id'] ) && $query_parameters['id'] ) ) {
|
284 |
+
return '';
|
285 |
+
}
|
286 |
+
|
287 |
+
$key_pieces = array( static::SHORTCODE_TAG, $query_parameters['id'] );
|
288 |
+
|
289 |
+
if ( isset( $query_parameters['maxwidth'] ) && $query_parameters['maxwidth'] ) {
|
290 |
+
$key_pieces[] = 'w' . $query_parameters['maxwidth'];
|
291 |
+
}
|
292 |
+
|
293 |
+
return implode( '_', $key_pieces );
|
294 |
+
}
|
295 |
+
}
|
src/Twitter/WordPress/User/Meta.php
CHANGED
@@ -34,26 +34,28 @@ class Meta
|
|
34 |
{
|
35 |
|
36 |
/**
|
37 |
-
* Get a
|
38 |
*
|
39 |
-
* @since 1.
|
40 |
*
|
41 |
* @param int|string $user_id WordPress user identifier. may be WP_User->ID or a separate identifier used by an extending system
|
|
|
42 |
*
|
43 |
-
* @return string
|
44 |
*/
|
45 |
-
public static function
|
46 |
-
{
|
47 |
// basic test for invalid passed parameter
|
48 |
if ( ! $user_id ) {
|
49 |
return '';
|
50 |
}
|
|
|
|
|
|
|
51 |
|
52 |
-
$meta_key = 'twitter';
|
53 |
if ( function_exists( 'get_user_attribute' ) ) {
|
54 |
-
$username = get_user_attribute( $user_id, $
|
55 |
} else {
|
56 |
-
$username = get_user_meta( $user_id, $
|
57 |
}
|
58 |
|
59 |
if ( ! is_string( $username ) ) {
|
@@ -70,9 +72,35 @@ class Meta
|
|
70 |
* @param string $username Twitter username associated with a WordPress user ID
|
71 |
* @param int|string $user_id WordPress user identifier. may be WP_User->ID or a separate identifier used by an extending system
|
72 |
*/
|
73 |
-
$username = apply_filters( '
|
74 |
}
|
75 |
|
76 |
return $username;
|
77 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
34 |
{
|
35 |
|
36 |
/**
|
37 |
+
* Get a username value stored for the given WordPress user identifier
|
38 |
*
|
39 |
+
* @since 1.3.0
|
40 |
*
|
41 |
* @param int|string $user_id WordPress user identifier. may be WP_User->ID or a separate identifier used by an extending system
|
42 |
+
* @param string $key user attribute or meta key storing the username of interest
|
43 |
*
|
44 |
+
* @return string stored username. empty string if no user_id provided or no username found
|
45 |
*/
|
46 |
+
public static function getSocialUsername( $user_id, $key ) {
|
|
|
47 |
// basic test for invalid passed parameter
|
48 |
if ( ! $user_id ) {
|
49 |
return '';
|
50 |
}
|
51 |
+
if ( ! is_string( $key ) || ! $key ) {
|
52 |
+
return '';
|
53 |
+
}
|
54 |
|
|
|
55 |
if ( function_exists( 'get_user_attribute' ) ) {
|
56 |
+
$username = get_user_attribute( $user_id, $key );
|
57 |
} else {
|
58 |
+
$username = get_user_meta( $user_id, $key, /* single */ true );
|
59 |
}
|
60 |
|
61 |
if ( ! is_string( $username ) ) {
|
72 |
* @param string $username Twitter username associated with a WordPress user ID
|
73 |
* @param int|string $user_id WordPress user identifier. may be WP_User->ID or a separate identifier used by an extending system
|
74 |
*/
|
75 |
+
$username = apply_filters( $key . '_username', $username, $user_id );
|
76 |
}
|
77 |
|
78 |
return $username;
|
79 |
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Get a Twitter @username stored for a given WordPress user identifier
|
83 |
+
*
|
84 |
+
* @since 1.0.0
|
85 |
+
*
|
86 |
+
* @param int|string $user_id WordPress user identifier. may be WP_User->ID or a separate identifier used by an extending system
|
87 |
+
*
|
88 |
+
* @return string Twitter username value stored for the given WordPress user identifier
|
89 |
+
*/
|
90 |
+
public static function getTwitterUsername( $user_id ) {
|
91 |
+
return static::getSocialUsername( $user_id, 'twitter' );
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Get a Periscope username stored for a given WordPress identifier
|
96 |
+
*
|
97 |
+
* @since 1.3.0
|
98 |
+
*
|
99 |
+
* @param int|string $user_id WordPress user identifier. may be WP_User->ID or a separate identifier used by an extending system
|
100 |
+
*
|
101 |
+
* @return string Periscope username value stored for the given WordPress user identifier
|
102 |
+
*/
|
103 |
+
public static function getPeriscopeUsername( $user_id ) {
|
104 |
+
return static::getSocialUsername( $user_id, 'periscope' );
|
105 |
+
}
|
106 |
}
|
src/Twitter/WordPress/Widgets/PeriscopeOnAir.php
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Twitter Inc.
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
namespace Twitter\WordPress\Widgets;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Add Periscope On Air button as a WordPress widget
|
30 |
+
*
|
31 |
+
* @link http://codex.wordpress.org/Widgets_API WordPress widgets API
|
32 |
+
*
|
33 |
+
* @since 1.3.0
|
34 |
+
*/
|
35 |
+
class PeriscopeOnAir extends \WP_Widget
|
36 |
+
{
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Widget base ID
|
40 |
+
*
|
41 |
+
* Widget identifiers will derive from the base based on their positioning. e.g. periscope-on-air-1
|
42 |
+
*
|
43 |
+
* @since 1.3.0
|
44 |
+
*
|
45 |
+
* @type string
|
46 |
+
*/
|
47 |
+
const BASE_ID = 'periscope-on-air';
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Register widget with WordPress
|
51 |
+
*
|
52 |
+
* @since 1.3.0
|
53 |
+
*
|
54 |
+
* @return void
|
55 |
+
*/
|
56 |
+
public function __construct()
|
57 |
+
{
|
58 |
+
parent::__construct(
|
59 |
+
static::BASE_ID, // Base ID
|
60 |
+
__( 'Periscope On Air', 'twitter' ), // name
|
61 |
+
array(
|
62 |
+
'description' => __( 'Lets a viewer discover your Periscope account and on air status', 'twitter' ) // args
|
63 |
+
)
|
64 |
+
);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Front-end display of widget
|
69 |
+
*
|
70 |
+
* @since 1.3.0
|
71 |
+
*
|
72 |
+
* @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
|
73 |
+
* @param array $instance The settings for the particular instance of the widget
|
74 |
+
*
|
75 |
+
* @return void
|
76 |
+
*/
|
77 |
+
public function widget( $args, $instance )
|
78 |
+
{
|
79 |
+
// no Periscope username target
|
80 |
+
if ( empty( $instance['username'] ) ) {
|
81 |
+
return;
|
82 |
+
}
|
83 |
+
|
84 |
+
/** This filter is documented in wp-includes/default-widgets.php */
|
85 |
+
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
|
86 |
+
unset( $instance['title'] );
|
87 |
+
|
88 |
+
$button_html = \Twitter\WordPress\Shortcodes\PeriscopeOnAir::shortcodeHandler( $instance );
|
89 |
+
if ( ! $button_html ) {
|
90 |
+
return;
|
91 |
+
}
|
92 |
+
|
93 |
+
echo $args['before_widget'];
|
94 |
+
|
95 |
+
if ( $title ) {
|
96 |
+
echo $args['before_title'] . $title . $args['after_title'];
|
97 |
+
}
|
98 |
+
|
99 |
+
// escaped in markup builder
|
100 |
+
// @codingStandardsIgnoreStart WordPress.XSS.EscapeOutput
|
101 |
+
echo $button_html;
|
102 |
+
// @codingStandardsIgnoreEnd WordPress.XSS.EscapeOutput
|
103 |
+
|
104 |
+
echo $args['after_widget'];
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Settings update form
|
109 |
+
*
|
110 |
+
* @since 1.3.0
|
111 |
+
*
|
112 |
+
* @param array $instance Current settings
|
113 |
+
*
|
114 |
+
* @return void
|
115 |
+
*/
|
116 |
+
public function form( $instance )
|
117 |
+
{
|
118 |
+
$instance = wp_parse_args(
|
119 |
+
(array) $instance,
|
120 |
+
array_merge(
|
121 |
+
array( 'title' => '' ),
|
122 |
+
\Twitter\WordPress\Shortcodes\PeriscopeOnAir::$SHORTCODE_DEFAULTS
|
123 |
+
)
|
124 |
+
);
|
125 |
+
|
126 |
+
$close_void_element = \Twitter\WordPress\Helpers\HTMLBuilder::closeVoidHTMLElement();
|
127 |
+
?>
|
128 |
+
<p><label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php echo esc_html( __( 'Title:', 'twitter' ) ); ?></label>
|
129 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( trim( strip_tags( $instance['title'] ) ) ); ?>"<?php echo $close_void_element; ?>></p>
|
130 |
+
|
131 |
+
<p><label for="<?php echo esc_attr( $this->get_field_id( 'username' ) ); ?>"><?php echo esc_html( __( 'Periscope username', 'twitter' ) ); ?></label>
|
132 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'username' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'username' ) ); ?>" type="text" pattern="[a-zA-Z0-9_]{1,20}" value="<?php echo esc_attr( $instance['username'] ); ?>"<?php echo $close_void_element; ?>></p>
|
133 |
+
|
134 |
+
<p><label for="<?php echo esc_attr( $this->get_field_id( 'size' ) ); ?>"><?php echo esc_html( __( 'Button size:', 'twitter' ) ); ?></label>
|
135 |
+
<fieldset id="<?php echo esc_attr( $this->get_field_id( 'size' ) ); ?>">
|
136 |
+
<label><input type="radio" name="<?php echo esc_attr( $this->get_field_name( 'size' ) ); ?>" value="small"<?php checked( 'large' != $instance['size'] ); echo $close_void_element; ?>> <?php echo esc_html( _x( 'small', 'small size button', 'twitter' ) ); ?> </label>
|
137 |
+
<label><input type="radio" name="<?php echo esc_attr( $this->get_field_name( 'size' ) ); ?>" value="large"<?php checked( 'large' == $instance['size'] ); echo $close_void_element; ?>> <?php echo esc_html( _x( 'large', 'large size button', 'twitter' ) ); ?> </label>
|
138 |
+
</fieldset></p>
|
139 |
+
<?php
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Update a widget instance
|
144 |
+
*
|
145 |
+
* @since 1.3.0
|
146 |
+
*
|
147 |
+
* @param array $new_instance New settings for this instance as input by the user via form()
|
148 |
+
* @param array $old_instance Old settings for this instance
|
149 |
+
*
|
150 |
+
* @return bool|array settings to save or false to cancel saving
|
151 |
+
*/
|
152 |
+
public function update( $new_instance, $old_instance )
|
153 |
+
{
|
154 |
+
$instance = array();
|
155 |
+
$new_instance = (array) $new_instance;
|
156 |
+
$title = trim( strip_tags( $new_instance['title'] ) );
|
157 |
+
if ( $title ) {
|
158 |
+
$instance['title'] = $title;
|
159 |
+
}
|
160 |
+
unset( $new_instance['title'] );
|
161 |
+
|
162 |
+
$on_air = \Twitter\Widgets\PeriscopeOnAir::fromArray( $new_instance );
|
163 |
+
if ( ! $on_air ) {
|
164 |
+
return false;
|
165 |
+
}
|
166 |
+
|
167 |
+
$filtered_options = $on_air->toArray();
|
168 |
+
$username = $on_air->getUsername();
|
169 |
+
if ( $username ) {
|
170 |
+
$filtered_options['username'] = $username;
|
171 |
+
}
|
172 |
+
unset( $username );
|
173 |
+
|
174 |
+
return array_merge( $instance, $filtered_options );
|
175 |
+
}
|
176 |
+
}
|
twitter.php
CHANGED
@@ -24,13 +24,13 @@ THE SOFTWARE.
|
|
24 |
*/
|
25 |
/**
|
26 |
* @package twitter
|
27 |
-
* @version 1.
|
28 |
*/
|
29 |
/*
|
30 |
Plugin Name: Twitter
|
31 |
Plugin URI: http://wordpress.org/plugins/twitter/
|
32 |
Description: Official Twitter plugin for WordPress. Embed Twitter content and grow your audience on Twitter. Requires PHP 5.4 or greater.
|
33 |
-
Version: 1.
|
34 |
Author: Twitter
|
35 |
Author URI: https://dev.twitter.com/
|
36 |
License: MIT
|
@@ -53,7 +53,7 @@ if ( ! function_exists( 'add_action' ) ) {
|
|
53 |
// plugin requires PHP 5.4 or greater
|
54 |
if ( version_compare( PHP_VERSION, '5.4.0', '<' ) ) {
|
55 |
if ( ! class_exists( 'Twitter_CompatibilityNotice' ) ) {
|
56 |
-
require_once( dirname(__FILE__) . '/compatibility-notice.php' );
|
57 |
}
|
58 |
|
59 |
// possibly display a notice, trigger error
|
24 |
*/
|
25 |
/**
|
26 |
* @package twitter
|
27 |
+
* @version 1.3.0
|
28 |
*/
|
29 |
/*
|
30 |
Plugin Name: Twitter
|
31 |
Plugin URI: http://wordpress.org/plugins/twitter/
|
32 |
Description: Official Twitter plugin for WordPress. Embed Twitter content and grow your audience on Twitter. Requires PHP 5.4 or greater.
|
33 |
+
Version: 1.3.0
|
34 |
Author: Twitter
|
35 |
Author URI: https://dev.twitter.com/
|
36 |
License: MIT
|
53 |
// plugin requires PHP 5.4 or greater
|
54 |
if ( version_compare( PHP_VERSION, '5.4.0', '<' ) ) {
|
55 |
if ( ! class_exists( 'Twitter_CompatibilityNotice' ) ) {
|
56 |
+
require_once( dirname( __FILE__ ) . '/compatibility-notice.php' );
|
57 |
}
|
58 |
|
59 |
// possibly display a notice, trigger error
|
uninstall.php
CHANGED
@@ -65,12 +65,14 @@ if ( function_exists( 'delete_post_meta_by_key' ) ) {
|
|
65 |
|
66 |
// user meta
|
67 |
if ( function_exists( 'delete_metadata' ) ) {
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
76 |
}
|
65 |
|
66 |
// user meta
|
67 |
if ( function_exists( 'delete_metadata' ) ) {
|
68 |
+
foreach ( array( 'twitter', 'periscope' ) as $social ) {
|
69 |
+
// delete Twitter customization stored for a WordPress user account
|
70 |
+
delete_metadata(
|
71 |
+
'user', // meta type
|
72 |
+
0, // user ID (ignored)
|
73 |
+
$social, // meta key
|
74 |
+
'', // delete all values
|
75 |
+
true // delete all. ignore passed user id
|
76 |
+
);
|
77 |
+
}
|
78 |
}
|