Coming Soon Page & Maintenance Mode by SeedProd - Version 5.0.25

Version Description

  • Fixed - Documentation Link
  • Tweak - Removed plugin recommendation
Download this release

Release Info

Developer seedprod
Plugin Icon 128x128 Coming Soon Page & Maintenance Mode by SeedProd
Version 5.0.25
Comparing to
See all releases

Code changes from version 5.0.24 to 5.0.25

README.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Plugin Name ===
2
  Contributors: seedprod, smub
3
  Donate link: http://www.seedprod.com
4
- Tags: maintenance mode, coming soon page, coming soon, under construction, launch page, launch, maintenance, construction, offline, unavailable, under construction page, landing page
5
  Requires at least: 3.5.1
6
- Tested up to: 5.1
7
- Stable tag: 5.0.24
8
  Text Domain: coming-soon
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -115,6 +115,10 @@ This is always a caching issue. Go to the caching plugin's setting page and clea
115
  4. Design Page
116
 
117
  == Changelog ==
 
 
 
 
118
  = 5.0.24 =
119
  * Tweak - Typos
120
  * Tweak - Remove Install Plugins menu when dismissed
@@ -224,6 +228,10 @@ This is always a caching issue. Go to the caching plugin's setting page and clea
224
  * Initial Commit
225
 
226
  == Upgrade Notice ==
 
 
 
 
227
  = 5.0.24 =
228
  * Tweak - Typos
229
  * Tweak - Remove Install Plugins menu when dismissed
1
  === Plugin Name ===
2
  Contributors: seedprod, smub
3
  Donate link: http://www.seedprod.com
4
+ Tags: maintenance mode, coming soon page, coming soon, under construction, landing page, launch, maintenance, construction, offline, unavailable, under construction page, launch page
5
  Requires at least: 3.5.1
6
+ Tested up to: 5.2
7
+ Stable tag: 5.0.25
8
  Text Domain: coming-soon
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
115
  4. Design Page
116
 
117
  == Changelog ==
118
+ = 5.0.25 =
119
+ * Fixed - Documentation Link
120
+ * Tweak - Removed plugin recommendation
121
+
122
  = 5.0.24 =
123
  * Tweak - Typos
124
  * Tweak - Remove Install Plugins menu when dismissed
228
  * Initial Commit
229
 
230
  == Upgrade Notice ==
231
+ = 5.0.25 =
232
+ * Fixed - Documentation Link
233
+ * Tweak - Removed plugin recommendation
234
+
235
  = 5.0.24 =
236
  * Tweak - Typos
237
  * Tweak - Remove Install Plugins menu when dismissed
coming-soon.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Coming Soon Page & Maintenance Mode by SeedProd
4
  * Plugin URI: http://www.seedprod.com
5
  * Description: The #1 Coming Soon Page, Under Construction & Maintenance Mode plugin for WordPress.
6
- * Version: 5.0.24
7
  * Author: SeedProd
8
  * Author URI: http://www.seedprod.com
9
  * Text Domain: coming-soon
@@ -16,21 +16,22 @@
16
  /**
17
  * Default Constants
18
  */
