Version Description
- Feature: Gutenberg integration with core blocks
- Bug Fix: Affiliate links with "Open In New Tab" not working correctly in Instgram's in-app browser
- Bug Fix: Module settings still able to be accessed even if the module was disabled
- Bug Fix: Import/Export settings page could be accessed by non-administrator Dashboard users
Download this release
Release Info
Developer | jkohlbach |
Plugin | ThirstyAffiliates Affiliate Link Manager |
Version | 3.6 |
Comparing to | |
See all releases |
Code changes from version 3.5 to 3.6
- .htaccess +2 -2
- Abstracts/Abstract_Main_Plugin_Class.php +112 -112
- Helpers/Helper_Functions.php +623 -591
- Helpers/Plugin_Constants.php +164 -164
- Interfaces/Deactivatable_Interface.php +22 -22
- Models/Affiliate_Link.php +768 -768
- Models/Affiliate_Links_CPT.php +1014 -1014
- Models/Bootstrap.php +520 -517
- Models/Guided_Tour.php +389 -389
- Models/Link_Fixer.php +289 -289
- Models/Link_Picker.php +709 -658
- Models/REST_API.php +354 -354
- Models/Rewrites_Redirection.php +440 -440
- Models/Script_Loader.php +16 -0
- Models/Settings.php +2114 -2073
- Models/Shortcodes.php +301 -301
- Models/Stats_Reporting.php +1077 -1077
- css/admin/ta-affiliate-link-list.css +29 -29
- css/admin/ta-editor.css +46 -46
- css/admin/ta-guided-tour.css +11 -11
- css/admin/ta-reports.css +255 -255
- css/admin/ta-settings.css +113 -113
- css/admin/tinymce/editor.css +8 -8
- css/lib/jquery-tiptip/jquery-tiptip.css +109 -109
- css/lib/select2/select2.css +484 -484
- css/lib/select2/select2.min.css +1 -1
- js/app/advance_link_picker/.eslintrc.json +29 -29
- js/app/advance_link_picker/package-lock.json +0 -7608
.htaccess
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
Options -Indexes
|
2 |
-
|
1 |
+
Options -Indexes
|
2 |
+
|
Abstracts/Abstract_Main_Plugin_Class.php
CHANGED
@@ -1,112 +1,112 @@
|
|
1 |
-
<?php
|
2 |
-
namespace ThirstyAffiliates\Abstracts;
|
3 |
-
|
4 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
5 |
-
|
6 |
-
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Abstract class that the main plugin class needs to extend.
|
10 |
-
*
|
11 |
-
* @since 3.0.0
|
12 |
-
*/
|
13 |
-
abstract class Abstract_Main_Plugin_Class {
|
14 |
-
|
15 |
-
/*
|
16 |
-
|--------------------------------------------------------------------------
|
17 |
-
| Class Properties
|
18 |
-
|--------------------------------------------------------------------------
|
19 |
-
*/
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Property that houses an array of all the "regular models" of the plugin.
|
23 |
-
*
|
24 |
-
* @since 3.0.0
|
25 |
-
* @access protected
|
26 |
-
* @var array
|
27 |
-
*/
|
28 |
-
protected $__all_models = array();
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Property that houses an array of all "public regular models" of the plugin.
|
32 |
-
* Public models can be accessed and utilized by external entities via the main plugin class.
|
33 |
-
*
|
34 |
-
* @since 3.0.0
|
35 |
-
* @access public
|
36 |
-
* @var array
|
37 |
-
*/
|
38 |
-
public $models = array();
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Property that houses an array of all "public helper classes" of the plugin.
|
42 |
-
*
|
43 |
-
* @since 3.0.0
|
44 |
-
* @access public
|
45 |
-
* @var array
|
46 |
-
*/
|
47 |
-
public $helpers = array();
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
/*
|
53 |
-
|--------------------------------------------------------------------------
|
54 |
-
| Class Methods
|
55 |
-
|--------------------------------------------------------------------------
|
56 |
-
*/
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Add a "regular model" to the main plugin class "all models" array.
|
60 |
-
*
|
61 |
-
* @since 3.0.0
|
62 |
-
* @access public
|
63 |
-
*
|
64 |
-
* @param Model_Interface $model Regular model.
|
65 |
-
*/
|
66 |
-
public function add_to_all_plugin_models( Model_Interface $model ) {
|
67 |
-
|
68 |
-
$class_reflection = new \ReflectionClass( $model );
|
69 |
-
$class_name = $class_reflection->getShortName();
|
70 |
-
|
71 |
-
if ( !array_key_exists( $class_name , $this->__all_models ) )
|
72 |
-
$this->__all_models[ $class_name ] = $model;
|
73 |
-
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Add a "regular model" to the main plugin class "public models" array.
|
78 |
-
*
|
79 |
-
* @since 3.0.0
|
80 |
-
* @access public
|
81 |
-
*
|
82 |
-
* @param Model_Interface $model Regular model.
|
83 |
-
*/
|
84 |
-
public function add_to_public_models( Model_Interface $model ) {
|
85 |
-
|
86 |
-
$class_reflection = new \ReflectionClass( $model );
|
87 |
-
$class_name = $class_reflection->getShortName();
|
88 |
-
|
89 |
-
if ( !array_key_exists( $class_name , $this->models ) )
|
90 |
-
$this->models[ $class_name ] = $model;
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Add a "helper class instance" to the main plugin class "public helpers" array.
|
96 |
-
*
|
97 |
-
* @since 3.0.0
|
98 |
-
* @access public
|
99 |
-
*
|
100 |
-
* @param object $helper Helper class instance.
|
101 |
-
*/
|
102 |
-
public function add_to_public_helpers( $helper ) {
|
103 |
-
|
104 |
-
$class_reflection = new \ReflectionClass( $helper );
|
105 |
-
$class_name = $class_reflection->getShortName();
|
106 |
-
|
107 |
-
if ( !array_key_exists( $class_name , $this->helpers ) )
|
108 |
-
$this->helpers[ $class_name ] = $helper;
|
109 |
-
|
110 |
-
}
|
111 |
-
|
112 |
-
}
|
1 |
+
<?php
|
2 |
+
namespace ThirstyAffiliates\Abstracts;
|
3 |
+
|
4 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
5 |
+
|
6 |
+
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Abstract class that the main plugin class needs to extend.
|
10 |
+
*
|
11 |
+
* @since 3.0.0
|
12 |
+
*/
|
13 |
+
abstract class Abstract_Main_Plugin_Class {
|
14 |
+
|
15 |
+
/*
|
16 |
+
|--------------------------------------------------------------------------
|
17 |
+
| Class Properties
|
18 |
+
|--------------------------------------------------------------------------
|
19 |
+
*/
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Property that houses an array of all the "regular models" of the plugin.
|
23 |
+
*
|
24 |
+
* @since 3.0.0
|
25 |
+
* @access protected
|
26 |
+
* @var array
|
27 |
+
*/
|
28 |
+
protected $__all_models = array();
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Property that houses an array of all "public regular models" of the plugin.
|
32 |
+
* Public models can be accessed and utilized by external entities via the main plugin class.
|
33 |
+
*
|
34 |
+
* @since 3.0.0
|
35 |
+
* @access public
|
36 |
+
* @var array
|
37 |
+
*/
|
38 |
+
public $models = array();
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Property that houses an array of all "public helper classes" of the plugin.
|
42 |
+
*
|
43 |
+
* @since 3.0.0
|
44 |
+
* @access public
|
45 |
+
* @var array
|
46 |
+
*/
|
47 |
+
public $helpers = array();
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
|
52 |
+
/*
|
53 |
+
|--------------------------------------------------------------------------
|
54 |
+
| Class Methods
|
55 |
+
|--------------------------------------------------------------------------
|
56 |
+
*/
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Add a "regular model" to the main plugin class "all models" array.
|
60 |
+
*
|
61 |
+
* @since 3.0.0
|
62 |
+
* @access public
|
63 |
+
*
|
64 |
+
* @param Model_Interface $model Regular model.
|
65 |
+
*/
|
66 |
+
public function add_to_all_plugin_models( Model_Interface $model ) {
|
67 |
+
|
68 |
+
$class_reflection = new \ReflectionClass( $model );
|
69 |
+
$class_name = $class_reflection->getShortName();
|
70 |
+
|
71 |
+
if ( !array_key_exists( $class_name , $this->__all_models ) )
|
72 |
+
$this->__all_models[ $class_name ] = $model;
|
73 |
+
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Add a "regular model" to the main plugin class "public models" array.
|
78 |
+
*
|
79 |
+
* @since 3.0.0
|
80 |
+
* @access public
|
81 |
+
*
|
82 |
+
* @param Model_Interface $model Regular model.
|
83 |
+
*/
|
84 |
+
public function add_to_public_models( Model_Interface $model ) {
|
85 |
+
|
86 |
+
$class_reflection = new \ReflectionClass( $model );
|
87 |
+
$class_name = $class_reflection->getShortName();
|
88 |
+
|
89 |
+
if ( !array_key_exists( $class_name , $this->models ) )
|
90 |
+
$this->models[ $class_name ] = $model;
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Add a "helper class instance" to the main plugin class "public helpers" array.
|
96 |
+
*
|
97 |
+
* @since 3.0.0
|
98 |
+
* @access public
|
99 |
+
*
|
100 |
+
* @param object $helper Helper class instance.
|
101 |
+
*/
|
102 |
+
public function add_to_public_helpers( $helper ) {
|
103 |
+
|
104 |
+
$class_reflection = new \ReflectionClass( $helper );
|
105 |
+
$class_name = $class_reflection->getShortName();
|
106 |
+
|
107 |
+
if ( !array_key_exists( $class_name , $this->helpers ) )
|
108 |
+
$this->helpers[ $class_name ] = $helper;
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
}
|
Helpers/Helper_Functions.php
CHANGED
@@ -1,591 +1,623 @@
|
|
1 |
-
<?php
|
2 |
-
namespace ThirstyAffiliates\Helpers;
|
3 |
-
|
4 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
-
|
6 |
-
use ThirstyAffiliates\Models\Affiliate_Link;
|
7 |
-
|
8 |
-
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Model that houses all the helper functions of the plugin.
|
12 |
-
*
|
13 |
-
* 3.0.0
|
14 |
-
*/
|
15 |
-
class Helper_Functions {
|
16 |
-
|
17 |
-
/*
|
18 |
-
|--------------------------------------------------------------------------
|
19 |
-
| Class Properties
|
20 |
-
|--------------------------------------------------------------------------
|
21 |
-
*/
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Property that holds the single main instance of Helper_Functions.
|
25 |
-
*
|
26 |
-
* @since 3.0.0
|
27 |
-
* @access private
|
28 |
-
* @var Helper_Functions
|
29 |
-
*/
|
30 |
-
private static $_instance;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Model that houses all the plugin constants.
|
34 |
-
*
|
35 |
-
* @since 3.0.0
|
36 |
-
* @access private
|
37 |
-
* @var Plugin_Constants
|
38 |
-
*/
|
39 |
-
private $_constants;
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Property that houses all the saved settings.
|
43 |
-
*
|
44 |
-
* @since 3.0.0
|
45 |
-
* @access private
|
46 |
-
*/
|
47 |
-
private $_settings = array();
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
/*
|
53 |
-
|--------------------------------------------------------------------------
|
54 |
-
| Class Methods
|
55 |
-
|--------------------------------------------------------------------------
|
56 |
-
*/
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Class constructor.
|
60 |
-
*
|
61 |
-
* @since 3.0.0
|
62 |
-
* @access public
|
63 |
-
*
|
64 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
65 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
66 |
-
*/
|
67 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants ) {
|
68 |
-
|
69 |
-
$this->_constants = $constants;
|
70 |
-
|
71 |
-
$main_plugin->add_to_public_helpers( $this );
|
72 |
-
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
77 |
-
*
|
78 |
-
* @since 3.0.0
|
79 |
-
* @access public
|
80 |
-
*
|
81 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
82 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
83 |
-
* @return Helper_Functions
|
84 |
-
*/
|
85 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants ) {
|
86 |
-
|
87 |
-
if ( !self::$_instance instanceof self )
|
88 |
-
self::$_instance = new self( $main_plugin , $constants );
|
89 |
-
|
90 |
-
return self::$_instance;
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
/*
|
98 |
-
|--------------------------------------------------------------------------
|
99 |
-
| Helper Functions
|
100 |
-
|--------------------------------------------------------------------------
|
101 |
-
*/
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Write data to plugin log file.
|
105 |
-
*
|
106 |
-
* @since 3.0.0
|
107 |
-
* @access public
|
108 |
-
*
|
109 |
-
* @param mixed Data to log.
|
110 |
-
*/
|
111 |
-
public function write_debug_log( $log ) {
|
112 |
-
|
113 |
-
error_log( "\n[" . current_time( 'mysql' ) . "]\n" . $log . "\n--------------------------------------------------\n" , 3 , $this->_constants->LOGS_ROOT_PATH() . 'debug.log' );
|
114 |
-
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Check if current user is authorized to manage the plugin on the backend.
|
119 |
-
*
|
120 |
-
* @since 3.0.0
|
121 |
-
* @access public
|
122 |
-
*
|
123 |
-
* @param WP_User $user WP_User object.
|
124 |
-
* @return boolean True if authorized, False otherwise.
|
125 |
-
*/
|
126 |
-
public function current_user_authorized( $user = null ) {
|
127 |
-
|
128 |
-
// Array of roles allowed to access/utilize the plugin
|
129 |
-
$admin_roles = apply_filters( 'ucfw_admin_roles' , array( 'administrator' ) );
|
130 |
-
|
131 |
-
if ( is_null( $user ) )
|
132 |
-
$user = wp_get_current_user();
|
133 |
-
|
134 |
-
if ( $user->ID )
|
135 |
-
return count( array_intersect( ( array ) $user->roles , $admin_roles ) ) ? true : false;
|
136 |
-
else
|
137 |
-
return false;
|
138 |
-
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Returns the timezone string for a site, even if it's set to a UTC offset
|
143 |
-
*
|
144 |
-
* Adapted from http://www.php.net/manual/en/function.timezone-name-from-abbr.php#89155
|
145 |
-
*
|
146 |
-
* Reference:
|
147 |
-
* http://www.skyverge.com/blog/down-the-rabbit-hole-wordpress-and-timezones/
|
148 |
-
*
|
149 |
-
* @since 3.0.0
|
150 |
-
* @access public
|
151 |
-
*
|
152 |
-
* @return string Valid PHP timezone string
|
153 |
-
*/
|
154 |
-
public function get_site_current_timezone() {
|
155 |
-
|
156 |
-
// if site timezone string exists, return it
|
157 |
-
if ( $timezone = get_option( 'timezone_string' ) )
|
158 |
-
return $timezone;
|
159 |
-
|
160 |
-
// get UTC offset, if it isn't set then return UTC
|
161 |
-
if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) )
|
162 |
-
return 'UTC';
|
163 |
-
|
164 |
-
return $this->convert_utc_offset_to_timezone( $utc_offset );
|
165 |
-
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* Conver UTC offset to timezone.
|
170 |
-
*
|
171 |
-
* @since 1.2.0
|
172 |
-
* @access public
|
173 |
-
*
|
174 |
-
* @param float|int|string $utc_offset UTC offset.
|
175 |
-
* @return string valid PHP timezone string
|
176 |
-
*/
|
177 |
-
public function convert_utc_offset_to_timezone( $utc_offset ) {
|
178 |
-
|
179 |
-
// adjust UTC offset from hours to seconds
|
180 |
-
$utc_offset *= 3600;
|
181 |
-
|
182 |
-
// attempt to guess the timezone string from the UTC offset
|
183 |
-
if ( $timezone = timezone_name_from_abbr( '' , $utc_offset , 0 ) )
|
184 |
-
return $timezone;
|
185 |
-
|
186 |
-
// last try, guess timezone string manually
|
187 |
-
$is_dst = date( 'I' );
|
188 |
-
|
189 |
-
foreach ( timezone_abbreviations_list() as $abbr )
|
190 |
-
foreach ( $abbr as $city )
|
191 |
-
if ( $city[ 'dst' ] == $is_dst && $city[ 'offset' ] == $utc_offset )
|
192 |
-
return $city[ 'timezone_id' ];
|
193 |
-
|
194 |
-
// fallback to UTC
|
195 |
-
return 'UTC';
|
196 |
-
|
197 |
-
}
|
198 |
-
|
199 |
-
/**
|
200 |
-
* Get all user roles.
|
201 |
-
*
|
202 |
-
* @since 3.0.0
|
203 |
-
* @access public
|
204 |
-
*
|
205 |
-
* @global WP_Roles $wp_roles Core class used to implement a user roles API.
|
206 |
-
*
|
207 |
-
* @return array Array of all site registered user roles. User role key as the key and value is user role text.
|
208 |
-
*/
|
209 |
-
public function get_all_user_roles() {
|
210 |
-
|
211 |
-
global $wp_roles;
|
212 |
-
return $wp_roles->get_names();
|
213 |
-
|
214 |
-
}
|
215 |
-
|
216 |
-
/**
|
217 |
-
* Check validity of a save post action.
|
218 |
-
*
|
219 |
-
* @since 3.0.0
|
220 |
-
* @access private
|
221 |
-
*
|
222 |
-
* @param int $post_id Id of the coupon post.
|
223 |
-
* @param string $post_type Post type to check.
|
224 |
-
* @return bool True if valid save post action, False otherwise.
|
225 |
-
*/
|
226 |
-
public function check_if_valid_save_post_action( $post_id , $post_type ) {
|
227 |
-
|
228 |
-
if ( get_post_type() != $post_type || empty( $_POST ) || wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) || !current_user_can( 'edit_page' , $post_id ) )
|
229 |
-
return false;
|
230 |
-
else
|
231 |
-
return true;
|
232 |
-
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* Get user IP address.
|
237 |
-
*
|
238 |
-
* @since 3.0.0
|
239 |
-
* @since 3.3.2 Added condition to disable IP address collection (for GDRP compliance).
|
240 |
-
* @access public
|
241 |
-
*
|
242 |
-
* @return string User's IP address.
|
243 |
-
*/
|
244 |
-
public function get_user_ip_address() {
|
245 |
-
|
246 |
-
if ( get_option( 'ta_disable_ip_address_collection' ) === 'yes' )
|
247 |
-
return;
|
248 |
-
|
249 |
-
if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) )
|
250 |
-
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
251 |
-
elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
|
252 |
-
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
253 |
-
else
|
254 |
-
$ip = $_SERVER['REMOTE_ADDR'];
|
255 |
-
|
256 |
-
return apply_filters( 'ta_get_user_ip_address', $ip );
|
257 |
-
}
|
258 |
-
|
259 |
-
/**
|
260 |
-
* Get the thirstylink slug set on the settings.
|
261 |
-
*
|
262 |
-
* @since 3.0.0
|
263 |
-
* @access public
|
264 |
-
*
|
265 |
-
* @return string $link_prefix Thirstyling link prefix.
|
266 |
-
*/
|
267 |
-
public function get_thirstylink_link_prefix() {
|
268 |
-
|
269 |
-
$link_prefix = get_option( 'ta_link_prefix' , 'recommends' );
|
270 |
-
|
271 |
-
if ( $link_prefix === 'custom' )
|
272 |
-
$link_prefix = get_option( 'ta_link_prefix_custom' , 'recommends' );
|
273 |
-
|
274 |
-
return $link_prefix ? $link_prefix : 'recommends';
|
275 |
-
}
|
276 |
-
|
277 |
-
/**
|
278 |
-
* Get the affiliate link post default category slug.
|
279 |
-
*
|
280 |
-
* @since 3.0.0
|
281 |
-
* @access public
|
282 |
-
*
|
283 |
-
* @param int $link_id Affiliate Link ID.
|
284 |
-
* @param array $terms Affiliate link categories.
|
285 |
-
* @return string Affiliate link default category slug.
|
286 |
-
*/
|
287 |
-
public function get_default_category_slug( $link_id , $terms = array() ) {
|
288 |
-
|
289 |
-
if ( ! is_array( $terms ) || empty( $terms ) )
|
290 |
-
$terms = get_the_terms( $link_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
291 |
-
|
292 |
-
if ( is_wp_error( $terms ) || empty( $terms ) )
|
293 |
-
return;
|
294 |
-
|
295 |
-
$link_cat_obj = array_shift( $terms );
|
296 |
-
|
297 |
-
return $link_cat_obj->slug;
|
298 |
-
}
|
299 |
-
|
300 |
-
/**
|
301 |
-
* Search affiliate links query
|
302 |
-
*
|
303 |
-
* @since 3.0.0
|
304 |
-
* @
|
305 |
-
*
|
306 |
-
*
|
307 |
-
* @param
|
308 |
-
* @param
|
309 |
-
* @param
|
310 |
-
* @
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
'
|
317 |
-
'
|
318 |
-
'
|
319 |
-
'
|
320 |
-
'
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
'
|
329 |
-
'
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
return $
|
353 |
-
}
|
354 |
-
|
355 |
-
/**
|
356 |
-
*
|
357 |
-
*
|
358 |
-
* @
|
359 |
-
*
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
*
|
373 |
-
*
|
374 |
-
* @
|
375 |
-
*
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
*
|
391 |
-
*
|
392 |
-
* @
|
393 |
-
* @
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
*
|
416 |
-
*
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
*
|
432 |
-
*
|
433 |
-
* @
|
434 |
-
*
|
435 |
-
*
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
*
|
506 |
-
*
|
507 |
-
* @
|
508 |
-
*
|
509 |
-
*
|
510 |
-
* @
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
*
|
522 |
-
*
|
523 |
-
*
|
524 |
-
* @
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
$
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
*
|
537 |
-
*
|
538 |
-
* @
|
539 |
-
*
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
*
|
579 |
-
*
|
580 |
-
* @
|
581 |
-
*
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ThirstyAffiliates\Helpers;
|
3 |
+
|
4 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
+
|
6 |
+
use ThirstyAffiliates\Models\Affiliate_Link;
|
7 |
+
|
8 |
+
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Model that houses all the helper functions of the plugin.
|
12 |
+
*
|
13 |
+
* 3.0.0
|
14 |
+
*/
|
15 |
+
class Helper_Functions {
|
16 |
+
|
17 |
+
/*
|
18 |
+
|--------------------------------------------------------------------------
|
19 |
+
| Class Properties
|
20 |
+
|--------------------------------------------------------------------------
|
21 |
+
*/
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Property that holds the single main instance of Helper_Functions.
|
25 |
+
*
|
26 |
+
* @since 3.0.0
|
27 |
+
* @access private
|
28 |
+
* @var Helper_Functions
|
29 |
+
*/
|
30 |
+
private static $_instance;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Model that houses all the plugin constants.
|
34 |
+
*
|
35 |
+
* @since 3.0.0
|
36 |
+
* @access private
|
37 |
+
* @var Plugin_Constants
|
38 |
+
*/
|
39 |
+
private $_constants;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Property that houses all the saved settings.
|
43 |
+
*
|
44 |
+
* @since 3.0.0
|
45 |
+
* @access private
|
46 |
+
*/
|
47 |
+
private $_settings = array();
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
|
52 |
+
/*
|
53 |
+
|--------------------------------------------------------------------------
|
54 |
+
| Class Methods
|
55 |
+
|--------------------------------------------------------------------------
|
56 |
+
*/
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Class constructor.
|
60 |
+
*
|
61 |
+
* @since 3.0.0
|
62 |
+
* @access public
|
63 |
+
*
|
64 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
65 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
66 |
+
*/
|
67 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants ) {
|
68 |
+
|
69 |
+
$this->_constants = $constants;
|
70 |
+
|
71 |
+
$main_plugin->add_to_public_helpers( $this );
|
72 |
+
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
77 |
+
*
|
78 |
+
* @since 3.0.0
|
79 |
+
* @access public
|
80 |
+
*
|
81 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
82 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
83 |
+
* @return Helper_Functions
|
84 |
+
*/
|
85 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants ) {
|
86 |
+
|
87 |
+
if ( !self::$_instance instanceof self )
|
88 |
+
self::$_instance = new self( $main_plugin , $constants );
|
89 |
+
|
90 |
+
return self::$_instance;
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
/*
|
98 |
+
|--------------------------------------------------------------------------
|
99 |
+
| Helper Functions
|
100 |
+
|--------------------------------------------------------------------------
|
101 |
+
*/
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Write data to plugin log file.
|
105 |
+
*
|
106 |
+
* @since 3.0.0
|
107 |
+
* @access public
|
108 |
+
*
|
109 |
+
* @param mixed Data to log.
|
110 |
+
*/
|
111 |
+
public function write_debug_log( $log ) {
|
112 |
+
|
113 |
+
error_log( "\n[" . current_time( 'mysql' ) . "]\n" . $log . "\n--------------------------------------------------\n" , 3 , $this->_constants->LOGS_ROOT_PATH() . 'debug.log' );
|
114 |
+
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Check if current user is authorized to manage the plugin on the backend.
|
119 |
+
*
|
120 |
+
* @since 3.0.0
|
121 |
+
* @access public
|
122 |
+
*
|
123 |
+
* @param WP_User $user WP_User object.
|
124 |
+
* @return boolean True if authorized, False otherwise.
|
125 |
+
*/
|
126 |
+
public function current_user_authorized( $user = null ) {
|
127 |
+
|
128 |
+
// Array of roles allowed to access/utilize the plugin
|
129 |
+
$admin_roles = apply_filters( 'ucfw_admin_roles' , array( 'administrator' ) );
|
130 |
+
|
131 |
+
if ( is_null( $user ) )
|
132 |
+
$user = wp_get_current_user();
|
133 |
+
|
134 |
+
if ( $user->ID )
|
135 |
+
return count( array_intersect( ( array ) $user->roles , $admin_roles ) ) ? true : false;
|
136 |
+
else
|
137 |
+
return false;
|
138 |
+
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Returns the timezone string for a site, even if it's set to a UTC offset
|
143 |
+
*
|
144 |
+
* Adapted from http://www.php.net/manual/en/function.timezone-name-from-abbr.php#89155
|
145 |
+
*
|
146 |
+
* Reference:
|
147 |
+
* http://www.skyverge.com/blog/down-the-rabbit-hole-wordpress-and-timezones/
|
148 |
+
*
|
149 |
+
* @since 3.0.0
|
150 |
+
* @access public
|
151 |
+
*
|
152 |
+
* @return string Valid PHP timezone string
|
153 |
+
*/
|
154 |
+
public function get_site_current_timezone() {
|
155 |
+
|
156 |
+
// if site timezone string exists, return it
|
157 |
+
if ( $timezone = get_option( 'timezone_string' ) )
|
158 |
+
return $timezone;
|
159 |
+
|
160 |
+
// get UTC offset, if it isn't set then return UTC
|
161 |
+
if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) )
|
162 |
+
return 'UTC';
|
163 |
+
|
164 |
+
return $this->convert_utc_offset_to_timezone( $utc_offset );
|
165 |
+
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Conver UTC offset to timezone.
|
170 |
+
*
|
171 |
+
* @since 1.2.0
|
172 |
+
* @access public
|
173 |
+
*
|
174 |
+
* @param float|int|string $utc_offset UTC offset.
|
175 |
+
* @return string valid PHP timezone string
|
176 |
+
*/
|
177 |
+
public function convert_utc_offset_to_timezone( $utc_offset ) {
|
178 |
+
|
179 |
+
// adjust UTC offset from hours to seconds
|
180 |
+
$utc_offset *= 3600;
|
181 |
+
|
182 |
+
// attempt to guess the timezone string from the UTC offset
|
183 |
+
if ( $timezone = timezone_name_from_abbr( '' , $utc_offset , 0 ) )
|
184 |
+
return $timezone;
|
185 |
+
|
186 |
+
// last try, guess timezone string manually
|
187 |
+
$is_dst = date( 'I' );
|
188 |
+
|
189 |
+
foreach ( timezone_abbreviations_list() as $abbr )
|
190 |
+
foreach ( $abbr as $city )
|
191 |
+
if ( $city[ 'dst' ] == $is_dst && $city[ 'offset' ] == $utc_offset )
|
192 |
+
return $city[ 'timezone_id' ];
|
193 |
+
|
194 |
+
// fallback to UTC
|
195 |
+
return 'UTC';
|
196 |
+
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Get all user roles.
|
201 |
+
*
|
202 |
+
* @since 3.0.0
|
203 |
+
* @access public
|
204 |
+
*
|
205 |
+
* @global WP_Roles $wp_roles Core class used to implement a user roles API.
|
206 |
+
*
|
207 |
+
* @return array Array of all site registered user roles. User role key as the key and value is user role text.
|
208 |
+
*/
|
209 |
+
public function get_all_user_roles() {
|
210 |
+
|
211 |
+
global $wp_roles;
|
212 |
+
return $wp_roles->get_names();
|
213 |
+
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Check validity of a save post action.
|
218 |
+
*
|
219 |
+
* @since 3.0.0
|
220 |
+
* @access private
|
221 |
+
*
|
222 |
+
* @param int $post_id Id of the coupon post.
|
223 |
+
* @param string $post_type Post type to check.
|
224 |
+
* @return bool True if valid save post action, False otherwise.
|
225 |
+
*/
|
226 |
+
public function check_if_valid_save_post_action( $post_id , $post_type ) {
|
227 |
+
|
228 |
+
if ( get_post_type() != $post_type || empty( $_POST ) || wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) || !current_user_can( 'edit_page' , $post_id ) )
|
229 |
+
return false;
|
230 |
+
else
|
231 |
+
return true;
|
232 |
+
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Get user IP address.
|
237 |
+
*
|
238 |
+
* @since 3.0.0
|
239 |
+
* @since 3.3.2 Added condition to disable IP address collection (for GDRP compliance).
|
240 |
+
* @access public
|
241 |
+
*
|
242 |
+
* @return string User's IP address.
|
243 |
+
*/
|
244 |
+
public function get_user_ip_address() {
|
245 |
+
|
246 |
+
if ( get_option( 'ta_disable_ip_address_collection' ) === 'yes' )
|
247 |
+
return;
|
248 |
+
|
249 |
+
if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) )
|
250 |
+
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
251 |
+
elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
|
252 |
+
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
253 |
+
else
|
254 |
+
$ip = $_SERVER['REMOTE_ADDR'];
|
255 |
+
|
256 |
+
return apply_filters( 'ta_get_user_ip_address', $ip );
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Get the thirstylink slug set on the settings.
|
261 |
+
*
|
262 |
+
* @since 3.0.0
|
263 |
+
* @access public
|
264 |
+
*
|
265 |
+
* @return string $link_prefix Thirstyling link prefix.
|
266 |
+
*/
|
267 |
+
public function get_thirstylink_link_prefix() {
|
268 |
+
|
269 |
+
$link_prefix = get_option( 'ta_link_prefix' , 'recommends' );
|
270 |
+
|
271 |
+
if ( $link_prefix === 'custom' )
|
272 |
+
$link_prefix = get_option( 'ta_link_prefix_custom' , 'recommends' );
|
273 |
+
|
274 |
+
return $link_prefix ? $link_prefix : 'recommends';
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Get the affiliate link post default category slug.
|
279 |
+
*
|
280 |
+
* @since 3.0.0
|
281 |
+
* @access public
|
282 |
+
*
|
283 |
+
* @param int $link_id Affiliate Link ID.
|
284 |
+
* @param array $terms Affiliate link categories.
|
285 |
+
* @return string Affiliate link default category slug.
|
286 |
+
*/
|
287 |
+
public function get_default_category_slug( $link_id , $terms = array() ) {
|
288 |
+
|
289 |
+
if ( ! is_array( $terms ) || empty( $terms ) )
|
290 |
+
$terms = get_the_terms( $link_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
291 |
+
|
292 |
+
if ( is_wp_error( $terms ) || empty( $terms ) )
|
293 |
+
return;
|
294 |
+
|
295 |
+
$link_cat_obj = array_shift( $terms );
|
296 |
+
|
297 |
+
return $link_cat_obj->slug;
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Search affiliate links query
|
302 |
+
*
|
303 |
+
* @since 3.0.0
|
304 |
+
* @since 3.6 Add suport for Gutenberg.
|
305 |
+
* @access public
|
306 |
+
*
|
307 |
+
* @param string $keyword Search keyword.
|
308 |
+
* @param int $paged WP_Query paged value.
|
309 |
+
* @param string $category Affiliate link category to search.
|
310 |
+
* @param array $exclude List of posts to be excluded.
|
311 |
+
* @return array List of affiliate link IDs.
|
312 |
+
*/
|
313 |
+
public function search_affiliate_links_query( $keyword = '' , $paged = 1 , $category = '' , $exclude = array() , $is_gutenberg = false ) {
|
314 |
+
|
315 |
+
$args = array(
|
316 |
+
'post_type' => Plugin_Constants::AFFILIATE_LINKS_CPT,
|
317 |
+
'post_status' => 'publish',
|
318 |
+
's' => $keyword,
|
319 |
+
'fields' => 'ids',
|
320 |
+
'paged' => $paged,
|
321 |
+
'post__not_in' => $exclude
|
322 |
+
);
|
323 |
+
|
324 |
+
if ( $category ) {
|
325 |
+
|
326 |
+
$args[ 'tax_query' ] = array(
|
327 |
+
array(
|
328 |
+
'taxonomy' => Plugin_Constants::AFFILIATE_LINKS_TAX,
|
329 |
+
'field' => 'slug',
|
330 |
+
'terms' => $category
|
331 |
+
)
|
332 |
+
);
|
333 |
+
}
|
334 |
+
|
335 |
+
if ( $is_gutenberg ) {
|
336 |
+
unset( $args[ 'fields' ] );
|
337 |
+
unset( $args[ 'paged' ] );
|
338 |
+
|
339 |
+
$args[ 'posts_per_page' ] = 20;
|
340 |
+
}
|
341 |
+
|
342 |
+
$query = new \WP_Query( $args );
|
343 |
+
|
344 |
+
return $is_gutenberg ? array_map( function( $post ) {
|
345 |
+
return array(
|
346 |
+
'id' => $post->ID,
|
347 |
+
'link' => get_permalink( $post ),
|
348 |
+
'title' => $post->post_title
|
349 |
+
);
|
350 |
+
} , $query->posts ) : $query->posts;
|
351 |
+
|
352 |
+
// return $query->posts;
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Check if affiliate link needs to be uncloaked.
|
357 |
+
*
|
358 |
+
* @deprecated 3.2.0
|
359 |
+
*
|
360 |
+
* @since 3.0.0
|
361 |
+
* @access public
|
362 |
+
*
|
363 |
+
* @param Affiliate_Link $thirstylink Thirsty affiliate link object.
|
364 |
+
* @return boolean Sets to true when affiliate link needs to be uncloaked.
|
365 |
+
*/
|
366 |
+
public function is_uncloak_link( $thirstylink ) {
|
367 |
+
|
368 |
+
return $thirstylink->is( 'uncloak_link' );
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Error log with a trace.
|
373 |
+
*
|
374 |
+
* @since 3.0.0
|
375 |
+
* @access public
|
376 |
+
*/
|
377 |
+
public function ta_error_log( $msg ) {
|
378 |
+
|
379 |
+
$trace = debug_backtrace();
|
380 |
+
$caller = array_shift( $trace );
|
381 |
+
|
382 |
+
error_log( $msg . ' | Trace: ' . $caller[ 'file' ] . ' on line ' . $caller[ 'line' ] );
|
383 |
+
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Utility function that determines if a plugin is active or not.
|
388 |
+
*
|
389 |
+
* @since 3.0.0
|
390 |
+
* @access public
|
391 |
+
*
|
392 |
+
* @param string $plugin_basename Plugin base name. Ex. woocommerce/woocommerce.php
|
393 |
+
* @return boolean True if active, false otherwise.
|
394 |
+
*/
|
395 |
+
public function is_plugin_active( $plugin_basename ) {
|
396 |
+
|
397 |
+
// Makes sure the plugin is defined before trying to use it
|
398 |
+
if ( !function_exists( 'is_plugin_active' ) )
|
399 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
400 |
+
|
401 |
+
return is_plugin_active( $plugin_basename );
|
402 |
+
|
403 |
+
}
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Send email.
|
407 |
+
*
|
408 |
+
* @since 3.0.0
|
409 |
+
* @access public
|
410 |
+
*
|
411 |
+
* @param array $recipients Array of recipients emails.
|
412 |
+
* @param string $subject Email subject.
|
413 |
+
* @param string $message Email message.
|
414 |
+
* @param array $headers Array of email headers.
|
415 |
+
* @param array $attachments Array of email attachments.
|
416 |
+
* @return boolean True if email sending is triggered, note it does not mean that the email was received, it just denotes that the email sending is triggered. False if email sending is not triggered.
|
417 |
+
*/
|
418 |
+
public function send_email( $recipients , $subject , $message , $headers = array() , $attachments = array() ) {
|
419 |
+
|
420 |
+
$from_name = apply_filters( 'ta_email_from_name' , get_bloginfo( 'name' ) );
|
421 |
+
$from_email = apply_filters( 'ta_email_from_email' , get_option( 'admin_email' ) );
|
422 |
+
|
423 |
+
$headers[] = 'From: ' . $from_name . ' <' . $from_email . '>';
|
424 |
+
$headers[] = 'Content-Type: text/html; charset=' . get_option( 'blog_charset' );
|
425 |
+
|
426 |
+
return wp_mail( $recipients , $subject , $message , $headers , $attachments );
|
427 |
+
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Get Affiliate_Link data object.
|
432 |
+
*
|
433 |
+
* @since 3.0.0
|
434 |
+
* @access public
|
435 |
+
*
|
436 |
+
* @param int $id Affiliate_Link post ID.
|
437 |
+
* @return Affiliate_Link Affiliate Link object.
|
438 |
+
*/
|
439 |
+
public function get_affiliate_link( $id = 0 ) {
|
440 |
+
|
441 |
+
return new Affiliate_Link( $id );
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Retrieve all categories as an option array list.
|
446 |
+
*
|
447 |
+
* @since 3.0.0
|
448 |
+
* @since 3.4.0 Add support for slug options.
|
449 |
+
* @access public
|
450 |
+
*
|
451 |
+
* @return array List of category options.
|
452 |
+
*/
|
453 |
+
public function get_all_category_as_options( $use_slug = false ) {
|
454 |
+
|
455 |
+
$options = array();
|
456 |
+
|
457 |
+
$categories = get_terms( array(
|
458 |
+
'taxonomy' => Plugin_Constants::AFFILIATE_LINKS_TAX,
|
459 |
+
'hide_empty' => false,
|
460 |
+
) );
|
461 |
+
|
462 |
+
if ( ! is_wp_error( $categories ) ) {
|
463 |
+
|
464 |
+
foreach( $categories as $category ) {
|
465 |
+
$key = $use_slug ? $category->slug : $category->term_id;
|
466 |
+
$options[ $key ] = $category->name;
|
467 |
+
}
|
468 |
+
|
469 |
+
} else {
|
470 |
+
|
471 |
+
// TODO: Handle error
|
472 |
+
|
473 |
+
}
|
474 |
+
|
475 |
+
return $options;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Set default term when affiliate link is saved.
|
480 |
+
*
|
481 |
+
* @since 3.2.0
|
482 |
+
* @access public
|
483 |
+
*
|
484 |
+
* @param int $post_id Affiliate link post ID.
|
485 |
+
*/
|
486 |
+
public function save_default_affiliate_link_category( $post_id ) {
|
487 |
+
|
488 |
+
$default_category = Plugin_Constants::DEFAULT_LINK_CATEGORY;
|
489 |
+
$taxonomy_slug = Plugin_Constants::AFFILIATE_LINKS_TAX;
|
490 |
+
|
491 |
+
if ( get_option( 'ta_disable_cat_auto_select' ) == 'yes' || get_the_terms( $post_id , $taxonomy_slug ) )
|
492 |
+
return;
|
493 |
+
|
494 |
+
// create the default term if it doesn't exist
|
495 |
+
if ( ! term_exists( $default_category , $taxonomy_slug ) )
|
496 |
+
wp_insert_term( $default_category , $taxonomy_slug );
|
497 |
+
|
498 |
+
$default_term = get_term_by( 'name' , $default_category , $taxonomy_slug );
|
499 |
+
|
500 |
+
wp_set_post_terms( $post_id , $default_term->term_id , $taxonomy_slug );
|
501 |
+
}
|
502 |
+
|
503 |
+
/**
|
504 |
+
* This function is an alias for WP get_option(), but will return the default value if option value is empty or invalid.
|
505 |
+
*
|
506 |
+
* @since 3.2.0
|
507 |
+
* @access public
|
508 |
+
*
|
509 |
+
* @param string $option_name Name of the option of value to fetch.
|
510 |
+
* @param mixed $default_value Defaut option value.
|
511 |
+
* @return mixed Option value.
|
512 |
+
*/
|
513 |
+
public function get_option( $option_name , $default_value = '' ) {
|
514 |
+
|
515 |
+
$option_value = get_option( $option_name , $default_value );
|
516 |
+
|
517 |
+
return ( gettype( $option_value ) === gettype( $default_value ) && $option_value ) ? $option_value : $default_value;
|
518 |
+
}
|
519 |
+
|
520 |
+
/**
|
521 |
+
* Get blocked bots from settings or default value.
|
522 |
+
*
|
523 |
+
* @since 3.3.2
|
524 |
+
* @access public
|
525 |
+
*
|
526 |
+
* @return array List of blocked bots.
|
527 |
+
*/
|
528 |
+
public function get_blocked_bots() {
|
529 |
+
|
530 |
+
$bots_string = $this->get_option( 'ta_blocked_bots' , Plugin_Constants::DEFAULT_BLOCKED_BOTS );
|
531 |
+
return str_replace( ',' , '|' , $bots_string );
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Check if useragent is bot.
|
536 |
+
*
|
537 |
+
* @since 3.3.3
|
538 |
+
* @access public
|
539 |
+
*
|
540 |
+
* @return bool True if detected as bot, otherwise false.
|
541 |
+
*/
|
542 |
+
public function is_user_agent_bot() {
|
543 |
+
|
544 |
+
$user_agent = isset( $_SERVER[ 'HTTP_USER_AGENT' ] ) ? strtolower( $_SERVER[ 'HTTP_USER_AGENT' ] ) : '';
|
545 |
+
$bots = apply_filters( 'ta_useragent_bots_phrase_list' , $this->get_blocked_bots() );
|
546 |
+
$pattern = '/' . $bots . '/i';
|
547 |
+
|
548 |
+
return preg_match( $pattern , $user_agent );
|
549 |
+
}
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Get screen ID.
|
553 |
+
*
|
554 |
+
* @since 3.3.3
|
555 |
+
* @access public
|
556 |
+
*/
|
557 |
+
public function get_screen_id( $object_id ) {
|
558 |
+
|
559 |
+
$screen_id = null;
|
560 |
+
|
561 |
+
if ( isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == Plugin_Constants::AFFILIATE_LINKS_CPT ) {
|
562 |
+
|
563 |
+
if ( isset( $_GET[ 'taxonomy' ] ) )
|
564 |
+
$screen_id = 'edit-' . $_GET[ 'taxonomy' ];
|
565 |
+
elseif ( isset( $_GET[ 'page' ] ) )
|
566 |
+
$screen_id = 'thirstylink_page_' . $_GET[ 'page' ];
|
567 |
+
else
|
568 |
+
$screen_id = 'edit-thirstylink';
|
569 |
+
|
570 |
+
} elseif ( $object_id )
|
571 |
+
$screen_id = 'thirstylink';
|
572 |
+
|
573 |
+
return apply_filters( 'ta_get_screen_id' , $screen_id );
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* Get visistor's browser and device.
|
578 |
+
*
|
579 |
+
* @since 3.4.0
|
580 |
+
* @access public
|
581 |
+
*
|
582 |
+
* @return string Browser and device.
|
583 |
+
*/
|
584 |
+
public function get_visitor_browser_device() {
|
585 |
+
|
586 |
+
if ( get_option( 'ta_disable_browser_device_collection' ) === 'yes' || ! ini_get( "browscap" ) )
|
587 |
+
return;
|
588 |
+
|
589 |
+
$browser = get_browser( null );
|
590 |
+
return is_object( $browser ) ? $browser->browser . '|' . $browser->platform . '|' . $browser->device_type : '';
|
591 |
+
}
|
592 |
+
|
593 |
+
/**
|
594 |
+
* Check if a page builder is active or not. Currently supports: Beaver Builder and Elementor.
|
595 |
+
*
|
596 |
+
* @since 3.4.0
|
597 |
+
* @access public
|
598 |
+
*/
|
599 |
+
public function is_page_builder_active() {
|
600 |
+
|
601 |
+
$is_bb_active = class_exists( 'FLBuilderModel' ) && \FLBuilderModel::is_builder_active();
|
602 |
+
$elementor = class_exists( 'Elementor\Editor' ) && isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'elementor';
|
603 |
+
|
604 |
+
return $is_bb_active || $elementor;
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* Get string in between two strins.
|
609 |
+
* Source: http://www.justin-cook.com/2006/03/31/php-parse-a-string-between-two-strings/
|
610 |
+
*
|
611 |
+
* @since 3.6
|
612 |
+
*/
|
613 |
+
public function get_string_between( $string , $start , $end ) {
|
614 |
+
|
615 |
+
$string = ' ' . $string;
|
616 |
+
$ini = strpos($string, $start);
|
617 |
+
if ($ini == 0) return '';
|
618 |
+
$ini += strlen($start);
|
619 |
+
$len = strpos($string, $end, $ini) - $ini;
|
620 |
+
return substr($string, $ini, $len);
|
621 |
+
}
|
622 |
+
|
623 |
+
}
|
Helpers/Plugin_Constants.php
CHANGED
@@ -1,164 +1,164 @@
|
|
1 |
-
<?php
|
2 |
-
namespace ThirstyAffiliates\Helpers;
|
3 |
-
|
4 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
-
|
6 |
-
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Model that houses all the plugin constants.
|
10 |
-
* Note as much as possible, we need to make this class succinct as the only purpose of this is to house all the constants that is utilized by the plugin.
|
11 |
-
* Therefore we omit class member comments and minimize comments as much as possible.
|
12 |
-
* In fact the only verbouse comment here is this comment you are reading right now.
|
13 |
-
* And guess what, it just got worse coz now this comment takes 5 lines instead of 3.
|
14 |
-
*
|
15 |
-
* @since 3.0.0
|
16 |
-
*/
|
17 |
-
class Plugin_Constants {
|
18 |
-
|
19 |
-
/*
|
20 |
-
|--------------------------------------------------------------------------
|
21 |
-
| Class Properties
|
22 |
-
|--------------------------------------------------------------------------
|
23 |
-
*/
|
24 |
-
|
25 |
-
private static $_instance;
|
26 |
-
|
27 |
-
// Plugin configuration constants
|
28 |
-
const TOKEN = 'ta';
|
29 |
-
const INSTALLED_VERSION = 'ta_installed_version';
|
30 |
-
const VERSION = '3.
|
31 |
-
const TEXT_DOMAIN = 'thirstyaffiliates';
|
32 |
-
const THEME_TEMPLATE_PATH = 'thirstyaffiliates';
|
33 |
-
const META_DATA_PREFIX = '_ta_';
|
34 |
-
|
35 |
-
// CPT Taxonomy constants
|
36 |
-
const AFFILIATE_LINKS_CPT = 'thirstylink';
|
37 |
-
const AFFILIATE_LINKS_TAX = 'thirstylink-category';
|
38 |
-
const DEFAULT_LINK_CATEGORY = 'Uncategorized';
|
39 |
-
|
40 |
-
// CRON
|
41 |
-
const CRON_REQUEST_REVIEW = 'ta_cron_request_review';
|
42 |
-
const CRON_MIGRATE_OLD_PLUGIN_DATA = 'ta_cron_migrate_old_plugin_data';
|
43 |
-
const CRON_TAPRO_NOTICE = 'ta_cron_tapro_notice';
|
44 |
-
const CRON_STATS_TRIMMER = 'ta_cron_stats_trimmer';
|
45 |
-
|
46 |
-
// Options
|
47 |
-
const SHOW_REQUEST_REVIEW = 'ta_show_request_review';
|
48 |
-
const REVIEW_REQUEST_RESPONSE = 'ta_request_review_response';
|
49 |
-
const MIGRATION_COMPLETE_FLAG = 'ta_migration_complete_flag';
|
50 |
-
const SHOW_TAPRO_NOTICE = 'ta_show_tapro_notice';
|
51 |
-
|
52 |
-
// Settings Constants
|
53 |
-
const DEFAULT_BLOCKED_BOTS = 'googlebot,bingbot,Slurp,DuckDuckBot,Baiduspider,YandexBot,Sogou,Exabot,facebo,ia_archiver';
|
54 |
-
|
55 |
-
// DB Tables
|
56 |
-
const LINK_CLICK_DB = 'ta_link_clicks';
|
57 |
-
const LINK_CLICK_META_DB = 'ta_link_clicks_meta';
|
58 |
-
|
59 |
-
// Help Section
|
60 |
-
const CLEAN_UP_PLUGIN_OPTIONS = 'ta_clean_up_plugin_options';
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
/*
|
66 |
-
|--------------------------------------------------------------------------
|
67 |
-
| Class Methods
|
68 |
-
|--------------------------------------------------------------------------
|
69 |
-
*/
|
70 |
-
|
71 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin ) {
|
72 |
-
|
73 |
-
// Path constants
|
74 |
-
$this->_MAIN_PLUGIN_FILE_PATH = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'thirstyaffiliates' . DIRECTORY_SEPARATOR . 'thirstyaffiliates.php';
|
75 |
-
$this->_PLUGIN_DIR_PATH = plugin_dir_path( $this->_MAIN_PLUGIN_FILE_PATH );
|
76 |
-
$this->_PLUGIN_DIR_URL = plugin_dir_url( $this->_MAIN_PLUGIN_FILE_PATH );
|
77 |
-
$this->_PLUGIN_DIRNAME = plugin_basename( dirname( $this->_MAIN_PLUGIN_FILE_PATH ) );
|
78 |
-
$this->_PLUGIN_BASENAME = plugin_basename( $this->_MAIN_PLUGIN_FILE_PATH );
|
79 |
-
|
80 |
-
$this->_CSS_ROOT_URL = $this->_PLUGIN_DIR_URL . 'css/';
|
81 |
-
$this->_IMAGES_ROOT_URL = $this->_PLUGIN_DIR_URL . 'images/';
|
82 |
-
$this->_JS_ROOT_URL = $this->_PLUGIN_DIR_URL . 'js/';
|
83 |
-
|
84 |
-
$this->_VIEWS_ROOT_PATH = $this->_PLUGIN_DIR_PATH . 'views/';
|
85 |
-
$this->_TEMPLATES_ROOT_PATH = $this->_PLUGIN_DIR_PATH . 'templates/';
|
86 |
-
$this->_LOGS_ROOT_PATH = $this->_PLUGIN_DIR_PATH . 'logs/';
|
87 |
-
|
88 |
-
$this->_REDIRECT_TYPES = apply_filters( 'ta_redirect_types' , array(
|
89 |
-
'301' => __( '301 Permanent' , 'thirstyaffiliates' ),
|
90 |
-
'302' => __( '302 Temporary' , 'thirstyaffiliates' ),
|
91 |
-
'307' => __( '307 Temporary (alternative)' , 'thirstyaffiliates' )
|
92 |
-
) );
|
93 |
-
|
94 |
-
$main_plugin->add_to_public_helpers( $this );
|
95 |
-
|
96 |
-
}
|
97 |
-
|
98 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin ) {
|
99 |
-
|
100 |
-
if ( !self::$_instance instanceof self )
|
101 |
-
self::$_instance = new self( $main_plugin );
|
102 |
-
|
103 |
-
return self::$_instance;
|
104 |
-
|
105 |
-
}
|
106 |
-
|
107 |
-
public function VERSION() {
|
108 |
-
return self::VERSION;
|
109 |
-
}
|
110 |
-
|
111 |
-
public function MAIN_PLUGIN_FILE_PATH() {
|
112 |
-
return $this->_MAIN_PLUGIN_FILE_PATH;
|
113 |
-
}
|
114 |
-
|
115 |
-
public function PLUGIN_DIR_PATH() {
|
116 |
-
return $this->_PLUGIN_DIR_PATH;
|
117 |
-
}
|
118 |
-
|
119 |
-
public function PLUGIN_DIR_URL() {
|
120 |
-
return $this->_PLUGIN_DIR_URL;
|
121 |
-
}
|
122 |
-
|
123 |
-
public function PLUGIN_DIRNAME() {
|
124 |
-
return $this->_PLUGIN_DIRNAME;
|
125 |
-
}
|
126 |
-
|
127 |
-
public function PLUGIN_BASENAME() {
|
128 |
-
return $this->_PLUGIN_BASENAME;
|
129 |
-
}
|
130 |
-
|
131 |
-
public function CSS_ROOT_URL() {
|
132 |
-
return $this->_CSS_ROOT_URL;
|
133 |
-
}
|
134 |
-
|
135 |
-
public function IMAGES_ROOT_URL() {
|
136 |
-
return $this->_IMAGES_ROOT_URL;
|
137 |
-
}
|
138 |
-
|
139 |
-
public function JS_ROOT_URL() {
|
140 |
-
return $this->_JS_ROOT_URL;
|
141 |
-
}
|
142 |
-
|
143 |
-
public function VIEWS_ROOT_PATH() {
|
144 |
-
return $this->_VIEWS_ROOT_PATH;
|
145 |
-
}
|
146 |
-
|
147 |
-
public function TEMPLATES_ROOT_PATH() {
|
148 |
-
return $this->_TEMPLATES_ROOT_PATH;
|
149 |
-
}
|
150 |
-
|
151 |
-
public function LOGS_ROOT_PATH() {
|
152 |
-
return $this->_LOGS_ROOT_PATH;
|
153 |
-
}
|
154 |
-
|
155 |
-
public function REDIRECT_TYPES() {
|
156 |
-
return $this->_REDIRECT_TYPES;
|
157 |
-
}
|
158 |
-
|
159 |
-
// HTAccess Module
|
160 |
-
public function HTACCESS_FILE() {
|
161 |
-
return ABSPATH . '/.htaccess';
|
162 |
-
}
|
163 |
-
|
164 |
-
}
|
1 |
+
<?php
|
2 |
+
namespace ThirstyAffiliates\Helpers;
|
3 |
+
|
4 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
+
|
6 |
+
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Model that houses all the plugin constants.
|
10 |
+
* Note as much as possible, we need to make this class succinct as the only purpose of this is to house all the constants that is utilized by the plugin.
|
11 |
+
* Therefore we omit class member comments and minimize comments as much as possible.
|
12 |
+
* In fact the only verbouse comment here is this comment you are reading right now.
|
13 |
+
* And guess what, it just got worse coz now this comment takes 5 lines instead of 3.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Plugin_Constants {
|
18 |
+
|
19 |
+
/*
|
20 |
+
|--------------------------------------------------------------------------
|
21 |
+
| Class Properties
|
22 |
+
|--------------------------------------------------------------------------
|
23 |
+
*/
|
24 |
+
|
25 |
+
private static $_instance;
|
26 |
+
|
27 |
+
// Plugin configuration constants
|
28 |
+
const TOKEN = 'ta';
|
29 |
+
const INSTALLED_VERSION = 'ta_installed_version';
|
30 |
+
const VERSION = '3.6';
|
31 |
+
const TEXT_DOMAIN = 'thirstyaffiliates';
|
32 |
+
const THEME_TEMPLATE_PATH = 'thirstyaffiliates';
|
33 |
+
const META_DATA_PREFIX = '_ta_';
|
34 |
+
|
35 |
+
// CPT Taxonomy constants
|
36 |
+
const AFFILIATE_LINKS_CPT = 'thirstylink';
|
37 |
+
const AFFILIATE_LINKS_TAX = 'thirstylink-category';
|
38 |
+
const DEFAULT_LINK_CATEGORY = 'Uncategorized';
|
39 |
+
|
40 |
+
// CRON
|
41 |
+
const CRON_REQUEST_REVIEW = 'ta_cron_request_review';
|
42 |
+
const CRON_MIGRATE_OLD_PLUGIN_DATA = 'ta_cron_migrate_old_plugin_data';
|
43 |
+
const CRON_TAPRO_NOTICE = 'ta_cron_tapro_notice';
|
44 |
+
const CRON_STATS_TRIMMER = 'ta_cron_stats_trimmer';
|
45 |
+
|
46 |
+
// Options
|
47 |
+
const SHOW_REQUEST_REVIEW = 'ta_show_request_review';
|
48 |
+
const REVIEW_REQUEST_RESPONSE = 'ta_request_review_response';
|
49 |
+
const MIGRATION_COMPLETE_FLAG = 'ta_migration_complete_flag';
|
50 |
+
const SHOW_TAPRO_NOTICE = 'ta_show_tapro_notice';
|
51 |
+
|
52 |
+
// Settings Constants
|
53 |
+
const DEFAULT_BLOCKED_BOTS = 'googlebot,bingbot,Slurp,DuckDuckBot,Baiduspider,YandexBot,Sogou,Exabot,facebo,ia_archiver';
|
54 |
+
|
55 |
+
// DB Tables
|
56 |
+
const LINK_CLICK_DB = 'ta_link_clicks';
|
57 |
+
const LINK_CLICK_META_DB = 'ta_link_clicks_meta';
|
58 |
+
|
59 |
+
// Help Section
|
60 |
+
const CLEAN_UP_PLUGIN_OPTIONS = 'ta_clean_up_plugin_options';
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
|
65 |
+
/*
|
66 |
+
|--------------------------------------------------------------------------
|
67 |
+
| Class Methods
|
68 |
+
|--------------------------------------------------------------------------
|
69 |
+
*/
|
70 |
+
|
71 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin ) {
|
72 |
+
|
73 |
+
// Path constants
|
74 |
+
$this->_MAIN_PLUGIN_FILE_PATH = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'thirstyaffiliates' . DIRECTORY_SEPARATOR . 'thirstyaffiliates.php';
|
75 |
+
$this->_PLUGIN_DIR_PATH = plugin_dir_path( $this->_MAIN_PLUGIN_FILE_PATH );
|
76 |
+
$this->_PLUGIN_DIR_URL = plugin_dir_url( $this->_MAIN_PLUGIN_FILE_PATH );
|
77 |
+
$this->_PLUGIN_DIRNAME = plugin_basename( dirname( $this->_MAIN_PLUGIN_FILE_PATH ) );
|
78 |
+
$this->_PLUGIN_BASENAME = plugin_basename( $this->_MAIN_PLUGIN_FILE_PATH );
|
79 |
+
|
80 |
+
$this->_CSS_ROOT_URL = $this->_PLUGIN_DIR_URL . 'css/';
|
81 |
+
$this->_IMAGES_ROOT_URL = $this->_PLUGIN_DIR_URL . 'images/';
|
82 |
+
$this->_JS_ROOT_URL = $this->_PLUGIN_DIR_URL . 'js/';
|
83 |
+
|
84 |
+
$this->_VIEWS_ROOT_PATH = $this->_PLUGIN_DIR_PATH . 'views/';
|
85 |
+
$this->_TEMPLATES_ROOT_PATH = $this->_PLUGIN_DIR_PATH . 'templates/';
|
86 |
+
$this->_LOGS_ROOT_PATH = $this->_PLUGIN_DIR_PATH . 'logs/';
|
87 |
+
|
88 |
+
$this->_REDIRECT_TYPES = apply_filters( 'ta_redirect_types' , array(
|
89 |
+
'301' => __( '301 Permanent' , 'thirstyaffiliates' ),
|
90 |
+
'302' => __( '302 Temporary' , 'thirstyaffiliates' ),
|
91 |
+
'307' => __( '307 Temporary (alternative)' , 'thirstyaffiliates' )
|
92 |
+
) );
|
93 |
+
|
94 |
+
$main_plugin->add_to_public_helpers( $this );
|
95 |
+
|
96 |
+
}
|
97 |
+
|
98 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin ) {
|
99 |
+
|
100 |
+
if ( !self::$_instance instanceof self )
|
101 |
+
self::$_instance = new self( $main_plugin );
|
102 |
+
|
103 |
+
return self::$_instance;
|
104 |
+
|
105 |
+
}
|
106 |
+
|
107 |
+
public function VERSION() {
|
108 |
+
return self::VERSION;
|
109 |
+
}
|
110 |
+
|
111 |
+
public function MAIN_PLUGIN_FILE_PATH() {
|
112 |
+
return $this->_MAIN_PLUGIN_FILE_PATH;
|
113 |
+
}
|
114 |
+
|
115 |
+
public function PLUGIN_DIR_PATH() {
|
116 |
+
return $this->_PLUGIN_DIR_PATH;
|
117 |
+
}
|
118 |
+
|
119 |
+
public function PLUGIN_DIR_URL() {
|
120 |
+
return $this->_PLUGIN_DIR_URL;
|
121 |
+
}
|
122 |
+
|
123 |
+
public function PLUGIN_DIRNAME() {
|
124 |
+
return $this->_PLUGIN_DIRNAME;
|
125 |
+
}
|
126 |
+
|
127 |
+
public function PLUGIN_BASENAME() {
|
128 |
+
return $this->_PLUGIN_BASENAME;
|
129 |
+
}
|
130 |
+
|
131 |
+
public function CSS_ROOT_URL() {
|
132 |
+
return $this->_CSS_ROOT_URL;
|
133 |
+
}
|
134 |
+
|
135 |
+
public function IMAGES_ROOT_URL() {
|
136 |
+
return $this->_IMAGES_ROOT_URL;
|
137 |
+
}
|
138 |
+
|
139 |
+
public function JS_ROOT_URL() {
|
140 |
+
return $this->_JS_ROOT_URL;
|
141 |
+
}
|
142 |
+
|
143 |
+
public function VIEWS_ROOT_PATH() {
|
144 |
+
return $this->_VIEWS_ROOT_PATH;
|
145 |
+
}
|
146 |
+
|
147 |
+
public function TEMPLATES_ROOT_PATH() {
|
148 |
+
return $this->_TEMPLATES_ROOT_PATH;
|
149 |
+
}
|
150 |
+
|
151 |
+
public function LOGS_ROOT_PATH() {
|
152 |
+
return $this->_LOGS_ROOT_PATH;
|
153 |
+
}
|
154 |
+
|
155 |
+
public function REDIRECT_TYPES() {
|
156 |
+
return $this->_REDIRECT_TYPES;
|
157 |
+
}
|
158 |
+
|
159 |
+
// HTAccess Module
|
160 |
+
public function HTACCESS_FILE() {
|
161 |
+
return ABSPATH . '/.htaccess';
|
162 |
+
}
|
163 |
+
|
164 |
+
}
|
Interfaces/Deactivatable_Interface.php
CHANGED
@@ -1,22 +1,22 @@
|
|
1 |
-
<?php
|
2 |
-
namespace ThirstyAffiliates\Interfaces;
|
3 |
-
|
4 |
-
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Abstraction that provides contract relating to deactivation.
|
8 |
-
* Any model that needs some sort of deactivation must implement this interface.
|
9 |
-
*
|
10 |
-
* @since 3.1.0
|
11 |
-
*/
|
12 |
-
interface Deactivatable_Interface {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Contract for deactivation.
|
16 |
-
*
|
17 |
-
* @since 3.1.0
|
18 |
-
* @access public
|
19 |
-
*/
|
20 |
-
public function deactivate();
|
21 |
-
|
22 |
-
}
|
1 |
+
<?php
|
2 |
+
namespace ThirstyAffiliates\Interfaces;
|
3 |
+
|
4 |
+
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Abstraction that provides contract relating to deactivation.
|
8 |
+
* Any model that needs some sort of deactivation must implement this interface.
|
9 |
+
*
|
10 |
+
* @since 3.1.0
|
11 |
+
*/
|
12 |
+
interface Deactivatable_Interface {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Contract for deactivation.
|
16 |
+
*
|
17 |
+
* @since 3.1.0
|
18 |
+
* @access public
|
19 |
+
*/
|
20 |
+
public function deactivate();
|
21 |
+
|
22 |
+
}
|
Models/Affiliate_Link.php
CHANGED
@@ -1,768 +1,768 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
-
|
9 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
10 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Model that houses the data model of an affiliate link.
|
14 |
-
*
|
15 |
-
* @since 3.0.0
|
16 |
-
*/
|
17 |
-
class Affiliate_Link {
|
18 |
-
|
19 |
-
|
20 |
-
/*
|
21 |
-
|--------------------------------------------------------------------------
|
22 |
-
| Class Properties
|
23 |
-
|--------------------------------------------------------------------------
|
24 |
-
*/
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Model that houses the main plugin object.
|
28 |
-
*
|
29 |
-
* @since 3.0.0
|
30 |
-
* @access private
|
31 |
-
* @var Abstract_Main_Plugin_Class
|
32 |
-
*/
|
33 |
-
private $_main_plugin;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Model that houses all the plugin constants.
|
37 |
-
*
|
38 |
-
* @since 3.0.0
|
39 |
-
* @access private
|
40 |
-
* @var Plugin_Constants
|
41 |
-
*/
|
42 |
-
private $_constants;
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Property that houses all the helper functions of the plugin.
|
46 |
-
*
|
47 |
-
* @since 3.0.0
|
48 |
-
* @access private
|
49 |
-
* @var Helper_Functions
|
50 |
-
*/
|
51 |
-
private $_helper_functions;
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Stores affiliate link ID.
|
55 |
-
*
|
56 |
-
* @since 3.0.0
|
57 |
-
* @access protected
|
58 |
-
* @var array
|
59 |
-
*/
|
60 |
-
protected $id;
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Stores affiliate link data.
|
64 |
-
*
|
65 |
-
* @since 3.0.0
|
66 |
-
* @access protected
|
67 |
-
* @var array
|
68 |
-
*/
|
69 |
-
protected $data = array();
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Stores affiliate link default data.
|
73 |
-
*
|
74 |
-
* @since 3.0.0
|
75 |
-
* @access protected
|
76 |
-
* @var array
|
77 |
-
*/
|
78 |
-
protected $default_data = array(
|
79 |
-
'name' => '',
|
80 |
-
'slug' => '',
|
81 |
-
'date_created' => '',
|
82 |
-
'date_modified' => '',
|
83 |
-
'status' => '',
|
84 |
-
'permalink' => '',
|
85 |
-
'destination_url' => '',
|
86 |
-
'rel_tags' => '',
|
87 |
-
'css_classes' => '',
|
88 |
-
'redirect_type' => 'global',
|
89 |
-
'no_follow' => 'global',
|
90 |
-
'new_window' => 'global',
|
91 |
-
'uncloak_link' => 'global',
|
92 |
-
'pass_query_str' => 'global',
|
93 |
-
'image_ids' => array(),
|
94 |
-
'categories' => array(),
|
95 |
-
'category_slug' => '',
|
96 |
-
'category_slug_id' => 0,
|
97 |
-
'inserted_to' => array(),
|
98 |
-
'scanned_inserted' => ''
|
99 |
-
);
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Stores affiliate link default data.
|
103 |
-
*
|
104 |
-
* @since 3.0.0
|
105 |
-
* @access protected
|
106 |
-
* @var array
|
107 |
-
*/
|
108 |
-
protected $extend_data = array();
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Stores affiliate link post data.
|
112 |
-
*
|
113 |
-
* @since 3.0.0
|
114 |
-
* @access private
|
115 |
-
* @var object
|
116 |
-
*/
|
117 |
-
protected $post_data;
|
118 |
-
|
119 |
-
/**
|
120 |
-
* This is where changes to the $data will be saved.
|
121 |
-
*
|
122 |
-
* @since 3.0.0
|
123 |
-
* @access protected
|
124 |
-
* @var object
|
125 |
-
*/
|
126 |
-
protected $changes = array();
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Stores boolean if the data has been read from the database or not.
|
130 |
-
*
|
131 |
-
* @since 3.0.0
|
132 |
-
* @access protected
|
133 |
-
* @var object
|
134 |
-
*/
|
135 |
-
protected $object_is_read = false;
|
136 |
-
|
137 |
-
/**
|
138 |
-
* List of deprecated properties.
|
139 |
-
*
|
140 |
-
* @since 3.3.1
|
141 |
-
* @access protected
|
142 |
-
* @var array
|
143 |
-
*/
|
144 |
-
protected $deprecated_props = array(
|
145 |
-
'link_health_issue',
|
146 |
-
'link_health_issue_ignored'
|
147 |
-
);
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
/*
|
153 |
-
|--------------------------------------------------------------------------
|
154 |
-
| Class Methods
|
155 |
-
|--------------------------------------------------------------------------
|
156 |
-
*/
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Class constructor.
|
160 |
-
*
|
161 |
-
* @since 3.0.0
|
162 |
-
* @access public
|
163 |
-
*
|
164 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
165 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
166 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
167 |
-
*/
|
168 |
-
public function __construct( $id = null ) {
|
169 |
-
|
170 |
-
$this->_constants = ThirstyAffiliates()->helpers[ 'Plugin_Constants' ];
|
171 |
-
$this->_helper_functions = ThirstyAffiliates()->helpers[ 'Helper_Functions' ];
|
172 |
-
$this->deprecated_props = apply_filters( 'ta_affiliate_link_deprecated_props' , $this->deprecated_props );
|
173 |
-
|
174 |
-
if ( filter_var( $id , FILTER_VALIDATE_INT ) && $id ) {
|
175 |
-
|
176 |
-
$this->extend_data = apply_filters( 'ta_affiliate_link_extended_data' , $this->extend_data , $this->default_data );
|
177 |
-
$this->data = $this->get_merged_default_extended_data();
|
178 |
-
$this->id = absint( $id );
|
179 |
-
|
180 |
-
$this->read();
|
181 |
-
|
182 |
-
}
|
183 |
-
|
184 |
-
}
|
185 |
-
|
186 |
-
/**
|
187 |
-
* Read data from DB and save on instance.
|
188 |
-
*
|
189 |
-
* @since 3.0.0
|
190 |
-
* @since 3.2.2 Optimize method by lessening the metadata fetch into one single function call.
|
191 |
-
* @access public
|
192 |
-
*/
|
193 |
-
private function read() {
|
194 |
-
|
195 |
-
$this->post_data = get_post( $this->id );
|
196 |
-
|
197 |
-
if ( ! is_a( $this->post_data , 'WP_Post' ) || $this->object_is_read )
|
198 |
-
return;
|
199 |
-
|
200 |
-
$this->id = $this->post_data->ID; // set the affiliate link ID
|
201 |
-
$meta_data = get_metadata( 'post' , $this->id );
|
202 |
-
$default_data = $this->get_merged_default_extended_data();
|
203 |
-
|
204 |
-
foreach ( $default_data as $prop => $value ) {
|
205 |
-
|
206 |
-
// fetch raw meta data if present.
|
207 |
-
$raw_data = isset( $meta_data[ Plugin_Constants::META_DATA_PREFIX . $prop ] ) ? maybe_unserialize( $meta_data[ Plugin_Constants::META_DATA_PREFIX . $prop ][0] ) : '';
|
208 |
-
|
209 |
-
switch ( $prop ) {
|
210 |
-
|
211 |
-
case 'name' :
|
212 |
-
case 'slug' :
|
213 |
-
case 'status' :
|
214 |
-
case 'date_created' :
|
215 |
-
case 'permalink' :
|
216 |
-
$this->data[ $prop ] = $this->get_post_data_equivalent( $prop );
|
217 |
-
break;
|
218 |
-
|
219 |
-
case 'no_follow' :
|
220 |
-
case 'new_window' :
|
221 |
-
case 'pass_query_str' :
|
222 |
-
case 'uncloak_link' :
|
223 |
-
case 'redirect_type' :
|
224 |
-
$this->data[ $prop ] = ! empty( $raw_data ) ? $raw_data : $default_data[ $prop ];
|
225 |
-
break;
|
226 |
-
|
227 |
-
case 'rel_tags' :
|
228 |
-
case 'css_classes' :
|
229 |
-
$this->data[ $prop ] = ! empty( $raw_data ) ? $raw_data : $this->get_prop_global_option_value( $prop );
|
230 |
-
break;
|
231 |
-
|
232 |
-
case 'image_ids' :
|
233 |
-
case 'inserted_to' :
|
234 |
-
$this->data[ $prop ] = ( is_array( $raw_data ) && ! empty( $raw_data ) ) ? $raw_data : $default_data[ $prop ];
|
235 |
-
break;
|
236 |
-
|
237 |
-
case 'categories' :
|
238 |
-
$categories = wp_get_post_terms( $this->id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
239 |
-
$this->data[ $prop ] = ! empty( $categories ) ? $categories : $default_data[ $prop ];
|
240 |
-
break;
|
241 |
-
|
242 |
-
default :
|
243 |
-
$this->data[ $prop ] = apply_filters( 'ta_read_thirstylink_property' , $raw_data , $prop , $default_data , $this->id , $meta_data );
|
244 |
-
break;
|
245 |
-
|
246 |
-
}
|
247 |
-
|
248 |
-
}
|
249 |
-
|
250 |
-
$this->object_is_read = true;
|
251 |
-
|
252 |
-
}
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
/*
|
258 |
-
|--------------------------------------------------------------------------
|
259 |
-
| Data getters
|
260 |
-
|--------------------------------------------------------------------------
|
261 |
-
*/
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Get merged $default_data and $extended_data class properties.
|
265 |
-
*
|
266 |
-
* @since 3.0.0
|
267 |
-
* @access public
|
268 |
-
*
|
269 |
-
* @return array Data properties.
|
270 |
-
*/
|
271 |
-
private function get_merged_default_extended_data() {
|
272 |
-
|
273 |
-
return array_merge( $this->default_data , $this->extend_data );
|
274 |
-
|
275 |
-
}
|
276 |
-
|
277 |
-
/**
|
278 |
-
* Return's the post data equivalent of a certain affiliate link data property.
|
279 |
-
*
|
280 |
-
* @since 3.0.0
|
281 |
-
* @access private
|
282 |
-
*
|
283 |
-
* @param string $prop Affiliate link property name.
|
284 |
-
* @return string WP Post property equivalent.
|
285 |
-
*/
|
286 |
-
private function get_post_data_equivalent( $prop ) {
|
287 |
-
|
288 |
-
$equivalents = apply_filters( 'ta_affiliate_link_post_data_equivalent' , array(
|
289 |
-
'name' => $this->post_data->post_title,
|
290 |
-
'slug' => $this->post_data->post_name,
|
291 |
-
'permalink' => get_permalink( $this->post_data->ID ),
|
292 |
-
'status' => $this->post_data->post_status,
|
293 |
-
'date_created' => $this->post_data->post_date,
|
294 |
-
'date_modified' => $this->post_data->post_modified,
|
295 |
-
) , $this->post_data );
|
296 |
-
|
297 |
-
if ( array_key_exists( $prop , $equivalents ) )
|
298 |
-
return $equivalents[ $prop ];
|
299 |
-
else
|
300 |
-
return;
|
301 |
-
|
302 |
-
}
|
303 |
-
|
304 |
-
/**
|
305 |
-
* Return data property.
|
306 |
-
*
|
307 |
-
* @since 3.0.0
|
308 |
-
* @since 3.3.1 Make sure deprecated props are ignored.
|
309 |
-
* @access public
|
310 |
-
*
|
311 |
-
* @param string $prop Data property slug.
|
312 |
-
* @param mixed $default Set property default value (optional).
|
313 |
-
* @return mixed Property data.
|
314 |
-
*/
|
315 |
-
public function get_prop( $prop , $default = '' ) {
|
316 |
-
|
317 |
-
$default_data = $this->get_merged_default_extended_data();
|
318 |
-
|
319 |
-
if ( in_array( $prop , $this->deprecated_props ) )
|
320 |
-
return $default;
|
321 |
-
|
322 |
-
if ( array_key_exists( $prop , $this->data ) && $this->data[ $prop ] )
|
323 |
-
$return_value = $this->data[ $prop ];
|
324 |
-
else
|
325 |
-
$return_value = ( $default ) ? $default : $default_data[ $prop ];
|
326 |
-
|
327 |
-
return $return_value;
|
328 |
-
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Get redirect type
|
333 |
-
*
|
334 |
-
* @since 3.4.0
|
335 |
-
* @access public
|
336 |
-
*
|
337 |
-
* @param string $default Default redirect type.
|
338 |
-
* @return string Redirect type.
|
339 |
-
*/
|
340 |
-
public function get_redirect_type( $default = '' ) {
|
341 |
-
|
342 |
-
$redirect_type = $this->data[ 'redirect_type' ];
|
343 |
-
|
344 |
-
if ( $redirect_type === 'global' )
|
345 |
-
$redirect_type = get_option( 'ta_link_redirect_type' , $default );
|
346 |
-
elseif ( ! $redirect_type )
|
347 |
-
$redirect_type = $default ? $default : $default_data[ 'redirect_type' ];
|
348 |
-
|
349 |
-
return $redirect_type;
|
350 |
-
}
|
351 |
-
|
352 |
-
/**
|
353 |
-
* Return Affiliate_Link ID.
|
354 |
-
*
|
355 |
-
* @since 3.0.0
|
356 |
-
* @access public
|
357 |
-
*
|
358 |
-
* @return int Affiliate_Link ID.
|
359 |
-
*/
|
360 |
-
public function get_id() {
|
361 |
-
|
362 |
-
return absint( $this->id );
|
363 |
-
|
364 |
-
}
|
365 |
-
|
366 |
-
/**
|
367 |
-
* Return changed data property.
|
368 |
-
*
|
369 |
-
* @since 3.0.0
|
370 |
-
* @access public
|
371 |
-
*
|
372 |
-
* @param string $prop Data property slug.
|
373 |
-
* @param mixed $default Set property default value (optional).
|
374 |
-
* @return mixed Property data.
|
375 |
-
*/
|
376 |
-
public function get_changed_prop( $prop , $default = '' ) {
|
377 |
-
|
378 |
-
return isset( $this->changes[ $prop ] ) ? $this->changes[ $prop ] : $this->get_prop( $prop , $default );
|
379 |
-
|
380 |
-
}
|
381 |
-
|
382 |
-
/**
|
383 |
-
* Return affiliate link's WP_Post data.
|
384 |
-
*
|
385 |
-
* @since 3.0.0
|
386 |
-
* @access public
|
387 |
-
*
|
388 |
-
* @return object Post data object.
|
389 |
-
*/
|
390 |
-
public function get_post_data() {
|
391 |
-
|
392 |
-
return $this->post_data;
|
393 |
-
|
394 |
-
}
|
395 |
-
|
396 |
-
/**
|
397 |
-
* Get the properties global option value.
|
398 |
-
*
|
399 |
-
* @since 3.0.0
|
400 |
-
* @since 3.2.2 Remove 'uncloak' option.
|
401 |
-
* @since 3.4.0 Remove 'redirect_type' option. Add additional CSS classes option.
|
402 |
-
* @access public
|
403 |
-
*
|
404 |
-
* @param string $prop Name of property.
|
405 |
-
* @return string Global option value.
|
406 |
-
*/
|
407 |
-
public function get_prop_global_option_value( $prop , $default = '' ) {
|
408 |
-
|
409 |
-
switch( $prop ) {
|
410 |
-
|
411 |
-
case 'rel_tags' :
|
412 |
-
$option = 'ta_additional_rel_tags';
|
413 |
-
break;
|
414 |
-
|
415 |
-
case 'css_classes' :
|
416 |
-
$option = 'ta_additional_css_classes';
|
417 |
-
break;
|
418 |
-
}
|
419 |
-
|
420 |
-
return $option ? get_option( $option , $default ) : $default;
|
421 |
-
}
|
422 |
-
|
423 |
-
/**
|
424 |
-
* Get the global value for the uncloak property.
|
425 |
-
*
|
426 |
-
* @deprecated 3.2.0
|
427 |
-
*
|
428 |
-
* @since 3.0.0
|
429 |
-
* @access public
|
430 |
-
*
|
431 |
-
* @return string Global option value.
|
432 |
-
*/
|
433 |
-
public function get_global_uncloak_value() {
|
434 |
-
|
435 |
-
return $this->get_toggle_prop_global_value( 'uncloak_link' );
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* Get toggle property global value. This function also checks for "category" valued options.
|
440 |
-
*
|
441 |
-
* @since 3.2.0
|
442 |
-
* @access public
|
443 |
-
*
|
444 |
-
* @param string $toggle_prop Affiliate linkg toggle property name.
|
445 |
-
* @return string 'yes' if true, otherwise 'no'.
|
446 |
-
*/
|
447 |
-
public function get_toggle_prop_global_value( $toggle_prop ) {
|
448 |
-
|
449 |
-
$global_props = apply_filters( 'ta_props_with_global_option' , array(
|
450 |
-
'no_follow' => 'ta_no_follow',
|
451 |
-
'new_window' => 'ta_new_window',
|
452 |
-
'uncloak_link' => '',
|
453 |
-
'pass_query_str' => 'ta_pass_query_str'
|
454 |
-
) );
|
455 |
-
$global_props_cat = apply_filters( 'ta_prop_selected_categories_option' , array(
|
456 |
-
'no_follow' => 'ta_no_follow_category',
|
457 |
-
'new_window' => 'ta_new_window_category',
|
458 |
-
'uncloak_link' => 'ta_category_to_uncloak',
|
459 |
-
'pass_query_str' => 'ta_pass_query_str_category'
|
460 |
-
) );
|
461 |
-
|
462 |
-
if ( ! array_key_exists( $toggle_prop , $global_props ) )
|
463 |
-
return 'no';
|
464 |
-
|
465 |
-
// get equivalent global value.
|
466 |
-
$prop_value = $toggle_prop == 'uncloak_link' ? 'category' : get_option( $global_props[ $toggle_prop ] );
|
467 |
-
|
468 |
-
if ( ! $prop_value )
|
469 |
-
return 'no';
|
470 |
-
|
471 |
-
// if prop value is not set to 'category', then return option value.
|
472 |
-
if ( $prop_value != 'category' || ! array_key_exists( $toggle_prop , $global_props_cat ) )
|
473 |
-
return $prop_value;
|
474 |
-
|
475 |
-
$prop_cats = maybe_unserialize( get_option( $global_props_cat[ $toggle_prop ] , array() ) );
|
476 |
-
$link_cats = $this->get_prop( 'categories' );
|
477 |
-
|
478 |
-
// skip when there are no categories to check (false)
|
479 |
-
if ( ! is_array( $prop_cats ) || empty( $prop_cats ) || empty( $link_cats ) )
|
480 |
-
return 'no';
|
481 |
-
|
482 |
-
foreach ( $link_cats as $category ) {
|
483 |
-
|
484 |
-
if ( in_array( $category->term_id , $prop_cats ) )
|
485 |
-
return 'yes';
|
486 |
-
}
|
487 |
-
|
488 |
-
return 'no';
|
489 |
-
}
|
490 |
-
|
491 |
-
/**
|
492 |
-
* Gets the category slug used for affiliate link (if present).
|
493 |
-
*
|
494 |
-
* @since 3.2.2
|
495 |
-
* @access public
|
496 |
-
*
|
497 |
-
* @return string Affiliate link ategory slug.
|
498 |
-
*/
|
499 |
-
public function get_category_slug() {
|
500 |
-
|
501 |
-
$cat_slug = $this->get_prop( 'category_slug' );
|
502 |
-
return $cat_slug ? $cat_slug : $this->_helper_functions->get_default_category_slug( $this->get_id() , $this->get_prop( 'categories' ) );
|
503 |
-
}
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
/*
|
509 |
-
|--------------------------------------------------------------------------
|
510 |
-
| Data setters
|
511 |
-
|--------------------------------------------------------------------------
|
512 |
-
*/
|
513 |
-
|
514 |
-
/**
|
515 |
-
* Set new value to properties and save it to $changes property.
|
516 |
-
* This stores changes in a special array so we can track what needs to be saved on the DB later.
|
517 |
-
*
|
518 |
-
* @since 3.0.0
|
519 |
-
* @access public
|
520 |
-
*
|
521 |
-
* @param string $prop Data property slug.
|
522 |
-
* @param string $value New property value.
|
523 |
-
*/
|
524 |
-
public function set_prop( $prop , $value ) {
|
525 |
-
|
526 |
-
$default_data = $this->get_merged_default_extended_data();
|
527 |
-
|
528 |
-
if ( array_key_exists( $prop , $this->data ) ) {
|
529 |
-
|
530 |
-
// permalink property must not be changed
|
531 |
-
if ( $prop == 'permalink' )
|
532 |
-
return;
|
533 |
-
|
534 |
-
if ( gettype( $value ) == gettype( $default_data[ $prop ] ) )
|
535 |
-
$this->changes[ $prop ] = $value;
|
536 |
-
else {
|
537 |
-
|
538 |
-
// TODO: handle error here.
|
539 |
-
|
540 |
-
}
|
541 |
-
|
542 |
-
} else {
|
543 |
-
|
544 |
-
$this->data[ $prop ] = $value;
|
545 |
-
$this->changes[ $prop ] = $value;
|
546 |
-
|
547 |
-
}
|
548 |
-
|
549 |
-
}
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
/*
|
555 |
-
|--------------------------------------------------------------------------
|
556 |
-
| Save (Create / Update) data to DB
|
557 |
-
|--------------------------------------------------------------------------
|
558 |
-
*/
|
559 |
-
|
560 |
-
/**
|
561 |
-
* Save data in $changes to the database.
|
562 |
-
*
|
563 |
-
* @since 3.0.0
|
564 |
-
* @access public
|
565 |
-
*
|
566 |
-
* @return WP_Error | int On success will return the post ID, otherwise it will return a WP_Error object.
|
567 |
-
*/
|
568 |
-
public function save() {
|
569 |
-
|
570 |
-
if ( ! empty( $this->changes ) ) {
|
571 |
-
|
572 |
-
$post_metas = array();
|
573 |
-
$post_data = array(
|
574 |
-
'post_title' => $this->get_changed_prop( 'name' ),
|
575 |
-
'post_name' => $this->get_changed_prop( 'slug' ),
|
576 |
-
'post_status' => $this->get_changed_prop( 'status' , 'publish' ),
|
577 |
-
'post_date' => $this->get_changed_prop( 'date_created' , current_time( 'mysql' ) ),
|
578 |
-
'post_modified' => $this->get_changed_prop( 'date_modified' , current_time( 'mysql' ) )
|
579 |
-
);
|
580 |
-
|
581 |
-
foreach ( $this->changes as $prop => $value ) {
|
582 |
-
|
583 |
-
// make sure that property is registered in default data
|
584 |
-
if ( ! array_key_exists( $prop , $this->get_merged_default_extended_data() ) )
|
585 |
-
continue;
|
586 |
-
|
587 |
-
if ( in_array( $prop , array( 'permalink' , 'name' , 'slug' , 'status' , 'date_created' , 'date_modified' ) ) )
|
588 |
-
continue;
|
589 |
-
|
590 |
-
$post_metas[ $prop ] = $value;
|
591 |
-
}
|
592 |
-
|
593 |
-
// create or update post
|
594 |
-
if ( $this->id )
|
595 |
-
$post_id = $this->update( $post_data );
|
596 |
-
else
|
597 |
-
$post_id = $this->create( $post_data );
|
598 |
-
|
599 |
-
if ( ! is_wp_error( $post_id ) )
|
600 |
-
$this->update_metas( $post_id , $post_metas );
|
601 |
-
else
|
602 |
-
return $post_id; // Return WP_Error object on error
|
603 |
-
|
604 |
-
do_action( 'ta_save_affiliate_link' , $this->changes , $this );
|
605 |
-
|
606 |
-
// update instance with new changes.
|
607 |
-
$this->object_is_read = false;
|
608 |
-
$this->read();
|
609 |
-
|
610 |
-
} else
|
611 |
-
return new \WP_Error( 'ta_affiliate_link_no_changes' , __( 'Unable to save affiliate link as there are no changes registered on the object yet.' , 'thirstyaffiliates' ) , array( 'changes' => $this->changes , 'affiliate_link' => $this ) );
|
612 |
-
|
613 |
-
return $post_id;
|
614 |
-
}
|
615 |
-
|
616 |
-
/**
|
617 |
-
* Create the affiliate link post.
|
618 |
-
*
|
619 |
-
* @since 3.0.0
|
620 |
-
* @access private
|
621 |
-
*
|
622 |
-
* @param array $post_data Affiliate link post data.
|
623 |
-
* @param WP_Error|int WP_Error on error, ID of newly created post otherwise.
|
624 |
-
*/
|
625 |
-
private function create( $post_data ) {
|
626 |
-
|
627 |
-
$post_data = array_merge( array( 'post_type' => Plugin_Constants::AFFILIATE_LINKS_CPT ) , $post_data );
|
628 |
-
$this->id = wp_insert_post( $post_data );
|
629 |
-
|
630 |
-
return $this->id;
|
631 |
-
|
632 |
-
}
|
633 |
-
|
634 |
-
/**
|
635 |
-
* Update the affiliate link post.
|
636 |
-
*
|
637 |
-
* @since 3.0.0
|
638 |
-
* @access private
|
639 |
-
*
|
640 |
-
* @param array $post_data Affiliate link post data.
|
641 |
-
* @return int ID of the updated post upon success. 0 on failure.
|
642 |
-
*/
|
643 |
-
private function update( $post_data ) {
|
644 |
-
|
645 |
-
$post_data = array_merge( array( 'ID' => $this->id ) , $post_data );
|
646 |
-
return wp_update_post( $post_data , true );
|
647 |
-
|
648 |
-
}
|
649 |
-
|
650 |
-
/**
|
651 |
-
* Update/add the affiliate link meta data.
|
652 |
-
*
|
653 |
-
* @since 3.0.0
|
654 |
-
* @access private
|
655 |
-
*
|
656 |
-
* @param int $post_id Affiliate link post ID.
|
657 |
-
* @param array $post_metas Affiliate link meta data.
|
658 |
-
*/
|
659 |
-
private function update_metas( $post_id , $post_metas ) {
|
660 |
-
|
661 |
-
foreach ( $post_metas as $key => $value )
|
662 |
-
update_post_meta( $post_id , Plugin_Constants::META_DATA_PREFIX . $key , $value );
|
663 |
-
|
664 |
-
}
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
/*
|
670 |
-
|--------------------------------------------------------------------------
|
671 |
-
| Utility Functions.
|
672 |
-
|--------------------------------------------------------------------------
|
673 |
-
*/
|
674 |
-
|
675 |
-
/**
|
676 |
-
* Conditional function that checks if a property is true for the affiliate link. This function also checks global and category set values.
|
677 |
-
*
|
678 |
-
* @since 3.2.0
|
679 |
-
* @access public
|
680 |
-
*
|
681 |
-
* @param string $toggle_prop Affiliate link toggle property to check.
|
682 |
-
* @return boolean true | false.
|
683 |
-
*/
|
684 |
-
public function is( $toggle_prop ) {
|
685 |
-
|
686 |
-
// check if global setting for uncloak link is enabled.
|
687 |
-
if ( $toggle_prop == 'uncloak_link' && get_option( 'ta_uncloak_link_per_link' ) !== 'yes' )
|
688 |
-
return;
|
689 |
-
|
690 |
-
$prop_value = $this->get_prop( $toggle_prop );
|
691 |
-
|
692 |
-
// if prop value is not set to 'global', then return with the boolean equivalent of its value.
|
693 |
-
if ( $prop_value != 'global' )
|
694 |
-
return $prop_value == 'yes' ? true : false;
|
695 |
-
|
696 |
-
// get property global value. Also checks for category selected options.
|
697 |
-
$prop_value = $this->get_toggle_prop_global_value( $toggle_prop );
|
698 |
-
|
699 |
-
return $prop_value == 'yes' ? true : false;
|
700 |
-
}
|
701 |
-
|
702 |
-
/**
|
703 |
-
* Count affiliate link clicks.
|
704 |
-
*
|
705 |
-
* @since 3.0.0
|
706 |
-
* @since 3.1.0 Add $date_offset parameter to count links only to a certain point.
|
707 |
-
* @access public
|
708 |
-
*
|
709 |
-
* @param string $date_offset Date before limit to check
|
710 |
-
* @return int Total number of clicks.
|
711 |
-
*/
|
712 |
-
public function count_clicks( $date_offset = '' ) {
|
713 |
-
|
714 |
-
global $wpdb;
|
715 |
-
|
716 |
-
$table_name = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
717 |
-
$link_id = $this->get_id();
|
718 |
-
$query = "SELECT count(*) from $table_name WHERE link_id = $link_id";
|
719 |
-
$query .= ( $date_offset && \DateTime::createFromFormat('Y-m-d H:i:s', $date_offset ) !== false ) ? " AND date_clicked > '$date_offset'" : '';
|
720 |
-
$clicks = $wpdb->get_var( $query );
|
721 |
-
|
722 |
-
return (int) $clicks;
|
723 |
-
}
|
724 |
-
|
725 |
-
/**
|
726 |
-
* Scan where links are inserted.
|
727 |
-
*
|
728 |
-
* @since 3.2.0
|
729 |
-
* @since 3.3.3 Improve the query to specify the results by searching using the permalink value, and alternating between the used link prefixes.
|
730 |
-
* @access public
|
731 |
-
*
|
732 |
-
* @return array List of WP_Post IDs where affiliate link is inserted in content.
|
733 |
-
*/
|
734 |
-
public function scan_where_links_inserted() {
|
735 |
-
|
736 |
-
global $wpdb;
|
737 |
-
|
738 |
-
// prepare the query.
|
739 |
-
$post_ids = array();
|
740 |
-
$link_id = $this->get_id();
|
741 |
-
$cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
|
742 |
-
$types = get_post_types( array( 'public' => true ) , 'names' , 'and' );
|
743 |
-
$types_str = implode( "','" , $types );
|
744 |
-
$permalink = $this->get_prop( 'permalink' );
|
745 |
-
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
746 |
-
$link_prefixes = $this->_helper_functions->get_option( 'ta_used_link_prefixes' , array() );
|
747 |
-
$like_query = array();
|
748 |
-
|
749 |
-
foreach ( $link_prefixes as $prefix )
|
750 |
-
$like_query[] = str_replace( $link_prefix , $prefix , "post_content LIKE '%$permalink\"%'" );
|
751 |
-
|
752 |
-
$like_query_str = implode( ' OR ' , $like_query );
|
753 |
-
$query = "SELECT ID FROM $wpdb->posts WHERE ( $like_query_str OR post_content LIKE '%[thirstylink%ids=\"$link_id%' ) AND post_type IN ( '$types_str' ) AND post_status = 'publish'";
|
754 |
-
|
755 |
-
// fetch WP_Post IDs where link is inserted to.
|
756 |
-
$raw_ids = $wpdb->get_col( $query );
|
757 |
-
|
758 |
-
// save last scanned
|
759 |
-
update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , current_time( 'mysql' , true ) );
|
760 |
-
|
761 |
-
// save to custom meta.
|
762 |
-
$post_ids = array_map( 'intval' , $raw_ids );
|
763 |
-
update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'inserted_to' , $post_ids );
|
764 |
-
|
765 |
-
return $post_ids;
|
766 |
-
}
|
767 |
-
|
768 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
+
|
9 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
10 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Model that houses the data model of an affiliate link.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Affiliate_Link {
|
18 |
+
|
19 |
+
|
20 |
+
/*
|
21 |
+
|--------------------------------------------------------------------------
|
22 |
+
| Class Properties
|
23 |
+
|--------------------------------------------------------------------------
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Model that houses the main plugin object.
|
28 |
+
*
|
29 |
+
* @since 3.0.0
|
30 |
+
* @access private
|
31 |
+
* @var Abstract_Main_Plugin_Class
|
32 |
+
*/
|
33 |
+
private $_main_plugin;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Model that houses all the plugin constants.
|
37 |
+
*
|
38 |
+
* @since 3.0.0
|
39 |
+
* @access private
|
40 |
+
* @var Plugin_Constants
|
41 |
+
*/
|
42 |
+
private $_constants;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Property that houses all the helper functions of the plugin.
|
46 |
+
*
|
47 |
+
* @since 3.0.0
|
48 |
+
* @access private
|
49 |
+
* @var Helper_Functions
|
50 |
+
*/
|
51 |
+
private $_helper_functions;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Stores affiliate link ID.
|
55 |
+
*
|
56 |
+
* @since 3.0.0
|
57 |
+
* @access protected
|
58 |
+
* @var array
|
59 |
+
*/
|
60 |
+
protected $id;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Stores affiliate link data.
|
64 |
+
*
|
65 |
+
* @since 3.0.0
|
66 |
+
* @access protected
|
67 |
+
* @var array
|
68 |
+
*/
|
69 |
+
protected $data = array();
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Stores affiliate link default data.
|
73 |
+
*
|
74 |
+
* @since 3.0.0
|
75 |
+
* @access protected
|
76 |
+
* @var array
|
77 |
+
*/
|
78 |
+
protected $default_data = array(
|
79 |
+
'name' => '',
|
80 |
+
'slug' => '',
|
81 |
+
'date_created' => '',
|
82 |
+
'date_modified' => '',
|
83 |
+
'status' => '',
|
84 |
+
'permalink' => '',
|
85 |
+
'destination_url' => '',
|
86 |
+
'rel_tags' => '',
|
87 |
+
'css_classes' => '',
|
88 |
+
'redirect_type' => 'global',
|
89 |
+
'no_follow' => 'global',
|
90 |
+
'new_window' => 'global',
|
91 |
+
'uncloak_link' => 'global',
|
92 |
+
'pass_query_str' => 'global',
|
93 |
+
'image_ids' => array(),
|
94 |
+
'categories' => array(),
|
95 |
+
'category_slug' => '',
|
96 |
+
'category_slug_id' => 0,
|
97 |
+
'inserted_to' => array(),
|
98 |
+
'scanned_inserted' => ''
|
99 |
+
);
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Stores affiliate link default data.
|
103 |
+
*
|
104 |
+
* @since 3.0.0
|
105 |
+
* @access protected
|
106 |
+
* @var array
|
107 |
+
*/
|
108 |
+
protected $extend_data = array();
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Stores affiliate link post data.
|
112 |
+
*
|
113 |
+
* @since 3.0.0
|
114 |
+
* @access private
|
115 |
+
* @var object
|
116 |
+
*/
|
117 |
+
protected $post_data;
|
118 |
+
|
119 |
+
/**
|
120 |
+
* This is where changes to the $data will be saved.
|
121 |
+
*
|
122 |
+
* @since 3.0.0
|
123 |
+
* @access protected
|
124 |
+
* @var object
|
125 |
+
*/
|
126 |
+
protected $changes = array();
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Stores boolean if the data has been read from the database or not.
|
130 |
+
*
|
131 |
+
* @since 3.0.0
|
132 |
+
* @access protected
|
133 |
+
* @var object
|
134 |
+
*/
|
135 |
+
protected $object_is_read = false;
|
136 |
+
|
137 |
+
/**
|
138 |
+
* List of deprecated properties.
|
139 |
+
*
|
140 |
+
* @since 3.3.1
|
141 |
+
* @access protected
|
142 |
+
* @var array
|
143 |
+
*/
|
144 |
+
protected $deprecated_props = array(
|
145 |
+
'link_health_issue',
|
146 |
+
'link_health_issue_ignored'
|
147 |
+
);
|
148 |
+
|
149 |
+
|
150 |
+
|
151 |
+
|
152 |
+
/*
|
153 |
+
|--------------------------------------------------------------------------
|
154 |
+
| Class Methods
|
155 |
+
|--------------------------------------------------------------------------
|
156 |
+
*/
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Class constructor.
|
160 |
+
*
|
161 |
+
* @since 3.0.0
|
162 |
+
* @access public
|
163 |
+
*
|
164 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
165 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
166 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
167 |
+
*/
|
168 |
+
public function __construct( $id = null ) {
|
169 |
+
|
170 |
+
$this->_constants = ThirstyAffiliates()->helpers[ 'Plugin_Constants' ];
|
171 |
+
$this->_helper_functions = ThirstyAffiliates()->helpers[ 'Helper_Functions' ];
|
172 |
+
$this->deprecated_props = apply_filters( 'ta_affiliate_link_deprecated_props' , $this->deprecated_props );
|
173 |
+
|
174 |
+
if ( filter_var( $id , FILTER_VALIDATE_INT ) && $id ) {
|
175 |
+
|
176 |
+
$this->extend_data = apply_filters( 'ta_affiliate_link_extended_data' , $this->extend_data , $this->default_data );
|
177 |
+
$this->data = $this->get_merged_default_extended_data();
|
178 |
+
$this->id = absint( $id );
|
179 |
+
|
180 |
+
$this->read();
|
181 |
+
|
182 |
+
}
|
183 |
+
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Read data from DB and save on instance.
|
188 |
+
*
|
189 |
+
* @since 3.0.0
|
190 |
+
* @since 3.2.2 Optimize method by lessening the metadata fetch into one single function call.
|
191 |
+
* @access public
|
192 |
+
*/
|
193 |
+
private function read() {
|
194 |
+
|
195 |
+
$this->post_data = get_post( $this->id );
|
196 |
+
|
197 |
+
if ( ! is_a( $this->post_data , 'WP_Post' ) || $this->object_is_read )
|
198 |
+
return;
|
199 |
+
|
200 |
+
$this->id = $this->post_data->ID; // set the affiliate link ID
|
201 |
+
$meta_data = get_metadata( 'post' , $this->id );
|
202 |
+
$default_data = $this->get_merged_default_extended_data();
|
203 |
+
|
204 |
+
foreach ( $default_data as $prop => $value ) {
|
205 |
+
|
206 |
+
// fetch raw meta data if present.
|
207 |
+
$raw_data = isset( $meta_data[ Plugin_Constants::META_DATA_PREFIX . $prop ] ) ? maybe_unserialize( $meta_data[ Plugin_Constants::META_DATA_PREFIX . $prop ][0] ) : '';
|
208 |
+
|
209 |
+
switch ( $prop ) {
|
210 |
+
|
211 |
+
case 'name' :
|
212 |
+
case 'slug' :
|
213 |
+
case 'status' :
|
214 |
+
case 'date_created' :
|
215 |
+
case 'permalink' :
|
216 |
+
$this->data[ $prop ] = $this->get_post_data_equivalent( $prop );
|
217 |
+
break;
|
218 |
+
|
219 |
+
case 'no_follow' :
|
220 |
+
case 'new_window' :
|
221 |
+
case 'pass_query_str' :
|
222 |
+
case 'uncloak_link' :
|
223 |
+
case 'redirect_type' :
|
224 |
+
$this->data[ $prop ] = ! empty( $raw_data ) ? $raw_data : $default_data[ $prop ];
|
225 |
+
break;
|
226 |
+
|
227 |
+
case 'rel_tags' :
|
228 |
+
case 'css_classes' :
|
229 |
+
$this->data[ $prop ] = ! empty( $raw_data ) ? $raw_data : $this->get_prop_global_option_value( $prop );
|
230 |
+
break;
|
231 |
+
|
232 |
+
case 'image_ids' :
|
233 |
+
case 'inserted_to' :
|
234 |
+
$this->data[ $prop ] = ( is_array( $raw_data ) && ! empty( $raw_data ) ) ? $raw_data : $default_data[ $prop ];
|
235 |
+
break;
|
236 |
+
|
237 |
+
case 'categories' :
|
238 |
+
$categories = wp_get_post_terms( $this->id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
239 |
+
$this->data[ $prop ] = ! empty( $categories ) ? $categories : $default_data[ $prop ];
|
240 |
+
break;
|
241 |
+
|
242 |
+
default :
|
243 |
+
$this->data[ $prop ] = apply_filters( 'ta_read_thirstylink_property' , $raw_data , $prop , $default_data , $this->id , $meta_data );
|
244 |
+
break;
|
245 |
+
|
246 |
+
}
|
247 |
+
|
248 |
+
}
|
249 |
+
|
250 |
+
$this->object_is_read = true;
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
|
255 |
+
|
256 |
+
|
257 |
+
/*
|
258 |
+
|--------------------------------------------------------------------------
|
259 |
+
| Data getters
|
260 |
+
|--------------------------------------------------------------------------
|
261 |
+
*/
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Get merged $default_data and $extended_data class properties.
|
265 |
+
*
|
266 |
+
* @since 3.0.0
|
267 |
+
* @access public
|
268 |
+
*
|
269 |
+
* @return array Data properties.
|
270 |
+
*/
|
271 |
+
private function get_merged_default_extended_data() {
|
272 |
+
|
273 |
+
return array_merge( $this->default_data , $this->extend_data );
|
274 |
+
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Return's the post data equivalent of a certain affiliate link data property.
|
279 |
+
*
|
280 |
+
* @since 3.0.0
|
281 |
+
* @access private
|
282 |
+
*
|
283 |
+
* @param string $prop Affiliate link property name.
|
284 |
+
* @return string WP Post property equivalent.
|
285 |
+
*/
|
286 |
+
private function get_post_data_equivalent( $prop ) {
|
287 |
+
|
288 |
+
$equivalents = apply_filters( 'ta_affiliate_link_post_data_equivalent' , array(
|
289 |
+
'name' => $this->post_data->post_title,
|
290 |
+
'slug' => $this->post_data->post_name,
|
291 |
+
'permalink' => get_permalink( $this->post_data->ID ),
|
292 |
+
'status' => $this->post_data->post_status,
|
293 |
+
'date_created' => $this->post_data->post_date,
|
294 |
+
'date_modified' => $this->post_data->post_modified,
|
295 |
+
) , $this->post_data );
|
296 |
+
|
297 |
+
if ( array_key_exists( $prop , $equivalents ) )
|
298 |
+
return $equivalents[ $prop ];
|
299 |
+
else
|
300 |
+
return;
|
301 |
+
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Return data property.
|
306 |
+
*
|
307 |
+
* @since 3.0.0
|
308 |
+
* @since 3.3.1 Make sure deprecated props are ignored.
|
309 |
+
* @access public
|
310 |
+
*
|
311 |
+
* @param string $prop Data property slug.
|
312 |
+
* @param mixed $default Set property default value (optional).
|
313 |
+
* @return mixed Property data.
|
314 |
+
*/
|
315 |
+
public function get_prop( $prop , $default = '' ) {
|
316 |
+
|
317 |
+
$default_data = $this->get_merged_default_extended_data();
|
318 |
+
|
319 |
+
if ( in_array( $prop , $this->deprecated_props ) )
|
320 |
+
return $default;
|
321 |
+
|
322 |
+
if ( array_key_exists( $prop , $this->data ) && $this->data[ $prop ] )
|
323 |
+
$return_value = $this->data[ $prop ];
|
324 |
+
else
|
325 |
+
$return_value = ( $default ) ? $default : $default_data[ $prop ];
|
326 |
+
|
327 |
+
return $return_value;
|
328 |
+
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Get redirect type
|
333 |
+
*
|
334 |
+
* @since 3.4.0
|
335 |
+
* @access public
|
336 |
+
*
|
337 |
+
* @param string $default Default redirect type.
|
338 |
+
* @return string Redirect type.
|
339 |
+
*/
|
340 |
+
public function get_redirect_type( $default = '' ) {
|
341 |
+
|
342 |
+
$redirect_type = $this->data[ 'redirect_type' ];
|
343 |
+
|
344 |
+
if ( $redirect_type === 'global' )
|
345 |
+
$redirect_type = get_option( 'ta_link_redirect_type' , $default );
|
346 |
+
elseif ( ! $redirect_type )
|
347 |
+
$redirect_type = $default ? $default : $default_data[ 'redirect_type' ];
|
348 |
+
|
349 |
+
return $redirect_type;
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Return Affiliate_Link ID.
|
354 |
+
*
|
355 |
+
* @since 3.0.0
|
356 |
+
* @access public
|
357 |
+
*
|
358 |
+
* @return int Affiliate_Link ID.
|
359 |
+
*/
|
360 |
+
public function get_id() {
|
361 |
+
|
362 |
+
return absint( $this->id );
|
363 |
+
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Return changed data property.
|
368 |
+
*
|
369 |
+
* @since 3.0.0
|
370 |
+
* @access public
|
371 |
+
*
|
372 |
+
* @param string $prop Data property slug.
|
373 |
+
* @param mixed $default Set property default value (optional).
|
374 |
+
* @return mixed Property data.
|
375 |
+
*/
|
376 |
+
public function get_changed_prop( $prop , $default = '' ) {
|
377 |
+
|
378 |
+
return isset( $this->changes[ $prop ] ) ? $this->changes[ $prop ] : $this->get_prop( $prop , $default );
|
379 |
+
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* Return affiliate link's WP_Post data.
|
384 |
+
*
|
385 |
+
* @since 3.0.0
|
386 |
+
* @access public
|
387 |
+
*
|
388 |
+
* @return object Post data object.
|
389 |
+
*/
|
390 |
+
public function get_post_data() {
|
391 |
+
|
392 |
+
return $this->post_data;
|
393 |
+
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Get the properties global option value.
|
398 |
+
*
|
399 |
+
* @since 3.0.0
|
400 |
+
* @since 3.2.2 Remove 'uncloak' option.
|
401 |
+
* @since 3.4.0 Remove 'redirect_type' option. Add additional CSS classes option.
|
402 |
+
* @access public
|
403 |
+
*
|
404 |
+
* @param string $prop Name of property.
|
405 |
+
* @return string Global option value.
|
406 |
+
*/
|
407 |
+
public function get_prop_global_option_value( $prop , $default = '' ) {
|
408 |
+
|
409 |
+
switch( $prop ) {
|
410 |
+
|
411 |
+
case 'rel_tags' :
|
412 |
+
$option = 'ta_additional_rel_tags';
|
413 |
+
break;
|
414 |
+
|
415 |
+
case 'css_classes' :
|
416 |
+
$option = 'ta_additional_css_classes';
|
417 |
+
break;
|
418 |
+
}
|
419 |
+
|
420 |
+
return $option ? get_option( $option , $default ) : $default;
|
421 |
+
}
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Get the global value for the uncloak property.
|
425 |
+
*
|
426 |
+
* @deprecated 3.2.0
|
427 |
+
*
|
428 |
+
* @since 3.0.0
|
429 |
+
* @access public
|
430 |
+
*
|
431 |
+
* @return string Global option value.
|
432 |
+
*/
|
433 |
+
public function get_global_uncloak_value() {
|
434 |
+
|
435 |
+
return $this->get_toggle_prop_global_value( 'uncloak_link' );
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Get toggle property global value. This function also checks for "category" valued options.
|
440 |
+
*
|
441 |
+
* @since 3.2.0
|
442 |
+
* @access public
|
443 |
+
*
|
444 |
+
* @param string $toggle_prop Affiliate linkg toggle property name.
|
445 |
+
* @return string 'yes' if true, otherwise 'no'.
|
446 |
+
*/
|
447 |
+
public function get_toggle_prop_global_value( $toggle_prop ) {
|
448 |
+
|
449 |
+
$global_props = apply_filters( 'ta_props_with_global_option' , array(
|
450 |
+
'no_follow' => 'ta_no_follow',
|
451 |
+
'new_window' => 'ta_new_window',
|
452 |
+
'uncloak_link' => '',
|
453 |
+
'pass_query_str' => 'ta_pass_query_str'
|
454 |
+
) );
|
455 |
+
$global_props_cat = apply_filters( 'ta_prop_selected_categories_option' , array(
|
456 |
+
'no_follow' => 'ta_no_follow_category',
|
457 |
+
'new_window' => 'ta_new_window_category',
|
458 |
+
'uncloak_link' => 'ta_category_to_uncloak',
|
459 |
+
'pass_query_str' => 'ta_pass_query_str_category'
|
460 |
+
) );
|
461 |
+
|
462 |
+
if ( ! array_key_exists( $toggle_prop , $global_props ) )
|
463 |
+
return 'no';
|
464 |
+
|
465 |
+
// get equivalent global value.
|
466 |
+
$prop_value = $toggle_prop == 'uncloak_link' ? 'category' : get_option( $global_props[ $toggle_prop ] );
|
467 |
+
|
468 |
+
if ( ! $prop_value )
|
469 |
+
return 'no';
|
470 |
+
|
471 |
+
// if prop value is not set to 'category', then return option value.
|
472 |
+
if ( $prop_value != 'category' || ! array_key_exists( $toggle_prop , $global_props_cat ) )
|
473 |
+
return $prop_value;
|
474 |
+
|
475 |
+
$prop_cats = maybe_unserialize( get_option( $global_props_cat[ $toggle_prop ] , array() ) );
|
476 |
+
$link_cats = $this->get_prop( 'categories' );
|
477 |
+
|
478 |
+
// skip when there are no categories to check (false)
|
479 |
+
if ( ! is_array( $prop_cats ) || empty( $prop_cats ) || empty( $link_cats ) )
|
480 |
+
return 'no';
|
481 |
+
|
482 |
+
foreach ( $link_cats as $category ) {
|
483 |
+
|
484 |
+
if ( in_array( $category->term_id , $prop_cats ) )
|
485 |
+
return 'yes';
|
486 |
+
}
|
487 |
+
|
488 |
+
return 'no';
|
489 |
+
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Gets the category slug used for affiliate link (if present).
|
493 |
+
*
|
494 |
+
* @since 3.2.2
|
495 |
+
* @access public
|
496 |
+
*
|
497 |
+
* @return string Affiliate link ategory slug.
|
498 |
+
*/
|
499 |
+
public function get_category_slug() {
|
500 |
+
|
501 |
+
$cat_slug = $this->get_prop( 'category_slug' );
|
502 |
+
return $cat_slug ? $cat_slug : $this->_helper_functions->get_default_category_slug( $this->get_id() , $this->get_prop( 'categories' ) );
|
503 |
+
}
|
504 |
+
|
505 |
+
|
506 |
+
|
507 |
+
|
508 |
+
/*
|
509 |
+
|--------------------------------------------------------------------------
|
510 |
+
| Data setters
|
511 |
+
|--------------------------------------------------------------------------
|
512 |
+
*/
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Set new value to properties and save it to $changes property.
|
516 |
+
* This stores changes in a special array so we can track what needs to be saved on the DB later.
|
517 |
+
*
|
518 |
+
* @since 3.0.0
|
519 |
+
* @access public
|
520 |
+
*
|
521 |
+
* @param string $prop Data property slug.
|
522 |
+
* @param string $value New property value.
|
523 |
+
*/
|
524 |
+
public function set_prop( $prop , $value ) {
|
525 |
+
|
526 |
+
$default_data = $this->get_merged_default_extended_data();
|
527 |
+
|
528 |
+
if ( array_key_exists( $prop , $this->data ) ) {
|
529 |
+
|
530 |
+
// permalink property must not be changed
|
531 |
+
if ( $prop == 'permalink' )
|
532 |
+
return;
|
533 |
+
|
534 |
+
if ( gettype( $value ) == gettype( $default_data[ $prop ] ) )
|
535 |
+
$this->changes[ $prop ] = $value;
|
536 |
+
else {
|
537 |
+
|
538 |
+
// TODO: handle error here.
|
539 |
+
|
540 |
+
}
|
541 |
+
|
542 |
+
} else {
|
543 |
+
|
544 |
+
$this->data[ $prop ] = $value;
|
545 |
+
$this->changes[ $prop ] = $value;
|
546 |
+
|
547 |
+
}
|
548 |
+
|
549 |
+
}
|
550 |
+
|
551 |
+
|
552 |
+
|
553 |
+
|
554 |
+
/*
|
555 |
+
|--------------------------------------------------------------------------
|
556 |
+
| Save (Create / Update) data to DB
|
557 |
+
|--------------------------------------------------------------------------
|
558 |
+
*/
|
559 |
+
|
560 |
+
/**
|
561 |
+
* Save data in $changes to the database.
|
562 |
+
*
|
563 |
+
* @since 3.0.0
|
564 |
+
* @access public
|
565 |
+
*
|
566 |
+
* @return WP_Error | int On success will return the post ID, otherwise it will return a WP_Error object.
|
567 |
+
*/
|
568 |
+
public function save() {
|
569 |
+
|
570 |
+
if ( ! empty( $this->changes ) ) {
|
571 |
+
|
572 |
+
$post_metas = array();
|
573 |
+
$post_data = array(
|
574 |
+
'post_title' => $this->get_changed_prop( 'name' ),
|
575 |
+
'post_name' => $this->get_changed_prop( 'slug' ),
|
576 |
+
'post_status' => $this->get_changed_prop( 'status' , 'publish' ),
|
577 |
+
'post_date' => $this->get_changed_prop( 'date_created' , current_time( 'mysql' ) ),
|
578 |
+
'post_modified' => $this->get_changed_prop( 'date_modified' , current_time( 'mysql' ) )
|
579 |
+
);
|
580 |
+
|
581 |
+
foreach ( $this->changes as $prop => $value ) {
|
582 |
+
|
583 |
+
// make sure that property is registered in default data
|
584 |
+
if ( ! array_key_exists( $prop , $this->get_merged_default_extended_data() ) )
|
585 |
+
continue;
|
586 |
+
|
587 |
+
if ( in_array( $prop , array( 'permalink' , 'name' , 'slug' , 'status' , 'date_created' , 'date_modified' ) ) )
|
588 |
+
continue;
|
589 |
+
|
590 |
+
$post_metas[ $prop ] = $value;
|
591 |
+
}
|
592 |
+
|
593 |
+
// create or update post
|
594 |
+
if ( $this->id )
|
595 |
+
$post_id = $this->update( $post_data );
|
596 |
+
else
|
597 |
+
$post_id = $this->create( $post_data );
|
598 |
+
|
599 |
+
if ( ! is_wp_error( $post_id ) )
|
600 |
+
$this->update_metas( $post_id , $post_metas );
|
601 |
+
else
|
602 |
+
return $post_id; // Return WP_Error object on error
|
603 |
+
|
604 |
+
do_action( 'ta_save_affiliate_link' , $this->changes , $this );
|
605 |
+
|
606 |
+
// update instance with new changes.
|
607 |
+
$this->object_is_read = false;
|
608 |
+
$this->read();
|
609 |
+
|
610 |
+
} else
|
611 |
+
return new \WP_Error( 'ta_affiliate_link_no_changes' , __( 'Unable to save affiliate link as there are no changes registered on the object yet.' , 'thirstyaffiliates' ) , array( 'changes' => $this->changes , 'affiliate_link' => $this ) );
|
612 |
+
|
613 |
+
return $post_id;
|
614 |
+
}
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Create the affiliate link post.
|
618 |
+
*
|
619 |
+
* @since 3.0.0
|
620 |
+
* @access private
|
621 |
+
*
|
622 |
+
* @param array $post_data Affiliate link post data.
|
623 |
+
* @param WP_Error|int WP_Error on error, ID of newly created post otherwise.
|
624 |
+
*/
|
625 |
+
private function create( $post_data ) {
|
626 |
+
|
627 |
+
$post_data = array_merge( array( 'post_type' => Plugin_Constants::AFFILIATE_LINKS_CPT ) , $post_data );
|
628 |
+
$this->id = wp_insert_post( $post_data );
|
629 |
+
|
630 |
+
return $this->id;
|
631 |
+
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Update the affiliate link post.
|
636 |
+
*
|
637 |
+
* @since 3.0.0
|
638 |
+
* @access private
|
639 |
+
*
|
640 |
+
* @param array $post_data Affiliate link post data.
|
641 |
+
* @return int ID of the updated post upon success. 0 on failure.
|
642 |
+
*/
|
643 |
+
private function update( $post_data ) {
|
644 |
+
|
645 |
+
$post_data = array_merge( array( 'ID' => $this->id ) , $post_data );
|
646 |
+
return wp_update_post( $post_data , true );
|
647 |
+
|
648 |
+
}
|
649 |
+
|
650 |
+
/**
|
651 |
+
* Update/add the affiliate link meta data.
|
652 |
+
*
|
653 |
+
* @since 3.0.0
|
654 |
+
* @access private
|
655 |
+
*
|
656 |
+
* @param int $post_id Affiliate link post ID.
|
657 |
+
* @param array $post_metas Affiliate link meta data.
|
658 |
+
*/
|
659 |
+
private function update_metas( $post_id , $post_metas ) {
|
660 |
+
|
661 |
+
foreach ( $post_metas as $key => $value )
|
662 |
+
update_post_meta( $post_id , Plugin_Constants::META_DATA_PREFIX . $key , $value );
|
663 |
+
|
664 |
+
}
|
665 |
+
|
666 |
+
|
667 |
+
|
668 |
+
|
669 |
+
/*
|
670 |
+
|--------------------------------------------------------------------------
|
671 |
+
| Utility Functions.
|
672 |
+
|--------------------------------------------------------------------------
|
673 |
+
*/
|
674 |
+
|
675 |
+
/**
|
676 |
+
* Conditional function that checks if a property is true for the affiliate link. This function also checks global and category set values.
|
677 |
+
*
|
678 |
+
* @since 3.2.0
|
679 |
+
* @access public
|
680 |
+
*
|
681 |
+
* @param string $toggle_prop Affiliate link toggle property to check.
|
682 |
+
* @return boolean true | false.
|
683 |
+
*/
|
684 |
+
public function is( $toggle_prop ) {
|
685 |
+
|
686 |
+
// check if global setting for uncloak link is enabled.
|
687 |
+
if ( $toggle_prop == 'uncloak_link' && get_option( 'ta_uncloak_link_per_link' ) !== 'yes' )
|
688 |
+
return;
|
689 |
+
|
690 |
+
$prop_value = $this->get_prop( $toggle_prop );
|
691 |
+
|
692 |
+
// if prop value is not set to 'global', then return with the boolean equivalent of its value.
|
693 |
+
if ( $prop_value != 'global' )
|
694 |
+
return $prop_value == 'yes' ? true : false;
|
695 |
+
|
696 |
+
// get property global value. Also checks for category selected options.
|
697 |
+
$prop_value = $this->get_toggle_prop_global_value( $toggle_prop );
|
698 |
+
|
699 |
+
return $prop_value == 'yes' ? true : false;
|
700 |
+
}
|
701 |
+
|
702 |
+
/**
|
703 |
+
* Count affiliate link clicks.
|
704 |
+
*
|
705 |
+
* @since 3.0.0
|
706 |
+
* @since 3.1.0 Add $date_offset parameter to count links only to a certain point.
|
707 |
+
* @access public
|
708 |
+
*
|
709 |
+
* @param string $date_offset Date before limit to check
|
710 |
+
* @return int Total number of clicks.
|
711 |
+
*/
|
712 |
+
public function count_clicks( $date_offset = '' ) {
|
713 |
+
|
714 |
+
global $wpdb;
|
715 |
+
|
716 |
+
$table_name = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
717 |
+
$link_id = $this->get_id();
|
718 |
+
$query = "SELECT count(*) from $table_name WHERE link_id = $link_id";
|
719 |
+
$query .= ( $date_offset && \DateTime::createFromFormat('Y-m-d H:i:s', $date_offset ) !== false ) ? " AND date_clicked > '$date_offset'" : '';
|
720 |
+
$clicks = $wpdb->get_var( $query );
|
721 |
+
|
722 |
+
return (int) $clicks;
|
723 |
+
}
|
724 |
+
|
725 |
+
/**
|
726 |
+
* Scan where links are inserted.
|
727 |
+
*
|
728 |
+
* @since 3.2.0
|
729 |
+
* @since 3.3.3 Improve the query to specify the results by searching using the permalink value, and alternating between the used link prefixes.
|
730 |
+
* @access public
|
731 |
+
*
|
732 |
+
* @return array List of WP_Post IDs where affiliate link is inserted in content.
|
733 |
+
*/
|
734 |
+
public function scan_where_links_inserted() {
|
735 |
+
|
736 |
+
global $wpdb;
|
737 |
+
|
738 |
+
// prepare the query.
|
739 |
+
$post_ids = array();
|
740 |
+
$link_id = $this->get_id();
|
741 |
+
$cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
|
742 |
+
$types = get_post_types( array( 'public' => true ) , 'names' , 'and' );
|
743 |
+
$types_str = implode( "','" , $types );
|
744 |
+
$permalink = $this->get_prop( 'permalink' );
|
745 |
+
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
746 |
+
$link_prefixes = $this->_helper_functions->get_option( 'ta_used_link_prefixes' , array() );
|
747 |
+
$like_query = array();
|
748 |
+
|
749 |
+
foreach ( $link_prefixes as $prefix )
|
750 |
+
$like_query[] = str_replace( $link_prefix , $prefix , "post_content LIKE '%$permalink\"%'" );
|
751 |
+
|
752 |
+
$like_query_str = implode( ' OR ' , $like_query );
|
753 |
+
$query = "SELECT ID FROM $wpdb->posts WHERE ( $like_query_str OR post_content LIKE '%[thirstylink%ids=\"$link_id%' ) AND post_type IN ( '$types_str' ) AND post_status = 'publish'";
|
754 |
+
|
755 |
+
// fetch WP_Post IDs where link is inserted to.
|
756 |
+
$raw_ids = $wpdb->get_col( $query );
|
757 |
+
|
758 |
+
// save last scanned
|
759 |
+
update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , current_time( 'mysql' , true ) );
|
760 |
+
|
761 |
+
// save to custom meta.
|
762 |
+
$post_ids = array_map( 'intval' , $raw_ids );
|
763 |
+
update_post_meta( $this->get_id() , Plugin_Constants::META_DATA_PREFIX . 'inserted_to' , $post_ids );
|
764 |
+
|
765 |
+
return $post_ids;
|
766 |
+
}
|
767 |
+
|
768 |
+
}
|
Models/Affiliate_Links_CPT.php
CHANGED
@@ -1,1014 +1,1014 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
-
|
10 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
-
|
13 |
-
// Data Models
|
14 |
-
use ThirstyAffiliates\Models\Affiliate_Link;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Model that houses the logic of registering the 'thirstylink' custom post type.
|
18 |
-
*
|
19 |
-
* @since 3.0.0
|
20 |
-
*/
|
21 |
-
class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
|
22 |
-
|
23 |
-
/*
|
24 |
-
|--------------------------------------------------------------------------
|
25 |
-
| Class Properties
|
26 |
-
|--------------------------------------------------------------------------
|
27 |
-
*/
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Property that holds the single main instance of Bootstrap.
|
31 |
-
*
|
32 |
-
* @since 3.0.0
|
33 |
-
* @access private
|
34 |
-
* @var Affiliate_Links_CPT
|
35 |
-
*/
|
36 |
-
private static $_instance;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Model that houses the main plugin object.
|
40 |
-
*
|
41 |
-
* @since 3.0.0
|
42 |
-
* @access private
|
43 |
-
* @var Abstract_Main_Plugin_Class
|
44 |
-
*/
|
45 |
-
private $_main_plugin;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Model that houses all the plugin constants.
|
49 |
-
*
|
50 |
-
* @since 3.0.0
|
51 |
-
* @access private
|
52 |
-
* @var Plugin_Constants
|
53 |
-
*/
|
54 |
-
private $_constants;
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Property that houses all the helper functions of the plugin.
|
58 |
-
*
|
59 |
-
* @since 3.0.0
|
60 |
-
* @access private
|
61 |
-
* @var Helper_Functions
|
62 |
-
*/
|
63 |
-
private $_helper_functions;
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Property that holds the currently loaded thirstylink post.
|
67 |
-
*
|
68 |
-
* @since 3.0.0
|
69 |
-
* @access private
|
70 |
-
*/
|
71 |
-
private $_thirstylink;
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
/*
|
77 |
-
|--------------------------------------------------------------------------
|
78 |
-
| Class Methods
|
79 |
-
|--------------------------------------------------------------------------
|
80 |
-
*/
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Class constructor.
|
84 |
-
*
|
85 |
-
* @since 3.0.0
|
86 |
-
* @access public
|
87 |
-
*
|
88 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
89 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
90 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
91 |
-
*/
|
92 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
93 |
-
|
94 |
-
$this->_constants = $constants;
|
95 |
-
$this->_helper_functions = $helper_functions;
|
96 |
-
|
97 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
98 |
-
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
103 |
-
*
|
104 |
-
* @since 3.0.0
|
105 |
-
* @access public
|
106 |
-
*
|
107 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
108 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
109 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
110 |
-
* @return Affiliate_Links_CPT
|
111 |
-
*/
|
112 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
113 |
-
|
114 |
-
if ( !self::$_instance instanceof self )
|
115 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
116 |
-
|
117 |
-
return self::$_instance;
|
118 |
-
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Register admin interfaces.
|
123 |
-
*
|
124 |
-
* @since 3.3.3
|
125 |
-
* @access public
|
126 |
-
*
|
127 |
-
* @param array $interfaces List of admin interfaces.
|
128 |
-
* @return array Filtered list of admin interfaces.
|
129 |
-
*/
|
130 |
-
public function register_admin_interfaces( $interfaces ) {
|
131 |
-
|
132 |
-
$interfaces[ 'edit-thirstylink' ] = 'edit_posts';
|
133 |
-
$interfaces[ 'thirstylink' ] = 'edit_posts';
|
134 |
-
$interfaces[ 'edit-thirstylink-category' ] = 'manage_categories';
|
135 |
-
|
136 |
-
return $interfaces;
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Register admin interfaces.
|
141 |
-
*
|
142 |
-
* @since 3.3.3
|
143 |
-
* @access public
|
144 |
-
*
|
145 |
-
* @param array $interfaces List of menu items.
|
146 |
-
* @return array Filtered list of menu items.
|
147 |
-
*/
|
148 |
-
public function register_admin_menu_items( $menu_items ) {
|
149 |
-
|
150 |
-
$list_slug = 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
|
151 |
-
$new_post_slug = 'post-new.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
|
152 |
-
$link_cat_slug = 'edit-tags.php?taxonomy=' . Plugin_Constants::AFFILIATE_LINKS_TAX . '&post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
|
153 |
-
$menu_items[ $list_slug ] = 'edit_posts';
|
154 |
-
$menu_items[ $new_post_slug ] = 'edit_posts';
|
155 |
-
$menu_items[ $link_cat_slug ] = 'manage_categories';
|
156 |
-
|
157 |
-
return $menu_items;
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* Get thirstylink Affiliate_Link object.
|
162 |
-
*
|
163 |
-
* @since 3.0.0
|
164 |
-
* @access private
|
165 |
-
*
|
166 |
-
* @param int $post_id Thirstylink post id.
|
167 |
-
* @return Affiliate_Link object.
|
168 |
-
*/
|
169 |
-
private function get_thirstylink_post( $post_id ) {
|
170 |
-
|
171 |
-
if ( is_object( $this->_thirstylink ) && $this->_thirstylink->get_id() == $post_id )
|
172 |
-
return $this->_thirstylink;
|
173 |
-
|
174 |
-
return $this->_thirstylink = new Affiliate_Link( $post_id );
|
175 |
-
|
176 |
-
}
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
/*
|
182 |
-
|--------------------------------------------------------------------------
|
183 |
-
| Register Post Type and Taxonomy
|
184 |
-
|--------------------------------------------------------------------------
|
185 |
-
*/
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Register the 'thirstylink' custom post type.
|
189 |
-
*
|
190 |
-
* @since 3.0.0
|
191 |
-
* @since 3.3.2 Set manage_terms capability to read so we can control visibility natively. see Bootstrap::admin_interface_visibility.
|
192 |
-
* @access private
|
193 |
-
*/
|
194 |
-
private function register_thirstylink_custom_post_type() {
|
195 |
-
|
196 |
-
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
197 |
-
|
198 |
-
$labels = array(
|
199 |
-
'name' => __( 'Affiliate Links' , 'thirstyaffiliates' ),
|
200 |
-
'singular_name' => __( 'Affiliate Link' , 'thirstyaffiliates' ),
|
201 |
-
'menu_name' => __( 'ThirstyAffiliates' , 'thirstyaffiliates' ),
|
202 |
-
'parent_item_colon' => __( 'Parent Affiliate Link' , 'thirstyaffiliates' ),
|
203 |
-
'all_items' => __( 'Affiliate Links' , 'thirstyaffiliates' ),
|
204 |
-
'view_item' => __( 'View Affiliate Link' , 'thirstyaffiliates' ),
|
205 |
-
'add_new_item' => __( 'Add Affiliate Link' , 'thirstyaffiliates' ),
|
206 |
-
'add_new' => __( 'New Affiliate Link' , 'thirstyaffiliates' ),
|
207 |
-
'edit_item' => __( 'Edit Affiliate Link' , 'thirstyaffiliates' ),
|
208 |
-
'update_item' => __( 'Update Affiliate Link' , 'thirstyaffiliates' ),
|
209 |
-
'search_items' => __( 'Search Affiliate Links' , 'thirstyaffiliates' ),
|
210 |
-
'not_found' => __( 'No Affiliate Link found' , 'thirstyaffiliates' ),
|
211 |
-
'not_found_in_trash' => __( 'No Affiliate Links found in Trash' , 'thirstyaffiliates' )
|
212 |
-
);
|
213 |
-
|
214 |
-
$args = array(
|
215 |
-
'label' => __( 'Affiliate Links' , 'thirstyaffiliates' ),
|
216 |
-
'description' => __( 'ThirstyAffiliates affiliate links' , 'thirstyaffiliates' ),
|
217 |
-
'labels' => $labels,
|
218 |
-
'supports' => array( 'title' , 'custom-fields' ),
|
219 |
-
'taxonomies' => array(),
|
220 |
-
'hierarchical' => true,
|
221 |
-
'public' => false,
|
222 |
-
'show_ui' => true,
|
223 |
-
'show_in_menu' => true,
|
224 |
-
'show_in_json' => false,
|
225 |
-
'query_var' => true,
|
226 |
-
'rewrite' => array(
|
227 |
-
'slug' => $link_prefix,
|
228 |
-
'with_front' => false,
|
229 |
-
'pages' => false
|
230 |
-
),
|
231 |
-
'show_in_nav_menus' => false,
|
232 |
-
'show_in_admin_bar' => true,
|
233 |
-
'menu_position' => 26,
|
234 |
-
'menu_icon' => 'data:image/svg+xml;base64,' . base64_encode('<svg xmlns="http://www.w3.org/2000/svg" width="16.688" height="9.875" viewBox="0 0 16.688 9.875">
|
235 |
-
<path id="TA.svg" fill="black" class="cls-1" d="M2.115,15.12H4.847L6.836,7.7H9.777l0.63-2.381H1.821L1.177,7.7H4.118Zm4.758,0H9.829l1.177-1.751h3.782l0.238,1.751h2.858L16.357,5.245H13.7Zm5.5-3.866,1.835-2.816,0.35,2.816H12.378Z" transform="translate(-1.188 -5.25)"/>
|
236 |
-
</svg>
|
237 |
-
'),
|
238 |
-
'can_export' => true,
|
239 |
-
'has_archive' => false,
|
240 |
-
'exclude_from_search' => true,
|
241 |
-
'publicly_queryable' => true,
|
242 |
-
'capability_type' => 'post',
|
243 |
-
'show_in_rest' => true,
|
244 |
-
);
|
245 |
-
|
246 |
-
register_post_type( Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_links_cpt_args' , $args , $labels ) );
|
247 |
-
|
248 |
-
do_action( 'ta_after_register_thirstylink_post_type' , $link_prefix );
|
249 |
-
}
|
250 |
-
|
251 |
-
/**
|
252 |
-
* Register the 'thirstylink-category' custom taxonomy.
|
253 |
-
*
|
254 |
-
* @since 3.0.0
|
255 |
-
* @since 3.3.2 Set manage_terms capability to read so we can control visibility natively. see Bootstrap::admin_interface_visibility.
|
256 |
-
* @access private
|
257 |
-
*/
|
258 |
-
private function register_thirstylink_category_custom_taxonomy() {
|
259 |
-
|
260 |
-
$labels = array(
|
261 |
-
'name' => __( 'Link Categories', 'thirstyaffiliates' ),
|
262 |
-
'singular_name' => __( 'Link Category', 'thirstyaffiliates' ),
|
263 |
-
'menu_name' => __( 'Link Categories', 'thirstyaffiliates' ),
|
264 |
-
'all_items' => __( 'All Categories', 'thirstyaffiliates' ),
|
265 |
-
'parent_item' => __( 'Parent Category', 'thirstyaffiliates' ),
|
266 |
-
'parent_item_colon' => __( 'Parent Category:', 'thirstyaffiliates' ),
|
267 |
-
'new_item_name' => __( 'New Category Name', 'thirstyaffiliates' ),
|
268 |
-
'add_new_item' => __( 'Add New Category', 'thirstyaffiliates' ),
|
269 |
-
'edit_item' => __( 'Edit Category', 'thirstyaffiliates' ),
|
270 |
-
'update_item' => __( 'Update Category', 'thirstyaffiliates' ),
|
271 |
-
'view_item' => __( 'View Category', 'thirstyaffiliates' ),
|
272 |
-
'separate_items_with_commas' => __( 'Separate items with commas', 'thirstyaffiliates' ),
|
273 |
-
'add_or_remove_items' => __( 'Add or remove items', 'thirstyaffiliates' ),
|
274 |
-
'choose_from_most_used' => __( 'Choose from the most used', 'thirstyaffiliates' ),
|
275 |
-
'popular_items' => __( 'Popular Categories', 'thirstyaffiliates' ),
|
276 |
-
'search_items' => __( 'Search Categories', 'thirstyaffiliates' ),
|
277 |
-
'not_found' => __( 'Not Found', 'thirstyaffiliates' ),
|
278 |
-
'no_terms' => __( 'No items', 'thirstyaffiliates' ),
|
279 |
-
'items_list' => __( 'Category list', 'thirstyaffiliates' ),
|
280 |
-
'items_list_navigation' => __( 'Category list navigation', 'thirstyaffiliates' )
|
281 |
-
);
|
282 |
-
|
283 |
-
$args = array(
|
284 |
-
'labels' => $labels,
|
285 |
-
'hierarchical' => true,
|
286 |
-
'public' => false,
|
287 |
-
'show_ui' => true,
|
288 |
-
'show_admin_column' => true,
|
289 |
-
'show_in_nav_menus' => false,
|
290 |
-
'show_tagcloud' => false,
|
291 |
-
'rewrite' => false,
|
292 |
-
'capabilities' => array(
|
293 |
-
'manage_terms' => 'read',
|
294 |
-
)
|
295 |
-
);
|
296 |
-
|
297 |
-
register_taxonomy( Plugin_Constants::AFFILIATE_LINKS_TAX , Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_link_taxonomy_args' , $args , $labels ) );
|
298 |
-
|
299 |
-
}
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
/*
|
305 |
-
|--------------------------------------------------------------------------
|
306 |
-
| UI and metabox related functions
|
307 |
-
|--------------------------------------------------------------------------
|
308 |
-
*/
|
309 |
-
|
310 |
-
/**
|
311 |
-
* Replace default post type permalink html with affiliate link ID.
|
312 |
-
*
|
313 |
-
* @since 3.0.0
|
314 |
-
* @access public
|
315 |
-
*
|
316 |
-
* @param string $html Permalink html.
|
317 |
-
* @param int $post_id Affiliate Link post id.
|
318 |
-
* @return string Link ID html.
|
319 |
-
*/
|
320 |
-
public function replace_permalink_with_id( $html , $post_id ) {
|
321 |
-
|
322 |
-
if ( get_post_type( $post_id ) == Plugin_Constants::AFFILIATE_LINKS_CPT )
|
323 |
-
return '<span id="link_id">' . __( 'Link ID:' , 'thirstyaffiliates' ) . ' <strong>' . $post_id . '</strong></span>';
|
324 |
-
|
325 |
-
return $html;
|
326 |
-
}
|
327 |
-
|
328 |
-
/**
|
329 |
-
* Register metaboxes
|
330 |
-
*
|
331 |
-
* @since 3.0.0
|
332 |
-
* @access public
|
333 |
-
*/
|
334 |
-
public function register_metaboxes() {
|
335 |
-
|
336 |
-
$normal_metaboxes = apply_filters( 'ta_register_normal_metaboxes' , array(
|
337 |
-
array(
|
338 |
-
'id' => 'ta-urls-metabox',
|
339 |
-
'title' => __( 'URLs', 'thirstyaffiliates' ),
|
340 |
-
'cb' => array( $this , 'urls_metabox' ),
|
341 |
-
'sort' => 10,
|
342 |
-
'priority' => 'high'
|
343 |
-
),
|
344 |
-
array(
|
345 |
-
'id' => 'ta-attach-images-metabox',
|
346 |
-
'title' => __( 'Attach Images', 'thirstyaffiliates' ),
|
347 |
-
'cb' => array( $this , 'attach_images_metabox' ),
|
348 |
-
'sort' => 20,
|
349 |
-
'priority' => 'high'
|
350 |
-
),
|
351 |
-
array(
|
352 |
-
'id' => 'ta-inserted-link-scanner-metabox',
|
353 |
-
'title' => __( 'Link Inserted Scanner', 'thirstyaffiliates' ),
|
354 |
-
'cb' => array( $this , 'inserted_link_scanner_metabox' ),
|
355 |
-
'sort' => 99,
|
356 |
-
'priority' => 'low'
|
357 |
-
),
|
358 |
-
) );
|
359 |
-
|
360 |
-
$side_metaboxes = apply_filters( 'ta_register_side_metaboxes' , array(
|
361 |
-
array(
|
362 |
-
'id' => 'ta-save-affiliate-link-metabox-side',
|
363 |
-
'title' => __( 'Save Affiliate Link', 'thirstyaffiliates' ),
|
364 |
-
'cb' => array( $this , 'save_affiliate_link_metabox' ),
|
365 |
-
'sort' => 10,
|
366 |
-
'priority' => 'high'
|
367 |
-
),
|
368 |
-
array(
|
369 |
-
'id' => 'ta-link-options-metabox',
|
370 |
-
'title' => __( 'Link Options', 'thirstyaffiliates' ),
|
371 |
-
'cb' => array( $this , 'link_options_metabox' ),
|
372 |
-
'sort' => 30,
|
373 |
-
'priority' => 'default'
|
374 |
-
),
|
375 |
-
) );
|
376 |
-
|
377 |
-
// sort metaboxes by priority.
|
378 |
-
$this->sort_metaboxes( $normal_metaboxes );
|
379 |
-
$this->sort_metaboxes( $side_metaboxes );
|
380 |
-
|
381 |
-
// register normal metaboxes.
|
382 |
-
foreach ( $normal_metaboxes as $metabox )
|
383 |
-
add_meta_box( $metabox[ 'id' ] , $metabox[ 'title' ] , $metabox[ 'cb' ] , Plugin_Constants::AFFILIATE_LINKS_CPT , 'normal' , $metabox[ 'priority' ] );
|
384 |
-
|
385 |
-
// register side metaboxes.
|
386 |
-
foreach ( $side_metaboxes as $metabox )
|
387 |
-
add_meta_box( $metabox[ 'id' ] , $metabox[ 'title' ] , $metabox[ 'cb' ] , Plugin_Constants::AFFILIATE_LINKS_CPT , 'side' , $metabox[ 'priority' ] );
|
388 |
-
|
389 |
-
// remove unnecessary metaboxes
|
390 |
-
remove_meta_box( 'submitdiv', Plugin_Constants::AFFILIATE_LINKS_CPT , 'side' );
|
391 |
-
remove_meta_box( 'postcustom' , Plugin_Constants::AFFILIATE_LINKS_CPT , 'normal' );
|
392 |
-
}
|
393 |
-
|
394 |
-
/**
|
395 |
-
* Function to sort registered metaboxes by priority.
|
396 |
-
*
|
397 |
-
* @since 3.2.1
|
398 |
-
* @access private
|
399 |
-
*
|
400 |
-
* @param array $metaboxes Metaboxes list to sort.
|
401 |
-
*/
|
402 |
-
private function sort_metaboxes( &$metaboxes ) {
|
403 |
-
|
404 |
-
usort( $metaboxes , function( $a , $b ) {
|
405 |
-
if ( $a[ 'sort' ] == $b[ 'sort' ] ) return 0;
|
406 |
-
return ( $a[ 'sort' ] > $b[ 'sort' ] ) ? 1 : -1;
|
407 |
-
} );
|
408 |
-
}
|
409 |
-
|
410 |
-
/**
|
411 |
-
* Display "URls" metabox
|
412 |
-
*
|
413 |
-
* @since 3.0.0
|
414 |
-
* @access public
|
415 |
-
*
|
416 |
-
* @param WP_Post $post Affiliate link WP_Post object.
|
417 |
-
*/
|
418 |
-
public function urls_metabox( $post ) {
|
419 |
-
|
420 |
-
$screen = get_current_screen();
|
421 |
-
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
422 |
-
$home_link_prefix = home_url( user_trailingslashit( $this->_helper_functions->get_thirstylink_link_prefix() ) );
|
423 |
-
$default_cat_slug = $this->_helper_functions->get_default_category_slug( $post->ID );
|
424 |
-
|
425 |
-
include_once( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-urls-metabox.php' );
|
426 |
-
|
427 |
-
}
|
428 |
-
|
429 |
-
/**
|
430 |
-
* Display "Attach Images" metabox
|
431 |
-
*
|
432 |
-
* @since 3.0.0
|
433 |
-
* @since 3.4.0 Add support for external images.
|
434 |
-
* @access public
|
435 |
-
*
|
436 |
-
* @param WP_Post $post Affiliate link WP_Post object.
|
437 |
-
*/
|
438 |
-
public function attach_images_metabox( $post ) {
|
439 |
-
|
440 |
-
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
441 |
-
$legacy_uploader = get_option( 'ta_legacy_uploader', 'no' );
|
442 |
-
$attachments = $thirstylink->get_prop( 'image_ids' );
|
443 |
-
|
444 |
-
include_once( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-attach-images-metabox.php' );
|
445 |
-
|
446 |
-
}
|
447 |
-
|
448 |
-
/**
|
449 |
-
* Display link options metabox
|
450 |
-
*
|
451 |
-
* @since 3.0.0
|
452 |
-
* @since 3.4.0 Add global option for redirect type. Add additional CSS classes field.
|
453 |
-
* @access public
|
454 |
-
*
|
455 |
-
* @param WP_Post $post Affiliate link WP_Post object.
|
456 |
-
*/
|
457 |
-
public function link_options_metabox( $post ) {
|
458 |
-
|
459 |
-
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
460 |
-
$default_redirect_type = $this->_helper_functions->get_option( 'ta_link_redirect_type' , '302' );
|
461 |
-
$post_redirect_type = $thirstylink->get_prop( 'redirect_type' );
|
462 |
-
$redirect_types = $this->_constants->REDIRECT_TYPES();
|
463 |
-
$global_no_follow = $thirstylink->get_toggle_prop_global_value( 'no_follow' );
|
464 |
-
$global_new_window = $thirstylink->get_toggle_prop_global_value( 'new_window' );
|
465 |
-
$global_pass_query_str = $thirstylink->get_toggle_prop_global_value( 'pass_query_str' );
|
466 |
-
$global_uncloak = $thirstylink->get_toggle_prop_global_value( 'uncloak_link' );
|
467 |
-
$rel_tags = get_post_meta( $post->ID , Plugin_Constants::META_DATA_PREFIX . 'rel_tags' , true );
|
468 |
-
$css_classes = get_post_meta( $post->ID , Plugin_Constants::META_DATA_PREFIX . 'css_classes' , true );
|
469 |
-
$global_rel_tags = get_option( 'ta_additional_rel_tags' );
|
470 |
-
$global_css_classes = get_option( 'ta_additional_css_classes' );
|
471 |
-
|
472 |
-
include_once( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-link-options-metabox.php' );
|
473 |
-
|
474 |
-
}
|
475 |
-
|
476 |
-
/**
|
477 |
-
* Display "Save Affiliate Link" metabox
|
478 |
-
*
|
479 |
-
* @since 3.0.0
|
480 |
-
* @access public
|
481 |
-
*
|
482 |
-
* @param WP_Post $post Affiliate link WP_Post object.
|
483 |
-
*/
|
484 |
-
public function save_affiliate_link_metabox( $post ) {
|
485 |
-
|
486 |
-
include( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-save-affiliate-link-metabox.php' );
|
487 |
-
|
488 |
-
}
|
489 |
-
|
490 |
-
/**
|
491 |
-
* Display inserted link scanner metabox
|
492 |
-
*
|
493 |
-
* @since 3.2.0
|
494 |
-
* @access public
|
495 |
-
*
|
496 |
-
* @param WP_Post $post Affiliate link WP_Post object.
|
497 |
-
*/
|
498 |
-
public function inserted_link_scanner_metabox( $post ) {
|
499 |
-
|
500 |
-
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
501 |
-
$spinner_image_src = $this->_constants->IMAGES_ROOT_URL() . 'spinner-2x.gif';
|
502 |
-
$inserted_to = $thirstylink->get_prop( 'inserted_to' );
|
503 |
-
$timezone = new \DateTimeZone( $this->_helper_functions->get_site_current_timezone() );
|
504 |
-
$last_scanned = \DateTime::createFromFormat( 'Y-m-d G:i:s' , $thirstylink->get_prop( 'scanned_inserted' ) );
|
505 |
-
$not_yet_scanned = __( 'Not yet scanned' , 'thirstyaffiliates' );
|
506 |
-
|
507 |
-
if ( $last_scanned )
|
508 |
-
$last_scanned->setTimezone( $timezone );
|
509 |
-
|
510 |
-
$last_scanned_txt = $last_scanned !== false ? __( 'Last scanned on:' , 'thirstyaffiliates' ) . ' <em>' . $last_scanned->format( 'F j, Y g:ia' ) . '</em>' : $not_yet_scanned;
|
511 |
-
$inserted_into_rows_html = $this->get_inserted_into_rows_html( $inserted_to );
|
512 |
-
|
513 |
-
include( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-inserted-link-scanner-metabox.php' );
|
514 |
-
}
|
515 |
-
|
516 |
-
/**
|
517 |
-
* Get the HTML for inserted into table rows.
|
518 |
-
*
|
519 |
-
* @since 3.2.0
|
520 |
-
* @access private
|
521 |
-
*
|
522 |
-
* @param array $inserted_to WP_Post IDs where affiliate link is inserte to.
|
523 |
-
* @param Affiliate_Link $thirstylink Affiliate link object.
|
524 |
-
*/
|
525 |
-
private function get_inserted_into_rows_html( $inserted_to ) {
|
526 |
-
|
527 |
-
global $wpdb;
|
528 |
-
|
529 |
-
if ( ! is_array( $inserted_to ) || empty( $inserted_to ) )
|
530 |
-
return '<tr><td colspan="4">' . __( 'No results found.' , 'thirstyaffiliates' ) . '</td></tr>';
|
531 |
-
|
532 |
-
$inserted_to_str = implode( ',' , $inserted_to );
|
533 |
-
$results = $wpdb->get_results( "SELECT ID , post_title , post_type FROM $wpdb->posts WHERE ID IN ( $inserted_to_str )" );
|
534 |
-
|
535 |
-
ob_start();
|
536 |
-
foreach ( $results as $object ) : ?>
|
537 |
-
<tr>
|
538 |
-
<td class="id"><?php echo esc_html( $object->ID ); ?></td>
|
539 |
-
<td class="title"><?php echo mb_strimwidth( esc_html( $object->post_title ) , 0 , 60 , "..." ); ?></td>
|
540 |
-
<td class="post-type"><?php echo esc_html( $object->post_type ); ?></td>
|
541 |
-
<td class="actions">
|
542 |
-
<a class="view" href="<?php echo get_permalink( $object->ID ); ?>" target="_blank"><span class="dashicons dashicons-admin-links"></span></a>
|
543 |
-
<a class="edit" href="<?php echo get_edit_post_link( $object->ID ); ?>" target="_blank"><span class="dashicons dashicons-edit"></span></a>
|
544 |
-
</td>
|
545 |
-
</tr>
|
546 |
-
<?php endforeach;
|
547 |
-
return ob_get_clean();
|
548 |
-
}
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
/*
|
554 |
-
|--------------------------------------------------------------------------
|
555 |
-
| Save Functions
|
556 |
-
|--------------------------------------------------------------------------
|
557 |
-
*/
|
558 |
-
|
559 |
-
/**
|
560 |
-
* Save thirstylink post.
|
561 |
-
*
|
562 |
-
* @since 3.0.0
|
563 |
-
* @since 3.2.2 Make sure post name (slug) is updated.
|
564 |
-
* @since 3.4.0 Add css_classes to the saved properties.
|
565 |
-
* @access public
|
566 |
-
*
|
567 |
-
* @param int $post_id Affiliate link post ID.
|
568 |
-
*/
|
569 |
-
public function save_post( $post_id ) {
|
570 |
-
|
571 |
-
if ( ! isset( $_POST[ '_thirstyaffiliates_nonce' ] ) || ! wp_verify_nonce( $_POST['_thirstyaffiliates_nonce'], 'thirsty_affiliates_cpt_nonce' ) )
|
572 |
-
return;
|
573 |
-
|
574 |
-
// remove save_post hooked action to prevent infinite loop
|
575 |
-
remove_action( 'save_post' , array( $this , 'save_post' ) );
|
576 |
-
|
577 |
-
$thirstylink = $this->get_thirstylink_post( $post_id );
|
578 |
-
|
579 |
-
// set Properties
|
580 |
-
$thirstylink->set_prop( 'destination_url' , esc_url_raw( $_POST[ 'ta_destination_url' ] ) );
|
581 |
-
$thirstylink->set_prop( 'no_follow' , sanitize_text_field( $_POST[ 'ta_no_follow' ] ) );
|
582 |
-
$thirstylink->set_prop( 'new_window' , sanitize_text_field( $_POST[ 'ta_new_window' ] ) );
|
583 |
-
$thirstylink->set_prop( 'pass_query_str' , sanitize_text_field( $_POST[ 'ta_pass_query_str' ] ) );
|
584 |
-
$thirstylink->set_prop( 'redirect_type' , sanitize_text_field( $_POST[ 'ta_redirect_type' ] ) );
|
585 |
-
$thirstylink->set_prop( 'rel_tags' , sanitize_text_field( $_POST[ 'ta_rel_tags' ] ) );
|
586 |
-
$thirstylink->set_prop( 'css_classes' , sanitize_text_field( $_POST[ 'ta_css_classes' ] ) );
|
587 |
-
|
588 |
-
if ( isset( $_POST[ 'post_name' ] ) )
|
589 |
-
$thirstylink->set_prop( 'slug' , sanitize_text_field( $_POST[ 'post_name' ] ) );
|
590 |
-
|
591 |
-
if ( isset( $_POST[ 'ta_uncloak_link' ] ) )
|
592 |
-
$thirstylink->set_prop( 'uncloak_link' , sanitize_text_field( $_POST[ 'ta_uncloak_link' ] ) );
|
593 |
-
|
594 |
-
if ( isset( $_POST[ 'ta_category_slug' ] ) && $_POST[ 'ta_category_slug' ] ) {
|
595 |
-
|
596 |
-
$category_slug_id = (int) sanitize_text_field( $_POST[ 'ta_category_slug' ] );
|
597 |
-
$category_slug = get_term( $category_slug_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
598 |
-
$thirstylink->set_prop( 'category_slug_id' , $category_slug_id );
|
599 |
-
$thirstylink->set_prop( 'category_slug' , $category_slug->slug );
|
600 |
-
|
601 |
-
} else {
|
602 |
-
|
603 |
-
$thirstylink->set_prop( 'category_slug_id' , 0 );
|
604 |
-
$thirstylink->set_prop( 'category_slug' , '' );
|
605 |
-
}
|
606 |
-
|
607 |
-
do_action( 'ta_save_affiliate_link_post' , $thirstylink , $post_id );
|
608 |
-
|
609 |
-
// save affiliate link
|
610 |
-
$thirstylink->save();
|
611 |
-
|
612 |
-
// set default term
|
613 |
-
$this->_helper_functions->save_default_affiliate_link_category( $post_id );
|
614 |
-
|
615 |
-
// add back save_post hooked action after saving
|
616 |
-
add_action( 'save_post' , array( $this , 'save_post' ) );
|
617 |
-
|
618 |
-
do_action( 'ta_after_save_affiliate_link_post' , $post_id , $thirstylink );
|
619 |
-
}
|
620 |
-
|
621 |
-
/**
|
622 |
-
* Set default term when affiliate link is saved.
|
623 |
-
*
|
624 |
-
* @deprecated 3.2.0 Moved to helper functions
|
625 |
-
*
|
626 |
-
* @since 3.0.0
|
627 |
-
* @access public
|
628 |
-
*
|
629 |
-
* @param int $post_id Affiliate link post ID.
|
630 |
-
*/
|
631 |
-
public function save_default_affiliate_link_category( $post_id ) {
|
632 |
-
|
633 |
-
$this->_helper_functions->save_default_affiliate_link_category( $post_id );
|
634 |
-
}
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
/*
|
640 |
-
|--------------------------------------------------------------------------
|
641 |
-
| Affiliate Link listing related UI functions
|
642 |
-
|--------------------------------------------------------------------------
|
643 |
-
*/
|
644 |
-
|
645 |
-
/**
|
646 |
-
* Add custom column to thirsty link listings (Link ID).
|
647 |
-
*
|
648 |
-
* @since 3.0.0
|
649 |
-
* @access public
|
650 |
-
*
|
651 |
-
* @param array $columns Post type listing columns.
|
652 |
-
* @return array Filtered post type listing columns.
|
653 |
-
*/
|
654 |
-
public function custom_post_listing_column( $columns ) {
|
655 |
-
|
656 |
-
$updated_columns = array();
|
657 |
-
|
658 |
-
foreach ( $columns as $key => $column ) {
|
659 |
-
|
660 |
-
// add link_id and link_destination column before link categories column
|
661 |
-
if ( $key == 'taxonomy-thirstylink-category' ) {
|
662 |
-
|
663 |
-
$updated_columns[ 'link_id' ] = __( 'Link ID' , 'thirstyaffiliates' );
|
664 |
-
$updated_columns[ 'redirect_type' ] = __( 'Redirect Type' , 'thirstyaffiliates' );
|
665 |
-
$updated_columns[ 'cloaked_url' ] = __( 'Cloaked URL' , 'thirstyaffiliates' );
|
666 |
-
$updated_columns[ 'link_destination' ] = __( 'Link Destination' , 'thirstyaffiliates' );
|
667 |
-
}
|
668 |
-
|
669 |
-
|
670 |
-
$updated_columns[ $key ] = $column;
|
671 |
-
}
|
672 |
-
|
673 |
-
return apply_filters( 'ta_post_listing_custom_columns' , $updated_columns );
|
674 |
-
|
675 |
-
}
|
676 |
-
|
677 |
-
/**
|
678 |
-
* Add custom column to thirsty link listings (Link ID).
|
679 |
-
*
|
680 |
-
* @since 3.2.0
|
681 |
-
* @access public
|
682 |
-
*
|
683 |
-
* @param array $columns Post type listing sortable columns.
|
684 |
-
* @return array Filtered Post type listing sortable columns.
|
685 |
-
*/
|
686 |
-
public function custom_post_listing_sortable_column( $columns ) {
|
687 |
-
|
688 |
-
$columns[ 'link_id' ] = 'ID';
|
689 |
-
$columns[ 'redirect_type' ] = '_ta_redirect_type';
|
690 |
-
$columns[ 'cloaked_url' ] = 'name';
|
691 |
-
$columns[ 'link_destination' ] = '_ta_destination_url';
|
692 |
-
|
693 |
-
return apply_filters( 'ta_post_listing_sortable_custom_columns' , $columns );
|
694 |
-
}
|
695 |
-
|
696 |
-
/**
|
697 |
-
* Add custom sorting support for TA custom columns with post meta values.
|
698 |
-
*
|
699 |
-
* @since 3.2.0
|
700 |
-
* @access public
|
701 |
-
*
|
702 |
-
* @param WP_Query $query Main WP_Query instance of the page.
|
703 |
-
*/
|
704 |
-
public function custom_post_listing_column_custom_sorting( $query ) {
|
705 |
-
|
706 |
-
$post_type = get_post_type();
|
707 |
-
if ( !$post_type && isset( $_GET[ 'post_type' ] ) )
|
708 |
-
$post_type = $_GET[ 'post_type' ];
|
709 |
-
|
710 |
-
if ( ! is_admin() || $post_type !== Plugin_Constants::AFFILIATE_LINKS_CPT )
|
711 |
-
return;
|
712 |
-
|
713 |
-
$meta_key = $query->get( 'orderby' );
|
714 |
-
$default_keys = array( '_ta_redirect_type', '_ta_destination_url' );
|
715 |
-
$extend_keys = apply_filters( 'ta_post_listing_custom_sorting_keys' , array() );
|
716 |
-
$meta_keys = array_unique( array_merge( $default_keys , $extend_keys ) );
|
717 |
-
|
718 |
-
|
719 |
-
if ( ! in_array( $meta_key , $meta_keys ) )
|
720 |
-
return;
|
721 |
-
|
722 |
-
$meta_data = apply_filters( 'ta_post_listing_custom_sorting_metadata' , array(
|
723 |
-
'meta_key' => $meta_key,
|
724 |
-
'orderby' => 'meta_value',
|
725 |
-
) , $meta_key , $meta_keys );
|
726 |
-
|
727 |
-
if ( ! $meta_data[ 'meta_key' ] || ! $meta_data[ 'orderby' ] )
|
728 |
-
return;
|
729 |
-
|
730 |
-
$query->set( 'meta_key' , $meta_key );
|
731 |
-
}
|
732 |
-
|
733 |
-
/**
|
734 |
-
* Add custom column to thirsty link listings (Link ID).
|
735 |
-
*
|
736 |
-
* @since 3.0.0
|
737 |
-
* @since 3.4.0 Update display for redirect type value.
|
738 |
-
* @access public
|
739 |
-
*
|
740 |
-
* @param string $column Current column name.
|
741 |
-
* @param int $post_id Thirstylink ID.
|
742 |
-
* @return array
|
743 |
-
*/
|
744 |
-
public function custom_post_listing_column_value( $column , $post_id ) {
|
745 |
-
|
746 |
-
$thirstylink = $this->get_thirstylink_post( $post_id );
|
747 |
-
$edit_link = get_edit_post_link( $post_id );
|
748 |
-
$redirect_type = $thirstylink->get_prop( 'redirect_type' );
|
749 |
-
|
750 |
-
switch ( $column ) {
|
751 |
-
|
752 |
-
case 'link_id' :
|
753 |
-
echo '<span>' . $post_id . '</span>';
|
754 |
-
break;
|
755 |
-
|
756 |
-
case 'redirect_type' :
|
757 |
-
echo $redirect_type;
|
758 |
-
echo $redirect_type === 'global' ? ' (' . $this->_helper_functions->get_option( 'ta_link_redirect_type' , '302' ) . ')' : '';
|
759 |
-
break;
|
760 |
-
|
761 |
-
case 'cloaked_url' :
|
762 |
-
echo '<div class="ta-display-input-wrap">';
|
763 |
-
echo '<input style="width:100%;" type="text" value="' . $thirstylink->get_prop( 'permalink' ) . '" readonly>';
|
764 |
-
echo '<a href="' . $edit_link . '"><span class="dashicons dashicons-edit"></span></a>';
|
765 |
-
echo '</div>';
|
766 |
-
break;
|
767 |
-
|
768 |
-
case 'link_destination' :
|
769 |
-
echo '<div class="ta-display-input-wrap">';
|
770 |
-
echo '<input style="width:100%;" type="text" value="' . $thirstylink->get_prop( 'destination_url' ) . '" readonly>';
|
771 |
-
echo '<a href="' . $edit_link . '"><span class="dashicons dashicons-edit"></span></a>';
|
772 |
-
echo '</div>';
|
773 |
-
break;
|
774 |
-
|
775 |
-
}
|
776 |
-
|
777 |
-
do_action( 'ta_post_listing_custom_columns_value' , $column , $thirstylink );
|
778 |
-
|
779 |
-
}
|
780 |
-
|
781 |
-
/**
|
782 |
-
* Setup the filter box for the list page so users can filter links by category
|
783 |
-
*
|
784 |
-
* @since 3.2.0
|
785 |
-
* @access public
|
786 |
-
*
|
787 |
-
* @global string $typenow Current post type context.
|
788 |
-
* @global WP_Query $wp_query Object that contains the main query of WP.
|
789 |
-
*/
|
790 |
-
public function restrict_links_by_category() {
|
791 |
-
|
792 |
-
global $typenow , $wp_query;
|
793 |
-
|
794 |
-
if ( $typenow != Plugin_Constants::AFFILIATE_LINKS_CPT )
|
795 |
-
return;
|
796 |
-
|
797 |
-
$taxonomy = Plugin_Constants::AFFILIATE_LINKS_TAX;
|
798 |
-
|
799 |
-
wp_dropdown_categories( array(
|
800 |
-
'show_option_all' => __( 'Show Link Categories' , 'thirstyaffiliates' ),
|
801 |
-
'taxonomy' => $taxonomy,
|
802 |
-
'name' => $taxonomy,
|
803 |
-
'orderby' => 'name',
|
804 |
-
'selected' => ( isset( $wp_query->query[ $taxonomy ] ) ? $wp_query->query[ $taxonomy ] : '' ),
|
805 |
-
'hierarchical' => true,
|
806 |
-
'depth' => 4,
|
807 |
-
'show_count' => true,
|
808 |
-
'hide_empty' => true
|
809 |
-
) );
|
810 |
-
}
|
811 |
-
|
812 |
-
/**
|
813 |
-
* Convert category ID to slug to make the filter by category dropdown work.
|
814 |
-
*
|
815 |
-
* @since 3.2.0
|
816 |
-
* @access public
|
817 |
-
*
|
818 |
-
* @global string $typenow Current post type context.
|
819 |
-
*
|
820 |
-
* @param WP_Query $query Current page query.
|
821 |
-
* @return WP_Query Filtered current page query.
|
822 |
-
*/
|
823 |
-
public function convert_cat_id_to_slug_in_query( $query ) {
|
824 |
-
|
825 |
-
global $typenow;
|
826 |
-
|
827 |
-
if ( $typenow != Plugin_Constants::AFFILIATE_LINKS_CPT )
|
828 |
-
return;
|
829 |
-
|
830 |
-
$qv = &$query->query_vars;
|
831 |
-
$taxonomy = Plugin_Constants::AFFILIATE_LINKS_TAX;
|
832 |
-
|
833 |
-
if ( isset( $qv[ $taxonomy ] ) && is_numeric( $qv[ $taxonomy ] ) ) {
|
834 |
-
|
835 |
-
$term = get_term_by( 'id' , $qv[ $taxonomy ] , $taxonomy );
|
836 |
-
$qv[ $taxonomy ] = is_object( $term ) ? $term->slug : '';
|
837 |
-
|
838 |
-
}
|
839 |
-
|
840 |
-
return $query;
|
841 |
-
}
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
/*
|
847 |
-
|--------------------------------------------------------------------------
|
848 |
-
| Affiliate Link Filters
|
849 |
-
|--------------------------------------------------------------------------
|
850 |
-
*/
|
851 |
-
|
852 |
-
/**
|
853 |
-
* Add category slug to the permalink.
|
854 |
-
*
|
855 |
-
* @since 3.0.0
|
856 |
-
* @access public
|
857 |
-
*
|
858 |
-
* @param string $post_link Thirstylink permalink.
|
859 |
-
* @param WP_Post $post Thirstylink WP_Post object.
|
860 |
-
* @return string Thirstylink permalink.
|
861 |
-
*/
|
862 |
-
public function add_category_slug_to_permalink( $post_link , $post ) {
|
863 |
-
|
864 |
-
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
865 |
-
|
866 |
-
if ( get_option( 'ta_show_cat_in_slug' ) !== 'yes' || is_wp_error( $post ) || $post->post_type != 'thirstylink' )
|
867 |
-
return $post_link;
|
868 |
-
|
869 |
-
$link_cat_id = get_post_meta( $post->ID , '_ta_category_slug_id' , true );
|
870 |
-
$link_cat = get_post_meta( $post->ID , '_ta_category_slug' , true );
|
871 |
-
|
872 |
-
if ( ! $link_cat && $link_cat_id ) {
|
873 |
-
|
874 |
-
$link_cat_obj = get_term( $link_cat_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
875 |
-
$link_cat = $link_cat_obj->slug;
|
876 |
-
|
877 |
-
} elseif ( ! $link_cat && ! $link_cat_id ) {
|
878 |
-
|
879 |
-
$link_cat = $this->_helper_functions->get_default_category_slug( $post->ID );
|
880 |
-
}
|
881 |
-
|
882 |
-
if ( ! $link_cat )
|
883 |
-
return $post_link;
|
884 |
-
|
885 |
-
return home_url( user_trailingslashit( $link_prefix . '/' . $link_cat . '/' . $post->post_name ) );
|
886 |
-
}
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
/*
|
892 |
-
|--------------------------------------------------------------------------
|
893 |
-
| AJAX functions.
|
894 |
-
|--------------------------------------------------------------------------
|
895 |
-
*/
|
896 |
-
|
897 |
-
/**
|
898 |
-
* Ajax get category slug.
|
899 |
-
*
|
900 |
-
* @since 3.0.0
|
901 |
-
* @access public
|
902 |
-
*/
|
903 |
-
public function ajax_get_category_slug() {
|
904 |
-
|
905 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
906 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
907 |
-
elseif ( ! isset( $_POST[ 'term_id' ] ) )
|
908 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
909 |
-
else {
|
910 |
-
|
911 |
-
$link_cat_id = (int) sanitize_text_field( $_POST[ 'term_id' ] );
|
912 |
-
$category = get_term( $link_cat_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
913 |
-
|
914 |
-
$response = array( 'status' => 'success' , 'category_slug' => $category->slug );
|
915 |
-
}
|
916 |
-
|
917 |
-
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
918 |
-
echo wp_json_encode( $response );
|
919 |
-
wp_die();
|
920 |
-
}
|
921 |
-
|
922 |
-
/**
|
923 |
-
* Ajax link inserted scanner.
|
924 |
-
*
|
925 |
-
* @since 3.2.0
|
926 |
-
* @access public
|
927 |
-
*/
|
928 |
-
public function ajax_link_inserted_scanner() {
|
929 |
-
|
930 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
931 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
932 |
-
elseif ( ! isset( $_POST[ 'link_id' ] ) )
|
933 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
934 |
-
else {
|
935 |
-
|
936 |
-
$link_id = (int) sanitize_text_field( $_POST[ 'link_id' ] );
|
937 |
-
$thirstylink = $this->get_thirstylink_post( $link_id );
|
938 |
-
$inserted_to = $thirstylink->scan_where_links_inserted();
|
939 |
-
$timezone = new \DateTimeZone( $this->_helper_functions->get_site_current_timezone() );
|
940 |
-
$last_scanned = \DateTime::createFromFormat( 'Y-m-d G:i:s' , get_post_meta( $link_id , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , true ) , $timezone );
|
941 |
-
|
942 |
-
$response = array(
|
943 |
-
'status' => 'success',
|
944 |
-
'results_markup' => $this->get_inserted_into_rows_html( $inserted_to ),
|
945 |
-
'last_scanned' => __( 'Last scanned on:' , 'thirstyaffiliates' ) . ' <em>' . $last_scanned->format( 'F j, Y g:ia' ) . '</em>'
|
946 |
-
);
|
947 |
-
}
|
948 |
-
|
949 |
-
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
950 |
-
echo wp_json_encode( $response );
|
951 |
-
wp_die();
|
952 |
-
}
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
/*
|
958 |
-
|--------------------------------------------------------------------------
|
959 |
-
| Fulfill implemented interface contracts
|
960 |
-
|--------------------------------------------------------------------------
|
961 |
-
*/
|
962 |
-
|
963 |
-
/**
|
964 |
-
* Method that houses codes to be executed on init hook.
|
965 |
-
*
|
966 |
-
* @since 3.0.0
|
967 |
-
* @access public
|
968 |
-
* @inherit ThirstyAffiliates\Interfaces\Initiable_Interface
|
969 |
-
*/
|
970 |
-
public function initialize() {
|
971 |
-
|
972 |
-
// cpt and taxonomy
|
973 |
-
$this->register_thirstylink_custom_post_type();
|
974 |
-
$this->register_thirstylink_category_custom_taxonomy();
|
975 |
-
|
976 |
-
add_action( 'wp_ajax_ta_get_category_slug' , array( $this , 'ajax_get_category_slug' ) );
|
977 |
-
add_action( 'wp_ajax_ta_link_inserted_scanner' , array( $this , 'ajax_link_inserted_scanner' ) );
|
978 |
-
}
|
979 |
-
|
980 |
-
/**
|
981 |
-
* Execute 'thirstylink' custom post type code.
|
982 |
-
*
|
983 |
-
* @since 3.0.0
|
984 |
-
* @access public
|
985 |
-
* @inherit ThirstyAffiliates\Interfaces\Model_Interface
|
986 |
-
*/
|
987 |
-
public function run() {
|
988 |
-
|
989 |
-
// replace permalink with link ID
|
990 |
-
add_filter( 'get_sample_permalink_html', array( $this , 'replace_permalink_with_id' ), 10 , 2 );
|
991 |
-
|
992 |
-
// metaboxes
|
993 |
-
add_action( 'add_meta_boxes' , array( $this , 'register_metaboxes' ) );
|
994 |
-
add_action( 'save_post' , array( $this , 'save_post' ) );
|
995 |
-
|
996 |
-
// custom column
|
997 |
-
add_filter( 'manage_edit-thirstylink_columns' , array( $this , 'custom_post_listing_column' ) );
|
998 |
-
add_filter( 'manage_edit-thirstylink_sortable_columns', array( $this , 'custom_post_listing_sortable_column' ) );
|
999 |
-
add_action( 'manage_thirstylink_posts_custom_column', array( $this , 'custom_post_listing_column_value' ) , 10 , 2 );
|
1000 |
-
add_action( 'pre_get_posts' , array( $this , 'custom_post_listing_column_custom_sorting' ) );
|
1001 |
-
|
1002 |
-
// filter by category
|
1003 |
-
add_action( 'restrict_manage_posts' , array( $this , 'restrict_links_by_category' ) );
|
1004 |
-
add_filter( 'parse_query' , array( $this , 'convert_cat_id_to_slug_in_query' ) );
|
1005 |
-
|
1006 |
-
// filter to add category on permalink
|
1007 |
-
add_filter( 'post_type_link' , array( $this , 'add_category_slug_to_permalink' ) , 10 , 2 );
|
1008 |
-
|
1009 |
-
// Register admin interface and menus.
|
1010 |
-
add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
|
1011 |
-
add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
|
1012 |
-
}
|
1013 |
-
|
1014 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
+
|
10 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
+
|
13 |
+
// Data Models
|
14 |
+
use ThirstyAffiliates\Models\Affiliate_Link;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Model that houses the logic of registering the 'thirstylink' custom post type.
|
18 |
+
*
|
19 |
+
* @since 3.0.0
|
20 |
+
*/
|
21 |
+
class Affiliate_Links_CPT implements Model_Interface , Initiable_Interface {
|
22 |
+
|
23 |
+
/*
|
24 |
+
|--------------------------------------------------------------------------
|
25 |
+
| Class Properties
|
26 |
+
|--------------------------------------------------------------------------
|
27 |
+
*/
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Property that holds the single main instance of Bootstrap.
|
31 |
+
*
|
32 |
+
* @since 3.0.0
|
33 |
+
* @access private
|
34 |
+
* @var Affiliate_Links_CPT
|
35 |
+
*/
|
36 |
+
private static $_instance;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Model that houses the main plugin object.
|
40 |
+
*
|
41 |
+
* @since 3.0.0
|
42 |
+
* @access private
|
43 |
+
* @var Abstract_Main_Plugin_Class
|
44 |
+
*/
|
45 |
+
private $_main_plugin;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Model that houses all the plugin constants.
|
49 |
+
*
|
50 |
+
* @since 3.0.0
|
51 |
+
* @access private
|
52 |
+
* @var Plugin_Constants
|
53 |
+
*/
|
54 |
+
private $_constants;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Property that houses all the helper functions of the plugin.
|
58 |
+
*
|
59 |
+
* @since 3.0.0
|
60 |
+
* @access private
|
61 |
+
* @var Helper_Functions
|
62 |
+
*/
|
63 |
+
private $_helper_functions;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Property that holds the currently loaded thirstylink post.
|
67 |
+
*
|
68 |
+
* @since 3.0.0
|
69 |
+
* @access private
|
70 |
+
*/
|
71 |
+
private $_thirstylink;
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
|
76 |
+
/*
|
77 |
+
|--------------------------------------------------------------------------
|
78 |
+
| Class Methods
|
79 |
+
|--------------------------------------------------------------------------
|
80 |
+
*/
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Class constructor.
|
84 |
+
*
|
85 |
+
* @since 3.0.0
|
86 |
+
* @access public
|
87 |
+
*
|
88 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
89 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
90 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
91 |
+
*/
|
92 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
93 |
+
|
94 |
+
$this->_constants = $constants;
|
95 |
+
$this->_helper_functions = $helper_functions;
|
96 |
+
|
97 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
98 |
+
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
103 |
+
*
|
104 |
+
* @since 3.0.0
|
105 |
+
* @access public
|
106 |
+
*
|
107 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
108 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
109 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
110 |
+
* @return Affiliate_Links_CPT
|
111 |
+
*/
|
112 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
113 |
+
|
114 |
+
if ( !self::$_instance instanceof self )
|
115 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
116 |
+
|
117 |
+
return self::$_instance;
|
118 |
+
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Register admin interfaces.
|
123 |
+
*
|
124 |
+
* @since 3.3.3
|
125 |
+
* @access public
|
126 |
+
*
|
127 |
+
* @param array $interfaces List of admin interfaces.
|
128 |
+
* @return array Filtered list of admin interfaces.
|
129 |
+
*/
|
130 |
+
public function register_admin_interfaces( $interfaces ) {
|
131 |
+
|
132 |
+
$interfaces[ 'edit-thirstylink' ] = 'edit_posts';
|
133 |
+
$interfaces[ 'thirstylink' ] = 'edit_posts';
|
134 |
+
$interfaces[ 'edit-thirstylink-category' ] = 'manage_categories';
|
135 |
+
|
136 |
+
return $interfaces;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Register admin interfaces.
|
141 |
+
*
|
142 |
+
* @since 3.3.3
|
143 |
+
* @access public
|
144 |
+
*
|
145 |
+
* @param array $interfaces List of menu items.
|
146 |
+
* @return array Filtered list of menu items.
|
147 |
+
*/
|
148 |
+
public function register_admin_menu_items( $menu_items ) {
|
149 |
+
|
150 |
+
$list_slug = 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
|
151 |
+
$new_post_slug = 'post-new.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
|
152 |
+
$link_cat_slug = 'edit-tags.php?taxonomy=' . Plugin_Constants::AFFILIATE_LINKS_TAX . '&post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
|
153 |
+
$menu_items[ $list_slug ] = 'edit_posts';
|
154 |
+
$menu_items[ $new_post_slug ] = 'edit_posts';
|
155 |
+
$menu_items[ $link_cat_slug ] = 'manage_categories';
|
156 |
+
|
157 |
+
return $menu_items;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Get thirstylink Affiliate_Link object.
|
162 |
+
*
|
163 |
+
* @since 3.0.0
|
164 |
+
* @access private
|
165 |
+
*
|
166 |
+
* @param int $post_id Thirstylink post id.
|
167 |
+
* @return Affiliate_Link object.
|
168 |
+
*/
|
169 |
+
private function get_thirstylink_post( $post_id ) {
|
170 |
+
|
171 |
+
if ( is_object( $this->_thirstylink ) && $this->_thirstylink->get_id() == $post_id )
|
172 |
+
return $this->_thirstylink;
|
173 |
+
|
174 |
+
return $this->_thirstylink = new Affiliate_Link( $post_id );
|
175 |
+
|
176 |
+
}
|
177 |
+
|
178 |
+
|
179 |
+
|
180 |
+
|
181 |
+
/*
|
182 |
+
|--------------------------------------------------------------------------
|
183 |
+
| Register Post Type and Taxonomy
|
184 |
+
|--------------------------------------------------------------------------
|
185 |
+
*/
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Register the 'thirstylink' custom post type.
|
189 |
+
*
|
190 |
+
* @since 3.0.0
|
191 |
+
* @since 3.3.2 Set manage_terms capability to read so we can control visibility natively. see Bootstrap::admin_interface_visibility.
|
192 |
+
* @access private
|
193 |
+
*/
|
194 |
+
private function register_thirstylink_custom_post_type() {
|
195 |
+
|
196 |
+
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
197 |
+
|
198 |
+
$labels = array(
|
199 |
+
'name' => __( 'Affiliate Links' , 'thirstyaffiliates' ),
|
200 |
+
'singular_name' => __( 'Affiliate Link' , 'thirstyaffiliates' ),
|
201 |
+
'menu_name' => __( 'ThirstyAffiliates' , 'thirstyaffiliates' ),
|
202 |
+
'parent_item_colon' => __( 'Parent Affiliate Link' , 'thirstyaffiliates' ),
|
203 |
+
'all_items' => __( 'Affiliate Links' , 'thirstyaffiliates' ),
|
204 |
+
'view_item' => __( 'View Affiliate Link' , 'thirstyaffiliates' ),
|
205 |
+
'add_new_item' => __( 'Add Affiliate Link' , 'thirstyaffiliates' ),
|
206 |
+
'add_new' => __( 'New Affiliate Link' , 'thirstyaffiliates' ),
|
207 |
+
'edit_item' => __( 'Edit Affiliate Link' , 'thirstyaffiliates' ),
|
208 |
+
'update_item' => __( 'Update Affiliate Link' , 'thirstyaffiliates' ),
|
209 |
+
'search_items' => __( 'Search Affiliate Links' , 'thirstyaffiliates' ),
|
210 |
+
'not_found' => __( 'No Affiliate Link found' , 'thirstyaffiliates' ),
|
211 |
+
'not_found_in_trash' => __( 'No Affiliate Links found in Trash' , 'thirstyaffiliates' )
|
212 |
+
);
|
213 |
+
|
214 |
+
$args = array(
|
215 |
+
'label' => __( 'Affiliate Links' , 'thirstyaffiliates' ),
|
216 |
+
'description' => __( 'ThirstyAffiliates affiliate links' , 'thirstyaffiliates' ),
|
217 |
+
'labels' => $labels,
|
218 |
+
'supports' => array( 'title' , 'custom-fields' ),
|
219 |
+
'taxonomies' => array(),
|
220 |
+
'hierarchical' => true,
|
221 |
+
'public' => false,
|
222 |
+
'show_ui' => true,
|
223 |
+
'show_in_menu' => true,
|
224 |
+
'show_in_json' => false,
|
225 |
+
'query_var' => true,
|
226 |
+
'rewrite' => array(
|
227 |
+
'slug' => $link_prefix,
|
228 |
+
'with_front' => false,
|
229 |
+
'pages' => false
|
230 |
+
),
|
231 |
+
'show_in_nav_menus' => false,
|
232 |
+
'show_in_admin_bar' => true,
|
233 |
+
'menu_position' => 26,
|
234 |
+
'menu_icon' => 'data:image/svg+xml;base64,' . base64_encode('<svg xmlns="http://www.w3.org/2000/svg" width="16.688" height="9.875" viewBox="0 0 16.688 9.875">
|
235 |
+
<path id="TA.svg" fill="black" class="cls-1" d="M2.115,15.12H4.847L6.836,7.7H9.777l0.63-2.381H1.821L1.177,7.7H4.118Zm4.758,0H9.829l1.177-1.751h3.782l0.238,1.751h2.858L16.357,5.245H13.7Zm5.5-3.866,1.835-2.816,0.35,2.816H12.378Z" transform="translate(-1.188 -5.25)"/>
|
236 |
+
</svg>
|
237 |
+
'),
|
238 |
+
'can_export' => true,
|
239 |
+
'has_archive' => false,
|
240 |
+
'exclude_from_search' => true,
|
241 |
+
'publicly_queryable' => true,
|
242 |
+
'capability_type' => 'post',
|
243 |
+
'show_in_rest' => true,
|
244 |
+
);
|
245 |
+
|
246 |
+
register_post_type( Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_links_cpt_args' , $args , $labels ) );
|
247 |
+
|
248 |
+
do_action( 'ta_after_register_thirstylink_post_type' , $link_prefix );
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Register the 'thirstylink-category' custom taxonomy.
|
253 |
+
*
|
254 |
+
* @since 3.0.0
|
255 |
+
* @since 3.3.2 Set manage_terms capability to read so we can control visibility natively. see Bootstrap::admin_interface_visibility.
|
256 |
+
* @access private
|
257 |
+
*/
|
258 |
+
private function register_thirstylink_category_custom_taxonomy() {
|
259 |
+
|
260 |
+
$labels = array(
|
261 |
+
'name' => __( 'Link Categories', 'thirstyaffiliates' ),
|
262 |
+
'singular_name' => __( 'Link Category', 'thirstyaffiliates' ),
|
263 |
+
'menu_name' => __( 'Link Categories', 'thirstyaffiliates' ),
|
264 |
+
'all_items' => __( 'All Categories', 'thirstyaffiliates' ),
|
265 |
+
'parent_item' => __( 'Parent Category', 'thirstyaffiliates' ),
|
266 |
+
'parent_item_colon' => __( 'Parent Category:', 'thirstyaffiliates' ),
|
267 |
+
'new_item_name' => __( 'New Category Name', 'thirstyaffiliates' ),
|
268 |
+
'add_new_item' => __( 'Add New Category', 'thirstyaffiliates' ),
|
269 |
+
'edit_item' => __( 'Edit Category', 'thirstyaffiliates' ),
|
270 |
+
'update_item' => __( 'Update Category', 'thirstyaffiliates' ),
|
271 |
+
'view_item' => __( 'View Category', 'thirstyaffiliates' ),
|
272 |
+
'separate_items_with_commas' => __( 'Separate items with commas', 'thirstyaffiliates' ),
|
273 |
+
'add_or_remove_items' => __( 'Add or remove items', 'thirstyaffiliates' ),
|
274 |
+
'choose_from_most_used' => __( 'Choose from the most used', 'thirstyaffiliates' ),
|
275 |
+
'popular_items' => __( 'Popular Categories', 'thirstyaffiliates' ),
|
276 |
+
'search_items' => __( 'Search Categories', 'thirstyaffiliates' ),
|
277 |
+
'not_found' => __( 'Not Found', 'thirstyaffiliates' ),
|
278 |
+
'no_terms' => __( 'No items', 'thirstyaffiliates' ),
|
279 |
+
'items_list' => __( 'Category list', 'thirstyaffiliates' ),
|
280 |
+
'items_list_navigation' => __( 'Category list navigation', 'thirstyaffiliates' )
|
281 |
+
);
|
282 |
+
|
283 |
+
$args = array(
|
284 |
+
'labels' => $labels,
|
285 |
+
'hierarchical' => true,
|
286 |
+
'public' => false,
|
287 |
+
'show_ui' => true,
|
288 |
+
'show_admin_column' => true,
|
289 |
+
'show_in_nav_menus' => false,
|
290 |
+
'show_tagcloud' => false,
|
291 |
+
'rewrite' => false,
|
292 |
+
'capabilities' => array(
|
293 |
+
'manage_terms' => 'read',
|
294 |
+
)
|
295 |
+
);
|
296 |
+
|
297 |
+
register_taxonomy( Plugin_Constants::AFFILIATE_LINKS_TAX , Plugin_Constants::AFFILIATE_LINKS_CPT , apply_filters( 'ta_affiliate_link_taxonomy_args' , $args , $labels ) );
|
298 |
+
|
299 |
+
}
|
300 |
+
|
301 |
+
|
302 |
+
|
303 |
+
|
304 |
+
/*
|
305 |
+
|--------------------------------------------------------------------------
|
306 |
+
| UI and metabox related functions
|
307 |
+
|--------------------------------------------------------------------------
|
308 |
+
*/
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Replace default post type permalink html with affiliate link ID.
|
312 |
+
*
|
313 |
+
* @since 3.0.0
|
314 |
+
* @access public
|
315 |
+
*
|
316 |
+
* @param string $html Permalink html.
|
317 |
+
* @param int $post_id Affiliate Link post id.
|
318 |
+
* @return string Link ID html.
|
319 |
+
*/
|
320 |
+
public function replace_permalink_with_id( $html , $post_id ) {
|
321 |
+
|
322 |
+
if ( get_post_type( $post_id ) == Plugin_Constants::AFFILIATE_LINKS_CPT )
|
323 |
+
return '<span id="link_id">' . __( 'Link ID:' , 'thirstyaffiliates' ) . ' <strong>' . $post_id . '</strong></span>';
|
324 |
+
|
325 |
+
return $html;
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Register metaboxes
|
330 |
+
*
|
331 |
+
* @since 3.0.0
|
332 |
+
* @access public
|
333 |
+
*/
|
334 |
+
public function register_metaboxes() {
|
335 |
+
|
336 |
+
$normal_metaboxes = apply_filters( 'ta_register_normal_metaboxes' , array(
|
337 |
+
array(
|
338 |
+
'id' => 'ta-urls-metabox',
|
339 |
+
'title' => __( 'URLs', 'thirstyaffiliates' ),
|
340 |
+
'cb' => array( $this , 'urls_metabox' ),
|
341 |
+
'sort' => 10,
|
342 |
+
'priority' => 'high'
|
343 |
+
),
|
344 |
+
array(
|
345 |
+
'id' => 'ta-attach-images-metabox',
|
346 |
+
'title' => __( 'Attach Images', 'thirstyaffiliates' ),
|
347 |
+
'cb' => array( $this , 'attach_images_metabox' ),
|
348 |
+
'sort' => 20,
|
349 |
+
'priority' => 'high'
|
350 |
+
),
|
351 |
+
array(
|
352 |
+
'id' => 'ta-inserted-link-scanner-metabox',
|
353 |
+
'title' => __( 'Link Inserted Scanner', 'thirstyaffiliates' ),
|
354 |
+
'cb' => array( $this , 'inserted_link_scanner_metabox' ),
|
355 |
+
'sort' => 99,
|
356 |
+
'priority' => 'low'
|
357 |
+
),
|
358 |
+
) );
|
359 |
+
|
360 |
+
$side_metaboxes = apply_filters( 'ta_register_side_metaboxes' , array(
|
361 |
+
array(
|
362 |
+
'id' => 'ta-save-affiliate-link-metabox-side',
|
363 |
+
'title' => __( 'Save Affiliate Link', 'thirstyaffiliates' ),
|
364 |
+
'cb' => array( $this , 'save_affiliate_link_metabox' ),
|
365 |
+
'sort' => 10,
|
366 |
+
'priority' => 'high'
|
367 |
+
),
|
368 |
+
array(
|
369 |
+
'id' => 'ta-link-options-metabox',
|
370 |
+
'title' => __( 'Link Options', 'thirstyaffiliates' ),
|
371 |
+
'cb' => array( $this , 'link_options_metabox' ),
|
372 |
+
'sort' => 30,
|
373 |
+
'priority' => 'default'
|
374 |
+
),
|
375 |
+
) );
|
376 |
+
|
377 |
+
// sort metaboxes by priority.
|
378 |
+
$this->sort_metaboxes( $normal_metaboxes );
|
379 |
+
$this->sort_metaboxes( $side_metaboxes );
|
380 |
+
|
381 |
+
// register normal metaboxes.
|
382 |
+
foreach ( $normal_metaboxes as $metabox )
|
383 |
+
add_meta_box( $metabox[ 'id' ] , $metabox[ 'title' ] , $metabox[ 'cb' ] , Plugin_Constants::AFFILIATE_LINKS_CPT , 'normal' , $metabox[ 'priority' ] );
|
384 |
+
|
385 |
+
// register side metaboxes.
|
386 |
+
foreach ( $side_metaboxes as $metabox )
|
387 |
+
add_meta_box( $metabox[ 'id' ] , $metabox[ 'title' ] , $metabox[ 'cb' ] , Plugin_Constants::AFFILIATE_LINKS_CPT , 'side' , $metabox[ 'priority' ] );
|
388 |
+
|
389 |
+
// remove unnecessary metaboxes
|
390 |
+
remove_meta_box( 'submitdiv', Plugin_Constants::AFFILIATE_LINKS_CPT , 'side' );
|
391 |
+
remove_meta_box( 'postcustom' , Plugin_Constants::AFFILIATE_LINKS_CPT , 'normal' );
|
392 |
+
}
|
393 |
+
|
394 |
+
/**
|
395 |
+
* Function to sort registered metaboxes by priority.
|
396 |
+
*
|
397 |
+
* @since 3.2.1
|
398 |
+
* @access private
|
399 |
+
*
|
400 |
+
* @param array $metaboxes Metaboxes list to sort.
|
401 |
+
*/
|
402 |
+
private function sort_metaboxes( &$metaboxes ) {
|
403 |
+
|
404 |
+
usort( $metaboxes , function( $a , $b ) {
|
405 |
+
if ( $a[ 'sort' ] == $b[ 'sort' ] ) return 0;
|
406 |
+
return ( $a[ 'sort' ] > $b[ 'sort' ] ) ? 1 : -1;
|
407 |
+
} );
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* Display "URls" metabox
|
412 |
+
*
|
413 |
+
* @since 3.0.0
|
414 |
+
* @access public
|
415 |
+
*
|
416 |
+
* @param WP_Post $post Affiliate link WP_Post object.
|
417 |
+
*/
|
418 |
+
public function urls_metabox( $post ) {
|
419 |
+
|
420 |
+
$screen = get_current_screen();
|
421 |
+
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
422 |
+
$home_link_prefix = home_url( user_trailingslashit( $this->_helper_functions->get_thirstylink_link_prefix() ) );
|
423 |
+
$default_cat_slug = $this->_helper_functions->get_default_category_slug( $post->ID );
|
424 |
+
|
425 |
+
include_once( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-urls-metabox.php' );
|
426 |
+
|
427 |
+
}
|
428 |
+
|
429 |
+
/**
|
430 |
+
* Display "Attach Images" metabox
|
431 |
+
*
|
432 |
+
* @since 3.0.0
|
433 |
+
* @since 3.4.0 Add support for external images.
|
434 |
+
* @access public
|
435 |
+
*
|
436 |
+
* @param WP_Post $post Affiliate link WP_Post object.
|
437 |
+
*/
|
438 |
+
public function attach_images_metabox( $post ) {
|
439 |
+
|
440 |
+
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
441 |
+
$legacy_uploader = get_option( 'ta_legacy_uploader', 'no' );
|
442 |
+
$attachments = $thirstylink->get_prop( 'image_ids' );
|
443 |
+
|
444 |
+
include_once( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-attach-images-metabox.php' );
|
445 |
+
|
446 |
+
}
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Display link options metabox
|
450 |
+
*
|
451 |
+
* @since 3.0.0
|
452 |
+
* @since 3.4.0 Add global option for redirect type. Add additional CSS classes field.
|
453 |
+
* @access public
|
454 |
+
*
|
455 |
+
* @param WP_Post $post Affiliate link WP_Post object.
|
456 |
+
*/
|
457 |
+
public function link_options_metabox( $post ) {
|
458 |
+
|
459 |
+
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
460 |
+
$default_redirect_type = $this->_helper_functions->get_option( 'ta_link_redirect_type' , '302' );
|
461 |
+
$post_redirect_type = $thirstylink->get_prop( 'redirect_type' );
|
462 |
+
$redirect_types = $this->_constants->REDIRECT_TYPES();
|
463 |
+
$global_no_follow = $thirstylink->get_toggle_prop_global_value( 'no_follow' );
|
464 |
+
$global_new_window = $thirstylink->get_toggle_prop_global_value( 'new_window' );
|
465 |
+
$global_pass_query_str = $thirstylink->get_toggle_prop_global_value( 'pass_query_str' );
|
466 |
+
$global_uncloak = $thirstylink->get_toggle_prop_global_value( 'uncloak_link' );
|
467 |
+
$rel_tags = get_post_meta( $post->ID , Plugin_Constants::META_DATA_PREFIX . 'rel_tags' , true );
|
468 |
+
$css_classes = get_post_meta( $post->ID , Plugin_Constants::META_DATA_PREFIX . 'css_classes' , true );
|
469 |
+
$global_rel_tags = get_option( 'ta_additional_rel_tags' );
|
470 |
+
$global_css_classes = get_option( 'ta_additional_css_classes' );
|
471 |
+
|
472 |
+
include_once( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-link-options-metabox.php' );
|
473 |
+
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Display "Save Affiliate Link" metabox
|
478 |
+
*
|
479 |
+
* @since 3.0.0
|
480 |
+
* @access public
|
481 |
+
*
|
482 |
+
* @param WP_Post $post Affiliate link WP_Post object.
|
483 |
+
*/
|
484 |
+
public function save_affiliate_link_metabox( $post ) {
|
485 |
+
|
486 |
+
include( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-save-affiliate-link-metabox.php' );
|
487 |
+
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* Display inserted link scanner metabox
|
492 |
+
*
|
493 |
+
* @since 3.2.0
|
494 |
+
* @access public
|
495 |
+
*
|
496 |
+
* @param WP_Post $post Affiliate link WP_Post object.
|
497 |
+
*/
|
498 |
+
public function inserted_link_scanner_metabox( $post ) {
|
499 |
+
|
500 |
+
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
501 |
+
$spinner_image_src = $this->_constants->IMAGES_ROOT_URL() . 'spinner-2x.gif';
|
502 |
+
$inserted_to = $thirstylink->get_prop( 'inserted_to' );
|
503 |
+
$timezone = new \DateTimeZone( $this->_helper_functions->get_site_current_timezone() );
|
504 |
+
$last_scanned = \DateTime::createFromFormat( 'Y-m-d G:i:s' , $thirstylink->get_prop( 'scanned_inserted' ) );
|
505 |
+
$not_yet_scanned = __( 'Not yet scanned' , 'thirstyaffiliates' );
|
506 |
+
|
507 |
+
if ( $last_scanned )
|
508 |
+
$last_scanned->setTimezone( $timezone );
|
509 |
+
|
510 |
+
$last_scanned_txt = $last_scanned !== false ? __( 'Last scanned on:' , 'thirstyaffiliates' ) . ' <em>' . $last_scanned->format( 'F j, Y g:ia' ) . '</em>' : $not_yet_scanned;
|
511 |
+
$inserted_into_rows_html = $this->get_inserted_into_rows_html( $inserted_to );
|
512 |
+
|
513 |
+
include( $this->_constants->VIEWS_ROOT_PATH() . 'cpt/view-inserted-link-scanner-metabox.php' );
|
514 |
+
}
|
515 |
+
|
516 |
+
/**
|
517 |
+
* Get the HTML for inserted into table rows.
|
518 |
+
*
|
519 |
+
* @since 3.2.0
|
520 |
+
* @access private
|
521 |
+
*
|
522 |
+
* @param array $inserted_to WP_Post IDs where affiliate link is inserte to.
|
523 |
+
* @param Affiliate_Link $thirstylink Affiliate link object.
|
524 |
+
*/
|
525 |
+
private function get_inserted_into_rows_html( $inserted_to ) {
|
526 |
+
|
527 |
+
global $wpdb;
|
528 |
+
|
529 |
+
if ( ! is_array( $inserted_to ) || empty( $inserted_to ) )
|
530 |
+
return '<tr><td colspan="4">' . __( 'No results found.' , 'thirstyaffiliates' ) . '</td></tr>';
|
531 |
+
|
532 |
+
$inserted_to_str = implode( ',' , $inserted_to );
|
533 |
+
$results = $wpdb->get_results( "SELECT ID , post_title , post_type FROM $wpdb->posts WHERE ID IN ( $inserted_to_str )" );
|
534 |
+
|
535 |
+
ob_start();
|
536 |
+
foreach ( $results as $object ) : ?>
|
537 |
+
<tr>
|
538 |
+
<td class="id"><?php echo esc_html( $object->ID ); ?></td>
|
539 |
+
<td class="title"><?php echo mb_strimwidth( esc_html( $object->post_title ) , 0 , 60 , "..." ); ?></td>
|
540 |
+
<td class="post-type"><?php echo esc_html( $object->post_type ); ?></td>
|
541 |
+
<td class="actions">
|
542 |
+
<a class="view" href="<?php echo get_permalink( $object->ID ); ?>" target="_blank"><span class="dashicons dashicons-admin-links"></span></a>
|
543 |
+
<a class="edit" href="<?php echo get_edit_post_link( $object->ID ); ?>" target="_blank"><span class="dashicons dashicons-edit"></span></a>
|
544 |
+
</td>
|
545 |
+
</tr>
|
546 |
+
<?php endforeach;
|
547 |
+
return ob_get_clean();
|
548 |
+
}
|
549 |
+
|
550 |
+
|
551 |
+
|
552 |
+
|
553 |
+
/*
|
554 |
+
|--------------------------------------------------------------------------
|
555 |
+
| Save Functions
|
556 |
+
|--------------------------------------------------------------------------
|
557 |
+
*/
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Save thirstylink post.
|
561 |
+
*
|
562 |
+
* @since 3.0.0
|
563 |
+
* @since 3.2.2 Make sure post name (slug) is updated.
|
564 |
+
* @since 3.4.0 Add css_classes to the saved properties.
|
565 |
+
* @access public
|
566 |
+
*
|
567 |
+
* @param int $post_id Affiliate link post ID.
|
568 |
+
*/
|
569 |
+
public function save_post( $post_id ) {
|
570 |
+
|
571 |
+
if ( ! isset( $_POST[ '_thirstyaffiliates_nonce' ] ) || ! wp_verify_nonce( $_POST['_thirstyaffiliates_nonce'], 'thirsty_affiliates_cpt_nonce' ) )
|
572 |
+
return;
|
573 |
+
|
574 |
+
// remove save_post hooked action to prevent infinite loop
|
575 |
+
remove_action( 'save_post' , array( $this , 'save_post' ) );
|
576 |
+
|
577 |
+
$thirstylink = $this->get_thirstylink_post( $post_id );
|
578 |
+
|
579 |
+
// set Properties
|
580 |
+
$thirstylink->set_prop( 'destination_url' , esc_url_raw( $_POST[ 'ta_destination_url' ] ) );
|
581 |
+
$thirstylink->set_prop( 'no_follow' , sanitize_text_field( $_POST[ 'ta_no_follow' ] ) );
|
582 |
+
$thirstylink->set_prop( 'new_window' , sanitize_text_field( $_POST[ 'ta_new_window' ] ) );
|
583 |
+
$thirstylink->set_prop( 'pass_query_str' , sanitize_text_field( $_POST[ 'ta_pass_query_str' ] ) );
|
584 |
+
$thirstylink->set_prop( 'redirect_type' , sanitize_text_field( $_POST[ 'ta_redirect_type' ] ) );
|
585 |
+
$thirstylink->set_prop( 'rel_tags' , sanitize_text_field( $_POST[ 'ta_rel_tags' ] ) );
|
586 |
+
$thirstylink->set_prop( 'css_classes' , sanitize_text_field( $_POST[ 'ta_css_classes' ] ) );
|
587 |
+
|
588 |
+
if ( isset( $_POST[ 'post_name' ] ) )
|
589 |
+
$thirstylink->set_prop( 'slug' , sanitize_text_field( $_POST[ 'post_name' ] ) );
|
590 |
+
|
591 |
+
if ( isset( $_POST[ 'ta_uncloak_link' ] ) )
|
592 |
+
$thirstylink->set_prop( 'uncloak_link' , sanitize_text_field( $_POST[ 'ta_uncloak_link' ] ) );
|
593 |
+
|
594 |
+
if ( isset( $_POST[ 'ta_category_slug' ] ) && $_POST[ 'ta_category_slug' ] ) {
|
595 |
+
|
596 |
+
$category_slug_id = (int) sanitize_text_field( $_POST[ 'ta_category_slug' ] );
|
597 |
+
$category_slug = get_term( $category_slug_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
598 |
+
$thirstylink->set_prop( 'category_slug_id' , $category_slug_id );
|
599 |
+
$thirstylink->set_prop( 'category_slug' , $category_slug->slug );
|
600 |
+
|
601 |
+
} else {
|
602 |
+
|
603 |
+
$thirstylink->set_prop( 'category_slug_id' , 0 );
|
604 |
+
$thirstylink->set_prop( 'category_slug' , '' );
|
605 |
+
}
|
606 |
+
|
607 |
+
do_action( 'ta_save_affiliate_link_post' , $thirstylink , $post_id );
|
608 |
+
|
609 |
+
// save affiliate link
|
610 |
+
$thirstylink->save();
|
611 |
+
|
612 |
+
// set default term
|
613 |
+
$this->_helper_functions->save_default_affiliate_link_category( $post_id );
|
614 |
+
|
615 |
+
// add back save_post hooked action after saving
|
616 |
+
add_action( 'save_post' , array( $this , 'save_post' ) );
|
617 |
+
|
618 |
+
do_action( 'ta_after_save_affiliate_link_post' , $post_id , $thirstylink );
|
619 |
+
}
|
620 |
+
|
621 |
+
/**
|
622 |
+
* Set default term when affiliate link is saved.
|
623 |
+
*
|
624 |
+
* @deprecated 3.2.0 Moved to helper functions
|
625 |
+
*
|
626 |
+
* @since 3.0.0
|
627 |
+
* @access public
|
628 |
+
*
|
629 |
+
* @param int $post_id Affiliate link post ID.
|
630 |
+
*/
|
631 |
+
public function save_default_affiliate_link_category( $post_id ) {
|
632 |
+
|
633 |
+
$this->_helper_functions->save_default_affiliate_link_category( $post_id );
|
634 |
+
}
|
635 |
+
|
636 |
+
|
637 |
+
|
638 |
+
|
639 |
+
/*
|
640 |
+
|--------------------------------------------------------------------------
|
641 |
+
| Affiliate Link listing related UI functions
|
642 |
+
|--------------------------------------------------------------------------
|
643 |
+
*/
|
644 |
+
|
645 |
+
/**
|
646 |
+
* Add custom column to thirsty link listings (Link ID).
|
647 |
+
*
|
648 |
+
* @since 3.0.0
|
649 |
+
* @access public
|
650 |
+
*
|
651 |
+
* @param array $columns Post type listing columns.
|
652 |
+
* @return array Filtered post type listing columns.
|
653 |
+
*/
|
654 |
+
public function custom_post_listing_column( $columns ) {
|
655 |
+
|
656 |
+
$updated_columns = array();
|
657 |
+
|
658 |
+
foreach ( $columns as $key => $column ) {
|
659 |
+
|
660 |
+
// add link_id and link_destination column before link categories column
|
661 |
+
if ( $key == 'taxonomy-thirstylink-category' ) {
|
662 |
+
|
663 |
+
$updated_columns[ 'link_id' ] = __( 'Link ID' , 'thirstyaffiliates' );
|
664 |
+
$updated_columns[ 'redirect_type' ] = __( 'Redirect Type' , 'thirstyaffiliates' );
|
665 |
+
$updated_columns[ 'cloaked_url' ] = __( 'Cloaked URL' , 'thirstyaffiliates' );
|
666 |
+
$updated_columns[ 'link_destination' ] = __( 'Link Destination' , 'thirstyaffiliates' );
|
667 |
+
}
|
668 |
+
|
669 |
+
|
670 |
+
$updated_columns[ $key ] = $column;
|
671 |
+
}
|
672 |
+
|
673 |
+
return apply_filters( 'ta_post_listing_custom_columns' , $updated_columns );
|
674 |
+
|
675 |
+
}
|
676 |
+
|
677 |
+
/**
|
678 |
+
* Add custom column to thirsty link listings (Link ID).
|
679 |
+
*
|
680 |
+
* @since 3.2.0
|
681 |
+
* @access public
|
682 |
+
*
|
683 |
+
* @param array $columns Post type listing sortable columns.
|
684 |
+
* @return array Filtered Post type listing sortable columns.
|
685 |
+
*/
|
686 |
+
public function custom_post_listing_sortable_column( $columns ) {
|
687 |
+
|
688 |
+
$columns[ 'link_id' ] = 'ID';
|
689 |
+
$columns[ 'redirect_type' ] = '_ta_redirect_type';
|
690 |
+
$columns[ 'cloaked_url' ] = 'name';
|
691 |
+
$columns[ 'link_destination' ] = '_ta_destination_url';
|
692 |
+
|
693 |
+
return apply_filters( 'ta_post_listing_sortable_custom_columns' , $columns );
|
694 |
+
}
|
695 |
+
|
696 |
+
/**
|
697 |
+
* Add custom sorting support for TA custom columns with post meta values.
|
698 |
+
*
|
699 |
+
* @since 3.2.0
|
700 |
+
* @access public
|
701 |
+
*
|
702 |
+
* @param WP_Query $query Main WP_Query instance of the page.
|
703 |
+
*/
|
704 |
+
public function custom_post_listing_column_custom_sorting( $query ) {
|
705 |
+
|
706 |
+
$post_type = get_post_type();
|
707 |
+
if ( !$post_type && isset( $_GET[ 'post_type' ] ) )
|
708 |
+
$post_type = $_GET[ 'post_type' ];
|
709 |
+
|
710 |
+
if ( ! is_admin() || $post_type !== Plugin_Constants::AFFILIATE_LINKS_CPT )
|
711 |
+
return;
|
712 |
+
|
713 |
+
$meta_key = $query->get( 'orderby' );
|
714 |
+
$default_keys = array( '_ta_redirect_type', '_ta_destination_url' );
|
715 |
+
$extend_keys = apply_filters( 'ta_post_listing_custom_sorting_keys' , array() );
|
716 |
+
$meta_keys = array_unique( array_merge( $default_keys , $extend_keys ) );
|
717 |
+
|
718 |
+
|
719 |
+
if ( ! in_array( $meta_key , $meta_keys ) )
|
720 |
+
return;
|
721 |
+
|
722 |
+
$meta_data = apply_filters( 'ta_post_listing_custom_sorting_metadata' , array(
|
723 |
+
'meta_key' => $meta_key,
|
724 |
+
'orderby' => 'meta_value',
|
725 |
+
) , $meta_key , $meta_keys );
|
726 |
+
|
727 |
+
if ( ! $meta_data[ 'meta_key' ] || ! $meta_data[ 'orderby' ] )
|
728 |
+
return;
|
729 |
+
|
730 |
+
$query->set( 'meta_key' , $meta_key );
|
731 |
+
}
|
732 |
+
|
733 |
+
/**
|
734 |
+
* Add custom column to thirsty link listings (Link ID).
|
735 |
+
*
|
736 |
+
* @since 3.0.0
|
737 |
+
* @since 3.4.0 Update display for redirect type value.
|
738 |
+
* @access public
|
739 |
+
*
|
740 |
+
* @param string $column Current column name.
|
741 |
+
* @param int $post_id Thirstylink ID.
|
742 |
+
* @return array
|
743 |
+
*/
|
744 |
+
public function custom_post_listing_column_value( $column , $post_id ) {
|
745 |
+
|
746 |
+
$thirstylink = $this->get_thirstylink_post( $post_id );
|
747 |
+
$edit_link = get_edit_post_link( $post_id );
|
748 |
+
$redirect_type = $thirstylink->get_prop( 'redirect_type' );
|
749 |
+
|
750 |
+
switch ( $column ) {
|
751 |
+
|
752 |
+
case 'link_id' :
|
753 |
+
echo '<span>' . $post_id . '</span>';
|
754 |
+
break;
|
755 |
+
|
756 |
+
case 'redirect_type' :
|
757 |
+
echo $redirect_type;
|
758 |
+
echo $redirect_type === 'global' ? ' (' . $this->_helper_functions->get_option( 'ta_link_redirect_type' , '302' ) . ')' : '';
|
759 |
+
break;
|
760 |
+
|
761 |
+
case 'cloaked_url' :
|
762 |
+
echo '<div class="ta-display-input-wrap">';
|
763 |
+
echo '<input style="width:100%;" type="text" value="' . $thirstylink->get_prop( 'permalink' ) . '" readonly>';
|
764 |
+
echo '<a href="' . $edit_link . '"><span class="dashicons dashicons-edit"></span></a>';
|
765 |
+
echo '</div>';
|
766 |
+
break;
|
767 |
+
|
768 |
+
case 'link_destination' :
|
769 |
+
echo '<div class="ta-display-input-wrap">';
|
770 |
+
echo '<input style="width:100%;" type="text" value="' . $thirstylink->get_prop( 'destination_url' ) . '" readonly>';
|
771 |
+
echo '<a href="' . $edit_link . '"><span class="dashicons dashicons-edit"></span></a>';
|
772 |
+
echo '</div>';
|
773 |
+
break;
|
774 |
+
|
775 |
+
}
|
776 |
+
|
777 |
+
do_action( 'ta_post_listing_custom_columns_value' , $column , $thirstylink );
|
778 |
+
|
779 |
+
}
|
780 |
+
|
781 |
+
/**
|
782 |
+
* Setup the filter box for the list page so users can filter links by category
|
783 |
+
*
|
784 |
+
* @since 3.2.0
|
785 |
+
* @access public
|
786 |
+
*
|
787 |
+
* @global string $typenow Current post type context.
|
788 |
+
* @global WP_Query $wp_query Object that contains the main query of WP.
|
789 |
+
*/
|
790 |
+
public function restrict_links_by_category() {
|
791 |
+
|
792 |
+
global $typenow , $wp_query;
|
793 |
+
|
794 |
+
if ( $typenow != Plugin_Constants::AFFILIATE_LINKS_CPT )
|
795 |
+
return;
|
796 |
+
|
797 |
+
$taxonomy = Plugin_Constants::AFFILIATE_LINKS_TAX;
|
798 |
+
|
799 |
+
wp_dropdown_categories( array(
|
800 |
+
'show_option_all' => __( 'Show Link Categories' , 'thirstyaffiliates' ),
|
801 |
+
'taxonomy' => $taxonomy,
|
802 |
+
'name' => $taxonomy,
|
803 |
+
'orderby' => 'name',
|
804 |
+
'selected' => ( isset( $wp_query->query[ $taxonomy ] ) ? $wp_query->query[ $taxonomy ] : '' ),
|
805 |
+
'hierarchical' => true,
|
806 |
+
'depth' => 4,
|
807 |
+
'show_count' => true,
|
808 |
+
'hide_empty' => true
|
809 |
+
) );
|
810 |
+
}
|
811 |
+
|
812 |
+
/**
|
813 |
+
* Convert category ID to slug to make the filter by category dropdown work.
|
814 |
+
*
|
815 |
+
* @since 3.2.0
|
816 |
+
* @access public
|
817 |
+
*
|
818 |
+
* @global string $typenow Current post type context.
|
819 |
+
*
|
820 |
+
* @param WP_Query $query Current page query.
|
821 |
+
* @return WP_Query Filtered current page query.
|
822 |
+
*/
|
823 |
+
public function convert_cat_id_to_slug_in_query( $query ) {
|
824 |
+
|
825 |
+
global $typenow;
|
826 |
+
|
827 |
+
if ( $typenow != Plugin_Constants::AFFILIATE_LINKS_CPT )
|
828 |
+
return;
|
829 |
+
|
830 |
+
$qv = &$query->query_vars;
|
831 |
+
$taxonomy = Plugin_Constants::AFFILIATE_LINKS_TAX;
|
832 |
+
|
833 |
+
if ( isset( $qv[ $taxonomy ] ) && is_numeric( $qv[ $taxonomy ] ) ) {
|
834 |
+
|
835 |
+
$term = get_term_by( 'id' , $qv[ $taxonomy ] , $taxonomy );
|
836 |
+
$qv[ $taxonomy ] = is_object( $term ) ? $term->slug : '';
|
837 |
+
|
838 |
+
}
|
839 |
+
|
840 |
+
return $query;
|
841 |
+
}
|
842 |
+
|
843 |
+
|
844 |
+
|
845 |
+
|
846 |
+
/*
|
847 |
+
|--------------------------------------------------------------------------
|
848 |
+
| Affiliate Link Filters
|
849 |
+
|--------------------------------------------------------------------------
|
850 |
+
*/
|
851 |
+
|
852 |
+
/**
|
853 |
+
* Add category slug to the permalink.
|
854 |
+
*
|
855 |
+
* @since 3.0.0
|
856 |
+
* @access public
|
857 |
+
*
|
858 |
+
* @param string $post_link Thirstylink permalink.
|
859 |
+
* @param WP_Post $post Thirstylink WP_Post object.
|
860 |
+
* @return string Thirstylink permalink.
|
861 |
+
*/
|
862 |
+
public function add_category_slug_to_permalink( $post_link , $post ) {
|
863 |
+
|
864 |
+
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
865 |
+
|
866 |
+
if ( get_option( 'ta_show_cat_in_slug' ) !== 'yes' || is_wp_error( $post ) || $post->post_type != 'thirstylink' )
|
867 |
+
return $post_link;
|
868 |
+
|
869 |
+
$link_cat_id = get_post_meta( $post->ID , '_ta_category_slug_id' , true );
|
870 |
+
$link_cat = get_post_meta( $post->ID , '_ta_category_slug' , true );
|
871 |
+
|
872 |
+
if ( ! $link_cat && $link_cat_id ) {
|
873 |
+
|
874 |
+
$link_cat_obj = get_term( $link_cat_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
875 |
+
$link_cat = $link_cat_obj->slug;
|
876 |
+
|
877 |
+
} elseif ( ! $link_cat && ! $link_cat_id ) {
|
878 |
+
|
879 |
+
$link_cat = $this->_helper_functions->get_default_category_slug( $post->ID );
|
880 |
+
}
|
881 |
+
|
882 |
+
if ( ! $link_cat )
|
883 |
+
return $post_link;
|
884 |
+
|
885 |
+
return home_url( user_trailingslashit( $link_prefix . '/' . $link_cat . '/' . $post->post_name ) );
|
886 |
+
}
|
887 |
+
|
888 |
+
|
889 |
+
|
890 |
+
|
891 |
+
/*
|
892 |
+
|--------------------------------------------------------------------------
|
893 |
+
| AJAX functions.
|
894 |
+
|--------------------------------------------------------------------------
|
895 |
+
*/
|
896 |
+
|
897 |
+
/**
|
898 |
+
* Ajax get category slug.
|
899 |
+
*
|
900 |
+
* @since 3.0.0
|
901 |
+
* @access public
|
902 |
+
*/
|
903 |
+
public function ajax_get_category_slug() {
|
904 |
+
|
905 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
906 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
907 |
+
elseif ( ! isset( $_POST[ 'term_id' ] ) )
|
908 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
909 |
+
else {
|
910 |
+
|
911 |
+
$link_cat_id = (int) sanitize_text_field( $_POST[ 'term_id' ] );
|
912 |
+
$category = get_term( $link_cat_id , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
913 |
+
|
914 |
+
$response = array( 'status' => 'success' , 'category_slug' => $category->slug );
|
915 |
+
}
|
916 |
+
|
917 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
918 |
+
echo wp_json_encode( $response );
|
919 |
+
wp_die();
|
920 |
+
}
|
921 |
+
|
922 |
+
/**
|
923 |
+
* Ajax link inserted scanner.
|
924 |
+
*
|
925 |
+
* @since 3.2.0
|
926 |
+
* @access public
|
927 |
+
*/
|
928 |
+
public function ajax_link_inserted_scanner() {
|
929 |
+
|
930 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
931 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
932 |
+
elseif ( ! isset( $_POST[ 'link_id' ] ) )
|
933 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
934 |
+
else {
|
935 |
+
|
936 |
+
$link_id = (int) sanitize_text_field( $_POST[ 'link_id' ] );
|
937 |
+
$thirstylink = $this->get_thirstylink_post( $link_id );
|
938 |
+
$inserted_to = $thirstylink->scan_where_links_inserted();
|
939 |
+
$timezone = new \DateTimeZone( $this->_helper_functions->get_site_current_timezone() );
|
940 |
+
$last_scanned = \DateTime::createFromFormat( 'Y-m-d G:i:s' , get_post_meta( $link_id , Plugin_Constants::META_DATA_PREFIX . 'scanned_inserted' , true ) , $timezone );
|
941 |
+
|
942 |
+
$response = array(
|
943 |
+
'status' => 'success',
|
944 |
+
'results_markup' => $this->get_inserted_into_rows_html( $inserted_to ),
|
945 |
+
'last_scanned' => __( 'Last scanned on:' , 'thirstyaffiliates' ) . ' <em>' . $last_scanned->format( 'F j, Y g:ia' ) . '</em>'
|
946 |
+
);
|
947 |
+
}
|
948 |
+
|
949 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
950 |
+
echo wp_json_encode( $response );
|
951 |
+
wp_die();
|
952 |
+
}
|
953 |
+
|
954 |
+
|
955 |
+
|
956 |
+
|
957 |
+
/*
|
958 |
+
|--------------------------------------------------------------------------
|
959 |
+
| Fulfill implemented interface contracts
|
960 |
+
|--------------------------------------------------------------------------
|
961 |
+
*/
|
962 |
+
|
963 |
+
/**
|
964 |
+
* Method that houses codes to be executed on init hook.
|
965 |
+
*
|
966 |
+
* @since 3.0.0
|
967 |
+
* @access public
|
968 |
+
* @inherit ThirstyAffiliates\Interfaces\Initiable_Interface
|
969 |
+
*/
|
970 |
+
public function initialize() {
|
971 |
+
|
972 |
+
// cpt and taxonomy
|
973 |
+
$this->register_thirstylink_custom_post_type();
|
974 |
+
$this->register_thirstylink_category_custom_taxonomy();
|
975 |
+
|
976 |
+
add_action( 'wp_ajax_ta_get_category_slug' , array( $this , 'ajax_get_category_slug' ) );
|
977 |
+
add_action( 'wp_ajax_ta_link_inserted_scanner' , array( $this , 'ajax_link_inserted_scanner' ) );
|
978 |
+
}
|
979 |
+
|
980 |
+
/**
|
981 |
+
* Execute 'thirstylink' custom post type code.
|
982 |
+
*
|
983 |
+
* @since 3.0.0
|
984 |
+
* @access public
|
985 |
+
* @inherit ThirstyAffiliates\Interfaces\Model_Interface
|
986 |
+
*/
|
987 |
+
public function run() {
|
988 |
+
|
989 |
+
// replace permalink with link ID
|
990 |
+
add_filter( 'get_sample_permalink_html', array( $this , 'replace_permalink_with_id' ), 10 , 2 );
|
991 |
+
|
992 |
+
// metaboxes
|
993 |
+
add_action( 'add_meta_boxes' , array( $this , 'register_metaboxes' ) );
|
994 |
+
add_action( 'save_post' , array( $this , 'save_post' ) );
|
995 |
+
|
996 |
+
// custom column
|
997 |
+
add_filter( 'manage_edit-thirstylink_columns' , array( $this , 'custom_post_listing_column' ) );
|
998 |
+
add_filter( 'manage_edit-thirstylink_sortable_columns', array( $this , 'custom_post_listing_sortable_column' ) );
|
999 |
+
add_action( 'manage_thirstylink_posts_custom_column', array( $this , 'custom_post_listing_column_value' ) , 10 , 2 );
|
1000 |
+
add_action( 'pre_get_posts' , array( $this , 'custom_post_listing_column_custom_sorting' ) );
|
1001 |
+
|
1002 |
+
// filter by category
|
1003 |
+
add_action( 'restrict_manage_posts' , array( $this , 'restrict_links_by_category' ) );
|
1004 |
+
add_filter( 'parse_query' , array( $this , 'convert_cat_id_to_slug_in_query' ) );
|
1005 |
+
|
1006 |
+
// filter to add category on permalink
|
1007 |
+
add_filter( 'post_type_link' , array( $this , 'add_category_slug_to_permalink' ) , 10 , 2 );
|
1008 |
+
|
1009 |
+
// Register admin interface and menus.
|
1010 |
+
add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
|
1011 |
+
add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
}
|
Models/Bootstrap.php
CHANGED
@@ -1,517 +1,520 @@
|
|
1 |
-
<?php
|
2 |
-
namespace ThirstyAffiliates\Models;
|
3 |
-
|
4 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
-
|
6 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
7 |
-
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
-
use ThirstyAffiliates\Interfaces\Deactivatable_Interface;
|
10 |
-
|
11 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
12 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
13 |
-
|
14 |
-
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Model that houses the logic of 'Bootstraping' the plugin.
|
18 |
-
*
|
19 |
-
* @since 3.0.0
|
20 |
-
*/
|
21 |
-
class Bootstrap implements Model_Interface {
|
22 |
-
|
23 |
-
/*
|
24 |
-
|--------------------------------------------------------------------------
|
25 |
-
| Class Properties
|
26 |
-
|--------------------------------------------------------------------------
|
27 |
-
*/
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Property that holds the single main instance of Bootstrap.
|
31 |
-
*
|
32 |
-
* @since 3.0.0
|
33 |
-
* @access private
|
34 |
-
* @var Bootstrap
|
35 |
-
*/
|
36 |
-
private static $_instance;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Model that houses all the plugin constants.
|
40 |
-
*
|
41 |
-
* @since 3.0.0
|
42 |
-
* @access private
|
43 |
-
* @var Plugin_Constants
|
44 |
-
*/
|
45 |
-
private $_constants;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Property that houses all the helper functions of the plugin.
|
49 |
-
*
|
50 |
-
* @since 3.0.0
|
51 |
-
* @access private
|
52 |
-
* @var Helper_Functions
|
53 |
-
*/
|
54 |
-
private $_helper_functions;
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Array of models implementing the ThirstyAffiliates\Interfaces\Activatable_Interface.
|
58 |
-
*
|
59 |
-
* @since 3.0.0
|
60 |
-
* @access private
|
61 |
-
* @var array
|
62 |
-
*/
|
63 |
-
private $_activatables;
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Array of models implementing the ThirstyAffiliates\Interfaces\Initiable_Interface.
|
67 |
-
*
|
68 |
-
* @since 3.0.0
|
69 |
-
* @access private
|
70 |
-
* @var array
|
71 |
-
*/
|
72 |
-
private $_initiables;
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Array of models implementing the ThirstyAffiliates\Interfaces\Deactivatable_Interface.
|
76 |
-
*
|
77 |
-
* @since 3.1.0
|
78 |
-
* @access private
|
79 |
-
* @var array
|
80 |
-
*/
|
81 |
-
private $_deactivatables;
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
/*
|
87 |
-
|--------------------------------------------------------------------------
|
88 |
-
| Class Methods
|
89 |
-
|--------------------------------------------------------------------------
|
90 |
-
*/
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Class constructor.
|
94 |
-
*
|
95 |
-
* @since 3.0.0
|
96 |
-
* @since 3.1.0 Add deactivatables interface.
|
97 |
-
* @access public
|
98 |
-
*
|
99 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
100 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
101 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
102 |
-
* @param array $activatables Array of models implementing ThirstyAffiliates\Interfaces\Activatable_Interface.
|
103 |
-
* @param array $initiables Array of models implementing ThirstyAffiliates\Interfaces\Initiable_Interface.
|
104 |
-
* @param array $deactivatables Array of models implementing ThirstyAffiliates\Interfaces\Deactivatable_Interface.
|
105 |
-
*/
|
106 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions , array $activatables = array() , array $initiables = array() , array $deactivatables = array() ) {
|
107 |
-
|
108 |
-
$this->_constants = $constants;
|
109 |
-
$this->_helper_functions = $helper_functions;
|
110 |
-
$this->_activatables = $activatables;
|
111 |
-
$this->_initiables = $initiables;
|
112 |
-
$this->_deactivatables = $deactivatables;
|
113 |
-
|
114 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
115 |
-
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
120 |
-
*
|
121 |
-
* @since 3.0.0
|
122 |
-
* @access public
|
123 |
-
*
|
124 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
125 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
126 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
127 |
-
* @param array $activatables Array of models implementing ThirstyAffiliates\Interfaces\Activatable_Interface.
|
128 |
-
* @param array $initiables Array of models implementing ThirstyAffiliates\Interfaces\Initiable_Interface.
|
129 |
-
* @return Bootstrap
|
130 |
-
*/
|
131 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions , array $activatables = array() , array $initiables = array() , array $deactivatables = array() ) {
|
132 |
-
|
133 |
-
if ( !self::$_instance instanceof self )
|
134 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions , $activatables , $initiables , $deactivatables );
|
135 |
-
|
136 |
-
return self::$_instance;
|
137 |
-
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Load plugin text domain.
|
142 |
-
*
|
143 |
-
* @since 3.0.0
|
144 |
-
* @access public
|
145 |
-
*/
|
146 |
-
public function load_plugin_textdomain() {
|
147 |
-
|
148 |
-
load_plugin_textdomain( Plugin_Constants::TEXT_DOMAIN , false , $this->_constants->PLUGIN_DIRNAME() . '/languages' );
|
149 |
-
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Method that houses the logic relating to activating the plugin.
|
154 |
-
*
|
155 |
-
* @since 3.0.0
|
156 |
-
* @access public
|
157 |
-
*
|
158 |
-
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
159 |
-
*
|
160 |
-
* @param boolean $network_wide Flag that determines whether the plugin has been activated network wid ( on multi site environment ) or not.
|
161 |
-
*/
|
162 |
-
public function activate_plugin( $network_wide ) {
|
163 |
-
|
164 |
-
// Suppress any errors
|
165 |
-
@deactivate_plugins( array(
|
166 |
-
'thirstyaffiliates-stats/thirstyaffiliates-stats.php',
|
167 |
-
'thirstyaffiliates-htaccess-redirect/thirstyaffiliates-htaccess-refactor.bootstrap.php',
|
168 |
-
'thirstyaffiliates-google-click-tracking/thirstyaffiliates-google-click-tracking.php',
|
169 |
-
'thirstyaffiliates-geolocations/thirstyaffiliates-geolocations.php',
|
170 |
-
'thirstyaffiliates-csv-importer/thirstyaffiliates-csv-importer.php',
|
171 |
-
'thirstyaffiliates-autolinker/thirstyaffiliates-autolinker.php',
|
172 |
-
'thirstyaffiliates-azon-add-on/azon-bootstrap.php',
|
173 |
-
'thirstyaffiliates-itunes/thirstyaffiliates-itunes.bootstrap.php'
|
174 |
-
) , true , null ); // Deactivate on all sites in the network and do not fire deactivation hooks
|
175 |
-
|
176 |
-
global $wpdb;
|
177 |
-
|
178 |
-
if ( is_multisite() ) {
|
179 |
-
|
180 |
-
if ( $network_wide ) {
|
181 |
-
|
182 |
-
// get ids of all sites
|
183 |
-
$blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
|
184 |
-
|
185 |
-
foreach ( $blog_ids as $blog_id ) {
|
186 |
-
|
187 |
-
switch_to_blog( $blog_id );
|
188 |
-
$this->_activate_plugin( $blog_id );
|
189 |
-
|
190 |
-
}
|
191 |
-
|
192 |
-
restore_current_blog();
|
193 |
-
|
194 |
-
} else
|
195 |
-
$this->_activate_plugin( $wpdb->blogid ); // activated on a single site, in a multi-site
|
196 |
-
|
197 |
-
} else
|
198 |
-
$this->_activate_plugin( $wpdb->blogid ); // activated on a single site
|
199 |
-
|
200 |
-
}
|
201 |
-
|
202 |
-
/**
|
203 |
-
* Method to initialize a newly created site in a multi site set up.
|
204 |
-
*
|
205 |
-
* @since 3.0.0
|
206 |
-
* @access public
|
207 |
-
*
|
208 |
-
* @param int $blogid Blog ID of the created blog.
|
209 |
-
* @param int $user_id User ID of the user creating the blog.
|
210 |
-
* @param string $domain Domain used for the new blog.
|
211 |
-
* @param string $path Path to the new blog.
|
212 |
-
* @param int $site_id Site ID. Only relevant on multi-network installs.
|
213 |
-
* @param array $meta Meta data. Used to set initial site options.
|
214 |
-
*/
|
215 |
-
public function new_mu_site_init( $blog_id , $user_id , $domain , $path , $site_id , $meta ) {
|
216 |
-
|
217 |
-
if ( is_plugin_active_for_network( 'thirstyaffiliates/thirstyaffiliates.php' ) ) {
|
218 |
-
|
219 |
-
switch_to_blog( $blog_id );
|
220 |
-
$this->_activate_plugin( $blog_id );
|
221 |
-
restore_current_blog();
|
222 |
-
|
223 |
-
}
|
224 |
-
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* Initialize plugin settings options.
|
229 |
-
* This is a compromise to my idea of 'Modularity'. Ideally, bootstrap should not take care of plugin settings stuff.
|
230 |
-
* However due to how WooCommerce do its thing, we need to do it this way. We can't separate settings on its own.
|
231 |
-
*
|
232 |
-
* @since 3.0.0
|
233 |
-
* @access private
|
234 |
-
*/
|
235 |
-
private function _initialize_plugin_settings_options() {
|
236 |
-
|
237 |
-
// Help settings section options
|
238 |
-
|
239 |
-
// Set initial value of 'no' for the option that sets the option that specify whether to delete the options on plugin uninstall. Optionception.
|
240 |
-
if ( !get_option( Plugin_Constants::CLEAN_UP_PLUGIN_OPTIONS , false ) )
|
241 |
-
update_option( Plugin_Constants::CLEAN_UP_PLUGIN_OPTIONS , 'no' );
|
242 |
-
|
243 |
-
// set redirect type default to '302' on activation.
|
244 |
-
if ( ! get_option( 'ta_link_redirect_type' , false ) )
|
245 |
-
update_option( 'ta_link_redirect_type' , 302 );
|
246 |
-
|
247 |
-
}
|
248 |
-
|
249 |
-
/**
|
250 |
-
* Actual function that houses the code to execute on plugin activation.
|
251 |
-
*
|
252 |
-
* @since 3.0.0
|
253 |
-
* @since 3.0.0 Added the ta_activation_date option
|
254 |
-
* @access private
|
255 |
-
*
|
256 |
-
* @param int $blogid Blog ID of the created blog.
|
257 |
-
*/
|
258 |
-
private function _activate_plugin( $blogid ) {
|
259 |
-
|
260 |
-
// Initialize settings options
|
261 |
-
$this->_initialize_plugin_settings_options();
|
262 |
-
|
263 |
-
// Create database tables
|
264 |
-
$this->_create_database_tables();
|
265 |
-
|
266 |
-
// set flush rewrite rules transient so it can be flushed after the CPT and rewrite rules have been registered.
|
267 |
-
set_transient( 'ta_flush_rewrite_rules' , 'true' , 5 * 60 );
|
268 |
-
|
269 |
-
// Execute 'activate' contract of models implementing ThirstyAffiliates\Interfaces\Activatable_Interface
|
270 |
-
foreach ( $this->_activatables as $activatable )
|
271 |
-
if ( $activatable instanceof Activatable_Interface )
|
272 |
-
$activatable->activate();
|
273 |
-
|
274 |
-
update_option( Plugin_Constants::INSTALLED_VERSION , Plugin_Constants::VERSION ); // Update current installed plugin version
|
275 |
-
update_option( 'ta_activation_code_triggered' , 'yes' ); // Mark activation code triggered
|
276 |
-
|
277 |
-
}
|
278 |
-
|
279 |
-
/**
|
280 |
-
* Method that houses the logic relating to deactivating the plugin.
|
281 |
-
*
|
282 |
-
* @since 3.0.0
|
283 |
-
* @access public
|
284 |
-
*
|
285 |
-
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
286 |
-
*
|
287 |
-
* @param boolean $network_wide Flag that determines whether the plugin has been activated network wid ( on multi site environment ) or not.
|
288 |
-
*/
|
289 |
-
public function deactivate_plugin( $network_wide ) {
|
290 |
-
|
291 |
-
global $wpdb;
|
292 |
-
|
293 |
-
// check if it is a multisite network
|
294 |
-
if ( is_multisite() ) {
|
295 |
-
|
296 |
-
// check if the plugin has been activated on the network or on a single site
|
297 |
-
if ( $network_wide ) {
|
298 |
-
|
299 |
-
// get ids of all sites
|
300 |
-
$blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
|
301 |
-
|
302 |
-
foreach ( $blog_ids as $blog_id ) {
|
303 |
-
|
304 |
-
switch_to_blog( $blog_id );
|
305 |
-
$this->_deactivate_plugin( $wpdb->blogid );
|
306 |
-
|
307 |
-
}
|
308 |
-
|
309 |
-
restore_current_blog();
|
310 |
-
|
311 |
-
} else
|
312 |
-
$this->_deactivate_plugin( $wpdb->blogid ); // activated on a single site, in a multi-site
|
313 |
-
|
314 |
-
} else
|
315 |
-
$this->_deactivate_plugin( $wpdb->blogid ); // activated on a single site
|
316 |
-
|
317 |
-
}
|
318 |
-
|
319 |
-
/**
|
320 |
-
* Actual method that houses the code to execute on plugin deactivation.
|
321 |
-
*
|
322 |
-
* @since 3.0.0
|
323 |
-
* @access private
|
324 |
-
*
|
325 |
-
* @param int $blogid Blog ID of the created blog.
|
326 |
-
*/
|
327 |
-
private function _deactivate_plugin( $blogid ) {
|
328 |
-
|
329 |
-
// Execute 'deactivate' contract of models implementing ThirstyAffiliates\Interfaces\Deactivatable_Interface
|
330 |
-
foreach ( $this->_deactivatables as $deactivatable )
|
331 |
-
if ( $deactivatable instanceof Deactivatable_Interface )
|
332 |
-
$deactivatable->deactivate();
|
333 |
-
|
334 |
-
flush_rewrite_rules();
|
335 |
-
|
336 |
-
}
|
337 |
-
|
338 |
-
/**
|
339 |
-
* Create database tables.
|
340 |
-
*
|
341 |
-
* @since 3.0.0
|
342 |
-
* @access private
|
343 |
-
*/
|
344 |
-
private function _create_database_tables() {
|
345 |
-
|
346 |
-
global $wpdb;
|
347 |
-
|
348 |
-
if ( get_option( 'ta_database_tables_created' ) === 'yes' )
|
349 |
-
return;
|
350 |
-
|
351 |
-
$link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
352 |
-
$link_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
353 |
-
$charset_collate = $wpdb->get_charset_collate();
|
354 |
-
|
355 |
-
// link clicks db sql command
|
356 |
-
$sql = "CREATE TABLE $link_click_db (
|
357 |
-
id bigint(20) NOT NULL AUTO_INCREMENT,
|
358 |
-
link_id bigint(20) NOT NULL,
|
359 |
-
date_clicked datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
360 |
-
PRIMARY KEY (id)
|
361 |
-
) $charset_collate;\n";
|
362 |
-
|
363 |
-
// link clicks meta db sql command
|
364 |
-
$sql .= "CREATE TABLE $link_click_meta_db (
|
365 |
-
id bigint(20) NOT NULL AUTO_INCREMENT,
|
366 |
-
click_id bigint(20) NOT NULL,
|
367 |
-
meta_key varchar(255) NULL,
|
368 |
-
meta_value longtext NULL,
|
369 |
-
PRIMARY KEY (id)
|
370 |
-
) $charset_collate;";
|
371 |
-
|
372 |
-
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
373 |
-
dbDelta( $sql );
|
374 |
-
|
375 |
-
update_option( 'ta_database_tables_created' , 'yes' );
|
376 |
-
}
|
377 |
-
|
378 |
-
/**
|
379 |
-
* Add custom links to the plugin's action links.
|
380 |
-
*
|
381 |
-
* @since 3.0.0
|
382 |
-
* @access public
|
383 |
-
*/
|
384 |
-
public function plugin_action_links( $links ) {
|
385 |
-
|
386 |
-
$settings_link = admin_url( 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT . '&page=thirsty-settings' );
|
387 |
-
|
388 |
-
$new_links = array(
|
389 |
-
'<a href="' . $settings_link . '">' . __( 'Settings' , 'thirstyaffiliates' ) . '</a>'
|
390 |
-
);
|
391 |
-
|
392 |
-
return array_merge( $new_links , $links );
|
393 |
-
}
|
394 |
-
|
395 |
-
/**
|
396 |
-
* Control admin interface visibility.
|
397 |
-
*
|
398 |
-
* @since 3.3.2
|
399 |
-
* @access public
|
400 |
-
*/
|
401 |
-
public function admin_interface_visibility() {
|
402 |
-
|
403 |
-
$object_id = isset( $_GET[ 'post' ] ) ? absint( $_GET[ 'post' ] ) : 0;
|
404 |
-
|
405 |
-
if ( ! $screen_id = $this->_helper_functions->get_screen_id( $object_id ) )
|
406 |
-
return;
|
407 |
-
|
408 |
-
$current_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : '';
|
409 |
-
$post_type = isset( $_GET[ 'post_type' ] ) ? sanitize_text_field( $_GET[ 'post_type' ] ) : '';
|
410 |
-
$interfaces = apply_filters( 'ta_admin_interfaces' , array() );
|
411 |
-
$current_interface = $screen_id && isset( $interfaces[ $screen_id ] ) ? $interfaces[ $screen_id ] : null;
|
412 |
-
|
413 |
-
// if interface is not present then don't proceed
|
414 |
-
if ( ! $current_interface || empty( $current_interface ) ) return;
|
415 |
-
if ( $current_tab && ! isset( $current_interface[ $current_tab ] ) ) return;
|
416 |
-
|
417 |
-
// get the capability allowed for the interface
|
418 |
-
if ( is_array( $current_interface ) )
|
419 |
-
$capability = $current_tab ? $current_interface[ $current_tab ] : array_values( $current_interface )[0];
|
420 |
-
else
|
421 |
-
$capability = $current_interface;
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
//
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
*
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
$
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
*
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
*
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
//
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
add_action( '
|
515 |
-
|
516 |
-
|
517 |
-
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ThirstyAffiliates\Models;
|
3 |
+
|
4 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
+
|
6 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
7 |
+
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
+
use ThirstyAffiliates\Interfaces\Deactivatable_Interface;
|
10 |
+
|
11 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
12 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
13 |
+
|
14 |
+
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Model that houses the logic of 'Bootstraping' the plugin.
|
18 |
+
*
|
19 |
+
* @since 3.0.0
|
20 |
+
*/
|
21 |
+
class Bootstrap implements Model_Interface {
|
22 |
+
|
23 |
+
/*
|
24 |
+
|--------------------------------------------------------------------------
|
25 |
+
| Class Properties
|
26 |
+
|--------------------------------------------------------------------------
|
27 |
+
*/
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Property that holds the single main instance of Bootstrap.
|
31 |
+
*
|
32 |
+
* @since 3.0.0
|
33 |
+
* @access private
|
34 |
+
* @var Bootstrap
|
35 |
+
*/
|
36 |
+
private static $_instance;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Model that houses all the plugin constants.
|
40 |
+
*
|
41 |
+
* @since 3.0.0
|
42 |
+
* @access private
|
43 |
+
* @var Plugin_Constants
|
44 |
+
*/
|
45 |
+
private $_constants;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Property that houses all the helper functions of the plugin.
|
49 |
+
*
|
50 |
+
* @since 3.0.0
|
51 |
+
* @access private
|
52 |
+
* @var Helper_Functions
|
53 |
+
*/
|
54 |
+
private $_helper_functions;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Array of models implementing the ThirstyAffiliates\Interfaces\Activatable_Interface.
|
58 |
+
*
|
59 |
+
* @since 3.0.0
|
60 |
+
* @access private
|
61 |
+
* @var array
|
62 |
+
*/
|
63 |
+
private $_activatables;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Array of models implementing the ThirstyAffiliates\Interfaces\Initiable_Interface.
|
67 |
+
*
|
68 |
+
* @since 3.0.0
|
69 |
+
* @access private
|
70 |
+
* @var array
|
71 |
+
*/
|
72 |
+
private $_initiables;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Array of models implementing the ThirstyAffiliates\Interfaces\Deactivatable_Interface.
|
76 |
+
*
|
77 |
+
* @since 3.1.0
|
78 |
+
* @access private
|
79 |
+
* @var array
|
80 |
+
*/
|
81 |
+
private $_deactivatables;
|
82 |
+
|
83 |
+
|
84 |
+
|
85 |
+
|
86 |
+
/*
|
87 |
+
|--------------------------------------------------------------------------
|
88 |
+
| Class Methods
|
89 |
+
|--------------------------------------------------------------------------
|
90 |
+
*/
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Class constructor.
|
94 |
+
*
|
95 |
+
* @since 3.0.0
|
96 |
+
* @since 3.1.0 Add deactivatables interface.
|
97 |
+
* @access public
|
98 |
+
*
|
99 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
100 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
101 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
102 |
+
* @param array $activatables Array of models implementing ThirstyAffiliates\Interfaces\Activatable_Interface.
|
103 |
+
* @param array $initiables Array of models implementing ThirstyAffiliates\Interfaces\Initiable_Interface.
|
104 |
+
* @param array $deactivatables Array of models implementing ThirstyAffiliates\Interfaces\Deactivatable_Interface.
|
105 |
+
*/
|
106 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions , array $activatables = array() , array $initiables = array() , array $deactivatables = array() ) {
|
107 |
+
|
108 |
+
$this->_constants = $constants;
|
109 |
+
$this->_helper_functions = $helper_functions;
|
110 |
+
$this->_activatables = $activatables;
|
111 |
+
$this->_initiables = $initiables;
|
112 |
+
$this->_deactivatables = $deactivatables;
|
113 |
+
|
114 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
115 |
+
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
120 |
+
*
|
121 |
+
* @since 3.0.0
|
122 |
+
* @access public
|
123 |
+
*
|
124 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
125 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
126 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
127 |
+
* @param array $activatables Array of models implementing ThirstyAffiliates\Interfaces\Activatable_Interface.
|
128 |
+
* @param array $initiables Array of models implementing ThirstyAffiliates\Interfaces\Initiable_Interface.
|
129 |
+
* @return Bootstrap
|
130 |
+
*/
|
131 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions , array $activatables = array() , array $initiables = array() , array $deactivatables = array() ) {
|
132 |
+
|
133 |
+
if ( !self::$_instance instanceof self )
|
134 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions , $activatables , $initiables , $deactivatables );
|
135 |
+
|
136 |
+
return self::$_instance;
|
137 |
+
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Load plugin text domain.
|
142 |
+
*
|
143 |
+
* @since 3.0.0
|
144 |
+
* @access public
|
145 |
+
*/
|
146 |
+
public function load_plugin_textdomain() {
|
147 |
+
|
148 |
+
load_plugin_textdomain( Plugin_Constants::TEXT_DOMAIN , false , $this->_constants->PLUGIN_DIRNAME() . '/languages' );
|
149 |
+
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Method that houses the logic relating to activating the plugin.
|
154 |
+
*
|
155 |
+
* @since 3.0.0
|
156 |
+
* @access public
|
157 |
+
*
|
158 |
+
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
159 |
+
*
|
160 |
+
* @param boolean $network_wide Flag that determines whether the plugin has been activated network wid ( on multi site environment ) or not.
|
161 |
+
*/
|
162 |
+
public function activate_plugin( $network_wide ) {
|
163 |
+
|
164 |
+
// Suppress any errors
|
165 |
+
@deactivate_plugins( array(
|
166 |
+
'thirstyaffiliates-stats/thirstyaffiliates-stats.php',
|
167 |
+
'thirstyaffiliates-htaccess-redirect/thirstyaffiliates-htaccess-refactor.bootstrap.php',
|
168 |
+
'thirstyaffiliates-google-click-tracking/thirstyaffiliates-google-click-tracking.php',
|
169 |
+
'thirstyaffiliates-geolocations/thirstyaffiliates-geolocations.php',
|
170 |
+
'thirstyaffiliates-csv-importer/thirstyaffiliates-csv-importer.php',
|
171 |
+
'thirstyaffiliates-autolinker/thirstyaffiliates-autolinker.php',
|
172 |
+
'thirstyaffiliates-azon-add-on/azon-bootstrap.php',
|
173 |
+
'thirstyaffiliates-itunes/thirstyaffiliates-itunes.bootstrap.php'
|
174 |
+
) , true , null ); // Deactivate on all sites in the network and do not fire deactivation hooks
|
175 |
+
|
176 |
+
global $wpdb;
|
177 |
+
|
178 |
+
if ( is_multisite() ) {
|
179 |
+
|
180 |
+
if ( $network_wide ) {
|
181 |
+
|
182 |
+
// get ids of all sites
|
183 |
+
$blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
|
184 |
+
|
185 |
+
foreach ( $blog_ids as $blog_id ) {
|
186 |
+
|
187 |
+
switch_to_blog( $blog_id );
|
188 |
+
$this->_activate_plugin( $blog_id );
|
189 |
+
|
190 |
+
}
|
191 |
+
|
192 |
+
restore_current_blog();
|
193 |
+
|
194 |
+
} else
|
195 |
+
$this->_activate_plugin( $wpdb->blogid ); // activated on a single site, in a multi-site
|
196 |
+
|
197 |
+
} else
|
198 |
+
$this->_activate_plugin( $wpdb->blogid ); // activated on a single site
|
199 |
+
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Method to initialize a newly created site in a multi site set up.
|
204 |
+
*
|
205 |
+
* @since 3.0.0
|
206 |
+
* @access public
|
207 |
+
*
|
208 |
+
* @param int $blogid Blog ID of the created blog.
|
209 |
+
* @param int $user_id User ID of the user creating the blog.
|
210 |
+
* @param string $domain Domain used for the new blog.
|
211 |
+
* @param string $path Path to the new blog.
|
212 |
+
* @param int $site_id Site ID. Only relevant on multi-network installs.
|
213 |
+
* @param array $meta Meta data. Used to set initial site options.
|
214 |
+
*/
|
215 |
+
public function new_mu_site_init( $blog_id , $user_id , $domain , $path , $site_id , $meta ) {
|
216 |
+
|
217 |
+
if ( is_plugin_active_for_network( 'thirstyaffiliates/thirstyaffiliates.php' ) ) {
|
218 |
+
|
219 |
+
switch_to_blog( $blog_id );
|
220 |
+
$this->_activate_plugin( $blog_id );
|
221 |
+
restore_current_blog();
|
222 |
+
|
223 |
+
}
|
224 |
+
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Initialize plugin settings options.
|
229 |
+
* This is a compromise to my idea of 'Modularity'. Ideally, bootstrap should not take care of plugin settings stuff.
|
230 |
+
* However due to how WooCommerce do its thing, we need to do it this way. We can't separate settings on its own.
|
231 |
+
*
|
232 |
+
* @since 3.0.0
|
233 |
+
* @access private
|
234 |
+
*/
|
235 |
+
private function _initialize_plugin_settings_options() {
|
236 |
+
|
237 |
+
// Help settings section options
|
238 |
+
|
239 |
+
// Set initial value of 'no' for the option that sets the option that specify whether to delete the options on plugin uninstall. Optionception.
|
240 |
+
if ( !get_option( Plugin_Constants::CLEAN_UP_PLUGIN_OPTIONS , false ) )
|
241 |
+
update_option( Plugin_Constants::CLEAN_UP_PLUGIN_OPTIONS , 'no' );
|
242 |
+
|
243 |
+
// set redirect type default to '302' on activation.
|
244 |
+
if ( ! get_option( 'ta_link_redirect_type' , false ) )
|
245 |
+
update_option( 'ta_link_redirect_type' , 302 );
|
246 |
+
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Actual function that houses the code to execute on plugin activation.
|
251 |
+
*
|
252 |
+
* @since 3.0.0
|
253 |
+
* @since 3.0.0 Added the ta_activation_date option
|
254 |
+
* @access private
|
255 |
+
*
|
256 |
+
* @param int $blogid Blog ID of the created blog.
|
257 |
+
*/
|
258 |
+
private function _activate_plugin( $blogid ) {
|
259 |
+
|
260 |
+
// Initialize settings options
|
261 |
+
$this->_initialize_plugin_settings_options();
|
262 |
+
|
263 |
+
// Create database tables
|
264 |
+
$this->_create_database_tables();
|
265 |
+
|
266 |
+
// set flush rewrite rules transient so it can be flushed after the CPT and rewrite rules have been registered.
|
267 |
+
set_transient( 'ta_flush_rewrite_rules' , 'true' , 5 * 60 );
|
268 |
+
|
269 |
+
// Execute 'activate' contract of models implementing ThirstyAffiliates\Interfaces\Activatable_Interface
|
270 |
+
foreach ( $this->_activatables as $activatable )
|
271 |
+
if ( $activatable instanceof Activatable_Interface )
|
272 |
+
$activatable->activate();
|
273 |
+
|
274 |
+
update_option( Plugin_Constants::INSTALLED_VERSION , Plugin_Constants::VERSION ); // Update current installed plugin version
|
275 |
+
update_option( 'ta_activation_code_triggered' , 'yes' ); // Mark activation code triggered
|
276 |
+
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Method that houses the logic relating to deactivating the plugin.
|
281 |
+
*
|
282 |
+
* @since 3.0.0
|
283 |
+
* @access public
|
284 |
+
*
|
285 |
+
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
286 |
+
*
|
287 |
+
* @param boolean $network_wide Flag that determines whether the plugin has been activated network wid ( on multi site environment ) or not.
|
288 |
+
*/
|
289 |
+
public function deactivate_plugin( $network_wide ) {
|
290 |
+
|
291 |
+
global $wpdb;
|
292 |
+
|
293 |
+
// check if it is a multisite network
|
294 |
+
if ( is_multisite() ) {
|
295 |
+
|
296 |
+
// check if the plugin has been activated on the network or on a single site
|
297 |
+
if ( $network_wide ) {
|
298 |
+
|
299 |
+
// get ids of all sites
|
300 |
+
$blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
|
301 |
+
|
302 |
+
foreach ( $blog_ids as $blog_id ) {
|
303 |
+
|
304 |
+
switch_to_blog( $blog_id );
|
305 |
+
$this->_deactivate_plugin( $wpdb->blogid );
|
306 |
+
|
307 |
+
}
|
308 |
+
|
309 |
+
restore_current_blog();
|
310 |
+
|
311 |
+
} else
|
312 |
+
$this->_deactivate_plugin( $wpdb->blogid ); // activated on a single site, in a multi-site
|
313 |
+
|
314 |
+
} else
|
315 |
+
$this->_deactivate_plugin( $wpdb->blogid ); // activated on a single site
|
316 |
+
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Actual method that houses the code to execute on plugin deactivation.
|
321 |
+
*
|
322 |
+
* @since 3.0.0
|
323 |
+
* @access private
|
324 |
+
*
|
325 |
+
* @param int $blogid Blog ID of the created blog.
|
326 |
+
*/
|
327 |
+
private function _deactivate_plugin( $blogid ) {
|
328 |
+
|
329 |
+
// Execute 'deactivate' contract of models implementing ThirstyAffiliates\Interfaces\Deactivatable_Interface
|
330 |
+
foreach ( $this->_deactivatables as $deactivatable )
|
331 |
+
if ( $deactivatable instanceof Deactivatable_Interface )
|
332 |
+
$deactivatable->deactivate();
|
333 |
+
|
334 |
+
flush_rewrite_rules();
|
335 |
+
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Create database tables.
|
340 |
+
*
|
341 |
+
* @since 3.0.0
|
342 |
+
* @access private
|
343 |
+
*/
|
344 |
+
private function _create_database_tables() {
|
345 |
+
|
346 |
+
global $wpdb;
|
347 |
+
|
348 |
+
if ( get_option( 'ta_database_tables_created' ) === 'yes' )
|
349 |
+
return;
|
350 |
+
|
351 |
+
$link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
352 |
+
$link_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
353 |
+
$charset_collate = $wpdb->get_charset_collate();
|
354 |
+
|
355 |
+
// link clicks db sql command
|
356 |
+
$sql = "CREATE TABLE $link_click_db (
|
357 |
+
id bigint(20) NOT NULL AUTO_INCREMENT,
|
358 |
+
link_id bigint(20) NOT NULL,
|
359 |
+
date_clicked datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
|
360 |
+
PRIMARY KEY (id)
|
361 |
+
) $charset_collate;\n";
|
362 |
+
|
363 |
+
// link clicks meta db sql command
|
364 |
+
$sql .= "CREATE TABLE $link_click_meta_db (
|
365 |
+
id bigint(20) NOT NULL AUTO_INCREMENT,
|
366 |
+
click_id bigint(20) NOT NULL,
|
367 |
+
meta_key varchar(255) NULL,
|
368 |
+
meta_value longtext NULL,
|
369 |
+
PRIMARY KEY (id)
|
370 |
+
) $charset_collate;";
|
371 |
+
|
372 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
373 |
+
dbDelta( $sql );
|
374 |
+
|
375 |
+
update_option( 'ta_database_tables_created' , 'yes' );
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Add custom links to the plugin's action links.
|
380 |
+
*
|
381 |
+
* @since 3.0.0
|
382 |
+
* @access public
|
383 |
+
*/
|
384 |
+
public function plugin_action_links( $links ) {
|
385 |
+
|
386 |
+
$settings_link = admin_url( 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT . '&page=thirsty-settings' );
|
387 |
+
|
388 |
+
$new_links = array(
|
389 |
+
'<a href="' . $settings_link . '">' . __( 'Settings' , 'thirstyaffiliates' ) . '</a>'
|
390 |
+
);
|
391 |
+
|
392 |
+
return array_merge( $new_links , $links );
|
393 |
+
}
|
394 |
+
|
395 |
+
/**
|
396 |
+
* Control admin interface visibility.
|
397 |
+
*
|
398 |
+
* @since 3.3.2
|
399 |
+
* @access public
|
400 |
+
*/
|
401 |
+
public function admin_interface_visibility() {
|
402 |
+
|
403 |
+
$object_id = isset( $_GET[ 'post' ] ) ? absint( $_GET[ 'post' ] ) : 0;
|
404 |
+
|
405 |
+
if ( ! $screen_id = $this->_helper_functions->get_screen_id( $object_id ) )
|
406 |
+
return;
|
407 |
+
|
408 |
+
$current_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : '';
|
409 |
+
$post_type = isset( $_GET[ 'post_type' ] ) ? sanitize_text_field( $_GET[ 'post_type' ] ) : '';
|
410 |
+
$interfaces = apply_filters( 'ta_admin_interfaces' , array() );
|
411 |
+
$current_interface = $screen_id && isset( $interfaces[ $screen_id ] ) ? $interfaces[ $screen_id ] : null;
|
412 |
+
|
413 |
+
// if interface is not present then don't proceed
|
414 |
+
if ( ! $current_interface || empty( $current_interface ) ) return;
|
415 |
+
if ( $current_tab && ! isset( $current_interface[ $current_tab ] ) ) return;
|
416 |
+
|
417 |
+
// get the capability allowed for the interface
|
418 |
+
if ( is_array( $current_interface ) )
|
419 |
+
$capability = $current_tab ? $current_interface[ $current_tab ] : array_values( $current_interface )[0];
|
420 |
+
else
|
421 |
+
$capability = $current_interface;
|
422 |
+
|
423 |
+
if ( $current_tab === 'ta_import_export_settings' )
|
424 |
+
$capability = 'manage_options';
|
425 |
+
|
426 |
+
// get error message.
|
427 |
+
$error_message = apply_filters( 'ta_admin_interface_error_message' , __( "Sorry, you are not allowed to access this page." , 'thirstyaffiliates' ) , $screen_id , $current_tab , $capability , $current_interface );
|
428 |
+
|
429 |
+
// kill page display error message if current user does not have capability.
|
430 |
+
if ( ( $capability && ! current_user_can( $capability ) ) || ( $object_id && isset( $_GET[ 'post' ] ) && get_current_user_id() != get_post_field( 'post_author' , $object_id ) && ! current_user_can( 'edit_others_posts' ) ) )
|
431 |
+
wp_die( $error_message );
|
432 |
+
}
|
433 |
+
|
434 |
+
/**
|
435 |
+
* Control admin menu items visibility.
|
436 |
+
*
|
437 |
+
* @since 3.3.2
|
438 |
+
* @access public
|
439 |
+
*/
|
440 |
+
public function admin_menu_items_visibilty() {
|
441 |
+
|
442 |
+
global $submenu;
|
443 |
+
|
444 |
+
$menu_slug = 'edit.php?post_type=' . Plugin_Constants::AFFILIATE_LINKS_CPT;
|
445 |
+
$menu_items = apply_filters( 'ta_menu_items' , array() );
|
446 |
+
$main_cap = null;
|
447 |
+
|
448 |
+
if ( ! is_array( $menu_items ) || empty( $menu_items ) ) return;
|
449 |
+
|
450 |
+
foreach ( $menu_items as $submenu_slug => $capability ) {
|
451 |
+
|
452 |
+
if ( $submenu_slug == $menu_slug ) {
|
453 |
+
$main_cap = $capability;
|
454 |
+
continue;
|
455 |
+
}
|
456 |
+
|
457 |
+
if ( $capability && ! current_user_can( $capability ) )
|
458 |
+
remove_submenu_page( $menu_slug , esc_attr( $submenu_slug ) );
|
459 |
+
}
|
460 |
+
|
461 |
+
$menu_count = isset( $submenu[ $menu_slug ] ) ? count( $submenu[ $menu_slug ] ) : 0;
|
462 |
+
|
463 |
+
if ( ( ! $main_cap || ! current_user_can( $main_cap ) ) && $menu_count <= 1 )
|
464 |
+
remove_menu_page( $menu_slug );
|
465 |
+
}
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Method that houses codes to be executed on init hook.
|
469 |
+
*
|
470 |
+
* @since 3.0.0
|
471 |
+
* @access public
|
472 |
+
*/
|
473 |
+
public function initialize() {
|
474 |
+
|
475 |
+
// Execute activation codebase if not yet executed on plugin activation ( Mostly due to plugin dependencies )
|
476 |
+
if ( get_option( 'ta_activation_code_triggered' , false ) !== 'yes' ) {
|
477 |
+
|
478 |
+
if ( ! function_exists( 'is_plugin_active_for_network' ) )
|
479 |
+
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
480 |
+
|
481 |
+
$network_wide = is_plugin_active_for_network( 'thirstyaffiliates/thirstyaffiliates.php' );
|
482 |
+
$this->activate_plugin( $network_wide );
|
483 |
+
|
484 |
+
}
|
485 |
+
|
486 |
+
// Execute 'initialize' contract of models implementing ThirstyAffiliates\Interfaces\Initiable_Interface
|
487 |
+
foreach ( $this->_initiables as $initiable )
|
488 |
+
if ( $initiable instanceof Initiable_Interface )
|
489 |
+
$initiable->initialize();
|
490 |
+
|
491 |
+
}
|
492 |
+
|
493 |
+
/**
|
494 |
+
* Execute plugin bootstrap code.
|
495 |
+
*
|
496 |
+
* @since 3.0.0
|
497 |
+
* @access public
|
498 |
+
*/
|
499 |
+
public function run() {
|
500 |
+
|
501 |
+
// Internationalization
|
502 |
+
add_action( 'plugins_loaded' , array( $this , 'load_plugin_textdomain' ) );
|
503 |
+
|
504 |
+
// Execute plugin activation/deactivation
|
505 |
+
register_activation_hook( $this->_constants->MAIN_PLUGIN_FILE_PATH() , array( $this , 'activate_plugin' ) );
|
506 |
+
register_deactivation_hook( $this->_constants->MAIN_PLUGIN_FILE_PATH() , array( $this , 'deactivate_plugin' ) );
|
507 |
+
|
508 |
+
// Execute plugin initialization ( plugin activation ) on every newly created site in a multi site set up
|
509 |
+
add_action( 'wpmu_new_blog' , array( $this , 'new_mu_site_init' ) , 10 , 6 );
|
510 |
+
|
511 |
+
add_filter( 'plugin_action_links_' . $this->_constants->PLUGIN_BASENAME() , array( $this , 'plugin_action_links' ) );
|
512 |
+
|
513 |
+
// Execute codes that need to run on 'init' hook
|
514 |
+
add_action( 'init' , array( $this , 'initialize' ) );
|
515 |
+
|
516 |
+
add_action( 'init' , array( $this , 'admin_interface_visibility' ) );
|
517 |
+
add_action( 'admin_menu' , array( $this , 'admin_menu_items_visibilty' ) , 20 );
|
518 |
+
}
|
519 |
+
|
520 |
+
}
|
Models/Guided_Tour.php
CHANGED
@@ -1,389 +1,389 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
10 |
-
|
11 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
12 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
16 |
-
*
|
17 |
-
* @since 3.0.0
|
18 |
-
*/
|
19 |
-
class Guided_Tour implements Model_Interface , Activatable_Interface , Initiable_Interface {
|
20 |
-
|
21 |
-
/*
|
22 |
-
|--------------------------------------------------------------------------
|
23 |
-
| Class Properties
|
24 |
-
|--------------------------------------------------------------------------
|
25 |
-
*/
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Property that holds the single main instance of Shortcodes.
|
29 |
-
*
|
30 |
-
* @since 3.0.0
|
31 |
-
* @access private
|
32 |
-
* @var Redirection
|
33 |
-
*/
|
34 |
-
private static $_instance;
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Model that houses the main plugin object.
|
38 |
-
*
|
39 |
-
* @since 3.0.0
|
40 |
-
* @access private
|
41 |
-
* @var Redirection
|
42 |
-
*/
|
43 |
-
private $_main_plugin;
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Model that houses all the plugin constants.
|
47 |
-
*
|
48 |
-
* @since 3.0.0
|
49 |
-
* @access private
|
50 |
-
* @var Plugin_Constants
|
51 |
-
*/
|
52 |
-
private $_constants;
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Property that houses all the helper functions of the plugin.
|
56 |
-
*
|
57 |
-
* @since 3.0.0
|
58 |
-
* @access private
|
59 |
-
* @var Helper_Functions
|
60 |
-
*/
|
61 |
-
private $_helper_functions;
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Property that urls of the guided tour screens.
|
65 |
-
*
|
66 |
-
* @since 3.0.0
|
67 |
-
* @access private
|
68 |
-
* @var array
|
69 |
-
*/
|
70 |
-
private $_urls = array();
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Property that houses the screens of the guided tour.
|
74 |
-
*
|
75 |
-
* @since 3.0.0
|
76 |
-
* @access private
|
77 |
-
* @var array
|
78 |
-
*/
|
79 |
-
private $_screens = array();
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
/*
|
85 |
-
|--------------------------------------------------------------------------
|
86 |
-
| Class Methods
|
87 |
-
|--------------------------------------------------------------------------
|
88 |
-
*/
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Class constructor.
|
92 |
-
*
|
93 |
-
* @since 3.0.0
|
94 |
-
* @access public
|
95 |
-
*
|
96 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
97 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
98 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
99 |
-
*/
|
100 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
101 |
-
|
102 |
-
$this->_constants = $constants;
|
103 |
-
$this->_helper_functions = $helper_functions;
|
104 |
-
|
105 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
110 |
-
*
|
111 |
-
* @since 3.0.0
|
112 |
-
* @access public
|
113 |
-
*
|
114 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
115 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
116 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
117 |
-
* @return Redirection
|
118 |
-
*/
|
119 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
120 |
-
|
121 |
-
if ( !self::$_instance instanceof self )
|
122 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
123 |
-
|
124 |
-
return self::$_instance;
|
125 |
-
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Define guided tour pages.
|
130 |
-
*
|
131 |
-
* @since 3.0.0
|
132 |
-
* @access private
|
133 |
-
*/
|
134 |
-
private function define_guided_tour_pages() {
|
135 |
-
|
136 |
-
$this->_urls = apply_filters( 'ta_guided_tour_pages' , array(
|
137 |
-
'plugin-listing' => admin_url( 'plugins.php' ),
|
138 |
-
'affiliate-links-listing' => admin_url( 'edit.php?post_type=thirstylink' ),
|
139 |
-
'new-wp-post' => admin_url( 'post-new.php' ),
|
140 |
-
'general-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings' ),
|
141 |
-
'link-apperance-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_links_settings' ),
|
142 |
-
'modules-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_modules_settings' ),
|
143 |
-
'import-export-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_import_export_settings' ),
|
144 |
-
'help-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_help_settings' ),
|
145 |
-
'new-affiliate-link' => admin_url( 'post-new.php?post_type=thirstylink' ),
|
146 |
-
) );
|
147 |
-
|
148 |
-
$this->_screens = apply_filters( 'ta_guided_tours' , array(
|
149 |
-
'plugins' => array(
|
150 |
-
'elem' => '#menu-posts-thirstylink .menu-top',
|
151 |
-
'html' => __( '<h3>Congratulations, you just activated ThirstyAffiliates!</h3>
|
152 |
-
<p>Would you like to take a tour of the plugin features? It takes less than a minute and you\'ll then know exactly how to use the plugin.</p>', 'thirstyaffiliates' ),
|
153 |
-
'prev' => null,
|
154 |
-
'next' => $this->_urls[ 'affiliate-links-listing' ],
|
155 |
-
'edge' => 'left',
|
156 |
-
'align' => 'left',
|
157 |
-
),
|
158 |
-
'edit-thirstylink' => array(
|
159 |
-
'elem' => '#wpbody-content > .wrap > .wp-heading-inline',
|
160 |
-
'html' => __( '<h3>ThirstyAffiliates helps you manage affiliate links that you are given from the various affiliate programs you are a member of.</h3>
|
161 |
-
<p>It lets you hide long, and often confusing looking, affiliate link URLs behind another URL called a redirect. When your visitors click on that new URL they are automatically redirected to your affiliate link.</p>
|
162 |
-
<p>This is helpful for five reasons:</p>
|
163 |
-
<ol><li>AESTHETICS: Affiliate links are often long and ugly as mentioned and this can look off putting to visitors. ThirstyAffiliates redirects make them shorter and more attractive to click on like "http://example.com/recommends/some-product-name"</li>
|
164 |
-
<li>PROTECTION: It hides the affiliate code, so malicious software (malware) cannot sniff out the affiliate code for common affiliate programs and replace it with their own code instead. In this way, it protects your commissions.</li>
|
165 |
-
<li>CONVENIENCE: If the affiliate program ever changes the link code you’ll only have ONE place to change it on your blog, rather than going through all your content and changing every instance of the link.</li>
|
166 |
-
<li>CATEGORIZATION: You categorize your affiliate links into logical groups which can make managing them much simpler.</li>
|
167 |
-
<li>STATISTICS: Finally, because your visitors are travelling via a ThirstyAffiliates redirect, the plugin can provide you with statistics on what is being clicked.</li></ol>
|
168 |
-
<p>You can now create an “Affiliate Link” in this new section in your dashboard. This view shows you all the affiliate links you are managing with ThirstyAffiliates.</p>', 'thirstyaffiliates' ),
|
169 |
-
'prev' => $this->_urls[ 'plugin-listing' ],
|
170 |
-
'next' => $this->_urls[ 'new-wp-post' ],
|
171 |
-
'edge' => 'top',
|
172 |
-
'align' => 'left',
|
173 |
-
'width' => 600
|
174 |
-
),
|
175 |
-
'post' => array(
|
176 |
-
'elem' => '#wpbody #insert-media-button',
|
177 |
-
'html' => __( '<h3>Affiliate links can be added to your posts easily by clicking on the “TA” button on your editor.</h3>
|
178 |
-
<p>This works identically to the WordPress link tool, but only searches for affiliate links.</p>
|
179 |
-
<p>Give it a try by typing in some text, highlighting it, then clicking the “TA” button.</p>
|
180 |
-
<p>If you need to you can click the cog icon for an advanced search view which is handy for doing more advanced searches and for inserting images pre-wrapped with your affiliate link or via a shortcode instead.</p>', 'thirstyaffiliates' ),
|
181 |
-
'prev' => $this->_urls[ 'affiliate-links-listing' ],
|
182 |
-
'next' => $this->_urls[ 'general-settings' ],
|
183 |
-
'edge' => 'top',
|
184 |
-
'align' => 'left',
|
185 |
-
'width' => 400
|
186 |
-
),
|
187 |
-
'thirstylink_page_thirsty-settings' => array(
|
188 |
-
'ta_general_settings' => array(
|
189 |
-
'elem' => '.nav-tab-wrapper .ta_general_settings',
|
190 |
-
'html' => __( '<h3>ThirstyAffiliates has a number of settings that change the way it works, behaves and how your links appear.</h3>
|
191 |
-
<p>Here are the General settings which are for changing the way you work with ThirstyAffiliates in the backend.</p>', 'thirstyaffiliates' ),
|
192 |
-
'prev' => $this->_urls[ 'new-wp-post' ],
|
193 |
-
'next' => $this->_urls[ 'link-apperance-settings' ],
|
194 |
-
'edge' => 'top',
|
195 |
-
'align' => 'left',
|
196 |
-
),
|
197 |
-
'ta_links_settings' => array(
|
198 |
-
'elem' => '.nav-tab-wrapper .ta_links_settings',
|
199 |
-
'html' => __( '<h3>One of the most important parts of the settings area is Link Appearance which changes the way your links look to your visitors.</h3>
|
200 |
-
<p>This includes the Link Prefix setting which is important to decide on before you start using ThirstyAffiliates.</p>
|
201 |
-
<p>By default, this is set to “recommends” so your links will look like “http://example.com/recommends/some-product-name”.</p>
|
202 |
-
<p>You can also choose to include the category slug in the URL, change the way ThirstyAffiliates redirects links, add no follow, make links open in a new window and more.</p>', 'thirstyaffiliates' ),
|
203 |
-
'prev' => $this->_urls[ 'general-settings' ],
|
204 |
-
'next' => $this->_urls[ 'modules-settings' ],
|
205 |
-
'edge' => 'top',
|
206 |
-
'align' => 'left',
|
207 |
-
'width' => 450
|
208 |
-
),
|
209 |
-
'ta_modules_settings' => array(
|
210 |
-
'elem' => '.nav-tab-wrapper .ta_modules_settings',
|
211 |
-
'html' => __( '<h3>We built ThirstyAffiliates to be flexible and as such, you can shut down the parts of ThirstyAffiliates that aren’t being used. This can make the plugin faster.</h3>
|
212 |
-
<p>If you have the Pro add-on each Pro module will show in here as well.</p>', 'thirstyaffiliates' ),
|
213 |
-
'prev' => $this->_urls[ 'link-apperance-settings' ],
|
214 |
-
'next' => $this->_urls[ 'import-export-settings' ],
|
215 |
-
'edge' => 'top',
|
216 |
-
'align' => 'left',
|
217 |
-
),
|
218 |
-
'ta_import_export_settings' => array(
|
219 |
-
'elem' => '.nav-tab-wrapper .ta_import_export_settings',
|
220 |
-
'html' => __( '<h3>Setting up multiple sites with all running ThirstyAffiliates?</h3>
|
221 |
-
<p>We’ve made it super simple to configure your additional sites by being able to import and export ThirstyAffiliate settings.</p>
|
222 |
-
<p>Just copy the Export section and paste it into the Import section on your other site and ThirstyAffiliates will be automatically configured the same way.</p>', 'thirstyaffiliates' ),
|
223 |
-
'prev' => $this->_urls[ 'modules-settings' ],
|
224 |
-
'next' => $this->_urls[ 'help-settings' ],
|
225 |
-
'edge' => 'top',
|
226 |
-
'align' => 'right',
|
227 |
-
),
|
228 |
-
'ta_help_settings' => array(
|
229 |
-
'elem' => '.nav-tab-wrapper .ta_help_settings',
|
230 |
-
'html' => __( '<h3>Need some help with ThirstyAffiliates?</h3>
|
231 |
-
<p>We have a growing knowledge base filled with guides, troubleshooting and FAQ.</p>
|
232 |
-
<p>Our blog is also very active with lots of interesting affiliate marketing topics to help you grow your affiliate marketing empire.</p>', 'thirstyaffiliates' ),
|
233 |
-
'prev' => $this->_urls[ 'import-export-settings' ],
|
234 |
-
'next' => $this->_urls[ 'new-affiliate-link' ],
|
235 |
-
'edge' => 'top',
|
236 |
-
'align' => 'right',
|
237 |
-
)
|
238 |
-
),
|
239 |
-
'thirstylink' => array(
|
240 |
-
'elem' => '#menu-posts-thirstylink',
|
241 |
-
'html' => __( '<h3>
This concludes the guide. You are now ready to setup your first affiliate link!</h3>
|
242 |
-
<p>We also have a Pro add-on for ThirstyAffiliates which contains lots of interesting features for affiliates like:</p>
|
243 |
-
<ul><li>Automatically link up your affiliate links to keywords in your blog</li>
|
244 |
-
<li>Get more detailed and advanced reports</li>
|
245 |
-
<li>Geolocated affiliate links</li>
|
246 |
-
<li>Google Analytics integration</li>
|
247 |
-
<li>CSV importing/exporting, Amazon importing, and more</li>
|
248 |
-
<li>Link event notification admin emails</li>
|
249 |
-
<li>Automatic link health checker</li></ul>
|
250 |
-
<p>Want to unlock all of the extra features you see here? The Pro add-on is for you. And we’re adding new features all the time!</p>', 'thirstyaffiliates' ),
|
251 |
-
'prev' => $this->_urls[ 'help-settings' ],
|
252 |
-
'next' => null,
|
253 |
-
'edge' => 'left',
|
254 |
-
'align' => 'left',
|
255 |
-
'width' => 620,
|
256 |
-
'btn_tour_done' => __( 'Check out the current Pro add-on features' , 'thirstyaffiliates' ),
|
257 |
-
'btn_tour_done_url' => 'https://thirstyaffiliates.com/pricing?utm_source=Free%20Plugin&utm_medium=Tour&utm_campaign=Pro%20Link'
|
258 |
-
),
|
259 |
-
) );
|
260 |
-
}
|
261 |
-
|
262 |
-
/**
|
263 |
-
* Get current screen.
|
264 |
-
*
|
265 |
-
* @since 3.0.0
|
266 |
-
* @access public
|
267 |
-
*
|
268 |
-
* @return array Current guide tour screen.
|
269 |
-
*/
|
270 |
-
public function get_current_screen() {
|
271 |
-
|
272 |
-
$screen = get_current_screen();
|
273 |
-
$tab = isset( $_GET[ 'tab' ] ) ? sanitize_text_field( $_GET[ 'tab' ] ) : '';
|
274 |
-
|
275 |
-
if ( ! isset( $this->_screens[ $screen->id ] ) || empty( $this->_screens[ $screen->id ] ) )
|
276 |
-
return;
|
277 |
-
|
278 |
-
if ( $screen->id == 'thirstylink_page_thirsty-settings' ) {
|
279 |
-
|
280 |
-
if( $tab && isset( $this->_screens[ $screen->id ][ $tab ] ) )
|
281 |
-
return $this->_screens[ $screen->id ][ $tab ];
|
282 |
-
elseif ( ! isset( $_GET[ 'tab' ] ) )
|
283 |
-
return $this->_screens[ $screen->id ][ 'ta_general_settings' ];
|
284 |
-
else
|
285 |
-
return array();
|
286 |
-
}
|
287 |
-
|
288 |
-
return $this->_screens[ $screen->id ];
|
289 |
-
}
|
290 |
-
|
291 |
-
/**
|
292 |
-
* Get all guide tour screens.
|
293 |
-
*
|
294 |
-
* @since 3.0.0
|
295 |
-
* @access public
|
296 |
-
*
|
297 |
-
* @return array List of all guide tour screens.
|
298 |
-
*/
|
299 |
-
public function get_screens() {
|
300 |
-
|
301 |
-
return $this->_screens;
|
302 |
-
}
|
303 |
-
|
304 |
-
/**
|
305 |
-
* AJAX close guided tour.
|
306 |
-
*
|
307 |
-
* @since 3.0.0
|
308 |
-
* @access public
|
309 |
-
*/
|
310 |
-
public function ajax_close_guided_tour() {
|
311 |
-
|
312 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
313 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
314 |
-
elseif ( ! check_ajax_referer( 'ta-close-guided-tour' , 'nonce' , false ) )
|
315 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Security Check Failed' , 'thirstyaffiliates' ) );
|
316 |
-
else {
|
317 |
-
|
318 |
-
update_option( 'ta_guided_tour_status' , 'close' );
|
319 |
-
$response = array( 'status' => 'success' );
|
320 |
-
}
|
321 |
-
|
322 |
-
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
323 |
-
echo wp_json_encode( $response );
|
324 |
-
wp_die();
|
325 |
-
}
|
326 |
-
|
327 |
-
/**
|
328 |
-
* Set the guided tour status option as 'open' on activation.
|
329 |
-
*
|
330 |
-
* @since 3.0.0
|
331 |
-
* @access private
|
332 |
-
*/
|
333 |
-
private function set_guided_tour_status_open() {
|
334 |
-
|
335 |
-
if ( get_option( 'ta_guided_tour_status' ) )
|
336 |
-
return;
|
337 |
-
|
338 |
-
update_option( 'ta_guided_tour_status' , 'open' );
|
339 |
-
}
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
/*
|
345 |
-
|--------------------------------------------------------------------------
|
346 |
-
| Implemented Interface Methods
|
347 |
-
|--------------------------------------------------------------------------
|
348 |
-
*/
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Execute codes that needs to run plugin activation.
|
352 |
-
*
|
353 |
-
* @since 3.0.0
|
354 |
-
* @access public
|
355 |
-
* @implements ThirstyAffiliates\Interfaces\Activatable_Interface
|
356 |
-
*/
|
357 |
-
public function activate() {
|
358 |
-
|
359 |
-
$this->set_guided_tour_status_open();
|
360 |
-
}
|
361 |
-
|
362 |
-
/**
|
363 |
-
* Method that houses codes to be executed on init hook.
|
364 |
-
*
|
365 |
-
* @since 3.0.0
|
366 |
-
* @access public
|
367 |
-
* @inherit ThirstyAffiliates\Interfaces\Initiable_Interface
|
368 |
-
*/
|
369 |
-
public function initialize() {
|
370 |
-
|
371 |
-
add_action( 'wp_ajax_ta_close_guided_tour' , array( $this , 'ajax_close_guided_tour' ) );
|
372 |
-
}
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Execute model.
|
376 |
-
*
|
377 |
-
* @implements ThirstyAffiliates\Interfaces\Model_Interface
|
378 |
-
*
|
379 |
-
* @since 3.0.0
|
380 |
-
* @access public
|
381 |
-
*/
|
382 |
-
public function run() {
|
383 |
-
|
384 |
-
if ( get_option( 'ta_guided_tour_status' ) !== 'open' )
|
385 |
-
return;
|
386 |
-
|
387 |
-
$this->define_guided_tour_pages();
|
388 |
-
}
|
389 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
10 |
+
|
11 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
12 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
16 |
+
*
|
17 |
+
* @since 3.0.0
|
18 |
+
*/
|
19 |
+
class Guided_Tour implements Model_Interface , Activatable_Interface , Initiable_Interface {
|
20 |
+
|
21 |
+
/*
|
22 |
+
|--------------------------------------------------------------------------
|
23 |
+
| Class Properties
|
24 |
+
|--------------------------------------------------------------------------
|
25 |
+
*/
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Property that holds the single main instance of Shortcodes.
|
29 |
+
*
|
30 |
+
* @since 3.0.0
|
31 |
+
* @access private
|
32 |
+
* @var Redirection
|
33 |
+
*/
|
34 |
+
private static $_instance;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Model that houses the main plugin object.
|
38 |
+
*
|
39 |
+
* @since 3.0.0
|
40 |
+
* @access private
|
41 |
+
* @var Redirection
|
42 |
+
*/
|
43 |
+
private $_main_plugin;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Model that houses all the plugin constants.
|
47 |
+
*
|
48 |
+
* @since 3.0.0
|
49 |
+
* @access private
|
50 |
+
* @var Plugin_Constants
|
51 |
+
*/
|
52 |
+
private $_constants;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Property that houses all the helper functions of the plugin.
|
56 |
+
*
|
57 |
+
* @since 3.0.0
|
58 |
+
* @access private
|
59 |
+
* @var Helper_Functions
|
60 |
+
*/
|
61 |
+
private $_helper_functions;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Property that urls of the guided tour screens.
|
65 |
+
*
|
66 |
+
* @since 3.0.0
|
67 |
+
* @access private
|
68 |
+
* @var array
|
69 |
+
*/
|
70 |
+
private $_urls = array();
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Property that houses the screens of the guided tour.
|
74 |
+
*
|
75 |
+
* @since 3.0.0
|
76 |
+
* @access private
|
77 |
+
* @var array
|
78 |
+
*/
|
79 |
+
private $_screens = array();
|
80 |
+
|
81 |
+
|
82 |
+
|
83 |
+
|
84 |
+
/*
|
85 |
+
|--------------------------------------------------------------------------
|
86 |
+
| Class Methods
|
87 |
+
|--------------------------------------------------------------------------
|
88 |
+
*/
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Class constructor.
|
92 |
+
*
|
93 |
+
* @since 3.0.0
|
94 |
+
* @access public
|
95 |
+
*
|
96 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
97 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
98 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
99 |
+
*/
|
100 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
101 |
+
|
102 |
+
$this->_constants = $constants;
|
103 |
+
$this->_helper_functions = $helper_functions;
|
104 |
+
|
105 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
110 |
+
*
|
111 |
+
* @since 3.0.0
|
112 |
+
* @access public
|
113 |
+
*
|
114 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
115 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
116 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
117 |
+
* @return Redirection
|
118 |
+
*/
|
119 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
120 |
+
|
121 |
+
if ( !self::$_instance instanceof self )
|
122 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
123 |
+
|
124 |
+
return self::$_instance;
|
125 |
+
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Define guided tour pages.
|
130 |
+
*
|
131 |
+
* @since 3.0.0
|
132 |
+
* @access private
|
133 |
+
*/
|
134 |
+
private function define_guided_tour_pages() {
|
135 |
+
|
136 |
+
$this->_urls = apply_filters( 'ta_guided_tour_pages' , array(
|
137 |
+
'plugin-listing' => admin_url( 'plugins.php' ),
|
138 |
+
'affiliate-links-listing' => admin_url( 'edit.php?post_type=thirstylink' ),
|
139 |
+
'new-wp-post' => admin_url( 'post-new.php' ),
|
140 |
+
'general-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings' ),
|
141 |
+
'link-apperance-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_links_settings' ),
|
142 |
+
'modules-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_modules_settings' ),
|
143 |
+
'import-export-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_import_export_settings' ),
|
144 |
+
'help-settings' => admin_url( 'edit.php?post_type=thirstylink&page=thirsty-settings&tab=ta_help_settings' ),
|
145 |
+
'new-affiliate-link' => admin_url( 'post-new.php?post_type=thirstylink' ),
|
146 |
+
) );
|
147 |
+
|
148 |
+
$this->_screens = apply_filters( 'ta_guided_tours' , array(
|
149 |
+
'plugins' => array(
|
150 |
+
'elem' => '#menu-posts-thirstylink .menu-top',
|
151 |
+
'html' => __( '<h3>Congratulations, you just activated ThirstyAffiliates!</h3>
|
152 |
+
<p>Would you like to take a tour of the plugin features? It takes less than a minute and you\'ll then know exactly how to use the plugin.</p>', 'thirstyaffiliates' ),
|
153 |
+
'prev' => null,
|
154 |
+
'next' => $this->_urls[ 'affiliate-links-listing' ],
|
155 |
+
'edge' => 'left',
|
156 |
+
'align' => 'left',
|
157 |
+
),
|
158 |
+
'edit-thirstylink' => array(
|
159 |
+
'elem' => '#wpbody-content > .wrap > .wp-heading-inline',
|
160 |
+
'html' => __( '<h3>ThirstyAffiliates helps you manage affiliate links that you are given from the various affiliate programs you are a member of.</h3>
|
161 |
+
<p>It lets you hide long, and often confusing looking, affiliate link URLs behind another URL called a redirect. When your visitors click on that new URL they are automatically redirected to your affiliate link.</p>
|
162 |
+
<p>This is helpful for five reasons:</p>
|
163 |
+
<ol><li>AESTHETICS: Affiliate links are often long and ugly as mentioned and this can look off putting to visitors. ThirstyAffiliates redirects make them shorter and more attractive to click on like "http://example.com/recommends/some-product-name"</li>
|
164 |
+
<li>PROTECTION: It hides the affiliate code, so malicious software (malware) cannot sniff out the affiliate code for common affiliate programs and replace it with their own code instead. In this way, it protects your commissions.</li>
|
165 |
+
<li>CONVENIENCE: If the affiliate program ever changes the link code you’ll only have ONE place to change it on your blog, rather than going through all your content and changing every instance of the link.</li>
|
166 |
+
<li>CATEGORIZATION: You categorize your affiliate links into logical groups which can make managing them much simpler.</li>
|
167 |
+
<li>STATISTICS: Finally, because your visitors are travelling via a ThirstyAffiliates redirect, the plugin can provide you with statistics on what is being clicked.</li></ol>
|
168 |
+
<p>You can now create an “Affiliate Link” in this new section in your dashboard. This view shows you all the affiliate links you are managing with ThirstyAffiliates.</p>', 'thirstyaffiliates' ),
|
169 |
+
'prev' => $this->_urls[ 'plugin-listing' ],
|
170 |
+
'next' => $this->_urls[ 'new-wp-post' ],
|
171 |
+
'edge' => 'top',
|
172 |
+
'align' => 'left',
|
173 |
+
'width' => 600
|
174 |
+
),
|
175 |
+
'post' => array(
|
176 |
+
'elem' => '#wpbody #insert-media-button',
|
177 |
+
'html' => __( '<h3>Affiliate links can be added to your posts easily by clicking on the “TA” button on your editor.</h3>
|
178 |
+
<p>This works identically to the WordPress link tool, but only searches for affiliate links.</p>
|
179 |
+
<p>Give it a try by typing in some text, highlighting it, then clicking the “TA” button.</p>
|
180 |
+
<p>If you need to you can click the cog icon for an advanced search view which is handy for doing more advanced searches and for inserting images pre-wrapped with your affiliate link or via a shortcode instead.</p>', 'thirstyaffiliates' ),
|
181 |
+
'prev' => $this->_urls[ 'affiliate-links-listing' ],
|
182 |
+
'next' => $this->_urls[ 'general-settings' ],
|
183 |
+
'edge' => 'top',
|
184 |
+
'align' => 'left',
|
185 |
+
'width' => 400
|
186 |
+
),
|
187 |
+
'thirstylink_page_thirsty-settings' => array(
|
188 |
+
'ta_general_settings' => array(
|
189 |
+
'elem' => '.nav-tab-wrapper .ta_general_settings',
|
190 |
+
'html' => __( '<h3>ThirstyAffiliates has a number of settings that change the way it works, behaves and how your links appear.</h3>
|
191 |
+
<p>Here are the General settings which are for changing the way you work with ThirstyAffiliates in the backend.</p>', 'thirstyaffiliates' ),
|
192 |
+
'prev' => $this->_urls[ 'new-wp-post' ],
|
193 |
+
'next' => $this->_urls[ 'link-apperance-settings' ],
|
194 |
+
'edge' => 'top',
|
195 |
+
'align' => 'left',
|
196 |
+
),
|
197 |
+
'ta_links_settings' => array(
|
198 |
+
'elem' => '.nav-tab-wrapper .ta_links_settings',
|
199 |
+
'html' => __( '<h3>One of the most important parts of the settings area is Link Appearance which changes the way your links look to your visitors.</h3>
|
200 |
+
<p>This includes the Link Prefix setting which is important to decide on before you start using ThirstyAffiliates.</p>
|
201 |
+
<p>By default, this is set to “recommends” so your links will look like “http://example.com/recommends/some-product-name”.</p>
|
202 |
+
<p>You can also choose to include the category slug in the URL, change the way ThirstyAffiliates redirects links, add no follow, make links open in a new window and more.</p>', 'thirstyaffiliates' ),
|
203 |
+
'prev' => $this->_urls[ 'general-settings' ],
|
204 |
+
'next' => $this->_urls[ 'modules-settings' ],
|
205 |
+
'edge' => 'top',
|
206 |
+
'align' => 'left',
|
207 |
+
'width' => 450
|
208 |
+
),
|
209 |
+
'ta_modules_settings' => array(
|
210 |
+
'elem' => '.nav-tab-wrapper .ta_modules_settings',
|
211 |
+
'html' => __( '<h3>We built ThirstyAffiliates to be flexible and as such, you can shut down the parts of ThirstyAffiliates that aren’t being used. This can make the plugin faster.</h3>
|
212 |
+
<p>If you have the Pro add-on each Pro module will show in here as well.</p>', 'thirstyaffiliates' ),
|
213 |
+
'prev' => $this->_urls[ 'link-apperance-settings' ],
|
214 |
+
'next' => $this->_urls[ 'import-export-settings' ],
|
215 |
+
'edge' => 'top',
|
216 |
+
'align' => 'left',
|
217 |
+
),
|
218 |
+
'ta_import_export_settings' => array(
|
219 |
+
'elem' => '.nav-tab-wrapper .ta_import_export_settings',
|
220 |
+
'html' => __( '<h3>Setting up multiple sites with all running ThirstyAffiliates?</h3>
|
221 |
+
<p>We’ve made it super simple to configure your additional sites by being able to import and export ThirstyAffiliate settings.</p>
|
222 |
+
<p>Just copy the Export section and paste it into the Import section on your other site and ThirstyAffiliates will be automatically configured the same way.</p>', 'thirstyaffiliates' ),
|
223 |
+
'prev' => $this->_urls[ 'modules-settings' ],
|
224 |
+
'next' => $this->_urls[ 'help-settings' ],
|
225 |
+
'edge' => 'top',
|
226 |
+
'align' => 'right',
|
227 |
+
),
|
228 |
+
'ta_help_settings' => array(
|
229 |
+
'elem' => '.nav-tab-wrapper .ta_help_settings',
|
230 |
+
'html' => __( '<h3>Need some help with ThirstyAffiliates?</h3>
|
231 |
+
<p>We have a growing knowledge base filled with guides, troubleshooting and FAQ.</p>
|
232 |
+
<p>Our blog is also very active with lots of interesting affiliate marketing topics to help you grow your affiliate marketing empire.</p>', 'thirstyaffiliates' ),
|
233 |
+
'prev' => $this->_urls[ 'import-export-settings' ],
|
234 |
+
'next' => $this->_urls[ 'new-affiliate-link' ],
|
235 |
+
'edge' => 'top',
|
236 |
+
'align' => 'right',
|
237 |
+
)
|
238 |
+
),
|
239 |
+
'thirstylink' => array(
|
240 |
+
'elem' => '#menu-posts-thirstylink',
|
241 |
+
'html' => __( '<h3>
This concludes the guide. You are now ready to setup your first affiliate link!</h3>
|
242 |
+
<p>We also have a Pro add-on for ThirstyAffiliates which contains lots of interesting features for affiliates like:</p>
|
243 |
+
<ul><li>Automatically link up your affiliate links to keywords in your blog</li>
|
244 |
+
<li>Get more detailed and advanced reports</li>
|
245 |
+
<li>Geolocated affiliate links</li>
|
246 |
+
<li>Google Analytics integration</li>
|
247 |
+
<li>CSV importing/exporting, Amazon importing, and more</li>
|
248 |
+
<li>Link event notification admin emails</li>
|
249 |
+
<li>Automatic link health checker</li></ul>
|
250 |
+
<p>Want to unlock all of the extra features you see here? The Pro add-on is for you. And we’re adding new features all the time!</p>', 'thirstyaffiliates' ),
|
251 |
+
'prev' => $this->_urls[ 'help-settings' ],
|
252 |
+
'next' => null,
|
253 |
+
'edge' => 'left',
|
254 |
+
'align' => 'left',
|
255 |
+
'width' => 620,
|
256 |
+
'btn_tour_done' => __( 'Check out the current Pro add-on features' , 'thirstyaffiliates' ),
|
257 |
+
'btn_tour_done_url' => 'https://thirstyaffiliates.com/pricing?utm_source=Free%20Plugin&utm_medium=Tour&utm_campaign=Pro%20Link'
|
258 |
+
),
|
259 |
+
) );
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Get current screen.
|
264 |
+
*
|
265 |
+
* @since 3.0.0
|
266 |
+
* @access public
|
267 |
+
*
|
268 |
+
* @return array Current guide tour screen.
|
269 |
+
*/
|
270 |
+
public function get_current_screen() {
|
271 |
+
|
272 |
+
$screen = get_current_screen();
|
273 |
+
$tab = isset( $_GET[ 'tab' ] ) ? sanitize_text_field( $_GET[ 'tab' ] ) : '';
|
274 |
+
|
275 |
+
if ( ! isset( $this->_screens[ $screen->id ] ) || empty( $this->_screens[ $screen->id ] ) )
|
276 |
+
return;
|
277 |
+
|
278 |
+
if ( $screen->id == 'thirstylink_page_thirsty-settings' ) {
|
279 |
+
|
280 |
+
if( $tab && isset( $this->_screens[ $screen->id ][ $tab ] ) )
|
281 |
+
return $this->_screens[ $screen->id ][ $tab ];
|
282 |
+
elseif ( ! isset( $_GET[ 'tab' ] ) )
|
283 |
+
return $this->_screens[ $screen->id ][ 'ta_general_settings' ];
|
284 |
+
else
|
285 |
+
return array();
|
286 |
+
}
|
287 |
+
|
288 |
+
return $this->_screens[ $screen->id ];
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Get all guide tour screens.
|
293 |
+
*
|
294 |
+
* @since 3.0.0
|
295 |
+
* @access public
|
296 |
+
*
|
297 |
+
* @return array List of all guide tour screens.
|
298 |
+
*/
|
299 |
+
public function get_screens() {
|
300 |
+
|
301 |
+
return $this->_screens;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* AJAX close guided tour.
|
306 |
+
*
|
307 |
+
* @since 3.0.0
|
308 |
+
* @access public
|
309 |
+
*/
|
310 |
+
public function ajax_close_guided_tour() {
|
311 |
+
|
312 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
313 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
314 |
+
elseif ( ! check_ajax_referer( 'ta-close-guided-tour' , 'nonce' , false ) )
|
315 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Security Check Failed' , 'thirstyaffiliates' ) );
|
316 |
+
else {
|
317 |
+
|
318 |
+
update_option( 'ta_guided_tour_status' , 'close' );
|
319 |
+
$response = array( 'status' => 'success' );
|
320 |
+
}
|
321 |
+
|
322 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
323 |
+
echo wp_json_encode( $response );
|
324 |
+
wp_die();
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* Set the guided tour status option as 'open' on activation.
|
329 |
+
*
|
330 |
+
* @since 3.0.0
|
331 |
+
* @access private
|
332 |
+
*/
|
333 |
+
private function set_guided_tour_status_open() {
|
334 |
+
|
335 |
+
if ( get_option( 'ta_guided_tour_status' ) )
|
336 |
+
return;
|
337 |
+
|
338 |
+
update_option( 'ta_guided_tour_status' , 'open' );
|
339 |
+
}
|
340 |
+
|
341 |
+
|
342 |
+
|
343 |
+
|
344 |
+
/*
|
345 |
+
|--------------------------------------------------------------------------
|
346 |
+
| Implemented Interface Methods
|
347 |
+
|--------------------------------------------------------------------------
|
348 |
+
*/
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Execute codes that needs to run plugin activation.
|
352 |
+
*
|
353 |
+
* @since 3.0.0
|
354 |
+
* @access public
|
355 |
+
* @implements ThirstyAffiliates\Interfaces\Activatable_Interface
|
356 |
+
*/
|
357 |
+
public function activate() {
|
358 |
+
|
359 |
+
$this->set_guided_tour_status_open();
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Method that houses codes to be executed on init hook.
|
364 |
+
*
|
365 |
+
* @since 3.0.0
|
366 |
+
* @access public
|
367 |
+
* @inherit ThirstyAffiliates\Interfaces\Initiable_Interface
|
368 |
+
*/
|
369 |
+
public function initialize() {
|
370 |
+
|
371 |
+
add_action( 'wp_ajax_ta_close_guided_tour' , array( $this , 'ajax_close_guided_tour' ) );
|
372 |
+
}
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Execute model.
|
376 |
+
*
|
377 |
+
* @implements ThirstyAffiliates\Interfaces\Model_Interface
|
378 |
+
*
|
379 |
+
* @since 3.0.0
|
380 |
+
* @access public
|
381 |
+
*/
|
382 |
+
public function run() {
|
383 |
+
|
384 |
+
if ( get_option( 'ta_guided_tour_status' ) !== 'open' )
|
385 |
+
return;
|
386 |
+
|
387 |
+
$this->define_guided_tour_pages();
|
388 |
+
}
|
389 |
+
}
|
Models/Link_Fixer.php
CHANGED
@@ -1,289 +1,289 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
-
|
10 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
-
|
13 |
-
use ThirstyAffiliates\Models\Affiliate_Link;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Model that houses the link fixer logic.
|
17 |
-
*
|
18 |
-
* @since 3.0.0
|
19 |
-
*/
|
20 |
-
class Link_Fixer implements Model_Interface , Initiable_Interface {
|
21 |
-
|
22 |
-
/*
|
23 |
-
|--------------------------------------------------------------------------
|
24 |
-
| Class Properties
|
25 |
-
|--------------------------------------------------------------------------
|
26 |
-
*/
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Property that holds the single main instance of Bootstrap.
|
30 |
-
*
|
31 |
-
* @since 3.0.0
|
32 |
-
* @access private
|
33 |
-
* @var Link_Fixer
|
34 |
-
*/
|
35 |
-
private static $_instance;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Model that houses the main plugin object.
|
39 |
-
*
|
40 |
-
* @since 3.0.0
|
41 |
-
* @access private
|
42 |
-
* @var Abstract_Main_Plugin_Class
|
43 |
-
*/
|
44 |
-
private $_main_plugin;
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Model that houses all the plugin constants.
|
48 |
-
*
|
49 |
-
* @since 3.0.0
|
50 |
-
* @access private
|
51 |
-
* @var Plugin_Constants
|
52 |
-
*/
|
53 |
-
private $_constants;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Property that houses all the helper functions of the plugin.
|
57 |
-
*
|
58 |
-
* @since 3.0.0
|
59 |
-
* @access private
|
60 |
-
* @var Helper_Functions
|
61 |
-
*/
|
62 |
-
private $_helper_functions;
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
/*
|
68 |
-
|--------------------------------------------------------------------------
|
69 |
-
| Class Methods
|
70 |
-
|--------------------------------------------------------------------------
|
71 |
-
*/
|
72 |
-
|
73 |
-
/**
|
74 |
-
* Class constructor.
|
75 |
-
*
|
76 |
-
* @since 3.0.0
|
77 |
-
* @access public
|
78 |
-
*
|
79 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
80 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
81 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
82 |
-
*/
|
83 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
84 |
-
|
85 |
-
$this->_constants = $constants;
|
86 |
-
$this->_helper_functions = $helper_functions;
|
87 |
-
|
88 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
89 |
-
$main_plugin->add_to_public_models( $this );
|
90 |
-
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
95 |
-
*
|
96 |
-
* @since 3.0.0
|
97 |
-
* @access public
|
98 |
-
*
|
99 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
100 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
101 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
102 |
-
* @return Link_Fixer
|
103 |
-
*/
|
104 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
105 |
-
|
106 |
-
if ( !self::$_instance instanceof self )
|
107 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
108 |
-
|
109 |
-
return self::$_instance;
|
110 |
-
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Get data of links to be fixed.
|
115 |
-
*
|
116 |
-
* @since 3.0.0
|
117 |
-
* @since 3.2.4 Make sure that link fixer runs using the default language set on WPML when it is active.
|
118 |
-
* @since 3.3.0 Add data-nojs attribute support.
|
119 |
-
* @since 3.4.0 Add support for additional classes field. Remove query string on href before processing.
|
120 |
-
* @access public
|
121 |
-
*
|
122 |
-
* @global SitePress $sitepress WPML main plugin object.
|
123 |
-
*
|
124 |
-
* @param array $links List of affiliate links to fix.
|
125 |
-
* @param int $post_id ID of the post currently being viewed.
|
126 |
-
* @param array $data Affiliate Links data.
|
127 |
-
* @return array Affiliate Links data.
|
128 |
-
*/
|
129 |
-
public function get_link_fixer_data( $links , $post_id = 0 , $data = array() ) {
|
130 |
-
|
131 |
-
global $sitepress;
|
132 |
-
|
133 |
-
if ( empty( $links ) )
|
134 |
-
return $data;
|
135 |
-
|
136 |
-
if ( is_object( $sitepress ) )
|
137 |
-
$sitepress->switch_lang( $sitepress->get_default_language() );
|
138 |
-
|
139 |
-
$global_rel = get_option( 'ta_additional_rel_tags' );
|
140 |
-
$global_class = get_option( 'ta_additional_css_classes' );
|
141 |
-
|
142 |
-
foreach( $links as $link ) {
|
143 |
-
|
144 |
-
$href = strtok( esc_url_raw( $link[ 'href' ] ) , '?' );
|
145 |
-
$class = isset( $link[ 'class' ] ) ? sanitize_text_field( $link[ 'class' ] ) : '';
|
146 |
-
$key = (int) sanitize_text_field( $link[ 'key' ] );
|
147 |
-
$link_id = $this->url_to_affiliate_link_id( $href );
|
148 |
-
|
149 |
-
$thirstylink = new Affiliate_Link( $link_id );
|
150 |
-
|
151 |
-
if ( ! $thirstylink->get_id() || get_post_type( $link_id ) !== Plugin_Constants::AFFILIATE_LINKS_CPT )
|
152 |
-
continue;
|
153 |
-
|
154 |
-
$class = str_replace( 'thirstylinkimg' , 'thirstylink' , $class );
|
155 |
-
$class .= ( get_option( 'ta_disable_thirsty_link_class' ) !== "yes" && strpos( $class , 'thirstylink' ) === false ) ? ' thirstylink' : '';
|
156 |
-
$href = ( $thirstylink->is( 'uncloak_link' ) ) ? apply_filters( 'ta_uncloak_link_url' , $thirstylink->get_prop( 'destination_url' ) , $thirstylink ) : $thirstylink->get_prop( 'permalink' );
|
157 |
-
$rel = $thirstylink->is( 'no_follow' ) ? 'nofollow' : '';
|
158 |
-
$target = $thirstylink->is( 'new_window' ) ? '_blank' : '';
|
159 |
-
$title = get_option( 'ta_disable_title_attribute' ) != 'yes' ? esc_attr( str_replace( '"' , '' , $thirstylink->get_prop( 'name' ) ) ) : '';
|
160 |
-
$title = str_replace( ''' , '\'' , $title );
|
161 |
-
|
162 |
-
// append custom rel tags.
|
163 |
-
if ( $thirstylink->get_prop( 'rel_tags' ) )
|
164 |
-
$rel = trim( $rel . ' ' . $thirstylink->get_prop( 'rel_tags' ) );
|
165 |
-
|
166 |
-
// make sure rel attribute entries are unique
|
167 |
-
$rel_array = explode( ' ' , $rel );
|
168 |
-
$rel = implode( ' ' , array_unique( $rel_array ) );
|
169 |
-
|
170 |
-
// append custom classes.
|
171 |
-
if ( $thirstylink->get_prop( 'css_classes' ) )
|
172 |
-
$class = trim( $class . ' ' . $thirstylink->get_prop( 'css_classes' ) );
|
173 |
-
|
174 |
-
// make sure class attribute entries are unique
|
175 |
-
$class_array = explode( ' ' , $class );
|
176 |
-
$class = implode( ' ' , array_unique( $class_array ) );
|
177 |
-
|
178 |
-
// if link is image, then change default class to 'thirstylinkimg'
|
179 |
-
if ( $link[ 'is_image' ] )
|
180 |
-
$class = str_replace( 'thirstylink' , 'thirstylinkimg' , $class );
|
181 |
-
|
182 |
-
// if thirstylink class is not the same with global class, then we remove global class.
|
183 |
-
if ( $thirstylink->get_prop( 'css_classes' ) != $global_class )
|
184 |
-
$class = str_replace( $global_class , '' , $class ) ;
|
185 |
-
|
186 |
-
$data[] = array(
|
187 |
-
'key' => $key,
|
188 |
-
'link_id' => $link_id,
|
189 |
-
'class' => trim( esc_attr( preg_replace( '!\s+!' , ' ', $class ) ) ),
|
190 |
-
'href' => esc_url_raw( $href ),
|
191 |
-
'rel' => trim( esc_attr( preg_replace( '!\s+!' , ' ', $rel ) ) ),
|
192 |
-
'target' => esc_attr( $target ),
|
193 |
-
'title' => $title,
|
194 |
-
'nojs' => apply_filters( 'ta_nojs_redirect_attribute' , false , $thirstylink ),
|
195 |
-
'pass_qs' => $thirstylink->is( 'pass_query_str' )
|
196 |
-
);
|
197 |
-
}
|
198 |
-
|
199 |
-
return $data;
|
200 |
-
}
|
201 |
-
|
202 |
-
/**
|
203 |
-
* Get the ID from a given affiliate link URL (replaces url_to_postid function).
|
204 |
-
*
|
205 |
-
* @since 3.3.0
|
206 |
-
* @access private
|
207 |
-
*
|
208 |
-
* @param string $href Affilaite link cloaked URL.
|
209 |
-
* @return int Affiliate link ID.
|
210 |
-
*/
|
211 |
-
private function url_to_affiliate_link_id( $href ) {
|
212 |
-
|
213 |
-
global $wpdb;
|
214 |
-
|
215 |
-
$link_parts = explode( "/" , $href );
|
216 |
-
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
217 |
-
$cpt_slug = esc_sql( Plugin_Constants::AFFILIATE_LINKS_CPT );
|
218 |
-
|
219 |
-
// get the key of the link prefix in the url from the $link_parts variable.
|
220 |
-
$key = (int) array_search( $link_prefix , $link_parts );
|
221 |
-
|
222 |
-
// get the slug from the $link_parts variable based on the position of the link prefix's key.
|
223 |
-
// if $key + 2 exists, this means that the link has a category slug in it, so we fetch $key + 2, otherwise we fetch $key + 1 (no category slug).
|
224 |
-
$slug = esc_sql( isset( $link_parts[ $key + 2 ] ) && $link_parts[ $key + 2 ] ? $link_parts[ $key + 2 ] : $link_parts[ $key + 1 ] );
|
225 |
-
|
226 |
-
// fetch the ID based on the post type and slug.
|
227 |
-
$id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type = '$cpt_slug' AND post_name = '$slug'" );
|
228 |
-
|
229 |
-
return $id ? absint( $id ) : 0;
|
230 |
-
}
|
231 |
-
|
232 |
-
/**
|
233 |
-
* Ajax link fixer.
|
234 |
-
*
|
235 |
-
* @since 3.0.0
|
236 |
-
* @access public
|
237 |
-
*/
|
238 |
-
public function ajax_link_fixer() {
|
239 |
-
|
240 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
241 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
242 |
-
elseif ( ! isset( $_POST[ 'hrefs' ] ) || empty( $_POST[ 'hrefs' ] ) )
|
243 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
244 |
-
else {
|
245 |
-
|
246 |
-
$links = $_POST[ 'hrefs' ];
|
247 |
-
$post_id = isset( $_POST[ 'post_id' ] ) ? intval( $_POST[ 'post_id' ] ) : 0;
|
248 |
-
$response = array(
|
249 |
-
'status' => 'success',
|
250 |
-
'data' => $this->get_link_fixer_data( $links , $post_id )
|
251 |
-
);
|
252 |
-
}
|
253 |
-
|
254 |
-
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
255 |
-
echo wp_json_encode( $response );
|
256 |
-
wp_die();
|
257 |
-
}
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
/*
|
263 |
-
|--------------------------------------------------------------------------
|
264 |
-
| Fulfill implemented interface contracts
|
265 |
-
|--------------------------------------------------------------------------
|
266 |
-
*/
|
267 |
-
|
268 |
-
/**
|
269 |
-
* Execute codes that needs to run on plugin initialization.
|
270 |
-
*
|
271 |
-
* @since 3.0.0
|
272 |
-
* @access public
|
273 |
-
* @implements ThirstyAffiliates\Interfaces\Initiable_Interface
|
274 |
-
*/
|
275 |
-
public function initialize() {
|
276 |
-
|
277 |
-
add_action( 'wp_ajax_ta_link_fixer' , array( $this , 'ajax_link_fixer' ) );
|
278 |
-
add_action( 'wp_ajax_nopriv_ta_link_fixer' , array( $this , 'ajax_link_fixer' ) );
|
279 |
-
}
|
280 |
-
|
281 |
-
/**
|
282 |
-
* Execute link picker.
|
283 |
-
*
|
284 |
-
* @since 3.0.0
|
285 |
-
* @access public
|
286 |
-
*/
|
287 |
-
public function run() {
|
288 |
-
}
|
289 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
+
|
10 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
+
|
13 |
+
use ThirstyAffiliates\Models\Affiliate_Link;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Model that houses the link fixer logic.
|
17 |
+
*
|
18 |
+
* @since 3.0.0
|
19 |
+
*/
|
20 |
+
class Link_Fixer implements Model_Interface , Initiable_Interface {
|
21 |
+
|
22 |
+
/*
|
23 |
+
|--------------------------------------------------------------------------
|
24 |
+
| Class Properties
|
25 |
+
|--------------------------------------------------------------------------
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Property that holds the single main instance of Bootstrap.
|
30 |
+
*
|
31 |
+
* @since 3.0.0
|
32 |
+
* @access private
|
33 |
+
* @var Link_Fixer
|
34 |
+
*/
|
35 |
+
private static $_instance;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Model that houses the main plugin object.
|
39 |
+
*
|
40 |
+
* @since 3.0.0
|
41 |
+
* @access private
|
42 |
+
* @var Abstract_Main_Plugin_Class
|
43 |
+
*/
|
44 |
+
private $_main_plugin;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Model that houses all the plugin constants.
|
48 |
+
*
|
49 |
+
* @since 3.0.0
|
50 |
+
* @access private
|
51 |
+
* @var Plugin_Constants
|
52 |
+
*/
|
53 |
+
private $_constants;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Property that houses all the helper functions of the plugin.
|
57 |
+
*
|
58 |
+
* @since 3.0.0
|
59 |
+
* @access private
|
60 |
+
* @var Helper_Functions
|
61 |
+
*/
|
62 |
+
private $_helper_functions;
|
63 |
+
|
64 |
+
|
65 |
+
|
66 |
+
|
67 |
+
/*
|
68 |
+
|--------------------------------------------------------------------------
|
69 |
+
| Class Methods
|
70 |
+
|--------------------------------------------------------------------------
|
71 |
+
*/
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Class constructor.
|
75 |
+
*
|
76 |
+
* @since 3.0.0
|
77 |
+
* @access public
|
78 |
+
*
|
79 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
80 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
81 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
82 |
+
*/
|
83 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
84 |
+
|
85 |
+
$this->_constants = $constants;
|
86 |
+
$this->_helper_functions = $helper_functions;
|
87 |
+
|
88 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
89 |
+
$main_plugin->add_to_public_models( $this );
|
90 |
+
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
95 |
+
*
|
96 |
+
* @since 3.0.0
|
97 |
+
* @access public
|
98 |
+
*
|
99 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
100 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
101 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
102 |
+
* @return Link_Fixer
|
103 |
+
*/
|
104 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
105 |
+
|
106 |
+
if ( !self::$_instance instanceof self )
|
107 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
108 |
+
|
109 |
+
return self::$_instance;
|
110 |
+
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Get data of links to be fixed.
|
115 |
+
*
|
116 |
+
* @since 3.0.0
|
117 |
+
* @since 3.2.4 Make sure that link fixer runs using the default language set on WPML when it is active.
|
118 |
+
* @since 3.3.0 Add data-nojs attribute support.
|
119 |
+
* @since 3.4.0 Add support for additional classes field. Remove query string on href before processing.
|
120 |
+
* @access public
|
121 |
+
*
|
122 |
+
* @global SitePress $sitepress WPML main plugin object.
|
123 |
+
*
|
124 |
+
* @param array $links List of affiliate links to fix.
|
125 |
+
* @param int $post_id ID of the post currently being viewed.
|
126 |
+
* @param array $data Affiliate Links data.
|
127 |
+
* @return array Affiliate Links data.
|
128 |
+
*/
|
129 |
+
public function get_link_fixer_data( $links , $post_id = 0 , $data = array() ) {
|
130 |
+
|
131 |
+
global $sitepress;
|
132 |
+
|
133 |
+
if ( empty( $links ) )
|
134 |
+
return $data;
|
135 |
+
|
136 |
+
if ( is_object( $sitepress ) )
|
137 |
+
$sitepress->switch_lang( $sitepress->get_default_language() );
|
138 |
+
|
139 |
+
$global_rel = get_option( 'ta_additional_rel_tags' );
|
140 |
+
$global_class = get_option( 'ta_additional_css_classes' );
|
141 |
+
|
142 |
+
foreach( $links as $link ) {
|
143 |
+
|
144 |
+
$href = strtok( esc_url_raw( $link[ 'href' ] ) , '?' );
|
145 |
+
$class = isset( $link[ 'class' ] ) ? sanitize_text_field( $link[ 'class' ] ) : '';
|
146 |
+
$key = (int) sanitize_text_field( $link[ 'key' ] );
|
147 |
+
$link_id = $this->url_to_affiliate_link_id( $href );
|
148 |
+
|
149 |
+
$thirstylink = new Affiliate_Link( $link_id );
|
150 |
+
|
151 |
+
if ( ! $thirstylink->get_id() || get_post_type( $link_id ) !== Plugin_Constants::AFFILIATE_LINKS_CPT )
|
152 |
+
continue;
|
153 |
+
|
154 |
+
$class = str_replace( 'thirstylinkimg' , 'thirstylink' , $class );
|
155 |
+
$class .= ( get_option( 'ta_disable_thirsty_link_class' ) !== "yes" && strpos( $class , 'thirstylink' ) === false ) ? ' thirstylink' : '';
|
156 |
+
$href = ( $thirstylink->is( 'uncloak_link' ) ) ? apply_filters( 'ta_uncloak_link_url' , $thirstylink->get_prop( 'destination_url' ) , $thirstylink ) : $thirstylink->get_prop( 'permalink' );
|
157 |
+
$rel = $thirstylink->is( 'no_follow' ) ? 'nofollow' : '';
|
158 |
+
$target = $thirstylink->is( 'new_window' ) ? '_blank' : '';
|
159 |
+
$title = get_option( 'ta_disable_title_attribute' ) != 'yes' ? esc_attr( str_replace( '"' , '' , $thirstylink->get_prop( 'name' ) ) ) : '';
|
160 |
+
$title = str_replace( ''' , '\'' , $title );
|
161 |
+
|
162 |
+
// append custom rel tags.
|
163 |
+
if ( $thirstylink->get_prop( 'rel_tags' ) )
|
164 |
+
$rel = trim( $rel . ' ' . $thirstylink->get_prop( 'rel_tags' ) );
|
165 |
+
|
166 |
+
// make sure rel attribute entries are unique
|
167 |
+
$rel_array = explode( ' ' , $rel );
|
168 |
+
$rel = implode( ' ' , array_unique( $rel_array ) );
|
169 |
+
|
170 |
+
// append custom classes.
|
171 |
+
if ( $thirstylink->get_prop( 'css_classes' ) )
|
172 |
+
$class = trim( $class . ' ' . $thirstylink->get_prop( 'css_classes' ) );
|
173 |
+
|
174 |
+
// make sure class attribute entries are unique
|
175 |
+
$class_array = explode( ' ' , $class );
|
176 |
+
$class = implode( ' ' , array_unique( $class_array ) );
|
177 |
+
|
178 |
+
// if link is image, then change default class to 'thirstylinkimg'
|
179 |
+
if ( $link[ 'is_image' ] )
|
180 |
+
$class = str_replace( 'thirstylink' , 'thirstylinkimg' , $class );
|
181 |
+
|
182 |
+
// if thirstylink class is not the same with global class, then we remove global class.
|
183 |
+
if ( $thirstylink->get_prop( 'css_classes' ) != $global_class )
|
184 |
+
$class = str_replace( $global_class , '' , $class ) ;
|
185 |
+
|
186 |
+
$data[] = array(
|
187 |
+
'key' => $key,
|
188 |
+
'link_id' => $link_id,
|
189 |
+
'class' => trim( esc_attr( preg_replace( '!\s+!' , ' ', $class ) ) ),
|
190 |
+
'href' => esc_url_raw( $href ),
|
191 |
+
'rel' => trim( esc_attr( preg_replace( '!\s+!' , ' ', $rel ) ) ),
|
192 |
+
'target' => esc_attr( $target ),
|
193 |
+
'title' => $title,
|
194 |
+
'nojs' => apply_filters( 'ta_nojs_redirect_attribute' , false , $thirstylink ),
|
195 |
+
'pass_qs' => $thirstylink->is( 'pass_query_str' )
|
196 |
+
);
|
197 |
+
}
|
198 |
+
|
199 |
+
return $data;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Get the ID from a given affiliate link URL (replaces url_to_postid function).
|
204 |
+
*
|
205 |
+
* @since 3.3.0
|
206 |
+
* @access private
|
207 |
+
*
|
208 |
+
* @param string $href Affilaite link cloaked URL.
|
209 |
+
* @return int Affiliate link ID.
|
210 |
+
*/
|
211 |
+
private function url_to_affiliate_link_id( $href ) {
|
212 |
+
|
213 |
+
global $wpdb;
|
214 |
+
|
215 |
+
$link_parts = explode( "/" , $href );
|
216 |
+
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
217 |
+
$cpt_slug = esc_sql( Plugin_Constants::AFFILIATE_LINKS_CPT );
|
218 |
+
|
219 |
+
// get the key of the link prefix in the url from the $link_parts variable.
|
220 |
+
$key = (int) array_search( $link_prefix , $link_parts );
|
221 |
+
|
222 |
+
// get the slug from the $link_parts variable based on the position of the link prefix's key.
|
223 |
+
// if $key + 2 exists, this means that the link has a category slug in it, so we fetch $key + 2, otherwise we fetch $key + 1 (no category slug).
|
224 |
+
$slug = esc_sql( isset( $link_parts[ $key + 2 ] ) && $link_parts[ $key + 2 ] ? $link_parts[ $key + 2 ] : $link_parts[ $key + 1 ] );
|
225 |
+
|
226 |
+
// fetch the ID based on the post type and slug.
|
227 |
+
$id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type = '$cpt_slug' AND post_name = '$slug'" );
|
228 |
+
|
229 |
+
return $id ? absint( $id ) : 0;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Ajax link fixer.
|
234 |
+
*
|
235 |
+
* @since 3.0.0
|
236 |
+
* @access public
|
237 |
+
*/
|
238 |
+
public function ajax_link_fixer() {
|
239 |
+
|
240 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
241 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
242 |
+
elseif ( ! isset( $_POST[ 'hrefs' ] ) || empty( $_POST[ 'hrefs' ] ) )
|
243 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
244 |
+
else {
|
245 |
+
|
246 |
+
$links = $_POST[ 'hrefs' ];
|
247 |
+
$post_id = isset( $_POST[ 'post_id' ] ) ? intval( $_POST[ 'post_id' ] ) : 0;
|
248 |
+
$response = array(
|
249 |
+
'status' => 'success',
|
250 |
+
'data' => $this->get_link_fixer_data( $links , $post_id )
|
251 |
+
);
|
252 |
+
}
|
253 |
+
|
254 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
255 |
+
echo wp_json_encode( $response );
|
256 |
+
wp_die();
|
257 |
+
}
|
258 |
+
|
259 |
+
|
260 |
+
|
261 |
+
|
262 |
+
/*
|
263 |
+
|--------------------------------------------------------------------------
|
264 |
+
| Fulfill implemented interface contracts
|
265 |
+
|--------------------------------------------------------------------------
|
266 |
+
*/
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Execute codes that needs to run on plugin initialization.
|
270 |
+
*
|
271 |
+
* @since 3.0.0
|
272 |
+
* @access public
|
273 |
+
* @implements ThirstyAffiliates\Interfaces\Initiable_Interface
|
274 |
+
*/
|
275 |
+
public function initialize() {
|
276 |
+
|
277 |
+
add_action( 'wp_ajax_ta_link_fixer' , array( $this , 'ajax_link_fixer' ) );
|
278 |
+
add_action( 'wp_ajax_nopriv_ta_link_fixer' , array( $this , 'ajax_link_fixer' ) );
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Execute link picker.
|
283 |
+
*
|
284 |
+
* @since 3.0.0
|
285 |
+
* @access public
|
286 |
+
*/
|
287 |
+
public function run() {
|
288 |
+
}
|
289 |
+
}
|
Models/Link_Picker.php
CHANGED
@@ -1,658 +1,709 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
-
|
10 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
-
|
13 |
-
use ThirstyAffiliates\Models\Affiliate_Link;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Model that houses the link picker logic.
|
17 |
-
*
|
18 |
-
* @since 3.0.0
|
19 |
-
*/
|
20 |
-
class Link_Picker implements Model_Interface , Initiable_Interface {
|
21 |
-
|
22 |
-
/*
|
23 |
-
|--------------------------------------------------------------------------
|
24 |
-
| Class Properties
|
25 |
-
|--------------------------------------------------------------------------
|
26 |
-
*/
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Property that holds the single main instance of Bootstrap.
|
30 |
-
*
|
31 |
-
* @since 3.0.0
|
32 |
-
* @access private
|
33 |
-
* @var Link_Picker
|
34 |
-
*/
|
35 |
-
private static $_instance;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Model that houses the main plugin object.
|
39 |
-
*
|
40 |
-
* @since 3.0.0
|
41 |
-
* @access private
|
42 |
-
* @var Abstract_Main_Plugin_Class
|
43 |
-
*/
|
44 |
-
private $_main_plugin;
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Model that houses all the plugin constants.
|
48 |
-
*
|
49 |
-
* @since 3.0.0
|
50 |
-
* @access private
|
51 |
-
* @var Plugin_Constants
|
52 |
-
*/
|
53 |
-
private $_constants;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Property that houses all the helper functions of the plugin.
|
57 |
-
*
|
58 |
-
* @since 3.0.0
|
59 |
-
* @access private
|
60 |
-
* @var Helper_Functions
|
61 |
-
*/
|
62 |
-
private $_helper_functions;
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
/*
|
68 |
-
|--------------------------------------------------------------------------
|
69 |
-
| Class Methods
|
70 |
-
|--------------------------------------------------------------------------
|
71 |
-
*/
|
72 |
-
|
73 |
-
/**
|
74 |
-
* Class constructor.
|
75 |
-
*
|
76 |
-
* @since 3.0.0
|
77 |
-
* @access public
|
78 |
-
*
|
79 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
80 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
81 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
82 |
-
*/
|
83 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
84 |
-
|
85 |
-
$this->_constants = $constants;
|
86 |
-
$this->_helper_functions = $helper_functions;
|
87 |
-
|
88 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
89 |
-
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
94 |
-
*
|
95 |
-
* @since 3.0.0
|
96 |
-
* @access public
|
97 |
-
*
|
98 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
99 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
100 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
101 |
-
* @return Link_Picker
|
102 |
-
*/
|
103 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
104 |
-
|
105 |
-
if ( !self::$_instance instanceof self )
|
106 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
107 |
-
|
108 |
-
return self::$_instance;
|
109 |
-
|
110 |
-
}
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
/*
|
115 |
-
|--------------------------------------------------------------------------
|
116 |
-
| Register tinymce buttons and scripts
|
117 |
-
|--------------------------------------------------------------------------
|
118 |
-
*/
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Initialize thirsty editor buttons.
|
122 |
-
*
|
123 |
-
* @since 3.0.0
|
124 |
-
* @access public
|
125 |
-
*/
|
126 |
-
public function init_thirsty_editor_buttons() {
|
127 |
-
|
128 |
-
if ( ! is_admin() || ! current_user_can( 'edit_posts' ) )
|
129 |
-
return;
|
130 |
-
|
131 |
-
if ( get_option( 'ta_disable_visual_editor_buttons' ) == 'yes' || get_user_option( 'rich_editing' ) != 'true' )
|
132 |
-
return;
|
133 |
-
|
134 |
-
add_filter( 'mce_external_plugins' , array( $this , 'load_thirsty_mce_plugin' ) );
|
135 |
-
add_filter( 'mce_buttons' , array( $this , 'register_mce_buttons' ) , 5 );
|
136 |
-
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Initialize thirsty editor buttons on page builders.
|
141 |
-
*
|
142 |
-
* @since 3.4.0
|
143 |
-
* @access public
|
144 |
-
*/
|
145 |
-
public function init_thirsty_editor_buttons_for_page_builders() {
|
146 |
-
|
147 |
-
if ( get_option( 'ta_disable_visual_editor_buttons' ) == 'yes' || get_user_option( 'rich_editing' ) != 'true' )
|
148 |
-
return;
|
149 |
-
|
150 |
-
if ( ! $this->_helper_functions->is_page_builder_active() || ! current_user_can( 'edit_posts' ) )
|
151 |
-
return;
|
152 |
-
|
153 |
-
add_filter( 'mce_external_plugins' , array( $this , 'load_thirsty_mce_plugin' ) , 99999 );
|
154 |
-
add_filter( 'mce_buttons' , array( $this , 'register_mce_buttons' ) , 99 );
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Load Thirsty Affiliate MCE plugin to TinyMCE.
|
159 |
-
*
|
160 |
-
* @since 3.0.0
|
161 |
-
* @access public
|
162 |
-
*
|
163 |
-
* @param array $mce_plugins Array of all MCE plugins.
|
164 |
-
* @return array
|
165 |
-
*/
|
166 |
-
public function load_thirsty_mce_plugin( $mce_plugins ) {
|
167 |
-
|
168 |
-
$mce_plugins[ 'thirstyaffiliates' ] = $this->_constants->JS_ROOT_URL() . 'lib/thirstymce/editor-plugin.js';
|
169 |
-
|
170 |
-
return $mce_plugins;
|
171 |
-
}
|
172 |
-
|
173 |
-
/**
|
174 |
-
* Register Thirsty Affiliate MCE buttons.
|
175 |
-
*
|
176 |
-
* @since 3.0.0
|
177 |
-
* @since 3.4.0 Make sure only one instance of the buttons are loaded.
|
178 |
-
* @access public
|
179 |
-
*
|
180 |
-
* @param array $buttons Array of all MCE buttons.
|
181 |
-
* @return array
|
182 |
-
*/
|
183 |
-
public function register_mce_buttons( $buttons ) {
|
184 |
-
|
185 |
-
// if buttons are already present, then skip to prevent duplicate.
|
186 |
-
if ( in_array( 'thirstyaffiliates_button' , $buttons ) )
|
187 |
-
return $buttons;
|
188 |
-
|
189 |
-
$enable_link_picker = current_user_can( apply_filters( 'ta_enable_advance_link_picker' , 'edit_posts' ) );
|
190 |
-
$enable_quick_add = current_user_can( apply_filters( 'ta_enable_quick_add_affiliate_link' , 'publish_posts' ) );
|
191 |
-
|
192 |
-
if ( $enable_link_picker ) array_push( $buttons , 'separator' , 'thirstyaffiliates_button' );
|
193 |
-
if ( $enable_quick_add ) array_push( $buttons , 'separator' , 'thirstyaffiliates_quickaddlink_button' );
|
194 |
-
|
195 |
-
return $buttons;
|
196 |
-
}
|
197 |
-
|
198 |
-
/**
|
199 |
-
* Register WP Editor style.
|
200 |
-
*
|
201 |
-
* @since 3.4.0
|
202 |
-
* @access public
|
203 |
-
*/
|
204 |
-
public function register_wp_editor_style() {
|
205 |
-
|
206 |
-
add_editor_style( $this->_constants->CSS_ROOT_URL() . 'admin/tinymce/editor.css' );
|
207 |
-
}
|
208 |
-
|
209 |
-
/**
|
210 |
-
* Register WP Editor style via mce_css filter (for frontend editors).
|
211 |
-
*
|
212 |
-
* @since 3.4.0
|
213 |
-
* @access public
|
214 |
-
*/
|
215 |
-
public function register_wp_editor_style_mce_css( $mce_css ) {
|
216 |
-
|
217 |
-
if ( ! empty( $mce_css ) ) $mce_css .= ',';
|
218 |
-
$mce_css .= $this->_constants->CSS_ROOT_URL() . 'admin/tinymce/editor.css';
|
219 |
-
|
220 |
-
return $mce_css;
|
221 |
-
}
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
/*
|
227 |
-
|--------------------------------------------------------------------------
|
228 |
-
| Link Picker methods
|
229 |
-
|--------------------------------------------------------------------------
|
230 |
-
*/
|
231 |
-
|
232 |
-
/**
|
233 |
-
* Return
|
234 |
-
*
|
235 |
-
* @since 3.0.0
|
236 |
-
* @since 3.4.0 Add support for additional CSS classes field. Add support for external images.
|
237 |
-
* @access public
|
238 |
-
*
|
239 |
-
* @param array $affiliate_links List of affiliate link IDs.
|
240 |
-
* @param bool $advanced Boolean check if its advanced or not.
|
241 |
-
* @param int $post_id ID of the post currently being edited.
|
242 |
-
* @param string $result_markup Search Affiliate Links result markup.
|
243 |
-
* @return Search Affiliate Links result markup
|
244 |
-
*/
|
245 |
-
public function search_affiliate_links_result_markup( $affiliate_links , $advance = false , $post_id = 0 , $result_markup = '' ) {
|
246 |
-
|
247 |
-
if ( is_array( $affiliate_links ) && ! empty( $affiliate_links ) ) {
|
248 |
-
|
249 |
-
foreach( $affiliate_links as $link_id ) {
|
250 |
-
|
251 |
-
$thirstylink = new Affiliate_Link( $link_id );
|
252 |
-
$rel = $thirstylink->is( 'no_follow' ) ? 'nofollow' : '';
|
253 |
-
$target = $thirstylink->is( 'new_window' ) ? '_blank' : '';
|
254 |
-
$class = ( get_option( 'ta_disable_thirsty_link_class' ) !== "yes" ) ? 'thirstylink' : '';
|
255 |
-
$title = ( get_option( 'ta_disable_title_attribute' ) !== "yes" ) ? $thirstylink->get_prop( 'name' ) : '';
|
256 |
-
$other_atts = esc_attr( json_encode( apply_filters( 'ta_link_insert_extend_data_attributes' , array() , $thirstylink , $post_id ) ) );
|
257 |
-
|
258 |
-
if ( $thirstylink->get_prop( 'rel_tags' ) )
|
259 |
-
$rel = trim( $rel . ' ' . $thirstylink->get_prop( 'rel_tags' ) );
|
260 |
-
|
261 |
-
if ( $thirstylink->get_prop( 'css_classes' ) )
|
262 |
-
$class = trim( $class . ' ' . $thirstylink->get_prop( 'css_classes' ) );
|
263 |
-
|
264 |
-
if ( $advance ) {
|
265 |
-
|
266 |
-
$images = $thirstylink->get_prop( 'image_ids' );
|
267 |
-
$images_markup = '<span class="images-block">';
|
268 |
-
|
269 |
-
if ( is_array( $images ) && ! empty( $images ) ) {
|
270 |
-
|
271 |
-
$images_markup .= '<span class="label">' . __( 'Select image:' , 'thirstyaffiliates' ) . '</span>';
|
272 |
-
$images_markup .= '<span class="images">';
|
273 |
-
|
274 |
-
foreach( $images as $image ) {
|
275 |
-
|
276 |
-
if ( filter_var( $image , FILTER_VALIDATE_URL ) )
|
277 |
-
$images_markup .= '<span class="image"><img src="'. $image .'" width="75" height="75" data-imgid="' . $image . '" data-type="image"></span>';
|
278 |
-
else
|
279 |
-
$images_markup .= '<span class="image">' . wp_get_attachment_image( $image , array( 75 , 75 ) , false , array( 'data-imgid' => $image , 'data-type' => 'image' ) ) . '</span>';
|
280 |
-
|
281 |
-
}
|
282 |
-
|
283 |
-
$images_markup .= '</span>';
|
284 |
-
} else {
|
285 |
-
|
286 |
-
$images_markup .= '<span class="no-images">' . __( 'No images found' , 'thirstyaffiliates' ) . '</span>';
|
287 |
-
}
|
288 |
-
|
289 |
-
$images_markup .= '</span>';
|
290 |
-
|
291 |
-
$result_markup .= '<li class="thirstylink"
|
292 |
-
data-linkid="' . $thirstylink->get_id() . '"
|
293 |
-
data-class="' . esc_attr( $class ) . '"
|
294 |
-
data-title="' . esc_attr( str_replace( '"' , '' , $title ) ) . '"
|
295 |
-
data-href="' . esc_url( $thirstylink->get_prop( 'permalink' ) ) . '"
|
296 |
-
data-rel="' . trim( esc_attr( $rel ) ) . '"
|
297 |
-
data-target="' . esc_attr( $target ) . '"
|
298 |
-
data-other-atts="' . $other_atts . '">
|
299 |
-
<span class="name">' . mb_strimwidth( $thirstylink->get_prop( 'name' ) , 0 , 44 , "..." ) . '</span>
|
300 |
-
<span class="slug">[' . mb_strimwidth( $thirstylink->get_prop( 'slug' ) , 0 , 35 , "..." ) . ']</span>
|
301 |
-
<span class="actions">
|
302 |
-
<button type="button" data-type="normal" class="button insert-link-button dashicons dashicons-admin-links" data-tip="' . __( 'Insert link' , 'thirstyaffiliates' ) . '"></button>
|
303 |
-
<button type="button" data-type="shortcode" class="button insert-shortcode-button dashicons dashicons-editor-code" data-tip="' . __( 'Insert shortcode' , 'thirstyaffiliates' ) . '"></button>
|
304 |
-
<button type="button" data-type="image" class="button insert-image-button dashicons dashicons-format-image" data-tip="' . __( 'Insert image' , 'thirstyaffiliates' ) . '"></button>
|
305 |
-
</span>
|
306 |
-
' . $images_markup . '
|
307 |
-
</li>';
|
308 |
-
} else {
|
309 |
-
|
310 |
-
$result_markup .= '<li data-class="' . esc_attr( $class ) . '"
|
311 |
-
data-title="' . esc_attr( str_replace( '"' , '' , $title ) ) . '"
|
312 |
-
data-href="' . esc_attr( $thirstylink->get_prop( 'permalink' ) ) . '"
|
313 |
-
data-rel="' . esc_attr( $rel ) . '"
|
314 |
-
data-target="' . esc_attr( $target ) . '"
|
315 |
-
data-link-id="' . esc_attr( $thirstylink->get_id() ) . '"
|
316 |
-
data-link-insertion-type="' . esc_attr( $this->_helper_functions->get_option( 'ta_link_insertion_type' , 'link' ) ) . '"
|
317 |
-
data-other-atts="' . $other_atts . '">';
|
318 |
-
$result_markup .= '<strong>' . $link_id . '</strong> : <span>' . $thirstylink->get_prop( 'name' ) . '</span></li>';
|
319 |
-
|
320 |
-
}
|
321 |
-
|
322 |
-
}
|
323 |
-
|
324 |
-
} else
|
325 |
-
$result_markup .= '<li class="no-links-found">' . __( 'No affiliate links found' , 'thirstyaffiliates' ) . '</li>';
|
326 |
-
|
327 |
-
return $result_markup;
|
328 |
-
}
|
329 |
-
|
330 |
-
/**
|
331 |
-
* Search Affiliate Links Query AJAX function
|
332 |
-
*
|
333 |
-
* @since 3.0.0
|
334 |
-
* @since 3.4.0 Add support for category in the search query.
|
335 |
-
* @access public
|
336 |
-
*/
|
337 |
-
public function ajax_search_affiliate_links_query() {
|
338 |
-
|
339 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
340 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
341 |
-
elseif ( ! isset( $_POST[ 'keyword' ] ) )
|
342 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
343 |
-
else {
|
344 |
-
|
345 |
-
$paged = ( isset( $_POST[ 'paged' ] ) && $_POST[ 'paged' ] ) ? $_POST[ 'paged' ] : 1;
|
346 |
-
$category = ( isset( $_POST[ 'category' ] ) && $_POST[ 'category' ] ) ? esc_attr( $_POST[ 'category' ] ) : '';
|
347 |
-
$exclude = ( isset( $_POST[ 'exclude' ] ) && is_array( $_POST[ 'exclude' ] ) && ! empty( $_POST[ 'exclude' ] ) ) ? $_POST[ 'exclude' ] : array();
|
348 |
-
$
|
349 |
-
$
|
350 |
-
$
|
351 |
-
$
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
$
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
$
|
457 |
-
$
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
$thirstylink
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
$thirstylink->
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
$
|
540 |
-
|
541 |
-
$
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
$
|
552 |
-
'
|
553 |
-
|
554 |
-
|
555 |
-
'
|
556 |
-
|
557 |
-
|
558 |
-
'
|
559 |
-
'
|
560 |
-
'
|
561 |
-
'
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
*
|
618 |
-
*
|
619 |
-
* @
|
620 |
-
*
|
621 |
-
* @
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
+
|
10 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
+
|
13 |
+
use ThirstyAffiliates\Models\Affiliate_Link;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Model that houses the link picker logic.
|
17 |
+
*
|
18 |
+
* @since 3.0.0
|
19 |
+
*/
|
20 |
+
class Link_Picker implements Model_Interface , Initiable_Interface {
|
21 |
+
|
22 |
+
/*
|
23 |
+
|--------------------------------------------------------------------------
|
24 |
+
| Class Properties
|
25 |
+
|--------------------------------------------------------------------------
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Property that holds the single main instance of Bootstrap.
|
30 |
+
*
|
31 |
+
* @since 3.0.0
|
32 |
+
* @access private
|
33 |
+
* @var Link_Picker
|
34 |
+
*/
|
35 |
+
private static $_instance;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Model that houses the main plugin object.
|
39 |
+
*
|
40 |
+
* @since 3.0.0
|
41 |
+
* @access private
|
42 |
+
* @var Abstract_Main_Plugin_Class
|
43 |
+
*/
|
44 |
+
private $_main_plugin;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Model that houses all the plugin constants.
|
48 |
+
*
|
49 |
+
* @since 3.0.0
|
50 |
+
* @access private
|
51 |
+
* @var Plugin_Constants
|
52 |
+
*/
|
53 |
+
private $_constants;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Property that houses all the helper functions of the plugin.
|
57 |
+
*
|
58 |
+
* @since 3.0.0
|
59 |
+
* @access private
|
60 |
+
* @var Helper_Functions
|
61 |
+
*/
|
62 |
+
private $_helper_functions;
|
63 |
+
|
64 |
+
|
65 |
+
|
66 |
+
|
67 |
+
/*
|
68 |
+
|--------------------------------------------------------------------------
|
69 |
+
| Class Methods
|
70 |
+
|--------------------------------------------------------------------------
|
71 |
+
*/
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Class constructor.
|
75 |
+
*
|
76 |
+
* @since 3.0.0
|
77 |
+
* @access public
|
78 |
+
*
|
79 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
80 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
81 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
82 |
+
*/
|
83 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
84 |
+
|
85 |
+
$this->_constants = $constants;
|
86 |
+
$this->_helper_functions = $helper_functions;
|
87 |
+
|
88 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
89 |
+
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
94 |
+
*
|
95 |
+
* @since 3.0.0
|
96 |
+
* @access public
|
97 |
+
*
|
98 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
99 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
100 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
101 |
+
* @return Link_Picker
|
102 |
+
*/
|
103 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
104 |
+
|
105 |
+
if ( !self::$_instance instanceof self )
|
106 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
107 |
+
|
108 |
+
return self::$_instance;
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
/*
|
115 |
+
|--------------------------------------------------------------------------
|
116 |
+
| Register tinymce buttons and scripts
|
117 |
+
|--------------------------------------------------------------------------
|
118 |
+
*/
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Initialize thirsty editor buttons.
|
122 |
+
*
|
123 |
+
* @since 3.0.0
|
124 |
+
* @access public
|
125 |
+
*/
|
126 |
+
public function init_thirsty_editor_buttons() {
|
127 |
+
|
128 |
+
if ( ! is_admin() || ! current_user_can( 'edit_posts' ) )
|
129 |
+
return;
|
130 |
+
|
131 |
+
if ( get_option( 'ta_disable_visual_editor_buttons' ) == 'yes' || get_user_option( 'rich_editing' ) != 'true' )
|
132 |
+
return;
|
133 |
+
|
134 |
+
add_filter( 'mce_external_plugins' , array( $this , 'load_thirsty_mce_plugin' ) );
|
135 |
+
add_filter( 'mce_buttons' , array( $this , 'register_mce_buttons' ) , 5 );
|
136 |
+
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Initialize thirsty editor buttons on page builders.
|
141 |
+
*
|
142 |
+
* @since 3.4.0
|
143 |
+
* @access public
|
144 |
+
*/
|
145 |
+
public function init_thirsty_editor_buttons_for_page_builders() {
|
146 |
+
|
147 |
+
if ( get_option( 'ta_disable_visual_editor_buttons' ) == 'yes' || get_user_option( 'rich_editing' ) != 'true' )
|
148 |
+
return;
|
149 |
+
|
150 |
+
if ( ! $this->_helper_functions->is_page_builder_active() || ! current_user_can( 'edit_posts' ) )
|
151 |
+
return;
|
152 |
+
|
153 |
+
add_filter( 'mce_external_plugins' , array( $this , 'load_thirsty_mce_plugin' ) , 99999 );
|
154 |
+
add_filter( 'mce_buttons' , array( $this , 'register_mce_buttons' ) , 99 );
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Load Thirsty Affiliate MCE plugin to TinyMCE.
|
159 |
+
*
|
160 |
+
* @since 3.0.0
|
161 |
+
* @access public
|
162 |
+
*
|
163 |
+
* @param array $mce_plugins Array of all MCE plugins.
|
164 |
+
* @return array
|
165 |
+
*/
|
166 |
+
public function load_thirsty_mce_plugin( $mce_plugins ) {
|
167 |
+
|
168 |
+
$mce_plugins[ 'thirstyaffiliates' ] = $this->_constants->JS_ROOT_URL() . 'lib/thirstymce/editor-plugin.js';
|
169 |
+
|
170 |
+
return $mce_plugins;
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Register Thirsty Affiliate MCE buttons.
|
175 |
+
*
|
176 |
+
* @since 3.0.0
|
177 |
+
* @since 3.4.0 Make sure only one instance of the buttons are loaded.
|
178 |
+
* @access public
|
179 |
+
*
|
180 |
+
* @param array $buttons Array of all MCE buttons.
|
181 |
+
* @return array
|
182 |
+
*/
|
183 |
+
public function register_mce_buttons( $buttons ) {
|
184 |
+
|
185 |
+
// if buttons are already present, then skip to prevent duplicate.
|
186 |
+
if ( in_array( 'thirstyaffiliates_button' , $buttons ) )
|
187 |
+
return $buttons;
|
188 |
+
|
189 |
+
$enable_link_picker = current_user_can( apply_filters( 'ta_enable_advance_link_picker' , 'edit_posts' ) );
|
190 |
+
$enable_quick_add = current_user_can( apply_filters( 'ta_enable_quick_add_affiliate_link' , 'publish_posts' ) );
|
191 |
+
|
192 |
+
if ( $enable_link_picker ) array_push( $buttons , 'separator' , 'thirstyaffiliates_button' );
|
193 |
+
if ( $enable_quick_add ) array_push( $buttons , 'separator' , 'thirstyaffiliates_quickaddlink_button' );
|
194 |
+
|
195 |
+
return $buttons;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Register WP Editor style.
|
200 |
+
*
|
201 |
+
* @since 3.4.0
|
202 |
+
* @access public
|
203 |
+
*/
|
204 |
+
public function register_wp_editor_style() {
|
205 |
+
|
206 |
+
add_editor_style( $this->_constants->CSS_ROOT_URL() . 'admin/tinymce/editor.css' );
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Register WP Editor style via mce_css filter (for frontend editors).
|
211 |
+
*
|
212 |
+
* @since 3.4.0
|
213 |
+
* @access public
|
214 |
+
*/
|
215 |
+
public function register_wp_editor_style_mce_css( $mce_css ) {
|
216 |
+
|
217 |
+
if ( ! empty( $mce_css ) ) $mce_css .= ',';
|
218 |
+
$mce_css .= $this->_constants->CSS_ROOT_URL() . 'admin/tinymce/editor.css';
|
219 |
+
|
220 |
+
return $mce_css;
|
221 |
+
}
|
222 |
+
|
223 |
+
|
224 |
+
|
225 |
+
|
226 |
+
/*
|
227 |
+
|--------------------------------------------------------------------------
|
228 |
+
| Link Picker methods
|
229 |
+
|--------------------------------------------------------------------------
|
230 |
+
*/
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Return
|
234 |
+
*
|
235 |
+
* @since 3.0.0
|
236 |
+
* @since 3.4.0 Add support for additional CSS classes field. Add support for external images.
|
237 |
+
* @access public
|
238 |
+
*
|
239 |
+
* @param array $affiliate_links List of affiliate link IDs.
|
240 |
+
* @param bool $advanced Boolean check if its advanced or not.
|
241 |
+
* @param int $post_id ID of the post currently being edited.
|
242 |
+
* @param string $result_markup Search Affiliate Links result markup.
|
243 |
+
* @return Search Affiliate Links result markup
|
244 |
+
*/
|
245 |
+
public function search_affiliate_links_result_markup( $affiliate_links , $advance = false , $post_id = 0 , $result_markup = '' ) {
|
246 |
+
|
247 |
+
if ( is_array( $affiliate_links ) && ! empty( $affiliate_links ) ) {
|
248 |
+
|
249 |
+
foreach( $affiliate_links as $link_id ) {
|
250 |
+
|
251 |
+
$thirstylink = new Affiliate_Link( $link_id );
|
252 |
+
$rel = $thirstylink->is( 'no_follow' ) ? 'nofollow' : '';
|
253 |
+
$target = $thirstylink->is( 'new_window' ) ? '_blank' : '';
|
254 |
+
$class = ( get_option( 'ta_disable_thirsty_link_class' ) !== "yes" ) ? 'thirstylink' : '';
|
255 |
+
$title = ( get_option( 'ta_disable_title_attribute' ) !== "yes" ) ? $thirstylink->get_prop( 'name' ) : '';
|
256 |
+
$other_atts = esc_attr( json_encode( apply_filters( 'ta_link_insert_extend_data_attributes' , array() , $thirstylink , $post_id ) ) );
|
257 |
+
|
258 |
+
if ( $thirstylink->get_prop( 'rel_tags' ) )
|
259 |
+
$rel = trim( $rel . ' ' . $thirstylink->get_prop( 'rel_tags' ) );
|
260 |
+
|
261 |
+
if ( $thirstylink->get_prop( 'css_classes' ) )
|
262 |
+
$class = trim( $class . ' ' . $thirstylink->get_prop( 'css_classes' ) );
|
263 |
+
|
264 |
+
if ( $advance ) {
|
265 |
+
|
266 |
+
$images = $thirstylink->get_prop( 'image_ids' );
|
267 |
+
$images_markup = '<span class="images-block">';
|
268 |
+
|
269 |
+
if ( is_array( $images ) && ! empty( $images ) ) {
|
270 |
+
|
271 |
+
$images_markup .= '<span class="label">' . __( 'Select image:' , 'thirstyaffiliates' ) . '</span>';
|
272 |
+
$images_markup .= '<span class="images">';
|
273 |
+
|
274 |
+
foreach( $images as $image ) {
|
275 |
+
|
276 |
+
if ( filter_var( $image , FILTER_VALIDATE_URL ) )
|
277 |
+
$images_markup .= '<span class="image"><img src="'. $image .'" width="75" height="75" data-imgid="' . $image . '" data-type="image"></span>';
|
278 |
+
else
|
279 |
+
$images_markup .= '<span class="image">' . wp_get_attachment_image( $image , array( 75 , 75 ) , false , array( 'data-imgid' => $image , 'data-type' => 'image' ) ) . '</span>';
|
280 |
+
|
281 |
+
}
|
282 |
+
|
283 |
+
$images_markup .= '</span>';
|
284 |
+
} else {
|
285 |
+
|
286 |
+
$images_markup .= '<span class="no-images">' . __( 'No images found' , 'thirstyaffiliates' ) . '</span>';
|
287 |
+
}
|
288 |
+
|
289 |
+
$images_markup .= '</span>';
|
290 |
+
|
291 |
+
$result_markup .= '<li class="thirstylink"
|
292 |
+
data-linkid="' . $thirstylink->get_id() . '"
|
293 |
+
data-class="' . esc_attr( $class ) . '"
|
294 |
+
data-title="' . esc_attr( str_replace( '"' , '' , $title ) ) . '"
|
295 |
+
data-href="' . esc_url( $thirstylink->get_prop( 'permalink' ) ) . '"
|
296 |
+
data-rel="' . trim( esc_attr( $rel ) ) . '"
|
297 |
+
data-target="' . esc_attr( $target ) . '"
|
298 |
+
data-other-atts="' . $other_atts . '">
|
299 |
+
<span class="name">' . mb_strimwidth( $thirstylink->get_prop( 'name' ) , 0 , 44 , "..." ) . '</span>
|
300 |
+
<span class="slug">[' . mb_strimwidth( $thirstylink->get_prop( 'slug' ) , 0 , 35 , "..." ) . ']</span>
|
301 |
+
<span class="actions">
|
302 |
+
<button type="button" data-type="normal" class="button insert-link-button dashicons dashicons-admin-links" data-tip="' . __( 'Insert link' , 'thirstyaffiliates' ) . '"></button>
|
303 |
+
<button type="button" data-type="shortcode" class="button insert-shortcode-button dashicons dashicons-editor-code" data-tip="' . __( 'Insert shortcode' , 'thirstyaffiliates' ) . '"></button>
|
304 |
+
<button type="button" data-type="image" class="button insert-image-button dashicons dashicons-format-image" data-tip="' . __( 'Insert image' , 'thirstyaffiliates' ) . '"></button>
|
305 |
+
</span>
|
306 |
+
' . $images_markup . '
|
307 |
+
</li>';
|
308 |
+
} else {
|
309 |
+
|
310 |
+
$result_markup .= '<li data-class="' . esc_attr( $class ) . '"
|
311 |
+
data-title="' . esc_attr( str_replace( '"' , '' , $title ) ) . '"
|
312 |
+
data-href="' . esc_attr( $thirstylink->get_prop( 'permalink' ) ) . '"
|
313 |
+
data-rel="' . esc_attr( $rel ) . '"
|
314 |
+
data-target="' . esc_attr( $target ) . '"
|
315 |
+
data-link-id="' . esc_attr( $thirstylink->get_id() ) . '"
|
316 |
+
data-link-insertion-type="' . esc_attr( $this->_helper_functions->get_option( 'ta_link_insertion_type' , 'link' ) ) . '"
|
317 |
+
data-other-atts="' . $other_atts . '">';
|
318 |
+
$result_markup .= '<strong>' . $link_id . '</strong> : <span>' . $thirstylink->get_prop( 'name' ) . '</span></li>';
|
319 |
+
|
320 |
+
}
|
321 |
+
|
322 |
+
}
|
323 |
+
|
324 |
+
} else
|
325 |
+
$result_markup .= '<li class="no-links-found">' . __( 'No affiliate links found' , 'thirstyaffiliates' ) . '</li>';
|
326 |
+
|
327 |
+
return $result_markup;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Search Affiliate Links Query AJAX function
|
332 |
+
*
|
333 |
+
* @since 3.0.0
|
334 |
+
* @since 3.4.0 Add support for category in the search query.
|
335 |
+
* @access public
|
336 |
+
*/
|
337 |
+
public function ajax_search_affiliate_links_query() {
|
338 |
+
|
339 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
340 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
341 |
+
elseif ( ! isset( $_POST[ 'keyword' ] ) )
|
342 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
343 |
+
else {
|
344 |
+
|
345 |
+
$paged = ( isset( $_POST[ 'paged' ] ) && $_POST[ 'paged' ] ) ? $_POST[ 'paged' ] : 1;
|
346 |
+
$category = ( isset( $_POST[ 'category' ] ) && $_POST[ 'category' ] ) ? esc_attr( $_POST[ 'category' ] ) : '';
|
347 |
+
$exclude = ( isset( $_POST[ 'exclude' ] ) && is_array( $_POST[ 'exclude' ] ) && ! empty( $_POST[ 'exclude' ] ) ) ? $_POST[ 'exclude' ] : array();
|
348 |
+
$is_gutenberg = isset( $_POST[ 'gutenberg' ] ) && $_POST[ 'gutenberg' ];
|
349 |
+
$affiliate_links = $this->_helper_functions->search_affiliate_links_query( $_POST[ 'keyword' ] , $paged , $category , $exclude , $is_gutenberg );
|
350 |
+
$advance = ( isset( $_POST[ 'advance' ] ) && $_POST[ 'advance' ] ) ? true : false;
|
351 |
+
$post_id = isset( $_POST[ 'post_id' ] ) ? intval( $_POST[ 'post_id' ] ) : 0;
|
352 |
+
|
353 |
+
if ( $is_gutenberg ) {
|
354 |
+
$response = array( 'status' => 'success' , 'affiliate_links' => $affiliate_links , 'count' => count( $affiliate_links ) );
|
355 |
+
} else {
|
356 |
+
$result_markup = $this->search_affiliate_links_result_markup( $affiliate_links , $advance , $post_id );
|
357 |
+
$response = array( 'status' => 'success' , 'search_query_markup' => $result_markup , 'count' => count( $affiliate_links ) );
|
358 |
+
}
|
359 |
+
|
360 |
+
}
|
361 |
+
|
362 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
363 |
+
echo wp_json_encode( $response );
|
364 |
+
wp_die();
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* AJAX function to display the advance add affiliate link thickbox content.
|
369 |
+
*
|
370 |
+
* @since 3.0.0
|
371 |
+
* @since 3.4.0 Add category field (selectized) in the search form.
|
372 |
+
* @access public
|
373 |
+
*/
|
374 |
+
public function ajax_display_advanced_add_affiliate_link() {
|
375 |
+
|
376 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX || ! current_user_can( apply_filters( 'ta_enable_advance_link_picker' , 'edit_posts' ) ) )
|
377 |
+
wp_die( "You're not allowed to do this." );
|
378 |
+
|
379 |
+
$post_id = isset( $_REQUEST[ 'post_id' ] ) ? intval( $_REQUEST[ 'post_id' ] ) : 0;
|
380 |
+
$affiliate_links = $this->_helper_functions->search_affiliate_links_query();
|
381 |
+
$result_markup = $this->search_affiliate_links_result_markup( $affiliate_links , true , $post_id );
|
382 |
+
$html_editor = isset( $_REQUEST[ 'html_editor' ] ) ? sanitize_text_field( $_REQUEST[ 'html_editor' ] ) : false;
|
383 |
+
|
384 |
+
wp_enqueue_script('editor');
|
385 |
+
wp_dequeue_script('jquery-ui-core');
|
386 |
+
wp_dequeue_script('jquery-ui-sortable');
|
387 |
+
wp_dequeue_script('admin-scripts');
|
388 |
+
wp_enqueue_style( 'jquery_tiptip' , $this->_constants->CSS_ROOT_URL() . 'lib/jquery-tiptip/jquery-tiptip.css' , array() , $this->_constants->VERSION() , 'all' );
|
389 |
+
wp_enqueue_style( 'ta_advance_link_picker_css' , $this->_constants->JS_ROOT_URL() . 'app/advance_link_picker/dist/advance-link-picker.css' , array( 'dashicons' ) , $this->_constants->VERSION() , 'all' );
|
390 |
+
wp_enqueue_style( 'selectize' , $this->_constants->JS_ROOT_URL() . 'lib/selectize/selectize.default.css' , array() , Plugin_Constants::VERSION , 'all' );
|
391 |
+
wp_enqueue_script( 'jquery_tiptip' , $this->_constants->JS_ROOT_URL() . 'lib/jquery-tiptip/jquery.tipTip.min.js' , array() , $this->_constants->VERSION() );
|
392 |
+
wp_enqueue_script( 'ta_advance_link_picker_js' , $this->_constants->JS_ROOT_URL() . 'app/advance_link_picker/dist/advance-link-picker.js' , array( 'jquery_tiptip' ) , $this->_constants->VERSION() );
|
393 |
+
wp_enqueue_script( 'selectize' , $this->_constants->JS_ROOT_URL() . 'lib/selectize/selectize.min.js' , array() , Plugin_Constants::VERSION );
|
394 |
+
|
395 |
+
include( $this->_constants->VIEWS_ROOT_PATH() . 'linkpicker/advance-link-picker.php' );
|
396 |
+
|
397 |
+
wp_die();
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Get image markup by ID.
|
402 |
+
*
|
403 |
+
* @since 3.0.0
|
404 |
+
* @since 3.4.0 Add support for external images.
|
405 |
+
* @access public
|
406 |
+
*/
|
407 |
+
public function ajax_get_image_markup_by_id() {
|
408 |
+
|
409 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
410 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
411 |
+
elseif ( ! isset( $_REQUEST[ 'imgid' ] ) )
|
412 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
413 |
+
else {
|
414 |
+
|
415 |
+
if ( filter_var( $_REQUEST[ 'imgid' ] , FILTER_VALIDATE_URL ) ) {
|
416 |
+
|
417 |
+
$image_url = esc_url( $_REQUEST[ 'imgid' ] );
|
418 |
+
$image_markup = '<img src="' . $image_url . '">';
|
419 |
+
|
420 |
+
} else {
|
421 |
+
|
422 |
+
$image_id = (int) sanitize_text_field( $_REQUEST[ 'imgid' ] );
|
423 |
+
$image_markup = wp_get_attachment_image( $image_id , 'full' );
|
424 |
+
}
|
425 |
+
|
426 |
+
$response = array( 'status' => 'success' , 'image_markup' => $image_markup );
|
427 |
+
}
|
428 |
+
|
429 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
430 |
+
echo wp_json_encode( $response );
|
431 |
+
wp_die();
|
432 |
+
}
|
433 |
+
|
434 |
+
|
435 |
+
|
436 |
+
|
437 |
+
|
438 |
+
/*
|
439 |
+
|--------------------------------------------------------------------------
|
440 |
+
| Quick Add Affiliate Link methods
|
441 |
+
|--------------------------------------------------------------------------
|
442 |
+
*/
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Display the quick add affiliate link content on the thickbox popup.
|
446 |
+
*
|
447 |
+
* @since 3.0.0
|
448 |
+
* @since 3.4.0 Add global option for redirect type.
|
449 |
+
* @access public
|
450 |
+
*/
|
451 |
+
public function ajax_display_quick_add_affiliate_link_thickbox() {
|
452 |
+
|
453 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX || ! current_user_can( apply_filters( 'ta_enable_quick_add_affiliate_link' , 'publish_posts' ) ) )
|
454 |
+
wp_die( "You're not allowed to do this." );
|
455 |
+
|
456 |
+
$post_id = isset( $_REQUEST[ 'post_id' ] ) ? intval( $_REQUEST[ 'post_id' ] ) : 0;
|
457 |
+
$redirect_types = $this->_constants->REDIRECT_TYPES();
|
458 |
+
$selection = sanitize_text_field( $_REQUEST[ 'selection' ] );
|
459 |
+
$default_redirect_type = get_option( 'ta_link_redirect_type' , '301' );
|
460 |
+
$global_no_follow = get_option( 'ta_no_follow' ) == 'yes' ? 'yes' : 'no';
|
461 |
+
$global_new_window = get_option( 'ta_new_window' ) == 'yes' ? 'yes' : 'no';
|
462 |
+
$html_editor = isset( $_REQUEST[ 'html_editor' ] ) ? sanitize_text_field( $_REQUEST[ 'html_editor' ] ) : false;
|
463 |
+
$categories = get_terms( Plugin_Constants::AFFILIATE_LINKS_TAX , array(
|
464 |
+
'hide_empty' => false,
|
465 |
+
) );
|
466 |
+
|
467 |
+
wp_enqueue_style( 'ta_quick_add_affiliate_link_css' , $this->_constants->JS_ROOT_URL() . 'app/quick_add_affiliate_link/dist/quick-add-affiliate-link.css' , array( 'dashicons' ) , $this->_constants->VERSION() , 'all' );
|
468 |
+
wp_enqueue_style( 'selectize' , $this->_constants->JS_ROOT_URL() . 'lib/selectize/selectize.default.css' , array() , Plugin_Constants::VERSION , 'all' );
|
469 |
+
|
470 |
+
wp_enqueue_script('editor');
|
471 |
+
wp_dequeue_script('jquery-ui-core');
|
472 |
+
wp_dequeue_script('jquery-ui-sortable');
|
473 |
+
wp_dequeue_script('admin-scripts');
|
474 |
+
wp_enqueue_script( 'ta_quick_add_affiliate_link_js' , $this->_constants->JS_ROOT_URL() . 'app/quick_add_affiliate_link/dist/quick-add-affiliate-link.js' , array() , $this->_constants->VERSION() );
|
475 |
+
wp_enqueue_script( 'selectize', $this->_constants->JS_ROOT_URL() . 'lib/selectize/selectize.min.js' , array( 'jquery' , 'jquery-ui-core' , 'jquery-ui-sortable' ) , Plugin_Constants::VERSION );
|
476 |
+
|
477 |
+
include( $this->_constants->VIEWS_ROOT_PATH() . 'linkpicker/quick-add-affiliate-link.php' );
|
478 |
+
|
479 |
+
wp_die();
|
480 |
+
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Process quick add affiliate link. Create Affiliate link post.
|
485 |
+
*
|
486 |
+
* @since 3.0.0
|
487 |
+
* @access public
|
488 |
+
*/
|
489 |
+
public function process_quick_add_affiliate_link() {
|
490 |
+
|
491 |
+
$thirstylink = new Affiliate_Link();
|
492 |
+
|
493 |
+
// set Properties
|
494 |
+
$thirstylink->set_prop( 'name' , sanitize_text_field( $_POST[ 'ta_link_name' ] ) );
|
495 |
+
$thirstylink->set_prop( 'destination_url' , esc_url_raw( $_POST[ 'ta_destination_url' ] ) );
|
496 |
+
$thirstylink->set_prop( 'no_follow' , sanitize_text_field( $_POST[ 'ta_no_follow' ] ) );
|
497 |
+
$thirstylink->set_prop( 'new_window' , sanitize_text_field( $_POST[ 'ta_new_window' ] ) );
|
498 |
+
$thirstylink->set_prop( 'redirect_type' , sanitize_text_field( $_POST[ 'ta_redirect_type' ] ) );
|
499 |
+
|
500 |
+
add_action( 'ta_save_quick_add_affiliate_link' , $thirstylink );
|
501 |
+
|
502 |
+
// save affiliate link
|
503 |
+
$thirstylink->save();
|
504 |
+
|
505 |
+
// save categories
|
506 |
+
$this->quick_add_save_categories( $thirstylink );
|
507 |
+
$this->_helper_functions->save_default_affiliate_link_category( $thirstylink->get_id() );
|
508 |
+
|
509 |
+
return $thirstylink;
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Quick add: Save categories for affiliate link on.
|
514 |
+
*
|
515 |
+
* @since 3.2.0
|
516 |
+
* @access private
|
517 |
+
*
|
518 |
+
* @param Affiliate_Link $thirstylink Affiliate link object.
|
519 |
+
*/
|
520 |
+
private function quick_add_save_categories( $thirstylink ) {
|
521 |
+
|
522 |
+
$categories = array();
|
523 |
+
if ( isset( $_POST[ 'ta_link_categories' ] ) )
|
524 |
+
$categories = array_map( 'intval' , $_POST[ 'ta_link_categories' ] );
|
525 |
+
|
526 |
+
if ( ! empty( $categories ) )
|
527 |
+
wp_set_post_terms( $thirstylink->get_id() , $categories , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
528 |
+
}
|
529 |
+
|
530 |
+
/**
|
531 |
+
* AJAX function to process quick add affiliate link.
|
532 |
+
*
|
533 |
+
* @since 3.0.0
|
534 |
+
* @access public
|
535 |
+
*/
|
536 |
+
public function ajax_process_quick_add_affiliate_link() {
|
537 |
+
|
538 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
539 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
540 |
+
elseif ( ! isset( $_REQUEST[ 'ta_link_name' ] ) || ! isset( $_REQUEST[ 'ta_destination_url' ] ) || ! isset( $_REQUEST[ 'ta_redirect_type' ] ) )
|
541 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
542 |
+
else {
|
543 |
+
|
544 |
+
$thirstylink = $this->process_quick_add_affiliate_link();
|
545 |
+
$post_id = isset( $_POST[ 'post_id' ] ) ? intval( sanitize_text_field( $_POST[ 'post_id' ] ) ) : 0;
|
546 |
+
$rel = $thirstylink->is( 'no_follow' ) ? 'nofollow' : '';
|
547 |
+
$target = $thirstylink->is( 'new_window' ) ? '_blank' : '';
|
548 |
+
$class = ( get_option( 'ta_disable_thirsty_link_class' ) !== "yes" ) ? 'thirstylink' : '';
|
549 |
+
$title = ( get_option( 'ta_disable_title_attribute' ) !== "yes" ) ? $thirstylink->get_prop( 'name' ) : '';
|
550 |
+
|
551 |
+
if ( $thirstylink->get_prop( 'rel_tags' ) )
|
552 |
+
$rel = trim( $rel . ' ' . $thirstylink->get_prop( 'rel_tags' ) );
|
553 |
+
|
554 |
+
if ( $thirstylink->get_prop( 'css_classes' ) )
|
555 |
+
$class = trim( $class . ' ' . $thirstylink->get_prop( 'css_classes' ) );
|
556 |
+
|
557 |
+
$response = array(
|
558 |
+
'status' => 'success',
|
559 |
+
'link_id' => $thirstylink->get_id(),
|
560 |
+
'content' => $thirstylink->get_prop( 'name' ),
|
561 |
+
'href' => $thirstylink->get_prop( 'permalink' ),
|
562 |
+
'class' => $class,
|
563 |
+
'title' => str_replace( '"' , '' , $title ),
|
564 |
+
'rel' => $rel,
|
565 |
+
'target' => $target,
|
566 |
+
'link_insertion_type' => $this->_helper_functions->get_option( 'ta_link_insertion_type' , 'link' ),
|
567 |
+
'other_atts' => apply_filters( 'ta_link_insert_extend_data_attributes' , array() , $thirstylink , $post_id )
|
568 |
+
);
|
569 |
+
|
570 |
+
}
|
571 |
+
|
572 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
573 |
+
echo wp_json_encode( $response );
|
574 |
+
wp_die();
|
575 |
+
}
|
576 |
+
|
577 |
+
|
578 |
+
|
579 |
+
/*
|
580 |
+
|--------------------------------------------------------------------------
|
581 |
+
| Shortcode editor modal interface
|
582 |
+
|--------------------------------------------------------------------------
|
583 |
+
*/
|
584 |
+
|
585 |
+
/**
|
586 |
+
* AJAX display shortcode editor form.
|
587 |
+
*
|
588 |
+
* @since 3.4.0
|
589 |
+
* @access public
|
590 |
+
*/
|
591 |
+
public function ajax_display_shortcode_editor_form() {
|
592 |
+
|
593 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX || ! current_user_can( apply_filters( 'ta_edit_affiliate_link_shortcode' , 'publish_posts' ) ) )
|
594 |
+
wp_die( "You're not allowed to do this." );
|
595 |
+
|
596 |
+
$post_id = isset( $_REQUEST[ 'post_id' ] ) ? intval( $_REQUEST[ 'post_id' ] ) : 0;
|
597 |
+
|
598 |
+
wp_enqueue_style( 'edit-shortcode' , $this->_constants->JS_ROOT_URL() . 'app/edit_shortcode/dist/edit-shortcode.css' , array( 'dashicons' ) , $this->_constants->VERSION() , 'all' );
|
599 |
+
wp_enqueue_style( 'selectize' , $this->_constants->JS_ROOT_URL() . 'lib/selectize/selectize.default.css' , array() , Plugin_Constants::VERSION , 'all' );
|
600 |
+
|
601 |
+
wp_enqueue_script('editor');
|
602 |
+
wp_dequeue_script('jquery-ui-core');
|
603 |
+
wp_dequeue_script('jquery-ui-sortable');
|
604 |
+
wp_dequeue_script('admin-scripts');
|
605 |
+
wp_enqueue_script( 'edit-shortcode' , $this->_constants->JS_ROOT_URL() . 'app/edit_shortcode/dist/edit-shortcode.js' , array() , $this->_constants->VERSION() );
|
606 |
+
wp_enqueue_script( 'selectize', $this->_constants->JS_ROOT_URL() . 'lib/selectize/selectize.min.js' , array( 'jquery' , 'jquery-ui-core' , 'jquery-ui-sortable' ) , Plugin_Constants::VERSION );
|
607 |
+
|
608 |
+
include( $this->_constants->VIEWS_ROOT_PATH() . 'linkpicker/edit-shortcode.php' );
|
609 |
+
|
610 |
+
wp_die();
|
611 |
+
}
|
612 |
+
|
613 |
+
/**
|
614 |
+
* Transform Gutenberg affiliate link <ta> tags to <a> tags.
|
615 |
+
*
|
616 |
+
* @since 3.6
|
617 |
+
* @access public
|
618 |
+
*
|
619 |
+
* @global WP_Post $post WP_Post object of currently loaded post.
|
620 |
+
*
|
621 |
+
* @param string $content WP_Post content.
|
622 |
+
* @return string Filtered WP_Post content.
|
623 |
+
*/
|
624 |
+
public function gutenberg_transform_ta_tags_to_link( $content ) {
|
625 |
+
|
626 |
+
preg_match_all( '/<ta [^>]*>(.*?)<\/ta>/i' , $content , $matches , PREG_OFFSET_CAPTURE );
|
627 |
+
|
628 |
+
if ( isset( $matches[0] ) && ! empty( $matches[0] ) ) {
|
629 |
+
|
630 |
+
$diff = 0;
|
631 |
+
|
632 |
+
foreach ( $matches[0] as $match ) {
|
633 |
+
|
634 |
+
$link_id = $this->_helper_functions->get_string_between( $match[0] , 'linkid="' , '"' );
|
635 |
+
$href = $this->_helper_functions->get_string_between( $match[0] , 'href="' , '"' );
|
636 |
+
$text = $this->_helper_functions->get_string_between( $match[0] , '>' , '</ta' );
|
637 |
+
|
638 |
+
if ( $link_id )
|
639 |
+
$replacement = do_shortcode( '[thirstylink ids="' . $link_id . '"]' . $text . '[/thirstylink]' );
|
640 |
+
else
|
641 |
+
$replacement = '<a href="' . $href . '">' . $text . '</a>';
|
642 |
+
|
643 |
+
$match[1] = $match[1] + $diff; // Fix the offset of the match after the last replacement
|
644 |
+
$content = substr_replace( $content , $replacement , $match[1] , strlen( $match[0] ) );
|
645 |
+
|
646 |
+
// Add the string length difference to the next match's offset
|
647 |
+
// because all the string positions have moved since the first
|
648 |
+
// replacement.
|
649 |
+
$diff = $diff + strlen( $replacement ) - strlen( $match[0] );
|
650 |
+
}
|
651 |
+
}
|
652 |
+
|
653 |
+
return $content;
|
654 |
+
}
|
655 |
+
|
656 |
+
|
657 |
+
|
658 |
+
|
659 |
+
/*
|
660 |
+
|--------------------------------------------------------------------------
|
661 |
+
| Fulfill implemented interface contracts
|
662 |
+
|--------------------------------------------------------------------------
|
663 |
+
*/
|
664 |
+
|
665 |
+
/**
|
666 |
+
* Method that houses codes to be executed on init hook.
|
667 |
+
*
|
668 |
+
* @since 3.0.0
|
669 |
+
* @access public
|
670 |
+
* @inherit ThirstyAffiliates\Interfaces\Initiable_Interface
|
671 |
+
*/
|
672 |
+
public function initialize() {
|
673 |
+
|
674 |
+
// // TinyMCE buttons
|
675 |
+
$this->init_thirsty_editor_buttons();
|
676 |
+
$this->init_thirsty_editor_buttons_for_page_builders();
|
677 |
+
|
678 |
+
// Advanced Link Picker hooks
|
679 |
+
add_action( 'wp_ajax_search_affiliate_links_query' , array( $this , 'ajax_search_affiliate_links_query' ) );
|
680 |
+
add_action( 'wp_ajax_ta_advanced_add_affiliate_link' , array( $this , 'ajax_display_advanced_add_affiliate_link' ) );
|
681 |
+
add_action( 'wp_ajax_ta_get_image_markup_by_id' , array( $this , 'ajax_get_image_markup_by_id' ) );
|
682 |
+
|
683 |
+
// Quick Add Affiliate Link hooks
|
684 |
+
add_action( 'wp_ajax_ta_quick_add_affiliate_link_thickbox' , array( $this , 'ajax_display_quick_add_affiliate_link_thickbox' ) );
|
685 |
+
add_action( 'wp_ajax_ta_process_quick_add_affiliate_link' , array( $this , 'ajax_process_quick_add_affiliate_link' ) );
|
686 |
+
|
687 |
+
// edit shortcode
|
688 |
+
add_action( 'wp_ajax_ta_edit_affiliate_link_shortcode' , array( $this , 'ajax_display_shortcode_editor_form' ) );
|
689 |
+
|
690 |
+
}
|
691 |
+
|
692 |
+
/**
|
693 |
+
* Execute link picker.
|
694 |
+
*
|
695 |
+
* @since 3.0.0
|
696 |
+
* @access public
|
697 |
+
*/
|
698 |
+
public function run() {
|
699 |
+
|
700 |
+
// TinyMCE buttons
|
701 |
+
add_action( 'wp' , array( $this , 'init_thirsty_editor_buttons_for_page_builders' ) );
|
702 |
+
|
703 |
+
// WP editor style
|
704 |
+
add_action( 'admin_init' , array( $this , 'register_wp_editor_style' ) );
|
705 |
+
add_filter( 'mce_css' , array( $this , 'register_wp_editor_style_mce_css' ) );
|
706 |
+
|
707 |
+
add_filter( 'the_content' , array( $this , 'gutenberg_transform_ta_tags_to_link' ) );
|
708 |
+
}
|
709 |
+
}
|
Models/REST_API.php
CHANGED
@@ -1,354 +1,354 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
9 |
-
|
10 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
15 |
-
*
|
16 |
-
* @since 3.1.0
|
17 |
-
*/
|
18 |
-
class REST_API implements Model_Interface {
|
19 |
-
|
20 |
-
/*
|
21 |
-
|--------------------------------------------------------------------------
|
22 |
-
| Class Properties
|
23 |
-
|--------------------------------------------------------------------------
|
24 |
-
*/
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Property that holds the single main instance of Shortcodes.
|
28 |
-
*
|
29 |
-
* @since 3.1.0
|
30 |
-
* @access private
|
31 |
-
* @var Redirection
|
32 |
-
*/
|
33 |
-
private static $_instance;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Model that houses the main plugin object.
|
37 |
-
*
|
38 |
-
* @since 3.1.0
|
39 |
-
* @access private
|
40 |
-
* @var Redirection
|
41 |
-
*/
|
42 |
-
private $_main_plugin;
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Model that houses all the plugin constants.
|
46 |
-
*
|
47 |
-
* @since 3.1.0
|
48 |
-
* @access private
|
49 |
-
* @var Plugin_Constants
|
50 |
-
*/
|
51 |
-
private $_constants;
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Property that houses all the helper functions of the plugin.
|
55 |
-
*
|
56 |
-
* @since 3.1.0
|
57 |
-
* @access private
|
58 |
-
* @var Helper_Functions
|
59 |
-
*/
|
60 |
-
private $_helper_functions;
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Rest field prefix.
|
64 |
-
*
|
65 |
-
* @since 3.1.0
|
66 |
-
* @access private
|
67 |
-
* @var string
|
68 |
-
*/
|
69 |
-
private $_rest_prefix = '_ta_';
|
70 |
-
|
71 |
-
/**
|
72 |
-
* TA custom fields default data.
|
73 |
-
*
|
74 |
-
* @since 3.1.0
|
75 |
-
* @access private
|
76 |
-
* @var array
|
77 |
-
*/
|
78 |
-
private $_ta_fields = array(
|
79 |
-
'destination_url' => '',
|
80 |
-
'rel_tags' => '',
|
81 |
-
'redirect_type' => 'global',
|
82 |
-
'no_follow' => 'global',
|
83 |
-
'new_window' => 'global',
|
84 |
-
'uncloak_link' => 'global',
|
85 |
-
'pass_query_str' => 'global',
|
86 |
-
'image_ids' => array(),
|
87 |
-
'categories' => array(),
|
88 |
-
'category_slug' => '',
|
89 |
-
'category_slug_id' => 0,
|
90 |
-
);
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
/*
|
96 |
-
|--------------------------------------------------------------------------
|
97 |
-
| Class Methods
|
98 |
-
|--------------------------------------------------------------------------
|
99 |
-
*/
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Class constructor.
|
103 |
-
*
|
104 |
-
* @since 3.1.0
|
105 |
-
* @access public
|
106 |
-
*
|
107 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
108 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
109 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
110 |
-
*/
|
111 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
112 |
-
|
113 |
-
$this->_constants = $constants;
|
114 |
-
$this->_helper_functions = $helper_functions;
|
115 |
-
|
116 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
121 |
-
*
|
122 |
-
* @since 3.1.0
|
123 |
-
* @access public
|
124 |
-
*
|
125 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
126 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
127 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
128 |
-
* @return Redirection
|
129 |
-
*/
|
130 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
131 |
-
|
132 |
-
if ( !self::$_instance instanceof self )
|
133 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
134 |
-
|
135 |
-
return self::$_instance;
|
136 |
-
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* Register ThirstyAffiliates custom fields so they can be accessible on REST.
|
141 |
-
*
|
142 |
-
* @since 3.1.0
|
143 |
-
* @access public
|
144 |
-
*/
|
145 |
-
public function register_ta_custom_fields_on_rest() {
|
146 |
-
|
147 |
-
$fields = apply_filters( 'ta_register_rest_api_fields' , $this->_ta_fields );
|
148 |
-
|
149 |
-
foreach ( $fields as $meta_key => $default_value )
|
150 |
-
$this->register_rest_field( $meta_key , $default_value );
|
151 |
-
|
152 |
-
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Register single field in the REST API.
|
157 |
-
*
|
158 |
-
* @since 3.1.0
|
159 |
-
* @access private
|
160 |
-
*
|
161 |
-
* @param string $meta_key Custom field meta key.
|
162 |
-
* @param mixed $default_value Custom field default value.
|
163 |
-
*/
|
164 |
-
private function register_rest_field( $meta_key , $default_value ) {
|
165 |
-
|
166 |
-
$field_type = gettype( $default_value );
|
167 |
-
|
168 |
-
register_rest_field( Plugin_Constants::AFFILIATE_LINKS_CPT , $this->_rest_prefix . $meta_key , array(
|
169 |
-
|
170 |
-
// REST field get callback.
|
171 |
-
'get_callback' => function( $post_data ) use ( $meta_key , $field_type , $default_value ) {
|
172 |
-
|
173 |
-
if ( $meta_key == 'categories' )
|
174 |
-
return wp_get_post_terms( $post_data[ 'id' ] , Plugin_Constants::AFFILIATE_LINKS_TAX , array( 'fields' => 'ids' ) );
|
175 |
-
else {
|
176 |
-
|
177 |
-
$meta_value = get_post_meta( $post_data[ 'id' ] , Plugin_Constants::META_DATA_PREFIX . $meta_key , true );
|
178 |
-
$meta_value = $this->esc_meta_value( $meta_value , $meta_key , $field_type );
|
179 |
-
return ( $meta_value && $field_type === gettype( $meta_value ) ) ? $meta_value : $default_value;
|
180 |
-
}
|
181 |
-
},
|
182 |
-
|
183 |
-
// REST field update callback.
|
184 |
-
'update_callback' => function( $new_value , $post_obj ) use ( $meta_key , $field_type , $default_value ) {
|
185 |
-
|
186 |
-
// Filter to determine if field allows to be updated or not.
|
187 |
-
if ( apply_filters( 'ta_restapi_field_update_cb' , false , $meta_key , $new_value , $field_type , $default_value ) )
|
188 |
-
return;
|
189 |
-
|
190 |
-
if ( $meta_key == 'categories' ) {
|
191 |
-
|
192 |
-
if ( ! is_array( $new_value ) || empty( $new_value ) )
|
193 |
-
return;
|
194 |
-
|
195 |
-
$categories = array_unique( array_map( 'intval' , $new_value ) );
|
196 |
-
wp_set_post_terms( $post_obj->ID , $categories , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
197 |
-
|
198 |
-
} else
|
199 |
-
update_post_meta( $post_obj->ID , Plugin_Constants::META_DATA_PREFIX . $meta_key , $this->sanitize_field( $new_value , $meta_key , $field_type , $default_value ) );
|
200 |
-
},
|
201 |
-
|
202 |
-
// REST field schema.
|
203 |
-
'schema' => array(
|
204 |
-
'type' => $field_type,
|
205 |
-
'context' => array( 'view' , 'edit' )
|
206 |
-
)
|
207 |
-
|
208 |
-
) );
|
209 |
-
}
|
210 |
-
|
211 |
-
/**
|
212 |
-
* Escape meta value before displaying.
|
213 |
-
*
|
214 |
-
* @since 3.1.0
|
215 |
-
* @access private
|
216 |
-
*
|
217 |
-
* @param mixed $meta_value Custom field value.
|
218 |
-
* @param string $meta_key Custom field meta key.
|
219 |
-
* @param string $field_type Custom field type.
|
220 |
-
* @return mixed Escaped custom field value.
|
221 |
-
*/
|
222 |
-
private function esc_meta_value( $meta_value , $meta_key , $field_type ) {
|
223 |
-
|
224 |
-
// allow TA pro and other third party plugins to escape value while not running the default function.
|
225 |
-
$escaped_value = apply_filters( 'ta_rest_api_esc_meta_value' , false , $meta_value , $meta_key , $field_type );
|
226 |
-
if ( $escaped_value !== false ) return $escaped_value;
|
227 |
-
|
228 |
-
switch ( $field_type ) {
|
229 |
-
|
230 |
-
case 'array' :
|
231 |
-
$sanitize_func = ( $meta_key == 'image_ids' ) ? 'intval' : 'esc_attr';
|
232 |
-
$escaped_value = is_array( $meta_value ) ? array_map( $sanitize_func , $meta_value ) : $meta_value;
|
233 |
-
break;
|
234 |
-
|
235 |
-
case 'integer' :
|
236 |
-
$escaped_value = intval( $meta_value );
|
237 |
-
break;
|
238 |
-
|
239 |
-
case 'string' :
|
240 |
-
default :
|
241 |
-
$escaped_value = ( $meta_key == 'destination_url' ) ? esc_url_raw( $meta_value ) : esc_attr( $meta_value );
|
242 |
-
break;
|
243 |
-
}
|
244 |
-
|
245 |
-
return $escaped_value;
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Sanitize updated meta value before saving.
|
250 |
-
*
|
251 |
-
* @since 3.1.0
|
252 |
-
* @access private
|
253 |
-
*
|
254 |
-
* @param mixed $field_value Custom field value.
|
255 |
-
* @param string $meta_key Custom field meta key.
|
256 |
-
* @param string $field_type Custom field type.
|
257 |
-
* @param mixed $default_value Custom field default value.
|
258 |
-
* @return mixed Sanitized custom field value.
|
259 |
-
*/
|
260 |
-
private function sanitize_field( $field_value , $meta_key , $field_type , $default_value ) {
|
261 |
-
|
262 |
-
// allow TA pro and other third party plugins to sanitize value while not running the default function.
|
263 |
-
$sanitized_value = apply_filters( 'ta_rest_api_sanitize_field' , false , $field_value , $meta_key , $field_type , $default_value );
|
264 |
-
if ( $sanitized_value !== false ) return $sanitized_value;
|
265 |
-
|
266 |
-
switch ( $field_type ) {
|
267 |
-
|
268 |
-
case 'array' :
|
269 |
-
$sanitize_func = ( $meta_key == 'image_ids' ) ? 'intval' : 'sanitize_text_field';
|
270 |
-
$sanitized_value = ( is_array( $field_value ) && ! empty( $field_value ) ) ? array_unique( array_map( $sanitize_func , $field_value ) ) : $default_value;
|
271 |
-
|
272 |
-
// validate if provided ids are already saved attachments for image_ids field.
|
273 |
-
if ( $meta_key == 'image_ids' ) {
|
274 |
-
|
275 |
-
$valid_images = array();
|
276 |
-
foreach ( $sanitized_value as $image_id )
|
277 |
-
if ( get_post_type( $image_id ) === 'attachment' ) $valid_images[] = $image_id;
|
278 |
-
|
279 |
-
$sanitized_value = $valid_images;
|
280 |
-
}
|
281 |
-
|
282 |
-
break;
|
283 |
-
|
284 |
-
case 'integer' :
|
285 |
-
$sanitized_value = ( $field_value ) ? intval( $field_value ) : $default_value;
|
286 |
-
break;
|
287 |
-
|
288 |
-
case 'string' :
|
289 |
-
default :
|
290 |
-
$sanitized_value = ( $field_value ) ? $field_value : $default_value;
|
291 |
-
$sanitized_value = ( $meta_key == 'destination_url' ) ? esc_url_raw( $field_value ) : sanitize_text_field( $field_value );
|
292 |
-
break;
|
293 |
-
}
|
294 |
-
|
295 |
-
return $sanitized_value;
|
296 |
-
}
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Sanitize special TA fields.
|
300 |
-
*
|
301 |
-
* @since 3.1.0
|
302 |
-
* @since 3.4.0 Allow global value for redirect type.
|
303 |
-
* @access public
|
304 |
-
*
|
305 |
-
* @param mixed $sanitized_value Value after sanitized. Defaults to boolean false.
|
306 |
-
* @param mixed $field_value Raw field value.
|
307 |
-
* @param string $meta_key TA field meta key.
|
308 |
-
* @param string $field_type TA field variable type.
|
309 |
-
* @param mixed $default_value TA field default value.
|
310 |
-
* @return mixed Filtered sanitized field value.
|
311 |
-
*/
|
312 |
-
public function sanitize_special_fields( $sanitized_value , $field_value , $meta_key , $field_type , $default_value ) {
|
313 |
-
|
314 |
-
$toggle_fields = apply_filters( 'ta_rest_api_sanitize_toggle_fields' , array(
|
315 |
-
'no_follow',
|
316 |
-
'new_window',
|
317 |
-
'uncloak_link',
|
318 |
-
'pass_query_str',
|
319 |
-
) );
|
320 |
-
|
321 |
-
if ( in_array( $meta_key , $toggle_fields ) )
|
322 |
-
$allowed_values = array( 'global' , 'yes' , 'no' );
|
323 |
-
elseif( $meta_key == 'redirect_type' )
|
324 |
-
$allowed_values = array( 'global' , '301' , '302' , '307' );
|
325 |
-
|
326 |
-
if ( isset( $allowed_values ) && is_array( $allowed_values ) )
|
327 |
-
$sanitized_value = in_array( $field_value , $allowed_values ) ? sanitize_text_field( $field_value ) : $default_value;
|
328 |
-
|
329 |
-
return $sanitized_value;
|
330 |
-
}
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
/*
|
336 |
-
|--------------------------------------------------------------------------
|
337 |
-
| Implemented Interface Methods
|
338 |
-
|--------------------------------------------------------------------------
|
339 |
-
*/
|
340 |
-
|
341 |
-
/**
|
342 |
-
* Execute model.
|
343 |
-
*
|
344 |
-
* @implements ThirstyAffiliates\Interfaces\Model_Interface
|
345 |
-
*
|
346 |
-
* @since 3.1.0
|
347 |
-
* @access public
|
348 |
-
*/
|
349 |
-
public function run() {
|
350 |
-
|
351 |
-
add_action( 'rest_api_init' , array( $this , 'register_ta_custom_fields_on_rest' ) , 10 );
|
352 |
-
add_filter( 'ta_rest_api_sanitize_field' , array( $this , 'sanitize_special_fields' ) , 10 , 5 );
|
353 |
-
}
|
354 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
9 |
+
|
10 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
15 |
+
*
|
16 |
+
* @since 3.1.0
|
17 |
+
*/
|
18 |
+
class REST_API implements Model_Interface {
|
19 |
+
|
20 |
+
/*
|
21 |
+
|--------------------------------------------------------------------------
|
22 |
+
| Class Properties
|
23 |
+
|--------------------------------------------------------------------------
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Property that holds the single main instance of Shortcodes.
|
28 |
+
*
|
29 |
+
* @since 3.1.0
|
30 |
+
* @access private
|
31 |
+
* @var Redirection
|
32 |
+
*/
|
33 |
+
private static $_instance;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Model that houses the main plugin object.
|
37 |
+
*
|
38 |
+
* @since 3.1.0
|
39 |
+
* @access private
|
40 |
+
* @var Redirection
|
41 |
+
*/
|
42 |
+
private $_main_plugin;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Model that houses all the plugin constants.
|
46 |
+
*
|
47 |
+
* @since 3.1.0
|
48 |
+
* @access private
|
49 |
+
* @var Plugin_Constants
|
50 |
+
*/
|
51 |
+
private $_constants;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Property that houses all the helper functions of the plugin.
|
55 |
+
*
|
56 |
+
* @since 3.1.0
|
57 |
+
* @access private
|
58 |
+
* @var Helper_Functions
|
59 |
+
*/
|
60 |
+
private $_helper_functions;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Rest field prefix.
|
64 |
+
*
|
65 |
+
* @since 3.1.0
|
66 |
+
* @access private
|
67 |
+
* @var string
|
68 |
+
*/
|
69 |
+
private $_rest_prefix = '_ta_';
|
70 |
+
|
71 |
+
/**
|
72 |
+
* TA custom fields default data.
|
73 |
+
*
|
74 |
+
* @since 3.1.0
|
75 |
+
* @access private
|
76 |
+
* @var array
|
77 |
+
*/
|
78 |
+
private $_ta_fields = array(
|
79 |
+
'destination_url' => '',
|
80 |
+
'rel_tags' => '',
|
81 |
+
'redirect_type' => 'global',
|
82 |
+
'no_follow' => 'global',
|
83 |
+
'new_window' => 'global',
|
84 |
+
'uncloak_link' => 'global',
|
85 |
+
'pass_query_str' => 'global',
|
86 |
+
'image_ids' => array(),
|
87 |
+
'categories' => array(),
|
88 |
+
'category_slug' => '',
|
89 |
+
'category_slug_id' => 0,
|
90 |
+
);
|
91 |
+
|
92 |
+
|
93 |
+
|
94 |
+
|
95 |
+
/*
|
96 |
+
|--------------------------------------------------------------------------
|
97 |
+
| Class Methods
|
98 |
+
|--------------------------------------------------------------------------
|
99 |
+
*/
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Class constructor.
|
103 |
+
*
|
104 |
+
* @since 3.1.0
|
105 |
+
* @access public
|
106 |
+
*
|
107 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
108 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
109 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
110 |
+
*/
|
111 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
112 |
+
|
113 |
+
$this->_constants = $constants;
|
114 |
+
$this->_helper_functions = $helper_functions;
|
115 |
+
|
116 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
121 |
+
*
|
122 |
+
* @since 3.1.0
|
123 |
+
* @access public
|
124 |
+
*
|
125 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
126 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
127 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
128 |
+
* @return Redirection
|
129 |
+
*/
|
130 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
131 |
+
|
132 |
+
if ( !self::$_instance instanceof self )
|
133 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
134 |
+
|
135 |
+
return self::$_instance;
|
136 |
+
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Register ThirstyAffiliates custom fields so they can be accessible on REST.
|
141 |
+
*
|
142 |
+
* @since 3.1.0
|
143 |
+
* @access public
|
144 |
+
*/
|
145 |
+
public function register_ta_custom_fields_on_rest() {
|
146 |
+
|
147 |
+
$fields = apply_filters( 'ta_register_rest_api_fields' , $this->_ta_fields );
|
148 |
+
|
149 |
+
foreach ( $fields as $meta_key => $default_value )
|
150 |
+
$this->register_rest_field( $meta_key , $default_value );
|
151 |
+
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Register single field in the REST API.
|
157 |
+
*
|
158 |
+
* @since 3.1.0
|
159 |
+
* @access private
|
160 |
+
*
|
161 |
+
* @param string $meta_key Custom field meta key.
|
162 |
+
* @param mixed $default_value Custom field default value.
|
163 |
+
*/
|
164 |
+
private function register_rest_field( $meta_key , $default_value ) {
|
165 |
+
|
166 |
+
$field_type = gettype( $default_value );
|
167 |
+
|
168 |
+
register_rest_field( Plugin_Constants::AFFILIATE_LINKS_CPT , $this->_rest_prefix . $meta_key , array(
|
169 |
+
|
170 |
+
// REST field get callback.
|
171 |
+
'get_callback' => function( $post_data ) use ( $meta_key , $field_type , $default_value ) {
|
172 |
+
|
173 |
+
if ( $meta_key == 'categories' )
|
174 |
+
return wp_get_post_terms( $post_data[ 'id' ] , Plugin_Constants::AFFILIATE_LINKS_TAX , array( 'fields' => 'ids' ) );
|
175 |
+
else {
|
176 |
+
|
177 |
+
$meta_value = get_post_meta( $post_data[ 'id' ] , Plugin_Constants::META_DATA_PREFIX . $meta_key , true );
|
178 |
+
$meta_value = $this->esc_meta_value( $meta_value , $meta_key , $field_type );
|
179 |
+
return ( $meta_value && $field_type === gettype( $meta_value ) ) ? $meta_value : $default_value;
|
180 |
+
}
|
181 |
+
},
|
182 |
+
|
183 |
+
// REST field update callback.
|
184 |
+
'update_callback' => function( $new_value , $post_obj ) use ( $meta_key , $field_type , $default_value ) {
|
185 |
+
|
186 |
+
// Filter to determine if field allows to be updated or not.
|
187 |
+
if ( apply_filters( 'ta_restapi_field_update_cb' , false , $meta_key , $new_value , $field_type , $default_value ) )
|
188 |
+
return;
|
189 |
+
|
190 |
+
if ( $meta_key == 'categories' ) {
|
191 |
+
|
192 |
+
if ( ! is_array( $new_value ) || empty( $new_value ) )
|
193 |
+
return;
|
194 |
+
|
195 |
+
$categories = array_unique( array_map( 'intval' , $new_value ) );
|
196 |
+
wp_set_post_terms( $post_obj->ID , $categories , Plugin_Constants::AFFILIATE_LINKS_TAX );
|
197 |
+
|
198 |
+
} else
|
199 |
+
update_post_meta( $post_obj->ID , Plugin_Constants::META_DATA_PREFIX . $meta_key , $this->sanitize_field( $new_value , $meta_key , $field_type , $default_value ) );
|
200 |
+
},
|
201 |
+
|
202 |
+
// REST field schema.
|
203 |
+
'schema' => array(
|
204 |
+
'type' => $field_type,
|
205 |
+
'context' => array( 'view' , 'edit' )
|
206 |
+
)
|
207 |
+
|
208 |
+
) );
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Escape meta value before displaying.
|
213 |
+
*
|
214 |
+
* @since 3.1.0
|
215 |
+
* @access private
|
216 |
+
*
|
217 |
+
* @param mixed $meta_value Custom field value.
|
218 |
+
* @param string $meta_key Custom field meta key.
|
219 |
+
* @param string $field_type Custom field type.
|
220 |
+
* @return mixed Escaped custom field value.
|
221 |
+
*/
|
222 |
+
private function esc_meta_value( $meta_value , $meta_key , $field_type ) {
|
223 |
+
|
224 |
+
// allow TA pro and other third party plugins to escape value while not running the default function.
|
225 |
+
$escaped_value = apply_filters( 'ta_rest_api_esc_meta_value' , false , $meta_value , $meta_key , $field_type );
|
226 |
+
if ( $escaped_value !== false ) return $escaped_value;
|
227 |
+
|
228 |
+
switch ( $field_type ) {
|
229 |
+
|
230 |
+
case 'array' :
|
231 |
+
$sanitize_func = ( $meta_key == 'image_ids' ) ? 'intval' : 'esc_attr';
|
232 |
+
$escaped_value = is_array( $meta_value ) ? array_map( $sanitize_func , $meta_value ) : $meta_value;
|
233 |
+
break;
|
234 |
+
|
235 |
+
case 'integer' :
|
236 |
+
$escaped_value = intval( $meta_value );
|
237 |
+
break;
|
238 |
+
|
239 |
+
case 'string' :
|
240 |
+
default :
|
241 |
+
$escaped_value = ( $meta_key == 'destination_url' ) ? esc_url_raw( $meta_value ) : esc_attr( $meta_value );
|
242 |
+
break;
|
243 |
+
}
|
244 |
+
|
245 |
+
return $escaped_value;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Sanitize updated meta value before saving.
|
250 |
+
*
|
251 |
+
* @since 3.1.0
|
252 |
+
* @access private
|
253 |
+
*
|
254 |
+
* @param mixed $field_value Custom field value.
|
255 |
+
* @param string $meta_key Custom field meta key.
|
256 |
+
* @param string $field_type Custom field type.
|
257 |
+
* @param mixed $default_value Custom field default value.
|
258 |
+
* @return mixed Sanitized custom field value.
|
259 |
+
*/
|
260 |
+
private function sanitize_field( $field_value , $meta_key , $field_type , $default_value ) {
|
261 |
+
|
262 |
+
// allow TA pro and other third party plugins to sanitize value while not running the default function.
|
263 |
+
$sanitized_value = apply_filters( 'ta_rest_api_sanitize_field' , false , $field_value , $meta_key , $field_type , $default_value );
|
264 |
+
if ( $sanitized_value !== false ) return $sanitized_value;
|
265 |
+
|
266 |
+
switch ( $field_type ) {
|
267 |
+
|
268 |
+
case 'array' :
|
269 |
+
$sanitize_func = ( $meta_key == 'image_ids' ) ? 'intval' : 'sanitize_text_field';
|
270 |
+
$sanitized_value = ( is_array( $field_value ) && ! empty( $field_value ) ) ? array_unique( array_map( $sanitize_func , $field_value ) ) : $default_value;
|
271 |
+
|
272 |
+
// validate if provided ids are already saved attachments for image_ids field.
|
273 |
+
if ( $meta_key == 'image_ids' ) {
|
274 |
+
|
275 |
+
$valid_images = array();
|
276 |
+
foreach ( $sanitized_value as $image_id )
|
277 |
+
if ( get_post_type( $image_id ) === 'attachment' ) $valid_images[] = $image_id;
|
278 |
+
|
279 |
+
$sanitized_value = $valid_images;
|
280 |
+
}
|
281 |
+
|
282 |
+
break;
|
283 |
+
|
284 |
+
case 'integer' :
|
285 |
+
$sanitized_value = ( $field_value ) ? intval( $field_value ) : $default_value;
|
286 |
+
break;
|
287 |
+
|
288 |
+
case 'string' :
|
289 |
+
default :
|
290 |
+
$sanitized_value = ( $field_value ) ? $field_value : $default_value;
|
291 |
+
$sanitized_value = ( $meta_key == 'destination_url' ) ? esc_url_raw( $field_value ) : sanitize_text_field( $field_value );
|
292 |
+
break;
|
293 |
+
}
|
294 |
+
|
295 |
+
return $sanitized_value;
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Sanitize special TA fields.
|
300 |
+
*
|
301 |
+
* @since 3.1.0
|
302 |
+
* @since 3.4.0 Allow global value for redirect type.
|
303 |
+
* @access public
|
304 |
+
*
|
305 |
+
* @param mixed $sanitized_value Value after sanitized. Defaults to boolean false.
|
306 |
+
* @param mixed $field_value Raw field value.
|
307 |
+
* @param string $meta_key TA field meta key.
|
308 |
+
* @param string $field_type TA field variable type.
|
309 |
+
* @param mixed $default_value TA field default value.
|
310 |
+
* @return mixed Filtered sanitized field value.
|
311 |
+
*/
|
312 |
+
public function sanitize_special_fields( $sanitized_value , $field_value , $meta_key , $field_type , $default_value ) {
|
313 |
+
|
314 |
+
$toggle_fields = apply_filters( 'ta_rest_api_sanitize_toggle_fields' , array(
|
315 |
+
'no_follow',
|
316 |
+
'new_window',
|
317 |
+
'uncloak_link',
|
318 |
+
'pass_query_str',
|
319 |
+
) );
|
320 |
+
|
321 |
+
if ( in_array( $meta_key , $toggle_fields ) )
|
322 |
+
$allowed_values = array( 'global' , 'yes' , 'no' );
|
323 |
+
elseif( $meta_key == 'redirect_type' )
|
324 |
+
$allowed_values = array( 'global' , '301' , '302' , '307' );
|
325 |
+
|
326 |
+
if ( isset( $allowed_values ) && is_array( $allowed_values ) )
|
327 |
+
$sanitized_value = in_array( $field_value , $allowed_values ) ? sanitize_text_field( $field_value ) : $default_value;
|
328 |
+
|
329 |
+
return $sanitized_value;
|
330 |
+
}
|
331 |
+
|
332 |
+
|
333 |
+
|
334 |
+
|
335 |
+
/*
|
336 |
+
|--------------------------------------------------------------------------
|
337 |
+
| Implemented Interface Methods
|
338 |
+
|--------------------------------------------------------------------------
|
339 |
+
*/
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Execute model.
|
343 |
+
*
|
344 |
+
* @implements ThirstyAffiliates\Interfaces\Model_Interface
|
345 |
+
*
|
346 |
+
* @since 3.1.0
|
347 |
+
* @access public
|
348 |
+
*/
|
349 |
+
public function run() {
|
350 |
+
|
351 |
+
add_action( 'rest_api_init' , array( $this , 'register_ta_custom_fields_on_rest' ) , 10 );
|
352 |
+
add_filter( 'ta_rest_api_sanitize_field' , array( $this , 'sanitize_special_fields' ) , 10 , 5 );
|
353 |
+
}
|
354 |
+
}
|
Models/Rewrites_Redirection.php
CHANGED
@@ -1,440 +1,440 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Deactivatable_Interface;
|
9 |
-
|
10 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
15 |
-
*
|
16 |
-
* @since 3.0.0
|
17 |
-
*/
|
18 |
-
class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface {
|
19 |
-
|
20 |
-
/*
|
21 |
-
|--------------------------------------------------------------------------
|
22 |
-
| Class Properties
|
23 |
-
|--------------------------------------------------------------------------
|
24 |
-
*/
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Property that holds the single main instance of Rewrites_Redirection.
|
28 |
-
*
|
29 |
-
* @since 3.0.0
|
30 |
-
* @access private
|
31 |
-
* @var Redirection
|
32 |
-
*/
|
33 |
-
private static $_instance;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Model that houses the main plugin object.
|
37 |
-
*
|
38 |
-
* @since 3.0.0
|
39 |
-
* @access private
|
40 |
-
* @var Redirection
|
41 |
-
*/
|
42 |
-
private $_main_plugin;
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Model that houses all the plugin constants.
|
46 |
-
*
|
47 |
-
* @since 3.0.0
|
48 |
-
* @access private
|
49 |
-
* @var Plugin_Constants
|
50 |
-
*/
|
51 |
-
private $_constants;
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Property that houses all the helper functions of the plugin.
|
55 |
-
*
|
56 |
-
* @since 3.0.0
|
57 |
-
* @access private
|
58 |
-
* @var Helper_Functions
|
59 |
-
*/
|
60 |
-
private $_helper_functions;
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Property that holds the currently loaded thirstylink post.
|
64 |
-
*
|
65 |
-
* @since 3.0.0
|
66 |
-
* @access private
|
67 |
-
*/
|
68 |
-
private $_thirstylink;
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
/*
|
74 |
-
|--------------------------------------------------------------------------
|
75 |
-
| Class Methods
|
76 |
-
|--------------------------------------------------------------------------
|
77 |
-
*/
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Class constructor.
|
81 |
-
*
|
82 |
-
* @since 3.0.0
|
83 |
-
* @access public
|
84 |
-
*
|
85 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
86 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
87 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
88 |
-
*/
|
89 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
90 |
-
|
91 |
-
$this->_constants = $constants;
|
92 |
-
$this->_helper_functions = $helper_functions;
|
93 |
-
|
94 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
95 |
-
$main_plugin->add_to_public_models( $this );
|
96 |
-
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
101 |
-
*
|
102 |
-
* @since 3.0.0
|
103 |
-
* @access public
|
104 |
-
*
|
105 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
106 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
107 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
108 |
-
* @return Redirection
|
109 |
-
*/
|
110 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
111 |
-
|
112 |
-
if ( !self::$_instance instanceof self )
|
113 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
114 |
-
|
115 |
-
return self::$_instance;
|
116 |
-
|
117 |
-
}
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
/*
|
123 |
-
|--------------------------------------------------------------------------
|
124 |
-
| Flush Rewrite Rules
|
125 |
-
|--------------------------------------------------------------------------
|
126 |
-
*/
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Get thirstylink Affiliate_Link object.
|
130 |
-
*
|
131 |
-
* @since 3.0.0
|
132 |
-
* @access private
|
133 |
-
*
|
134 |
-
* @param int $post_id Thirstylink post id.
|
135 |
-
* @return Affiliate_Link object.
|
136 |
-
*/
|
137 |
-
private function get_thirstylink_post( $post_id ) {
|
138 |
-
|
139 |
-
if ( is_object( $this->_thirstylink ) && $this->_thirstylink->get_id() == $post_id )
|
140 |
-
return $this->_thirstylink;
|
141 |
-
|
142 |
-
return $this->_thirstylink = new Affiliate_Link( $post_id );
|
143 |
-
|
144 |
-
}
|
145 |
-
|
146 |
-
/**
|
147 |
-
* Set ta_flush_rewrite_rules transient value to true if the link prefix value has changed.
|
148 |
-
*
|
149 |
-
* @since 3.0.0
|
150 |
-
* @access public
|
151 |
-
*
|
152 |
-
* @param string $new_value Option new value.
|
153 |
-
* @param string $old_value Option old value.
|
154 |
-
*/
|
155 |
-
public function set_flush_rewrite_rules_transient( $new_value , $old_value ) {
|
156 |
-
|
157 |
-
if ( $new_value != $old_value )
|
158 |
-
set_transient( 'ta_flush_rewrite_rules' , 'true' , 5 * 60 );
|
159 |
-
|
160 |
-
return $new_value;
|
161 |
-
|
162 |
-
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* Set rewrite tags and rules.
|
166 |
-
*
|
167 |
-
* @since 3.0.0
|
168 |
-
* @access private
|
169 |
-
*
|
170 |
-
* @param string $link_prefix Thirstylink post type slug.
|
171 |
-
*/
|
172 |
-
public function set_rewrites( $link_prefix ) {
|
173 |
-
|
174 |
-
add_rewrite_tag( '%' . $link_prefix . '%' , '([^&]+)' );
|
175 |
-
add_rewrite_rule( "$link_prefix/([^/]+)?/?$" , 'index.php?thirstylink=$matches[1]' , 'top' );
|
176 |
-
|
177 |
-
if ( get_option( 'ta_show_cat_in_slug' ) === 'yes' ) {
|
178 |
-
|
179 |
-
add_rewrite_tag( '%thirstylink-category%' , '([^&]+)');
|
180 |
-
add_rewrite_rule( "$link_prefix/([^/]+)?/?([^/]+)?/?" , 'index.php?thirstylink=$matches[2]&thirstylink-category=$matches[1]' , 'top' );
|
181 |
-
}
|
182 |
-
}
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Flush rewrite rules (soft) when the ta_flush_rewrite_rules transient is set to 'true'.
|
186 |
-
*
|
187 |
-
* @since 3.0.0
|
188 |
-
* @access public
|
189 |
-
*/
|
190 |
-
public function flush_rewrite_rules() {
|
191 |
-
|
192 |
-
if ( 'true' !== get_transient( 'ta_flush_rewrite_rules' ) )
|
193 |
-
return;
|
194 |
-
|
195 |
-
flush_rewrite_rules( false );
|
196 |
-
delete_transient( 'ta_flush_rewrite_rules' );
|
197 |
-
|
198 |
-
// block bots on accessing/indexing affiliate links on htaccess
|
199 |
-
$this->block_bots_to_access_affiliate_links_on_htaccess();
|
200 |
-
}
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
/*
|
206 |
-
|--------------------------------------------------------------------------
|
207 |
-
| Redirection Handler
|
208 |
-
|--------------------------------------------------------------------------
|
209 |
-
*/
|
210 |
-
|
211 |
-
/**
|
212 |
-
* Handles redirect for thirstylink link urls.
|
213 |
-
*
|
214 |
-
* @since 3.0.0
|
215 |
-
* @since 3.2.2 Add implementation for disabling cache for 301 redirects.
|
216 |
-
* @since 3.3.2 TA-265 when attachment page is viewed link prefix, set page to 404 via $wp_query object.
|
217 |
-
* @access public
|
218 |
-
*/
|
219 |
-
public function redirect_url() {
|
220 |
-
|
221 |
-
global $post , $wp_query;
|
222 |
-
|
223 |
-
if ( is_admin() || ! is_object( $post ) || $post->post_type != Plugin_Constants::AFFILIATE_LINKS_CPT ) {
|
224 |
-
|
225 |
-
if ( is_object( $post ) && $post->post_type === 'attachment' && $this->validate_cloaked_url() )
|
226 |
-
$wp_query->set_404();
|
227 |
-
|
228 |
-
return;
|
229 |
-
}
|
230 |
-
|
231 |
-
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
232 |
-
$redirect_url = html_entity_decode( $thirstylink->get_prop( 'destination_url' ) );
|
233 |
-
$redirect_type = $thirstylink->get_redirect_type();
|
234 |
-
|
235 |
-
// Apply any filters to the url and redirect type before redirecting
|
236 |
-
$redirect_url = apply_filters( 'ta_filter_redirect_url' , $redirect_url , $thirstylink , '' );
|
237 |
-
$redirect_type = apply_filters( 'ta_filter_redirect_type' , $redirect_type , $thirstylink );
|
238 |
-
|
239 |
-
// if cloaked url is invalid, then don't redirect.
|
240 |
-
if ( ! $this->validate_cloaked_url( $thirstylink ) ) {
|
241 |
-
|
242 |
-
$wp_query->set_404();
|
243 |
-
remove_action( 'template_redirect' , array( $this , 'redirect_url' ) , 1 );
|
244 |
-
return;
|
245 |
-
}
|
246 |
-
|
247 |
-
// perform actions before redirecting
|
248 |
-
do_action( 'ta_before_link_redirect' , $thirstylink , $redirect_url , $redirect_type );
|
249 |
-
|
250 |
-
if ( $redirect_url && $redirect_type ) {
|
251 |
-
|
252 |
-
// tell browser not to cache 301 redirects (if option is enabled)
|
253 |
-
if ( $redirect_type == 301 && get_option( 'ta_browser_no_cache_301_redirect' ) == 'yes' ) {
|
254 |
-
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
|
255 |
-
header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
|
256 |
-
}
|
257 |
-
|
258 |
-
wp_redirect( $redirect_url , intval( $redirect_type ) );
|
259 |
-
exit;
|
260 |
-
}
|
261 |
-
|
262 |
-
}
|
263 |
-
|
264 |
-
/**
|
265 |
-
* Validate the cloaked url.
|
266 |
-
*
|
267 |
-
* @since 3.2.2
|
268 |
-
* @since 3.3.2 improved code so it will always check the link prefix and only check category when it is present and eligible.
|
269 |
-
* @access private
|
270 |
-
*
|
271 |
-
* @return boolean True if cloaked url is valid, false otherwise.
|
272 |
-
*/
|
273 |
-
private function validate_cloaked_url( $thirstylink = null ) {
|
274 |
-
|
275 |
-
$cat_slug = is_object( $thirstylink ) ? $thirstylink->get_category_slug() : '';
|
276 |
-
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
277 |
-
$referrer = isset( $_SERVER[ 'REQUEST_URI' ] ) ? $_SERVER[ 'REQUEST_URI' ] : '';
|
278 |
-
$needle = '/' . $link_prefix . '/';
|
279 |
-
|
280 |
-
// if setting is disabled or category slug is not defined, then return as validated.
|
281 |
-
if ( get_option( 'ta_show_cat_in_slug' ) == 'yes' && $cat_slug )
|
282 |
-
$needle .= $cat_slug . '/';
|
283 |
-
|
284 |
-
return strpos( $referrer , $needle ) !== false;
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* Pass query strings to destination url when option is enabled on settings.
|
289 |
-
*
|
290 |
-
* @since 3.0.0
|
291 |
-
* @since 3.4.0 Add query string as a parameter to support enhanced JS redirect.
|
292 |
-
* @access public
|
293 |
-
*
|
294 |
-
* @param string $redirect_url Affiliate link destination url.
|
295 |
-
* @param Affiliate_Link $thirstylink Affiliate link object.
|
296 |
-
* @param string $query_string Query string.
|
297 |
-
* @return string Redirect url with query string or not.
|
298 |
-
*/
|
299 |
-
public function pass_query_string_to_destination_url( $redirect_url , $thirstylink , $query_string = '' ) {
|
300 |
-
|
301 |
-
if ( ! $query_string && isset( $_SERVER[ 'QUERY_STRING' ] ) )
|
302 |
-
$query_string = $_SERVER[ 'QUERY_STRING' ];
|
303 |
-
|
304 |
-
if ( ! $query_string || ! $thirstylink->is( 'pass_query_str' ) )
|
305 |
-
return $redirect_url;
|
306 |
-
|
307 |
-
$connector = ( strpos( $redirect_url , '?' ) === false ) ? '?' : '&';
|
308 |
-
|
309 |
-
return $redirect_url . $connector . $query_string;
|
310 |
-
}
|
311 |
-
|
312 |
-
/**
|
313 |
-
* Add/Recreate htaccess rule to block bots access to affiliate links.
|
314 |
-
*
|
315 |
-
* @since 3.1.0
|
316 |
-
* @since 3.3.2 Get blocked bots from setting value.
|
317 |
-
* @since 3.3.7 We only add the htaccess bots blocker content when the ta_enable_bot_crawl_blocker_script setting option is set to "yes".
|
318 |
-
* @access public
|
319 |
-
*/
|
320 |
-
public function block_bots_to_access_affiliate_links_on_htaccess() {
|
321 |
-
|
322 |
-
$htaccess = $this->remove_block_bots_htaccess_rules();
|
323 |
-
|
324 |
-
if ( get_option( 'ta_enable_bot_crawl_blocker_script' ) == 'yes' ) {
|
325 |
-
|
326 |
-
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
327 |
-
$bots_list = apply_filters( 'ta_block_bots_on_htaccess' , $this->_helper_functions->get_blocked_bots() );
|
328 |
-
|
329 |
-
// prepare new TA block bots htaccess content.
|
330 |
-
$block_bots = "\n#BEGIN Block-Bots-ThirstyAffiliates\n";
|
331 |
-
$block_bots .= "<IfModule mod_rewrite.c>\n";
|
332 |
-
$block_bots .= "RewriteEngine On\n";
|
333 |
-
$block_bots .= "RewriteCond %{HTTP_USER_AGENT} (" . $bots_list . ") [NC]\n";
|
334 |
-
$block_bots .= "RewriteRule ^" . $link_prefix . "/ - [L,F]\n";
|
335 |
-
$block_bots .= "</IfModule>\n";
|
336 |
-
$block_bots .= "#END Block-Bots-ThirstyAffiliates\n\n";
|
337 |
-
|
338 |
-
// prepend block bots rules in the htaccess content.
|
339 |
-
$htaccess = $block_bots . $htaccess;
|
340 |
-
}
|
341 |
-
|
342 |
-
file_put_contents( $this->_constants->HTACCESS_FILE() , $htaccess );
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Remove ThirstyAffiliates block bots htaccess rules.
|
347 |
-
*
|
348 |
-
* @since 3.1.0
|
349 |
-
* @access public
|
350 |
-
*
|
351 |
-
* @param boolean $put_contents Toggle to check if function needs to save htaccess file or not.
|
352 |
-
* @return string Htaccess content after removing TA block bots rules.
|
353 |
-
*/
|
354 |
-
public function remove_block_bots_htaccess_rules( $put_contents = false ) {
|
355 |
-
|
356 |
-
$htaccess = file_get_contents( $this->_constants->HTACCESS_FILE() );
|
357 |
-
$pattern = "/[\n]*#[\s]*BEGIN Block-Bots-ThirstyAffiliates.*?#[\s]*END Block-Bots-ThirstyAffiliates[\n][\n]/is";
|
358 |
-
$htaccess = preg_replace( $pattern , "" , $htaccess );
|
359 |
-
|
360 |
-
if ( $put_contents )
|
361 |
-
file_put_contents( $this->_constants->HTACCESS_FILE() , $htaccess );
|
362 |
-
|
363 |
-
return $htaccess;
|
364 |
-
}
|
365 |
-
|
366 |
-
/**
|
367 |
-
* Block bots access to affiliate links for non-apache servers.
|
368 |
-
*
|
369 |
-
* @since 3.3.3
|
370 |
-
* @since 3.3.7 We only block bots when the ta_enable_bot_crawl_blocker_script setting option is set to "yes".
|
371 |
-
* @access public
|
372 |
-
*/
|
373 |
-
public function block_bots_non_apache_server() {
|
374 |
-
|
375 |
-
global $post;
|
376 |
-
|
377 |
-
$is_apache = strpos( $_SERVER[ 'SERVER_SOFTWARE' ] , 'Apache' ) !== false;
|
378 |
-
|
379 |
-
if ( $is_apache || ! is_object( $post ) || $post->post_type !== Plugin_Constants::AFFILIATE_LINKS_CPT || ! $this->_helper_functions->is_user_agent_bot() )
|
380 |
-
return;
|
381 |
-
|
382 |
-
$message = apply_filters( 'ta_blocked_bots_non_apache_message' , sprintf( __( "<h1>Forbidden</h1><p>You don't have permission to access %s on this server.</p>" , 'thirstyaffiliates' ) , $_SERVER[ 'REQUEST_URI' ] ) );
|
383 |
-
header( 'HTTP/1.0 403 Forbidden' );
|
384 |
-
die( $message );
|
385 |
-
}
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
/*
|
391 |
-
|--------------------------------------------------------------------------
|
392 |
-
| Fulfill implemented interface contracts
|
393 |
-
|--------------------------------------------------------------------------
|
394 |
-
*/
|
395 |
-
|
396 |
-
/**
|
397 |
-
* Execute codes that needs to run plugin deactivation.
|
398 |
-
*
|
399 |
-
* @since 1.0.0
|
400 |
-
* @access public
|
401 |
-
* @implements ThirstyAffiliates\Interfaces\Deactivatable_Interface
|
402 |
-
*/
|
403 |
-
public function deactivate() {
|
404 |
-
|
405 |
-
$this->remove_block_bots_htaccess_rules( true );
|
406 |
-
}
|
407 |
-
|
408 |
-
/**
|
409 |
-
* Execute ajax handler.
|
410 |
-
*
|
411 |
-
* @since 3.0.0
|
412 |
-
* @access public
|
413 |
-
* @inherit ThirstyAffiliates\Interfaces\Model_Interface
|
414 |
-
*/
|
415 |
-
public function run() {
|
416 |
-
|
417 |
-
// flush rewrite rules
|
418 |
-
add_filter( 'pre_update_option_ta_link_prefix' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
419 |
-
add_filter( 'pre_update_option_ta_link_prefix_custom' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
420 |
-
add_filter( 'pre_update_option_ta_show_cat_in_slug' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
421 |
-
add_filter( 'pre_update_option_ta_blocked_bots' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
422 |
-
add_action( 'update_option_ta_enable_bot_crawl_blocker_script' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
423 |
-
add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'set_rewrites' ) , 1 , 1 );
|
424 |
-
add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'flush_rewrite_rules' ) );
|
425 |
-
|
426 |
-
// redirection handler
|
427 |
-
add_action( 'template_redirect' , array( $this , 'redirect_url' ) , 1 );
|
428 |
-
|
429 |
-
// filter redirect url before redirecting
|
430 |
-
add_filter( 'ta_filter_redirect_url' , array( $this , 'pass_query_string_to_destination_url' ) , 10 , 3 );
|
431 |
-
|
432 |
-
// block bots on redirect (for non-apache servers).
|
433 |
-
if ( get_option( 'ta_enable_bot_crawl_blocker_script' ) == 'yes' )
|
434 |
-
add_action( 'wp' , array( $this , 'block_bots_non_apache_server' ) );
|
435 |
-
|
436 |
-
// update the ta_enable_bot_crawl_blocker_script setting option if it has no value yet on database.
|
437 |
-
if ( get_option( 'ta_enable_bot_crawl_blocker_script' , 'not_on_db' ) === 'not_on_db' )
|
438 |
-
update_option( 'ta_enable_bot_crawl_blocker_script' , '' );
|
439 |
-
}
|
440 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Deactivatable_Interface;
|
9 |
+
|
10 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
15 |
+
*
|
16 |
+
* @since 3.0.0
|
17 |
+
*/
|
18 |
+
class Rewrites_Redirection implements Model_Interface , Deactivatable_Interface {
|
19 |
+
|
20 |
+
/*
|
21 |
+
|--------------------------------------------------------------------------
|
22 |
+
| Class Properties
|
23 |
+
|--------------------------------------------------------------------------
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Property that holds the single main instance of Rewrites_Redirection.
|
28 |
+
*
|
29 |
+
* @since 3.0.0
|
30 |
+
* @access private
|
31 |
+
* @var Redirection
|
32 |
+
*/
|
33 |
+
private static $_instance;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Model that houses the main plugin object.
|
37 |
+
*
|
38 |
+
* @since 3.0.0
|
39 |
+
* @access private
|
40 |
+
* @var Redirection
|
41 |
+
*/
|
42 |
+
private $_main_plugin;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Model that houses all the plugin constants.
|
46 |
+
*
|
47 |
+
* @since 3.0.0
|
48 |
+
* @access private
|
49 |
+
* @var Plugin_Constants
|
50 |
+
*/
|
51 |
+
private $_constants;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Property that houses all the helper functions of the plugin.
|
55 |
+
*
|
56 |
+
* @since 3.0.0
|
57 |
+
* @access private
|
58 |
+
* @var Helper_Functions
|
59 |
+
*/
|
60 |
+
private $_helper_functions;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Property that holds the currently loaded thirstylink post.
|
64 |
+
*
|
65 |
+
* @since 3.0.0
|
66 |
+
* @access private
|
67 |
+
*/
|
68 |
+
private $_thirstylink;
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
|
73 |
+
/*
|
74 |
+
|--------------------------------------------------------------------------
|
75 |
+
| Class Methods
|
76 |
+
|--------------------------------------------------------------------------
|
77 |
+
*/
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Class constructor.
|
81 |
+
*
|
82 |
+
* @since 3.0.0
|
83 |
+
* @access public
|
84 |
+
*
|
85 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
86 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
87 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
88 |
+
*/
|
89 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
90 |
+
|
91 |
+
$this->_constants = $constants;
|
92 |
+
$this->_helper_functions = $helper_functions;
|
93 |
+
|
94 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
95 |
+
$main_plugin->add_to_public_models( $this );
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
101 |
+
*
|
102 |
+
* @since 3.0.0
|
103 |
+
* @access public
|
104 |
+
*
|
105 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
106 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
107 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
108 |
+
* @return Redirection
|
109 |
+
*/
|
110 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
111 |
+
|
112 |
+
if ( !self::$_instance instanceof self )
|
113 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
114 |
+
|
115 |
+
return self::$_instance;
|
116 |
+
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
|
121 |
+
|
122 |
+
/*
|
123 |
+
|--------------------------------------------------------------------------
|
124 |
+
| Flush Rewrite Rules
|
125 |
+
|--------------------------------------------------------------------------
|
126 |
+
*/
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Get thirstylink Affiliate_Link object.
|
130 |
+
*
|
131 |
+
* @since 3.0.0
|
132 |
+
* @access private
|
133 |
+
*
|
134 |
+
* @param int $post_id Thirstylink post id.
|
135 |
+
* @return Affiliate_Link object.
|
136 |
+
*/
|
137 |
+
private function get_thirstylink_post( $post_id ) {
|
138 |
+
|
139 |
+
if ( is_object( $this->_thirstylink ) && $this->_thirstylink->get_id() == $post_id )
|
140 |
+
return $this->_thirstylink;
|
141 |
+
|
142 |
+
return $this->_thirstylink = new Affiliate_Link( $post_id );
|
143 |
+
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Set ta_flush_rewrite_rules transient value to true if the link prefix value has changed.
|
148 |
+
*
|
149 |
+
* @since 3.0.0
|
150 |
+
* @access public
|
151 |
+
*
|
152 |
+
* @param string $new_value Option new value.
|
153 |
+
* @param string $old_value Option old value.
|
154 |
+
*/
|
155 |
+
public function set_flush_rewrite_rules_transient( $new_value , $old_value ) {
|
156 |
+
|
157 |
+
if ( $new_value != $old_value )
|
158 |
+
set_transient( 'ta_flush_rewrite_rules' , 'true' , 5 * 60 );
|
159 |
+
|
160 |
+
return $new_value;
|
161 |
+
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Set rewrite tags and rules.
|
166 |
+
*
|
167 |
+
* @since 3.0.0
|
168 |
+
* @access private
|
169 |
+
*
|
170 |
+
* @param string $link_prefix Thirstylink post type slug.
|
171 |
+
*/
|
172 |
+
public function set_rewrites( $link_prefix ) {
|
173 |
+
|
174 |
+
add_rewrite_tag( '%' . $link_prefix . '%' , '([^&]+)' );
|
175 |
+
add_rewrite_rule( "$link_prefix/([^/]+)?/?$" , 'index.php?thirstylink=$matches[1]' , 'top' );
|
176 |
+
|
177 |
+
if ( get_option( 'ta_show_cat_in_slug' ) === 'yes' ) {
|
178 |
+
|
179 |
+
add_rewrite_tag( '%thirstylink-category%' , '([^&]+)');
|
180 |
+
add_rewrite_rule( "$link_prefix/([^/]+)?/?([^/]+)?/?" , 'index.php?thirstylink=$matches[2]&thirstylink-category=$matches[1]' , 'top' );
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Flush rewrite rules (soft) when the ta_flush_rewrite_rules transient is set to 'true'.
|
186 |
+
*
|
187 |
+
* @since 3.0.0
|
188 |
+
* @access public
|
189 |
+
*/
|
190 |
+
public function flush_rewrite_rules() {
|
191 |
+
|
192 |
+
if ( 'true' !== get_transient( 'ta_flush_rewrite_rules' ) )
|
193 |
+
return;
|
194 |
+
|
195 |
+
flush_rewrite_rules( false );
|
196 |
+
delete_transient( 'ta_flush_rewrite_rules' );
|
197 |
+
|
198 |
+
// block bots on accessing/indexing affiliate links on htaccess
|
199 |
+
$this->block_bots_to_access_affiliate_links_on_htaccess();
|
200 |
+
}
|
201 |
+
|
202 |
+
|
203 |
+
|
204 |
+
|
205 |
+
/*
|
206 |
+
|--------------------------------------------------------------------------
|
207 |
+
| Redirection Handler
|
208 |
+
|--------------------------------------------------------------------------
|
209 |
+
*/
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Handles redirect for thirstylink link urls.
|
213 |
+
*
|
214 |
+
* @since 3.0.0
|
215 |
+
* @since 3.2.2 Add implementation for disabling cache for 301 redirects.
|
216 |
+
* @since 3.3.2 TA-265 when attachment page is viewed link prefix, set page to 404 via $wp_query object.
|
217 |
+
* @access public
|
218 |
+
*/
|
219 |
+
public function redirect_url() {
|
220 |
+
|
221 |
+
global $post , $wp_query;
|
222 |
+
|
223 |
+
if ( is_admin() || ! is_object( $post ) || $post->post_type != Plugin_Constants::AFFILIATE_LINKS_CPT ) {
|
224 |
+
|
225 |
+
if ( is_object( $post ) && $post->post_type === 'attachment' && $this->validate_cloaked_url() )
|
226 |
+
$wp_query->set_404();
|
227 |
+
|
228 |
+
return;
|
229 |
+
}
|
230 |
+
|
231 |
+
$thirstylink = $this->get_thirstylink_post( $post->ID );
|
232 |
+
$redirect_url = html_entity_decode( $thirstylink->get_prop( 'destination_url' ) );
|
233 |
+
$redirect_type = $thirstylink->get_redirect_type();
|
234 |
+
|
235 |
+
// Apply any filters to the url and redirect type before redirecting
|
236 |
+
$redirect_url = apply_filters( 'ta_filter_redirect_url' , $redirect_url , $thirstylink , '' );
|
237 |
+
$redirect_type = apply_filters( 'ta_filter_redirect_type' , $redirect_type , $thirstylink );
|
238 |
+
|
239 |
+
// if cloaked url is invalid, then don't redirect.
|
240 |
+
if ( ! $this->validate_cloaked_url( $thirstylink ) ) {
|
241 |
+
|
242 |
+
$wp_query->set_404();
|
243 |
+
remove_action( 'template_redirect' , array( $this , 'redirect_url' ) , 1 );
|
244 |
+
return;
|
245 |
+
}
|
246 |
+
|
247 |
+
// perform actions before redirecting
|
248 |
+
do_action( 'ta_before_link_redirect' , $thirstylink , $redirect_url , $redirect_type );
|
249 |
+
|
250 |
+
if ( $redirect_url && $redirect_type ) {
|
251 |
+
|
252 |
+
// tell browser not to cache 301 redirects (if option is enabled)
|
253 |
+
if ( $redirect_type == 301 && get_option( 'ta_browser_no_cache_301_redirect' ) == 'yes' ) {
|
254 |
+
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
|
255 |
+
header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
|
256 |
+
}
|
257 |
+
|
258 |
+
wp_redirect( $redirect_url , intval( $redirect_type ) );
|
259 |
+
exit;
|
260 |
+
}
|
261 |
+
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Validate the cloaked url.
|
266 |
+
*
|
267 |
+
* @since 3.2.2
|
268 |
+
* @since 3.3.2 improved code so it will always check the link prefix and only check category when it is present and eligible.
|
269 |
+
* @access private
|
270 |
+
*
|
271 |
+
* @return boolean True if cloaked url is valid, false otherwise.
|
272 |
+
*/
|
273 |
+
private function validate_cloaked_url( $thirstylink = null ) {
|
274 |
+
|
275 |
+
$cat_slug = is_object( $thirstylink ) ? $thirstylink->get_category_slug() : '';
|
276 |
+
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
277 |
+
$referrer = isset( $_SERVER[ 'REQUEST_URI' ] ) ? $_SERVER[ 'REQUEST_URI' ] : '';
|
278 |
+
$needle = '/' . $link_prefix . '/';
|
279 |
+
|
280 |
+
// if setting is disabled or category slug is not defined, then return as validated.
|
281 |
+
if ( get_option( 'ta_show_cat_in_slug' ) == 'yes' && $cat_slug )
|
282 |
+
$needle .= $cat_slug . '/';
|
283 |
+
|
284 |
+
return strpos( $referrer , $needle ) !== false;
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Pass query strings to destination url when option is enabled on settings.
|
289 |
+
*
|
290 |
+
* @since 3.0.0
|
291 |
+
* @since 3.4.0 Add query string as a parameter to support enhanced JS redirect.
|
292 |
+
* @access public
|
293 |
+
*
|
294 |
+
* @param string $redirect_url Affiliate link destination url.
|
295 |
+
* @param Affiliate_Link $thirstylink Affiliate link object.
|
296 |
+
* @param string $query_string Query string.
|
297 |
+
* @return string Redirect url with query string or not.
|
298 |
+
*/
|
299 |
+
public function pass_query_string_to_destination_url( $redirect_url , $thirstylink , $query_string = '' ) {
|
300 |
+
|
301 |
+
if ( ! $query_string && isset( $_SERVER[ 'QUERY_STRING' ] ) )
|
302 |
+
$query_string = $_SERVER[ 'QUERY_STRING' ];
|
303 |
+
|
304 |
+
if ( ! $query_string || ! $thirstylink->is( 'pass_query_str' ) )
|
305 |
+
return $redirect_url;
|
306 |
+
|
307 |
+
$connector = ( strpos( $redirect_url , '?' ) === false ) ? '?' : '&';
|
308 |
+
|
309 |
+
return $redirect_url . $connector . $query_string;
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Add/Recreate htaccess rule to block bots access to affiliate links.
|
314 |
+
*
|
315 |
+
* @since 3.1.0
|
316 |
+
* @since 3.3.2 Get blocked bots from setting value.
|
317 |
+
* @since 3.3.7 We only add the htaccess bots blocker content when the ta_enable_bot_crawl_blocker_script setting option is set to "yes".
|
318 |
+
* @access public
|
319 |
+
*/
|
320 |
+
public function block_bots_to_access_affiliate_links_on_htaccess() {
|
321 |
+
|
322 |
+
$htaccess = $this->remove_block_bots_htaccess_rules();
|
323 |
+
|
324 |
+
if ( get_option( 'ta_enable_bot_crawl_blocker_script' ) == 'yes' ) {
|
325 |
+
|
326 |
+
$link_prefix = $this->_helper_functions->get_thirstylink_link_prefix();
|
327 |
+
$bots_list = apply_filters( 'ta_block_bots_on_htaccess' , $this->_helper_functions->get_blocked_bots() );
|
328 |
+
|
329 |
+
// prepare new TA block bots htaccess content.
|
330 |
+
$block_bots = "\n#BEGIN Block-Bots-ThirstyAffiliates\n";
|
331 |
+
$block_bots .= "<IfModule mod_rewrite.c>\n";
|
332 |
+
$block_bots .= "RewriteEngine On\n";
|
333 |
+
$block_bots .= "RewriteCond %{HTTP_USER_AGENT} (" . $bots_list . ") [NC]\n";
|
334 |
+
$block_bots .= "RewriteRule ^" . $link_prefix . "/ - [L,F]\n";
|
335 |
+
$block_bots .= "</IfModule>\n";
|
336 |
+
$block_bots .= "#END Block-Bots-ThirstyAffiliates\n\n";
|
337 |
+
|
338 |
+
// prepend block bots rules in the htaccess content.
|
339 |
+
$htaccess = $block_bots . $htaccess;
|
340 |
+
}
|
341 |
+
|
342 |
+
file_put_contents( $this->_constants->HTACCESS_FILE() , $htaccess );
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Remove ThirstyAffiliates block bots htaccess rules.
|
347 |
+
*
|
348 |
+
* @since 3.1.0
|
349 |
+
* @access public
|
350 |
+
*
|
351 |
+
* @param boolean $put_contents Toggle to check if function needs to save htaccess file or not.
|
352 |
+
* @return string Htaccess content after removing TA block bots rules.
|
353 |
+
*/
|
354 |
+
public function remove_block_bots_htaccess_rules( $put_contents = false ) {
|
355 |
+
|
356 |
+
$htaccess = file_get_contents( $this->_constants->HTACCESS_FILE() );
|
357 |
+
$pattern = "/[\n]*#[\s]*BEGIN Block-Bots-ThirstyAffiliates.*?#[\s]*END Block-Bots-ThirstyAffiliates[\n][\n]/is";
|
358 |
+
$htaccess = preg_replace( $pattern , "" , $htaccess );
|
359 |
+
|
360 |
+
if ( $put_contents )
|
361 |
+
file_put_contents( $this->_constants->HTACCESS_FILE() , $htaccess );
|
362 |
+
|
363 |
+
return $htaccess;
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Block bots access to affiliate links for non-apache servers.
|
368 |
+
*
|
369 |
+
* @since 3.3.3
|
370 |
+
* @since 3.3.7 We only block bots when the ta_enable_bot_crawl_blocker_script setting option is set to "yes".
|
371 |
+
* @access public
|
372 |
+
*/
|
373 |
+
public function block_bots_non_apache_server() {
|
374 |
+
|
375 |
+
global $post;
|
376 |
+
|
377 |
+
$is_apache = strpos( $_SERVER[ 'SERVER_SOFTWARE' ] , 'Apache' ) !== false;
|
378 |
+
|
379 |
+
if ( $is_apache || ! is_object( $post ) || $post->post_type !== Plugin_Constants::AFFILIATE_LINKS_CPT || ! $this->_helper_functions->is_user_agent_bot() )
|
380 |
+
return;
|
381 |
+
|
382 |
+
$message = apply_filters( 'ta_blocked_bots_non_apache_message' , sprintf( __( "<h1>Forbidden</h1><p>You don't have permission to access %s on this server.</p>" , 'thirstyaffiliates' ) , $_SERVER[ 'REQUEST_URI' ] ) );
|
383 |
+
header( 'HTTP/1.0 403 Forbidden' );
|
384 |
+
die( $message );
|
385 |
+
}
|
386 |
+
|
387 |
+
|
388 |
+
|
389 |
+
|
390 |
+
/*
|
391 |
+
|--------------------------------------------------------------------------
|
392 |
+
| Fulfill implemented interface contracts
|
393 |
+
|--------------------------------------------------------------------------
|
394 |
+
*/
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Execute codes that needs to run plugin deactivation.
|
398 |
+
*
|
399 |
+
* @since 1.0.0
|
400 |
+
* @access public
|
401 |
+
* @implements ThirstyAffiliates\Interfaces\Deactivatable_Interface
|
402 |
+
*/
|
403 |
+
public function deactivate() {
|
404 |
+
|
405 |
+
$this->remove_block_bots_htaccess_rules( true );
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Execute ajax handler.
|
410 |
+
*
|
411 |
+
* @since 3.0.0
|
412 |
+
* @access public
|
413 |
+
* @inherit ThirstyAffiliates\Interfaces\Model_Interface
|
414 |
+
*/
|
415 |
+
public function run() {
|
416 |
+
|
417 |
+
// flush rewrite rules
|
418 |
+
add_filter( 'pre_update_option_ta_link_prefix' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
419 |
+
add_filter( 'pre_update_option_ta_link_prefix_custom' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
420 |
+
add_filter( 'pre_update_option_ta_show_cat_in_slug' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
421 |
+
add_filter( 'pre_update_option_ta_blocked_bots' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
422 |
+
add_action( 'update_option_ta_enable_bot_crawl_blocker_script' , array( $this , 'set_flush_rewrite_rules_transient' ) , 10 , 2 );
|
423 |
+
add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'set_rewrites' ) , 1 , 1 );
|
424 |
+
add_action( 'ta_after_register_thirstylink_post_type' , array( $this , 'flush_rewrite_rules' ) );
|
425 |
+
|
426 |
+
// redirection handler
|
427 |
+
add_action( 'template_redirect' , array( $this , 'redirect_url' ) , 1 );
|
428 |
+
|
429 |
+
// filter redirect url before redirecting
|
430 |
+
add_filter( 'ta_filter_redirect_url' , array( $this , 'pass_query_string_to_destination_url' ) , 10 , 3 );
|
431 |
+
|
432 |
+
// block bots on redirect (for non-apache servers).
|
433 |
+
if ( get_option( 'ta_enable_bot_crawl_blocker_script' ) == 'yes' )
|
434 |
+
add_action( 'wp' , array( $this , 'block_bots_non_apache_server' ) );
|
435 |
+
|
436 |
+
// update the ta_enable_bot_crawl_blocker_script setting option if it has no value yet on database.
|
437 |
+
if ( get_option( 'ta_enable_bot_crawl_blocker_script' , 'not_on_db' ) === 'not_on_db' )
|
438 |
+
update_option( 'ta_enable_bot_crawl_blocker_script' , '' );
|
439 |
+
}
|
440 |
+
}
|
Models/Script_Loader.php
CHANGED
@@ -306,6 +306,19 @@ class Script_Loader implements Model_Interface {
|
|
306 |
) ) );
|
307 |
}
|
308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
/**
|
310 |
* Get absolute home_url by recreating it and removing unneeded information.
|
311 |
*
|
@@ -338,6 +351,9 @@ class Script_Loader implements Model_Interface {
|
|
338 |
|
339 |
// Add support for elementor.
|
340 |
add_action( 'elementor/editor/before_enqueue_scripts' , array( $this , 'load_wp_editor_scripts' ) );
|
|
|
|
|
|
|
341 |
}
|
342 |
|
343 |
}
|
306 |
) ) );
|
307 |
}
|
308 |
|
309 |
+
/**
|
310 |
+
* Gutenberg backend scripts.
|
311 |
+
*
|
312 |
+
* @since 3.6
|
313 |
+
* @access public
|
314 |
+
*/
|
315 |
+
public function gutenberg_backend_scripts() {
|
316 |
+
|
317 |
+
wp_enqueue_style( 'ta-gutenberg-support' , $this->_constants->JS_ROOT_URL() . 'app/gutenberg_support/dist/gutenberg-support.css' , Plugin_Constants::VERSION , 'screen' );
|
318 |
+
|
319 |
+
wp_enqueue_script( 'ta-gutenberg-support' , $this->_constants->JS_ROOT_URL() . 'app/gutenberg_support/dist/gutenberg-support.js' , array( 'wp-blocks' , 'wp-element' , 'wp-components' , 'wp-i18n' ) , '1.0.0' , true );
|
320 |
+
}
|
321 |
+
|
322 |
/**
|
323 |
* Get absolute home_url by recreating it and removing unneeded information.
|
324 |
*
|
351 |
|
352 |
// Add support for elementor.
|
353 |
add_action( 'elementor/editor/before_enqueue_scripts' , array( $this , 'load_wp_editor_scripts' ) );
|
354 |
+
|
355 |
+
// Gutenberg support
|
356 |
+
add_action( 'enqueue_block_editor_assets' , array( $this , 'gutenberg_backend_scripts' ) );
|
357 |
}
|
358 |
|
359 |
}
|
Models/Settings.php
CHANGED
@@ -1,2073 +1,2114 @@
|
|
1 |
-
<?php
|
2 |
-
namespace ThirstyAffiliates\Models;
|
3 |
-
|
4 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
-
|
6 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
7 |
-
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
-
|
10 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
-
|
13 |
-
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Model that houses the logic of plugin Settings.
|
17 |
-
* General Information:
|
18 |
-
* The Ultimate Settings API ( Of course there will always be room for improvements ).
|
19 |
-
* Basically we are using parts of the WordPress Settings API ( Only the backend processes )
|
20 |
-
* But we are using our own custom render codebase.
|
21 |
-
* The issue with WordPress Settings API is that we need to supply callbacks for each option field we add, so its not really extensible.
|
22 |
-
* The data supplied on those callbacks are not ideal or not complete too to make a very extensible Settings API.
|
23 |
-
* So what we did is, Register the settings and settings options in a way that we can utilize WordPress Settings API to handle them on the backend.
|
24 |
-
* But use our own render codebase so we can make the Settings API very easy to extend.
|
25 |
-
*
|
26 |
-
* Important Note:
|
27 |
-
* Be careful with default values. Default values only take effect if you haven't set the option yet. Meaning the option is not yet registered yet to the options db. ( get_option ).
|
28 |
-
* Now if you hit save on a settings section with a field that have a default value, and you haven't changed that default value, Alas! it will still not register that option to the options db.
|
29 |
-
* The reason is the default value and the current value of the options is the same.
|
30 |
-
* Bug if you modify the value of the option, and hit save, this time, that option will be registered to the options db.
|
31 |
-
* Then if you set back the value of that option, same as its default, it will still updated that option that is registered to the options db with that value.
|
32 |
-
* Again remember, default value only kicks in if the option you are trying to get via get_option function is not yet registered to the options db.
|
33 |
-
*
|
34 |
-
* Important Note:
|
35 |
-
* If the option can contain multiple values ( in array form , ex. checkbox and multiselect option types ), the default value must be in array form even if it only contains one value.
|
36 |
-
*
|
37 |
-
* Private Model.
|
38 |
-
*
|
39 |
-
* @since 3.0.0
|
40 |
-
*/
|
41 |
-
class Settings implements Model_Interface , Activatable_Interface , Initiable_Interface {
|
42 |
-
|
43 |
-
/*
|
44 |
-
|--------------------------------------------------------------------------
|
45 |
-
| Class Properties
|
46 |
-
|--------------------------------------------------------------------------
|
47 |
-
*/
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Property that holds the single main instance of Settings.
|
51 |
-
*
|
52 |
-
* @since 3.0.0
|
53 |
-
* @access private
|
54 |
-
* @var Settings
|
55 |
-
*/
|
56 |
-
private static $_instance;
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Model that houses all the plugin constants.
|
60 |
-
*
|
61 |
-
* @since 3.0.0
|
62 |
-
* @access private
|
63 |
-
* @var Plugin_Constants
|
64 |
-
*/
|
65 |
-
private $_constants;
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Property that houses all the helper functions of the plugin.
|
69 |
-
*
|
70 |
-
* @since 3.0.0
|
71 |
-
* @access private
|
72 |
-
* @var Helper_Functions
|
73 |
-
*/
|
74 |
-
private $_helper_functions;
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Property that houses all the supported option field types.
|
78 |
-
*
|
79 |
-
* @since 3.0.0
|
80 |
-
* @access private
|
81 |
-
* @var array
|
82 |
-
*/
|
83 |
-
private $_supported_field_types;
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Property that houses all the supported option field types that do not needed to be registered to the WP Settings API.
|
87 |
-
* Ex. of this are field types that are for decorative purposes only and has no underlying option data to save.
|
88 |
-
* Another is type of option fields that perform specialized task and does not need any underlying data to be saved.
|
89 |
-
*
|
90 |
-
* @since 3.0.0
|
91 |
-
* @access public
|
92 |
-
*/
|
93 |
-
private $_skip_wp_settings_registration;
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Property that houses all the registered settings sections.
|
97 |
-
*
|
98 |
-
*
|
99 |
-
* @since 3.0.0
|
100 |
-
* @access private
|
101 |
-
* @var array
|
102 |
-
*/
|
103 |
-
private $_settings_sections;
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Property that houses all the registered options of the registered settings sections.
|
107 |
-
*
|
108 |
-
* @since 3.0.0
|
109 |
-
* @access private
|
110 |
-
* @var array
|
111 |
-
*/
|
112 |
-
private $_settings_section_options;
|
113 |
-
|
114 |
-
/**
|
115 |
-
* Property that holds all plugin options that can be exported.
|
116 |
-
*
|
117 |
-
* @since 3.0.0
|
118 |
-
* @access private
|
119 |
-
* @var array
|
120 |
-
*/
|
121 |
-
private $_exportable_options;
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Property that holds list of post update function callbacks per option if there are any.
|
125 |
-
*
|
126 |
-
* @since 3.0.0
|
127 |
-
* @access private
|
128 |
-
* @var array
|
129 |
-
*/
|
130 |
-
private $_post_update_option_cbs = array();
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
/*
|
136 |
-
|--------------------------------------------------------------------------
|
137 |
-
| Class Methods
|
138 |
-
|--------------------------------------------------------------------------
|
139 |
-
*/
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Class constructor.
|
143 |
-
*
|
144 |
-
* @since 3.0.0
|
145 |
-
* @access public
|
146 |
-
*
|
147 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
148 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
149 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
150 |
-
*/
|
151 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
152 |
-
|
153 |
-
$this->_constants = $constants;
|
154 |
-
$this->_helper_functions = $helper_functions;
|
155 |
-
|
156 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
157 |
-
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
162 |
-
*
|
163 |
-
* @since 3.0.0
|
164 |
-
* @access public
|
165 |
-
*
|
166 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
167 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
168 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
169 |
-
* @return Settings
|
170 |
-
*/
|
171 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
172 |
-
|
173 |
-
if ( !self::$_instance instanceof self )
|
174 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
175 |
-
|
176 |
-
return self::$_instance;
|
177 |
-
|
178 |
-
}
|
179 |
-
|
180 |
-
/**
|
181 |
-
* Register admin interfaces.
|
182 |
-
*
|
183 |
-
* @since 3.3.2
|
184 |
-
* @access public
|
185 |
-
*
|
186 |
-
* @param array $interfaces List of admin interfaces.
|
187 |
-
* @return array Filtered list of admin interfaces.
|
188 |
-
*/
|
189 |
-
public function register_admin_interfaces( $interfaces ) {
|
190 |
-
|
191 |
-
$interfaces[ 'thirstylink_page_thirsty-settings' ] = apply_filters( 'ta_settings_admin_interface' , array(
|
192 |
-
'ta_general_settings' => 'manage_options',
|
193 |
-
'ta_links_settings' => 'manage_options',
|
194 |
-
'ta_modules_settings' => 'manage_options',
|
195 |
-
'ta_help_settings' => 'manage_options',
|
196 |
-
) );
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
*
|
205 |
-
*
|
206 |
-
*
|
207 |
-
* @
|
208 |
-
*
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|--------------------------------------------------------------------------
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
*
|
229 |
-
*
|
230 |
-
* @since 3.
|
231 |
-
* @
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
'
|
239 |
-
'
|
240 |
-
'
|
241 |
-
'
|
242 |
-
'
|
243 |
-
'
|
244 |
-
'
|
245 |
-
'
|
246 |
-
'
|
247 |
-
'
|
248 |
-
'
|
249 |
-
'
|
250 |
-
'
|
251 |
-
'
|
252 |
-
'
|
253 |
-
'
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
'
|
260 |
-
'
|
261 |
-
'
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
'
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
$
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
'
|
302 |
-
'
|
303 |
-
'
|
304 |
-
'
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
'
|
314 |
-
'
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
'
|
321 |
-
'
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
'
|
328 |
-
'
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
'
|
335 |
-
'
|
336 |
-
'
|
337 |
-
'
|
338 |
-
'
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
'
|
345 |
-
'
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
'
|
352 |
-
'
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
'
|
359 |
-
'
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
'
|
366 |
-
'
|
367 |
-
'
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
'
|
375 |
-
'
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
'
|
385 |
-
'
|
386 |
-
'
|
387 |
-
'
|
388 |
-
|
389 |
-
|
390 |
-
'
|
391 |
-
'
|
392 |
-
'
|
393 |
-
'
|
394 |
-
'
|
395 |
-
'
|
396 |
-
'
|
397 |
-
'
|
398 |
-
'
|
399 |
-
'
|
400 |
-
'
|
401 |
-
'
|
402 |
-
'
|
403 |
-
'
|
404 |
-
'
|
405 |
-
'
|
406 |
-
'
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
'
|
414 |
-
'
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
'
|
421 |
-
'
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
'
|
428 |
-
'
|
429 |
-
'
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
'
|
436 |
-
'
|
437 |
-
'
|
438 |
-
'
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
'
|
445 |
-
'
|
446 |
-
'
|
447 |
-
'
|
448 |
-
'
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
'
|
455 |
-
'
|
456 |
-
'
|
457 |
-
'
|
458 |
-
'
|
459 |
-
'
|
460 |
-
'
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
'
|
467 |
-
'
|
468 |
-
'
|
469 |
-
'
|
470 |
-
'
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
'
|
477 |
-
'
|
478 |
-
'
|
479 |
-
'
|
480 |
-
'
|
481 |
-
'
|
482 |
-
'
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
'
|
489 |
-
'
|
490 |
-
'
|
491 |
-
'
|
492 |
-
'
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
'
|
499 |
-
'
|
500 |
-
'
|
501 |
-
'
|
502 |
-
'
|
503 |
-
'
|
504 |
-
'
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
'
|
511 |
-
'
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
'
|
518 |
-
'
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
'
|
525 |
-
'
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
'
|
532 |
-
'
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
'
|
539 |
-
'
|
540 |
-
'
|
541 |
-
'
|
542 |
-
'
|
543 |
-
'
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
'
|
554 |
-
'
|
555 |
-
'
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
'
|
562 |
-
'
|
563 |
-
'
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
'
|
570 |
-
'
|
571 |
-
'
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
'
|
581 |
-
'
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
'
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
'
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
'
|
603 |
-
'
|
604 |
-
'
|
605 |
-
'
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
'
|
612 |
-
'
|
613 |
-
'
|
614 |
-
'
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
'
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
'
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
'
|
633 |
-
'
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
*
|
663 |
-
*
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
$
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
*
|
684 |
-
*
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
$
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
*
|
734 |
-
* We
|
735 |
-
*
|
736 |
-
*
|
737 |
-
*
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
$this->
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
*
|
751 |
-
*
|
752 |
-
* @
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
'
|
763 |
-
'
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
*
|
773 |
-
*
|
774 |
-
* @
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
<?php
|
796 |
-
|
797 |
-
<?php
|
798 |
-
|
799 |
-
<?php
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
$this->
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
*
|
830 |
-
*
|
831 |
-
*
|
832 |
-
* @
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
*
|
844 |
-
*
|
845 |
-
*
|
846 |
-
* @
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
*
|
866 |
-
*
|
867 |
-
*
|
868 |
-
*
|
869 |
-
*
|
870 |
-
* @
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
<?php
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
*
|
889 |
-
*
|
890 |
-
*
|
891 |
-
* @
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
$this->
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|--------------------------------------------------------------------------
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
*
|
943 |
-
*
|
944 |
-
*
|
945 |
-
* @
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
<
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
*
|
977 |
-
*
|
978 |
-
*
|
979 |
-
* @
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
<
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
*
|
1011 |
-
*
|
1012 |
-
*
|
1013 |
-
* @
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
<
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
*
|
1046 |
-
*
|
1047 |
-
*
|
1048 |
-
* @
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
<
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
*
|
1080 |
-
*
|
1081 |
-
*
|
1082 |
-
* @
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
<
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
<?php echo
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
*
|
1136 |
-
*
|
1137 |
-
*
|
1138 |
-
* @
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
<
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
<?php echo $
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
*
|
1189 |
-
*
|
1190 |
-
*
|
1191 |
-
* @
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
<
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
<?php
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
*
|
1236 |
-
*
|
1237 |
-
*
|
1238 |
-
* @
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
<
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
<?php echo isset( $option[ '
|
1258 |
-
|
1259 |
-
<?php
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
*
|
1288 |
-
*
|
1289 |
-
*
|
1290 |
-
*
|
1291 |
-
* @
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
<
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
<?php echo
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
*
|
1333 |
-
*
|
1334 |
-
*
|
1335 |
-
* @
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
<
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
'
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
*
|
1365 |
-
*
|
1366 |
-
*
|
1367 |
-
* @
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
<
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
*
|
1415 |
-
*
|
1416 |
-
*
|
1417 |
-
* @
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
<
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
<
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
<
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
*
|
1484 |
-
*
|
1485 |
-
*
|
1486 |
-
* @
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
<
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
*
|
1509 |
-
*
|
1510 |
-
*
|
1511 |
-
* @
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
|
1528 |
-
|
1529 |
-
|
1530 |
-
|
1531 |
-
*
|
1532 |
-
*
|
1533 |
-
*
|
1534 |
-
* @
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
$
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
|
1547 |
-
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
-
<
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
|
1570 |
-
|
1571 |
-
|
1572 |
-
|
1573 |
-
|
1574 |
-
|
1575 |
-
|
1576 |
-
|
1577 |
-
|
1578 |
-
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
1588 |
-
*
|
1589 |
-
*
|
1590 |
-
*
|
1591 |
-
* @
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
|
1611 |
-
|
1612 |
-
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
|
1621 |
-
|
1622 |
-
|
1623 |
-
|
1624 |
-
*
|
1625 |
-
*
|
1626 |
-
*
|
1627 |
-
* @
|
1628 |
-
|
1629 |
-
|
1630 |
-
|
1631 |
-
|
1632 |
-
|
1633 |
-
|
1634 |
-
|
1635 |
-
|
1636 |
-
|
1637 |
-
|
1638 |
-
|
1639 |
-
|
1640 |
-
|
1641 |
-
|
1642 |
-
|
1643 |
-
|
1644 |
-
|
1645 |
-
|
1646 |
-
|
1647 |
-
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
|
1655 |
-
|
1656 |
-
|
1657 |
-
|
1658 |
-
*
|
1659 |
-
*
|
1660 |
-
*
|
1661 |
-
* @
|
1662 |
-
|
1663 |
-
|
1664 |
-
|
1665 |
-
|
1666 |
-
|
1667 |
-
|
1668 |
-
|
1669 |
-
|
1670 |
-
|
1671 |
-
|
1672 |
-
|
1673 |
-
|
1674 |
-
|
1675 |
-
|
1676 |
-
|
1677 |
-
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
1681 |
-
|
1682 |
-
|
1683 |
-
|
1684 |
-
|
1685 |
-
|
1686 |
-
|
1687 |
-
|
1688 |
-
|
1689 |
-
|
1690 |
-
|
1691 |
-
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|--------------------------------------------------------------------------
|
1699 |
-
|
1700 |
-
|
1701 |
-
|
1702 |
-
|
1703 |
-
|
1704 |
-
*
|
1705 |
-
*
|
1706 |
-
|
1707 |
-
|
1708 |
-
|
1709 |
-
|
1710 |
-
|
1711 |
-
|
1712 |
-
|
1713 |
-
|
1714 |
-
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
|
1721 |
-
|
1722 |
-
|
1723 |
-
|
1724 |
-
|
1725 |
-
|
1726 |
-
|
1727 |
-
|
1728 |
-
|
1729 |
-
|
1730 |
-
|
1731 |
-
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
1742 |
-
|
1743 |
-
|
1744 |
-
|
1745 |
-
|
1746 |
-
|
1747 |
-
|
1748 |
-
|
1749 |
-
|
1750 |
-
|
1751 |
-
|
1752 |
-
|
1753 |
-
|
1754 |
-
|
1755 |
-
|
1756 |
-
|
1757 |
-
|
1758 |
-
|
1759 |
-
|
1760 |
-
*
|
1761 |
-
*
|
1762 |
-
|
1763 |
-
|
1764 |
-
|
1765 |
-
|
1766 |
-
|
1767 |
-
|
1768 |
-
|
1769 |
-
|
1770 |
-
|
1771 |
-
|
1772 |
-
|
1773 |
-
|
1774 |
-
|
1775 |
-
|
1776 |
-
|
1777 |
-
|
1778 |
-
|
1779 |
-
$( this ).find( ".data-set .controls .delete" ).
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
|
1784 |
-
|
1785 |
-
|
1786 |
-
|
1787 |
-
|
1788 |
-
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
1793 |
-
$data_set.
|
1794 |
-
|
1795 |
-
|
1796 |
-
"<
|
1797 |
-
|
1798 |
-
|
1799 |
-
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
-
|
1804 |
-
|
1805 |
-
|
1806 |
-
|
1807 |
-
|
1808 |
-
|
1809 |
-
|
1810 |
-
$data_set.
|
1811 |
-
|
1812 |
-
|
1813 |
-
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
|
1825 |
-
|
1826 |
-
|
1827 |
-
|
1828 |
-
|
1829 |
-
|
1830 |
-
|
1831 |
-
|
1832 |
-
|
1833 |
-
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
1837 |
-
|
1838 |
-
|
1839 |
-
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
1849 |
-
|
1850 |
-
|
1851 |
-
|
1852 |
-
|
1853 |
-
|
1854 |
-
|
1855 |
-
|
1856 |
-
|
1857 |
-
|--------------------------------------------------------------------------
|
1858 |
-
|
1859 |
-
|
1860 |
-
|
1861 |
-
|
1862 |
-
|
1863 |
-
*
|
1864 |
-
*
|
1865 |
-
|
1866 |
-
|
1867 |
-
|
1868 |
-
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
1877 |
-
$response = array( 'status' => '
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
1885 |
-
|
1886 |
-
|
1887 |
-
|
1888 |
-
|
1889 |
-
|
1890 |
-
*
|
1891 |
-
*
|
1892 |
-
*
|
1893 |
-
* @
|
1894 |
-
|
1895 |
-
|
1896 |
-
|
1897 |
-
|
1898 |
-
|
1899 |
-
|
1900 |
-
|
1901 |
-
|
1902 |
-
|
1903 |
-
|
1904 |
-
|
1905 |
-
|
1906 |
-
|
1907 |
-
|
1908 |
-
|
1909 |
-
|
1910 |
-
|
1911 |
-
*
|
1912 |
-
*
|
1913 |
-
|
1914 |
-
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( '
|
1920 |
-
|
1921 |
-
|
1922 |
-
|
1923 |
-
|
1924 |
-
|
1925 |
-
|
1926 |
-
|
1927 |
-
$response = array( 'status' => '
|
1928 |
-
|
1929 |
-
|
1930 |
-
|
1931 |
-
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
1935 |
-
|
1936 |
-
|
1937 |
-
|
1938 |
-
|
1939 |
-
|
1940 |
-
*
|
1941 |
-
*
|
1942 |
-
*
|
1943 |
-
* @
|
1944 |
-
*
|
1945 |
-
|
1946 |
-
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
1957 |
-
|
1958 |
-
|
1959 |
-
|
1960 |
-
|
1961 |
-
|
1962 |
-
|
1963 |
-
|
1964 |
-
|
1965 |
-
|
1966 |
-
|
1967 |
-
|
1968 |
-
|
1969 |
-
|
1970 |
-
|
1971 |
-
|
1972 |
-
|
1973 |
-
|
1974 |
-
|
1975 |
-
*
|
1976 |
-
*
|
1977 |
-
*
|
1978 |
-
* @
|
1979 |
-
*
|
1980 |
-
* @param string $option
|
1981 |
-
|
1982 |
-
|
1983 |
-
|
1984 |
-
|
1985 |
-
|
1986 |
-
|
1987 |
-
|
1988 |
-
|
1989 |
-
|
1990 |
-
|
1991 |
-
|
1992 |
-
|
1993 |
-
|
1994 |
-
|
1995 |
-
|
1996 |
-
|
1997 |
-
|
1998 |
-
|
1999 |
-
|
2000 |
-
|
2001 |
-
|
2002 |
-
|
2003 |
-
|
2004 |
-
|
2005 |
-
|
2006 |
-
|
2007 |
-
|
2008 |
-
|
2009 |
-
|
2010 |
-
|
2011 |
-
|
2012 |
-
|
2013 |
-
|
2014 |
-
|
2015 |
-
|
2016 |
-
|
2017 |
-
|
2018 |
-
|
2019 |
-
|
2020 |
-
|
2021 |
-
|
2022 |
-
|
2023 |
-
|
2024 |
-
|
2025 |
-
|
2026 |
-
|
2027 |
-
|
2028 |
-
|
2029 |
-
|
2030 |
-
|
2031 |
-
|
2032 |
-
|
2033 |
-
|
2034 |
-
|
2035 |
-
|
2036 |
-
|
2037 |
-
|
2038 |
-
|
2039 |
-
|
2040 |
-
|
2041 |
-
|
2042 |
-
|
2043 |
-
|
2044 |
-
|
2045 |
-
|
2046 |
-
|
2047 |
-
|
2048 |
-
|
2049 |
-
|
2050 |
-
|
2051 |
-
|
2052 |
-
|
2053 |
-
|
2054 |
-
|
2055 |
-
|
2056 |
-
|
2057 |
-
*
|
2058 |
-
|
2059 |
-
|
2060 |
-
|
2061 |
-
|
2062 |
-
|
2063 |
-
|
2064 |
-
|
2065 |
-
|
2066 |
-
|
2067 |
-
|
2068 |
-
|
2069 |
-
|
2070 |
-
|
2071 |
-
|
2072 |
-
|
2073 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ThirstyAffiliates\Models;
|
3 |
+
|
4 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
5 |
+
|
6 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
7 |
+
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
+
|
10 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
11 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
12 |
+
|
13 |
+
if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Model that houses the logic of plugin Settings.
|
17 |
+
* General Information:
|
18 |
+
* The Ultimate Settings API ( Of course there will always be room for improvements ).
|
19 |
+
* Basically we are using parts of the WordPress Settings API ( Only the backend processes )
|
20 |
+
* But we are using our own custom render codebase.
|
21 |
+
* The issue with WordPress Settings API is that we need to supply callbacks for each option field we add, so its not really extensible.
|
22 |
+
* The data supplied on those callbacks are not ideal or not complete too to make a very extensible Settings API.
|
23 |
+
* So what we did is, Register the settings and settings options in a way that we can utilize WordPress Settings API to handle them on the backend.
|
24 |
+
* But use our own render codebase so we can make the Settings API very easy to extend.
|
25 |
+
*
|
26 |
+
* Important Note:
|
27 |
+
* Be careful with default values. Default values only take effect if you haven't set the option yet. Meaning the option is not yet registered yet to the options db. ( get_option ).
|
28 |
+
* Now if you hit save on a settings section with a field that have a default value, and you haven't changed that default value, Alas! it will still not register that option to the options db.
|
29 |
+
* The reason is the default value and the current value of the options is the same.
|
30 |
+
* Bug if you modify the value of the option, and hit save, this time, that option will be registered to the options db.
|
31 |
+
* Then if you set back the value of that option, same as its default, it will still updated that option that is registered to the options db with that value.
|
32 |
+
* Again remember, default value only kicks in if the option you are trying to get via get_option function is not yet registered to the options db.
|
33 |
+
*
|
34 |
+
* Important Note:
|
35 |
+
* If the option can contain multiple values ( in array form , ex. checkbox and multiselect option types ), the default value must be in array form even if it only contains one value.
|
36 |
+
*
|
37 |
+
* Private Model.
|
38 |
+
*
|
39 |
+
* @since 3.0.0
|
40 |
+
*/
|
41 |
+
class Settings implements Model_Interface , Activatable_Interface , Initiable_Interface {
|
42 |
+
|
43 |
+
/*
|
44 |
+
|--------------------------------------------------------------------------
|
45 |
+
| Class Properties
|
46 |
+
|--------------------------------------------------------------------------
|
47 |
+
*/
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Property that holds the single main instance of Settings.
|
51 |
+
*
|
52 |
+
* @since 3.0.0
|
53 |
+
* @access private
|
54 |
+
* @var Settings
|
55 |
+
*/
|
56 |
+
private static $_instance;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Model that houses all the plugin constants.
|
60 |
+
*
|
61 |
+
* @since 3.0.0
|
62 |
+
* @access private
|
63 |
+
* @var Plugin_Constants
|
64 |
+
*/
|
65 |
+
private $_constants;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Property that houses all the helper functions of the plugin.
|
69 |
+
*
|
70 |
+
* @since 3.0.0
|
71 |
+
* @access private
|
72 |
+
* @var Helper_Functions
|
73 |
+
*/
|
74 |
+
private $_helper_functions;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Property that houses all the supported option field types.
|
78 |
+
*
|
79 |
+
* @since 3.0.0
|
80 |
+
* @access private
|
81 |
+
* @var array
|
82 |
+
*/
|
83 |
+
private $_supported_field_types;
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Property that houses all the supported option field types that do not needed to be registered to the WP Settings API.
|
87 |
+
* Ex. of this are field types that are for decorative purposes only and has no underlying option data to save.
|
88 |
+
* Another is type of option fields that perform specialized task and does not need any underlying data to be saved.
|
89 |
+
*
|
90 |
+
* @since 3.0.0
|
91 |
+
* @access public
|
92 |
+
*/
|
93 |
+
private $_skip_wp_settings_registration;
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Property that houses all the registered settings sections.
|
97 |
+
*
|
98 |
+
*
|
99 |
+
* @since 3.0.0
|
100 |
+
* @access private
|
101 |
+
* @var array
|
102 |
+
*/
|
103 |
+
private $_settings_sections;
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Property that houses all the registered options of the registered settings sections.
|
107 |
+
*
|
108 |
+
* @since 3.0.0
|
109 |
+
* @access private
|
110 |
+
* @var array
|
111 |
+
*/
|
112 |
+
private $_settings_section_options;
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Property that holds all plugin options that can be exported.
|
116 |
+
*
|
117 |
+
* @since 3.0.0
|
118 |
+
* @access private
|
119 |
+
* @var array
|
120 |
+
*/
|
121 |
+
private $_exportable_options;
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Property that holds list of post update function callbacks per option if there are any.
|
125 |
+
*
|
126 |
+
* @since 3.0.0
|
127 |
+
* @access private
|
128 |
+
* @var array
|
129 |
+
*/
|
130 |
+
private $_post_update_option_cbs = array();
|
131 |
+
|
132 |
+
|
133 |
+
|
134 |
+
|
135 |
+
/*
|
136 |
+
|--------------------------------------------------------------------------
|
137 |
+
| Class Methods
|
138 |
+
|--------------------------------------------------------------------------
|
139 |
+
*/
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Class constructor.
|
143 |
+
*
|
144 |
+
* @since 3.0.0
|
145 |
+
* @access public
|
146 |
+
*
|
147 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
148 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
149 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
150 |
+
*/
|
151 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
152 |
+
|
153 |
+
$this->_constants = $constants;
|
154 |
+
$this->_helper_functions = $helper_functions;
|
155 |
+
|
156 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
157 |
+
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
162 |
+
*
|
163 |
+
* @since 3.0.0
|
164 |
+
* @access public
|
165 |
+
*
|
166 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
167 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
168 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
169 |
+
* @return Settings
|
170 |
+
*/
|
171 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
172 |
+
|
173 |
+
if ( !self::$_instance instanceof self )
|
174 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
175 |
+
|
176 |
+
return self::$_instance;
|
177 |
+
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Register admin interfaces.
|
182 |
+
*
|
183 |
+
* @since 3.3.2
|
184 |
+
* @access public
|
185 |
+
*
|
186 |
+
* @param array $interfaces List of admin interfaces.
|
187 |
+
* @return array Filtered list of admin interfaces.
|
188 |
+
*/
|
189 |
+
public function register_admin_interfaces( $interfaces ) {
|
190 |
+
|
191 |
+
$interfaces[ 'thirstylink_page_thirsty-settings' ] = apply_filters( 'ta_settings_admin_interface' , array(
|
192 |
+
'ta_general_settings' => 'manage_options',
|
193 |
+
'ta_links_settings' => 'manage_options',
|
194 |
+
'ta_modules_settings' => 'manage_options',
|
195 |
+
'ta_help_settings' => 'manage_options',
|
196 |
+
) );
|
197 |
+
|
198 |
+
$interfaces[ 'thirstylink_page_thirsty-settings' ][ 'ta_import_export_settings' ] = 'manage_options';
|
199 |
+
|
200 |
+
return $interfaces;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Register admin interfaces.
|
205 |
+
*
|
206 |
+
* @since 3.3.2
|
207 |
+
* @access public
|
208 |
+
*
|
209 |
+
* @param array $interfaces List of menu items.
|
210 |
+
* @return array Filtered list of menu items.
|
211 |
+
*/
|
212 |
+
public function register_admin_menu_items( $menu_items ) {
|
213 |
+
|
214 |
+
$menu_items[ 'thirsty-settings' ] = 'manage_options';
|
215 |
+
return $menu_items;
|
216 |
+
}
|
217 |
+
|
218 |
+
|
219 |
+
|
220 |
+
|
221 |
+
/*
|
222 |
+
|--------------------------------------------------------------------------
|
223 |
+
| Initialize Settings
|
224 |
+
|--------------------------------------------------------------------------
|
225 |
+
*/
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Initialize the list of plugin built-in settings sections and its corresponding options.
|
229 |
+
*
|
230 |
+
* @since 3.0.0
|
231 |
+
* @since 3.3.1 Add support for URL input type.
|
232 |
+
* @since 3.3.5 Hide enhanced javascript redirect setting when statistics module is disabled.
|
233 |
+
* @access public
|
234 |
+
*/
|
235 |
+
public function init_settings_sections_and_options() {
|
236 |
+
|
237 |
+
$this->_supported_field_types = apply_filters( 'ta_supported_field_types' , array(
|
238 |
+
'text' => array( $this , 'render_text_option_field' ),
|
239 |
+
'url' => array( $this , 'render_url_option_field' ),
|
240 |
+
'number' => array( $this , 'render_number_option_field' ),
|
241 |
+
'textarea' => array( $this , 'render_textarea_option_field' ),
|
242 |
+
'checkbox' => array( $this , 'render_checkbox_option_field' ),
|
243 |
+
'radio' => array( $this , 'render_radio_option_field' ),
|
244 |
+
'select' => array( $this , 'render_select_option_field' ),
|
245 |
+
'multiselect' => array( $this , 'render_multiselect_option_field' ),
|
246 |
+
'toggle' => array( $this , 'render_toggle_option_field' ),
|
247 |
+
'editor' => array( $this , 'render_editor_option_field' ),
|
248 |
+
'csv' => array( $this , 'render_csv_option_field' ),
|
249 |
+
'key_value' => array( $this , 'render_key_value_option_field' ),
|
250 |
+
'link' => array( $this , 'render_link_option_field' ),
|
251 |
+
'option_divider' => array( $this , 'render_option_divider_option_field' ),
|
252 |
+
'migration_controls' => array( $this , 'render_migration_controls_option_field' ),
|
253 |
+
'social_links' => array( $this , 'render_social_links_option_field' ),
|
254 |
+
'export_global_settings' => array( $this , 'render_export_global_settings_option_field' ),
|
255 |
+
'import_global_settings' => array( $this , 'render_import_global_settings_option_field' )
|
256 |
+
) );
|
257 |
+
|
258 |
+
$this->_skip_wp_settings_registration = apply_filters( 'ta_skip_wp_settings_registration' , array(
|
259 |
+
'link',
|
260 |
+
'option_divider',
|
261 |
+
'migration_controls',
|
262 |
+
'export_global_settings',
|
263 |
+
'import_global_settings'
|
264 |
+
) );
|
265 |
+
|
266 |
+
// Toggle options for settings with 'category' as an option.
|
267 |
+
$toggle_cat_options = array(
|
268 |
+
'yes' => __( 'Yes' , 'thirstyaffiliates' ),
|
269 |
+
'no' => __( 'No' , 'thirstyaffiliates' ),
|
270 |
+
'category' => __( 'Per category' , 'thirstyaffiliates' )
|
271 |
+
);
|
272 |
+
$all_categories = $this->_helper_functions->get_all_category_as_options();
|
273 |
+
|
274 |
+
$this->_settings_sections = apply_filters( 'ta_settings_option_sections' , array(
|
275 |
+
'ta_general_settings' => array(
|
276 |
+
'title' => __( 'General' , 'thirstyaffiliates' ) ,
|
277 |
+
'desc' => __( 'Settings that change the general behaviour of ThirstyAffiliates.' , 'thirstyaffiliates' )
|
278 |
+
),
|
279 |
+
'ta_links_settings' => array(
|
280 |
+
'title' => __( 'Link Appearance' , 'thirstyaffiliates' ) ,
|
281 |
+
'desc' => __( 'Settings that specifically affect the behaviour & appearance of your affiliate links.' , 'thirstyaffiliates' )
|
282 |
+
),
|
283 |
+
'ta_modules_settings' => array(
|
284 |
+
'title' => __( 'Modules' , 'thirstyaffiliates' ),
|
285 |
+
'desc' => __( 'This section allows you to turn certain parts of ThirstyAffiliates on or off. Below are the individual modules and features of the plugin that can be controlled.' , 'thirstyaffiliates' )
|
286 |
+
),
|
287 |
+
'ta_import_export_settings' => array(
|
288 |
+
'title' => __( 'Import/Export' , 'thirstyaffiliates' ),
|
289 |
+
'desc' => __( 'Import and Export global ThirstyAffiliates plugin settings from one site to another.' , 'thirstyaffiliates' )
|
290 |
+
),
|
291 |
+
'ta_help_settings' => array(
|
292 |
+
'title' => __( 'Help' , 'thirstyaffiliates' ),
|
293 |
+
'desc' => __( 'Links to knowledge base and other utilities.' , 'thirstyaffiliates' )
|
294 |
+
)
|
295 |
+
) );
|
296 |
+
|
297 |
+
$this->_settings_section_options = apply_filters( 'ta_settings_section_options' , array(
|
298 |
+
'ta_general_settings' => apply_filters( 'ta_general_settings_options' , array(
|
299 |
+
|
300 |
+
array(
|
301 |
+
'id' => 'ta_link_insertion_type',
|
302 |
+
'title' => __( 'Default Link Insertion Type' , 'thirstyaffiliates' ),
|
303 |
+
'desc' => __( "Determines the default link type when inserting a link using the quick search." , 'thirstyaffiliates' ),
|
304 |
+
'type' => 'select',
|
305 |
+
'default' => 'link',
|
306 |
+
'options' => array(
|
307 |
+
'link' => __( 'Link' , 'thirstyaffiliates' ),
|
308 |
+
'shortcode' => __( 'Shortcode' , 'thirstyaffiliates' ),
|
309 |
+
)
|
310 |
+
),
|
311 |
+
|
312 |
+
array(
|
313 |
+
'id' => 'ta_disable_cat_auto_select',
|
314 |
+
'title' => __( 'Disable "uncategorized" category on save?' , 'thirstyaffiliates' ),
|
315 |
+
'desc' => __( 'If links are including categories in the URL then by default ThirstyAffiliates will add an "uncategorized" category to apply to non-categorised links during save. If you disable this, it allows you to have some links with categories in the URL and some without.' , 'thirstyaffiliates' ),
|
316 |
+
'type' => 'toggle'
|
317 |
+
),
|
318 |
+
|
319 |
+
array(
|
320 |
+
'id' => 'ta_disable_visual_editor_buttons',
|
321 |
+
'title' => __( 'Disable buttons on the Visual editor?' , 'thirstyaffiliates' ),
|
322 |
+
'desc' => __( "Hide the ThirstyAffiliates buttons on the Visual editor." , 'thirstyaffiliates' ),
|
323 |
+
'type' => 'toggle'
|
324 |
+
),
|
325 |
+
|
326 |
+
array(
|
327 |
+
'id' => 'ta_disable_text_editor_buttons',
|
328 |
+
'title' => __( 'Disable buttons on the Text/Quicktags editor?' , 'thirstyaffiliates' ),
|
329 |
+
'desc' => __( "Hide the ThirstyAffiliates buttons on the Text editor." , 'thirstyaffiliates' ),
|
330 |
+
'type' => 'toggle'
|
331 |
+
),
|
332 |
+
|
333 |
+
array(
|
334 |
+
'id' => 'ta_stats_trimer_set_point',
|
335 |
+
'title' => __( 'Trim stats older than:' , 'thirstyaffiliates' ),
|
336 |
+
'desc' => __( "months (Automatically clean the statistics database records older than a set point. Setting this to 0 will disable it)." , 'thirstyaffiliates' ),
|
337 |
+
'type' => 'number',
|
338 |
+
'min' => 0,
|
339 |
+
'default' => 0,
|
340 |
+
'condition_cb' => function() { return get_option( 'ta_enable_stats_reporting_module' ) === 'yes'; }
|
341 |
+
),
|
342 |
+
|
343 |
+
array(
|
344 |
+
'id' => 'ta_browser_no_cache_301_redirect',
|
345 |
+
'title' => __( "Don't cache 301 redirects? (server side redirects)" , 'thirstyaffiliates' ),
|
346 |
+
'desc' => __( "By default, browsers caches the 301 redirects. Enabling this option will tell the browser not to cache 301 redirects. Be aware that it is still up to the browser if it will cache it or not." , 'thirstyaffiliates' ),
|
347 |
+
'type' => 'toggle'
|
348 |
+
),
|
349 |
+
|
350 |
+
array(
|
351 |
+
'id' => 'ta_disable_ip_address_collection',
|
352 |
+
'title' => __( "Disable IP address collection" , 'thirstyaffiliates' ),
|
353 |
+
'desc' => __( "By default ThirstyAffiliates plugin collects visitor's IP address everytime they click an affiliate link as part of the statistics information. By checking this the IP address collection will be disabled, but other information will still be saved." , 'thirstyaffiliates' ),
|
354 |
+
'type' => 'toggle'
|
355 |
+
),
|
356 |
+
|
357 |
+
array(
|
358 |
+
'id' => 'ta_disable_browser_device_collection',
|
359 |
+
'title' => __( "Disable browser/device data collection" , 'thirstyaffiliates' ),
|
360 |
+
'desc' => __( "As of version 3.4, by default ThirstyAffiliates plugin collects visitor's browser and device used everytime they click an affiliate link as part of the statistics information. By checking this the browser/device collection will be disabled, but other information will still be saved." , 'thirstyaffiliates' ),
|
361 |
+
'type' => 'toggle'
|
362 |
+
),
|
363 |
+
|
364 |
+
array(
|
365 |
+
'id' => 'ta_blocked_bots',
|
366 |
+
'title' => __( "Blocked bots" , 'thirstyaffiliates' ),
|
367 |
+
'desc' => __( "By default ThirstyAffiliates blocks bots accessing your affiliate links to give you a more appropriate data in the report. Select bots, or enter new ones to block." , 'thirstyaffiliates' ),
|
368 |
+
'type' => 'textarea',
|
369 |
+
'default' => Plugin_Constants::DEFAULT_BLOCKED_BOTS,
|
370 |
+
|
371 |
+
),
|
372 |
+
|
373 |
+
array(
|
374 |
+
'id' => 'ta_enable_bot_crawl_blocker_script',
|
375 |
+
'title' => __( "Enable Bot Crawl Blocker Script" , 'thirstyaffiliates' ),
|
376 |
+
'desc' => __( "By enabling this setting, your affiliate links won't redirect for all the <em>blocked bots</em> set above and will send out a 403 forbidden error." , 'thirstyaffiliates' ),
|
377 |
+
'type' => 'toggle'
|
378 |
+
)
|
379 |
+
|
380 |
+
) ),
|
381 |
+
'ta_links_settings' => apply_filters( 'ta_links_settings_options' , array(
|
382 |
+
|
383 |
+
array(
|
384 |
+
'id' => 'ta_link_prefix',
|
385 |
+
'title' => __( 'Link Prefix' , 'thirstyaffiliates' ),
|
386 |
+
'desc' => sprintf( __( "The prefix that comes before your cloaked link's slug. <br>eg. %s/<strong>recommends</strong>/your-affiliate-link-name.<br><br><b>Warning :</b> Changing this setting after you've used links in a post could break those links. Be careful!" , 'thirstyaffiliates' ) , home_url() ),
|
387 |
+
'type' => 'select',
|
388 |
+
'default' => 'recommends',
|
389 |
+
'options' => array(
|
390 |
+
'custom' => '-- custom --',
|
391 |
+
'recommends' => 'recommends',
|
392 |
+
'link' => 'link',
|
393 |
+
'go' => 'go',
|
394 |
+
'review' => 'review',
|
395 |
+
'product' => 'product',
|
396 |
+
'suggests' => 'suggests',
|
397 |
+
'follow' => 'follow',
|
398 |
+
'endorses' => 'endorses',
|
399 |
+
'proceed' => 'proceed',
|
400 |
+
'fly' => 'fly',
|
401 |
+
'goto' => 'goto',
|
402 |
+
'get' => 'get',
|
403 |
+
'find' => 'find',
|
404 |
+
'act' => 'act',
|
405 |
+
'click' => 'click',
|
406 |
+
'move' => 'move',
|
407 |
+
'offer' => 'offer',
|
408 |
+
'run' => 'run'
|
409 |
+
)
|
410 |
+
),
|
411 |
+
|
412 |
+
array(
|
413 |
+
'id' => 'ta_link_prefix_custom',
|
414 |
+
'title' => __( 'Custom Link Prefix' , 'thirstyaffiliates' ),
|
415 |
+
'desc' => __( 'Enter your preferred link prefix.' , 'thirstyaffiliates' ),
|
416 |
+
'type' => 'text'
|
417 |
+
),
|
418 |
+
|
419 |
+
array(
|
420 |
+
'id' => 'ta_show_cat_in_slug',
|
421 |
+
'title' => __( 'Link Category in URL?' , 'thirstyaffiliates' ),
|
422 |
+
'desc' => sprintf( __( "Shows the primary selected category in the url. eg. %s/recommends/<strong>link-category</strong>/your-affiliate-link-name.<br><br><b>Warning :</b> Changing this setting after you've used links in a post could break those links. Be careful!" , 'thirstyaffiliates' ) , home_url() ),
|
423 |
+
'type' => 'toggle'
|
424 |
+
),
|
425 |
+
|
426 |
+
array(
|
427 |
+
'id' => 'ta_enable_javascript_frontend_redirect',
|
428 |
+
'title' => __( "Enable Enhanced Javascript Redirect on Frontend" , 'thirstyaffiliates' ),
|
429 |
+
'desc' => __( "By default affiliate links are redirected on the server side. Enabling this will set all affiliate links to be redirected via javascript on your website's frontend. This will then improve the accuracy of the link performance report (This will only work when <strong>Statistics</strong> module is enabled)." , 'thirstyaffiliates' ),
|
430 |
+
'type' => 'toggle',
|
431 |
+
'condition_cb' => function() { return get_option( 'ta_enable_stats_reporting_module' ) === 'yes'; }
|
432 |
+
),
|
433 |
+
|
434 |
+
array(
|
435 |
+
'id' => 'ta_link_redirect_type',
|
436 |
+
'title' => __( 'Link Redirect Type (server side redirects)' , 'thirstyaffiliates' ),
|
437 |
+
'desc' => __( "This is the type of redirect ThirstyAffiliates will use to redirect the user to your affiliate link." , 'thirstyaffiliates' ),
|
438 |
+
'type' => 'radio',
|
439 |
+
'options' => $this->_constants->REDIRECT_TYPES(),
|
440 |
+
'default' => '302'
|
441 |
+
),
|
442 |
+
|
443 |
+
array(
|
444 |
+
'id' => 'ta_no_follow',
|
445 |
+
'title' => __( 'Use no follow on links? (server side redirects)' , 'thirstyaffiliates' ),
|
446 |
+
'desc' => __( "Add the nofollow attribute to links so search engines don't index them." , 'thirstyaffiliates' ),
|
447 |
+
'type' => 'select',
|
448 |
+
'options' => $toggle_cat_options,
|
449 |
+
'default' => 'no',
|
450 |
+
'class' => 'toggle-cat'
|
451 |
+
),
|
452 |
+
|
453 |
+
array(
|
454 |
+
'id' => 'ta_no_follow_category',
|
455 |
+
'title' => __( 'No follow categories (server side redirects)' , 'thirstyaffiliates' ),
|
456 |
+
'desc' => __( "The links assigned to the selected category will be set as \"no follow\"." , 'thirstyaffiliates' ),
|
457 |
+
'type' => 'multiselect',
|
458 |
+
'options' => $all_categories,
|
459 |
+
'default' => array(),
|
460 |
+
'placeholder' => __( 'Select category...' , 'thirstyaffiliates' ),
|
461 |
+
'class' => 'toggle-cat-select toggle-cat-ta_no_follow',
|
462 |
+
'required' => true,
|
463 |
+
),
|
464 |
+
|
465 |
+
array(
|
466 |
+
'id' => 'ta_new_window',
|
467 |
+
'title' => __( 'Open links in new window?' , 'thirstyaffiliates' ),
|
468 |
+
'desc' => __( "Make links open in a new browser tab by default." , 'thirstyaffiliates' ),
|
469 |
+
'type' => 'select',
|
470 |
+
'options' => $toggle_cat_options,
|
471 |
+
'default' => 'no',
|
472 |
+
'class' => 'toggle-cat'
|
473 |
+
),
|
474 |
+
|
475 |
+
array(
|
476 |
+
'id' => 'ta_new_window_category',
|
477 |
+
'title' => __( 'New window categories' , 'thirstyaffiliates' ),
|
478 |
+
'desc' => __( "The links assigned to the selected category will be set as \"new window\"." , 'thirstyaffiliates' ),
|
479 |
+
'type' => 'multiselect',
|
480 |
+
'options' => $all_categories,
|
481 |
+
'default' => array(),
|
482 |
+
'placeholder' => __( 'Select category...' , 'thirstyaffiliates' ),
|
483 |
+
'class' => 'toggle-cat-select toggle-cat-ta_new_window',
|
484 |
+
'required' => true,
|
485 |
+
),
|
486 |
+
|
487 |
+
array(
|
488 |
+
'id' => 'ta_pass_query_str',
|
489 |
+
'title' => __( 'Pass query strings to destination url?' , 'thirstyaffiliates' ),
|
490 |
+
'desc' => __( "Enabling this option will pass all of the query strings present after the cloaked url to the destination url automatically when redirecting." , 'thirstyaffiliates' ),
|
491 |
+
'type' => 'select',
|
492 |
+
'options' => $toggle_cat_options,
|
493 |
+
'default' => 'no',
|
494 |
+
'class' => 'toggle-cat',
|
495 |
+
),
|
496 |
+
|
497 |
+
array(
|
498 |
+
'id' => 'ta_pass_query_str_category',
|
499 |
+
'title' => __( 'Pass query strings categories' , 'thirstyaffiliates' ),
|
500 |
+
'desc' => __( "The links assigned to the selected category will be set as \"pass query strings\"." , 'thirstyaffiliates' ),
|
501 |
+
'type' => 'multiselect',
|
502 |
+
'options' => $all_categories,
|
503 |
+
'default' => array(),
|
504 |
+
'placeholder' => __( 'Select category...' , 'thirstyaffiliates' ),
|
505 |
+
'class' => 'toggle-cat-select toggle-cat-ta_pass_query_str',
|
506 |
+
'required' => true,
|
507 |
+
),
|
508 |
+
|
509 |
+
array(
|
510 |
+
'id' => 'ta_additional_rel_tags',
|
511 |
+
'title' => __( 'Additional rel attribute tags' , 'thirstyaffiliates' ),
|
512 |
+
'desc' => __( "Allows you to add extra tags into the rel= attribute when links are inserted." , 'thirstyaffiliates' ),
|
513 |
+
'type' => 'text'
|
514 |
+
),
|
515 |
+
|
516 |
+
array(
|
517 |
+
'id' => 'ta_additional_css_classes',
|
518 |
+
'title' => __( 'Additional CSS classes' , 'thirstyaffiliates' ),
|
519 |
+
'desc' => __( "Allows you to add extra CSS classes when links are inserted." , 'thirstyaffiliates' ),
|
520 |
+
'type' => 'text'
|
521 |
+
),
|
522 |
+
|
523 |
+
array(
|
524 |
+
'id' => 'ta_disable_thirsty_link_class',
|
525 |
+
'title' => __( 'Disable ThirstyAffiliates CSS classes?' , 'thirstyaffiliates' ),
|
526 |
+
'desc' => __( 'To help with styling a CSS class called "thirstylink" is added links on insertion.<br>Likewise the "thirstylinkimg" class is added to images when using the image insertion type. This option disables the addition these CSS classes.' , 'thirstyaffiliates' ),
|
527 |
+
'type' => 'toggle'
|
528 |
+
),
|
529 |
+
|
530 |
+
array(
|
531 |
+
'id' => 'ta_disable_title_attribute',
|
532 |
+
'title' => __( 'Disable title attribute on link insertion?' , 'thirstyaffiliates' ),
|
533 |
+
'desc' => __( "Links are automatically output with a title html attribute (by default this shows the title of the affiliate link).<br>This option disables the output of the title attribute on your links." , 'thirstyaffiliates' ),
|
534 |
+
'type' => 'toggle'
|
535 |
+
),
|
536 |
+
|
537 |
+
array(
|
538 |
+
'id' => 'ta_category_to_uncloak',
|
539 |
+
'title' => __( 'Select Category to Uncloak' , 'thirstyaffiliates' ),
|
540 |
+
'desc' => __( "The links assigned to the selected category will be uncloaked." , 'thirstyaffiliates' ),
|
541 |
+
'type' => 'multiselect',
|
542 |
+
'options' => $all_categories,
|
543 |
+
'default' => array(),
|
544 |
+
'condition_cb' => function() { return get_option( 'ta_uncloak_link_per_link' ) === 'yes'; },
|
545 |
+
'placeholder' => __( 'Select category...' , 'thirstyaffiliates' )
|
546 |
+
)
|
547 |
+
|
548 |
+
) ),
|
549 |
+
|
550 |
+
'ta_modules_settings' => apply_filters( 'ta_modules_settings_options' , array(
|
551 |
+
|
552 |
+
array(
|
553 |
+
'id' => 'ta_enable_stats_reporting_module',
|
554 |
+
'title' => __( 'Statistics' , 'thirstyaffiliates' ),
|
555 |
+
'desc' => __( "When enabled, ThirstyAffiliates will collect click statistics information about visitors that click on your affiliate links. Also adds a new Reports section." , 'thirstyaffiliates' ),
|
556 |
+
'type' => 'toggle',
|
557 |
+
'default' => 'yes'
|
558 |
+
),
|
559 |
+
|
560 |
+
array(
|
561 |
+
'id' => 'ta_enable_link_fixer',
|
562 |
+
'title' => __( 'Link Fixer' , 'thirstyaffiliates' ),
|
563 |
+
'desc' => __( "Link Fixer is a tiny piece of javascript code that runs on the frontend of your site to fix any outdated/broken affiliate links it detects. It's cache-friendly and runs after page load so it doesn't affect the rendering of content. Changed the settings on your site recently? Enabling Link Fixer means you don't need to update all your previously inserted affiliate links one by one – your visitors will never see an out of date affiliate link again." , 'thirstyaffiliates' ),
|
564 |
+
'type' => 'toggle',
|
565 |
+
'default' => 'yes',
|
566 |
+
),
|
567 |
+
|
568 |
+
array(
|
569 |
+
'id' => 'ta_uncloak_link_per_link',
|
570 |
+
'title' => __( 'Uncloak Links' , 'thirstyaffiliates' ),
|
571 |
+
'desc' => __( "Uncloak Links is a feature to allow uncloaking of specific links on your site. It replaces the cloaked url with the actual destination url which is important for compatibility with some affiliate program with stricter terms (such as Amazon Associates). Once enabled, you will see a new Uncloak Link checkbox on the affiliate link edit screen. It also introduces a new setting under the Links tab for uncloaking whole categories.<br><br><b>Warning : </b>For this feature to work, the <strong>Link Fixer</strong> module needs to be turned on." , 'thirstyaffiliates' ),
|
572 |
+
'type' => 'toggle',
|
573 |
+
'default' => 'no',
|
574 |
+
)
|
575 |
+
|
576 |
+
) ),
|
577 |
+
'ta_import_export_settings' => apply_filters( 'ta_import_export_settings_options' , array(
|
578 |
+
|
579 |
+
array(
|
580 |
+
'id' => 'ta_import_settings',
|
581 |
+
'title' => __( 'Import Global Settings' , 'thirstyaffiliates' ),
|
582 |
+
'type' => 'import_global_settings',
|
583 |
+
'placeholder' => __( 'Paste settings string here...' , 'thirstyaffiliates' )
|
584 |
+
),
|
585 |
+
|
586 |
+
array(
|
587 |
+
'id' => 'ta_export_settings',
|
588 |
+
'title' => __( 'Export Global Settings' , 'thirstyaffiliates' ),
|
589 |
+
'type' => 'export_global_settings'
|
590 |
+
)
|
591 |
+
|
592 |
+
) ),
|
593 |
+
'ta_help_settings' => apply_filters( 'ta_help_settings_options' , array(
|
594 |
+
|
595 |
+
array(
|
596 |
+
'id' => 'ta_knowledge_base_divider', // Even though no option is really saved, we still add id, for the purpose of later when extending this section options, they can search for this specific section divider during array loop
|
597 |
+
'title' => __( 'Knowledge Base' , 'thirstyaffiliates' ),
|
598 |
+
'type' => 'option_divider'
|
599 |
+
),
|
600 |
+
|
601 |
+
array(
|
602 |
+
'title' => __( 'Documentation' , 'thirstyaffiliates' ),
|
603 |
+
'type' => 'link',
|
604 |
+
'link_url' => 'https://thirstyaffiliates.com/knowledge-base/?utm_source=Free%20Plugin&utm_medium=Help&utm_campaign=Knowledge%20Base%20Link',
|
605 |
+
'link_text' => __( 'Knowledge Base' , 'thirstyaffiliates' ),
|
606 |
+
'desc' => __( 'Guides, troubleshooting, FAQ and more.' , 'thirstyaffiliates' ),
|
607 |
+
'id' => 'ta_kb_link',
|
608 |
+
),
|
609 |
+
|
610 |
+
array(
|
611 |
+
'title' => __( 'Our Blog' , 'thirstyaffiliates' ),
|
612 |
+
'type' => 'link',
|
613 |
+
'link_url' => 'https://thirstyaffiliates.com/blog?utm_source=Free%20Plugin&utm_medium=Help&utm_campaign=Blog%20Link',
|
614 |
+
'link_text' => __( 'ThirstyAffiliates Blog' , 'thirstyaffiliates' ),
|
615 |
+
'desc' => __( 'Learn & grow your affiliate marketing – covering increasing sales, generating traffic, optimising your affiliate marketing, interviews & case studies.' , 'thirstyaffiliates' ),
|
616 |
+
'id' => 'ta_blog_link',
|
617 |
+
),
|
618 |
+
|
619 |
+
array(
|
620 |
+
'title' => __( 'Join the Community' , 'thirstyaffiliates' ),
|
621 |
+
'type' => 'social_links',
|
622 |
+
'id' => 'ta_social_links'
|
623 |
+
),
|
624 |
+
|
625 |
+
array(
|
626 |
+
'id' => 'ta_other_utilities_divider', // Even though no option is really saved, we still add id, for the purpose of later when extending this section options, they can search for this specific section divider during array loop
|
627 |
+
'title' => __( 'Other Utilities' , 'thirstyaffiliates' ),
|
628 |
+
'type' => 'option_divider'
|
629 |
+
),
|
630 |
+
|
631 |
+
array(
|
632 |
+
'title' => __( 'Migrate Old Data' , 'thirstyaffiliates' ),
|
633 |
+
'type' => 'migration_controls',
|
634 |
+
'desc' => __( 'Migrate old ThirstyAffiliates version 2 data to new version 3 data model.' , 'thirstyaffiliates' ),
|
635 |
+
'id' => 'ta_migrate_old_data'
|
636 |
+
)
|
637 |
+
|
638 |
+
) )
|
639 |
+
|
640 |
+
) );
|
641 |
+
|
642 |
+
// Get all the exportable options
|
643 |
+
foreach ( $this->_settings_section_options as $section_id => $section_options ) {
|
644 |
+
|
645 |
+
foreach ( $section_options as $option ) {
|
646 |
+
|
647 |
+
if ( in_array( $option[ 'type' ] , $this->_skip_wp_settings_registration ) )
|
648 |
+
continue;
|
649 |
+
|
650 |
+
$this->_exportable_options[ $option[ 'id' ] ] = isset( $option[ 'default' ] ) ? $option[ 'default' ] : '';
|
651 |
+
|
652 |
+
if ( isset( $option[ 'post_update_cb' ] ) && is_callable( $option[ 'post_update_cb' ] ) )
|
653 |
+
add_action( 'update_option_' . $option[ 'id' ] , $option[ 'post_update_cb' ] , 10 , 3 );
|
654 |
+
|
655 |
+
}
|
656 |
+
|
657 |
+
}
|
658 |
+
|
659 |
+
}
|
660 |
+
|
661 |
+
/**
|
662 |
+
* Register Settings Section and Options Group to WordPress Settings API.
|
663 |
+
*
|
664 |
+
* @since 3.0.0
|
665 |
+
* @access public
|
666 |
+
*/
|
667 |
+
public function register_settings_section_and_options_group() {
|
668 |
+
|
669 |
+
foreach ( $this->_settings_sections as $section_id => $section_data ) {
|
670 |
+
|
671 |
+
add_settings_section(
|
672 |
+
$section_id, // Settings Section ID
|
673 |
+
$section_data[ 'title' ], // Settings Section Title
|
674 |
+
function() {}, // Callback. Intentionally Left Empty. We Will Handle UI Rendering.
|
675 |
+
$section_id . '_options_group' // Options Group
|
676 |
+
);
|
677 |
+
|
678 |
+
}
|
679 |
+
|
680 |
+
}
|
681 |
+
|
682 |
+
/**
|
683 |
+
* Register Settings Section Options to WordPress Settings API.
|
684 |
+
*
|
685 |
+
* @since 3.0.0
|
686 |
+
* @access public
|
687 |
+
*/
|
688 |
+
public function register_settings_section_options() {
|
689 |
+
|
690 |
+
foreach ( $this->_settings_section_options as $section_id => $section_options ) {
|
691 |
+
|
692 |
+
foreach ( $section_options as $option ) {
|
693 |
+
|
694 |
+
if ( !array_key_exists( $option[ 'type' ] , $this->_supported_field_types ) || in_array( $option[ 'type' ] , $this->_skip_wp_settings_registration ) )
|
695 |
+
continue;
|
696 |
+
|
697 |
+
// Register The Option To The Options Group It Is Scoped With
|
698 |
+
add_settings_field(
|
699 |
+
$option[ 'id' ], // Option ID
|
700 |
+
$option[ 'title' ], // Option Title
|
701 |
+
function() {}, // Render Callback. Intentionally Left Empty. We Will Handle UI Rendering.
|
702 |
+
$section_id . '_options_group', // Options Group
|
703 |
+
$section_id // Settings Section ID
|
704 |
+
);
|
705 |
+
|
706 |
+
// Register The Actual Settings Option
|
707 |
+
$args = array();
|
708 |
+
|
709 |
+
if ( isset( $option[ 'data_type' ] ) )
|
710 |
+
$args[ 'type' ] = $option[ 'data_type' ];
|
711 |
+
|
712 |
+
if ( isset( $option[ 'desc' ] ) )
|
713 |
+
$args[ 'description' ] = $option[ 'desc' ];
|
714 |
+
|
715 |
+
if ( isset( $option[ 'sanitation_cb' ] ) && is_callable( $option[ 'sanitation_cb' ] ) )
|
716 |
+
$args[ 'sanitize_callback' ] = $option[ 'sanitation_cb' ];
|
717 |
+
|
718 |
+
if ( isset( $option[ 'show_in_rest' ] ) )
|
719 |
+
$args[ 'show_in_rest' ] = $option[ 'show_in_rest' ];
|
720 |
+
|
721 |
+
if ( isset( $option[ 'default' ] ) )
|
722 |
+
$args[ 'default' ] = $option[ 'default' ]; // Important Note: This will be used on "get_option" function automatically if the current option is not registered yet to the options db.
|
723 |
+
|
724 |
+
register_setting( $section_id . '_options_group' , $option[ 'id' ] , $args );
|
725 |
+
|
726 |
+
}
|
727 |
+
|
728 |
+
}
|
729 |
+
|
730 |
+
}
|
731 |
+
|
732 |
+
/**
|
733 |
+
* Initialize Plugin Settings API.
|
734 |
+
* We register the plugin settings section and settings section options to WordPress Settings API.
|
735 |
+
* We let WordPress Settings API handle the backend stuff.
|
736 |
+
* We will handle the UI rendering.
|
737 |
+
*
|
738 |
+
* @since 3.0.0
|
739 |
+
* @access public
|
740 |
+
*/
|
741 |
+
public function init_plugin_settings() {
|
742 |
+
|
743 |
+
$this->init_settings_sections_and_options();
|
744 |
+
$this->register_settings_section_and_options_group();
|
745 |
+
$this->register_settings_section_options();
|
746 |
+
|
747 |
+
}
|
748 |
+
|
749 |
+
/**
|
750 |
+
* Add settings page.
|
751 |
+
*
|
752 |
+
* @since 3.0.0
|
753 |
+
* @since 3.2.2 Access to the settings page will now be controlled by the plugin. see Bootstrap::admin_interface_visibility.
|
754 |
+
* @access public
|
755 |
+
*/
|
756 |
+
public function add_settings_page() {
|
757 |
+
|
758 |
+
if ( ! current_user_can( 'edit_posts' ) ) return;
|
759 |
+
|
760 |
+
add_submenu_page(
|
761 |
+
'edit.php?post_type=thirstylink',
|
762 |
+
__( 'ThirstyAffiliates Settings' , 'thirstyaffiliates' ),
|
763 |
+
__( 'Settings' , 'thirstyaffiliates' ),
|
764 |
+
'read',
|
765 |
+
'thirsty-settings',
|
766 |
+
array( $this, 'view_settings_page' )
|
767 |
+
);
|
768 |
+
|
769 |
+
}
|
770 |
+
|
771 |
+
/**
|
772 |
+
* Settings page view.
|
773 |
+
*
|
774 |
+
* @since 3.0.0
|
775 |
+
* @since 3.3.1 Add a new <div> to wrap the side navigation and form. Add additional action hooks.
|
776 |
+
* @access public
|
777 |
+
*/
|
778 |
+
public function view_settings_page() {
|
779 |
+
?>
|
780 |
+
|
781 |
+
<div class="wrap ta-settings">
|
782 |
+
|
783 |
+
<h2><?php _e( 'ThirstyAffiliates Settings' , 'thirstyaffiliates' ); ?></h2>
|
784 |
+
|
785 |
+
<?php
|
786 |
+
settings_errors(); // Show notices based on the outcome of the settings save action
|
787 |
+
$active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'ta_general_settings';
|
788 |
+
?>
|
789 |
+
|
790 |
+
<div class="ta-settings-wrapper">
|
791 |
+
|
792 |
+
<?php do_action( 'ta_before_settings_sidenav' ); ?>
|
793 |
+
|
794 |
+
<h2 class="nav-tab-wrapper">
|
795 |
+
<?php foreach ( $this->_settings_sections as $section_key => $section_data ) { ?>
|
796 |
+
<a href="?post_type=thirstylink&page=thirsty-settings&tab=<?php echo $section_key; ?>" class="nav-tab <?php echo $active_tab == $section_key ? 'nav-tab-active' : ''; ?> <?php echo $section_key; ?>"><?php echo $section_data[ 'title' ]; ?></a>
|
797 |
+
<?php } ?>
|
798 |
+
|
799 |
+
<?php if ( ! $this->_helper_functions->is_plugin_active( 'thirstyaffiliates-pro/thirstyaffiliates-pro.php' ) ) : ?>
|
800 |
+
<a class="tapro-upgrade nav-tab" href="https://thirstyaffiliates.com/pricing/?utm_source=Free%20Plugin&utm_medium=Pro&utm_campaign=Admin%20Settings" target="_blank"><?php _e( 'Pro Features →' , 'thirstyaffiliates' ); ?></a>
|
801 |
+
<?php endif; ?>
|
802 |
+
</h2>
|
803 |
+
|
804 |
+
<?php do_action( 'ta_before_settings_form' ); ?>
|
805 |
+
|
806 |
+
<div class="ta-settings-form">
|
807 |
+
|
808 |
+
<form method="post" action="options.php" enctype="multipart/form-data">
|
809 |
+
|
810 |
+
<?php
|
811 |
+
$this->render_settings_section_nonces( $active_tab );
|
812 |
+
$this->render_settings_section_header( $active_tab );
|
813 |
+
$this->render_settings_section_fields( $active_tab );
|
814 |
+
?>
|
815 |
+
|
816 |
+
</form>
|
817 |
+
</div>
|
818 |
+
|
819 |
+
<?php do_action( 'ta_after_settings_form' ); ?>
|
820 |
+
|
821 |
+
</div>
|
822 |
+
|
823 |
+
</div><!--wrap-->
|
824 |
+
|
825 |
+
<?php
|
826 |
+
}
|
827 |
+
|
828 |
+
/**
|
829 |
+
* Render all necessary nonces for the current settings section.
|
830 |
+
*
|
831 |
+
* @since 3.0.0
|
832 |
+
* @access public
|
833 |
+
*
|
834 |
+
* @param string $active_tab Currently active settings section.
|
835 |
+
*/
|
836 |
+
public function render_settings_section_nonces( $active_tab ) {
|
837 |
+
|
838 |
+
settings_fields( $active_tab . '_options_group' );
|
839 |
+
|
840 |
+
}
|
841 |
+
|
842 |
+
/**
|
843 |
+
* Render the current settings section header markup.
|
844 |
+
*
|
845 |
+
* @since 3.0.0
|
846 |
+
* @access public
|
847 |
+
*
|
848 |
+
* @param string $active_tab Currently active settings section.
|
849 |
+
*/
|
850 |
+
public function render_settings_section_header( $active_tab ) {
|
851 |
+
|
852 |
+
if ( ! isset( $this->_settings_sections[ $active_tab ] ) )
|
853 |
+
return;
|
854 |
+
|
855 |
+
?>
|
856 |
+
|
857 |
+
<h2><?php echo $this->_settings_sections[ $active_tab ][ 'title' ]; ?></h2>
|
858 |
+
<p class="desc"><?php echo $this->_settings_sections[ $active_tab ][ 'desc' ]; ?></p>
|
859 |
+
|
860 |
+
<?php
|
861 |
+
|
862 |
+
}
|
863 |
+
|
864 |
+
/**
|
865 |
+
* Render an option as a hidden field.
|
866 |
+
* We do this if that option's condition callback failed.
|
867 |
+
* We don't show it for the end user, but we still need to pass on the form the current data so we don't lost it.
|
868 |
+
*
|
869 |
+
* @since 3.0.0
|
870 |
+
* @access public
|
871 |
+
*
|
872 |
+
* @param array $option Array of options data. May vary depending on option type.
|
873 |
+
*/
|
874 |
+
public function render_option_as_hidden_field( $option ) {
|
875 |
+
|
876 |
+
if ( in_array( $option[ 'type' ] , $this->_skip_wp_settings_registration ) )
|
877 |
+
return; // This is a decorative option type, no need to render this as a hidden field
|
878 |
+
|
879 |
+
?>
|
880 |
+
|
881 |
+
<input type="hidden" name="<?php echo esc_attr( $option[ 'id' ] ); ?>" value="<?php echo get_option( $option[ 'id' ] , '' ); ?>">
|
882 |
+
|
883 |
+
<?php
|
884 |
+
|
885 |
+
}
|
886 |
+
|
887 |
+
/**
|
888 |
+
* Render settings section option fields.
|
889 |
+
*
|
890 |
+
* @since 3.0.0
|
891 |
+
* @access public
|
892 |
+
*
|
893 |
+
* @param string $active_tab Currently active settings section.
|
894 |
+
*/
|
895 |
+
public function render_settings_section_fields( $active_tab ) {
|
896 |
+
|
897 |
+
$no_save_sections = apply_filters( 'ta_render_settings_no_save_section' , array(
|
898 |
+
'ta_import_export_settings'
|
899 |
+
) );
|
900 |
+
?>
|
901 |
+
|
902 |
+
<table class="form-table">
|
903 |
+
<tbody>
|
904 |
+
<?php
|
905 |
+
foreach ( $this->_settings_section_options as $section_id => $section_options ) {
|
906 |
+
|
907 |
+
if ( $section_id !== $active_tab )
|
908 |
+
continue;
|
909 |
+
|
910 |
+
foreach ( $section_options as $option ) {
|
911 |
+
|
912 |
+
if ( isset( $option[ 'condition_cb' ] ) && is_callable( $option[ 'condition_cb' ] ) && !$option[ 'condition_cb' ]() )
|
913 |
+
$this->render_option_as_hidden_field( $option ); // Option condition failed. Render it as a hidden field so its value is preserved
|
914 |
+
else
|
915 |
+
$this->_supported_field_types[ $option[ 'type' ] ]( $option );
|
916 |
+
|
917 |
+
}
|
918 |
+
|
919 |
+
}
|
920 |
+
?>
|
921 |
+
</tbody>
|
922 |
+
</table>
|
923 |
+
|
924 |
+
<?php if ( ! in_array( $active_tab , $no_save_sections ) ) : ?>
|
925 |
+
<p class="submit">
|
926 |
+
<input name="submit" id="submit" class="button button-primary" value="<?php _e( 'Save Changes' , 'thirstyaffiliates' ); ?>" type="submit">
|
927 |
+
</p>
|
928 |
+
<?php endif;
|
929 |
+
|
930 |
+
}
|
931 |
+
|
932 |
+
|
933 |
+
|
934 |
+
|
935 |
+
/*
|
936 |
+
|--------------------------------------------------------------------------
|
937 |
+
| Option Field Views
|
938 |
+
|--------------------------------------------------------------------------
|
939 |
+
*/
|
940 |
+
|
941 |
+
/**
|
942 |
+
* Render 'text' type option field.
|
943 |
+
*
|
944 |
+
* @since 3.0.0
|
945 |
+
* @access public
|
946 |
+
*
|
947 |
+
* @param array $option Array of options data. May vary depending on option type.
|
948 |
+
*/
|
949 |
+
public function render_text_option_field( $option ) {
|
950 |
+
|
951 |
+
?>
|
952 |
+
|
953 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
954 |
+
|
955 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
956 |
+
|
957 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
958 |
+
<input
|
959 |
+
type = "text"
|
960 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
961 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
962 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
963 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : 'width: 360px;'; ?>"
|
964 |
+
value = "<?php echo get_option( $option[ 'id' ] ); ?>" >
|
965 |
+
<br>
|
966 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
967 |
+
</td>
|
968 |
+
|
969 |
+
</tr>
|
970 |
+
|
971 |
+
<?php
|
972 |
+
|
973 |
+
}
|
974 |
+
|
975 |
+
/**
|
976 |
+
* Render 'url' type option field.
|
977 |
+
*
|
978 |
+
* @since 3.3.1
|
979 |
+
* @access public
|
980 |
+
*
|
981 |
+
* @param array $option Array of options data. May vary depending on option type.
|
982 |
+
*/
|
983 |
+
public function render_url_option_field( $option ) {
|
984 |
+
|
985 |
+
?>
|
986 |
+
|
987 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
988 |
+
|
989 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
990 |
+
|
991 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
992 |
+
<input
|
993 |
+
type = "url"
|
994 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
995 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
996 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
997 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : 'width: 360px;'; ?>"
|
998 |
+
value = "<?php echo get_option( $option[ 'id' ] ); ?>" >
|
999 |
+
<br>
|
1000 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1001 |
+
</td>
|
1002 |
+
|
1003 |
+
</tr>
|
1004 |
+
|
1005 |
+
<?php
|
1006 |
+
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
/**
|
1010 |
+
* Render 'text' type option field.
|
1011 |
+
*
|
1012 |
+
* @since 3.0.0
|
1013 |
+
* @access public
|
1014 |
+
*
|
1015 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1016 |
+
*/
|
1017 |
+
public function render_number_option_field( $option ) {
|
1018 |
+
|
1019 |
+
?>
|
1020 |
+
|
1021 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1022 |
+
|
1023 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1024 |
+
|
1025 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1026 |
+
<input
|
1027 |
+
type = "number"
|
1028 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1029 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1030 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1031 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : 'width: 100px;'; ?>"
|
1032 |
+
value = "<?php echo get_option( $option[ 'id' ] ); ?>"
|
1033 |
+
min = "<?php echo isset( $option[ 'min' ] ) ? $option[ 'min' ] : 0; ?>"
|
1034 |
+
max = "<?php echo isset( $option[ 'max' ] ) ? $option[ 'max' ] : ''; ?>" >
|
1035 |
+
<span><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></span>
|
1036 |
+
</td>
|
1037 |
+
|
1038 |
+
</tr>
|
1039 |
+
|
1040 |
+
<?php
|
1041 |
+
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
/**
|
1045 |
+
* Render 'textarea' type option field.
|
1046 |
+
*
|
1047 |
+
* @since 3.0.0
|
1048 |
+
* @access public
|
1049 |
+
*
|
1050 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1051 |
+
*/
|
1052 |
+
public function render_textarea_option_field( $option ) {
|
1053 |
+
|
1054 |
+
?>
|
1055 |
+
|
1056 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1057 |
+
|
1058 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1059 |
+
|
1060 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1061 |
+
<textarea
|
1062 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1063 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1064 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1065 |
+
cols = "60"
|
1066 |
+
rows = "8"
|
1067 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : 'width: 360px;'; ?>"><?php echo get_option( $option[ 'id' ] ); ?></textarea>
|
1068 |
+
<br />
|
1069 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1070 |
+
</td>
|
1071 |
+
|
1072 |
+
</tr>
|
1073 |
+
|
1074 |
+
<?php
|
1075 |
+
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
/**
|
1079 |
+
* Render 'checkbox' type option field.
|
1080 |
+
*
|
1081 |
+
* @since 3.0.0
|
1082 |
+
* @access public
|
1083 |
+
*
|
1084 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1085 |
+
*/
|
1086 |
+
public function render_checkbox_option_field( $option ) {
|
1087 |
+
|
1088 |
+
$option_val = get_option( $option[ 'id' ] );
|
1089 |
+
if ( !is_array( $option_val ) )
|
1090 |
+
$option_val = array(); ?>
|
1091 |
+
|
1092 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1093 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1094 |
+
|
1095 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1096 |
+
<?php foreach ( $option[ 'options' ] as $opt_key => $opt_text ) {
|
1097 |
+
|
1098 |
+
$opt_key_class = str_replace( " " , "-" , $opt_key ); ?>
|
1099 |
+
|
1100 |
+
<input
|
1101 |
+
type = "checkbox"
|
1102 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>[]"
|
1103 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1104 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1105 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : ''; ?>"
|
1106 |
+
value = "<?php echo $opt_key; ?>"
|
1107 |
+
<?php echo in_array( $opt_key , $option_val ) ? 'checked' : ''; ?>>
|
1108 |
+
|
1109 |
+
<label class="<?php echo esc_attr( $option[ 'id' ] ); ?>"><?php echo $opt_text; ?></label>
|
1110 |
+
<br>
|
1111 |
+
|
1112 |
+
<?php } ?>
|
1113 |
+
|
1114 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1115 |
+
</td>
|
1116 |
+
|
1117 |
+
<script>
|
1118 |
+
jQuery( document ).ready( function( $ ) {
|
1119 |
+
|
1120 |
+
$( "label.<?php echo esc_attr( $option[ 'id' ] ); ?>" ).on( "click" , function() {
|
1121 |
+
|
1122 |
+
$( this ).prev( "input[type='checkbox']" ).trigger( "click" );
|
1123 |
+
|
1124 |
+
} );
|
1125 |
+
|
1126 |
+
} );
|
1127 |
+
</script>
|
1128 |
+
</tr>
|
1129 |
+
|
1130 |
+
<?php
|
1131 |
+
|
1132 |
+
}
|
1133 |
+
|
1134 |
+
/**
|
1135 |
+
* Render 'radio' type option field.
|
1136 |
+
*
|
1137 |
+
* @since 3.0.0
|
1138 |
+
* @access public
|
1139 |
+
*
|
1140 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1141 |
+
*/
|
1142 |
+
public function render_radio_option_field( $option ) {
|
1143 |
+
|
1144 |
+
$option_val = get_option( $option[ 'id' ] ); ?>
|
1145 |
+
|
1146 |
+
|
1147 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1148 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1149 |
+
|
1150 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1151 |
+
<?php foreach ( $option[ 'options' ] as $opt_key => $opt_text ) { ?>
|
1152 |
+
|
1153 |
+
<input
|
1154 |
+
type = "radio"
|
1155 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1156 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1157 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1158 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : ''; ?>"
|
1159 |
+
value = "<?php echo $opt_key; ?>"
|
1160 |
+
<?php echo $opt_key == $option_val ? 'checked' : ''; ?>>
|
1161 |
+
|
1162 |
+
<label class="<?php echo esc_attr( $option[ 'id' ] ); ?>"><?php echo $opt_text; ?></label>
|
1163 |
+
<br>
|
1164 |
+
|
1165 |
+
<?php } ?>
|
1166 |
+
|
1167 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1168 |
+
</td>
|
1169 |
+
|
1170 |
+
<script>
|
1171 |
+
jQuery( document ).ready( function( $ ) {
|
1172 |
+
|
1173 |
+
$( "label.<?php echo esc_attr( $option[ 'id' ] ); ?>" ).on( "click" , function() {
|
1174 |
+
|
1175 |
+
$( this ).prev( "input[type='radio']" ).trigger( "click" );
|
1176 |
+
|
1177 |
+
} );
|
1178 |
+
|
1179 |
+
} );
|
1180 |
+
</script>
|
1181 |
+
</tr>
|
1182 |
+
|
1183 |
+
<?php
|
1184 |
+
|
1185 |
+
}
|
1186 |
+
|
1187 |
+
/**
|
1188 |
+
* Render 'select' type option field.
|
1189 |
+
*
|
1190 |
+
* @since 3.0.0
|
1191 |
+
* @access public
|
1192 |
+
*
|
1193 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1194 |
+
*/
|
1195 |
+
public function render_select_option_field( $option ) {
|
1196 |
+
|
1197 |
+
$option_value = $this->_helper_functions->get_option( $option[ 'id' ] , $option[ 'default' ] ); ?>
|
1198 |
+
|
1199 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1200 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1201 |
+
|
1202 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?> <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>">
|
1203 |
+
<select
|
1204 |
+
data-placeholder = "<?php echo isset( $option[ 'placeholder' ] ) ? $option[ 'placeholder' ] : 'Choose an option...' ; ?>"
|
1205 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1206 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1207 |
+
class = "option-field selectize-select <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1208 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : 'width:360px;'; ?>">
|
1209 |
+
|
1210 |
+
<?php foreach ( $option[ 'options' ] as $opt_key => $opt_text ) { ?>
|
1211 |
+
|
1212 |
+
<option value="<?php echo $opt_key; ?>" <?php selected( $option_value , $opt_key ); ?>><?php echo $opt_text; ?></option>
|
1213 |
+
|
1214 |
+
<?php } ?>
|
1215 |
+
</select>
|
1216 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1217 |
+
</td>
|
1218 |
+
|
1219 |
+
<script>
|
1220 |
+
jQuery( document ).ready( function( $ ) {
|
1221 |
+
|
1222 |
+
$( '#<?php echo esc_attr( $option[ 'id' ] ); ?>' ).selectize({
|
1223 |
+
searchField : 'text'
|
1224 |
+
});
|
1225 |
+
|
1226 |
+
} );
|
1227 |
+
</script>
|
1228 |
+
</tr>
|
1229 |
+
|
1230 |
+
<?php
|
1231 |
+
|
1232 |
+
}
|
1233 |
+
|
1234 |
+
/**
|
1235 |
+
* Render 'multiselect' type option field.
|
1236 |
+
*
|
1237 |
+
* @since 3.0.0
|
1238 |
+
* @access public
|
1239 |
+
*
|
1240 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1241 |
+
*/
|
1242 |
+
public function render_multiselect_option_field( $option ) {
|
1243 |
+
|
1244 |
+
$option_val = get_option( $option[ 'id' ] );
|
1245 |
+
if ( !is_array( $option_val ) )
|
1246 |
+
$option_val = array(); ?>
|
1247 |
+
|
1248 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1249 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1250 |
+
|
1251 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1252 |
+
<select
|
1253 |
+
multiple
|
1254 |
+
data-placeholder = "<?php echo isset( $option[ 'placeholder' ] ) ? $option[ 'placeholder' ] : 'Choose an option...' ; ?>"
|
1255 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>[]"
|
1256 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1257 |
+
class = "option-field selectize-select <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1258 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : 'width:360px;'; ?>"
|
1259 |
+
<?php echo isset( $option[ 'required' ] ) && $option[ 'required' ] ? 'required' : '' ?>>
|
1260 |
+
|
1261 |
+
<?php foreach ( $option[ 'options' ] as $opt_key => $opt_text ) { ?>
|
1262 |
+
|
1263 |
+
<option value="<?php echo $opt_key; ?>" <?php echo in_array( $opt_key , $option_val ) ? 'selected="selected"' : ''; ?>><?php echo $opt_text; ?></option>
|
1264 |
+
|
1265 |
+
<?php } ?>
|
1266 |
+
</select>
|
1267 |
+
<br>
|
1268 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1269 |
+
</td>
|
1270 |
+
|
1271 |
+
<script>
|
1272 |
+
jQuery( document ).ready( function( $ ) {
|
1273 |
+
|
1274 |
+
$( '#<?php echo esc_attr( $option[ 'id' ] ); ?>' ).selectize({
|
1275 |
+
plugins : [ 'remove_button' , 'drag_drop' ]
|
1276 |
+
});
|
1277 |
+
|
1278 |
+
} );
|
1279 |
+
</script>
|
1280 |
+
</tr>
|
1281 |
+
|
1282 |
+
<?php
|
1283 |
+
|
1284 |
+
}
|
1285 |
+
|
1286 |
+
/**
|
1287 |
+
* Render 'toggle' type option field.
|
1288 |
+
* Basically a single check box style option field.
|
1289 |
+
*
|
1290 |
+
* @since 3.0.0
|
1291 |
+
* @access public
|
1292 |
+
*
|
1293 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1294 |
+
*/
|
1295 |
+
public function render_toggle_option_field( $option ) {
|
1296 |
+
|
1297 |
+
?>
|
1298 |
+
|
1299 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1300 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1301 |
+
|
1302 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1303 |
+
<input
|
1304 |
+
type = "checkbox"
|
1305 |
+
name = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1306 |
+
id = "<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1307 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1308 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : ''; ?>"
|
1309 |
+
value = "yes"
|
1310 |
+
<?php echo get_option( $option[ 'id' ] ) === "yes" ? 'checked' : ''; ?>>
|
1311 |
+
<label class="<?php echo esc_attr( $option[ 'id' ] ); ?>"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></label>
|
1312 |
+
</td>
|
1313 |
+
|
1314 |
+
<script>
|
1315 |
+
jQuery( document ).ready( function( $ ) {
|
1316 |
+
|
1317 |
+
$( "label.<?php echo esc_attr( $option[ 'id' ] ); ?>" ).on( "click" , function() {
|
1318 |
+
|
1319 |
+
$( this ).prev( "input[type='checkbox']" ).trigger( "click" );
|
1320 |
+
|
1321 |
+
} );
|
1322 |
+
|
1323 |
+
} );
|
1324 |
+
</script>
|
1325 |
+
</tr>
|
1326 |
+
|
1327 |
+
<?php
|
1328 |
+
|
1329 |
+
}
|
1330 |
+
|
1331 |
+
/**
|
1332 |
+
* Render 'editor' type option field.
|
1333 |
+
*
|
1334 |
+
* @since 3.0.0
|
1335 |
+
* @access public
|
1336 |
+
*
|
1337 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1338 |
+
*/
|
1339 |
+
public function render_editor_option_field( $option ) {
|
1340 |
+
|
1341 |
+
$editor_value = html_entity_decode( get_option( $option[ 'id' ] ) ); ?>
|
1342 |
+
|
1343 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1344 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1345 |
+
|
1346 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1347 |
+
<style type="text/css"><?php echo "div#wp-" . $option[ 'id' ] . "-wrap{ width: 70% !important; }"; ?></style>
|
1348 |
+
|
1349 |
+
<?php wp_editor( $editor_value , $option[ 'id' ] , array(
|
1350 |
+
'wpautop' => true,
|
1351 |
+
'textarea_name' => $option[ 'id' ],
|
1352 |
+
'editor_height' => '300'
|
1353 |
+
) ); ?>
|
1354 |
+
<br>
|
1355 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1356 |
+
</td>
|
1357 |
+
</tr>
|
1358 |
+
|
1359 |
+
<?php
|
1360 |
+
|
1361 |
+
}
|
1362 |
+
|
1363 |
+
/**
|
1364 |
+
* Render 'csv' type option field.
|
1365 |
+
*
|
1366 |
+
* @since 3.0.0
|
1367 |
+
* @access public
|
1368 |
+
*
|
1369 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1370 |
+
*/
|
1371 |
+
public function render_csv_option_field( $option ) {
|
1372 |
+
|
1373 |
+
?>
|
1374 |
+
|
1375 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1376 |
+
<th scope="row"><?php echo $option[ 'title' ]; ?></th>
|
1377 |
+
|
1378 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1379 |
+
<input
|
1380 |
+
type = "text"
|
1381 |
+
name = "<?php echo $option[ 'id' ]; ?>"
|
1382 |
+
id = "<?php echo $option[ 'id' ]; ?>"
|
1383 |
+
class = "option-field <?php echo isset( $option[ 'class' ] ) ? $option[ 'class' ] : ''; ?>"
|
1384 |
+
style = "<?php echo isset( $option[ 'style' ] ) ? $option[ 'style' ] : 'width: 360px;'; ?>"
|
1385 |
+
value = "<?php echo get_option( $option[ 'id' ] ); ?>" >
|
1386 |
+
<br>
|
1387 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1388 |
+
</td>
|
1389 |
+
|
1390 |
+
<script>
|
1391 |
+
jQuery( document ).ready( function( $ ) {
|
1392 |
+
|
1393 |
+
$( '#<?php echo $option[ 'id' ]; ?>' ).selectize( {
|
1394 |
+
plugins : [ 'restore_on_backspace' , 'remove_button' , 'drag_drop' ],
|
1395 |
+
delimiter : ',',
|
1396 |
+
persist : false,
|
1397 |
+
create : function( input ) {
|
1398 |
+
return {
|
1399 |
+
value: input,
|
1400 |
+
text: input
|
1401 |
+
}
|
1402 |
+
}
|
1403 |
+
} );
|
1404 |
+
|
1405 |
+
} );
|
1406 |
+
</script>
|
1407 |
+
</tr>
|
1408 |
+
|
1409 |
+
<?php
|
1410 |
+
|
1411 |
+
}
|
1412 |
+
|
1413 |
+
/**
|
1414 |
+
* Render 'key_value' type option field. Do not need to be registered to WP Settings API.
|
1415 |
+
*
|
1416 |
+
* @since 3.0.0
|
1417 |
+
* @access public
|
1418 |
+
*
|
1419 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1420 |
+
*/
|
1421 |
+
public function render_key_value_option_field( $option ) {
|
1422 |
+
|
1423 |
+
$option_value = get_option( $option[ 'id' ] );
|
1424 |
+
if ( !is_array( $option_value ) )
|
1425 |
+
$option_value = array(); ?>
|
1426 |
+
|
1427 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1428 |
+
<th scope="row"><?php echo $option[ 'title' ]; ?></th>
|
1429 |
+
|
1430 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1431 |
+
|
1432 |
+
<div class="key-value-fields-container" data-field-id="<?php echo $option[ 'id' ]; ?>">
|
1433 |
+
|
1434 |
+
<header>
|
1435 |
+
<span class="key"><?php _e( 'Key' , 'thirstyaffiliates' ); ?></span>
|
1436 |
+
<span class="value"><?php _e( 'Value' , 'thirstyaffiliates' ); ?></span>
|
1437 |
+
</header>
|
1438 |
+
|
1439 |
+
<div class="fields">
|
1440 |
+
|
1441 |
+
<?php if ( empty( $option_value ) ) { ?>
|
1442 |
+
|
1443 |
+
<div class="data-set">
|
1444 |
+
<input type="text" class="field key-field">
|
1445 |
+
<input type="text" class="field value-field">
|
1446 |
+
<div class="controls">
|
1447 |
+
<span class="control add dashicons dashicons-plus-alt" autocomplete="off"></span>
|
1448 |
+
<span class="control delete dashicons dashicons-dismiss" autocomplete="off"></span>
|
1449 |
+
</div>
|
1450 |
+
</div>
|
1451 |
+
|
1452 |
+
<?php } else {
|
1453 |
+
|
1454 |
+
foreach ( $option_value as $key => $val ) { ?>
|
1455 |
+
|
1456 |
+
<div class="data-set">
|
1457 |
+
<input type="text" class="field key-field" value="<?php echo $key; ?>">
|
1458 |
+
<input type="text" class="field value-field" value="<?php echo $val; ?>">
|
1459 |
+
<div class="controls">
|
1460 |
+
<span class="control add dashicons dashicons-plus-alt" autocomplete="off"></span>
|
1461 |
+
<span class="control delete dashicons dashicons-dismiss" autocomplete="off"></span>
|
1462 |
+
</div>
|
1463 |
+
</div>
|
1464 |
+
|
1465 |
+
<?php }
|
1466 |
+
|
1467 |
+
} ?>
|
1468 |
+
|
1469 |
+
</div>
|
1470 |
+
|
1471 |
+
</div>
|
1472 |
+
|
1473 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1474 |
+
|
1475 |
+
</td>
|
1476 |
+
</tr>
|
1477 |
+
|
1478 |
+
<?php
|
1479 |
+
|
1480 |
+
}
|
1481 |
+
|
1482 |
+
/**
|
1483 |
+
* Render 'link' type option field. Do not need to be registered to WP Settings API.
|
1484 |
+
*
|
1485 |
+
* @since 3.0.0
|
1486 |
+
* @access public
|
1487 |
+
*
|
1488 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1489 |
+
*/
|
1490 |
+
public function render_link_option_field( $option ) {
|
1491 |
+
|
1492 |
+
?>
|
1493 |
+
|
1494 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1495 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1496 |
+
<td>
|
1497 |
+
<a id="<?php echo esc_attr( $option[ 'id' ] ); ?>" href="<?php echo $option[ 'link_url' ]; ?>" target="_blank"><?php echo $option[ 'link_text' ]; ?></a>
|
1498 |
+
<br>
|
1499 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1500 |
+
</td>
|
1501 |
+
</tr>
|
1502 |
+
|
1503 |
+
<?php
|
1504 |
+
|
1505 |
+
}
|
1506 |
+
|
1507 |
+
/**
|
1508 |
+
* Render option divider. Decorative field. Do not need to be registered to WP Settings API.
|
1509 |
+
*
|
1510 |
+
* @since 3.0.0
|
1511 |
+
* @access public
|
1512 |
+
*
|
1513 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1514 |
+
*/
|
1515 |
+
public function render_option_divider_option_field( $option ) {
|
1516 |
+
|
1517 |
+
?>
|
1518 |
+
|
1519 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1520 |
+
<th scope="row" colspan="2">
|
1521 |
+
<h3><?php echo sanitize_text_field( $option[ 'title' ] ); ?></h3>
|
1522 |
+
<?php echo isset( $option[ 'markup' ] ) ? $option[ 'markup' ] : ''; ?>
|
1523 |
+
</th>
|
1524 |
+
</tr>
|
1525 |
+
|
1526 |
+
<?php
|
1527 |
+
|
1528 |
+
}
|
1529 |
+
|
1530 |
+
/**
|
1531 |
+
* Render custom "migration_controls" field. Do not need to be registered to WP Settings API.
|
1532 |
+
*
|
1533 |
+
* @since 3.0.0
|
1534 |
+
* @access public
|
1535 |
+
*
|
1536 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1537 |
+
*/
|
1538 |
+
public function render_migration_controls_option_field( $option ) {
|
1539 |
+
|
1540 |
+
$database_processing = apply_filters( 'ta_database_processing' , true ); // Flag to determine if another application is processing the db. ex. data downgrade.
|
1541 |
+
$processing = "";
|
1542 |
+
$disabled = false;
|
1543 |
+
|
1544 |
+
if ( get_option( Plugin_Constants::MIGRATION_COMPLETE_FLAG ) === 'no' ) {
|
1545 |
+
|
1546 |
+
$processing = "-processing";
|
1547 |
+
$disabled = true;
|
1548 |
+
|
1549 |
+
} ?>
|
1550 |
+
|
1551 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1552 |
+
|
1553 |
+
<th scope="row" class="title_desc"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1554 |
+
|
1555 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?> <?php echo $processing; ?>">
|
1556 |
+
|
1557 |
+
<?php if ( !$database_processing ) { ?>
|
1558 |
+
|
1559 |
+
<p><?php _e( 'Another application is currently processing the database. Please wait for this to complete.' , 'thirstyaffiliates' ); ?></p>
|
1560 |
+
|
1561 |
+
<?php } else { ?>
|
1562 |
+
|
1563 |
+
<input
|
1564 |
+
<?php echo $disabled ? "disabled" : ""; ?>
|
1565 |
+
type="button"
|
1566 |
+
id="<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1567 |
+
class="button button-primary"
|
1568 |
+
style="<?php echo isset( $option[ 'style' ] ) ? esc_attr( $option[ 'style' ] ) : ''; ?>"
|
1569 |
+
value="<?php _e( 'Migrate' , 'thirstyaffiliates' ); ?>">
|
1570 |
+
|
1571 |
+
<span class="spinner"></span>
|
1572 |
+
<p class="status"><?php _e( 'Migrating data. Please wait...' , 'thirstyaffiliates' ); ?></p>
|
1573 |
+
|
1574 |
+
<?php } ?>
|
1575 |
+
|
1576 |
+
<br /><br />
|
1577 |
+
<p class="desc"><?php echo isset( $option[ 'desc' ] ) ? $option[ 'desc' ] : ''; ?></p>
|
1578 |
+
|
1579 |
+
</td>
|
1580 |
+
|
1581 |
+
</tr>
|
1582 |
+
|
1583 |
+
<?php
|
1584 |
+
|
1585 |
+
}
|
1586 |
+
|
1587 |
+
/**
|
1588 |
+
* Render custom "social_links" field. Do not need to be registered to WP Settings API.
|
1589 |
+
*
|
1590 |
+
* @since 3.1.0
|
1591 |
+
* @access public
|
1592 |
+
*
|
1593 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1594 |
+
*/
|
1595 |
+
public function render_social_links_option_field( $option ) {
|
1596 |
+
|
1597 |
+
?>
|
1598 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1599 |
+
<th scope="row"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1600 |
+
<td>
|
1601 |
+
<ul>
|
1602 |
+
<li>
|
1603 |
+
<a href="https://www.facebook.com/thirstyaffiliates/"><?php _e( 'Like us on Facebook' , 'thirstyaffiliates' ); ?></a>
|
1604 |
+
<iframe src="//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fthirstyaffiliates&send=false&layout=button_count&width=450&show_faces=false&font=arial&colorscheme=light&action=like&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:21px; vertical-align: bottom;" allowTransparency="true"></iframe>
|
1605 |
+
</li>
|
1606 |
+
<li>
|
1607 |
+
<a href="http://twitter.com/thirstyaff"><?php _e( 'Follow us on Twitter' , 'thirstyaffiliates' ); ?></a>
|
1608 |
+
<a href="https://twitter.com/thirstyaff" class="twitter-follow-button" data-show-count="true" style="vertical-align: bottom;">Follow @thirstyaff</a><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?"http":"https";if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document, "script", "twitter-wjs");</script>
|
1609 |
+
</li>
|
1610 |
+
<li>
|
1611 |
+
<a href="https://www.linkedin.com/company-beta/2928598/"><?php _e( 'Follow us on Linkedin' , 'thirstyaffiliates' ); ?></a>
|
1612 |
+
</li>
|
1613 |
+
<li>
|
1614 |
+
<a href="https://thirstyaffiliates.com/affiliates?utm_source=Free%20Plugin&utm_medium=Help&utm_campaign=Affiliates%20Link" target="_blank"><?php _e( 'Join Our Affiliate Program' , 'thirstyaffiliates' ); ?></a>
|
1615 |
+
<?php _e( '(up to 30% commisions)' , 'thirstyaffiliates' ); ?>
|
1616 |
+
</li>
|
1617 |
+
</ul>
|
1618 |
+
</td>
|
1619 |
+
</tr>
|
1620 |
+
<?php
|
1621 |
+
}
|
1622 |
+
|
1623 |
+
/**
|
1624 |
+
* Render custom "export_global_settings" field. Do not need to be registered to WP Settings API.
|
1625 |
+
*
|
1626 |
+
* @since 3.0.0
|
1627 |
+
* @access public
|
1628 |
+
*
|
1629 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1630 |
+
*/
|
1631 |
+
public function render_export_global_settings_option_field( $option ) {
|
1632 |
+
|
1633 |
+
$global_settings_string = $this->get_global_settings_string(); ?>
|
1634 |
+
|
1635 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1636 |
+
<th scope="row" class="title_desc"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></th>
|
1637 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1638 |
+
<textarea
|
1639 |
+
name="<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1640 |
+
id="<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1641 |
+
style="<?php echo isset( $option[ 'style' ] ) ? esc_attr( $option[ 'style' ] ) : ''; ?>"
|
1642 |
+
class="<?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1643 |
+
placeholder="<?php echo isset( $option[ 'placeholder' ] ) ? esc_attr( $option[ 'placeholder' ] ) : ''; ?>"
|
1644 |
+
autocomplete="off"
|
1645 |
+
readonly
|
1646 |
+
rows="10"><?php echo $global_settings_string; ?></textarea>
|
1647 |
+
<div class="controls">
|
1648 |
+
<a id="copy-settings-string" data-clipboard-target="#<?php echo esc_attr( $option[ 'id' ] ); ?>"><?php _e( 'Copy' , 'thirstyaffiliates' ); ?></a>
|
1649 |
+
</div>
|
1650 |
+
</td>
|
1651 |
+
</tr>
|
1652 |
+
|
1653 |
+
<?php
|
1654 |
+
|
1655 |
+
}
|
1656 |
+
|
1657 |
+
/**
|
1658 |
+
* Render custom "import_global_settings" field. Do not need to be registered to WP Settings API.
|
1659 |
+
*
|
1660 |
+
* @since 3.0.0
|
1661 |
+
* @access public
|
1662 |
+
*
|
1663 |
+
* @param array $option Array of options data. May vary depending on option type.
|
1664 |
+
*/
|
1665 |
+
public function render_import_global_settings_option_field( $option ) {
|
1666 |
+
|
1667 |
+
?>
|
1668 |
+
|
1669 |
+
<tr valign="top" class="<?php echo esc_attr( $option[ 'id' ] ) . '-row'; ?>">
|
1670 |
+
<th scope="row" class="title_desc">
|
1671 |
+
<label for="<?php echo esc_attr( $option[ 'id' ] ); ?>"><?php echo sanitize_text_field( $option[ 'title' ] ); ?></label>
|
1672 |
+
</th>
|
1673 |
+
<td class="forminp forminp-<?php echo sanitize_title( $option[ 'type' ] ) ?>">
|
1674 |
+
<textarea
|
1675 |
+
name="<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1676 |
+
id="<?php echo esc_attr( $option[ 'id' ] ); ?>"
|
1677 |
+
style="<?php echo isset( $option[ 'style' ] ) ? esc_attr( $option[ 'style' ] ) : ''; ?>"
|
1678 |
+
class="<?php echo isset( $option[ 'class' ] ) ? esc_attr( $option[ 'class' ] ) : ''; ?>"
|
1679 |
+
placeholder="<?php echo esc_attr( $option[ 'placeholder' ] ); ?>"
|
1680 |
+
autocomplete="off"
|
1681 |
+
rows="10"></textarea>
|
1682 |
+
<p class="desc"><?php echo isset( $option[ 'description' ] ) ? $option[ 'description' ] : ''; ?></p>
|
1683 |
+
<div class="controls">
|
1684 |
+
<span class="spinner"></span>
|
1685 |
+
<input type="button" id="import-setting-button" class="button button-primary" value="<?php _e( 'Import Settings' , 'thirstyaffiliates' ); ?>">
|
1686 |
+
</di>
|
1687 |
+
</td>
|
1688 |
+
</tr>
|
1689 |
+
|
1690 |
+
<?php
|
1691 |
+
|
1692 |
+
}
|
1693 |
+
|
1694 |
+
|
1695 |
+
|
1696 |
+
|
1697 |
+
/*
|
1698 |
+
|--------------------------------------------------------------------------
|
1699 |
+
| "key_value" option field type helpers
|
1700 |
+
|--------------------------------------------------------------------------
|
1701 |
+
*/
|
1702 |
+
|
1703 |
+
/**
|
1704 |
+
* Load styling relating to 'key_value' field type.
|
1705 |
+
*
|
1706 |
+
* @since 3.0.0
|
1707 |
+
* @access public
|
1708 |
+
*/
|
1709 |
+
public function load_key_value_option_field_type_styling() {
|
1710 |
+
|
1711 |
+
?>
|
1712 |
+
|
1713 |
+
<style>
|
1714 |
+
.key-value-fields-container header span {
|
1715 |
+
display: inline-block;
|
1716 |
+
font-weight: 600;
|
1717 |
+
margin-bottom: 8px;
|
1718 |
+
}
|
1719 |
+
.key-value-fields-container header .key {
|
1720 |
+
width: 144px;
|
1721 |
+
}
|
1722 |
+
.key-value-fields-container header .value {
|
1723 |
+
width: 214px;
|
1724 |
+
}
|
1725 |
+
.key-value-fields-container .fields .data-set {
|
1726 |
+
margin-bottom: 8px;
|
1727 |
+
}
|
1728 |
+
.key-value-fields-container .fields .data-set:last-child {
|
1729 |
+
margin-bottom: 0;
|
1730 |
+
}
|
1731 |
+
.key-value-fields-container .fields .data-set .key-field {
|
1732 |
+
width: 140px;
|
1733 |
+
margin-left: 0;
|
1734 |
+
}
|
1735 |
+
.key-value-fields-container .fields .data-set .value-field {
|
1736 |
+
width: 215px;
|
1737 |
+
}
|
1738 |
+
.key-value-fields-container .fields .data-set .controls {
|
1739 |
+
display: none;
|
1740 |
+
}
|
1741 |
+
.key-value-fields-container .fields .data-set:hover .controls {
|
1742 |
+
display: inline-block;
|
1743 |
+
}
|
1744 |
+
.key-value-fields-container .fields .data-set .controls .control {
|
1745 |
+
cursor: pointer;
|
1746 |
+
}
|
1747 |
+
.key-value-fields-container .fields .data-set .controls .add {
|
1748 |
+
color: green;
|
1749 |
+
}
|
1750 |
+
.key-value-fields-container .fields .data-set .controls .delete {
|
1751 |
+
color: red;
|
1752 |
+
}
|
1753 |
+
</style>
|
1754 |
+
|
1755 |
+
<?php
|
1756 |
+
|
1757 |
+
}
|
1758 |
+
|
1759 |
+
/**
|
1760 |
+
* Load scripts relating to 'key_value' field type.
|
1761 |
+
*
|
1762 |
+
* @since 3.0.0
|
1763 |
+
* @access public
|
1764 |
+
*/
|
1765 |
+
public function load_key_value_option_field_type_script() {
|
1766 |
+
|
1767 |
+
?>
|
1768 |
+
|
1769 |
+
<script>
|
1770 |
+
|
1771 |
+
jQuery( document ).ready( function( $ ) {
|
1772 |
+
|
1773 |
+
// Hide the delete button if only 1 data set is available
|
1774 |
+
function init_data_set_controls() {
|
1775 |
+
|
1776 |
+
$( ".key-value-fields-container" ).each( function() {
|
1777 |
+
|
1778 |
+
if ( $( this ).find( ".data-set" ).length === 1 )
|
1779 |
+
$( this ).find( ".data-set .controls .delete" ).css( "display" , "none" );
|
1780 |
+
else
|
1781 |
+
$( this ).find( ".data-set .controls .delete" ).removeAttr( "style" );
|
1782 |
+
|
1783 |
+
} );
|
1784 |
+
|
1785 |
+
}
|
1786 |
+
|
1787 |
+
init_data_set_controls();
|
1788 |
+
|
1789 |
+
|
1790 |
+
// Attach "add" and "delete" events
|
1791 |
+
$( ".key-value-fields-container" ).on( "click" , ".controls .add" , function() {
|
1792 |
+
|
1793 |
+
let $data_set = $( this ).closest( '.data-set' );
|
1794 |
+
|
1795 |
+
$data_set.after( "<div class='data-set'>" +
|
1796 |
+
"<input type='text' class='field key-field' autocomplete='off'> " +
|
1797 |
+
"<input type='text' class='field value-field' autocomplete='off'>" +
|
1798 |
+
"<div class='controls'>" +
|
1799 |
+
"<span class='control add dashicons dashicons-plus-alt'></span>" +
|
1800 |
+
"<span class='control delete dashicons dashicons-dismiss'></span>" +
|
1801 |
+
"</div>" +
|
1802 |
+
"</div>" );
|
1803 |
+
|
1804 |
+
init_data_set_controls();
|
1805 |
+
|
1806 |
+
} );
|
1807 |
+
|
1808 |
+
$( ".key-value-fields-container" ).on( "click" , ".controls .delete" , function() {
|
1809 |
+
|
1810 |
+
let $data_set = $( this ).closest( '.data-set' );
|
1811 |
+
|
1812 |
+
$data_set.remove();
|
1813 |
+
|
1814 |
+
init_data_set_controls();
|
1815 |
+
|
1816 |
+
} );
|
1817 |
+
|
1818 |
+
|
1819 |
+
// Construct hidden fields for each of "key_value" option field types upon form submission
|
1820 |
+
$( "form" ).submit( function() {
|
1821 |
+
|
1822 |
+
$( ".key-value-fields-container" ).each( function() {
|
1823 |
+
|
1824 |
+
var $this = $( this ),
|
1825 |
+
field_id = $this.attr( "data-field-id" ),
|
1826 |
+
field_inputs = "";
|
1827 |
+
|
1828 |
+
$this.find( ".data-set" ).each( function() {
|
1829 |
+
|
1830 |
+
var $this = $( this ),
|
1831 |
+
key_field = $.trim( $this.find( ".key-field" ).val() ),
|
1832 |
+
value_field = $.trim( $this.find( ".value-field" ).val() );
|
1833 |
+
|
1834 |
+
if ( key_field !== "" && value_field !== "" )
|
1835 |
+
field_inputs += "<input type='hidden' name='" + field_id + "[" + key_field + "]' value='" + value_field + "'>";
|
1836 |
+
|
1837 |
+
} );
|
1838 |
+
|
1839 |
+
$this.append( field_inputs );
|
1840 |
+
|
1841 |
+
} );
|
1842 |
+
|
1843 |
+
} );
|
1844 |
+
|
1845 |
+
} );
|
1846 |
+
|
1847 |
+
</script>
|
1848 |
+
|
1849 |
+
<?php
|
1850 |
+
|
1851 |
+
}
|
1852 |
+
|
1853 |
+
|
1854 |
+
|
1855 |
+
|
1856 |
+
/*
|
1857 |
+
|--------------------------------------------------------------------------
|
1858 |
+
| Settings helper
|
1859 |
+
|--------------------------------------------------------------------------
|
1860 |
+
*/
|
1861 |
+
|
1862 |
+
/**
|
1863 |
+
* Get global settings string via ajax.
|
1864 |
+
*
|
1865 |
+
* @since 3.0.0
|
1866 |
+
* @access public
|
1867 |
+
*/
|
1868 |
+
public function ajax_get_global_settings_string() {
|
1869 |
+
|
1870 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
1871 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
1872 |
+
else {
|
1873 |
+
|
1874 |
+
$global_settings_string = $this->get_global_settings_string();
|
1875 |
+
|
1876 |
+
if ( is_wp_error( $global_settings_string ) )
|
1877 |
+
$response = array( 'status' => 'fail' , 'error_msg' => $global_settings_string->get_error_message() );
|
1878 |
+
else
|
1879 |
+
$response = array( 'status' => 'success' , 'global_settings_string' => $global_settings_string );
|
1880 |
+
|
1881 |
+
}
|
1882 |
+
|
1883 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
1884 |
+
echo wp_json_encode( $response );
|
1885 |
+
wp_die();
|
1886 |
+
|
1887 |
+
}
|
1888 |
+
|
1889 |
+
/**
|
1890 |
+
* Get global settings string.
|
1891 |
+
*
|
1892 |
+
* @since 3.0.0
|
1893 |
+
* @access public
|
1894 |
+
*
|
1895 |
+
* @return WP_Error|string WP_Error on error, Base 64 encoded serialized global plugin settings otherwise.
|
1896 |
+
*/
|
1897 |
+
public function get_global_settings_string() {
|
1898 |
+
|
1899 |
+
if ( !$this->_helper_functions->current_user_authorized() )
|
1900 |
+
return new \WP_Error( 'ta_unauthorized_operation_export_settings' , __( 'Unauthorized operation. Only authorized accounts can access global plugin settings string' , 'thirstyaffiliates' ) );
|
1901 |
+
|
1902 |
+
$global_settings_arr = array();
|
1903 |
+
foreach ( $this->_exportable_options as $key => $default )
|
1904 |
+
$global_settings_arr[ $key ] = get_option( $key , $default );
|
1905 |
+
|
1906 |
+
return base64_encode( serialize( $global_settings_arr ) );
|
1907 |
+
|
1908 |
+
}
|
1909 |
+
|
1910 |
+
/**
|
1911 |
+
* Import settings via ajax.
|
1912 |
+
*
|
1913 |
+
* @access public
|
1914 |
+
* @since 3.0.0
|
1915 |
+
*/
|
1916 |
+
public function ajax_import_settings() {
|
1917 |
+
|
1918 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
1919 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
1920 |
+
elseif ( !isset( $_POST[ 'ta_settings_string' ] ) )
|
1921 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Required parameter not passed' , 'thirstyaffiliates' ) );
|
1922 |
+
else {
|
1923 |
+
|
1924 |
+
$result = $this->import_settings( filter_var( $_POST[ 'ta_settings_string' ] , FILTER_SANITIZE_STRING ) );
|
1925 |
+
|
1926 |
+
if ( is_wp_error( $result ) )
|
1927 |
+
$response = array( 'status' => 'fail' , 'error_msg' => $result->get_error_message() );
|
1928 |
+
else
|
1929 |
+
$response = array( 'status' => 'success' , 'success_msg' => __( 'Settings successfully imported' , 'thirstyaffiliates' ) );
|
1930 |
+
|
1931 |
+
}
|
1932 |
+
|
1933 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
1934 |
+
echo wp_json_encode( $response );
|
1935 |
+
wp_die();
|
1936 |
+
|
1937 |
+
}
|
1938 |
+
|
1939 |
+
/**
|
1940 |
+
* Import settings from external global settings string.
|
1941 |
+
*
|
1942 |
+
* @since 3.0.0
|
1943 |
+
* @access public
|
1944 |
+
*
|
1945 |
+
* @param string $global_settings_string Settings string.
|
1946 |
+
* @return WP_Error | boolean WP_Error instance on failure, boolean true otherwise.
|
1947 |
+
*/
|
1948 |
+
public function import_settings( $global_settings_string ) {
|
1949 |
+
|
1950 |
+
if ( !$this->_helper_functions->current_user_authorized() )
|
1951 |
+
return new \WP_Error( 'ta_unauthorized_operation_import_settings' , __( 'Unauthorized operation. Only authorized accounts can import settings' , 'thirstyaffiliates' ) );
|
1952 |
+
|
1953 |
+
$settings_arr = @unserialize( base64_decode( $global_settings_string ) );
|
1954 |
+
|
1955 |
+
if ( !is_array( $settings_arr ) )
|
1956 |
+
return new \WP_Error( 'ta_invalid_global_settings_string' , __( 'Invalid global settings string' , 'thirstyaffiliates' ) , array( 'global_settings_string' => $global_settings_string ) );
|
1957 |
+
else {
|
1958 |
+
|
1959 |
+
foreach ( $settings_arr as $key => $val ) {
|
1960 |
+
|
1961 |
+
if ( !array_key_exists( $key , $this->_exportable_options ) )
|
1962 |
+
continue;
|
1963 |
+
|
1964 |
+
update_option( $key , $val );
|
1965 |
+
|
1966 |
+
}
|
1967 |
+
|
1968 |
+
return true;
|
1969 |
+
|
1970 |
+
}
|
1971 |
+
|
1972 |
+
}
|
1973 |
+
|
1974 |
+
/**
|
1975 |
+
* Post update option callback for link prefix options.
|
1976 |
+
*
|
1977 |
+
* @since 3.0.0
|
1978 |
+
* @access public
|
1979 |
+
*
|
1980 |
+
* @param string $old_value Old option value before the update.
|
1981 |
+
* @param string $value New value saved.
|
1982 |
+
* @param string $option Option id.
|
1983 |
+
*/
|
1984 |
+
public function link_prefix_post_update_callback( $value , $old_value , $option ) {
|
1985 |
+
|
1986 |
+
if ( $option === 'ta_link_prefix' && $value === 'custom' )
|
1987 |
+
return $value;
|
1988 |
+
|
1989 |
+
if ( $option === 'ta_link_prefix_custom' && get_option( 'ta_link_prefix' ) !== 'custom' )
|
1990 |
+
return $value;
|
1991 |
+
|
1992 |
+
$used_link_prefixes = maybe_unserialize( get_option( 'ta_used_link_prefixes' , array() ) );
|
1993 |
+
$check_duplicate = array_search( $value , $used_link_prefixes );
|
1994 |
+
|
1995 |
+
if ( $check_duplicate !== false )
|
1996 |
+
unset( $used_link_prefixes[ $check_duplicate ] );
|
1997 |
+
|
1998 |
+
$used_link_prefixes[] = sanitize_text_field( $value );
|
1999 |
+
$count = count( $used_link_prefixes );
|
2000 |
+
|
2001 |
+
if ( $count > 10 )
|
2002 |
+
$used_link_prefixes = array_slice( $used_link_prefixes , $count - 10 , 10 , false );
|
2003 |
+
|
2004 |
+
update_option( 'ta_used_link_prefixes' , array_unique( $used_link_prefixes ) );
|
2005 |
+
|
2006 |
+
return $value;
|
2007 |
+
}
|
2008 |
+
|
2009 |
+
/**
|
2010 |
+
* Restrict modules settings.
|
2011 |
+
*
|
2012 |
+
* @since 3.6
|
2013 |
+
* @access public
|
2014 |
+
*/
|
2015 |
+
public function restrict_module_settings() {
|
2016 |
+
|
2017 |
+
$screen = get_current_screen();
|
2018 |
+
$tab = isset( $_GET[ 'tab' ] ) ? sanitize_text_field( $_GET[ 'tab' ] ) : null;
|
2019 |
+
|
2020 |
+
if ( $screen->id !== 'thirstylink_page_thirsty-settings' || ! $tab ) return;
|
2021 |
+
|
2022 |
+
$default_values = array();
|
2023 |
+
$registered = apply_filters( 'ta_modules_settings_options' , array(
|
2024 |
+
array( 'id' => 'ta_enable_stats_reporting_module' , 'default' => 'yes' ),
|
2025 |
+
array( 'id' => 'ta_enable_link_fixer' , 'default' => 'yes' ),
|
2026 |
+
array( 'id' => 'ta_uncloak_link_per_link' , 'default' => 'no' )
|
2027 |
+
) );
|
2028 |
+
|
2029 |
+
if ( function_exists( 'array_column' ) )
|
2030 |
+
$default_values = array_column( $registered , 'default' , 'id' );
|
2031 |
+
else {
|
2032 |
+
|
2033 |
+
foreach ( $registered as $module )
|
2034 |
+
$default_values[ $module[ 'id' ] ] = isset( $module[ 'default' ] ) ? $module[ 'default' ] : 'yes';
|
2035 |
+
}
|
2036 |
+
|
2037 |
+
$modules = array_keys( $default_values );
|
2038 |
+
$current_module = str_replace( array( 'tap_' , 'amazon_settings_section' , '_settings' ) , array( 'tap_enable_' , 'azon' , '' ) , $tab );
|
2039 |
+
$current_module = apply_filters( 'ta_restrict_current_module' , $current_module , $tab , $modules );
|
2040 |
+
$default = in_array( $current_module , $modules ) ? $default_values[ $current_module ] : null;
|
2041 |
+
|
2042 |
+
if ( ! is_null( $default ) && get_option( $current_module , $default ) !== 'yes' )
|
2043 |
+
wp_die( __( "Sorry, you are not allowed to access this page." , 'thirstyaffiliates' ) );
|
2044 |
+
|
2045 |
+
}
|
2046 |
+
|
2047 |
+
|
2048 |
+
|
2049 |
+
|
2050 |
+
/*
|
2051 |
+
|--------------------------------------------------------------------------
|
2052 |
+
| Implemented Interface Methods
|
2053 |
+
|--------------------------------------------------------------------------
|
2054 |
+
*/
|
2055 |
+
|
2056 |
+
/**
|
2057 |
+
* Execute codes that needs to run plugin activation.
|
2058 |
+
*
|
2059 |
+
* @since 3.0.0
|
2060 |
+
* @access public
|
2061 |
+
* @implements ThirstyAffiliates\Interfaces\Activatable_Interface
|
2062 |
+
*/
|
2063 |
+
public function activate() {
|
2064 |
+
|
2065 |
+
if ( get_option( 'ta_settings_initialized' ) !== 'yes' ) {
|
2066 |
+
|
2067 |
+
update_option( 'ta_link_prefix' , 'recommends' );
|
2068 |
+
update_option( 'ta_link_prefix_custom' , '' );
|
2069 |
+
update_option( 'ta_used_link_prefixes' , array( 'recommends' ) );
|
2070 |
+
update_option( 'ta_enable_javascript_frontend_redirect' , 'yes' );
|
2071 |
+
update_option( 'ta_show_enable_js_redirect_notice' , 'no' );
|
2072 |
+
update_option( 'ta_dismiss_marketing_notice_option' , 'no' );
|
2073 |
+
update_option( 'ta_settings_initialized' , 'yes' );
|
2074 |
+
}
|
2075 |
+
}
|
2076 |
+
|
2077 |
+
/**
|
2078 |
+
* Execute codes that needs to run on plugin initialization.
|
2079 |
+
*
|
2080 |
+
* @since 3.0.0
|
2081 |
+
* @access public
|
2082 |
+
* @implements ThirstyAffiliates\Interfaces\Initiable_Interface
|
2083 |
+
*/
|
2084 |
+
public function initialize() {
|
2085 |
+
|
2086 |
+
add_action( 'wp_ajax_ta_get_global_settings_string' , array( $this , 'ajax_get_global_settings_string' ) );
|
2087 |
+
add_action( 'wp_ajax_ta_import_settings' , array( $this , 'ajax_import_settings' ) );
|
2088 |
+
|
2089 |
+
}
|
2090 |
+
|
2091 |
+
/**
|
2092 |
+
* Execute model.
|
2093 |
+
*
|
2094 |
+
* @implements WordPress_Plugin_Boilerplate\Interfaces\Model_Interface
|
2095 |
+
*
|
2096 |
+
* @since 3.0.0
|
2097 |
+
* @access public
|
2098 |
+
*/
|
2099 |
+
public function run() {
|
2100 |
+
|
2101 |
+
add_action( 'admin_init' , array( $this , 'init_plugin_settings' ) );
|
2102 |
+
add_action( 'admin_menu' , array( $this , 'add_settings_page' ) );
|
2103 |
+
add_action( 'current_screen' , array( $this , 'restrict_module_settings' ) );
|
2104 |
+
|
2105 |
+
add_action( 'ta_before_settings_form' , array( $this , 'load_key_value_option_field_type_styling' ) );
|
2106 |
+
add_action( 'ta_before_settings_form' , array( $this , 'load_key_value_option_field_type_script' ) );
|
2107 |
+
add_action( 'pre_update_option_ta_link_prefix' , array( $this , 'link_prefix_post_update_callback' ) , 10 , 3 );
|
2108 |
+
add_action( 'pre_update_option_ta_link_prefix_custom' , array( $this , 'link_prefix_post_update_callback' ) , 10 , 3 );
|
2109 |
+
|
2110 |
+
add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
|
2111 |
+
add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
|
2112 |
+
}
|
2113 |
+
|
2114 |
+
}
|
Models/Shortcodes.php
CHANGED
@@ -1,301 +1,301 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
-
|
9 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
10 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
14 |
-
*
|
15 |
-
* @since 3.0.0
|
16 |
-
*/
|
17 |
-
class Shortcodes implements Model_Interface {
|
18 |
-
|
19 |
-
/*
|
20 |
-
|--------------------------------------------------------------------------
|
21 |
-
| Class Properties
|
22 |
-
|--------------------------------------------------------------------------
|
23 |
-
*/
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Property that holds the single main instance of Shortcodes.
|
27 |
-
*
|
28 |
-
* @since 3.0.0
|
29 |
-
* @access private
|
30 |
-
* @var Redirection
|
31 |
-
*/
|
32 |
-
private static $_instance;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Model that houses the main plugin object.
|
36 |
-
*
|
37 |
-
* @since 3.0.0
|
38 |
-
* @access private
|
39 |
-
* @var Redirection
|
40 |
-
*/
|
41 |
-
private $_main_plugin;
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Model that houses all the plugin constants.
|
45 |
-
*
|
46 |
-
* @since 3.0.0
|
47 |
-
* @access private
|
48 |
-
* @var Plugin_Constants
|
49 |
-
*/
|
50 |
-
private $_constants;
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Property that houses all the helper functions of the plugin.
|
54 |
-
*
|
55 |
-
* @since 3.0.0
|
56 |
-
* @access private
|
57 |
-
* @var Helper_Functions
|
58 |
-
*/
|
59 |
-
private $_helper_functions;
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
/*
|
65 |
-
|--------------------------------------------------------------------------
|
66 |
-
| Class Methods
|
67 |
-
|--------------------------------------------------------------------------
|
68 |
-
*/
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Class constructor.
|
72 |
-
*
|
73 |
-
* @since 3.0.0
|
74 |
-
* @access public
|
75 |
-
*
|
76 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
77 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
78 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
79 |
-
*/
|
80 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
81 |
-
|
82 |
-
$this->_constants = $constants;
|
83 |
-
$this->_helper_functions = $helper_functions;
|
84 |
-
|
85 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
86 |
-
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
91 |
-
*
|
92 |
-
* @since 3.0.0
|
93 |
-
* @access public
|
94 |
-
*
|
95 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
96 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
97 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
98 |
-
* @return Redirection
|
99 |
-
*/
|
100 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
101 |
-
|
102 |
-
if ( !self::$_instance instanceof self )
|
103 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
104 |
-
|
105 |
-
return self::$_instance;
|
106 |
-
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Checks if the given ID needs to be uncloaked
|
111 |
-
*
|
112 |
-
* @since 3.0.0
|
113 |
-
* @access public
|
114 |
-
*
|
115 |
-
* @param int $link_id Affiliate Link post ID.
|
116 |
-
* @return boolean.
|
117 |
-
*/
|
118 |
-
public function is_link_to_be_uncloaked( $link_id ) {
|
119 |
-
|
120 |
-
if ( get_option( 'ta_uncloak_link_per_link' ) == 'yes' ) {
|
121 |
-
|
122 |
-
$links_to_uncloak = maybe_unserialize( get_option( 'ta_links_to_uncloak' , array() ) );
|
123 |
-
|
124 |
-
if ( in_array( $link_id , $links_to_uncloak ) )
|
125 |
-
return true;
|
126 |
-
|
127 |
-
}
|
128 |
-
|
129 |
-
if ( get_option( 'ta_uncloak_link_per_category' ) == 'yes' && $category_to_uncloak = get_option( 'ta_category_to_uncloak' ) ) {
|
130 |
-
|
131 |
-
if ( has_term( $category_to_uncloak , Plugin_Constants::AFFILIATE_LINKS_TAX , $link_id ) )
|
132 |
-
return true;
|
133 |
-
}
|
134 |
-
|
135 |
-
return false;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* thirstylink shortcode.
|
140 |
-
* example: [thirstylink ids="10,15,18,20"]Affiliate Link[/thirstylink]
|
141 |
-
*
|
142 |
-
* @since 3.0.0
|
143 |
-
* @since 3.3.0 Add data-nojs attribute support.
|
144 |
-
* @since 3.4.0 Add additional classes field support.
|
145 |
-
* @access public
|
146 |
-
*
|
147 |
-
* @param array $atts Shortcode attributes.
|
148 |
-
* @param string $content Shortcode content.
|
149 |
-
* @return string Processed shortcode output.
|
150 |
-
*/
|
151 |
-
public function thirstylink_shortcode( $atts , $content = '' ) {
|
152 |
-
|
153 |
-
global $post;
|
154 |
-
|
155 |
-
$post_id = is_a( $post , 'WP_Post' ) ? $post->ID : 0;
|
156 |
-
|
157 |
-
$atts = shortcode_atts( array(
|
158 |
-
'ids' => '',
|
159 |
-
'linkid' => '',
|
160 |
-
'linktext' => '',
|
161 |
-
'class' => '',
|
162 |
-
'rel' => '',
|
163 |
-
'target' => '',
|
164 |
-
'title' => ''
|
165 |
-
), $atts , 'thirstylink' );
|
166 |
-
|
167 |
-
// get all link attributes from $atts
|
168 |
-
$link_attributes = array_diff_assoc(
|
169 |
-
$atts,
|
170 |
-
array(
|
171 |
-
'ids' => $atts[ 'ids' ],
|
172 |
-
'linkid' => $atts[ 'linkid' ],
|
173 |
-
'linktext' => $atts[ 'linktext' ],
|
174 |
-
)
|
175 |
-
);
|
176 |
-
|
177 |
-
// get the link ID
|
178 |
-
if ( ! $atts[ 'linkid' ] ) {
|
179 |
-
|
180 |
-
$ids = isset( $atts[ 'ids' ] ) ? array_map( 'intval' , explode( ',' , $atts[ 'ids' ] ) ) : array();
|
181 |
-
$key = rand( 0 , count( $ids ) - 1 );
|
182 |
-
$link_id = $ids[ $key ];
|
183 |
-
} else
|
184 |
-
$link_id = (int) $atts[ 'linkid' ];
|
185 |
-
|
186 |
-
$output = '';
|
187 |
-
|
188 |
-
if ( $link_id && get_post_type( $link_id ) == Plugin_Constants::AFFILIATE_LINKS_CPT ) {
|
189 |
-
|
190 |
-
// load thirstylink
|
191 |
-
$thirstylink = new Affiliate_Link( $link_id );
|
192 |
-
$uncloak_link = $thirstylink->is( 'uncloak_link' );
|
193 |
-
|
194 |
-
// get the link URL
|
195 |
-
$link_attributes[ 'href' ] = ( $uncloak_link ) ? apply_filters( 'ta_uncloak_link_url' , $thirstylink->get_prop( 'destination_url' ) , $thirstylink ) : $thirstylink->get_prop( 'permalink' );
|
196 |
-
|
197 |
-
if ( ! $uncloak_link )
|
198 |
-
$link_attributes[ 'href' ] = $this->clean_url( $link_attributes[ 'href' ] );
|
199 |
-
|
200 |
-
// get link text content default if no value is set
|
201 |
-
if ( empty( $content ) && $atts[ 'linktext' ] )
|
202 |
-
$content = $atts[ 'linktext' ]; // backward compatibility to get the link text content.
|
203 |
-
else if ( empty( $content ) )
|
204 |
-
$content = $thirstylink->get_prop( 'name' );
|
205 |
-
|
206 |
-
// check for nofollow defaults if no value is set
|
207 |
-
if ( empty( $link_attributes[ 'rel' ] ) ) {
|
208 |
-
|
209 |
-
$link_attributes[ 'rel' ] = $thirstylink->is( 'no_follow' ) ? 'nofollow' : '';
|
210 |
-
|
211 |
-
if ( $thirstylink->get_prop( 'rel_tags' ) )
|
212 |
-
$link_attributes[ 'rel' ] = trim( $link_attributes[ 'rel' ] . ' ' . $thirstylink->get_prop( 'rel_tags' ) );
|
213 |
-
}
|
214 |
-
|
215 |
-
// check for new window defaults if no value is set
|
216 |
-
if ( empty( $link_attributes[ 'target' ] ) ) {
|
217 |
-
|
218 |
-
$link_attributes[ 'target' ] = $thirstylink->is( 'new_window' ) ? '_blank' : '';
|
219 |
-
}
|
220 |
-
|
221 |
-
// provide default class value if it is not set
|
222 |
-
if ( empty( $link_attributes[ 'class' ] ) ){
|
223 |
-
|
224 |
-
$link_attributes[ 'class' ] = get_option( 'ta_disable_thirsty_link_class' ) !== 'yes' ? 'thirstylink' : '';
|
225 |
-
|
226 |
-
if ( $thirstylink->get_prop( 'css_classes' ) )
|
227 |
-
$link_attributes[ 'class' ] = trim( $link_attributes[ 'class' ] . ' ' . $thirstylink->get_prop( 'css_classes' ) );
|
228 |
-
}
|
229 |
-
|
230 |
-
|
231 |
-
// provide default class value if it is not set
|
232 |
-
if ( empty( $link_attributes[ 'title' ] ) && get_option( 'ta_disable_title_attribute' ) !== 'yes' )
|
233 |
-
$link_attributes[ 'title' ] = $thirstylink->get_prop( 'name' );
|
234 |
-
|
235 |
-
// remove double quote character on title attribute.
|
236 |
-
$link_attributes[ 'title' ] = esc_attr( str_replace( '"' , '' , $link_attributes[ 'title' ] ) );
|
237 |
-
|
238 |
-
// add data-link_id attribute if affiliate link is uncloaked.
|
239 |
-
if ( $uncloak_link )
|
240 |
-
$link_attributes[ 'data-linkid' ] = $link_id;
|
241 |
-
|
242 |
-
// tag links as "nojs" to disable JS redirect for them.
|
243 |
-
if ( get_option( 'ta_enable_javascript_frontend_redirect' ) == 'yes' )
|
244 |
-
$link_attributes[ 'data-nojs' ] = apply_filters( 'ta_nojs_redirect_attribute' , false , $thirstylink );
|
245 |
-
|
246 |
-
// allow the ability to add custom link attributes
|
247 |
-
$link_attributes = apply_filters( 'ta_link_insert_extend_data_attributes' , $link_attributes , $thirstylink , $post_id );
|
248 |
-
|
249 |
-
// Build the link ready for output
|
250 |
-
$output .= '<a';
|
251 |
-
|
252 |
-
foreach ( $link_attributes as $name => $value ) {
|
253 |
-
// Handle square bracket escaping (used for some addons, eg. Google Analytics click tracking)
|
254 |
-
$value = html_entity_decode( $value );
|
255 |
-
$value = preg_replace( '/[/' , '[' , $value );
|
256 |
-
$value = preg_replace( '/]/' , ']' , $value );
|
257 |
-
$output .= ! empty($value) ? ' ' . $name . '="' . trim( esc_attr( $value ) ) . '"' : '';
|
258 |
-
}
|
259 |
-
|
260 |
-
$output .= ' data-shortcode="true">' . do_shortcode( $content ) . '</a>';
|
261 |
-
|
262 |
-
|
263 |
-
} else
|
264 |
-
$output .= '<span style="color: #0000ff;">' . __( 'SHORTCODE ERROR: ThirstyAffiliates did not detect a valid link id, please check your short code!' , 'thirstyaffiliates' ) . '</span>';
|
265 |
-
|
266 |
-
return $output;
|
267 |
-
}
|
268 |
-
|
269 |
-
/**
|
270 |
-
* Remove parameters in the URL added via the get_permalink hook and escape it.
|
271 |
-
* Note: This is needed for WPML support.
|
272 |
-
*
|
273 |
-
* @since 3.2.1
|
274 |
-
* @access private
|
275 |
-
*
|
276 |
-
* @param string $raw_url Raw URL.
|
277 |
-
* @param string Cleaned URL.
|
278 |
-
*/
|
279 |
-
private function clean_url( $raw_url ) {
|
280 |
-
|
281 |
-
$parse = parse_url( $raw_url );
|
282 |
-
extract( $parse );
|
283 |
-
|
284 |
-
// rebuild url excluding parameters.
|
285 |
-
$url = $scheme . '://' . $host;
|
286 |
-
$url .= isset( $path ) ? $path : '';
|
287 |
-
|
288 |
-
return esc_url( $url );
|
289 |
-
}
|
290 |
-
|
291 |
-
/**
|
292 |
-
* Execute shortcodes class.
|
293 |
-
*
|
294 |
-
* @since 3.0.0
|
295 |
-
* @access public
|
296 |
-
*/
|
297 |
-
public function run() {
|
298 |
-
|
299 |
-
add_shortcode( 'thirstylink' , array( $this , 'thirstylink_shortcode' ) );
|
300 |
-
}
|
301 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
+
|
9 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
10 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
14 |
+
*
|
15 |
+
* @since 3.0.0
|
16 |
+
*/
|
17 |
+
class Shortcodes implements Model_Interface {
|
18 |
+
|
19 |
+
/*
|
20 |
+
|--------------------------------------------------------------------------
|
21 |
+
| Class Properties
|
22 |
+
|--------------------------------------------------------------------------
|
23 |
+
*/
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Property that holds the single main instance of Shortcodes.
|
27 |
+
*
|
28 |
+
* @since 3.0.0
|
29 |
+
* @access private
|
30 |
+
* @var Redirection
|
31 |
+
*/
|
32 |
+
private static $_instance;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Model that houses the main plugin object.
|
36 |
+
*
|
37 |
+
* @since 3.0.0
|
38 |
+
* @access private
|
39 |
+
* @var Redirection
|
40 |
+
*/
|
41 |
+
private $_main_plugin;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Model that houses all the plugin constants.
|
45 |
+
*
|
46 |
+
* @since 3.0.0
|
47 |
+
* @access private
|
48 |
+
* @var Plugin_Constants
|
49 |
+
*/
|
50 |
+
private $_constants;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Property that houses all the helper functions of the plugin.
|
54 |
+
*
|
55 |
+
* @since 3.0.0
|
56 |
+
* @access private
|
57 |
+
* @var Helper_Functions
|
58 |
+
*/
|
59 |
+
private $_helper_functions;
|
60 |
+
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
/*
|
65 |
+
|--------------------------------------------------------------------------
|
66 |
+
| Class Methods
|
67 |
+
|--------------------------------------------------------------------------
|
68 |
+
*/
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Class constructor.
|
72 |
+
*
|
73 |
+
* @since 3.0.0
|
74 |
+
* @access public
|
75 |
+
*
|
76 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
77 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
78 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
79 |
+
*/
|
80 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
81 |
+
|
82 |
+
$this->_constants = $constants;
|
83 |
+
$this->_helper_functions = $helper_functions;
|
84 |
+
|
85 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
86 |
+
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
91 |
+
*
|
92 |
+
* @since 3.0.0
|
93 |
+
* @access public
|
94 |
+
*
|
95 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
96 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
97 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
98 |
+
* @return Redirection
|
99 |
+
*/
|
100 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
101 |
+
|
102 |
+
if ( !self::$_instance instanceof self )
|
103 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
104 |
+
|
105 |
+
return self::$_instance;
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Checks if the given ID needs to be uncloaked
|
111 |
+
*
|
112 |
+
* @since 3.0.0
|
113 |
+
* @access public
|
114 |
+
*
|
115 |
+
* @param int $link_id Affiliate Link post ID.
|
116 |
+
* @return boolean.
|
117 |
+
*/
|
118 |
+
public function is_link_to_be_uncloaked( $link_id ) {
|
119 |
+
|
120 |
+
if ( get_option( 'ta_uncloak_link_per_link' ) == 'yes' ) {
|
121 |
+
|
122 |
+
$links_to_uncloak = maybe_unserialize( get_option( 'ta_links_to_uncloak' , array() ) );
|
123 |
+
|
124 |
+
if ( in_array( $link_id , $links_to_uncloak ) )
|
125 |
+
return true;
|
126 |
+
|
127 |
+
}
|
128 |
+
|
129 |
+
if ( get_option( 'ta_uncloak_link_per_category' ) == 'yes' && $category_to_uncloak = get_option( 'ta_category_to_uncloak' ) ) {
|
130 |
+
|
131 |
+
if ( has_term( $category_to_uncloak , Plugin_Constants::AFFILIATE_LINKS_TAX , $link_id ) )
|
132 |
+
return true;
|
133 |
+
}
|
134 |
+
|
135 |
+
return false;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* thirstylink shortcode.
|
140 |
+
* example: [thirstylink ids="10,15,18,20"]Affiliate Link[/thirstylink]
|
141 |
+
*
|
142 |
+
* @since 3.0.0
|
143 |
+
* @since 3.3.0 Add data-nojs attribute support.
|
144 |
+
* @since 3.4.0 Add additional classes field support.
|
145 |
+
* @access public
|
146 |
+
*
|
147 |
+
* @param array $atts Shortcode attributes.
|
148 |
+
* @param string $content Shortcode content.
|
149 |
+
* @return string Processed shortcode output.
|
150 |
+
*/
|
151 |
+
public function thirstylink_shortcode( $atts , $content = '' ) {
|
152 |
+
|
153 |
+
global $post;
|
154 |
+
|
155 |
+
$post_id = is_a( $post , 'WP_Post' ) ? $post->ID : 0;
|
156 |
+
|
157 |
+
$atts = shortcode_atts( array(
|
158 |
+
'ids' => '',
|
159 |
+
'linkid' => '',
|
160 |
+
'linktext' => '',
|
161 |
+
'class' => '',
|
162 |
+
'rel' => '',
|
163 |
+
'target' => '',
|
164 |
+
'title' => ''
|
165 |
+
), $atts , 'thirstylink' );
|
166 |
+
|
167 |
+
// get all link attributes from $atts
|
168 |
+
$link_attributes = array_diff_assoc(
|
169 |
+
$atts,
|
170 |
+
array(
|
171 |
+
'ids' => $atts[ 'ids' ],
|
172 |
+
'linkid' => $atts[ 'linkid' ],
|
173 |
+
'linktext' => $atts[ 'linktext' ],
|
174 |
+
)
|
175 |
+
);
|
176 |
+
|
177 |
+
// get the link ID
|
178 |
+
if ( ! $atts[ 'linkid' ] ) {
|
179 |
+
|
180 |
+
$ids = isset( $atts[ 'ids' ] ) ? array_map( 'intval' , explode( ',' , $atts[ 'ids' ] ) ) : array();
|
181 |
+
$key = rand( 0 , count( $ids ) - 1 );
|
182 |
+
$link_id = $ids[ $key ];
|
183 |
+
} else
|
184 |
+
$link_id = (int) $atts[ 'linkid' ];
|
185 |
+
|
186 |
+
$output = '';
|
187 |
+
|
188 |
+
if ( $link_id && get_post_type( $link_id ) == Plugin_Constants::AFFILIATE_LINKS_CPT ) {
|
189 |
+
|
190 |
+
// load thirstylink
|
191 |
+
$thirstylink = new Affiliate_Link( $link_id );
|
192 |
+
$uncloak_link = $thirstylink->is( 'uncloak_link' );
|
193 |
+
|
194 |
+
// get the link URL
|
195 |
+
$link_attributes[ 'href' ] = ( $uncloak_link ) ? apply_filters( 'ta_uncloak_link_url' , $thirstylink->get_prop( 'destination_url' ) , $thirstylink ) : $thirstylink->get_prop( 'permalink' );
|
196 |
+
|
197 |
+
if ( ! $uncloak_link )
|
198 |
+
$link_attributes[ 'href' ] = $this->clean_url( $link_attributes[ 'href' ] );
|
199 |
+
|
200 |
+
// get link text content default if no value is set
|
201 |
+
if ( empty( $content ) && $atts[ 'linktext' ] )
|
202 |
+
$content = $atts[ 'linktext' ]; // backward compatibility to get the link text content.
|
203 |
+
else if ( empty( $content ) )
|
204 |
+
$content = $thirstylink->get_prop( 'name' );
|
205 |
+
|
206 |
+
// check for nofollow defaults if no value is set
|
207 |
+
if ( empty( $link_attributes[ 'rel' ] ) ) {
|
208 |
+
|
209 |
+
$link_attributes[ 'rel' ] = $thirstylink->is( 'no_follow' ) ? 'nofollow' : '';
|
210 |
+
|
211 |
+
if ( $thirstylink->get_prop( 'rel_tags' ) )
|
212 |
+
$link_attributes[ 'rel' ] = trim( $link_attributes[ 'rel' ] . ' ' . $thirstylink->get_prop( 'rel_tags' ) );
|
213 |
+
}
|
214 |
+
|
215 |
+
// check for new window defaults if no value is set
|
216 |
+
if ( empty( $link_attributes[ 'target' ] ) ) {
|
217 |
+
|
218 |
+
$link_attributes[ 'target' ] = $thirstylink->is( 'new_window' ) ? '_blank' : '';
|
219 |
+
}
|
220 |
+
|
221 |
+
// provide default class value if it is not set
|
222 |
+
if ( empty( $link_attributes[ 'class' ] ) ){
|
223 |
+
|
224 |
+
$link_attributes[ 'class' ] = get_option( 'ta_disable_thirsty_link_class' ) !== 'yes' ? 'thirstylink' : '';
|
225 |
+
|
226 |
+
if ( $thirstylink->get_prop( 'css_classes' ) )
|
227 |
+
$link_attributes[ 'class' ] = trim( $link_attributes[ 'class' ] . ' ' . $thirstylink->get_prop( 'css_classes' ) );
|
228 |
+
}
|
229 |
+
|
230 |
+
|
231 |
+
// provide default class value if it is not set
|
232 |
+
if ( empty( $link_attributes[ 'title' ] ) && get_option( 'ta_disable_title_attribute' ) !== 'yes' )
|
233 |
+
$link_attributes[ 'title' ] = $thirstylink->get_prop( 'name' );
|
234 |
+
|
235 |
+
// remove double quote character on title attribute.
|
236 |
+
$link_attributes[ 'title' ] = esc_attr( str_replace( '"' , '' , $link_attributes[ 'title' ] ) );
|
237 |
+
|
238 |
+
// add data-link_id attribute if affiliate link is uncloaked.
|
239 |
+
if ( $uncloak_link )
|
240 |
+
$link_attributes[ 'data-linkid' ] = $link_id;
|
241 |
+
|
242 |
+
// tag links as "nojs" to disable JS redirect for them.
|
243 |
+
if ( get_option( 'ta_enable_javascript_frontend_redirect' ) == 'yes' )
|
244 |
+
$link_attributes[ 'data-nojs' ] = apply_filters( 'ta_nojs_redirect_attribute' , false , $thirstylink );
|
245 |
+
|
246 |
+
// allow the ability to add custom link attributes
|
247 |
+
$link_attributes = apply_filters( 'ta_link_insert_extend_data_attributes' , $link_attributes , $thirstylink , $post_id );
|
248 |
+
|
249 |
+
// Build the link ready for output
|
250 |
+
$output .= '<a';
|
251 |
+
|
252 |
+
foreach ( $link_attributes as $name => $value ) {
|
253 |
+
// Handle square bracket escaping (used for some addons, eg. Google Analytics click tracking)
|
254 |
+
$value = html_entity_decode( $value );
|
255 |
+
$value = preg_replace( '/[/' , '[' , $value );
|
256 |
+
$value = preg_replace( '/]/' , ']' , $value );
|
257 |
+
$output .= ! empty($value) ? ' ' . $name . '="' . trim( esc_attr( $value ) ) . '"' : '';
|
258 |
+
}
|
259 |
+
|
260 |
+
$output .= ' data-shortcode="true">' . do_shortcode( $content ) . '</a>';
|
261 |
+
|
262 |
+
|
263 |
+
} else
|
264 |
+
$output .= '<span style="color: #0000ff;">' . __( 'SHORTCODE ERROR: ThirstyAffiliates did not detect a valid link id, please check your short code!' , 'thirstyaffiliates' ) . '</span>';
|
265 |
+
|
266 |
+
return $output;
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Remove parameters in the URL added via the get_permalink hook and escape it.
|
271 |
+
* Note: This is needed for WPML support.
|
272 |
+
*
|
273 |
+
* @since 3.2.1
|
274 |
+
* @access private
|
275 |
+
*
|
276 |
+
* @param string $raw_url Raw URL.
|
277 |
+
* @param string Cleaned URL.
|
278 |
+
*/
|
279 |
+
private function clean_url( $raw_url ) {
|
280 |
+
|
281 |
+
$parse = parse_url( $raw_url );
|
282 |
+
extract( $parse );
|
283 |
+
|
284 |
+
// rebuild url excluding parameters.
|
285 |
+
$url = $scheme . '://' . $host;
|
286 |
+
$url .= isset( $path ) ? $path : '';
|
287 |
+
|
288 |
+
return esc_url( $url );
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Execute shortcodes class.
|
293 |
+
*
|
294 |
+
* @since 3.0.0
|
295 |
+
* @access public
|
296 |
+
*/
|
297 |
+
public function run() {
|
298 |
+
|
299 |
+
add_shortcode( 'thirstylink' , array( $this , 'thirstylink_shortcode' ) );
|
300 |
+
}
|
301 |
+
}
|
Models/Stats_Reporting.php
CHANGED
@@ -1,1077 +1,1077 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace ThirstyAffiliates\Models;
|
4 |
-
|
5 |
-
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
-
|
7 |
-
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
-
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
-
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
10 |
-
|
11 |
-
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
12 |
-
use ThirstyAffiliates\Helpers\Helper_Functions;
|
13 |
-
|
14 |
-
use ThirstyAffiliates\Models\Affiliate_Link;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
18 |
-
*
|
19 |
-
* @since 3.0.0
|
20 |
-
*/
|
21 |
-
class Stats_Reporting implements Model_Interface , Initiable_Interface , Activatable_Interface {
|
22 |
-
|
23 |
-
/*
|
24 |
-
|--------------------------------------------------------------------------
|
25 |
-
| Class Properties
|
26 |
-
|--------------------------------------------------------------------------
|
27 |
-
*/
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Property that holds the single main instance of Stats_Reporting.
|
31 |
-
*
|
32 |
-
* @since 3.0.0
|
33 |
-
* @access private
|
34 |
-
* @var Redirection
|
35 |
-
*/
|
36 |
-
private static $_instance;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Model that houses the main plugin object.
|
40 |
-
*
|
41 |
-
* @since 3.0.0
|
42 |
-
* @access private
|
43 |
-
* @var Redirection
|
44 |
-
*/
|
45 |
-
private $_main_plugin;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Model that houses all the plugin constants.
|
49 |
-
*
|
50 |
-
* @since 3.0.0
|
51 |
-
* @access private
|
52 |
-
* @var Plugin_Constants
|
53 |
-
*/
|
54 |
-
private $_constants;
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Property that houses all the helper functions of the plugin.
|
58 |
-
*
|
59 |
-
* @since 3.0.0
|
60 |
-
* @access private
|
61 |
-
* @var Helper_Functions
|
62 |
-
*/
|
63 |
-
private $_helper_functions;
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Variable to store local browser's zone string.
|
67 |
-
*
|
68 |
-
* @since 3.2.2
|
69 |
-
* @access private
|
70 |
-
* @var string
|
71 |
-
*/
|
72 |
-
private $_browser_zone_str;
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
/*
|
78 |
-
|--------------------------------------------------------------------------
|
79 |
-
| Class Methods
|
80 |
-
|--------------------------------------------------------------------------
|
81 |
-
*/
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Class constructor.
|
85 |
-
*
|
86 |
-
* @since 3.0.0
|
87 |
-
* @access public
|
88 |
-
*
|
89 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
90 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
91 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
92 |
-
*/
|
93 |
-
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
94 |
-
|
95 |
-
$this->_constants = $constants;
|
96 |
-
$this->_helper_functions = $helper_functions;
|
97 |
-
|
98 |
-
$main_plugin->add_to_all_plugin_models( $this );
|
99 |
-
$main_plugin->add_to_public_models( $this );
|
100 |
-
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
105 |
-
*
|
106 |
-
* @since 3.0.0
|
107 |
-
* @access public
|
108 |
-
*
|
109 |
-
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
110 |
-
* @param Plugin_Constants $constants Plugin constants object.
|
111 |
-
* @param Helper_Functions $helper_functions Helper functions object.
|
112 |
-
* @return Redirection
|
113 |
-
*/
|
114 |
-
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
115 |
-
|
116 |
-
if ( !self::$_instance instanceof self )
|
117 |
-
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
118 |
-
|
119 |
-
return self::$_instance;
|
120 |
-
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Update $_browser_zone_str class property value.
|
125 |
-
*
|
126 |
-
* @since 3.3.3
|
127 |
-
* @access public
|
128 |
-
*
|
129 |
-
* @param string $timezone Timezone set on browser
|
130 |
-
*/
|
131 |
-
public function set_browser_zone_str( $timezone ) {
|
132 |
-
|
133 |
-
if ( in_array( $timezone , timezone_identifiers_list() ) )
|
134 |
-
$this->_browser_zone_str = $timezone;
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Register admin interfaces.
|
139 |
-
*
|
140 |
-
* @since 3.3.2
|
141 |
-
* @access public
|
142 |
-
*
|
143 |
-
* @param array $interfaces List of admin interfaces.
|
144 |
-
* @return array Filtered list of admin interfaces.
|
145 |
-
*/
|
146 |
-
public function register_admin_interfaces( $interfaces ) {
|
147 |
-
|
148 |
-
$interfaces[ 'thirstylink_page_thirsty-reports' ] = apply_filters( 'ta_reports_admin_interface' , array(
|
149 |
-
'link_performance' => 'manage_options'
|
150 |
-
) );
|
151 |
-
|
152 |
-
return $interfaces;
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Register admin interfaces.
|
157 |
-
*
|
158 |
-
* @since 3.3.2
|
159 |
-
* @access public
|
160 |
-
*
|
161 |
-
* @param array $interfaces List of menu items.
|
162 |
-
* @return array Filtered list of menu items.
|
163 |
-
*/
|
164 |
-
public function register_admin_menu_items( $menu_items ) {
|
165 |
-
|
166 |
-
$menu_items[ 'thirsty-reports' ] = 'manage_options';
|
167 |
-
return $menu_items;
|
168 |
-
}
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
/*
|
174 |
-
|--------------------------------------------------------------------------
|
175 |
-
| Data saving
|
176 |
-
|--------------------------------------------------------------------------
|
177 |
-
*/
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Save link click data to the database.
|
181 |
-
*
|
182 |
-
* @since 3.0.0
|
183 |
-
* @since 3.1.0 Set to save additional information: $cloaked_url , $redirect_url and $redirect_type.
|
184 |
-
* @since 3.2.0 Set to save additonal information: keyword.
|
185 |
-
* @since 3.4.0 Add tracking for browser/device.
|
186 |
-
* @access private
|
187 |
-
*
|
188 |
-
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
189 |
-
*
|
190 |
-
* @param Affiliate_Link $thirstylink Affiliate link object.
|
191 |
-
* @param string $http_referer HTTP Referrer value.
|
192 |
-
* @param string cloaked_url Affiliate link cloaked url.
|
193 |
-
* @param string $redirect_url Link to where user is redirected to.
|
194 |
-
* @param string $redirect_type Redirect type (301,302, etc.)
|
195 |
-
* @param string $keyword Affiliate link keyword.
|
196 |
-
*/
|
197 |
-
private function save_click_data( $thirstylink , $http_referer , $cloaked_url , $redirect_url , $redirect_type , $keyword = '' ) {
|
198 |
-
|
199 |
-
global $wpdb;
|
200 |
-
|
201 |
-
if ( apply_filters( 'ta_filter_before_save_click' , false , $thirstylink , $http_referer ) )
|
202 |
-
return;
|
203 |
-
|
204 |
-
$link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
205 |
-
$link_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
206 |
-
|
207 |
-
// insert click entry
|
208 |
-
$wpdb->insert(
|
209 |
-
$link_click_db,
|
210 |
-
array(
|
211 |
-
'link_id' => $thirstylink->get_id(),
|
212 |
-
'date_clicked' => current_time( 'mysql' , true )
|
213 |
-
)
|
214 |
-
);
|
215 |
-
|
216 |
-
// save click meta data
|
217 |
-
if ( $click_id = $wpdb->insert_id ) {
|
218 |
-
|
219 |
-
$meta_data = apply_filters( 'ta_save_click_data' , array(
|
220 |
-
'user_ip_address' => $this->_helper_functions->get_user_ip_address(),
|
221 |
-
'http_referer' => $http_referer,
|
222 |
-
'cloaked_url' => $cloaked_url,
|
223 |
-
'redirect_url' => $redirect_url,
|
224 |
-
'redirect_type' => $redirect_type,
|
225 |
-
'keyword' => $keyword,
|
226 |
-
'browser_device' => $this->_helper_functions->get_visitor_browser_device()
|
227 |
-
), $thirstylink );
|
228 |
-
|
229 |
-
foreach ( $meta_data as $key => $value ) {
|
230 |
-
|
231 |
-
// make sure there is a key and a value before saving.
|
232 |
-
if ( ! $key || ! $value )
|
233 |
-
continue;
|
234 |
-
|
235 |
-
$wpdb->insert(
|
236 |
-
$link_click_meta_db,
|
237 |
-
array(
|
238 |
-
'click_id' => $click_id,
|
239 |
-
'meta_key' => $key,
|
240 |
-
'meta_value' => $value
|
241 |
-
)
|
242 |
-
);
|
243 |
-
}
|
244 |
-
|
245 |
-
}
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Save click data on redirect
|
250 |
-
*
|
251 |
-
* @since 3.0.0
|
252 |
-
* @since 3.1.0 Passed additional 2 parameters: $redirect_url and $redirect type. Updated save_click_data function call to include new required arguments.
|
253 |
-
* @since 3.3.0 If enhanced javascript redirect in frontend is enabled, then all server redirects are allowed (with this, stats links clicked via "open new tab" will be saved).
|
254 |
-
* @access public
|
255 |
-
*
|
256 |
-
* @param Affiliate_Link $thirstylink Affiliate link object.
|
257 |
-
* @param string $redirect_url Link to where user is redirected to.
|
258 |
-
* @param string $redirect_type Redirect type (301,302, etc.)
|
259 |
-
*/
|
260 |
-
public function save_click_data_on_redirect( $thirstylink , $redirect_url , $redirect_type ) {
|
261 |
-
|
262 |
-
// make sure that this is only runs on the frontend and not on the backend.
|
263 |
-
if ( is_admin() ) return;
|
264 |
-
|
265 |
-
$link_id = $thirstylink->get_id();
|
266 |
-
$http_referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
|
267 |
-
$query_string = isset( $_SERVER[ 'QUERY_STRING' ] ) ? $_SERVER[ 'QUERY_STRING' ] : '';
|
268 |
-
$cloaked_url = $query_string ? $thirstylink->get_prop( 'permalink' ) . '?' . $query_string : $thirstylink->get_prop( 'permalink' );
|
269 |
-
|
270 |
-
$same_site = $http_referer && strrpos( 'x' . $http_referer , home_url() );
|
271 |
-
$admin_referrer = $http_referer && strrpos( 'x' . $http_referer , admin_url() );
|
272 |
-
$js_redirect_enabled = get_option( 'ta_enable_javascript_frontend_redirect' ) == 'yes';
|
273 |
-
|
274 |
-
// NOTE: this fixes a bug reported on TA-250
|
275 |
-
if ( $http_referer == $cloaked_url || $admin_referrer ) return;
|
276 |
-
|
277 |
-
// if the refferer is from an external site, then record stat.
|
278 |
-
if ( ( $same_site && $js_redirect_enabled ) || ! $same_site )
|
279 |
-
$this->save_click_data( $thirstylink , $http_referer , $cloaked_url , $redirect_url , $redirect_type );
|
280 |
-
}
|
281 |
-
|
282 |
-
/**
|
283 |
-
* AJAX save click data on redirect
|
284 |
-
*
|
285 |
-
* @since 3.0.0
|
286 |
-
* @since 3.1.0 Updated save_click_data function call to include new required arguments.
|
287 |
-
* @since 3.2.0 Updated save_click_data function call to include keyword argument.
|
288 |
-
* @since 3.3.0 print actual affiliate link redirect url for ehanced javascript redirect support.
|
289 |
-
* @since 3.4.0 Add query string as parameter to support passing query strings in enhanced JS redirect.
|
290 |
-
* @access public
|
291 |
-
*/
|
292 |
-
public function ajax_save_click_data_on_redirect() {
|
293 |
-
|
294 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
295 |
-
wp_die();
|
296 |
-
|
297 |
-
$link_id = isset( $_REQUEST[ 'link_id' ] ) ? (int) sanitize_text_field( $_REQUEST[ 'link_id' ] ) : 0;
|
298 |
-
$http_referer = isset( $_REQUEST[ 'page' ] ) ? esc_url_raw( $_REQUEST[ 'page' ] ) : '';
|
299 |
-
$cloaked_url = isset( $_REQUEST[ 'href' ] ) ? esc_url_raw( $_REQUEST[ 'href' ] ) : '';
|
300 |
-
$keyword = isset( $_REQUEST[ 'keyword' ] ) ? sanitize_text_field( $_REQUEST[ 'keyword' ] ) : '';
|
301 |
-
$query_string = isset( $_REQUEST[ 'qs' ] ) ? sanitize_text_field( $_REQUEST[ 'qs' ] ) : '';
|
302 |
-
|
303 |
-
if ( ! $link_id )
|
304 |
-
$link_id = url_to_postid( $cloaked_url );
|
305 |
-
|
306 |
-
if ( $link_id ) {
|
307 |
-
|
308 |
-
$thirstylink = new Affiliate_Link( $link_id );
|
309 |
-
$redirect_url = apply_filters( 'ta_filter_redirect_url' , $thirstylink->get_prop( 'destination_url' ) , $thirstylink , $query_string );
|
310 |
-
$redirect_type = $thirstylink->get_redirect_type();
|
311 |
-
|
312 |
-
$this->save_click_data( $thirstylink , $http_referer , $cloaked_url , $redirect_url , $redirect_type , $keyword );
|
313 |
-
|
314 |
-
// print actual affiliate link redirect url for enhanced javascript redirect support.
|
315 |
-
if ( get_option( 'ta_enable_javascript_frontend_redirect' ) == 'yes' )
|
316 |
-
echo $redirect_url;
|
317 |
-
}
|
318 |
-
|
319 |
-
wp_die();
|
320 |
-
}
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
/*
|
326 |
-
|--------------------------------------------------------------------------
|
327 |
-
| Fetch Report Data
|
328 |
-
|--------------------------------------------------------------------------
|
329 |
-
*/
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Fetch link performance data by date range.
|
333 |
-
*
|
334 |
-
* @since 3.0.0
|
335 |
-
* @access public
|
336 |
-
*
|
337 |
-
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
338 |
-
*
|
339 |
-
* @param string $start_date Report start date. Format: YYYY-MM-DD hh:mm:ss
|
340 |
-
* @param string $end_date Report end date. Format: YYYY-MM-DD hh:mm:ss
|
341 |
-
* @param array $link_ids Affiliate Link post ID
|
342 |
-
* @return string/array Link click meta data value.
|
343 |
-
*/
|
344 |
-
public function get_link_performance_data( $start_date , $end_date , $link_ids ) {
|
345 |
-
|
346 |
-
global $wpdb;
|
347 |
-
|
348 |
-
if ( ! is_array( $link_ids ) || empty( $link_ids ) )
|
349 |
-
return array();
|
350 |
-
|
351 |
-
$link_clicks_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
352 |
-
$link_ids_str = implode( ', ' , $link_ids );
|
353 |
-
$query = "SELECT * FROM $link_clicks_db WHERE date_clicked between '$start_date' and '$end_date' and link_id IN ( $link_ids_str )";
|
354 |
-
|
355 |
-
return $wpdb->get_results( $query );
|
356 |
-
}
|
357 |
-
|
358 |
-
/**
|
359 |
-
* Get link click meta by id and key.
|
360 |
-
*
|
361 |
-
* @since 3.0.0
|
362 |
-
* @access public
|
363 |
-
*
|
364 |
-
* @param int $click_id Link click ID.
|
365 |
-
* @param string $meta_key Meta key column value.
|
366 |
-
* @param boolean $single Return single result or array.
|
367 |
-
* @return array Link performance data.
|
368 |
-
*/
|
369 |
-
private function get_click_meta( $click_id , $meta_key , $single = false ) {
|
370 |
-
|
371 |
-
global $wpdb;
|
372 |
-
|
373 |
-
$links_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
374 |
-
|
375 |
-
if ( $single ){
|
376 |
-
|
377 |
-
$meta = $wpdb->get_row( "SELECT meta_value FROM $links_click_meta_db WHERE click_id = '$click_id' and meta_key = '$meta_key'" , ARRAY_A );
|
378 |
-
return array_shift( $meta );
|
379 |
-
|
380 |
-
} else {
|
381 |
-
|
382 |
-
$meta = array();
|
383 |
-
$raw_data = $wpdb->get_results( "SELECT meta_value FROM $links_click_meta_db WHERE click_id = '$click_id' and meta_key = '$meta_key'" , ARRAY_N );
|
384 |
-
|
385 |
-
foreach ( $raw_data as $data )
|
386 |
-
$meta[] = array_shift( $data );
|
387 |
-
|
388 |
-
return $meta;
|
389 |
-
}
|
390 |
-
}
|
391 |
-
|
392 |
-
/**
|
393 |
-
* AJAX fetch report by linkid.
|
394 |
-
*
|
395 |
-
* @since 3.0.0
|
396 |
-
* @since 3.1.2 Add total clicks count on the response.
|
397 |
-
* @access public
|
398 |
-
*/
|
399 |
-
public function ajax_fetch_report_by_linkid() {
|
400 |
-
|
401 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
402 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
403 |
-
elseif ( ! isset( $_POST[ 'link_id' ] ) )
|
404 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
405 |
-
else {
|
406 |
-
|
407 |
-
// save timezone to use
|
408 |
-
$timezone = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
|
409 |
-
$this->set_browser_zone_str( $timezone );
|
410 |
-
|
411 |
-
$link_id = isset( $_POST[ 'link_id' ] ) ? (int) sanitize_text_field( $_POST[ 'link_id' ] ) : 0;
|
412 |
-
$thirstylink = new Affiliate_Link( $link_id );
|
413 |
-
$range_txt = isset( $_POST[ 'range' ] ) ? sanitize_text_field( $_POST[ 'range' ] ) : '';
|
414 |
-
$start_date = isset( $_POST[ 'start_date' ] ) ? sanitize_text_field( $_POST[ 'start_date' ] ) : '';
|
415 |
-
$end_date = isset( $_POST[ 'end_date' ] ) ? sanitize_text_field( $_POST[ 'end_date' ] ) : '';
|
416 |
-
|
417 |
-
if ( ! $thirstylink->get_id() )
|
418 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Selected affiliate link is invalid' , 'thirstyaffiliates' ) );
|
419 |
-
else {
|
420 |
-
|
421 |
-
$range = $this->get_report_range_details( $range_txt , $start_date , $end_date );
|
422 |
-
$data = $this->prepare_data_for_flot( $range , array( $link_id ) );
|
423 |
-
|
424 |
-
$response = array(
|
425 |
-
'status' => 'success',
|
426 |
-
'label' => $thirstylink->get_prop( 'name' ),
|
427 |
-
'slug' => $thirstylink->get_prop( 'slug' ),
|
428 |
-
'report_data' => $data,
|
429 |
-
'total_clicks' => $this->count_total_clicks_from_flot_data( $data )
|
430 |
-
);
|
431 |
-
}
|
432 |
-
}
|
433 |
-
|
434 |
-
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
435 |
-
echo wp_json_encode( $response );
|
436 |
-
wp_die();
|
437 |
-
}
|
438 |
-
|
439 |
-
/**
|
440 |
-
* AJAX init first report.
|
441 |
-
*
|
442 |
-
* @since 3.2.2
|
443 |
-
* @access public
|
444 |
-
*/
|
445 |
-
public function ajax_init_first_report() {
|
446 |
-
|
447 |
-
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
448 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
449 |
-
elseif ( ! isset( $_POST[ 'timezone' ] ) )
|
450 |
-
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
451 |
-
else {
|
452 |
-
|
453 |
-
// save timezone to use
|
454 |
-
$timezone = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
|
455 |
-
$this->set_browser_zone_str( $timezone );
|
456 |
-
|
457 |
-
$cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
|
458 |
-
$current_range = isset( $_POST[ 'range' ] ) ? sanitize_text_field( $_POST[ 'range' ] ) : '7day';
|
459 |
-
$start_date = isset( $_POST[ 'start_date' ] ) ? sanitize_text_field( $_POST[ 'start_date' ] ) : '';
|
460 |
-
$end_date = isset( $_POST[ 'end_date' ] ) ? sanitize_text_field( $_POST[ 'end_date' ] ) : '';
|
461 |
-
$range = $this->get_report_range_details( $current_range , $start_date , $end_date );
|
462 |
-
|
463 |
-
// get all published affiliate link ids
|
464 |
-
$query = new \WP_Query( array(
|
465 |
-
'post_type' => $cpt_slug,
|
466 |
-
'post_status' => 'publish',
|
467 |
-
'fields' => 'ids',
|
468 |
-
'posts_per_page' => -1
|
469 |
-
) );
|
470 |
-
|
471 |
-
$data = $this->prepare_data_for_flot( $range , $query->posts );
|
472 |
-
$total_clicks = $this->count_total_clicks_from_flot_data( $data );
|
473 |
-
|
474 |
-
$response = array(
|
475 |
-
'status' => 'success',
|
476 |
-
'flot_data' => $data,
|
477 |
-
'total_clicks' => $total_clicks,
|
478 |
-
);
|
479 |
-
|
480 |
-
}
|
481 |
-
|
482 |
-
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
483 |
-
echo wp_json_encode( $response );
|
484 |
-
wp_die();
|
485 |
-
}
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
/*
|
491 |
-
|--------------------------------------------------------------------------
|
492 |
-
| Reports Structure
|
493 |
-
|--------------------------------------------------------------------------
|
494 |
-
*/
|
495 |
-
|
496 |
-
/**
|
497 |
-
* Get all registered reports.
|
498 |
-
*
|
499 |
-
* @since 3.0.0
|
500 |
-
* @access public
|
501 |
-
*
|
502 |
-
* @return array Settings sections.
|
503 |
-
*/
|
504 |
-
public function get_all_reports() {
|
505 |
-
|
506 |
-
return apply_filters( 'ta_register_reports' , array() );
|
507 |
-
}
|
508 |
-
|
509 |
-
/**
|
510 |
-
* Get current loaded report.
|
511 |
-
*
|
512 |
-
* @since 3.0.0
|
513 |
-
* @access public
|
514 |
-
*
|
515 |
-
* @param string $tab Current report tab.
|
516 |
-
* @return array Current loaded report.
|
517 |
-
*/
|
518 |
-
public function get_current_report( $tab = '' ) {
|
519 |
-
|
520 |
-
if ( ! $tab )
|
521 |
-
$tab = isset( $_GET[ 'tab' ] ) ? esc_attr( $_GET[ 'tab' ] ) : 'link_performance';
|
522 |
-
|
523 |
-
// get all registered sections and fields
|
524 |
-
$reports = $this->get_all_reports();
|
525 |
-
|
526 |
-
return isset( $reports[ $tab ] ) ? $reports[ $tab ] : array();
|
527 |
-
}
|
528 |
-
|
529 |
-
/**
|
530 |
-
* Register link performance report.
|
531 |
-
*
|
532 |
-
* @since 3.0.0
|
533 |
-
* @access public
|
534 |
-
*
|
535 |
-
* @param array $reports Array list of all registered reports.
|
536 |
-
* @return array Array list of all registered reports.
|
537 |
-
*/
|
538 |
-
public function register_link_performance_report( $reports ) {
|
539 |
-
|
540 |
-
$reports[ 'link_performance' ] = array(
|
541 |
-
'id' => 'ta_link_performance_report',
|
542 |
-
'tab' => 'link_performance',
|
543 |
-
'name' => __( 'Link Overview' , 'thirstyaffiliates' ),
|
544 |
-
'title' => __( 'Link Overview Report' , 'thirstyaffiliates' ),
|
545 |
-
'desc' => __( 'Total clicks on affiliate links over a given period.' , 'thirstyaffiliates' ),
|
546 |
-
'content' => function() { return $this->get_link_performance_report_content(); }
|
547 |
-
);
|
548 |
-
|
549 |
-
return $reports;
|
550 |
-
}
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
/*
|
556 |
-
|--------------------------------------------------------------------------
|
557 |
-
| Display Report
|
558 |
-
|--------------------------------------------------------------------------
|
559 |
-
*/
|
560 |
-
|
561 |
-
/**
|
562 |
-
* Register reports menu page.
|
563 |
-
*
|
564 |
-
* @since 3.0.0
|
565 |
-
* @since 3.2.2 Access to the settings page will now be controlled by the plugin. see Bootstrap::admin_interface_visibility.
|
566 |
-
*
|
567 |
-
* @access public
|
568 |
-
*/
|
569 |
-
public function add_reports_submenu() {
|
570 |
-
|
571 |
-
if ( ! current_user_can( 'edit_posts' ) ) return;
|
572 |
-
|
573 |
-
add_submenu_page(
|
574 |
-
'edit.php?post_type=thirstylink',
|
575 |
-
__( 'ThirstyAffiliates Reports' , 'thirstyaffiliates' ),
|
576 |
-
__( 'Reports' , 'thirstyaffiliates' ),
|
577 |
-
'read',
|
578 |
-
'thirsty-reports',
|
579 |
-
array( $this, 'render_reports' )
|
580 |
-
);
|
581 |
-
}
|
582 |
-
|
583 |
-
/**
|
584 |
-
* Render reports page.
|
585 |
-
*
|
586 |
-
* @since 3.0.0
|
587 |
-
* @access public
|
588 |
-
*/
|
589 |
-
public function render_reports() {
|
590 |
-
|
591 |
-
// fetch current section
|
592 |
-
$current_report = $this->get_current_report();
|
593 |
-
$report_content = is_callable( $current_report[ 'content' ] ) ? $current_report[ 'content' ]() : $current_report[ 'content' ];
|
594 |
-
|
595 |
-
// skip if section data is empty
|
596 |
-
if ( empty( $current_report ) ) return; ?>
|
597 |
-
|
598 |
-
<div class="ta-settings ta-settings-<?php echo $current_report[ 'tab' ]; ?> wrap">
|
599 |
-
|
600 |
-
<?php $this->render_reports_nav(); ?>
|
601 |
-
|
602 |
-
<h1><?php echo $current_report[ 'title' ]; ?></h1>
|
603 |
-
<p class="desc"><?php echo $current_report[ 'desc' ]; ?></p>
|
604 |
-
|
605 |
-
<?php echo $report_content; ?>
|
606 |
-
</div>
|
607 |
-
<?php
|
608 |
-
}
|
609 |
-
|
610 |
-
/**
|
611 |
-
* Render the settings navigation.
|
612 |
-
*
|
613 |
-
* @since 3.0.0
|
614 |
-
* @access public
|
615 |
-
*/
|
616 |
-
public function render_reports_nav() {
|
617 |
-
|
618 |
-
$reports = $this->get_all_reports();
|
619 |
-
$current = $this->get_current_report();
|
620 |
-
$base_url = admin_url( 'edit.php?post_type=thirstylink&page=thirsty-reports' );
|
621 |
-
|
622 |
-
if ( empty( $reports ) ) return; ?>
|
623 |
-
|
624 |
-
<nav class="thirsty-nav-tab">
|
625 |
-
<?php foreach ( $reports as $report ) : ?>
|
626 |
-
|
627 |
-
<a href="<?php echo $base_url . '&tab=' . $report[ 'tab' ]; ?>" class="tab <?php echo ( $current[ 'tab' ] === $report[ 'tab' ] ) ? 'tab-active' : ''; ?>">
|
628 |
-
<?php echo $report[ 'name' ]; ?>
|
629 |
-
</a>
|
630 |
-
|
631 |
-
<?php endforeach; ?>
|
632 |
-
</nav>
|
633 |
-
|
634 |
-
<?php
|
635 |
-
}
|
636 |
-
|
637 |
-
/**
|
638 |
-
* Get Link performance report content.
|
639 |
-
*
|
640 |
-
* @since 3.0.0
|
641 |
-
* @since 3.3.2 Remove report data query on page first load.
|
642 |
-
* @access public
|
643 |
-
*
|
644 |
-
* @return string Link performance report content.
|
645 |
-
*/
|
646 |
-
public function get_link_performance_report_content() {
|
647 |
-
|
648 |
-
$cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
|
649 |
-
$current_range = isset( $_GET[ 'range' ] ) ? sanitize_text_field( $_GET[ 'range' ] ) : '7day';
|
650 |
-
$start_date = isset( $_GET[ 'start_date' ] ) ? sanitize_text_field( $_GET[ 'start_date' ] ) : '';
|
651 |
-
$end_date = isset( $_GET[ 'end_date' ] ) ? sanitize_text_field( $_GET[ 'end_date' ] ) : '';
|
652 |
-
$link_id = isset( $_GET[ 'link_id' ] ) ? sanitize_text_field( $_GET[ 'link_id' ] ) : '';
|
653 |
-
$range = $this->get_report_range_details( $current_range , $start_date , $end_date );
|
654 |
-
$range_nav = apply_filters( 'ta_link_performances_report_nav' , array(
|
655 |
-
'year' => __( 'Year' , 'thirstyaffiliates' ),
|
656 |
-
'last_month' => __( 'Last Month' , 'thirstyaffiliates' ),
|
657 |
-
'month' => __( 'This Month' , 'thirstyaffiliates' ),
|
658 |
-
'7day' => __( 'Last 7 Days' , 'thirstyaffiliates' )
|
659 |
-
) );
|
660 |
-
|
661 |
-
// make sure link_id is an affiliate link (published).
|
662 |
-
// NOTE: when false, this needs to return an empty string as it is used for display.
|
663 |
-
if ( $link_id ) $link_id = ( get_post_type( $link_id ) == $cpt_slug && get_post_status( $link_id ) == 'publish' ) ? $link_id : '';
|
664 |
-
|
665 |
-
ob_start();
|
666 |
-
include( $this->_constants->VIEWS_ROOT_PATH() . 'reports/link-performance-report.php' );
|
667 |
-
|
668 |
-
return ob_get_clean();
|
669 |
-
}
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
/*
|
675 |
-
|--------------------------------------------------------------------------
|
676 |
-
| Helper methods
|
677 |
-
|--------------------------------------------------------------------------
|
678 |
-
*/
|
679 |
-
|
680 |
-
/**
|
681 |
-
* Get report range details.
|
682 |
-
*
|
683 |
-
* @since 3.0.0
|
684 |
-
* @since 3.2.2 Change method of getting timezone sting name.
|
685 |
-
* @access public
|
686 |
-
*
|
687 |
-
* @param string $range Report range type.
|
688 |
-
* @param string $start_date Starting date of range.
|
689 |
-
* @param string $end_date Ending date of range.
|
690 |
-
* @return array Report range details.
|
691 |
-
*/
|
692 |
-
public function get_report_range_details( $range = '7day' , $start_date = 'now -6 days' , $end_date = 'now' ) {
|
693 |
-
|
694 |
-
$data = array();
|
695 |
-
$zone_str = $this->get_report_timezone_string();
|
696 |
-
$timezone = new \DateTimeZone( $zone_str );
|
697 |
-
$now = new \DateTime( 'now' , $timezone );
|
698 |
-
|
699 |
-
switch ( $range ) {
|
700 |
-
|
701 |
-
case 'year' :
|
702 |
-
$data[ 'type' ] = 'year';
|
703 |
-
$data[ 'start_date' ] = new \DateTime( 'first day of January' . date( 'Y' ) , $timezone );
|
704 |
-
$data[ 'end_date' ] = $now;
|
705 |
-
break;
|
706 |
-
|
707 |
-
case 'last_month' :
|
708 |
-
$data[ 'type' ] = 'last_month';
|
709 |
-
$data[ 'start_date' ] = new \DateTime( 'first day of last month' , $timezone );
|
710 |
-
$data[ 'end_date' ] = new \DateTime( 'last day of last month' , $timezone );
|
711 |
-
break;
|
712 |
-
|
713 |
-
case 'month' :
|
714 |
-
$data[ 'type' ] = 'month';
|
715 |
-
$data[ 'start_date' ] = new \DateTime( 'first day of this month' , $timezone );
|
716 |
-
$data[ 'end_date' ] = $now;
|
717 |
-
$data[ 'start_date' ]->setTime( 0 , 0 , 0 );
|
718 |
-
break;
|
719 |
-
|
720 |
-
case 'custom' :
|
721 |
-
$data[ 'type' ] = 'custom';
|
722 |
-
$data[ 'start_date' ] = new \DateTime( $start_date , $timezone );
|
723 |
-
$data[ 'end_date' ] = new \DateTime( $end_date . ' 23:59:59' , $timezone );
|
724 |
-
break;
|
725 |
-
|
726 |
-
case '7day' :
|
727 |
-
default :
|
728 |
-
$start_date = new \DateTime( 'now -6 days' , $timezone );
|
729 |
-
|
730 |
-
// set hours, minutes and seconds to zero
|
731 |
-
$start_date->setTime( 0 , 0 , 0 );
|
732 |
-
$now->setTime( 23 , 59 , 59 );
|
733 |
-
|
734 |
-
$data[ 'type' ] = '7day';
|
735 |
-
$data[ 'start_date' ] = $start_date;
|
736 |
-
$data[ 'end_date' ] = $now;
|
737 |
-
break;
|
738 |
-
}
|
739 |
-
|
740 |
-
return apply_filters( 'ta_report_range_data' , $data , $range );
|
741 |
-
}
|
742 |
-
|
743 |
-
/**
|
744 |
-
* Prepare data to feed for jQuery flot.
|
745 |
-
*
|
746 |
-
* @since 3.0.0
|
747 |
-
* @since 3.2.2 Change method of getting timezone sting name.
|
748 |
-
* @since 3.3.3 Set range timezone to UTC before fetching raw data.
|
749 |
-
* @since 3.3.4 Set date range timezone back to local browser before setting start time to zero.
|
750 |
-
* @access public
|
751 |
-
*
|
752 |
-
* @param array $range Report range details
|
753 |
-
* @param array $link_ids Affiliate Link post ID
|
754 |
-
* @return array Processed data for jQuery flot.
|
755 |
-
*/
|
756 |
-
public function prepare_data_for_flot( $range , $link_ids ) {
|
757 |
-
|
758 |
-
$start_date = $range[ 'start_date' ];
|
759 |
-
$end_date = $range[ 'end_date' ];
|
760 |
-
$zone_str = $this->get_report_timezone_string();
|
761 |
-
$timezone = new \DateTimeZone( $zone_str );
|
762 |
-
$utc = new \DateTimeZone( 'UTC' );
|
763 |
-
$flot_data = array();
|
764 |
-
|
765 |
-
$start_date->setTimezone( $timezone );
|
766 |
-
$end_date->setTimezone( $timezone );
|
767 |
-
|
768 |
-
if ( apply_filters( 'ta_report_set_start_date_time_to_zero' , true , $range ) )
|
769 |
-
$start_date->setTime( 0 , 0 );
|
770 |
-
|
771 |
-
$start_date->setTimezone( $utc );
|
772 |
-
$end_date->setTimezone( $utc );
|
773 |
-
|
774 |
-
$raw_data = $this->get_link_performance_data( $start_date->format( 'Y-m-d H:i:s' ) , $end_date->format( 'Y-m-d H:i:s' ) , $link_ids );
|
775 |
-
|
776 |
-
// get number of days difference between start and end
|
777 |
-
$incrementor = apply_filters( 'ta_report_flot_data_incrementor' , ( 60 * 60 * 24 ) , $range );
|
778 |
-
$timestamp_diff = ( $start_date->getTimestamp() - $end_date->getTimestamp() );
|
779 |
-
$days_diff = abs( floor( $timestamp_diff / $incrementor ) );
|
780 |
-
|
781 |
-
// save the timestamp for first day
|
782 |
-
$timestamp = $start_date->format( 'U' );
|
783 |
-
$month_time = $this->get_month_first_day_datetime_obj( 'February' );
|
784 |
-
$next_timestamp = ( $range[ 'type' ] == 'year' ) ? $month_time->format( 'U' ) : $timestamp + $incrementor;
|
785 |
-
$flot_data[] = array(
|
786 |
-
'timestamp' => (int) $timestamp,
|
787 |
-
'count' => 0,
|
788 |
-
'next_timestamp' => $next_timestamp
|
789 |
-
);
|
790 |
-
|
791 |
-
if ( $range[ 'type' ] == 'year' ) {
|
792 |
-
|
793 |
-
$months = array( 'February' , 'March' , 'April' , 'May' , 'June' , 'July' , 'August' , 'September' , 'October' , 'November' , 'December' );
|
794 |
-
|
795 |
-
foreach ( $months as $key => $month ) {
|
796 |
-
|
797 |
-
$month_time = $this->get_month_first_day_datetime_obj( $month );
|
798 |
-
$next_month = isset( $months[ $key + 1 ] ) ? $this->get_month_first_day_datetime_obj( $months[ $key + 1 ] ) : new \DateTime( 'now' , $timezone );
|
799 |
-
|
800 |
-
$flot_data[] = array(
|
801 |
-
'timestamp' => $month_time->format( 'U' ),
|
802 |
-
'count' => 0,
|
803 |
-
'next_timestamp' => $next_month->format( 'U' )
|
804 |
-
);
|
805 |
-
|
806 |
-
if ( $end_date->format( 'F' ) == $month )
|
807 |
-
break;
|
808 |
-
}
|
809 |
-
|
810 |
-
} else {
|
811 |
-
|
812 |
-
// determine timestamps for succeeding days
|
813 |
-
for ( $x = 1; $x < $days_diff; $x++ ) {
|
814 |
-
|
815 |
-
$timestamp = $next_timestamp;
|
816 |
-
$next_timestamp = $timestamp + $incrementor;
|
817 |
-
|
818 |
-
$flot_data[] = array(
|
819 |
-
'timestamp' => (int) $timestamp,
|
820 |
-
'count' => 0,
|
821 |
-
'next_timestamp' => $next_timestamp
|
822 |
-
);
|
823 |
-
|
824 |
-
}
|
825 |
-
}
|
826 |
-
|
827 |
-
// count each click data and assign to appropriate day.
|
828 |
-
foreach ( $raw_data as $click_entry ) {
|
829 |
-
|
830 |
-
$click_date = new \DateTime( $click_entry->date_clicked , $utc );
|
831 |
-
$click_date->setTimezone( $timezone );
|
832 |
-
|
833 |
-
$click_timestamp = (int) $click_date->format( 'U' );
|
834 |
-
|
835 |
-
foreach ( $flot_data as $key => $day_data ) {
|
836 |
-
|
837 |
-
if ( $click_timestamp >= $day_data[ 'timestamp' ] && $click_timestamp < $day_data[ 'next_timestamp' ] ) {
|
838 |
-
$flot_data[ $key ][ 'count' ] += 1;
|
839 |
-
continue;
|
840 |
-
}
|
841 |
-
}
|
842 |
-
}
|
843 |
-
|
844 |
-
// convert $flot_data array into non-associative array
|
845 |
-
foreach ( $flot_data as $key => $day_data ) {
|
846 |
-
|
847 |
-
unset( $day_data[ 'next_timestamp' ] );
|
848 |
-
|
849 |
-
$day_data[ 'timestamp' ] = $day_data[ 'timestamp' ] * 1000;
|
850 |
-
$flot_data[ $key ] = array_values( $day_data );
|
851 |
-
}
|
852 |
-
|
853 |
-
return $flot_data;
|
854 |
-
}
|
855 |
-
|
856 |
-
/**
|
857 |
-
* Count total clicks from flot data.
|
858 |
-
*
|
859 |
-
* @since 3.2.1
|
860 |
-
* @access public
|
861 |
-
*
|
862 |
-
* @param array $data Flot data.
|
863 |
-
* @param int $total Total click counts (offset).
|
864 |
-
* @return int Total click clounts.
|
865 |
-
*/
|
866 |
-
public function count_total_clicks_from_flot_data( $data , $total = 0 ) {
|
867 |
-
|
868 |
-
if ( ! is_array( $data ) || empty( $data ) )
|
869 |
-
return;
|
870 |
-
|
871 |
-
foreach ( $data as $flot )
|
872 |
-
$total += intval( $flot[1] );
|
873 |
-
|
874 |
-
return $total;
|
875 |
-
}
|
876 |
-
|
877 |
-
/**
|
878 |
-
* Get the DateTime object of the first day of a given month.
|
879 |
-
*
|
880 |
-
* @since 3.0.0
|
881 |
-
* @since 3.2.2 Change method of getting timezone sting name.
|
882 |
-
* @access public
|
883 |
-
*
|
884 |
-
* @param string $month Month full textual representation.
|
885 |
-
* @return DateTime First day of the given month DateTime object.
|
886 |
-
*/
|
887 |
-
public function get_month_first_day_datetime_obj( $month ) {
|
888 |
-
|
889 |
-
$zone_str = $this->get_report_timezone_string();
|
890 |
-
$timezone = new \DateTimeZone( $zone_str );
|
891 |
-
|
892 |
-
return new \DateTime( 'First day of ' . $month . ' ' . date( 'Y' ) , $timezone );
|
893 |
-
}
|
894 |
-
|
895 |
-
/**
|
896 |
-
* Schedule stats trimmer cron job.
|
897 |
-
*
|
898 |
-
* @since 3.1.0
|
899 |
-
* @access private
|
900 |
-
*/
|
901 |
-
private function schedule_stats_trimmer_cron() {
|
902 |
-
|
903 |
-
$zone_str = $this->_helper_functions->get_site_current_timezone();
|
904 |
-
$timezone = new \DateTimeZone( $zone_str );
|
905 |
-
$time = new \DateTime( 'first day of next month' , $timezone );
|
906 |
-
|
907 |
-
// clear all scheduled crons so there will always only be one.
|
908 |
-
wp_clear_scheduled_hook( Plugin_Constants::CRON_STATS_TRIMMER );
|
909 |
-
|
910 |
-
// schedule cron job
|
911 |
-
wp_schedule_single_event( $time->format( 'U' ) , Plugin_Constants::CRON_STATS_TRIMMER );
|
912 |
-
}
|
913 |
-
|
914 |
-
/**
|
915 |
-
* Implement stats trimmer
|
916 |
-
*
|
917 |
-
* @since 3.1.0
|
918 |
-
* @access public
|
919 |
-
*
|
920 |
-
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
921 |
-
*/
|
922 |
-
public function implement_stats_trimmer() {
|
923 |
-
|
924 |
-
global $wpdb;
|
925 |
-
|
926 |
-
$trim_point = (int) get_option( 'ta_stats_trimer_set_point' , 0 );
|
927 |
-
|
928 |
-
if ( $trim_point > 0 ) {
|
929 |
-
|
930 |
-
$clicks_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
931 |
-
$clicks_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
932 |
-
|
933 |
-
// get click ids based on set range.
|
934 |
-
$query = "SELECT id FROM $clicks_db WHERE date_clicked < DATE_ADD( NOW() , INTERVAL -" . $trim_point . " MONTH )";
|
935 |
-
$click_ids = $wpdb->get_col( $query );
|
936 |
-
|
937 |
-
// Proceed on deleting data when $click_ids are present
|
938 |
-
if ( is_array( $click_ids ) && ! empty( $click_ids ) ) {
|
939 |
-
|
940 |
-
$click_ids_string = implode( $click_ids , ',' );
|
941 |
-
|
942 |
-
// delete click data
|
943 |
-
$wpdb->query( "DELETE FROM $clicks_meta_db WHERE click_id IN ( $click_ids_string )" );
|
944 |
-
$wpdb->query( "DELETE FROM $clicks_db WHERE id IN ( $click_ids_string )" );
|
945 |
-
}
|
946 |
-
}
|
947 |
-
|
948 |
-
// reschedule the cron job
|
949 |
-
$this->schedule_stats_trimmer_cron();
|
950 |
-
}
|
951 |
-
|
952 |
-
/**
|
953 |
-
* Prevent saving click data if useragent is a bot (for non-apache servers).
|
954 |
-
*
|
955 |
-
* @since 3.1.0
|
956 |
-
* @since 3.3.3 Moved code to a helper function (DRY).
|
957 |
-
* @access public
|
958 |
-
*
|
959 |
-
* @param boolean $response Default response of filter.
|
960 |
-
* @return boolean True if needs to be prevented, false otherwise.
|
961 |
-
*/
|
962 |
-
public function prevent_save_click_if_useragent_is_bot( $response ) {
|
963 |
-
|
964 |
-
return $this->_helper_functions->is_user_agent_bot();
|
965 |
-
}
|
966 |
-
|
967 |
-
/**
|
968 |
-
* Delete stats data when an affiliate link is deleted permanently.
|
969 |
-
*
|
970 |
-
* @since 3.0.1
|
971 |
-
* @access public
|
972 |
-
*
|
973 |
-
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
974 |
-
*
|
975 |
-
* @param int $link_id Affiliate link ID.
|
976 |
-
*/
|
977 |
-
public function delete_stats_data_on_affiliate_link_deletion( $link_id ) {
|
978 |
-
|
979 |
-
global $wpdb;
|
980 |
-
|
981 |
-
if ( Plugin_Constants::AFFILIATE_LINKS_CPT !== get_post_type( $link_id ) )
|
982 |
-
return;
|
983 |
-
|
984 |
-
$link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
985 |
-
$link_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
986 |
-
$click_ids = $wpdb->get_col( "SELECT id FROM $link_click_db WHERE link_id = $link_id" );
|
987 |
-
|
988 |
-
if ( ! is_array( $click_ids ) || empty( $click_ids ) )
|
989 |
-
return;
|
990 |
-
|
991 |
-
$click_ids_str = implode( ',' , $click_ids );
|
992 |
-
|
993 |
-
// delete click meta records.
|
994 |
-
$wpdb->query( "DELETE FROM $link_click_meta_db WHERE click_id IN ( $click_ids_str )" );
|
995 |
-
|
996 |
-
// delete click records.
|
997 |
-
$wpdb->query( "DELETE FROM $link_click_db WHERE id IN ( $click_ids_str )" );
|
998 |
-
}
|
999 |
-
|
1000 |
-
/**
|
1001 |
-
* Get timezone to use for the report.
|
1002 |
-
*
|
1003 |
-
* @since 3.2.2
|
1004 |
-
* @since 3.3.3 Made the method public so TAP can utilize it.
|
1005 |
-
* @access public
|
1006 |
-
*
|
1007 |
-
* @return string Timezone string name.
|
1008 |
-
*/
|
1009 |
-
public function get_report_timezone_string() {
|
1010 |
-
|
1011 |
-
return $this->_browser_zone_str ? $this->_browser_zone_str : $this->_helper_functions->get_site_current_timezone();
|
1012 |
-
}
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
/*
|
1018 |
-
|--------------------------------------------------------------------------
|
1019 |
-
| Fulfill implemented interface contracts
|
1020 |
-
|--------------------------------------------------------------------------
|
1021 |
-
*/
|
1022 |
-
|
1023 |
-
/**
|
1024 |
-
* Execute codes that needs to run plugin activation.
|
1025 |
-
*
|
1026 |
-
* @since 3.0.0
|
1027 |
-
* @access public
|
1028 |
-
* @implements ThirstyAffiliates\Interfaces\Activatable_Interface
|
1029 |
-
*/
|
1030 |
-
public function activate() {
|
1031 |
-
|
1032 |
-
$this->schedule_stats_trimmer_cron();
|
1033 |
-
}
|
1034 |
-
|
1035 |
-
/**
|
1036 |
-
* Method that houses codes to be executed on init hook.
|
1037 |
-
*
|
1038 |
-
* @since 3.0.0
|
1039 |
-
* @access public
|
1040 |
-
* @inherit ThirstyAffiliates\Interfaces\Initiable_Interface
|
1041 |
-
*/
|
1042 |
-
public function initialize() {
|
1043 |
-
|
1044 |
-
// When module is disabled in the settings, then it shouldn't run the whole class.
|
1045 |
-
if ( get_option( 'ta_enable_stats_reporting_module' , 'yes' ) !== 'yes' )
|
1046 |
-
return;
|
1047 |
-
|
1048 |
-
add_action( 'wp_ajax_ta_click_data_redirect' , array( $this , 'ajax_save_click_data_on_redirect' ) , 10 );
|
1049 |
-
add_action( 'wp_ajax_ta_fetch_report_by_linkid' , array( $this , 'ajax_fetch_report_by_linkid' ) , 10 );
|
1050 |
-
add_action( 'wp_ajax_ta_init_first_report' , array( $this , 'ajax_init_first_report' ) , 10 );
|
1051 |
-
add_action( 'wp_ajax_nopriv_ta_click_data_redirect' , array( $this , 'ajax_save_click_data_on_redirect' ) , 10 );
|
1052 |
-
}
|
1053 |
-
|
1054 |
-
/**
|
1055 |
-
* Execute ajax handler.
|
1056 |
-
*
|
1057 |
-
* @since 3.0.0
|
1058 |
-
* @access public
|
1059 |
-
* @inherit ThirstyAffiliates\Interfaces\Model_Interface
|
1060 |
-
*/
|
1061 |
-
public function run() {
|
1062 |
-
|
1063 |
-
// When module is disabled in the settings, then it shouldn't run the whole class.
|
1064 |
-
if ( get_option( 'ta_enable_stats_reporting_module' , 'yes' ) !== 'yes' )
|
1065 |
-
return;
|
1066 |
-
|
1067 |
-
add_filter( 'ta_filter_before_save_click' , array( $this , 'prevent_save_click_if_useragent_is_bot' ) , 10 , 1 );
|
1068 |
-
add_action( 'ta_before_link_redirect' , array( $this , 'save_click_data_on_redirect' ) , 10 , 3 );
|
1069 |
-
add_action( 'admin_menu' , array( $this , 'add_reports_submenu' ) , 10 );
|
1070 |
-
add_action( 'ta_register_reports' , array( $this , 'register_link_performance_report' ) , 10 );
|
1071 |
-
add_action( Plugin_Constants::CRON_STATS_TRIMMER , array( $this , 'implement_stats_trimmer' ) );
|
1072 |
-
add_action( 'before_delete_post' , array( $this , 'delete_stats_data_on_affiliate_link_deletion' ) , 10 );
|
1073 |
-
|
1074 |
-
add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
|
1075 |
-
add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
|
1076 |
-
}
|
1077 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ThirstyAffiliates\Models;
|
4 |
+
|
5 |
+
use ThirstyAffiliates\Abstracts\Abstract_Main_Plugin_Class;
|
6 |
+
|
7 |
+
use ThirstyAffiliates\Interfaces\Model_Interface;
|
8 |
+
use ThirstyAffiliates\Interfaces\Initiable_Interface;
|
9 |
+
use ThirstyAffiliates\Interfaces\Activatable_Interface;
|
10 |
+
|
11 |
+
use ThirstyAffiliates\Helpers\Plugin_Constants;
|
12 |
+
use ThirstyAffiliates\Helpers\Helper_Functions;
|
13 |
+
|
14 |
+
use ThirstyAffiliates\Models\Affiliate_Link;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Model that houses the logic for permalink rewrites and affiliate link redirections.
|
18 |
+
*
|
19 |
+
* @since 3.0.0
|
20 |
+
*/
|
21 |
+
class Stats_Reporting implements Model_Interface , Initiable_Interface , Activatable_Interface {
|
22 |
+
|
23 |
+
/*
|
24 |
+
|--------------------------------------------------------------------------
|
25 |
+
| Class Properties
|
26 |
+
|--------------------------------------------------------------------------
|
27 |
+
*/
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Property that holds the single main instance of Stats_Reporting.
|
31 |
+
*
|
32 |
+
* @since 3.0.0
|
33 |
+
* @access private
|
34 |
+
* @var Redirection
|
35 |
+
*/
|
36 |
+
private static $_instance;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Model that houses the main plugin object.
|
40 |
+
*
|
41 |
+
* @since 3.0.0
|
42 |
+
* @access private
|
43 |
+
* @var Redirection
|
44 |
+
*/
|
45 |
+
private $_main_plugin;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Model that houses all the plugin constants.
|
49 |
+
*
|
50 |
+
* @since 3.0.0
|
51 |
+
* @access private
|
52 |
+
* @var Plugin_Constants
|
53 |
+
*/
|
54 |
+
private $_constants;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Property that houses all the helper functions of the plugin.
|
58 |
+
*
|
59 |
+
* @since 3.0.0
|
60 |
+
* @access private
|
61 |
+
* @var Helper_Functions
|
62 |
+
*/
|
63 |
+
private $_helper_functions;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Variable to store local browser's zone string.
|
67 |
+
*
|
68 |
+
* @since 3.2.2
|
69 |
+
* @access private
|
70 |
+
* @var string
|
71 |
+
*/
|
72 |
+
private $_browser_zone_str;
|
73 |
+
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
/*
|
78 |
+
|--------------------------------------------------------------------------
|
79 |
+
| Class Methods
|
80 |
+
|--------------------------------------------------------------------------
|
81 |
+
*/
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Class constructor.
|
85 |
+
*
|
86 |
+
* @since 3.0.0
|
87 |
+
* @access public
|
88 |
+
*
|
89 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
90 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
91 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
92 |
+
*/
|
93 |
+
public function __construct( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
94 |
+
|
95 |
+
$this->_constants = $constants;
|
96 |
+
$this->_helper_functions = $helper_functions;
|
97 |
+
|
98 |
+
$main_plugin->add_to_all_plugin_models( $this );
|
99 |
+
$main_plugin->add_to_public_models( $this );
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Ensure that only one instance of this class is loaded or can be loaded ( Singleton Pattern ).
|
105 |
+
*
|
106 |
+
* @since 3.0.0
|
107 |
+
* @access public
|
108 |
+
*
|
109 |
+
* @param Abstract_Main_Plugin_Class $main_plugin Main plugin object.
|
110 |
+
* @param Plugin_Constants $constants Plugin constants object.
|
111 |
+
* @param Helper_Functions $helper_functions Helper functions object.
|
112 |
+
* @return Redirection
|
113 |
+
*/
|
114 |
+
public static function get_instance( Abstract_Main_Plugin_Class $main_plugin , Plugin_Constants $constants , Helper_Functions $helper_functions ) {
|
115 |
+
|
116 |
+
if ( !self::$_instance instanceof self )
|
117 |
+
self::$_instance = new self( $main_plugin , $constants , $helper_functions );
|
118 |
+
|
119 |
+
return self::$_instance;
|
120 |
+
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Update $_browser_zone_str class property value.
|
125 |
+
*
|
126 |
+
* @since 3.3.3
|
127 |
+
* @access public
|
128 |
+
*
|
129 |
+
* @param string $timezone Timezone set on browser
|
130 |
+
*/
|
131 |
+
public function set_browser_zone_str( $timezone ) {
|
132 |
+
|
133 |
+
if ( in_array( $timezone , timezone_identifiers_list() ) )
|
134 |
+
$this->_browser_zone_str = $timezone;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Register admin interfaces.
|
139 |
+
*
|
140 |
+
* @since 3.3.2
|
141 |
+
* @access public
|
142 |
+
*
|
143 |
+
* @param array $interfaces List of admin interfaces.
|
144 |
+
* @return array Filtered list of admin interfaces.
|
145 |
+
*/
|
146 |
+
public function register_admin_interfaces( $interfaces ) {
|
147 |
+
|
148 |
+
$interfaces[ 'thirstylink_page_thirsty-reports' ] = apply_filters( 'ta_reports_admin_interface' , array(
|
149 |
+
'link_performance' => 'manage_options'
|
150 |
+
) );
|
151 |
+
|
152 |
+
return $interfaces;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Register admin interfaces.
|
157 |
+
*
|
158 |
+
* @since 3.3.2
|
159 |
+
* @access public
|
160 |
+
*
|
161 |
+
* @param array $interfaces List of menu items.
|
162 |
+
* @return array Filtered list of menu items.
|
163 |
+
*/
|
164 |
+
public function register_admin_menu_items( $menu_items ) {
|
165 |
+
|
166 |
+
$menu_items[ 'thirsty-reports' ] = 'manage_options';
|
167 |
+
return $menu_items;
|
168 |
+
}
|
169 |
+
|
170 |
+
|
171 |
+
|
172 |
+
|
173 |
+
/*
|
174 |
+
|--------------------------------------------------------------------------
|
175 |
+
| Data saving
|
176 |
+
|--------------------------------------------------------------------------
|
177 |
+
*/
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Save link click data to the database.
|
181 |
+
*
|
182 |
+
* @since 3.0.0
|
183 |
+
* @since 3.1.0 Set to save additional information: $cloaked_url , $redirect_url and $redirect_type.
|
184 |
+
* @since 3.2.0 Set to save additonal information: keyword.
|
185 |
+
* @since 3.4.0 Add tracking for browser/device.
|
186 |
+
* @access private
|
187 |
+
*
|
188 |
+
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
189 |
+
*
|
190 |
+
* @param Affiliate_Link $thirstylink Affiliate link object.
|
191 |
+
* @param string $http_referer HTTP Referrer value.
|
192 |
+
* @param string cloaked_url Affiliate link cloaked url.
|
193 |
+
* @param string $redirect_url Link to where user is redirected to.
|
194 |
+
* @param string $redirect_type Redirect type (301,302, etc.)
|
195 |
+
* @param string $keyword Affiliate link keyword.
|
196 |
+
*/
|
197 |
+
private function save_click_data( $thirstylink , $http_referer , $cloaked_url , $redirect_url , $redirect_type , $keyword = '' ) {
|
198 |
+
|
199 |
+
global $wpdb;
|
200 |
+
|
201 |
+
if ( apply_filters( 'ta_filter_before_save_click' , false , $thirstylink , $http_referer ) )
|
202 |
+
return;
|
203 |
+
|
204 |
+
$link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
205 |
+
$link_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
206 |
+
|
207 |
+
// insert click entry
|
208 |
+
$wpdb->insert(
|
209 |
+
$link_click_db,
|
210 |
+
array(
|
211 |
+
'link_id' => $thirstylink->get_id(),
|
212 |
+
'date_clicked' => current_time( 'mysql' , true )
|
213 |
+
)
|
214 |
+
);
|
215 |
+
|
216 |
+
// save click meta data
|
217 |
+
if ( $click_id = $wpdb->insert_id ) {
|
218 |
+
|
219 |
+
$meta_data = apply_filters( 'ta_save_click_data' , array(
|
220 |
+
'user_ip_address' => $this->_helper_functions->get_user_ip_address(),
|
221 |
+
'http_referer' => $http_referer,
|
222 |
+
'cloaked_url' => $cloaked_url,
|
223 |
+
'redirect_url' => $redirect_url,
|
224 |
+
'redirect_type' => $redirect_type,
|
225 |
+
'keyword' => $keyword,
|
226 |
+
'browser_device' => $this->_helper_functions->get_visitor_browser_device()
|
227 |
+
), $thirstylink );
|
228 |
+
|
229 |
+
foreach ( $meta_data as $key => $value ) {
|
230 |
+
|
231 |
+
// make sure there is a key and a value before saving.
|
232 |
+
if ( ! $key || ! $value )
|
233 |
+
continue;
|
234 |
+
|
235 |
+
$wpdb->insert(
|
236 |
+
$link_click_meta_db,
|
237 |
+
array(
|
238 |
+
'click_id' => $click_id,
|
239 |
+
'meta_key' => $key,
|
240 |
+
'meta_value' => $value
|
241 |
+
)
|
242 |
+
);
|
243 |
+
}
|
244 |
+
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Save click data on redirect
|
250 |
+
*
|
251 |
+
* @since 3.0.0
|
252 |
+
* @since 3.1.0 Passed additional 2 parameters: $redirect_url and $redirect type. Updated save_click_data function call to include new required arguments.
|
253 |
+
* @since 3.3.0 If enhanced javascript redirect in frontend is enabled, then all server redirects are allowed (with this, stats links clicked via "open new tab" will be saved).
|
254 |
+
* @access public
|
255 |
+
*
|
256 |
+
* @param Affiliate_Link $thirstylink Affiliate link object.
|
257 |
+
* @param string $redirect_url Link to where user is redirected to.
|
258 |
+
* @param string $redirect_type Redirect type (301,302, etc.)
|
259 |
+
*/
|
260 |
+
public function save_click_data_on_redirect( $thirstylink , $redirect_url , $redirect_type ) {
|
261 |
+
|
262 |
+
// make sure that this is only runs on the frontend and not on the backend.
|
263 |
+
if ( is_admin() ) return;
|
264 |
+
|
265 |
+
$link_id = $thirstylink->get_id();
|
266 |
+
$http_referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
|
267 |
+
$query_string = isset( $_SERVER[ 'QUERY_STRING' ] ) ? $_SERVER[ 'QUERY_STRING' ] : '';
|
268 |
+
$cloaked_url = $query_string ? $thirstylink->get_prop( 'permalink' ) . '?' . $query_string : $thirstylink->get_prop( 'permalink' );
|
269 |
+
|
270 |
+
$same_site = $http_referer && strrpos( 'x' . $http_referer , home_url() );
|
271 |
+
$admin_referrer = $http_referer && strrpos( 'x' . $http_referer , admin_url() );
|
272 |
+
$js_redirect_enabled = get_option( 'ta_enable_javascript_frontend_redirect' ) == 'yes';
|
273 |
+
|
274 |
+
// NOTE: this fixes a bug reported on TA-250
|
275 |
+
if ( $http_referer == $cloaked_url || $admin_referrer ) return;
|
276 |
+
|
277 |
+
// if the refferer is from an external site, then record stat.
|
278 |
+
if ( ( $same_site && $js_redirect_enabled ) || ! $same_site )
|
279 |
+
$this->save_click_data( $thirstylink , $http_referer , $cloaked_url , $redirect_url , $redirect_type );
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* AJAX save click data on redirect
|
284 |
+
*
|
285 |
+
* @since 3.0.0
|
286 |
+
* @since 3.1.0 Updated save_click_data function call to include new required arguments.
|
287 |
+
* @since 3.2.0 Updated save_click_data function call to include keyword argument.
|
288 |
+
* @since 3.3.0 print actual affiliate link redirect url for ehanced javascript redirect support.
|
289 |
+
* @since 3.4.0 Add query string as parameter to support passing query strings in enhanced JS redirect.
|
290 |
+
* @access public
|
291 |
+
*/
|
292 |
+
public function ajax_save_click_data_on_redirect() {
|
293 |
+
|
294 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
295 |
+
wp_die();
|
296 |
+
|
297 |
+
$link_id = isset( $_REQUEST[ 'link_id' ] ) ? (int) sanitize_text_field( $_REQUEST[ 'link_id' ] ) : 0;
|
298 |
+
$http_referer = isset( $_REQUEST[ 'page' ] ) ? esc_url_raw( $_REQUEST[ 'page' ] ) : '';
|
299 |
+
$cloaked_url = isset( $_REQUEST[ 'href' ] ) ? esc_url_raw( $_REQUEST[ 'href' ] ) : '';
|
300 |
+
$keyword = isset( $_REQUEST[ 'keyword' ] ) ? sanitize_text_field( $_REQUEST[ 'keyword' ] ) : '';
|
301 |
+
$query_string = isset( $_REQUEST[ 'qs' ] ) ? sanitize_text_field( $_REQUEST[ 'qs' ] ) : '';
|
302 |
+
|
303 |
+
if ( ! $link_id )
|
304 |
+
$link_id = url_to_postid( $cloaked_url );
|
305 |
+
|
306 |
+
if ( $link_id ) {
|
307 |
+
|
308 |
+
$thirstylink = new Affiliate_Link( $link_id );
|
309 |
+
$redirect_url = apply_filters( 'ta_filter_redirect_url' , $thirstylink->get_prop( 'destination_url' ) , $thirstylink , $query_string );
|
310 |
+
$redirect_type = $thirstylink->get_redirect_type();
|
311 |
+
|
312 |
+
$this->save_click_data( $thirstylink , $http_referer , $cloaked_url , $redirect_url , $redirect_type , $keyword );
|
313 |
+
|
314 |
+
// print actual affiliate link redirect url for enhanced javascript redirect support.
|
315 |
+
if ( get_option( 'ta_enable_javascript_frontend_redirect' ) == 'yes' )
|
316 |
+
echo $redirect_url;
|
317 |
+
}
|
318 |
+
|
319 |
+
wp_die();
|
320 |
+
}
|
321 |
+
|
322 |
+
|
323 |
+
|
324 |
+
|
325 |
+
/*
|
326 |
+
|--------------------------------------------------------------------------
|
327 |
+
| Fetch Report Data
|
328 |
+
|--------------------------------------------------------------------------
|
329 |
+
*/
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Fetch link performance data by date range.
|
333 |
+
*
|
334 |
+
* @since 3.0.0
|
335 |
+
* @access public
|
336 |
+
*
|
337 |
+
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
338 |
+
*
|
339 |
+
* @param string $start_date Report start date. Format: YYYY-MM-DD hh:mm:ss
|
340 |
+
* @param string $end_date Report end date. Format: YYYY-MM-DD hh:mm:ss
|
341 |
+
* @param array $link_ids Affiliate Link post ID
|
342 |
+
* @return string/array Link click meta data value.
|
343 |
+
*/
|
344 |
+
public function get_link_performance_data( $start_date , $end_date , $link_ids ) {
|
345 |
+
|
346 |
+
global $wpdb;
|
347 |
+
|
348 |
+
if ( ! is_array( $link_ids ) || empty( $link_ids ) )
|
349 |
+
return array();
|
350 |
+
|
351 |
+
$link_clicks_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
352 |
+
$link_ids_str = implode( ', ' , $link_ids );
|
353 |
+
$query = "SELECT * FROM $link_clicks_db WHERE date_clicked between '$start_date' and '$end_date' and link_id IN ( $link_ids_str )";
|
354 |
+
|
355 |
+
return $wpdb->get_results( $query );
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Get link click meta by id and key.
|
360 |
+
*
|
361 |
+
* @since 3.0.0
|
362 |
+
* @access public
|
363 |
+
*
|
364 |
+
* @param int $click_id Link click ID.
|
365 |
+
* @param string $meta_key Meta key column value.
|
366 |
+
* @param boolean $single Return single result or array.
|
367 |
+
* @return array Link performance data.
|
368 |
+
*/
|
369 |
+
private function get_click_meta( $click_id , $meta_key , $single = false ) {
|
370 |
+
|
371 |
+
global $wpdb;
|
372 |
+
|
373 |
+
$links_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
374 |
+
|
375 |
+
if ( $single ){
|
376 |
+
|
377 |
+
$meta = $wpdb->get_row( "SELECT meta_value FROM $links_click_meta_db WHERE click_id = '$click_id' and meta_key = '$meta_key'" , ARRAY_A );
|
378 |
+
return array_shift( $meta );
|
379 |
+
|
380 |
+
} else {
|
381 |
+
|
382 |
+
$meta = array();
|
383 |
+
$raw_data = $wpdb->get_results( "SELECT meta_value FROM $links_click_meta_db WHERE click_id = '$click_id' and meta_key = '$meta_key'" , ARRAY_N );
|
384 |
+
|
385 |
+
foreach ( $raw_data as $data )
|
386 |
+
$meta[] = array_shift( $data );
|
387 |
+
|
388 |
+
return $meta;
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* AJAX fetch report by linkid.
|
394 |
+
*
|
395 |
+
* @since 3.0.0
|
396 |
+
* @since 3.1.2 Add total clicks count on the response.
|
397 |
+
* @access public
|
398 |
+
*/
|
399 |
+
public function ajax_fetch_report_by_linkid() {
|
400 |
+
|
401 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
402 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
403 |
+
elseif ( ! isset( $_POST[ 'link_id' ] ) )
|
404 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
405 |
+
else {
|
406 |
+
|
407 |
+
// save timezone to use
|
408 |
+
$timezone = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
|
409 |
+
$this->set_browser_zone_str( $timezone );
|
410 |
+
|
411 |
+
$link_id = isset( $_POST[ 'link_id' ] ) ? (int) sanitize_text_field( $_POST[ 'link_id' ] ) : 0;
|
412 |
+
$thirstylink = new Affiliate_Link( $link_id );
|
413 |
+
$range_txt = isset( $_POST[ 'range' ] ) ? sanitize_text_field( $_POST[ 'range' ] ) : '';
|
414 |
+
$start_date = isset( $_POST[ 'start_date' ] ) ? sanitize_text_field( $_POST[ 'start_date' ] ) : '';
|
415 |
+
$end_date = isset( $_POST[ 'end_date' ] ) ? sanitize_text_field( $_POST[ 'end_date' ] ) : '';
|
416 |
+
|
417 |
+
if ( ! $thirstylink->get_id() )
|
418 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Selected affiliate link is invalid' , 'thirstyaffiliates' ) );
|
419 |
+
else {
|
420 |
+
|
421 |
+
$range = $this->get_report_range_details( $range_txt , $start_date , $end_date );
|
422 |
+
$data = $this->prepare_data_for_flot( $range , array( $link_id ) );
|
423 |
+
|
424 |
+
$response = array(
|
425 |
+
'status' => 'success',
|
426 |
+
'label' => $thirstylink->get_prop( 'name' ),
|
427 |
+
'slug' => $thirstylink->get_prop( 'slug' ),
|
428 |
+
'report_data' => $data,
|
429 |
+
'total_clicks' => $this->count_total_clicks_from_flot_data( $data )
|
430 |
+
);
|
431 |
+
}
|
432 |
+
}
|
433 |
+
|
434 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
435 |
+
echo wp_json_encode( $response );
|
436 |
+
wp_die();
|
437 |
+
}
|
438 |
+
|
439 |
+
/**
|
440 |
+
* AJAX init first report.
|
441 |
+
*
|
442 |
+
* @since 3.2.2
|
443 |
+
* @access public
|
444 |
+
*/
|
445 |
+
public function ajax_init_first_report() {
|
446 |
+
|
447 |
+
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
|
448 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Invalid AJAX call' , 'thirstyaffiliates' ) );
|
449 |
+
elseif ( ! isset( $_POST[ 'timezone' ] ) )
|
450 |
+
$response = array( 'status' => 'fail' , 'error_msg' => __( 'Missing required post data' , 'thirstyaffiliates' ) );
|
451 |
+
else {
|
452 |
+
|
453 |
+
// save timezone to use
|
454 |
+
$timezone = isset( $_POST[ 'timezone' ] ) ? sanitize_text_field( $_POST[ 'timezone' ] ) : '';
|
455 |
+
$this->set_browser_zone_str( $timezone );
|
456 |
+
|
457 |
+
$cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
|
458 |
+
$current_range = isset( $_POST[ 'range' ] ) ? sanitize_text_field( $_POST[ 'range' ] ) : '7day';
|
459 |
+
$start_date = isset( $_POST[ 'start_date' ] ) ? sanitize_text_field( $_POST[ 'start_date' ] ) : '';
|
460 |
+
$end_date = isset( $_POST[ 'end_date' ] ) ? sanitize_text_field( $_POST[ 'end_date' ] ) : '';
|
461 |
+
$range = $this->get_report_range_details( $current_range , $start_date , $end_date );
|
462 |
+
|
463 |
+
// get all published affiliate link ids
|
464 |
+
$query = new \WP_Query( array(
|
465 |
+
'post_type' => $cpt_slug,
|
466 |
+
'post_status' => 'publish',
|
467 |
+
'fields' => 'ids',
|
468 |
+
'posts_per_page' => -1
|
469 |
+
) );
|
470 |
+
|
471 |
+
$data = $this->prepare_data_for_flot( $range , $query->posts );
|
472 |
+
$total_clicks = $this->count_total_clicks_from_flot_data( $data );
|
473 |
+
|
474 |
+
$response = array(
|
475 |
+
'status' => 'success',
|
476 |
+
'flot_data' => $data,
|
477 |
+
'total_clicks' => $total_clicks,
|
478 |
+
);
|
479 |
+
|
480 |
+
}
|
481 |
+
|
482 |
+
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
483 |
+
echo wp_json_encode( $response );
|
484 |
+
wp_die();
|
485 |
+
}
|
486 |
+
|
487 |
+
|
488 |
+
|
489 |
+
|
490 |
+
/*
|
491 |
+
|--------------------------------------------------------------------------
|
492 |
+
| Reports Structure
|
493 |
+
|--------------------------------------------------------------------------
|
494 |
+
*/
|
495 |
+
|
496 |
+
/**
|
497 |
+
* Get all registered reports.
|
498 |
+
*
|
499 |
+
* @since 3.0.0
|
500 |
+
* @access public
|
501 |
+
*
|
502 |
+
* @return array Settings sections.
|
503 |
+
*/
|
504 |
+
public function get_all_reports() {
|
505 |
+
|
506 |
+
return apply_filters( 'ta_register_reports' , array() );
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Get current loaded report.
|
511 |
+
*
|
512 |
+
* @since 3.0.0
|
513 |
+
* @access public
|
514 |
+
*
|
515 |
+
* @param string $tab Current report tab.
|
516 |
+
* @return array Current loaded report.
|
517 |
+
*/
|
518 |
+
public function get_current_report( $tab = '' ) {
|
519 |
+
|
520 |
+
if ( ! $tab )
|
521 |
+
$tab = isset( $_GET[ 'tab' ] ) ? esc_attr( $_GET[ 'tab' ] ) : 'link_performance';
|
522 |
+
|
523 |
+
// get all registered sections and fields
|
524 |
+
$reports = $this->get_all_reports();
|
525 |
+
|
526 |
+
return isset( $reports[ $tab ] ) ? $reports[ $tab ] : array();
|
527 |
+
}
|
528 |
+
|
529 |
+
/**
|
530 |
+
* Register link performance report.
|
531 |
+
*
|
532 |
+
* @since 3.0.0
|
533 |
+
* @access public
|
534 |
+
*
|
535 |
+
* @param array $reports Array list of all registered reports.
|
536 |
+
* @return array Array list of all registered reports.
|
537 |
+
*/
|
538 |
+
public function register_link_performance_report( $reports ) {
|
539 |
+
|
540 |
+
$reports[ 'link_performance' ] = array(
|
541 |
+
'id' => 'ta_link_performance_report',
|
542 |
+
'tab' => 'link_performance',
|
543 |
+
'name' => __( 'Link Overview' , 'thirstyaffiliates' ),
|
544 |
+
'title' => __( 'Link Overview Report' , 'thirstyaffiliates' ),
|
545 |
+
'desc' => __( 'Total clicks on affiliate links over a given period.' , 'thirstyaffiliates' ),
|
546 |
+
'content' => function() { return $this->get_link_performance_report_content(); }
|
547 |
+
);
|
548 |
+
|
549 |
+
return $reports;
|
550 |
+
}
|
551 |
+
|
552 |
+
|
553 |
+
|
554 |
+
|
555 |
+
/*
|
556 |
+
|--------------------------------------------------------------------------
|
557 |
+
| Display Report
|
558 |
+
|--------------------------------------------------------------------------
|
559 |
+
*/
|
560 |
+
|
561 |
+
/**
|
562 |
+
* Register reports menu page.
|
563 |
+
*
|
564 |
+
* @since 3.0.0
|
565 |
+
* @since 3.2.2 Access to the settings page will now be controlled by the plugin. see Bootstrap::admin_interface_visibility.
|
566 |
+
*
|
567 |
+
* @access public
|
568 |
+
*/
|
569 |
+
public function add_reports_submenu() {
|
570 |
+
|
571 |
+
if ( ! current_user_can( 'edit_posts' ) ) return;
|
572 |
+
|
573 |
+
add_submenu_page(
|
574 |
+
'edit.php?post_type=thirstylink',
|
575 |
+
__( 'ThirstyAffiliates Reports' , 'thirstyaffiliates' ),
|
576 |
+
__( 'Reports' , 'thirstyaffiliates' ),
|
577 |
+
'read',
|
578 |
+
'thirsty-reports',
|
579 |
+
array( $this, 'render_reports' )
|
580 |
+
);
|
581 |
+
}
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Render reports page.
|
585 |
+
*
|
586 |
+
* @since 3.0.0
|
587 |
+
* @access public
|
588 |
+
*/
|
589 |
+
public function render_reports() {
|
590 |
+
|
591 |
+
// fetch current section
|
592 |
+
$current_report = $this->get_current_report();
|
593 |
+
$report_content = is_callable( $current_report[ 'content' ] ) ? $current_report[ 'content' ]() : $current_report[ 'content' ];
|
594 |
+
|
595 |
+
// skip if section data is empty
|
596 |
+
if ( empty( $current_report ) ) return; ?>
|
597 |
+
|
598 |
+
<div class="ta-settings ta-settings-<?php echo $current_report[ 'tab' ]; ?> wrap">
|
599 |
+
|
600 |
+
<?php $this->render_reports_nav(); ?>
|
601 |
+
|
602 |
+
<h1><?php echo $current_report[ 'title' ]; ?></h1>
|
603 |
+
<p class="desc"><?php echo $current_report[ 'desc' ]; ?></p>
|
604 |
+
|
605 |
+
<?php echo $report_content; ?>
|
606 |
+
</div>
|
607 |
+
<?php
|
608 |
+
}
|
609 |
+
|
610 |
+
/**
|
611 |
+
* Render the settings navigation.
|
612 |
+
*
|
613 |
+
* @since 3.0.0
|
614 |
+
* @access public
|
615 |
+
*/
|
616 |
+
public function render_reports_nav() {
|
617 |
+
|
618 |
+
$reports = $this->get_all_reports();
|
619 |
+
$current = $this->get_current_report();
|
620 |
+
$base_url = admin_url( 'edit.php?post_type=thirstylink&page=thirsty-reports' );
|
621 |
+
|
622 |
+
if ( empty( $reports ) ) return; ?>
|
623 |
+
|
624 |
+
<nav class="thirsty-nav-tab">
|
625 |
+
<?php foreach ( $reports as $report ) : ?>
|
626 |
+
|
627 |
+
<a href="<?php echo $base_url . '&tab=' . $report[ 'tab' ]; ?>" class="tab <?php echo ( $current[ 'tab' ] === $report[ 'tab' ] ) ? 'tab-active' : ''; ?>">
|
628 |
+
<?php echo $report[ 'name' ]; ?>
|
629 |
+
</a>
|
630 |
+
|
631 |
+
<?php endforeach; ?>
|
632 |
+
</nav>
|
633 |
+
|
634 |
+
<?php
|
635 |
+
}
|
636 |
+
|
637 |
+
/**
|
638 |
+
* Get Link performance report content.
|
639 |
+
*
|
640 |
+
* @since 3.0.0
|
641 |
+
* @since 3.3.2 Remove report data query on page first load.
|
642 |
+
* @access public
|
643 |
+
*
|
644 |
+
* @return string Link performance report content.
|
645 |
+
*/
|
646 |
+
public function get_link_performance_report_content() {
|
647 |
+
|
648 |
+
$cpt_slug = Plugin_Constants::AFFILIATE_LINKS_CPT;
|
649 |
+
$current_range = isset( $_GET[ 'range' ] ) ? sanitize_text_field( $_GET[ 'range' ] ) : '7day';
|
650 |
+
$start_date = isset( $_GET[ 'start_date' ] ) ? sanitize_text_field( $_GET[ 'start_date' ] ) : '';
|
651 |
+
$end_date = isset( $_GET[ 'end_date' ] ) ? sanitize_text_field( $_GET[ 'end_date' ] ) : '';
|
652 |
+
$link_id = isset( $_GET[ 'link_id' ] ) ? sanitize_text_field( $_GET[ 'link_id' ] ) : '';
|
653 |
+
$range = $this->get_report_range_details( $current_range , $start_date , $end_date );
|
654 |
+
$range_nav = apply_filters( 'ta_link_performances_report_nav' , array(
|
655 |
+
'year' => __( 'Year' , 'thirstyaffiliates' ),
|
656 |
+
'last_month' => __( 'Last Month' , 'thirstyaffiliates' ),
|
657 |
+
'month' => __( 'This Month' , 'thirstyaffiliates' ),
|
658 |
+
'7day' => __( 'Last 7 Days' , 'thirstyaffiliates' )
|
659 |
+
) );
|
660 |
+
|
661 |
+
// make sure link_id is an affiliate link (published).
|
662 |
+
// NOTE: when false, this needs to return an empty string as it is used for display.
|
663 |
+
if ( $link_id ) $link_id = ( get_post_type( $link_id ) == $cpt_slug && get_post_status( $link_id ) == 'publish' ) ? $link_id : '';
|
664 |
+
|
665 |
+
ob_start();
|
666 |
+
include( $this->_constants->VIEWS_ROOT_PATH() . 'reports/link-performance-report.php' );
|
667 |
+
|
668 |
+
return ob_get_clean();
|
669 |
+
}
|
670 |
+
|
671 |
+
|
672 |
+
|
673 |
+
|
674 |
+
/*
|
675 |
+
|--------------------------------------------------------------------------
|
676 |
+
| Helper methods
|
677 |
+
|--------------------------------------------------------------------------
|
678 |
+
*/
|
679 |
+
|
680 |
+
/**
|
681 |
+
* Get report range details.
|
682 |
+
*
|
683 |
+
* @since 3.0.0
|
684 |
+
* @since 3.2.2 Change method of getting timezone sting name.
|
685 |
+
* @access public
|
686 |
+
*
|
687 |
+
* @param string $range Report range type.
|
688 |
+
* @param string $start_date Starting date of range.
|
689 |
+
* @param string $end_date Ending date of range.
|
690 |
+
* @return array Report range details.
|
691 |
+
*/
|
692 |
+
public function get_report_range_details( $range = '7day' , $start_date = 'now -6 days' , $end_date = 'now' ) {
|
693 |
+
|
694 |
+
$data = array();
|
695 |
+
$zone_str = $this->get_report_timezone_string();
|
696 |
+
$timezone = new \DateTimeZone( $zone_str );
|
697 |
+
$now = new \DateTime( 'now' , $timezone );
|
698 |
+
|
699 |
+
switch ( $range ) {
|
700 |
+
|
701 |
+
case 'year' :
|
702 |
+
$data[ 'type' ] = 'year';
|
703 |
+
$data[ 'start_date' ] = new \DateTime( 'first day of January' . date( 'Y' ) , $timezone );
|
704 |
+
$data[ 'end_date' ] = $now;
|
705 |
+
break;
|
706 |
+
|
707 |
+
case 'last_month' :
|
708 |
+
$data[ 'type' ] = 'last_month';
|
709 |
+
$data[ 'start_date' ] = new \DateTime( 'first day of last month' , $timezone );
|
710 |
+
$data[ 'end_date' ] = new \DateTime( 'last day of last month' , $timezone );
|
711 |
+
break;
|
712 |
+
|
713 |
+
case 'month' :
|
714 |
+
$data[ 'type' ] = 'month';
|
715 |
+
$data[ 'start_date' ] = new \DateTime( 'first day of this month' , $timezone );
|
716 |
+
$data[ 'end_date' ] = $now;
|
717 |
+
$data[ 'start_date' ]->setTime( 0 , 0 , 0 );
|
718 |
+
break;
|
719 |
+
|
720 |
+
case 'custom' :
|
721 |
+
$data[ 'type' ] = 'custom';
|
722 |
+
$data[ 'start_date' ] = new \DateTime( $start_date , $timezone );
|
723 |
+
$data[ 'end_date' ] = new \DateTime( $end_date . ' 23:59:59' , $timezone );
|
724 |
+
break;
|
725 |
+
|
726 |
+
case '7day' :
|
727 |
+
default :
|
728 |
+
$start_date = new \DateTime( 'now -6 days' , $timezone );
|
729 |
+
|
730 |
+
// set hours, minutes and seconds to zero
|
731 |
+
$start_date->setTime( 0 , 0 , 0 );
|
732 |
+
$now->setTime( 23 , 59 , 59 );
|
733 |
+
|
734 |
+
$data[ 'type' ] = '7day';
|
735 |
+
$data[ 'start_date' ] = $start_date;
|
736 |
+
$data[ 'end_date' ] = $now;
|
737 |
+
break;
|
738 |
+
}
|
739 |
+
|
740 |
+
return apply_filters( 'ta_report_range_data' , $data , $range );
|
741 |
+
}
|
742 |
+
|
743 |
+
/**
|
744 |
+
* Prepare data to feed for jQuery flot.
|
745 |
+
*
|
746 |
+
* @since 3.0.0
|
747 |
+
* @since 3.2.2 Change method of getting timezone sting name.
|
748 |
+
* @since 3.3.3 Set range timezone to UTC before fetching raw data.
|
749 |
+
* @since 3.3.4 Set date range timezone back to local browser before setting start time to zero.
|
750 |
+
* @access public
|
751 |
+
*
|
752 |
+
* @param array $range Report range details
|
753 |
+
* @param array $link_ids Affiliate Link post ID
|
754 |
+
* @return array Processed data for jQuery flot.
|
755 |
+
*/
|
756 |
+
public function prepare_data_for_flot( $range , $link_ids ) {
|
757 |
+
|
758 |
+
$start_date = $range[ 'start_date' ];
|
759 |
+
$end_date = $range[ 'end_date' ];
|
760 |
+
$zone_str = $this->get_report_timezone_string();
|
761 |
+
$timezone = new \DateTimeZone( $zone_str );
|
762 |
+
$utc = new \DateTimeZone( 'UTC' );
|
763 |
+
$flot_data = array();
|
764 |
+
|
765 |
+
$start_date->setTimezone( $timezone );
|
766 |
+
$end_date->setTimezone( $timezone );
|
767 |
+
|
768 |
+
if ( apply_filters( 'ta_report_set_start_date_time_to_zero' , true , $range ) )
|
769 |
+
$start_date->setTime( 0 , 0 );
|
770 |
+
|
771 |
+
$start_date->setTimezone( $utc );
|
772 |
+
$end_date->setTimezone( $utc );
|
773 |
+
|
774 |
+
$raw_data = $this->get_link_performance_data( $start_date->format( 'Y-m-d H:i:s' ) , $end_date->format( 'Y-m-d H:i:s' ) , $link_ids );
|
775 |
+
|
776 |
+
// get number of days difference between start and end
|
777 |
+
$incrementor = apply_filters( 'ta_report_flot_data_incrementor' , ( 60 * 60 * 24 ) , $range );
|
778 |
+
$timestamp_diff = ( $start_date->getTimestamp() - $end_date->getTimestamp() );
|
779 |
+
$days_diff = abs( floor( $timestamp_diff / $incrementor ) );
|
780 |
+
|
781 |
+
// save the timestamp for first day
|
782 |
+
$timestamp = $start_date->format( 'U' );
|
783 |
+
$month_time = $this->get_month_first_day_datetime_obj( 'February' );
|
784 |
+
$next_timestamp = ( $range[ 'type' ] == 'year' ) ? $month_time->format( 'U' ) : $timestamp + $incrementor;
|
785 |
+
$flot_data[] = array(
|
786 |
+
'timestamp' => (int) $timestamp,
|
787 |
+
'count' => 0,
|
788 |
+
'next_timestamp' => $next_timestamp
|
789 |
+
);
|
790 |
+
|
791 |
+
if ( $range[ 'type' ] == 'year' ) {
|
792 |
+
|
793 |
+
$months = array( 'February' , 'March' , 'April' , 'May' , 'June' , 'July' , 'August' , 'September' , 'October' , 'November' , 'December' );
|
794 |
+
|
795 |
+
foreach ( $months as $key => $month ) {
|
796 |
+
|
797 |
+
$month_time = $this->get_month_first_day_datetime_obj( $month );
|
798 |
+
$next_month = isset( $months[ $key + 1 ] ) ? $this->get_month_first_day_datetime_obj( $months[ $key + 1 ] ) : new \DateTime( 'now' , $timezone );
|
799 |
+
|
800 |
+
$flot_data[] = array(
|
801 |
+
'timestamp' => $month_time->format( 'U' ),
|
802 |
+
'count' => 0,
|
803 |
+
'next_timestamp' => $next_month->format( 'U' )
|
804 |
+
);
|
805 |
+
|
806 |
+
if ( $end_date->format( 'F' ) == $month )
|
807 |
+
break;
|
808 |
+
}
|
809 |
+
|
810 |
+
} else {
|
811 |
+
|
812 |
+
// determine timestamps for succeeding days
|
813 |
+
for ( $x = 1; $x < $days_diff; $x++ ) {
|
814 |
+
|
815 |
+
$timestamp = $next_timestamp;
|
816 |
+
$next_timestamp = $timestamp + $incrementor;
|
817 |
+
|
818 |
+
$flot_data[] = array(
|
819 |
+
'timestamp' => (int) $timestamp,
|
820 |
+
'count' => 0,
|
821 |
+
'next_timestamp' => $next_timestamp
|
822 |
+
);
|
823 |
+
|
824 |
+
}
|
825 |
+
}
|
826 |
+
|
827 |
+
// count each click data and assign to appropriate day.
|
828 |
+
foreach ( $raw_data as $click_entry ) {
|
829 |
+
|
830 |
+
$click_date = new \DateTime( $click_entry->date_clicked , $utc );
|
831 |
+
$click_date->setTimezone( $timezone );
|
832 |
+
|
833 |
+
$click_timestamp = (int) $click_date->format( 'U' );
|
834 |
+
|
835 |
+
foreach ( $flot_data as $key => $day_data ) {
|
836 |
+
|
837 |
+
if ( $click_timestamp >= $day_data[ 'timestamp' ] && $click_timestamp < $day_data[ 'next_timestamp' ] ) {
|
838 |
+
$flot_data[ $key ][ 'count' ] += 1;
|
839 |
+
continue;
|
840 |
+
}
|
841 |
+
}
|
842 |
+
}
|
843 |
+
|
844 |
+
// convert $flot_data array into non-associative array
|
845 |
+
foreach ( $flot_data as $key => $day_data ) {
|
846 |
+
|
847 |
+
unset( $day_data[ 'next_timestamp' ] );
|
848 |
+
|
849 |
+
$day_data[ 'timestamp' ] = $day_data[ 'timestamp' ] * 1000;
|
850 |
+
$flot_data[ $key ] = array_values( $day_data );
|
851 |
+
}
|
852 |
+
|
853 |
+
return $flot_data;
|
854 |
+
}
|
855 |
+
|
856 |
+
/**
|
857 |
+
* Count total clicks from flot data.
|
858 |
+
*
|
859 |
+
* @since 3.2.1
|
860 |
+
* @access public
|
861 |
+
*
|
862 |
+
* @param array $data Flot data.
|
863 |
+
* @param int $total Total click counts (offset).
|
864 |
+
* @return int Total click clounts.
|
865 |
+
*/
|
866 |
+
public function count_total_clicks_from_flot_data( $data , $total = 0 ) {
|
867 |
+
|
868 |
+
if ( ! is_array( $data ) || empty( $data ) )
|
869 |
+
return;
|
870 |
+
|
871 |
+
foreach ( $data as $flot )
|
872 |
+
$total += intval( $flot[1] );
|
873 |
+
|
874 |
+
return $total;
|
875 |
+
}
|
876 |
+
|
877 |
+
/**
|
878 |
+
* Get the DateTime object of the first day of a given month.
|
879 |
+
*
|
880 |
+
* @since 3.0.0
|
881 |
+
* @since 3.2.2 Change method of getting timezone sting name.
|
882 |
+
* @access public
|
883 |
+
*
|
884 |
+
* @param string $month Month full textual representation.
|
885 |
+
* @return DateTime First day of the given month DateTime object.
|
886 |
+
*/
|
887 |
+
public function get_month_first_day_datetime_obj( $month ) {
|
888 |
+
|
889 |
+
$zone_str = $this->get_report_timezone_string();
|
890 |
+
$timezone = new \DateTimeZone( $zone_str );
|
891 |
+
|
892 |
+
return new \DateTime( 'First day of ' . $month . ' ' . date( 'Y' ) , $timezone );
|
893 |
+
}
|
894 |
+
|
895 |
+
/**
|
896 |
+
* Schedule stats trimmer cron job.
|
897 |
+
*
|
898 |
+
* @since 3.1.0
|
899 |
+
* @access private
|
900 |
+
*/
|
901 |
+
private function schedule_stats_trimmer_cron() {
|
902 |
+
|
903 |
+
$zone_str = $this->_helper_functions->get_site_current_timezone();
|
904 |
+
$timezone = new \DateTimeZone( $zone_str );
|
905 |
+
$time = new \DateTime( 'first day of next month' , $timezone );
|
906 |
+
|
907 |
+
// clear all scheduled crons so there will always only be one.
|
908 |
+
wp_clear_scheduled_hook( Plugin_Constants::CRON_STATS_TRIMMER );
|
909 |
+
|
910 |
+
// schedule cron job
|
911 |
+
wp_schedule_single_event( $time->format( 'U' ) , Plugin_Constants::CRON_STATS_TRIMMER );
|
912 |
+
}
|
913 |
+
|
914 |
+
/**
|
915 |
+
* Implement stats trimmer
|
916 |
+
*
|
917 |
+
* @since 3.1.0
|
918 |
+
* @access public
|
919 |
+
*
|
920 |
+
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
921 |
+
*/
|
922 |
+
public function implement_stats_trimmer() {
|
923 |
+
|
924 |
+
global $wpdb;
|
925 |
+
|
926 |
+
$trim_point = (int) get_option( 'ta_stats_trimer_set_point' , 0 );
|
927 |
+
|
928 |
+
if ( $trim_point > 0 ) {
|
929 |
+
|
930 |
+
$clicks_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
931 |
+
$clicks_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
932 |
+
|
933 |
+
// get click ids based on set range.
|
934 |
+
$query = "SELECT id FROM $clicks_db WHERE date_clicked < DATE_ADD( NOW() , INTERVAL -" . $trim_point . " MONTH )";
|
935 |
+
$click_ids = $wpdb->get_col( $query );
|
936 |
+
|
937 |
+
// Proceed on deleting data when $click_ids are present
|
938 |
+
if ( is_array( $click_ids ) && ! empty( $click_ids ) ) {
|
939 |
+
|
940 |
+
$click_ids_string = implode( $click_ids , ',' );
|
941 |
+
|
942 |
+
// delete click data
|
943 |
+
$wpdb->query( "DELETE FROM $clicks_meta_db WHERE click_id IN ( $click_ids_string )" );
|
944 |
+
$wpdb->query( "DELETE FROM $clicks_db WHERE id IN ( $click_ids_string )" );
|
945 |
+
}
|
946 |
+
}
|
947 |
+
|
948 |
+
// reschedule the cron job
|
949 |
+
$this->schedule_stats_trimmer_cron();
|
950 |
+
}
|
951 |
+
|
952 |
+
/**
|
953 |
+
* Prevent saving click data if useragent is a bot (for non-apache servers).
|
954 |
+
*
|
955 |
+
* @since 3.1.0
|
956 |
+
* @since 3.3.3 Moved code to a helper function (DRY).
|
957 |
+
* @access public
|
958 |
+
*
|
959 |
+
* @param boolean $response Default response of filter.
|
960 |
+
* @return boolean True if needs to be prevented, false otherwise.
|
961 |
+
*/
|
962 |
+
public function prevent_save_click_if_useragent_is_bot( $response ) {
|
963 |
+
|
964 |
+
return $this->_helper_functions->is_user_agent_bot();
|
965 |
+
}
|
966 |
+
|
967 |
+
/**
|
968 |
+
* Delete stats data when an affiliate link is deleted permanently.
|
969 |
+
*
|
970 |
+
* @since 3.0.1
|
971 |
+
* @access public
|
972 |
+
*
|
973 |
+
* @global wpdb $wpdb Object that contains a set of functions used to interact with a database.
|
974 |
+
*
|
975 |
+
* @param int $link_id Affiliate link ID.
|
976 |
+
*/
|
977 |
+
public function delete_stats_data_on_affiliate_link_deletion( $link_id ) {
|
978 |
+
|
979 |
+
global $wpdb;
|
980 |
+
|
981 |
+
if ( Plugin_Constants::AFFILIATE_LINKS_CPT !== get_post_type( $link_id ) )
|
982 |
+
return;
|
983 |
+
|
984 |
+
$link_click_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_DB;
|
985 |
+
$link_click_meta_db = $wpdb->prefix . Plugin_Constants::LINK_CLICK_META_DB;
|
986 |
+
$click_ids = $wpdb->get_col( "SELECT id FROM $link_click_db WHERE link_id = $link_id" );
|
987 |
+
|
988 |
+
if ( ! is_array( $click_ids ) || empty( $click_ids ) )
|
989 |
+
return;
|
990 |
+
|
991 |
+
$click_ids_str = implode( ',' , $click_ids );
|
992 |
+
|
993 |
+
// delete click meta records.
|
994 |
+
$wpdb->query( "DELETE FROM $link_click_meta_db WHERE click_id IN ( $click_ids_str )" );
|
995 |
+
|
996 |
+
// delete click records.
|
997 |
+
$wpdb->query( "DELETE FROM $link_click_db WHERE id IN ( $click_ids_str )" );
|
998 |
+
}
|
999 |
+
|
1000 |
+
/**
|
1001 |
+
* Get timezone to use for the report.
|
1002 |
+
*
|
1003 |
+
* @since 3.2.2
|
1004 |
+
* @since 3.3.3 Made the method public so TAP can utilize it.
|
1005 |
+
* @access public
|
1006 |
+
*
|
1007 |
+
* @return string Timezone string name.
|
1008 |
+
*/
|
1009 |
+
public function get_report_timezone_string() {
|
1010 |
+
|
1011 |
+
return $this->_browser_zone_str ? $this->_browser_zone_str : $this->_helper_functions->get_site_current_timezone();
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
|
1015 |
+
|
1016 |
+
|
1017 |
+
/*
|
1018 |
+
|--------------------------------------------------------------------------
|
1019 |
+
| Fulfill implemented interface contracts
|
1020 |
+
|--------------------------------------------------------------------------
|
1021 |
+
*/
|
1022 |
+
|
1023 |
+
/**
|
1024 |
+
* Execute codes that needs to run plugin activation.
|
1025 |
+
*
|
1026 |
+
* @since 3.0.0
|
1027 |
+
* @access public
|
1028 |
+
* @implements ThirstyAffiliates\Interfaces\Activatable_Interface
|
1029 |
+
*/
|
1030 |
+
public function activate() {
|
1031 |
+
|
1032 |
+
$this->schedule_stats_trimmer_cron();
|
1033 |
+
}
|
1034 |
+
|
1035 |
+
/**
|
1036 |
+
* Method that houses codes to be executed on init hook.
|
1037 |
+
*
|
1038 |
+
* @since 3.0.0
|
1039 |
+
* @access public
|
1040 |
+
* @inherit ThirstyAffiliates\Interfaces\Initiable_Interface
|
1041 |
+
*/
|
1042 |
+
public function initialize() {
|
1043 |
+
|
1044 |
+
// When module is disabled in the settings, then it shouldn't run the whole class.
|
1045 |
+
if ( get_option( 'ta_enable_stats_reporting_module' , 'yes' ) !== 'yes' )
|
1046 |
+
return;
|
1047 |
+
|
1048 |
+
add_action( 'wp_ajax_ta_click_data_redirect' , array( $this , 'ajax_save_click_data_on_redirect' ) , 10 );
|
1049 |
+
add_action( 'wp_ajax_ta_fetch_report_by_linkid' , array( $this , 'ajax_fetch_report_by_linkid' ) , 10 );
|
1050 |
+
add_action( 'wp_ajax_ta_init_first_report' , array( $this , 'ajax_init_first_report' ) , 10 );
|
1051 |
+
add_action( 'wp_ajax_nopriv_ta_click_data_redirect' , array( $this , 'ajax_save_click_data_on_redirect' ) , 10 );
|
1052 |
+
}
|
1053 |
+
|
1054 |
+
/**
|
1055 |
+
* Execute ajax handler.
|
1056 |
+
*
|
1057 |
+
* @since 3.0.0
|
1058 |
+
* @access public
|
1059 |
+
* @inherit ThirstyAffiliates\Interfaces\Model_Interface
|
1060 |
+
*/
|
1061 |
+
public function run() {
|
1062 |
+
|
1063 |
+
// When module is disabled in the settings, then it shouldn't run the whole class.
|
1064 |
+
if ( get_option( 'ta_enable_stats_reporting_module' , 'yes' ) !== 'yes' )
|
1065 |
+
return;
|
1066 |
+
|
1067 |
+
add_filter( 'ta_filter_before_save_click' , array( $this , 'prevent_save_click_if_useragent_is_bot' ) , 10 , 1 );
|
1068 |
+
add_action( 'ta_before_link_redirect' , array( $this , 'save_click_data_on_redirect' ) , 10 , 3 );
|
1069 |
+
add_action( 'admin_menu' , array( $this , 'add_reports_submenu' ) , 10 );
|
1070 |
+
add_action( 'ta_register_reports' , array( $this , 'register_link_performance_report' ) , 10 );
|
1071 |
+
add_action( Plugin_Constants::CRON_STATS_TRIMMER , array( $this , 'implement_stats_trimmer' ) );
|
1072 |
+
add_action( 'before_delete_post' , array( $this , 'delete_stats_data_on_affiliate_link_deletion' ) , 10 );
|
1073 |
+
|
1074 |
+
add_filter( 'ta_admin_interfaces' , array( $this , 'register_admin_interfaces' ) );
|
1075 |
+
add_filter( 'ta_menu_items' , array( $this , 'register_admin_menu_items' ) );
|
1076 |
+
}
|
1077 |
+
}
|
css/admin/ta-affiliate-link-list.css
CHANGED
@@ -1,29 +1,29 @@
|
|
1 |
-
.ta-display-input-wrap {
|
2 |
-
position: relative;
|
3 |
-
}
|
4 |
-
.ta-display-input-wrap a {
|
5 |
-
position: absolute;
|
6 |
-
top: 2px;
|
7 |
-
right: -16px;
|
8 |
-
display: none;
|
9 |
-
width: 15px;
|
10 |
-
height: 15px;
|
11 |
-
background: #0273aa;
|
12 |
-
color: #fff;
|
13 |
-
border-radius: 100px;
|
14 |
-
padding: 4px;
|
15 |
-
text-align: center;
|
16 |
-
opacity: 0.85;
|
17 |
-
}
|
18 |
-
.ta-display-input-wrap a .dashicons {
|
19 |
-
font-size: 16px;
|
20 |
-
line-height: 16px;
|
21 |
-
width: auto;
|
22 |
-
height: auto;
|
23 |
-
}
|
24 |
-
.ta-display-input-wrap:hover a {
|
25 |
-
display: block;
|
26 |
-
}
|
27 |
-
.ta-display-input-wrap:hover a:hover {
|
28 |
-
opacity: 1.0;
|
29 |
-
}
|
1 |
+
.ta-display-input-wrap {
|
2 |
+
position: relative;
|
3 |
+
}
|
4 |
+
.ta-display-input-wrap a {
|
5 |
+
position: absolute;
|
6 |
+
top: 2px;
|
7 |
+
right: -16px;
|
8 |
+
display: none;
|
9 |
+
width: 15px;
|
10 |
+
height: 15px;
|
11 |
+
background: #0273aa;
|
12 |
+
color: #fff;
|
13 |
+
border-radius: 100px;
|
14 |
+
padding: 4px;
|
15 |
+
text-align: center;
|
16 |
+
opacity: 0.85;
|
17 |
+
}
|
18 |
+
.ta-display-input-wrap a .dashicons {
|
19 |
+
font-size: 16px;
|
20 |
+
line-height: 16px;
|
21 |
+
width: auto;
|
22 |
+
height: auto;
|
23 |
+
}
|
24 |
+
.ta-display-input-wrap:hover a {
|
25 |
+
display: block;
|
26 |
+
}
|
27 |
+
.ta-display-input-wrap:hover a:hover {
|
28 |
+
opacity: 1.0;
|
29 |
+
}
|
css/admin/ta-editor.css
CHANGED
@@ -1,47 +1,47 @@
|
|
1 |
-
.mce-container div.wp-thirstylink-input {
|
2 |
-
float: left;
|
3 |
-
margin: 2px;
|
4 |
-
max-width: 694px;
|
5 |
-
position: relative;
|
6 |
-
}
|
7 |
-
|
8 |
-
.mce-container div.wp-thirstylink-input input {
|
9 |
-
width: 300px;
|
10 |
-
padding: 5px;
|
11 |
-
-webkit-box-sizing: border-box;
|
12 |
-
-moz-box-sizing: border-box;
|
13 |
-
box-sizing: border-box
|
14 |
-
}
|
15 |
-
.mce-container div.wp-thirstylink-input .affiliate-link-list {
|
16 |
-
position: absolute;
|
17 |
-
top: 100%;
|
18 |
-
left: 0;
|
19 |
-
width: 100%;
|
20 |
-
max-height: 150px;
|
21 |
-
overflow: auto;
|
22 |
-
border: 1px solid #eee;
|
23 |
-
background: #fff;
|
24 |
-
}
|
25 |
-
.mce-container div.wp-thirstylink-input .affiliate-link-list li {
|
26 |
-
padding: 5px;
|
27 |
-
border-bottom: 1px solid #eee;
|
28 |
-
cursor: pointer;
|
29 |
-
}
|
30 |
-
.mce-container div.wp-thirstylink-input .affiliate-link-list li:hover {
|
31 |
-
background: #eee;
|
32 |
-
}
|
33 |
-
.mce-container div.wp-thirstylink-input .affiliate-link-list li * {
|
34 |
-
font-size: 13px;
|
35 |
-
}
|
36 |
-
.mce-container div.wp-thirstylink-input .affiliate-link-list li:last-child {
|
37 |
-
border-bottom: 0;
|
38 |
-
}
|
39 |
-
.shortcode-preview-toolbar div.shortcode-preview {
|
40 |
-
display:inline-block;
|
41 |
-
padding: 6px 8px;
|
42 |
-
color: #3ca99c;
|
43 |
-
}
|
44 |
-
.shortcode-preview-toolbar .mce-btn-group {
|
45 |
-
border: 0 !important;
|
46 |
-
padding: 0 !important;
|
47 |
}
|
1 |
+
.mce-container div.wp-thirstylink-input {
|
2 |
+
float: left;
|
3 |
+
margin: 2px;
|
4 |
+
max-width: 694px;
|
5 |
+
position: relative;
|
6 |
+
}
|
7 |
+
|
8 |
+
.mce-container div.wp-thirstylink-input input {
|
9 |
+
width: 300px;
|
10 |
+
padding: 5px;
|
11 |
+
-webkit-box-sizing: border-box;
|
12 |
+
-moz-box-sizing: border-box;
|
13 |
+
box-sizing: border-box
|
14 |
+
}
|
15 |
+
.mce-container div.wp-thirstylink-input .affiliate-link-list {
|
16 |
+
position: absolute;
|
17 |
+
top: 100%;
|
18 |
+
left: 0;
|
19 |
+
width: 100%;
|
20 |
+
max-height: 150px;
|
21 |
+
overflow: auto;
|
22 |
+
border: 1px solid #eee;
|
23 |
+
background: #fff;
|
24 |
+
}
|
25 |
+
.mce-container div.wp-thirstylink-input .affiliate-link-list li {
|
26 |
+
padding: 5px;
|
27 |
+
border-bottom: 1px solid #eee;
|
28 |
+
cursor: pointer;
|
29 |
+
}
|
30 |
+
.mce-container div.wp-thirstylink-input .affiliate-link-list li:hover {
|
31 |
+
background: #eee;
|
32 |
+
}
|
33 |
+
.mce-container div.wp-thirstylink-input .affiliate-link-list li * {
|
34 |
+
font-size: 13px;
|
35 |
+
}
|
36 |
+
.mce-container div.wp-thirstylink-input .affiliate-link-list li:last-child {
|
37 |
+
border-bottom: 0;
|
38 |
+
}
|
39 |
+
.shortcode-preview-toolbar div.shortcode-preview {
|
40 |
+
display:inline-block;
|
41 |
+
padding: 6px 8px;
|
42 |
+
color: #3ca99c;
|
43 |
+
}
|
44 |
+
.shortcode-preview-toolbar .mce-btn-group {
|
45 |
+
border: 0 !important;
|
46 |
+
padding: 0 !important;
|
47 |
}
|
css/admin/ta-guided-tour.css
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
.ta-tour-buttons {
|
2 |
-
display: block;
|
3 |
-
text-align: right;
|
4 |
-
}
|
5 |
-
.ta-tour-buttons > .button {
|
6 |
-
margin-left: 10px;
|
7 |
-
}
|
8 |
-
.wp-pointer ul {
|
9 |
-
padding: 0 15px 0 40px;
|
10 |
-
list-style: disc;
|
11 |
-
}
|
1 |
+
.ta-tour-buttons {
|
2 |
+
display: block;
|
3 |
+
text-align: right;
|
4 |
+
}
|
5 |
+
.ta-tour-buttons > .button {
|
6 |
+
margin-left: 10px;
|
7 |
+
}
|
8 |
+
.wp-pointer ul {
|
9 |
+
padding: 0 15px 0 40px;
|
10 |
+
list-style: disc;
|
11 |
+
}
|
css/admin/ta-reports.css
CHANGED
@@ -1,255 +1,255 @@
|
|
1 |
-
/* Top Navigation */
|
2 |
-
.thirsty-nav-tab {
|
3 |
-
margin: 20px 0 15px;
|
4 |
-
position: relative;
|
5 |
-
}
|
6 |
-
.thirsty-nav-tab:after {
|
7 |
-
content: '';
|
8 |
-
display: block;
|
9 |
-
position: absolute;
|
10 |
-
z-index: 1;
|
11 |
-
bottom: -1px;
|
12 |
-
width: 100%;
|
13 |
-
height:1px;
|
14 |
-
border-top: 1px solid #ccc;
|
15 |
-
}
|
16 |
-
.thirsty-nav-tab a.tab {
|
17 |
-
display: inline-block;
|
18 |
-
position: relative;
|
19 |
-
z-index: 2;
|
20 |
-
padding: 8px 10px;
|
21 |
-
margin-right: 2px;
|
22 |
-
background: #e5e5e5;
|
23 |
-
border: 1px solid #ccc;
|
24 |
-
text-decoration: none;
|
25 |
-
font-weight: bold;
|
26 |
-
color: #111;
|
27 |
-
font-size: 14px;
|
28 |
-
}
|
29 |
-
.thirsty-nav-tab a.tab:hover {
|
30 |
-
background: #fff;
|
31 |
-
}
|
32 |
-
.thirsty-nav-tab a.tab-active {
|
33 |
-
background: #f1f1f1 !important;
|
34 |
-
border-bottom-color: #f1f1f1;
|
35 |
-
}
|
36 |
-
.thirsty-nav-tab a.tab:first-child {
|
37 |
-
margin-left: 8px;
|
38 |
-
}
|
39 |
-
|
40 |
-
/* Range navigation */
|
41 |
-
.link-performance-report {
|
42 |
-
position: relative;
|
43 |
-
background:#fff;
|
44 |
-
min-height: 300px;
|
45 |
-
border: 1px solid #dedede;
|
46 |
-
}
|
47 |
-
.link-performance-report .stats-range {
|
48 |
-
position: relative;
|
49 |
-
background: #f7f7f7;
|
50 |
-
}
|
51 |
-
.link-performance-report .stats-range:after {
|
52 |
-
content: '';
|
53 |
-
display: table;
|
54 |
-
position: absolute;
|
55 |
-
z-index: 1;
|
56 |
-
bottom: -1px;
|
57 |
-
border-top: 1px solid #ccc;
|
58 |
-
width: 100%;
|
59 |
-
height: 1px;
|
60 |
-
}
|
61 |
-
.link-performance-report .stats-range ul {
|
62 |
-
margin: 0;
|
63 |
-
padding: 0;
|
64 |
-
}
|
65 |
-
.link-performance-report .stats-range ul:after {
|
66 |
-
content: '';
|
67 |
-
display: block;
|
68 |
-
clear: both;
|
69 |
-
}
|
70 |
-
.link-performance-report .stats-range ul li {
|
71 |
-
float: left;
|
72 |
-
position: relative;
|
73 |
-
margin: 0;
|
74 |
-
}
|
75 |
-
.link-performance-report .stats-range ul li a,
|
76 |
-
.link-performance-report .stats-range ul li > span {
|
77 |
-
position:relative;
|
78 |
-
z-index: 2;
|
79 |
-
display: block;
|
80 |
-
padding: 15px 10px;
|
81 |
-
font-weight: bold;
|
82 |
-
font-size: 14px;
|
83 |
-
text-decoration: none;
|
84 |
-
border-right: 1px solid #dedede;
|
85 |
-
border-bottom: 1px solid transparent;
|
86 |
-
}
|
87 |
-
.link-performance-report .stats-range ul li.current a {
|
88 |
-
background:#fff;
|
89 |
-
border-bottom-color: #fff;
|
90 |
-
color: #555 !important;
|
91 |
-
}
|
92 |
-
.link-performance-report .stats-range ul li.custom-range {
|
93 |
-
width: 400px;
|
94 |
-
}
|
95 |
-
.link-performance-report .stats-range ul li.custom-range span {
|
96 |
-
display: inline-block;
|
97 |
-
float: left;
|
98 |
-
color: #555;
|
99 |
-
border-right: 0;
|
100 |
-
}
|
101 |
-
.link-performance-report .stats-range ul li.custom-range:after {
|
102 |
-
content: '';
|
103 |
-
display: table;
|
104 |
-
clear: both;
|
105 |
-
}
|
106 |
-
|
107 |
-
/* Custom range form */
|
108 |
-
#custom-date-range {
|
109 |
-
margin-top: 10px;
|
110 |
-
}
|
111 |
-
#custom-date-range .range_datepicker {
|
112 |
-
float: left;
|
113 |
-
width: 100px;
|
114 |
-
text-align: center;
|
115 |
-
background: transparent;
|
116 |
-
border: 0;
|
117 |
-
box-shadow: none;
|
118 |
-
-moz-box-shadow: none;
|
119 |
-
-webkit-box-shadow: none;
|
120 |
-
}
|
121 |
-
#custom-date-range span {
|
122 |
-
display: inline-block;
|
123 |
-
float: left;
|
124 |
-
margin-top: 3px;
|
125 |
-
}
|
126 |
-
|
127 |
-
/* Chart layout */
|
128 |
-
.chart-sidebar {
|
129 |
-
display: block;
|
130 |
-
width: 225px;
|
131 |
-
float: left;
|
132 |
-
}
|
133 |
-
.report-chart-wrap {
|
134 |
-
margin: 10px;
|
135 |
-
}
|
136 |
-
|
137 |
-
/* Chart legend */
|
138 |
-
ul.chart-legend {
|
139 |
-
margin: 15px 0 0 0;
|
140 |
-
border: 1px solid #dadada;
|
141 |
-
border-right: 0;
|
142 |
-
}
|
143 |
-
ul.chart-legend li {
|
144 |
-
position: relative;
|
145 |
-
padding: 10px 15px;
|
146 |
-
margin: 0;
|
147 |
-
border-right: 5px solid #ccc;
|
148 |
-
border-bottom: 1px solid #dadada !important;
|
149 |
-
}
|
150 |
-
ul.chart-legend li span {
|
151 |
-
display: block;
|
152 |
-
color: #aaa;
|
153 |
-
font-size: 11px;
|
154 |
-
}
|
155 |
-
ul.chart-legend li em.count {
|
156 |
-
position: absolute;
|
157 |
-
top: 50%;
|
158 |
-
right: 10px;
|
159 |
-
margin-top: -12px;
|
160 |
-
display: inline-block;
|
161 |
-
padding: 1px 5px;
|
162 |
-
background: #565656;
|
163 |
-
color: #fff;
|
164 |
-
border-radius: 50px;
|
165 |
-
font-size: 11px;
|
166 |
-
font-style: normal;
|
167 |
-
}
|
168 |
-
ul.chart-legend li:hover {
|
169 |
-
background: #efefef;
|
170 |
-
}
|
171 |
-
ul.chart-legend li:last-child {
|
172 |
-
border-bottom: 0 !important;
|
173 |
-
}
|
174 |
-
.add-legend {
|
175 |
-
padding: 7px 12px;
|
176 |
-
border: 1px solid #dadada;
|
177 |
-
border-top: 0;
|
178 |
-
}
|
179 |
-
.add-legend:after {
|
180 |
-
content: '';
|
181 |
-
display: table;
|
182 |
-
clear: both;
|
183 |
-
}
|
184 |
-
.add-legend label {
|
185 |
-
display: block;
|
186 |
-
margin-bottom: 5px;
|
187 |
-
}
|
188 |
-
.add-legend input {
|
189 |
-
width: 100%;
|
190 |
-
padding: 5px;
|
191 |
-
box-sizing: border-box;
|
192 |
-
}
|
193 |
-
.add-legend button {
|
194 |
-
float: right;
|
195 |
-
}
|
196 |
-
.add-legend .input-wrap {
|
197 |
-
position: relative;
|
198 |
-
margin-bottom: 5px;
|
199 |
-
}
|
200 |
-
.add-legend ul.link-search-result {
|
201 |
-
position: absolute;
|
202 |
-
z-index: 2;
|
203 |
-
top: 100%;
|
204 |
-
left: 0;
|
205 |
-
width: 99%;
|
206 |
-
margin: -2px 0 0 1px;
|
207 |
-
background: #fff;
|
208 |
-
border: 1px solid #dadada;
|
209 |
-
}
|
210 |
-
.add-legend ul.link-search-result li {
|
211 |
-
margin: 0;
|
212 |
-
padding: 3px 5px;
|
213 |
-
border-bottom: 1px solid #dadada;
|
214 |
-
white-space: nowrap;
|
215 |
-
overflow: hidden;
|
216 |
-
}
|
217 |
-
.add-legend ul.link-search-result li:hover {
|
218 |
-
background: #efefef;
|
219 |
-
cursor: pointer;
|
220 |
-
}
|
221 |
-
|
222 |
-
|
223 |
-
/* Chart placeholder */
|
224 |
-
.report-chart-placeholder {
|
225 |
-
height: 600px;
|
226 |
-
margin-left: 235px;
|
227 |
-
}
|
228 |
-
.report-chart-placeholder:after {
|
229 |
-
content: '';
|
230 |
-
display: table;
|
231 |
-
clear: both;
|
232 |
-
}
|
233 |
-
body .chart-tooltip {
|
234 |
-
position: absolute;
|
235 |
-
padding: 3px 5px;
|
236 |
-
background: rgba( 0, 0, 0, 0.8 );
|
237 |
-
color: #fff;
|
238 |
-
font-size: 11px;
|
239 |
-
border-radius: 5px;
|
240 |
-
}
|
241 |
-
|
242 |
-
/* overlay */
|
243 |
-
.link-performance-report .overlay {
|
244 |
-
display: none;
|
245 |
-
position: absolute;
|
246 |
-
top: 0;
|
247 |
-
left:0;
|
248 |
-
background-image: url( '../../images/spinner-2x.gif' );
|
249 |
-
background-repeat: no-repeat;
|
250 |
-
background-position: center center;
|
251 |
-
background-color: rgba(255, 255, 255, 0.64);
|
252 |
-
width: 100%;
|
253 |
-
height: 1000px;
|
254 |
-
z-index: 10;
|
255 |
-
}
|
1 |
+
/* Top Navigation */
|
2 |
+
.thirsty-nav-tab {
|
3 |
+
margin: 20px 0 15px;
|
4 |
+
position: relative;
|
5 |
+
}
|
6 |
+
.thirsty-nav-tab:after {
|
7 |
+
content: '';
|
8 |
+
display: block;
|
9 |
+
position: absolute;
|
10 |
+
z-index: 1;
|
11 |
+
bottom: -1px;
|
12 |
+
width: 100%;
|
13 |
+
height:1px;
|
14 |
+
border-top: 1px solid #ccc;
|
15 |
+
}
|
16 |
+
.thirsty-nav-tab a.tab {
|
17 |
+
display: inline-block;
|
18 |
+
position: relative;
|
19 |
+
z-index: 2;
|
20 |
+
padding: 8px 10px;
|
21 |
+
margin-right: 2px;
|
22 |
+
background: #e5e5e5;
|
23 |
+
border: 1px solid #ccc;
|
24 |
+
text-decoration: none;
|
25 |
+
font-weight: bold;
|
26 |
+
color: #111;
|
27 |
+
font-size: 14px;
|
28 |
+
}
|
29 |
+
.thirsty-nav-tab a.tab:hover {
|
30 |
+
background: #fff;
|
31 |
+
}
|
32 |
+
.thirsty-nav-tab a.tab-active {
|
33 |
+
background: #f1f1f1 !important;
|
34 |
+
border-bottom-color: #f1f1f1;
|
35 |
+
}
|
36 |
+
.thirsty-nav-tab a.tab:first-child {
|
37 |
+
margin-left: 8px;
|
38 |
+
}
|
39 |
+
|
40 |
+
/* Range navigation */
|
41 |
+
.link-performance-report {
|
42 |
+
position: relative;
|
43 |
+
background:#fff;
|
44 |
+
min-height: 300px;
|
45 |
+
border: 1px solid #dedede;
|
46 |
+
}
|
47 |
+
.link-performance-report .stats-range {
|
48 |
+
position: relative;
|
49 |
+
background: #f7f7f7;
|
50 |
+
}
|
51 |
+
.link-performance-report .stats-range:after {
|
52 |
+
content: '';
|
53 |
+
display: table;
|
54 |
+
position: absolute;
|
55 |
+
z-index: 1;
|
56 |
+
bottom: -1px;
|
57 |
+
border-top: 1px solid #ccc;
|
58 |
+
width: 100%;
|
59 |
+
height: 1px;
|
60 |
+
}
|
61 |
+
.link-performance-report .stats-range ul {
|
62 |
+
margin: 0;
|
63 |
+
padding: 0;
|
64 |
+
}
|
65 |
+
.link-performance-report .stats-range ul:after {
|
66 |
+
content: '';
|
67 |
+
display: block;
|
68 |
+
clear: both;
|
69 |
+
}
|
70 |
+
.link-performance-report .stats-range ul li {
|
71 |
+
float: left;
|
72 |
+
position: relative;
|
73 |
+
margin: 0;
|
74 |
+
}
|
75 |
+
.link-performance-report .stats-range ul li a,
|
76 |
+
.link-performance-report .stats-range ul li > span {
|
77 |
+
position:relative;
|
78 |
+
z-index: 2;
|
79 |
+
display: block;
|
80 |
+
padding: 15px 10px;
|
81 |
+
font-weight: bold;
|
82 |
+
font-size: 14px;
|
83 |
+
text-decoration: none;
|
84 |
+
border-right: 1px solid #dedede;
|
85 |
+
border-bottom: 1px solid transparent;
|
86 |
+
}
|
87 |
+
.link-performance-report .stats-range ul li.current a {
|
88 |
+
background:#fff;
|
89 |
+
border-bottom-color: #fff;
|
90 |
+
color: #555 !important;
|
91 |
+
}
|
92 |
+
.link-performance-report .stats-range ul li.custom-range {
|
93 |
+
width: 400px;
|
94 |
+
}
|
95 |
+
.link-performance-report .stats-range ul li.custom-range span {
|
96 |
+
display: inline-block;
|
97 |
+
float: left;
|
98 |
+
color: #555;
|
99 |
+
border-right: 0;
|
100 |
+
}
|
101 |
+
.link-performance-report .stats-range ul li.custom-range:after {
|
102 |
+
content: '';
|
103 |
+
display: table;
|
104 |
+
clear: both;
|
105 |
+
}
|
106 |
+
|
107 |
+
/* Custom range form */
|
108 |
+
#custom-date-range {
|
109 |
+
margin-top: 10px;
|
110 |
+
}
|
111 |
+
#custom-date-range .range_datepicker {
|
112 |
+
float: left;
|
113 |
+
width: 100px;
|
114 |
+
text-align: center;
|
115 |
+
background: transparent;
|
116 |
+
border: 0;
|
117 |
+
box-shadow: none;
|
118 |
+
-moz-box-shadow: none;
|
119 |
+
-webkit-box-shadow: none;
|
120 |
+
}
|
121 |
+
#custom-date-range span {
|
122 |
+
display: inline-block;
|
123 |
+
float: left;
|
124 |
+
margin-top: 3px;
|
125 |
+
}
|
126 |
+
|
127 |
+
/* Chart layout */
|
128 |
+
.chart-sidebar {
|
129 |
+
display: block;
|
130 |
+
width: 225px;
|
131 |
+
float: left;
|
132 |
+
}
|
133 |
+
.report-chart-wrap {
|
134 |
+
margin: 10px;
|
135 |
+
}
|
136 |
+
|
137 |
+
/* Chart legend */
|
138 |
+
ul.chart-legend {
|
139 |
+
margin: 15px 0 0 0;
|
140 |
+
border: 1px solid #dadada;
|
141 |
+
border-right: 0;
|
142 |
+
}
|
143 |
+
ul.chart-legend li {
|
144 |
+
position: relative;
|
145 |
+
padding: 10px 15px;
|
146 |
+
margin: 0;
|
147 |
+
border-right: 5px solid #ccc;
|
148 |
+
border-bottom: 1px solid #dadada !important;
|
149 |
+
}
|
150 |
+
ul.chart-legend li span {
|
151 |
+
display: block;
|
152 |
+
color: #aaa;
|
153 |
+
font-size: 11px;
|
154 |
+
}
|
155 |
+
ul.chart-legend li em.count {
|
156 |
+
position: absolute;
|
157 |
+
top: 50%;
|
158 |
+
right: 10px;
|
159 |
+
margin-top: -12px;
|
160 |
+
display: inline-block;
|
161 |
+
padding: 1px 5px;
|
162 |
+
background: #565656;
|
163 |
+
color: #fff;
|
164 |
+
border-radius: 50px;
|
165 |
+
font-size: 11px;
|
166 |
+
font-style: normal;
|
167 |
+
}
|
168 |
+
ul.chart-legend li:hover {
|
169 |
+
background: #efefef;
|
170 |
+
}
|
171 |
+
ul.chart-legend li:last-child {
|
172 |
+
border-bottom: 0 !important;
|
173 |
+
}
|
174 |
+
.add-legend {
|
175 |
+
padding: 7px 12px;
|
176 |
+
border: 1px solid #dadada;
|
177 |
+
border-top: 0;
|
178 |
+
}
|
179 |
+
.add-legend:after {
|
180 |
+
content: '';
|
181 |
+
display: table;
|
182 |
+
clear: both;
|
183 |
+
}
|
184 |
+
.add-legend label {
|
185 |
+
display: block;
|
186 |
+
margin-bottom: 5px;
|
187 |
+
}
|
188 |
+
.add-legend input {
|
189 |
+
width: 100%;
|
190 |
+
padding: 5px;
|
191 |
+
box-sizing: border-box;
|
192 |
+
}
|
193 |
+
.add-legend button {
|
194 |
+
float: right;
|
195 |
+
}
|
196 |
+
.add-legend .input-wrap {
|
197 |
+
position: relative;
|
198 |
+
margin-bottom: 5px;
|
199 |
+
}
|
200 |
+
.add-legend ul.link-search-result {
|
201 |
+
position: absolute;
|
202 |
+
z-index: 2;
|
203 |
+
top: 100%;
|
204 |
+
left: 0;
|
205 |
+
width: 99%;
|
206 |
+
margin: -2px 0 0 1px;
|
207 |
+
background: #fff;
|
208 |
+
border: 1px solid #dadada;
|
209 |
+
}
|
210 |
+
.add-legend ul.link-search-result li {
|
211 |
+
margin: 0;
|
212 |
+
padding: 3px 5px;
|
213 |
+
border-bottom: 1px solid #dadada;
|
214 |
+
white-space: nowrap;
|
215 |
+
overflow: hidden;
|
216 |
+
}
|
217 |
+
.add-legend ul.link-search-result li:hover {
|
218 |
+
background: #efefef;
|
219 |
+
cursor: pointer;
|
220 |
+
}
|
221 |
+
|
222 |
+
|
223 |
+
/* Chart placeholder */
|
224 |
+
.report-chart-placeholder {
|
225 |
+
height: 600px;
|
226 |
+
margin-left: 235px;
|
227 |
+
}
|
228 |
+
.report-chart-placeholder:after {
|
229 |
+
content: '';
|
230 |
+
display: table;
|
231 |
+
clear: both;
|
232 |
+
}
|
233 |
+
body .chart-tooltip {
|
234 |
+
position: absolute;
|
235 |
+
padding: 3px 5px;
|
236 |
+
background: rgba( 0, 0, 0, 0.8 );
|
237 |
+
color: #fff;
|
238 |
+
font-size: 11px;
|
239 |
+
border-radius: 5px;
|
240 |
+
}
|
241 |
+
|
242 |
+
/* overlay */
|
243 |
+
.link-performance-report .overlay {
|
244 |
+
display: none;
|
245 |
+
position: absolute;
|
246 |
+
top: 0;
|
247 |
+
left:0;
|
248 |
+
background-image: url( '../../images/spinner-2x.gif' );
|
249 |
+
background-repeat: no-repeat;
|
250 |
+
background-position: center center;
|
251 |
+
background-color: rgba(255, 255, 255, 0.64);
|
252 |
+
width: 100%;
|
253 |
+
height: 1000px;
|
254 |
+
z-index: 10;
|
255 |
+
}
|
css/admin/ta-settings.css
CHANGED
@@ -1,113 +1,113 @@
|
|
1 |
-
#wpbody-content {
|
2 |
-
padding-bottom: 10px;
|
3 |
-
margin-bottom: 45px;
|
4 |
-
}
|
5 |
-
#wpbody-content .ta-settings-wrapper {
|
6 |
-
position: relative;
|
7 |
-
}
|
8 |
-
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper {
|
9 |
-
float: left;
|
10 |
-
width: 150px;
|
11 |
-
border: 0;
|
12 |
-
margin-left: 20px;
|
13 |
-
}
|
14 |
-
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a {
|
15 |
-
width: 100%;
|
16 |
-
float: right;
|
17 |
-
clear: right;
|
18 |
-
position: relative;
|
19 |
-
z-index: 3;
|
20 |
-
}
|
21 |
-
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a.nav-tab-active {
|
22 |
-
border-right: 1px solid #f1f1f1;
|
23 |
-
}
|
24 |
-
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a:last-child {
|
25 |
-
border-bottom: 1px solid #ccc;
|
26 |
-
}
|
27 |
-
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a.tapro-upgrade.nav-tab {
|
28 |
-
color: #fff;
|
29 |
-
background: #338850;
|
30 |
-
background: -moz-linear-gradient(left, #338850 0%, #2f867e 51%, #2e6e8a 100%);
|
31 |
-
background: -webkit-linear-gradient(left, #338850 0%,#2f867e 51%,#2e6e8a 100%);
|
32 |
-
background: linear-gradient(to right, #338850 0%,#2f867e 51%,#2e6e8a 100%);
|
33 |
-
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#338850', endColorstr='#2e6e8a',GradientType=1 );
|
34 |
-
border: 1px solid #276573 !important;
|
35 |
-
}
|
36 |
-
#wpbody-content .ta-settings-wrapper > .ta-settings-form {
|
37 |
-
position: relative;
|
38 |
-
float:left;
|
39 |
-
left: -1px;
|
40 |
-
padding-left: 20px;
|
41 |
-
width: -moz-calc(100% - 190px);
|
42 |
-
width: -webkit-calc(100% - 190px);
|
43 |
-
width: -o-calc(100% - 190px);
|
44 |
-
width: calc(100% - 190px);
|
45 |
-
overflow: hidden;
|
46 |
-
}
|
47 |
-
#wpbody-content .ta-settings-wrapper > .ta-settings-form:before {
|
48 |
-
content: '';
|
49 |
-
position: absolute;
|
50 |
-
z-index: 1;
|
51 |
-
top: 0;
|
52 |
-
left: 0px;
|
53 |
-
display: block;
|
54 |
-
width: 1px;
|
55 |
-
height: 3000px;
|
56 |
-
border-left:1px solid #ccc;
|
57 |
-
}
|
58 |
-
#wpbody-content .ta-settings:after,
|
59 |
-
#wpbody-content .ta-settings-wrapper:after,
|
60 |
-
#wpbody-content .ta-settings .nav-tab-wrapper:after {
|
61 |
-
content: '';
|
62 |
-
display: table;
|
63 |
-
clear: both;
|
64 |
-
}
|
65 |
-
.ta-settings .form-table td,
|
66 |
-
.ta-settings .form-table th {
|
67 |
-
vertical-align: top;
|
68 |
-
padding: 20px 10px 20px 0;
|
69 |
-
}
|
70 |
-
.ta-settings .form-table .submit-wrapper {
|
71 |
-
padding: 0;
|
72 |
-
}
|
73 |
-
.ta-settings .form-table .forminp-radio label {
|
74 |
-
margin-top: 0 !important;
|
75 |
-
line-height: 1em;
|
76 |
-
}
|
77 |
-
.ta-settings .form-table .forminp-radio ul {
|
78 |
-
margin: 5px 0 0;
|
79 |
-
}
|
80 |
-
.ta-settings .form-table .forminp-checkbox label {
|
81 |
-
margin-top: 5px !important;
|
82 |
-
line-height: 1em;
|
83 |
-
}
|
84 |
-
.ta-settings .form-table td .description {
|
85 |
-
margin-top: 0;
|
86 |
-
}
|
87 |
-
tr.ta_link_prefix_custom-row {
|
88 |
-
display: none;
|
89 |
-
}
|
90 |
-
tr.ta_social_links-row ul {
|
91 |
-
margin: 0;
|
92 |
-
}
|
93 |
-
tr.ta_social_links-row ul li {
|
94 |
-
margin-bottom: 15px;
|
95 |
-
}
|
96 |
-
tr.ta_social_links-row ul li:nth-child(1) a {
|
97 |
-
margin-right: 8px;
|
98 |
-
}
|
99 |
-
tr.ta_social_links-row ul li:nth-child(2) a {
|
100 |
-
margin-right: 10px;
|
101 |
-
}
|
102 |
-
td.forminp .selectize-input {
|
103 |
-
padding: 5px 8px;
|
104 |
-
}
|
105 |
-
td.forminp.toggle-cat select,
|
106 |
-
td.forminp.toggle-cat .selectize-input {
|
107 |
-
width: 120px !important;
|
108 |
-
display: inline-block;
|
109 |
-
}
|
110 |
-
td.forminp.toggle-cat .desc {
|
111 |
-
display: inline;
|
112 |
-
margin-left: 5px;
|
113 |
-
}
|
1 |
+
#wpbody-content {
|
2 |
+
padding-bottom: 10px;
|
3 |
+
margin-bottom: 45px;
|
4 |
+
}
|
5 |
+
#wpbody-content .ta-settings-wrapper {
|
6 |
+
position: relative;
|
7 |
+
}
|
8 |
+
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper {
|
9 |
+
float: left;
|
10 |
+
width: 150px;
|
11 |
+
border: 0;
|
12 |
+
margin-left: 20px;
|
13 |
+
}
|
14 |
+
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a {
|
15 |
+
width: 100%;
|
16 |
+
float: right;
|
17 |
+
clear: right;
|
18 |
+
position: relative;
|
19 |
+
z-index: 3;
|
20 |
+
}
|
21 |
+
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a.nav-tab-active {
|
22 |
+
border-right: 1px solid #f1f1f1;
|
23 |
+
}
|
24 |
+
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a:last-child {
|
25 |
+
border-bottom: 1px solid #ccc;
|
26 |
+
}
|
27 |
+
#wpbody-content .ta-settings-wrapper .nav-tab-wrapper a.tapro-upgrade.nav-tab {
|
28 |
+
color: #fff;
|
29 |
+
background: #338850;
|
30 |
+
background: -moz-linear-gradient(left, #338850 0%, #2f867e 51%, #2e6e8a 100%);
|
31 |
+
background: -webkit-linear-gradient(left, #338850 0%,#2f867e 51%,#2e6e8a 100%);
|
32 |
+
background: linear-gradient(to right, #338850 0%,#2f867e 51%,#2e6e8a 100%);
|
33 |
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#338850', endColorstr='#2e6e8a',GradientType=1 );
|
34 |
+
border: 1px solid #276573 !important;
|
35 |
+
}
|
36 |
+
#wpbody-content .ta-settings-wrapper > .ta-settings-form {
|
37 |
+
position: relative;
|
38 |
+
float:left;
|
39 |
+
left: -1px;
|
40 |
+
padding-left: 20px;
|
41 |
+
width: -moz-calc(100% - 190px);
|
42 |
+
width: -webkit-calc(100% - 190px);
|
43 |
+
width: -o-calc(100% - 190px);
|
44 |
+
width: calc(100% - 190px);
|
45 |
+
overflow: hidden;
|
46 |
+
}
|
47 |
+
#wpbody-content .ta-settings-wrapper > .ta-settings-form:before {
|
48 |
+
content: '';
|
49 |
+
position: absolute;
|
50 |
+
z-index: 1;
|
51 |
+
top: 0;
|
52 |
+
left: 0px;
|
53 |
+
display: block;
|
54 |
+
width: 1px;
|
55 |
+
height: 3000px;
|
56 |
+
border-left:1px solid #ccc;
|
57 |
+
}
|
58 |
+
#wpbody-content .ta-settings:after,
|
59 |
+
#wpbody-content .ta-settings-wrapper:after,
|
60 |
+
#wpbody-content .ta-settings .nav-tab-wrapper:after {
|
61 |
+
content: '';
|
62 |
+
display: table;
|
63 |
+
clear: both;
|
64 |
+
}
|
65 |
+
.ta-settings .form-table td,
|
66 |
+
.ta-settings .form-table th {
|
67 |
+
vertical-align: top;
|
68 |
+
padding: 20px 10px 20px 0;
|
69 |
+
}
|
70 |
+
.ta-settings .form-table .submit-wrapper {
|
71 |
+
padding: 0;
|
72 |
+
}
|
73 |
+
.ta-settings .form-table .forminp-radio label {
|
74 |
+
margin-top: 0 !important;
|
75 |
+
line-height: 1em;
|
76 |
+
}
|
77 |
+
.ta-settings .form-table .forminp-radio ul {
|
78 |
+
margin: 5px 0 0;
|
79 |
+
}
|
80 |
+
.ta-settings .form-table .forminp-checkbox label {
|
81 |
+
margin-top: 5px !important;
|
82 |
+
line-height: 1em;
|
83 |
+
}
|
84 |
+
.ta-settings .form-table td .description {
|
85 |
+
margin-top: 0;
|
86 |
+
}
|
87 |
+
tr.ta_link_prefix_custom-row {
|
88 |
+
display: none;
|
89 |
+
}
|
90 |
+
tr.ta_social_links-row ul {
|
91 |
+
margin: 0;
|
92 |
+
}
|
93 |
+
tr.ta_social_links-row ul li {
|
94 |
+
margin-bottom: 15px;
|
95 |
+
}
|
96 |
+
tr.ta_social_links-row ul li:nth-child(1) a {
|
97 |
+
margin-right: 8px;
|
98 |
+
}
|
99 |
+
tr.ta_social_links-row ul li:nth-child(2) a {
|
100 |
+
margin-right: 10px;
|
101 |
+
}
|
102 |
+
td.forminp .selectize-input {
|
103 |
+
padding: 5px 8px;
|
104 |
+
}
|
105 |
+
td.forminp.toggle-cat select,
|
106 |
+
td.forminp.toggle-cat .selectize-input {
|
107 |
+
width: 120px !important;
|
108 |
+
display: inline-block;
|
109 |
+
}
|
110 |
+
td.forminp.toggle-cat .desc {
|
111 |
+
display: inline;
|
112 |
+
margin-left: 5px;
|
113 |
+
}
|
css/admin/tinymce/editor.css
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
-
span.ta-editor-shortcode {
|
2 |
-
border-bottom: 1px dashed #3faa67;
|
3 |
-
cursor: pointer;
|
4 |
-
}
|
5 |
-
span.ta-editor-shortcode.shortcode-selected {
|
6 |
-
background: #e5f5ed;
|
7 |
-
box-shadow: 0 0 2px 3px #e5f5ed;
|
8 |
-
border-radius: 5px
|
9 |
}
|
1 |
+
span.ta-editor-shortcode {
|
2 |
+
border-bottom: 1px dashed #3faa67;
|
3 |
+
cursor: pointer;
|
4 |
+
}
|
5 |
+
span.ta-editor-shortcode.shortcode-selected {
|
6 |
+
background: #e5f5ed;
|
7 |
+
box-shadow: 0 0 2px 3px #e5f5ed;
|
8 |
+
border-radius: 5px
|
9 |
}
|
css/lib/jquery-tiptip/jquery-tiptip.css
CHANGED
@@ -1,109 +1,109 @@
|
|
1 |
-
/* TipTip CSS - Version 1.2 */
|
2 |
-
|
3 |
-
#tiptip_holder {
|
4 |
-
display: none;
|
5 |
-
position: absolute;
|
6 |
-
top: 0;
|
7 |
-
left: 0;
|
8 |
-
z-index: 99999;
|
9 |
-
}
|
10 |
-
|
11 |
-
#tiptip_holder.tip_top {
|
12 |
-
padding-bottom: 5px;
|
13 |
-
}
|
14 |
-
|
15 |
-
#tiptip_holder.tip_bottom {
|
16 |
-
padding-top: 5px;
|
17 |
-
}
|
18 |
-
|
19 |
-
#tiptip_holder.tip_right {
|
20 |
-
padding-left: 5px;
|
21 |
-
}
|
22 |
-
|
23 |
-
#tiptip_holder.tip_left {
|
24 |
-
padding-right: 5px;
|
25 |
-
}
|
26 |
-
|
27 |
-
#tiptip_content {
|
28 |
-
font-size: 11px;
|
29 |
-
color: #fff;
|
30 |
-
text-shadow: 0 0 2px #000;
|
31 |
-
padding: 4px 8px;
|
32 |
-
border: 1px solid rgba(255,255,255,0.25);
|
33 |
-
background-color: rgb(25,25,25);
|
34 |
-
background-color: rgba(25,25,25,0.92);
|
35 |
-
border-radius: 3px;
|
36 |
-
-webkit-border-radius: 3px;
|
37 |
-
-moz-border-radius: 3px;
|
38 |
-
}
|
39 |
-
|
40 |
-
#tiptip_arrow, #tiptip_arrow_inner {
|
41 |
-
position: absolute;
|
42 |
-
border-color: transparent;
|
43 |
-
border-style: solid;
|
44 |
-
border-width: 6px;
|
45 |
-
height: 0;
|
46 |
-
width: 0;
|
47 |
-
}
|
48 |
-
|
49 |
-
#tiptip_holder.tip_top #tiptip_arrow {
|
50 |
-
border-top-color: #fff;
|
51 |
-
border-top-color: rgba(255,255,255,0.35);
|
52 |
-
}
|
53 |
-
|
54 |
-
#tiptip_holder.tip_bottom #tiptip_arrow {
|
55 |
-
border-bottom-color: #fff;
|
56 |
-
border-bottom-color: rgba(255,255,255,0.35);
|
57 |
-
}
|
58 |
-
|
59 |
-
#tiptip_holder.tip_right #tiptip_arrow {
|
60 |
-
border-right-color: #fff;
|
61 |
-
border-right-color: rgba(255,255,255,0.35);
|
62 |
-
}
|
63 |
-
|
64 |
-
#tiptip_holder.tip_left #tiptip_arrow {
|
65 |
-
border-left-color: #fff;
|
66 |
-
border-left-color: rgba(255,255,255,0.35);
|
67 |
-
}
|
68 |
-
|
69 |
-
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
70 |
-
margin-top: -7px;
|
71 |
-
margin-left: -6px;
|
72 |
-
border-top-color: rgb(25,25,25);
|
73 |
-
border-top-color: rgba(25,25,25,0.92);
|
74 |
-
}
|
75 |
-
|
76 |
-
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
77 |
-
margin-top: -5px;
|
78 |
-
margin-left: -6px;
|
79 |
-
border-bottom-color: rgb(25,25,25);
|
80 |
-
border-bottom-color: rgba(25,25,25,0.92);
|
81 |
-
}
|
82 |
-
|
83 |
-
#tiptip_holder.tip_right #tiptip_arrow_inner {
|
84 |
-
margin-top: -6px;
|
85 |
-
margin-left: -5px;
|
86 |
-
border-right-color: rgb(25,25,25);
|
87 |
-
border-right-color: rgba(25,25,25,0.92);
|
88 |
-
}
|
89 |
-
|
90 |
-
#tiptip_holder.tip_left #tiptip_arrow_inner {
|
91 |
-
margin-top: -6px;
|
92 |
-
margin-left: -7px;
|
93 |
-
border-left-color: rgb(25,25,25);
|
94 |
-
border-left-color: rgba(25,25,25,0.92);
|
95 |
-
}
|
96 |
-
|
97 |
-
/* Webkit Hacks */
|
98 |
-
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
99 |
-
#tiptip_content {
|
100 |
-
padding: 4px 8px 5px 8px;
|
101 |
-
background-color: rgba(45,45,45,0.88);
|
102 |
-
}
|
103 |
-
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
104 |
-
border-bottom-color: rgba(45,45,45,0.88);
|
105 |
-
}
|
106 |
-
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
107 |
-
border-top-color: rgba(20,20,20,0.92);
|
108 |
-
}
|
109 |
-
}
|
1 |
+
/* TipTip CSS - Version 1.2 */
|
2 |
+
|
3 |
+
#tiptip_holder {
|
4 |
+
display: none;
|
5 |
+
position: absolute;
|
6 |
+
top: 0;
|
7 |
+
left: 0;
|
8 |
+
z-index: 99999;
|
9 |
+
}
|
10 |
+
|
11 |
+
#tiptip_holder.tip_top {
|
12 |
+
padding-bottom: 5px;
|
13 |
+
}
|
14 |
+
|
15 |
+
#tiptip_holder.tip_bottom {
|
16 |
+
padding-top: 5px;
|
17 |
+
}
|
18 |
+
|
19 |
+
#tiptip_holder.tip_right {
|
20 |
+
padding-left: 5px;
|
21 |
+
}
|
22 |
+
|
23 |
+
#tiptip_holder.tip_left {
|
24 |
+
padding-right: 5px;
|
25 |
+
}
|
26 |
+
|
27 |
+
#tiptip_content {
|
28 |
+
font-size: 11px;
|
29 |
+
color: #fff;
|
30 |
+
text-shadow: 0 0 2px #000;
|
31 |
+
padding: 4px 8px;
|
32 |
+
border: 1px solid rgba(255,255,255,0.25);
|
33 |
+
background-color: rgb(25,25,25);
|
34 |
+
background-color: rgba(25,25,25,0.92);
|
35 |
+
border-radius: 3px;
|
36 |
+
-webkit-border-radius: 3px;
|
37 |
+
-moz-border-radius: 3px;
|
38 |
+
}
|
39 |
+
|
40 |
+
#tiptip_arrow, #tiptip_arrow_inner {
|
41 |
+
position: absolute;
|
42 |
+
border-color: transparent;
|
43 |
+
border-style: solid;
|
44 |
+
border-width: 6px;
|
45 |
+
height: 0;
|
46 |
+
width: 0;
|
47 |
+
}
|
48 |
+
|
49 |
+
#tiptip_holder.tip_top #tiptip_arrow {
|
50 |
+
border-top-color: #fff;
|
51 |
+
border-top-color: rgba(255,255,255,0.35);
|
52 |
+
}
|
53 |
+
|
54 |
+
#tiptip_holder.tip_bottom #tiptip_arrow {
|
55 |
+
border-bottom-color: #fff;
|
56 |
+
border-bottom-color: rgba(255,255,255,0.35);
|
57 |
+
}
|
58 |
+
|
59 |
+
#tiptip_holder.tip_right #tiptip_arrow {
|
60 |
+
border-right-color: #fff;
|
61 |
+
border-right-color: rgba(255,255,255,0.35);
|
62 |
+
}
|
63 |
+
|
64 |
+
#tiptip_holder.tip_left #tiptip_arrow {
|
65 |
+
border-left-color: #fff;
|
66 |
+
border-left-color: rgba(255,255,255,0.35);
|
67 |
+
}
|
68 |
+
|
69 |
+
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
70 |
+
margin-top: -7px;
|
71 |
+
margin-left: -6px;
|
72 |
+
border-top-color: rgb(25,25,25);
|
73 |
+
border-top-color: rgba(25,25,25,0.92);
|
74 |
+
}
|
75 |
+
|
76 |
+
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
77 |
+
margin-top: -5px;
|
78 |
+
margin-left: -6px;
|
79 |
+
border-bottom-color: rgb(25,25,25);
|
80 |
+
border-bottom-color: rgba(25,25,25,0.92);
|
81 |
+
}
|
82 |
+
|
83 |
+
#tiptip_holder.tip_right #tiptip_arrow_inner {
|
84 |
+
margin-top: -6px;
|
85 |
+
margin-left: -5px;
|
86 |
+
border-right-color: rgb(25,25,25);
|
87 |
+
border-right-color: rgba(25,25,25,0.92);
|
88 |
+
}
|
89 |
+
|
90 |
+
#tiptip_holder.tip_left #tiptip_arrow_inner {
|
91 |
+
margin-top: -6px;
|
92 |
+
margin-left: -7px;
|
93 |
+
border-left-color: rgb(25,25,25);
|
94 |
+
border-left-color: rgba(25,25,25,0.92);
|
95 |
+
}
|
96 |
+
|
97 |
+
/* Webkit Hacks */
|
98 |
+
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
99 |
+
#tiptip_content {
|
100 |
+
padding: 4px 8px 5px 8px;
|
101 |
+
background-color: rgba(45,45,45,0.88);
|
102 |
+
}
|
103 |
+
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
104 |
+
border-bottom-color: rgba(45,45,45,0.88);
|
105 |
+
}
|
106 |
+
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
107 |
+
border-top-color: rgba(20,20,20,0.92);
|
108 |
+
}
|
109 |
+
}
|
css/lib/select2/select2.css
CHANGED
@@ -1,484 +1,484 @@
|
|
1 |
-
.select2-container {
|
2 |
-
box-sizing: border-box;
|
3 |
-
display: inline-block;
|
4 |
-
margin: 0;
|
5 |
-
position: relative;
|
6 |
-
vertical-align: middle; }
|
7 |
-
.select2-container .select2-selection--single {
|
8 |
-
box-sizing: border-box;
|
9 |
-
cursor: pointer;
|
10 |
-
display: block;
|
11 |
-
height: 28px;
|
12 |
-
user-select: none;
|
13 |
-
-webkit-user-select: none; }
|
14 |
-
.select2-container .select2-selection--single .select2-selection__rendered {
|
15 |
-
display: block;
|
16 |
-
padding-left: 8px;
|
17 |
-
padding-right: 20px;
|
18 |
-
overflow: hidden;
|
19 |
-
text-overflow: ellipsis;
|
20 |
-
white-space: nowrap; }
|
21 |
-
.select2-container .select2-selection--single .select2-selection__clear {
|
22 |
-
position: relative; }
|
23 |
-
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
|
24 |
-
padding-right: 8px;
|
25 |
-
padding-left: 20px; }
|
26 |
-
.select2-container .select2-selection--multiple {
|
27 |
-
box-sizing: border-box;
|
28 |
-
cursor: pointer;
|
29 |
-
display: block;
|
30 |
-
min-height: 32px;
|
31 |
-
user-select: none;
|
32 |
-
-webkit-user-select: none; }
|
33 |
-
.select2-container .select2-selection--multiple .select2-selection__rendered {
|
34 |
-
display: inline-block;
|
35 |
-
overflow: hidden;
|
36 |
-
padding-left: 8px;
|
37 |
-
text-overflow: ellipsis;
|
38 |
-
white-space: nowrap; }
|
39 |
-
.select2-container .select2-search--inline {
|
40 |
-
float: left; }
|
41 |
-
.select2-container .select2-search--inline .select2-search__field {
|
42 |
-
box-sizing: border-box;
|
43 |
-
border: none;
|
44 |
-
font-size: 100%;
|
45 |
-
margin-top: 5px;
|
46 |
-
padding: 0; }
|
47 |
-
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
|
48 |
-
-webkit-appearance: none; }
|
49 |
-
|
50 |
-
.select2-dropdown {
|
51 |
-
background-color: white;
|
52 |
-
border: 1px solid #aaa;
|
53 |
-
border-radius: 4px;
|
54 |
-
box-sizing: border-box;
|
55 |
-
display: block;
|
56 |
-
position: absolute;
|
57 |
-
left: -100000px;
|
58 |
-
width: 100%;
|
59 |
-
z-index: 1051; }
|
60 |
-
|
61 |
-
.select2-results {
|
62 |
-
display: block; }
|
63 |
-
|
64 |
-
.select2-results__options {
|
65 |
-
list-style: none;
|
66 |
-
margin: 0;
|
67 |
-
padding: 0; }
|
68 |
-
|
69 |
-
.select2-results__option {
|
70 |
-
padding: 6px;
|
71 |
-
user-select: none;
|
72 |
-
-webkit-user-select: none; }
|
73 |
-
.select2-results__option[aria-selected] {
|
74 |
-
cursor: pointer; }
|
75 |
-
|
76 |
-
.select2-container--open .select2-dropdown {
|
77 |
-
left: 0; }
|
78 |
-
|
79 |
-
.select2-container--open .select2-dropdown--above {
|
80 |
-
border-bottom: none;
|
81 |
-
border-bottom-left-radius: 0;
|
82 |
-
border-bottom-right-radius: 0; }
|
83 |
-
|
84 |
-
.select2-container--open .select2-dropdown--below {
|
85 |
-
border-top: none;
|
86 |
-
border-top-left-radius: 0;
|
87 |
-
border-top-right-radius: 0; }
|
88 |
-
|
89 |
-
.select2-search--dropdown {
|
90 |
-
display: block;
|
91 |
-
padding: 4px; }
|
92 |
-
.select2-search--dropdown .select2-search__field {
|
93 |
-
padding: 4px;
|
94 |
-
width: 100%;
|
95 |
-
box-sizing: border-box; }
|
96 |
-
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
|
97 |
-
-webkit-appearance: none; }
|
98 |
-
.select2-search--dropdown.select2-search--hide {
|
99 |
-
display: none; }
|
100 |
-
|
101 |
-
.select2-close-mask {
|
102 |
-
border: 0;
|
103 |
-
margin: 0;
|
104 |
-
padding: 0;
|
105 |
-
display: block;
|
106 |
-
position: fixed;
|
107 |
-
left: 0;
|
108 |
-
top: 0;
|
109 |
-
min-height: 100%;
|
110 |
-
min-width: 100%;
|
111 |
-
height: auto;
|
112 |
-
width: auto;
|
113 |
-
opacity: 0;
|
114 |
-
z-index: 99;
|
115 |
-
background-color: #fff;
|
116 |
-
filter: alpha(opacity=0); }
|
117 |
-
|
118 |
-
.select2-hidden-accessible {
|
119 |
-
border: 0 !important;
|
120 |
-
clip: rect(0 0 0 0) !important;
|
121 |
-
height: 1px !important;
|
122 |
-
margin: -1px !important;
|
123 |
-
overflow: hidden !important;
|
124 |
-
padding: 0 !important;
|
125 |
-
position: absolute !important;
|
126 |
-
width: 1px !important; }
|
127 |
-
|
128 |
-
.select2-container--default .select2-selection--single {
|
129 |
-
background-color: #fff;
|
130 |
-
border: 1px solid #aaa;
|
131 |
-
border-radius: 4px; }
|
132 |
-
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
133 |
-
color: #444;
|
134 |
-
line-height: 28px; }
|
135 |
-
.select2-container--default .select2-selection--single .select2-selection__clear {
|
136 |
-
cursor: pointer;
|
137 |
-
float: right;
|
138 |
-
font-weight: bold; }
|
139 |
-
.select2-container--default .select2-selection--single .select2-selection__placeholder {
|
140 |
-
color: #999; }
|
141 |
-
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
142 |
-
height: 26px;
|
143 |
-
position: absolute;
|
144 |
-
top: 1px;
|
145 |
-
right: 1px;
|
146 |
-
width: 20px; }
|
147 |
-
.select2-container--default .select2-selection--single .select2-selection__arrow b {
|
148 |
-
border-color: #888 transparent transparent transparent;
|
149 |
-
border-style: solid;
|
150 |
-
border-width: 5px 4px 0 4px;
|
151 |
-
height: 0;
|
152 |
-
left: 50%;
|
153 |
-
margin-left: -4px;
|
154 |
-
margin-top: -2px;
|
155 |
-
position: absolute;
|
156 |
-
top: 50%;
|
157 |
-
width: 0; }
|
158 |
-
|
159 |
-
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
|
160 |
-
float: left; }
|
161 |
-
|
162 |
-
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
|
163 |
-
left: 1px;
|
164 |
-
right: auto; }
|
165 |
-
|
166 |
-
.select2-container--default.select2-container--disabled .select2-selection--single {
|
167 |
-
background-color: #eee;
|
168 |
-
cursor: default; }
|
169 |
-
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
|
170 |
-
display: none; }
|
171 |
-
|
172 |
-
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
|
173 |
-
border-color: transparent transparent #888 transparent;
|
174 |
-
border-width: 0 4px 5px 4px; }
|
175 |
-
|
176 |
-
.select2-container--default .select2-selection--multiple {
|
177 |
-
background-color: white;
|
178 |
-
border: 1px solid #aaa;
|
179 |
-
border-radius: 4px;
|
180 |
-
cursor: text; }
|
181 |
-
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
182 |
-
box-sizing: border-box;
|
183 |
-
list-style: none;
|
184 |
-
margin: 0;
|
185 |
-
padding: 0 5px;
|
186 |
-
width: 100%; }
|
187 |
-
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
|
188 |
-
list-style: none; }
|
189 |
-
.select2-container--default .select2-selection--multiple .select2-selection__placeholder {
|
190 |
-
color: #999;
|
191 |
-
margin-top: 5px;
|
192 |
-
float: left; }
|
193 |
-
.select2-container--default .select2-selection--multiple .select2-selection__clear {
|
194 |
-
cursor: pointer;
|
195 |
-
float: right;
|
196 |
-
font-weight: bold;
|
197 |
-
margin-top: 5px;
|
198 |
-
margin-right: 10px; }
|
199 |
-
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
200 |
-
background-color: #e4e4e4;
|
201 |
-
border: 1px solid #aaa;
|
202 |
-
border-radius: 4px;
|
203 |
-
cursor: default;
|
204 |
-
float: left;
|
205 |
-
margin-right: 5px;
|
206 |
-
margin-top: 5px;
|
207 |
-
padding: 0 5px; }
|
208 |
-
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
|
209 |
-
color: #999;
|
210 |
-
cursor: pointer;
|
211 |
-
display: inline-block;
|
212 |
-
font-weight: bold;
|
213 |
-
margin-right: 2px; }
|
214 |
-
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
|
215 |
-
color: #333; }
|
216 |
-
|
217 |
-
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
|
218 |
-
float: right; }
|
219 |
-
|
220 |
-
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
221 |
-
margin-left: 5px;
|
222 |
-
margin-right: auto; }
|
223 |
-
|
224 |
-
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
|
225 |
-
margin-left: 2px;
|
226 |
-
margin-right: auto; }
|
227 |
-
|
228 |
-
.select2-container--default.select2-container--focus .select2-selection--multiple {
|
229 |
-
border: solid black 1px;
|
230 |
-
outline: 0; }
|
231 |
-
|
232 |
-
.select2-container--default.select2-container--disabled .select2-selection--multiple {
|
233 |
-
background-color: #eee;
|
234 |
-
cursor: default; }
|
235 |
-
|
236 |
-
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
|
237 |
-
display: none; }
|
238 |
-
|
239 |
-
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
|
240 |
-
border-top-left-radius: 0;
|
241 |
-
border-top-right-radius: 0; }
|
242 |
-
|
243 |
-
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
|
244 |
-
border-bottom-left-radius: 0;
|
245 |
-
border-bottom-right-radius: 0; }
|
246 |
-
|
247 |
-
.select2-container--default .select2-search--dropdown .select2-search__field {
|
248 |
-
border: 1px solid #aaa; }
|
249 |
-
|
250 |
-
.select2-container--default .select2-search--inline .select2-search__field {
|
251 |
-
background: transparent;
|
252 |
-
border: none;
|
253 |
-
outline: 0;
|
254 |
-
box-shadow: none;
|
255 |
-
-webkit-appearance: textfield; }
|
256 |
-
|
257 |
-
.select2-container--default .select2-results > .select2-results__options {
|
258 |
-
max-height: 200px;
|
259 |
-
overflow-y: auto; }
|
260 |
-
|
261 |
-
.select2-container--default .select2-results__option[role=group] {
|
262 |
-
padding: 0; }
|
263 |
-
|
264 |
-
.select2-container--default .select2-results__option[aria-disabled=true] {
|
265 |
-
color: #999; }
|
266 |
-
|
267 |
-
.select2-container--default .select2-results__option[aria-selected=true] {
|
268 |
-
background-color: #ddd; }
|
269 |
-
|
270 |
-
.select2-container--default .select2-results__option .select2-results__option {
|
271 |
-
padding-left: 1em; }
|
272 |
-
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
|
273 |
-
padding-left: 0; }
|
274 |
-
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
|
275 |
-
margin-left: -1em;
|
276 |
-
padding-left: 2em; }
|
277 |
-
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
278 |
-
margin-left: -2em;
|
279 |
-
padding-left: 3em; }
|
280 |
-
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
281 |
-
margin-left: -3em;
|
282 |
-
padding-left: 4em; }
|
283 |
-
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
284 |
-
margin-left: -4em;
|
285 |
-
padding-left: 5em; }
|
286 |
-
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
287 |
-
margin-left: -5em;
|
288 |
-
padding-left: 6em; }
|
289 |
-
|
290 |
-
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
291 |
-
background-color: #5897fb;
|
292 |
-
color: white; }
|
293 |
-
|
294 |
-
.select2-container--default .select2-results__group {
|
295 |
-
cursor: default;
|
296 |
-
display: block;
|
297 |
-
padding: 6px; }
|
298 |
-
|
299 |
-
.select2-container--classic .select2-selection--single {
|
300 |
-
background-color: #f7f7f7;
|
301 |
-
border: 1px solid #aaa;
|
302 |
-
border-radius: 4px;
|
303 |
-
outline: 0;
|
304 |
-
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
|
305 |
-
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
|
306 |
-
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
|
307 |
-
background-repeat: repeat-x;
|
308 |
-
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
309 |
-
.select2-container--classic .select2-selection--single:focus {
|
310 |
-
border: 1px solid #5897fb; }
|
311 |
-
.select2-container--classic .select2-selection--single .select2-selection__rendered {
|
312 |
-
color: #444;
|
313 |
-
line-height: 28px; }
|
314 |
-
.select2-container--classic .select2-selection--single .select2-selection__clear {
|
315 |
-
cursor: pointer;
|
316 |
-
float: right;
|
317 |
-
font-weight: bold;
|
318 |
-
margin-right: 10px; }
|
319 |
-
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
|
320 |
-
color: #999; }
|
321 |
-
.select2-container--classic .select2-selection--single .select2-selection__arrow {
|
322 |
-
background-color: #ddd;
|
323 |
-
border: none;
|
324 |
-
border-left: 1px solid #aaa;
|
325 |
-
border-top-right-radius: 4px;
|
326 |
-
border-bottom-right-radius: 4px;
|
327 |
-
height: 26px;
|
328 |
-
position: absolute;
|
329 |
-
top: 1px;
|
330 |
-
right: 1px;
|
331 |
-
width: 20px;
|
332 |
-
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
333 |
-
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
334 |
-
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
|
335 |
-
background-repeat: repeat-x;
|
336 |
-
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
|
337 |
-
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
|
338 |
-
border-color: #888 transparent transparent transparent;
|
339 |
-
border-style: solid;
|
340 |
-
border-width: 5px 4px 0 4px;
|
341 |
-
height: 0;
|
342 |
-
left: 50%;
|
343 |
-
margin-left: -4px;
|
344 |
-
margin-top: -2px;
|
345 |
-
position: absolute;
|
346 |
-
top: 50%;
|
347 |
-
width: 0; }
|
348 |
-
|
349 |
-
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
|
350 |
-
float: left; }
|
351 |
-
|
352 |
-
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
|
353 |
-
border: none;
|
354 |
-
border-right: 1px solid #aaa;
|
355 |
-
border-radius: 0;
|
356 |
-
border-top-left-radius: 4px;
|
357 |
-
border-bottom-left-radius: 4px;
|
358 |
-
left: 1px;
|
359 |
-
right: auto; }
|
360 |
-
|
361 |
-
.select2-container--classic.select2-container--open .select2-selection--single {
|
362 |
-
border: 1px solid #5897fb; }
|
363 |
-
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
|
364 |
-
background: transparent;
|
365 |
-
border: none; }
|
366 |
-
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
|
367 |
-
border-color: transparent transparent #888 transparent;
|
368 |
-
border-width: 0 4px 5px 4px; }
|
369 |
-
|
370 |
-
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
|
371 |
-
border-top: none;
|
372 |
-
border-top-left-radius: 0;
|
373 |
-
border-top-right-radius: 0;
|
374 |
-
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
|
375 |
-
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
|
376 |
-
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
|
377 |
-
background-repeat: repeat-x;
|
378 |
-
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
379 |
-
|
380 |
-
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
|
381 |
-
border-bottom: none;
|
382 |
-
border-bottom-left-radius: 0;
|
383 |
-
border-bottom-right-radius: 0;
|
384 |
-
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
|
385 |
-
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
|
386 |
-
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
|
387 |
-
background-repeat: repeat-x;
|
388 |
-
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
|
389 |
-
|
390 |
-
.select2-container--classic .select2-selection--multiple {
|
391 |
-
background-color: white;
|
392 |
-
border: 1px solid #aaa;
|
393 |
-
border-radius: 4px;
|
394 |
-
cursor: text;
|
395 |
-
outline: 0; }
|
396 |
-
.select2-container--classic .select2-selection--multiple:focus {
|
397 |
-
border: 1px solid #5897fb; }
|
398 |
-
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
|
399 |
-
list-style: none;
|
400 |
-
margin: 0;
|
401 |
-
padding: 0 5px; }
|
402 |
-
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
|
403 |
-
display: none; }
|
404 |
-
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
|
405 |
-
background-color: #e4e4e4;
|
406 |
-
border: 1px solid #aaa;
|
407 |
-
border-radius: 4px;
|
408 |
-
cursor: default;
|
409 |
-
float: left;
|
410 |
-
margin-right: 5px;
|
411 |
-
margin-top: 5px;
|
412 |
-
padding: 0 5px; }
|
413 |
-
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
|
414 |
-
color: #888;
|
415 |
-
cursor: pointer;
|
416 |
-
display: inline-block;
|
417 |
-
font-weight: bold;
|
418 |
-
margin-right: 2px; }
|
419 |
-
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
|
420 |
-
color: #555; }
|
421 |
-
|
422 |
-
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
423 |
-
float: right; }
|
424 |
-
|
425 |
-
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
426 |
-
margin-left: 5px;
|
427 |
-
margin-right: auto; }
|
428 |
-
|
429 |
-
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
|
430 |
-
margin-left: 2px;
|
431 |
-
margin-right: auto; }
|
432 |
-
|
433 |
-
.select2-container--classic.select2-container--open .select2-selection--multiple {
|
434 |
-
border: 1px solid #5897fb; }
|
435 |
-
|
436 |
-
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
|
437 |
-
border-top: none;
|
438 |
-
border-top-left-radius: 0;
|
439 |
-
border-top-right-radius: 0; }
|
440 |
-
|
441 |
-
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
|
442 |
-
border-bottom: none;
|
443 |
-
border-bottom-left-radius: 0;
|
444 |
-
border-bottom-right-radius: 0; }
|
445 |
-
|
446 |
-
.select2-container--classic .select2-search--dropdown .select2-search__field {
|
447 |
-
border: 1px solid #aaa;
|
448 |
-
outline: 0; }
|
449 |
-
|
450 |
-
.select2-container--classic .select2-search--inline .select2-search__field {
|
451 |
-
outline: 0;
|
452 |
-
box-shadow: none; }
|
453 |
-
|
454 |
-
.select2-container--classic .select2-dropdown {
|
455 |
-
background-color: white;
|
456 |
-
border: 1px solid transparent; }
|
457 |
-
|
458 |
-
.select2-container--classic .select2-dropdown--above {
|
459 |
-
border-bottom: none; }
|
460 |
-
|
461 |
-
.select2-container--classic .select2-dropdown--below {
|
462 |
-
border-top: none; }
|
463 |
-
|
464 |
-
.select2-container--classic .select2-results > .select2-results__options {
|
465 |
-
max-height: 200px;
|
466 |
-
overflow-y: auto; }
|
467 |
-
|
468 |
-
.select2-container--classic .select2-results__option[role=group] {
|
469 |
-
padding: 0; }
|
470 |
-
|
471 |
-
.select2-container--classic .select2-results__option[aria-disabled=true] {
|
472 |
-
color: grey; }
|
473 |
-
|
474 |
-
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
|
475 |
-
background-color: #3875d7;
|
476 |
-
color: white; }
|
477 |
-
|
478 |
-
.select2-container--classic .select2-results__group {
|
479 |
-
cursor: default;
|
480 |
-
display: block;
|
481 |
-
padding: 6px; }
|
482 |
-
|
483 |
-
.select2-container--classic.select2-container--open .select2-dropdown {
|
484 |
-
border-color: #5897fb; }
|
1 |
+
.select2-container {
|
2 |
+
box-sizing: border-box;
|
3 |
+
display: inline-block;
|
4 |
+
margin: 0;
|
5 |
+
position: relative;
|
6 |
+
vertical-align: middle; }
|
7 |
+
.select2-container .select2-selection--single {
|
8 |
+
box-sizing: border-box;
|
9 |
+
cursor: pointer;
|
10 |
+
display: block;
|
11 |
+
height: 28px;
|
12 |
+
user-select: none;
|
13 |
+
-webkit-user-select: none; }
|
14 |
+
.select2-container .select2-selection--single .select2-selection__rendered {
|
15 |
+
display: block;
|
16 |
+
padding-left: 8px;
|
17 |
+
padding-right: 20px;
|
18 |
+
overflow: hidden;
|
19 |
+
text-overflow: ellipsis;
|
20 |
+
white-space: nowrap; }
|
21 |
+
.select2-container .select2-selection--single .select2-selection__clear {
|
22 |
+
position: relative; }
|
23 |
+
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
|
24 |
+
padding-right: 8px;
|
25 |
+
padding-left: 20px; }
|
26 |
+
.select2-container .select2-selection--multiple {
|
27 |
+
box-sizing: border-box;
|
28 |
+
cursor: pointer;
|
29 |
+
display: block;
|
30 |
+
min-height: 32px;
|
31 |
+
user-select: none;
|
32 |
+
-webkit-user-select: none; }
|
33 |
+
.select2-container .select2-selection--multiple .select2-selection__rendered {
|
34 |
+
display: inline-block;
|
35 |
+
overflow: hidden;
|
36 |
+
padding-left: 8px;
|
37 |
+
text-overflow: ellipsis;
|
38 |
+
white-space: nowrap; }
|
39 |
+
.select2-container .select2-search--inline {
|
40 |
+
float: left; }
|
41 |
+
.select2-container .select2-search--inline .select2-search__field {
|
42 |
+
box-sizing: border-box;
|
43 |
+
border: none;
|
44 |
+
font-size: 100%;
|
45 |
+
margin-top: 5px;
|
46 |
+
padding: 0; }
|
47 |
+
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
|
48 |
+
-webkit-appearance: none; }
|
49 |
+
|
50 |
+
.select2-dropdown {
|
51 |
+
background-color: white;
|
52 |
+
border: 1px solid #aaa;
|
53 |
+
border-radius: 4px;
|
54 |
+
box-sizing: border-box;
|
55 |
+
display: block;
|
56 |
+
position: absolute;
|
57 |
+
left: -100000px;
|
58 |
+
width: 100%;
|
59 |
+
z-index: 1051; }
|
60 |
+
|
61 |
+
.select2-results {
|
62 |
+
display: block; }
|
63 |
+
|
64 |
+
.select2-results__options {
|
65 |
+
list-style: none;
|
66 |
+
margin: 0;
|
67 |
+
padding: 0; }
|
68 |
+
|
69 |
+
.select2-results__option {
|
70 |
+
padding: 6px;
|
71 |
+
user-select: none;
|
72 |
+
-webkit-user-select: none; }
|
73 |
+
.select2-results__option[aria-selected] {
|
74 |
+
cursor: pointer; }
|
75 |
+
|
76 |
+
.select2-container--open .select2-dropdown {
|
77 |
+
left: 0; }
|
78 |
+
|
79 |
+
.select2-container--open .select2-dropdown--above {
|
80 |
+
border-bottom: none;
|
81 |
+
border-bottom-left-radius: 0;
|
82 |
+
border-bottom-right-radius: 0; }
|
83 |
+
|
84 |
+
.select2-container--open .select2-dropdown--below {
|
85 |
+
border-top: none;
|
86 |
+
border-top-left-radius: 0;
|
87 |
+
border-top-right-radius: 0; }
|
88 |
+
|
89 |
+
.select2-search--dropdown {
|
90 |
+
display: block;
|
91 |
+
padding: 4px; }
|
92 |
+
.select2-search--dropdown .select2-search__field {
|
93 |
+
padding: 4px;
|
94 |
+
width: 100%;
|
95 |
+
box-sizing: border-box; }
|
96 |
+
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
|
97 |
+
-webkit-appearance: none; }
|
98 |
+
.select2-search--dropdown.select2-search--hide {
|
99 |
+
display: none; }
|
100 |
+
|
101 |
+
.select2-close-mask {
|
102 |
+
border: 0;
|
103 |
+
margin: 0;
|
104 |
+
padding: 0;
|
105 |
+
display: block;
|
106 |
+
position: fixed;
|
107 |
+
left: 0;
|
108 |
+
top: 0;
|
109 |
+
min-height: 100%;
|
110 |
+
min-width: 100%;
|
111 |
+
height: auto;
|
112 |
+
width: auto;
|
113 |
+
opacity: 0;
|
114 |
+
z-index: 99;
|
115 |
+
background-color: #fff;
|
116 |
+
filter: alpha(opacity=0); }
|
117 |
+
|
118 |
+
.select2-hidden-accessible {
|
119 |
+
border: 0 !important;
|
120 |
+
clip: rect(0 0 0 0) !important;
|
121 |
+
height: 1px !important;
|
122 |
+
margin: -1px !important;
|
123 |
+
overflow: hidden !important;
|
124 |
+
padding: 0 !important;
|
125 |
+
position: absolute !important;
|
126 |
+
width: 1px !important; }
|
127 |
+
|
128 |
+
.select2-container--default .select2-selection--single {
|
129 |
+
background-color: #fff;
|
130 |
+
border: 1px solid #aaa;
|
131 |
+
border-radius: 4px; }
|
132 |
+
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
133 |
+
color: #444;
|
134 |
+
line-height: 28px; }
|
135 |
+
.select2-container--default .select2-selection--single .select2-selection__clear {
|
136 |
+
cursor: pointer;
|
137 |
+
float: right;
|
138 |
+
font-weight: bold; }
|
139 |
+
.select2-container--default .select2-selection--single .select2-selection__placeholder {
|
140 |
+
color: #999; }
|
141 |
+
.select2-container--default .select2-selection--single .select2-selection__arrow {
|
142 |
+
height: 26px;
|
143 |
+
position: absolute;
|
144 |
+
top: 1px;
|
145 |
+
right: 1px;
|
146 |
+
width: 20px; }
|
147 |
+
.select2-container--default .select2-selection--single .select2-selection__arrow b {
|
148 |
+
border-color: #888 transparent transparent transparent;
|
149 |
+
border-style: solid;
|
150 |
+
border-width: 5px 4px 0 4px;
|
151 |
+
height: 0;
|
152 |
+
left: 50%;
|
153 |
+
margin-left: -4px;
|
154 |
+
margin-top: -2px;
|
155 |
+
position: absolute;
|
156 |
+
top: 50%;
|
157 |
+
width: 0; }
|
158 |
+
|
159 |
+
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
|
160 |
+
float: left; }
|
161 |
+
|
162 |
+
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
|
163 |
+
left: 1px;
|
164 |
+
right: auto; }
|
165 |
+
|
166 |
+
.select2-container--default.select2-container--disabled .select2-selection--single {
|
167 |
+
background-color: #eee;
|
168 |
+
cursor: default; }
|
169 |
+
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
|
170 |
+
display: none; }
|
171 |
+
|
172 |
+
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
|
173 |
+
border-color: transparent transparent #888 transparent;
|
174 |
+
border-width: 0 4px 5px 4px; }
|
175 |
+
|
176 |
+
.select2-container--default .select2-selection--multiple {
|
177 |
+
background-color: white;
|
178 |
+
border: 1px solid #aaa;
|
179 |
+
border-radius: 4px;
|
180 |
+
cursor: text; }
|
181 |
+
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
182 |
+
box-sizing: border-box;
|
183 |
+
list-style: none;
|
184 |
+
margin: 0;
|
185 |
+
padding: 0 5px;
|
186 |
+
width: 100%; }
|
187 |
+
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
|
188 |
+
list-style: none; }
|
189 |
+
.select2-container--default .select2-selection--multiple .select2-selection__placeholder {
|
190 |
+
color: #999;
|
191 |
+
margin-top: 5px;
|
192 |
+
float: left; }
|
193 |
+
.select2-container--default .select2-selection--multiple .select2-selection__clear {
|
194 |
+
cursor: pointer;
|
195 |
+
float: right;
|
196 |
+
font-weight: bold;
|
197 |
+
margin-top: 5px;
|
198 |
+
margin-right: 10px; }
|
199 |
+
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
200 |
+
background-color: #e4e4e4;
|
201 |
+
border: 1px solid #aaa;
|
202 |
+
border-radius: 4px;
|
203 |
+
cursor: default;
|
204 |
+
float: left;
|
205 |
+
margin-right: 5px;
|
206 |
+
margin-top: 5px;
|
207 |
+
padding: 0 5px; }
|
208 |
+
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
|
209 |
+
color: #999;
|
210 |
+
cursor: pointer;
|
211 |
+
display: inline-block;
|
212 |
+
font-weight: bold;
|
213 |
+
margin-right: 2px; }
|
214 |
+
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
|
215 |
+
color: #333; }
|
216 |
+
|
217 |
+
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
|
218 |
+
float: right; }
|
219 |
+
|
220 |
+
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
221 |
+
margin-left: 5px;
|
222 |
+
margin-right: auto; }
|
223 |
+
|
224 |
+
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
|
225 |
+
margin-left: 2px;
|
226 |
+
margin-right: auto; }
|
227 |
+
|
228 |
+
.select2-container--default.select2-container--focus .select2-selection--multiple {
|
229 |
+
border: solid black 1px;
|
230 |
+
outline: 0; }
|
231 |
+
|
232 |
+
.select2-container--default.select2-container--disabled .select2-selection--multiple {
|
233 |
+
background-color: #eee;
|
234 |
+
cursor: default; }
|
235 |
+
|
236 |
+
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
|
237 |
+
display: none; }
|
238 |
+
|
239 |
+
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
|
240 |
+
border-top-left-radius: 0;
|
241 |
+
border-top-right-radius: 0; }
|
242 |
+
|
243 |
+
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
|
244 |
+
border-bottom-left-radius: 0;
|
245 |
+
border-bottom-right-radius: 0; }
|
246 |
+
|
247 |
+
.select2-container--default .select2-search--dropdown .select2-search__field {
|
248 |
+
border: 1px solid #aaa; }
|
249 |
+
|
250 |
+
.select2-container--default .select2-search--inline .select2-search__field {
|
251 |
+
background: transparent;
|
252 |
+
border: none;
|
253 |
+
outline: 0;
|
254 |
+
box-shadow: none;
|
255 |
+
-webkit-appearance: textfield; }
|
256 |
+
|
257 |
+
.select2-container--default .select2-results > .select2-results__options {
|
258 |
+
max-height: 200px;
|
259 |
+
overflow-y: auto; }
|
260 |
+
|
261 |
+
.select2-container--default .select2-results__option[role=group] {
|
262 |
+
padding: 0; }
|
263 |
+
|
264 |
+
.select2-container--default .select2-results__option[aria-disabled=true] {
|
265 |
+
color: #999; }
|
266 |
+
|
267 |
+
.select2-container--default .select2-results__option[aria-selected=true] {
|
268 |
+
background-color: #ddd; }
|
269 |
+
|
270 |
+
.select2-container--default .select2-results__option .select2-results__option {
|
271 |
+
padding-left: 1em; }
|
272 |
+
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
|
273 |
+
padding-left: 0; }
|
274 |
+
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
|
275 |
+
margin-left: -1em;
|
276 |
+
padding-left: 2em; }
|
277 |
+
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
278 |
+
margin-left: -2em;
|
279 |
+
padding-left: 3em; }
|
280 |
+
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
281 |
+
margin-left: -3em;
|
282 |
+
padding-left: 4em; }
|
283 |
+
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
284 |
+
margin-left: -4em;
|
285 |
+
padding-left: 5em; }
|
286 |
+
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
|
287 |
+
margin-left: -5em;
|
288 |
+
padding-left: 6em; }
|
289 |
+
|
290 |
+
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
291 |
+
background-color: #5897fb;
|
292 |
+
color: white; }
|
293 |
+
|
294 |
+
.select2-container--default .select2-results__group {
|
295 |
+
cursor: default;
|
296 |
+
display: block;
|
297 |
+
padding: 6px; }
|
298 |
+
|
299 |
+
.select2-container--classic .select2-selection--single {
|
300 |
+
background-color: #f7f7f7;
|
301 |
+
border: 1px solid #aaa;
|
302 |
+
border-radius: 4px;
|
303 |
+
outline: 0;
|
304 |
+
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
|
305 |
+
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
|
306 |
+
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
|
307 |
+
background-repeat: repeat-x;
|
308 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
309 |
+
.select2-container--classic .select2-selection--single:focus {
|
310 |
+
border: 1px solid #5897fb; }
|
311 |
+
.select2-container--classic .select2-selection--single .select2-selection__rendered {
|
312 |
+
color: #444;
|
313 |
+
line-height: 28px; }
|
314 |
+
.select2-container--classic .select2-selection--single .select2-selection__clear {
|
315 |
+
cursor: pointer;
|
316 |
+
float: right;
|
317 |
+
font-weight: bold;
|
318 |
+
margin-right: 10px; }
|
319 |
+
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
|
320 |
+
color: #999; }
|
321 |
+
.select2-container--classic .select2-selection--single .select2-selection__arrow {
|
322 |
+
background-color: #ddd;
|
323 |
+
border: none;
|
324 |
+
border-left: 1px solid #aaa;
|
325 |
+
border-top-right-radius: 4px;
|
326 |
+
border-bottom-right-radius: 4px;
|
327 |
+
height: 26px;
|
328 |
+
position: absolute;
|
329 |
+
top: 1px;
|
330 |
+
right: 1px;
|
331 |
+
width: 20px;
|
332 |
+
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
333 |
+
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
334 |
+
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
|
335 |
+
background-repeat: repeat-x;
|
336 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
|
337 |
+
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
|
338 |
+
border-color: #888 transparent transparent transparent;
|
339 |
+
border-style: solid;
|
340 |
+
border-width: 5px 4px 0 4px;
|
341 |
+
height: 0;
|
342 |
+
left: 50%;
|
343 |
+
margin-left: -4px;
|
344 |
+
margin-top: -2px;
|
345 |
+
position: absolute;
|
346 |
+
top: 50%;
|
347 |
+
width: 0; }
|
348 |
+
|
349 |
+
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
|
350 |
+
float: left; }
|
351 |
+
|
352 |
+
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
|
353 |
+
border: none;
|
354 |
+
border-right: 1px solid #aaa;
|
355 |
+
border-radius: 0;
|
356 |
+
border-top-left-radius: 4px;
|
357 |
+
border-bottom-left-radius: 4px;
|
358 |
+
left: 1px;
|
359 |
+
right: auto; }
|
360 |
+
|
361 |
+
.select2-container--classic.select2-container--open .select2-selection--single {
|
362 |
+
border: 1px solid #5897fb; }
|
363 |
+
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
|
364 |
+
background: transparent;
|
365 |
+
border: none; }
|
366 |
+
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
|
367 |
+
border-color: transparent transparent #888 transparent;
|
368 |
+
border-width: 0 4px 5px 4px; }
|
369 |
+
|
370 |
+
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
|
371 |
+
border-top: none;
|
372 |
+
border-top-left-radius: 0;
|
373 |
+
border-top-right-radius: 0;
|
374 |
+
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
|
375 |
+
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
|
376 |
+
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
|
377 |
+
background-repeat: repeat-x;
|
378 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
379 |
+
|
380 |
+
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
|
381 |
+
border-bottom: none;
|
382 |
+
border-bottom-left-radius: 0;
|
383 |
+
border-bottom-right-radius: 0;
|
384 |
+
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
|
385 |
+
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
|
386 |
+
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
|
387 |
+
background-repeat: repeat-x;
|
388 |
+
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
|
389 |
+
|
390 |
+
.select2-container--classic .select2-selection--multiple {
|
391 |
+
background-color: white;
|
392 |
+
border: 1px solid #aaa;
|
393 |
+
border-radius: 4px;
|
394 |
+
cursor: text;
|
395 |
+
outline: 0; }
|
396 |
+
.select2-container--classic .select2-selection--multiple:focus {
|
397 |
+
border: 1px solid #5897fb; }
|
398 |
+
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
|
399 |
+
list-style: none;
|
400 |
+
margin: 0;
|
401 |
+
padding: 0 5px; }
|
402 |
+
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
|
403 |
+
display: none; }
|
404 |
+
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
|
405 |
+
background-color: #e4e4e4;
|
406 |
+
border: 1px solid #aaa;
|
407 |
+
border-radius: 4px;
|
408 |
+
cursor: default;
|
409 |
+
float: left;
|
410 |
+
margin-right: 5px;
|
411 |
+
margin-top: 5px;
|
412 |
+
padding: 0 5px; }
|
413 |
+
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
|
414 |
+
color: #888;
|
415 |
+
cursor: pointer;
|
416 |
+
display: inline-block;
|
417 |
+
font-weight: bold;
|
418 |
+
margin-right: 2px; }
|
419 |
+
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
|
420 |
+
color: #555; }
|
421 |
+
|
422 |
+
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
423 |
+
float: right; }
|
424 |
+
|
425 |
+
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
|
426 |
+
margin-left: 5px;
|
427 |
+
margin-right: auto; }
|
428 |
+
|
429 |
+
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
|
430 |
+
margin-left: 2px;
|
431 |
+
margin-right: auto; }
|
432 |
+
|
433 |
+
.select2-container--classic.select2-container--open .select2-selection--multiple {
|
434 |
+
border: 1px solid #5897fb; }
|
435 |
+
|
436 |
+
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
|
437 |
+
border-top: none;
|
438 |
+
border-top-left-radius: 0;
|
439 |
+
border-top-right-radius: 0; }
|
440 |
+
|
441 |
+
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
|
442 |
+
border-bottom: none;
|
443 |
+
border-bottom-left-radius: 0;
|
444 |
+
border-bottom-right-radius: 0; }
|
445 |
+
|
446 |
+
.select2-container--classic .select2-search--dropdown .select2-search__field {
|
447 |
+
border: 1px solid #aaa;
|
448 |
+
outline: 0; }
|
449 |
+
|
450 |
+
.select2-container--classic .select2-search--inline .select2-search__field {
|
451 |
+
outline: 0;
|
452 |
+
box-shadow: none; }
|
453 |
+
|
454 |
+
.select2-container--classic .select2-dropdown {
|
455 |
+
background-color: white;
|
456 |
+
border: 1px solid transparent; }
|
457 |
+
|
458 |
+
.select2-container--classic .select2-dropdown--above {
|
459 |
+
border-bottom: none; }
|
460 |
+
|
461 |
+
.select2-container--classic .select2-dropdown--below {
|
462 |
+
border-top: none; }
|
463 |
+
|
464 |
+
.select2-container--classic .select2-results > .select2-results__options {
|
465 |
+
max-height: 200px;
|
466 |
+
overflow-y: auto; }
|
467 |
+
|
468 |
+
.select2-container--classic .select2-results__option[role=group] {
|
469 |
+
padding: 0; }
|
470 |
+
|
471 |
+
.select2-container--classic .select2-results__option[aria-disabled=true] {
|
472 |
+
color: grey; }
|
473 |
+
|
474 |
+
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
|
475 |
+
background-color: #3875d7;
|
476 |
+
color: white; }
|
477 |
+
|
478 |
+
.select2-container--classic .select2-results__group {
|
479 |
+
cursor: default;
|
480 |
+
display: block;
|
481 |
+
padding: 6px; }
|
482 |
+
|
483 |
+
.select2-container--classic.select2-container--open .select2-dropdown {
|
484 |
+
border-color: #5897fb; }
|
css/lib/select2/select2.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
|
1 |
+
.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
|
js/app/advance_link_picker/.eslintrc.json
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
{
|
2 |
-
"env": {
|
3 |
-
"browser": true,
|
4 |
-
"es6": true
|
5 |
-
},
|
6 |
-
"extends": "eslint:recommended",
|
7 |
-
"parserOptions": {
|
8 |
-
"sourceType": "module"
|
9 |
-
},
|
10 |
-
"rules": {
|
11 |
-
"no-console" : 0,
|
12 |
-
"indent": 0,
|
13 |
-
"indent": [
|
14 |
-
"error",
|
15 |
-
4
|
16 |
-
],
|
17 |
-
"linebreak-style": [
|
18 |
-
"error",
|
19 |
-
"unix"
|
20 |
-
],
|
21 |
-
"quotes": [
|
22 |
-
"error",
|
23 |
-
"double"
|
24 |
-
],
|
25 |
-
"semi": [
|
26 |
-
"error",
|
27 |
-
"always"
|
28 |
-
]
|
29 |
-
}
|
30 |
}
|
1 |
+
{
|
2 |
+
"env": {
|
3 |
+
"browser": true,
|
4 |
+
"es6": true
|
5 |
+
},
|
6 |
+
"extends": "eslint:recommended",
|
7 |
+
"parserOptions": {
|
8 |
+
"sourceType": "module"
|
9 |
+
},
|
10 |
+
"rules": {
|
11 |
+
"no-console" : 0,
|
12 |
+
"indent": 0,
|
13 |
+
"indent": [
|
14 |
+
"error",
|
15 |
+
4
|
16 |
+
],
|
17 |
+
"linebreak-style": [
|
18 |
+
"error",
|
19 |
+
"unix"
|
20 |
+
],
|
21 |
+
"quotes": [
|
22 |
+
"error",
|
23 |
+
"double"
|
24 |
+
],
|
25 |
+
"semi": [
|
26 |
+
"error",
|
27 |
+
"always"
|
28 |
+
]
|
29 |
+
}
|
30 |
}
|
js/app/advance_link_picker/package-lock.json
CHANGED
@@ -1,9586 +1,9586 @@
|
|
1 |
-
{
|
2 |
-
"name": "affiliate_link_page",
|
3 |
-
"version": "1.0.0",
|
4 |
-
"lockfileVersion": 1,
|
5 |
-
"requires": true,
|
6 |
-
"dependencies": {
|
7 |
-
"abbrev": {
|
8 |
-
"version": "1.1.1",
|
9 |
-
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
10 |
-
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
11 |
-
"dev": true
|
12 |
-
},
|
13 |
-
"acorn": {
|
14 |
-
"version": "5.2.1",
|
15 |
-
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz",
|
16 |
-
"integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==",
|
17 |
-
"dev": true
|
18 |
-
},
|
19 |
-
"acorn-dynamic-import": {
|
20 |
-
"version": "2.0.2",
|
21 |
-
"resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
|
22 |
-
"integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
|
23 |
-
"dev": true,
|
24 |
-
"requires": {
|
25 |
-
"acorn": "^4.0.3"
|
26 |
-
},
|
27 |
-
"dependencies": {
|
28 |
-
"acorn": {
|
29 |
-
"version": "4.0.13",
|
30 |
-
"resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
|
31 |
-
"integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
|
32 |
-
"dev": true
|
33 |
-
}
|
34 |
-
}
|
35 |
-
},
|
36 |
-
"acorn-jsx": {
|
37 |
-
"version": "3.0.1",
|
38 |
-
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
|
39 |
-
"integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
|
40 |
-
"dev": true,
|
41 |
-
"requires": {
|
42 |
-
"acorn": "^3.0.4"
|
43 |
-
},
|
44 |
-
"dependencies": {
|
45 |
-
"acorn": {
|
46 |
-
"version": "3.3.0",
|
47 |
-
"resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
|
48 |
-
"integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
|
49 |
-
"dev": true
|
50 |
-
}
|
51 |
-
}
|
52 |
-
},
|
53 |
-
"ajv": {
|
54 |
-
"version": "4.11.8",
|
55 |
-
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
|
56 |
-
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
|
57 |
-
"dev": true,
|
58 |
-
"requires": {
|
59 |
-
"co": "^4.6.0",
|
60 |
-
"json-stable-stringify": "^1.0.1"
|
61 |
-
}
|
62 |
-
},
|
63 |
-
"ajv-keywords": {
|
64 |
-
"version": "1.5.1",
|
65 |
-
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
|
66 |
-
"integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
|
67 |
-
"dev": true
|
68 |
-
},
|
69 |
-
"align-text": {
|
70 |
-
"version": "0.1.4",
|
71 |
-
"resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
|
72 |
-
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
|
73 |
-
"dev": true,
|
74 |
-
"requires": {
|
75 |
-
"kind-of": "^3.0.2",
|
76 |
-
"longest": "^1.0.1",
|
77 |
-
"repeat-string": "^1.5.2"
|
78 |
-
}
|
79 |
-
},
|
80 |
-
"alphanum-sort": {
|
81 |
-
"version": "1.0.2",
|
82 |
-
"resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
|
83 |
-
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
|
84 |
-
"dev": true
|
85 |
-
},
|
86 |
-
"amdefine": {
|
87 |
-
"version": "1.0.1",
|
88 |
-
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
|
89 |
-
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
90 |
-
"dev": true
|
91 |
-
},
|
92 |
-
"ansi-escapes": {
|
93 |
-
"version": "1.4.0",
|
94 |
-
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
|
95 |
-
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
|
96 |
-
"dev": true
|
97 |
-
},
|
98 |
-
"ansi-regex": {
|
99 |
-
"version": "2.1.1",
|
100 |
-
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
101 |
-
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
102 |
-
"dev": true
|
103 |
-
},
|
104 |
-
"ansi-styles": {
|
105 |
-
"version": "2.2.1",
|
106 |
-
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
107 |
-
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
108 |
-
"dev": true
|
109 |
-
},
|
110 |
-
"anymatch": {
|
111 |
-
"version": "1.3.2",
|
112 |
-
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
|
113 |
-
"integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
|
114 |
-
"dev": true,
|
115 |
-
"requires": {
|
116 |
-
"micromatch": "^2.1.5",
|
117 |
-
"normalize-path": "^2.0.0"
|
118 |
-
}
|
119 |
-
},
|
120 |
-
"aproba": {
|
121 |
-
"version": "1.2.0",
|
122 |
-
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
123 |
-
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
124 |
-
"dev": true
|
125 |
-
},
|
126 |
-
"are-we-there-yet": {
|
127 |
-
"version": "1.1.4",
|
128 |
-
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
|
129 |
-
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
130 |
-
"dev": true,
|
131 |
-
"requires": {
|
132 |
-
"delegates": "^1.0.0",
|
133 |
-
"readable-stream": "^2.0.6"
|
134 |
-
}
|
135 |
-
},
|
136 |
-
"argparse": {
|
137 |
-
"version": "1.0.9",
|
138 |
-
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
|
139 |
-
"integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
|
140 |
-
"dev": true,
|
141 |
-
"requires": {
|
142 |
-
"sprintf-js": "~1.0.2"
|
143 |
-
}
|
144 |
-
},
|
145 |
-
"arr-diff": {
|
146 |
-
"version": "2.0.0",
|
147 |
-
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
|
148 |
-
"integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
|
149 |
-
"dev": true,
|
150 |
-
"requires": {
|
151 |
-
"arr-flatten": "^1.0.1"
|
152 |
-
}
|
153 |
-
},
|
154 |
-
"arr-flatten": {
|
155 |
-
"version": "1.1.0",
|
156 |
-
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
|
157 |
-
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
|
158 |
-
"dev": true
|
159 |
-
},
|
160 |
-
"array-find-index": {
|
161 |
-
"version": "1.0.2",
|
162 |
-
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
|
163 |
-
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
|
164 |
-
"dev": true
|
165 |
-
},
|
166 |
-
"array-union": {
|
167 |
-
"version": "1.0.2",
|
168 |
-
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
|
169 |
-
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
|
170 |
-
"dev": true,
|
171 |
-
"requires": {
|
172 |
-
"array-uniq": "^1.0.1"
|
173 |
-
}
|
174 |
-
},
|
175 |
-
"array-uniq": {
|
176 |
-
"version": "1.0.3",
|
177 |
-
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
|
178 |
-
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
|
179 |
-
"dev": true
|
180 |
-
},
|
181 |
-
"array-unique": {
|
182 |
-
"version": "0.2.1",
|
183 |
-
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
|
184 |
-
"integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
|
185 |
-
"dev": true
|
186 |
-
},
|
187 |
-
"arrify": {
|
188 |
-
"version": "1.0.1",
|
189 |
-
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
190 |
-
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
191 |
-
"dev": true
|
192 |
-
},
|
193 |
-
"asn1": {
|
194 |
-
"version": "0.2.3",
|
195 |
-
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
|
196 |
-
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
|
197 |
-
"dev": true
|
198 |
-
},
|
199 |
-
"asn1.js": {
|
200 |
-
"version": "4.9.2",
|
201 |
-
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz",
|
202 |
-
"integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==",
|
203 |
-
"dev": true,
|
204 |
-
"requires": {
|
205 |
-
"bn.js": "^4.0.0",
|
206 |
-
"inherits": "^2.0.1",
|
207 |
-
"minimalistic-assert": "^1.0.0"
|
208 |
-
}
|
209 |
-
},
|
210 |
-
"assert": {
|
211 |
-
"version": "1.4.1",
|
212 |
-
"resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
|
213 |
-
"integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
|
214 |
-
"dev": true,
|
215 |
-
"requires": {
|
216 |
-
"util": "0.10.3"
|
217 |
-
}
|
218 |
-
},
|
219 |
-
"assert-plus": {
|
220 |
-
"version": "0.2.0",
|
221 |
-
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
222 |
-
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
|
223 |
-
"dev": true
|
224 |
-
},
|
225 |
-
"async": {
|
226 |
-
"version": "2.6.0",
|
227 |
-
"resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
|
228 |
-
"integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
|
229 |
-
"dev": true,
|
230 |
-
"requires": {
|
231 |
-
"lodash": "^4.14.0"
|
232 |
-
}
|
233 |
-
},
|
234 |
-
"async-each": {
|
235 |
-
"version": "1.0.1",
|
236 |
-
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
|
237 |
-
"integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
|
238 |
-
"dev": true
|
239 |
-
},
|
240 |
-
"async-foreach": {
|
241 |
-
"version": "0.1.3",
|
242 |
-
"resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
|
243 |
-
"integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
|
244 |
-
"dev": true
|
245 |
-
},
|
246 |
-
"asynckit": {
|
247 |
-
"version": "0.4.0",
|
248 |
-
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
249 |
-
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
250 |
-
"dev": true
|
251 |
-
},
|
252 |
-
"autoprefixer": {
|
253 |
-
"version": "6.7.7",
|
254 |
-
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
|
255 |
-
"integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
|
256 |
-
"dev": true,
|
257 |
-
"requires": {
|
258 |
-
"browserslist": "^1.7.6",
|
259 |
-
"caniuse-db": "^1.0.30000634",
|
260 |
-
"normalize-range": "^0.1.2",
|
261 |
-
"num2fraction": "^1.2.2",
|
262 |
-
"postcss": "^5.2.16",
|
263 |
-
"postcss-value-parser": "^3.2.3"
|
264 |
-
},
|
265 |
-
"dependencies": {
|
266 |
-
"browserslist": {
|
267 |
-
"version": "1.7.7",
|
268 |
-
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
|
269 |
-
"integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
|
270 |
-
"dev": true,
|
271 |
-
"requires": {
|
272 |
-
"caniuse-db": "^1.0.30000639",
|
273 |
-
"electron-to-chromium": "^1.2.7"
|
274 |
-
}
|
275 |
-
}
|
276 |
-
}
|
277 |
-
},
|
278 |
-
"aws-sign2": {
|
279 |
-
"version": "0.6.0",
|
280 |
-
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
|
281 |
-
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
|
282 |
-
"dev": true
|
283 |
-
},
|
284 |
-
"aws4": {
|
285 |
-
"version": "1.6.0",
|
286 |
-
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
|
287 |
-
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
|
288 |
-
"dev": true
|
289 |
-
},
|
290 |
-
"babel-code-frame": {
|
291 |
-
"version": "6.26.0",
|
292 |
-
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
293 |
-
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
294 |
-
"dev": true,
|
295 |
-
"requires": {
|
296 |
-
"chalk": "^1.1.3",
|
297 |
-
"esutils": "^2.0.2",
|
298 |
-
"js-tokens": "^3.0.2"
|
299 |
-
}
|
300 |
-
},
|
301 |
-
"babel-core": {
|
302 |
-
"version": "6.26.0",
|
303 |
-
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
|
304 |
-
"integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
|
305 |
-
"dev": true,
|
306 |
-
"requires": {
|
307 |
-
"babel-code-frame": "^6.26.0",
|
308 |
-
"babel-generator": "^6.26.0",
|
309 |
-
"babel-helpers": "^6.24.1",
|
310 |
-
"babel-messages": "^6.23.0",
|
311 |
-
"babel-register": "^6.26.0",
|
312 |
-
"babel-runtime": "^6.26.0",
|
313 |
-
"babel-template": "^6.26.0",
|
314 |
-
"babel-traverse": "^6.26.0",
|
315 |
-
"babel-types": "^6.26.0",
|
316 |
-
"babylon": "^6.18.0",
|
317 |
-
"convert-source-map": "^1.5.0",
|
318 |
-
"debug": "^2.6.8",
|
319 |
-
"json5": "^0.5.1",
|
320 |
-
"lodash": "^4.17.4",
|
321 |
-
"minimatch": "^3.0.4",
|
322 |
-
"path-is-absolute": "^1.0.1",
|
323 |
-
"private": "^0.1.7",
|
324 |
-
"slash": "^1.0.0",
|
325 |
-
"source-map": "^0.5.6"
|
326 |
-
}
|
327 |
-
},
|
328 |
-
"babel-generator": {
|
329 |
-
"version": "6.26.0",
|
330 |
-
"resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
|
331 |
-
"integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
|
332 |
-
"dev": true,
|
333 |
-
"requires": {
|
334 |
-
"babel-messages": "^6.23.0",
|
335 |
-
"babel-runtime": "^6.26.0",
|
336 |
-
"babel-types": "^6.26.0",
|
337 |
-
"detect-indent": "^4.0.0",
|
338 |
-
"jsesc": "^1.3.0",
|
339 |
-
"lodash": "^4.17.4",
|
340 |
-
"source-map": "^0.5.6",
|
341 |
-
"trim-right": "^1.0.1"
|
342 |
-
}
|
343 |
-
},
|
344 |
-
"babel-helper-builder-binary-assignment-operator-visitor": {
|
345 |
-
"version": "6.24.1",
|
346 |
-
"resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
|
347 |
-
"integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
|
348 |
-
"dev": true,
|
349 |
-
"requires": {
|
350 |
-
"babel-helper-explode-assignable-expression": "^6.24.1",
|
351 |
-
"babel-runtime": "^6.22.0",
|
352 |
-
"babel-types": "^6.24.1"
|
353 |
-
}
|
354 |
-
},
|
355 |
-
"babel-helper-call-delegate": {
|
356 |
-
"version": "6.24.1",
|
357 |
-
"resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
|
358 |
-
"integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
|
359 |
-
"dev": true,
|
360 |
-
"requires": {
|
361 |
-
"babel-helper-hoist-variables": "^6.24.1",
|
362 |
-
"babel-runtime": "^6.22.0",
|
363 |
-
"babel-traverse": "^6.24.1",
|
364 |
-
"babel-types": "^6.24.1"
|
365 |
-
}
|
366 |
-
},
|
367 |
-
"babel-helper-define-map": {
|
368 |
-
"version": "6.26.0",
|
369 |
-
"resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
|
370 |
-
"integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
|
371 |
-
"dev": true,
|
372 |
-
"requires": {
|
373 |
-
"babel-helper-function-name": "^6.24.1",
|
374 |
-
"babel-runtime": "^6.26.0",
|
375 |
-
"babel-types": "^6.26.0",
|
376 |
-
"lodash": "^4.17.4"
|
377 |
-
}
|
378 |
-
},
|
379 |
-
"babel-helper-explode-assignable-expression": {
|
380 |
-
"version": "6.24.1",
|
381 |
-
"resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
|
382 |
-
"integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
|
383 |
-
"dev": true,
|
384 |
-
"requires": {
|
385 |
-
"babel-runtime": "^6.22.0",
|
386 |
-
"babel-traverse": "^6.24.1",
|
387 |
-
"babel-types": "^6.24.1"
|
388 |
-
}
|
389 |
-
},
|
390 |
-
"babel-helper-function-name": {
|
391 |
-
"version": "6.24.1",
|
392 |
-
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
|
393 |
-
"integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
|
394 |
-
"dev": true,
|
395 |
-
"requires": {
|
396 |
-
"babel-helper-get-function-arity": "^6.24.1",
|
397 |
-
"babel-runtime": "^6.22.0",
|
398 |
-
"babel-template": "^6.24.1",
|
399 |
-
"babel-traverse": "^6.24.1",
|
400 |
-
"babel-types": "^6.24.1"
|
401 |
-
}
|
402 |
-
},
|
403 |
-
"babel-helper-get-function-arity": {
|
404 |
-
"version": "6.24.1",
|
405 |
-
"resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
|
406 |
-
"integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
|
407 |
-
"dev": true,
|
408 |
-
"requires": {
|
409 |
-
"babel-runtime": "^6.22.0",
|
410 |
-
"babel-types": "^6.24.1"
|
411 |
-
}
|
412 |
-
},
|
413 |
-
"babel-helper-hoist-variables": {
|
414 |
-
"version": "6.24.1",
|
415 |
-
"resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
|
416 |
-
"integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
|
417 |
-
"dev": true,
|
418 |
-
"requires": {
|
419 |
-
"babel-runtime": "^6.22.0",
|
420 |
-
"babel-types": "^6.24.1"
|
421 |
-
}
|
422 |
-
},
|
423 |
-
"babel-helper-optimise-call-expression": {
|
424 |
-
"version": "6.24.1",
|
425 |
-
"resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
|
426 |
-
"integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
|
427 |
-
"dev": true,
|
428 |
-
"requires": {
|
429 |
-
"babel-runtime": "^6.22.0",
|
430 |
-
"babel-types": "^6.24.1"
|
431 |
-
}
|
432 |
-
},
|
433 |
-
"babel-helper-regex": {
|
434 |
-
"version": "6.26.0",
|
435 |
-
"resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
|
436 |
-
"integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
|
437 |
-
"dev": true,
|
438 |
-
"requires": {
|
439 |
-
"babel-runtime": "^6.26.0",
|
440 |
-
"babel-types": "^6.26.0",
|
441 |
-
"lodash": "^4.17.4"
|
442 |
-
}
|
443 |
-
},
|
444 |
-
"babel-helper-remap-async-to-generator": {
|
445 |
-
"version": "6.24.1",
|
446 |
-
"resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
|
447 |
-
"integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
|
448 |
-
"dev": true,
|
449 |
-
"requires": {
|
450 |
-
"babel-helper-function-name": "^6.24.1",
|
451 |
-
"babel-runtime": "^6.22.0",
|
452 |
-
"babel-template": "^6.24.1",
|
453 |
-
"babel-traverse": "^6.24.1",
|
454 |
-
"babel-types": "^6.24.1"
|
455 |
-
}
|
456 |
-
},
|
457 |
-
"babel-helper-replace-supers": {
|
458 |
-
"version": "6.24.1",
|
459 |
-
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
460 |
-
"integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
|
461 |
-
"dev": true,
|
462 |
-
"requires": {
|
463 |
-
"babel-helper-optimise-call-expression": "^6.24.1",
|
464 |
-
"babel-messages": "^6.23.0",
|
465 |
-
"babel-runtime": "^6.22.0",
|
466 |
-
"babel-template": "^6.24.1",
|
467 |
-
"babel-traverse": "^6.24.1",
|
468 |
-
"babel-types": "^6.24.1"
|
469 |
-
}
|
470 |
-
},
|
471 |
-
"babel-helpers": {
|
472 |
-
"version": "6.24.1",
|
473 |
-
"resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
|
474 |
-
"integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
|
475 |
-
"dev": true,
|
476 |
-
"requires": {
|
477 |
-
"babel-runtime": "^6.22.0",
|
478 |
-
"babel-template": "^6.24.1"
|
479 |
-
}
|
480 |
-
},
|
481 |
-
"babel-loader": {
|
482 |
-
"version": "7.1.2",
|
483 |
-
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz",
|
484 |
-
"integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==",
|
485 |
-
"dev": true,
|
486 |
-
"requires": {
|
487 |
-
"find-cache-dir": "^1.0.0",
|
488 |
-
"loader-utils": "^1.0.2",
|
489 |
-
"mkdirp": "^0.5.1"
|
490 |
-
}
|
491 |
-
},
|
492 |
-
"babel-messages": {
|
493 |
-
"version": "6.23.0",
|
494 |
-
"resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
|
495 |
-
"integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
|
496 |
-
"dev": true,
|
497 |
-
"requires": {
|
498 |
-
"babel-runtime": "^6.22.0"
|
499 |
-
}
|
500 |
-
},
|
501 |
-
"babel-plugin-check-es2015-constants": {
|
502 |
-
"version": "6.22.0",
|
503 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
|
504 |
-
"integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
|
505 |
-
"dev": true,
|
506 |
-
"requires": {
|
507 |
-
"babel-runtime": "^6.22.0"
|
508 |
-
}
|
509 |
-
},
|
510 |
-
"babel-plugin-syntax-async-functions": {
|
511 |
-
"version": "6.13.0",
|
512 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
|
513 |
-
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
|
514 |
-
"dev": true
|
515 |
-
},
|
516 |
-
"babel-plugin-syntax-exponentiation-operator": {
|
517 |
-
"version": "6.13.0",
|
518 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
|
519 |
-
"integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
|
520 |
-
"dev": true
|
521 |
-
},
|
522 |
-
"babel-plugin-syntax-trailing-function-commas": {
|
523 |
-
"version": "6.22.0",
|
524 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
|
525 |
-
"integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
|
526 |
-
"dev": true
|
527 |
-
},
|
528 |
-
"babel-plugin-transform-async-to-generator": {
|
529 |
-
"version": "6.24.1",
|
530 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
|
531 |
-
"integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
|
532 |
-
"dev": true,
|
533 |
-
"requires": {
|
534 |
-
"babel-helper-remap-async-to-generator": "^6.24.1",
|
535 |
-
"babel-plugin-syntax-async-functions": "^6.8.0",
|
536 |
-
"babel-runtime": "^6.22.0"
|
537 |
-
}
|
538 |
-
},
|
539 |
-
"babel-plugin-transform-es2015-arrow-functions": {
|
540 |
-
"version": "6.22.0",
|
541 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
542 |
-
"integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
|
543 |
-
"dev": true,
|
544 |
-
"requires": {
|
545 |
-
"babel-runtime": "^6.22.0"
|
546 |
-
}
|
547 |
-
},
|
548 |
-
"babel-plugin-transform-es2015-block-scoped-functions": {
|
549 |
-
"version": "6.22.0",
|
550 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
|
551 |
-
"integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
|
552 |
-
"dev": true,
|
553 |
-
"requires": {
|
554 |
-
"babel-runtime": "^6.22.0"
|
555 |
-
}
|
556 |
-
},
|
557 |
-
"babel-plugin-transform-es2015-block-scoping": {
|
558 |
-
"version": "6.26.0",
|
559 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
|
560 |
-
"integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
|
561 |
-
"dev": true,
|
562 |
-
"requires": {
|
563 |
-
"babel-runtime": "^6.26.0",
|
564 |
-
"babel-template": "^6.26.0",
|
565 |
-
"babel-traverse": "^6.26.0",
|
566 |
-
"babel-types": "^6.26.0",
|
567 |
-
"lodash": "^4.17.4"
|
568 |
-
}
|
569 |
-
},
|
570 |
-
"babel-plugin-transform-es2015-classes": {
|
571 |
-
"version": "6.24.1",
|
572 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
|
573 |
-
"integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
|
574 |
-
"dev": true,
|
575 |
-
"requires": {
|
576 |
-
"babel-helper-define-map": "^6.24.1",
|
577 |
-
"babel-helper-function-name": "^6.24.1",
|
578 |
-
"babel-helper-optimise-call-expression": "^6.24.1",
|
579 |
-
"babel-helper-replace-supers": "^6.24.1",
|
580 |
-
"babel-messages": "^6.23.0",
|
581 |
-
"babel-runtime": "^6.22.0",
|
582 |
-
"babel-template": "^6.24.1",
|
583 |
-
"babel-traverse": "^6.24.1",
|
584 |
-
"babel-types": "^6.24.1"
|
585 |
-
}
|
586 |
-
},
|
587 |
-
"babel-plugin-transform-es2015-computed-properties": {
|
588 |
-
"version": "6.24.1",
|
589 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
|
590 |
-
"integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
|
591 |
-
"dev": true,
|
592 |
-
"requires": {
|
593 |
-
"babel-runtime": "^6.22.0",
|
594 |
-
"babel-template": "^6.24.1"
|
595 |
-
}
|
596 |
-
},
|
597 |
-
"babel-plugin-transform-es2015-destructuring": {
|
598 |
-
"version": "6.23.0",
|
599 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
|
600 |
-
"integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
|
601 |
-
"dev": true,
|
602 |
-
"requires": {
|
603 |
-
"babel-runtime": "^6.22.0"
|
604 |
-
}
|
605 |
-
},
|
606 |
-
"babel-plugin-transform-es2015-duplicate-keys": {
|
607 |
-
"version": "6.24.1",
|
608 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
|
609 |
-
"integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
|
610 |
-
"dev": true,
|
611 |
-
"requires": {
|
612 |
-
"babel-runtime": "^6.22.0",
|
613 |
-
"babel-types": "^6.24.1"
|
614 |
-
}
|
615 |
-
},
|
616 |
-
"babel-plugin-transform-es2015-for-of": {
|
617 |
-
"version": "6.23.0",
|
618 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
|
619 |
-
"integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
|
620 |
-
"dev": true,
|
621 |
-
"requires": {
|
622 |
-
"babel-runtime": "^6.22.0"
|
623 |
-
}
|
624 |
-
},
|
625 |
-
"babel-plugin-transform-es2015-function-name": {
|
626 |
-
"version": "6.24.1",
|
627 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
|
628 |
-
"integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
|
629 |
-
"dev": true,
|
630 |
-
"requires": {
|
631 |
-
"babel-helper-function-name": "^6.24.1",
|
632 |
-
"babel-runtime": "^6.22.0",
|
633 |
-
"babel-types": "^6.24.1"
|
634 |
-
}
|
635 |
-
},
|
636 |
-
"babel-plugin-transform-es2015-literals": {
|
637 |
-
"version": "6.22.0",
|
638 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
|
639 |
-
"integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
|
640 |
-
"dev": true,
|
641 |
-
"requires": {
|
642 |
-
"babel-runtime": "^6.22.0"
|
643 |
-
}
|
644 |
-
},
|
645 |
-
"babel-plugin-transform-es2015-modules-amd": {
|
646 |
-
"version": "6.24.1",
|
647 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
|
648 |
-
"integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
|
649 |
-
"dev": true,
|
650 |
-
"requires": {
|
651 |
-
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
|
652 |
-
"babel-runtime": "^6.22.0",
|
653 |
-
"babel-template": "^6.24.1"
|
654 |
-
}
|
655 |
-
},
|
656 |
-
"babel-plugin-transform-es2015-modules-commonjs": {
|
657 |
-
"version": "6.26.0",
|
658 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
|
659 |
-
"integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
|
660 |
-
"dev": true,
|
661 |
-
"requires": {
|
662 |
-
"babel-plugin-transform-strict-mode": "^6.24.1",
|
663 |
-
"babel-runtime": "^6.26.0",
|
664 |
-
"babel-template": "^6.26.0",
|
665 |
-
"babel-types": "^6.26.0"
|
666 |
-
}
|
667 |
-
},
|
668 |
-
"babel-plugin-transform-es2015-modules-systemjs": {
|
669 |
-
"version": "6.24.1",
|
670 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
|
671 |
-
"integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
|
672 |
-
"dev": true,
|
673 |
-
"requires": {
|
674 |
-
"babel-helper-hoist-variables": "^6.24.1",
|
675 |
-
"babel-runtime": "^6.22.0",
|
676 |
-
"babel-template": "^6.24.1"
|
677 |
-
}
|
678 |
-
},
|
679 |
-
"babel-plugin-transform-es2015-modules-umd": {
|
680 |
-
"version": "6.24.1",
|
681 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
|
682 |
-
"integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
|
683 |
-
"dev": true,
|
684 |
-
"requires": {
|
685 |
-
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
|
686 |
-
"babel-runtime": "^6.22.0",
|
687 |
-
"babel-template": "^6.24.1"
|
688 |
-
}
|
689 |
-
},
|
690 |
-
"babel-plugin-transform-es2015-object-super": {
|
691 |
-
"version": "6.24.1",
|
692 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
|
693 |
-
"integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
|
694 |
-
"dev": true,
|
695 |
-
"requires": {
|
696 |
-
"babel-helper-replace-supers": "^6.24.1",
|
697 |
-
"babel-runtime": "^6.22.0"
|
698 |
-
}
|
699 |
-
},
|
700 |
-
"babel-plugin-transform-es2015-parameters": {
|
701 |
-
"version": "6.24.1",
|
702 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
|
703 |
-
"integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
|
704 |
-
"dev": true,
|
705 |
-
"requires": {
|
706 |
-
"babel-helper-call-delegate": "^6.24.1",
|
707 |
-
"babel-helper-get-function-arity": "^6.24.1",
|
708 |
-
"babel-runtime": "^6.22.0",
|
709 |
-
"babel-template": "^6.24.1",
|
710 |
-
"babel-traverse": "^6.24.1",
|
711 |
-
"babel-types": "^6.24.1"
|
712 |
-
}
|
713 |
-
},
|
714 |
-
"babel-plugin-transform-es2015-shorthand-properties": {
|
715 |
-
"version": "6.24.1",
|
716 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
|
717 |
-
"integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
|
718 |
-
"dev": true,
|
719 |
-
"requires": {
|
720 |
-
"babel-runtime": "^6.22.0",
|
721 |
-
"babel-types": "^6.24.1"
|
722 |
-
}
|
723 |
-
},
|
724 |
-
"babel-plugin-transform-es2015-spread": {
|
725 |
-
"version": "6.22.0",
|
726 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
|
727 |
-
"integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
|
728 |
-
"dev": true,
|
729 |
-
"requires": {
|
730 |
-
"babel-runtime": "^6.22.0"
|
731 |
-
}
|
732 |
-
},
|
733 |
-
"babel-plugin-transform-es2015-sticky-regex": {
|
734 |
-
"version": "6.24.1",
|
735 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
|
736 |
-
"integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
|
737 |
-
"dev": true,
|
738 |
-
"requires": {
|
739 |
-
"babel-helper-regex": "^6.24.1",
|
740 |
-
"babel-runtime": "^6.22.0",
|
741 |
-
"babel-types": "^6.24.1"
|
742 |
-
}
|
743 |
-
},
|
744 |
-
"babel-plugin-transform-es2015-template-literals": {
|
745 |
-
"version": "6.22.0",
|
746 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
|
747 |
-
"integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
|
748 |
-
"dev": true,
|
749 |
-
"requires": {
|
750 |
-
"babel-runtime": "^6.22.0"
|
751 |
-
}
|
752 |
-
},
|
753 |
-
"babel-plugin-transform-es2015-typeof-symbol": {
|
754 |
-
"version": "6.23.0",
|
755 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
|
756 |
-
"integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
|
757 |
-
"dev": true,
|
758 |
-
"requires": {
|
759 |
-
"babel-runtime": "^6.22.0"
|
760 |
-
}
|
761 |
-
},
|
762 |
-
"babel-plugin-transform-es2015-unicode-regex": {
|
763 |
-
"version": "6.24.1",
|
764 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
|
765 |
-
"integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
|
766 |
-
"dev": true,
|
767 |
-
"requires": {
|
768 |
-
"babel-helper-regex": "^6.24.1",
|
769 |
-
"babel-runtime": "^6.22.0",
|
770 |
-
"regexpu-core": "^2.0.0"
|
771 |
-
}
|
772 |
-
},
|
773 |
-
"babel-plugin-transform-exponentiation-operator": {
|
774 |
-
"version": "6.24.1",
|
775 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
|
776 |
-
"integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
|
777 |
-
"dev": true,
|
778 |
-
"requires": {
|
779 |
-
"babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
|
780 |
-
"babel-plugin-syntax-exponentiation-operator": "^6.8.0",
|
781 |
-
"babel-runtime": "^6.22.0"
|
782 |
-
}
|
783 |
-
},
|
784 |
-
"babel-plugin-transform-regenerator": {
|
785 |
-
"version": "6.26.0",
|
786 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
|
787 |
-
"integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
|
788 |
-
"dev": true,
|
789 |
-
"requires": {
|
790 |
-
"regenerator-transform": "^0.10.0"
|
791 |
-
}
|
792 |
-
},
|
793 |
-
"babel-plugin-transform-strict-mode": {
|
794 |
-
"version": "6.24.1",
|
795 |
-
"resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
|
796 |
-
"integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
|
797 |
-
"dev": true,
|
798 |
-
"requires": {
|
799 |
-
"babel-runtime": "^6.22.0",
|
800 |
-
"babel-types": "^6.24.1"
|
801 |
-
}
|
802 |
-
},
|
803 |
-
"babel-preset-env": {
|
804 |
-
"version": "1.6.1",
|
805 |
-
"resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
|
806 |
-
"integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==",
|
807 |
-
"dev": true,
|
808 |
-
"requires": {
|
809 |
-
"babel-plugin-check-es2015-constants": "^6.22.0",
|
810 |
-
"babel-plugin-syntax-trailing-function-commas": "^6.22.0",
|
811 |
-
"babel-plugin-transform-async-to-generator": "^6.22.0",
|
812 |
-
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
813 |
-
"babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
|
814 |
-
"babel-plugin-transform-es2015-block-scoping": "^6.23.0",
|
815 |
-
"babel-plugin-transform-es2015-classes": "^6.23.0",
|
816 |
-
"babel-plugin-transform-es2015-computed-properties": "^6.22.0",
|
817 |
-
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
|
818 |
-
"babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
|
819 |
-
"babel-plugin-transform-es2015-for-of": "^6.23.0",
|
820 |
-
"babel-plugin-transform-es2015-function-name": "^6.22.0",
|
821 |
-
"babel-plugin-transform-es2015-literals": "^6.22.0",
|
822 |
-
"babel-plugin-transform-es2015-modules-amd": "^6.22.0",
|
823 |
-
"babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
|
824 |
-
"babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
|
825 |
-
"babel-plugin-transform-es2015-modules-umd": "^6.23.0",
|
826 |
-
"babel-plugin-transform-es2015-object-super": "^6.22.0",
|
827 |
-
"babel-plugin-transform-es2015-parameters": "^6.23.0",
|
828 |
-
"babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
|
829 |
-
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
830 |
-
"babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
|
831 |
-
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
832 |
-
"babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
|
833 |
-
"babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
|
834 |
-
"babel-plugin-transform-exponentiation-operator": "^6.22.0",
|
835 |
-
"babel-plugin-transform-regenerator": "^6.22.0",
|
836 |
-
"browserslist": "^2.1.2",
|
837 |
-
"invariant": "^2.2.2",
|
838 |
-
"semver": "^5.3.0"
|
839 |
-
}
|
840 |
-
},
|
841 |
-
"babel-register": {
|
842 |
-
"version": "6.26.0",
|
843 |
-
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
|
844 |
-
"integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
|
845 |
-
"dev": true,
|
846 |
-
"requires": {
|
847 |
-
"babel-core": "^6.26.0",
|
848 |
-
"babel-runtime": "^6.26.0",
|
849 |
-
"core-js": "^2.5.0",
|
850 |
-
"home-or-tmp": "^2.0.0",
|
851 |
-
"lodash": "^4.17.4",
|
852 |
-
"mkdirp": "^0.5.1",
|
853 |
-
"source-map-support": "^0.4.15"
|
854 |
-
}
|
855 |
-
},
|
856 |
-
"babel-runtime": {
|
857 |
-
"version": "6.26.0",
|
858 |
-
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
859 |
-
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
860 |
-
"dev": true,
|
861 |
-
"requires": {
|
862 |
-
"core-js": "^2.4.0",
|
863 |
-
"regenerator-runtime": "^0.11.0"
|
864 |
-
}
|
865 |
-
},
|
866 |
-
"babel-template": {
|
867 |
-
"version": "6.26.0",
|
868 |
-
"resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
|
869 |
-
"integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
|
870 |
-
"dev": true,
|
871 |
-
"requires": {
|
872 |
-
"babel-runtime": "^6.26.0",
|
873 |
-
"babel-traverse": "^6.26.0",
|
874 |
-
"babel-types": "^6.26.0",
|
875 |
-
"babylon": "^6.18.0",
|
876 |
-
"lodash": "^4.17.4"
|
877 |
-
}
|
878 |
-
},
|
879 |
-
"babel-traverse": {
|
880 |
-
"version": "6.26.0",
|
881 |
-
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
|
882 |
-
"integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
|
883 |
-
"dev": true,
|
884 |
-
"requires": {
|
885 |
-
"babel-code-frame": "^6.26.0",
|
886 |
-
"babel-messages": "^6.23.0",
|
887 |
-
"babel-runtime": "^6.26.0",
|
888 |
-
"babel-types": "^6.26.0",
|
889 |
-
"babylon": "^6.18.0",
|
890 |
-
"debug": "^2.6.8",
|
891 |
-
"globals": "^9.18.0",
|
892 |
-
"invariant": "^2.2.2",
|
893 |
-
"lodash": "^4.17.4"
|
894 |
-
}
|
895 |
-
},
|
896 |
-
"babel-types": {
|
897 |
-
"version": "6.26.0",
|
898 |
-
"resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
|
899 |
-
"integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
|
900 |
-
"dev": true,
|
901 |
-
"requires": {
|
902 |
-
"babel-runtime": "^6.26.0",
|
903 |
-
"esutils": "^2.0.2",
|
904 |
-
"lodash": "^4.17.4",
|
905 |
-
"to-fast-properties": "^1.0.3"
|
906 |
-
}
|
907 |
-
},
|
908 |
-
"babylon": {
|
909 |
-
"version": "6.18.0",
|
910 |
-
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
|
911 |
-
"integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
|
912 |
-
"dev": true
|
913 |
-
},
|
914 |
-
"balanced-match": {
|
915 |
-
"version": "1.0.0",
|
916 |
-
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
917 |
-
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
918 |
-
"dev": true
|
919 |
-
},
|
920 |
-
"base64-js": {
|
921 |
-
"version": "1.2.1",
|
922 |
-
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
|
923 |
-
"integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
|
924 |
-
"dev": true
|
925 |
-
},
|
926 |
-
"bcrypt-pbkdf": {
|
927 |
-
"version": "1.0.1",
|
928 |
-
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
|
929 |
-
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
|
930 |
-
"dev": true,
|
931 |
-
"optional": true,
|
932 |
-
"requires": {
|
933 |
-
"tweetnacl": "^0.14.3"
|
934 |
-
}
|
935 |
-
},
|
936 |
-
"big.js": {
|
937 |
-
"version": "3.2.0",
|
938 |
-
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
|
939 |
-
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
|
940 |
-
"dev": true
|
941 |
-
},
|
942 |
-
"binary-extensions": {
|
943 |
-
"version": "1.11.0",
|
944 |
-
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
|
945 |
-
"integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
|
946 |
-
"dev": true
|
947 |
-
},
|
948 |
-
"block-stream": {
|
949 |
-
"version": "0.0.9",
|
950 |
-
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
951 |
-
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
|
952 |
-
"dev": true,
|
953 |
-
"requires": {
|
954 |
-
"inherits": "~2.0.0"
|
955 |
-
}
|
956 |
-
},
|
957 |
-
"bn.js": {
|
958 |
-
"version": "4.11.8",
|
959 |
-
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
|
960 |
-
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
|
961 |
-
"dev": true
|
962 |
-
},
|
963 |
-
"boom": {
|
964 |
-
"version": "2.10.1",
|
965 |
-
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
966 |
-
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
967 |
-
"dev": true,
|
968 |
-
"requires": {
|
969 |
-
"hoek": "2.x.x"
|
970 |
-
}
|
971 |
-
},
|
972 |
-
"brace-expansion": {
|
973 |
-
"version": "1.1.8",
|
974 |
-
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
|
975 |
-
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
|
976 |
-
"dev": true,
|
977 |
-
"requires": {
|
978 |
-
"balanced-match": "^1.0.0",
|
979 |
-
"concat-map": "0.0.1"
|
980 |
-
}
|
981 |
-
},
|
982 |
-
"braces": {
|
983 |
-
"version": "1.8.5",
|
984 |
-
"resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
|
985 |
-
"integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
|
986 |
-
"dev": true,
|
987 |
-
"requires": {
|
988 |
-
"expand-range": "^1.8.1",
|
989 |
-
"preserve": "^0.2.0",
|
990 |
-
"repeat-element": "^1.1.2"
|
991 |
-
}
|
992 |
-
},
|
993 |
-
"brorand": {
|
994 |
-
"version": "1.1.0",
|
995 |
-
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
996 |
-
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
|
997 |
-
"dev": true
|
998 |
-
},
|
999 |
-
"browserify-aes": {
|
1000 |
-
"version": "1.1.1",
|
1001 |
-
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz",
|
1002 |
-
"integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==",
|
1003 |
-
"dev": true,
|
1004 |
-
"requires": {
|
1005 |
-
"buffer-xor": "^1.0.3",
|
1006 |
-
"cipher-base": "^1.0.0",
|
1007 |
-
"create-hash": "^1.1.0",
|
1008 |
-
"evp_bytestokey": "^1.0.3",
|
1009 |
-
"inherits": "^2.0.1",
|
1010 |
-
"safe-buffer": "^5.0.1"
|
1011 |
-
}
|
1012 |
-
},
|
1013 |
-
"browserify-cipher": {
|
1014 |
-
"version": "1.0.0",
|
1015 |
-
"resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
|
1016 |
-
"integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
|
1017 |
-
"dev": true,
|
1018 |
-
"requires": {
|
1019 |
-
"browserify-aes": "^1.0.4",
|
1020 |
-
"browserify-des": "^1.0.0",
|
1021 |
-
"evp_bytestokey": "^1.0.0"
|
1022 |
-
}
|
1023 |
-
},
|
1024 |
-
"browserify-des": {
|
1025 |
-
"version": "1.0.0",
|
1026 |
-
"resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
|
1027 |
-
"integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
|
1028 |
-
"dev": true,
|
1029 |
-
"requires": {
|
1030 |
-
"cipher-base": "^1.0.1",
|
1031 |
-
"des.js": "^1.0.0",
|
1032 |
-
"inherits": "^2.0.1"
|
1033 |
-
}
|
1034 |
-
},
|
1035 |
-
"browserify-rsa": {
|
1036 |
-
"version": "4.0.1",
|
1037 |
-
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
|
1038 |
-
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
|
1039 |
-
"dev": true,
|
1040 |
-
"requires": {
|
1041 |
-
"bn.js": "^4.1.0",
|
1042 |
-
"randombytes": "^2.0.1"
|
1043 |
-
}
|
1044 |
-
},
|
1045 |
-
"browserify-sign": {
|
1046 |
-
"version": "4.0.4",
|
1047 |
-
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
|
1048 |
-
"integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
|
1049 |
-
"dev": true,
|
1050 |
-
"requires": {
|
1051 |
-
"bn.js": "^4.1.1",
|
1052 |
-
"browserify-rsa": "^4.0.0",
|
1053 |
-
"create-hash": "^1.1.0",
|
1054 |
-
"create-hmac": "^1.1.2",
|
1055 |
-
"elliptic": "^6.0.0",
|
1056 |
-
"inherits": "^2.0.1",
|
1057 |
-
"parse-asn1": "^5.0.0"
|
1058 |
-
}
|
1059 |
-
},
|
1060 |
-
"browserify-zlib": {
|
1061 |
-
"version": "0.2.0",
|
1062 |
-
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
|
1063 |
-
"integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
|
1064 |
-
"dev": true,
|
1065 |
-
"requires": {
|
1066 |
-
"pako": "~1.0.5"
|
1067 |
-
}
|
1068 |
-
},
|
1069 |
-
"browserslist": {
|
1070 |
-
"version": "2.9.1",
|
1071 |
-
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.9.1.tgz",
|
1072 |
-
"integrity": "sha512-3n3nPdbUqn3nWmsy4PeSQthz2ja1ndpoXta+dwFFNhveGjMg6FXpWYe12vsTpNoXJbzx3j7GZXdtoVIdvh3JbA==",
|
1073 |
-
"dev": true,
|
1074 |
-
"requires": {
|
1075 |
-
"caniuse-lite": "^1.0.30000770",
|
1076 |
-
"electron-to-chromium": "^1.3.27"
|
1077 |
-
}
|
1078 |
-
},
|
1079 |
-
"buffer": {
|
1080 |
-
"version": "4.9.1",
|
1081 |
-
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
|
1082 |
-
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
|
1083 |
-
"dev": true,
|
1084 |
-
"requires": {
|
1085 |
-
"base64-js": "^1.0.2",
|
1086 |
-
"ieee754": "^1.1.4",
|
1087 |
-
"isarray": "^1.0.0"
|
1088 |
-
}
|
1089 |
-
},
|
1090 |
-
"buffer-xor": {
|
1091 |
-
"version": "1.0.3",
|
1092 |
-
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
|
1093 |
-
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
|
1094 |
-
"dev": true
|
1095 |
-
},
|
1096 |
-
"builtin-modules": {
|
1097 |
-
"version": "1.1.1",
|
1098 |
-
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
1099 |
-
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
|
1100 |
-
"dev": true
|
1101 |
-
},
|
1102 |
-
"builtin-status-codes": {
|
1103 |
-
"version": "3.0.0",
|
1104 |
-
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
|
1105 |
-
"integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
|
1106 |
-
"dev": true
|
1107 |
-
},
|
1108 |
-
"caller-path": {
|
1109 |
-
"version": "0.1.0",
|
1110 |
-
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
|
1111 |
-
"integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
|
1112 |
-
"dev": true,
|
1113 |
-
"requires": {
|
1114 |
-
"callsites": "^0.2.0"
|
1115 |
-
}
|
1116 |
-
},
|
1117 |
-
"callsites": {
|
1118 |
-
"version": "0.2.0",
|
1119 |
-
"resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
|
1120 |
-
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
|
1121 |
-
"dev": true
|
1122 |
-
},
|
1123 |
-
"camelcase": {
|
1124 |
-
"version": "2.1.1",
|
1125 |
-
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
|
1126 |
-
"integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
|
1127 |
-
"dev": true
|
1128 |
-
},
|
1129 |
-
"camelcase-keys": {
|
1130 |
-
"version": "2.1.0",
|
1131 |
-
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
|
1132 |
-
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
|
1133 |
-
"dev": true,
|
1134 |
-
"requires": {
|
1135 |
-
"camelcase": "^2.0.0",
|
1136 |
-
"map-obj": "^1.0.0"
|
1137 |
-
}
|
1138 |
-
},
|
1139 |
-
"caniuse-api": {
|
1140 |
-
"version": "1.6.1",
|
1141 |
-
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
|
1142 |
-
"integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
|
1143 |
-
"dev": true,
|
1144 |
-
"requires": {
|
1145 |
-
"browserslist": "^1.3.6",
|
1146 |
-
"caniuse-db": "^1.0.30000529",
|
1147 |
-
"lodash.memoize": "^4.1.2",
|
1148 |
-
"lodash.uniq": "^4.5.0"
|
1149 |
-
},
|
1150 |
-
"dependencies": {
|
1151 |
-
"browserslist": {
|
1152 |
-
"version": "1.7.7",
|
1153 |
-
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
|
1154 |
-
"integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
|
1155 |
-
"dev": true,
|
1156 |
-
"requires": {
|
1157 |
-
"caniuse-db": "^1.0.30000639",
|
1158 |
-
"electron-to-chromium": "^1.2.7"
|
1159 |
-
}
|
1160 |
-
}
|
1161 |
-
}
|
1162 |
-
},
|
1163 |
-
"caniuse-db": {
|
1164 |
-
"version": "1.0.30000770",
|
1165 |
-
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000770.tgz",
|
1166 |
-
"integrity": "sha1-z2iuHLioL208Nd9Bxi3Glz5HAkQ=",
|
1167 |
-
"dev": true
|
1168 |
-
},
|
1169 |
-
"caniuse-lite": {
|
1170 |
-
"version": "1.0.30000770",
|
1171 |
-
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000770.tgz",
|
1172 |
-
"integrity": "sha1-vI5/ULBzJzOQ22qzVzeJCaFOm9s=",
|
1173 |
-
"dev": true
|
1174 |
-
},
|
1175 |
-
"caseless": {
|
1176 |
-
"version": "0.11.0",
|
1177 |
-
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
|
1178 |
-
"integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
|
1179 |
-
"dev": true
|
1180 |
-
},
|
1181 |
-
"center-align": {
|
1182 |
-
"version": "0.1.3",
|
1183 |
-
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
|
1184 |
-
"integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
|
1185 |
-
"dev": true,
|
1186 |
-
"requires": {
|
1187 |
-
"align-text": "^0.1.3",
|
1188 |
-
"lazy-cache": "^1.0.3"
|
1189 |
-
},
|
1190 |
-
"dependencies": {
|
1191 |
-
"lazy-cache": {
|
1192 |
-
"version": "1.0.4",
|
1193 |
-
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
|
1194 |
-
"integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
|
1195 |
-
"dev": true
|
1196 |
-
}
|
1197 |
-
}
|
1198 |
-
},
|
1199 |
-
"chalk": {
|
1200 |
-
"version": "1.1.3",
|
1201 |
-
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
1202 |
-
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
1203 |
-
"dev": true,
|
1204 |
-
"requires": {
|
1205 |
-
"ansi-styles": "^2.2.1",
|
1206 |
-
"escape-string-regexp": "^1.0.2",
|
1207 |
-
"has-ansi": "^2.0.0",
|
1208 |
-
"strip-ansi": "^3.0.0",
|
1209 |
-
"supports-color": "^2.0.0"
|
1210 |
-
}
|
1211 |
-
},
|
1212 |
-
"chokidar": {
|
1213 |
-
"version": "1.7.0",
|
1214 |
-
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
|
1215 |
-
"integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
|
1216 |
-
"dev": true,
|
1217 |
-
"requires": {
|
1218 |
-
"anymatch": "^1.3.0",
|
1219 |
-
"async-each": "^1.0.0",
|
1220 |
-
"fsevents": "^1.0.0",
|
1221 |
-
"glob-parent": "^2.0.0",
|
1222 |
-
"inherits": "^2.0.1",
|
1223 |
-
"is-binary-path": "^1.0.0",
|
1224 |
-
"is-glob": "^2.0.0",
|
1225 |
-
"path-is-absolute": "^1.0.0",
|
1226 |
-
"readdirp": "^2.0.0"
|
1227 |
-
}
|
1228 |
-
},
|
1229 |
-
"cipher-base": {
|
1230 |
-
"version": "1.0.4",
|
1231 |
-
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
1232 |
-
"integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
|
1233 |
-
"dev": true,
|
1234 |
-
"requires": {
|
1235 |
-
"inherits": "^2.0.1",
|
1236 |
-
"safe-buffer": "^5.0.1"
|
1237 |
-
}
|
1238 |
-
},
|
1239 |
-
"circular-json": {
|
1240 |
-
"version": "0.3.3",
|
1241 |
-
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
|
1242 |
-
"integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
|
1243 |
-
"dev": true
|
1244 |
-
},
|
1245 |
-
"clap": {
|
1246 |
-
"version": "1.2.3",
|
1247 |
-
"resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
|
1248 |
-
"integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
|
1249 |
-
"dev": true,
|
1250 |
-
"requires": {
|
1251 |
-
"chalk": "^1.1.3"
|
1252 |
-
}
|
1253 |
-
},
|
1254 |
-
"cli-cursor": {
|
1255 |
-
"version": "1.0.2",
|
1256 |
-
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
|
1257 |
-
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
|
1258 |
-
"dev": true,
|
1259 |
-
"requires": {
|
1260 |
-
"restore-cursor": "^1.0.1"
|
1261 |
-
}
|
1262 |
-
},
|
1263 |
-
"cli-width": {
|
1264 |
-
"version": "2.2.0",
|
1265 |
-
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
|
1266 |
-
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
|
1267 |
-
"dev": true
|
1268 |
-
},
|
1269 |
-
"cliui": {
|
1270 |
-
"version": "3.2.0",
|
1271 |
-
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
|
1272 |
-
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
|
1273 |
-
"dev": true,
|
1274 |
-
"requires": {
|
1275 |
-
"string-width": "^1.0.1",
|
1276 |
-
"strip-ansi": "^3.0.1",
|
1277 |
-
"wrap-ansi": "^2.0.0"
|
1278 |
-
}
|
1279 |
-
},
|
1280 |
-
"clone": {
|
1281 |
-
"version": "1.0.3",
|
1282 |
-
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
|
1283 |
-
"integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
|
1284 |
-
"dev": true
|
1285 |
-
},
|
1286 |
-
"clone-deep": {
|
1287 |
-
"version": "0.3.0",
|
1288 |
-
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.3.0.tgz",
|
1289 |
-
"integrity": "sha1-NIxhrpzb4O3+BT2R/0zFIdeQ7eg=",
|
1290 |
-
"dev": true,
|
1291 |
-
"requires": {
|
1292 |
-
"for-own": "^1.0.0",
|
1293 |
-
"is-plain-object": "^2.0.1",
|
1294 |
-
"kind-of": "^3.2.2",
|
1295 |
-
"shallow-clone": "^0.1.2"
|
1296 |
-
}
|
1297 |
-
},
|
1298 |
-
"co": {
|
1299 |
-
"version": "4.6.0",
|
1300 |
-
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
1301 |
-
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
|
1302 |
-
"dev": true
|
1303 |
-
},
|
1304 |
-
"coa": {
|
1305 |
-
"version": "1.0.4",
|
1306 |
-
"resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
|
1307 |
-
"integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
|
1308 |
-
"dev": true,
|
1309 |
-
"requires": {
|
1310 |
-
"q": "^1.1.2"
|
1311 |
-
}
|
1312 |
-
},
|
1313 |
-
"code-point-at": {
|
1314 |
-
"version": "1.1.0",
|
1315 |
-
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
1316 |
-
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
1317 |
-
"dev": true
|
1318 |
-
},
|
1319 |
-
"color": {
|
1320 |
-
"version": "0.11.4",
|
1321 |
-
"resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
|
1322 |
-
"integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
|
1323 |
-
"dev": true,
|
1324 |
-
"requires": {
|
1325 |
-
"clone": "^1.0.2",
|
1326 |
-
"color-convert": "^1.3.0",
|
1327 |
-
"color-string": "^0.3.0"
|
1328 |
-
}
|
1329 |
-
},
|
1330 |
-
"color-convert": {
|
1331 |
-
"version": "1.9.1",
|
1332 |
-
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
|
1333 |
-
"integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
|
1334 |
-
"dev": true,
|
1335 |
-
"requires": {
|
1336 |
-
"color-name": "^1.1.1"
|
1337 |
-
}
|
1338 |
-
},
|
1339 |
-
"color-name": {
|
1340 |
-
"version": "1.1.3",
|
1341 |
-
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
1342 |
-
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
1343 |
-
"dev": true
|
1344 |
-
},
|
1345 |
-
"color-string": {
|
1346 |
-
"version": "0.3.0",
|
1347 |
-
"resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
|
1348 |
-
"integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
|
1349 |
-
"dev": true,
|
1350 |
-
"requires": {
|
1351 |
-
"color-name": "^1.0.0"
|
1352 |
-
}
|
1353 |
-
},
|
1354 |
-
"colormin": {
|
1355 |
-
"version": "1.1.2",
|
1356 |
-
"resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
|
1357 |
-
"integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
|
1358 |
-
"dev": true,
|
1359 |
-
"requires": {
|
1360 |
-
"color": "^0.11.0",
|
1361 |
-
"css-color-names": "0.0.4",
|
1362 |
-
"has": "^1.0.1"
|
1363 |
-
}
|
1364 |
-
},
|
1365 |
-
"colors": {
|
1366 |
-
"version": "1.1.2",
|
1367 |
-
"resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
|
1368 |
-
"integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
|
1369 |
-
"dev": true
|
1370 |
-
},
|
1371 |
-
"combined-stream": {
|
1372 |
-
"version": "1.0.5",
|
1373 |
-
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
|
1374 |
-
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
|
1375 |
-
"dev": true,
|
1376 |
-
"requires": {
|
1377 |
-
"delayed-stream": "~1.0.0"
|
1378 |
-
}
|
1379 |
-
},
|
1380 |
-
"commander": {
|
1381 |
-
"version": "2.12.1",
|
1382 |
-
"resolved": "https://registry.npmjs.org/commander/-/commander-2.12.1.tgz",
|
1383 |
-
"integrity": "sha512-PCNLExLlI5HiPdaJs4pMXwOTHkSCpNQ1QJH9ykZLKtKEyKu3p9HgmH5l97vM8c0IUz6d54l+xEu2GG9yuYrFzA==",
|
1384 |
-
"dev": true
|
1385 |
-
},
|
1386 |
-
"commondir": {
|
1387 |
-
"version": "1.0.1",
|
1388 |
-
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
1389 |
-
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
|
1390 |
-
"dev": true
|
1391 |
-
},
|
1392 |
-
"concat-map": {
|
1393 |
-
"version": "0.0.1",
|
1394 |
-
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
1395 |
-
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
1396 |
-
"dev": true
|
1397 |
-
},
|
1398 |
-
"concat-stream": {
|
1399 |
-
"version": "1.6.0",
|
1400 |
-
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
|
1401 |
-
"integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
|
1402 |
-
"dev": true,
|
1403 |
-
"requires": {
|
1404 |
-
"inherits": "^2.0.3",
|
1405 |
-
"readable-stream": "^2.2.2",
|
1406 |
-
"typedarray": "^0.0.6"
|
1407 |
-
}
|
1408 |
-
},
|
1409 |
-
"console-browserify": {
|
1410 |
-
"version": "1.1.0",
|
1411 |
-
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
|
1412 |
-
"integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
|
1413 |
-
"dev": true,
|
1414 |
-
"requires": {
|
1415 |
-
"date-now": "^0.1.4"
|
1416 |
-
}
|
1417 |
-
},
|
1418 |
-
"console-control-strings": {
|
1419 |
-
"version": "1.1.0",
|
1420 |
-
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
1421 |
-
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
1422 |
-
"dev": true
|
1423 |
-
},
|
1424 |
-
"constants-browserify": {
|
1425 |
-
"version": "1.0.0",
|
1426 |
-
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
|
1427 |
-
"integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
|
1428 |
-
"dev": true
|
1429 |
-
},
|
1430 |
-
"convert-source-map": {
|
1431 |
-
"version": "1.5.1",
|
1432 |
-
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
|
1433 |
-
"integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
|
1434 |
-
"dev": true
|
1435 |
-
},
|
1436 |
-
"core-js": {
|
1437 |
-
"version": "2.5.1",
|
1438 |
-
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
|
1439 |
-
"integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=",
|
1440 |
-
"dev": true
|
1441 |
-
},
|
1442 |
-
"core-util-is": {
|
1443 |
-
"version": "1.0.2",
|
1444 |
-
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
1445 |
-
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
1446 |
-
"dev": true
|
1447 |
-
},
|
1448 |
-
"create-ecdh": {
|
1449 |
-
"version": "4.0.0",
|
1450 |
-
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
|
1451 |
-
"integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
|
1452 |
-
"dev": true,
|
1453 |
-
"requires": {
|
1454 |
-
"bn.js": "^4.1.0",
|
1455 |
-
"elliptic": "^6.0.0"
|
1456 |
-
}
|
1457 |
-
},
|
1458 |
-
"create-hash": {
|
1459 |
-
"version": "1.1.3",
|
1460 |
-
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
|
1461 |
-
"integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
|
1462 |
-
"dev": true,
|
1463 |
-
"requires": {
|
1464 |
-
"cipher-base": "^1.0.1",
|
1465 |
-
"inherits": "^2.0.1",
|
1466 |
-
"ripemd160": "^2.0.0",
|
1467 |
-
"sha.js": "^2.4.0"
|
1468 |
-
}
|
1469 |
-
},
|
1470 |
-
"create-hmac": {
|
1471 |
-
"version": "1.1.6",
|
1472 |
-
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
|
1473 |
-
"integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
|
1474 |
-
"dev": true,
|
1475 |
-
"requires": {
|
1476 |
-
"cipher-base": "^1.0.3",
|
1477 |
-
"create-hash": "^1.1.0",
|
1478 |
-
"inherits": "^2.0.1",
|
1479 |
-
"ripemd160": "^2.0.0",
|
1480 |
-
"safe-buffer": "^5.0.1",
|
1481 |
-
"sha.js": "^2.4.8"
|
1482 |
-
}
|
1483 |
-
},
|
1484 |
-
"cross-spawn": {
|
1485 |
-
"version": "3.0.1",
|
1486 |
-
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
|
1487 |
-
"integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
|
1488 |
-
"dev": true,
|
1489 |
-
"requires": {
|
1490 |
-
"lru-cache": "^4.0.1",
|
1491 |
-
"which": "^1.2.9"
|
1492 |
-
}
|
1493 |
-
},
|
1494 |
-
"cryptiles": {
|
1495 |
-
"version": "2.0.5",
|
1496 |
-
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
|
1497 |
-
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
|
1498 |
-
"dev": true,
|
1499 |
-
"requires": {
|
1500 |
-
"boom": "2.x.x"
|
1501 |
-
}
|
1502 |
-
},
|
1503 |
-
"crypto-browserify": {
|
1504 |
-
"version": "3.12.0",
|
1505 |
-
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
|
1506 |
-
"integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
|
1507 |
-
"dev": true,
|
1508 |
-
"requires": {
|
1509 |
-
"browserify-cipher": "^1.0.0",
|
1510 |
-
"browserify-sign": "^4.0.0",
|
1511 |
-
"create-ecdh": "^4.0.0",
|
1512 |
-
"create-hash": "^1.1.0",
|
1513 |
-
"create-hmac": "^1.1.0",
|
1514 |
-
"diffie-hellman": "^5.0.0",
|
1515 |
-
"inherits": "^2.0.1",
|
1516 |
-
"pbkdf2": "^3.0.3",
|
1517 |
-
"public-encrypt": "^4.0.0",
|
1518 |
-
"randombytes": "^2.0.0",
|
1519 |
-
"randomfill": "^1.0.3"
|
1520 |
-
}
|
1521 |
-
},
|
1522 |
-
"css-color-names": {
|
1523 |
-
"version": "0.0.4",
|
1524 |
-
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
|
1525 |
-
"integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
|
1526 |
-
"dev": true
|
1527 |
-
},
|
1528 |
-
"css-loader": {
|
1529 |
-
"version": "0.28.7",
|
1530 |
-
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.7.tgz",
|
1531 |
-
"integrity": "sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==",
|
1532 |
-
"dev": true,
|
1533 |
-
"requires": {
|
1534 |
-
"babel-code-frame": "^6.11.0",
|
1535 |
-
"css-selector-tokenizer": "^0.7.0",
|
1536 |
-
"cssnano": ">=2.6.1 <4",
|
1537 |
-
"icss-utils": "^2.1.0",
|
1538 |
-
"loader-utils": "^1.0.2",
|
1539 |
-
"lodash.camelcase": "^4.3.0",
|
1540 |
-
"object-assign": "^4.0.1",
|
1541 |
-
"postcss": "^5.0.6",
|
1542 |
-
"postcss-modules-extract-imports": "^1.0.0",
|
1543 |
-
"postcss-modules-local-by-default": "^1.0.1",
|
1544 |
-
"postcss-modules-scope": "^1.0.0",
|
1545 |
-
"postcss-modules-values": "^1.1.0",
|
1546 |
-
"postcss-value-parser": "^3.3.0",
|
1547 |
-
"source-list-map": "^2.0.0"
|
1548 |
-
}
|
1549 |
-
},
|
1550 |
-
"css-selector-tokenizer": {
|
1551 |
-
"version": "0.7.0",
|
1552 |
-
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
|
1553 |
-
"integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
|
1554 |
-
"dev": true,
|
1555 |
-
"requires": {
|
1556 |
-
"cssesc": "^0.1.0",
|
1557 |
-
"fastparse": "^1.1.1",
|
1558 |
-
"regexpu-core": "^1.0.0"
|
1559 |
-
},
|
1560 |
-
"dependencies": {
|
1561 |
-
"regexpu-core": {
|
1562 |
-
"version": "1.0.0",
|
1563 |
-
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
|
1564 |
-
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
|
1565 |
-
"dev": true,
|
1566 |
-
"requires": {
|
1567 |
-
"regenerate": "^1.2.1",
|
1568 |
-
"regjsgen": "^0.2.0",
|
1569 |
-
"regjsparser": "^0.1.4"
|
1570 |
-
}
|
1571 |
-
}
|
1572 |
-
}
|
1573 |
-
},
|
1574 |
-
"cssesc": {
|
1575 |
-
"version": "0.1.0",
|
1576 |
-
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
|
1577 |
-
"integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
|
1578 |
-
"dev": true
|
1579 |
-
},
|
1580 |
-
"cssnano": {
|
1581 |
-
"version": "3.10.0",
|
1582 |
-
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
|
1583 |
-
"integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
|
1584 |
-
"dev": true,
|
1585 |
-
"requires": {
|
1586 |
-
"autoprefixer": "^6.3.1",
|
1587 |
-
"decamelize": "^1.1.2",
|
1588 |
-
"defined": "^1.0.0",
|
1589 |
-
"has": "^1.0.1",
|
1590 |
-
"object-assign": "^4.0.1",
|
1591 |
-
"postcss": "^5.0.14",
|
1592 |
-
"postcss-calc": "^5.2.0",
|
1593 |
-
"postcss-colormin": "^2.1.8",
|
1594 |
-
"postcss-convert-values": "^2.3.4",
|
1595 |
-
"postcss-discard-comments": "^2.0.4",
|
1596 |
-
"postcss-discard-duplicates": "^2.0.1",
|
1597 |
-
"postcss-discard-empty": "^2.0.1",
|
1598 |
-
"postcss-discard-overridden": "^0.1.1",
|
1599 |
-
"postcss-discard-unused": "^2.2.1",
|
1600 |
-
"postcss-filter-plugins": "^2.0.0",
|
1601 |
-
"postcss-merge-idents": "^2.1.5",
|
1602 |
-
"postcss-merge-longhand": "^2.0.1",
|
1603 |
-
"postcss-merge-rules": "^2.0.3",
|
1604 |
-
"postcss-minify-font-values": "^1.0.2",
|
1605 |
-
"postcss-minify-gradients": "^1.0.1",
|
1606 |
-
"postcss-minify-params": "^1.0.4",
|
1607 |
-
"postcss-minify-selectors": "^2.0.4",
|
1608 |
-
"postcss-normalize-charset": "^1.1.0",
|
1609 |
-
"postcss-normalize-url": "^3.0.7",
|
1610 |
-
"postcss-ordered-values": "^2.1.0",
|
1611 |
-
"postcss-reduce-idents": "^2.2.2",
|
1612 |
-
"postcss-reduce-initial": "^1.0.0",
|
1613 |
-
"postcss-reduce-transforms": "^1.0.3",
|
1614 |
-
"postcss-svgo": "^2.1.1",
|
1615 |
-
"postcss-unique-selectors": "^2.0.2",
|
1616 |
-
"postcss-value-parser": "^3.2.3",
|
1617 |
-
"postcss-zindex": "^2.0.1"
|
1618 |
-
}
|
1619 |
-
},
|
1620 |
-
"csso": {
|
1621 |
-
"version": "2.3.2",
|
1622 |
-
"resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
|
1623 |
-
"integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
|
1624 |
-
"dev": true,
|
1625 |
-
"requires": {
|
1626 |
-
"clap": "^1.0.9",
|
1627 |
-
"source-map": "^0.5.3"
|
1628 |
-
}
|
1629 |
-
},
|
1630 |
-
"currently-unhandled": {
|
1631 |
-
"version": "0.4.1",
|
1632 |
-
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
1633 |
-
"integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
|
1634 |
-
"dev": true,
|
1635 |
-
"requires": {
|
1636 |
-
"array-find-index": "^1.0.1"
|
1637 |
-
}
|
1638 |
-
},
|
1639 |
-
"d": {
|
1640 |
-
"version": "1.0.0",
|
1641 |
-
"resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
|
1642 |
-
"integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
|
1643 |
-
"dev": true,
|
1644 |
-
"requires": {
|
1645 |
-
"es5-ext": "^0.10.9"
|
1646 |
-
}
|
1647 |
-
},
|
1648 |
-
"dashdash": {
|
1649 |
-
"version": "1.14.1",
|
1650 |
-
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
1651 |
-
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
1652 |
-
"dev": true,
|
1653 |
-
"requires": {
|
1654 |
-
"assert-plus": "^1.0.0"
|
1655 |
-
},
|
1656 |
-
"dependencies": {
|
1657 |
-
"assert-plus": {
|
1658 |
-
"version": "1.0.0",
|
1659 |
-
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
1660 |
-
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
1661 |
-
"dev": true
|
1662 |
-
}
|
1663 |
-
}
|
1664 |
-
},
|
1665 |
-
"date-now": {
|
1666 |
-
"version": "0.1.4",
|
1667 |
-
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
|
1668 |
-
"integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
|
1669 |
-
"dev": true
|
1670 |
-
},
|
1671 |
-
"debug": {
|
1672 |
-
"version": "2.6.9",
|
1673 |
-
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
1674 |
-
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
1675 |
-
"dev": true,
|
1676 |
-
"requires": {
|
1677 |
-
"ms": "2.0.0"
|
1678 |
-
}
|
1679 |
-
},
|
1680 |
-
"decamelize": {
|
1681 |
-
"version": "1.2.0",
|
1682 |
-
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
1683 |
-
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
1684 |
-
"dev": true
|
1685 |
-
},
|
1686 |
-
"deep-is": {
|
1687 |
-
"version": "0.1.3",
|
1688 |
-
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
|
1689 |
-
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
|
1690 |
-
"dev": true
|
1691 |
-
},
|
1692 |
-
"defined": {
|
1693 |
-
"version": "1.0.0",
|
1694 |
-
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
|
1695 |
-
"integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
|
1696 |
-
"dev": true
|
1697 |
-
},
|
1698 |
-
"del": {
|
1699 |
-
"version": "2.2.2",
|
1700 |
-
"resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
|
1701 |
-
"integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
|
1702 |
-
"dev": true,
|
1703 |
-
"requires": {
|
1704 |
-
"globby": "^5.0.0",
|
1705 |
-
"is-path-cwd": "^1.0.0",
|
1706 |
-
"is-path-in-cwd": "^1.0.0",
|
1707 |
-
"object-assign": "^4.0.1",
|
1708 |
-
"pify": "^2.0.0",
|
1709 |
-
"pinkie-promise": "^2.0.0",
|
1710 |
-
"rimraf": "^2.2.8"
|
1711 |
-
},
|
1712 |
-
"dependencies": {
|
1713 |
-
"pify": {
|
1714 |
-
"version": "2.3.0",
|
1715 |
-
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
1716 |
-
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
1717 |
-
"dev": true
|
1718 |
-
}
|
1719 |
-
}
|
1720 |
-
},
|
1721 |
-
"delayed-stream": {
|
1722 |
-
"version": "1.0.0",
|
1723 |
-
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
1724 |
-
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
1725 |
-
"dev": true
|
1726 |
-
},
|
1727 |
-
"delegates": {
|
1728 |
-
"version": "1.0.0",
|
1729 |
-
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
1730 |
-
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
1731 |
-
"dev": true
|
1732 |
-
},
|
1733 |
-
"des.js": {
|
1734 |
-
"version": "1.0.0",
|
1735 |
-
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
|
1736 |
-
"integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
|
1737 |
-
"dev": true,
|
1738 |
-
"requires": {
|
1739 |
-
"inherits": "^2.0.1",
|
1740 |
-
"minimalistic-assert": "^1.0.0"
|
1741 |
-
}
|
1742 |
-
},
|
1743 |
-
"detect-indent": {
|
1744 |
-
"version": "4.0.0",
|
1745 |
-
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
|
1746 |
-
"integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
|
1747 |
-
"dev": true,
|
1748 |
-
"requires": {
|
1749 |
-
"repeating": "^2.0.0"
|
1750 |
-
}
|
1751 |
-
},
|
1752 |
-
"diffie-hellman": {
|
1753 |
-
"version": "5.0.2",
|
1754 |
-
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
|
1755 |
-
"integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
|
1756 |
-
"dev": true,
|
1757 |
-
"requires": {
|
1758 |
-
"bn.js": "^4.1.0",
|
1759 |
-
"miller-rabin": "^4.0.0",
|
1760 |
-
"randombytes": "^2.0.0"
|
1761 |
-
}
|
1762 |
-
},
|
1763 |
-
"doctrine": {
|
1764 |
-
"version": "2.0.0",
|
1765 |
-
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
|
1766 |
-
"integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=",
|
1767 |
-
"dev": true,
|
1768 |
-
"requires": {
|
1769 |
-
"esutils": "^2.0.2",
|
1770 |
-
"isarray": "^1.0.0"
|
1771 |
-
}
|
1772 |
-
},
|
1773 |
-
"domain-browser": {
|
1774 |
-
"version": "1.1.7",
|
1775 |
-
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
|
1776 |
-
"integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=",
|
1777 |
-
"dev": true
|
1778 |
-
},
|
1779 |
-
"ecc-jsbn": {
|
1780 |
-
"version": "0.1.1",
|
1781 |
-
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
|
1782 |
-
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
|
1783 |
-
"dev": true,
|
1784 |
-
"optional": true,
|
1785 |
-
"requires": {
|
1786 |
-
"jsbn": "~0.1.0"
|
1787 |
-
}
|
1788 |
-
},
|
1789 |
-
"electron-to-chromium": {
|
1790 |
-
"version": "1.3.27",
|
1791 |
-
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz",
|
1792 |
-
"integrity": "sha1-eOy4o5kGYYe7N07t412ccFZagD0=",
|
1793 |
-
"dev": true
|
1794 |
-
},
|
1795 |
-
"elliptic": {
|
1796 |
-
"version": "6.4.0",
|
1797 |
-
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
|
1798 |
-
"integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
|
1799 |
-
"dev": true,
|
1800 |
-
"requires": {
|
1801 |
-
"bn.js": "^4.4.0",
|
1802 |
-
"brorand": "^1.0.1",
|
1803 |
-
"hash.js": "^1.0.0",
|
1804 |
-
"hmac-drbg": "^1.0.0",
|
1805 |
-
"inherits": "^2.0.1",
|
1806 |
-
"minimalistic-assert": "^1.0.0",
|
1807 |
-
"minimalistic-crypto-utils": "^1.0.0"
|
1808 |
-
}
|
1809 |
-
},
|
1810 |
-
"emojis-list": {
|
1811 |
-
"version": "2.1.0",
|
1812 |
-
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
|
1813 |
-
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
|
1814 |
-
"dev": true
|
1815 |
-
},
|
1816 |
-
"enhanced-resolve": {
|
1817 |
-
"version": "3.4.1",
|
1818 |
-
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
|
1819 |
-
"integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
|
1820 |
-
"dev": true,
|
1821 |
-
"requires": {
|
1822 |
-
"graceful-fs": "^4.1.2",
|
1823 |
-
"memory-fs": "^0.4.0",
|
1824 |
-
"object-assign": "^4.0.1",
|
1825 |
-
"tapable": "^0.2.7"
|
1826 |
-
}
|
1827 |
-
},
|
1828 |
-
"errno": {
|
1829 |
-
"version": "0.1.4",
|
1830 |
-
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz",
|
1831 |
-
"integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=",
|
1832 |
-
"dev": true,
|
1833 |
-
"requires": {
|
1834 |
-
"prr": "~0.0.0"
|
1835 |
-
}
|
1836 |
-
},
|
1837 |
-
"error-ex": {
|
1838 |
-
"version": "1.3.1",
|
1839 |
-
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
|
1840 |
-
"integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
|
1841 |
-
"dev": true,
|
1842 |
-
"requires": {
|
1843 |
-
"is-arrayish": "^0.2.1"
|
1844 |
-
}
|
1845 |
-
},
|
1846 |
-
"es5-ext": {
|
1847 |
-
"version": "0.10.37",
|
1848 |
-
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz",
|
1849 |
-
"integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=",
|
1850 |
-
"dev": true,
|
1851 |
-
"requires": {
|
1852 |
-
"es6-iterator": "~2.0.1",
|
1853 |
-
"es6-symbol": "~3.1.1"
|
1854 |
-
}
|
1855 |
-
},
|
1856 |
-
"es6-iterator": {
|
1857 |
-
"version": "2.0.3",
|
1858 |
-
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
|
1859 |
-
"integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
|
1860 |
-
"dev": true,
|
1861 |
-
"requires": {
|
1862 |
-
"d": "1",
|
1863 |
-
"es5-ext": "^0.10.35",
|
1864 |
-
"es6-symbol": "^3.1.1"
|
1865 |
-
}
|
1866 |
-
},
|
1867 |
-
"es6-map": {
|
1868 |
-
"version": "0.1.5",
|
1869 |
-
"resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
|
1870 |
-
"integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
|
1871 |
-
"dev": true,
|
1872 |
-
"requires": {
|
1873 |
-
"d": "1",
|
1874 |
-
"es5-ext": "~0.10.14",
|
1875 |
-
"es6-iterator": "~2.0.1",
|
1876 |
-
"es6-set": "~0.1.5",
|
1877 |
-
"es6-symbol": "~3.1.1",
|
1878 |
-
"event-emitter": "~0.3.5"
|
1879 |
-
}
|
1880 |
-
},
|
1881 |
-
"es6-set": {
|
1882 |
-
"version": "0.1.5",
|
1883 |
-
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
|
1884 |
-
"integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
|
1885 |
-
"dev": true,
|
1886 |
-
"requires": {
|
1887 |
-
"d": "1",
|
1888 |
-
"es5-ext": "~0.10.14",
|
1889 |
-
"es6-iterator": "~2.0.1",
|
1890 |
-
"es6-symbol": "3.1.1",
|
1891 |
-
"event-emitter": "~0.3.5"
|
1892 |
-
}
|
1893 |
-
},
|
1894 |
-
"es6-symbol": {
|
1895 |
-
"version": "3.1.1",
|
1896 |
-
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
|
1897 |
-
"integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
|
1898 |
-
"dev": true,
|
1899 |
-
"requires": {
|
1900 |
-
"d": "1",
|
1901 |
-
"es5-ext": "~0.10.14"
|
1902 |
-
}
|
1903 |
-
},
|
1904 |
-
"es6-weak-map": {
|
1905 |
-
"version": "2.0.2",
|
1906 |
-
"resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
|
1907 |
-
"integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
|
1908 |
-
"dev": true,
|
1909 |
-
"requires": {
|
1910 |
-
"d": "1",
|
1911 |
-
"es5-ext": "^0.10.14",
|
1912 |
-
"es6-iterator": "^2.0.1",
|
1913 |
-
"es6-symbol": "^3.1.1"
|
1914 |
-
}
|
1915 |
-
},
|
1916 |
-
"escape-string-regexp": {
|
1917 |
-
"version": "1.0.5",
|
1918 |
-
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
1919 |
-
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
1920 |
-
"dev": true
|
1921 |
-
},
|
1922 |
-
"escope": {
|
1923 |
-
"version": "3.6.0",
|
1924 |
-
"resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
|
1925 |
-
"integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
|
1926 |
-
"dev": true,
|
1927 |
-
"requires": {
|
1928 |
-
"es6-map": "^0.1.3",
|
1929 |
-
"es6-weak-map": "^2.0.1",
|
1930 |
-
"esrecurse": "^4.1.0",
|
1931 |
-
"estraverse": "^4.1.1"
|
1932 |
-
}
|
1933 |
-
},
|
1934 |
-
"eslint": {
|
1935 |
-
"version": "3.19.0",
|
1936 |
-
"resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz",
|
1937 |
-
"integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=",
|
1938 |
-
"dev": true,
|
1939 |
-
"requires": {
|
1940 |
-
"babel-code-frame": "^6.16.0",
|
1941 |
-
"chalk": "^1.1.3",
|
1942 |
-
"concat-stream": "^1.5.2",
|
1943 |
-
"debug": "^2.1.1",
|
1944 |
-
"doctrine": "^2.0.0",
|
1945 |
-
"escope": "^3.6.0",
|
1946 |
-
"espree": "^3.4.0",
|
1947 |
-
"esquery": "^1.0.0",
|
1948 |
-
"estraverse": "^4.2.0",
|
1949 |
-
"esutils": "^2.0.2",
|
1950 |
-
"file-entry-cache": "^2.0.0",
|
1951 |
-
"glob": "^7.0.3",
|
1952 |
-
"globals": "^9.14.0",
|
1953 |
-
"ignore": "^3.2.0",
|
1954 |
-
"imurmurhash": "^0.1.4",
|
1955 |
-
"inquirer": "^0.12.0",
|
1956 |
-
"is-my-json-valid": "^2.10.0",
|
1957 |
-
"is-resolvable": "^1.0.0",
|
1958 |
-
"js-yaml": "^3.5.1",
|
1959 |
-
"json-stable-stringify": "^1.0.0",
|
1960 |
-
"levn": "^0.3.0",
|
1961 |
-
"lodash": "^4.0.0",
|
1962 |
-
"mkdirp": "^0.5.0",
|
1963 |
-
"natural-compare": "^1.4.0",
|
1964 |
-
"optionator": "^0.8.2",
|
1965 |
-
"path-is-inside": "^1.0.1",
|
1966 |
-
"pluralize": "^1.2.1",
|
1967 |
-
"progress": "^1.1.8",
|
1968 |
-
"require-uncached": "^1.0.2",
|
1969 |
-
"shelljs": "^0.7.5",
|
1970 |
-
"strip-bom": "^3.0.0",
|
1971 |
-
"strip-json-comments": "~2.0.1",
|
1972 |
-
"table": "^3.7.8",
|
1973 |
-
"text-table": "~0.2.0",
|
1974 |
-
"user-home": "^2.0.0"
|
1975 |
-
}
|
1976 |
-
},
|
1977 |
-
"espree": {
|
1978 |
-
"version": "3.5.2",
|
1979 |
-
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
|
1980 |
-
"integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
|
1981 |
-
"dev": true,
|
1982 |
-
"requires": {
|
1983 |
-
"acorn": "^5.2.1",
|
1984 |
-
"acorn-jsx": "^3.0.0"
|
1985 |
-
}
|
1986 |
-
},
|
1987 |
-
"esprima": {
|
1988 |
-
"version": "2.7.3",
|
1989 |
-
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
|
1990 |
-
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
|
1991 |
-
"dev": true
|
1992 |
-
},
|
1993 |
-
"esquery": {
|
1994 |
-
"version": "1.0.0",
|
1995 |
-
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
|
1996 |
-
"integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
|
1997 |
-
"dev": true,
|
1998 |
-
"requires": {
|
1999 |
-
"estraverse": "^4.0.0"
|
2000 |
-
}
|
2001 |
-
},
|
2002 |
-
"esrecurse": {
|
2003 |
-
"version": "4.2.0",
|
2004 |
-
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
|
2005 |
-
"integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
|
2006 |
-
"dev": true,
|
2007 |
-
"requires": {
|
2008 |
-
"estraverse": "^4.1.0",
|
2009 |
-
"object-assign": "^4.0.1"
|
2010 |
-
}
|
2011 |
-
},
|
2012 |
-
"estraverse": {
|
2013 |
-
"version": "4.2.0",
|
2014 |
-
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
|
2015 |
-
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
|
2016 |
-
"dev": true
|
2017 |
-
},
|
2018 |
-
"esutils": {
|
2019 |
-
"version": "2.0.2",
|
2020 |
-
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
2021 |
-
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
2022 |
-
"dev": true
|
2023 |
-
},
|
2024 |
-
"event-emitter": {
|
2025 |
-
"version": "0.3.5",
|
2026 |
-
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
|
2027 |
-
"integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
|
2028 |
-
"dev": true,
|
2029 |
-
"requires": {
|
2030 |
-
"d": "1",
|
2031 |
-
"es5-ext": "~0.10.14"
|
2032 |
-
}
|
2033 |
-
},
|
2034 |
-
"events": {
|
2035 |
-
"version": "1.1.1",
|
2036 |
-
"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
|
2037 |
-
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
|
2038 |
-
"dev": true
|
2039 |
-
},
|
2040 |
-
"evp_bytestokey": {
|
2041 |
-
"version": "1.0.3",
|
2042 |
-
"resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
|
2043 |
-
"integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
|
2044 |
-
"dev": true,
|
2045 |
-
"requires": {
|
2046 |
-
"md5.js": "^1.3.4",
|
2047 |
-
"safe-buffer": "^5.1.1"
|
2048 |
-
}
|
2049 |
-
},
|
2050 |
-
"exit-hook": {
|
2051 |
-
"version": "1.1.1",
|
2052 |
-
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
|
2053 |
-
"integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
|
2054 |
-
"dev": true
|
2055 |
-
},
|
2056 |
-
"expand-brackets": {
|
2057 |
-
"version": "0.1.5",
|
2058 |
-
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
|
2059 |
-
"integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
|
2060 |
-
"dev": true,
|
2061 |
-
"requires": {
|
2062 |
-
"is-posix-bracket": "^0.1.0"
|
2063 |
-
}
|
2064 |
-
},
|
2065 |
-
"expand-range": {
|
2066 |
-
"version": "1.8.2",
|
2067 |
-
"resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
|
2068 |
-
"integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
|
2069 |
-
"dev": true,
|
2070 |
-
"requires": {
|
2071 |
-
"fill-range": "^2.1.0"
|
2072 |
-
}
|
2073 |
-
},
|
2074 |
-
"extend": {
|
2075 |
-
"version": "3.0.1",
|
2076 |
-
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
2077 |
-
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
|
2078 |
-
"dev": true
|
2079 |
-
},
|
2080 |
-
"extglob": {
|
2081 |
-
"version": "0.3.2",
|
2082 |
-
"resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
|
2083 |
-
"integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
|
2084 |
-
"dev": true,
|
2085 |
-
"requires": {
|
2086 |
-
"is-extglob": "^1.0.0"
|
2087 |
-
}
|
2088 |
-
},
|
2089 |
-
"extract-text-webpack-plugin": {
|
2090 |
-
"version": "2.1.2",
|
2091 |
-
"resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.2.tgz",
|
2092 |
-
"integrity": "sha1-dW7076gVXDaBgz+8NNpTuUF0bWw=",
|
2093 |
-
"dev": true,
|
2094 |
-
"requires": {
|
2095 |
-
"async": "^2.1.2",
|
2096 |
-
"loader-utils": "^1.0.2",
|
2097 |
-
"schema-utils": "^0.3.0",
|
2098 |
-
"webpack-sources": "^1.0.1"
|
2099 |
-
}
|
2100 |
-
},
|
2101 |
-
"extsprintf": {
|
2102 |
-
"version": "1.3.0",
|
2103 |
-
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
2104 |
-
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
2105 |
-
"dev": true
|
2106 |
-
},
|
2107 |
-
"fast-deep-equal": {
|
2108 |
-
"version": "1.0.0",
|
2109 |
-
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
|
2110 |
-
"integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
|
2111 |
-
"dev": true
|
2112 |
-
},
|
2113 |
-
"fast-json-stable-stringify": {
|
2114 |
-
"version": "2.0.0",
|
2115 |
-
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
2116 |
-
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
|
2117 |
-
"dev": true
|
2118 |
-
},
|
2119 |
-
"fast-levenshtein": {
|
2120 |
-
"version": "2.0.6",
|
2121 |
-
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
2122 |
-
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
2123 |
-
"dev": true
|
2124 |
-
},
|
2125 |
-
"fastparse": {
|
2126 |
-
"version": "1.1.1",
|
2127 |
-
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
|
2128 |
-
"integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
|
2129 |
-
"dev": true
|
2130 |
-
},
|
2131 |
-
"figures": {
|
2132 |
-
"version": "1.7.0",
|
2133 |
-
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
|
2134 |
-
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
|
2135 |
-
"dev": true,
|
2136 |
-
"requires": {
|
2137 |
-
"escape-string-regexp": "^1.0.5",
|
2138 |
-
"object-assign": "^4.1.0"
|
2139 |
-
}
|
2140 |
-
},
|
2141 |
-
"file-entry-cache": {
|
2142 |
-
"version": "2.0.0",
|
2143 |
-
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
|
2144 |
-
"integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
|
2145 |
-
"dev": true,
|
2146 |
-
"requires": {
|
2147 |
-
"flat-cache": "^1.2.1",
|
2148 |
-
"object-assign": "^4.0.1"
|
2149 |
-
}
|
2150 |
-
},
|
2151 |
-
"filename-regex": {
|
2152 |
-
"version": "2.0.1",
|
2153 |
-
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
|
2154 |
-
"integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
|
2155 |
-
"dev": true
|
2156 |
-
},
|
2157 |
-
"fill-range": {
|
2158 |
-
"version": "2.2.3",
|
2159 |
-
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
|
2160 |
-
"integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
|
2161 |
-
"dev": true,
|
2162 |
-
"requires": {
|
2163 |
-
"is-number": "^2.1.0",
|
2164 |
-
"isobject": "^2.0.0",
|
2165 |
-
"randomatic": "^1.1.3",
|
2166 |
-
"repeat-element": "^1.1.2",
|
2167 |
-
"repeat-string": "^1.5.2"
|
2168 |
-
},
|
2169 |
-
"dependencies": {
|
2170 |
-
"isobject": {
|
2171 |
-
"version": "2.1.0",
|
2172 |
-
"resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
|
2173 |
-
"integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
|
2174 |
-
"dev": true,
|
2175 |
-
"requires": {
|
2176 |
-
"isarray": "1.0.0"
|
2177 |
-
}
|
2178 |
-
}
|
2179 |
-
}
|
2180 |
-
},
|
2181 |
-
"find-cache-dir": {
|
2182 |
-
"version": "1.0.0",
|
2183 |
-
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
|
2184 |
-
"integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
|
2185 |
-
"dev": true,
|
2186 |
-
"requires": {
|
2187 |
-
"commondir": "^1.0.1",
|
2188 |
-
"make-dir": "^1.0.0",
|
2189 |
-
"pkg-dir": "^2.0.0"
|
2190 |
-
}
|
2191 |
-
},
|
2192 |
-
"find-up": {
|
2193 |
-
"version": "2.1.0",
|
2194 |
-
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
|
2195 |
-
"integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
|
2196 |
-
"dev": true,
|
2197 |
-
"requires": {
|
2198 |
-
"locate-path": "^2.0.0"
|
2199 |
-
}
|
2200 |
-
},
|
2201 |
-
"flat-cache": {
|
2202 |
-
"version": "1.3.0",
|
2203 |
-
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
|
2204 |
-
"integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
|
2205 |
-
"dev": true,
|
2206 |
-
"requires": {
|
2207 |
-
"circular-json": "^0.3.1",
|
2208 |
-
"del": "^2.0.2",
|
2209 |
-
"graceful-fs": "^4.1.2",
|
2210 |
-
"write": "^0.2.1"
|
2211 |
-
}
|
2212 |
-
},
|
2213 |
-
"flatten": {
|
2214 |
-
"version": "1.0.2",
|
2215 |
-
"resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
|
2216 |
-
"integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
|
2217 |
-
"dev": true
|
2218 |
-
},
|
2219 |
-
"for-in": {
|
2220 |
-
"version": "1.0.2",
|
2221 |
-
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
2222 |
-
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
|
2223 |
-
"dev": true
|
2224 |
-
},
|
2225 |
-
"for-own": {
|
2226 |
-
"version": "1.0.0",
|
2227 |
-
"resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
|
2228 |
-
"integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
|
2229 |
-
"dev": true,
|
2230 |
-
"requires": {
|
2231 |
-
"for-in": "^1.0.1"
|
2232 |
-
}
|
2233 |
-
},
|
2234 |
-
"forever-agent": {
|
2235 |
-
"version": "0.6.1",
|
2236 |
-
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
2237 |
-
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
2238 |
-
"dev": true
|
2239 |
-
},
|
2240 |
-
"form-data": {
|
2241 |
-
"version": "2.1.4",
|
2242 |
-
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
|
2243 |
-
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
|
2244 |
-
"dev": true,
|
2245 |
-
"requires": {
|
2246 |
-
"asynckit": "^0.4.0",
|
2247 |
-
"combined-stream": "^1.0.5",
|
2248 |
-
"mime-types": "^2.1.12"
|
2249 |
-
}
|
2250 |
-
},
|
2251 |
-
"fs.realpath": {
|
2252 |
-
"version": "1.0.0",
|
2253 |
-
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
2254 |
-
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
2255 |
-
"dev": true
|
2256 |
-
},
|
2257 |
-
"fsevents": {
|
2258 |
-
"version": "1.1.3",
|
2259 |
-
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
|
2260 |
-
"integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
|
2261 |
-
"dev": true,
|
2262 |
-
"optional": true,
|
2263 |
-
"requires": {
|
2264 |
-
"nan": "^2.3.0",
|
2265 |
-
"node-pre-gyp": "^0.6.39"
|
2266 |
-
},
|
2267 |
-
"dependencies": {
|
2268 |
-
"abbrev": {
|
2269 |
-
"version": "1.1.0",
|
2270 |
-
"bundled": true,
|
2271 |
-
"dev": true,
|
2272 |
-
"optional": true
|
2273 |
-
},
|
2274 |
-
"ajv": {
|
2275 |
-
"version": "4.11.8",
|
2276 |
-
"bundled": true,
|
2277 |
-
"dev": true,
|
2278 |
-
"optional": true,
|
2279 |
-
"requires": {
|
2280 |
-
"co": "^4.6.0",
|
2281 |
-
"json-stable-stringify": "^1.0.1"
|
2282 |
-
}
|
2283 |
-
},
|
2284 |
-
"ansi-regex": {
|
2285 |
-
"version": "2.1.1",
|
2286 |
-
"bundled": true,
|
2287 |
-
"dev": true
|
2288 |
-
},
|
2289 |
-
"aproba": {
|
2290 |
-
"version": "1.1.1",
|
2291 |
-
"bundled": true,
|
2292 |
-
"dev": true,
|
2293 |
-
"optional": true
|
2294 |
-
},
|
2295 |
-
"are-we-there-yet": {
|
2296 |
-
"version": "1.1.4",
|
2297 |
-
"bundled": true,
|
2298 |
-
"dev": true,
|
2299 |
-
"optional": true,
|
2300 |
-
"requires": {
|
2301 |
-
"delegates": "^1.0.0",
|
2302 |
-
"readable-stream": "^2.0.6"
|
2303 |
-
}
|
2304 |
-
},
|
2305 |
-
"asn1": {
|
2306 |
-
"version": "0.2.3",
|
2307 |
-
"bundled": true,
|
2308 |
-
"dev": true,
|
2309 |
-
"optional": true
|
2310 |
-
},
|
2311 |
-
"assert-plus": {
|
2312 |
-
"version": "0.2.0",
|
2313 |
-
"bundled": true,
|
2314 |
-
"dev": true,
|
2315 |
-
"optional": true
|
2316 |
-
},
|
2317 |
-
"asynckit": {
|
2318 |
-
"version": "0.4.0",
|
2319 |
-
"bundled": true,
|
2320 |
-
"dev": true,
|
2321 |
-
"optional": true
|
2322 |
-
},
|
2323 |
-
"aws-sign2": {
|
2324 |
-
"version": "0.6.0",
|
2325 |
-
"bundled": true,
|
2326 |
-
"dev": true,
|
2327 |
-
"optional": true
|
2328 |
-
},
|
2329 |
-
"aws4": {
|
2330 |
-
"version": "1.6.0",
|
2331 |
-
"bundled": true,
|
2332 |
-
"dev": true,
|
2333 |
-
"optional": true
|
2334 |
-
},
|
2335 |
-
"balanced-match": {
|
2336 |
-
"version": "0.4.2",
|
2337 |
-
"bundled": true,
|
2338 |
-
"dev": true
|
2339 |
-
},
|
2340 |
-
"bcrypt-pbkdf": {
|
2341 |
-
"version": "1.0.1",
|
2342 |
-
"bundled": true,
|
2343 |
-
"dev": true,
|
2344 |
-
"optional": true,
|
2345 |
-
"requires": {
|
2346 |
-
"tweetnacl": "^0.14.3"
|
2347 |
-
}
|
2348 |
-
},
|
2349 |
-
"block-stream": {
|
2350 |
-
"version": "0.0.9",
|
2351 |
-
"bundled": true,
|
2352 |
-
"dev": true,
|
2353 |
-
"requires": {
|
2354 |
-
"inherits": "~2.0.0"
|
2355 |
-
}
|
2356 |
-
},
|
2357 |
-
"boom": {
|
2358 |
-
"version": "2.10.1",
|
2359 |
-
"bundled": true,
|
2360 |
-
"dev": true,
|
2361 |
-
"requires": {
|
2362 |
-
"hoek": "2.x.x"
|
2363 |
-
}
|
2364 |
-
},
|
2365 |
-
"brace-expansion": {
|
2366 |
-
"version": "1.1.7",
|
2367 |
-
"bundled": true,
|
2368 |
-
"dev": true,
|
2369 |
-
"requires": {
|
2370 |
-
"balanced-match": "^0.4.1",
|
2371 |
-
"concat-map": "0.0.1"
|
2372 |
-
}
|
2373 |
-
},
|
2374 |
-
"buffer-shims": {
|
2375 |
-
"version": "1.0.0",
|
2376 |
-
"bundled": true,
|
2377 |
-
"dev": true
|
2378 |
-
},
|
2379 |
-
"caseless": {
|
2380 |
-
"version": "0.12.0",
|
2381 |
-
"bundled": true,
|
2382 |
-
"dev": true,
|
2383 |
-
"optional": true
|
2384 |
-
},
|
2385 |
-
"co": {
|
2386 |
-
"version": "4.6.0",
|
2387 |
-
"bundled": true,
|
2388 |
-
"dev": true,
|
2389 |
-
"optional": true
|
2390 |
-
},
|
2391 |
-
"code-point-at": {
|
2392 |
-
"version": "1.1.0",
|
2393 |
-
"bundled": true,
|
2394 |
-
"dev": true
|
2395 |
-
},
|
2396 |
-
"combined-stream": {
|
2397 |
-
"version": "1.0.5",
|
2398 |
-
"bundled": true,
|
2399 |
-
"dev": true,
|
2400 |
-
"requires": {
|
2401 |
-
"delayed-stream": "~1.0.0"
|
2402 |
-
}
|
2403 |
-
},
|
2404 |
-
"concat-map": {
|
2405 |
-
"version": "0.0.1",
|
2406 |
-
"bundled": true,
|
2407 |
-
"dev": true
|
2408 |
-
},
|
2409 |
-
"console-control-strings": {
|
2410 |
-
"version": "1.1.0",
|
2411 |
-
"bundled": true,
|
2412 |
-
"dev": true
|
2413 |
-
},
|
2414 |
-
"core-util-is": {
|
2415 |
-
"version": "1.0.2",
|
2416 |
-
"bundled": true,
|
2417 |
-
"dev": true
|
2418 |
-
},
|
2419 |
-
"cryptiles": {
|
2420 |
-
"version": "2.0.5",
|
2421 |
-
"bundled": true,
|
2422 |
-
"dev": true,
|
2423 |
-
"requires": {
|
2424 |
-
"boom": "2.x.x"
|
2425 |
-
}
|
2426 |
-
},
|
2427 |
-
"dashdash": {
|
2428 |
-
"version": "1.14.1",
|
2429 |
-
"bundled": true,
|
2430 |
-
"dev": true,
|
2431 |
-
"optional": true,
|
2432 |
-
"requires": {
|
2433 |
-
"assert-plus": "^1.0.0"
|
2434 |
-
},
|
2435 |
-
"dependencies": {
|
2436 |
-
"assert-plus": {
|
2437 |
-
"version": "1.0.0",
|
2438 |
-
"bundled": true,
|
2439 |
-
"dev": true,
|
2440 |
-
"optional": true
|
2441 |
-
}
|
2442 |
-
}
|
2443 |
-
},
|
2444 |
-
"debug": {
|
2445 |
-
"version": "2.6.8",
|
2446 |
-
"bundled": true,
|
2447 |
-
"dev": true,
|
2448 |
-
"optional": true,
|
2449 |
-
"requires": {
|
2450 |
-
"ms": "2.0.0"
|
2451 |
-
}
|
2452 |
-
},
|
2453 |
-
"deep-extend": {
|
2454 |
-
"version": "0.4.2",
|
2455 |
-
"bundled": true,
|
2456 |
-
"dev": true,
|
2457 |
-
"optional": true
|
2458 |
-
},
|
2459 |
-
"delayed-stream": {
|
2460 |
-
"version": "1.0.0",
|
2461 |
-
"bundled": true,
|
2462 |
-
"dev": true
|
2463 |
-
},
|
2464 |
-
"delegates": {
|
2465 |
-
"version": "1.0.0",
|
2466 |
-
"bundled": true,
|
2467 |
-
"dev": true,
|
2468 |
-
"optional": true
|
2469 |
-
},
|
2470 |
-
"detect-libc": {
|
2471 |
-
"version": "1.0.2",
|
2472 |
-
"bundled": true,
|
2473 |
-
"dev": true,
|
2474 |
-
"optional": true
|
2475 |
-
},
|
2476 |
-
"ecc-jsbn": {
|
2477 |
-
"version": "0.1.1",
|
2478 |
-
"bundled": true,
|
2479 |
-
"dev": true,
|
2480 |
-
"optional": true,
|
2481 |
-
"requires": {
|
2482 |
-
"jsbn": "~0.1.0"
|
2483 |
-
}
|
2484 |
-
},
|
2485 |
-
"extend": {
|
2486 |
-
"version": "3.0.1",
|
2487 |
-
"bundled": true,
|
2488 |
-
"dev": true,
|
2489 |
-
"optional": true
|
2490 |
-
},
|
2491 |
-
"extsprintf": {
|
2492 |
-
"version": "1.0.2",
|
2493 |
-
"bundled": true,
|
2494 |
-
"dev": true
|
2495 |
-
},
|
2496 |
-
"forever-agent": {
|
2497 |
-
"version": "0.6.1",
|
2498 |
-
"bundled": true,
|
2499 |
-
"dev": true,
|
2500 |
-
"optional": true
|
2501 |
-
},
|
2502 |
-
"form-data": {
|
2503 |
-
"version": "2.1.4",
|
2504 |
-
"bundled": true,
|
2505 |
-
"dev": true,
|
2506 |
-
"optional": true,
|
2507 |
-
"requires": {
|
2508 |
-
"asynckit": "^0.4.0",
|
2509 |
-
"combined-stream": "^1.0.5",
|
2510 |
-
"mime-types": "^2.1.12"
|
2511 |
-
}
|
2512 |
-
},
|
2513 |
-
"fs.realpath": {
|
2514 |
-
"version": "1.0.0",
|
2515 |
-
"bundled": true,
|
2516 |
-
"dev": true
|
2517 |
-
},
|
2518 |
-
"fstream": {
|
2519 |
-
"version": "1.0.11",
|
2520 |
-
"bundled": true,
|
2521 |
-
"dev": true,
|
2522 |
-
"requires": {
|
2523 |
-
"graceful-fs": "^4.1.2",
|
2524 |
-
"inherits": "~2.0.0",
|
2525 |
-
"mkdirp": ">=0.5 0",
|
2526 |
-
"rimraf": "2"
|
2527 |
-
}
|
2528 |
-
},
|
2529 |
-
"fstream-ignore": {
|
2530 |
-
"version": "1.0.5",
|
2531 |
-
"bundled": true,
|
2532 |
-
"dev": true,
|
2533 |
-
"optional": true,
|
2534 |
-
"requires": {
|
2535 |
-
"fstream": "^1.0.0",
|
2536 |
-
"inherits": "2",
|
2537 |
-
"minimatch": "^3.0.0"
|
2538 |
-
}
|
2539 |
-
},
|
2540 |
-
"gauge": {
|
2541 |
-
"version": "2.7.4",
|
2542 |
-
"bundled": true,
|
2543 |
-
"dev": true,
|
2544 |
-
"optional": true,
|
2545 |
-
"requires": {
|
2546 |
-
"aproba": "^1.0.3",
|
2547 |
-
"console-control-strings": "^1.0.0",
|
2548 |
-
"has-unicode": "^2.0.0",
|
2549 |
-
"object-assign": "^4.1.0",
|
2550 |
-
"signal-exit": "^3.0.0",
|
2551 |
-
"string-width": "^1.0.1",
|
2552 |
-
"strip-ansi": "^3.0.1",
|
2553 |
-
"wide-align": "^1.1.0"
|
2554 |
-
}
|
2555 |
-
},
|
2556 |
-
"getpass": {
|
2557 |
-
"version": "0.1.7",
|
2558 |
-
"bundled": true,
|
2559 |
-
"dev": true,
|
2560 |
-
"optional": true,
|
2561 |
-
"requires": {
|
2562 |
-
"assert-plus": "^1.0.0"
|
2563 |
-
},
|
2564 |
-
"dependencies": {
|
2565 |
-
"assert-plus": {
|
2566 |
-
"version": "1.0.0",
|
2567 |
-
"bundled": true,
|
2568 |
-
"dev": true,
|
2569 |
-
"optional": true
|
2570 |
-
}
|
2571 |
-
}
|
2572 |
-
},
|
2573 |
-
"glob": {
|
2574 |
-
"version": "7.1.2",
|
2575 |
-
"bundled": true,
|
2576 |
-
"dev": true,
|
2577 |
-
"requires": {
|
2578 |
-
"fs.realpath": "^1.0.0",
|
2579 |
-
"inflight": "^1.0.4",
|
2580 |
-
"inherits": "2",
|
2581 |
-
"minimatch": "^3.0.4",
|
2582 |
-
"once": "^1.3.0",
|
2583 |
-
"path-is-absolute": "^1.0.0"
|
2584 |
-
}
|
2585 |
-
},
|
2586 |
-
"graceful-fs": {
|
2587 |
-
"version": "4.1.11",
|
2588 |
-
"bundled": true,
|
2589 |
-
"dev": true
|
2590 |
-
},
|
2591 |
-
"har-schema": {
|
2592 |
-
"version": "1.0.5",
|
2593 |
-
"bundled": true,
|
2594 |
-
"dev": true,
|
2595 |
-
"optional": true
|
2596 |
-
},
|
2597 |
-
"har-validator": {
|
2598 |
-
"version": "4.2.1",
|
2599 |
-
"bundled": true,
|
2600 |
-
"dev": true,
|
2601 |
-
"optional": true,
|
2602 |
-
"requires": {
|
2603 |
-
"ajv": "^4.9.1",
|
2604 |
-
"har-schema": "^1.0.5"
|
2605 |
-
}
|
2606 |
-
},
|
2607 |
-
"has-unicode": {
|
2608 |
-
"version": "2.0.1",
|
2609 |
-
"bundled": true,
|
2610 |
-
"dev": true,
|
2611 |
-
"optional": true
|
2612 |
-
},
|
2613 |
-
"hawk": {
|
2614 |
-
"version": "3.1.3",
|
2615 |
-
"bundled": true,
|
2616 |
-
"dev": true,
|
2617 |
-
"requires": {
|
2618 |
-
"boom": "2.x.x",
|
2619 |
-
"cryptiles": "2.x.x",
|
2620 |
-
"hoek": "2.x.x",
|
2621 |
-
"sntp": "1.x.x"
|
2622 |
-
}
|
2623 |
-
},
|
2624 |
-
"hoek": {
|
2625 |
-
"version": "2.16.3",
|
2626 |
-
"bundled": true,
|
2627 |
-
"dev": true
|
2628 |
-
},
|
2629 |
-
"http-signature": {
|
2630 |
-
"version": "1.1.1",
|
2631 |
-
"bundled": true,
|
2632 |
-
"dev": true,
|
2633 |
-
"optional": true,
|
2634 |
-
"requires": {
|
2635 |
-
"assert-plus": "^0.2.0",
|
2636 |
-
"jsprim": "^1.2.2",
|
2637 |
-
"sshpk": "^1.7.0"
|
2638 |
-
}
|
2639 |
-
},
|
2640 |
-
"inflight": {
|
2641 |
-
"version": "1.0.6",
|
2642 |
-
"bundled": true,
|
2643 |
-
"dev": true,
|
2644 |
-
"requires": {
|
2645 |
-
"once": "^1.3.0",
|
2646 |
-
"wrappy": "1"
|
2647 |
-
}
|
2648 |
-
},
|
2649 |
-
"inherits": {
|
2650 |
-
"version": "2.0.3",
|
2651 |
-
"bundled": true,
|
2652 |
-
"dev": true
|
2653 |
-
},
|
2654 |
-
"ini": {
|
2655 |
-
"version": "1.3.4",
|
2656 |
-
"bundled": true,
|
2657 |
-
"dev": true,
|
2658 |
-
"optional": true
|
2659 |
-
},
|
2660 |
-
"is-fullwidth-code-point": {
|
2661 |
-
"version": "1.0.0",
|
2662 |
-
"bundled": true,
|
2663 |
-
"dev": true,
|
2664 |
-
"requires": {
|
2665 |
-
"number-is-nan": "^1.0.0"
|
2666 |
-
}
|
2667 |
-
},
|
2668 |
-
"is-typedarray": {
|
2669 |
-
"version": "1.0.0",
|
2670 |
-
"bundled": true,
|
2671 |
-
"dev": true,
|
2672 |
-
"optional": true
|
2673 |
-
},
|
2674 |
-
"isarray": {
|
2675 |
-
"version": "1.0.0",
|
2676 |
-
"bundled": true,
|
2677 |
-
"dev": true
|
2678 |
-
},
|
2679 |
-
"isstream": {
|
2680 |
-
"version": "0.1.2",
|
2681 |
-
"bundled": true,
|
2682 |
-
"dev": true,
|
2683 |
-
"optional": true
|
2684 |
-
},
|
2685 |
-
"jodid25519": {
|
2686 |
-
"version": "1.0.2",
|
2687 |
-
"bundled": true,
|
2688 |
-
"dev": true,
|
2689 |
-
"optional": true,
|
2690 |
-
"requires": {
|
2691 |
-
"jsbn": "~0.1.0"
|
2692 |
-
}
|
2693 |
-
},
|
2694 |
-
"jsbn": {
|
2695 |
-
"version": "0.1.1",
|
2696 |
-
"bundled": true,
|
2697 |
-
"dev": true,
|
2698 |
-
"optional": true
|
2699 |
-
},
|
2700 |
-
"json-schema": {
|
2701 |
-
"version": "0.2.3",
|
2702 |
-
"bundled": true,
|
2703 |
-
"dev": true,
|
2704 |
-
"optional": true
|
2705 |
-
},
|
2706 |
-
"json-stable-stringify": {
|
2707 |
-
"version": "1.0.1",
|
2708 |
-
"bundled": true,
|
2709 |
-
"dev": true,
|
2710 |
-
"optional": true,
|
2711 |
-
"requires": {
|
2712 |
-
"jsonify": "~0.0.0"
|
2713 |
-
}
|
2714 |
-
},
|
2715 |
-
"json-stringify-safe": {
|
2716 |
-
"version": "5.0.1",
|
2717 |
-
"bundled": true,
|
2718 |
-
"dev": true,
|
2719 |
-
"optional": true
|
2720 |
-
},
|
2721 |
-
"jsonify": {
|
2722 |
-
"version": "0.0.0",
|
2723 |
-
"bundled": true,
|
2724 |
-
"dev": true,
|
2725 |
-
"optional": true
|
2726 |
-
},
|
2727 |
-
"jsprim": {
|
2728 |
-
"version": "1.4.0",
|
2729 |
-
"bundled": true,
|
2730 |
-
"dev": true,
|
2731 |
-
"optional": true,
|
2732 |
-
"requires": {
|
2733 |
-
"assert-plus": "1.0.0",
|
2734 |
-
"extsprintf": "1.0.2",
|
2735 |
-
"json-schema": "0.2.3",
|
2736 |
-
"verror": "1.3.6"
|
2737 |
-
},
|
2738 |
-
"dependencies": {
|
2739 |
-
"assert-plus": {
|
2740 |
-
"version": "1.0.0",
|
2741 |
-
"bundled": true,
|
2742 |
-
"dev": true,
|
2743 |
-
"optional": true
|
2744 |
-
}
|
2745 |
-
}
|
2746 |
-
},
|
2747 |
-
"mime-db": {
|
2748 |
-
"version": "1.27.0",
|
2749 |
-
"bundled": true,
|
2750 |
-
"dev": true
|
2751 |
-
},
|
2752 |
-
"mime-types": {
|
2753 |
-
"version": "2.1.15",
|
2754 |
-
"bundled": true,
|
2755 |
-
"dev": true,
|
2756 |
-
"requires": {
|
2757 |
-
"mime-db": "~1.27.0"
|
2758 |
-
}
|
2759 |
-
},
|
2760 |
-
"minimatch": {
|
2761 |
-
"version": "3.0.4",
|
2762 |
-
"bundled": true,
|
2763 |
-
"dev": true,
|
2764 |
-
"requires": {
|
2765 |
-
"brace-expansion": "^1.1.7"
|
2766 |
-
}
|
2767 |
-
},
|
2768 |
-
"minimist": {
|
2769 |
-
"version": "0.0.8",
|
2770 |
-
"bundled": true,
|
2771 |
-
"dev": true
|
2772 |
-
},
|
2773 |
-
"mkdirp": {
|
2774 |
-
"version": "0.5.1",
|
2775 |
-
"bundled": true,
|
2776 |
-
"dev": true,
|
2777 |
-
"requires": {
|
2778 |
-
"minimist": "0.0.8"
|
2779 |
-
}
|
2780 |
-
},
|
2781 |
-
"ms": {
|
2782 |
-
"version": "2.0.0",
|
2783 |
-
"bundled": true,
|
2784 |
-
"dev": true,
|
2785 |
-
"optional": true
|
2786 |
-
},
|
2787 |
-
"node-pre-gyp": {
|
2788 |
-
"version": "0.6.39",
|
2789 |
-
"bundled": true,
|
2790 |
-
"dev": true,
|
2791 |
-
"optional": true,
|
2792 |
-
"requires": {
|
2793 |
-
"detect-libc": "^1.0.2",
|
2794 |
-
"hawk": "3.1.3",
|
2795 |
-
"mkdirp": "^0.5.1",
|
2796 |
-
"nopt": "^4.0.1",
|
2797 |
-
"npmlog": "^4.0.2",
|
2798 |
-
"rc": "^1.1.7",
|
2799 |
-
"request": "2.81.0",
|
2800 |
-
"rimraf": "^2.6.1",
|
2801 |
-
"semver": "^5.3.0",
|
2802 |
-
"tar": "^2.2.1",
|
2803 |
-
"tar-pack": "^3.4.0"
|
2804 |
-
}
|
2805 |
-
},
|
2806 |
-
"nopt": {
|
2807 |
-
"version": "4.0.1",
|
2808 |
-
"bundled": true,
|
2809 |
-
"dev": true,
|
2810 |
-
"optional": true,
|
2811 |
-
"requires": {
|
2812 |
-
"abbrev": "1",
|
2813 |
-
"osenv": "^0.1.4"
|
2814 |
-
}
|
2815 |
-
},
|
2816 |
-
"npmlog": {
|
2817 |
-
"version": "4.1.0",
|
2818 |
-
"bundled": true,
|
2819 |
-
"dev": true,
|
2820 |
-
"optional": true,
|
2821 |
-
"requires": {
|
2822 |
-
"are-we-there-yet": "~1.1.2",
|
2823 |
-
"console-control-strings": "~1.1.0",
|
2824 |
-
"gauge": "~2.7.3",
|
2825 |
-
"set-blocking": "~2.0.0"
|
2826 |
-
}
|
2827 |
-
},
|
2828 |
-
"number-is-nan": {
|
2829 |
-
"version": "1.0.1",
|
2830 |
-
"bundled": true,
|
2831 |
-
"dev": true
|
2832 |
-
},
|
2833 |
-
"oauth-sign": {
|
2834 |
-
"version": "0.8.2",
|
2835 |
-
"bundled": true,
|
2836 |
-
"dev": true,
|
2837 |
-
"optional": true
|
2838 |
-
},
|
2839 |
-
"object-assign": {
|
2840 |
-
"version": "4.1.1",
|
2841 |
-
"bundled": true,
|
2842 |
-
"dev": true,
|
2843 |
-
"optional": true
|
2844 |
-
},
|
2845 |
-
"once": {
|
2846 |
-
"version": "1.4.0",
|
2847 |
-
"bundled": true,
|
2848 |
-
"dev": true,
|
2849 |
-
"requires": {
|
2850 |
-
"wrappy": "1"
|
2851 |
-
}
|
2852 |
-
},
|
2853 |
-
"os-homedir": {
|
2854 |
-
"version": "1.0.2",
|
2855 |
-
"bundled": true,
|
2856 |
-
"dev": true,
|
2857 |
-
"optional": true
|
2858 |
-
},
|
2859 |
-
"os-tmpdir": {
|
2860 |
-
"version": "1.0.2",
|
2861 |
-
"bundled": true,
|
2862 |
-
"dev": true,
|
2863 |
-
"optional": true
|
2864 |
-
},
|
2865 |
-
"osenv": {
|
2866 |
-
"version": "0.1.4",
|
2867 |
-
"bundled": true,
|
2868 |
-
"dev": true,
|
2869 |
-
"optional": true,
|
2870 |
-
"requires": {
|
2871 |
-
"os-homedir": "^1.0.0",
|
2872 |
-
"os-tmpdir": "^1.0.0"
|
2873 |
-
}
|
2874 |
-
},
|
2875 |
-
"path-is-absolute": {
|
2876 |
-
"version": "1.0.1",
|
2877 |
-
"bundled": true,
|
2878 |
-
"dev": true
|
2879 |
-
},
|
2880 |
-
"performance-now": {
|
2881 |
-
"version": "0.2.0",
|
2882 |
-
"bundled": true,
|
2883 |
-
"dev": true,
|
2884 |
-
"optional": true
|
2885 |
-
},
|
2886 |
-
"process-nextick-args": {
|
2887 |
-
"version": "1.0.7",
|
2888 |
-
"bundled": true,
|
2889 |
-
"dev": true
|
2890 |
-
},
|
2891 |
-
"punycode": {
|
2892 |
-
"version": "1.4.1",
|
2893 |
-
"bundled": true,
|
2894 |
-
"dev": true,
|
2895 |
-
"optional": true
|
2896 |
-
},
|
2897 |
-
"qs": {
|
2898 |
-
"version": "6.4.0",
|
2899 |
-
"bundled": true,
|
2900 |
-
"dev": true,
|
2901 |
-
"optional": true
|
2902 |
-
},
|
2903 |
-
"rc": {
|
2904 |
-
"version": "1.2.1",
|
2905 |
-
"bundled": true,
|
2906 |
-
"dev": true,
|
2907 |
-
"optional": true,
|
2908 |
-
"requires": {
|
2909 |
-
"deep-extend": "~0.4.0",
|
2910 |
-
"ini": "~1.3.0",
|
2911 |
-
"minimist": "^1.2.0",
|
2912 |
-
"strip-json-comments": "~2.0.1"
|
2913 |
-
},
|
2914 |
-
"dependencies": {
|
2915 |
-
"minimist": {
|
2916 |
-
"version": "1.2.0",
|
2917 |
-
"bundled": true,
|
2918 |
-
"dev": true,
|
2919 |
-
"optional": true
|
2920 |
-
}
|
2921 |
-
}
|
2922 |
-
},
|
2923 |
-
"readable-stream": {
|
2924 |
-
"version": "2.2.9",
|
2925 |
-
"bundled": true,
|
2926 |
-
"dev": true,
|
2927 |
-
"requires": {
|
2928 |
-
"buffer-shims": "~1.0.0",
|
2929 |
-
"core-util-is": "~1.0.0",
|
2930 |
-
"inherits": "~2.0.1",
|
2931 |
-
"isarray": "~1.0.0",
|
2932 |
-
"process-nextick-args": "~1.0.6",
|
2933 |
-
"string_decoder": "~1.0.0",
|
2934 |
-
"util-deprecate": "~1.0.1"
|
2935 |
-
}
|
2936 |
-
},
|
2937 |
-
"request": {
|
2938 |
-
"version": "2.81.0",
|
2939 |
-
"bundled": true,
|
2940 |
-
"dev": true,
|
2941 |
-
"optional": true,
|
2942 |
-
"requires": {
|
2943 |
-
"aws-sign2": "~0.6.0",
|
2944 |
-
"aws4": "^1.2.1",
|
2945 |
-
"caseless": "~0.12.0",
|
2946 |
-
"combined-stream": "~1.0.5",
|
2947 |
-
"extend": "~3.0.0",
|
2948 |
-
"forever-agent": "~0.6.1",
|
2949 |
-
"form-data": "~2.1.1",
|
2950 |
-
"har-validator": "~4.2.1",
|
2951 |
-
"hawk": "~3.1.3",
|
2952 |
-
"http-signature": "~1.1.0",
|
2953 |
-
"is-typedarray": "~1.0.0",
|
2954 |
-
"isstream": "~0.1.2",
|
2955 |
-
"json-stringify-safe": "~5.0.1",
|
2956 |
-
"mime-types": "~2.1.7",
|
2957 |
-
"oauth-sign": "~0.8.1",
|
2958 |
-
"performance-now": "^0.2.0",
|
2959 |
-
"qs": "~6.4.0",
|
2960 |
-
"safe-buffer": "^5.0.1",
|
2961 |
-
"stringstream": "~0.0.4",
|
2962 |
-
"tough-cookie": "~2.3.0",
|
2963 |
-
"tunnel-agent": "^0.6.0",
|
2964 |
-
"uuid": "^3.0.0"
|
2965 |
-
}
|
2966 |
-
},
|
2967 |
-
"rimraf": {
|
2968 |
-
"version": "2.6.1",
|
2969 |
-
"bundled": true,
|
2970 |
-
"dev": true,
|
2971 |
-
"requires": {
|
2972 |
-
"glob": "^7.0.5"
|
2973 |
-
}
|
2974 |
-
},
|
2975 |
-
"safe-buffer": {
|
2976 |
-
"version": "5.0.1",
|
2977 |
-
"bundled": true,
|
2978 |
-
"dev": true
|
2979 |
-
},
|
2980 |
-
"semver": {
|
2981 |
-
"version": "5.3.0",
|
2982 |
-
"bundled": true,
|
2983 |
-
"dev": true,
|
2984 |
-
"optional": true
|
2985 |
-
},
|
2986 |
-
"set-blocking": {
|
2987 |
-
"version": "2.0.0",
|
2988 |
-
"bundled": true,
|
2989 |
-
"dev": true,
|
2990 |
-
"optional": true
|
2991 |
-
},
|
2992 |
-
"signal-exit": {
|
2993 |
-
"version": "3.0.2",
|
2994 |
-
"bundled": true,
|
2995 |
-
"dev": true,
|
2996 |
-
"optional": true
|
2997 |
-
},
|
2998 |
-
"sntp": {
|
2999 |
-
"version": "1.0.9",
|
3000 |
-
"bundled": true,
|
3001 |
-
"dev": true,
|
3002 |
-
"requires": {
|
3003 |
-
"hoek": "2.x.x"
|
3004 |
-
}
|
3005 |
-
},
|
3006 |
-
"sshpk": {
|
3007 |
-
"version": "1.13.0",
|
3008 |
-
"bundled": true,
|
3009 |
-
"dev": true,
|
3010 |
-
"optional": true,
|
3011 |
-
"requires": {
|
3012 |
-
"asn1": "~0.2.3",
|
3013 |
-
"assert-plus": "^1.0.0",
|
3014 |
-
"bcrypt-pbkdf": "^1.0.0",
|
3015 |
-
"dashdash": "^1.12.0",
|
3016 |
-
"ecc-jsbn": "~0.1.1",
|
3017 |
-
"getpass": "^0.1.1",
|
3018 |
-
"jodid25519": "^1.0.0",
|
3019 |
-
"jsbn": "~0.1.0",
|
3020 |
-
"tweetnacl": "~0.14.0"
|
3021 |
-
},
|
3022 |
-
"dependencies": {
|
3023 |
-
"assert-plus": {
|
3024 |
-
"version": "1.0.0",
|
3025 |
-
"bundled": true,
|
3026 |
-
"dev": true,
|
3027 |
-
"optional": true
|
3028 |
-
}
|
3029 |
-
}
|
3030 |
-
},
|
3031 |
-
"string-width": {
|
3032 |
-
"version": "1.0.2",
|
3033 |
-
"bundled": true,
|
3034 |
-
"dev": true,
|
3035 |
-
"requires": {
|
3036 |
-
"code-point-at": "^1.0.0",
|
3037 |
-
"is-fullwidth-code-point": "^1.0.0",
|
3038 |
-
"strip-ansi": "^3.0.0"
|
3039 |
-
}
|
3040 |
-
},
|
3041 |
-
"string_decoder": {
|
3042 |
-
"version": "1.0.1",
|
3043 |
-
"bundled": true,
|
3044 |
-
"dev": true,
|
3045 |
-
"requires": {
|
3046 |
-
"safe-buffer": "^5.0.1"
|
3047 |
-
}
|
3048 |
-
},
|
3049 |
-
"stringstream": {
|
3050 |
-
"version": "0.0.5",
|
3051 |
-
"bundled": true,
|
3052 |
-
"dev": true,
|
3053 |
-
"optional": true
|
3054 |
-
},
|
3055 |
-
"strip-ansi": {
|
3056 |
-
"version": "3.0.1",
|
3057 |
-
"bundled": true,
|
3058 |
-
"dev": true,
|
3059 |
-
"requires": {
|
3060 |
-
"ansi-regex": "^2.0.0"
|
3061 |
-
}
|
3062 |
-
},
|
3063 |
-
"strip-json-comments": {
|
3064 |
-
"version": "2.0.1",
|
3065 |
-
"bundled": true,
|
3066 |
-
"dev": true,
|
3067 |
-
"optional": true
|
3068 |
-
},
|
3069 |
-
"tar": {
|
3070 |
-
"version": "2.2.1",
|
3071 |
-
"bundled": true,
|
3072 |
-
"dev": true,
|
3073 |
-
"requires": {
|
3074 |
-
"block-stream": "*",
|
3075 |
-
"fstream": "^1.0.2",
|
3076 |
-
"inherits": "2"
|
3077 |
-
}
|
3078 |
-
},
|
3079 |
-
"tar-pack": {
|
3080 |
-
"version": "3.4.0",
|
3081 |
-
"bundled": true,
|
3082 |
-
"dev": true,
|
3083 |
-
"optional": true,
|
3084 |
-
"requires": {
|
3085 |
-
"debug": "^2.2.0",
|
3086 |
-
"fstream": "^1.0.10",
|
3087 |
-
"fstream-ignore": "^1.0.5",
|
3088 |
-
"once": "^1.3.3",
|
3089 |
-
"readable-stream": "^2.1.4",
|
3090 |
-
"rimraf": "^2.5.1",
|
3091 |
-
"tar": "^2.2.1",
|
3092 |
-
"uid-number": "^0.0.6"
|
3093 |
-
}
|
3094 |
-
},
|
3095 |
-
"tough-cookie": {
|
3096 |
-
"version": "2.3.2",
|
3097 |
-
"bundled": true,
|
3098 |
-
"dev": true,
|
3099 |
-
"optional": true,
|
3100 |
-
"requires": {
|
3101 |
-
"punycode": "^1.4.1"
|
3102 |
-
}
|
3103 |
-
},
|
3104 |
-
"tunnel-agent": {
|
3105 |
-
"version": "0.6.0",
|
3106 |
-
"bundled": true,
|
3107 |
-
"dev": true,
|
3108 |
-
"optional": true,
|
3109 |
-
"requires": {
|
3110 |
-
"safe-buffer": "^5.0.1"
|
3111 |
-
}
|
3112 |
-
},
|
3113 |
-
"tweetnacl": {
|
3114 |
-
"version": "0.14.5",
|
3115 |
-
"bundled": true,
|
3116 |
-
"dev": true,
|
3117 |
-
"optional": true
|
3118 |
-
},
|
3119 |
-
"uid-number": {
|
3120 |
-
"version": "0.0.6",
|
3121 |
-
"bundled": true,
|
3122 |
-
"dev": true,
|
3123 |
-
"optional": true
|
3124 |
-
},
|
3125 |
-
"util-deprecate": {
|
3126 |
-
"version": "1.0.2",
|
3127 |
-
"bundled": true,
|
3128 |
-
"dev": true
|
3129 |
-
},
|
3130 |
-
"uuid": {
|
3131 |
-
"version": "3.0.1",
|
3132 |
-
"bundled": true,
|
3133 |
-
"dev": true,
|
3134 |
-
"optional": true
|
3135 |
-
},
|
3136 |
-
"verror": {
|
3137 |
-
"version": "1.3.6",
|
3138 |
-
"bundled": true,
|
3139 |
-
"dev": true,
|
3140 |
-
"optional": true,
|
3141 |
-
"requires": {
|
3142 |
-
"extsprintf": "1.0.2"
|
3143 |
-
}
|
3144 |
-
},
|
3145 |
-
"wide-align": {
|
3146 |
-
"version": "1.1.2",
|
3147 |
-
"bundled": true,
|
3148 |
-
"dev": true,
|
3149 |
-
"optional": true,
|
3150 |
-
"requires": {
|
3151 |
-
"string-width": "^1.0.2"
|
3152 |
-
}
|
3153 |
-
},
|
3154 |
-
"wrappy": {
|
3155 |
-
"version": "1.0.2",
|
3156 |
-
"bundled": true,
|
3157 |
-
"dev": true
|
3158 |
-
}
|
3159 |
-
}
|
3160 |
-
},
|
3161 |
-
"fstream": {
|
3162 |
-
"version": "1.0.11",
|
3163 |
-
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
|
3164 |
-
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
|
3165 |
-
"dev": true,
|
3166 |
-
"requires": {
|
3167 |
-
"graceful-fs": "^4.1.2",
|
3168 |
-
"inherits": "~2.0.0",
|
3169 |
-
"mkdirp": ">=0.5 0",
|
3170 |
-
"rimraf": "2"
|
3171 |
-
}
|
3172 |
-
},
|
3173 |
-
"function-bind": {
|
3174 |
-
"version": "1.1.1",
|
3175 |
-
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
3176 |
-
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
3177 |
-
"dev": true
|
3178 |
-
},
|
3179 |
-
"gauge": {
|
3180 |
-
"version": "2.7.4",
|
3181 |
-
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
3182 |
-
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
3183 |
-
"dev": true,
|
3184 |
-
"requires": {
|
3185 |
-
"aproba": "^1.0.3",
|
3186 |
-
"console-control-strings": "^1.0.0",
|
3187 |
-
"has-unicode": "^2.0.0",
|
3188 |
-
"object-assign": "^4.1.0",
|
3189 |
-
"signal-exit": "^3.0.0",
|
3190 |
-
"string-width": "^1.0.1",
|
3191 |
-
"strip-ansi": "^3.0.1",
|
3192 |
-
"wide-align": "^1.1.0"
|
3193 |
-
}
|
3194 |
-
},
|
3195 |
-
"gaze": {
|
3196 |
-
"version": "1.1.2",
|
3197 |
-
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
|
3198 |
-
"integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
|
3199 |
-
"dev": true,
|
3200 |
-
"requires": {
|
3201 |
-
"globule": "^1.0.0"
|
3202 |
-
}
|
3203 |
-
},
|
3204 |
-
"generate-function": {
|
3205 |
-
"version": "2.0.0",
|
3206 |
-
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
|
3207 |
-
"integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
|
3208 |
-
"dev": true
|
3209 |
-
},
|
3210 |
-
"generate-object-property": {
|
3211 |
-
"version": "1.2.0",
|
3212 |
-
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
|
3213 |
-
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
|
3214 |
-
"dev": true,
|
3215 |
-
"requires": {
|
3216 |
-
"is-property": "^1.0.0"
|
3217 |
-
}
|
3218 |
-
},
|
3219 |
-
"get-caller-file": {
|
3220 |
-
"version": "1.0.2",
|
3221 |
-
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
|
3222 |
-
"integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
|
3223 |
-
"dev": true
|
3224 |
-
},
|
3225 |
-
"get-stdin": {
|
3226 |
-
"version": "4.0.1",
|
3227 |
-
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
|
3228 |
-
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
|
3229 |
-
"dev": true
|
3230 |
-
},
|
3231 |
-
"getpass": {
|
3232 |
-
"version": "0.1.7",
|
3233 |
-
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
3234 |
-
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
3235 |
-
"dev": true,
|
3236 |
-
"requires": {
|
3237 |
-
"assert-plus": "^1.0.0"
|
3238 |
-
},
|
3239 |
-
"dependencies": {
|
3240 |
-
"assert-plus": {
|
3241 |
-
"version": "1.0.0",
|
3242 |
-
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
3243 |
-
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
3244 |
-
"dev": true
|
3245 |
-
}
|
3246 |
-
}
|
3247 |
-
},
|
3248 |
-
"glob": {
|
3249 |
-
"version": "7.1.2",
|
3250 |
-
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
3251 |
-
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
3252 |
-
"dev": true,
|
3253 |
-
"requires": {
|
3254 |
-
"fs.realpath": "^1.0.0",
|
3255 |
-
"inflight": "^1.0.4",
|
3256 |
-
"inherits": "2",
|
3257 |
-
"minimatch": "^3.0.4",
|
3258 |
-
"once": "^1.3.0",
|
3259 |
-
"path-is-absolute": "^1.0.0"
|
3260 |
-
}
|
3261 |
-
},
|
3262 |
-
"glob-base": {
|
3263 |
-
"version": "0.3.0",
|
3264 |
-
"resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
|
3265 |
-
"integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
|
3266 |
-
"dev": true,
|
3267 |
-
"requires": {
|
3268 |
-
"glob-parent": "^2.0.0",
|
3269 |
-
"is-glob": "^2.0.0"
|
3270 |
-
}
|
3271 |
-
},
|
3272 |
-
"glob-parent": {
|
3273 |
-
"version": "2.0.0",
|
3274 |
-
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
|
3275 |
-
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
|
3276 |
-
"dev": true,
|
3277 |
-
"requires": {
|
3278 |
-
"is-glob": "^2.0.0"
|
3279 |
-
}
|
3280 |
-
},
|
3281 |
-
"globals": {
|
3282 |
-
"version": "9.18.0",
|
3283 |
-
"resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
|
3284 |
-
"integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
|
3285 |
-
"dev": true
|
3286 |
-
},
|
3287 |
-
"globby": {
|
3288 |
-
"version": "5.0.0",
|
3289 |
-
"resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
|
3290 |
-
"integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
|
3291 |
-
"dev": true,
|
3292 |
-
"requires": {
|
3293 |
-
"array-union": "^1.0.1",
|
3294 |
-
"arrify": "^1.0.0",
|
3295 |
-
"glob": "^7.0.3",
|
3296 |
-
"object-assign": "^4.0.1",
|
3297 |
-
"pify": "^2.0.0",
|
3298 |
-
"pinkie-promise": "^2.0.0"
|
3299 |
-
},
|
3300 |
-
"dependencies": {
|
3301 |
-
"pify": {
|
3302 |
-
"version": "2.3.0",
|
3303 |
-
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
3304 |
-
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
3305 |
-
"dev": true
|
3306 |
-
}
|
3307 |
-
}
|
3308 |
-
},
|
3309 |
-
"globule": {
|
3310 |
-
"version": "1.2.0",
|
3311 |
-
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
|
3312 |
-
"integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
|
3313 |
-
"dev": true,
|
3314 |
-
"requires": {
|
3315 |
-
"glob": "~7.1.1",
|
3316 |
-
"lodash": "~4.17.4",
|
3317 |
-
"minimatch": "~3.0.2"
|
3318 |
-
}
|
3319 |
-
},
|
3320 |
-
"graceful-fs": {
|
3321 |
-
"version": "4.1.11",
|
3322 |
-
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
3323 |
-
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
3324 |
-
"dev": true
|
3325 |
-
},
|
3326 |
-
"har-validator": {
|
3327 |
-
"version": "2.0.6",
|
3328 |
-
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
|
3329 |
-
"integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
|
3330 |
-
"dev": true,
|
3331 |
-
"requires": {
|
3332 |
-
"chalk": "^1.1.1",
|
3333 |
-
"commander": "^2.9.0",
|
3334 |
-
"is-my-json-valid": "^2.12.4",
|
3335 |
-
"pinkie-promise": "^2.0.0"
|
3336 |
-
}
|
3337 |
-
},
|
3338 |
-
"has": {
|
3339 |
-
"version": "1.0.1",
|
3340 |
-
"resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
|
3341 |
-
"integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
|
3342 |
-
"dev": true,
|
3343 |
-
"requires": {
|
3344 |
-
"function-bind": "^1.0.2"
|
3345 |
-
}
|
3346 |
-
},
|
3347 |
-
"has-ansi": {
|
3348 |
-
"version": "2.0.0",
|
3349 |
-
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
3350 |
-
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
3351 |
-
"dev": true,
|
3352 |
-
"requires": {
|
3353 |
-
"ansi-regex": "^2.0.0"
|
3354 |
-
}
|
3355 |
-
},
|
3356 |
-
"has-flag": {
|
3357 |
-
"version": "1.0.0",
|
3358 |
-
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
|
3359 |
-
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
|
3360 |
-
"dev": true
|
3361 |
-
},
|
3362 |
-
"has-unicode": {
|
3363 |
-
"version": "2.0.1",
|
3364 |
-
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
3365 |
-
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
3366 |
-
"dev": true
|
3367 |
-
},
|
3368 |
-
"hash-base": {
|
3369 |
-
"version": "2.0.2",
|
3370 |
-
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
|
3371 |
-
"integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
|
3372 |
-
"dev": true,
|
3373 |
-
"requires": {
|
3374 |
-
"inherits": "^2.0.1"
|
3375 |
-
}
|
3376 |
-
},
|
3377 |
-
"hash.js": {
|
3378 |
-
"version": "1.1.3",
|
3379 |
-
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
|
3380 |
-
"integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
|
3381 |
-
"dev": true,
|
3382 |
-
"requires": {
|
3383 |
-
"inherits": "^2.0.3",
|
3384 |
-
"minimalistic-assert": "^1.0.0"
|
3385 |
-
}
|
3386 |
-
},
|
3387 |
-
"hawk": {
|
3388 |
-
"version": "3.1.3",
|
3389 |
-
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
|
3390 |
-
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
|
3391 |
-
"dev": true,
|
3392 |
-
"requires": {
|
3393 |
-
"boom": "2.x.x",
|
3394 |
-
"cryptiles": "2.x.x",
|
3395 |
-
"hoek": "2.x.x",
|
3396 |
-
"sntp": "1.x.x"
|
3397 |
-
}
|
3398 |
-
},
|
3399 |
-
"hmac-drbg": {
|
3400 |
-
"version": "1.0.1",
|
3401 |
-
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
3402 |
-
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
|
3403 |
-
"dev": true,
|
3404 |
-
"requires": {
|
3405 |
-
"hash.js": "^1.0.3",
|
3406 |
-
"minimalistic-assert": "^1.0.0",
|
3407 |
-
"minimalistic-crypto-utils": "^1.0.1"
|
3408 |
-
}
|
3409 |
-
},
|
3410 |
-
"hoek": {
|
3411 |
-
"version": "2.16.3",
|
3412 |
-
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
3413 |
-
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
3414 |
-
"dev": true
|
3415 |
-
},
|
3416 |
-
"home-or-tmp": {
|
3417 |
-
"version": "2.0.0",
|
3418 |
-
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
|
3419 |
-
"integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
|
3420 |
-
"dev": true,
|
3421 |
-
"requires": {
|
3422 |
-
"os-homedir": "^1.0.0",
|
3423 |
-
"os-tmpdir": "^1.0.1"
|
3424 |
-
}
|
3425 |
-
},
|
3426 |
-
"hosted-git-info": {
|
3427 |
-
"version": "2.5.0",
|
3428 |
-
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
|
3429 |
-
"integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
|
3430 |
-
"dev": true
|
3431 |
-
},
|
3432 |
-
"html-comment-regex": {
|
3433 |
-
"version": "1.1.1",
|
3434 |
-
"resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
|
3435 |
-
"integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
|
3436 |
-
"dev": true
|
3437 |
-
},
|
3438 |
-
"http-signature": {
|
3439 |
-
"version": "1.1.1",
|
3440 |
-
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
|
3441 |
-
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
|
3442 |
-
"dev": true,
|
3443 |
-
"requires": {
|
3444 |
-
"assert-plus": "^0.2.0",
|
3445 |
-
"jsprim": "^1.2.2",
|
3446 |
-
"sshpk": "^1.7.0"
|
3447 |
-
}
|
3448 |
-
},
|
3449 |
-
"https-browserify": {
|
3450 |
-
"version": "1.0.0",
|
3451 |
-
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
|
3452 |
-
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
|
3453 |
-
"dev": true
|
3454 |
-
},
|
3455 |
-
"icss-replace-symbols": {
|
3456 |
-
"version": "1.1.0",
|
3457 |
-
"resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
|
3458 |
-
"integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
|
3459 |
-
"dev": true
|
3460 |
-
},
|
3461 |
-
"icss-utils": {
|
3462 |
-
"version": "2.1.0",
|
3463 |
-
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz",
|
3464 |
-
"integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
|
3465 |
-
"dev": true,
|
3466 |
-
"requires": {
|
3467 |
-
"postcss": "^6.0.1"
|
3468 |
-
},
|
3469 |
-
"dependencies": {
|
3470 |
-
"ansi-styles": {
|
3471 |
-
"version": "3.2.0",
|
3472 |
-
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
|
3473 |
-
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
|
3474 |
-
"dev": true,
|
3475 |
-
"requires": {
|
3476 |
-
"color-convert": "^1.9.0"
|
3477 |
-
}
|
3478 |
-
},
|
3479 |
-
"chalk": {
|
3480 |
-
"version": "2.3.0",
|
3481 |
-
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
|
3482 |
-
"integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
|
3483 |
-
"dev": true,
|
3484 |
-
"requires": {
|
3485 |
-
"ansi-styles": "^3.1.0",
|
3486 |
-
"escape-string-regexp": "^1.0.5",
|
3487 |
-
"supports-color": "^4.0.0"
|
3488 |
-
}
|
3489 |
-
},
|
3490 |
-
"has-flag": {
|
3491 |
-
"version": "2.0.0",
|
3492 |
-
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
|
3493 |
-
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
|
3494 |
-
"dev": true
|
3495 |
-
},
|
3496 |
-
"postcss": {
|
3497 |
-
"version": "6.0.14",
|
3498 |
-
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz",
|
3499 |
-
"integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==",
|
3500 |
-
"dev": true,
|
3501 |
-
"requires": {
|
3502 |
-
"chalk": "^2.3.0",
|
3503 |
-
"source-map": "^0.6.1",
|
3504 |
-
"supports-color": "^4.4.0"
|
3505 |
-
}
|
3506 |
-
},
|
3507 |
-
"source-map": {
|
3508 |
-
"version": "0.6.1",
|
3509 |
-
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
3510 |
-
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
3511 |
-
"dev": true
|
3512 |
-
},
|
3513 |
-
"supports-color": {
|
3514 |
-
"version": "4.5.0",
|
3515 |
-
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
|
3516 |
-
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
|
3517 |
-
"dev": true,
|
3518 |
-
"requires": {
|
3519 |
-
"has-flag": "^2.0.0"
|
3520 |
-
}
|
3521 |
-
}
|
3522 |
-
}
|
3523 |
-
},
|
3524 |
-
"ieee754": {
|
3525 |
-
"version": "1.1.8",
|
3526 |
-
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
|
3527 |
-
"integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
|
3528 |
-
"dev": true
|
3529 |
-
},
|
3530 |
-
"ignore": {
|
3531 |
-
"version": "3.3.7",
|
3532 |
-
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz",
|
3533 |
-
"integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==",
|
3534 |
-
"dev": true
|
3535 |
-
},
|
3536 |
-
"imurmurhash": {
|
3537 |
-
"version": "0.1.4",
|
3538 |
-
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
3539 |
-
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
3540 |
-
"dev": true
|
3541 |
-
},
|
3542 |
-
"in-publish": {
|
3543 |
-
"version": "2.0.0",
|
3544 |
-
"resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
|
3545 |
-
"integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
|
3546 |
-
"dev": true
|
3547 |
-
},
|
3548 |
-
"indent-string": {
|
3549 |
-
"version": "2.1.0",
|
3550 |
-
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
|
3551 |
-
"integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
|
3552 |
-
"dev": true,
|
3553 |
-
"requires": {
|
3554 |
-
"repeating": "^2.0.0"
|
3555 |
-
}
|
3556 |
-
},
|
3557 |
-
"indexes-of": {
|
3558 |
-
"version": "1.0.1",
|
3559 |
-
"resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
|
3560 |
-
"integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
|
3561 |
-
"dev": true
|
3562 |
-
},
|
3563 |
-
"indexof": {
|
3564 |
-
"version": "0.0.1",
|
3565 |
-
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
|
3566 |
-
"integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
|
3567 |
-
"dev": true
|
3568 |
-
},
|
3569 |
-
"inflight": {
|
3570 |
-
"version": "1.0.6",
|
3571 |
-
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
3572 |
-
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
3573 |
-
"dev": true,
|
3574 |
-
"requires": {
|
3575 |
-
"once": "^1.3.0",
|
3576 |
-
"wrappy": "1"
|
3577 |
-
}
|
3578 |
-
},
|
3579 |
-
"inherits": {
|
3580 |
-
"version": "2.0.3",
|
3581 |
-
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
3582 |
-
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
3583 |
-
"dev": true
|
3584 |
-
},
|
3585 |
-
"inquirer": {
|
3586 |
-
"version": "0.12.0",
|
3587 |
-
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
|
3588 |
-
"integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
|
3589 |
-
"dev": true,
|
3590 |
-
"requires": {
|
3591 |
-
"ansi-escapes": "^1.1.0",
|
3592 |
-
"ansi-regex": "^2.0.0",
|
3593 |
-
"chalk": "^1.0.0",
|
3594 |
-
"cli-cursor": "^1.0.1",
|
3595 |
-
"cli-width": "^2.0.0",
|
3596 |
-
"figures": "^1.3.5",
|
3597 |
-
"lodash": "^4.3.0",
|
3598 |
-
"readline2": "^1.0.1",
|
3599 |
-
"run-async": "^0.1.0",
|
3600 |
-
"rx-lite": "^3.1.2",
|
3601 |
-
"string-width": "^1.0.1",
|
3602 |
-
"strip-ansi": "^3.0.0",
|
3603 |
-
"through": "^2.3.6"
|
3604 |
-
}
|
3605 |
-
},
|
3606 |
-
"interpret": {
|
3607 |
-
"version": "1.0.4",
|
3608 |
-
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz",
|
3609 |
-
"integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=",
|
3610 |
-
"dev": true
|
3611 |
-
},
|
3612 |
-
"invariant": {
|
3613 |
-
"version": "2.2.2",
|
3614 |
-
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
|
3615 |
-
"integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
|
3616 |
-
"dev": true,
|
3617 |
-
"requires": {
|
3618 |
-
"loose-envify": "^1.0.0"
|
3619 |
-
}
|
3620 |
-
},
|
3621 |
-
"invert-kv": {
|
3622 |
-
"version": "1.0.0",
|
3623 |
-
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
3624 |
-
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
|
3625 |
-
"dev": true
|
3626 |
-
},
|
3627 |
-
"is-absolute-url": {
|
3628 |
-
"version": "2.1.0",
|
3629 |
-
"resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
|
3630 |
-
"integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
|
3631 |
-
"dev": true
|
3632 |
-
},
|
3633 |
-
"is-arrayish": {
|
3634 |
-
"version": "0.2.1",
|
3635 |
-
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
3636 |
-
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
|
3637 |
-
"dev": true
|
3638 |
-
},
|
3639 |
-
"is-binary-path": {
|
3640 |
-
"version": "1.0.1",
|
3641 |
-
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
|
3642 |
-
"integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
|
3643 |
-
"dev": true,
|
3644 |
-
"requires": {
|
3645 |
-
"binary-extensions": "^1.0.0"
|
3646 |
-
}
|
3647 |
-
},
|
3648 |
-
"is-buffer": {
|
3649 |
-
"version": "1.1.6",
|
3650 |
-
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
|
3651 |
-
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
|
3652 |
-
"dev": true
|
3653 |
-
},
|
3654 |
-
"is-builtin-module": {
|
3655 |
-
"version": "1.0.0",
|
3656 |
-
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
|
3657 |
-
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
|
3658 |
-
"dev": true,
|
3659 |
-
"requires": {
|
3660 |
-
"builtin-modules": "^1.0.0"
|
3661 |
-
}
|
3662 |
-
},
|
3663 |
-
"is-dotfile": {
|
3664 |
-
"version": "1.0.3",
|
3665 |
-
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
|
3666 |
-
"integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
|
3667 |
-
"dev": true
|
3668 |
-
},
|
3669 |
-
"is-equal-shallow": {
|
3670 |
-
"version": "0.1.3",
|
3671 |
-
"resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
|
3672 |
-
"integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
|
3673 |
-
"dev": true,
|
3674 |
-
"requires": {
|
3675 |
-
"is-primitive": "^2.0.0"
|
3676 |
-
}
|
3677 |
-
},
|
3678 |
-
"is-extendable": {
|
3679 |
-
"version": "0.1.1",
|
3680 |
-
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
3681 |
-
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
|
3682 |
-
"dev": true
|
3683 |
-
},
|
3684 |
-
"is-extglob": {
|
3685 |
-
"version": "1.0.0",
|
3686 |
-
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
|
3687 |
-
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
|
3688 |
-
"dev": true
|
3689 |
-
},
|
3690 |
-
"is-finite": {
|
3691 |
-
"version": "1.0.2",
|
3692 |
-
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
|
3693 |
-
"integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
|
3694 |
-
"dev": true,
|
3695 |
-
"requires": {
|
3696 |
-
"number-is-nan": "^1.0.0"
|
3697 |
-
}
|
3698 |
-
},
|
3699 |
-
"is-fullwidth-code-point": {
|
3700 |
-
"version": "1.0.0",
|
3701 |
-
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
3702 |
-
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
3703 |
-
"dev": true,
|
3704 |
-
"requires": {
|
3705 |
-
"number-is-nan": "^1.0.0"
|
3706 |
-
}
|
3707 |
-
},
|
3708 |
-
"is-glob": {
|
3709 |
-
"version": "2.0.1",
|
3710 |
-
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
|
3711 |
-
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
|
3712 |
-
"dev": true,
|
3713 |
-
"requires": {
|
3714 |
-
"is-extglob": "^1.0.0"
|
3715 |
-
}
|
3716 |
-
},
|
3717 |
-
"is-my-json-valid": {
|
3718 |
-
"version": "2.16.1",
|
3719 |
-
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
|
3720 |
-
"integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
|
3721 |
-
"dev": true,
|
3722 |
-
"requires": {
|
3723 |
-
"generate-function": "^2.0.0",
|
3724 |
-
"generate-object-property": "^1.1.0",
|
3725 |
-
"jsonpointer": "^4.0.0",
|
3726 |
-
"xtend": "^4.0.0"
|
3727 |
-
}
|
3728 |
-
},
|
3729 |
-
"is-number": {
|
3730 |
-
"version": "2.1.0",
|
3731 |
-
"resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
|
3732 |
-
"integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
|
3733 |
-
"dev": true,
|
3734 |
-
"requires": {
|
3735 |
-
"kind-of": "^3.0.2"
|
3736 |
-
}
|
3737 |
-
},
|
3738 |
-
"is-path-cwd": {
|
3739 |
-
"version": "1.0.0",
|
3740 |
-
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
|
3741 |
-
"integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
|
3742 |
-
"dev": true
|
3743 |
-
},
|
3744 |
-
"is-path-in-cwd": {
|
3745 |
-
"version": "1.0.0",
|
3746 |
-
"resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
|
3747 |
-
"integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
|
3748 |
-
"dev": true,
|
3749 |
-
"requires": {
|
3750 |
-
"is-path-inside": "^1.0.0"
|
3751 |
-
}
|
3752 |
-
},
|
3753 |
-
"is-path-inside": {
|
3754 |
-
"version": "1.0.0",
|
3755 |
-
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
|
3756 |
-
"integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
|
3757 |
-
"dev": true,
|
3758 |
-
"requires": {
|
3759 |
-
"path-is-inside": "^1.0.1"
|
3760 |
-
}
|
3761 |
-
},
|
3762 |
-
"is-plain-obj": {
|
3763 |
-
"version": "1.1.0",
|
3764 |
-
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
|
3765 |
-
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
|
3766 |
-
"dev": true
|
3767 |
-
},
|
3768 |
-
"is-plain-object": {
|
3769 |
-
"version": "2.0.4",
|
3770 |
-
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
3771 |
-
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
|
3772 |
-
"dev": true,
|
3773 |
-
"requires": {
|
3774 |
-
"isobject": "^3.0.1"
|
3775 |
-
}
|
3776 |
-
},
|
3777 |
-
"is-posix-bracket": {
|
3778 |
-
"version": "0.1.1",
|
3779 |
-
"resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
|
3780 |
-
"integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
|
3781 |
-
"dev": true
|
3782 |
-
},
|
3783 |
-
"is-primitive": {
|
3784 |
-
"version": "2.0.0",
|
3785 |
-
"resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
|
3786 |
-
"integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
|
3787 |
-
"dev": true
|
3788 |
-
},
|
3789 |
-
"is-property": {
|
3790 |
-
"version": "1.0.2",
|
3791 |
-
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
3792 |
-
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
|
3793 |
-
"dev": true
|
3794 |
-
},
|
3795 |
-
"is-resolvable": {
|
3796 |
-
"version": "1.0.0",
|
3797 |
-
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
|
3798 |
-
"integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
|
3799 |
-
"dev": true,
|
3800 |
-
"requires": {
|
3801 |
-
"tryit": "^1.0.1"
|
3802 |
-
}
|
3803 |
-
},
|
3804 |
-
"is-svg": {
|
3805 |
-
"version": "2.1.0",
|
3806 |
-
"resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
|
3807 |
-
"integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
|
3808 |
-
"dev": true,
|
3809 |
-
"requires": {
|
3810 |
-
"html-comment-regex": "^1.1.0"
|
3811 |
-
}
|
3812 |
-
},
|
3813 |
-
"is-typedarray": {
|
3814 |
-
"version": "1.0.0",
|
3815 |
-
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
3816 |
-
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
3817 |
-
"dev": true
|
3818 |
-
},
|
3819 |
-
"is-utf8": {
|
3820 |
-
"version": "0.2.1",
|
3821 |
-
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
|
3822 |
-
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
|
3823 |
-
"dev": true
|
3824 |
-
},
|
3825 |
-
"isarray": {
|
3826 |
-
"version": "1.0.0",
|
3827 |
-
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
3828 |
-
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
3829 |
-
"dev": true
|
3830 |
-
},
|
3831 |
-
"isexe": {
|
3832 |
-
"version": "2.0.0",
|
3833 |
-
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
3834 |
-
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
3835 |
-
"dev": true
|
3836 |
-
},
|
3837 |
-
"isobject": {
|
3838 |
-
"version": "3.0.1",
|
3839 |
-
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
3840 |
-
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
|
3841 |
-
"dev": true
|
3842 |
-
},
|
3843 |
-
"isstream": {
|
3844 |
-
"version": "0.1.2",
|
3845 |
-
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
3846 |
-
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
3847 |
-
"dev": true
|
3848 |
-
},
|
3849 |
-
"jquery": {
|
3850 |
-
"version": "3.2.1",
|
3851 |
-
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
|
3852 |
-
"integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c="
|
3853 |
-
},
|
3854 |
-
"js-base64": {
|
3855 |
-
"version": "2.3.2",
|
3856 |
-
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
|
3857 |
-
"integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==",
|
3858 |
-
"dev": true
|
3859 |
-
},
|
3860 |
-
"js-tokens": {
|
3861 |
-
"version": "3.0.2",
|
3862 |
-
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
3863 |
-
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
|
3864 |
-
"dev": true
|
3865 |
-
},
|
3866 |
-
"js-yaml": {
|
3867 |
-
"version": "3.7.0",
|
3868 |
-
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
|
3869 |
-
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
|
3870 |
-
"dev": true,
|
3871 |
-
"requires": {
|
3872 |
-
"argparse": "^1.0.7",
|
3873 |
-
"esprima": "^2.6.0"
|
3874 |
-
}
|
3875 |
-
},
|
3876 |
-
"jsbn": {
|
3877 |
-
"version": "0.1.1",
|
3878 |
-
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
3879 |
-
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
3880 |
-
"dev": true,
|
3881 |
-
"optional": true
|
3882 |
-
},
|
3883 |
-
"jsesc": {
|
3884 |
-
"version": "1.3.0",
|
3885 |
-
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
|
3886 |
-
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
|
3887 |
-
"dev": true
|
3888 |
-
},
|
3889 |
-
"json-loader": {
|
3890 |
-
"version": "0.5.7",
|
3891 |
-
"resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
|
3892 |
-
"integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
|
3893 |
-
"dev": true
|
3894 |
-
},
|
3895 |
-
"json-schema": {
|
3896 |
-
"version": "0.2.3",
|
3897 |
-
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
3898 |
-
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
3899 |
-
"dev": true
|
3900 |
-
},
|
3901 |
-
"json-schema-traverse": {
|
3902 |
-
"version": "0.3.1",
|
3903 |
-
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
|
3904 |
-
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
|
3905 |
-
"dev": true
|
3906 |
-
},
|
3907 |
-
"json-stable-stringify": {
|
3908 |
-
"version": "1.0.1",
|
3909 |
-
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
|
3910 |
-
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
|
3911 |
-
"dev": true,
|
3912 |
-
"requires": {
|
3913 |
-
"jsonify": "~0.0.0"
|
3914 |
-
}
|
3915 |
-
},
|
3916 |
-
"json-stringify-safe": {
|
3917 |
-
"version": "5.0.1",
|
3918 |
-
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
3919 |
-
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
3920 |
-
"dev": true
|
3921 |
-
},
|
3922 |
-
"json5": {
|
3923 |
-
"version": "0.5.1",
|
3924 |
-
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
3925 |
-
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
3926 |
-
"dev": true
|
3927 |
-
},
|
3928 |
-
"jsonify": {
|
3929 |
-
"version": "0.0.0",
|
3930 |
-
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
3931 |
-
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
|
3932 |
-
"dev": true
|
3933 |
-
},
|
3934 |
-
"jsonpointer": {
|
3935 |
-
"version": "4.0.1",
|
3936 |
-
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
|
3937 |
-
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
|
3938 |
-
"dev": true
|
3939 |
-
},
|
3940 |
-
"jsprim": {
|
3941 |
-
"version": "1.4.1",
|
3942 |
-
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
3943 |
-
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
3944 |
-
"dev": true,
|
3945 |
-
"requires": {
|
3946 |
-
"assert-plus": "1.0.0",
|
3947 |
-
"extsprintf": "1.3.0",
|
3948 |
-
"json-schema": "0.2.3",
|
3949 |
-
"verror": "1.10.0"
|
3950 |
-
},
|
3951 |
-
"dependencies": {
|
3952 |
-
"assert-plus": {
|
3953 |
-
"version": "1.0.0",
|
3954 |
-
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
3955 |
-
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
3956 |
-
"dev": true
|
3957 |
-
}
|
3958 |
-
}
|
3959 |
-
},
|
3960 |
-
"kind-of": {
|
3961 |
-
"version": "3.2.2",
|
3962 |
-
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
3963 |
-
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
3964 |
-
"dev": true,
|
3965 |
-
"requires": {
|
3966 |
-
"is-buffer": "^1.1.5"
|
3967 |
-
}
|
3968 |
-
},
|
3969 |
-
"lazy-cache": {
|
3970 |
-
"version": "0.2.7",
|
3971 |
-
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
|
3972 |
-
"integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
|
3973 |
-
"dev": true
|
3974 |
-
},
|
3975 |
-
"lcid": {
|
3976 |
-
"version": "1.0.0",
|
3977 |
-
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
|
3978 |
-
"integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
|
3979 |
-
"dev": true,
|
3980 |
-
"requires": {
|
3981 |
-
"invert-kv": "^1.0.0"
|
3982 |
-
}
|
3983 |
-
},
|
3984 |
-
"levn": {
|
3985 |
-
"version": "0.3.0",
|
3986 |
-
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
|
3987 |
-
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
|
3988 |
-
"dev": true,
|
3989 |
-
"requires": {
|
3990 |
-
"prelude-ls": "~1.1.2",
|
3991 |
-
"type-check": "~0.3.2"
|
3992 |
-
}
|
3993 |
-
},
|
3994 |
-
"load-json-file": {
|
3995 |
-
"version": "1.1.0",
|
3996 |
-
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
|
3997 |
-
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
|
3998 |
-
"dev": true,
|
3999 |
-
"requires": {
|
4000 |
-
"graceful-fs": "^4.1.2",
|
4001 |
-
"parse-json": "^2.2.0",
|
4002 |
-
"pify": "^2.0.0",
|
4003 |
-
"pinkie-promise": "^2.0.0",
|
4004 |
-
"strip-bom": "^2.0.0"
|
4005 |
-
},
|
4006 |
-
"dependencies": {
|
4007 |
-
"pify": {
|
4008 |
-
"version": "2.3.0",
|
4009 |
-
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
4010 |
-
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
4011 |
-
"dev": true
|
4012 |
-
},
|
4013 |
-
"strip-bom": {
|
4014 |
-
"version": "2.0.0",
|
4015 |
-
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
|
4016 |
-
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
|
4017 |
-
"dev": true,
|
4018 |
-
"requires": {
|
4019 |
-
"is-utf8": "^0.2.0"
|
4020 |
-
}
|
4021 |
-
}
|
4022 |
-
}
|
4023 |
-
},
|
4024 |
-
"loader-runner": {
|
4025 |
-
"version": "2.3.0",
|
4026 |
-
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
|
4027 |
-
"integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
|
4028 |
-
"dev": true
|
4029 |
-
},
|
4030 |
-
"loader-utils": {
|
4031 |
-
"version": "1.1.0",
|
4032 |
-
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
|
4033 |
-
"integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
|
4034 |
-
"dev": true,
|
4035 |
-
"requires": {
|
4036 |
-
"big.js": "^3.1.3",
|
4037 |
-
"emojis-list": "^2.0.0",
|
4038 |
-
"json5": "^0.5.0"
|
4039 |
-
}
|
4040 |
-
},
|
4041 |
-
"locate-path": {
|
4042 |
-
"version": "2.0.0",
|
4043 |
-
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
|
4044 |
-
"integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
|
4045 |
-
"dev": true,
|
4046 |
-
"requires": {
|
4047 |
-
"p-locate": "^2.0.0",
|
4048 |
-
"path-exists": "^3.0.0"
|
4049 |
-
}
|
4050 |
-
},
|
4051 |
-
"lodash": {
|
4052 |
-
"version": "4.17.4",
|
4053 |
-
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
4054 |
-
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
|
4055 |
-
"dev": true
|
4056 |
-
},
|
4057 |
-
"lodash.assign": {
|
4058 |
-
"version": "4.2.0",
|
4059 |
-
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
|
4060 |
-
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
|
4061 |
-
"dev": true
|
4062 |
-
},
|
4063 |
-
"lodash.camelcase": {
|
4064 |
-
"version": "4.3.0",
|
4065 |
-
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
4066 |
-
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
|
4067 |
-
"dev": true
|
4068 |
-
},
|
4069 |
-
"lodash.clonedeep": {
|
4070 |
-
"version": "4.5.0",
|
4071 |
-
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
4072 |
-
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
|
4073 |
-
"dev": true
|
4074 |
-
},
|
4075 |
-
"lodash.memoize": {
|
4076 |
-
"version": "4.1.2",
|
4077 |
-
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
4078 |
-
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
|
4079 |
-
"dev": true
|
4080 |
-
},
|
4081 |
-
"lodash.mergewith": {
|
4082 |
-
"version": "4.6.0",
|
4083 |
-
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz",
|
4084 |
-
"integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=",
|
4085 |
-
"dev": true
|
4086 |
-
},
|
4087 |
-
"lodash.tail": {
|
4088 |
-
"version": "4.1.1",
|
4089 |
-
"resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
|
4090 |
-
"integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
|
4091 |
-
"dev": true
|
4092 |
-
},
|
4093 |
-
"lodash.uniq": {
|
4094 |
-
"version": "4.5.0",
|
4095 |
-
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
4096 |
-
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
|
4097 |
-
"dev": true
|
4098 |
-
},
|
4099 |
-
"longest": {
|
4100 |
-
"version": "1.0.1",
|
4101 |
-
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
|
4102 |
-
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
|
4103 |
-
"dev": true
|
4104 |
-
},
|
4105 |
-
"loose-envify": {
|
4106 |
-
"version": "1.3.1",
|
4107 |
-
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
|
4108 |
-
"integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
|
4109 |
-
"dev": true,
|
4110 |
-
"requires": {
|
4111 |
-
"js-tokens": "^3.0.0"
|
4112 |
-
}
|
4113 |
-
},
|
4114 |
-
"loud-rejection": {
|
4115 |
-
"version": "1.6.0",
|
4116 |
-
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
4117 |
-
"integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
|
4118 |
-
"dev": true,
|
4119 |
-
"requires": {
|
4120 |
-
"currently-unhandled": "^0.4.1",
|
4121 |
-
"signal-exit": "^3.0.0"
|
4122 |
-
}
|
4123 |
-
},
|
4124 |
-
"lru-cache": {
|
4125 |
-
"version": "4.1.1",
|
4126 |
-
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
|
4127 |
-
"integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
|
4128 |
-
"dev": true,
|
4129 |
-
"requires": {
|
4130 |
-
"pseudomap": "^1.0.2",
|
4131 |
-
"yallist": "^2.1.2"
|
4132 |
-
}
|
4133 |
-
},
|
4134 |
-
"macaddress": {
|
4135 |
-
"version": "0.2.8",
|
4136 |
-
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
|
4137 |
-
"integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=",
|
4138 |
-
"dev": true
|
4139 |
-
},
|
4140 |
-
"make-dir": {
|
4141 |
-
"version": "1.1.0",
|
4142 |
-
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
|
4143 |
-
"integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
|
4144 |
-
"dev": true,
|
4145 |
-
"requires": {
|
4146 |
-
"pify": "^3.0.0"
|
4147 |
-
}
|
4148 |
-
},
|
4149 |
-
"map-obj": {
|
4150 |
-
"version": "1.0.1",
|
4151 |
-
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
|
4152 |
-
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
|
4153 |
-
"dev": true
|
4154 |
-
},
|
4155 |
-
"math-expression-evaluator": {
|
4156 |
-
"version": "1.2.17",
|
4157 |
-
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
|
4158 |
-
"integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
|
4159 |
-
"dev": true
|
4160 |
-
},
|
4161 |
-
"md5.js": {
|
4162 |
-
"version": "1.3.4",
|
4163 |
-
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
|
4164 |
-
"integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
|
4165 |
-
"dev": true,
|
4166 |
-
"requires": {
|
4167 |
-
"hash-base": "^3.0.0",
|
4168 |
-
"inherits": "^2.0.1"
|
4169 |
-
},
|
4170 |
-
"dependencies": {
|
4171 |
-
"hash-base": {
|
4172 |
-
"version": "3.0.4",
|
4173 |
-
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
|
4174 |
-
"integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
|
4175 |
-
"dev": true,
|
4176 |
-
"requires": {
|
4177 |
-
"inherits": "^2.0.1",
|
4178 |
-
"safe-buffer": "^5.0.1"
|
4179 |
-
}
|
4180 |
-
}
|
4181 |
-
}
|
4182 |
-
},
|
4183 |
-
"memory-fs": {
|
4184 |
-
"version": "0.4.1",
|
4185 |
-
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
|
4186 |
-
"integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
|
4187 |
-
"dev": true,
|
4188 |
-
"requires": {
|
4189 |
-
"errno": "^0.1.3",
|
4190 |
-
"readable-stream": "^2.0.1"
|
4191 |
-
}
|
4192 |
-
},
|
4193 |
-
"meow": {
|
4194 |
-
"version": "3.7.0",
|
4195 |
-
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
|
4196 |
-
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
|
4197 |
-
"dev": true,
|
4198 |
-
"requires": {
|
4199 |
-
"camelcase-keys": "^2.0.0",
|
4200 |
-
"decamelize": "^1.1.2",
|
4201 |
-
"loud-rejection": "^1.0.0",
|
4202 |
-
"map-obj": "^1.0.1",
|
4203 |
-
"minimist": "^1.1.3",
|
4204 |
-
"normalize-package-data": "^2.3.4",
|
4205 |
-
"object-assign": "^4.0.1",
|
4206 |
-
"read-pkg-up": "^1.0.1",
|
4207 |
-
"redent": "^1.0.0",
|
4208 |
-
"trim-newlines": "^1.0.0"
|
4209 |
-
},
|
4210 |
-
"dependencies": {
|
4211 |
-
"minimist": {
|
4212 |
-
"version": "1.2.0",
|
4213 |
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
4214 |
-
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
4215 |
-
"dev": true
|
4216 |
-
}
|
4217 |
-
}
|
4218 |
-
},
|
4219 |
-
"micromatch": {
|
4220 |
-
"version": "2.3.11",
|
4221 |
-
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
|
4222 |
-
"integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
|
4223 |
-
"dev": true,
|
4224 |
-
"requires": {
|
4225 |
-
"arr-diff": "^2.0.0",
|
4226 |
-
"array-unique": "^0.2.1",
|
4227 |
-
"braces": "^1.8.2",
|
4228 |
-
"expand-brackets": "^0.1.4",
|
4229 |
-
"extglob": "^0.3.1",
|
4230 |
-
"filename-regex": "^2.0.0",
|
4231 |
-
"is-extglob": "^1.0.0",
|
4232 |
-
"is-glob": "^2.0.1",
|
4233 |
-
"kind-of": "^3.0.2",
|
4234 |
-
"normalize-path": "^2.0.1",
|
4235 |
-
"object.omit": "^2.0.0",
|
4236 |
-
"parse-glob": "^3.0.4",
|
4237 |
-
"regex-cache": "^0.4.2"
|
4238 |
-
}
|
4239 |
-
},
|
4240 |
-
"miller-rabin": {
|
4241 |
-
"version": "4.0.1",
|
4242 |
-
"resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
|
4243 |
-
"integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
|
4244 |
-
"dev": true,
|
4245 |
-
"requires": {
|
4246 |
-
"bn.js": "^4.0.0",
|
4247 |
-
"brorand": "^1.0.1"
|
4248 |
-
}
|
4249 |
-
},
|
4250 |
-
"mime-db": {
|
4251 |
-
"version": "1.30.0",
|
4252 |
-
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
|
4253 |
-
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
|
4254 |
-
"dev": true
|
4255 |
-
},
|
4256 |
-
"mime-types": {
|
4257 |
-
"version": "2.1.17",
|
4258 |
-
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
|
4259 |
-
"integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
|
4260 |
-
"dev": true,
|
4261 |
-
"requires": {
|
4262 |
-
"mime-db": "~1.30.0"
|
4263 |
-
}
|
4264 |
-
},
|
4265 |
-
"minimalistic-assert": {
|
4266 |
-
"version": "1.0.0",
|
4267 |
-
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
|
4268 |
-
"integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
|
4269 |
-
"dev": true
|
4270 |
-
},
|
4271 |
-
"minimalistic-crypto-utils": {
|
4272 |
-
"version": "1.0.1",
|
4273 |
-
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
4274 |
-
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
|
4275 |
-
"dev": true
|
4276 |
-
},
|
4277 |
-
"minimatch": {
|
4278 |
-
"version": "3.0.4",
|
4279 |
-
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
4280 |
-
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
4281 |
-
"dev": true,
|
4282 |
-
"requires": {
|
4283 |
-
"brace-expansion": "^1.1.7"
|
4284 |
-
}
|
4285 |
-
},
|
4286 |
-
"minimist": {
|
4287 |
-
"version": "0.0.8",
|
4288 |
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
4289 |
-
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
4290 |
-
"dev": true
|
4291 |
-
},
|
4292 |
-
"mixin-object": {
|
4293 |
-
"version": "2.0.1",
|
4294 |
-
"resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
|
4295 |
-
"integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
|
4296 |
-
"dev": true,
|
4297 |
-
"requires": {
|
4298 |
-
"for-in": "^0.1.3",
|
4299 |
-
"is-extendable": "^0.1.1"
|
4300 |
-
},
|
4301 |
-
"dependencies": {
|
4302 |
-
"for-in": {
|
4303 |
-
"version": "0.1.8",
|
4304 |
-
"resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
|
4305 |
-
"integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
|
4306 |
-
"dev": true
|
4307 |
-
}
|
4308 |
-
}
|
4309 |
-
},
|
4310 |
-
"mkdirp": {
|
4311 |
-
"version": "0.5.1",
|
4312 |
-
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
4313 |
-
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
4314 |
-
"dev": true,
|
4315 |
-
"requires": {
|
4316 |
-
"minimist": "0.0.8"
|
4317 |
-
}
|
4318 |
-
},
|
4319 |
-
"ms": {
|
4320 |
-
"version": "2.0.0",
|
4321 |
-
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
4322 |
-
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
4323 |
-
"dev": true
|
4324 |
-
},
|
4325 |
-
"mute-stream": {
|
4326 |
-
"version": "0.0.5",
|
4327 |
-
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
|
4328 |
-
"integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
|
4329 |
-
"dev": true
|
4330 |
-
},
|
4331 |
-
"nan": {
|
4332 |
-
"version": "2.8.0",
|
4333 |
-
"resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
|
4334 |
-
"integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=",
|
4335 |
-
"dev": true
|
4336 |
-
},
|
4337 |
-
"natural-compare": {
|
4338 |
-
"version": "1.4.0",
|
4339 |
-
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
4340 |
-
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
4341 |
-
"dev": true
|
4342 |
-
},
|
4343 |
-
"node-gyp": {
|
4344 |
-
"version": "3.6.2",
|
4345 |
-
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
|
4346 |
-
"integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
|
4347 |
-
"dev": true,
|
4348 |
-
"requires": {
|
4349 |
-
"fstream": "^1.0.0",
|
4350 |
-
"glob": "^7.0.3",
|
4351 |
-
"graceful-fs": "^4.1.2",
|
4352 |
-
"minimatch": "^3.0.2",
|
4353 |
-
"mkdirp": "^0.5.0",
|
4354 |
-
"nopt": "2 || 3",
|
4355 |
-
"npmlog": "0 || 1 || 2 || 3 || 4",
|
4356 |
-
"osenv": "0",
|
4357 |
-
"request": "2",
|
4358 |
-
"rimraf": "2",
|
4359 |
-
"semver": "~5.3.0",
|
4360 |
-
"tar": "^2.0.0",
|
4361 |
-
"which": "1"
|
4362 |
-
},
|
4363 |
-
"dependencies": {
|
4364 |
-
"semver": {
|
4365 |
-
"version": "5.3.0",
|
4366 |
-
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
4367 |
-
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
|
4368 |
-
"dev": true
|
4369 |
-
}
|
4370 |
-
}
|
4371 |
-
},
|
4372 |
-
"node-libs-browser": {
|
4373 |
-
"version": "2.1.0",
|
4374 |
-
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
|
4375 |
-
"integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
|
4376 |
-
"dev": true,
|
4377 |
-
"requires": {
|
4378 |
-
"assert": "^1.1.1",
|
4379 |
-
"browserify-zlib": "^0.2.0",
|
4380 |
-
"buffer": "^4.3.0",
|
4381 |
-
"console-browserify": "^1.1.0",
|
4382 |
-
"constants-browserify": "^1.0.0",
|
4383 |
-
"crypto-browserify": "^3.11.0",
|
4384 |
-
"domain-browser": "^1.1.1",
|
4385 |
-
"events": "^1.0.0",
|
4386 |
-
"https-browserify": "^1.0.0",
|
4387 |
-
"os-browserify": "^0.3.0",
|
4388 |
-
"path-browserify": "0.0.0",
|
4389 |
-
"process": "^0.11.10",
|
4390 |
-
"punycode": "^1.2.4",
|
4391 |
-
"querystring-es3": "^0.2.0",
|
4392 |
-
"readable-stream": "^2.3.3",
|
4393 |
-
"stream-browserify": "^2.0.1",
|
4394 |
-
"stream-http": "^2.7.2",
|
4395 |
-
"string_decoder": "^1.0.0",
|
4396 |
-
"timers-browserify": "^2.0.4",
|
4397 |
-
"tty-browserify": "0.0.0",
|
4398 |
-
"url": "^0.11.0",
|
4399 |
-
"util": "^0.10.3",
|
4400 |
-
"vm-browserify": "0.0.4"
|
4401 |
-
}
|
4402 |
-
},
|
4403 |
-
"node-sass": {
|
4404 |
-
"version": "4.7.2",
|
4405 |
-
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.7.2.tgz",
|
4406 |
-
"integrity": "sha512-CaV+wLqZ7//Jdom5aUFCpGNoECd7BbNhjuwdsX/LkXBrHl8eb1Wjw4HvWqcFvhr5KuNgAk8i/myf/MQ1YYeroA==",
|
4407 |
-
"dev": true,
|
4408 |
-
"requires": {
|
4409 |
-
"async-foreach": "^0.1.3",
|
4410 |
-
"chalk": "^1.1.1",
|
4411 |
-
"cross-spawn": "^3.0.0",
|
4412 |
-
"gaze": "^1.0.0",
|
4413 |
-
"get-stdin": "^4.0.1",
|
4414 |
-
"glob": "^7.0.3",
|
4415 |
-
"in-publish": "^2.0.0",
|
4416 |
-
"lodash.assign": "^4.2.0",
|
4417 |
-
"lodash.clonedeep": "^4.3.2",
|
4418 |
-
"lodash.mergewith": "^4.6.0",
|
4419 |
-
"meow": "^3.7.0",
|
4420 |
-
"mkdirp": "^0.5.1",
|
4421 |
-
"nan": "^2.3.2",
|
4422 |
-
"node-gyp": "^3.3.1",
|
4423 |
-
"npmlog": "^4.0.0",
|
4424 |
-
"request": "~2.79.0",
|
4425 |
-
"sass-graph": "^2.2.4",
|
4426 |
-
"stdout-stream": "^1.4.0",
|
4427 |
-
"true-case-path": "^1.0.2"
|
4428 |
-
}
|
4429 |
-
},
|
4430 |
-
"nopt": {
|
4431 |
-
"version": "3.0.6",
|
4432 |
-
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
|
4433 |
-
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
|
4434 |
-
"dev": true,
|
4435 |
-
"requires": {
|
4436 |
-
"abbrev": "1"
|
4437 |
-
}
|
4438 |
-
},
|
4439 |
-
"normalize-package-data": {
|
4440 |
-
"version": "2.4.0",
|
4441 |
-
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
|
4442 |
-
"integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
|
4443 |
-
"dev": true,
|
4444 |
-
"requires": {
|
4445 |
-
"hosted-git-info": "^2.1.4",
|
4446 |
-
"is-builtin-module": "^1.0.0",
|
4447 |
-
"semver": "2 || 3 || 4 || 5",
|
4448 |
-
"validate-npm-package-license": "^3.0.1"
|
4449 |
-
}
|
4450 |
-
},
|
4451 |
-
"normalize-path": {
|
4452 |
-
"version": "2.1.1",
|
4453 |
-
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
|
4454 |
-
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
|
4455 |
-
"dev": true,
|
4456 |
-
"requires": {
|
4457 |
-
"remove-trailing-separator": "^1.0.1"
|
4458 |
-
}
|
4459 |
-
},
|
4460 |
-
"normalize-range": {
|
4461 |
-
"version": "0.1.2",
|
4462 |
-
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
|
4463 |
-
"integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
|
4464 |
-
"dev": true
|
4465 |
-
},
|
4466 |
-
"normalize-url": {
|
4467 |
-
"version": "1.9.1",
|
4468 |
-
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
|
4469 |
-
"integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
|
4470 |
-
"dev": true,
|
4471 |
-
"requires": {
|
4472 |
-
"object-assign": "^4.0.1",
|
4473 |
-
"prepend-http": "^1.0.0",
|
4474 |
-
"query-string": "^4.1.0",
|
4475 |
-
"sort-keys": "^1.0.0"
|
4476 |
-
}
|
4477 |
-
},
|
4478 |
-
"npm": {
|
4479 |
-
"version": "6.3.0",
|
4480 |
-
"resolved": "https://registry.npmjs.org/npm/-/npm-6.3.0.tgz",
|
4481 |
-
"integrity": "sha512-oDtLFo3wXue/xe3pU/oks9VHS5501OAWlYrZrApZkFv7l2LXk+9CfPMbjbfZWK7Jqlc1jbNcJMkB6KZC7K/vEA==",
|
4482 |
-
"requires": {
|
4483 |
-
"JSONStream": "^1.3.3",
|
4484 |
-
"abbrev": "~1.1.1",
|
4485 |
-
"ansicolors": "~0.3.2",
|
4486 |
-
"ansistyles": "~0.1.3",
|
4487 |
-
"aproba": "~1.2.0",
|
4488 |
-
"archy": "~1.0.0",
|
4489 |
-
"bin-links": "^1.1.2",
|
4490 |
-
"bluebird": "~3.5.1",
|
4491 |
-
"byte-size": "^4.0.3",
|
4492 |
-
"cacache": "^11.1.0",
|
4493 |
-
"call-limit": "~1.1.0",
|
4494 |
-
"chownr": "~1.0.1",
|
4495 |
-
"cli-columns": "^3.1.2",
|
4496 |
-
"cli-table3": "^0.5.0",
|
4497 |
-
"cmd-shim": "~2.0.2",
|
4498 |
-
"columnify": "~1.5.4",
|
4499 |
-
"config-chain": "~1.1.11",
|
4500 |
-
"debuglog": "*",
|
4501 |
-
"detect-indent": "~5.0.0",
|
4502 |
-
"detect-newline": "^2.1.0",
|
4503 |
-
"dezalgo": "~1.0.3",
|
4504 |
-
"editor": "~1.0.0",
|
4505 |
-
"figgy-pudding": "^3.2.0",
|
4506 |
-
"find-npm-prefix": "^1.0.2",
|
4507 |
-
"fs-vacuum": "~1.2.10",
|
4508 |
-
"fs-write-stream-atomic": "~1.0.10",
|
4509 |
-
"gentle-fs": "^2.0.1",
|
4510 |
-
"glob": "~7.1.2",
|
4511 |
-
"graceful-fs": "~4.1.11",
|
4512 |
-
"has-unicode": "~2.0.1",
|
4513 |
-
"hosted-git-info": "^2.6.0",
|
4514 |
-
"iferr": "^1.0.0",
|
4515 |
-
"imurmurhash": "*",
|
4516 |
-
"inflight": "~1.0.6",
|
4517 |
-
"inherits": "~2.0.3",
|
4518 |
-
"ini": "^1.3.5",
|
4519 |
-
"init-package-json": "^1.10.3",
|
4520 |
-
"is-cidr": "^2.0.6",
|
4521 |
-
"json-parse-better-errors": "^1.0.2",
|
4522 |
-
"lazy-property": "~1.0.0",
|
4523 |
-
"libcipm": "^2.0.0",
|
4524 |
-
"libnpmhook": "^4.0.1",
|
4525 |
-
"libnpx": "^10.2.0",
|
4526 |
-
"lock-verify": "^2.0.2",
|
4527 |
-
"lockfile": "^1.0.4",
|
4528 |
-
"lodash._baseindexof": "*",
|
4529 |
-
"lodash._baseuniq": "~4.6.0",
|
4530 |
-
"lodash._bindcallback": "*",
|
4531 |
-
"lodash._cacheindexof": "*",
|
4532 |
-
"lodash._createcache": "*",
|
4533 |
-
"lodash._getnative": "*",
|
4534 |
-
"lodash.clonedeep": "~4.5.0",
|
4535 |
-
"lodash.restparam": "*",
|
4536 |
-
"lodash.union": "~4.6.0",
|
4537 |
-
"lodash.uniq": "~4.5.0",
|
4538 |
-
"lodash.without": "~4.4.0",
|
4539 |
-
"lru-cache": "^4.1.3",
|
4540 |
-
"meant": "~1.0.1",
|
4541 |
-
"mississippi": "^3.0.0",
|
4542 |
-
"mkdirp": "~0.5.1",
|
4543 |
-
"move-concurrently": "^1.0.1",
|
4544 |
-
"node-gyp": "^3.7.0",
|
4545 |
-
"nopt": "~4.0.1",
|
4546 |
-
"normalize-package-data": "~2.4.0",
|
4547 |
-
"npm-audit-report": "^1.3.1",
|
4548 |
-
"npm-cache-filename": "~1.0.2",
|
4549 |
-
"npm-install-checks": "~3.0.0",
|
4550 |
-
"npm-lifecycle": "^2.0.3",
|
4551 |
-
"npm-package-arg": "^6.1.0",
|
4552 |
-
"npm-packlist": "~1.1.10",
|
4553 |
-
"npm-pick-manifest": "^2.1.0",
|
4554 |
-
"npm-profile": "^3.0.2",
|
4555 |
-
"npm-registry-client": "^8.5.1",
|
4556 |
-
"npm-registry-fetch": "^1.1.0",
|
4557 |
-
"npm-user-validate": "~1.0.0",
|
4558 |
-
"npmlog": "~4.1.2",
|
4559 |
-
"once": "~1.4.0",
|
4560 |
-
"opener": "~1.4.3",
|
4561 |
-
"osenv": "^0.1.5",
|
4562 |
-
"pacote": "^8.1.6",
|
4563 |
-
"path-is-inside": "~1.0.2",
|
4564 |
-
"promise-inflight": "~1.0.1",
|
4565 |
-
"qrcode-terminal": "^0.12.0",
|
4566 |
-
"query-string": "^6.1.0",
|
4567 |
-
"qw": "~1.0.1",
|
4568 |
-
"read": "~1.0.7",
|
4569 |
-
"read-cmd-shim": "~1.0.1",
|
4570 |
-
"read-installed": "~4.0.3",
|
4571 |
-
"read-package-json": "^2.0.13",
|
4572 |
-
"read-package-tree": "^5.2.1",
|
4573 |
-
"readable-stream": "^2.3.6",
|
4574 |
-
"readdir-scoped-modules": "*",
|
4575 |
-
"request": "^2.81.0",
|
4576 |
-
"retry": "^0.12.0",
|
4577 |
-
"rimraf": "~2.6.2",
|
4578 |
-
"safe-buffer": "^5.1.2",
|
4579 |
-
"semver": "^5.5.0",
|
4580 |
-
"sha": "~2.0.1",
|
4581 |
-
"slide": "~1.1.6",
|
4582 |
-
"sorted-object": "~2.0.1",
|
4583 |
-
"sorted-union-stream": "~2.1.3",
|
4584 |
-
"ssri": "^6.0.0",
|
4585 |
-
"stringify-package": "^1.0.0",
|
4586 |
-
"tar": "^4.4.4",
|
4587 |
-
"text-table": "~0.2.0",
|
4588 |
-
"tiny-relative-date": "^1.3.0",
|
4589 |
-
"uid-number": "0.0.6",
|
4590 |
-
"umask": "~1.1.0",
|
4591 |
-
"unique-filename": "~1.1.0",
|
4592 |
-
"unpipe": "~1.0.0",
|
4593 |
-
"update-notifier": "^2.5.0",
|
4594 |
-
"uuid": "^3.3.2",
|
4595 |
-
"validate-npm-package-license": "^3.0.3",
|
4596 |
-
"validate-npm-package-name": "~3.0.0",
|
4597 |
-
"which": "^1.3.1",
|
4598 |
-
"worker-farm": "^1.6.0",
|
4599 |
-
"write-file-atomic": "^2.3.0"
|
4600 |
-
},
|
4601 |
-
"dependencies": {
|
4602 |
-
"JSONStream": {
|
4603 |
-
"version": "1.3.3",
|
4604 |
-
"bundled": true,
|
4605 |
-
"requires": {
|
4606 |
-
"jsonparse": "^1.2.0",
|
4607 |
-
"through": ">=2.2.7 <3"
|
4608 |
-
}
|
4609 |
-
},
|
4610 |
-
"abbrev": {
|
4611 |
-
"version": "1.1.1",
|
4612 |
-
"bundled": true
|
4613 |
-
},
|
4614 |
-
"agent-base": {
|
4615 |
-
"version": "4.2.0",
|
4616 |
-
"bundled": true,
|
4617 |
-
"requires": {
|
4618 |
-
"es6-promisify": "^5.0.0"
|
4619 |
-
}
|
4620 |
-
},
|
4621 |
-
"agentkeepalive": {
|
4622 |
-
"version": "3.4.1",
|
4623 |
-
"bundled": true,
|
4624 |
-
"requires": {
|
4625 |
-
"humanize-ms": "^1.2.1"
|
4626 |
-
}
|
4627 |
-
},
|
4628 |
-
"ansi-align": {
|
4629 |
-
"version": "2.0.0",
|
4630 |
-
"bundled": true,
|
4631 |
-
"requires": {
|
4632 |
-
"string-width": "^2.0.0"
|
4633 |
-
}
|
4634 |
-
},
|
4635 |
-
"ansi-regex": {
|
4636 |
-
"version": "2.1.1",
|
4637 |
-
"bundled": true
|
4638 |
-
},
|
4639 |
-
"ansi-styles": {
|
4640 |
-
"version": "3.2.1",
|
4641 |
-
"bundled": true,
|
4642 |
-
"requires": {
|
4643 |
-
"color-convert": "^1.9.0"
|
4644 |
-
}
|
4645 |
-
},
|
4646 |
-
"ansicolors": {
|
4647 |
-
"version": "0.3.2",
|
4648 |
-
"bundled": true
|
4649 |
-
},
|
4650 |
-
"ansistyles": {
|
4651 |
-
"version": "0.1.3",
|
4652 |
-
"bundled": true
|
4653 |
-
},
|
4654 |
-
"aproba": {
|
4655 |
-
"version": "1.2.0",
|
4656 |
-
"bundled": true
|
4657 |
-
},
|
4658 |
-
"archy": {
|
4659 |
-
"version": "1.0.0",
|
4660 |
-
"bundled": true
|
4661 |
-
},
|
4662 |
-
"are-we-there-yet": {
|
4663 |
-
"version": "1.1.4",
|
4664 |
-
"bundled": true,
|
4665 |
-
"requires": {
|
4666 |
-
"delegates": "^1.0.0",
|
4667 |
-
"readable-stream": "^2.0.6"
|
4668 |
-
}
|
4669 |
-
},
|
4670 |
-
"asap": {
|
4671 |
-
"version": "2.0.6",
|
4672 |
-
"bundled": true
|
4673 |
-
},
|
4674 |
-
"asn1": {
|
4675 |
-
"version": "0.2.3",
|
4676 |
-
"bundled": true
|
4677 |
-
},
|
4678 |
-
"assert-plus": {
|
4679 |
-
"version": "0.2.0",
|
4680 |
-
"bundled": true
|
4681 |
-
},
|
4682 |
-
"asynckit": {
|
4683 |
-
"version": "0.4.0",
|
4684 |
-
"bundled": true
|
4685 |
-
},
|
4686 |
-
"aws-sign2": {
|
4687 |
-
"version": "0.6.0",
|
4688 |
-
"bundled": true
|
4689 |
-
},
|
4690 |
-
"aws4": {
|
4691 |
-
"version": "1.7.0",
|
4692 |
-
"bundled": true
|
4693 |
-
},
|
4694 |
-
"balanced-match": {
|
4695 |
-
"version": "1.0.0",
|
4696 |
-
"bundled": true
|
4697 |
-
},
|
4698 |
-
"bcrypt-pbkdf": {
|
4699 |
-
"version": "1.0.2",
|
4700 |
-
"bundled": true,
|
4701 |
-
"optional": true,
|
4702 |
-
"requires": {
|
4703 |
-
"tweetnacl": "^0.14.3"
|
4704 |
-
}
|
4705 |
-
},
|
4706 |
-
"bin-links": {
|
4707 |
-
"version": "1.1.2",
|
4708 |
-
"bundled": true,
|
4709 |
-
"requires": {
|
4710 |
-
"bluebird": "^3.5.0",
|
4711 |
-
"cmd-shim": "^2.0.2",
|
4712 |
-
"gentle-fs": "^2.0.0",
|
4713 |
-
"graceful-fs": "^4.1.11",
|
4714 |
-
"write-file-atomic": "^2.3.0"
|
4715 |
-
}
|
4716 |
-
},
|
4717 |
-
"block-stream": {
|
4718 |
-
"version": "0.0.9",
|
4719 |
-
"bundled": true,
|
4720 |
-
"requires": {
|
4721 |
-
"inherits": "~2.0.0"
|
4722 |
-
}
|
4723 |
-
},
|
4724 |
-
"bluebird": {
|
4725 |
-
"version": "3.5.1",
|
4726 |
-
"bundled": true
|
4727 |
-
},
|
4728 |
-
"boom": {
|
4729 |
-
"version": "2.10.1",
|
4730 |
-
"bundled": true,
|
4731 |
-
"requires": {
|
4732 |
-
"hoek": "2.x.x"
|
4733 |
-
}
|
4734 |
-
},
|
4735 |
-
"boxen": {
|
4736 |
-
"version": "1.3.0",
|
4737 |
-
"bundled": true,
|
4738 |
-
"requires": {
|
4739 |
-
"ansi-align": "^2.0.0",
|
4740 |
-
"camelcase": "^4.0.0",
|
4741 |
-
"chalk": "^2.0.1",
|
4742 |
-
"cli-boxes": "^1.0.0",
|
4743 |
-
"string-width": "^2.0.0",
|
4744 |
-
"term-size": "^1.2.0",
|
4745 |
-
"widest-line": "^2.0.0"
|
4746 |
-
}
|
4747 |
-
},
|
4748 |
-
"brace-expansion": {
|
4749 |
-
"version": "1.1.11",
|
4750 |
-
"bundled": true,
|
4751 |
-
"requires": {
|
4752 |
-
"balanced-match": "^1.0.0",
|
4753 |
-
"concat-map": "0.0.1"
|
4754 |
-
}
|
4755 |
-
},
|
4756 |
-
"buffer-from": {
|
4757 |
-
"version": "1.0.0",
|
4758 |
-
"bundled": true
|
4759 |
-
},
|
4760 |
-
"builtin-modules": {
|
4761 |
-
"version": "1.1.1",
|
4762 |
-
"bundled": true
|
4763 |
-
},
|
4764 |
-
"builtins": {
|
4765 |
-
"version": "1.0.3",
|
4766 |
-
"bundled": true
|
4767 |
-
},
|
4768 |
-
"byline": {
|
4769 |
-
"version": "5.0.0",
|
4770 |
-
"bundled": true
|
4771 |
-
},
|
4772 |
-
"byte-size": {
|
4773 |
-
"version": "4.0.3",
|
4774 |
-
"bundled": true
|
4775 |
-
},
|
4776 |
-
"cacache": {
|
4777 |
-
"version": "11.1.0",
|
4778 |
-
"bundled": true,
|
4779 |
-
"requires": {
|
4780 |
-
"bluebird": "^3.5.1",
|
4781 |
-
"chownr": "^1.0.1",
|
4782 |
-
"figgy-pudding": "^3.1.0",
|
4783 |
-
"glob": "^7.1.2",
|
4784 |
-
"graceful-fs": "^4.1.11",
|
4785 |
-
"lru-cache": "^4.1.3",
|
4786 |
-
"mississippi": "^3.0.0",
|
4787 |
-
"mkdirp": "^0.5.1",
|
4788 |
-
"move-concurrently": "^1.0.1",
|
4789 |
-
"promise-inflight": "^1.0.1",
|
4790 |
-
"rimraf": "^2.6.2",
|
4791 |
-
"ssri": "^6.0.0",
|
4792 |
-
"unique-filename": "^1.1.0",
|
4793 |
-
"y18n": "^4.0.0"
|
4794 |
-
}
|
4795 |
-
},
|
4796 |
-
"call-limit": {
|
4797 |
-
"version": "1.1.0",
|
4798 |
-
"bundled": true
|
4799 |
-
},
|
4800 |
-
"camelcase": {
|
4801 |
-
"version": "4.1.0",
|
4802 |
-
"bundled": true
|
4803 |
-
},
|
4804 |
-
"capture-stack-trace": {
|
4805 |
-
"version": "1.0.0",
|
4806 |
-
"bundled": true
|
4807 |
-
},
|
4808 |
-
"caseless": {
|
4809 |
-
"version": "0.12.0",
|
4810 |
-
"bundled": true
|
4811 |
-
},
|
4812 |
-
"chalk": {
|
4813 |
-
"version": "2.4.1",
|
4814 |
-
"bundled": true,
|
4815 |
-
"requires": {
|
4816 |
-
"ansi-styles": "^3.2.1",
|
4817 |
-
"escape-string-regexp": "^1.0.5",
|
4818 |
-
"supports-color": "^5.3.0"
|
4819 |
-
}
|
4820 |
-
},
|
4821 |
-
"chownr": {
|
4822 |
-
"version": "1.0.1",
|
4823 |
-
"bundled": true
|
4824 |
-
},
|
4825 |
-
"ci-info": {
|
4826 |
-
"version": "1.1.3",
|
4827 |
-
"bundled": true
|
4828 |
-
},
|
4829 |
-
"cidr-regex": {
|
4830 |
-
"version": "2.0.9",
|
4831 |
-
"bundled": true,
|
4832 |
-
"requires": {
|
4833 |
-
"ip-regex": "^2.1.0"
|
4834 |
-
}
|
4835 |
-
},
|
4836 |
-
"cli-boxes": {
|
4837 |
-
"version": "1.0.0",
|
4838 |
-
"bundled": true
|
4839 |
-
},
|
4840 |
-
"cli-columns": {
|
4841 |
-
"version": "3.1.2",
|
4842 |
-
"bundled": true,
|
4843 |
-
"requires": {
|
4844 |
-
"string-width": "^2.0.0",
|
4845 |
-
"strip-ansi": "^3.0.1"
|
4846 |
-
}
|
4847 |
-
},
|
4848 |
-
"cli-table3": {
|
4849 |
-
"version": "0.5.0",
|
4850 |
-
"bundled": true,
|
4851 |
-
"requires": {
|
4852 |
-
"colors": "^1.1.2",
|
4853 |
-
"object-assign": "^4.1.0",
|
4854 |
-
"string-width": "^2.1.1"
|
4855 |
-
}
|
4856 |
-
},
|
4857 |
-
"cliui": {
|
4858 |
-
"version": "4.1.0",
|
4859 |
-
"bundled": true,
|
4860 |
-
"requires": {
|
4861 |
-
"string-width": "^2.1.1",
|
4862 |
-
"strip-ansi": "^4.0.0",
|
4863 |
-
"wrap-ansi": "^2.0.0"
|
4864 |
-
},
|
4865 |
-
"dependencies": {
|
4866 |
-
"ansi-regex": {
|
4867 |
-
"version": "3.0.0",
|
4868 |
-
"bundled": true
|
4869 |
-
},
|
4870 |
-
"strip-ansi": {
|
4871 |
-
"version": "4.0.0",
|
4872 |
-
"bundled": true,
|
4873 |
-
"requires": {
|
4874 |
-
"ansi-regex": "^3.0.0"
|
4875 |
-
}
|
4876 |
-
}
|
4877 |
-
}
|
4878 |
-
},
|
4879 |
-
"clone": {
|
4880 |
-
"version": "1.0.4",
|
4881 |
-
"bundled": true
|
4882 |
-
},
|
4883 |
-
"cmd-shim": {
|
4884 |
-
"version": "2.0.2",
|
4885 |
-
"bundled": true,
|
4886 |
-
"requires": {
|
4887 |
-
"graceful-fs": "^4.1.2",
|
4888 |
-
"mkdirp": "~0.5.0"
|
4889 |
-
}
|
4890 |
-
},
|
4891 |
-
"co": {
|
4892 |
-
"version": "4.6.0",
|
4893 |
-
"bundled": true
|
4894 |
-
},
|
4895 |
-
"code-point-at": {
|
4896 |
-
"version": "1.1.0",
|
4897 |
-
"bundled": true
|
4898 |
-
},
|
4899 |
-
"color-convert": {
|
4900 |
-
"version": "1.9.1",
|
4901 |
-
"bundled": true,
|
4902 |
-
"requires": {
|
4903 |
-
"color-name": "^1.1.1"
|
4904 |
-
}
|
4905 |
-
},
|
4906 |
-
"color-name": {
|
4907 |
-
"version": "1.1.3",
|
4908 |
-
"bundled": true
|
4909 |
-
},
|
4910 |
-
"colors": {
|
4911 |
-
"version": "1.3.0",
|
4912 |
-
"bundled": true,
|
4913 |
-
"optional": true
|
4914 |
-
},
|
4915 |
-
"columnify": {
|
4916 |
-
"version": "1.5.4",
|
4917 |
-
"bundled": true,
|
4918 |
-
"requires": {
|
4919 |
-
"strip-ansi": "^3.0.0",
|
4920 |
-
"wcwidth": "^1.0.0"
|
4921 |
-
}
|
4922 |
-
},
|
4923 |
-
"combined-stream": {
|
4924 |
-
"version": "1.0.6",
|
4925 |
-
"bundled": true,
|
4926 |
-
"requires": {
|
4927 |
-
"delayed-stream": "~1.0.0"
|
4928 |
-
}
|
4929 |
-
},
|
4930 |
-
"concat-map": {
|
4931 |
-
"version": "0.0.1",
|
4932 |
-
"bundled": true
|
4933 |
-
},
|
4934 |
-
"concat-stream": {
|
4935 |
-
"version": "1.6.2",
|
4936 |
-
"bundled": true,
|
4937 |
-
"requires": {
|
4938 |
-
"buffer-from": "^1.0.0",
|
4939 |
-
"inherits": "^2.0.3",
|
4940 |
-
"readable-stream": "^2.2.2",
|
4941 |
-
"typedarray": "^0.0.6"
|
4942 |
-
}
|
4943 |
-
},
|
4944 |
-
"config-chain": {
|
4945 |
-
"version": "1.1.11",
|
4946 |
-
"bundled": true,
|
4947 |
-
"requires": {
|
4948 |
-
"ini": "^1.3.4",
|
4949 |
-
"proto-list": "~1.2.1"
|
4950 |
-
}
|
4951 |
-
},
|
4952 |
-
"configstore": {
|
4953 |
-
"version": "3.1.2",
|
4954 |
-
"bundled": true,
|
4955 |
-
"requires": {
|
4956 |
-
"dot-prop": "^4.1.0",
|
4957 |
-
"graceful-fs": "^4.1.2",
|
4958 |
-
"make-dir": "^1.0.0",
|
4959 |
-
"unique-string": "^1.0.0",
|
4960 |
-
"write-file-atomic": "^2.0.0",
|
4961 |
-
"xdg-basedir": "^3.0.0"
|
4962 |
-
}
|
4963 |
-
},
|
4964 |
-
"console-control-strings": {
|
4965 |
-
"version": "1.1.0",
|
4966 |
-
"bundled": true
|
4967 |
-
},
|
4968 |
-
"copy-concurrently": {
|
4969 |
-
"version": "1.0.5",
|
4970 |
-
"bundled": true,
|
4971 |
-
"requires": {
|
4972 |
-
"aproba": "^1.1.1",
|
4973 |
-
"fs-write-stream-atomic": "^1.0.8",
|
4974 |
-
"iferr": "^0.1.5",
|
4975 |
-
"mkdirp": "^0.5.1",
|
4976 |
-
"rimraf": "^2.5.4",
|
4977 |
-
"run-queue": "^1.0.0"
|
4978 |
-
},
|
4979 |
-
"dependencies": {
|
4980 |
-
"iferr": {
|
4981 |
-
"version": "0.1.5",
|
4982 |
-
"bundled": true
|
4983 |
-
}
|
4984 |
-
}
|
4985 |
-
},
|
4986 |
-
"core-util-is": {
|
4987 |
-
"version": "1.0.2",
|
4988 |
-
"bundled": true
|
4989 |
-
},
|
4990 |
-
"create-error-class": {
|
4991 |
-
"version": "3.0.2",
|
4992 |
-
"bundled": true,
|
4993 |
-
"requires": {
|
4994 |
-
"capture-stack-trace": "^1.0.0"
|
4995 |
-
}
|
4996 |
-
},
|
4997 |
-
"cross-spawn": {
|
4998 |
-
"version": "5.1.0",
|
4999 |
-
"bundled": true,
|
5000 |
-
"requires": {
|
5001 |
-
"lru-cache": "^4.0.1",
|
5002 |
-
"shebang-command": "^1.2.0",
|
5003 |
-
"which": "^1.2.9"
|
5004 |
-
}
|
5005 |
-
},
|
5006 |
-
"cryptiles": {
|
5007 |
-
"version": "2.0.5",
|
5008 |
-
"bundled": true,
|
5009 |
-
"requires": {
|
5010 |
-
"boom": "2.x.x"
|
5011 |
-
}
|
5012 |
-
},
|
5013 |
-
"crypto-random-string": {
|
5014 |
-
"version": "1.0.0",
|
5015 |
-
"bundled": true
|
5016 |
-
},
|
5017 |
-
"cyclist": {
|
5018 |
-
"version": "0.2.2",
|
5019 |
-
"bundled": true
|
5020 |
-
},
|
5021 |
-
"dashdash": {
|
5022 |
-
"version": "1.14.1",
|
5023 |
-
"bundled": true,
|
5024 |
-
"requires": {
|
5025 |
-
"assert-plus": "^1.0.0"
|
5026 |
-
},
|
5027 |
-
"dependencies": {
|
5028 |
-
"assert-plus": {
|
5029 |
-
"version": "1.0.0",
|
5030 |
-
"bundled": true
|
5031 |
-
}
|
5032 |
-
}
|
5033 |
-
},
|
5034 |
-
"debug": {
|
5035 |
-
"version": "3.1.0",
|
5036 |
-
"bundled": true,
|
5037 |
-
"requires": {
|
5038 |
-
"ms": "2.0.0"
|
5039 |
-
},
|
5040 |
-
"dependencies": {
|
5041 |
-
"ms": {
|
5042 |
-
"version": "2.0.0",
|
5043 |
-
"bundled": true
|
5044 |
-
}
|
5045 |
-
}
|
5046 |
-
},
|
5047 |
-
"debuglog": {
|
5048 |
-
"version": "1.0.1",
|
5049 |
-
"bundled": true
|
5050 |
-
},
|
5051 |
-
"decamelize": {
|
5052 |
-
"version": "1.2.0",
|
5053 |
-
"bundled": true
|
5054 |
-
},
|
5055 |
-
"decode-uri-component": {
|
5056 |
-
"version": "0.2.0",
|
5057 |
-
"bundled": true
|
5058 |
-
},
|
5059 |
-
"deep-extend": {
|
5060 |
-
"version": "0.5.1",
|
5061 |
-
"bundled": true
|
5062 |
-
},
|
5063 |
-
"defaults": {
|
5064 |
-
"version": "1.0.3",
|
5065 |
-
"bundled": true,
|
5066 |
-
"requires": {
|
5067 |
-
"clone": "^1.0.2"
|
5068 |
-
}
|
5069 |
-
},
|
5070 |
-
"delayed-stream": {
|
5071 |
-
"version": "1.0.0",
|
5072 |
-
"bundled": true
|
5073 |
-
},
|
5074 |
-
"delegates": {
|
5075 |
-
"version": "1.0.0",
|
5076 |
-
"bundled": true
|
5077 |
-
},
|
5078 |
-
"detect-indent": {
|
5079 |
-
"version": "5.0.0",
|
5080 |
-
"bundled": true
|
5081 |
-
},
|
5082 |
-
"detect-newline": {
|
5083 |
-
"version": "2.1.0",
|
5084 |
-
"bundled": true
|
5085 |
-
},
|
5086 |
-
"dezalgo": {
|
5087 |
-
"version": "1.0.3",
|
5088 |
-
"bundled": true,
|
5089 |
-
"requires": {
|
5090 |
-
"asap": "^2.0.0",
|
5091 |
-
"wrappy": "1"
|
5092 |
-
}
|
5093 |
-
},
|
5094 |
-
"dot-prop": {
|
5095 |
-
"version": "4.2.0",
|
5096 |
-
"bundled": true,
|
5097 |
-
"requires": {
|
5098 |
-
"is-obj": "^1.0.0"
|
5099 |
-
}
|
5100 |
-
},
|
5101 |
-
"dotenv": {
|
5102 |
-
"version": "5.0.1",
|
5103 |
-
"bundled": true
|
5104 |
-
},
|
5105 |
-
"duplexer3": {
|
5106 |
-
"version": "0.1.4",
|
5107 |
-
"bundled": true
|
5108 |
-
},
|
5109 |
-
"duplexify": {
|
5110 |
-
"version": "3.6.0",
|
5111 |
-
"bundled": true,
|
5112 |
-
"requires": {
|
5113 |
-
"end-of-stream": "^1.0.0",
|
5114 |
-
"inherits": "^2.0.1",
|
5115 |
-
"readable-stream": "^2.0.0",
|
5116 |
-
"stream-shift": "^1.0.0"
|
5117 |
-
}
|
5118 |
-
},
|
5119 |
-
"ecc-jsbn": {
|
5120 |
-
"version": "0.1.1",
|
5121 |
-
"bundled": true,
|
5122 |
-
"optional": true,
|
5123 |
-
"requires": {
|
5124 |
-
"jsbn": "~0.1.0"
|
5125 |
-
}
|
5126 |
-
},
|
5127 |
-
"editor": {
|
5128 |
-
"version": "1.0.0",
|
5129 |
-
"bundled": true
|
5130 |
-
},
|
5131 |
-
"encoding": {
|
5132 |
-
"version": "0.1.12",
|
5133 |
-
"bundled": true,
|
5134 |
-
"requires": {
|
5135 |
-
"iconv-lite": "~0.4.13"
|
5136 |
-
}
|
5137 |
-
},
|
5138 |
-
"end-of-stream": {
|
5139 |
-
"version": "1.4.1",
|
5140 |
-
"bundled": true,
|
5141 |
-
"requires": {
|
5142 |
-
"once": "^1.4.0"
|
5143 |
-
}
|
5144 |
-
},
|
5145 |
-
"err-code": {
|
5146 |
-
"version": "1.1.2",
|
5147 |
-
"bundled": true
|
5148 |
-
},
|
5149 |
-
"errno": {
|
5150 |
-
"version": "0.1.7",
|
5151 |
-
"bundled": true,
|
5152 |
-
"requires": {
|
5153 |
-
"prr": "~1.0.1"
|
5154 |
-
}
|
5155 |
-
},
|
5156 |
-
"es6-promise": {
|
5157 |
-
"version": "4.2.4",
|
5158 |
-
"bundled": true
|
5159 |
-
},
|
5160 |
-
"es6-promisify": {
|
5161 |
-
"version": "5.0.0",
|
5162 |
-
"bundled": true,
|
5163 |
-
"requires": {
|
5164 |
-
"es6-promise": "^4.0.3"
|
5165 |
-
}
|
5166 |
-
},
|
5167 |
-
"escape-string-regexp": {
|
5168 |
-
"version": "1.0.5",
|
5169 |
-
"bundled": true
|
5170 |
-
},
|
5171 |
-
"execa": {
|
5172 |
-
"version": "0.7.0",
|
5173 |
-
"bundled": true,
|
5174 |
-
"requires": {
|
5175 |
-
"cross-spawn": "^5.0.1",
|
5176 |
-
"get-stream": "^3.0.0",
|
5177 |
-
"is-stream": "^1.1.0",
|
5178 |
-
"npm-run-path": "^2.0.0",
|
5179 |
-
"p-finally": "^1.0.0",
|
5180 |
-
"signal-exit": "^3.0.0",
|
5181 |
-
"strip-eof": "^1.0.0"
|
5182 |
-
}
|
5183 |
-
},
|
5184 |
-
"extend": {
|
5185 |
-
"version": "3.0.1",
|
5186 |
-
"bundled": true
|
5187 |
-
},
|
5188 |
-
"extsprintf": {
|
5189 |
-
"version": "1.3.0",
|
5190 |
-
"bundled": true
|
5191 |
-
},
|
5192 |
-
"figgy-pudding": {
|
5193 |
-
"version": "3.2.0",
|
5194 |
-
"bundled": true
|
5195 |
-
},
|
5196 |
-
"find-npm-prefix": {
|
5197 |
-
"version": "1.0.2",
|
5198 |
-
"bundled": true
|
5199 |
-
},
|
5200 |
-
"find-up": {
|
5201 |
-
"version": "2.1.0",
|
5202 |
-
"bundled": true,
|
5203 |
-
"requires": {
|
5204 |
-
"locate-path": "^2.0.0"
|
5205 |
-
}
|
5206 |
-
},
|
5207 |
-
"flush-write-stream": {
|
5208 |
-
"version": "1.0.3",
|
5209 |
-
"bundled": true,
|
5210 |
-
"requires": {
|
5211 |
-
"inherits": "^2.0.1",
|
5212 |
-
"readable-stream": "^2.0.4"
|
5213 |
-
}
|
5214 |
-
},
|
5215 |
-
"forever-agent": {
|
5216 |
-
"version": "0.6.1",
|
5217 |
-
"bundled": true
|
5218 |
-
},
|
5219 |
-
"form-data": {
|
5220 |
-
"version": "2.1.4",
|
5221 |
-
"bundled": true,
|
5222 |
-
"requires": {
|
5223 |
-
"asynckit": "^0.4.0",
|
5224 |
-
"combined-stream": "^1.0.5",
|
5225 |
-
"mime-types": "^2.1.12"
|
5226 |
-
}
|
5227 |
-
},
|
5228 |
-
"from2": {
|
5229 |
-
"version": "2.3.0",
|
5230 |
-
"bundled": true,
|
5231 |
-
"requires": {
|
5232 |
-
"inherits": "^2.0.1",
|
5233 |
-
"readable-stream": "^2.0.0"
|
5234 |
-
}
|
5235 |
-
},
|
5236 |
-
"fs-minipass": {
|
5237 |
-
"version": "1.2.5",
|
5238 |
-
"bundled": true,
|
5239 |
-
"requires": {
|
5240 |
-
"minipass": "^2.2.1"
|
5241 |
-
}
|
5242 |
-
},
|
5243 |
-
"fs-vacuum": {
|
5244 |
-
"version": "1.2.10",
|
5245 |
-
"bundled": true,
|
5246 |
-
"requires": {
|
5247 |
-
"graceful-fs": "^4.1.2",
|
5248 |
-
"path-is-inside": "^1.0.1",
|
5249 |
-
"rimraf": "^2.5.2"
|
5250 |
-
}
|
5251 |
-
},
|
5252 |
-
"fs-write-stream-atomic": {
|
5253 |
-
"version": "1.0.10",
|
5254 |
-
"bundled": true,
|
5255 |
-
"requires": {
|
5256 |
-
"graceful-fs": "^4.1.2",
|
5257 |
-
"iferr": "^0.1.5",
|
5258 |
-
"imurmurhash": "^0.1.4",
|
5259 |
-
"readable-stream": "1 || 2"
|
5260 |
-
},
|
5261 |
-
"dependencies": {
|
5262 |
-
"iferr": {
|
5263 |
-
"version": "0.1.5",
|
5264 |
-
"bundled": true
|
5265 |
-
}
|
5266 |
-
}
|
5267 |
-
},
|
5268 |
-
"fs.realpath": {
|
5269 |
-
"version": "1.0.0",
|
5270 |
-
"bundled": true
|
5271 |
-
},
|
5272 |
-
"fstream": {
|
5273 |
-
"version": "1.0.11",
|
5274 |
-
"bundled": true,
|
5275 |
-
"requires": {
|
5276 |
-
"graceful-fs": "^4.1.2",
|
5277 |
-
"inherits": "~2.0.0",
|
5278 |
-
"mkdirp": ">=0.5 0",
|
5279 |
-
"rimraf": "2"
|
5280 |
-
}
|
5281 |
-
},
|
5282 |
-
"gauge": {
|
5283 |
-
"version": "2.7.4",
|
5284 |
-
"bundled": true,
|
5285 |
-
"requires": {
|
5286 |
-
"aproba": "^1.0.3",
|
5287 |
-
"console-control-strings": "^1.0.0",
|
5288 |
-
"has-unicode": "^2.0.0",
|
5289 |
-
"object-assign": "^4.1.0",
|
5290 |
-
"signal-exit": "^3.0.0",
|
5291 |
-
"string-width": "^1.0.1",
|
5292 |
-
"strip-ansi": "^3.0.1",
|
5293 |
-
"wide-align": "^1.1.0"
|
5294 |
-
},
|
5295 |
-
"dependencies": {
|
5296 |
-
"string-width": {
|
5297 |
-
"version": "1.0.2",
|
5298 |
-
"bundled": true,
|
5299 |
-
"requires": {
|
5300 |
-
"code-point-at": "^1.0.0",
|
5301 |
-
"is-fullwidth-code-point": "^1.0.0",
|
5302 |
-
"strip-ansi": "^3.0.0"
|
5303 |
-
}
|
5304 |
-
}
|
5305 |
-
}
|
5306 |
-
},
|
5307 |
-
"genfun": {
|
5308 |
-
"version": "4.0.1",
|
5309 |
-
"bundled": true
|
5310 |
-
},
|
5311 |
-
"gentle-fs": {
|
5312 |
-
"version": "2.0.1",
|
5313 |
-
"bundled": true,
|
5314 |
-
"requires": {
|
5315 |
-
"aproba": "^1.1.2",
|
5316 |
-
"fs-vacuum": "^1.2.10",
|
5317 |
-
"graceful-fs": "^4.1.11",
|
5318 |
-
"iferr": "^0.1.5",
|
5319 |
-
"mkdirp": "^0.5.1",
|
5320 |
-
"path-is-inside": "^1.0.2",
|
5321 |
-
"read-cmd-shim": "^1.0.1",
|
5322 |
-
"slide": "^1.1.6"
|
5323 |
-
},
|
5324 |
-
"dependencies": {
|
5325 |
-
"iferr": {
|
5326 |
-
"version": "0.1.5",
|
5327 |
-
"bundled": true
|
5328 |
-
}
|
5329 |
-
}
|
5330 |
-
},
|
5331 |
-
"get-caller-file": {
|
5332 |
-
"version": "1.0.2",
|
5333 |
-
"bundled": true
|
5334 |
-
},
|
5335 |
-
"get-stream": {
|
5336 |
-
"version": "3.0.0",
|
5337 |
-
"bundled": true
|
5338 |
-
},
|
5339 |
-
"getpass": {
|
5340 |
-
"version": "0.1.7",
|
5341 |
-
"bundled": true,
|
5342 |
-
"requires": {
|
5343 |
-
"assert-plus": "^1.0.0"
|
5344 |
-
},
|
5345 |
-
"dependencies": {
|
5346 |
-
"assert-plus": {
|
5347 |
-
"version": "1.0.0",
|
5348 |
-
"bundled": true
|
5349 |
-
}
|
5350 |
-
}
|
5351 |
-
},
|
5352 |
-
"glob": {
|
5353 |
-
"version": "7.1.2",
|
5354 |
-
"bundled": true,
|
5355 |
-
"requires": {
|
5356 |
-
"fs.realpath": "^1.0.0",
|
5357 |
-
"inflight": "^1.0.4",
|
5358 |
-
"inherits": "2",
|
5359 |
-
"minimatch": "^3.0.4",
|
5360 |
-
"once": "^1.3.0",
|
5361 |
-
"path-is-absolute": "^1.0.0"
|
5362 |
-
}
|
5363 |
-
},
|
5364 |
-
"global-dirs": {
|
5365 |
-
"version": "0.1.1",
|
5366 |
-
"bundled": true,
|
5367 |
-
"requires": {
|
5368 |
-
"ini": "^1.3.4"
|
5369 |
-
}
|
5370 |
-
},
|
5371 |
-
"got": {
|
5372 |
-
"version": "6.7.1",
|
5373 |
-
"bundled": true,
|
5374 |
-
"requires": {
|
5375 |
-
"create-error-class": "^3.0.0",
|
5376 |
-
"duplexer3": "^0.1.4",
|
5377 |
-
"get-stream": "^3.0.0",
|
5378 |
-
"is-redirect": "^1.0.0",
|
5379 |
-
"is-retry-allowed": "^1.0.0",
|
5380 |
-
"is-stream": "^1.0.0",
|
5381 |
-
"lowercase-keys": "^1.0.0",
|
5382 |
-
"safe-buffer": "^5.0.1",
|
5383 |
-
"timed-out": "^4.0.0",
|
5384 |
-
"unzip-response": "^2.0.1",
|
5385 |
-
"url-parse-lax": "^1.0.0"
|
5386 |
-
}
|
5387 |
-
},
|
5388 |
-
"graceful-fs": {
|
5389 |
-
"version": "4.1.11",
|
5390 |
-
"bundled": true
|
5391 |
-
},
|
5392 |
-
"har-schema": {
|
5393 |
-
"version": "1.0.5",
|
5394 |
-
"bundled": true
|
5395 |
-
},
|
5396 |
-
"har-validator": {
|
5397 |
-
"version": "4.2.1",
|
5398 |
-
"bundled": true,
|
5399 |
-
"requires": {
|
5400 |
-
"ajv": "^4.9.1",
|
5401 |
-
"har-schema": "^1.0.5"
|
5402 |
-
},
|
5403 |
-
"dependencies": {
|
5404 |
-
"ajv": {
|
5405 |
-
"version": "4.11.8",
|
5406 |
-
"bundled": true,
|
5407 |
-
"requires": {
|
5408 |
-
"co": "^4.6.0",
|
5409 |
-
"json-stable-stringify": "^1.0.1"
|
5410 |
-
}
|
5411 |
-
}
|
5412 |
-
}
|
5413 |
-
},
|
5414 |
-
"has-flag": {
|
5415 |
-
"version": "3.0.0",
|
5416 |
-
"bundled": true
|
5417 |
-
},
|
5418 |
-
"has-unicode": {
|
5419 |
-
"version": "2.0.1",
|
5420 |
-
"bundled": true
|
5421 |
-
},
|
5422 |
-
"hawk": {
|
5423 |
-
"version": "3.1.3",
|
5424 |
-
"bundled": true,
|
5425 |
-
"requires": {
|
5426 |
-
"boom": "2.x.x",
|
5427 |
-
"cryptiles": "2.x.x",
|
5428 |
-
"hoek": "2.x.x",
|
5429 |
-
"sntp": "1.x.x"
|
5430 |
-
}
|
5431 |
-
},
|
5432 |
-
"hoek": {
|
5433 |
-
"version": "2.16.3",
|
5434 |
-
"bundled": true
|
5435 |
-
},
|
5436 |
-
"hosted-git-info": {
|
5437 |
-
"version": "2.6.0",
|
5438 |
-
"bundled": true
|
5439 |
-
},
|
5440 |
-
"http-cache-semantics": {
|
5441 |
-
"version": "3.8.1",
|
5442 |
-
"bundled": true
|
5443 |
-
},
|
5444 |
-
"http-proxy-agent": {
|
5445 |
-
"version": "2.1.0",
|
5446 |
-
"bundled": true,
|
5447 |
-
"requires": {
|
5448 |
-
"agent-base": "4",
|
5449 |
-
"debug": "3.1.0"
|
5450 |
-
}
|
5451 |
-
},
|
5452 |
-
"http-signature": {
|
5453 |
-
"version": "1.1.1",
|
5454 |
-
"bundled": true,
|
5455 |
-
"requires": {
|
5456 |
-
"assert-plus": "^0.2.0",
|
5457 |
-
"jsprim": "^1.2.2",
|
5458 |
-
"sshpk": "^1.7.0"
|
5459 |
-
}
|
5460 |
-
},
|
5461 |
-
"https-proxy-agent": {
|
5462 |
-
"version": "2.2.1",
|
5463 |
-
"bundled": true,
|
5464 |
-
"requires": {
|
5465 |
-
"agent-base": "^4.1.0",
|
5466 |
-
"debug": "^3.1.0"
|
5467 |
-
}
|
5468 |
-
},
|
5469 |
-
"humanize-ms": {
|
5470 |
-
"version": "1.2.1",
|
5471 |
-
"bundled": true,
|
5472 |
-
"requires": {
|
5473 |
-
"ms": "^2.0.0"
|
5474 |
-
}
|
5475 |
-
},
|
5476 |
-
"iconv-lite": {
|
5477 |
-
"version": "0.4.23",
|
5478 |
-
"bundled": true,
|
5479 |
-
"requires": {
|
5480 |
-
"safer-buffer": ">= 2.1.2 < 3"
|
5481 |
-
}
|
5482 |
-
},
|
5483 |
-
"iferr": {
|
5484 |
-
"version": "1.0.0",
|
5485 |
-
"bundled": true
|
5486 |
-
},
|
5487 |
-
"ignore-walk": {
|
5488 |
-
"version": "3.0.1",
|
5489 |
-
"bundled": true,
|
5490 |
-
"requires": {
|
5491 |
-
"minimatch": "^3.0.4"
|
5492 |
-
}
|
5493 |
-
},
|
5494 |
-
"import-lazy": {
|
5495 |
-
"version": "2.1.0",
|
5496 |
-
"bundled": true
|
5497 |
-
},
|
5498 |
-
"imurmurhash": {
|
5499 |
-
"version": "0.1.4",
|
5500 |
-
"bundled": true
|
5501 |
-
},
|
5502 |
-
"inflight": {
|
5503 |
-
"version": "1.0.6",
|
5504 |
-
"bundled": true,
|
5505 |
-
"requires": {
|
5506 |
-
"once": "^1.3.0",
|
5507 |
-
"wrappy": "1"
|
5508 |
-
}
|
5509 |
-
},
|
5510 |
-
"inherits": {
|
5511 |
-
"version": "2.0.3",
|
5512 |
-
"bundled": true
|
5513 |
-
},
|
5514 |
-
"ini": {
|
5515 |
-
"version": "1.3.5",
|
5516 |
-
"bundled": true
|
5517 |
-
},
|
5518 |
-
"init-package-json": {
|
5519 |
-
"version": "1.10.3",
|
5520 |
-
"bundled": true,
|
5521 |
-
"requires": {
|
5522 |
-
"glob": "^7.1.1",
|
5523 |
-
"npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0",
|
5524 |
-
"promzard": "^0.3.0",
|
5525 |
-
"read": "~1.0.1",
|
5526 |
-
"read-package-json": "1 || 2",
|
5527 |
-
"semver": "2.x || 3.x || 4 || 5",
|
5528 |
-
"validate-npm-package-license": "^3.0.1",
|
5529 |
-
"validate-npm-package-name": "^3.0.0"
|
5530 |
-
}
|
5531 |
-
},
|
5532 |
-
"invert-kv": {
|
5533 |
-
"version": "1.0.0",
|
5534 |
-
"bundled": true
|
5535 |
-
},
|
5536 |
-
"ip": {
|
5537 |
-
"version": "1.1.5",
|
5538 |
-
"bundled": true
|
5539 |
-
},
|
5540 |
-
"ip-regex": {
|
5541 |
-
"version": "2.1.0",
|
5542 |
-
"bundled": true
|
5543 |
-
},
|
5544 |
-
"is-builtin-module": {
|
5545 |
-
"version": "1.0.0",
|
5546 |
-
"bundled": true,
|
5547 |
-
"requires": {
|
5548 |
-
"builtin-modules": "^1.0.0"
|
5549 |
-
}
|
5550 |
-
},
|
5551 |
-
"is-ci": {
|
5552 |
-
"version": "1.1.0",
|
5553 |
-
"bundled": true,
|
5554 |
-
"requires": {
|
5555 |
-
"ci-info": "^1.0.0"
|
5556 |
-
}
|
5557 |
-
},
|
5558 |
-
"is-cidr": {
|
5559 |
-
"version": "2.0.6",
|
5560 |
-
"bundled": true,
|
5561 |
-
"requires": {
|
5562 |
-
"cidr-regex": "^2.0.8"
|
5563 |
-
}
|
5564 |
-
},
|
5565 |
-
"is-fullwidth-code-point": {
|
5566 |
-
"version": "1.0.0",
|
5567 |
-
"bundled": true,
|
5568 |
-
"requires": {
|
5569 |
-
"number-is-nan": "^1.0.0"
|
5570 |
-
}
|
5571 |
-
},
|
5572 |
-
"is-installed-globally": {
|
5573 |
-
"version": "0.1.0",
|
5574 |
-
"bundled": true,
|
5575 |
-
"requires": {
|
5576 |
-
"global-dirs": "^0.1.0",
|
5577 |
-
"is-path-inside": "^1.0.0"
|
5578 |
-
}
|
5579 |
-
},
|
5580 |
-
"is-npm": {
|
5581 |
-
"version": "1.0.0",
|
5582 |
-
"bundled": true
|
5583 |
-
},
|
5584 |
-
"is-obj": {
|
5585 |
-
"version": "1.0.1",
|
5586 |
-
"bundled": true
|
5587 |
-
},
|
5588 |
-
"is-path-inside": {
|
5589 |
-
"version": "1.0.1",
|
5590 |
-
"bundled": true,
|
5591 |
-
"requires": {
|
5592 |
-
"path-is-inside": "^1.0.1"
|
5593 |
-
}
|
5594 |
-
},
|
5595 |
-
"is-redirect": {
|
5596 |
-
"version": "1.0.0",
|
5597 |
-
"bundled": true
|
5598 |
-
},
|
5599 |
-
"is-retry-allowed": {
|
5600 |
-
"version": "1.1.0",
|
5601 |
-
"bundled": true
|
5602 |
-
},
|
5603 |
-
"is-stream": {
|
5604 |
-
"version": "1.1.0",
|
5605 |
-
"bundled": true
|
5606 |
-
},
|
5607 |
-
"is-typedarray": {
|
5608 |
-
"version": "1.0.0",
|
5609 |
-
"bundled": true
|
5610 |
-
},
|
5611 |
-
"isarray": {
|
5612 |
-
"version": "1.0.0",
|
5613 |
-
"bundled": true
|
5614 |
-
},
|
5615 |
-
"isexe": {
|
5616 |
-
"version": "2.0.0",
|
5617 |
-
"bundled": true
|
5618 |
-
},
|
5619 |
-
"isstream": {
|
5620 |
-
"version": "0.1.2",
|
5621 |
-
"bundled": true
|
5622 |
-
},
|
5623 |
-
"jsbn": {
|
5624 |
-
"version": "0.1.1",
|
5625 |
-
"bundled": true,
|
5626 |
-
"optional": true
|
5627 |
-
},
|
5628 |
-
"json-parse-better-errors": {
|
5629 |
-
"version": "1.0.2",
|
5630 |
-
"bundled": true
|
5631 |
-
},
|
5632 |
-
"json-schema": {
|
5633 |
-
"version": "0.2.3",
|
5634 |
-
"bundled": true
|
5635 |
-
},
|
5636 |
-
"json-stable-stringify": {
|
5637 |
-
"version": "1.0.1",
|
5638 |
-
"bundled": true,
|
5639 |
-
"requires": {
|
5640 |
-
"jsonify": "~0.0.0"
|
5641 |
-
}
|
5642 |
-
},
|
5643 |
-
"json-stringify-safe": {
|
5644 |
-
"version": "5.0.1",
|
5645 |
-
"bundled": true
|
5646 |
-
},
|
5647 |
-
"jsonify": {
|
5648 |
-
"version": "0.0.0",
|
5649 |
-
"bundled": true
|
5650 |
-
},
|
5651 |
-
"jsonparse": {
|
5652 |
-
"version": "1.3.1",
|
5653 |
-
"bundled": true
|
5654 |
-
},
|
5655 |
-
"jsprim": {
|
5656 |
-
"version": "1.4.1",
|
5657 |
-
"bundled": true,
|
5658 |
-
"requires": {
|
5659 |
-
"assert-plus": "1.0.0",
|
5660 |
-
"extsprintf": "1.3.0",
|
5661 |
-
"json-schema": "0.2.3",
|
5662 |
-
"verror": "1.10.0"
|
5663 |
-
},
|
5664 |
-
"dependencies": {
|
5665 |
-
"assert-plus": {
|
5666 |
-
"version": "1.0.0",
|
5667 |
-
"bundled": true
|
5668 |
-
}
|
5669 |
-
}
|
5670 |
-
},
|
5671 |
-
"latest-version": {
|
5672 |
-
"version": "3.1.0",
|
5673 |
-
"bundled": true,
|
5674 |
-
"requires": {
|
5675 |
-
"package-json": "^4.0.0"
|
5676 |
-
}
|
5677 |
-
},
|
5678 |
-
"lazy-property": {
|
5679 |
-
"version": "1.0.0",
|
5680 |
-
"bundled": true
|
5681 |
-
},
|
5682 |
-
"lcid": {
|
5683 |
-
"version": "1.0.0",
|
5684 |
-
"bundled": true,
|
5685 |
-
"requires": {
|
5686 |
-
"invert-kv": "^1.0.0"
|
5687 |
-
}
|
5688 |
-
},
|
5689 |
-
"libcipm": {
|
5690 |
-
"version": "2.0.0",
|
5691 |
-
"bundled": true,
|
5692 |
-
"requires": {
|
5693 |
-
"bin-links": "^1.1.2",
|
5694 |
-
"bluebird": "^3.5.1",
|
5695 |
-
"find-npm-prefix": "^1.0.2",
|
5696 |
-
"graceful-fs": "^4.1.11",
|
5697 |
-
"lock-verify": "^2.0.2",
|
5698 |
-
"npm-lifecycle": "^2.0.3",
|
5699 |
-
"npm-logical-tree": "^1.2.1",
|
5700 |
-
"npm-package-arg": "^6.1.0",
|
5701 |
-
"pacote": "^8.1.6",
|
5702 |
-
"protoduck": "^5.0.0",
|
5703 |
-
"read-package-json": "^2.0.13",
|
5704 |
-
"rimraf": "^2.6.2",
|
5705 |
-
"worker-farm": "^1.6.0"
|
5706 |
-
}
|
5707 |
-
},
|
5708 |
-
"libnpmhook": {
|
5709 |
-
"version": "4.0.1",
|
5710 |
-
"bundled": true,
|
5711 |
-
"requires": {
|
5712 |
-
"figgy-pudding": "^3.1.0",
|
5713 |
-
"npm-registry-fetch": "^3.0.0"
|
5714 |
-
},
|
5715 |
-
"dependencies": {
|
5716 |
-
"npm-registry-fetch": {
|
5717 |
-
"version": "3.1.1",
|
5718 |
-
"bundled": true,
|
5719 |
-
"requires": {
|
5720 |
-
"bluebird": "^3.5.1",
|
5721 |
-
"figgy-pudding": "^3.1.0",
|
5722 |
-
"lru-cache": "^4.1.2",
|
5723 |
-
"make-fetch-happen": "^4.0.0",
|
5724 |
-
"npm-package-arg": "^6.0.0"
|
5725 |
-
}
|
5726 |
-
}
|
5727 |
-
}
|
5728 |
-
},
|
5729 |
-
"libnpx": {
|
5730 |
-
"version": "10.2.0",
|
5731 |
-
"bundled": true,
|
5732 |
-
"requires": {
|
5733 |
-
"dotenv": "^5.0.1",
|
5734 |
-
"npm-package-arg": "^6.0.0",
|
5735 |
-
"rimraf": "^2.6.2",
|
5736 |
-
"safe-buffer": "^5.1.0",
|
5737 |
-
"update-notifier": "^2.3.0",
|
5738 |
-
"which": "^1.3.0",
|
5739 |
-
"y18n": "^4.0.0",
|
5740 |
-
"yargs": "^11.0.0"
|
5741 |
-
}
|
5742 |
-
},
|
5743 |
-
"locate-path": {
|
5744 |
-
"version": "2.0.0",
|
5745 |
-
"bundled": true,
|
5746 |
-
"requires": {
|
5747 |
-
"p-locate": "^2.0.0",
|
5748 |
-
"path-exists": "^3.0.0"
|
5749 |
-
}
|
5750 |
-
},
|
5751 |
-
"lock-verify": {
|
5752 |
-
"version": "2.0.2",
|
5753 |
-
"bundled": true,
|
5754 |
-
"requires": {
|
5755 |
-
"npm-package-arg": "^5.1.2 || 6",
|
5756 |
-
"semver": "^5.4.1"
|
5757 |
-
}
|
5758 |
-
},
|
5759 |
-
"lockfile": {
|
5760 |
-
"version": "1.0.4",
|
5761 |
-
"bundled": true,
|
5762 |
-
"requires": {
|
5763 |
-
"signal-exit": "^3.0.2"
|
5764 |
-
}
|
5765 |
-
},
|
5766 |
-
"lodash._baseindexof": {
|
5767 |
-
"version": "3.1.0",
|
5768 |
-
"bundled": true
|
5769 |
-
},
|
5770 |
-
"lodash._baseuniq": {
|
5771 |
-
"version": "4.6.0",
|
5772 |
-
"bundled": true,
|
5773 |
-
"requires": {
|
5774 |
-
"lodash._createset": "~4.0.0",
|
5775 |
-
"lodash._root": "~3.0.0"
|
5776 |
-
}
|
5777 |
-
},
|
5778 |
-
"lodash._bindcallback": {
|
5779 |
-
"version": "3.0.1",
|
5780 |
-
"bundled": true
|
5781 |
-
},
|
5782 |
-
"lodash._cacheindexof": {
|
5783 |
-
"version": "3.0.2",
|
5784 |
-
"bundled": true
|
5785 |
-
},
|
5786 |
-
"lodash._createcache": {
|
5787 |
-
"version": "3.1.2",
|
5788 |
-
"bundled": true,
|
5789 |
-
"requires": {
|
5790 |
-
"lodash._getnative": "^3.0.0"
|
5791 |
-
}
|
5792 |
-
},
|
5793 |
-
"lodash._createset": {
|
5794 |
-
"version": "4.0.3",
|
5795 |
-
"bundled": true
|
5796 |
-
},
|
5797 |
-
"lodash._getnative": {
|
5798 |
-
"version": "3.9.1",
|
5799 |
-
"bundled": true
|
5800 |
-
},
|
5801 |
-
"lodash._root": {
|
5802 |
-
"version": "3.0.1",
|
5803 |
-
"bundled": true
|
5804 |
-
},
|
5805 |
-
"lodash.clonedeep": {
|
5806 |
-
"version": "4.5.0",
|
5807 |
-
"bundled": true
|
5808 |
-
},
|
5809 |
-
"lodash.restparam": {
|
5810 |
-
"version": "3.6.1",
|
5811 |
-
"bundled": true
|
5812 |
-
},
|
5813 |
-
"lodash.union": {
|
5814 |
-
"version": "4.6.0",
|
5815 |
-
"bundled": true
|
5816 |
-
},
|
5817 |
-
"lodash.uniq": {
|
5818 |
-
"version": "4.5.0",
|
5819 |
-
"bundled": true
|
5820 |
-
},
|
5821 |
-
"lodash.without": {
|
5822 |
-
"version": "4.4.0",
|
5823 |
-
"bundled": true
|
5824 |
-
},
|
5825 |
-
"lowercase-keys": {
|
5826 |
-
"version": "1.0.1",
|
5827 |
-
"bundled": true
|
5828 |
-
},
|
5829 |
-
"lru-cache": {
|
5830 |
-
"version": "4.1.3",
|
5831 |
-
"bundled": true,
|
5832 |
-
"requires": {
|
5833 |
-
"pseudomap": "^1.0.2",
|
5834 |
-
"yallist": "^2.1.2"
|
5835 |
-
}
|
5836 |
-
},
|
5837 |
-
"make-dir": {
|
5838 |
-
"version": "1.3.0",
|
5839 |
-
"bundled": true,
|
5840 |
-
"requires": {
|
5841 |
-
"pify": "^3.0.0"
|
5842 |
-
}
|
5843 |
-
},
|
5844 |
-
"make-fetch-happen": {
|
5845 |
-
"version": "4.0.1",
|
5846 |
-
"bundled": true,
|
5847 |
-
"requires": {
|
5848 |
-
"agentkeepalive": "^3.4.1",
|
5849 |
-
"cacache": "^11.0.1",
|
5850 |
-
"http-cache-semantics": "^3.8.1",
|
5851 |
-
"http-proxy-agent": "^2.1.0",
|
5852 |
-
"https-proxy-agent": "^2.2.1",
|
5853 |
-
"lru-cache": "^4.1.2",
|
5854 |
-
"mississippi": "^3.0.0",
|
5855 |
-
"node-fetch-npm": "^2.0.2",
|
5856 |
-
"promise-retry": "^1.1.1",
|
5857 |
-
"socks-proxy-agent": "^4.0.0",
|
5858 |
-
"ssri": "^6.0.0"
|
5859 |
-
}
|
5860 |
-
},
|
5861 |
-
"meant": {
|
5862 |
-
"version": "1.0.1",
|
5863 |
-
"bundled": true
|
5864 |
-
},
|
5865 |
-
"mem": {
|
5866 |
-
"version": "1.1.0",
|
5867 |
-
"bundled": true,
|
5868 |
-
"requires": {
|
5869 |
-
"mimic-fn": "^1.0.0"
|
5870 |
-
}
|
5871 |
-
},
|
5872 |
-
"mime-db": {
|
5873 |
-
"version": "1.33.0",
|
5874 |
-
"bundled": true
|
5875 |
-
},
|
5876 |
-
"mime-types": {
|
5877 |
-
"version": "2.1.18",
|
5878 |
-
"bundled": true,
|
5879 |
-
"requires": {
|
5880 |
-
"mime-db": "~1.33.0"
|
5881 |
-
}
|
5882 |
-
},
|
5883 |
-
"mimic-fn": {
|
5884 |
-
"version": "1.2.0",
|
5885 |
-
"bundled": true
|
5886 |
-
},
|
5887 |
-
"minimatch": {
|
5888 |
-
"version": "3.0.4",
|
5889 |
-
"bundled": true,
|
5890 |
-
"requires": {
|
5891 |
-
"brace-expansion": "^1.1.7"
|
5892 |
-
}
|
5893 |
-
},
|
5894 |
-
"minimist": {
|
5895 |
-
"version": "0.0.8",
|
5896 |
-
"bundled": true
|
5897 |
-
},
|
5898 |
-
"minipass": {
|
5899 |
-
"version": "2.3.3",
|
5900 |
-
"bundled": true,
|
5901 |
-
"requires": {
|
5902 |
-
"safe-buffer": "^5.1.2",
|
5903 |
-
"yallist": "^3.0.0"
|
5904 |
-
},
|
5905 |
-
"dependencies": {
|
5906 |
-
"yallist": {
|
5907 |
-
"version": "3.0.2",
|
5908 |
-
"bundled": true
|
5909 |
-
}
|
5910 |
-
}
|
5911 |
-
},
|
5912 |
-
"minizlib": {
|
5913 |
-
"version": "1.1.0",
|
5914 |
-
"bundled": true,
|
5915 |
-
"requires": {
|
5916 |
-
"minipass": "^2.2.1"
|
5917 |
-
}
|
5918 |
-
},
|
5919 |
-
"mississippi": {
|
5920 |
-
"version": "3.0.0",
|
5921 |
-
"bundled": true,
|
5922 |
-
"requires": {
|
5923 |
-
"concat-stream": "^1.5.0",
|
5924 |
-
"duplexify": "^3.4.2",
|
5925 |
-
"end-of-stream": "^1.1.0",
|
5926 |
-
"flush-write-stream": "^1.0.0",
|
5927 |
-
"from2": "^2.1.0",
|
5928 |
-
"parallel-transform": "^1.1.0",
|
5929 |
-
"pump": "^3.0.0",
|
5930 |
-
"pumpify": "^1.3.3",
|
5931 |
-
"stream-each": "^1.1.0",
|
5932 |
-
"through2": "^2.0.0"
|
5933 |
-
}
|
5934 |
-
},
|
5935 |
-
"mkdirp": {
|
5936 |
-
"version": "0.5.1",
|
5937 |
-
"bundled": true,
|
5938 |
-
"requires": {
|
5939 |
-
"minimist": "0.0.8"
|
5940 |
-
}
|
5941 |
-
},
|
5942 |
-
"move-concurrently": {
|
5943 |
-
"version": "1.0.1",
|
5944 |
-
"bundled": true,
|
5945 |
-
"requires": {
|
5946 |
-
"aproba": "^1.1.1",
|
5947 |
-
"copy-concurrently": "^1.0.0",
|
5948 |
-
"fs-write-stream-atomic": "^1.0.8",
|
5949 |
-
"mkdirp": "^0.5.1",
|
5950 |
-
"rimraf": "^2.5.4",
|
5951 |
-
"run-queue": "^1.0.3"
|
5952 |
-
}
|
5953 |
-
},
|
5954 |
-
"ms": {
|
5955 |
-
"version": "2.1.1",
|
5956 |
-
"bundled": true
|
5957 |
-
},
|
5958 |
-
"mute-stream": {
|
5959 |
-
"version": "0.0.7",
|
5960 |
-
"bundled": true
|
5961 |
-
},
|
5962 |
-
"node-fetch-npm": {
|
5963 |
-
"version": "2.0.2",
|
5964 |
-
"bundled": true,
|
5965 |
-
"requires": {
|
5966 |
-
"encoding": "^0.1.11",
|
5967 |
-
"json-parse-better-errors": "^1.0.0",
|
5968 |
-
"safe-buffer": "^5.1.1"
|
5969 |
-
}
|
5970 |
-
},
|
5971 |
-
"node-gyp": {
|
5972 |
-
"version": "3.7.0",
|
5973 |
-
"bundled": true,
|
5974 |
-
"requires": {
|
5975 |
-
"fstream": "^1.0.0",
|
5976 |
-
"glob": "^7.0.3",
|
5977 |
-
"graceful-fs": "^4.1.2",
|
5978 |
-
"mkdirp": "^0.5.0",
|
5979 |
-
"nopt": "2 || 3",
|
5980 |
-
"npmlog": "0 || 1 || 2 || 3 || 4",
|
5981 |
-
"osenv": "0",
|
5982 |
-
"request": ">=2.9.0 <2.82.0",
|
5983 |
-
"rimraf": "2",
|
5984 |
-
"semver": "~5.3.0",
|
5985 |
-
"tar": "^2.0.0",
|
5986 |
-
"which": "1"
|
5987 |
-
},
|
5988 |
-
"dependencies": {
|
5989 |
-
"nopt": {
|
5990 |
-
"version": "3.0.6",
|
5991 |
-
"bundled": true,
|
5992 |
-
"requires": {
|
5993 |
-
"abbrev": "1"
|
5994 |
-
}
|
5995 |
-
},
|
5996 |
-
"semver": {
|
5997 |
-
"version": "5.3.0",
|
5998 |
-
"bundled": true
|
5999 |
-
},
|
6000 |
-
"tar": {
|
6001 |
-
"version": "2.2.1",
|
6002 |
-
"bundled": true,
|
6003 |
-
"requires": {
|
6004 |
-
"block-stream": "*",
|
6005 |
-
"fstream": "^1.0.2",
|
6006 |
-
"inherits": "2"
|
6007 |
-
}
|
6008 |
-
}
|
6009 |
-
}
|
6010 |
-
},
|
6011 |
-
"nopt": {
|
6012 |
-
"version": "4.0.1",
|
6013 |
-
"bundled": true,
|
6014 |
-
"requires": {
|
6015 |
-
"abbrev": "1",
|
6016 |
-
"osenv": "^0.1.4"
|
6017 |
-
}
|
6018 |
-
},
|
6019 |
-
"normalize-package-data": {
|
6020 |
-
"version": "2.4.0",
|
6021 |
-
"bundled": true,
|
6022 |
-
"requires": {
|
6023 |
-
"hosted-git-info": "^2.1.4",
|
6024 |
-
"is-builtin-module": "^1.0.0",
|
6025 |
-
"semver": "2 || 3 || 4 || 5",
|
6026 |
-
"validate-npm-package-license": "^3.0.1"
|
6027 |
-
}
|
6028 |
-
},
|
6029 |
-
"npm-audit-report": {
|
6030 |
-
"version": "1.3.1",
|
6031 |
-
"bundled": true,
|
6032 |
-
"requires": {
|
6033 |
-
"cli-table3": "^0.5.0",
|
6034 |
-
"console-control-strings": "^1.1.0"
|
6035 |
-
}
|
6036 |
-
},
|
6037 |
-
"npm-bundled": {
|
6038 |
-
"version": "1.0.3",
|
6039 |
-
"bundled": true
|
6040 |
-
},
|
6041 |
-
"npm-cache-filename": {
|
6042 |
-
"version": "1.0.2",
|
6043 |
-
"bundled": true
|
6044 |
-
},
|
6045 |
-
"npm-install-checks": {
|
6046 |
-
"version": "3.0.0",
|
6047 |
-
"bundled": true,
|
6048 |
-
"requires": {
|
6049 |
-
"semver": "^2.3.0 || 3.x || 4 || 5"
|
6050 |
-
}
|
6051 |
-
},
|
6052 |
-
"npm-lifecycle": {
|
6053 |
-
"version": "2.0.3",
|
6054 |
-
"bundled": true,
|
6055 |
-
"requires": {
|
6056 |
-
"byline": "^5.0.0",
|
6057 |
-
"graceful-fs": "^4.1.11",
|
6058 |
-
"node-gyp": "^3.6.2",
|
6059 |
-
"resolve-from": "^4.0.0",
|
6060 |
-
"slide": "^1.1.6",
|
6061 |
-
"uid-number": "0.0.6",
|
6062 |
-
"umask": "^1.1.0",
|
6063 |
-
"which": "^1.3.0"
|
6064 |
-
}
|
6065 |
-
},
|
6066 |
-
"npm-logical-tree": {
|
6067 |
-
"version": "1.2.1",
|
6068 |
-
"bundled": true
|
6069 |
-
},
|
6070 |
-
"npm-package-arg": {
|
6071 |
-
"version": "6.1.0",
|
6072 |
-
"bundled": true,
|
6073 |
-
"requires": {
|
6074 |
-
"hosted-git-info": "^2.6.0",
|
6075 |
-
"osenv": "^0.1.5",
|
6076 |
-
"semver": "^5.5.0",
|
6077 |
-
"validate-npm-package-name": "^3.0.0"
|
6078 |
-
}
|
6079 |
-
},
|
6080 |
-
"npm-packlist": {
|
6081 |
-
"version": "1.1.10",
|
6082 |
-
"bundled": true,
|
6083 |
-
"requires": {
|
6084 |
-
"ignore-walk": "^3.0.1",
|
6085 |
-
"npm-bundled": "^1.0.1"
|
6086 |
-
}
|
6087 |
-
},
|
6088 |
-
"npm-pick-manifest": {
|
6089 |
-
"version": "2.1.0",
|
6090 |
-
"bundled": true,
|
6091 |
-
"requires": {
|
6092 |
-
"npm-package-arg": "^6.0.0",
|
6093 |
-
"semver": "^5.4.1"
|
6094 |
-
}
|
6095 |
-
},
|
6096 |
-
"npm-profile": {
|
6097 |
-
"version": "3.0.2",
|
6098 |
-
"bundled": true,
|
6099 |
-
"requires": {
|
6100 |
-
"aproba": "^1.1.2 || 2",
|
6101 |
-
"make-fetch-happen": "^2.5.0 || 3 || 4"
|
6102 |
-
}
|
6103 |
-
},
|
6104 |
-
"npm-registry-client": {
|
6105 |
-
"version": "8.5.1",
|
6106 |
-
"bundled": true,
|
6107 |
-
"requires": {
|
6108 |
-
"concat-stream": "^1.5.2",
|
6109 |
-
"graceful-fs": "^4.1.6",
|
6110 |
-
"normalize-package-data": "~1.0.1 || ^2.0.0",
|
6111 |
-
"npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
|
6112 |
-
"npmlog": "2 || ^3.1.0 || ^4.0.0",
|
6113 |
-
"once": "^1.3.3",
|
6114 |
-
"request": "^2.74.0",
|
6115 |
-
"retry": "^0.10.0",
|
6116 |
-
"safe-buffer": "^5.1.1",
|
6117 |
-
"semver": "2 >=2.2.1 || 3.x || 4 || 5",
|
6118 |
-
"slide": "^1.1.3",
|
6119 |
-
"ssri": "^5.2.4"
|
6120 |
-
},
|
6121 |
-
"dependencies": {
|
6122 |
-
"retry": {
|
6123 |
-
"version": "0.10.1",
|
6124 |
-
"bundled": true
|
6125 |
-
},
|
6126 |
-
"ssri": {
|
6127 |
-
"version": "5.3.0",
|
6128 |
-
"bundled": true,
|
6129 |
-
"requires": {
|
6130 |
-
"safe-buffer": "^5.1.1"
|
6131 |
-
}
|
6132 |
-
}
|
6133 |
-
}
|
6134 |
-
},
|
6135 |
-
"npm-registry-fetch": {
|
6136 |
-
"version": "1.1.0",
|
6137 |
-
"bundled": true,
|
6138 |
-
"requires": {
|
6139 |
-
"bluebird": "^3.5.1",
|
6140 |
-
"figgy-pudding": "^2.0.1",
|
6141 |
-
"lru-cache": "^4.1.2",
|
6142 |
-
"make-fetch-happen": "^3.0.0",
|
6143 |
-
"npm-package-arg": "^6.0.0",
|
6144 |
-
"safe-buffer": "^5.1.1"
|
6145 |
-
},
|
6146 |
-
"dependencies": {
|
6147 |
-
"cacache": {
|
6148 |
-
"version": "10.0.4",
|
6149 |
-
"bundled": true,
|
6150 |
-
"requires": {
|
6151 |
-
"bluebird": "^3.5.1",
|
6152 |
-
"chownr": "^1.0.1",
|
6153 |
-
"glob": "^7.1.2",
|
6154 |
-
"graceful-fs": "^4.1.11",
|
6155 |
-
"lru-cache": "^4.1.1",
|
6156 |
-
"mississippi": "^2.0.0",
|
6157 |
-
"mkdirp": "^0.5.1",
|
6158 |
-
"move-concurrently": "^1.0.1",
|
6159 |
-
"promise-inflight": "^1.0.1",
|
6160 |
-
"rimraf": "^2.6.2",
|
6161 |
-
"ssri": "^5.2.4",
|
6162 |
-
"unique-filename": "^1.1.0",
|
6163 |
-
"y18n": "^4.0.0"
|
6164 |
-
},
|
6165 |
-
"dependencies": {
|
6166 |
-
"mississippi": {
|
6167 |
-
"version": "2.0.0",
|
6168 |
-
"bundled": true,
|
6169 |
-
"requires": {
|
6170 |
-
"concat-stream": "^1.5.0",
|
6171 |
-
"duplexify": "^3.4.2",
|
6172 |
-
"end-of-stream": "^1.1.0",
|
6173 |
-
"flush-write-stream": "^1.0.0",
|
6174 |
-
"from2": "^2.1.0",
|
6175 |
-
"parallel-transform": "^1.1.0",
|
6176 |
-
"pump": "^2.0.1",
|
6177 |
-
"pumpify": "^1.3.3",
|
6178 |
-
"stream-each": "^1.1.0",
|
6179 |
-
"through2": "^2.0.0"
|
6180 |
-
}
|
6181 |
-
}
|
6182 |
-
}
|
6183 |
-
},
|
6184 |
-
"figgy-pudding": {
|
6185 |
-
"version": "2.0.1",
|
6186 |
-
"bundled": true
|
6187 |
-
},
|
6188 |
-
"make-fetch-happen": {
|
6189 |
-
"version": "3.0.0",
|
6190 |
-
"bundled": true,
|
6191 |
-
"requires": {
|
6192 |
-
"agentkeepalive": "^3.4.1",
|
6193 |
-
"cacache": "^10.0.4",
|
6194 |
-
"http-cache-semantics": "^3.8.1",
|
6195 |
-
"http-proxy-agent": "^2.1.0",
|
6196 |
-
"https-proxy-agent": "^2.2.0",
|
6197 |
-
"lru-cache": "^4.1.2",
|
6198 |
-
"mississippi": "^3.0.0",
|
6199 |
-
"node-fetch-npm": "^2.0.2",
|
6200 |
-
"promise-retry": "^1.1.1",
|
6201 |
-
"socks-proxy-agent": "^3.0.1",
|
6202 |
-
"ssri": "^5.2.4"
|
6203 |
-
}
|
6204 |
-
},
|
6205 |
-
"pump": {
|
6206 |
-
"version": "2.0.1",
|
6207 |
-
"bundled": true,
|
6208 |
-
"requires": {
|
6209 |
-
"end-of-stream": "^1.1.0",
|
6210 |
-
"once": "^1.3.1"
|
6211 |
-
}
|
6212 |
-
},
|
6213 |
-
"smart-buffer": {
|
6214 |
-
"version": "1.1.15",
|
6215 |
-
"bundled": true
|
6216 |
-
},
|
6217 |
-
"socks": {
|
6218 |
-
"version": "1.1.10",
|
6219 |
-
"bundled": true,
|
6220 |
-
"requires": {
|
6221 |
-
"ip": "^1.1.4",
|
6222 |
-
"smart-buffer": "^1.0.13"
|
6223 |
-
}
|
6224 |
-
},
|
6225 |
-
"socks-proxy-agent": {
|
6226 |
-
"version": "3.0.1",
|
6227 |
-
"bundled": true,
|
6228 |
-
"requires": {
|
6229 |
-
"agent-base": "^4.1.0",
|
6230 |
-
"socks": "^1.1.10"
|
6231 |
-
}
|
6232 |
-
},
|
6233 |
-
"ssri": {
|
6234 |
-
"version": "5.3.0",
|
6235 |
-
"bundled": true,
|
6236 |
-
"requires": {
|
6237 |
-
"safe-buffer": "^5.1.1"
|
6238 |
-
}
|
6239 |
-
}
|
6240 |
-
}
|
6241 |
-
},
|
6242 |
-
"npm-run-path": {
|
6243 |
-
"version": "2.0.2",
|
6244 |
-
"bundled": true,
|
6245 |
-
"requires": {
|
6246 |
-
"path-key": "^2.0.0"
|
6247 |
-
}
|
6248 |
-
},
|
6249 |
-
"npm-user-validate": {
|
6250 |
-
"version": "1.0.0",
|
6251 |
-
"bundled": true
|
6252 |
-
},
|
6253 |
-
"npmlog": {
|
6254 |
-
"version": "4.1.2",
|
6255 |
-
"bundled": true,
|
6256 |
-
"requires": {
|
6257 |
-
"are-we-there-yet": "~1.1.2",
|
6258 |
-
"console-control-strings": "~1.1.0",
|
6259 |
-
"gauge": "~2.7.3",
|
6260 |
-
"set-blocking": "~2.0.0"
|
6261 |
-
}
|
6262 |
-
},
|
6263 |
-
"number-is-nan": {
|
6264 |
-
"version": "1.0.1",
|
6265 |
-
"bundled": true
|
6266 |
-
},
|
6267 |
-
"oauth-sign": {
|
6268 |
-
"version": "0.8.2",
|
6269 |
-
"bundled": true
|
6270 |
-
},
|
6271 |
-
"object-assign": {
|
6272 |
-
"version": "4.1.1",
|
6273 |
-
"bundled": true
|
6274 |
-
},
|
6275 |
-
"once": {
|
6276 |
-
"version": "1.4.0",
|
6277 |
-
"bundled": true,
|
6278 |
-
"requires": {
|
6279 |
-
"wrappy": "1"
|
6280 |
-
}
|
6281 |
-
},
|
6282 |
-
"opener": {
|
6283 |
-
"version": "1.4.3",
|
6284 |
-
"bundled": true
|
6285 |
-
},
|
6286 |
-
"os-homedir": {
|
6287 |
-
"version": "1.0.2",
|
6288 |
-
"bundled": true
|
6289 |
-
},
|
6290 |
-
"os-locale": {
|
6291 |
-
"version": "2.1.0",
|
6292 |
-
"bundled": true,
|
6293 |
-
"requires": {
|
6294 |
-
"execa": "^0.7.0",
|
6295 |
-
"lcid": "^1.0.0",
|
6296 |
-
"mem": "^1.1.0"
|
6297 |
-
}
|
6298 |
-
},
|
6299 |
-
"os-tmpdir": {
|
6300 |
-
"version": "1.0.2",
|
6301 |
-
"bundled": true
|
6302 |
-
},
|
6303 |
-
"osenv": {
|
6304 |
-
"version": "0.1.5",
|
6305 |
-
"bundled": true,
|
6306 |
-
"requires": {
|
6307 |
-
"os-homedir": "^1.0.0",
|
6308 |
-
"os-tmpdir": "^1.0.0"
|
6309 |
-
}
|
6310 |
-
},
|
6311 |
-
"p-finally": {
|
6312 |
-
"version": "1.0.0",
|
6313 |
-
"bundled": true
|
6314 |
-
},
|
6315 |
-
"p-limit": {
|
6316 |
-
"version": "1.2.0",
|
6317 |
-
"bundled": true,
|
6318 |
-
"requires": {
|
6319 |
-
"p-try": "^1.0.0"
|
6320 |
-
}
|
6321 |
-
},
|
6322 |
-
"p-locate": {
|
6323 |
-
"version": "2.0.0",
|
6324 |
-
"bundled": true,
|
6325 |
-
"requires": {
|
6326 |
-
"p-limit": "^1.1.0"
|
6327 |
-
}
|
6328 |
-
},
|
6329 |
-
"p-try": {
|
6330 |
-
"version": "1.0.0",
|
6331 |
-
"bundled": true
|
6332 |
-
},
|
6333 |
-
"package-json": {
|
6334 |
-
"version": "4.0.1",
|
6335 |
-
"bundled": true,
|
6336 |
-
"requires": {
|
6337 |
-
"got": "^6.7.1",
|
6338 |
-
"registry-auth-token": "^3.0.1",
|
6339 |
-
"registry-url": "^3.0.3",
|
6340 |
-
"semver": "^5.1.0"
|
6341 |
-
}
|
6342 |
-
},
|
6343 |
-
"pacote": {
|
6344 |
-
"version": "8.1.6",
|
6345 |
-
"bundled": true,
|
6346 |
-
"requires": {
|
6347 |
-
"bluebird": "^3.5.1",
|
6348 |
-
"cacache": "^11.0.2",
|
6349 |
-
"get-stream": "^3.0.0",
|
6350 |
-
"glob": "^7.1.2",
|
6351 |
-
"lru-cache": "^4.1.3",
|
6352 |
-
"make-fetch-happen": "^4.0.1",
|
6353 |
-
"minimatch": "^3.0.4",
|
6354 |
-
"minipass": "^2.3.3",
|
6355 |
-
"mississippi": "^3.0.0",
|
6356 |
-
"mkdirp": "^0.5.1",
|
6357 |
-
"normalize-package-data": "^2.4.0",
|
6358 |
-
"npm-package-arg": "^6.1.0",
|
6359 |
-
"npm-packlist": "^1.1.10",
|
6360 |
-
"npm-pick-manifest": "^2.1.0",
|
6361 |
-
"osenv": "^0.1.5",
|
6362 |
-
"promise-inflight": "^1.0.1",
|
6363 |
-
"promise-retry": "^1.1.1",
|
6364 |
-
"protoduck": "^5.0.0",
|
6365 |
-
"rimraf": "^2.6.2",
|
6366 |
-
"safe-buffer": "^5.1.2",
|
6367 |
-
"semver": "^5.5.0",
|
6368 |
-
"ssri": "^6.0.0",
|
6369 |
-
"tar": "^4.4.3",
|
6370 |
-
"unique-filename": "^1.1.0",
|
6371 |
-
"which": "^1.3.0"
|
6372 |
-
}
|
6373 |
-
},
|
6374 |
-
"parallel-transform": {
|
6375 |
-
"version": "1.1.0",
|
6376 |
-
"bundled": true,
|
6377 |
-
"requires": {
|
6378 |
-
"cyclist": "~0.2.2",
|
6379 |
-
"inherits": "^2.0.3",
|
6380 |
-
"readable-stream": "^2.1.5"
|
6381 |
-
}
|
6382 |
-
},
|
6383 |
-
"path-exists": {
|
6384 |
-
"version": "3.0.0",
|
6385 |
-
"bundled": true
|
6386 |
-
},
|
6387 |
-
"path-is-absolute": {
|
6388 |
-
"version": "1.0.1",
|
6389 |
-
"bundled": true
|
6390 |
-
},
|
6391 |
-
"path-is-inside": {
|
6392 |
-
"version": "1.0.2",
|
6393 |
-
"bundled": true
|
6394 |
-
},
|
6395 |
-
"path-key": {
|
6396 |
-
"version": "2.0.1",
|
6397 |
-
"bundled": true
|
6398 |
-
},
|
6399 |
-
"performance-now": {
|
6400 |
-
"version": "0.2.0",
|
6401 |
-
"bundled": true
|
6402 |
-
},
|
6403 |
-
"pify": {
|
6404 |
-
"version": "3.0.0",
|
6405 |
-
"bundled": true
|
6406 |
-
},
|
6407 |
-
"prepend-http": {
|
6408 |
-
"version": "1.0.4",
|
6409 |
-
"bundled": true
|
6410 |
-
},
|
6411 |
-
"process-nextick-args": {
|
6412 |
-
"version": "2.0.0",
|
6413 |
-
"bundled": true
|
6414 |
-
},
|
6415 |
-
"promise-inflight": {
|
6416 |
-
"version": "1.0.1",
|
6417 |
-
"bundled": true
|
6418 |
-
},
|
6419 |
-
"promise-retry": {
|
6420 |
-
"version": "1.1.1",
|
6421 |
-
"bundled": true,
|
6422 |
-
"requires": {
|
6423 |
-
"err-code": "^1.0.0",
|
6424 |
-
"retry": "^0.10.0"
|
6425 |
-
},
|
6426 |
-
"dependencies": {
|
6427 |
-
"retry": {
|
6428 |
-
"version": "0.10.1",
|
6429 |
-
"bundled": true
|
6430 |
-
}
|
6431 |
-
}
|
6432 |
-
},
|
6433 |
-
"promzard": {
|
6434 |
-
"version": "0.3.0",
|
6435 |
-
"bundled": true,
|
6436 |
-
"requires": {
|
6437 |
-
"read": "1"
|
6438 |
-
}
|
6439 |
-
},
|
6440 |
-
"proto-list": {
|
6441 |
-
"version": "1.2.4",
|
6442 |
-
"bundled": true
|
6443 |
-
},
|
6444 |
-
"protoduck": {
|
6445 |
-
"version": "5.0.0",
|
6446 |
-
"bundled": true,
|
6447 |
-
"requires": {
|
6448 |
-
"genfun": "^4.0.1"
|
6449 |
-
}
|
6450 |
-
},
|
6451 |
-
"prr": {
|
6452 |
-
"version": "1.0.1",
|
6453 |
-
"bundled": true
|
6454 |
-
},
|
6455 |
-
"pseudomap": {
|
6456 |
-
"version": "1.0.2",
|
6457 |
-
"bundled": true
|
6458 |
-
},
|
6459 |
-
"pump": {
|
6460 |
-
"version": "3.0.0",
|
6461 |
-
"bundled": true,
|
6462 |
-
"requires": {
|
6463 |
-
"end-of-stream": "^1.1.0",
|
6464 |
-
"once": "^1.3.1"
|
6465 |
-
}
|
6466 |
-
},
|
6467 |
-
"pumpify": {
|
6468 |
-
"version": "1.5.1",
|
6469 |
-
"bundled": true,
|
6470 |
-
"requires": {
|
6471 |
-
"duplexify": "^3.6.0",
|
6472 |
-
"inherits": "^2.0.3",
|
6473 |
-
"pump": "^2.0.0"
|
6474 |
-
},
|
6475 |
-
"dependencies": {
|
6476 |
-
"pump": {
|
6477 |
-
"version": "2.0.1",
|
6478 |
-
"bundled": true,
|
6479 |
-
"requires": {
|
6480 |
-
"end-of-stream": "^1.1.0",
|
6481 |
-
"once": "^1.3.1"
|
6482 |
-
}
|
6483 |
-
}
|
6484 |
-
}
|
6485 |
-
},
|
6486 |
-
"punycode": {
|
6487 |
-
"version": "1.4.1",
|
6488 |
-
"bundled": true
|
6489 |
-
},
|
6490 |
-
"qrcode-terminal": {
|
6491 |
-
"version": "0.12.0",
|
6492 |
-
"bundled": true
|
6493 |
-
},
|
6494 |
-
"qs": {
|
6495 |
-
"version": "6.4.0",
|
6496 |
-
"bundled": true
|
6497 |
-
},
|
6498 |
-
"query-string": {
|
6499 |
-
"version": "6.1.0",
|
6500 |
-
"bundled": true,
|
6501 |
-
"requires": {
|
6502 |
-
"decode-uri-component": "^0.2.0",
|
6503 |
-
"strict-uri-encode": "^2.0.0"
|
6504 |
-
}
|
6505 |
-
},
|
6506 |
-
"qw": {
|
6507 |
-
"version": "1.0.1",
|
6508 |
-
"bundled": true
|
6509 |
-
},
|
6510 |
-
"rc": {
|
6511 |
-
"version": "1.2.7",
|
6512 |
-
"bundled": true,
|
6513 |
-
"requires": {
|
6514 |
-
"deep-extend": "^0.5.1",
|
6515 |
-
"ini": "~1.3.0",
|
6516 |
-
"minimist": "^1.2.0",
|
6517 |
-
"strip-json-comments": "~2.0.1"
|
6518 |
-
},
|
6519 |
-
"dependencies": {
|
6520 |
-
"minimist": {
|
6521 |
-
"version": "1.2.0",
|
6522 |
-
"bundled": true
|
6523 |
-
}
|
6524 |
-
}
|
6525 |
-
},
|
6526 |
-
"read": {
|
6527 |
-
"version": "1.0.7",
|
6528 |
-
"bundled": true,
|
6529 |
-
"requires": {
|
6530 |
-
"mute-stream": "~0.0.4"
|
6531 |
-
}
|
6532 |
-
},
|
6533 |
-
"read-cmd-shim": {
|
6534 |
-
"version": "1.0.1",
|
6535 |
-
"bundled": true,
|
6536 |
-
"requires": {
|
6537 |
-
"graceful-fs": "^4.1.2"
|
6538 |
-
}
|
6539 |
-
},
|
6540 |
-
"read-installed": {
|
6541 |
-
"version": "4.0.3",
|
6542 |
-
"bundled": true,
|
6543 |
-
"requires": {
|
6544 |
-
"debuglog": "^1.0.1",
|
6545 |
-
"graceful-fs": "^4.1.2",
|
6546 |
-
"read-package-json": "^2.0.0",
|
6547 |
-
"readdir-scoped-modules": "^1.0.0",
|
6548 |
-
"semver": "2 || 3 || 4 || 5",
|
6549 |
-
"slide": "~1.1.3",
|
6550 |
-
"util-extend": "^1.0.1"
|
6551 |
-
}
|
6552 |
-
},
|
6553 |
-
"read-package-json": {
|
6554 |
-
"version": "2.0.13",
|
6555 |
-
"bundled": true,
|
6556 |
-
"requires": {
|
6557 |
-
"glob": "^7.1.1",
|
6558 |
-
"graceful-fs": "^4.1.2",
|
6559 |
-
"json-parse-better-errors": "^1.0.1",
|
6560 |
-
"normalize-package-data": "^2.0.0",
|
6561 |
-
"slash": "^1.0.0"
|
6562 |
-
}
|
6563 |
-
},
|
6564 |
-
"read-package-tree": {
|
6565 |
-
"version": "5.2.1",
|
6566 |
-
"bundled": true,
|
6567 |
-
"requires": {
|
6568 |
-
"debuglog": "^1.0.1",
|
6569 |
-
"dezalgo": "^1.0.0",
|
6570 |
-
"once": "^1.3.0",
|
6571 |
-
"read-package-json": "^2.0.0",
|
6572 |
-
"readdir-scoped-modules": "^1.0.0"
|
6573 |
-
}
|
6574 |
-
},
|
6575 |
-
"readable-stream": {
|
6576 |
-
"version": "2.3.6",
|
6577 |
-
"bundled": true,
|
6578 |
-
"requires": {
|
6579 |
-
"core-util-is": "~1.0.0",
|
6580 |
-
"inherits": "~2.0.3",
|
6581 |
-
"isarray": "~1.0.0",
|
6582 |
-
"process-nextick-args": "~2.0.0",
|
6583 |
-
"safe-buffer": "~5.1.1",
|
6584 |
-
"string_decoder": "~1.1.1",
|
6585 |
-
"util-deprecate": "~1.0.1"
|
6586 |
-
}
|
6587 |
-
},
|
6588 |
-
"readdir-scoped-modules": {
|
6589 |
-
"version": "1.0.2",
|
6590 |
-
"bundled": true,
|
6591 |
-
"requires": {
|
6592 |
-
"debuglog": "^1.0.1",
|
6593 |
-
"dezalgo": "^1.0.0",
|
6594 |
-
"graceful-fs": "^4.1.2",
|
6595 |
-
"once": "^1.3.0"
|
6596 |
-
}
|
6597 |
-
},
|
6598 |
-
"registry-auth-token": {
|
6599 |
-
"version": "3.3.2",
|
6600 |
-
"bundled": true,
|
6601 |
-
"requires": {
|
6602 |
-
"rc": "^1.1.6",
|
6603 |
-
"safe-buffer": "^5.0.1"
|
6604 |
-
}
|
6605 |
-
},
|
6606 |
-
"registry-url": {
|
6607 |
-
"version": "3.1.0",
|
6608 |
-
"bundled": true,
|
6609 |
-
"requires": {
|
6610 |
-
"rc": "^1.0.1"
|
6611 |
-
}
|
6612 |
-
},
|
6613 |
-
"request": {
|
6614 |
-
"version": "2.81.0",
|
6615 |
-
"bundled": true,
|
6616 |
-
"requires": {
|
6617 |
-
"aws-sign2": "~0.6.0",
|
6618 |
-
"aws4": "^1.2.1",
|
6619 |
-
"caseless": "~0.12.0",
|
6620 |
-
"combined-stream": "~1.0.5",
|
6621 |
-
"extend": "~3.0.0",
|
6622 |
-
"forever-agent": "~0.6.1",
|
6623 |
-
"form-data": "~2.1.1",
|
6624 |
-
"har-validator": "~4.2.1",
|
6625 |
-
"hawk": "~3.1.3",
|
6626 |
-
"http-signature": "~1.1.0",
|
6627 |
-
"is-typedarray": "~1.0.0",
|
6628 |
-
"isstream": "~0.1.2",
|
6629 |
-
"json-stringify-safe": "~5.0.1",
|
6630 |
-
"mime-types": "~2.1.7",
|
6631 |
-
"oauth-sign": "~0.8.1",
|
6632 |
-
"performance-now": "^0.2.0",
|
6633 |
-
"qs": "~6.4.0",
|
6634 |
-
"safe-buffer": "^5.0.1",
|
6635 |
-
"stringstream": "~0.0.4",
|
6636 |
-
"tough-cookie": "~2.3.0",
|
6637 |
-
"tunnel-agent": "^0.6.0",
|
6638 |
-
"uuid": "^3.0.0"
|
6639 |
-
}
|
6640 |
-
},
|
6641 |
-
"require-directory": {
|
6642 |
-
"version": "2.1.1",
|
6643 |
-
"bundled": true
|
6644 |
-
},
|
6645 |
-
"require-main-filename": {
|
6646 |
-
"version": "1.0.1",
|
6647 |
-
"bundled": true
|
6648 |
-
},
|
6649 |
-
"resolve-from": {
|
6650 |
-
"version": "4.0.0",
|
6651 |
-
"bundled": true
|
6652 |
-
},
|
6653 |
-
"retry": {
|
6654 |
-
"version": "0.12.0",
|
6655 |
-
"bundled": true
|
6656 |
-
},
|
6657 |
-
"rimraf": {
|
6658 |
-
"version": "2.6.2",
|
6659 |
-
"bundled": true,
|
6660 |
-
"requires": {
|
6661 |
-
"glob": "^7.0.5"
|
6662 |
-
}
|
6663 |
-
},
|
6664 |
-
"run-queue": {
|
6665 |
-
"version": "1.0.3",
|
6666 |
-
"bundled": true,
|
6667 |
-
"requires": {
|
6668 |
-
"aproba": "^1.1.1"
|
6669 |
-
}
|
6670 |
-
},
|
6671 |
-
"safe-buffer": {
|
6672 |
-
"version": "5.1.2",
|
6673 |
-
"bundled": true
|
6674 |
-
},
|
6675 |
-
"safer-buffer": {
|
6676 |
-
"version": "2.1.2",
|
6677 |
-
"bundled": true
|
6678 |
-
},
|
6679 |
-
"semver": {
|
6680 |
-
"version": "5.5.0",
|
6681 |
-
"bundled": true
|
6682 |
-
},
|
6683 |
-
"semver-diff": {
|
6684 |
-
"version": "2.1.0",
|
6685 |
-
"bundled": true,
|
6686 |
-
"requires": {
|
6687 |
-
"semver": "^5.0.3"
|
6688 |
-
}
|
6689 |
-
},
|
6690 |
-
"set-blocking": {
|
6691 |
-
"version": "2.0.0",
|
6692 |
-
"bundled": true
|
6693 |
-
},
|
6694 |
-
"sha": {
|
6695 |
-
"version": "2.0.1",
|
6696 |
-
"bundled": true,
|
6697 |
-
"requires": {
|
6698 |
-
"graceful-fs": "^4.1.2",
|
6699 |
-
"readable-stream": "^2.0.2"
|
6700 |
-
}
|
6701 |
-
},
|
6702 |
-
"shebang-command": {
|
6703 |
-
"version": "1.2.0",
|
6704 |
-
"bundled": true,
|
6705 |
-
"requires": {
|
6706 |
-
"shebang-regex": "^1.0.0"
|
6707 |
-
}
|
6708 |
-
},
|
6709 |
-
"shebang-regex": {
|
6710 |
-
"version": "1.0.0",
|
6711 |
-
"bundled": true
|
6712 |
-
},
|
6713 |
-
"signal-exit": {
|
6714 |
-
"version": "3.0.2",
|
6715 |
-
"bundled": true
|
6716 |
-
},
|
6717 |
-
"slash": {
|
6718 |
-
"version": "1.0.0",
|
6719 |
-
"bundled": true
|
6720 |
-
},
|
6721 |
-
"slide": {
|
6722 |
-
"version": "1.1.6",
|
6723 |
-
"bundled": true
|
6724 |
-
},
|
6725 |
-
"smart-buffer": {
|
6726 |
-
"version": "4.0.1",
|
6727 |
-
"bundled": true
|
6728 |
-
},
|
6729 |
-
"sntp": {
|
6730 |
-
"version": "1.0.9",
|
6731 |
-
"bundled": true,
|
6732 |
-
"requires": {
|
6733 |
-
"hoek": "2.x.x"
|
6734 |
-
}
|
6735 |
-
},
|
6736 |
-
"socks": {
|
6737 |
-
"version": "2.2.0",
|
6738 |
-
"bundled": true,
|
6739 |
-
"requires": {
|
6740 |
-
"ip": "^1.1.5",
|
6741 |
-
"smart-buffer": "^4.0.1"
|
6742 |
-
}
|
6743 |
-
},
|
6744 |
-
"socks-proxy-agent": {
|
6745 |
-
"version": "4.0.1",
|
6746 |
-
"bundled": true,
|
6747 |
-
"requires": {
|
6748 |
-
"agent-base": "~4.2.0",
|
6749 |
-
"socks": "~2.2.0"
|
6750 |
-
}
|
6751 |
-
},
|
6752 |
-
"sorted-object": {
|
6753 |
-
"version": "2.0.1",
|
6754 |
-
"bundled": true
|
6755 |
-
},
|
6756 |
-
"sorted-union-stream": {
|
6757 |
-
"version": "2.1.3",
|
6758 |
-
"bundled": true,
|
6759 |
-
"requires": {
|
6760 |
-
"from2": "^1.3.0",
|
6761 |
-
"stream-iterate": "^1.1.0"
|
6762 |
-
},
|
6763 |
-
"dependencies": {
|
6764 |
-
"from2": {
|
6765 |
-
"version": "1.3.0",
|
6766 |
-
"bundled": true,
|
6767 |
-
"requires": {
|
6768 |
-
"inherits": "~2.0.1",
|
6769 |
-
"readable-stream": "~1.1.10"
|
6770 |
-
}
|
6771 |
-
},
|
6772 |
-
"isarray": {
|
6773 |
-
"version": "0.0.1",
|
6774 |
-
"bundled": true
|
6775 |
-
},
|
6776 |
-
"readable-stream": {
|
6777 |
-
"version": "1.1.14",
|
6778 |
-
"bundled": true,
|
6779 |
-
"requires": {
|
6780 |
-
"core-util-is": "~1.0.0",
|
6781 |
-
"inherits": "~2.0.1",
|
6782 |
-
"isarray": "0.0.1",
|
6783 |
-
"string_decoder": "~0.10.x"
|
6784 |
-
}
|
6785 |
-
},
|
6786 |
-
"string_decoder": {
|
6787 |
-
"version": "0.10.31",
|
6788 |
-
"bundled": true
|
6789 |
-
}
|
6790 |
-
}
|
6791 |
-
},
|
6792 |
-
"spdx-correct": {
|
6793 |
-
"version": "3.0.0",
|
6794 |
-
"bundled": true,
|
6795 |
-
"requires": {
|
6796 |
-
"spdx-expression-parse": "^3.0.0",
|
6797 |
-
"spdx-license-ids": "^3.0.0"
|
6798 |
-
}
|
6799 |
-
},
|
6800 |
-
"spdx-exceptions": {
|
6801 |
-
"version": "2.1.0",
|
6802 |
-
"bundled": true
|
6803 |
-
},
|
6804 |
-
"spdx-expression-parse": {
|
6805 |
-
"version": "3.0.0",
|
6806 |
-
"bundled": true,
|
6807 |
-
"requires": {
|
6808 |
-
"spdx-exceptions": "^2.1.0",
|
6809 |
-
"spdx-license-ids": "^3.0.0"
|
6810 |
-
}
|
6811 |
-
},
|
6812 |
-
"spdx-license-ids": {
|
6813 |
-
"version": "3.0.0",
|
6814 |
-
"bundled": true
|
6815 |
-
},
|
6816 |
-
"sshpk": {
|
6817 |
-
"version": "1.14.2",
|
6818 |
-
"bundled": true,
|
6819 |
-
"requires": {
|
6820 |
-
"asn1": "~0.2.3",
|
6821 |
-
"assert-plus": "^1.0.0",
|
6822 |
-
"bcrypt-pbkdf": "^1.0.0",
|
6823 |
-
"dashdash": "^1.12.0",
|
6824 |
-
"ecc-jsbn": "~0.1.1",
|
6825 |
-
"getpass": "^0.1.1",
|
6826 |
-
"jsbn": "~0.1.0",
|
6827 |
-
"safer-buffer": "^2.0.2",
|
6828 |
-
"tweetnacl": "~0.14.0"
|
6829 |
-
},
|
6830 |
-
"dependencies": {
|
6831 |
-
"assert-plus": {
|
6832 |
-
"version": "1.0.0",
|
6833 |
-
"bundled": true
|
6834 |
-
}
|
6835 |
-
}
|
6836 |
-
},
|
6837 |
-
"ssri": {
|
6838 |
-
"version": "6.0.0",
|
6839 |
-
"bundled": true
|
6840 |
-
},
|
6841 |
-
"stream-each": {
|
6842 |
-
"version": "1.2.2",
|
6843 |
-
"bundled": true,
|
6844 |
-
"requires": {
|
6845 |
-
"end-of-stream": "^1.1.0",
|
6846 |
-
"stream-shift": "^1.0.0"
|
6847 |
-
}
|
6848 |
-
},
|
6849 |
-
"stream-iterate": {
|
6850 |
-
"version": "1.2.0",
|
6851 |
-
"bundled": true,
|
6852 |
-
"requires": {
|
6853 |
-
"readable-stream": "^2.1.5",
|
6854 |
-
"stream-shift": "^1.0.0"
|
6855 |
-
}
|
6856 |
-
},
|
6857 |
-
"stream-shift": {
|
6858 |
-
"version": "1.0.0",
|
6859 |
-
"bundled": true
|
6860 |
-
},
|
6861 |
-
"strict-uri-encode": {
|
6862 |
-
"version": "2.0.0",
|
6863 |
-
"bundled": true
|
6864 |
-
},
|
6865 |
-
"string-width": {
|
6866 |
-
"version": "2.1.1",
|
6867 |
-
"bundled": true,
|
6868 |
-
"requires": {
|
6869 |
-
"is-fullwidth-code-point": "^2.0.0",
|
6870 |
-
"strip-ansi": "^4.0.0"
|
6871 |
-
},
|
6872 |
-
"dependencies": {
|
6873 |
-
"ansi-regex": {
|
6874 |
-
"version": "3.0.0",
|
6875 |
-
"bundled": true
|
6876 |
-
},
|
6877 |
-
"is-fullwidth-code-point": {
|
6878 |
-
"version": "2.0.0",
|
6879 |
-
"bundled": true
|
6880 |
-
},
|
6881 |
-
"strip-ansi": {
|
6882 |
-
"version": "4.0.0",
|
6883 |
-
"bundled": true,
|
6884 |
-
"requires": {
|
6885 |
-
"ansi-regex": "^3.0.0"
|
6886 |
-
}
|
6887 |
-
}
|
6888 |
-
}
|
6889 |
-
},
|
6890 |
-
"string_decoder": {
|
6891 |
-
"version": "1.1.1",
|
6892 |
-
"bundled": true,
|
6893 |
-
"requires": {
|
6894 |
-
"safe-buffer": "~5.1.0"
|
6895 |
-
}
|
6896 |
-
},
|
6897 |
-
"stringify-package": {
|
6898 |
-
"version": "1.0.0",
|
6899 |
-
"bundled": true
|
6900 |
-
},
|
6901 |
-
"stringstream": {
|
6902 |
-
"version": "0.0.6",
|
6903 |
-
"bundled": true
|
6904 |
-
},
|
6905 |
-
"strip-ansi": {
|
6906 |
-
"version": "3.0.1",
|
6907 |
-
"bundled": true,
|
6908 |
-
"requires": {
|
6909 |
-
"ansi-regex": "^2.0.0"
|
6910 |
-
}
|
6911 |
-
},
|
6912 |
-
"strip-eof": {
|
6913 |
-
"version": "1.0.0",
|
6914 |
-
"bundled": true
|
6915 |
-
},
|
6916 |
-
"strip-json-comments": {
|
6917 |
-
"version": "2.0.1",
|
6918 |
-
"bundled": true
|
6919 |
-
},
|
6920 |
-
"supports-color": {
|
6921 |
-
"version": "5.4.0",
|
6922 |
-
"bundled": true,
|
6923 |
-
"requires": {
|
6924 |
-
"has-flag": "^3.0.0"
|
6925 |
-
}
|
6926 |
-
},
|
6927 |
-
"tar": {
|
6928 |
-
"version": "4.4.4",
|
6929 |
-
"bundled": true,
|
6930 |
-
"requires": {
|
6931 |
-
"chownr": "^1.0.1",
|
6932 |
-
"fs-minipass": "^1.2.5",
|
6933 |
-
"minipass": "^2.3.3",
|
6934 |
-
"minizlib": "^1.1.0",
|
6935 |
-
"mkdirp": "^0.5.0",
|
6936 |
-
"safe-buffer": "^5.1.2",
|
6937 |
-
"yallist": "^3.0.2"
|
6938 |
-
},
|
6939 |
-
"dependencies": {
|
6940 |
-
"yallist": {
|
6941 |
-
"version": "3.0.2",
|
6942 |
-
"bundled": true
|
6943 |
-
}
|
6944 |
-
}
|
6945 |
-
},
|
6946 |
-
"term-size": {
|
6947 |
-
"version": "1.2.0",
|
6948 |
-
"bundled": true,
|
6949 |
-
"requires": {
|
6950 |
-
"execa": "^0.7.0"
|
6951 |
-
}
|
6952 |
-
},
|
6953 |
-
"text-table": {
|
6954 |
-
"version": "0.2.0",
|
6955 |
-
"bundled": true
|
6956 |
-
},
|
6957 |
-
"through": {
|
6958 |
-
"version": "2.3.8",
|
6959 |
-
"bundled": true
|
6960 |
-
},
|
6961 |
-
"through2": {
|
6962 |
-
"version": "2.0.3",
|
6963 |
-
"bundled": true,
|
6964 |
-
"requires": {
|
6965 |
-
"readable-stream": "^2.1.5",
|
6966 |
-
"xtend": "~4.0.1"
|
6967 |
-
}
|
6968 |
-
},
|
6969 |
-
"timed-out": {
|
6970 |
-
"version": "4.0.1",
|
6971 |
-
"bundled": true
|
6972 |
-
},
|
6973 |
-
"tiny-relative-date": {
|
6974 |
-
"version": "1.3.0",
|
6975 |
-
"bundled": true
|
6976 |
-
},
|
6977 |
-
"tough-cookie": {
|
6978 |
-
"version": "2.3.4",
|
6979 |
-
"bundled": true,
|
6980 |
-
"requires": {
|
6981 |
-
"punycode": "^1.4.1"
|
6982 |
-
}
|
6983 |
-
},
|
6984 |
-
"tunnel-agent": {
|
6985 |
-
"version": "0.6.0",
|
6986 |
-
"bundled": true,
|
6987 |
-
"requires": {
|
6988 |
-
"safe-buffer": "^5.0.1"
|
6989 |
-
}
|
6990 |
-
},
|
6991 |
-
"tweetnacl": {
|
6992 |
-
"version": "0.14.5",
|
6993 |
-
"bundled": true,
|
6994 |
-
"optional": true
|
6995 |
-
},
|
6996 |
-
"typedarray": {
|
6997 |
-
"version": "0.0.6",
|
6998 |
-
"bundled": true
|
6999 |
-
},
|
7000 |
-
"uid-number": {
|
7001 |
-
"version": "0.0.6",
|
7002 |
-
"bundled": true
|
7003 |
-
},
|
7004 |
-
"umask": {
|
7005 |
-
"version": "1.1.0",
|
7006 |
-
"bundled": true
|
7007 |
-
},
|
7008 |
-
"unique-filename": {
|
7009 |
-
"version": "1.1.0",
|
7010 |
-
"bundled": true,
|
7011 |
-
"requires": {
|
7012 |
-
"unique-slug": "^2.0.0"
|
7013 |
-
}
|
7014 |
-
},
|
7015 |
-
"unique-slug": {
|
7016 |
-
"version": "2.0.0",
|
7017 |
-
"bundled": true,
|
7018 |
-
"requires": {
|
7019 |
-
"imurmurhash": "^0.1.4"
|
7020 |
-
}
|
7021 |
-
},
|
7022 |
-
"unique-string": {
|
7023 |
-
"version": "1.0.0",
|
7024 |
-
"bundled": true,
|
7025 |
-
"requires": {
|
7026 |
-
"crypto-random-string": "^1.0.0"
|
7027 |
-
}
|
7028 |
-
},
|
7029 |
-
"unpipe": {
|
7030 |
-
"version": "1.0.0",
|
7031 |
-
"bundled": true
|
7032 |
-
},
|
7033 |
-
"unzip-response": {
|
7034 |
-
"version": "2.0.1",
|
7035 |
-
"bundled": true
|
7036 |
-
},
|
7037 |
-
"update-notifier": {
|
7038 |
-
"version": "2.5.0",
|
7039 |
-
"bundled": true,
|
7040 |
-
"requires": {
|
7041 |
-
"boxen": "^1.2.1",
|
7042 |
-
"chalk": "^2.0.1",
|
7043 |
-
"configstore": "^3.0.0",
|
7044 |
-
"import-lazy": "^2.1.0",
|
7045 |
-
"is-ci": "^1.0.10",
|
7046 |
-
"is-installed-globally": "^0.1.0",
|
7047 |
-
"is-npm": "^1.0.0",
|
7048 |
-
"latest-version": "^3.0.0",
|
7049 |
-
"semver-diff": "^2.0.0",
|
7050 |
-
"xdg-basedir": "^3.0.0"
|
7051 |
-
}
|
7052 |
-
},
|
7053 |
-
"url-parse-lax": {
|
7054 |
-
"version": "1.0.0",
|
7055 |
-
"bundled": true,
|
7056 |
-
"requires": {
|
7057 |
-
"prepend-http": "^1.0.1"
|
7058 |
-
}
|
7059 |
-
},
|
7060 |
-
"util-deprecate": {
|
7061 |
-
"version": "1.0.2",
|
7062 |
-
"bundled": true
|
7063 |
-
},
|
7064 |
-
"util-extend": {
|
7065 |
-
"version": "1.0.3",
|
7066 |
-
"bundled": true
|
7067 |
-
},
|
7068 |
-
"uuid": {
|
7069 |
-
"version": "3.3.2",
|
7070 |
-
"bundled": true
|
7071 |
-
},
|
7072 |
-
"validate-npm-package-license": {
|
7073 |
-
"version": "3.0.3",
|
7074 |
-
"bundled": true,
|
7075 |
-
"requires": {
|
7076 |
-
"spdx-correct": "^3.0.0",
|
7077 |
-
"spdx-expression-parse": "^3.0.0"
|
7078 |
-
}
|
7079 |
-
},
|
7080 |
-
"validate-npm-package-name": {
|
7081 |
-
"version": "3.0.0",
|
7082 |
-
"bundled": true,
|
7083 |
-
"requires": {
|
7084 |
-
"builtins": "^1.0.3"
|
7085 |
-
}
|
7086 |
-
},
|
7087 |
-
"verror": {
|
7088 |
-
"version": "1.10.0",
|
7089 |
-
"bundled": true,
|
7090 |
-
"requires": {
|
7091 |
-
"assert-plus": "^1.0.0",
|
7092 |
-
"core-util-is": "1.0.2",
|
7093 |
-
"extsprintf": "^1.2.0"
|
7094 |
-
},
|
7095 |
-
"dependencies": {
|
7096 |
-
"assert-plus": {
|
7097 |
-
"version": "1.0.0",
|
7098 |
-
"bundled": true
|
7099 |
-
}
|
7100 |
-
}
|
7101 |
-
},
|
7102 |
-
"wcwidth": {
|
7103 |
-
"version": "1.0.1",
|
7104 |
-
"bundled": true,
|
7105 |
-
"requires": {
|
7106 |
-
"defaults": "^1.0.3"
|
7107 |
-
}
|
7108 |
-
},
|
7109 |
-
"which": {
|
7110 |
-
"version": "1.3.1",
|
7111 |
-
"bundled": true,
|
7112 |
-
"requires": {
|
7113 |
-
"isexe": "^2.0.0"
|
7114 |
-
}
|
7115 |
-
},
|
7116 |
-
"which-module": {
|
7117 |
-
"version": "2.0.0",
|
7118 |
-
"bundled": true
|
7119 |
-
},
|
7120 |
-
"wide-align": {
|
7121 |
-
"version": "1.1.2",
|
7122 |
-
"bundled": true,
|
7123 |
-
"requires": {
|
7124 |
-
"string-width": "^1.0.2"
|
7125 |
-
},
|
7126 |
-
"dependencies": {
|
7127 |
-
"string-width": {
|
7128 |
-
"version": "1.0.2",
|
7129 |
-
"bundled": true,
|
7130 |
-
"requires": {
|
7131 |
-
"code-point-at": "^1.0.0",
|
7132 |
-
"is-fullwidth-code-point": "^1.0.0",
|
7133 |
-
"strip-ansi": "^3.0.0"
|
7134 |
-
}
|
7135 |
-
}
|
7136 |
-
}
|
7137 |
-
},
|
7138 |
-
"widest-line": {
|
7139 |
-
"version": "2.0.0",
|
7140 |
-
"bundled": true,
|
7141 |
-
"requires": {
|
7142 |
-
"string-width": "^2.1.1"
|
7143 |
-
}
|
7144 |
-
},
|
7145 |
-
"worker-farm": {
|
7146 |
-
"version": "1.6.0",
|
7147 |
-
"bundled": true,
|
7148 |
-
"requires": {
|
7149 |
-
"errno": "~0.1.7"
|
7150 |
-
}
|
7151 |
-
},
|
7152 |
-
"wrap-ansi": {
|
7153 |
-
"version": "2.1.0",
|
7154 |
-
"bundled": true,
|
7155 |
-
"requires": {
|
7156 |
-
"string-width": "^1.0.1",
|
7157 |
-
"strip-ansi": "^3.0.1"
|
7158 |
-
},
|
7159 |
-
"dependencies": {
|
7160 |
-
"string-width": {
|
7161 |
-
"version": "1.0.2",
|
7162 |
-
"bundled": true,
|
7163 |
-
"requires": {
|
7164 |
-
"code-point-at": "^1.0.0",
|
7165 |
-
"is-fullwidth-code-point": "^1.0.0",
|
7166 |
-
"strip-ansi": "^3.0.0"
|
7167 |
-
}
|
7168 |
-
}
|
7169 |
-
}
|
7170 |
-
},
|
7171 |
-
"wrappy": {
|
7172 |
-
"version": "1.0.2",
|
7173 |
-
"bundled": true
|
7174 |
-
},
|
7175 |
-
"write-file-atomic": {
|
7176 |
-
"version": "2.3.0",
|
7177 |
-
"bundled": true,
|
7178 |
-
"requires": {
|
7179 |
-
"graceful-fs": "^4.1.11",
|
7180 |
-
"imurmurhash": "^0.1.4",
|
7181 |
-
"signal-exit": "^3.0.2"
|
7182 |
-
}
|
7183 |
-
},
|
7184 |
-
"xdg-basedir": {
|
7185 |
-
"version": "3.0.0",
|
7186 |
-
"bundled": true
|
7187 |
-
},
|
7188 |
-
"xtend": {
|
7189 |
-
"version": "4.0.1",
|
7190 |
-
"bundled": true
|
7191 |
-
},
|
7192 |
-
"y18n": {
|
7193 |
-
"version": "4.0.0",
|
7194 |
-
"bundled": true
|
7195 |
-
},
|
7196 |
-
"yallist": {
|
7197 |
-
"version": "2.1.2",
|
7198 |
-
"bundled": true
|
7199 |
-
},
|
7200 |
-
"yargs": {
|
7201 |
-
"version": "11.0.0",
|
7202 |
-
"bundled": true,
|
7203 |
-
"requires": {
|
7204 |
-
"cliui": "^4.0.0",
|
7205 |
-
"decamelize": "^1.1.1",
|
7206 |
-
"find-up": "^2.1.0",
|
7207 |
-
"get-caller-file": "^1.0.1",
|
7208 |
-
"os-locale": "^2.0.0",
|
7209 |
-
"require-directory": "^2.1.1",
|
7210 |
-
"require-main-filename": "^1.0.1",
|
7211 |
-
"set-blocking": "^2.0.0",
|
7212 |
-
"string-width": "^2.0.0",
|
7213 |
-
"which-module": "^2.0.0",
|
7214 |
-
"y18n": "^3.2.1",
|
7215 |
-
"yargs-parser": "^9.0.2"
|
7216 |
-
},
|
7217 |
-
"dependencies": {
|
7218 |
-
"y18n": {
|
7219 |
-
"version": "3.2.1",
|
7220 |
-
"bundled": true
|
7221 |
-
}
|
7222 |
-
}
|
7223 |
-
},
|
7224 |
-
"yargs-parser": {
|
7225 |
-
"version": "9.0.2",
|
7226 |
-
"bundled": true,
|
7227 |
-
"requires": {
|
7228 |
-
"camelcase": "^4.1.0"
|
7229 |
-
}
|
7230 |
-
}
|
7231 |
-
}
|
7232 |
-
},
|
7233 |
-
"npmlog": {
|
7234 |
-
"version": "4.1.2",
|
7235 |
-
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
7236 |
-
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
7237 |
-
"dev": true,
|
7238 |
-
"requires": {
|
7239 |
-
"are-we-there-yet": "~1.1.2",
|
7240 |
-
"console-control-strings": "~1.1.0",
|
7241 |
-
"gauge": "~2.7.3",
|
7242 |
-
"set-blocking": "~2.0.0"
|
7243 |
-
}
|
7244 |
-
},
|
7245 |
-
"num2fraction": {
|
7246 |
-
"version": "1.2.2",
|
7247 |
-
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
|
7248 |
-
"integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
|
7249 |
-
"dev": true
|
7250 |
-
},
|
7251 |
-
"number-is-nan": {
|
7252 |
-
"version": "1.0.1",
|
7253 |
-
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
7254 |
-
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
7255 |
-
"dev": true
|
7256 |
-
},
|
7257 |
-
"oauth-sign": {
|
7258 |
-
"version": "0.8.2",
|
7259 |
-
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
|
7260 |
-
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
|
7261 |
-
"dev": true
|
7262 |
-
},
|
7263 |
-
"object-assign": {
|
7264 |
-
"version": "4.1.1",
|
7265 |
-
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
7266 |
-
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
7267 |
-
"dev": true
|
7268 |
-
},
|
7269 |
-
"object.omit": {
|
7270 |
-
"version": "2.0.1",
|
7271 |
-
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
|
7272 |
-
"integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
|
7273 |
-
"dev": true,
|
7274 |
-
"requires": {
|
7275 |
-
"for-own": "^0.1.4",
|
7276 |
-
"is-extendable": "^0.1.1"
|
7277 |
-
},
|
7278 |
-
"dependencies": {
|
7279 |
-
"for-own": {
|
7280 |
-
"version": "0.1.5",
|
7281 |
-
"resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
|
7282 |
-
"integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
|
7283 |
-
"dev": true,
|
7284 |
-
"requires": {
|
7285 |
-
"for-in": "^1.0.1"
|
7286 |
-
}
|
7287 |
-
}
|
7288 |
-
}
|
7289 |
-
},
|
7290 |
-
"once": {
|
7291 |
-
"version": "1.4.0",
|
7292 |
-
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
7293 |
-
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
7294 |
-
"dev": true,
|
7295 |
-
"requires": {
|
7296 |
-
"wrappy": "1"
|
7297 |
-
}
|
7298 |
-
},
|
7299 |
-
"onetime": {
|
7300 |
-
"version": "1.1.0",
|
7301 |
-
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
|
7302 |
-
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
|
7303 |
-
"dev": true
|
7304 |
-
},
|
7305 |
-
"optionator": {
|
7306 |
-
"version": "0.8.2",
|
7307 |
-
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
|
7308 |
-
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
|
7309 |
-
"dev": true,
|
7310 |
-
"requires": {
|
7311 |
-
"deep-is": "~0.1.3",
|
7312 |
-
"fast-levenshtein": "~2.0.4",
|
7313 |
-
"levn": "~0.3.0",
|
7314 |
-
"prelude-ls": "~1.1.2",
|
7315 |
-
"type-check": "~0.3.2",
|
7316 |
-
"wordwrap": "~1.0.0"
|
7317 |
-
}
|
7318 |
-
},
|
7319 |
-
"os-browserify": {
|
7320 |
-
"version": "0.3.0",
|
7321 |
-
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
|
7322 |
-
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
|
7323 |
-
"dev": true
|
7324 |
-
},
|
7325 |
-
"os-homedir": {
|
7326 |
-
"version": "1.0.2",
|
7327 |
-
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
7328 |
-
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
7329 |
-
"dev": true
|
7330 |
-
},
|
7331 |
-
"os-locale": {
|
7332 |
-
"version": "1.4.0",
|
7333 |
-
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
|
7334 |
-
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
|
7335 |
-
"dev": true,
|
7336 |
-
"requires": {
|
7337 |
-
"lcid": "^1.0.0"
|
7338 |
-
}
|
7339 |
-
},
|
7340 |
-
"os-tmpdir": {
|
7341 |
-
"version": "1.0.2",
|
7342 |
-
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
7343 |
-
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
7344 |
-
"dev": true
|
7345 |
-
},
|
7346 |
-
"osenv": {
|
7347 |
-
"version": "0.1.4",
|
7348 |
-
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
|
7349 |
-
"integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
|
7350 |
-
"dev": true,
|
7351 |
-
"requires": {
|
7352 |
-
"os-homedir": "^1.0.0",
|
7353 |
-
"os-tmpdir": "^1.0.0"
|
7354 |
-
}
|
7355 |
-
},
|
7356 |
-
"p-limit": {
|
7357 |
-
"version": "1.1.0",
|
7358 |
-
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
|
7359 |
-
"integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
|
7360 |
-
"dev": true
|
7361 |
-
},
|
7362 |
-
"p-locate": {
|
7363 |
-
"version": "2.0.0",
|
7364 |
-
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
|
7365 |
-
"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
|
7366 |
-
"dev": true,
|
7367 |
-
"requires": {
|
7368 |
-
"p-limit": "^1.1.0"
|
7369 |
-
}
|
7370 |
-
},
|
7371 |
-
"pako": {
|
7372 |
-
"version": "1.0.6",
|
7373 |
-
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
|
7374 |
-
"integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
|
7375 |
-
"dev": true
|
7376 |
-
},
|
7377 |
-
"parse-asn1": {
|
7378 |
-
"version": "5.1.0",
|
7379 |
-
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
|
7380 |
-
"integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
|
7381 |
-
"dev": true,
|
7382 |
-
"requires": {
|
7383 |
-
"asn1.js": "^4.0.0",
|
7384 |
-
"browserify-aes": "^1.0.0",
|
7385 |
-
"create-hash": "^1.1.0",
|
7386 |
-
"evp_bytestokey": "^1.0.0",
|
7387 |
-
"pbkdf2": "^3.0.3"
|
7388 |
-
}
|
7389 |
-
},
|
7390 |
-
"parse-glob": {
|
7391 |
-
"version": "3.0.4",
|
7392 |
-
"resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
|
7393 |
-
"integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
|
7394 |
-
"dev": true,
|
7395 |
-
"requires": {
|
7396 |
-
"glob-base": "^0.3.0",
|
7397 |
-
"is-dotfile": "^1.0.0",
|
7398 |
-
"is-extglob": "^1.0.0",
|
7399 |
-
"is-glob": "^2.0.0"
|
7400 |
-
}
|
7401 |
-
},
|
7402 |
-
"parse-json": {
|
7403 |
-
"version": "2.2.0",
|
7404 |
-
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
|
7405 |
-
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
|
7406 |
-
"dev": true,
|
7407 |
-
"requires": {
|
7408 |
-
"error-ex": "^1.2.0"
|
7409 |
-
}
|
7410 |
-
},
|
7411 |
-
"path-browserify": {
|
7412 |
-
"version": "0.0.0",
|
7413 |
-
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
|
7414 |
-
"integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
|
7415 |
-
"dev": true
|
7416 |
-
},
|
7417 |
-
"path-exists": {
|
7418 |
-
"version": "3.0.0",
|
7419 |
-
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
7420 |
-
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
7421 |
-
"dev": true
|
7422 |
-
},
|
7423 |
-
"path-is-absolute": {
|
7424 |
-
"version": "1.0.1",
|
7425 |
-
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
7426 |
-
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
7427 |
-
"dev": true
|
7428 |
-
},
|
7429 |
-
"path-is-inside": {
|
7430 |
-
"version": "1.0.2",
|
7431 |
-
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
|
7432 |
-
"integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
|
7433 |
-
"dev": true
|
7434 |
-
},
|
7435 |
-
"path-parse": {
|
7436 |
-
"version": "1.0.5",
|
7437 |
-
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
|
7438 |
-
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
|
7439 |
-
"dev": true
|
7440 |
-
},
|
7441 |
-
"path-type": {
|
7442 |
-
"version": "1.1.0",
|
7443 |
-
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
|
7444 |
-
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
|
7445 |
-
"dev": true,
|
7446 |
-
"requires": {
|
7447 |
-
"graceful-fs": "^4.1.2",
|
7448 |
-
"pify": "^2.0.0",
|
7449 |
-
"pinkie-promise": "^2.0.0"
|
7450 |
-
},
|
7451 |
-
"dependencies": {
|
7452 |
-
"pify": {
|
7453 |
-
"version": "2.3.0",
|
7454 |
-
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
7455 |
-
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
7456 |
-
"dev": true
|
7457 |
-
}
|
7458 |
-
}
|
7459 |
-
},
|
7460 |
-
"pbkdf2": {
|
7461 |
-
"version": "3.0.14",
|
7462 |
-
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
|
7463 |
-
"integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
|
7464 |
-
"dev": true,
|
7465 |
-
"requires": {
|
7466 |
-
"create-hash": "^1.1.2",
|
7467 |
-
"create-hmac": "^1.1.4",
|
7468 |
-
"ripemd160": "^2.0.1",
|
7469 |
-
"safe-buffer": "^5.0.1",
|
7470 |
-
"sha.js": "^2.4.8"
|
7471 |
-
}
|
7472 |
-
},
|
7473 |
-
"pify": {
|
7474 |
-
"version": "3.0.0",
|
7475 |
-
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
7476 |
-
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
|
7477 |
-
"dev": true
|
7478 |
-
},
|
7479 |
-
"pinkie": {
|
7480 |
-
"version": "2.0.4",
|
7481 |
-
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
|
7482 |
-
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
|
7483 |
-
"dev": true
|
7484 |
-
},
|
7485 |
-
"pinkie-promise": {
|
7486 |
-
"version": "2.0.1",
|
7487 |
-
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
|
7488 |
-
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
|
7489 |
-
"dev": true,
|
7490 |
-
"requires": {
|
7491 |
-
"pinkie": "^2.0.0"
|
7492 |
-
}
|
7493 |
-
},
|
7494 |
-
"pkg-dir": {
|
7495 |
-
"version": "2.0.0",
|
7496 |
-
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
|
7497 |
-
"integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
|
7498 |
-
"dev": true,
|
7499 |
-
"requires": {
|
7500 |
-
"find-up": "^2.1.0"
|
7501 |
-
}
|
7502 |
-
},
|
7503 |
-
"pluralize": {
|
7504 |
-
"version": "1.2.1",
|
7505 |
-
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
|
7506 |
-
"integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
|
7507 |
-
"dev": true
|
7508 |
-
},
|
7509 |
-
"postcss": {
|
7510 |
-
"version": "5.2.18",
|
7511 |
-
"resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
|
7512 |
-
"integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
|
7513 |
-
"dev": true,
|
7514 |
-
"requires": {
|
7515 |
-
"chalk": "^1.1.3",
|
7516 |
-
"js-base64": "^2.1.9",
|
7517 |
-
"source-map": "^0.5.6",
|
7518 |
-
"supports-color": "^3.2.3"
|
7519 |
-
},
|
7520 |
-
"dependencies": {
|
7521 |
-
"supports-color": {
|
7522 |
-
"version": "3.2.3",
|
7523 |
-
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
|
7524 |
-
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
|
7525 |
-
"dev": true,
|
7526 |
-
"requires": {
|
7527 |
-
"has-flag": "^1.0.0"
|
7528 |
-
}
|
7529 |
-
}
|
7530 |
-
}
|
7531 |
-
},
|
7532 |
-
"postcss-calc": {
|
7533 |
-
"version": "5.3.1",
|
7534 |
-
"resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
|
7535 |
-
"integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
|
7536 |
-
"dev": true,
|
7537 |
-
"requires": {
|
7538 |
-
"postcss": "^5.0.2",
|
7539 |
-
"postcss-message-helpers": "^2.0.0",
|
7540 |
-
"reduce-css-calc": "^1.2.6"
|
7541 |
-
}
|
7542 |
-
},
|
7543 |
-
"postcss-colormin": {
|
7544 |
-
"version": "2.2.2",
|
7545 |
-
"resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
|
7546 |
-
"integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
|
7547 |
-
"dev": true,
|
7548 |
-
"requires": {
|
7549 |
-
"colormin": "^1.0.5",
|
7550 |
-
"postcss": "^5.0.13",
|
7551 |
-
"postcss-value-parser": "^3.2.3"
|
7552 |
-
}
|
7553 |
-
},
|
7554 |
-
"postcss-convert-values": {
|
7555 |
-
"version": "2.6.1",
|
7556 |
-
"resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz",
|
7557 |
-
"integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
|
7558 |
-
"dev": true,
|
7559 |
-
"requires": {
|
7560 |
-
"postcss": "^5.0.11",
|
7561 |
-
"postcss-value-parser": "^3.1.2"
|
7562 |
-
}
|
7563 |
-
},
|
7564 |
-
"postcss-discard-comments": {
|
7565 |
-
"version": "2.0.4",
|
7566 |
-
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
|
7567 |
-
"integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
|
7568 |
-
"dev": true,
|
7569 |
-
"requires": {
|
7570 |
-
"postcss": "^5.0.14"
|
7571 |
-
}
|
7572 |
-
},
|
7573 |
-
"postcss-discard-duplicates": {
|
7574 |
-
"version": "2.1.0",
|
7575 |
-
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz",
|
7576 |
-
"integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
|
7577 |
-
"dev": true,
|
7578 |
-
"requires": {
|
7579 |
-
"postcss": "^5.0.4"
|
7580 |
-
}
|
7581 |
-
},
|
7582 |
-
"postcss-discard-empty": {
|
7583 |
-
"version": "2.1.0",
|
7584 |
-
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
|
7585 |
-
"integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
|
7586 |
-
"dev": true,
|
7587 |
-
"requires": {
|
7588 |
-
"postcss": "^5.0.14"
|
7589 |
-
}
|
7590 |
-
},
|
7591 |
-
"postcss-discard-overridden": {
|
7592 |
-
"version": "0.1.1",
|
7593 |
-
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
|
7594 |
-
"integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
|
7595 |
-
"dev": true,
|
7596 |
-
"requires": {
|
7597 |
-
"postcss": "^5.0.16"
|
7598 |
-
}
|
7599 |
-
},
|
7600 |
-
"postcss-discard-unused": {
|
7601 |
-
"version": "2.2.3",
|
7602 |
-
"resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
|
7603 |
-
"integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
|
7604 |
-
"dev": true,
|
7605 |
-
"requires": {
|
7606 |
-
"postcss": "^5.0.14",
|
7607 |
-
"uniqs": "^2.0.0"
|
7608 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|