19
- define( 'SEED_CSP4_SHORTNAME', 'seed_csp4' ); // Used to reference namespace functions.
20
- define( 'SEED_CSP4_SLUG', 'coming-soon/coming-soon.php' ); // Used for settings link.
21
- define( 'SEED_CSP4_TEXTDOMAIN', 'coming-soon' ); // Your textdomain
22
- define( 'SEED_CSP4_PLUGIN_NAME', __( 'Coming Soon Page & Maintenance Mode by SeedProd', 'coming-soon' ) ); // Plugin Name shows up on the admin settings screen.
23
- define( 'SEED_CSP4_VERSION', '5.0.24'); // Plugin Version Number. Recommend you use Semantic Versioning http://semver.org/
24
- define( 'SEED_CSP4_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); // Example output: /Applications/MAMP/htdocs/wordpress/wp-content/plugins/seed_csp4/
25
- define( 'SEED_CSP4_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); // Example output: http://localhost:8888/wordpress/wp-content/plugins/seed_csp4/
26
- define( 'SEED_CSP4_TABLENAME', 'seed_csp4_subscribers' );
27
 
28
 
29
  /**
30
  * Load Translation
31
  */
32
- function seed_csp4_load_textdomain() {
33
- load_plugin_textdomain( 'coming-soon', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
 
34
  }
35
  add_action('plugins_loaded', 'seed_csp4_load_textdomain');
36
 
@@ -40,52 +41,55 @@ add_action('plugins_loaded', 'seed_csp4_load_textdomain');
40
  *
41
  * @since 0.1.0
42
  */
43
- function seed_csp4_activation(){
44
- // Store the plugin version when initial install occurred.
45
- $has_seed_csp4_settings_content = get_option('seed_csp4_settings_content');
46
- if(!empty($has_seed_csp4_settings_content)){
47
- add_option( 'seed_csp4_initial_version', 0, '', false );
48
- }else{
49
- add_option( 'seed_csp4_initial_version', SEED_CSP4_VERSION, '', false );
50
- }
 
51
 
52
 
53
- // Store the plugin version activated to reference with upgrades.
54
- update_option( 'seed_csp4_version', SEED_CSP4_VERSION, false );
55
- require_once( 'inc/default-settings.php' );
56
- add_option('seed_csp4_settings_content',unserialize($seed_csp4_settings_deafults['seed_csp4_settings_content']));
57
- add_option('seed_csp4_settings_design',unserialize($seed_csp4_settings_deafults['seed_csp4_settings_design']));
58
- add_option('seed_csp4_settings_advanced',unserialize($seed_csp4_settings_deafults['seed_csp4_settings_advanced']));
59
  }
60
- register_activation_hook( __FILE__, 'seed_csp4_activation' );
61
 
62
 
63
 
64
  // Welcome Page
65
 
66
- register_activation_hook( __FILE__, 'seed_csp4_welcome_screen_activate' );
67
- function seed_csp4_welcome_screen_activate() {
68
- set_transient( '_seed_csp4_welcome_screen_activation_redirect', true, 30 );
 
69
  }
70
 
71
 
72
- add_action( 'admin_init', 'seed_csp4_welcome_screen_do_activation_redirect' );
73
- function seed_csp4_welcome_screen_do_activation_redirect() {
74
- // Bail if no activation redirect
75
- if ( ! get_transient( '_seed_csp4_welcome_screen_activation_redirect' ) ) {
76
- return;
77
- }
 
78
 
79
- // Delete the redirect transient
80
- delete_transient( '_seed_csp4_welcome_screen_activation_redirect' );
81
 
82
- // Bail if activating from network, or bulk
83
- if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
84
- return;
85
- }
86
 
87
- // Redirect to bbPress about page
88
- wp_safe_redirect( add_query_arg( array( 'page' => 'seed_csp4' ), admin_url( 'admin.php' ) ) );
89
  }
90
 
91
 
@@ -96,75 +100,67 @@ function seed_csp4_welcome_screen_do_activation_redirect() {
96
  // Global
97
  global $seed_csp4_settings;
98
 
99
- require_once( SEED_CSP4_PLUGIN_PATH.'framework/get-settings.php' );
100
  $seed_csp4_settings = seed_csp4_get_settings();
101
 
102
- require_once( SEED_CSP4_PLUGIN_PATH.'inc/class-seed-csp4.php' );
103
- add_action( 'plugins_loaded', array( 'SEED_CSP4', 'get_instance' ) );
104
-
105
- if( is_admin() ) {
106
- // Admin Only
107
- require_once( SEED_CSP4_PLUGIN_PATH.'inc/config-settings.php' );
108
- require_once( SEED_CSP4_PLUGIN_PATH.'framework/framework.php' );
109
- add_action( 'plugins_loaded', array( 'SEED_CSP4_ADMIN', 'get_instance' ) );
110
- require_once( SEED_CSP4_PLUGIN_PATH.'framework/review.php' );
111
- if(version_compare(phpversion(), '5.3.3', '>=')){
112
- require_once( SEED_CSP4_PLUGIN_PATH.'lib/setup_tgmpa.php' );
113
- require_once( SEED_CSP4_PLUGIN_PATH.'lib/TGMPA.php' );
114
- }
115
- } else {
116
- // Public only
117
 
 
 
 
 
 
 
 
 
118
  }
119
 
120
 
121
  // Clear Popular Caches
122
- add_action( 'update_option_seed_csp4_settings_content', 'seed_csp4_clear_known_caches', 10, 2 );
123
 
124
- function seed_csp4_clear_known_caches($o,$n){
125
- try {
126
- if(isset($o['status']) && isset($n['status'])){
127
- if($o['status'] != $n['status']){
 
128
 
129
  // Clear Litespeed cache
130
- method_exists( 'LiteSpeed_Cache_API', 'purge_all' ) && LiteSpeed_Cache_API::purge_all() ;
131
-
132
- // WP Super Cache
133
- if ( function_exists( 'wp_cache_clear_cache' ) ) {
134
- wp_cache_clear_cache();
135
- }
136
-
137
- // W3 Total Cahce
138
- if ( function_exists( 'w3tc_pgcache_flush' ) ) {
139
- w3tc_pgcache_flush();
140
- }
141
-
142
- // Site ground
143
- if ( class_exists( 'SG_CachePress_Supercacher' ) && method_exists( 'SG_CachePress_Supercacher ', 'purge_cache' )) {
144
- SG_CachePress_Supercacher::purge_cache(true);
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  }
146
-
147
- // Endurance Cache
148
- if ( class_exists( 'Endurance_Page_Cache' ) ) {
149
- $e = new Endurance_Page_Cache;
150
- $e->purge_all();
151
- }
152
-
153
- // WP Fastest Cache
154
- if ( isset($GLOBALS['wp_fastest_cache'] ) && method_exists( $GLOBALS['wp_fastest_cache'], 'deleteCache') ) {
155
- $GLOBALS['wp_fastest_cache']->deleteCache(true);
156
- }
157
-
158
- }
159
  }
160
- } catch (Exception $e) {}
161
  }
162
 
163
- function seed_csp4_admin_upgrade_link( $medium = 'link' ) {
164
- return apply_filters( 'seed_csp4_upgrade_link', 'https://www.seedprod.com/ultimate-coming-soon-page-vs-coming-soon-pro/?utm_source=WordPress&utm_medium=' . sanitize_key( apply_filters( 'seed_csp4_upgrade_link_medium', $medium ) ) . '&utm_campaign=liteplugin' );
165
- }
166
-
167
-
168
-
169
-
170
-
3
  * Plugin Name: Coming Soon Page & Maintenance Mode by SeedProd
4
  * Plugin URI: http://www.seedprod.com
5
  * Description: The #1 Coming Soon Page, Under Construction & Maintenance Mode plugin for WordPress.
6
+ * Version: 5.0.25
7
  * Author: SeedProd
8
  * Author URI: http://www.seedprod.com
9
  * Text Domain: coming-soon
16
  /**
17
  * Default Constants
18
  */
19
+ define('SEED_CSP4_SHORTNAME', 'seed_csp4'); // Used to reference namespace functions.
20
+ define('SEED_CSP4_SLUG', 'coming-soon/coming-soon.php'); // Used for settings link.
21
+ define('SEED_CSP4_TEXTDOMAIN', 'coming-soon'); // Your textdomain
22
+ define('SEED_CSP4_PLUGIN_NAME', __('Coming Soon Page & Maintenance Mode by SeedProd', 'coming-soon')); // Plugin Name shows up on the admin settings screen.
23
+ define('SEED_CSP4_VERSION', '5.0.25'); // Plugin Version Number. Recommend you use Semantic Versioning http://semver.org/
24
+ define('SEED_CSP4_PLUGIN_PATH', plugin_dir_path(__FILE__)); // Example output: /Applications/MAMP/htdocs/wordpress/wp-content/plugins/seed_csp4/
25
+ define('SEED_CSP4_PLUGIN_URL', plugin_dir_url(__FILE__)); // Example output: http://localhost:8888/wordpress/wp-content/plugins/seed_csp4/
26
+ define('SEED_CSP4_TABLENAME', 'seed_csp4_subscribers');
27
 
28
 
29
  /**
30
  * Load Translation
31
  */
32
+ function seed_csp4_load_textdomain()
33
+ {
34
+ load_plugin_textdomain('coming-soon', false, dirname(plugin_basename(__FILE__)) . '/languages/');
35
  }
36
  add_action('plugins_loaded', 'seed_csp4_load_textdomain');
37
 
41
  *
42
  * @since 0.1.0
43
  */
44
+ function seed_csp4_activation()
45
+ {
46
+ // Store the plugin version when initial install occurred.
47
+ $has_seed_csp4_settings_content = get_option('seed_csp4_settings_content');
48
+ if (!empty($has_seed_csp4_settings_content)) {
49
+ add_option('seed_csp4_initial_version', 0, '', false);
50
+ } else {
51
+ add_option('seed_csp4_initial_version', SEED_CSP4_VERSION, '', false);
52
+ }
53
 
54
 
55
+ // Store the plugin version activated to reference with upgrades.
56
+ update_option('seed_csp4_version', SEED_CSP4_VERSION, false);
57
+ require_once('inc/default-settings.php');
58
+ add_option('seed_csp4_settings_content', unserialize($seed_csp4_settings_deafults['seed_csp4_settings_content']));
59
+ add_option('seed_csp4_settings_design', unserialize($seed_csp4_settings_deafults['seed_csp4_settings_design']));
60
+ add_option('seed_csp4_settings_advanced', unserialize($seed_csp4_settings_deafults['seed_csp4_settings_advanced']));
61
  }
62
+ register_activation_hook(__FILE__, 'seed_csp4_activation');
63
 
64
 
65
 
66
  // Welcome Page
67
 
68
+ register_activation_hook(__FILE__, 'seed_csp4_welcome_screen_activate');
69
+ function seed_csp4_welcome_screen_activate()
70
+ {
71
+ set_transient('_seed_csp4_welcome_screen_activation_redirect', true, 30);
72
  }
73
 
74
 
75
+ add_action('admin_init', 'seed_csp4_welcome_screen_do_activation_redirect');
76
+ function seed_csp4_welcome_screen_do_activation_redirect()
77
+ {
78
+ // Bail if no activation redirect
79
+ if (! get_transient('_seed_csp4_welcome_screen_activation_redirect')) {
80
+ return;
81
+ }
82
 
83
+ // Delete the redirect transient
84
+ delete_transient('_seed_csp4_welcome_screen_activation_redirect');
85
 
86
+ // Bail if activating from network, or bulk
87
+ if (is_network_admin() || isset($_GET['activate-multi'])) {
88
+ return;
89
+ }
90
 
91
+ // Redirect to bbPress about page
92
+ wp_safe_redirect(add_query_arg(array( 'page' => 'seed_csp4' ), admin_url('admin.php')));
93
  }
94
 
95
 
100
  // Global
101
  global $seed_csp4_settings;
102
 
103
+ require_once(SEED_CSP4_PLUGIN_PATH.'framework/get-settings.php');
104
  $seed_csp4_settings = seed_csp4_get_settings();
105
 
106
+ require_once(SEED_CSP4_PLUGIN_PATH.'inc/class-seed-csp4.php');
107
+ add_action('plugins_loaded', array( 'SEED_CSP4', 'get_instance' ));
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
+ if (is_admin()) {
110
+ // Admin Only
111
+ require_once(SEED_CSP4_PLUGIN_PATH.'inc/config-settings.php');
112
+ require_once(SEED_CSP4_PLUGIN_PATH.'framework/framework.php');
113
+ add_action('plugins_loaded', array( 'SEED_CSP4_ADMIN', 'get_instance' ));
114
+ require_once(SEED_CSP4_PLUGIN_PATH.'framework/review.php');
115
+ } else {
116
+ // Public only
117
  }
118
 
119
 
120
  // Clear Popular Caches
121
+ add_action('update_option_seed_csp4_settings_content', 'seed_csp4_clear_known_caches', 10, 2);
122
 
123
+ function seed_csp4_clear_known_caches($o, $n)
124
+ {
125
+ try {
126
+ if (isset($o['status']) && isset($n['status'])) {
127
+ if ($o['status'] != $n['status']) {
128
 
129
  // Clear Litespeed cache
130
+ method_exists('LiteSpeed_Cache_API', 'purge_all') && LiteSpeed_Cache_API::purge_all() ;
131
+
132
+ // WP Super Cache
133
+ if (function_exists('wp_cache_clear_cache')) {
134
+ wp_cache_clear_cache();
135
+ }
136
+
137
+ // W3 Total Cahce
138
+ if (function_exists('w3tc_pgcache_flush')) {
139
+ w3tc_pgcache_flush();
140
+ }
141
+
142
+ // Site ground
143
+ if (class_exists('SG_CachePress_Supercacher') && method_exists('SG_CachePress_Supercacher ', 'purge_cache')) {
144
+ SG_CachePress_Supercacher::purge_cache(true);
145
+ }
146
+
147
+ // Endurance Cache
148
+ if (class_exists('Endurance_Page_Cache')) {
149
+ $e = new Endurance_Page_Cache;
150
+ $e->purge_all();
151
+ }
152
+
153
+ // WP Fastest Cache
154
+ if (isset($GLOBALS['wp_fastest_cache']) && method_exists($GLOBALS['wp_fastest_cache'], 'deleteCache')) {
155
+ $GLOBALS['wp_fastest_cache']->deleteCache(true);
156
+ }
157
+ }
158
  }
159
+ } catch (Exception $e) {
 
 
 
 
 
 
 
 
 
 
 
 
160
  }
 
161
  }
162
 
163
+ function seed_csp4_admin_upgrade_link($medium = 'link')
164
+ {
165
+ return apply_filters('seed_csp4_upgrade_link', 'https://www.seedprod.com/ultimate-coming-soon-page-vs-coming-soon-pro/?utm_source=WordPress&utm_medium=' . sanitize_key(apply_filters('seed_csp4_upgrade_link_medium', $medium)) . '&utm_campaign=liteplugin');
166
+ }
 
 
 
 
framework/framework.php CHANGED
@@ -22,35 +22,32 @@ class SEED_CSP4_ADMIN
22
  */
23
  protected static $instance = null;
24
 
25
- /**
26
- * Slug of the plugin screen.
27
- *
28
- * @since 1.0.0
29
- *
30
- * @var string
31
- */
32
  protected $plugin_screen_hook_suffix = null;
33
 
34
  /**
35
  * Load Hooks
36
  */
37
- function __construct( )
38
  {
39
- if ( is_admin() && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) ){
40
- add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
41
- add_action( 'admin_menu', array( &$this, 'create_menus' ) );
42
- add_action( 'admin_init', array( &$this, 'reset_defaults' ) );
43
- add_action( 'admin_init', array( &$this, 'create_settings' ) );
44
- add_filter( 'plugin_action_links', array( &$this, 'plugin_action_links' ), 10, 2 );
45
- add_filter( 'tmp_grunion_allow_editor_view', '__return_false' );
46
- if(version_compare(phpversion(), '5.3.3', '>=')){
47
- add_action( 'wpms_tgmpa_register', 'coming_soon_init_recommendations' );
48
- }
49
  }
50
 
51
- if (defined( 'DOING_AJAX' )){
52
  // Background API Ajax
53
- add_action( 'wp_ajax_seed_csp4_backgrounds', array(&$this,'backgrounds'));
54
  }
55
  }
56
 
@@ -61,10 +58,11 @@ class SEED_CSP4_ADMIN
61
  *
62
  * @return object A single instance of this class.
63
  */
64
- public static function get_instance() {
 
65
 
66
  // If the single instance hasn't been set, set it now.
67
- if ( null == self::$instance ) {
68
  self::$instance = new self;
69
  }
70
 
@@ -75,49 +73,47 @@ class SEED_CSP4_ADMIN
75
  * backgrounds api
76
  *
77
  */
78
- function backgrounds( )
79
  {
80
- if(check_ajax_referer('seed_csp4_backgrounds')){
81
-
82
- $r = array();
83
  $page = '';
84
- if(isset($_REQUEST['page'])){
85
  $page = $_REQUEST['page'];
86
  $page = '?page='.$page;
87
  $r['page'] = $_REQUEST['page'];
88
  }
89
  $query = '';
90
- if(isset($_REQUEST['query'])){
91
  $query = $_REQUEST['query'];
92
  $query = '?query='.$query;
93
  $r['query'] = $_REQUEST['query'];
94
  }
95
 
96
- if ( false === ( get_transient( 'seed_csp4_backgrounds_page_'.$query.$page ) ) ) {
97
- //f(1){
98
  //echo 'miss';
99
 
100
  $bg_api = 'https://api.seedprod.com/v3/free_background_search';
101
 
102
- $url = $bg_api.'?'.http_build_query($r);
103
- $response = wp_remote_get( $url );
104
  //var_dump($url);
105
- if ( is_wp_error( $response ) ) {
106
  $error_message = $response->get_error_message();
107
  echo "Something went wrong: $error_message";
108
- }else{
109
- $response_code = wp_remote_retrieve_response_code( $response );
110
- if($response_code == '200'){
111
- set_transient('seed_csp4_backgrounds_page_'.$query.$page,$response['body'],604800);
112
  echo $response['body'];
113
- }else{
114
  echo 'There was an issue loading the stock images. Please try again later.';
115
  }
116
-
117
  }
118
- }else{
119
  //echo 'hit';
120
- echo get_transient( 'seed_csp4_backgrounds_page_'.$query.$page );
121
  }
122
 
123
 
@@ -130,15 +126,15 @@ class SEED_CSP4_ADMIN
130
  * Reset the settings page. Reset works per settings id.
131
  *
132
  */
133
- function reset_defaults( )
134
  {
135
- if ( isset( $_POST[ 'seed_csp4_reset' ] ) ) {
136
  $option_page = $_POST[ 'option_page' ];
137
- check_admin_referer( $option_page . '-options' );
138
  require_once(SEED_CSP4_PLUGIN_PATH.'inc/default-settings.php');
139
 
140
  $_POST[ $_POST[ 'option_page' ] ] = $seed_csp4_settings_deafults[$_POST[ 'option_page' ]];
141
- add_settings_error( 'general', 'seed_csp4-settings-reset', __( "Settings reset." ), 'updated' );
142
  }
143
  }
144
 
@@ -151,24 +147,25 @@ class SEED_CSP4_ADMIN
151
  * @since 0.1.0
152
  * @param string $hook_suffix The name of the current page we are on.
153
  */
154
- function admin_enqueue_scripts( $hook_suffix )
155
  {
156
- if (strpos($hook_suffix, 'seed_csp4') === false )
157
  return;
 
158
 
159
- wp_enqueue_script( 'media-upload' );
160
- wp_enqueue_script( 'jquery-ui-sortable' );
161
- wp_enqueue_script( 'wp-lists' );
162
- wp_enqueue_script( 'seed_csp4-framework-js', SEED_CSP4_PLUGIN_URL . 'framework/settings-scripts.js', array( 'jquery' ), $this->plugin_version );
163
- wp_enqueue_script( 'seed_csp4-magnific-popup-js', SEED_CSP4_PLUGIN_URL . 'public/vendor/magnific-popup/jquery.magnific-popup.min.js', array( 'jquery' ), $this->plugin_version );
164
- wp_enqueue_script( 'theme-preview' );
165
- wp_enqueue_style( 'thickbox' );
166
- wp_enqueue_style( 'media-upload' );
167
- wp_enqueue_style( 'wp-color-picker' );
168
- wp_enqueue_style( 'seed_csp4-framework-css', SEED_CSP4_PLUGIN_URL . 'framework/settings-style.css', false, $this->plugin_version );
169
- wp_enqueue_style( 'font-awesome-solid', SEED_CSP4_PLUGIN_URL . 'public/vendor/fontawesome/css/solid.min.css', false, $this->plugin_version, false, $this->plugin_version );
170
- wp_enqueue_style( 'font-awesome', SEED_CSP4_PLUGIN_URL . 'public/vendor/fontawesome/css/fontawesome.min.css', false, $this->plugin_version, false, $this->plugin_version );
171
- wp_enqueue_style( 'seed_csp4-magnific-popup-js', SEED_CSP4_PLUGIN_URL . 'public/vendor/magnific-popup/magnific-popup.css', false, $this->plugin_version, false, $this->plugin_version );
172
  }
173
 
174
  /**
@@ -178,11 +175,11 @@ class SEED_CSP4_ADMIN
178
  *
179
  * @since 0.1.0
180
  */
181
- function create_menus( )
182
  {
183
  add_menu_page(
184
- __( "SeedProd", 'coming-soon' ),
185
- __( "SeedProd", 'coming-soon' ),
186
  'manage_options',
187
  'seed_csp4',
188
  array( &$this , 'option_page' ),
@@ -192,8 +189,8 @@ class SEED_CSP4_ADMIN
192
 
193
  add_submenu_page(
194
  'seed_csp4',
195
- __( "Settings", 'coming-soon' ),
196
- __( "Settings", 'coming-soon' ),
197
  'manage_options',
198
  'seed_csp4',
199
  array( &$this , 'option_page' )
@@ -201,8 +198,8 @@ class SEED_CSP4_ADMIN
201
 
202
  add_submenu_page(
203
  'seed_csp4',
204
- __( "Themes", 'coming-soon' ),
205
- __( "Themes", 'coming-soon' ),
206
  'manage_options',
207
  'seed_csp4_themes',
208
  array( &$this , 'themes_page' )
@@ -210,8 +207,8 @@ class SEED_CSP4_ADMIN
210
 
211
  add_submenu_page(
212
  'seed_csp4',
213
- __( "Free Stock Images", 'coming-soon' ),
214
- __( "Free Stock Images", 'coming-soon' ),
215
  'manage_options',
216
  'seed_csp4_stockimages',
217
  array( &$this , 'stockimages_page' )
@@ -219,8 +216,8 @@ class SEED_CSP4_ADMIN
219
 
220
  add_submenu_page(
221
  'seed_csp4',
222
- __( "Subscribers", 'coming-soon' ),
223
- __( "Subscribers", 'coming-soon' ),
224
  'manage_options',
225
  'seed_csp4_subscribers',
226
  array( &$this , 'subscribers_page' )
@@ -228,27 +225,31 @@ class SEED_CSP4_ADMIN
228
 
229
  add_submenu_page(
230
  'seed_csp4',
231
- __( "Addons", 'coming-soon' ),
232
- __( "<span style='color:#ff9a4b'>Addons</span>", 'coming-soon' ),
233
  'manage_options',
234
  'seed_csp4_addons',
235
  array( &$this , 'addons_page' )
236
  );
237
  }
238
 
239
- function themes_page(){
 
240
  include SEED_CSP4_PLUGIN_PATH.'resources/views/themes.php';
241
  }
242
 
243
- function stockimages_page(){
 
244
  include SEED_CSP4_PLUGIN_PATH.'resources/views/stockimages.php';
245
  }
246
 
247
- function subscribers_page(){
 
248
  include SEED_CSP4_PLUGIN_PATH.'resources/views/subscribers.php';
249
  }
250
 
251
- function addons_page(){
 
252
  include SEED_CSP4_PLUGIN_PATH.'resources/views/addons.php';
253
  }
254
 
@@ -257,13 +258,13 @@ class SEED_CSP4_ADMIN
257
  /**
258
  * Display settings link on plugin page
259
  */
260
- function plugin_action_links( $links, $file )
261
  {
262
  $plugin_file = SEED_CSP4_SLUG;
263
 
264
- if ( $file == $plugin_file ) {
265
  $settings_link = '<a href="admin.php?page=seed_csp4">Settings</a>';
266
- array_unshift( $links, $settings_link );
267
  }
268
  return $links;
269
  }
@@ -273,65 +274,64 @@ class SEED_CSP4_ADMIN
273
  * Allow Tabs on the Settings Page
274
  *
275
  */
276
- function plugin_options_tabs( )
277
  {
278
  $menu_slug = null;
279
  $page = $_REQUEST[ 'page' ];
280
  $uses_tabs = false;
281
- $current_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : false;
282
 
283
  //Check if this config uses tabs
284
- foreach ( seed_csp4_get_options() as $v ) {
285
- if ( $v[ 'type' ] == 'tab' ) {
286
  $uses_tabs = true;
287
  break;
288
  }
289
  }
290
 
291
  // If uses tabs then generate the tabs
292
- if ( $uses_tabs ) {
293
  echo '<h2 class="nav-tab-wrapper" style="padding-left:20px">';
294
  $c = 1;
295
- foreach ( seed_csp4_get_options() as $v ) {
296
- if ( isset( $v[ 'menu_slug' ] ) ) {
297
- $menu_slug = $v[ 'menu_slug' ];
 
 
 
 
 
 
 
 
 
 
 
 
298
  }
299
- if ( $menu_slug == $page && $v[ 'type' ] == 'tab' ) {
300
- $active = '';
301
- if ( $current_tab ) {
302
- $active = $current_tab == $v[ 'id' ] ? 'nav-tab-active' : '';
303
- } elseif ( $c == 1 ) {
304
- $active = 'nav-tab-active';
305
- }
306
- if($v[ 'id' ] == 'seed_csp4_subscribers'){
307
- echo '<a id="'.$v[ 'id' ].'" class="nav-tab ' . $active . '" href="admin.php?page=seed_csp4_subscribers">';
308
- }else{
309
- echo '<a id="'.$v[ 'id' ].'" class="nav-tab ' . $active . '" href="?page=' . $menu_slug . '&tab=' . $v[ 'id' ] . '">';
310
- }
311
 
312
- if($v[ 'id' ] == 'seed_csp4_setting'){
313
- echo '<i class="fas fa-edit"></i> ';
314
- }
315
- if($v[ 'id' ] == 'seed_csp4_design'){
316
- echo '<i class="fas fa-image"></i> ';
317
- }
318
- if($v[ 'id' ] == 'seed_csp4_subscribers'){
319
- echo '<i class="fas fa-users"></i> ';
320
- }
321
- if($v[ 'id' ] == 'seed_csp4_advanced'){
322
- echo '<i class="fas fa-code"></i> ';
323
- }
324
- echo $v[ 'label' ] . '</a>';
325
- $c++;
326
  }
 
 
 
 
 
 
327
  }
328
- echo '<a class="nav-tab seed_csp4-preview thickbox-preview" target="_blank" href="'.home_url().'?cs_preview=true" title="'.__('&larr; Close Window','coming-soon').'"><i class="fas fa-external-link-alt"></i> '.__('Live Preview','coming-soon').'</a>';
329
 
330
- echo '<a class="nav-tab seed_csp4-support seed-csp4-cta" style="background-color: #04be5b;color: #fff" href="'.seed_csp4_admin_upgrade_link( 'upgrade-tab' ).'" target="_blank" rel="noopener noreferrer"><i class="fas fa-star"></i> '.__('Upgrade to Pro for More Features','coming-soon').'</a>';
331
 
332
 
333
  echo '</h2>';
334
-
335
  }
336
  }
337
 
@@ -339,15 +339,15 @@ class SEED_CSP4_ADMIN
339
  * Get the layout for the page. classic|2-col
340
  *
341
  */
342
- function get_page_layout( )
343
  {
344
  $layout = 'classic';
345
- foreach ( seed_csp4_get_options() as $v ) {
346
- switch ( $v[ 'type' ] ) {
347
- case 'menu';
348
  $page = $_REQUEST[ 'page' ];
349
- if ( $page == $v[ 'menu_slug' ] ) {
350
- if ( isset( $v[ 'layout' ] ) ) {
351
  $layout = $v[ 'layout' ];
352
  }
353
  }
@@ -362,100 +362,100 @@ class SEED_CSP4_ADMIN
362
  *
363
  * @since 0.1.0
364
  */
365
- function option_page( )
366
  {
367
  $menu_slug = null;
368
  $page = $_REQUEST[ 'page' ];
369
- $layout = $this->get_page_layout();
370
- ?>
371
 
372
 
373
- <div class="wrap columns-2 seed-csp4">
374
- <div id="seed_csp4_header">
375
- <h1>
376
- <img style="width:150px;margin-right:10px;margin-bottom: -2px;vertical-align: text-bottom;" src="<?php echo SEED_CSP4_PLUGIN_URL ?>public/images/seedprod-logo.png">
377
- Coming Soon Page and Maintenance Mode Lite
378
- <span class="seed_csp4_version" style="font-size: 10px;"> Version <?php echo SEED_CSP4_VERSION; ?></span>
379
- </h1>
 
380
 
381
 
382
 
383
- <?php $this->plugin_options_tabs(); ?>
384
- </div>
385
-
386
- <div class="seed-wrap">
387
- <?php if ( $layout == '2-col' ): ?>
388
- <div id="poststuff">
389
- <div id="post-body" class="metabox-holder columns-2">
390
- <div id="post-body-content" >
391
- <?php endif; ?>
392
- <?php if(!empty($_GET['tab']))
393
- do_action( 'seed_csp4_render_page', array('tab'=>$_GET['tab']));
394
- ?>
395
  <form action="options.php" method="post">
396
 
397
- <!-- <input name="submit" type="submit" value="<?php _e( 'Save All Changes', 'coming-soon' ); ?>" class="button-primary"/> -->
398
- <?php if(!empty($_GET['tab']) && $_GET['tab'] != 'seed_csp4_tab_3') { ?>
399
- <!-- <input id="reset" name="reset" type="submit" value="<?php _e( 'Reset Settings', 'coming-soon' ); ?>" class="button-secondary"/> -->
400
- <?php } ?>
 
 
401
 
402
- <?php
403
  $show_submit = false;
404
- foreach ( seed_csp4_get_options() as $v ) {
405
- if ( isset( $v[ 'menu_slug' ] ) ) {
406
- $menu_slug = $v[ 'menu_slug' ];
407
- }
408
- if ( $menu_slug == $page ) {
409
- switch ( $v[ 'type' ] ) {
410
- case 'menu';
411
  break;
412
- case 'tab';
413
  $tab = $v;
414
- if ( empty( $default_tab ) )
415
  $default_tab = $v[ 'id' ];
 
416
  break;
417
  case 'setting':
418
- $current_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : $default_tab;
419
- if ( $current_tab == $tab[ 'id' ] ) {
420
- settings_fields( $v[ 'id' ] );
421
  $show_submit = true;
422
  }
423
 
424
  break;
425
  case 'section':
426
- $current_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : $default_tab;
427
- if ( $current_tab == $tab[ 'id' ] or $current_tab === false ) {
428
- if ( $layout == '2-col' ) {
429
  echo '<div id="'.$v[ 'id' ].'" class="postbox seedprod-postbox">';
430
- $this->do_settings_sections( $v[ 'id' ],$show_submit );
431
  echo '</div>';
432
  } else {
433
- do_settings_sections( $v[ 'id' ] );
434
  }
435
-
436
  }
437
  break;
438
 
439
  }
440
-
441
- }
442
- }
443
- ?>
444
- <?php if($show_submit): ?>
445
- <p>
446
- <!-- <input name="submit" type="submit" value="<?php _e( 'Save All Changes', 'coming-soon' ); ?>" class="button-primary"/> -->
447
- <!-- <input id="reset" name="reset" type="submit" value="<?php _e( 'Reset Settings', 'coming-soon' ); ?>" class="button-secondary"/> -->
448
- </p>
449
- <?php endif; ?>
450
  </form>
451
 
452
- <?php if ( $layout == '2-col' ): ?>
453
- </div> <!-- #post-body-content -->
454
 
455
- <div id="postbox-container-1" class="postbox-container">
456
- <div id="side-sortables" class="meta-box-sortables ui-sortable">
457
 
458
- <!-- <div class="postbox ">
459
  <div class="handlediv" title="Click to toggle"><br /></div>
460
  <h3 class="hndle"><span><i class="fas fa-rocket"></i>&nbsp;&nbsp;<?php _e('Getting Started Video - 60 sec', 'coming-soon') ?></span></h3>
461
  <div class="inside">
@@ -465,16 +465,22 @@ class SEED_CSP4_ADMIN
465
  </div>
466
  </div> -->
467
 
468
-
469
- <a style="border:1px solid #ddd;display:inline-block;" href="https://www.seedprod.com/landing/coming-soon-page-getting-started-video/?utm_source=coming-soon-plugin&utm_medium=banner&utm_campaign=coming-soon-banner-in-plugin" target="_blank"><img src="<?php echo SEED_CSP4_PLUGIN_URL; ?>framework/getting-started-banner.png" /></a>
470
- <br><br>
471
 
472
-
473
- <a style="border:1px solid #ddd;display:inline-block;" href="<?php echo seed_csp4_admin_upgrade_link( 'sidebar-banner' )?>" target="_blank" rel="noopener noreferrer" class="seed-csp4-cta"><img src="<?php echo SEED_CSP4_PLUGIN_URL; ?>framework/coming-soon-pro-sidebar.png" /></a>
474
- <br><br>
 
 
 
 
 
 
 
 
 
475
 
476
 
477
- <!-- <div class="postbox " style="background-color:#FAE6A4;color:#333 !important; border-color:#333 !important">
478
  <div class="handlediv" title="Click to toggle"><br /></div>
479
  <h3 class="hndle" style="color:#fff !important;border-color:#333 !important; background-color:#333"><span><i class="fas fa-star"></i>&nbsp;&nbsp;<?php _e('Yo-Yo-Yo, Why Go Pro?', 'coming-soon') ?></span></h3>
480
  <div class="inside">
@@ -499,45 +505,49 @@ class SEED_CSP4_ADMIN
499
  <li><strong>Plus lots more!</strong></li>
500
  </ul>
501
  <p>
502
- <a class="button-primary" style="background-color:#05AE0E; border-color:#05AE0E; box-shadow:none; text-shadow: none; width:100%; text-align:center;" href="<?php echo seed_csp4_admin_upgrade_link( 'sidebar' ); ?>" target="_blank" rel="noopener noreferrer">See What's In The Pro Version</a>
503
  </p>
504
 
505
  </div>
506
  </div>
507
  </div> -->
508
 
509
- <div class="postbox ">
510
- <div class="handlediv" title="Click to toggle"><br /></div>
511
-
512
- <div class="inside">
513
- <div class="support-widget">
514
-
515
- <p style="text-align: center;margin-bottom:0"><a href="https://wordpress.org/support/plugin/coming-soon" target="_blank"><?php _e('Got a Support Question', 'coming-soon') ?></a> <i class="fas fa-question-circle"></i>
516
- <!-- <li>&raquo; <a href="http://support.seedprod.com/article/83-how-to-clear-wp-super-caches-cache" target="_blank"><?php _e('Common Caching Issues Resolutions', 'coming-soon') ?></a></li> -->
517
- </p>
518
- <!-- <p style="text-align: center; margin-top:0">
 
 
 
519
 
520
  <a style="display:inline-block" href="https://wordpress.org/support/plugin/coming-soon/reviews/?filter=5#new-post">Please Rate this Plugin to show your Support!</a> <i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i></p> -->
521
-
522
 
523
-
524
 
525
- </div>
 
526
  </div>
527
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
528
 
529
- <form id="seed-bg-form" style="display:none" action="https://www.getdrip.com/forms/247721848/submissions" method="post" target="_blank">
530
- <div>
531
- <label for="drip-email">Email Address</label><br />
532
- <input type="email" id="drip-email" name="fields[email]" value="" />
533
- </div>
534
- <div>
535
- <input id="drip-submit" type="submit" name="submit" value="Sign Up" />
536
- </div>
537
- </form>
538
 
539
-
540
- <!-- <div class="postbox like-postbox">
541
  <div class="handlediv" title="Click to toggle"><br /></div>
542
  <h3 class="hndle"><span><i class="fas fa-heart"></i>&nbsp;&nbsp;<?php _e('Show Some Love', 'coming-soon') ?></span></h3>
543
  <div class="inside">
@@ -552,25 +562,24 @@ class SEED_CSP4_ADMIN
552
  </div>
553
  </div>
554
  </div> -->
555
-
556
 
557
 
558
- <!-- <div class="postbox rss-postbox">
 
559
  <div class="handlediv" title="Click to toggle"><br /></div>
560
  <h3 class="hndle"><span><i class="fab fa-wordpress"></i>&nbsp;&nbsp;<?php _e('SeedProd Blog', 'ultimate-coming-soon-page') ?></span></h3>
561
  <div class="inside">
562
 
563
  <div class="rss-widget">
564
  <?php
565
- wp_widget_rss_output(array(
566
- 'url' => 'http://feeds.feedburner.com/seedprod/',
567
- 'title' => 'SeedProd Blog',
568
- 'items' => 3,
569
- 'show_summary' => 0,
570
- 'show_author' => 0,
571
- 'show_date' => 1,
572
- ));
573
- ?>
574
  <ul>
575
 
576
  </ul>
@@ -578,46 +587,48 @@ class SEED_CSP4_ADMIN
578
  </div>
579
  </div> -->
580
 
581
- </div>
582
  </div>
583
- </div> <!-- #post-body -->
 
584
 
585
 
586
- </div> <!-- #poststuff -->
587
- <?php endif; ?>
588
- </div> <!-- .wrap --></div>
 
589
 
590
- <?php
591
- if(!empty($_GET['tab']) && $_GET['tab'] == 'seed_csp4_design'){
592
- ?>
593
 
594
 
595
- <?php
 
 
 
 
 
 
 
 
 
 
596
  }
597
- ?>
598
-
599
- <!-- JS login to confirm setting resets. -->
600
- <script>
601
- jQuery(document).ready(function($) {
602
- $('#reset').click(function(e){
603
- if(!confirm('<?php _e( 'This tabs settings be deleted and reset to the defaults. Are you sure you want to reset?', 'coming-soon' ); ?>')){
604
- e.preventDefault();
605
- }
606
- });
607
- });
608
- </script>
609
 
610
 
611
- <?php include SEED_CSP4_PLUGIN_PATH.'resources/views/exit-pop.php';?>
612
 
613
- <script>
614
- jQuery( document ).ready(function($) {
615
- $( ".seed-csp4-cta" ).click(function(e) {
616
- jQuery('.exit-popup-link').magnificPopup('open');
617
- });
618
- });
619
- </script>
620
- <?php
621
  }
622
 
623
  /**
@@ -627,27 +638,26 @@ class SEED_CSP4_ADMIN
627
  *
628
  * @since 0.1.0
629
  */
630
- function create_settings( )
631
  {
632
- foreach ( seed_csp4_get_options() as $k => $v ) {
633
-
634
- switch ( $v[ 'type' ] ) {
635
  case 'menu':
636
  $menu_slug = $v[ 'menu_slug' ];
637
 
638
  break;
639
  case 'setting':
640
- if ( empty( $v[ 'validate_function' ] ) ) {
641
  $v[ 'validate_function' ] = array(
642
  &$this,
643
  'validate_machine'
644
  );
645
  }
646
- register_setting( $v[ 'id' ], $v[ 'id' ], $v[ 'validate_function' ] );
647
  $setting_id = $v[ 'id' ];
648
  break;
649
  case 'section':
650
- if ( empty( $v[ 'desc_callback' ] ) ) {
651
  $v[ 'desc_callback' ] = array(
652
  &$this,
653
  'return_empty_string'
@@ -655,28 +665,28 @@ class SEED_CSP4_ADMIN
655
  } else {
656
  $v[ 'desc_callback' ] = $v[ 'desc_callback' ];
657
  }
658
- add_settings_section( $v[ 'id' ], $v[ 'label' ], $v[ 'desc_callback' ], $v[ 'id' ] );
659
  $section_id = $v[ 'id' ];
660
  break;
661
  case 'tab':
662
  break;
663
  default:
664
- if ( empty( $v[ 'callback' ] ) ) {
665
  $v[ 'callback' ] = array(
666
  &$this,
667
  'field_machine'
668
  );
669
  }
670
 
671
- add_settings_field( $v[ 'id' ], $v[ 'label' ], $v[ 'callback' ], $section_id, $section_id, array(
672
  'id' => $v[ 'id' ],
673
- 'desc' => ( isset( $v[ 'desc' ] ) ? $v[ 'desc' ] : '' ),
674
  'setting_id' => $setting_id,
675
- 'class' => ( isset( $v[ 'class' ] ) ? $v[ 'class' ] : '' ),
676
  'type' => $v[ 'type' ],
677
- 'default_value' => ( isset( $v[ 'default_value' ] ) ? $v[ 'default_value' ] : '' ),
678
- 'option_values' => ( isset( $v[ 'option_values' ] ) ? $v[ 'option_values' ] : '' )
679
- ) );
680
 
681
  }
682
  }
@@ -687,38 +697,37 @@ class SEED_CSP4_ADMIN
687
  *
688
  * @since 0.1.0
689
  */
690
- function field_machine( $args )
691
  {
692
- extract( $args ); //$id, $desc, $setting_id, $class, $type, $default_value, $option_values
693
 
694
  // Load defaults
695
  $defaults = array( );
696
- foreach ( seed_csp4_get_options() as $k ) {
697
- switch ( $k[ 'type' ] ) {
698
  case 'setting':
699
  case 'section':
700
  case 'tab':
701
  break;
702
  default:
703
- if ( isset( $k[ 'default_value' ] ) ) {
704
  $defaults[ $k[ 'id' ] ] = $k[ 'default_value' ];
705
  }
706
  }
707
  }
708
- $options = get_option( $setting_id );
709
 
710
- $options = wp_parse_args( $options, $defaults );
711
 
712
  $path = SEED_CSP4_PLUGIN_PATH . 'framework/field-types/' . $type . '.php';
713
- if ( file_exists( $path ) ) {
714
  // Show Field
715
- include( $path );
716
  // Show description
717
- if ( !empty( $desc ) ) {
718
  echo "<small class='description'>{$desc}</small>";
719
  }
720
  }
721
-
722
  }
723
 
724
  /**
@@ -729,42 +738,42 @@ class SEED_CSP4_ADMIN
729
  * @return array $input Contains sanitized values.
730
  * @todo Figure out best way to validate values.
731
  */
732
- function validate_machine( $input )
733
  {
734
  $option_page = $_POST['option_page'];
735
- foreach ( seed_csp4_get_options() as $k ) {
736
- switch ( $k[ 'type' ] ) {
737
  case 'menu':
738
  case 'setting':
739
- if(isset($k['id']))
740
  $setting_id = $k['id'];
 
 
741
  case 'section':
742
- case 'tab';
743
  break;
744
  default:
745
- if ( !empty( $k[ 'validate' ] ) && $setting_id == $option_page ) {
746
- $validation_rules = explode( ',', $k[ 'validate' ] );
747
 
748
- foreach ( $validation_rules as $v ) {
749
  $path = SEED_CSP4_PLUGIN_PATH . 'framework/validations/' . $v . '.php';
750
- if ( file_exists( $path ) ) {
751
  // Defaults Values
752
  $is_valid = true;
753
  $error_msg = '';
754
 
755
  // Test Validation
756
- include( $path );
757
 
758
  // Is it valid?
759
- if ( $is_valid === false ) {
760
- add_settings_error( $k[ 'id' ], 'seedprod_error', $error_msg, 'error' );
761
  // Unset invalids
762
- unset( $input[ $k[ 'id' ] ] );
763
  }
764
-
765
  }
766
  } //end foreach
767
-
768
  }
769
  }
770
  }
@@ -778,7 +787,7 @@ class SEED_CSP4_ADMIN
778
  * @since 0.1.0
779
  * @return string Empty
780
  */
781
- function return_empty_string( )
782
  {
783
  echo '';
784
  }
@@ -789,62 +798,65 @@ class SEED_CSP4_ADMIN
789
  *
790
  * @since 0.1.0
791
  */
792
- function do_settings_sections( $page, $show_submit )
793
  {
794
  global $wp_settings_sections, $wp_settings_fields;
795
 
796
- if ( !isset( $wp_settings_sections ) || !isset( $wp_settings_sections[ $page ] ) )
797
  return;
 
798
 
799
- foreach ( (array) $wp_settings_sections[ $page ] as $section ) {
800
  echo "<h3 class='hndle'>{$section['title']}</h3>\n";
801
  echo '<div class="inside">';
802
- call_user_func( $section[ 'callback' ], $section );
803
- if ( !isset( $wp_settings_fields ) || !isset( $wp_settings_fields[ $page ] ) || !isset( $wp_settings_fields[ $page ][ $section[ 'id' ] ] ) )
804
  continue;
 
805
  echo '<table class="form-table">';
806
- $this->do_settings_fields( $page, $section[ 'id' ] );
807
  echo '</table>';
808
- if($show_submit): ?>
809
- <p>
810
- <input name="submit" type="submit" value="<?php _e( 'Save All Changes', 'coming-soon' ); ?>" class="button-primary"/>
811
- </p>
812
- <?php endif;
813
  echo '</div>';
814
  }
815
  }
816
 
817
- function do_settings_fields($page, $section) {
818
- global $wp_settings_fields;
819
-
820
- if ( !isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section]) )
821
- return;
822
-
823
- foreach ( (array) $wp_settings_fields[$page][$section] as $field ) {
824
- echo '<tr valign="top">';
825
- if ( !empty($field['args']['label_for']) )
826
- echo '<th scope="row"><label for="' . $field['args']['label_for'] . '">' . $field['title'] . '</label></th>';
827
- else
828
- echo '<th scope="row"><strong>' . $field['title'] . '</strong><!--<br>'.$field['args']['desc'].'--></th>';
829
- echo '<td>';
830
- call_user_func($field['callback'], $field['args']);
831
- echo '</td>';
832
- echo '</tr>';
833
- }
834
- }
835
 
836
- }
 
 
837
 
838
- add_action( 'admin_head', 'seed_csp4_set_user_settings' );
839
- function seed_csp4_set_user_settings() {
840
- if(isset($_GET['page']) && $_GET['page'] == 'seed_csp4'){
841
- $user_id = get_current_user_id();
842
- $options = get_user_option( 'user-settings', $user_id );
843
- parse_str($options,$user_settings);
844
- $user_settings['imgsize'] = 'full';
845
- update_user_option( $user_id, 'user-settings', http_build_query($user_settings), false );
846
- update_user_option( $user_id, 'user-settings-time', time(), false );
847
- }
 
 
 
848
  }
849
 
850
-
 
 
 
 
 
 
 
 
 
 
 
22
  */
23
  protected static $instance = null;
24
 
25
+ /**
26
+ * Slug of the plugin screen.
27
+ *
28
+ * @since 1.0.0
29
+ *
30
+ * @var string
31
+ */
32
  protected $plugin_screen_hook_suffix = null;
33
 
34
  /**
35
  * Load Hooks
36
  */
37
+ public function __construct()
38
  {
39
+ if (is_admin() && (!defined('DOING_AJAX') || !DOING_AJAX)) {
40
+ add_action('admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ));
41
+ add_action('admin_menu', array( &$this, 'create_menus' ));
42
+ add_action('admin_init', array( &$this, 'reset_defaults' ));
43
+ add_action('admin_init', array( &$this, 'create_settings' ));
44
+ add_filter('plugin_action_links', array( &$this, 'plugin_action_links' ), 10, 2);
45
+ add_filter('tmp_grunion_allow_editor_view', '__return_false');
 
 
 
46
  }
47
 
48
+ if (defined('DOING_AJAX')) {
49
  // Background API Ajax
50
+ add_action('wp_ajax_seed_csp4_backgrounds', array(&$this,'backgrounds'));
51
  }
52
  }
53
 
58
  *
59
  * @return object A single instance of this class.
60
  */
61
+ public static function get_instance()
62
+ {
63
 
64
  // If the single instance hasn't been set, set it now.
65
+ if (null == self::$instance) {
66
  self::$instance = new self;
67
  }
68
 
73
  * backgrounds api
74
  *
75
  */
76
+ public function backgrounds()
77
  {
78
+ if (check_ajax_referer('seed_csp4_backgrounds')) {
79
+ $r = array();
 
80
  $page = '';
81
+ if (isset($_REQUEST['page'])) {
82
  $page = $_REQUEST['page'];
83
  $page = '?page='.$page;
84
  $r['page'] = $_REQUEST['page'];
85
  }
86
  $query = '';
87
+ if (isset($_REQUEST['query'])) {
88
  $query = $_REQUEST['query'];
89
  $query = '?query='.$query;
90
  $r['query'] = $_REQUEST['query'];
91
  }
92
 
93
+ if (false === (get_transient('seed_csp4_backgrounds_page_'.$query.$page))) {
94
+ //f(1){
95
  //echo 'miss';
96
 
97
  $bg_api = 'https://api.seedprod.com/v3/free_background_search';
98
 
99
+ $url = $bg_api.'?'.http_build_query($r);
100
+ $response = wp_remote_get($url);
101
  //var_dump($url);
102
+ if (is_wp_error($response)) {
103
  $error_message = $response->get_error_message();
104
  echo "Something went wrong: $error_message";
105
+ } else {
106
+ $response_code = wp_remote_retrieve_response_code($response);
107
+ if ($response_code == '200') {
108
+ set_transient('seed_csp4_backgrounds_page_'.$query.$page, $response['body'], 604800);
109
  echo $response['body'];
110
+ } else {
111
  echo 'There was an issue loading the stock images. Please try again later.';
112
  }
 
113
  }
114
+ } else {
115
  //echo 'hit';
116
+ echo get_transient('seed_csp4_backgrounds_page_'.$query.$page);
117
  }
118
 
119
 
126
  * Reset the settings page. Reset works per settings id.
127
  *
128
  */
129
+ public function reset_defaults()
130
  {
131
+ if (isset($_POST[ 'seed_csp4_reset' ])) {
132
  $option_page = $_POST[ 'option_page' ];
133
+ check_admin_referer($option_page . '-options');
134
  require_once(SEED_CSP4_PLUGIN_PATH.'inc/default-settings.php');
135
 
136
  $_POST[ $_POST[ 'option_page' ] ] = $seed_csp4_settings_deafults[$_POST[ 'option_page' ]];
137
+ add_settings_error('general', 'seed_csp4-settings-reset', __("Settings reset."), 'updated');
138
  }
139
  }
140
 
147
  * @since 0.1.0
148
  * @param string $hook_suffix The name of the current page we are on.
149
  */
150
+ public function admin_enqueue_scripts($hook_suffix)
151
  {
152
+ if (strpos($hook_suffix, 'seed_csp4') === false) {
153
  return;
154
+ }
155
 
156
+ wp_enqueue_script('media-upload');
157
+ wp_enqueue_script('jquery-ui-sortable');
158
+ wp_enqueue_script('wp-lists');
159
+ wp_enqueue_script('seed_csp4-framework-js', SEED_CSP4_PLUGIN_URL . 'framework/settings-scripts.js', array( 'jquery' ), $this->plugin_version);
160
+ wp_enqueue_script('seed_csp4-magnific-popup-js', SEED_CSP4_PLUGIN_URL . 'public/vendor/magnific-popup/jquery.magnific-popup.min.js', array( 'jquery' ), $this->plugin_version);
161
+ wp_enqueue_script('theme-preview');
162
+ wp_enqueue_style('thickbox');
163
+ wp_enqueue_style('media-upload');
164
+ wp_enqueue_style('wp-color-picker');
165
+ wp_enqueue_style('seed_csp4-framework-css', SEED_CSP4_PLUGIN_URL . 'framework/settings-style.css', false, $this->plugin_version);
166
+ wp_enqueue_style('font-awesome-solid', SEED_CSP4_PLUGIN_URL . 'public/vendor/fontawesome/css/solid.min.css', false, $this->plugin_version, false, $this->plugin_version);
167
+ wp_enqueue_style('font-awesome', SEED_CSP4_PLUGIN_URL . 'public/vendor/fontawesome/css/fontawesome.min.css', false, $this->plugin_version, false, $this->plugin_version);
168
+ wp_enqueue_style('seed_csp4-magnific-popup-js', SEED_CSP4_PLUGIN_URL . 'public/vendor/magnific-popup/magnific-popup.css', false, $this->plugin_version, false, $this->plugin_version);
169
  }
170
 
171
  /**
175
  *
176
  * @since 0.1.0
177
  */
178
+ public function create_menus()
179
  {
180
  add_menu_page(
181
+ __("SeedProd", 'coming-soon'),
182
+ __("SeedProd", 'coming-soon'),
183
  'manage_options',
184
  'seed_csp4',
185
  array( &$this , 'option_page' ),
189
 
190
  add_submenu_page(
191
  'seed_csp4',
192
+ __("Settings", 'coming-soon'),
193
+ __("Settings", 'coming-soon'),
194
  'manage_options',
195
  'seed_csp4',
196
  array( &$this , 'option_page' )
198
 
199
  add_submenu_page(
200
  'seed_csp4',
201
+ __("Themes", 'coming-soon'),
202
+ __("Themes", 'coming-soon'),
203
  'manage_options',
204
  'seed_csp4_themes',
205
  array( &$this , 'themes_page' )
207
 
208
  add_submenu_page(
209
  'seed_csp4',
210
+ __("Free Stock Images", 'coming-soon'),
211
+ __("Free Stock Images", 'coming-soon'),
212
  'manage_options',
213
  'seed_csp4_stockimages',
214
  array( &$this , 'stockimages_page' )
216
 
217
  add_submenu_page(
218
  'seed_csp4',
219
+ __("Subscribers", 'coming-soon'),
220
+ __("Subscribers", 'coming-soon'),
221
  'manage_options',
222
  'seed_csp4_subscribers',
223
  array( &$this , 'subscribers_page' )
225
 
226
  add_submenu_page(
227
  'seed_csp4',
228
+ __("Addons", 'coming-soon'),
229
+ __("<span style='color:#ff9a4b'>Addons</span>", 'coming-soon'),
230
  'manage_options',
231
  'seed_csp4_addons',
232
  array( &$this , 'addons_page' )
233
  );
234
  }
235
 
236
+ public function themes_page()
237
+ {
238
  include SEED_CSP4_PLUGIN_PATH.'resources/views/themes.php';
239
  }
240
 
241
+ public function stockimages_page()
242
+ {
243
  include SEED_CSP4_PLUGIN_PATH.'resources/views/stockimages.php';
244
  }
245
 
246
+ public function subscribers_page()
247
+ {
248
  include SEED_CSP4_PLUGIN_PATH.'resources/views/subscribers.php';
249
  }
250
 
251
+ public function addons_page()
252
+ {
253
  include SEED_CSP4_PLUGIN_PATH.'resources/views/addons.php';
254
  }
255
 
258
  /**
259
  * Display settings link on plugin page
260
  */
261
+ public function plugin_action_links($links, $file)
262
  {
263
  $plugin_file = SEED_CSP4_SLUG;
264
 
265
+ if ($file == $plugin_file) {
266
  $settings_link = '<a href="admin.php?page=seed_csp4">Settings</a>';
267
+ array_unshift($links, $settings_link);
268
  }
269
  return $links;
270
  }
274
  * Allow Tabs on the Settings Page
275
  *
276
  */
277
+ public function plugin_options_tabs()
278
  {
279
  $menu_slug = null;
280
  $page = $_REQUEST[ 'page' ];
281
  $uses_tabs = false;
282
+ $current_tab = isset($_GET[ 'tab' ]) ? $_GET[ 'tab' ] : false;
283
 
284
  //Check if this config uses tabs
285
+ foreach (seed_csp4_get_options() as $v) {
286
+ if ($v[ 'type' ] == 'tab') {
287
  $uses_tabs = true;
288
  break;
289
  }
290
  }
291
 
292
  // If uses tabs then generate the tabs
293
+ if ($uses_tabs) {
294
  echo '<h2 class="nav-tab-wrapper" style="padding-left:20px">';
295
  $c = 1;
296
+ foreach (seed_csp4_get_options() as $v) {
297
+ if (isset($v[ 'menu_slug' ])) {
298
+ $menu_slug = $v[ 'menu_slug' ];
299
+ }
300
+ if ($menu_slug == $page && $v[ 'type' ] == 'tab') {
301
+ $active = '';
302
+ if ($current_tab) {
303
+ $active = $current_tab == $v[ 'id' ] ? 'nav-tab-active' : '';
304
+ } elseif ($c == 1) {
305
+ $active = 'nav-tab-active';
306
+ }
307
+ if ($v[ 'id' ] == 'seed_csp4_subscribers') {
308
+ echo '<a id="'.$v[ 'id' ].'" class="nav-tab ' . $active . '" href="admin.php?page=seed_csp4_subscribers">';
309
+ } else {
310
+ echo '<a id="'.$v[ 'id' ].'" class="nav-tab ' . $active . '" href="?page=' . $menu_slug . '&tab=' . $v[ 'id' ] . '">';
311
  }
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
+ if ($v[ 'id' ] == 'seed_csp4_setting') {
314
+ echo '<i class="fas fa-edit"></i> ';
315
+ }
316
+ if ($v[ 'id' ] == 'seed_csp4_design') {
317
+ echo '<i class="fas fa-image"></i> ';
318
+ }
319
+ if ($v[ 'id' ] == 'seed_csp4_subscribers') {
320
+ echo '<i class="fas fa-users"></i> ';
 
 
 
 
 
 
321
  }
322
+ if ($v[ 'id' ] == 'seed_csp4_advanced') {
323
+ echo '<i class="fas fa-code"></i> ';
324
+ }
325
+ echo $v[ 'label' ] . '</a>';
326
+ $c++;
327
+ }
328
  }
329
+ echo '<a class="nav-tab seed_csp4-preview thickbox-preview" target="_blank" href="'.home_url().'?cs_preview=true" title="'.__('&larr; Close Window', 'coming-soon').'"><i class="fas fa-external-link-alt"></i> '.__('Live Preview', 'coming-soon').'</a>';
330
 
331
+ echo '<a class="nav-tab seed_csp4-support seed-csp4-cta" style="background-color: #04be5b;color: #fff" href="'.seed_csp4_admin_upgrade_link('upgrade-tab').'" target="_blank" rel="noopener noreferrer"><i class="fas fa-star"></i> '.__('Upgrade to Pro for More Features', 'coming-soon').'</a>';
332
 
333
 
334
  echo '</h2>';
 
335
  }
336
  }
337
 
339
  * Get the layout for the page. classic|2-col
340
  *
341
  */
342
+ public function get_page_layout()
343
  {
344
  $layout = 'classic';
345
+ foreach (seed_csp4_get_options() as $v) {
346
+ switch ($v[ 'type' ]) {
347
+ case 'menu':
348
  $page = $_REQUEST[ 'page' ];
349
+ if ($page == $v[ 'menu_slug' ]) {
350
+ if (isset($v[ 'layout' ])) {
351
  $layout = $v[ 'layout' ];
352
  }
353
  }
362
  *
363
  * @since 0.1.0
364
  */
365
+ public function option_page()
366
  {
367
  $menu_slug = null;
368
  $page = $_REQUEST[ 'page' ];
369
+ $layout = $this->get_page_layout(); ?>
 
370
 
371
 
372
+ <div class="wrap columns-2 seed-csp4">
373
+ <div id="seed_csp4_header">
374
+ <h1>
375
+ <img style="width:150px;margin-right:10px;margin-bottom: -2px;vertical-align: text-bottom;"
376
+ src="<?php echo SEED_CSP4_PLUGIN_URL ?>public/images/seedprod-logo.png">
377
+ Coming Soon Page and Maintenance Mode Lite
378
+ <span class="seed_csp4_version" style="font-size: 10px;"> Version <?php echo SEED_CSP4_VERSION; ?></span>
379
+ </h1>
380
 
381
 
382
 
383
+ <?php $this->plugin_options_tabs(); ?>
384
+ </div>
385
+
386
+ <div class="seed-wrap">
387
+ <?php if ($layout == '2-col'): ?>
388
+ <div id="poststuff">
389
+ <div id="post-body" class="metabox-holder columns-2">
390
+ <div id="post-body-content">
391
+ <?php endif; ?>
392
+ <?php if (!empty($_GET['tab'])) {
393
+ do_action('seed_csp4_render_page', array('tab'=>$_GET['tab']));
394
+ } ?>
395
  <form action="options.php" method="post">
396
 
397
+ <!-- <input name="submit" type="submit" value="<?php _e('Save All Changes', 'coming-soon'); ?>" class="button-primary"/> -->
398
+ <?php if (!empty($_GET['tab']) && $_GET['tab'] != 'seed_csp4_tab_3') {
399
+ ?>
400
+ <!-- <input id="reset" name="reset" type="submit" value="<?php _e('Reset Settings', 'coming-soon'); ?>" class="button-secondary"/> -->
401
+ <?php
402
+ } ?>
403
 
404
+ <?php
405
  $show_submit = false;
406
+ foreach (seed_csp4_get_options() as $v) {
407
+ if (isset($v[ 'menu_slug' ])) {
408
+ $menu_slug = $v[ 'menu_slug' ];
409
+ }
410
+ if ($menu_slug == $page) {
411
+ switch ($v[ 'type' ]) {
412
+ case 'menu':
413
  break;
414
+ case 'tab':
415
  $tab = $v;
416
+ if (empty($default_tab)) {
417
  $default_tab = $v[ 'id' ];
418
+ }
419
  break;
420
  case 'setting':
421
+ $current_tab = isset($_GET[ 'tab' ]) ? $_GET[ 'tab' ] : $default_tab;
422
+ if ($current_tab == $tab[ 'id' ]) {
423
+ settings_fields($v[ 'id' ]);
424
  $show_submit = true;
425
  }
426
 
427
  break;
428
  case 'section':
429
+ $current_tab = isset($_GET[ 'tab' ]) ? $_GET[ 'tab' ] : $default_tab;
430
+ if ($current_tab == $tab[ 'id' ] or $current_tab === false) {
431
+ if ($layout == '2-col') {
432
  echo '<div id="'.$v[ 'id' ].'" class="postbox seedprod-postbox">';
433
+ $this->do_settings_sections($v[ 'id' ], $show_submit);
434
  echo '</div>';
435
  } else {
436
+ do_settings_sections($v[ 'id' ]);
437
  }
 
438
  }
439
  break;
440
 
441
  }
442
+ }
443
+ } ?>
444
+ <?php if ($show_submit): ?>
445
+ <p>
446
+ <!-- <input name="submit" type="submit" value="<?php _e('Save All Changes', 'coming-soon'); ?>" class="button-primary"/> -->
447
+ <!-- <input id="reset" name="reset" type="submit" value="<?php _e('Reset Settings', 'coming-soon'); ?>" class="button-secondary"/> -->
448
+ </p>
449
+ <?php endif; ?>
 
 
450
  </form>
451
 
452
+ <?php if ($layout == '2-col'): ?>
453
+ </div> <!-- #post-body-content -->
454
 
455
+ <div id="postbox-container-1" class="postbox-container">
456
+ <div id="side-sortables" class="meta-box-sortables ui-sortable">
457
 
458
+ <!-- <div class="postbox ">
459
  <div class="handlediv" title="Click to toggle"><br /></div>
460
  <h3 class="hndle"><span><i class="fas fa-rocket"></i>&nbsp;&nbsp;<?php _e('Getting Started Video - 60 sec', 'coming-soon') ?></span></h3>
461
  <div class="inside">
465
  </div>
466
  </div> -->
467
 
 
 
 
468
 
469
+ <a style="border:1px solid #ddd;display:inline-block;"
470
+ href="https://www.seedprod.com/landing/coming-soon-page-getting-started-video/?utm_source=coming-soon-plugin&utm_medium=banner&utm_campaign=coming-soon-banner-in-plugin"
471
+ target="_blank"><img
472
+ src="<?php echo SEED_CSP4_PLUGIN_URL; ?>framework/getting-started-banner.png" /></a>
473
+ <br><br>
474
+
475
+
476
+ <a style="border:1px solid #ddd;display:inline-block;"
477
+ href="<?php echo seed_csp4_admin_upgrade_link('sidebar-banner')?>" target="_blank"
478
+ rel="noopener noreferrer" class="seed-csp4-cta"><img
479
+ src="<?php echo SEED_CSP4_PLUGIN_URL; ?>framework/coming-soon-pro-sidebar.png" /></a>
480
+ <br><br>
481
 
482
 
483
+ <!-- <div class="postbox " style="background-color:#FAE6A4;color:#333 !important; border-color:#333 !important">
484
  <div class="handlediv" title="Click to toggle"><br /></div>
485
  <h3 class="hndle" style="color:#fff !important;border-color:#333 !important; background-color:#333"><span><i class="fas fa-star"></i>&nbsp;&nbsp;<?php _e('Yo-Yo-Yo, Why Go Pro?', 'coming-soon') ?></span></h3>
486
  <div class="inside">
505
  <li><strong>Plus lots more!</strong></li>
506
  </ul>
507
  <p>
508
+ <a class="button-primary" style="background-color:#05AE0E; border-color:#05AE0E; box-shadow:none; text-shadow: none; width:100%; text-align:center;" href="<?php echo seed_csp4_admin_upgrade_link('sidebar'); ?>" target="_blank" rel="noopener noreferrer">See What's In The Pro Version</a>
509
  </p>
510
 
511
  </div>
512
  </div>
513
  </div> -->
514
 
515
+ <div class="postbox ">
516
+ <div class="handlediv" title="Click to toggle"><br /></div>
517
+
518
+ <div class="inside">
519
+ <div class="support-widget">
520
+
521
+ <p style="text-align: center;margin-bottom:0"><a
522
+ href="https://wordpress.org/support/plugin/coming-soon"
523
+ target="_blank"><?php _e('Got a Support Question', 'coming-soon') ?></a> <i
524
+ class="fas fa-question-circle"></i>
525
+ <!-- <li>&raquo; <a href="http://support.seedprod.com/article/83-how-to-clear-wp-super-caches-cache" target="_blank"><?php _e('Common Caching Issues Resolutions', 'coming-soon') ?></a></li> -->
526
+ </p>
527
+ <!-- <p style="text-align: center; margin-top:0">
528
 
529
  <a style="display:inline-block" href="https://wordpress.org/support/plugin/coming-soon/reviews/?filter=5#new-post">Please Rate this Plugin to show your Support!</a> <i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i></p> -->
 
530
 
 
531
 
532
+
533
+
534
  </div>
535
  </div>
536
+ </div>
537
+
538
+ <form id="seed-bg-form" style="display:none"
539
+ action="https://www.getdrip.com/forms/247721848/submissions" method="post" target="_blank">
540
+ <div>
541
+ <label for="drip-email">Email Address</label><br />
542
+ <input type="email" id="drip-email" name="fields[email]" value="" />
543
+ </div>
544
+ <div>
545
+ <input id="drip-submit" type="submit" name="submit" value="Sign Up" />
546
+ </div>
547
+ </form>
548
 
 
 
 
 
 
 
 
 
 
549
 
550
+ <!-- <div class="postbox like-postbox">
 
551
  <div class="handlediv" title="Click to toggle"><br /></div>
552
  <h3 class="hndle"><span><i class="fas fa-heart"></i>&nbsp;&nbsp;<?php _e('Show Some Love', 'coming-soon') ?></span></h3>
553
  <div class="inside">
562
  </div>
563
  </div>
564
  </div> -->
 
565
 
566
 
567
+
568
+ <!-- <div class="postbox rss-postbox">
569
  <div class="handlediv" title="Click to toggle"><br /></div>
570
  <h3 class="hndle"><span><i class="fab fa-wordpress"></i>&nbsp;&nbsp;<?php _e('SeedProd Blog', 'ultimate-coming-soon-page') ?></span></h3>
571
  <div class="inside">
572
 
573
  <div class="rss-widget">
574
  <?php
575
+ wp_widget_rss_output(array(
576
+ 'url' => 'http://feeds.feedburner.com/seedprod/',
577
+ 'title' => 'SeedProd Blog',
578
+ 'items' => 3,
579
+ 'show_summary' => 0,
580
+ 'show_author' => 0,
581
+ 'show_date' => 1,
582
+ )); ?>
 
583
  <ul>
584
 
585
  </ul>
587
  </div>
588
  </div> -->
589
 
 
590
  </div>
591
+ </div>
592
+ </div> <!-- #post-body -->
593
 
594
 
595
+ </div> <!-- #poststuff -->
596
+ <?php endif; ?>
597
+ </div> <!-- .wrap -->
598
+ </div>
599
 
600
+ <?php
601
+ if (!empty($_GET['tab']) && $_GET['tab'] == 'seed_csp4_design') {
602
+ ?>
603
 
604
 
605
+ <?php
606
+ } ?>
607
+
608
+ <!-- JS login to confirm setting resets. -->
609
+ <script>
610
+ jQuery(document).ready(function($) {
611
+ $('#reset').click(function(e) {
612
+ if (!confirm(
613
+ '<?php _e('This tabs settings be deleted and reset to the defaults. Are you sure you want to reset?', 'coming-soon'); ?>'
614
+ )) {
615
+ e.preventDefault();
616
  }
617
+ });
618
+ });
619
+ </script>
 
 
 
 
 
 
 
 
 
620
 
621
 
622
+ <?php include SEED_CSP4_PLUGIN_PATH.'resources/views/exit-pop.php'; ?>
623
 
624
+ <script>
625
+ jQuery(document).ready(function($) {
626
+ $(".seed-csp4-cta").click(function(e) {
627
+ jQuery('.exit-popup-link').magnificPopup('open');
628
+ });
629
+ });
630
+ </script>
631
+ <?php
632
  }
633
 
634
  /**
638
  *
639
  * @since 0.1.0
640
  */
641
+ public function create_settings()
642
  {
643
+ foreach (seed_csp4_get_options() as $k => $v) {
644
+ switch ($v[ 'type' ]) {
 
645
  case 'menu':
646
  $menu_slug = $v[ 'menu_slug' ];
647
 
648
  break;
649
  case 'setting':
650
+ if (empty($v[ 'validate_function' ])) {
651
  $v[ 'validate_function' ] = array(
652
  &$this,
653
  'validate_machine'
654
  );
655
  }
656
+ register_setting($v[ 'id' ], $v[ 'id' ], $v[ 'validate_function' ]);
657
  $setting_id = $v[ 'id' ];
658
  break;
659
  case 'section':
660
+ if (empty($v[ 'desc_callback' ])) {
661
  $v[ 'desc_callback' ] = array(
662
  &$this,
663
  'return_empty_string'
665
  } else {
666
  $v[ 'desc_callback' ] = $v[ 'desc_callback' ];
667
  }
668
+ add_settings_section($v[ 'id' ], $v[ 'label' ], $v[ 'desc_callback' ], $v[ 'id' ]);
669
  $section_id = $v[ 'id' ];
670
  break;
671
  case 'tab':
672
  break;
673
  default:
674
+ if (empty($v[ 'callback' ])) {
675
  $v[ 'callback' ] = array(
676
  &$this,
677
  'field_machine'
678
  );
679
  }
680
 
681
+ add_settings_field($v[ 'id' ], $v[ 'label' ], $v[ 'callback' ], $section_id, $section_id, array(
682
  'id' => $v[ 'id' ],
683
+ 'desc' => (isset($v[ 'desc' ]) ? $v[ 'desc' ] : ''),
684
  'setting_id' => $setting_id,
685
+ 'class' => (isset($v[ 'class' ]) ? $v[ 'class' ] : ''),
686
  'type' => $v[ 'type' ],
687
+ 'default_value' => (isset($v[ 'default_value' ]) ? $v[ 'default_value' ] : ''),
688
+ 'option_values' => (isset($v[ 'option_values' ]) ? $v[ 'option_values' ] : '')
689
+ ));
690
 
691
  }
692
  }
697
  *
698
  * @since 0.1.0
699
  */
700
+ public function field_machine($args)
701
  {
702
+ extract($args); //$id, $desc, $setting_id, $class, $type, $default_value, $option_values
703
 
704
  // Load defaults
705
  $defaults = array( );
706
+ foreach (seed_csp4_get_options() as $k) {
707
+ switch ($k[ 'type' ]) {
708
  case 'setting':
709
  case 'section':
710
  case 'tab':
711
  break;
712
  default:
713
+ if (isset($k[ 'default_value' ])) {
714
  $defaults[ $k[ 'id' ] ] = $k[ 'default_value' ];
715
  }
716
  }
717
  }
718
+ $options = get_option($setting_id);
719
 
720
+ $options = wp_parse_args($options, $defaults);
721
 
722
  $path = SEED_CSP4_PLUGIN_PATH . 'framework/field-types/' . $type . '.php';
723
+ if (file_exists($path)) {
724
  // Show Field
725
+ include($path);
726
  // Show description
727
+ if (!empty($desc)) {
728
  echo "<small class='description'>{$desc}</small>";
729
  }
730
  }
 
731
  }
732
 
733
  /**
738
  * @return array $input Contains sanitized values.
739
  * @todo Figure out best way to validate values.
740
  */
741
+ public function validate_machine($input)
742
  {
743
  $option_page = $_POST['option_page'];
744
+ foreach (seed_csp4_get_options() as $k) {
745
+ switch ($k[ 'type' ]) {
746
  case 'menu':
747
  case 'setting':
748
+ if (isset($k['id'])) {
749
  $setting_id = $k['id'];
750
+ }
751
+ // no break
752
  case 'section':
753
+ case 'tab':
754
  break;
755
  default:
756
+ if (!empty($k[ 'validate' ]) && $setting_id == $option_page) {
757
+ $validation_rules = explode(',', $k[ 'validate' ]);
758
 
759
+ foreach ($validation_rules as $v) {
760
  $path = SEED_CSP4_PLUGIN_PATH . 'framework/validations/' . $v . '.php';
761
+ if (file_exists($path)) {
762
  // Defaults Values
763
  $is_valid = true;
764
  $error_msg = '';
765
 
766
  // Test Validation
767
+ include($path);
768
 
769
  // Is it valid?
770
+ if ($is_valid === false) {
771
+ add_settings_error($k[ 'id' ], 'seedprod_error', $error_msg, 'error');
772
  // Unset invalids
773
+ unset($input[ $k[ 'id' ] ]);
774
  }
 
775
  }
776
  } //end foreach
 
777
  }
778
  }
779
  }
787
  * @since 0.1.0
788
  * @return string Empty
789
  */
790
+ public function return_empty_string()
791
  {
792
  echo '';
793
  }
798
  *
799
  * @since 0.1.0
800
  */
801
+ public function do_settings_sections($page, $show_submit)
802
  {
803
  global $wp_settings_sections, $wp_settings_fields;
804
 
805
+ if (!isset($wp_settings_sections) || !isset($wp_settings_sections[ $page ])) {
806
  return;
807
+ }
808
 
809
+ foreach ((array) $wp_settings_sections[ $page ] as $section) {
810
  echo "<h3 class='hndle'>{$section['title']}</h3>\n";
811
  echo '<div class="inside">';
812
+ call_user_func($section[ 'callback' ], $section);
813
+ if (!isset($wp_settings_fields) || !isset($wp_settings_fields[ $page ]) || !isset($wp_settings_fields[ $page ][ $section[ 'id' ] ])) {
814
  continue;
815
+ }
816
  echo '<table class="form-table">';
817
+ $this->do_settings_fields($page, $section[ 'id' ]);
818
  echo '</table>';
819
+ if ($show_submit): ?>
820
+ <p>
821
+ <input name="submit" type="submit" value="<?php _e('Save All Changes', 'coming-soon'); ?>" class="button-primary" />
822
+ </p>
823
+ <?php endif;
824
  echo '</div>';
825
  }
826
  }
827
 
828
+ public function do_settings_fields($page, $section)
829
+ {
830
+ global $wp_settings_fields;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
831
 
832
+ if (!isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section])) {
833
+ return;
834
+ }
835
 
836
+ foreach ((array) $wp_settings_fields[$page][$section] as $field) {
837
+ echo '<tr valign="top">';
838
+ if (!empty($field['args']['label_for'])) {
839
+ echo '<th scope="row"><label for="' . $field['args']['label_for'] . '">' . $field['title'] . '</label></th>';
840
+ } else {
841
+ echo '<th scope="row"><strong>' . $field['title'] . '</strong><!--<br>'.$field['args']['desc'].'--></th>';
842
+ }
843
+ echo '<td>';
844
+ call_user_func($field['callback'], $field['args']);
845
+ echo '</td>';
846
+ echo '</tr>';
847
+ }
848
+ }
849
  }
850
 
851
+ add_action('admin_head', 'seed_csp4_set_user_settings');
852
+ function seed_csp4_set_user_settings()
853
+ {
854
+ if (isset($_GET['page']) && $_GET['page'] == 'seed_csp4') {
855
+ $user_id = get_current_user_id();
856
+ $options = get_user_option('user-settings', $user_id);
857
+ parse_str($options, $user_settings);
858
+ $user_settings['imgsize'] = 'full';
859
+ update_user_option($user_id, 'user-settings', http_build_query($user_settings), false);
860
+ update_user_option($user_id, 'user-settings-time', time(), false);
861
+ }
862
+ }
lib/TGMPA.php DELETED
@@ -1,3833 +0,0 @@
1
- <?php
2
-
3
- namespace ComingSoon;
4
-
5
- /**
6
- * Plugin installation and activation for WordPress themes.
7
- *
8
- * Please note that this is a drop-in library for a theme or plugin.
9
- * The authors of this library (Thomas, Gary and Juliette) are NOT responsible
10
- * for the support of your plugin or theme. Please contact the plugin
11
- * or theme author for support.
12
- *
13
- * @package TGM-Plugin-Activation
14
- * @version 2.6.1
15
- * @link http://tgmpluginactivation.com/
16
- * @author Thomas Griffin, Gary Jones, Juliette Reinders Folmer
17
- * @copyright Copyright (c) 2011, Thomas Griffin
18
- * @license GPL-2.0+
19
- */
20
-
21
- /*
22
- Copyright 2011 Thomas Griffin (thomasgriffinmedia.com)
23
-
24
- This program is free software; you can redistribute it and/or modify
25
- it under the terms of the GNU General Public License, version 2, as
26
- published by the Free Software Foundation.
27
-
28
- This program is distributed in the hope that it will be useful,
29
- but WITHOUT ANY WARRANTY; without even the implied warranty of
30
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31
- GNU General Public License for more details.
32
-
33
- You should have received a copy of the GNU General Public License
34
- along with this program; if not, write to the Free Software
35
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36
- */
37
-
38
- /**
39
- * Automatic plugin installation and activation library.
40
- *
41
- * Creates a way to automatically install and activate plugins from within themes.
42
- * The plugins can be either bundled, downloaded from the WordPress
43
- * Plugin Repository or downloaded from another external source.
44
- *
45
- * @since 1.0.0
46
- *
47
- * @package TGM-Plugin-Activation
48
- * @author Thomas Griffin
49
- * @author Gary Jones
50
- */
51
- class TGM_Plugin_Activation {
52
- /**
53
- * TGMPA version number.
54
- *
55
- * @since 2.5.0
56
- *
57
- * @const string Version number.
58
- */
59
- const TGMPA_VERSION = '2.6.1';
60
-
61
- /**
62
- * Regular expression to test if a URL is a WP plugin repo URL.
63
- *
64
- * @const string Regex.
65
- *
66
- * @since 2.5.0
67
- */
68
- const WP_REPO_REGEX = '|^http[s]?://wordpress\.org/(?:extend/)?plugins/|';
69
-
70
- /**
71
- * Arbitrary regular expression to test if a string starts with a URL.
72
- *
73
- * @const string Regex.
74
- *
75
- * @since 2.5.0
76
- */
77
- const IS_URL_REGEX = '|^http[s]?://|';
78
-
79
- /**
80
- * Holds a copy of itself, so it can be referenced by the class name.
81
- *
82
- * @since 1.0.0
83
- *
84
- * @var TGM_Plugin_Activation
85
- */
86
- public static $instance;
87
-
88
- /**
89
- * Holds arrays of plugin details.
90
- *
91
- * @since 1.0.0
92
- * @since 2.5.0 the array has the plugin slug as an associative key.
93
- *
94
- * @var array
95
- */
96
- public $plugins = array();
97
-
98
- /**
99
- * Holds arrays of plugin names to use to sort the plugins array.
100
- *
101
- * @since 2.5.0
102
- *
103
- * @var array
104
- */
105
- protected $sort_order = array();
106
-
107
- /**
108
- * Whether any plugins have the 'force_activation' setting set to true.
109
- *
110
- * @since 2.5.0
111
- *
112
- * @var bool
113
- */
114
- protected $has_forced_activation = false;
115
-
116
- /**
117
- * Whether any plugins have the 'force_deactivation' setting set to true.
118
- *
119
- * @since 2.5.0
120
- *
121
- * @var bool
122
- */
123
- protected $has_forced_deactivation = false;
124
-
125
- /**
126
- * Name of the unique ID to hash notices.
127
- *
128
- * @since 2.4.0
129
- *
130
- * @var string
131
- */
132
- public $id = 'tgmpa';
133
-
134
- /**
135
- * Name of the query-string argument for the admin page.
136
- *
137
- * @since 1.0.0
138
- *
139
- * @var string
140
- */
141
- protected $menu = 'tgmpa-install-plugins';
142
-
143
- /**
144
- * Parent menu file slug.
145
- *
146
- * @since 2.5.0
147
- *
148
- * @var string
149
- */
150
- public $parent_slug = 'themes.php';
151
-
152
- /**
153
- * Capability needed to view the plugin installation menu item.
154
- *
155
- * @since 2.5.0
156
- *
157
- * @var string
158
- */
159
- public $capability = 'edit_theme_options';
160
-
161
- /**
162
- * Default absolute path to folder containing bundled plugin zip files.
163
- *
164
- * @since 2.0.0
165
- *
166
- * @var string Absolute path prefix to zip file location for bundled plugins. Default is empty string.
167
- */
168
- public $default_path = '';
169
-
170
- /**
171
- * Flag to show admin notices or not.
172
- *
173
- * @since 2.1.0
174
- *
175
- * @var boolean
176
- */
177
- public $has_notices = true;
178
-
179
- /**
180
- * Flag to determine if the user can dismiss the notice nag.
181
- *
182
- * @since 2.4.0
183
- *
184
- * @var boolean
185
- */
186
- public $dismissable = true;
187
-
188
- /**
189
- * Message to be output above nag notice if dismissable is false.
190
- *
191
- * @since 2.4.0
192
- *
193
- * @var string
194
- */
195
- public $dismiss_msg = '';
196
-
197
- /**
198
- * Flag to set automatic activation of plugins. Off by default.
199
- *
200
- * @since 2.2.0
201
- *
202
- * @var boolean
203
- */
204
- public $is_automatic = false;
205
-
206
- /**
207
- * Optional message to display before the plugins table.
208
- *
209
- * @since 2.2.0
210
- *
211
- * @var string Message filtered by wp_kses_post(). Default is empty string.
212
- */
213
- public $message = '';
214
-
215
- /**
216
- * Holds configurable array of strings.
217
- *
218
- * Default values are added in the constructor.
219
- *
220
- * @since 2.0.0
221
- *
222
- * @var array
223
- */
224
- public $strings = array();
225
-
226
- /**
227
- * Holds the version of WordPress.
228
- *
229
- * @since 2.4.0
230
- *
231
- * @var int
232
- */
233
- public $wp_version;
234
-
235
- /**
236
- * Holds the hook name for the admin page.
237
- *
238
- * @since 2.5.0
239
- *
240
- * @var string
241
- */
242
- public $page_hook;
243
-
244
- /**
245
- * Adds a reference of this object to $instance, populates default strings,
246
- * does the tgmpa_init action hook, and hooks in the interactions to init.
247
- *
248
- * {@internal This method should be `protected`, but as too many TGMPA implementations
249
- * haven't upgraded beyond v2.3.6 yet, this gives backward compatibility issues.
250
- * Reverted back to public for the time being.}}
251
- *
252
- * @since 1.0.0
253
- *
254
- * @see TGM_Plugin_Activation::init()
255
- */
256
- public function __construct() {
257
- // Set the current WordPress version.
258
- $this->wp_version = $GLOBALS['wp_version'];
259
-
260
- // Announce that the class is ready, and pass the object (for advanced use).
261
- do_action_ref_array( 'wpms_tgmpa_init', array( $this ) );
262
-
263
- /*
264
- * Load our text domain and allow for overloading the fall-back file.
265
- *
266
- * {@internal IMPORTANT! If this code changes, review the regex in the custom TGMPA
267
- * generator on the website.}}
268
- */
269
- add_action( 'init', array( $this, 'load_textdomain' ), 5 );
270
- add_filter( 'load_textdomain_mofile', array( $this, 'overload_textdomain_mofile' ), 10, 2 );
271
-
272
- // When the rest of WP has loaded, kick-start the rest of the class.
273
- add_action( 'init', array( $this, 'init' ) );
274
- }
275
-
276
- /**
277
- * Magic method to (not) set protected properties from outside of this class.
278
- *
279
- * {@internal hackedihack... There is a serious bug in v2.3.2 - 2.3.6 where the `menu` property
280
- * is being assigned rather than tested in a conditional, effectively rendering it useless.
281
- * This 'hack' prevents this from happening.}}
282
- *
283
- * @see https://github.com/TGMPA/TGM-Plugin-Activation/blob/2.3.6/tgm-plugin-activation/class-tgm-plugin-activation.php#L1593
284
- *
285
- * @since 2.5.2
286
- *
287
- * @param string $name Name of an inaccessible property.
288
- * @param mixed $value Value to assign to the property.
289
- * @return void Silently fail to set the property when this is tried from outside of this class context.
290
- * (Inside this class context, the __set() method if not used as there is direct access.)
291
- */
292
- public function __set( $name, $value ) {
293
- return;
294
- }
295
-
296
- /**
297
- * Magic method to get the value of a protected property outside of this class context.
298
- *
299
- * @since 2.5.2
300
- *
301
- * @param string $name Name of an inaccessible property.
302
- * @return mixed The property value.
303
- */
304
- public function __get( $name ) {
305
- return $this->{$name};
306
- }
307
-
308
- /**
309
- * Initialise the interactions between this class and WordPress.
310
- *
311
- * Hooks in three new methods for the class: admin_menu, notices and styles.
312
- *
313
- * @since 2.0.0
314
- *
315
- * @see TGM_Plugin_Activation::admin_menu()
316
- * @see TGM_Plugin_Activation::notices()
317
- * @see TGM_Plugin_Activation::styles()
318
- */
319
- public function init() {
320
- /**
321
- * By default TGMPA only loads on the WP back-end and not in an Ajax call. Using this filter
322
- * you can overrule that behaviour.
323
- *
324
- * @since 2.5.0
325
- *
326
- * @param bool $load Whether or not TGMPA should load.
327
- * Defaults to the return of `is_admin() && ! defined( 'DOING_AJAX' )`.
328
- */
329
- if ( true !== apply_filters( 'wpms_tgmpa_load', ( is_admin() && ! defined( 'DOING_AJAX' ) ) ) ) {
330
- return;
331
- }
332
-
333
- // Load class strings.
334
- $this->strings = array(
335
- 'page_title' => __( 'Install Required Plugins', 'tgmpa' ),
336
- 'menu_title' => __( 'Install Plugins', 'tgmpa' ),
337
- /* translators: %s: plugin name. */
338
- 'installing' => __( 'Installing Plugin: %s', 'tgmpa' ),
339
- /* translators: %s: plugin name. */
340
- 'updating' => __( 'Updating Plugin: %s', 'tgmpa' ),
341
- 'oops' => __( 'Something went wrong with the plugin API.', 'tgmpa' ),
342
- 'notice_can_install_required' => _n_noop(
343
- /* translators: 1: plugin name(s). */
344
- 'This theme requires the following plugin: %1$s.',
345
- 'This theme requires the following plugins: %1$s.',
346
- 'tgmpa'
347
- ),
348
- 'notice_can_install_recommended' => _n_noop(
349
- /* translators: 1: plugin name(s). */
350
- 'This theme recommends the following plugin: %1$s.',
351
- 'This theme recommends the following plugins: %1$s.',
352
- 'tgmpa'
353
- ),
354
- 'notice_ask_to_update' => _n_noop(
355
- /* translators: 1: plugin name(s). */
356
- 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.',
357
- 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.',
358
- 'tgmpa'
359
- ),
360
- 'notice_ask_to_update_maybe' => _n_noop(
361
- /* translators: 1: plugin name(s). */
362
- 'There is an update available for: %1$s.',
363
- 'There are updates available for the following plugins: %1$s.',
364
- 'tgmpa'
365
- ),
366
- 'notice_can_activate_required' => _n_noop(
367
- /* translators: 1: plugin name(s). */
368
- 'The following required plugin is currently inactive: %1$s.',
369
- 'The following required plugins are currently inactive: %1$s.',
370
- 'tgmpa'
371
- ),
372
- 'notice_can_activate_recommended' => _n_noop(
373
- /* translators: 1: plugin name(s). */
374
- 'The following recommended plugin is currently inactive: %1$s.',
375
- 'The following recommended plugins are currently inactive: %1$s.',
376
- 'tgmpa'
377
- ),
378
- 'install_link' => _n_noop(
379
- 'Begin installing plugin',
380
- 'Begin installing plugins',
381
- 'tgmpa'
382
- ),
383
- 'update_link' => _n_noop(
384
- 'Begin updating plugin',
385
- 'Begin updating plugins',
386
- 'tgmpa'
387
- ),
388
- 'activate_link' => _n_noop(
389
- 'Begin activating plugin',
390
- 'Begin activating plugins',
391
- 'tgmpa'
392
- ),
393
- 'return' => __( 'Return to Required Plugins Installer', 'tgmpa' ),
394
- 'dashboard' => __( 'Return to the Dashboard', 'tgmpa' ),
395
- 'plugin_activated' => __( 'Plugin activated successfully.', 'tgmpa' ),
396
- 'activated_successfully' => __( 'The following plugin was activated successfully:', 'tgmpa' ),
397
- /* translators: 1: plugin name. */
398
- 'plugin_already_active' => __( 'No action taken. Plugin %1$s was already active.', 'tgmpa' ),
399
- /* translators: 1: plugin name. */
400
- 'plugin_needs_higher_version' => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'tgmpa' ),
401
- /* translators: 1: dashboard link. */
402
- 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ),
403
- 'dismiss' => __( 'Dismiss this notice', 'tgmpa' ),
404
- 'notice_cannot_install_activate' => __( 'There are one or more required or recommended plugins to install, update or activate.', 'tgmpa' ),
405
- 'contact_admin' => __( 'Please contact the administrator of this site for help.', 'tgmpa' ),
406
- );
407
-
408
- do_action( 'wpms_tgmpa_register' );
409
-
410
- /* After this point, the plugins should be registered and the configuration set. */
411
-
412
- // Proceed only if we have plugins to handle.
413
- if ( empty( $this->plugins ) || ! is_array( $this->plugins ) ) {
414
- return;
415
- }
416
-
417
- // Set up the menu and notices if we still have outstanding actions.
418
- if ( true !== $this->is_tgmpa_complete() ) {
419
- // Sort the plugins.
420
- array_multisort( $this->sort_order, SORT_ASC, $this->plugins );
421
-
422
- add_action( 'admin_menu', array( $this, 'admin_menu' ) );
423
- add_action( 'admin_head', array( $this, 'dismiss' ) );
424
-
425
- // Prevent the normal links from showing underneath a single install/update page.
426
- add_filter( 'install_plugin_complete_actions', array( $this, 'actions' ) );
427
- add_filter( 'update_plugin_complete_actions', array( $this, 'actions' ) );
428
-
429
- if ( $this->has_notices ) {
430
- add_action( 'admin_notices', array( $this, 'notices' ) );
431
- add_action( 'admin_init', array( $this, 'admin_init' ), 1 );
432
- add_action( 'admin_enqueue_scripts', array( $this, 'thickbox' ) );
433
- }
434
- }
435
-
436
- // If needed, filter plugin action links.
437
- add_action( 'load-plugins.php', array( $this, 'add_plugin_action_link_filters' ), 1 );
438
-
439
- // Make sure things get reset on switch theme.
440
- add_action( 'switch_theme', array( $this, 'flush_plugins_cache' ) );
441
-
442
- if ( $this->has_notices ) {
443
- add_action( 'switch_theme', array( $this, 'update_dismiss' ) );
444
- }
445
-
446
- // Setup the force activation hook.
447
- if ( true === $this->has_forced_activation ) {
448
- add_action( 'admin_init', array( $this, 'force_activation' ) );
449
- }
450
-
451
- // Setup the force deactivation hook.
452
- if ( true === $this->has_forced_deactivation ) {
453
- add_action( 'switch_theme', array( $this, 'force_deactivation' ) );
454
- }
455
- }
456
-
457
- /**
458
- * Load translations.
459
- *
460
- * @since 2.6.0
461
- *
462
- * (@internal Uses `load_theme_textdomain()` rather than `load_plugin_textdomain()` to
463
- * get round the different ways of handling the path and deprecated notices being thrown
464
- * and such. For plugins, the actual file name will be corrected by a filter.}}
465
- *
466
- * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA
467
- * generator on the website.}}
468
- */
469
- public function load_textdomain() {
470
- if ( is_textdomain_loaded( 'tgmpa' ) ) {
471
- return;
472
- }
473
-
474
- if ( false !== strpos( __FILE__, WP_PLUGIN_DIR ) || false !== strpos( __FILE__, WPMU_PLUGIN_DIR ) ) {
475
- // Plugin, we'll need to adjust the file name.
476
- add_action( 'load_textdomain_mofile', array( $this, 'correct_plugin_mofile' ), 10, 2 );
477
- load_theme_textdomain( 'tgmpa', dirname( __FILE__ ) . '/languages' );
478
- remove_action( 'load_textdomain_mofile', array( $this, 'correct_plugin_mofile' ), 10 );
479
- } else {
480
- load_theme_textdomain( 'tgmpa', dirname( __FILE__ ) . '/languages' );
481
- }
482
- }
483
-
484
- /**
485
- * Correct the .mo file name for (must-use) plugins.
486
- *
487
- * Themese use `/path/{locale}.mo` while plugins use `/path/{text-domain}-{locale}.mo`.
488
- *
489
- * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA
490
- * generator on the website.}}
491
- *
492
- * @since 2.6.0
493
- *
494
- * @param string $mofile Full path to the target mofile.
495
- * @param string $domain The domain for which a language file is being loaded.
496
- * @return string $mofile
497
- */
498
- public function correct_plugin_mofile( $mofile, $domain ) {
499
- // Exit early if not our domain (just in case).
500
- if ( 'tgmpa' !== $domain ) {
501
- return $mofile;
502
- }
503
- return preg_replace( '`/([a-z]{2}_[A-Z]{2}.mo)$`', '/tgmpa-$1', $mofile );
504
- }
505
-
506
- /**
507
- * Potentially overload the fall-back translation file for the current language.
508
- *
509
- * WP, by default since WP 3.7, will load a local translation first and if none
510
- * can be found, will try and find a translation in the /wp-content/languages/ directory.
511
- * As this library is theme/plugin agnostic, translation files for TGMPA can exist both
512
- * in the WP_LANG_DIR /plugins/ subdirectory as well as in the /themes/ subdirectory.
513
- *
514
- * This method makes sure both directories are checked.
515
- *
516
- * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA
517
- * generator on the website.}}
518
- *
519
- * @since 2.6.0
520
- *
521
- * @param string $mofile Full path to the target mofile.
522
- * @param string $domain The domain for which a language file is being loaded.
523
- * @return string $mofile
524
- */
525
- public function overload_textdomain_mofile( $mofile, $domain ) {
526
- // Exit early if not our domain, not a WP_LANG_DIR load or if the file exists and is readable.
527
- if ( 'tgmpa' !== $domain || false === strpos( $mofile, WP_LANG_DIR ) || @is_readable( $mofile ) ) {
528
- return $mofile;
529
- }
530
-
531
- // Current fallback file is not valid, let's try the alternative option.
532
- if ( false !== strpos( $mofile, '/themes/' ) ) {
533
- return str_replace( '/themes/', '/plugins/', $mofile );
534
- } elseif ( false !== strpos( $mofile, '/plugins/' ) ) {
535
- return str_replace( '/plugins/', '/themes/', $mofile );
536
- } else {
537
- return $mofile;
538
- }
539
- }
540
-
541
- /**
542
- * Hook in plugin action link filters for the WP native plugins page.
543
- *
544
- * - Prevent activation of plugins which don't meet the minimum version requirements.
545
- * - Prevent deactivation of force-activated plugins.
546
- * - Add update notice if update available.
547
- *
548
- * @since 2.5.0
549
- */
550
- public function add_plugin_action_link_filters() {
551
- foreach ( $this->plugins as $slug => $plugin ) {
552
- if ( false === $this->can_plugin_activate( $slug ) ) {
553
- add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_activate' ), 20 );
554
- }
555
-
556
- if ( true === $plugin['force_activation'] ) {
557
- add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_deactivate' ), 20 );
558
- }
559
-
560
- if ( false !== $this->does_plugin_require_update( $slug ) ) {
561
- add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_update' ), 20 );
562
- }
563
- }
564
- }
565
-
566
- /**
567
- * Remove the 'Activate' link on the WP native plugins page if the plugin does not meet the
568
- * minimum version requirements.
569
- *
570
- * @since 2.5.0
571
- *
572
- * @param array $actions Action links.
573
- * @return array
574
- */
575
- public function filter_plugin_action_links_activate( $actions ) {
576
- unset( $actions['activate'] );
577
-
578
- return $actions;
579
- }
580
-
581
- /**
582
- * Remove the 'Deactivate' link on the WP native plugins page if the plugin has been set to force activate.
583
- *
584
- * @since 2.5.0
585
- *
586
- * @param array $actions Action links.
587
- * @return array
588
- */
589
- public function filter_plugin_action_links_deactivate( $actions ) {
590
- unset( $actions['deactivate'] );
591
-
592
- return $actions;
593
- }
594
-
595
- /**
596
- * Add a 'Requires update' link on the WP native plugins page if the plugin does not meet the
597
- * minimum version requirements.
598
- *
599
- * @since 2.5.0
600
- *
601
- * @param array $actions Action links.
602
- * @return array
603
- */
604
- public function filter_plugin_action_links_update( $actions ) {
605
- $actions['update'] = sprintf(
606
- '<a href="%1$s" title="%2$s" class="edit">%3$s</a>',
607
- esc_url( $this->get_tgmpa_status_url( 'update' ) ),
608
- esc_attr__( 'This plugin needs to be updated to be compatible with your theme.', 'tgmpa' ),
609
- esc_html__( 'Update Required', 'tgmpa' )
610
- );
611
-
612
- return $actions;
613
- }
614
-
615
- /**
616
- * Handles calls to show plugin information via links in the notices.
617
- *
618
- * We get the links in the admin notices to point to the TGMPA page, rather
619
- * than the typical plugin-install.php file, so we can prepare everything
620
- * beforehand.
621
- *
622
- * WP does not make it easy to show the plugin information in the thickbox -
623
- * here we have to require a file that includes a function that does the
624
- * main work of displaying it, enqueue some styles, set up some globals and
625
- * finally call that function before exiting.
626
- *
627
- * Down right easy once you know how...
628
- *
629
- * Returns early if not the TGMPA page.
630
- *
631
- * @since 2.1.0
632
- *
633
- * @global string $tab Used as iframe div class names, helps with styling
634
- * @global string $body_id Used as the iframe body ID, helps with styling
635
- *
636
- * @return void Returns early if not the TGMPA page.
637
- */
638
- public function admin_init() {
639
- if ( ! $this->is_tgmpa_page() ) {
640
- return;
641
- }
642
-
643
- if ( isset( $_REQUEST['tab'] ) && 'plugin-information' === $_REQUEST['tab'] ) {
644
- // Needed for install_plugin_information().
645
- require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
646
-
647
- wp_enqueue_style( 'plugin-install' );
648
-
649
- global $tab, $body_id;
650
- $body_id = 'plugin-information';
651
- // @codingStandardsIgnoreStart
652
- $tab = 'plugin-information';
653
- // @codingStandardsIgnoreEnd
654
-
655
- install_plugin_information();
656
-
657
- exit;
658
- }
659
- }
660
-
661
- /**
662
- * Enqueue thickbox scripts/styles for plugin info.
663
- *
664
- * Thickbox is not automatically included on all admin pages, so we must
665
- * manually enqueue it for those pages.
666
- *
667
- * Thickbox is only loaded if the user has not dismissed the admin
668
- * notice or if there are any plugins left to install and activate.
669
- *
670
- * @since 2.1.0
671
- */
672
- public function thickbox() {
673
- if ( ! get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) ) {
674
- add_thickbox();
675
- }
676
- }
677
-
678
- /**
679
- * Adds submenu page if there are plugin actions to take.
680
- *
681
- * This method adds the submenu page letting users know that a required
682
- * plugin needs to be installed.
683
- *
684
- * This page disappears once the plugin has been installed and activated.
685
- *
686
- * @since 1.0.0
687
- *
688
- * @see TGM_Plugin_Activation::init()
689
- * @see TGM_Plugin_Activation::install_plugins_page()
690
- *
691
- * @return void Return early if user lacks capability to install a plugin.
692
- */
693
- public function admin_menu() {
694
- // Make sure privileges are correct to see the page.
695
- if ( ! current_user_can( 'install_plugins' ) ) {
696
- return;
697
- }
698
-
699
- $args = apply_filters(
700
- 'wpms_tgmpa_admin_menu_args',
701
- array(
702
- 'parent_slug' => $this->parent_slug, // Parent Menu slug.
703
- 'page_title' => $this->strings['page_title'], // Page title.
704
- 'menu_title' => $this->strings['menu_title'], // Menu title.
705
- 'capability' => $this->capability, // Capability.
706
- 'menu_slug' => $this->menu, // Menu slug.
707
- 'function' => array( $this, 'install_plugins_page' ), // Callback.
708
- )
709
- );
710
-
711
- $this->add_admin_menu( $args );
712
- }
713
-
714
- /**
715
- * Add the menu item.
716
- *
717
- * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA
718
- * generator on the website.}}
719
- *
720
- * @since 2.5.0
721
- *
722
- * @param array $args Menu item configuration.
723
- */
724
- protected function add_admin_menu( array $args ) {
725
- if ( has_filter( 'wpms_tgmpa_admin_menu_use_add_theme_page' ) ) {
726
- _deprecated_function( 'The "tgmpa_admin_menu_use_add_theme_page" filter', '2.5.0', esc_html__( 'Set the parent_slug config variable instead.', 'tgmpa' ) );
727
- }
728
-
729
- if ( 'themes.php' === $this->parent_slug ) {
730
- $this->page_hook = call_user_func( 'add_theme_page', $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] );
731
- } else {
732
- $this->page_hook = call_user_func( 'add_submenu_page', $args['parent_slug'], $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] );
733
- }
734
- }
735
-
736
- /**
737
- * Echoes plugin installation form.
738
- *
739
- * This method is the callback for the admin_menu method function.
740
- * This displays the admin page and form area where the user can select to install and activate the plugin.
741
- * Aborts early if we're processing a plugin installation action.
742
- *
743
- * @since 1.0.0
744
- *
745
- * @return null Aborts early if we're processing a plugin installation action.
746
- */
747
- public function install_plugins_page() {
748
- // Store new instance of plugin table in object.
749
- $plugin_table = new TGMPA_List_Table();
750
-
751
- // Return early if processing a plugin installation action.
752
- if ( ( ( 'tgmpa-bulk-install' === $plugin_table->current_action() || 'tgmpa-bulk-update' === $plugin_table->current_action() ) && $plugin_table->process_bulk_actions() ) || $this->do_plugin_install() ) {
753
- return;
754
- }
755
-
756
- // Force refresh of available plugin information so we'll know about manual updates/deletes.
757
- wp_clean_plugins_cache( false );
758
-
759
- ?>
760
- <div class="tgmpa wrap">
761
- <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
762
- <?php $plugin_table->prepare_items(); ?>
763
-
764
- <?php
765
- if ( ! empty( $this->message ) && is_string( $this->message ) ) {
766
- echo wp_kses_post( $this->message );
767
- }
768
- ?>
769
- <?php $plugin_table->views(); ?>
770
-
771
- <form id="tgmpa-plugins" action="" method="post">
772
- <input type="hidden" name="tgmpa-page" value="<?php echo esc_attr( $this->menu ); ?>" />
773
- <input type="hidden" name="plugin_status" value="<?php echo esc_attr( $plugin_table->view_context ); ?>" />
774
- <?php $plugin_table->display(); ?>
775
- </form>
776
- </div>
777
- <?php
778
- }
779
-
780
- /**
781
- * Installs, updates or activates a plugin depending on the action link clicked by the user.
782
- *
783
- * Checks the $_GET variable to see which actions have been
784
- * passed and responds with the appropriate method.
785
- *
786
- * Uses WP_Filesystem to process and handle the plugin installation
787
- * method.
788
- *
789
- * @since 1.0.0
790
- *
791
- * @uses WP_Filesystem
792
- * @uses WP_Error
793
- * @uses WP_Upgrader
794
- * @uses Plugin_Upgrader
795
- * @uses Plugin_Installer_Skin
796
- * @uses Plugin_Upgrader_Skin
797
- *
798
- * @return boolean True on success, false on failure.
799
- */
800
- protected function do_plugin_install() {
801
- if ( empty( $_GET['plugin'] ) ) {
802
- return false;
803
- }
804
-
805
- // All plugin information will be stored in an array for processing.
806
- $slug = $this->sanitize_key( urldecode( $_GET['plugin'] ) );
807
-
808
- if ( ! isset( $this->plugins[ $slug ] ) ) {
809
- return false;
810
- }
811
-
812
- // Was an install or upgrade action link clicked?
813
- if ( ( isset( $_GET['tgmpa-install'] ) && 'install-plugin' === $_GET['tgmpa-install'] ) || ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) ) {
814
-
815
- $install_type = 'install';
816
- if ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) {
817
- $install_type = 'update';
818
- }
819
-
820
- // Note that SeedProd referred the install
821
- if($install_type == 'install'){
822
- add_option('seed_csp4_wpforms', true,'', false);
823
- }
824
-
825
- check_admin_referer( 'tgmpa-' . $install_type, 'tgmpa-nonce' );
826
-
827
- // Pass necessary information via URL if WP_Filesystem is needed.
828
- $url = wp_nonce_url(
829
- add_query_arg(
830
- array(
831
- 'plugin' => urlencode( $slug ),
832
- 'tgmpa-' . $install_type => $install_type . '-plugin',
833
- ),
834
- $this->get_tgmpa_url()
835
- ),
836
- 'tgmpa-' . $install_type,
837
- 'tgmpa-nonce'
838
- );
839
-
840
- $method = ''; // Leave blank so WP_Filesystem can populate it as necessary.
841
-
842
- if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, array() ) ) ) {
843
- return true;
844
- }
845
-
846
- if ( ! WP_Filesystem( $creds ) ) {
847
- request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, array() ); // Setup WP_Filesystem.
848
- return true;
849
- }
850
-
851
- /* If we arrive here, we have the filesystem. */
852
-
853
- // Prep variables for Plugin_Installer_Skin class.
854
- $extra = array();
855
- $extra['slug'] = $slug; // Needed for potentially renaming of directory name.
856
- $source = $this->get_download_url( $slug );
857
- $api = ( 'repo' === $this->plugins[ $slug ]['source_type'] ) ? $this->get_plugins_api( $slug ) : null;
858
- $api = ( false !== $api ) ? $api : null;
859
-
860
- $url = add_query_arg(
861
- array(
862
- 'action' => $install_type . '-plugin',
863
- 'plugin' => urlencode( $slug ),
864
- ),
865
- 'update.php'
866
- );
867
-
868
- if ( ! class_exists( '\Plugin_Upgrader', false ) ) {
869
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
870
- }
871
-
872
- $title = ( 'update' === $install_type ) ? $this->strings['updating'] : $this->strings['installing'];
873
- $skin_args = array(
874
- 'type' => ( 'bundled' !== $this->plugins[ $slug ]['source_type'] ) ? 'web' : 'upload',
875
- 'title' => sprintf( $title, $this->plugins[ $slug ]['name'] ),
876
- 'url' => esc_url_raw( $url ),
877
- 'nonce' => $install_type . '-plugin_' . $slug,
878
- 'plugin' => '',
879
- 'api' => $api,
880
- 'extra' => $extra,
881
- );
882
- unset( $title );
883
-
884
- if ( 'update' === $install_type ) {
885
- $skin_args['plugin'] = $this->plugins[ $slug ]['file_path'];
886
- $skin = new \Plugin_Upgrader_Skin( $skin_args );
887
- } else {
888
- $skin = new \Plugin_Installer_Skin( $skin_args );
889
- }
890
-
891
- // Create a new instance of Plugin_Upgrader.
892
- $upgrader = new \Plugin_Upgrader( $skin );
893
-
894
- // Perform the action and install the plugin from the $source urldecode().
895
- add_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1, 3 );
896
-
897
- if ( 'update' === $install_type ) {
898
- // Inject our info into the update transient.
899
- $to_inject = array( $slug => $this->plugins[ $slug ] );
900
- $to_inject[ $slug ]['source'] = $source;
901
- $this->inject_update_info( $to_inject );
902
-
903
- $upgrader->upgrade( $this->plugins[ $slug ]['file_path'] );
904
- } else {
905
- $upgrader->install( $source );
906
- }
907
-
908
- remove_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1 );
909
-
910
- // Make sure we have the correct file path now the plugin is installed/updated.
911
- $this->populate_file_path( $slug );
912
-
913
- // Only activate plugins if the config option is set to true and the plugin isn't
914
- // already active (upgrade).
915
- if ( $this->is_automatic && ! $this->is_plugin_active( $slug ) ) {
916
- $plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method.
917
- if ( false === $this->activate_single_plugin( $plugin_activate, $slug, true ) ) {
918
- return true; // Finish execution of the function early as we encountered an error.
919
- }
920
- }
921
-
922
- $this->show_tgmpa_version();
923
-
924
- // Display message based on if all plugins are now active or not.
925
- if ( $this->is_tgmpa_complete() ) {
926
- echo '<p>', sprintf( esc_html( $this->strings['complete'] ), '<a href="' . esc_url( self_admin_url() ) . '">' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '</a>' ), '</p>';
927
- echo '<style type="text/css">#adminmenu .wp-submenu li.current { display: none !important; }</style>';
928
- } else {
929
- echo '<p><a href="', esc_url( $this->get_tgmpa_url() ), '" target="_parent">', esc_html( $this->strings['return'] ), '</a></p>';
930
- }
931
-
932
- return true;
933
- } elseif ( isset( $this->plugins[ $slug ]['file_path'], $_GET['tgmpa-activate'] ) && 'activate-plugin' === $_GET['tgmpa-activate'] ) {
934
- // Activate action link was clicked.
935
- check_admin_referer( 'tgmpa-activate', 'tgmpa-nonce' );
936
-
937
- if ( false === $this->activate_single_plugin( $this->plugins[ $slug ]['file_path'], $slug ) ) {
938
- return true; // Finish execution of the function early as we encountered an error.
939
- }
940
- }
941
-
942
- return false;
943
- }
944
-
945
- /**
946
- * Inject information into the 'update_plugins' site transient as WP checks that before running an update.
947
- *
948
- * @since 2.5.0
949
- *
950
- * @param array $plugins The plugin information for the plugins which are to be updated.
951
- */
952
- public function inject_update_info( $plugins ) {
953
- $repo_updates = get_site_transient( 'update_plugins' );
954
-
955
- if ( ! is_object( $repo_updates ) ) {
956
- $repo_updates = new \stdClass();
957
- }
958
-
959
- foreach ( $plugins as $slug => $plugin ) {
960
- $file_path = $plugin['file_path'];
961
-
962
- if ( empty( $repo_updates->response[ $file_path ] ) ) {
963
- $repo_updates->response[ $file_path ] = new \stdClass();
964
- }
965
-
966
- // We only really need to set package, but let's do all we can in case WP changes something.
967
- $repo_updates->response[ $file_path ]->slug = $slug;
968
- $repo_updates->response[ $file_path ]->plugin = $file_path;
969
- $repo_updates->response[ $file_path ]->new_version = $plugin['version'];
970
- $repo_updates->response[ $file_path ]->package = $plugin['source'];
971
- if ( empty( $repo_updates->response[ $file_path ]->url ) && ! empty( $plugin['external_url'] ) ) {
972
- $repo_updates->response[ $file_path ]->url = $plugin['external_url'];
973
- }
974
- }
975
-
976
- set_site_transient( 'update_plugins', $repo_updates );
977
- }
978
-
979
- /**
980
- * Adjust the plugin directory name if necessary.
981
- *
982
- * The final destination directory of a plugin is based on the subdirectory name found in the
983
- * (un)zipped source. In some cases - most notably GitHub repository plugin downloads -, this
984
- * subdirectory name is not the same as the expected slug and the plugin will not be recognized
985
- * as installed. This is fixed by adjusting the temporary unzipped source subdirectory name to
986
- * the expected plugin slug.
987
- *
988
- * @since 2.5.0
989
- *
990
- * @param string $source Path to upgrade/zip-file-name.tmp/subdirectory/.
991
- * @param string $remote_source Path to upgrade/zip-file-name.tmp.
992
- * @param \WP_Upgrader $upgrader Instance of the upgrader which installs the plugin.
993
- * @return string $source
994
- */
995
- public function maybe_adjust_source_dir( $source, $remote_source, $upgrader ) {
996
- if ( ! $this->is_tgmpa_page() || ! is_object( $GLOBALS['wp_filesystem'] ) ) {
997
- return $source;
998
- }
999
-
1000
- // Check for single file plugins.
1001
- $source_files = array_keys( $GLOBALS['wp_filesystem']->dirlist( $remote_source ) );
1002
- if ( 1 === count( $source_files ) && false === $GLOBALS['wp_filesystem']->is_dir( $source ) ) {
1003
- return $source;
1004
- }
1005
-
1006
- // Multi-file plugin, let's see if the directory is correctly named.
1007
- $desired_slug = '';
1008
-
1009
- // Figure out what the slug is supposed to be.
1010
- if ( false === $upgrader->bulk && ! empty( $upgrader->skin->options['extra']['slug'] ) ) {
1011
- $desired_slug = $upgrader->skin->options['extra']['slug'];
1012
- } else {
1013
- // Bulk installer contains less info, so fall back on the info registered here.
1014
- foreach ( $this->plugins as $slug => $plugin ) {
1015
- if ( ! empty( $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) && $plugin['name'] === $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) {
1016
- $desired_slug = $slug;
1017
- break;
1018
- }
1019
- }
1020
- unset( $slug, $plugin );
1021
- }
1022
-
1023
- if ( ! empty( $desired_slug ) ) {
1024
- $subdir_name = untrailingslashit( str_replace( trailingslashit( $remote_source ), '', $source ) );
1025
-
1026
- if ( ! empty( $subdir_name ) && $subdir_name !== $desired_slug ) {
1027
- $from_path = untrailingslashit( $source );
1028
- $to_path = trailingslashit( $remote_source ) . $desired_slug;
1029
-
1030
- if ( true === $GLOBALS['wp_filesystem']->move( $from_path, $to_path ) ) {
1031
- return trailingslashit( $to_path );
1032
- } else {
1033
- return new \WP_Error( 'rename_failed', esc_html__( 'The remote plugin package does not contain a folder with the desired slug and renaming did not work.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) );
1034
- }
1035
- } elseif ( empty( $subdir_name ) ) {
1036
- return new \WP_Error( 'packaged_wrong', esc_html__( 'The remote plugin package consists of more than one file, but the files are not packaged in a folder.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) );
1037
- }
1038
- }
1039
-
1040
- return $source;
1041
- }
1042
-
1043
- /**
1044
- * Activate a single plugin and send feedback about the result to the screen.
1045
- *
1046
- * @since 2.5.0
1047
- *
1048
- * @param string $file_path Path within wp-plugins/ to main plugin file.
1049
- * @param string $slug Plugin slug.
1050
- * @param bool $automatic Whether this is an automatic activation after an install. Defaults to false.
1051
- * This determines the styling of the output messages.
1052
- * @return bool False if an error was encountered, true otherwise.
1053
- */
1054
- protected function activate_single_plugin( $file_path, $slug, $automatic = false ) {
1055
- if ( $this->can_plugin_activate( $slug ) ) {
1056
- $activate = activate_plugin( $file_path );
1057
-
1058
- if ( is_wp_error( $activate ) ) {
1059
- echo '<div id="message" class="error"><p>', wp_kses_post( $activate->get_error_message() ), '</p></div>',
1060
- '<p><a href="', esc_url( $this->get_tgmpa_url() ), '" target="_parent">', esc_html( $this->strings['return'] ), '</a></p>';
1061
-
1062
- return false; // End it here if there is an error with activation.
1063
- } else {
1064
- if ( ! $automatic ) {
1065
- // Make sure message doesn't display again if bulk activation is performed
1066
- // immediately after a single activation.
1067
- if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK.
1068
- echo '<div id="message" class="updated"><p>', esc_html( $this->strings['activated_successfully'] ), ' <strong>', esc_html( $this->plugins[ $slug ]['name'] ), '.</strong></p></div>';
1069
- }
1070
- } else {
1071
- // Simpler message layout for use on the plugin install page.
1072
- echo '<p>', esc_html( $this->strings['plugin_activated'] ), '</p>';
1073
- }
1074
- }
1075
- } elseif ( $this->is_plugin_active( $slug ) ) {
1076
- // No simpler message format provided as this message should never be encountered
1077
- // on the plugin install page.
1078
- echo '<div id="message" class="error"><p>',
1079
- sprintf(
1080
- esc_html( $this->strings['plugin_already_active'] ),
1081
- '<strong>' . esc_html( $this->plugins[ $slug ]['name'] ) . '</strong>'
1082
- ),
1083
- '</p></div>';
1084
- } elseif ( $this->does_plugin_require_update( $slug ) ) {
1085
- if ( ! $automatic ) {
1086
- // Make sure message doesn't display again if bulk activation is performed
1087
- // immediately after a single activation.
1088
- if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK.
1089
- echo '<div id="message" class="error"><p>',
1090
- sprintf(
1091
- esc_html( $this->strings['plugin_needs_higher_version'] ),
1092
- '<strong>' . esc_html( $this->plugins[ $slug ]['name'] ) . '</strong>'
1093
- ),
1094
- '</p></div>';
1095
- }
1096
- } else {
1097
- // Simpler message layout for use on the plugin install page.
1098
- echo '<p>', sprintf( esc_html( $this->strings['plugin_needs_higher_version'] ), esc_html( $this->plugins[ $slug ]['name'] ) ), '</p>';
1099
- }
1100
- }
1101
-
1102
- return true;
1103
- }
1104
-
1105
- /**
1106
- * Echoes required plugin notice.
1107
- *
1108
- * Outputs a message telling users that a specific plugin is required for
1109
- * their theme. If appropriate, it includes a link to the form page where
1110
- * users can install and activate the plugin.
1111
- *
1112
- * Returns early if we're on the Install page.
1113
- *
1114
- * @since 1.0.0
1115
- *
1116
- * @global object $current_screen
1117
- *
1118
- * @return void Returns early if we're on the Install page.
1119
- */
1120
- public function notices() {
1121
- // Remove nag on the install page / Return early if the nag message has been dismissed or user < author.
1122
- if ( ( $this->is_tgmpa_page() || $this->is_core_update_page() ) || get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) || ! current_user_can( apply_filters( 'wpms_tgmpa_show_admin_notice_capability', 'publish_posts' ) ) ) {
1123
- return;
1124
- }
1125
-
1126
- // Store for the plugin slugs by message type.
1127
- $message = array();
1128
-
1129
- // Initialize counters used to determine plurality of action link texts.
1130
- $install_link_count = 0;
1131
- $update_link_count = 0;
1132
- $activate_link_count = 0;
1133
- $total_required_action_count = 0;
1134
-
1135
- foreach ( $this->plugins as $slug => $plugin ) {
1136
- if ( $this->is_plugin_active( $slug ) && false === $this->does_plugin_have_update( $slug ) ) {
1137
- continue;
1138
- }
1139
-
1140
- if ( ! $this->is_plugin_installed( $slug ) ) {
1141
- if ( current_user_can( 'install_plugins' ) ) {
1142
- $install_link_count++;
1143
-
1144
- if ( true === $plugin['required'] ) {
1145
- $message['notice_can_install_required'][] = $slug;
1146
- } else {
1147
- $message['notice_can_install_recommended'][] = $slug;
1148
- }
1149
- }
1150
- if ( true === $plugin['required'] ) {
1151
- $total_required_action_count++;
1152
- }
1153
- } else {
1154
- if ( ! $this->is_plugin_active( $slug ) && $this->can_plugin_activate( $slug ) ) {
1155
- if ( current_user_can( 'activate_plugins' ) ) {
1156
- $activate_link_count++;
1157
-
1158
- if ( true === $plugin['required'] ) {
1159
- $message['notice_can_activate_required'][] = $slug;
1160
- } else {
1161
- $message['notice_can_activate_recommended'][] = $slug;
1162
- }
1163
- }
1164
- if ( true === $plugin['required'] ) {
1165
- $total_required_action_count++;
1166
- }
1167
- }
1168
-
1169
- if ( $this->does_plugin_require_update( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) {
1170
-
1171
- if ( current_user_can( 'update_plugins' ) ) {
1172
- $update_link_count++;
1173
-
1174
- if ( $this->does_plugin_require_update( $slug ) ) {
1175
- $message['notice_ask_to_update'][] = $slug;
1176
- } elseif ( false !== $this->does_plugin_have_update( $slug ) ) {
1177
- $message['notice_ask_to_update_maybe'][] = $slug;
1178
- }
1179
- }
1180
- if ( true === $plugin['required'] ) {
1181
- $total_required_action_count++;
1182
- }
1183
- }
1184
- }
1185
- }
1186
- unset( $slug, $plugin );
1187
-
1188
- // If we have notices to display, we move forward.
1189
- if ( ! empty( $message ) || $total_required_action_count > 0 ) {
1190
- krsort( $message ); // Sort messages.
1191
- $rendered = '';
1192
-
1193
- // As add_settings_error() wraps the final message in a <p> and as the final message can't be
1194
- // filtered, using <p>'s in our html would render invalid html output.
1195
- $line_template = '<span style="display: block; margin: 0.5em 0.5em 0 0; clear: both;">%s</span>' . "\n";
1196
-
1197
- if ( ! current_user_can( 'activate_plugins' ) && ! current_user_can( 'install_plugins' ) && ! current_user_can( 'update_plugins' ) ) {
1198
- $rendered = esc_html( $this->strings['notice_cannot_install_activate'] ) . ' ' . esc_html( $this->strings['contact_admin'] );
1199
- $rendered .= $this->create_user_action_links_for_notice( 0, 0, 0, $line_template );
1200
- } else {
1201
-
1202
- // If dismissable is false and a message is set, output it now.
1203
- if ( ! $this->dismissable && ! empty( $this->dismiss_msg ) ) {
1204
- $rendered .= sprintf( $line_template, wp_kses_post( $this->dismiss_msg ) );
1205
- }
1206
-
1207
- // Render the individual message lines for the notice.
1208
- foreach ( $message as $type => $plugin_group ) {
1209
- $linked_plugins = array();
1210
-
1211
- // Get the external info link for a plugin if one is available.
1212
- foreach ( $plugin_group as $plugin_slug ) {
1213
- $linked_plugins[] = $this->get_info_link( $plugin_slug );
1214
- }
1215
- unset( $plugin_slug );
1216
-
1217
- $count = count( $plugin_group );
1218
- $linked_plugins = array_map( array( '\ComingSoon\TGMPA_Utils', 'wrap_in_em' ), $linked_plugins );
1219
- $last_plugin = array_pop( $linked_plugins ); // Pop off last name to prep for readability.
1220
- $imploded = empty( $linked_plugins ) ? $last_plugin : ( implode( ', ', $linked_plugins ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin );
1221
-
1222
- $rendered .= sprintf(
1223
- $line_template,
1224
- sprintf(
1225
- translate_nooped_plural( $this->strings[ $type ], $count, 'tgmpa' ),
1226
- $imploded,
1227
- $count
1228
- )
1229
- );
1230
-
1231
- }
1232
- unset( $type, $plugin_group, $linked_plugins, $count, $last_plugin, $imploded );
1233
-
1234
- $rendered .= $this->create_user_action_links_for_notice( $install_link_count, $update_link_count, $activate_link_count, $line_template );
1235
- }
1236
-
1237
- // Register the nag messages and prepare them to be processed.
1238
- add_settings_error( 'tgmpa', 'tgmpa', $rendered, $this->get_admin_notice_class() );
1239
- }
1240
-
1241
- // Admin options pages already output settings_errors, so this is to avoid duplication.
1242
- if ( 'options-general' !== $GLOBALS['current_screen']->parent_base ) {
1243
- $this->display_settings_errors();
1244
- }
1245
- }
1246
-
1247
- /**
1248
- * Generate the user action links for the admin notice.
1249
- *
1250
- * @since 2.6.0
1251
- *
1252
- * @param int $install_count Number of plugins to install.
1253
- * @param int $update_count Number of plugins to update.
1254
- * @param int $activate_count Number of plugins to activate.
1255
- * @param int $line_template Template for the HTML tag to output a line.
1256
- * @return string Action links.
1257
- */
1258
- protected function create_user_action_links_for_notice( $install_count, $update_count, $activate_count, $line_template ) {
1259
- // Setup action links.
1260
- $action_links = array(
1261
- 'install' => '',
1262
- 'update' => '',
1263
- 'activate' => '',
1264
- 'dismiss' => $this->dismissable ? '<a href="' . esc_url( wp_nonce_url( add_query_arg( 'tgmpa-dismiss', 'dismiss_admin_notices' ), 'tgmpa-dismiss-' . get_current_user_id() ) ) . '" class="dismiss-notice" target="_parent">' . esc_html( $this->strings['dismiss'] ) . '</a>' : '',
1265
- );
1266
-
1267
- $link_template = '<a href="%2$s">%1$s</a>';
1268
-
1269
- if ( current_user_can( 'install_plugins' ) ) {
1270
- if ( $install_count > 0 ) {
1271
- $action_links['install'] = sprintf(
1272
- $link_template,
1273
- translate_nooped_plural( $this->strings['install_link'], $install_count, 'tgmpa' ),
1274
- esc_url( $this->get_tgmpa_status_url( 'install' ) )
1275
- );
1276
- }
1277
- if ( $update_count > 0 ) {
1278
- $action_links['update'] = sprintf(
1279
- $link_template,
1280
- translate_nooped_plural( $this->strings['update_link'], $update_count, 'tgmpa' ),
1281
- esc_url( $this->get_tgmpa_status_url( 'update' ) )
1282
- );
1283
- }
1284
- }
1285
-
1286
- if ( current_user_can( 'activate_plugins' ) && $activate_count > 0 ) {
1287
- $action_links['activate'] = sprintf(
1288
- $link_template,
1289
- translate_nooped_plural( $this->strings['activate_link'], $activate_count, 'tgmpa' ),
1290
- esc_url( $this->get_tgmpa_status_url( 'activate' ) )
1291
- );
1292
- }
1293
-
1294
- $action_links = apply_filters( 'wpms_tgmpa_notice_action_links', $action_links );
1295
-
1296
- $action_links = array_filter( (array) $action_links ); // Remove any empty array items.
1297
-
1298
- if ( ! empty( $action_links ) ) {
1299
- $action_links = sprintf( $line_template, implode( ' | ', $action_links ) );
1300
- return apply_filters( 'wpms_tgmpa_notice_rendered_action_links', $action_links );
1301
- } else {
1302
- return '';
1303
- }
1304
- }
1305
-
1306
- /**
1307
- * Get admin notice class.
1308
- *
1309
- * Work around all the changes to the various admin notice classes between WP 4.4 and 3.7
1310
- * (lowest supported version by TGMPA).
1311
- *
1312
- * @since 2.6.0
1313
- *
1314
- * @return string
1315
- */
1316
- protected function get_admin_notice_class() {
1317
- if ( ! empty( $this->strings['nag_type'] ) ) {
1318
- return sanitize_html_class( strtolower( $this->strings['nag_type'] ) );
1319
- } else {
1320
- if ( version_compare( $this->wp_version, '4.2', '>=' ) ) {
1321
- return 'notice-warning';
1322
- } elseif ( version_compare( $this->wp_version, '4.1', '>=' ) ) {
1323
- return 'notice';
1324
- } else {
1325
- return 'updated';
1326
- }
1327
- }
1328
- }
1329
-
1330
- /**
1331
- * Display settings errors and remove those which have been displayed to avoid duplicate messages showing
1332
- *
1333
- * @since 2.5.0
1334
- */
1335
- protected function display_settings_errors() {
1336
- global $wp_settings_errors;
1337
-
1338
- settings_errors( 'tgmpa' );
1339
-
1340
- foreach ( (array) $wp_settings_errors as $key => $details ) {
1341
- if ( 'tgmpa' === $details['setting'] ) {
1342
- unset( $wp_settings_errors[ $key ] );
1343
- break;
1344
- }
1345
- }
1346
- }
1347
-
1348
- /**
1349
- * Register dismissal of admin notices.
1350
- *
1351
- * Acts on the dismiss link in the admin nag messages.
1352
- * If clicked, the admin notice disappears and will no longer be visible to this user.
1353
- *
1354
- * @since 2.1.0
1355
- */
1356
- public function dismiss() {
1357
- if ( isset( $_GET['tgmpa-dismiss'] ) && check_admin_referer( 'tgmpa-dismiss-' . get_current_user_id() ) ) {
1358
- update_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, 1 );
1359
- }
1360
- }
1361
-
1362
- /**
1363
- * Add individual plugin to our collection of plugins.
1364
- *
1365
- * If the required keys are not set or the plugin has already
1366
- * been registered, the plugin is not added.
1367
- *
1368
- * @since 2.0.0
1369
- *
1370
- * @param array|null $plugin Array of plugin arguments or null if invalid argument.
1371
- * @return void Return early if incorrect argument.
1372
- */
1373
- public function register( $plugin ) {
1374
- if ( empty( $plugin['slug'] ) || empty( $plugin['name'] ) ) {
1375
- return;
1376
- }
1377
-
1378
- if ( empty( $plugin['slug'] ) || ! is_string( $plugin['slug'] ) || isset( $this->plugins[ $plugin['slug'] ] ) ) {
1379
- return;
1380
- }
1381
-
1382
- $defaults = array(
1383
- 'name' => '', // String.
1384
- 'slug' => '', // String.
1385
- 'source' => 'repo', // String.
1386
- 'required' => false, // Boolean.
1387
- 'version' => '', // String.
1388
- 'force_activation' => false, // Boolean.
1389
- 'force_deactivation' => false, // Boolean.
1390
- 'external_url' => '', // String.
1391
- 'is_callable' => '', // String|Array.
1392
- );
1393
-
1394
- // Prepare the received data.
1395
- $plugin = wp_parse_args( $plugin, $defaults );
1396
-
1397
- // Standardize the received slug.
1398
- $plugin['slug'] = $this->sanitize_key( $plugin['slug'] );
1399
-
1400
- // Forgive users for using string versions of booleans or floats for version number.
1401
- $plugin['version'] = (string) $plugin['version'];
1402
- $plugin['source'] = empty( $plugin['source'] ) ? 'repo' : $plugin['source'];
1403
- $plugin['required'] = TGMPA_Utils::validate_bool( $plugin['required'] );
1404
- $plugin['force_activation'] = TGMPA_Utils::validate_bool( $plugin['force_activation'] );
1405
- $plugin['force_deactivation'] = TGMPA_Utils::validate_bool( $plugin['force_deactivation'] );
1406
-
1407
- // Enrich the received data.
1408
- $plugin['file_path'] = $this->_get_plugin_basename_from_slug( $plugin['slug'] );
1409
- $plugin['source_type'] = $this->get_plugin_source_type( $plugin['source'] );
1410
-
1411
- // Set the class properties.
1412
- $this->plugins[ $plugin['slug'] ] = $plugin;
1413
- $this->sort_order[ $plugin['slug'] ] = $plugin['name'];
1414
-
1415
- // Should we add the force activation hook ?
1416
- if ( true === $plugin['force_activation'] ) {
1417
- $this->has_forced_activation = true;
1418
- }
1419
-
1420
- // Should we add the force deactivation hook ?
1421
- if ( true === $plugin['force_deactivation'] ) {
1422
- $this->has_forced_deactivation = true;
1423
- }
1424
- }
1425
-
1426
- /**
1427
- * Determine what type of source the plugin comes from.
1428
- *
1429
- * @since 2.5.0
1430
- *
1431
- * @param string $source The source of the plugin as provided, either empty (= WP repo), a file path
1432
- * (= bundled) or an external URL.
1433
- * @return string 'repo', 'external', or 'bundled'
1434
- */
1435
- protected function get_plugin_source_type( $source ) {
1436
- if ( 'repo' === $source || preg_match( self::WP_REPO_REGEX, $source ) ) {
1437
- return 'repo';
1438
- } elseif ( preg_match( self::IS_URL_REGEX, $source ) ) {
1439
- return 'external';
1440
- } else {
1441
- return 'bundled';
1442
- }
1443
- }
1444
-
1445
- /**
1446
- * Sanitizes a string key.
1447
- *
1448
- * Near duplicate of WP Core `sanitize_key()`. The difference is that uppercase characters *are*
1449
- * allowed, so as not to break upgrade paths from non-standard bundled plugins using uppercase
1450
- * characters in the plugin directory path/slug. Silly them.
1451
- *
1452
- * @see https://developer.wordpress.org/reference/hooks/sanitize_key/
1453
- *
1454
- * @since 2.5.0
1455
- *
1456
- * @param string $key String key.
1457
- * @return string Sanitized key
1458
- */
1459
- public function sanitize_key( $key ) {
1460
- $raw_key = $key;
1461
- $key = preg_replace( '`[^A-Za-z0-9_-]`', '', $key );
1462
-
1463
- /**
1464
- * Filter a sanitized key string.
1465
- *
1466
- * @since 2.5.0
1467
- *
1468
- * @param string $key Sanitized key.
1469
- * @param string $raw_key The key prior to sanitization.
1470
- */
1471
- return apply_filters( 'wpms_tgmpa_sanitize_key', $key, $raw_key );
1472
- }
1473
-
1474
- /**
1475
- * Amend default configuration settings.
1476
- *
1477
- * @since 2.0.0
1478
- *
1479
- * @param array $config Array of config options to pass as class properties.
1480
- */
1481
- public function config( $config ) {
1482
- $keys = array(
1483
- 'id',
1484
- 'default_path',
1485
- 'has_notices',
1486
- 'dismissable',
1487
- 'dismiss_msg',
1488
- 'menu',
1489
- 'parent_slug',
1490
- 'capability',
1491
- 'is_automatic',
1492
- 'message',
1493
- 'strings',
1494
- );
1495
-
1496
- foreach ( $keys as $key ) {
1497
- if ( isset( $config[ $key ] ) ) {
1498
- if ( is_array( $config[ $key ] ) ) {
1499
- $this->$key = array_merge( $this->$key, $config[ $key ] );
1500
- } else {
1501
- $this->$key = $config[ $key ];
1502
- }
1503
- }
1504
- }
1505
- }
1506
-
1507
- /**
1508
- * Amend action link after plugin installation.
1509
- *
1510
- * @since 2.0.0
1511
- *
1512
- * @param array $install_actions Existing array of actions.
1513
- * @return false|array Amended array of actions.
1514
- */
1515
- public function actions( $install_actions ) {
1516
- // Remove action links on the TGMPA install page.
1517
- if ( $this->is_tgmpa_page() ) {
1518
- return false;
1519
- }
1520
-
1521
- return $install_actions;
1522
- }
1523
-
1524
- /**
1525
- * Flushes the plugins cache on theme switch to prevent stale entries
1526
- * from remaining in the plugin table.
1527
- *
1528
- * @since 2.4.0
1529
- *
1530
- * @param bool $clear_update_cache Optional. Whether to clear the Plugin updates cache.
1531
- * Parameter added in v2.5.0.
1532
- */
1533
- public function flush_plugins_cache( $clear_update_cache = true ) {
1534
- wp_clean_plugins_cache( $clear_update_cache );
1535
- }
1536
-
1537
- /**
1538
- * Set file_path key for each installed plugin.
1539
- *
1540
- * @since 2.1.0
1541
- *
1542
- * @param string $plugin_slug Optional. If set, only (re-)populates the file path for that specific plugin.
1543
- * Parameter added in v2.5.0.
1544
- */
1545
- public function populate_file_path( $plugin_slug = '' ) {
1546
- if ( ! empty( $plugin_slug ) && is_string( $plugin_slug ) && isset( $this->plugins[ $plugin_slug ] ) ) {
1547
- $this->plugins[ $plugin_slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $plugin_slug );
1548
- } else {
1549
- // Add file_path key for all plugins.
1550
- foreach ( $this->plugins as $slug => $values ) {
1551
- $this->plugins[ $slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $slug );
1552
- }
1553
- }
1554
- }
1555
-
1556
- /**
1557
- * Helper function to extract the file path of the plugin file from the
1558
- * plugin slug, if the plugin is installed.
1559
- *
1560
- * @since 2.0.0
1561
- *
1562
- * @param string $slug Plugin slug (typically folder name) as provided by the developer.
1563
- * @return string Either file path for plugin if installed, or just the plugin slug.
1564
- */
1565
- protected function _get_plugin_basename_from_slug( $slug ) {
1566
- $keys = array_keys( $this->get_plugins() );
1567
-
1568
- foreach ( $keys as $key ) {
1569
- if ( preg_match( '|^' . $slug . '/|', $key ) ) {
1570
- return $key;
1571
- }
1572
- }
1573
-
1574
- return $slug;
1575
- }
1576
-
1577
- /**
1578
- * Retrieve plugin data, given the plugin name.
1579
- *
1580
- * Loops through the registered plugins looking for $name. If it finds it,
1581
- * it returns the $data from that plugin. Otherwise, returns false.
1582
- *
1583
- * @since 2.1.0
1584
- *
1585
- * @param string $name Name of the plugin, as it was registered.
1586
- * @param string $data Optional. Array key of plugin data to return. Default is slug.
1587
- * @return string|boolean Plugin slug if found, false otherwise.
1588
- */
1589
- public function _get_plugin_data_from_name( $name, $data = 'slug' ) {
1590
- foreach ( $this->plugins as $values ) {
1591
- if ( $name === $values['name'] && isset( $values[ $data ] ) ) {
1592
- return $values[ $data ];
1593
- }
1594
- }
1595
-
1596
- return false;
1597
- }
1598
-
1599
- /**
1600
- * Retrieve the download URL for a package.
1601
- *
1602
- * @since 2.5.0
1603
- *
1604
- * @param string $slug Plugin slug.
1605
- * @return string Plugin download URL or path to local file or empty string if undetermined.
1606
- */
1607
- public function get_download_url( $slug ) {
1608
- $dl_source = '';
1609
-
1610
- switch ( $this->plugins[ $slug ]['source_type'] ) {
1611
- case 'repo':
1612
- return $this->get_wp_repo_download_url( $slug );
1613
- case 'external':
1614
- return $this->plugins[ $slug ]['source'];
1615
- case 'bundled':
1616
- return $this->default_path . $this->plugins[ $slug ]['source'];
1617
- }
1618
-
1619
- return $dl_source; // Should never happen.
1620
- }
1621
-
1622
- /**
1623
- * Retrieve the download URL for a WP repo package.
1624
- *
1625
- * @since 2.5.0
1626
- *
1627
- * @param string $slug Plugin slug.
1628
- * @return string Plugin download URL.
1629
- */
1630
- protected function get_wp_repo_download_url( $slug ) {
1631
- $source = '';
1632
- $api = $this->get_plugins_api( $slug );
1633
-
1634
- if ( false !== $api && isset( $api->download_link ) ) {
1635
- $source = $api->download_link;
1636
- }
1637
-
1638
- return $source;
1639
- }
1640
-
1641
- /**
1642
- * Try to grab information from WordPress API.
1643
- *
1644
- * @since 2.5.0
1645
- *
1646
- * @param string $slug Plugin slug.
1647
- * @return object Plugins_api response object on success, WP_Error on failure.
1648
- */
1649
- protected function get_plugins_api( $slug ) {
1650
- static $api = array(); // Cache received responses.
1651
-
1652
- if ( ! isset( $api[ $slug ] ) ) {
1653
- if ( ! function_exists( 'plugins_api' ) ) {
1654
- require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
1655
- }
1656
-
1657
- $response = plugins_api(
1658
- 'plugin_information',
1659
- array(
1660
- 'slug' => $slug,
1661
- 'fields' => array(
1662
- 'sections' => false,
1663
- ),
1664
- )
1665
- );
1666
-
1667
- $api[ $slug ] = false;
1668
-
1669
- if ( is_wp_error( $response ) ) {
1670
- wp_die( esc_html( $this->strings['oops'] ) );
1671
- } else {
1672
- $api[ $slug ] = $response;
1673
- }
1674
- }
1675
-
1676
- return $api[ $slug ];
1677
- }
1678
-
1679
- /**
1680
- * Retrieve a link to a plugin information page.
1681
- *
1682
- * @since 2.5.0
1683
- *
1684
- * @param string $slug Plugin slug.
1685
- * @return string Fully formed html link to a plugin information page if available
1686
- * or the plugin name if not.
1687
- */
1688
- public function get_info_link( $slug ) {
1689
- if ( ! empty( $this->plugins[ $slug ]['external_url'] ) && preg_match( self::IS_URL_REGEX, $this->plugins[ $slug ]['external_url'] ) ) {
1690
- $link = sprintf(
1691
- '<a href="%1$s" target="_blank">%2$s</a>',
1692
- esc_url( $this->plugins[ $slug ]['external_url'] ),
1693
- esc_html( $this->plugins[ $slug ]['name'] )
1694
- );
1695
- } elseif ( 'repo' === $this->plugins[ $slug ]['source_type'] ) {
1696
- $url = add_query_arg(
1697
- array(
1698
- 'tab' => 'plugin-information',
1699
- 'plugin' => rawurlencode( $slug ),
1700
- 'TB_iframe' => 'true',
1701
- 'width' => '640',
1702
- 'height' => '500',
1703
- ),
1704
- self_admin_url( 'plugin-install.php' )
1705
- );
1706
-
1707
- $link = sprintf(
1708
- '<a href="%1$s" class="thickbox">%2$s</a>',
1709
- esc_url( $url ),
1710
- esc_html( $this->plugins[ $slug ]['name'] )
1711
- );
1712
- } else {
1713
- $link = esc_html( $this->plugins[ $slug ]['name'] ); // No hyperlink.
1714
- }
1715
-
1716
- return $link;
1717
- }
1718
-
1719
- /**
1720
- * Determine if we're on the TGMPA Install page.
1721
- *
1722
- * @since 2.1.0
1723
- *
1724
- * @return boolean True when on the TGMPA page, false otherwise.
1725
- */
1726
- protected function is_tgmpa_page() {
1727
- return isset( $_GET['page'] ) && $this->menu === $_GET['page'];
1728
- }
1729
-
1730
- /**
1731
- * Determine if we're on a WP Core installation/upgrade page.
1732
- *
1733
- * @since 2.6.0
1734
- *
1735
- * @return boolean True when on a WP Core installation/upgrade page, false otherwise.
1736
- */
1737
- protected function is_core_update_page() {
1738
- // Current screen is not always available, most notably on the customizer screen.
1739
- if ( ! function_exists( 'get_current_screen' ) ) {
1740
- return false;
1741
- }
1742
-
1743
- $screen = get_current_screen();
1744
-
1745
- if ( 'update-core' === $screen->base ) {
1746
- // Core update screen.
1747
- return true;
1748
- } elseif ( 'plugins' === $screen->base && ! empty( $_POST['action'] ) ) { // WPCS: CSRF ok.
1749
- // Plugins bulk update screen.
1750
- return true;
1751
- } elseif ( 'update' === $screen->base && ! empty( $_POST['action'] ) ) { // WPCS: CSRF ok.
1752
- // Individual updates (ajax call).
1753
- return true;
1754
- }
1755
-
1756
- return false;
1757
- }
1758
-
1759
- /**
1760
- * Retrieve the URL to the TGMPA Install page.
1761
- *
1762
- * I.e. depending on the config settings passed something along the lines of:
1763
- * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins
1764
- *
1765
- * @since 2.5.0
1766
- *
1767
- * @return string Properly encoded URL (not escaped).
1768
- */
1769
- public function get_tgmpa_url() {
1770
- static $url;
1771
-
1772
- if ( ! isset( $url ) ) {
1773
- $parent = $this->parent_slug;
1774
- if ( false === strpos( $parent, '.php' ) ) {
1775
- $parent = 'admin.php';
1776
- }
1777
- $url = add_query_arg(
1778
- array(
1779
- 'page' => rawurlencode( $this->menu ),
1780
- ),
1781
- self_admin_url( $parent )
1782
- );
1783
- }
1784
-
1785
- return $url;
1786
- }
1787
-
1788
- /**
1789
- * Retrieve the URL to the TGMPA Install page for a specific plugin status (view).
1790
- *
1791
- * I.e. depending on the config settings passed something along the lines of:
1792
- * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins&plugin_status=install
1793
- *
1794
- * @since 2.5.0
1795
- *
1796
- * @param string $status Plugin status - either 'install', 'update' or 'activate'.
1797
- * @return string Properly encoded URL (not escaped).
1798
- */
1799
- public function get_tgmpa_status_url( $status ) {
1800
- return add_query_arg(
1801
- array(
1802
- 'plugin_status' => rawurlencode( $status ),
1803
- ),
1804
- $this->get_tgmpa_url()
1805
- );
1806
- }
1807
-
1808
- /**
1809
- * Determine whether there are open actions for plugins registered with TGMPA.
1810
- *
1811
- * @since 2.5.0
1812
- *
1813
- * @return bool True if complete, i.e. no outstanding actions. False otherwise.
1814
- */
1815
- public function is_tgmpa_complete() {
1816
- $complete = true;
1817
- foreach ( $this->plugins as $slug => $plugin ) {
1818
- if ( ! $this->is_plugin_active( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) {
1819
- $complete = false;
1820
- break;
1821
- }
1822
- }
1823
-
1824
- return $complete;
1825
- }
1826
-
1827
- /**
1828
- * Check if a plugin is installed. Does not take must-use plugins into account.
1829
- *
1830
- * @since 2.5.0
1831
- *
1832
- * @param string $slug Plugin slug.
1833
- * @return bool True if installed, false otherwise.
1834
- */
1835
- public function is_plugin_installed( $slug ) {
1836
- $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached).
1837
-
1838
- return ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ] ) );
1839
- }
1840
-
1841
- /**
1842
- * Check if a plugin is active.
1843
- *
1844
- * @since 2.5.0
1845
- *
1846
- * @param string $slug Plugin slug.
1847
- * @return bool True if active, false otherwise.
1848
- */
1849
- public function is_plugin_active( $slug ) {
1850
- return ( ( ! empty( $this->plugins[ $slug ]['is_callable'] ) && is_callable( $this->plugins[ $slug ]['is_callable'] ) ) || is_plugin_active( $this->plugins[ $slug ]['file_path'] ) );
1851
- }
1852
-
1853
- /**
1854
- * Check if a plugin can be updated, i.e. if we have information on the minimum WP version required
1855
- * available, check whether the current install meets them.
1856
- *
1857
- * @since 2.5.0
1858
- *
1859
- * @param string $slug Plugin slug.
1860
- * @return bool True if OK to update, false otherwise.
1861
- */
1862
- public function can_plugin_update( $slug ) {
1863
- // We currently can't get reliable info on non-WP-repo plugins - issue #380.
1864
- if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) {
1865
- return true;
1866
- }
1867
-
1868
- $api = $this->get_plugins_api( $slug );
1869
-
1870
- if ( false !== $api && isset( $api->requires ) ) {
1871
- return version_compare( $this->wp_version, $api->requires, '>=' );
1872
- }
1873
-
1874
- // No usable info received from the plugins API, presume we can update.
1875
- return true;
1876
- }
1877
-
1878
- /**
1879
- * Check to see if the plugin is 'updatetable', i.e. installed, with an update available
1880
- * and no WP version requirements blocking it.
1881
- *
1882
- * @since 2.6.0
1883
- *
1884
- * @param string $slug Plugin slug.
1885
- * @return bool True if OK to proceed with update, false otherwise.
1886
- */
1887
- public function is_plugin_updatetable( $slug ) {
1888
- if ( ! $this->is_plugin_installed( $slug ) ) {
1889
- return false;
1890
- } else {
1891
- return ( false !== $this->does_plugin_have_update( $slug ) && $this->can_plugin_update( $slug ) );
1892
- }
1893
- }
1894
-
1895
- /**
1896
- * Check if a plugin can be activated, i.e. is not currently active and meets the minimum
1897
- * plugin version requirements set in TGMPA (if any).
1898
- *
1899
- * @since 2.5.0
1900
- *
1901
- * @param string $slug Plugin slug.
1902
- * @return bool True if OK to activate, false otherwise.
1903
- */
1904
- public function can_plugin_activate( $slug ) {
1905
- return ( ! $this->is_plugin_active( $slug ) && ! $this->does_plugin_require_update( $slug ) );
1906
- }
1907
-
1908
- /**
1909
- * Retrieve the version number of an installed plugin.
1910
- *
1911
- * @since 2.5.0
1912
- *
1913
- * @param string $slug Plugin slug.
1914
- * @return string Version number as string or an empty string if the plugin is not installed
1915
- * or version unknown (plugins which don't comply with the plugin header standard).
1916
- */
1917
- public function get_installed_version( $slug ) {
1918
- $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached).
1919
-
1920
- if ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version'] ) ) {
1921
- return $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version'];
1922
- }
1923
-
1924
- return '';
1925
- }
1926
-
1927
- /**
1928
- * Check whether a plugin complies with the minimum version requirements.
1929
- *
1930
- * @since 2.5.0
1931
- *
1932
- * @param string $slug Plugin slug.
1933
- * @return bool True when a plugin needs to be updated, otherwise false.
1934
- */
1935
- public function does_plugin_require_update( $slug ) {
1936
- $installed_version = $this->get_installed_version( $slug );
1937
- $minimum_version = $this->plugins[ $slug ]['version'];
1938
-
1939
- return version_compare( $minimum_version, $installed_version, '>' );
1940
- }
1941
-
1942
- /**
1943
- * Check whether there is an update available for a plugin.
1944
- *
1945
- * @since 2.5.0
1946
- *
1947
- * @param string $slug Plugin slug.
1948
- * @return false|string Version number string of the available update or false if no update available.
1949
- */
1950
- public function does_plugin_have_update( $slug ) {
1951
- // Presume bundled and external plugins will point to a package which meets the minimum required version.
1952
- if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) {
1953
- if ( $this->does_plugin_require_update( $slug ) ) {
1954
- return $this->plugins[ $slug ]['version'];
1955
- }
1956
-
1957
- return false;
1958
- }
1959
-
1960
- $repo_updates = get_site_transient( 'update_plugins' );
1961
-
1962
- if ( isset( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version ) ) {
1963
- return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version;
1964
- }
1965
-
1966
- return false;
1967
- }
1968
-
1969
- /**
1970
- * Retrieve potential upgrade notice for a plugin.
1971
- *
1972
- * @since 2.5.0
1973
- *
1974
- * @param string $slug Plugin slug.
1975
- * @return string The upgrade notice or an empty string if no message was available or provided.
1976
- */
1977
- public function get_upgrade_notice( $slug ) {
1978
- // We currently can't get reliable info on non-WP-repo plugins - issue #380.
1979
- if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) {
1980
- return '';
1981
- }
1982
-
1983
- $repo_updates = get_site_transient( 'update_plugins' );
1984
-
1985
- if ( ! empty( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice ) ) {
1986
- return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice;
1987
- }
1988
-
1989
- return '';
1990
- }
1991
-
1992
- /**
1993
- * Wrapper around the core WP get_plugins function, making sure it's actually available.
1994
- *
1995
- * @since 2.5.0
1996
- *
1997
- * @param string $plugin_folder Optional. Relative path to single plugin folder.
1998
- * @return array Array of installed plugins with plugin information.
1999
- */
2000
- public function get_plugins( $plugin_folder = '' ) {
2001
- if ( ! function_exists( 'get_plugins' ) ) {
2002
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
2003
- }
2004
-
2005
- return get_plugins( $plugin_folder );
2006
- }
2007
-
2008
- /**
2009
- * Delete dismissable nag option when theme is switched.
2010
- *
2011
- * This ensures that the user(s) is/are again reminded via nag of required
2012
- * and/or recommended plugins if they re-activate the theme.
2013
- *
2014
- * @since 2.1.1
2015
- */
2016
- public function update_dismiss() {
2017
- delete_metadata( 'user', null, 'tgmpa_dismissed_notice_' . $this->id, null, true );
2018
- }
2019
-
2020
- /**
2021
- * Forces plugin activation if the parameter 'force_activation' is
2022
- * set to true.
2023
- *
2024
- * This allows theme authors to specify certain plugins that must be
2025
- * active at all times while using the current theme.
2026
- *
2027
- * Please take special care when using this parameter as it has the
2028
- * potential to be harmful if not used correctly. Setting this parameter
2029
- * to true will not allow the specified plugin to be deactivated unless
2030
- * the user switches themes.
2031
- *
2032
- * @since 2.2.0
2033
- */
2034
- public function force_activation() {
2035
- foreach ( $this->plugins as $slug => $plugin ) {
2036
- if ( true === $plugin['force_activation'] ) {
2037
- if ( ! $this->is_plugin_installed( $slug ) ) {
2038
- // Oops, plugin isn't there so iterate to next condition.
2039
- continue;
2040
- } elseif ( $this->can_plugin_activate( $slug ) ) {
2041
- // There we go, activate the plugin.
2042
- activate_plugin( $plugin['file_path'] );
2043
- }
2044
- }
2045
- }
2046
- }
2047
-
2048
- /**
2049
- * Forces plugin deactivation if the parameter 'force_deactivation'
2050
- * is set to true and adds the plugin to the 'recently active' plugins list.
2051
- *
2052
- * This allows theme authors to specify certain plugins that must be
2053
- * deactivated upon switching from the current theme to another.
2054
- *
2055
- * Please take special care when using this parameter as it has the
2056
- * potential to be harmful if not used correctly.
2057
- *
2058
- * @since 2.2.0
2059
- */
2060
- public function force_deactivation() {
2061
- $deactivated = array();
2062
-
2063
- foreach ( $this->plugins as $slug => $plugin ) {
2064
- /*
2065
- * Only proceed forward if the parameter is set to true and plugin is active
2066
- * as a 'normal' (not must-use) plugin.
2067
- */
2068
- if ( true === $plugin['force_deactivation'] && is_plugin_active( $plugin['file_path'] ) ) {
2069
- deactivate_plugins( $plugin['file_path'] );
2070
- $deactivated[ $plugin['file_path'] ] = time();
2071
- }
2072
- }
2073
-
2074
- if ( ! empty( $deactivated ) ) {
2075
- update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ) );
2076
- }
2077
- }
2078
-
2079
- /**
2080
- * Echo the current TGMPA version number to the page.
2081
- *
2082
- * @since 2.5.0
2083
- */
2084
- public function show_tgmpa_version() {
2085
- echo '<p style="float: right; padding: 0em 1.5em 0.5em 0;"><strong><small>',
2086
- esc_html(
2087
- sprintf(
2088
- /* translators: %s: version number */
2089
- __( 'TGMPA v%s', 'tgmpa' ),
2090
- self::TGMPA_VERSION
2091
- )
2092
- ),
2093
- '</small></strong></p>';
2094
- }
2095
-
2096
- /**
2097
- * Returns the singleton instance of the class.
2098
- *
2099
- * @since 2.4.0
2100
- *
2101
- * @return TGM_Plugin_Activation The TGM_Plugin_Activation object.
2102
- */
2103
- public static function get_instance() {
2104
- if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) {
2105
- self::$instance = new self();
2106
- }
2107
-
2108
- return self::$instance;
2109
- }
2110
- }
2111
-
2112
- /**
2113
- * Ensure only one instance of the class is ever invoked.
2114
- *
2115
- * @since 2.5.0
2116
- */
2117
- function load_tgm_plugin_activation() {
2118
- $GLOBALS['wp_mail_smtp_tgmpa'] = TGM_Plugin_Activation::get_instance();
2119
- }
2120
-
2121
- if ( did_action( 'plugins_loaded' ) ) {
2122
- load_tgm_plugin_activation();
2123
- } else {
2124
- add_action( 'plugins_loaded', '\ComingSoon\load_tgm_plugin_activation' );
2125
- }
2126
-
2127
- /**
2128
- * Helper function to register a collection of required plugins.
2129
- *
2130
- * @since 2.0.0
2131
- * @api
2132
- *
2133
- * @param array $plugins An array of plugin arrays.
2134
- * @param array $config Optional. An array of configuration values.
2135
- */
2136
- function tgmpa( $plugins, $config = array() ) {
2137
- $instance = call_user_func( array( get_class( $GLOBALS['wp_mail_smtp_tgmpa'] ), 'get_instance' ) );
2138
-
2139
- foreach ( $plugins as $plugin ) {
2140
- call_user_func( array( $instance, 'register' ), $plugin );
2141
- }
2142
-
2143
- if ( ! empty( $config ) && is_array( $config ) ) {
2144
- // Send out notices for deprecated arguments passed.
2145
- if ( isset( $config['notices'] ) ) {
2146
- _deprecated_argument( __FUNCTION__, '2.2.0', 'The `notices` config parameter was renamed to `has_notices` in TGMPA 2.2.0. Please adjust your configuration.' );
2147
- if ( ! isset( $config['has_notices'] ) ) {
2148
- $config['has_notices'] = $config['notices'];
2149
- }
2150
- }
2151
-
2152
- if ( isset( $config['parent_menu_slug'] ) ) {
2153
- _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_menu_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' );
2154
- }
2155
- if ( isset( $config['parent_url_slug'] ) ) {
2156
- _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_url_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' );
2157
- }
2158
-
2159
- call_user_func( array( $instance, 'config' ), $config );
2160
- }
2161
- }
2162
-
2163
- /**
2164
- * WP_List_Table isn't always available. If it isn't available,
2165
- * we load it here.
2166
- *
2167
- * @since 2.2.0
2168
- */
2169
- if ( ! class_exists( 'WP_List_Table', false ) ) {
2170
- require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
2171
- }
2172
-
2173
- /**
2174
- * List table class for handling plugins.
2175
- *
2176
- * Extends the WP_List_Table class to provide a future-compatible
2177
- * way of listing out all required/recommended plugins.
2178
- *
2179
- * Gives users an interface similar to the Plugin Administration
2180
- * area with similar (albeit stripped down) capabilities.
2181
- *
2182
- * This class also allows for the bulk install of plugins.
2183
- *
2184
- * @since 2.2.0
2185
- *
2186
- * @package TGM-Plugin-Activation
2187
- * @author Thomas Griffin
2188
- * @author Gary Jones
2189
- */
2190
- class TGMPA_List_Table extends \WP_List_Table {
2191
- /**
2192
- * TGMPA instance.
2193
- *
2194
- * @since 2.5.0
2195
- *
2196
- * @var object
2197
- */
2198
- protected $tgmpa;
2199
-
2200
- /**
2201
- * The currently chosen view.
2202
- *
2203
- * @since 2.5.0
2204
- *
2205
- * @var string One of: 'all', 'install', 'update', 'activate'
2206
- */
2207
- public $view_context = 'all';
2208
-
2209
- /**
2210
- * The plugin counts for the various views.
2211
- *
2212
- * @since 2.5.0
2213
- *
2214
- * @var array
2215
- */
2216
- protected $view_totals = array(
2217
- 'all' => 0,
2218
- 'install' => 0,
2219
- 'update' => 0,
2220
- 'activate' => 0,
2221
- );
2222
-
2223
- /**
2224
- * References parent constructor and sets defaults for class.
2225
- *
2226
- * @since 2.2.0
2227
- */
2228
- public function __construct() {
2229
- $this->tgmpa = call_user_func( array( get_class( $GLOBALS['wp_mail_smtp_tgmpa'] ), 'get_instance' ) );
2230
-
2231
- parent::__construct(
2232
- array(
2233
- 'singular' => 'plugin',
2234
- 'plural' => 'plugins',
2235
- 'ajax' => false,
2236
- )
2237
- );
2238
-
2239
- if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'install', 'update', 'activate' ), true ) ) {
2240
- $this->view_context = sanitize_key( $_REQUEST['plugin_status'] );
2241
- }
2242
-
2243
- add_filter( 'wpms_tgmpa_table_data_items', array( $this, 'sort_table_items' ) );
2244
- }
2245
-
2246
- /**
2247
- * Get a list of CSS classes for the <table> tag.
2248
- *
2249
- * Overruled to prevent the 'plural' argument from being added.
2250
- *
2251
- * @since 2.5.0
2252
- *
2253
- * @return array CSS classnames.
2254
- */
2255
- public function get_table_classes() {
2256
- return array( 'widefat', 'fixed' );
2257
- }
2258
-
2259
- /**
2260
- * Gathers and renames all of our plugin information to be used by WP_List_Table to create our table.
2261
- *
2262
- * @since 2.2.0
2263
- *
2264
- * @return array $table_data Information for use in table.
2265
- */
2266
- protected function _gather_plugin_data() {
2267
- // Load thickbox for plugin links.
2268
- $this->tgmpa->admin_init();
2269
- $this->tgmpa->thickbox();
2270
-
2271
- // Categorize the plugins which have open actions.
2272
- $plugins = $this->categorize_plugins_to_views();
2273
-
2274
- // Set the counts for the view links.
2275
- $this->set_view_totals( $plugins );
2276
-
2277
- // Prep variables for use and grab list of all installed plugins.
2278
- $table_data = array();
2279
- $i = 0;
2280
-
2281
- // Redirect to the 'all' view if no plugins were found for the selected view context.
2282
- if ( empty( $plugins[ $this->view_context ] ) ) {
2283
- $this->view_context = 'all';
2284
- }
2285
-
2286
- foreach ( $plugins[ $this->view_context ] as $slug => $plugin ) {
2287
- $table_data[ $i ]['sanitized_plugin'] = $plugin['name'];
2288
- $table_data[ $i ]['slug'] = $slug;
2289
- $table_data[ $i ]['plugin'] = '<strong>' . $this->tgmpa->get_info_link( $slug ) . '</strong>';
2290
- $table_data[ $i ]['source'] = $this->get_plugin_source_type_text( $plugin['source_type'] );
2291
- $table_data[ $i ]['type'] = $this->get_plugin_advise_type_text( $plugin['required'] );
2292
- $table_data[ $i ]['status'] = $this->get_plugin_status_text( $slug );
2293
- $table_data[ $i ]['installed_version'] = $this->tgmpa->get_installed_version( $slug );
2294
- $table_data[ $i ]['minimum_version'] = $plugin['version'];
2295
- $table_data[ $i ]['available_version'] = $this->tgmpa->does_plugin_have_update( $slug );
2296
-
2297
- // Prep the upgrade notice info.
2298
- $upgrade_notice = $this->tgmpa->get_upgrade_notice( $slug );
2299
- if ( ! empty( $upgrade_notice ) ) {
2300
- $table_data[ $i ]['upgrade_notice'] = $upgrade_notice;
2301
-
2302
- add_action( "tgmpa_after_plugin_row_{$slug}", array( $this, 'wp_plugin_update_row' ), 10, 2 );
2303
- }
2304
-
2305
- $table_data[ $i ] = apply_filters( 'wpms_tgmpa_table_data_item', $table_data[ $i ], $plugin );
2306
-
2307
- $i++;
2308
- }
2309
-
2310
- return $table_data;
2311
- }
2312
-
2313
- /**
2314
- * Categorize the plugins which have open actions into views for the TGMPA page.
2315
- *
2316
- * @since 2.5.0
2317
- */
2318
- protected function categorize_plugins_to_views() {
2319
- $plugins = array(
2320
- 'all' => array(), // Meaning: all plugins which still have open actions.
2321
- 'install' => array(),
2322
- 'update' => array(),
2323
- 'activate' => array(),
2324
- );
2325
-
2326
- foreach ( $this->tgmpa->plugins as $slug => $plugin ) {
2327
- if ( $this->tgmpa->is_plugin_active( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) {
2328
- // No need to display plugins if they are installed, up-to-date and active.
2329
- continue;
2330
- } else {
2331
- $plugins['all'][ $slug ] = $plugin;
2332
-
2333
- if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) {
2334
- $plugins['install'][ $slug ] = $plugin;
2335
- } else {
2336
- if ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) {
2337
- $plugins['update'][ $slug ] = $plugin;
2338
- }
2339
-
2340
- if ( $this->tgmpa->can_plugin_activate( $slug ) ) {
2341
- $plugins['activate'][ $slug ] = $plugin;
2342
- }
2343
- }
2344
- }
2345
- }
2346
-
2347
- return $plugins;
2348
- }
2349
-
2350
- /**
2351
- * Set the counts for the view links.
2352
- *
2353
- * @since 2.5.0
2354
- *
2355
- * @param array $plugins Plugins order by view.
2356
- */
2357
- protected function set_view_totals( $plugins ) {
2358
- foreach ( $plugins as $type => $list ) {
2359
- $this->view_totals[ $type ] = count( $list );
2360
- }
2361
- }
2362
-
2363
- /**
2364
- * Get the plugin required/recommended text string.
2365
- *
2366
- * @since 2.5.0
2367
- *
2368
- * @param string $required Plugin required setting.
2369
- * @return string
2370
- */
2371
- protected function get_plugin_advise_type_text( $required ) {
2372
- if ( true === $required ) {
2373
- return __( 'Required', 'tgmpa' );
2374
- }
2375
-
2376
- return __( 'Recommended', 'tgmpa' );
2377
- }
2378
-
2379
- /**
2380
- * Get the plugin source type text string.
2381
- *
2382
- * @since 2.5.0
2383
- *
2384
- * @param string $type Plugin type.
2385
- * @return string
2386
- */
2387
- protected function get_plugin_source_type_text( $type ) {
2388
- $string = '';
2389
-
2390
- switch ( $type ) {
2391
- case 'repo':
2392
- $string = __( 'WordPress Repository', 'tgmpa' );
2393
- break;
2394
- case 'external':
2395
- $string = __( 'External Source', 'tgmpa' );
2396
- break;
2397
- case 'bundled':
2398
- $string = __( 'Pre-Packaged', 'tgmpa' );
2399
- break;
2400
- }
2401
-
2402
- return $string;
2403
- }
2404
-
2405
- /**
2406
- * Determine the plugin status message.
2407
- *
2408
- * @since 2.5.0
2409
- *
2410
- * @param string $slug Plugin slug.
2411
- * @return string
2412
- */
2413
- protected function get_plugin_status_text( $slug ) {
2414
- if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) {
2415
- return __( 'Not Installed', 'tgmpa' );
2416
- }
2417
-
2418
- if ( ! $this->tgmpa->is_plugin_active( $slug ) ) {
2419
- $install_status = __( 'Installed But Not Activated', 'tgmpa' );
2420
- } else {
2421
- $install_status = __( 'Active', 'tgmpa' );
2422
- }
2423
-
2424
- $update_status = '';
2425
-
2426
- if ( $this->tgmpa->does_plugin_require_update( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) {
2427
- $update_status = __( 'Required Update not Available', 'tgmpa' );
2428
-
2429
- } elseif ( $this->tgmpa->does_plugin_require_update( $slug ) ) {
2430
- $update_status = __( 'Requires Update', 'tgmpa' );
2431
-
2432
- } elseif ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) {
2433
- $update_status = __( 'Update recommended', 'tgmpa' );
2434
- }
2435
-
2436
- if ( '' === $update_status ) {
2437
- return $install_status;
2438
- }
2439
-
2440
- return sprintf(
2441
- /* translators: 1: install status, 2: update status */
2442
- _x( '%1$s, %2$s', 'Install/Update Status', 'tgmpa' ),
2443
- $install_status,
2444
- $update_status
2445
- );
2446
- }
2447
-
2448
- /**
2449
- * Sort plugins by Required/Recommended type and by alphabetical plugin name within each type.
2450
- *
2451
- * @since 2.5.0
2452
- *
2453
- * @param array $items Prepared table items.
2454
- * @return array Sorted table items.
2455
- */
2456
- public function sort_table_items( $items ) {
2457
- $type = array();
2458
- $name = array();
2459
-
2460
- foreach ( $items as $i => $plugin ) {
2461
- $type[ $i ] = $plugin['type']; // Required / recommended.
2462
- $name[ $i ] = $plugin['sanitized_plugin'];
2463
- }
2464
-
2465
- array_multisort( $type, SORT_DESC, $name, SORT_ASC, $items );
2466
-
2467
- return $items;
2468
- }
2469
-
2470
- /**
2471
- * Get an associative array ( id => link ) of the views available on this table.
2472
- *
2473
- * @since 2.5.0
2474
- *
2475
- * @return array
2476
- */
2477
- public function get_views() {
2478
- $status_links = array();
2479
-
2480
- foreach ( $this->view_totals as $type => $count ) {
2481
- if ( $count < 1 ) {
2482
- continue;
2483
- }
2484
-
2485
- switch ( $type ) {
2486
- case 'all':
2487
- /* translators: 1: number of plugins. */
2488
- $text = _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $count, 'plugins', 'tgmpa' );
2489
- break;
2490
- case 'install':
2491
- /* translators: 1: number of plugins. */
2492
- $text = _n( 'To Install <span class="count">(%s)</span>', 'To Install <span class="count">(%s)</span>', $count, 'tgmpa' );
2493
- break;
2494
- case 'update':
2495
- /* translators: 1: number of plugins. */
2496
- $text = _n( 'Update Available <span class="count">(%s)</span>', 'Update Available <span class="count">(%s)</span>', $count, 'tgmpa' );
2497
- break;
2498
- case 'activate':
2499
- /* translators: 1: number of plugins. */
2500
- $text = _n( 'To Activate <span class="count">(%s)</span>', 'To Activate <span class="count">(%s)</span>', $count, 'tgmpa' );
2501
- break;
2502
- default:
2503
- $text = '';
2504
- break;
2505
- }
2506
-
2507
- if ( ! empty( $text ) ) {
2508
-
2509
- $status_links[ $type ] = sprintf(
2510
- '<a href="%s"%s>%s</a>',
2511
- esc_url( $this->tgmpa->get_tgmpa_status_url( $type ) ),
2512
- ( $type === $this->view_context ) ? ' class="current"' : '',
2513
- sprintf( $text, number_format_i18n( $count ) )
2514
- );
2515
- }
2516
- }
2517
-
2518
- return $status_links;
2519
- }
2520
-
2521
- /**
2522
- * Create default columns to display important plugin information
2523
- * like type, action and status.
2524
- *
2525
- * @since 2.2.0
2526
- *
2527
- * @param array $item Array of item data.
2528
- * @param string $column_name The name of the column.
2529
- * @return string
2530
- */
2531
- public function column_default( $item, $column_name ) {
2532
- return $item[ $column_name ];
2533
- }
2534
-
2535
- /**
2536
- * Required for bulk installing.
2537
- *
2538
- * Adds a checkbox for each plugin.
2539
- *
2540
- * @since 2.2.0
2541
- *
2542
- * @param array $item Array of item data.
2543
- * @return string The input checkbox with all necessary info.
2544
- */
2545
- public function column_cb( $item ) {
2546
- return sprintf(
2547
- '<input type="checkbox" name="%1$s[]" value="%2$s" id="%3$s" />',
2548
- esc_attr( $this->_args['singular'] ),
2549
- esc_attr( $item['slug'] ),
2550
- esc_attr( $item['sanitized_plugin'] )
2551
- );
2552
- }
2553
-
2554
- /**
2555
- * Create default title column along with the action links.
2556
- *
2557
- * @since 2.2.0
2558
- *
2559
- * @param array $item Array of item data.
2560
- * @return string The plugin name and action links.
2561
- */
2562
- public function column_plugin( $item ) {
2563
- return sprintf(
2564
- '%1$s %2$s',
2565
- $item['plugin'],
2566
- $this->row_actions( $this->get_row_actions( $item ), true )
2567
- );
2568
- }
2569
-
2570
- /**
2571
- * Create version information column.
2572
- *
2573
- * @since 2.5.0
2574
- *
2575
- * @param array $item Array of item data.
2576
- * @return string HTML-formatted version information.
2577
- */
2578
- public function column_version( $item ) {
2579
- $output = array();
2580
-
2581
- if ( $this->tgmpa->is_plugin_installed( $item['slug'] ) ) {
2582
- $installed = ! empty( $item['installed_version'] ) ? $item['installed_version'] : _x( 'unknown', 'as in: "version nr unknown"', 'tgmpa' );
2583
-
2584
- $color = '';
2585
- if ( ! empty( $item['minimum_version'] ) && $this->tgmpa->does_plugin_require_update( $item['slug'] ) ) {
2586
- $color = ' color: #ff0000; font-weight: bold;';
2587
- }
2588
-
2589
- $output[] = sprintf(
2590
- '<p><span style="min-width: 32px; text-align: right; float: right;%1$s">%2$s</span>' . __( 'Installed version:', 'tgmpa' ) . '</p>',
2591
- $color,
2592
- $installed
2593
- );
2594
- }
2595
-
2596
- if ( ! empty( $item['minimum_version'] ) ) {
2597
- $output[] = sprintf(
2598
- '<p><span style="min-width: 32px; text-align: right; float: right;">%1$s</span>' . __( 'Minimum required version:', 'tgmpa' ) . '</p>',
2599
- $item['minimum_version']
2600
- );
2601
- }
2602
-
2603
- if ( ! empty( $item['available_version'] ) ) {
2604
- $color = '';
2605
- if ( ! empty( $item['minimum_version'] ) && version_compare( $item['available_version'], $item['minimum_version'], '>=' ) ) {
2606
- $color = ' color: #71C671; font-weight: bold;';
2607
- }
2608
-
2609
- $output[] = sprintf(
2610
- '<p><span style="min-width: 32px; text-align: right; float: right;%1$s">%2$s</span>' . __( 'Available version:', 'tgmpa' ) . '</p>',
2611
- $color,
2612
- $item['available_version']
2613
- );
2614
- }
2615
-
2616
- if ( empty( $output ) ) {
2617
- return '&nbsp;'; // Let's not break the table layout.
2618
- } else {
2619
- return implode( "\n", $output );
2620
- }
2621
- }
2622
-
2623
- /**
2624
- * Sets default message within the plugins table if no plugins
2625
- * are left for interaction.
2626
- *
2627
- * Hides the menu item to prevent the user from clicking and
2628
- * getting a permissions error.
2629
- *
2630
- * @since 2.2.0
2631
- */
2632
- public function no_items() {
2633
- echo esc_html__( 'No plugins to install, update or activate.', 'tgmpa' ) . ' <a href="' . esc_url( self_admin_url() ) . '"> ' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '</a>';
2634
- echo '<style type="text/css">#adminmenu .wp-submenu li.current { display: none !important; }</style>';
2635
- }
2636
-
2637
- /**
2638
- * Output all the column information within the table.
2639
- *
2640
- * @since 2.2.0
2641
- *
2642
- * @return array $columns The column names.
2643
- */
2644
- public function get_columns() {
2645
- $columns = array(
2646
- 'cb' => '<input type="checkbox" />',
2647
- 'plugin' => __( 'Plugin', 'tgmpa' ),
2648
- 'source' => __( 'Source', 'tgmpa' ),
2649
- 'type' => __( 'Type', 'tgmpa' ),
2650
- );
2651
-
2652
- if ( 'all' === $this->view_context || 'update' === $this->view_context ) {
2653
- $columns['version'] = __( 'Version', 'tgmpa' );
2654
- $columns['status'] = __( 'Status', 'tgmpa' );
2655
- }
2656
-
2657
- return apply_filters( 'wpms_tgmpa_table_columns', $columns );
2658
- }
2659
-
2660
- /**
2661
- * Get name of default primary column
2662
- *
2663
- * @since 2.5.0 / WP 4.3+ compatibility
2664
- * @access protected
2665
- *
2666
- * @return string
2667
- */
2668
- protected function get_default_primary_column_name() {
2669
- return 'plugin';
2670
- }
2671
-
2672
- /**
2673
- * Get the name of the primary column.
2674
- *
2675
- * @since 2.5.0 / WP 4.3+ compatibility
2676
- * @access protected
2677
- *
2678
- * @return string The name of the primary column.
2679
- */
2680
- protected function get_primary_column_name() {
2681
- if ( method_exists( 'WP_List_Table', 'get_primary_column_name' ) ) {
2682
- return parent::get_primary_column_name();
2683
- } else {
2684
- return $this->get_default_primary_column_name();
2685
- }
2686
- }
2687
-
2688
- /**
2689
- * Get the actions which are relevant for a specific plugin row.
2690
- *
2691
- * @since 2.5.0
2692
- *
2693
- * @param array $item Array of item data.
2694
- * @return array Array with relevant action links.
2695
- */
2696
- protected function get_row_actions( $item ) {
2697
- $actions = array();
2698
- $action_links = array();
2699
-
2700
- // Display the 'Install' action link if the plugin is not yet available.
2701
- if ( ! $this->tgmpa->is_plugin_installed( $item['slug'] ) ) {
2702
- /* translators: %2$s: plugin name in screen reader markup */
2703
- $actions['install'] = __( 'Install %2$s', 'tgmpa' );
2704
- } else {
2705
- // Display the 'Update' action link if an update is available and WP complies with plugin minimum.
2706
- if ( false !== $this->tgmpa->does_plugin_have_update( $item['slug'] ) && $this->tgmpa->can_plugin_update( $item['slug'] ) ) {
2707
- /* translators: %2$s: plugin name in screen reader markup */
2708
- $actions['update'] = __( 'Update %2$s', 'tgmpa' );
2709
- }
2710
-
2711
- // Display the 'Activate' action link, but only if the plugin meets the minimum version.
2712
- if ( $this->tgmpa->can_plugin_activate( $item['slug'] ) ) {
2713
- /* translators: %2$s: plugin name in screen reader markup */
2714
- $actions['activate'] = __( 'Activate %2$s', 'tgmpa' );
2715
- }
2716
- }
2717
-
2718
- // Create the actual links.
2719
- foreach ( $actions as $action => $text ) {
2720
- $nonce_url = wp_nonce_url(
2721
- add_query_arg(
2722
- array(
2723
- 'plugin' => rawurlencode( $item['slug'] ),
2724
- 'tgmpa-' . $action => $action . '-plugin',
2725
- ),
2726
- $this->tgmpa->get_tgmpa_url()
2727
- ),
2728
- 'tgmpa-' . $action,
2729
- 'tgmpa-nonce'
2730
- );
2731
-
2732
- $action_links[ $action ] = sprintf(
2733
- '<a href="%1$s">' . esc_html( $text ) . '</a>', // $text contains the second placeholder.
2734
- esc_url( $nonce_url ),
2735
- '<span class="screen-reader-text">' . esc_html( $item['sanitized_plugin'] ) . '</span>'
2736
- );
2737
- }
2738
-
2739
- $prefix = ( defined( 'WP_NETWORK_ADMIN' ) && WP_NETWORK_ADMIN ) ? 'network_admin_' : '';
2740
- return apply_filters( "wpms_tgmpa_{$prefix}plugin_action_links", array_filter( $action_links ), $item['slug'], $item, $this->view_context );
2741
- }
2742
-
2743
- /**
2744
- * Generates content for a single row of the table.
2745
- *
2746
- * @since 2.5.0
2747
- *
2748
- * @param object $item The current item.
2749
- */
2750
- public function single_row( $item ) {
2751
- parent::single_row( $item );
2752
-
2753
- /**
2754
- * Fires after each specific row in the TGMPA Plugins list table.
2755
- *
2756
- * The dynamic portion of the hook name, `$item['slug']`, refers to the slug
2757
- * for the plugin.
2758
- *
2759
- * @since 2.5.0
2760
- */
2761
- do_action( "wpms_tgmpa_after_plugin_row_{$item['slug']}", $item['slug'], $item, $this->view_context );
2762
- }
2763
-
2764
- /**
2765
- * Show the upgrade notice below a plugin row if there is one.
2766
- *
2767
- * @since 2.5.0
2768
- *
2769
- * @see /wp-admin/includes/update.php
2770
- *
2771
- * @param string $slug Plugin slug.
2772
- * @param array $item The information available in this table row.
2773
- * @return null Return early if upgrade notice is empty.
2774
- */
2775
- public function wp_plugin_update_row( $slug, $item ) {
2776
- if ( empty( $item['upgrade_notice'] ) ) {
2777
- return;
2778
- }
2779
-
2780
- echo '
2781
- <tr class="plugin-update-tr">
2782
- <td colspan="', absint( $this->get_column_count() ), '" class="plugin-update colspanchange">
2783
- <div class="update-message">',
2784
- esc_html__( 'Upgrade message from the plugin author:', 'tgmpa' ),
2785
- ' <strong>', wp_kses_data( $item['upgrade_notice'] ), '</strong>
2786
- </div>
2787
- </td>
2788
- </tr>';
2789
- }
2790
-
2791
- /**
2792
- * Extra controls to be displayed between bulk actions and pagination.
2793
- *
2794
- * @since 2.5.0
2795
- *
2796
- * @param string $which 'top' or 'bottom' table navigation.
2797
- */
2798
- public function extra_tablenav( $which ) {
2799
- if ( 'bottom' === $which ) {
2800
- $this->tgmpa->show_tgmpa_version();
2801
- }
2802
- }
2803
-
2804
- /**
2805
- * Defines the bulk actions for handling registered plugins.
2806
- *
2807
- * @since 2.2.0
2808
- *
2809
- * @return array $actions The bulk actions for the plugin install table.
2810
- */
2811
- public function get_bulk_actions() {
2812
-
2813
- $actions = array();
2814
-
2815
- if ( 'update' !== $this->view_context && 'activate' !== $this->view_context ) {
2816
- if ( current_user_can( 'install_plugins' ) ) {
2817
- $actions['tgmpa-bulk-install'] = __( 'Install', 'tgmpa' );
2818
- }
2819
- }
2820
-
2821
- if ( 'install' !== $this->view_context ) {
2822
- if ( current_user_can( 'update_plugins' ) ) {
2823
- $actions['tgmpa-bulk-update'] = __( 'Update', 'tgmpa' );
2824
- }
2825
- if ( current_user_can( 'activate_plugins' ) ) {
2826
- $actions['tgmpa-bulk-activate'] = __( 'Activate', 'tgmpa' );
2827
- }
2828
- }
2829
-
2830
- return $actions;
2831
- }
2832
-
2833
- /**
2834
- * Processes bulk installation and activation actions.
2835
- *
2836
- * The bulk installation process looks for the $_POST information and passes that
2837
- * through if a user has to use WP_Filesystem to enter their credentials.
2838
- *
2839
- * @since 2.2.0
2840
- */
2841
- public function process_bulk_actions() {
2842
- // Bulk installation process.
2843
- if ( 'tgmpa-bulk-install' === $this->current_action() || 'tgmpa-bulk-update' === $this->current_action() ) {
2844
-
2845
- check_admin_referer( 'bulk-' . $this->_args['plural'] );
2846
-
2847
- $install_type = 'install';
2848
- if ( 'tgmpa-bulk-update' === $this->current_action() ) {
2849
- $install_type = 'update';
2850
- }
2851
-
2852
- $plugins_to_install = array();
2853
-
2854
- // Did user actually select any plugins to install/update ?
2855
- if ( empty( $_POST['plugin'] ) ) {
2856
- if ( 'install' === $install_type ) {
2857
- $message = __( 'No plugins were selected to be installed. No action taken.', 'tgmpa' );
2858
- } else {
2859
- $message = __( 'No plugins were selected to be updated. No action taken.', 'tgmpa' );
2860
- }
2861
-
2862
- echo '<div id="message" class="error"><p>', esc_html( $message ), '</p></div>';
2863
-
2864
- return false;
2865
- }
2866
-
2867
- if ( is_array( $_POST['plugin'] ) ) {
2868
- $plugins_to_install = (array) $_POST['plugin'];
2869
- } elseif ( is_string( $_POST['plugin'] ) ) {
2870
- // Received via Filesystem page - un-flatten array (WP bug #19643).
2871
- $plugins_to_install = explode( ',', $_POST['plugin'] );
2872
- }
2873
-
2874
- // Sanitize the received input.
2875
- $plugins_to_install = array_map( 'urldecode', $plugins_to_install );
2876
- $plugins_to_install = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins_to_install );
2877
-
2878
- // Validate the received input.
2879
- foreach ( $plugins_to_install as $key => $slug ) {
2880
- // Check if the plugin was registered with TGMPA and remove if not.
2881
- if ( ! isset( $this->tgmpa->plugins[ $slug ] ) ) {
2882
- unset( $plugins_to_install[ $key ] );
2883
- continue;
2884
- }
2885
-
2886
- // For install: make sure this is a plugin we *can* install and not one already installed.
2887
- if ( 'install' === $install_type && true === $this->tgmpa->is_plugin_installed( $slug ) ) {
2888
- unset( $plugins_to_install[ $key ] );
2889
- }
2890
-
2891
- // For updates: make sure this is a plugin we *can* update (update available and WP version ok).
2892
- if ( 'update' === $install_type && false === $this->tgmpa->is_plugin_updatetable( $slug ) ) {
2893
- unset( $plugins_to_install[ $key ] );
2894
- }
2895
- }
2896
-
2897
- // No need to proceed further if we have no plugins to handle.
2898
- if ( empty( $plugins_to_install ) ) {
2899
- if ( 'install' === $install_type ) {
2900
- $message = __( 'No plugins are available to be installed at this time.', 'tgmpa' );
2901
- } else {
2902
- $message = __( 'No plugins are available to be updated at this time.', 'tgmpa' );
2903
- }
2904
-
2905
- echo '<div id="message" class="error"><p>', esc_html( $message ), '</p></div>';
2906
-
2907
- return false;
2908
- }
2909
-
2910
- // Pass all necessary information if WP_Filesystem is needed.
2911
- $url = wp_nonce_url(
2912
- $this->tgmpa->get_tgmpa_url(),
2913
- 'bulk-' . $this->_args['plural']
2914
- );
2915
-
2916
- // Give validated data back to $_POST which is the only place the filesystem looks for extra fields.
2917
- $_POST['plugin'] = implode( ',', $plugins_to_install ); // Work around for WP bug #19643.
2918
-
2919
- $method = ''; // Leave blank so WP_Filesystem can populate it as necessary.
2920
- $fields = array_keys( $_POST ); // Extra fields to pass to WP_Filesystem.
2921
-
2922
- if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, $fields ) ) ) {
2923
- return true; // Stop the normal page form from displaying, credential request form will be shown.
2924
- }
2925
-
2926
- // Now we have some credentials, setup WP_Filesystem.
2927
- if ( ! WP_Filesystem( $creds ) ) {
2928
- // Our credentials were no good, ask the user for them again.
2929
- request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, $fields );
2930
-
2931
- return true;
2932
- }
2933
-
2934
- /* If we arrive here, we have the filesystem */
2935
-
2936
- // Store all information in arrays since we are processing a bulk installation.
2937
- $names = array();
2938
- $sources = array(); // Needed for installs.
2939
- $file_paths = array(); // Needed for upgrades.
2940
- $to_inject = array(); // Information to inject into the update_plugins transient.
2941
-
2942
- // Prepare the data for validated plugins for the install/upgrade.
2943
- foreach ( $plugins_to_install as $slug ) {
2944
- $name = $this->tgmpa->plugins[ $slug ]['name'];
2945
- $source = $this->tgmpa->get_download_url( $slug );
2946
-
2947
- if ( ! empty( $name ) && ! empty( $source ) ) {
2948
- $names[] = $name;
2949
-
2950
- switch ( $install_type ) {
2951
-
2952
- case 'install':
2953
- $sources[] = $source;
2954
- break;
2955
-
2956
- case 'update':
2957
- $file_paths[] = $this->tgmpa->plugins[ $slug ]['file_path'];
2958
- $to_inject[ $slug ] = $this->tgmpa->plugins[ $slug ];
2959
- $to_inject[ $slug ]['source'] = $source;
2960
- break;
2961
- }
2962
- }
2963
- }
2964
- unset( $slug, $name, $source );
2965
-
2966
- // Create a new instance of TGMPA_Bulk_Installer.
2967
- $installer = new TGMPA_Bulk_Installer(
2968
- new TGMPA_Bulk_Installer_Skin(
2969
- array(
2970
- 'url' => esc_url_raw( $this->tgmpa->get_tgmpa_url() ),
2971
- 'nonce' => 'bulk-' . $this->_args['plural'],
2972
- 'names' => $names,
2973
- 'install_type' => $install_type,
2974
- )
2975
- )
2976
- );
2977
-
2978
- // Wrap the install process with the appropriate HTML.
2979
- echo '<div class="tgmpa">',
2980
- '<h2 style="font-size: 23px; font-weight: 400; line-height: 29px; margin: 0; padding: 9px 15px 4px 0;">', esc_html( get_admin_page_title() ), '</h2>
2981
- <div class="update-php" style="width: 100%; height: 98%; min-height: 850px; padding-top: 1px;">';
2982
-
2983
- // Process the bulk installation submissions.
2984
- add_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1, 3 );
2985
-
2986
- if ( 'tgmpa-bulk-update' === $this->current_action() ) {
2987
- // Inject our info into the update transient.
2988
- $this->tgmpa->inject_update_info( $to_inject );
2989
-
2990
- $installer->bulk_upgrade( $file_paths );
2991
- } else {
2992
- $installer->bulk_install( $sources );
2993
- }
2994
-
2995
- remove_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1 );
2996
-
2997
- echo '</div></div>';
2998
-
2999
- return true;
3000
- }
3001
-
3002
- // Bulk activation process.
3003
- if ( 'tgmpa-bulk-activate' === $this->current_action() ) {
3004
- check_admin_referer( 'bulk-' . $this->_args['plural'] );
3005
-
3006
- // Did user actually select any plugins to activate ?
3007
- if ( empty( $_POST['plugin'] ) ) {
3008
- echo '<div id="message" class="error"><p>', esc_html__( 'No plugins were selected to be activated. No action taken.', 'tgmpa' ), '</p></div>';
3009
-
3010
- return false;
3011
- }
3012
-
3013
- // Grab plugin data from $_POST.
3014
- $plugins = array();
3015
- if ( isset( $_POST['plugin'] ) ) {
3016
- $plugins = array_map( 'urldecode', (array) $_POST['plugin'] );
3017
- $plugins = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins );
3018
- }
3019
-
3020
- $plugins_to_activate = array();
3021
- $plugin_names = array();
3022
-
3023
- // Grab the file paths for the selected & inactive plugins from the registration array.
3024
- foreach ( $plugins as $slug ) {
3025
- if ( $this->tgmpa->can_plugin_activate( $slug ) ) {
3026
- $plugins_to_activate[] = $this->tgmpa->plugins[ $slug ]['file_path'];
3027
- $plugin_names[] = $this->tgmpa->plugins[ $slug ]['name'];
3028
- }
3029
- }
3030
- unset( $slug );
3031
-
3032
- // Return early if there are no plugins to activate.
3033
- if ( empty( $plugins_to_activate ) ) {
3034
- echo '<div id="message" class="error"><p>', esc_html__( 'No plugins are available to be activated at this time.', 'tgmpa' ), '</p></div>';
3035
-
3036
- return false;
3037
- }
3038
-
3039
- // Now we are good to go - let's start activating plugins.
3040
- $activate = activate_plugins( $plugins_to_activate );
3041
-
3042
- if ( is_wp_error( $activate ) ) {
3043
- echo '<div id="message" class="error"><p>', wp_kses_post( $activate->get_error_message() ), '</p></div>';
3044
- } else {
3045
- $count = count( $plugin_names ); // Count so we can use _n function.
3046
- $plugin_names = array_map( array( 'TGMPA_Utils', 'wrap_in_strong' ), $plugin_names );
3047
- $last_plugin = array_pop( $plugin_names ); // Pop off last name to prep for readability.
3048
- $imploded = empty( $plugin_names ) ? $last_plugin : ( implode( ', ', $plugin_names ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin );
3049
-
3050
- printf( // WPCS: xss ok.
3051
- '<div id="message" class="updated"><p>%1$s %2$s.</p></div>',
3052
- esc_html( _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'tgmpa' ) ),
3053
- $imploded
3054
- );
3055
-
3056
- // Update recently activated plugins option.
3057
- $recent = (array) get_option( 'recently_activated' );
3058
- foreach ( $plugins_to_activate as $plugin => $time ) {
3059
- if ( isset( $recent[ $plugin ] ) ) {
3060
- unset( $recent[ $plugin ] );
3061
- }
3062
- }
3063
- update_option( 'recently_activated', $recent );
3064
- }
3065
-
3066
- unset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another.
3067
-
3068
- return true;
3069
- }
3070
-
3071
- return false;
3072
- }
3073
-
3074
- /**
3075
- * Prepares all of our information to be outputted into a usable table.
3076
- *
3077
- * @since 2.2.0
3078
- */
3079
- public function prepare_items() {
3080
- $columns = $this->get_columns(); // Get all necessary column information.
3081
- $hidden = array(); // No columns to hide, but we must set as an array.
3082
- $sortable = array(); // No reason to make sortable columns.
3083
- $primary = $this->get_primary_column_name(); // Column which has the row actions.
3084
- $this->_column_headers = array( $columns, $hidden, $sortable, $primary ); // Get all necessary column headers.
3085
-
3086
- // Process our bulk activations here.
3087
- if ( 'tgmpa-bulk-activate' === $this->current_action() ) {
3088
- $this->process_bulk_actions();
3089
- }
3090
-
3091
- // Store all of our plugin data into $items array so WP_List_Table can use it.
3092
- $this->items = apply_filters( 'wpms_tgmpa_table_data_items', $this->_gather_plugin_data() );
3093
- }
3094
-
3095
- /* *********** DEPRECATED METHODS *********** */
3096
-
3097
- /**
3098
- * Retrieve plugin data, given the plugin name.
3099
- *
3100
- * @since 2.2.0
3101
- * @deprecated 2.5.0 use {@see TGM_Plugin_Activation::_get_plugin_data_from_name()} instead.
3102
- * @see TGM_Plugin_Activation::_get_plugin_data_from_name()
3103
- *
3104
- * @param string $name Name of the plugin, as it was registered.
3105
- * @param string $data Optional. Array key of plugin data to return. Default is slug.
3106
- * @return string|boolean Plugin slug if found, false otherwise.
3107
- */
3108
- protected function _get_plugin_data_from_name( $name, $data = 'slug' ) {
3109
- _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'TGM_Plugin_Activation::_get_plugin_data_from_name()' );
3110
-
3111
- return $this->tgmpa->_get_plugin_data_from_name( $name, $data );
3112
- }
3113
- }
3114
-
3115
- /**
3116
- * Hack: Prevent TGMPA v2.4.1- bulk installer class from being loaded if 2.4.1- is loaded after 2.5+.
3117
- *
3118
- * @since 2.5.2
3119
- *
3120
- * {@internal The TGMPA_Bulk_Installer class was originally called TGM_Bulk_Installer.
3121
- * For more information, see that class.}}
3122
- */
3123
- class TGM_Bulk_Installer {
3124
- }
3125
-
3126
- /**
3127
- * Hack: Prevent TGMPA v2.4.1- bulk installer skin class from being loaded if 2.4.1- is loaded after 2.5+.
3128
- *
3129
- * @since 2.5.2
3130
- *
3131
- * {@internal The TGMPA_Bulk_Installer_Skin class was originally called TGM_Bulk_Installer_Skin.
3132
- * For more information, see that class.}}
3133
- */
3134
- class TGM_Bulk_Installer_Skin {
3135
- }
3136
-
3137
- /**
3138
- * The WP_Upgrader file isn't always available. If it isn't available,
3139
- * we load it here.
3140
- *
3141
- * We check to make sure no action or activation keys are set so that WordPress
3142
- * does not try to re-include the class when processing upgrades or installs outside
3143
- * of the class.
3144
- *
3145
- * @since 2.2.0
3146
- */
3147
- add_action( 'admin_init', '\ComingSoon\tgmpa_load_bulk_installer' );
3148
-
3149
- /**
3150
- * Load bulk installer
3151
- */
3152
- function tgmpa_load_bulk_installer() {
3153
- // Silently fail if 2.5+ is loaded *after* an older version.
3154
- if ( ! isset( $GLOBALS['wp_mail_smtp_tgmpa'] ) ) {
3155
- return;
3156
- }
3157
-
3158
- // Get TGMPA class instance.
3159
- $tgmpa_instance = call_user_func( array( get_class( $GLOBALS['wp_mail_smtp_tgmpa'] ), 'get_instance' ) );
3160
-
3161
- if ( isset( $_GET['page'] ) && $tgmpa_instance->menu === $_GET['page'] ) {
3162
- if ( ! class_exists( '\Plugin_Upgrader', false ) ) {
3163
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
3164
- }
3165
-
3166
- if ( ! class_exists( '\ComingSoon\TGMPA_Bulk_Installer', false ) ) {
3167
-
3168
- /**
3169
- * Installer class to handle bulk plugin installations.
3170
- *
3171
- * Extends WP_Upgrader and customizes to suit the installation of multiple
3172
- * plugins.
3173
- *
3174
- * @since 2.2.0
3175
- *
3176
- * {@internal Since 2.5.0 the class is an extension of Plugin_Upgrader rather than WP_Upgrader.}}
3177
- * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer to TGMPA_Bulk_Installer.
3178
- * This was done to prevent backward compatibility issues with v2.3.6.}}
3179
- *
3180
- * @package TGM-Plugin-Activation
3181
- * @author Thomas Griffin
3182
- * @author Gary Jones
3183
- */
3184
- class TGMPA_Bulk_Installer extends \Plugin_Upgrader {
3185
- /**
3186
- * Holds result of bulk plugin installation.
3187
- *
3188
- * @since 2.2.0
3189
- *
3190
- * @var string
3191
- */
3192
- public $result;
3193
-
3194
- /**
3195
- * Flag to check if bulk installation is occurring or not.
3196
- *
3197
- * @since 2.2.0
3198
- *
3199
- * @var boolean
3200
- */
3201
- public $bulk = false;
3202
-
3203
- /**
3204
- * TGMPA instance
3205
- *
3206
- * @since 2.5.0
3207
- *
3208
- * @var object
3209
- */
3210
- protected $tgmpa;
3211
-
3212
- /**
3213
- * Whether or not the destination directory needs to be cleared ( = on update).
3214
- *
3215
- * @since 2.5.0
3216
- *
3217
- * @var bool
3218
- */
3219
- protected $clear_destination = false;
3220
-
3221
- /**
3222
- * References parent constructor and sets defaults for class.
3223
- *
3224
- * @since 2.2.0
3225
- *
3226
- * @param \Bulk_Upgrader_Skin|null $skin Installer skin.
3227
- */
3228
- public function __construct( $skin = null ) {
3229
- // Get TGMPA class instance.
3230
- $this->tgmpa = call_user_func( array( get_class( $GLOBALS['wp_mail_smtp_tgmpa'] ), 'get_instance' ) );
3231
-
3232
- parent::__construct( $skin );
3233
-
3234
- if ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) {
3235
- $this->clear_destination = true;
3236
- }
3237
-
3238
- if ( $this->tgmpa->is_automatic ) {
3239
- $this->activate_strings();
3240
- }
3241
-
3242
- add_action( 'upgrader_process_complete', array( $this->tgmpa, 'populate_file_path' ) );
3243
- }
3244
-
3245
- /**
3246
- * Sets the correct activation strings for the installer skin to use.
3247
- *
3248
- * @since 2.2.0
3249
- */
3250
- public function activate_strings() {
3251
- $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'tgmpa' );
3252
- $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' );
3253
- }
3254
-
3255
- /**
3256
- * Performs the actual installation of each plugin.
3257
- *
3258
- * @since 2.2.0
3259
- *
3260
- * @see WP_Upgrader::run()
3261
- *
3262
- * @param array $options The installation config options.
3263
- * @return null|array Return early if error, array of installation data on success.
3264
- */
3265
- public function run( $options ) {
3266
- $result = parent::run( $options );
3267
-
3268
- // Reset the strings in case we changed one during automatic activation.
3269
- if ( $this->tgmpa->is_automatic ) {
3270
- if ( 'update' === $this->skin->options['install_type'] ) {
3271
- $this->upgrade_strings();
3272
- } else {
3273
- $this->install_strings();
3274
- }
3275
- }
3276
-
3277
- return $result;
3278
- }
3279
-
3280
- /**
3281
- * Processes the bulk installation of plugins.
3282
- *
3283
- * @since 2.2.0
3284
- *
3285
- * {@internal This is basically a near identical copy of the WP Core
3286
- * Plugin_Upgrader::bulk_upgrade() method, with minor adjustments to deal with
3287
- * new installs instead of upgrades.
3288
- * For ease of future synchronizations, the adjustments are clearly commented, but no other
3289
- * comments are added. Code style has been made to comply.}}
3290
- *
3291
- * @see Plugin_Upgrader::bulk_upgrade()
3292
- * @see https://core.trac.wordpress.org/browser/tags/4.2.1/src/wp-admin/includes/class-wp-upgrader.php#L838
3293
- * (@internal Last synced: Dec 31st 2015 against https://core.trac.wordpress.org/browser/trunk?rev=36134}}
3294
- *
3295
- * @param array $plugins The plugin sources needed for installation.
3296
- * @param array $args Arbitrary passed extra arguments.
3297
- * @return array|false Install confirmation messages on success, false on failure.
3298
- */
3299
- public function bulk_install( $plugins, $args = array() ) {
3300
- // [TGMPA + ] Hook auto-activation in.
3301
- add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );
3302
-
3303
- $defaults = array(
3304
- 'clear_update_cache' => true,
3305
- );
3306
- $parsed_args = wp_parse_args( $args, $defaults );
3307
-
3308
- $this->init();
3309
- $this->bulk = true;
3310
-
3311
- $this->install_strings(); // [TGMPA + ] adjusted.
3312
-
3313
- /* [TGMPA - ] $current = get_site_transient( 'update_plugins' ); */
3314
-
3315
- /* [TGMPA - ] add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4); */
3316
-
3317
- $this->skin->header();
3318
-
3319
- // Connect to the Filesystem first.
3320
- $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );
3321
- if ( ! $res ) {
3322
- $this->skin->footer();
3323
- return false;
3324
- }
3325
-
3326
- $this->skin->bulk_header();
3327
-
3328
- /*
3329
- * Only start maintenance mode if:
3330
- * - running Multisite and there are one or more plugins specified, OR
3331
- * - a plugin with an update available is currently active.
3332
- * @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible.
3333
- */
3334
- $maintenance = ( is_multisite() && ! empty( $plugins ) );
3335
-
3336
- /*
3337
- [TGMPA - ]
3338
- foreach ( $plugins as $plugin )
3339
- $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) );
3340
- */
3341
- if ( $maintenance ) {
3342
- $this->maintenance_mode( true );
3343
- }
3344
-
3345
- $results = array();
3346
-
3347
- $this->update_count = count( $plugins );
3348
- $this->update_current = 0;
3349
- foreach ( $plugins as $plugin ) {
3350
- $this->update_current++;
3351
-
3352
- $result = $this->run(
3353
- array(
3354
- 'package' => $plugin, // [TGMPA + ] adjusted.
3355
- 'destination' => \WP_PLUGIN_DIR,
3356
- 'clear_destination' => false, // [TGMPA + ] adjusted.
3357
- 'clear_working' => true,
3358
- 'is_multi' => true,
3359
- 'hook_extra' => array(
3360
- 'plugin' => $plugin,
3361
- ),
3362
- )
3363
- );
3364
-
3365
- $results[ $plugin ] = $this->result;
3366
-
3367
- // Prevent credentials auth screen from displaying multiple times.
3368
- if ( false === $result ) {
3369
- break;
3370
- }
3371
- } //end foreach $plugins
3372
-
3373
- $this->maintenance_mode( false );
3374
-
3375
- /**
3376
- * Fires when the bulk upgrader process is complete.
3377
- *
3378
- * @since WP 3.6.0 / TGMPA 2.5.0
3379
- *
3380
- * @param \Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might
3381
- * be a Theme_Upgrader or Core_Upgrade instance.
3382
- * @param array $data {
3383
- * Array of bulk item update data.
3384
- *
3385
- * @type string $action Type of action. Default 'update'.
3386
- * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'.
3387
- * @type bool $bulk Whether the update process is a bulk update. Default true.
3388
- * @type array $packages Array of plugin, theme, or core packages to update.
3389
- * }
3390
- */
3391
- do_action( 'upgrader_process_complete', $this, array(
3392
- 'action' => 'install', // [TGMPA + ] adjusted.
3393
- 'type' => 'plugin',
3394
- 'bulk' => true,
3395
- 'plugins' => $plugins,
3396
- ) );
3397
-
3398
- $this->skin->bulk_footer();
3399
-
3400
- $this->skin->footer();
3401
-
3402
- // Cleanup our hooks, in case something else does a upgrade on this connection.
3403
- /* [TGMPA - ] remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin')); */
3404
-
3405
- // [TGMPA + ] Remove our auto-activation hook.
3406
- remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );
3407
-
3408
- // Force refresh of plugin update information.
3409
- wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
3410
-
3411
- return $results;
3412
- }
3413
-
3414
- /**
3415
- * Handle a bulk upgrade request.
3416
- *
3417
- * @since 2.5.0
3418
- *
3419
- * @see Plugin_Upgrader::bulk_upgrade()
3420
- *
3421
- * @param array $plugins The local WP file_path's of the plugins which should be upgraded.
3422
- * @param array $args Arbitrary passed extra arguments.
3423
- * @return string|bool Install confirmation messages on success, false on failure.
3424
- */
3425
- public function bulk_upgrade( $plugins, $args = array() ) {
3426
-
3427
- add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );
3428
-
3429
- $result = parent::bulk_upgrade( $plugins, $args );
3430
-
3431
- remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 );
3432
-
3433
- return $result;
3434
- }
3435
-
3436
- /**
3437
- * Abuse a filter to auto-activate plugins after installation.
3438
- *
3439
- * Hooked into the 'upgrader_post_install' filter hook.
3440
- *
3441
- * @since 2.5.0
3442
- *
3443
- * @param bool $bool The value we need to give back (true).
3444
- * @return bool
3445
- */
3446
- public function auto_activate( $bool ) {
3447
- // Only process the activation of installed plugins if the automatic flag is set to true.
3448
- if ( $this->tgmpa->is_automatic ) {
3449
- // Flush plugins cache so the headers of the newly installed plugins will be read correctly.
3450
- wp_clean_plugins_cache();
3451
-
3452
- // Get the installed plugin file.
3453
- $plugin_info = $this->plugin_info();
3454
-
3455
- // Don't try to activate on upgrade of active plugin as WP will do this already.
3456
- if ( ! is_plugin_active( $plugin_info ) ) {
3457
- $activate = activate_plugin( $plugin_info );
3458
-
3459
- // Adjust the success string based on the activation result.
3460
- $this->strings['process_success'] = $this->strings['process_success'] . "<br />\n";
3461
-
3462
- if ( is_wp_error( $activate ) ) {
3463
- $this->skin->error( $activate );
3464
- $this->strings['process_success'] .= $this->strings['activation_failed'];
3465
- } else {
3466
- $this->strings['process_success'] .= $this->strings['activation_success'];
3467
- }
3468
- }
3469
- }
3470
-
3471
- return $bool;
3472
- }
3473
- }
3474
- }
3475
-
3476
- if ( ! class_exists( '\ComingSoon\TGMPA_Bulk_Installer_Skin', false ) ) {
3477
-
3478
- /**
3479
- * Installer skin to set strings for the bulk plugin installations..
3480
- *
3481
- * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple
3482
- * plugins.
3483
- *
3484
- * @since 2.2.0
3485
- *
3486
- * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer_Skin to
3487
- * TGMPA_Bulk_Installer_Skin.
3488
- * This was done to prevent backward compatibility issues with v2.3.6.}}
3489
- *
3490
- * @see https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/class-wp-upgrader-skins.php
3491
- *
3492
- * @package TGM-Plugin-Activation
3493
- * @author Thomas Griffin
3494
- * @author Gary Jones
3495
- */
3496
- class TGMPA_Bulk_Installer_Skin extends \Bulk_Upgrader_Skin {
3497
- /**
3498
- * Holds plugin info for each individual plugin installation.
3499
- *
3500
- * @since 2.2.0
3501
- *
3502
- * @var array
3503
- */
3504
- public $plugin_info = array();
3505
-
3506
- /**
3507
- * Holds names of plugins that are undergoing bulk installations.
3508
- *
3509
- * @since 2.2.0
3510
- *
3511
- * @var array
3512
- */
3513
- public $plugin_names = array();
3514
-
3515
- /**
3516
- * Integer to use for iteration through each plugin installation.
3517
- *
3518
- * @since 2.2.0
3519
- *
3520
- * @var integer
3521
- */
3522
- public $i = 0;
3523
-
3524
- /**
3525
- * TGMPA instance
3526
- *
3527
- * @since 2.5.0
3528
- *
3529
- * @var object
3530
- */
3531
- protected $tgmpa;
3532
-
3533
- /**
3534
- * Constructor. Parses default args with new ones and extracts them for use.
3535
- *
3536
- * @since 2.2.0
3537
- *
3538
- * @param array $args Arguments to pass for use within the class.
3539
- */
3540
- public function __construct( $args = array() ) {
3541
- // Get TGMPA class instance.
3542
- $this->tgmpa = call_user_func( array( get_class( $GLOBALS['wp_mail_smtp_tgmpa'] ), 'get_instance' ) );
3543
-
3544
- // Parse default and new args.
3545
- $defaults = array(
3546
- 'url' => '',
3547
- 'nonce' => '',
3548
- 'names' => array(),
3549
- 'install_type' => 'install',
3550
- );
3551
- $args = wp_parse_args( $args, $defaults );
3552
-
3553
- // Set plugin names to $this->plugin_names property.
3554
- $this->plugin_names = $args['names'];
3555
-
3556
- // Extract the new args.
3557
- parent::__construct( $args );
3558
- }
3559
-
3560
- /**
3561
- * Sets install skin strings for each individual plugin.
3562
- *
3563
- * Checks to see if the automatic activation flag is set and uses the
3564
- * the proper strings accordingly.
3565
- *
3566
- * @since 2.2.0
3567
- */
3568
- public function add_strings() {
3569
- if ( 'update' === $this->options['install_type'] ) {
3570
- parent::add_strings();
3571
- /* translators: 1: plugin name, 2: action number 3: total number of actions. */
3572
- $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)', 'tgmpa' );
3573
- } else {
3574
- /* translators: 1: plugin name, 2: error message. */
3575
- $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: <strong>%2$s</strong>.', 'tgmpa' );
3576
- /* translators: 1: plugin name. */
3577
- $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'tgmpa' );
3578
-
3579
- if ( $this->tgmpa->is_automatic ) {
3580
- // Automatic activation strings.
3581
- $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' );
3582
- /* translators: 1: plugin name. */
3583
- $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'tgmpa' ) . ' <a href="#" class="hide-if-no-js" onclick="%2$s"><span>' . esc_html__( 'Show Details', 'tgmpa' ) . '</span><span class="hidden">' . esc_html__( 'Hide Details', 'tgmpa' ) . '</span>.</a>';
3584
- $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'tgmpa' );
3585
- /* translators: 1: plugin name, 2: action number 3: total number of actions. */
3586
- $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' );
3587
- } else {
3588
- // Default installation strings.
3589
- $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' );
3590
- /* translators: 1: plugin name. */
3591
- $this->upgrader->strings['skin_update_successful'] = esc_html__( '%1$s installed successfully.', 'tgmpa' ) . ' <a href="#" class="hide-if-no-js" onclick="%2$s"><span>' . esc_html__( 'Show Details', 'tgmpa' ) . '</span><span class="hidden">' . esc_html__( 'Hide Details', 'tgmpa' ) . '</span>.</a>';
3592
- $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'tgmpa' );
3593
- /* translators: 1: plugin name, 2: action number 3: total number of actions. */
3594
- $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' );
3595
- }
3596
- }
3597
- }
3598
-
3599
- /**
3600
- * Outputs the header strings and necessary JS before each plugin installation.
3601
- *
3602
- * @since 2.2.0
3603
- *
3604
- * @param string $title Unused in this implementation.
3605
- */
3606
- public function before( $title = '' ) {
3607
- if ( empty( $title ) ) {
3608
- $title = esc_html( $this->plugin_names[ $this->i ] );
3609
- }
3610
- parent::before( $title );
3611
- }
3612
-
3613
- /**
3614
- * Outputs the footer strings and necessary JS after each plugin installation.
3615
- *
3616
- * Checks for any errors and outputs them if they exist, else output
3617
- * success strings.
3618
- *
3619
- * @since 2.2.0
3620
- *
3621
- * @param string $title Unused in this implementation.
3622
- */
3623
- public function after( $title = '' ) {
3624
- if ( empty( $title ) ) {
3625
- $title = esc_html( $this->plugin_names[ $this->i ] );
3626
- }
3627
- parent::after( $title );
3628
-
3629
- $this->i++;
3630
- }
3631
-
3632
- /**
3633
- * Outputs links after bulk plugin installation is complete.
3634
- *
3635
- * @since 2.2.0
3636
- */
3637
- public function bulk_footer() {
3638
- // Serve up the string to say installations (and possibly activations) are complete.
3639
- parent::bulk_footer();
3640
-
3641
- // Flush plugins cache so we can make sure that the installed plugins list is always up to date.
3642
- wp_clean_plugins_cache();
3643
-
3644
- $this->tgmpa->show_tgmpa_version();
3645
-
3646
- // Display message based on if all plugins are now active or not.
3647
- $update_actions = array();
3648
-
3649
- if ( $this->tgmpa->is_tgmpa_complete() ) {
3650
- // All plugins are active, so we display the complete string and hide the menu to protect users.
3651
- echo '<style type="text/css">#adminmenu .wp-submenu li.current { display: none !important; }</style>';
3652
- $update_actions['dashboard'] = sprintf(
3653
- esc_html( $this->tgmpa->strings['complete'] ),
3654
- '<a href="' . esc_url( self_admin_url() ) . '">' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '</a>'
3655
- );
3656
- } else {
3657
- $update_actions['tgmpa_page'] = '<a href="' . esc_url( $this->tgmpa->get_tgmpa_url() ) . '" target="_parent">' . esc_html( $this->tgmpa->strings['return'] ) . '</a>';
3658
- }
3659
-
3660
- /**
3661
- * Filter the list of action links available following bulk plugin installs/updates.
3662
- *
3663
- * @since 2.5.0
3664
- *
3665
- * @param array $update_actions Array of plugin action links.
3666
- * @param array $plugin_info Array of information for the last-handled plugin.
3667
- */
3668
- $update_actions = apply_filters( 'wpms_tgmpa_update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
3669
-
3670
- if ( ! empty( $update_actions ) ) {
3671
- $this->feedback( implode( ' | ', (array) $update_actions ) );
3672
- }
3673
- }
3674
-
3675
- /* *********** DEPRECATED METHODS *********** */
3676
-
3677
- /**
3678
- * Flush header output buffer.
3679
- *
3680
- * @since 2.2.0
3681
- * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead
3682
- * @see Bulk_Upgrader_Skin::flush_output()
3683
- */
3684
- public function before_flush_output() {
3685
- _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' );
3686
- $this->flush_output();
3687
- }
3688
-
3689
- /**
3690
- * Flush footer output buffer and iterate $this->i to make sure the
3691
- * installation strings reference the correct plugin.
3692
- *
3693
- * @since 2.2.0
3694
- * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead
3695
- * @see Bulk_Upgrader_Skin::flush_output()
3696
- */
3697
- public function after_flush_output() {
3698
- _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' );
3699
- $this->flush_output();
3700
- $this->i++;
3701
- }
3702
- }
3703
- }
3704
- }
3705
- }
3706
-
3707
-
3708
- /**
3709
- * Generic utilities for TGMPA.
3710
- *
3711
- * All methods are static, poor-dev name-spacing class wrapper.
3712
- *
3713
- * Class was called TGM_Utils in 2.5.0 but renamed TGMPA_Utils in 2.5.1 as this was conflicting with Soliloquy.
3714
- *
3715
- * @since 2.5.0
3716
- *
3717
- * @package TGM-Plugin-Activation
3718
- * @author Juliette Reinders Folmer
3719
- */
3720
- class TGMPA_Utils {
3721
- /**
3722
- * Whether the PHP filter extension is enabled.
3723
- *
3724
- * @see http://php.net/book.filter
3725
- *
3726
- * @since 2.5.0
3727
- *
3728
- * @static
3729
- *
3730
- * @var bool $has_filters True is the extension is enabled.
3731
- */
3732
- public static $has_filters;
3733
-
3734
- /**
3735
- * Wrap an arbitrary string in <em> tags. Meant to be used in combination with array_map().
3736
- *
3737
- * @since 2.5.0
3738
- *
3739
- * @static
3740
- *
3741
- * @param string $string Text to be wrapped.
3742
- * @return string
3743
- */
3744
- public static function wrap_in_em( $string ) {
3745
- return '<em>' . wp_kses_post( $string ) . '</em>';
3746
- }
3747
-
3748
- /**
3749
- * Wrap an arbitrary string in <strong> tags. Meant to be used in combination with array_map().
3750
- *
3751
- * @since 2.5.0
3752
- *
3753
- * @static
3754
- *
3755
- * @param string $string Text to be wrapped.
3756
- * @return string
3757
- */
3758
- public static function wrap_in_strong( $string ) {
3759
- return '<strong>' . wp_kses_post( $string ) . '</strong>';
3760
- }
3761
-
3762
- /**
3763
- * Helper function: Validate a value as boolean
3764
- *
3765
- * @since 2.5.0
3766
- *
3767
- * @static
3768
- *
3769
- * @param mixed $value Arbitrary value.
3770
- * @return bool
3771
- */
3772
- public static function validate_bool( $value ) {
3773
- if ( ! isset( self::$has_filters ) ) {
3774
- self::$has_filters = extension_loaded( 'filter' );
3775
- }
3776
-
3777
- if ( self::$has_filters ) {
3778
- return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
3779
- } else {
3780
- return self::emulate_filter_bool( $value );
3781
- }
3782
- }
3783
-
3784
- /**
3785
- * Helper function: Cast a value to bool
3786
- *
3787
- * @since 2.5.0
3788
- *
3789
- * @static
3790
- *
3791
- * @param mixed $value Value to cast.
3792
- * @return bool
3793
- */
3794
- protected static function emulate_filter_bool( $value ) {
3795
- // @codingStandardsIgnoreStart
3796
- static $true = array(
3797
- '1',
3798
- 'true', 'True', 'TRUE',
3799
- 'y', 'Y',
3800
- 'yes', 'Yes', 'YES',
3801
- 'on', 'On', 'ON',
3802
- );
3803
- static $false = array(
3804
- '0',
3805
- 'false', 'False', 'FALSE',
3806
- 'n', 'N',
3807
- 'no', 'No', 'NO',
3808
- 'off', 'Off', 'OFF',
3809
- );
3810
- // @codingStandardsIgnoreEnd
3811
-
3812
- if ( is_bool( $value ) ) {
3813
- return $value;
3814
- } elseif ( is_int( $value ) && ( 0 === $value || 1 === $value ) ) {
3815
- return (bool) $value;
3816
- } elseif ( ( is_float( $value ) && ! is_nan( $value ) ) && ( (float) 0 === $value || (float) 1 === $value ) ) {
3817
- return (bool) $value;
3818
- } elseif ( is_string( $value ) ) {
3819
- $value = trim( $value );
3820
- if ( in_array( $value, $true, true ) ) {
3821
- return true;
3822
- } elseif ( in_array( $value, $false, true ) ) {
3823
- return false;
3824
- } else {
3825
- return false;
3826
- }
3827
- }
3828
-
3829
- return false;
3830
- }
3831
- }
3832
-
3833
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/setup_tgmpa.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
- /**
3
- * Recommend WPForms Lite using TGM Activation.
4
- *
5
- * @since 5.0.20
6
- */
7
- function coming_soon_init_recommendations() {
8
- $dismmised = get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_coming-soon', true);
9
- if($dismmised == 1){
10
- return;
11
- }
12
-
13
- // Recommend only for new installs.
14
- if ( ! coming_soon_is_new_install() ) {
15
- return;
16
- }
17
- // Specify a plugin that we want to recommend.
18
- $plugins = apply_filters( 'coming_soon_recommendations_plugins', array(
19
- array(
20
- 'name' => 'Contact Form by WPForms',
21
- 'slug' => 'wpforms-lite',
22
- 'required' => false,
23
- 'is_callable' => 'wpforms', // This will target the Pro version as well, not only the one from WP.org repository.
24
- ),
25
- ) );
26
- /*
27
- * Array of configuration settings.
28
- */
29
- $config = apply_filters( 'coming_soon_recommendations_config', array(
30
- 'id' => 'coming-soon', // Unique ID for hashing notices for multiple instances of TGMPA.
31
- 'menu' => 'coming-soon-install-plugins', // Menu slug.
32
- 'parent_slug' => 'plugins.php', // Parent menu slug.
33
- 'capability' => 'manage_options', // Capability needed to view plugin install page, should be a capability associated with the parent menu used.
34
- 'has_notices' => true, // Show admin notices or not.
35
- 'dismissable' => true, // If false, a user cannot dismiss the nag message.
36
- 'dismiss_msg' => '', // If 'dismissable' is false, this message will be output at top of nag.
37
- 'is_automatic' => false, // Automatically activate plugins after installation or not.
38
- 'message' => '', // Message to output right before the plugins table.
39
- 'strings' => array(
40
- /* translators: 1: plugin name(s). */
41
- 'notice_can_install_recommended' => _n_noop(
42
- 'Thanks for using Coming Soon Page & Maintenance Mode by SeedProd. We also recommend using %1$s. It\'s the best drag & drop form builder, has over 1 million active installs, and over 2000+ 5 star ratings.',
43
- 'Thanks for using Coming Soon Page & Maintenance Mode by SeedProd. We also recommend using %1$s. It\'s the best drag & drop form builder, has over 1 million active installs, and over 2000+ 5 star ratings.',
44
- 'coming-soon'
45
- ),
46
- /* translators: 1: plugin name(s). */
47
- 'notice_can_activate_recommended' => _n_noop(
48
- 'Thanks for using Coming Soon Page & Maintenance Mode by SeedProd. We also recommend using %1$s. It\'s the best drag & drop form builder, has over 1 million active installs, and over 2000+ 5 star ratings.',
49
- 'Thanks for using Coming Soon Page & Maintenance Mode by SeedProd. We also recommend using %1$s. It\'s the best drag & drop form builder, has over 1 million active installs, and over 2000+ 5 star ratings.',
50
- 'coming-soon'
51
- ),
52
- 'install_link' => _n_noop(
53
- 'Install WPForms Now',
54
- 'Begin installing plugins',
55
- 'coming-soon'
56
- ),
57
- 'activate_link' => _n_noop(
58
- 'Activate WPForms',
59
- 'Begin activating plugins',
60
- 'coming-soon'
61
- ),
62
- 'nag_type' => 'notice-info',
63
- ),
64
- ) );
65
- \ComingSoon\tgmpa( (array) $plugins, (array) $config );
66
- }
67
-
68
- function coming_soon_is_new_install() {
69
- /*
70
- * No previously installed 0.*.
71
- * 'wp_mail_smtp_initial_version' option appeared in 1.3.0. So we make sure it exists.
72
- * No previous plugin upgrades.
73
- */
74
- if (
75
- get_option( 'seed_csp4_initial_version', false ) &&
76
- version_compare( SEED_CSP4_VERSION, get_option( 'seed_csp4_initial_version' ), '=' )
77
- ) {
78
- return true;
79
- }
80
-
81
- return false;
82
- }
83
-
84
- function coming_soon_wpforms_upgrade_link( $medium ) {
85
- // track cross referrals to Awesome Motive products
86
- $medium = 'seedprod';
87
- return $medium;
88
- }
89
-
90
- $seed_csp4_wpforms = get_option('seed_csp4_wpforms');
91
- if(!empty($seed_csp4_wpforms)){
92
- add_filter( 'wpforms_upgrade_link_medium', 'coming_soon_wpforms_upgrade_link' );
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
resources/views/exit-pop.php CHANGED
@@ -1,19 +1,25 @@
1
  <div id="cexit-popup" class="exit-popup mfp-hide">
2
- <div><p>Thanks for your interest in SeedProd Pro!<br>If you have any questions or issues just <a href="https://www.seedprod.com/contact/" target="_blank" rel="noopener noreferrer">let us know</a>.</p><p>After purchasing SeedProd Pro, you'll need to <strong>download and install the Pro version of the plugin</strong>, and then <strong>remove the free plugin</strong>.<br>(Don't worry, all your settings will be preserved.)</p><p>Check out <a href="https://support.seedprod.com/article/51-installing-the-coming-soon-pro-version-3-plugin?utm_source=WordPress&;utm_medium=link&utm_campaign=liteplugin" target="_blank" rel="noopener noreferrer">our documentation</a> for step-by-step instructions.</p></div>
3
- <button type="button" class="exit-popup-close button-primary">OK</button>
 
 
 
 
 
 
 
 
 
4
  </div>
5
 
6
  <a href="#cexit-popup" class="exit-popup-link" style="display:none">Show inline popup</a>
7
 
8
  <script>
9
-
10
-
11
  jQuery('.exit-popup-link').magnificPopup({
12
- type:'inline',
13
  });
14
 
15
- jQuery( ".exit-popup-close" ).click(function() {
16
- jQuery('.exit-popup-link').magnificPopup('close');
17
  });
18
-
19
  </script>
1
  <div id="cexit-popup" class="exit-popup mfp-hide">
2
+ <div>
3
+ <p>Thanks for your interest in SeedProd Pro!<br>If you have any questions or issues just <a
4
+ href="https://www.seedprod.com/contact/" target="_blank" rel="noopener noreferrer">let us know</a>.</p>
5
+ <p>After purchasing SeedProd Pro, you'll need to <strong>download and install the Pro version of the
6
+ plugin</strong>, and then <strong>remove the free plugin</strong>.<br>(Don't worry, all your settings
7
+ will be preserved.)</p>
8
+ <p>Check out <a
9
+ href="https://support.seedprod.com/article/49-installing-and-activating-the-coming-soon-pro-plugin?utm_source=WordPress&;utm_medium=link&utm_campaign=liteplugin"
10
+ target="_blank" rel="noopener noreferrer">our documentation</a> for step-by-step instructions.</p>
11
+ </div>
12
+ <button type="button" class="exit-popup-close button-primary">OK</button>
13
  </div>
14
 
15
  <a href="#cexit-popup" class="exit-popup-link" style="display:none">Show inline popup</a>
16
 
17
  <script>
 
 
18
  jQuery('.exit-popup-link').magnificPopup({
19
+ type: 'inline',
20
  });
21
 
22
+ jQuery(".exit-popup-close").click(function() {
23
+ jQuery('.exit-popup-link').magnificPopup('close');
24
  });
 
25
  </script>