Easy Updates Manager - Version 5.0.0

Version Description

Updated 2015-04-23 to ensure WordPress 4.2 compatibility Released 2015-03-24

In version 5.0.0 we completely re-wrote the plugin to offer a faster and more secure experience. You will also notice that we added lots more settings to cover almost every aspect of managing updates.

  • Complete re-write of Disable Updates Manager with new user interface.
  • Now compatible with WordPress Multisite installations.
  • New name: Easy Updates Manager
  • New contributor: ronalfy

=

Download this release

Release Info

Developer ronalfy
Plugin Icon 128x128 Easy Updates Manager
Version 5.0.0
Comparing to
See all releases

Code changes from version 4.7.0 to 5.0.0

assets/admin.js DELETED
@@ -1,24 +0,0 @@
1
- ;jQuery(document).ready( function($) {
2
-
3
- /* Add jQuery Chosen to enhance selects. */
4
- if ( $.fn.chosen ) {
5
-
6
- $('.dum-enhanced-select').chosen( { width: '100%' } );
7
-
8
- $('#dum-disable-themes, #dum-disable-plugins').click( function() {
9
-
10
- id = $(this).attr('id');
11
-
12
- if ( $(this).is(':checked') ) {
13
-
14
- $( '#' + id + '-select').attr( 'disabled', false ).trigger('chosen:updated');
15
-
16
- } else {
17
-
18
- $( '#' + id + '-select').val( function( i, value ) { return $(this).data('placeholder'); } ).attr( 'disabled', true ).trigger('chosen:updated');
19
- }
20
-
21
- });
22
- }
23
-
24
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/admin.min.js DELETED
@@ -1,3 +0,0 @@
1
- jQuery(document).ready(function(a){if(a.fn.chosen){a(".dum-enhanced-select").chosen({width:"100%"});a("#dum-disable-themes, #dum-disable-plugins").click(function(){id=a(this).attr("id");
2
- if(a(this).is(":checked")){a("#"+id+"-select").attr("disabled",false).trigger("chosen:updated");}else{a("#"+id+"-select").val(function(b,c){return a(this).data("placeholder");
3
- }).attr("disabled",true).trigger("chosen:updated");}});}});
 
 
 
assets/style.css DELETED
@@ -1,59 +0,0 @@
1
- /* Description: Setting Tooltips */
2
- .showonhover {
3
- position: relative;
4
- }
5
-
6
- .showonhover .hovertext {
7
- opacity: 0;
8
- top: -99999px;
9
- position: absolute;
10
- z-index: 1000;
11
- border: 1px solid #ffd971;
12
- background-color: #fffdce;
13
- padding: 2px 8px 2px 8px;
14
- width: auto;
15
- height: auto;
16
- font-size: .85em;
17
- -webkit-transition: opacity .3s ease;
18
- -moz-transition: opacity .3s ease;
19
- -o-transition: opacity .3s ease;
20
- transition: opacity .3s ease;
21
- }
22
-
23
- .showonhover:hover .hovertext {
24
- opacity: 1;
25
- top: 0;
26
- }
27
-
28
- a.viewdescription {
29
- color: #999;
30
- }
31
-
32
- a.viewdescription:hover {
33
- background-color: #999;
34
- color: #FFF;
35
- }
36
-
37
- /* Description: Tutorial Columns */
38
- #acolumn1 {
39
- width: 40%;
40
- padding: 0 5pt 0 0;
41
- float: left;
42
- }
43
-
44
- #acolumn2 {
45
- width: 40%;
46
- padding: 0 5pt 0 0;
47
- float: right;
48
- }
49
-
50
- /* Description: Chosen Settings */
51
- select.dum-enhanced-select {
52
- width: 100%;
53
- }
54
-
55
- .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
56
- -webkit-box-sizing: content-box;
57
- -moz-box-sizing: content-box;
58
- box-sizing: content-box;
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/style.min.css DELETED
@@ -1,4 +0,0 @@
1
- .showonhover{position:relative}.showonhover .hovertext{opacity:0;top:-99999px;position:absolute;z-index:1000;border:1px solid #ffd971;background-color:#fffdce;padding:2px 8px 2px 8px;width:auto;height:auto;font-size:.85em;-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;-o-transition:opacity .3s ease;transition:opacity .3s ease}
2
- .showonhover:hover .hovertext{opacity:1;top:0}a.viewdescription{color:#999}a.viewdescription:hover{background-color:#999;color:#FFF}select.dum-enhanced-select{width:100%}
3
- .chosen-container-multi .chosen-choices li.search-field input[type="text"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
4
- #acolumn1{width:40%;padding:0 5pt 0 0;float:left;}#acolumn2{width:40%;padding:0 5pt 0 0;float:right;}
 
 
 
 
includes/MPSUM_Admin.php ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Easy Updates Manager admin controller.
4
+ *
5
+ * Initializes the admin panel options and load the admin dependencies
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ class MPSUM_Admin {
12
+
13
+ /**
14
+ * Holds the class instance.
15
+ *
16
+ * @since 5.0.0
17
+ * @access static
18
+ * @var MPSUM_Admin $instance
19
+ */
20
+ private static $instance = null;
21
+
22
+ /**
23
+ * Holds the URL to the admin panel page
24
+ *
25
+ * @since 5.0.0
26
+ * @access static
27
+ * @var string $url
28
+ */
29
+ private static $url = '';
30
+
31
+ /**
32
+ * Holds the slug to the admin panel page
33
+ *
34
+ * @since 5.0.0
35
+ * @access static
36
+ * @var string $slug
37
+ */
38
+ private static $slug = 'mpsum-update-options';
39
+
40
+ /**
41
+ * Set a class instance.
42
+ *
43
+ * Set a class instance.
44
+ *
45
+ * @since 5.0.0
46
+ * @access static
47
+ *
48
+ */
49
+ public static function run() {
50
+ if ( null == self::$instance ) {
51
+ self::$instance = new self;
52
+ }
53
+ } //end get_instance
54
+
55
+ /**
56
+ * Class constructor.
57
+ *
58
+ * Initialize the class
59
+ *
60
+ * @since 5.0.0
61
+ * @access private
62
+ *
63
+ */
64
+ private function __construct() {
65
+ add_action( 'init', array( $this, 'init' ), 9 );
66
+ } //end constructor
67
+
68
+ /**
69
+ * Return the URL to the admin panel page.
70
+ *
71
+ * Return the URL to the admin panel page.
72
+ *
73
+ * @since 5.0.0
74
+ * @access static
75
+ *
76
+ * @return string URL to the admin panel page.
77
+ */
78
+ public static function get_url() {
79
+ $url = self::$url;
80
+ if ( empty( $url ) ) {
81
+ if ( is_multisite() ) {
82
+ $url = add_query_arg( array( 'page' => self::get_slug() ), network_admin_url( 'update-core.php' ) );
83
+ } else {
84
+ $url = add_query_arg( array( 'page' => self::get_slug() ), admin_url( 'index.php' ) );
85
+ }
86
+ self::$url = $url;
87
+ }
88
+ return $url;
89
+ }
90
+
91
+ /**
92
+ * Return the slug for the admin panel page.
93
+ *
94
+ * Return the slug for the admin panel page.
95
+ *
96
+ * @since 5.0.0
97
+ * @access static
98
+ *
99
+ * @return string slug to the admin panel page.
100
+ */
101
+ public static function get_slug() {
102
+ return self::$slug;
103
+ }
104
+
105
+ /**
106
+ * Initialize the admin menu.
107
+ *
108
+ * Initialize the admin menu.
109
+ *
110
+ * @since 5.0.0
111
+ * @access public
112
+ * @see __construct
113
+ * @internal Uses init action
114
+ *
115
+ */
116
+ public function init() {
117
+
118
+ //Plugin and Theme actions
119
+ if ( is_multisite() ) {
120
+ add_action( 'network_admin_menu', array( $this, 'init_network_admin_menus' ) );
121
+ } else {
122
+ add_action( 'admin_menu', array( $this, 'init_single_site_admin_menus' ) );
123
+ }
124
+
125
+ //Add settings link to plugins screen
126
+ $prefix = is_multisite() ? 'network_admin_' : '';
127
+ add_action( $prefix . 'plugin_action_links_' . MPSUM_Updates_Manager::get_plugin_basename(), array( $this, 'plugin_settings_link' ) );
128
+
129
+ //todo - maybe load these conditionally based on $_REQUEST[ 'tab' ] param
130
+ new MPSUM_Admin_Plugins( self::get_slug() );
131
+ new MPSUM_Admin_Themes( self::get_slug() );
132
+ new MPSUM_Admin_Core( self::get_slug() );
133
+ new MPSUM_Admin_Advanced( self::get_slug() );
134
+
135
+ }
136
+
137
+ /**
138
+ * Initializes the help screen.
139
+ *
140
+ * Initializes the help screen.
141
+ *
142
+ * @since 5.0.0
143
+ * @access public
144
+ * @see init
145
+ * @internal Uses load_{$hook} action
146
+ *
147
+ */
148
+ public function init_help_screen() {
149
+ new MPSUM_Admin_Help();
150
+ }
151
+
152
+ /**
153
+ * Adds a sub-menu page for multisite.
154
+ *
155
+ * Adds a sub-menu page for multisite.
156
+ *
157
+ * @since 5.0.0
158
+ * @access public
159
+ * @see init
160
+ * @internal Uses network_admin_menu action
161
+ *
162
+ */
163
+ public function init_network_admin_menus() {
164
+ $hook = add_submenu_page( 'update-core.php', __( 'Update Options', 'stops-core-theme-and-plugin-updates' ) , __( 'Update Options', 'stops-core-theme-and-plugin-updates' ), 'update_core', self::get_slug(), array( $this, 'output_admin_interface' ) );
165
+ add_action( "load-$hook", array( $this, 'init_help_screen' ) );
166
+ }
167
+
168
+ /**
169
+ * Adds a sub-menu page for single-site.
170
+ *
171
+ * Adds a sub-menu page for single-site.
172
+ *
173
+ * @since 5.0.0
174
+ * @access public
175
+ * @see init
176
+ * @internal Uses admin_menu action
177
+ *
178
+ */
179
+ public function init_single_site_admin_menus() {
180
+ $hook = add_dashboard_page( __( 'Update Options', 'stops-core-theme-and-plugin-updates' ) , __( 'Update Options', 'stops-core-theme-and-plugin-updates' ), 'update_core', self::get_slug(), array( $this, 'output_admin_interface' ) );
181
+ add_action( "load-$hook", array( $this, 'init_help_screen' ) );
182
+ }
183
+
184
+ /**
185
+ * Outputs admin interface for sub-menu.
186
+ *
187
+ * Outputs admin interface for sub-menu.
188
+ *
189
+ * @since 5.0.0
190
+ * @access public
191
+ * @see init_network_admin_menus, init_single_site_admin_menus
192
+ *
193
+ */
194
+ public function output_admin_interface() {
195
+ ?>
196
+ <div class="wrap">
197
+ <h2>
198
+ <?php echo esc_html_e( 'Manage Updates', 'stops-core-theme-and-plugin-updates' ); ?>
199
+ </h2>
200
+ <?php
201
+ $tabs =
202
+ array(
203
+ array(
204
+ 'url' => add_query_arg( array( 'tab' => 'main' ), self::get_url() ), /* URL to the tab */
205
+ 'label' => esc_html__( 'General', 'stops-core-theme-and-plugin-updates' ),
206
+ 'get' => 'main' /*$_GET variable*/,
207
+ 'action' => 'mpsum_admin_tab_main' /* action variable in do_action */
208
+ ),
209
+ array(
210
+ 'url' => add_query_arg( array( 'tab' => 'plugins' ), self::get_url() ), /* URL to the tab */
211
+ 'label' => esc_html__( 'Plugins', 'stops-core-theme-and-plugin-updates' ),
212
+ 'get' => 'plugins' /*$_GET variable*/,
213
+ 'action' => 'mpsum_admin_tab_plugins' /* action variable in do_action */
214
+ ),
215
+ array(
216
+ 'url' => add_query_arg( array( 'tab' => 'themes' ), self::get_url() ), /* URL to the tab */
217
+ 'label' => esc_html__( 'Themes', 'stops-core-theme-and-plugin-updates' ),
218
+ 'get' => 'themes' /*$_GET variable*/,
219
+ 'action' => 'mpsum_admin_tab_themes' /* action variable in do_action */
220
+ ),
221
+ array(
222
+ 'url' => add_query_arg( array( 'tab' => 'advanced' ), self::get_url() ), /* URL to the tab */
223
+ 'label' => esc_html__( 'Advanced', 'stops-core-theme-and-plugin-updates' ),
224
+ 'get' => 'advanced' /*$_GET variable*/,
225
+ 'action' => 'mpsum_admin_tab_advanced' /* action variable in do_action */
226
+ )
227
+ );
228
+ $tabs_count = count( $tabs );
229
+ if ( $tabs && !empty( $tabs ) ) {
230
+ $tab_html = '<h2 class="nav-tab-wrapper">';
231
+ $active_tab = isset( $_GET[ 'tab' ] ) ? sanitize_text_field( $_GET[ 'tab' ] ) : 'main';
232
+ $do_action = false;
233
+ foreach( $tabs as $tab ) {
234
+ $classes = array( 'nav-tab' );
235
+ $tab_get = isset( $tab[ 'get' ] ) ? $tab[ 'get' ] : '';
236
+ if ( $active_tab == $tab_get ) {
237
+ $classes[] = 'nav-tab-active';
238
+ $do_action = isset( $tab[ 'action' ] ) ? $tab[ 'action' ] : false;
239
+ }
240
+ $tab_url = isset( $tab[ 'url' ] ) ? $tab[ 'url' ] : '';
241
+ $tab_label = isset( $tab[ 'label' ] ) ? $tab[ 'label' ] : '';
242
+ $tab_html .= sprintf( '<a href="%s" class="%s">%s</a>', esc_url( $tab_url ), esc_attr( implode( ' ', $classes ) ), esc_html( $tab[ 'label' ] ) );
243
+ }
244
+ $tab_html .= '</h2>';
245
+ if ( $tabs_count > 1 ) {
246
+ echo $tab_html;
247
+ }
248
+ if ( $do_action ) {
249
+ /**
250
+ * Perform a tab action.
251
+ *
252
+ * Perform a tab action.
253
+ *
254
+ * @since 5.0.0
255
+ *
256
+ * @param string $action Can be mpsum_admin_tab_main, mpsum_admin_tab_plugins, mpsum_admin_tab_themes, and mpsum_admin_tab_advanced.
257
+ */
258
+ do_action( $do_action );
259
+ }
260
+ }
261
+ ?>
262
+
263
+ </div><!-- .wrap -->
264
+ <?php
265
+ } //end output_admin_interface
266
+
267
+ /**
268
+ * Outputs admin interface for sub-menu.
269
+ *
270
+ * Outputs admin interface for sub-menu.
271
+ *
272
+ * @since 5.0.0
273
+ * @access public
274
+ * @see __construct
275
+ * @internal Uses $prefix . "plugin_action_links_$plugin_file" action
276
+ * @return array Array of settings
277
+ */
278
+ public function plugin_settings_link( $settings ) {
279
+ $admin_anchor = sprintf( '<a href="%s">%s</a>', esc_url( $this->get_url() ), esc_html__( 'Configure', 'stops-core-theme-and-plugin-updates' ) );
280
+ return array_merge( array( $admin_anchor ), $settings );
281
+ }
282
+ }
includes/MPSUM_Admin_Advanced.php ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controls the advanced tab
4
+ *
5
+ * Controls the advanced tab and handles the saving of its options.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ class MPSUM_Admin_Advanced {
12
+ /**
13
+ * Holds the slug to the admin panel page
14
+ *
15
+ * @since 5.0.0
16
+ * @access private
17
+ * @var string $slug
18
+ */
19
+ private $slug = '';
20
+
21
+ /**
22
+ * Holds the tab name
23
+ *
24
+ * @since 5.0.0
25
+ * @access static
26
+ * @var string $tab
27
+ */
28
+ private $tab = 'advanced';
29
+
30
+ /**
31
+ * Class constructor.
32
+ *
33
+ * Initialize the class
34
+ *
35
+ * @since 5.0.0
36
+ * @access public
37
+ *
38
+ * @param string $slug Slug to the admin panel page
39
+ */
40
+ public function __construct( $slug = '' ) {
41
+ $this->slug = $slug;
42
+ //Admin Tab Actions
43
+ add_action( 'mpsum_admin_tab_advanced', array( $this, 'tab_output' ) );
44
+ add_action( 'admin_init', array( $this, 'maybe_save_options' ) );
45
+ }
46
+
47
+ /**
48
+ * Determine whether the save the advanced options or not.
49
+ *
50
+ * Determine whether the save the advanced options or not.
51
+ *
52
+ * @since 5.0.0
53
+ * @access public
54
+ * @see __construct
55
+ * @internal Uses admin_init action
56
+ *
57
+ */
58
+ public function maybe_save_options() {
59
+ if ( !current_user_can( 'update_core' ) ) return;
60
+ if ( !isset( $_GET[ 'page' ] ) || $_GET[ 'page' ] != $this->slug ) return;
61
+ if ( !isset( $_POST[ 'action' ] ) ) return;
62
+ if ( !isset( $_POST[ '_mpsum' ] ) ) return;
63
+
64
+ //Get action
65
+ $action = $_POST[ 'action' ];
66
+ if ( empty( $action ) ) return;
67
+
68
+ switch( $action ) {
69
+ case 'mpsum_save_excluded_users':
70
+ check_admin_referer( 'mpsum_exclude_users', '_mpsum' );
71
+ $users = $_POST[ 'mpsum_excluded_users' ];
72
+ if ( !is_array( $users ) || empty( $users ) ) return;
73
+ $users_to_save = array();
74
+ foreach( $users as $index => $user_id ) {
75
+ $user_id = absint( $user_id );
76
+ if ( 0 === $user_id ) continue;
77
+ $users_to_save[] = $user_id;
78
+ }
79
+ MPSUM_Updates_Manager::update_options( $users_to_save, 'excluded_users' );
80
+ break;
81
+ case 'mpsum_reset_options':
82
+ check_admin_referer( 'mpsum_reset_options', '_mpsum' );
83
+ MPSUM_Updates_Manager::update_options( array() );
84
+ break;
85
+ default:
86
+ return;
87
+ }
88
+
89
+ //Redirect args
90
+ $query_args = array();
91
+ $query_args[ 'updated' ] = "1";
92
+ $query_args[ 'tab' ] = $this->tab;
93
+
94
+
95
+ //Redirect back to settings screen
96
+ wp_redirect( esc_url_raw( add_query_arg( $query_args, MPSUM_Admin::get_url() ) ) );
97
+ exit;
98
+ }
99
+
100
+ /**
101
+ * Output the HTML interface for the advanced tab.
102
+ *
103
+ * Output the HTML interface for the advanced tab.
104
+ *
105
+ * @since 5.0.0
106
+ * @access public
107
+ * @see __construct
108
+ * @internal Uses the mpsum_admin_tab_main action
109
+ */
110
+ public function tab_output() {
111
+
112
+ if ( isset( $_GET[ 'updated' ] ) ) {
113
+ $message = __( 'Options saved.', 'stops-core-theme-and-plugin-updates' );
114
+ ?>
115
+ <br />
116
+ <div class="updated"><p><strong><?php echo esc_html( $message ); ?></strong></p></div>
117
+ <?php
118
+ }
119
+
120
+ ?>
121
+ <form action="<?php echo esc_url( add_query_arg( array() ) ); ?>" method="post">
122
+ <h3><?php esc_html_e( 'Exclude Users', 'stops-core-theme-and-plugin-updates' ); ?></h3>
123
+ <p><?php esc_html_e( 'Select which users to be excluded from the settings of this plugin. Default WordPress behavior will be used.', 'stops-core-theme-and-plugin-updates' ); ?></p>
124
+ <p><?php esc_html_e( 'This option is useful if, for example, you would like to disable updates, but have a user account that can still update WordPress.', 'stops-core-theme-and-plugin-updates' ); ?></p>
125
+ <table class="form-table">
126
+ <tr>
127
+ <th scope="row"><?php esc_html_e( 'Users to be Excluded', 'stops-core-theme-and-plugin-updates' ); ?></th>
128
+ <td>
129
+ <?php
130
+ //Code from wp-admin/includes/class-wp-ms-users-list-table
131
+ $users = array();
132
+ if ( is_multisite() ) {
133
+ global $wpdb;
134
+ $logins = implode( "', '", get_super_admins() );
135
+ $users = $wpdb->get_col( "SELECT ID FROM $wpdb->users WHERE user_login IN ('$logins')" );
136
+
137
+ } else {
138
+ /**
139
+ * Determine which role gets queried for admin users.
140
+ *
141
+ * Determine which role gets queried for admin users.
142
+ *
143
+ * @since 5.0.0
144
+ *
145
+ * @param string $var administrator.
146
+ */
147
+ $role = apply_filters( 'mpsum_admin_role', 'administrator' );
148
+ $users = get_users( array( 'role' => $role, 'orderby' => 'display_name', 'order' => 'ASC', 'fields' => 'ID' ) );
149
+ }
150
+ if ( is_array( $users ) && !empty( $users ) ) {
151
+ echo '<input type="hidden" value="0" name="mpsum_excluded_users[]" />';
152
+ $excluded_users = MPSUM_Updates_Manager::get_options( 'excluded_users' );
153
+ foreach( $users as $index => $user_id ) {
154
+ $user = get_userdata( $user_id );
155
+ printf( '<input type="checkbox" name="mpsum_excluded_users[]" id="mpsum_user_%1$d" value="%1$d" %3$s />&nbsp;<label for="mpsum_user_%1$d">%2$s</label><br />', esc_attr( $user_id ), esc_html( $user->display_name ), checked( true, in_array( $user_id, $excluded_users ), false ) );
156
+ }
157
+ }
158
+ ?>
159
+ </td>
160
+ </tr>
161
+ </table>
162
+ <input type="hidden" name="action" value='mpsum_save_excluded_users' />
163
+ <?php
164
+ wp_nonce_field( 'mpsum_exclude_users', '_mpsum' );
165
+ echo '<p class="submit">';
166
+ submit_button( __( 'Save Users', 'stops-core-theme-and-plugin-updates' ) , 'primary', 'submit', false );
167
+ echo '</p>';
168
+ ?>
169
+ </form>
170
+ <form action="<?php echo esc_url( add_query_arg( array() ) ); ?>" method="post">
171
+ <h3><?php esc_html_e( 'Reset Options', 'stops-core-theme-and-plugin-updates' ); ?></h3>
172
+ <p><?php esc_html_e( 'This will reset all options to as if you have just installed the plugin.', 'stops-core-theme-and-plugin-updates' ); ?></p>
173
+ <input type="hidden" name="action" value='mpsum_reset_options' />
174
+ <?php
175
+ wp_nonce_field( 'mpsum_reset_options', '_mpsum' );
176
+ echo '<p class="submit">';
177
+ submit_button( __( 'Reset All Options', 'stops-core-theme-and-plugin-updates' ) , 'primary', 'submit', false );
178
+ echo '</p>';
179
+ ?>
180
+ </form>
181
+ <?php
182
+ } //end tab_output
183
+ }
includes/MPSUM_Admin_Core.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controls the main (general) tab
4
+ *
5
+ * Controls the main (general) tab and handles the saving of its options.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ class MPSUM_Admin_Core {
12
+ /**
13
+ * Holds the slug to the admin panel page
14
+ *
15
+ * @since 5.0.0
16
+ * @access private
17
+ * @var string $slug
18
+ */
19
+ private $slug = '';
20
+
21
+ /**
22
+ * Holds the tab name
23
+ *
24
+ * @since 5.0.0
25
+ * @access static
26
+ * @var string $tab
27
+ */
28
+ private $tab = 'main';
29
+
30
+ /**
31
+ * Class constructor.
32
+ *
33
+ * Initialize the class
34
+ *
35
+ * @since 5.0.0
36
+ * @access public
37
+ *
38
+ * @param string $slug Slug to the admin panel page
39
+ */
40
+ public function __construct( $slug = '' ) {
41
+ $this->slug = $slug;
42
+ //Admin Tab Actions
43
+ add_action( 'mpsum_admin_tab_main', array( $this, 'tab_output' ) );
44
+ add_action( 'admin_init', array( $this, 'maybe_save_options' ) );
45
+ }
46
+
47
+ /**
48
+ * Get tab defaults.
49
+ *
50
+ * Get default core plugin options.
51
+ *
52
+ * @since 5.0.0
53
+ * @access private
54
+ *
55
+ * @return array Associative array of default options
56
+ */
57
+ private function get_defaults() {
58
+ return array(
59
+ 'all_updates' => 'on',
60
+ 'core_updates' => 'on',
61
+ 'plugin_updates' => 'on',
62
+ 'theme_updates' => 'on',
63
+ 'translation_updates' => 'on',
64
+ 'automatic_development_updates' => 'off',
65
+ 'automatic_major_updates' => 'off',
66
+ 'automatic_minor_updates' => 'on',
67
+ 'automatic_plugin_updates' => 'off',
68
+ 'automatic_theme_updates' => 'off',
69
+ 'automatic_translation_updates' => 'on',
70
+ 'notification_core_update_emails' => 'on',
71
+ 'misc_browser_nag' => 'on',
72
+ 'misc_wp_footer' => 'on'
73
+ );
74
+ }
75
+
76
+ /**
77
+ * Determine whether the save the main options or not.
78
+ *
79
+ * Determine whether the save the main options or not.
80
+ *
81
+ * @since 5.0.0
82
+ * @access public
83
+ * @see __construct
84
+ * @internal Uses admin_init action
85
+ *
86
+ */
87
+ public function maybe_save_options() {
88
+ if ( !current_user_can( 'update_core' ) ) return;
89
+ if ( !isset( $_GET[ 'page' ] ) || $_GET[ 'page' ] != $this->slug ) return;
90
+ if ( !isset( $_REQUEST[ 'action' ] ) ) return;
91
+ if ( !isset( $_POST[ 'options' ] ) ) return;
92
+ if ( 'mpsum_save_core_options' !== $_REQUEST[ 'action' ] ) return;
93
+ check_admin_referer( 'mpsum_main_update', '_mpsum' );
94
+
95
+ $query_args = array();
96
+ $query_args[ 'updated' ] = "1";
97
+
98
+ //Save options
99
+ $options = $_POST[ 'options' ];
100
+ if ( isset( $_POST[ 'reset' ] ) ) {
101
+ $options = $this->get_defaults();
102
+ }
103
+ $options_to_save = array();
104
+ foreach( $options as $key => $value ) {
105
+ $option_value = sanitize_text_field( $value );
106
+ $options_to_save[ sanitize_key( $key ) ] = $option_value;
107
+ }
108
+ MPSUM_Updates_Manager::update_options( $options_to_save, 'core' );
109
+
110
+ //Redirect back to settings screen
111
+ wp_redirect( esc_url_raw( add_query_arg( $query_args, MPSUM_Admin::get_url() ) ) );
112
+ exit;
113
+ }
114
+
115
+ /**
116
+ * Output the HTML interface for the main tab.
117
+ *
118
+ * Output the HTML interface for the main tab.
119
+ *
120
+ * @since 5.0.0
121
+ * @access public
122
+ * @see __construct
123
+ * @internal Uses the mpsum_admin_tab_main action
124
+ */
125
+ public function tab_output() {
126
+ $options = MPSUM_Updates_Manager::get_options( 'core' );
127
+ $options = wp_parse_args( $options, $this->get_defaults() );
128
+
129
+ if ( isset( $_GET[ 'updated' ] ) ) {
130
+ $message = __( 'Options saved.', 'stops-core-theme-and-plugin-updates' );
131
+ ?>
132
+ <br />
133
+ <div class="updated"><p><strong><?php echo esc_html( $message ); ?></strong></p></div>
134
+ <?php
135
+ }
136
+
137
+ ?>
138
+ <form action="<?php echo esc_url( add_query_arg( array() ) ); ?>" method="post">
139
+ <h3><?php esc_html_e( 'Global Settings', 'stops-core-theme-and-plugin-updates' ); ?></h3>
140
+ <table class="form-table">
141
+ <tr>
142
+ <th scope="row"><?php esc_html_e( 'All Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
143
+ <td>
144
+ <input type="radio" name="options[all_updates]" value="on" id="all_updates_on" <?php checked( 'on', $options[ 'all_updates' ] ); ?> />&nbsp;<label for="all_updates_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
145
+ <input type="radio" name="options[all_updates]" value="off" id="all_updates_off" <?php checked( 'off', $options[ 'all_updates' ] ); ?> />&nbsp;<label for="all_updates_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
146
+ <p class="description"><?php esc_html_e( 'If this option is disabled, this will override all settings.', 'stops-core-theme-and-plugin-updates' ); ?></p>
147
+ </td>
148
+ </tr>
149
+ <tr>
150
+ <th scope="row"><?php esc_html_e( 'WordPress Core Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
151
+ <td>
152
+ <input type="radio" name="options[core_updates]" value="on" id="core_updates_on" <?php checked( 'on', $options[ 'core_updates' ] ); ?> />&nbsp;<label for="core_updates_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
153
+ <input type="radio" name="options[core_updates]" value="off" id="core_updates_off" <?php checked( 'off', $options[ 'core_updates' ] ); ?> />&nbsp;<label for="core_updates_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
154
+ <p class="description"><?php esc_html_e( 'Prevents WordPress from showing it needs to be updated.', 'stops-core-theme-and-plugin-updates' ); ?></p>
155
+ </td>
156
+ </tr>
157
+ <tr>
158
+ <th scope="row"><?php esc_html_e( 'All Plugin Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
159
+ <td>
160
+ <input type="radio" name="options[plugin_updates]" value="on" id="plugin_updates_on" <?php checked( 'on', $options[ 'plugin_updates' ] ); ?> />&nbsp;<label for="plugin_updates_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
161
+ <input type="radio" name="options[plugin_updates]" value="off" id="plugin_updates_off" <?php checked( 'off', $options[ 'plugin_updates' ] ); ?> />&nbsp;<label for="plugin_updates_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
162
+ </td>
163
+ </tr>
164
+ <tr>
165
+ <th scope="row"><?php esc_html_e( 'All Theme Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
166
+ <td>
167
+ <input type="radio" name="options[theme_updates]" value="on" id="theme_updates_on" <?php checked( 'on', $options[ 'theme_updates' ] ); ?> />&nbsp;<label for="theme_updates_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
168
+ <input type="radio" name="options[theme_updates]" value="off" id="theme_updates_off" <?php checked( 'off', $options[ 'theme_updates' ] ); ?> />&nbsp;<label for="theme_updates_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
169
+ </td>
170
+ </tr>
171
+ <tr>
172
+ <th scope="row"><?php esc_html_e( 'All Translation Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
173
+ <td>
174
+ <input type="radio" name="options[translation_updates]" value="on" id="translation_updates_on" <?php checked( 'on', $options[ 'translation_updates' ] ); ?> />&nbsp;<label for="translation_updates_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
175
+ <input type="radio" name="options[translation_updates]" value="off" id="translation_updates_off" <?php checked( 'off', $options[ 'translation_updates' ] ); ?> />&nbsp;<label for="translation_updates_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
176
+ </td>
177
+ </tr>
178
+ </table>
179
+ <h3><?php esc_html_e( 'Automatic Updates', 'stops-core-theme-and-plugin-updates' ); ?></h3>
180
+ <p><?php esc_html_e( 'These options will enable or disable automatic updates (background updates) of certain parts of WordPress.', 'stops-core-theme-and-plugin-updates' ); ?></p>
181
+ <table class="form-table">
182
+ <tr>
183
+ <th scope="row"><?php esc_html_e( 'Major Releases', 'stops-core-theme-and-plugin-updates' ); ?></th>
184
+ <td>
185
+ <input type="radio" name="options[automatic_major_updates]" value="on" id="automatic_major_on" <?php checked( 'on', $options[ 'automatic_major_updates' ] ); ?> />&nbsp;<label for="automatic_major_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
186
+ <input type="radio" name="options[automatic_major_updates]" value="off" id="automatic_major_off" <?php checked( 'off', $options[ 'automatic_major_updates' ] ); ?> />&nbsp;<label for="automatic_major_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
187
+ <p class="description"><?php esc_html_e( 'Automatically update to major releases (e.g., 4.1, 4.2, 4.3).', 'stops-core-theme-and-plugin-updates' ); ?></p>
188
+ </td>
189
+ </tr>
190
+ <tr>
191
+ <th scope="row"><?php esc_html_e( 'Minor Releases', 'stops-core-theme-and-plugin-updates' ); ?></th>
192
+ <td>
193
+ <input type="radio" name="options[automatic_minor_updates]" value="on" id="automatic_minor_on" <?php checked( 'on', $options[ 'automatic_minor_updates' ] ); ?> />&nbsp;<label for="automatic_minor_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
194
+ <input type="radio" name="options[automatic_minor_updates]" value="off" id="automatic_minor_off" <?php checked( 'off', $options[ 'automatic_minor_updates' ] ); ?> />&nbsp;<label for="automatic_minor_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
195
+ <p class="description"><?php esc_html_e( 'Automatically update to minor releases (e.g., 4.1.1, 4.1.2, 4.1.3).', 'stops-core-theme-and-plugin-updates' ); ?></p>
196
+ </td>
197
+ </tr>
198
+ <tr>
199
+ <th scope="row"><?php esc_html_e( 'Development Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
200
+ <td>
201
+ <input type="radio" name="options[automatic_development_updates]" value="on" id="automatic_dev_on" <?php checked( 'on', $options[ 'automatic_development_updates' ] ); ?> />&nbsp;<label for="automatic_dev_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
202
+ <input type="radio" name="options[automatic_development_updates]" value="off" id="automatic_dev_off" <?php checked( 'off', $options[ 'automatic_development_updates' ] ); ?> />&nbsp;<label for="automatic_dev_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
203
+ <p class="description"><?php esc_html_e( 'Update automatically to Bleeding Edge releases.', 'stops-core-theme-and-plugin-updates' ); ?></p>
204
+ </td>
205
+ </tr>
206
+ <tr>
207
+ <th scope="row"><?php esc_html_e( 'Automatic Plugin Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
208
+ <td>
209
+ <input type="radio" name="options[automatic_plugin_updates]" value="on" id="automatic_plugin_on" <?php checked( 'on', $options[ 'automatic_plugin_updates' ] ); ?> />&nbsp;<label for="automatic_plugin_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
210
+ <input type="radio" name="options[automatic_plugin_updates]" value="off" id="automatic_plugin_off" <?php checked( 'off', $options[ 'automatic_plugin_updates' ] ); ?> />&nbsp;<label for="automatic_plugin_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
211
+ <input type="radio" name="options[automatic_plugin_updates]" value="individual" id="automatic_plugin_individual" <?php checked( 'individual', $options[ 'automatic_plugin_updates' ] ); ?> />&nbsp;<label for="automatic_plugin_individual"><?php esc_html_e( 'Select Individually', 'stops-core-theme-and-plugin-updates' ); ?></label>
212
+ <p class="description"><?php esc_html_e( 'Automatically update your plugins. Select always on, always off, or select plugins individually.', 'stops-core-theme-and-plugin-updates' ); ?></p>
213
+ </td>
214
+ </tr>
215
+ <tr>
216
+ <th scope="row"><?php esc_html_e( 'Automatic Theme Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
217
+ <td>
218
+ <input type="radio" name="options[automatic_theme_updates]" value="on" id="automatic_theme_on" <?php checked( 'on', $options[ 'automatic_theme_updates' ] ); ?> />&nbsp;<label for="automatic_theme_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
219
+ <input type="radio" name="options[automatic_theme_updates]" value="off" id="automatic_theme_off" <?php checked( 'off', $options[ 'automatic_theme_updates' ] ); ?> />&nbsp;<label for="automatic_theme_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
220
+ <input type="radio" name="options[automatic_theme_updates]" value="individual" id="automatic_theme_individual" <?php checked( 'individual', $options[ 'automatic_theme_updates' ] ); ?> />&nbsp;<label for="automatic_theme_individual"><?php esc_html_e( 'Select Individually', 'stops-core-theme-and-plugin-updates' ); ?></label>
221
+ <p class="description"><?php esc_html_e( 'Automatically update your themes. Select always on, always off, or select themes individually.', 'stops-core-theme-and-plugin-updates' ); ?></p>
222
+ </td>
223
+ </tr>
224
+ <tr>
225
+ <th scope="row"><?php esc_html_e( 'Translation Updates', 'stops-core-theme-and-plugin-updates' ); ?></th>
226
+ <td>
227
+ <input type="radio" name="options[automatic_translation_updates]" value="on" id="automatic_translation_on" <?php checked( 'on', $options[ 'automatic_translation_updates' ] ); ?> />&nbsp;<label for="automatic_translation_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
228
+ <input type="radio" name="options[automatic_translation_updates]" value="off" id="automatic_translation_off" <?php checked( 'off', $options[ 'automatic_translation_updates' ] ); ?> />&nbsp;<label for="automatic_translation_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
229
+ <p class="description"><?php esc_html_e( 'Automatically update your translations.', 'stops-core-theme-and-plugin-updates' ); ?></p>
230
+ </td>
231
+ </tr>
232
+ </table>
233
+ <h3><?php esc_html_e( 'Notifications', 'stops-core-theme-and-plugin-updates' ); ?></h3>
234
+ <table class="form-table">
235
+ <tr>
236
+ <th scope="row"><?php esc_html_e( 'Core Update E-mails', 'stops-core-theme-and-plugin-updates' ); ?></th>
237
+ <td>
238
+ <input type="radio" name="options[notification_core_update_emails]" value="on" id="notification_core_update_emails_on" <?php checked( 'on', $options[ 'notification_core_update_emails' ] ); ?> />&nbsp;<label for="notification_core_update_emails_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
239
+ <input type="radio" name="options[notification_core_update_emails]" value="off" id="notification_core_update_emails_off" <?php checked( 'off', $options[ 'notification_core_update_emails' ] ); ?> />&nbsp;<label for="notification_core_update_emails_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
240
+ <p class="description"><?php esc_html_e( 'Disable e-mails that are sent when your site has been upgraded automatically.', 'stops-core-theme-and-plugin-updates' ); ?></p>
241
+ </td>
242
+ </tr>
243
+ </table>
244
+ <h3><?php esc_html_e( 'Miscellaneous', 'stops-core-theme-and-plugin-updates' ); ?></h3>
245
+ <table class="form-table">
246
+ <tr>
247
+ <th scope="row"><?php esc_html_e( 'Browser Nag', 'stops-core-theme-and-plugin-updates' ); ?></th>
248
+ <td>
249
+ <input type="radio" name="options[misc_browser_nag]" value="on" id="misc_browser_nag_on" <?php checked( 'on', $options[ 'misc_browser_nag' ] ); ?> />&nbsp;<label for="misc_browser_nag_on"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
250
+ <input type="radio" name="options[misc_browser_nag]" value="off" id="misc_browser_nag_off" <?php checked( 'off', $options[ 'misc_browser_nag' ] ); ?> />&nbsp;<label for="misc_browser_nag_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
251
+ <p class="description"><?php esc_html_e( 'Removes the browser nag for people using older browsers.', 'stops-core-theme-and-plugin-updates' ); ?></p>
252
+ </td>
253
+ </tr>
254
+ <tr>
255
+ <th scope="row"><?php esc_html_e( 'WordPress Version in Footer', 'stops-core-theme-and-plugin-updates' ); ?></th>
256
+ <td>
257
+ <input type="radio" name="options[misc_wp_footer]" value="on" id="misc_wp_footer_on" <?php checked( 'on', $options[ 'misc_wp_footer' ] ); ?> />&nbsp;<label for="misc_wp_footer_off"><?php esc_html_e( 'Enabled', 'stops-core-theme-and-plugin-updates' ); ?></label><br />
258
+ <input type="radio" name="options[misc_wp_footer]" value="off" id="misc_wp_footer_off" <?php checked( 'off', $options[ 'misc_wp_footer' ] ); ?> />&nbsp;<label for="misc_wp_footer_off"><?php esc_html_e( 'Disabled', 'stops-core-theme-and-plugin-updates' ); ?></label>
259
+ <p class="description"><?php esc_html_e( 'Removes the WordPress version in the footer.', 'stops-core-theme-and-plugin-updates' ); ?></p>
260
+ </td>
261
+ </tr>
262
+ </table>
263
+ <input type="hidden" name="action" value='mpsum_save_core_options' />
264
+ <?php
265
+ wp_nonce_field( 'mpsum_main_update', '_mpsum' );
266
+ echo '<p class="submit">';
267
+ submit_button( __( 'Save Changes', 'stops-core-theme-and-plugin-updates' ) , 'primary', 'submit', false );
268
+ echo '&nbsp;&nbsp;';
269
+ submit_button( __( 'Reset to Defaults', 'stops-core-theme-and-plugin-updates' ) , 'secondary', 'reset', false );
270
+ echo '</p>';
271
+ ?>
272
+ </form>
273
+ <?php
274
+ } //end tab_output_plugins
275
+ }
includes/MPSUM_Admin_Help.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Help Screen for Easy Updates Manager
4
+ *
5
+ * Initializes and outputs the help screen for the plugin.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ class MPSUM_Admin_Help {
12
+
13
+ /**
14
+ * Class constructor.
15
+ *
16
+ * Initialize the class
17
+ *
18
+ * @since 5.0.0
19
+ * @access public
20
+ *
21
+ */
22
+ public function __construct() {
23
+ $screen = get_current_screen();
24
+
25
+ $screen = get_current_screen();
26
+ $content1 = '<p>';
27
+ $content1 .= esc_html__( 'This is the Easy Updates Manager settings help tab. In here you will find helpful information on what Easy Updates Manager does and how to use it.', 'stops-core-theme-and-plugin-updates' );
28
+ $content1 .= '</p>';
29
+ $content1 .= sprintf( '<div><p><strong>%s - </strong>%s</p></div>', esc_html__( 'Please Note!', 'stops-core-theme-and-plugin-updates' ), esc_html__( 'If either your WordPress core, theme, or plugins get too out of date, you may run into compatibility problems. Check the capability tab for more information.', 'stops-core-theme-and-plugin-updates' ) );
30
+
31
+ $content2 = sprintf( '<div><p><a href="https://github.com/easy-updates-manager/easy-updates-manager/wiki">%s</a></p></div>', esc_html__( 'Please see our Wiki for documentation and videos.', 'stops-core-theme-and-plugin-updates' ) );
32
+
33
+ $content3_strings = array(
34
+ 'website' => esc_html__( 'Our Website', 'stops-core-theme-and-plugin-updates' ),
35
+ 'support' => esc_html__( 'Support on WordPress', 'stops-core-theme-and-plugin-updates' ),
36
+ 'github' => esc_html__( 'GitHub Repository', 'stops-core-theme-and-plugin-updates' ),
37
+ 'official' => esc_html__( 'Official Documentation', 'stops-core-theme-and-plugin-updates' ),
38
+ );
39
+ $content3 = <<<CONTENT3
40
+ <p>
41
+ <a href="http://mpswp.wordpress.com" class="button">{$content3_strings['website']}</a>
42
+ <a href="http://wordpress.org/support/plugin/stops-core-theme-and-plugin-updates" class="button">{$content3_strings['support']}</a>
43
+ <a href="https://github.com/easy-updates-manager/easy-updates-manager" class="button">{$content3_strings['github']}</a>
44
+ <a href="https://github.com/easy-updates-manager/easy-updates-manager/wiki" class="button">{$content3_strings['official']}</a>
45
+ </p>
46
+
47
+ CONTENT3;
48
+
49
+ $content4_strings = array(
50
+ 'intro' => esc_html__( 'You will see four tabs where you can configure the update options.', 'stops-core-theme-and-plugin-updates' ),
51
+ 'general' => sprintf( '<strong>%s</strong> - %s', esc_html__( 'General', 'stops-core-theme-and-plugin-updates' ), esc_html__( 'Use this screen to finely tune which updates and automatic updates you would like to see.', 'stops-core-theme-and-plugin-updates' ) ),
52
+ 'plugins' => sprintf( '<strong>%s</strong> - %s', esc_html__( 'Plugins', 'stops-core-theme-and-plugin-updates' ), esc_html__( 'If plugin updates are enabled and/or automatic updates for plugins are enabled, you can configure which plugins will receive updates and/or automatic updates.', 'stops-core-theme-and-plugin-updates' ) ),
53
+ 'themes' => sprintf( '<strong>%s</strong> - %s', esc_html__( 'Themes', 'stops-core-theme-and-plugin-updates' ), esc_html__( 'If theme updates are enabled and/or automatic updates for themes are enabled, you can configure which themes will receive updates and/or automatic updates.', 'stops-core-theme-and-plugin-updates' ) ),
54
+ 'advanced' => sprintf( '<strong>%s</strong> - %s', esc_html__( 'Advanced', 'stops-core-theme-and-plugin-updates' ), esc_html__( 'Reset all options or allow certain users to see all updates regardless of what settings you have set.', 'stops-core-theme-and-plugin-updates' ) ),
55
+
56
+ );
57
+ $content4 = <<<CONTENT4
58
+ <p>
59
+ {$content4_strings['intro']}
60
+ <br>
61
+ <br>
62
+ {$content4_strings['general']}
63
+ <br>
64
+ <br>
65
+ {$content4_strings['plugins']}
66
+ <br>
67
+ <br>
68
+ {$content4_strings['themes']}
69
+ <br>
70
+ <br>
71
+ {$content4_strings['advanced']}
72
+ <br>
73
+ <br>
74
+ </p>
75
+
76
+ CONTENT4;
77
+
78
+ $content5_strings = array(
79
+ 'contributors' => esc_html__( 'Contributors:', 'stops-core-theme-and-plugin-updates' )
80
+ );
81
+ $content5 = <<<CONTENT5
82
+
83
+ <p style="align: center;">
84
+ <h3>{$content5_strings[ 'contributors' ]}</h3>
85
+ <ul>
86
+ <li><a href="http://profiles.wordpress.org/kidsguide/">Matthew</a></li>
87
+ <li><a href="http://profiles.wordpress.org/ronalfy/">Ronalfy</a></li>
88
+ </ul>
89
+ </p>
90
+
91
+ CONTENT5;
92
+
93
+ $content6 = '<p>';
94
+ $content6 .= esc_html__( 'WordPress encourages you to update your plugins, themes, and core to make sure that there are no bugs. Even though you most likely want to disable all the updates and never think about updating again, you should still consider updating every once in a while to avoid major bugs and errors on your WordPress website.', 'stops-core-theme-and-plugin-updates' );
95
+ $content6 .= sprintf( '<h3>%s</h3>', esc_html__( 'This plugin is tested so there are no known major issues.', 'stops-core-theme-and-plugin-updates' ) );
96
+ $content6 .= '<ul>';
97
+ $content6 .= sprintf( '<li>%s</li>', esc_html__( 'Tested with WordPress 4.1.1.', 'stops-core-theme-and-plugin-updates' ) );
98
+ $content6 .= sprintf( '<li>%s</li>', esc_html__( 'Tested with popular plugins to ensure that there are no conflicts.', 'stops-core-theme-and-plugin-updates' ) );
99
+ $content6 .= sprintf( '<li>%s</li>', esc_html__( 'Tested with popular themes to ensure that there are no conflicts.', 'stops-core-theme-and-plugin-updates' ) );
100
+ $content6 .= '</ul>';
101
+ $content6 .= '</p>';
102
+
103
+ $screen->add_help_tab(array(
104
+ 'id' => 'help_tab_content_1',
105
+ 'title' => __( 'Overview', 'stops-core-theme-and-plugin-updates' ),
106
+ 'content' => $content1,
107
+ ));
108
+
109
+ $screen->add_help_tab(array(
110
+ 'id' => 'help_tab_content_4',
111
+ 'title' => __( 'Tabs', 'stops-core-theme-and-plugin-updates' ),
112
+ 'content' => $content4,
113
+ ));
114
+
115
+ $screen->add_help_tab(array(
116
+ 'id' => 'help_tab_content_2',
117
+ 'title' => __( 'Documentation', 'stops-core-theme-and-plugin-updates' ),
118
+ 'content' => $content2,
119
+ ));
120
+
121
+ $screen->add_help_tab(array(
122
+ 'id' => 'help_tab_content_6',
123
+ 'title' => __( 'Capability', 'stops-core-theme-and-plugin-updates' ),
124
+ 'content' => $content6,
125
+ ));
126
+
127
+ $screen->add_help_tab(array(
128
+ 'id' => 'help_tab_content_3',
129
+ 'title' => __( 'Troubleshooting', 'stops-core-theme-and-plugin-updates' ),
130
+ 'content' => $content3,
131
+ ));
132
+
133
+ $screen->set_help_sidebar($content5);
134
+
135
+ } //end constructor
136
+
137
+ }
includes/MPSUM_Admin_Plugins.php ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controls the plugins tab
4
+ *
5
+ * Controls the plugins tab and handles the saving of its options.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ class MPSUM_Admin_Plugins {
12
+ /**
13
+ * Holds the slug to the admin panel page
14
+ *
15
+ * @since 5.0.0
16
+ * @access private
17
+ * @var string $slug
18
+ */
19
+ private $slug = '';
20
+
21
+ /**
22
+ * Holds the tab name
23
+ *
24
+ * @since 5.0.0
25
+ * @access static
26
+ * @var string $tab
27
+ */
28
+ private $tab = 'plugins';
29
+
30
+ /**
31
+ * Class constructor.
32
+ *
33
+ * Initialize the class
34
+ *
35
+ * @since 5.0.0
36
+ * @access public
37
+ *
38
+ * @param string $slug Slug to the admin panel page
39
+ */
40
+ public function __construct( $slug = '' ) {
41
+ $this->slug = $slug;
42
+ //Admin Tab Actions
43
+ add_action( 'mpsum_admin_tab_plugins', array( $this, 'tab_output_plugins' ) );
44
+ add_filter( 'mpsum_plugin_action_links', array( $this, 'plugin_action_links' ), 11, 2 );
45
+ add_action( 'admin_init', array( $this, 'maybe_save_plugin_options' ) );
46
+ }
47
+
48
+ /**
49
+ * Determine whether the plugins can be updated or not.
50
+ *
51
+ * Determine whether the plugins can be updated or not.
52
+ *
53
+ * @since 5.0.0
54
+ * @access private
55
+ *
56
+ * @return bool True if the plugins can be updated, false if not.
57
+ */
58
+ private function can_update() {
59
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
60
+ if ( isset( $core_options[ 'all_updates' ] ) && 'off' == $core_options[ 'all_updates' ] ) {
61
+ return false;
62
+ }
63
+ if ( isset( $core_options[ 'plugin_updates' ] ) && 'off' == $core_options[ 'plugin_updates' ] ) {
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+
69
+ /**
70
+ * Determine whether the save the plugin options or not.
71
+ *
72
+ * Determine whether the save the plugin options or not.
73
+ *
74
+ * @since 5.0.0
75
+ * @access public
76
+ * @see __construct
77
+ * @internal Uses admin_init action
78
+ *
79
+ */
80
+ public function maybe_save_plugin_options() {
81
+ if ( !current_user_can( 'update_plugins' ) ) return;
82
+ if ( !isset( $_GET[ 'page' ] ) || $_GET[ 'page' ] != $this->slug ) return;
83
+ if ( !isset( $_GET[ 'tab' ] ) || $_GET[ 'tab' ] != $this->tab ) return;
84
+ if ( !isset( $_REQUEST[ 'action' ] ) ) return;
85
+
86
+ $action = $_REQUEST[ 'action' ];
87
+ $plugin_disabled = false;
88
+ if ( 'disallow-update-selected' == $action || 'disallow-automatic-selected' == $action ) {
89
+ $plugin_disabled = true;
90
+ }
91
+
92
+ //Build Query Args
93
+ $paged = isset( $_GET[ 'paged' ] ) ? absint( $_GET[ 'paged' ] ) : false;
94
+ $query_args = array();
95
+ $query_args[ 'page' ] = $this->slug;
96
+ if ( false !== $paged ) {
97
+ $query_args[ 'paged' ] = $paged;
98
+ }
99
+ if ( false == $plugin_disabled ) {
100
+ $query_args[ 'disabled' ] = 0;
101
+ } else {
102
+ $query_args[ 'disabled' ] = 1;
103
+ }
104
+ $query_args[ 'tab' ] = $this->tab;
105
+ $plugin_status = isset( $_REQUEST[ 'plugin_status' ] ) ? $_REQUEST[ 'plugin_status' ] : false;
106
+ if ( false !== $plugin_status ) {
107
+ $query_args[ 'plugin_status' ] = $plugin_status;
108
+ }
109
+
110
+ //Save theme options
111
+ $this->save_plugin_update_options( $action );
112
+
113
+ //Redirect back to settings screen
114
+ wp_redirect( esc_url_raw( add_query_arg( $query_args, MPSUM_Admin::get_url() ) ) );
115
+ exit;
116
+ }
117
+
118
+ /**
119
+ * Outputs the plugin action links beneath each plugin row.
120
+ *
121
+ * Outputs the plugin action links beneath each plugin row.
122
+ *
123
+ * @since 5.0.0
124
+ * @access public
125
+ * @see __construct
126
+ * @internal uses mpsum_plugin_action_links filter
127
+ *
128
+ * @param array $settings Array of settings to output.
129
+ * @param string $plugin The relative plugin path.
130
+ */
131
+ public function plugin_action_links( $settings, $plugin ) {
132
+ $plugin_options = MPSUM_Updates_Manager::get_options( 'plugins' );
133
+ if ( false !== $key = array_search( $plugin, $plugin_options ) ) {
134
+ $enable_url = add_query_arg( array( 'action' => 'allow-update-selected', '_mpsum' => wp_create_nonce( 'mpsum_plugin_update' ), 'checked' => array( $plugin ) ) );
135
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $enable_url ), esc_html__( 'Allow Updates', 'stops-core-theme-and-plugin-updates' ) );
136
+ } else {
137
+ //Disable Link
138
+ $disable_url = add_query_arg( array( 'action' => 'disallow-update-selected', '_mpsum' => wp_create_nonce( 'mpsum_plugin_update' ), 'checked' => array( $plugin ) ) );
139
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $disable_url ), esc_html__( 'Disallow Updates', 'stops-core-theme-and-plugin-updates' ) );
140
+
141
+ //Automatic Link
142
+ $plugin_automatic_options = MPSUM_Updates_Manager::get_options( 'plugins_automatic' );
143
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
144
+ if ( isset( $core_options[ 'automatic_plugin_updates' ] ) && 'individual' == $core_options[ 'automatic_plugin_updates' ] ) {
145
+ if ( in_array( $plugin, $plugin_automatic_options ) ) {
146
+ //Disable Link
147
+ $disable_automatic_url = add_query_arg( array( 'action' => 'disallow-automatic-selected', '_mpsum' => wp_create_nonce( 'mpsum_plugin_update' ), 'checked' => array( $plugin ) ) );
148
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $disable_automatic_url ), esc_html__( 'Disallow Automatic Updates', 'stops-core-theme-and-plugin-updates' ) );
149
+ } else {
150
+ //Enable Link
151
+ $enable_automatic_url = add_query_arg( array( 'action' => 'allow-automatic-selected', '_mpsum' => wp_create_nonce( 'mpsum_plugin_update' ), 'checked' => array( $plugin ) ) );
152
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $enable_automatic_url ), esc_html__( 'Enable Automatic Updates', 'stops-core-theme-and-plugin-updates' ) );
153
+ }
154
+ }
155
+ }
156
+ return $settings;
157
+ }
158
+
159
+ /**
160
+ * Save the plugin options based on the passed action.
161
+ *
162
+ * Save the plugin options based on the passed action.
163
+ *
164
+ * @since 5.0.0
165
+ * @access private
166
+ * @see maybe_save_plugin_options
167
+ * @param string $action Action to take action on
168
+ *
169
+ */
170
+ private function save_plugin_update_options( $action ) {
171
+ //Check capability
172
+ $capability = 'update_plugins'; //On single site, admins can use this, on multisite, only network admins can
173
+ if ( !current_user_can( $capability ) ) return;
174
+
175
+ $plugins = isset( $_REQUEST[ 'checked' ] ) ? (array) $_REQUEST[ 'checked' ] : array();
176
+ $plugin_options = MPSUM_Updates_Manager::get_options( 'plugins' );
177
+ $plugin_automatic_options = MPSUM_Updates_Manager::get_options( 'plugins_automatic' );
178
+ switch( $action ) {
179
+ case 'disallow-update-selected':
180
+ foreach( $plugins as $plugin ) {
181
+ $plugin_options[] = $plugin;
182
+ if ( ( $key = array_search( $plugin, $plugin_automatic_options ) ) !== false ) {
183
+ unset( $plugin_automatic_options[ $key ] );
184
+ }
185
+ }
186
+
187
+ break;
188
+ case 'allow-update-selected':
189
+ foreach( $plugins as $plugin ) {
190
+ if ( ( $key = array_search( $plugin, $plugin_options ) ) !== false ) {
191
+ unset( $plugin_options[ $key ] );
192
+ }
193
+ }
194
+ break;
195
+ case 'allow-automatic-selected':
196
+ foreach( $plugins as $plugin ) {
197
+ $plugin_automatic_options[] = $plugin;
198
+ if ( ( $key = array_search( $plugin, $plugin_options ) ) !== false ) {
199
+ unset( $plugin_options[ $key ] );
200
+ }
201
+ }
202
+ break;
203
+ case 'disallow-automatic-selected':
204
+ foreach( $plugins as $plugin ) {
205
+ if ( ( $key = array_search( $plugin, $plugin_automatic_options ) ) !== false ) {
206
+ unset( $plugin_automatic_options[ $key ] );
207
+ }
208
+ }
209
+ break;
210
+ default:
211
+ return;
212
+ }
213
+ //Check nonce
214
+ check_admin_referer( 'mpsum_plugin_update', '_mpsum' );
215
+
216
+ //Update option
217
+ $plugin_options = array_values( array_unique( $plugin_options ) );
218
+ $plugin_automatic_options = array_values( array_unique( $plugin_automatic_options ) );
219
+ $options = MPSUM_Updates_Manager::get_options();
220
+ $options[ 'plugins' ] = $plugin_options;
221
+ $options[ 'plugins_automatic' ] = $plugin_automatic_options;
222
+ MPSUM_Updates_Manager::update_options( $options );
223
+ }
224
+
225
+ /**
226
+ * Output the HTML interface for the plugins tab.
227
+ *
228
+ * Output the HTML interface for the plugins tab.
229
+ *
230
+ * @since 5.0.0
231
+ * @access public
232
+ * @see __construct
233
+ * @internal Uses the mpsum_admin_tab_plugins action
234
+ */
235
+ public function tab_output_plugins() {
236
+ if ( isset( $_GET[ 'disabled' ] ) ) {
237
+ $message = __( 'The selected plugin updates have been enabled.', 'stops-core-theme-and-plugin-updates' );
238
+ if ( $_GET[ 'disabled' ] == 1 ) {
239
+ $message = __( 'The selected plugin updates have been disabled.', 'stops-core-theme-and-plugin-updates' );
240
+ }
241
+ ?>
242
+ <div class="updated"><p><strong><?php echo esc_html( $message ); ?></strong></p></div>
243
+ <?php
244
+ }
245
+
246
+ ?>
247
+ <form action="<?php echo esc_url( add_query_arg( array() ) ); ?>" method="post">
248
+ <?php
249
+ $plugin_status = isset( $_GET[ 'plugin_status' ] ) ? $_GET[ 'plugin_status' ] : false;
250
+ if ( false !== $plugin_status ) {
251
+ printf( '<input type="hidden" name="plugin_status" value="%s" />', esc_attr( $plugin_status ) );
252
+ }
253
+ wp_nonce_field( 'mpsum_plugin_update', '_mpsum' );
254
+ ?>
255
+ <h3><?php esc_html_e( 'Plugin Update Options', 'stops-core-theme-and-plugin-updates' ); ?></h3>
256
+ <?php
257
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
258
+ if ( false === $this->can_update() ) {
259
+ printf( '<div class="error"><p><strong>%s</strong></p></div>', esc_html__( 'All plugin updates have been disabled.', 'stops-core-theme-and-plugin-updates' ) );
260
+ }
261
+ $plugin_table = new MPSUM_Plugins_List_Table( $args = array( 'screen' => $this->slug, 'tab' => $this->tab ) );
262
+ $plugin_table->prepare_items();
263
+ $plugin_table->views();
264
+ $plugin_table->display();
265
+ ?>
266
+ </form>
267
+ <?php
268
+ } //end tab_output_plugins
269
+ }
includes/MPSUM_Admin_Themes.php ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controls the themes tab
4
+ *
5
+ * Controls the themes tab and handles the saving of its options.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ class MPSUM_Admin_Themes {
12
+
13
+ /**
14
+ * Holds the slug to the admin panel page
15
+ *
16
+ * @since 5.0.0
17
+ * @access private
18
+ * @var string $slug
19
+ */
20
+ private $slug = '';
21
+
22
+ /**
23
+ * Holds the tab name
24
+ *
25
+ * @since 5.0.0
26
+ * @access static
27
+ * @var string $tab
28
+ */
29
+ private $tab = 'themes';
30
+
31
+ /**
32
+ * Class constructor.
33
+ *
34
+ * Initialize the class
35
+ *
36
+ * @since 5.0.0
37
+ * @access public
38
+ *
39
+ * @param string $slug Slug to the admin panel page
40
+ */
41
+ public function __construct( $slug = '' ) {
42
+ $this->slug = $slug;
43
+ //Admin Tab Actions
44
+ add_action( 'mpsum_admin_tab_themes', array( $this, 'tab_output_themes' ) );
45
+ add_filter( 'mpsum_theme_action_links', array( $this, 'theme_action_links' ), 11, 2 );
46
+ add_action( 'admin_init', array( $this, 'maybe_save_theme_options' ) );
47
+ }
48
+
49
+ /**
50
+ * Determine whether the themes can be updated or not.
51
+ *
52
+ * Determine whether the themes can be updated or not.
53
+ *
54
+ * @since 5.0.0
55
+ * @access private
56
+ *
57
+ * @return bool True if the themes can be updated, false if not.
58
+ */
59
+ private function can_update() {
60
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
61
+ if ( isset( $core_options[ 'all_updates' ] ) && 'off' == $core_options[ 'all_updates' ] ) {
62
+ return false;
63
+ }
64
+ if ( isset( $core_options[ 'theme_updates' ] ) && 'off' == $core_options[ 'theme_updates' ] ) {
65
+ return false;
66
+ }
67
+ return true;
68
+ }
69
+
70
+ /**
71
+ * Determine whether the save the theme options or not.
72
+ *
73
+ * Determine whether the save the theme options or not.
74
+ *
75
+ * @since 5.0.0
76
+ * @access public
77
+ * @see __construct
78
+ * @internal Uses admin_init action
79
+ *
80
+ */
81
+ public function maybe_save_theme_options() {
82
+ if ( !current_user_can( 'update_themes' ) ) return;
83
+ if ( !isset( $_GET[ 'page' ] ) || $_GET[ 'page' ] != $this->slug ) return;
84
+ if ( !isset( $_GET[ 'tab' ] ) || $_GET[ 'tab' ] != $this->tab ) return;
85
+ if ( !isset( $_REQUEST[ 'action' ] ) ) return;
86
+
87
+ $action = $_REQUEST[ 'action' ];
88
+ $theme_disabled = false;
89
+ if ( 'disallow-update-selected' == $action || 'disallow-automatic-selected' == $action ) {
90
+ $theme_disabled = true;
91
+ }
92
+
93
+ //Build Query Args
94
+ $paged = isset( $_GET[ 'paged' ] ) ? absint( $_GET[ 'paged' ] ) : false;
95
+ $query_args = array();
96
+ $query_args[ 'page' ] = $this->slug;
97
+ if ( false !== $paged ) {
98
+ $query_args[ 'paged' ] = $paged;
99
+ }
100
+ if ( false == $theme_disabled ) {
101
+ $query_args[ 'disabled' ] = 0;
102
+ } else {
103
+ $query_args[ 'disabled' ] = 1;
104
+ }
105
+ $query_args[ 'tab' ] = $this->tab;
106
+ $theme_status = isset( $_REQUEST[ 'theme_status' ] ) ? $_REQUEST[ 'theme_status' ] : false;
107
+ if ( false !== $theme_status ) {
108
+ $query_args[ 'theme_status' ] = $theme_status;
109
+ }
110
+
111
+ //Save theme options
112
+ $this->save_theme_update_options( $action );
113
+
114
+ //Redirect back to settings screen
115
+ wp_redirect( esc_url_raw( add_query_arg( $query_args, MPSUM_Admin::get_url() ) ) );
116
+ exit;
117
+ }
118
+
119
+ /**
120
+ * Save the theme options based on the passed action.
121
+ *
122
+ * Save the theme options based on the passed action.
123
+ *
124
+ * @since 5.0.0
125
+ * @access private
126
+ * @see maybe_save_theme_options
127
+ * @param string $action Action to take action on
128
+ *
129
+ */
130
+ private function save_theme_update_options( $action ) {
131
+ //Check capability
132
+ $capability = 'update_themes'; //On single site, admins can use this, on multisite, only network admins can
133
+ if ( !current_user_can( $capability ) ) return;
134
+
135
+ $themes = isset( $_REQUEST[ 'checked' ] ) ? (array) $_REQUEST[ 'checked' ] : array();
136
+ $theme_options = MPSUM_Updates_Manager::get_options( 'themes' );
137
+ $theme_automatic_options = MPSUM_Updates_Manager::get_options( 'themes_automatic' );
138
+
139
+ switch( $action ) {
140
+ case 'disallow-update-selected':
141
+ foreach( $themes as $theme ) {
142
+ $theme_options[] = $theme;
143
+ if ( ( $key = array_search( $theme, $theme_automatic_options ) ) !== false ) {
144
+ unset( $theme_automatic_options[ $key ] );
145
+ }
146
+ }
147
+
148
+ break;
149
+ case 'allow-update-selected':
150
+ foreach( $themes as $theme ) {
151
+ if ( ( $key = array_search( $theme, $theme_options ) ) !== false ) {
152
+ unset( $theme_options[ $key ] );
153
+ }
154
+ }
155
+ break;
156
+ case 'allow-automatic-selected':
157
+ foreach( $themes as $theme ) {
158
+ $theme_automatic_options[] = $theme;
159
+ if ( ( $key = array_search( $theme, $theme_options ) ) !== false ) {
160
+ unset( $theme_options[ $key ] );
161
+ }
162
+ }
163
+ break;
164
+ case 'disallow-automatic-selected':
165
+ foreach( $themes as $theme ) {
166
+ if ( ( $key = array_search( $theme, $theme_automatic_options ) ) !== false ) {
167
+ unset( $theme_automatic_options[ $key ] );
168
+ }
169
+ }
170
+ break;
171
+ default:
172
+ return;
173
+ }
174
+ //Check nonce
175
+ check_admin_referer( 'mpsum_theme_update', '_mpsum' );
176
+
177
+ //Update option
178
+ $theme_options = array_values( array_unique( $theme_options ) );
179
+ $theme_automatic_options = array_values( array_unique( $theme_automatic_options ) );
180
+ $options = MPSUM_Updates_Manager::get_options();
181
+ $options[ 'themes' ] = $theme_options;
182
+ $options[ 'themes_automatic' ] = $theme_automatic_options;
183
+ MPSUM_Updates_Manager::update_options( $options );
184
+ }
185
+
186
+ /**
187
+ * Output the HTML interface for the themes tab.
188
+ *
189
+ * Output the HTML interface for the themes tab.
190
+ *
191
+ * @since 5.0.0
192
+ * @access public
193
+ * @see __construct
194
+ * @internal Uses the mpsum_admin_tab_themes action
195
+ */
196
+ public function tab_output_themes() {
197
+ if ( isset( $_GET[ 'disabled' ] ) ) {
198
+ $message = __( 'The selected theme updates have been enabled.', 'stops-core-theme-and-plugin-updates' );
199
+ if ( $_GET[ 'disabled' ] == 1 ) {
200
+ $message = __( 'The selected theme updates have been disabled.', 'stops-core-theme-and-plugin-updates' );
201
+ }
202
+ ?>
203
+ <div class="updated"><p><strong><?php echo esc_html( $message ); ?></strong></p></div>
204
+ <?php
205
+ }
206
+
207
+
208
+ ?>
209
+ <form action="<?php echo esc_url( add_query_arg( array() ) ); ?>" method="post">
210
+ <?php
211
+ $theme_status = isset( $_GET[ 'theme_status' ] ) ? $_GET[ 'theme_status' ] : false;
212
+ if ( false !== $theme_status ) {
213
+ printf( '<input type="hidden" name="theme_status" value="%s" />', esc_attr( $theme_status ) );
214
+ }
215
+ wp_nonce_field( 'mpsum_theme_update', '_mpsum' );
216
+ ?>
217
+ <h3><?php esc_html_e( 'Theme Update Options', 'stops-core-theme-and-plugin-updates' ); ?></h3>
218
+ <?php
219
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
220
+
221
+ if ( false === $this->can_update() ) {
222
+ printf( '<div class="error"><p><strong>%s</strong></p></div>', esc_html__( 'All theme updates have been disabled.', 'stops-core-theme-and-plugin-updates' ) );
223
+ }
224
+ $theme_table = new MPSUM_Themes_List_Table( $args = array( 'screen' => $this->slug, 'tab' => $this->tab ) );
225
+ $theme_table->prepare_items();
226
+ $theme_table->views();
227
+ $theme_table->display();
228
+ ?>
229
+ </form>
230
+ <?php
231
+ } //end tab_output_plugins
232
+
233
+ /**
234
+ * Outputs the theme action links beneath each theme row.
235
+ *
236
+ * Outputs the theme action links beneath each theme row.
237
+ *
238
+ * @since 5.0.0
239
+ * @access public
240
+ * @see __construct
241
+ * @internal uses mpsum_theme_action_links filter
242
+ *
243
+ * @param array $settings Array of settings to output.
244
+ * @param WP_Theme $theme The theme object to take action on.
245
+ */
246
+ public function theme_action_links( $settings, $theme ) {
247
+ $stylesheet = $theme->get_stylesheet();
248
+ $theme_options = MPSUM_Updates_Manager::get_options( 'themes' );
249
+ if ( false !== $key = array_search( $stylesheet, $theme_options ) ) {
250
+ $enable_url = add_query_arg( array( 'action' => 'allow-update-selected', '_mpsum' => wp_create_nonce( 'mpsum_theme_update' ), 'checked' => array( $stylesheet ) ) );
251
+ $enable_url = remove_query_arg( 'disabled', $enable_url );
252
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $enable_url ), esc_html__( 'Allow Updates', 'stops-core-theme-and-plugin-updates' ) );
253
+ } else {
254
+ //Disable Link
255
+ $disable_url = add_query_arg( array( 'action' => 'disallow-update-selected', '_mpsum' => wp_create_nonce( 'mpsum_theme_update' ), 'checked' => array( $stylesheet ) ) );
256
+ $disable_url = remove_query_arg( 'disabled', $disable_url );
257
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $disable_url ), esc_html__( 'Disallow Updates', 'stops-core-theme-and-plugin-updates' ) );
258
+
259
+ //Automatic Link
260
+ $theme_automatic_options = MPSUM_Updates_Manager::get_options( 'themes_automatic' );
261
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
262
+ if ( isset( $core_options[ 'automatic_theme_updates' ] ) && 'individual' == $core_options[ 'automatic_theme_updates' ] ) {
263
+ if ( in_array( $stylesheet, $theme_automatic_options ) ) {
264
+ //Disable Link
265
+ $disable_automatic_url = add_query_arg( array( 'action' => 'disallow-automatic-selected', '_mpsum' => wp_create_nonce( 'mpsum_theme_update' ), 'checked' => array( $stylesheet ) ) );
266
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $disable_automatic_url ), esc_html__( 'Disallow Automatic Updates', 'stops-core-theme-and-plugin-updates' ) );
267
+ } else {
268
+ //Enable Link
269
+ $enable_automatic_url = add_query_arg( array( 'action' => 'allow-automatic-selected', '_mpsum' => wp_create_nonce( 'mpsum_theme_update' ), 'checked' => array( $stylesheet ) ) );
270
+ $settings[] = sprintf( '<a href="%s">%s</a>', esc_url( $enable_automatic_url ), esc_html__( 'Enable Automatic Updates', 'stops-core-theme-and-plugin-updates' ) );
271
+ }
272
+ }
273
+ }
274
+ return $settings;
275
+ }
276
+ }
includes/MPSUM_Disable_Updates.php ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controller class for disabling updates throughout WordPress
4
+ *
5
+ * Controller class for disabling updates throughout WordPress.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ class MPSUM_Disable_Updates {
12
+
13
+ /**
14
+ * Holds the class instance.
15
+ *
16
+ * @since 5.0.0
17
+ * @access static
18
+ * @var MPSUM_Disable_Updates $instance
19
+ */
20
+ private static $instance = null;
21
+
22
+ /**
23
+ * Set a class instance.
24
+ *
25
+ * Set a class instance.
26
+ *
27
+ * @since 5.0.0
28
+ * @access static
29
+ *
30
+ */
31
+ public static function run() {
32
+ if ( null == self::$instance ) {
33
+ self::$instance = new self;
34
+ }
35
+ } //end get_instance
36
+
37
+ /**
38
+ * Class constructor.
39
+ *
40
+ * Read in the plugin options and determine which updates are disabled.
41
+ *
42
+ * @since 5.0.0
43
+ * @access private
44
+ *
45
+ */
46
+ private function __construct() {
47
+
48
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
49
+
50
+ //Disable Footer Nag
51
+ if ( isset( $core_options[ 'misc_wp_footer' ] ) && 'off' === $core_options[ 'misc_wp_footer' ] ) {
52
+ add_filter( 'update_footer', '__return_empty_string', 11 );
53
+ }
54
+
55
+ //Disable Browser Nag
56
+ if ( isset( $core_options[ 'misc_browser_nag' ] ) && 'off' === $core_options[ 'misc_browser_nag' ] ) {
57
+ add_action( 'wp_dashboard_setup', array( $this, 'disable_browser_nag' ), 9 );
58
+ add_action( 'wp_network_dashboard_setup', array( $this, 'disable_browser_nag' ), 9 );
59
+ }
60
+
61
+ //Disable All Updates
62
+ if ( isset( $core_options[ 'all_updates' ] ) && 'off' == $core_options[ 'all_updates' ] ) {
63
+ new MPSUM_Disable_Updates_All();
64
+ return;
65
+ }
66
+
67
+ //Disable WordPress Updates
68
+ if ( isset( $core_options[ 'core_updates' ] ) && 'off' == $core_options[ 'core_updates' ] ) {
69
+ new MPSUM_Disable_Updates_WordPress();
70
+ }
71
+
72
+ //Disable Plugin Updates
73
+ if ( isset( $core_options[ 'plugin_updates' ] ) && 'off' == $core_options[ 'plugin_updates' ] ) {
74
+ new MPSUM_Disable_Updates_Plugins();
75
+ }
76
+
77
+ //Disable Theme Updates
78
+ if ( isset( $core_options[ 'theme_updates' ] ) && 'off' == $core_options[ 'theme_updates' ] ) {
79
+ new MPSUM_Disable_Updates_Themes();
80
+ }
81
+
82
+ //Disable Translation Updates
83
+ if ( isset( $core_options[ 'translation_updates' ] ) && 'off' == $core_options[ 'translation_updates' ] ) {
84
+ new MPSUM_Disable_Updates_Translations();
85
+ }
86
+
87
+ //Enable Development Updates
88
+ if ( isset( $core_options[ 'automatic_development_updates' ] ) && 'on' == $core_options[ 'automatic_development_updates' ] ) {
89
+ add_filter( 'allow_dev_auto_core_updates', '__return_true', 50 );
90
+ } elseif( isset( $core_options[ 'automatic_development_updates' ] ) && 'off' == $core_options[ 'automatic_development_updates' ] ) {
91
+ add_filter( 'allow_dev_auto_core_updates', '__return_false', 50 );
92
+ }
93
+
94
+ //Enable Core Major Updates
95
+ if ( isset( $core_options[ 'automatic_major_updates' ] ) && 'on' == $core_options[ 'automatic_major_updates' ] ) {
96
+ add_filter( 'allow_major_auto_core_updates', '__return_true', 50 );
97
+ } elseif( isset( $core_options[ 'automatic_major_updates' ] ) && 'off' == $core_options[ 'automatic_major_updates' ] ) {
98
+ add_filter( 'allow_major_auto_core_updates', '__return_false', 50 );
99
+ }
100
+
101
+ //Enable Core Minor Updates
102
+ if ( isset( $core_options[ 'automatic_minor_updates' ] ) && 'on' == $core_options[ 'automatic_minor_updates' ] ) {
103
+ add_filter( 'allow_minor_auto_core_updates', '__return_true', 50 );
104
+ } elseif( isset( $core_options[ 'automatic_minor_updates' ] ) && 'off' == $core_options[ 'automatic_minor_updates' ] ) {
105
+ add_filter( 'allow_minor_auto_core_updates', '__return_false', 50 );
106
+ }
107
+
108
+ //Enable Translation Updates
109
+ if ( isset( $core_options[ 'automatic_translation_updates' ] ) && 'on' == $core_options[ 'automatic_translation_updates' ] ) {
110
+ add_filter( 'auto_update_translation', '__return_true', 50 );
111
+ } elseif( isset( $core_options[ 'automatic_translation_updates' ] ) && 'off' == $core_options[ 'automatic_translation_updates' ] ) {
112
+ add_filter( 'auto_update_translation', '__return_false', 50 );
113
+ }
114
+
115
+ //Disable the Update Notification
116
+ if ( isset( $core_options[ 'notification_core_update_emails' ] ) && 'on' == $core_options[ 'notification_core_update_emails' ] ) {
117
+ add_filter( 'auto_core_update_send_email', '__return_true', 50 );
118
+ add_filter( 'send_core_update_notification_email', '__return_true', 50 );
119
+ add_filter( 'automatic_updates_send_debug_email', '__return_true', 50 );
120
+ } elseif( isset( $core_options[ 'notification_core_update_emails' ] ) && 'off' == $core_options[ 'notification_core_update_emails' ] ) {
121
+ add_filter( 'auto_core_update_send_email', '__return_false', 50 );
122
+ add_filter( 'send_core_update_notification_email', '__return_false', 50 );
123
+ add_filter( 'automatic_updates_send_debug_email', '__return_false', 50 );
124
+ }
125
+
126
+ //Enable Plugin Auto-updates
127
+ if ( isset( $core_options[ 'plugin_updates' ] ) && 'on' == $core_options[ 'plugin_updates' ] ) {
128
+ if ( isset( $core_options[ 'automatic_plugin_updates' ] ) && 'on' == $core_options[ 'automatic_plugin_updates' ] ) {
129
+ add_filter( 'auto_update_plugin', '__return_true', 10, 2 );
130
+ } elseif( isset( $core_options[ 'automatic_plugin_updates' ] ) && 'off' == $core_options[ 'automatic_plugin_updates' ] ) {
131
+ add_filter( 'auto_update_plugin', '__return_false', 10, 2 );
132
+ } elseif( isset( $core_options[ 'automatic_plugin_updates' ] ) && 'individual' == $core_options[ 'automatic_plugin_updates' ] ) {
133
+ add_filter( 'auto_update_plugin', array( $this, 'automatic_updates_plugins' ), 10, 2 );
134
+ }
135
+ }
136
+
137
+
138
+ //Enable Theme Auto-updates
139
+ if ( isset( $core_options[ 'theme_updates' ] ) && 'on' == $core_options[ 'theme_updates' ] ) {
140
+ if ( isset( $core_options[ 'automatic_theme_updates' ] ) && 'on' == $core_options[ 'automatic_theme_updates' ] ) {
141
+ add_filter( 'auto_update_theme', '__return_true', 10, 2 );
142
+ } elseif( isset( $core_options[ 'automatic_theme_updates' ] ) && 'off' == $core_options[ 'automatic_theme_updates' ] ) {
143
+ add_filter( 'auto_update_theme', '__return_false', 10, 2 );
144
+ } elseif( isset( $core_options[ 'automatic_theme_updates' ] ) && 'individual' == $core_options[ 'automatic_theme_updates' ] ) {
145
+ add_filter( 'auto_update_theme', array( $this, 'automatic_updates_theme' ), 10, 2 );
146
+ }
147
+ }
148
+
149
+
150
+ //Prevent updates on themes/plugins
151
+ add_filter( 'site_transient_update_plugins', array( $this, 'disable_plugin_notifications' ), 50 );
152
+ add_filter( 'site_transient_update_themes', array( $this, 'disable_theme_notifications' ), 50 );
153
+ add_filter( 'http_request_args', array( $this, 'http_request_args_remove_plugins_themes' ), 5, 2 );
154
+
155
+ } //end constructor
156
+
157
+ /**
158
+ * Disable the out-of-date browser nag on the WordPress Dashboard.
159
+ *
160
+ * Disable the out-of-date browser nag on the WordPress Dashboard.
161
+ *
162
+ * @since 5.0.0
163
+ * @access public
164
+ * @see __construct
165
+ * @internal uses wp_dashboard_setup action on single-site, wp_network_dashboard_setup action on multisite
166
+ *
167
+ */
168
+ public function disable_browser_nag() {
169
+ remove_meta_box( 'dashboard_browser_nag', 'dashboard-network', 'normal' );
170
+ remove_meta_box( 'dashboard_browser_nag', 'dashboard', 'normal' );
171
+ }
172
+
173
+ /**
174
+ * Enables plugin automatic updates on an individual basis.
175
+ *
176
+ * Enables plugin automatic updates on an individual basis.
177
+ *
178
+ * @since 5.0.0
179
+ * @access public
180
+ * @see __construct
181
+ * @internal uses auto_update_plugin filter
182
+ *
183
+ * @param bool $update Whether the item has automatic updates enabled
184
+ * @param object $item Object holding the asset to be updated
185
+ * @return bool True of automatic updates enabled, false if not
186
+ */
187
+ public function automatic_updates_plugins( $update, $item ) {
188
+ $plugin_automatic_options = MPSUM_Updates_Manager::get_options( 'plugins_automatic' );
189
+ if ( in_array( $item->plugin, $plugin_automatic_options ) ) {
190
+ return true;
191
+ }
192
+ return false;
193
+ }
194
+
195
+ /**
196
+ * Enables theme automatic updates on an individual basis.
197
+ *
198
+ * Enables theme automatic updates on an individual basis.
199
+ *
200
+ * @since 5.0.0
201
+ * @access public
202
+ * @see __construct
203
+ * @internal uses auto_update_theme filter
204
+ *
205
+ * @param bool $update Whether the item has automatic updates enabled
206
+ * @param object $item Object holding the asset to be updated
207
+ * @return bool True of automatic updates enabled, false if not
208
+ */
209
+ public function automatic_updates_theme( $update, $item ) {
210
+ $theme_automatic_options = MPSUM_Updates_Manager::get_options( 'themes_automatic' );
211
+ if ( in_array( $item->theme , $theme_automatic_options) ) {
212
+ return true;
213
+ }
214
+ return false;
215
+ }
216
+
217
+ /**
218
+ * Disables plugin updates on an individual basis.
219
+ *
220
+ * Disables plugin updates on an individual basis.
221
+ *
222
+ * @since 5.0.0
223
+ * @access public
224
+ * @see __construct
225
+ * @internal uses site_transient_update_plugins filter
226
+ *
227
+ * @param object $plugins Plugins that may have update notifications
228
+ * @return object Updated plugins list with updates
229
+ */
230
+ public function disable_plugin_notifications( $plugins ) {
231
+ if ( !isset( $plugins->response ) || empty( $plugins->response ) ) return $plugins;
232
+
233
+ $plugin_options = MPSUM_Updates_Manager::get_options( 'plugins' );
234
+ foreach( $plugin_options as $plugin ) {
235
+ unset( $plugins->response[ $plugin ] );
236
+ }
237
+ return $plugins;
238
+ }
239
+
240
+ /**
241
+ * Disables theme updates on an individual basis.
242
+ *
243
+ * Disables theme updates on an individual basis.
244
+ *
245
+ * @since 5.0.0
246
+ * @access public
247
+ * @see __construct
248
+ * @internal uses site_transient_update_themes filter
249
+ *
250
+ * @param object $themes Themes that may have update notifications
251
+ * @return object Updated themes list with updates
252
+ */
253
+ public function disable_theme_notifications( $themes ) {
254
+ if ( !isset( $themes->response ) || empty( $themes->response ) ) return $themes;
255
+
256
+ $theme_options = MPSUM_Updates_Manager::get_options( 'themes' );
257
+ foreach( $theme_options as $theme ) {
258
+ unset( $themes->response[ $theme ] );
259
+ }
260
+ return $themes;
261
+ }
262
+
263
+ /**
264
+ * Disables theme and plugin http requests on an individual basis.
265
+ *
266
+ * Disables theme and plugin http requests on an individual basis.
267
+ *
268
+ * @since 5.0.0
269
+ * @access public
270
+ * @see __construct
271
+ * @internal uses http_request_args filter
272
+ *
273
+ * @param array $r Request array
274
+ * @param string $url URL requested
275
+ * @return array Updated Request array
276
+ */
277
+ public function http_request_args_remove_plugins_themes( $r, $url ) {
278
+ if ( 0 !== strpos( $url, 'https://api.wordpress.org/plugins/update-check/1.1/' ) ) return $r;
279
+
280
+ if ( isset( $r[ 'body' ][ 'plugins' ] ) ) {
281
+ $r_plugins = json_decode( $r[ 'body' ][ 'plugins' ], true );
282
+ $plugin_options = MPSUM_Updates_Manager::get_options( 'plugins' );
283
+ foreach( $plugin_options as $plugin ) {
284
+ unset( $r_plugins[ $plugin ] );
285
+ if ( false !== $key = array_search( $plugin, $r_plugins[ 'active' ] ) ) {
286
+ unset( $r_plugins[ 'active' ][ $key ] );
287
+ $r_plugins[ 'active' ] = array_values( $r_plugins[ 'active' ] );
288
+ }
289
+ }
290
+ $r[ 'body' ][ 'plugins' ] = json_encode( $r_plugins );
291
+ }
292
+ if ( isset( $r[ 'body' ][ 'themes' ] ) ) {
293
+ $r_themes = json_decode( $r[ 'body' ][ 'themes' ], true );
294
+ $theme_options = MPSUM_Updates_Manager::get_options( 'themes' );
295
+ foreach( $theme_options as $theme ) {
296
+ unset( $r_themes[ $theme ] );
297
+ }
298
+ $r[ 'body' ][ 'themes' ] = json_encode( $r_themes );
299
+ }
300
+ return $r;
301
+ }
302
+
303
+ }
includes/MPSUM_Disable_Updates_All.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Disables all WordPress updates.
4
+ *
5
+ * Disables all WordPress updates.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ //Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
12
+ class MPSUM_Disable_Updates_All {
13
+
14
+ public function __construct() {
15
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
16
+
17
+
18
+ /*
19
+ * Disable Theme Updates
20
+ * 2.8 to 3.0
21
+ */
22
+ add_filter( 'pre_transient_update_themes', array( $this, 'last_checked_now' ) );
23
+ /*
24
+ * 3.0
25
+ */
26
+ add_filter( 'pre_site_transient_update_themes', array( $this, 'last_checked_now' ) );
27
+
28
+
29
+ /*
30
+ * Disable Plugin Updates
31
+ * 2.8 to 3.0
32
+ */
33
+ add_action( 'pre_transient_update_plugins', array( $this, 'last_checked_now' ) );
34
+ /*
35
+ * 3.0
36
+ */
37
+ add_filter( 'pre_site_transient_update_plugins', array( $this, 'last_checked_now' ) );
38
+
39
+
40
+ /*
41
+ * Disable Core Updates
42
+ * 2.8 to 3.0
43
+ */
44
+ add_filter( 'pre_transient_update_core', array( $this, 'last_checked_now' ) );
45
+ /*
46
+ * 3.0
47
+ */
48
+ add_filter( 'pre_site_transient_update_core', array( $this, 'last_checked_now' ) );
49
+
50
+
51
+ /*
52
+ * Disable All Automatic Updates
53
+ * 3.7+
54
+ *
55
+ * @author sLa NGjI's @ slangji.wordpress.com
56
+ */
57
+ add_filter( 'auto_update_translation', '__return_false' );
58
+ add_filter( 'automatic_updater_disabled', '__return_true' );
59
+ add_filter( 'allow_minor_auto_core_updates', '__return_false' );
60
+ add_filter( 'allow_major_auto_core_updates', '__return_false' );
61
+ add_filter( 'allow_dev_auto_core_updates', '__return_false' );
62
+ add_filter( 'auto_update_core', '__return_false' );
63
+ add_filter( 'wp_auto_update_core', '__return_false' );
64
+ add_filter( 'auto_core_update_send_email', '__return_false' );
65
+ add_filter( 'send_core_update_notification_email', '__return_false' );
66
+ add_filter( 'auto_update_plugin', '__return_false' );
67
+ add_filter( 'auto_update_theme', '__return_false' );
68
+ add_filter( 'automatic_updates_send_debug_email', '__return_false' );
69
+ add_filter( 'automatic_updates_is_vcs_checkout', '__return_true' );
70
+
71
+ } //end constructor
72
+
73
+ /**
74
+ * Initialize and load the plugin stuff
75
+ *
76
+ * @since 1.3
77
+ * @author scripts@schloebe.de
78
+ */
79
+ function admin_init() {
80
+
81
+ /*
82
+ * Disable Theme Updates
83
+ * 2.8 to 3.0
84
+ */
85
+ remove_action( 'load-themes.php', 'wp_update_themes' );
86
+ remove_action( 'load-update.php', 'wp_update_themes' );
87
+ remove_action( 'admin_init', '_maybe_update_themes' );
88
+ remove_action( 'wp_update_themes', 'wp_update_themes' );
89
+ wp_clear_scheduled_hook( 'wp_update_themes' );
90
+
91
+ /*
92
+ * 3.0
93
+ */
94
+ remove_action( 'load-update-core.php', 'wp_update_themes' );
95
+ wp_clear_scheduled_hook( 'wp_update_themes' );
96
+
97
+
98
+ /*
99
+ * Disable Plugin Updates
100
+ * 2.8 to 3.0
101
+ */
102
+ remove_action( 'load-plugins.php', 'wp_update_plugins' );
103
+ remove_action( 'load-update.php', 'wp_update_plugins' );
104
+ remove_action( 'admin_init', '_maybe_update_plugins' );
105
+ remove_action( 'wp_update_plugins', 'wp_update_plugins' );
106
+ wp_clear_scheduled_hook( 'wp_update_plugins' );
107
+
108
+ /*
109
+ * 3.0
110
+ */
111
+ remove_action( 'load-update-core.php', 'wp_update_plugins' );
112
+ wp_clear_scheduled_hook( 'wp_update_plugins' );
113
+
114
+
115
+ /*
116
+ * Disable Core Updates
117
+ * 2.8 to 3.0
118
+ */
119
+ remove_action( 'wp_version_check', 'wp_version_check' );
120
+ remove_action( 'admin_init', '_maybe_update_core' );
121
+ wp_clear_scheduled_hook( 'wp_version_check' );
122
+
123
+
124
+ /*
125
+ * 3.0
126
+ */
127
+ wp_clear_scheduled_hook( 'wp_version_check' );
128
+
129
+
130
+ /*
131
+ * 3.7+
132
+ */
133
+ remove_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
134
+ remove_action( 'admin_init', 'wp_maybe_auto_update' );
135
+ remove_action( 'admin_init', 'wp_auto_update_core' );
136
+ wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
137
+ }
138
+
139
+ public function last_checked_now( $transient ) {
140
+ include ABSPATH . WPINC . '/version.php';
141
+ $current = new stdClass;
142
+ $current->updates = array();
143
+ $current->version_checked = $wp_version;
144
+ $current->last_checked = time();
145
+
146
+ return $current;
147
+ }
148
+
149
+ }
includes/MPSUM_Disable_Updates_Plugins.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Disables all WordPress plugin updates.
4
+ *
5
+ * Disables all WordPress plugin updates.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ //Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
12
+ class MPSUM_Disable_Updates_Plugins {
13
+
14
+ public function __construct() {
15
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
16
+
17
+ /*
18
+ * Disable Plugin Updates
19
+ * 2.8 to 3.0
20
+ */
21
+ add_action( 'pre_transient_update_plugins', array( $this, 'last_checked_now' ) );
22
+ /*
23
+ * 3.0
24
+ */
25
+ add_filter( 'pre_site_transient_update_plugins', array( $this, 'last_checked_now' ) );
26
+
27
+ /*
28
+ * Disable All Automatic Updates
29
+ * 3.7+
30
+ *
31
+ * @author sLa NGjI's @ slangji.wordpress.com
32
+ */
33
+ add_filter( 'auto_update_plugin', '__return_false' );
34
+
35
+ } //end constructor
36
+
37
+ /**
38
+ * Initialize and load the plugin stuff
39
+ *
40
+ * @since 1.3
41
+ * @author scripts@schloebe.de
42
+ */
43
+ function admin_init() {
44
+
45
+
46
+ /*
47
+ * Disable Plugin Updates
48
+ * 2.8 to 3.0
49
+ */
50
+ remove_action( 'load-plugins.php', 'wp_update_plugins' );
51
+ remove_action( 'load-update.php', 'wp_update_plugins' );
52
+ remove_action( 'admin_init', '_maybe_update_plugins' );
53
+ remove_action( 'wp_update_plugins', 'wp_update_plugins' );
54
+ wp_clear_scheduled_hook( 'wp_update_plugins' );
55
+
56
+ /*
57
+ * 3.0
58
+ */
59
+ remove_action( 'load-update-core.php', 'wp_update_plugins' );
60
+ wp_clear_scheduled_hook( 'wp_update_plugins' );
61
+
62
+ }
63
+
64
+ public function last_checked_now( $transient ) {
65
+ include ABSPATH . WPINC . '/version.php';
66
+ $current = new stdClass;
67
+ $current->updates = array();
68
+ $current->version_checked = $wp_version;
69
+ $current->last_checked = time();
70
+
71
+ return $current;
72
+ }
73
+
74
+ }
includes/MPSUM_Disable_Updates_Themes.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Disables all WordPress theme updates.
4
+ *
5
+ * Disables all WordPress theme updates.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ //Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
12
+ class MPSUM_Disable_Updates_Themes {
13
+
14
+ public function __construct() {
15
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
16
+
17
+
18
+ /*
19
+ * Disable Theme Updates
20
+ * 2.8 to 3.0
21
+ */
22
+ add_filter( 'pre_transient_update_themes', array( $this, 'last_checked_now' ) );
23
+ /*
24
+ * 3.0
25
+ */
26
+ add_filter( 'pre_site_transient_update_themes', array( $this, 'last_checked_now' ) );
27
+
28
+ /*
29
+ * Disable All Automatic Updates
30
+ * 3.7+
31
+ *
32
+ * @author sLa NGjI's @ slangji.wordpress.com
33
+ */
34
+ add_filter( 'auto_update_theme', '__return_false' );
35
+
36
+ } //end constructor
37
+
38
+ /**
39
+ * Initialize and load the plugin stuff
40
+ *
41
+ * @since 1.3
42
+ * @author scripts@schloebe.de
43
+ */
44
+ function admin_init() {
45
+
46
+ /*
47
+ * Disable Theme Updates
48
+ * 2.8 to 3.0
49
+ */
50
+ remove_action( 'load-themes.php', 'wp_update_themes' );
51
+ remove_action( 'load-update.php', 'wp_update_themes' );
52
+ remove_action( 'admin_init', '_maybe_update_themes' );
53
+ remove_action( 'wp_update_themes', 'wp_update_themes' );
54
+ wp_clear_scheduled_hook( 'wp_update_themes' );
55
+
56
+ /*
57
+ * 3.0
58
+ */
59
+ remove_action( 'load-update-core.php', 'wp_update_themes' );
60
+ wp_clear_scheduled_hook( 'wp_update_themes' );
61
+
62
+ }
63
+
64
+ public function last_checked_now( $transient ) {
65
+ include ABSPATH . WPINC . '/version.php';
66
+ $current = new stdClass;
67
+ $current->updates = array();
68
+ $current->version_checked = $wp_version;
69
+ $current->last_checked = time();
70
+
71
+ return $current;
72
+ }
73
+
74
+ }
includes/MPSUM_Disable_Updates_Translations.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Disables all WordPress translation updates.
4
+ *
5
+ * Disables all WordPress translation updates.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ //Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
12
+ class MPSUM_Disable_Updates_Translations {
13
+
14
+ public function __construct() {
15
+
16
+
17
+ /*
18
+ * Disable All Automatic Updates
19
+ * 3.7+
20
+ *
21
+ * @author sLa NGjI's @ slangji.wordpress.com
22
+ */
23
+ add_filter( 'auto_update_translation', '__return_false' );
24
+
25
+ /*
26
+ * Disable Theme Translations
27
+ * 2.8 to 3.0
28
+ */
29
+ add_filter( 'transient_update_themes', array( $this, 'remove_translations' ) );
30
+ /*
31
+ * 3.0
32
+ */
33
+ add_filter( 'site_transient_update_themes', array( $this, 'remove_translations' ) );
34
+
35
+
36
+ /*
37
+ * Disable Plugin Translations
38
+ * 2.8 to 3.0
39
+ */
40
+ add_action( 'transient_update_plugins', array( $this, 'remove_translations' ) );
41
+ /*
42
+ * 3.0
43
+ */
44
+ add_filter( 'site_transient_update_plugins', array( $this, 'remove_translations' ) );
45
+
46
+
47
+ /*
48
+ * Disable Core Translations
49
+ * 2.8 to 3.0
50
+ */
51
+ add_filter( 'transient_update_core', array( $this, 'remove_translations' ) );
52
+ /*
53
+ * 3.0
54
+ */
55
+ add_filter( 'site_transient_update_core', array( $this, 'remove_translations' ) );
56
+
57
+ } //end constructor
58
+
59
+
60
+ public function remove_translations( $transient ) {
61
+
62
+ if ( is_object( $transient ) && isset( $transient->translations ) ) {
63
+ $transient->translations = array();
64
+ }
65
+ return $transient;
66
+ }
67
+
68
+ }
includes/MPSUM_Disable_Updates_WordPress.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Disables all core WordPress updates
4
+ *
5
+ * Disables all core WordPress updates.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
+ //Credit - From https://wordpress.org/plugins/disable-wordpress-updates/
12
+ class MPSUM_Disable_Updates_WordPress {
13
+
14
+ public function __construct() {
15
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
16
+
17
+
18
+ /*
19
+ * Disable Core Updates
20
+ * 2.8 to 3.0
21
+ */
22
+ add_filter( 'pre_transient_update_core', array( $this, 'last_checked_now' ) );
23
+ /*
24
+ * 3.0
25
+ */
26
+ add_filter( 'pre_site_transient_update_core', array( $this, 'last_checked_now' ) );
27
+
28
+
29
+ /*
30
+ * Disable All Automatic Updates
31
+ * 3.7+
32
+ *
33
+ * @author sLa NGjI's @ slangji.wordpress.com
34
+ */
35
+ add_filter( 'automatic_updater_disabled', '__return_true' );
36
+ add_filter( 'allow_minor_auto_core_updates', '__return_false' );
37
+ add_filter( 'allow_major_auto_core_updates', '__return_false' );
38
+ add_filter( 'allow_dev_auto_core_updates', '__return_false' );
39
+ add_filter( 'auto_update_core', '__return_false' );
40
+ add_filter( 'wp_auto_update_core', '__return_false' );
41
+ add_filter( 'auto_core_update_send_email', '__return_false' );
42
+ add_filter( 'send_core_update_notification_email', '__return_false' );
43
+ add_filter( 'automatic_updates_send_debug_email', '__return_false' );
44
+ add_filter( 'automatic_updates_is_vcs_checkout', '__return_true' );
45
+
46
+ } //end constructor
47
+
48
+ /**
49
+ * Initialize and load the plugin stuff
50
+ *
51
+ * @since 1.3
52
+ * @author scripts@schloebe.de
53
+ */
54
+ function admin_init() {
55
+
56
+
57
+ /*
58
+ * Disable Core Updates
59
+ * 2.8 to 3.0
60
+ */
61
+ remove_action( 'wp_version_check', 'wp_version_check' );
62
+ remove_action( 'admin_init', '_maybe_update_core' );
63
+ wp_clear_scheduled_hook( 'wp_version_check' );
64
+
65
+
66
+ /*
67
+ * 3.0
68
+ */
69
+ wp_clear_scheduled_hook( 'wp_version_check' );
70
+
71
+
72
+ /*
73
+ * 3.7+
74
+ */
75
+ remove_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
76
+ remove_action( 'admin_init', 'wp_maybe_auto_update' );
77
+ remove_action( 'admin_init', 'wp_auto_update_core' );
78
+ wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
79
+ }
80
+
81
+ public function last_checked_now( $transient ) {
82
+ include ABSPATH . WPINC . '/version.php';
83
+ $current = new stdClass;
84
+ $current->updates = array();
85
+ $current->version_checked = $wp_version;
86
+ $current->last_checked = time();
87
+
88
+ return $current;
89
+ }
90
+
91
+ }
includes/MPSUM_List_Table.php ADDED
@@ -0,0 +1,1104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base class for displaying a list of items in an ajaxified HTML table.
4
+ * Copied from wp-admin/includes as per http://codex.wordpress.org/Class_Reference/WP_List_Table
5
+ *
6
+ * @since 5.0.0
7
+ * @access private
8
+ *
9
+ * @package WordPress
10
+ * @subpackage MPSUM_List_Table
11
+ */
12
+ class MPSUM_List_Table {
13
+
14
+ /**
15
+ * The current list of items
16
+ *
17
+ * @since 3.1.0
18
+ * @var array
19
+ * @access public
20
+ */
21
+ public $items;
22
+
23
+ /**
24
+ * Various information about the current table
25
+ *
26
+ * @since 3.1.0
27
+ * @var array
28
+ * @access private
29
+ */
30
+ private $_args;
31
+
32
+ /**
33
+ * Various information needed for displaying the pagination
34
+ *
35
+ * @since 3.1.0
36
+ * @var array
37
+ * @access private
38
+ */
39
+ private $_pagination_args = array();
40
+
41
+ /**
42
+ * The current screen
43
+ *
44
+ * @since 3.1.0
45
+ * @var object
46
+ * @access protected
47
+ */
48
+ protected $screen;
49
+
50
+ /**
51
+ * Cached bulk actions
52
+ *
53
+ * @since 3.1.0
54
+ * @var array
55
+ * @access private
56
+ */
57
+ private $_actions;
58
+
59
+ /**
60
+ * Cached pagination output
61
+ *
62
+ * @since 3.1.0
63
+ * @var string
64
+ * @access private
65
+ */
66
+ private $_pagination;
67
+
68
+ /**
69
+ * The view switcher modes.
70
+ *
71
+ * @since 4.1.0
72
+ * @var array
73
+ * @access protected
74
+ */
75
+ protected $modes = array();
76
+
77
+ /**
78
+ * Constructor.
79
+ *
80
+ * The child class should call this constructor from its own constructor to override
81
+ * the default $args.
82
+ *
83
+ * @since 3.1.0
84
+ * @access public
85
+ *
86
+ * @param array|string $args {
87
+ * Array or string of arguments.
88
+ *
89
+ * @type string $plural Plural value used for labels and the objects being listed.
90
+ * This affects things such as CSS class-names and nonces used
91
+ * in the list table, e.g. 'posts'. Default empty.
92
+ * @type string $singular Singular label for an object being listed, e.g. 'post'.
93
+ * Default empty
94
+ * @type bool $ajax Whether the list table supports AJAX. This includes loading
95
+ * and sorting data, for example. If true, the class will call
96
+ * the {@see _js_vars()} method in the footer to provide variables
97
+ * to any scripts handling AJAX events. Default false.
98
+ * @type string $screen String containing the hook name used to determine the current
99
+ * screen. If left null, the current screen will be automatically set.
100
+ * Default null.
101
+ * }
102
+ */
103
+ public function __construct( $args = array() ) {
104
+ $args = wp_parse_args( $args, array(
105
+ 'plural' => '',
106
+ 'singular' => '',
107
+ 'ajax' => false,
108
+ 'screen' => null,
109
+ ) );
110
+
111
+ $this->screen = convert_to_screen( $args['screen'] );
112
+
113
+ add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
114
+
115
+ if ( !$args['plural'] )
116
+ $args['plural'] = $this->screen->base;
117
+
118
+ $args['plural'] = sanitize_key( $args['plural'] );
119
+ $args['singular'] = sanitize_key( $args['singular'] );
120
+
121
+ $this->_args = $args;
122
+
123
+ if ( $args['ajax'] ) {
124
+ // wp_enqueue_script( 'list-table' );
125
+ add_action( 'admin_footer', array( $this, '_js_vars' ) );
126
+ }
127
+
128
+ if ( empty( $this->modes ) ) {
129
+ $this->modes = array(
130
+ 'list' => __( 'List View' ),
131
+ 'excerpt' => __( 'Excerpt View' )
132
+ );
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Make private properties readable for backwards compatibility.
138
+ *
139
+ * @since 4.0.0
140
+ * @access public
141
+ *
142
+ * @param string $name Property to get.
143
+ * @return mixed Property.
144
+ */
145
+ public function __get( $name ) {
146
+ return $this->$name;
147
+ }
148
+
149
+ /**
150
+ * Make private properties settable for backwards compatibility.
151
+ *
152
+ * @since 4.0.0
153
+ * @access public
154
+ *
155
+ * @param string $name Property to set.
156
+ * @param mixed $value Property value.
157
+ * @return mixed Newly-set property.
158
+ */
159
+ public function __set( $name, $value ) {
160
+ return $this->$name = $value;
161
+ }
162
+
163
+ /**
164
+ * Make private properties checkable for backwards compatibility.
165
+ *
166
+ * @since 4.0.0
167
+ * @access public
168
+ *
169
+ * @param string $name Property to check if set.
170
+ * @return bool Whether the property is set.
171
+ */
172
+ public function __isset( $name ) {
173
+ return isset( $this->$name );
174
+ }
175
+
176
+ /**
177
+ * Make private properties un-settable for backwards compatibility.
178
+ *
179
+ * @since 4.0.0
180
+ * @access public
181
+ *
182
+ * @param string $name Property to unset.
183
+ */
184
+ public function __unset( $name ) {
185
+ unset( $this->$name );
186
+ }
187
+
188
+ /**
189
+ * Make private/protected methods readable for backwards compatibility.
190
+ *
191
+ * @since 4.0.0
192
+ * @access public
193
+ *
194
+ * @param callable $name Method to call.
195
+ * @param array $arguments Arguments to pass when calling.
196
+ * @return mixed|bool Return value of the callback, false otherwise.
197
+ */
198
+ public function __call( $name, $arguments ) {
199
+ return call_user_func_array( array( $this, $name ), $arguments );
200
+ }
201
+
202
+ /**
203
+ * Checks the current user's permissions
204
+ *
205
+ * @since 3.1.0
206
+ * @access public
207
+ * @abstract
208
+ */
209
+ public function ajax_user_can() {
210
+ die( 'function WP_List_Table::ajax_user_can() must be over-ridden in a sub-class.' );
211
+ }
212
+
213
+ /**
214
+ * Prepares the list of items for displaying.
215
+ * @uses WP_List_Table::set_pagination_args()
216
+ *
217
+ * @since 3.1.0
218
+ * @access public
219
+ * @abstract
220
+ */
221
+ public function prepare_items() {
222
+ die( 'function WP_List_Table::prepare_items() must be over-ridden in a sub-class.' );
223
+ }
224
+
225
+ /**
226
+ * An internal method that sets all the necessary pagination arguments
227
+ *
228
+ * @param array $args An associative array with information about the pagination
229
+ * @access protected
230
+ */
231
+ protected function set_pagination_args( $args ) {
232
+ $args = wp_parse_args( $args, array(
233
+ 'total_items' => 0,
234
+ 'total_pages' => 0,
235
+ 'per_page' => 0,
236
+ ) );
237
+
238
+ if ( !$args['total_pages'] && $args['per_page'] > 0 )
239
+ $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
240
+
241
+ // Redirect if page number is invalid and headers are not already sent.
242
+ if ( ! headers_sent() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
243
+ wp_redirect( add_query_arg( 'paged', $args['total_pages'] ) );
244
+ exit;
245
+ }
246
+
247
+ $this->_pagination_args = $args;
248
+ }
249
+
250
+ /**
251
+ * Access the pagination args.
252
+ *
253
+ * @since 3.1.0
254
+ * @access public
255
+ *
256
+ * @param string $key Pagination argument to retrieve. Common values include 'total_items',
257
+ * 'total_pages', 'per_page', or 'infinite_scroll'.
258
+ * @return int Number of items that correspond to the given pagination argument.
259
+ */
260
+ public function get_pagination_arg( $key ) {
261
+ if ( 'page' == $key )
262
+ return $this->get_pagenum();
263
+
264
+ if ( isset( $this->_pagination_args[$key] ) )
265
+ return $this->_pagination_args[$key];
266
+ }
267
+
268
+ /**
269
+ * Whether the table has items to display or not
270
+ *
271
+ * @since 3.1.0
272
+ * @access public
273
+ *
274
+ * @return bool
275
+ */
276
+ public function has_items() {
277
+ return !empty( $this->items );
278
+ }
279
+
280
+ /**
281
+ * Message to be displayed when there are no items
282
+ *
283
+ * @since 3.1.0
284
+ * @access public
285
+ */
286
+ public function no_items() {
287
+ _e( 'No items found.' );
288
+ }
289
+
290
+ /**
291
+ * Display the search box.
292
+ *
293
+ * @since 3.1.0
294
+ * @access public
295
+ *
296
+ * @param string $text The search button text
297
+ * @param string $input_id The search input id
298
+ */
299
+ public function search_box( $text, $input_id ) {
300
+ if ( empty( $_REQUEST['s'] ) && !$this->has_items() )
301
+ return;
302
+
303
+ $input_id = $input_id . '-search-input';
304
+
305
+ if ( ! empty( $_REQUEST['orderby'] ) )
306
+ echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
307
+ if ( ! empty( $_REQUEST['order'] ) )
308
+ echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
309
+ if ( ! empty( $_REQUEST['post_mime_type'] ) )
310
+ echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
311
+ if ( ! empty( $_REQUEST['detached'] ) )
312
+ echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
313
+ ?>
314
+ <p class="search-box">
315
+ <label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
316
+ <input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>" />
317
+ <?php submit_button( $text, 'button', false, false, array('id' => 'search-submit') ); ?>
318
+ </p>
319
+ <?php
320
+ }
321
+
322
+ /**
323
+ * Get an associative array ( id => link ) with the list
324
+ * of views available on this table.
325
+ *
326
+ * @since 3.1.0
327
+ * @access protected
328
+ *
329
+ * @return array
330
+ */
331
+ protected function get_views() {
332
+ return array();
333
+ }
334
+
335
+ /**
336
+ * Display the list of views available on this table.
337
+ *
338
+ * @since 3.1.0
339
+ * @access public
340
+ */
341
+ public function views() {
342
+ $views = $this->get_views();
343
+ /**
344
+ * Filter the list of available list table views.
345
+ *
346
+ * The dynamic portion of the hook name, `$this->screen->id`, refers
347
+ * to the ID of the current screen, usually a string.
348
+ *
349
+ * @since 3.5.0
350
+ *
351
+ * @param array $views An array of available list table views.
352
+ */
353
+ $views = apply_filters( "views_{$this->screen->id}", $views );
354
+
355
+ if ( empty( $views ) )
356
+ return;
357
+
358
+ echo "<ul class='subsubsub'>\n";
359
+ foreach ( $views as $class => $view ) {
360
+ $views[ $class ] = "\t<li class='$class'>$view";
361
+ }
362
+ echo implode( " |</li>\n", $views ) . "</li>\n";
363
+ echo "</ul>";
364
+ }
365
+
366
+ /**
367
+ * Get an associative array ( option_name => option_title ) with the list
368
+ * of bulk actions available on this table.
369
+ *
370
+ * @since 3.1.0
371
+ * @access protected
372
+ *
373
+ * @return array
374
+ */
375
+ protected function get_bulk_actions() {
376
+ return array();
377
+ }
378
+
379
+ /**
380
+ * Display the bulk actions dropdown.
381
+ *
382
+ * @since 3.1.0
383
+ * @access protected
384
+ *
385
+ * @param string $which The location of the bulk actions: 'top' or 'bottom'.
386
+ * This is designated as optional for backwards-compatibility.
387
+ */
388
+ protected function bulk_actions( $which = '' ) {
389
+ if ( is_null( $this->_actions ) ) {
390
+ $no_new_actions = $this->_actions = $this->get_bulk_actions();
391
+ /**
392
+ * Filter the list table Bulk Actions drop-down.
393
+ *
394
+ * The dynamic portion of the hook name, `$this->screen->id`, refers
395
+ * to the ID of the current screen, usually a string.
396
+ *
397
+ * This filter can currently only be used to remove bulk actions.
398
+ *
399
+ * @since 3.5.0
400
+ *
401
+ * @param array $actions An array of the available bulk actions.
402
+ */
403
+ $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
404
+ $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions );
405
+ $two = '';
406
+ } else {
407
+ $two = '2';
408
+ }
409
+
410
+ if ( empty( $this->_actions ) )
411
+ return;
412
+
413
+ echo "<label for='bulk-action-selector-" . esc_attr( $which ) . "' class='screen-reader-text'>" . __( 'Select bulk action' ) . "</label>";
414
+ echo "<select name='action$two' id='bulk-action-selector-" . esc_attr( $which ) . "'>\n";
415
+ echo "<option value='-1' selected='selected'>" . __( 'Bulk Actions' ) . "</option>\n";
416
+
417
+ foreach ( $this->_actions as $name => $title ) {
418
+ $class = 'edit' == $name ? ' class="hide-if-no-js"' : '';
419
+
420
+ echo "\t<option value='$name'$class>$title</option>\n";
421
+ }
422
+
423
+ echo "</select>\n";
424
+
425
+ submit_button( __( 'Apply' ), 'action', false, false, array( 'id' => "doaction$two" ) );
426
+ echo "\n";
427
+ }
428
+
429
+ /**
430
+ * Get the current action selected from the bulk actions dropdown.
431
+ *
432
+ * @since 3.1.0
433
+ * @access public
434
+ *
435
+ * @return string|bool The action name or False if no action was selected
436
+ */
437
+ public function current_action() {
438
+ if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) )
439
+ return false;
440
+
441
+ if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )
442
+ return $_REQUEST['action'];
443
+
444
+ if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] )
445
+ return $_REQUEST['action2'];
446
+
447
+ return false;
448
+ }
449
+
450
+ /**
451
+ * Generate row actions div
452
+ *
453
+ * @since 3.1.0
454
+ * @access protected
455
+ *
456
+ * @param array $actions The list of actions
457
+ * @param bool $always_visible Whether the actions should be always visible
458
+ * @return string
459
+ */
460
+ protected function row_actions( $actions, $always_visible = false ) {
461
+ $action_count = count( $actions );
462
+ $i = 0;
463
+
464
+ if ( !$action_count )
465
+ return '';
466
+
467
+ $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
468
+ foreach ( $actions as $action => $link ) {
469
+ ++$i;
470
+ ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
471
+ $out .= "<span class='$action'>$link$sep</span>";
472
+ }
473
+ $out .= '</div>';
474
+
475
+ return $out;
476
+ }
477
+
478
+ /**
479
+ * Display a monthly dropdown for filtering items
480
+ *
481
+ * @since 3.1.0
482
+ * @access protected
483
+ *
484
+ * @param string $post_type
485
+ */
486
+ protected function months_dropdown( $post_type ) {
487
+ global $wpdb, $wp_locale;
488
+
489
+ $months = $wpdb->get_results( $wpdb->prepare( "
490
+ SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
491
+ FROM $wpdb->posts
492
+ WHERE post_type = %s
493
+ ORDER BY post_date DESC
494
+ ", $post_type ) );
495
+
496
+ /**
497
+ * Filter the 'Months' drop-down results.
498
+ *
499
+ * @since 3.7.0
500
+ *
501
+ * @param object $months The months drop-down query results.
502
+ * @param string $post_type The post type.
503
+ */
504
+ $months = apply_filters( 'months_dropdown_results', $months, $post_type );
505
+
506
+ $month_count = count( $months );
507
+
508
+ if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) )
509
+ return;
510
+
511
+ $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
512
+ ?>
513
+ <label for="filter-by-date" class="screen-reader-text"><?php _e( 'Filter by date' ); ?></label>
514
+ <select name="m" id="filter-by-date">
515
+ <option<?php selected( $m, 0 ); ?> value="0"><?php _e( 'All dates' ); ?></option>
516
+ <?php
517
+ foreach ( $months as $arc_row ) {
518
+ if ( 0 == $arc_row->year )
519
+ continue;
520
+
521
+ $month = zeroise( $arc_row->month, 2 );
522
+ $year = $arc_row->year;
523
+
524
+ printf( "<option %s value='%s'>%s</option>\n",
525
+ selected( $m, $year . $month, false ),
526
+ esc_attr( $arc_row->year . $month ),
527
+ /* translators: 1: month name, 2: 4-digit year */
528
+ sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year )
529
+ );
530
+ }
531
+ ?>
532
+ </select>
533
+ <?php
534
+ }
535
+
536
+ /**
537
+ * Display a view switcher
538
+ *
539
+ * @since 3.1.0
540
+ * @access protected
541
+ *
542
+ * @param string $current_mode
543
+ */
544
+ protected function view_switcher( $current_mode ) {
545
+ ?>
546
+ <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" />
547
+ <div class="view-switch">
548
+ <?php
549
+ foreach ( $this->modes as $mode => $title ) {
550
+ $classes = array( 'view-' . $mode );
551
+ if ( $current_mode == $mode )
552
+ $classes[] = 'current';
553
+ printf(
554
+ "<a href='%s' class='%s' id='view-switch-$mode'><span class='screen-reader-text'>%s</span></a>\n",
555
+ esc_url( add_query_arg( 'mode', $mode ) ),
556
+ implode( ' ', $classes ),
557
+ $title
558
+ );
559
+ }
560
+ ?>
561
+ </div>
562
+ <?php
563
+ }
564
+
565
+ /**
566
+ * Display a comment count bubble
567
+ *
568
+ * @since 3.1.0
569
+ * @access protected
570
+ *
571
+ * @param int $post_id The post ID.
572
+ * @param int $pending_comments Number of pending comments.
573
+ */
574
+ protected function comments_bubble( $post_id, $pending_comments ) {
575
+ $pending_phrase = sprintf( __( '%s pending' ), number_format( $pending_comments ) );
576
+
577
+ if ( $pending_comments )
578
+ echo '<strong>';
579
+
580
+ echo "<a href='" . esc_url( add_query_arg( 'p', $post_id, admin_url( 'edit-comments.php' ) ) ) . "' title='" . esc_attr( $pending_phrase ) . "' class='post-com-count'><span class='comment-count'>" . number_format_i18n( get_comments_number() ) . "</span></a>";
581
+
582
+ if ( $pending_comments )
583
+ echo '</strong>';
584
+ }
585
+
586
+ /**
587
+ * Get the current page number
588
+ *
589
+ * @since 3.1.0
590
+ * @access public
591
+ *
592
+ * @return int
593
+ */
594
+ public function get_pagenum() {
595
+ $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
596
+
597
+ if( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] )
598
+ $pagenum = $this->_pagination_args['total_pages'];
599
+
600
+ return max( 1, $pagenum );
601
+ }
602
+
603
+ /**
604
+ * Get number of items to display on a single page
605
+ *
606
+ * @since 3.1.0
607
+ * @access protected
608
+ *
609
+ * @param string $option
610
+ * @param int $default
611
+ * @return int
612
+ */
613
+ protected function get_items_per_page( $option, $default = 20 ) {
614
+ $per_page = (int) get_user_option( $option );
615
+ if ( empty( $per_page ) || $per_page < 1 )
616
+ $per_page = $default;
617
+
618
+ /**
619
+ * Filter the number of items to be displayed on each page of the list table.
620
+ *
621
+ * The dynamic hook name, $option, refers to the `per_page` option depending
622
+ * on the type of list table in use. Possible values include: 'edit_comments_per_page',
623
+ * 'sites_network_per_page', 'site_themes_network_per_page', 'themes_network_per_page',
624
+ * 'users_network_per_page', 'edit_post_per_page', 'edit_page_per_page',
625
+ * 'edit_{$post_type}_per_page', etc.
626
+ *
627
+ * @since 2.9.0
628
+ *
629
+ * @param int $per_page Number of items to be displayed. Default 20.
630
+ */
631
+ return (int) apply_filters( $option, $per_page );
632
+ }
633
+
634
+ /**
635
+ * Display the pagination.
636
+ *
637
+ * @since 3.1.0
638
+ * @access protected
639
+ *
640
+ * @param string $which
641
+ */
642
+ protected function pagination( $which ) {
643
+ if ( empty( $this->_pagination_args ) ) {
644
+ return;
645
+ }
646
+
647
+ $total_items = $this->_pagination_args['total_items'];
648
+ $total_pages = $this->_pagination_args['total_pages'];
649
+ $infinite_scroll = false;
650
+ if ( isset( $this->_pagination_args['infinite_scroll'] ) ) {
651
+ $infinite_scroll = $this->_pagination_args['infinite_scroll'];
652
+ }
653
+
654
+ $output = '<span class="displaying-num">' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>';
655
+
656
+ $current = $this->get_pagenum();
657
+
658
+ $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
659
+
660
+ $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
661
+
662
+ $page_links = array();
663
+
664
+ $disable_first = $disable_last = '';
665
+ if ( $current == 1 ) {
666
+ $disable_first = ' disabled';
667
+ }
668
+ if ( $current == $total_pages ) {
669
+ $disable_last = ' disabled';
670
+ }
671
+ $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
672
+ 'first-page' . $disable_first,
673
+ esc_attr__( 'Go to the first page' ),
674
+ esc_url( remove_query_arg( 'paged', $current_url ) ),
675
+ '&laquo;'
676
+ );
677
+
678
+ $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
679
+ 'prev-page' . $disable_first,
680
+ esc_attr__( 'Go to the previous page' ),
681
+ esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ),
682
+ '&lsaquo;'
683
+ );
684
+
685
+ if ( 'bottom' == $which ) {
686
+ $html_current_page = $current;
687
+ } else {
688
+ $html_current_page = sprintf( "%s<input class='current-page' id='current-page-selector' title='%s' type='text' name='paged' value='%s' size='%d' />",
689
+ '<label for="current-page-selector" class="screen-reader-text">' . __( 'Select Page' ) . '</label>',
690
+ esc_attr__( 'Current page' ),
691
+ $current,
692
+ strlen( $total_pages )
693
+ );
694
+ }
695
+ $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
696
+ $page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . '</span>';
697
+
698
+ $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
699
+ 'next-page' . $disable_last,
700
+ esc_attr__( 'Go to the next page' ),
701
+ esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ),
702
+ '&rsaquo;'
703
+ );
704
+
705
+ $page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
706
+ 'last-page' . $disable_last,
707
+ esc_attr__( 'Go to the last page' ),
708
+ esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
709
+ '&raquo;'
710
+ );
711
+
712
+ $pagination_links_class = 'pagination-links';
713
+ if ( ! empty( $infinite_scroll ) ) {
714
+ $pagination_links_class = ' hide-if-js';
715
+ }
716
+ $output .= "\n<span class='$pagination_links_class'>" . join( "\n", $page_links ) . '</span>';
717
+
718
+ if ( $total_pages ) {
719
+ $page_class = $total_pages < 2 ? ' one-page' : '';
720
+ } else {
721
+ $page_class = ' no-pages';
722
+ }
723
+ $this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
724
+
725
+ echo $this->_pagination;
726
+ }
727
+
728
+ /**
729
+ * Get a list of columns. The format is:
730
+ * 'internal-name' => 'Title'
731
+ *
732
+ * @since 3.1.0
733
+ * @access public
734
+ * @abstract
735
+ *
736
+ * @return array
737
+ */
738
+ public function get_columns() {
739
+ die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' );
740
+ }
741
+
742
+ /**
743
+ * Get a list of sortable columns. The format is:
744
+ * 'internal-name' => 'orderby'
745
+ * or
746
+ * 'internal-name' => array( 'orderby', true )
747
+ *
748
+ * The second format will make the initial sorting order be descending
749
+ *
750
+ * @since 3.1.0
751
+ * @access protected
752
+ *
753
+ * @return array
754
+ */
755
+ protected function get_sortable_columns() {
756
+ return array();
757
+ }
758
+
759
+ /**
760
+ * Get a list of all, hidden and sortable columns, with filter applied
761
+ *
762
+ * @since 3.1.0
763
+ * @access protected
764
+ *
765
+ * @return array
766
+ */
767
+ protected function get_column_info() {
768
+ if ( isset( $this->_column_headers ) )
769
+ return $this->_column_headers;
770
+
771
+ $columns = get_column_headers( $this->screen );
772
+ $hidden = get_hidden_columns( $this->screen );
773
+
774
+ $sortable_columns = $this->get_sortable_columns();
775
+ /**
776
+ * Filter the list table sortable columns for a specific screen.
777
+ *
778
+ * The dynamic portion of the hook name, `$this->screen->id`, refers
779
+ * to the ID of the current screen, usually a string.
780
+ *
781
+ * @since 3.5.0
782
+ *
783
+ * @param array $sortable_columns An array of sortable columns.
784
+ */
785
+ $_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns );
786
+
787
+ $sortable = array();
788
+ foreach ( $_sortable as $id => $data ) {
789
+ if ( empty( $data ) )
790
+ continue;
791
+
792
+ $data = (array) $data;
793
+ if ( !isset( $data[1] ) )
794
+ $data[1] = false;
795
+
796
+ $sortable[$id] = $data;
797
+ }
798
+
799
+ $this->_column_headers = array( $columns, $hidden, $sortable );
800
+
801
+ return $this->_column_headers;
802
+ }
803
+
804
+ /**
805
+ * Return number of visible columns
806
+ *
807
+ * @since 3.1.0
808
+ * @access public
809
+ *
810
+ * @return int
811
+ */
812
+ public function get_column_count() {
813
+ list ( $columns, $hidden ) = $this->get_column_info();
814
+ $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
815
+ return count( $columns ) - count( $hidden );
816
+ }
817
+
818
+ /**
819
+ * Print column headers, accounting for hidden and sortable columns.
820
+ *
821
+ * @since 3.1.0
822
+ * @access public
823
+ *
824
+ * @param bool $with_id Whether to set the id attribute or not
825
+ */
826
+ public function print_column_headers( $with_id = true ) {
827
+ list( $columns, $hidden, $sortable ) = $this->get_column_info();
828
+
829
+ $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
830
+ $current_url = remove_query_arg( 'paged', $current_url );
831
+
832
+ if ( isset( $_GET['orderby'] ) )
833
+ $current_orderby = $_GET['orderby'];
834
+ else
835
+ $current_orderby = '';
836
+
837
+ if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] )
838
+ $current_order = 'desc';
839
+ else
840
+ $current_order = 'asc';
841
+
842
+ if ( ! empty( $columns['cb'] ) ) {
843
+ static $cb_counter = 1;
844
+ $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>'
845
+ . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
846
+ $cb_counter++;
847
+ }
848
+
849
+ foreach ( $columns as $column_key => $column_display_name ) {
850
+ $class = array( 'manage-column', "column-$column_key" );
851
+
852
+ $style = '';
853
+ if ( in_array( $column_key, $hidden ) )
854
+ $style = 'display:none;';
855
+
856
+ $style = ' style="' . $style . '"';
857
+
858
+ if ( 'cb' == $column_key )
859
+ $class[] = 'check-column';
860
+ elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) )
861
+ $class[] = 'num';
862
+
863
+ if ( isset( $sortable[$column_key] ) ) {
864
+ list( $orderby, $desc_first ) = $sortable[$column_key];
865
+
866
+ if ( $current_orderby == $orderby ) {
867
+ $order = 'asc' == $current_order ? 'desc' : 'asc';
868
+ $class[] = 'sorted';
869
+ $class[] = $current_order;
870
+ } else {
871
+ $order = $desc_first ? 'desc' : 'asc';
872
+ $class[] = 'sortable';
873
+ $class[] = $desc_first ? 'asc' : 'desc';
874
+ }
875
+
876
+ $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
877
+ }
878
+
879
+ $id = $with_id ? "id='$column_key'" : '';
880
+
881
+ if ( !empty( $class ) )
882
+ $class = "class='" . join( ' ', $class ) . "'";
883
+
884
+ echo "<th scope='col' $id $class $style>$column_display_name</th>";
885
+ }
886
+ }
887
+
888
+ /**
889
+ * Display the table
890
+ *
891
+ * @since 3.1.0
892
+ * @access public
893
+ */
894
+ public function display() {
895
+ $singular = $this->_args['singular'];
896
+
897
+ $this->display_tablenav( 'top' );
898
+
899
+ ?>
900
+ <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
901
+ <thead>
902
+ <tr>
903
+ <?php $this->print_column_headers(); ?>
904
+ </tr>
905
+ </thead>
906
+
907
+ <tfoot>
908
+ <tr>
909
+ <?php $this->print_column_headers( false ); ?>
910
+ </tr>
911
+ </tfoot>
912
+
913
+ <tbody id="the-list"<?php
914
+ if ( $singular ) {
915
+ echo " data-wp-lists='list:$singular'";
916
+ } ?>>
917
+ <?php $this->display_rows_or_placeholder(); ?>
918
+ </tbody>
919
+ </table>
920
+ <?php
921
+ $this->display_tablenav( 'bottom' );
922
+ }
923
+
924
+ /**
925
+ * Get a list of CSS classes for the list table table tag.
926
+ *
927
+ * @since 3.1.0
928
+ * @access protected
929
+ *
930
+ * @return array List of CSS classes for the table tag.
931
+ */
932
+ protected function get_table_classes() {
933
+ return array( 'widefat', 'fixed', $this->_args['plural'] );
934
+ }
935
+
936
+ /**
937
+ * Generate the table navigation above or below the table
938
+ *
939
+ * @since 3.1.0
940
+ * @access protected
941
+ * @param string $which
942
+ */
943
+ protected function display_tablenav( $which ) {
944
+ if ( 'top' == $which )
945
+ wp_nonce_field( 'bulk-' . $this->_args['plural'] );
946
+ ?>
947
+ <div class="tablenav <?php echo esc_attr( $which ); ?>">
948
+
949
+ <div class="alignleft actions bulkactions">
950
+ <?php $this->bulk_actions( $which ); ?>
951
+ </div>
952
+ <?php
953
+ $this->extra_tablenav( $which );
954
+ $this->pagination( $which );
955
+ ?>
956
+
957
+ <br class="clear" />
958
+ </div>
959
+ <?php
960
+ }
961
+
962
+ /**
963
+ * Extra controls to be displayed between bulk actions and pagination
964
+ *
965
+ * @since 3.1.0
966
+ * @access protected
967
+ *
968
+ * @param string $which
969
+ */
970
+ protected function extra_tablenav( $which ) {}
971
+
972
+ /**
973
+ * Generate the tbody element for the list table.
974
+ *
975
+ * @since 3.1.0
976
+ * @access public
977
+ */
978
+ public function display_rows_or_placeholder() {
979
+ if ( $this->has_items() ) {
980
+ $this->display_rows();
981
+ } else {
982
+ echo '<tr class="no-items"><td class="colspanchange" colspan="' . $this->get_column_count() . '">';
983
+ $this->no_items();
984
+ echo '</td></tr>';
985
+ }
986
+ }
987
+
988
+ /**
989
+ * Generate the table rows
990
+ *
991
+ * @since 3.1.0
992
+ * @access public
993
+ */
994
+ public function display_rows() {
995
+ foreach ( $this->items as $item )
996
+ $this->single_row( $item );
997
+ }
998
+
999
+ /**
1000
+ * Generates content for a single row of the table
1001
+ *
1002
+ * @since 3.1.0
1003
+ * @access public
1004
+ *
1005
+ * @param object $item The current item
1006
+ */
1007
+ public function single_row( $item ) {
1008
+ static $row_class = '';
1009
+ $row_class = ( $row_class == '' ? ' class="alternate"' : '' );
1010
+
1011
+ echo '<tr' . $row_class . '>';
1012
+ $this->single_row_columns( $item );
1013
+ echo '</tr>';
1014
+ }
1015
+
1016
+ /**
1017
+ * Generates the columns for a single row of the table
1018
+ *
1019
+ * @since 3.1.0
1020
+ * @access protected
1021
+ *
1022
+ * @param object $item The current item
1023
+ */
1024
+ protected function single_row_columns( $item ) {
1025
+ list( $columns, $hidden ) = $this->get_column_info();
1026
+
1027
+ foreach ( $columns as $column_name => $column_display_name ) {
1028
+ $class = "class='$column_name column-$column_name'";
1029
+
1030
+ $style = '';
1031
+ if ( in_array( $column_name, $hidden ) )
1032
+ $style = ' style="display:none;"';
1033
+
1034
+ $attributes = "$class$style";
1035
+
1036
+ if ( 'cb' == $column_name ) {
1037
+ echo '<th scope="row" class="check-column">';
1038
+ echo $this->column_cb( $item );
1039
+ echo '</th>';
1040
+ }
1041
+ elseif ( method_exists( $this, 'column_' . $column_name ) ) {
1042
+ echo "<td $attributes>";
1043
+ echo call_user_func( array( $this, 'column_' . $column_name ), $item );
1044
+ echo "</td>";
1045
+ }
1046
+ else {
1047
+ echo "<td $attributes>";
1048
+ echo $this->column_default( $item, $column_name );
1049
+ echo "</td>";
1050
+ }
1051
+ }
1052
+ }
1053
+
1054
+ /**
1055
+ * Handle an incoming ajax request (called from admin-ajax.php)
1056
+ *
1057
+ * @since 3.1.0
1058
+ * @access public
1059
+ */
1060
+ public function ajax_response() {
1061
+ $this->prepare_items();
1062
+
1063
+ ob_start();
1064
+ if ( ! empty( $_REQUEST['no_placeholder'] ) ) {
1065
+ $this->display_rows();
1066
+ } else {
1067
+ $this->display_rows_or_placeholder();
1068
+ }
1069
+
1070
+ $rows = ob_get_clean();
1071
+
1072
+ $response = array( 'rows' => $rows );
1073
+
1074
+ if ( isset( $this->_pagination_args['total_items'] ) ) {
1075
+ $response['total_items_i18n'] = sprintf(
1076
+ _n( '1 item', '%s items', $this->_pagination_args['total_items'] ),
1077
+ number_format_i18n( $this->_pagination_args['total_items'] )
1078
+ );
1079
+ }
1080
+ if ( isset( $this->_pagination_args['total_pages'] ) ) {
1081
+ $response['total_pages'] = $this->_pagination_args['total_pages'];
1082
+ $response['total_pages_i18n'] = number_format_i18n( $this->_pagination_args['total_pages'] );
1083
+ }
1084
+
1085
+ die( wp_json_encode( $response ) );
1086
+ }
1087
+
1088
+ /**
1089
+ * Send required variables to JavaScript land
1090
+ *
1091
+ * @access public
1092
+ */
1093
+ public function _js_vars() {
1094
+ $args = array(
1095
+ 'class' => get_class( $this ),
1096
+ 'screen' => array(
1097
+ 'id' => $this->screen->id,
1098
+ 'base' => $this->screen->base,
1099
+ )
1100
+ );
1101
+
1102
+ printf( "<script type='text/javascript'>list_args = %s;</script>\n", wp_json_encode( $args ) );
1103
+ }
1104
+ }
includes/MPSUM_Plugins_List_Table.php ADDED
@@ -0,0 +1,467 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Easy Updates Manager Plugins List Table class.
4
+ *
5
+ * @package WordPress
6
+ * @subpackage MPSUM_List_Table
7
+ * @since 5.0.0
8
+ * @access private
9
+ */
10
+ class MPSUM_Plugins_List_Table extends MPSUM_List_Table {
11
+
12
+ private $tab = '';
13
+
14
+ /**
15
+ * Constructor.
16
+ *
17
+ * @since 3.1.0
18
+ * @access public
19
+ *
20
+ * @see WP_List_Table::__construct() for more information on default arguments.
21
+ *
22
+ * @param array $args An associative array of arguments.
23
+ */
24
+ public function __construct( $args = array() ) {
25
+ global $status, $page;
26
+
27
+ parent::__construct( array(
28
+ 'plural' => 'plugins',
29
+ 'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
30
+ ) );
31
+
32
+ $this->tab = isset( $args[ 'tab' ] ) ? $args[ 'tab' ] : '';
33
+
34
+
35
+ $status = 'all';
36
+ if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'update_disabled', 'update_enabled', 'automatic' ) ) ) {
37
+ $status = $_REQUEST['plugin_status'];
38
+ }
39
+
40
+ if ( isset($_REQUEST['s']) )
41
+ $_SERVER['REQUEST_URI'] = add_query_arg('s', wp_unslash($_REQUEST['s']) );
42
+
43
+ $page = $this->get_pagenum();
44
+ }
45
+
46
+ protected function get_table_classes() {
47
+ return array( 'widefat', $this->_args['plural'] );
48
+ }
49
+
50
+ public function ajax_user_can() {
51
+ return current_user_can('activate_plugins');
52
+ }
53
+
54
+ public function prepare_items() {
55
+
56
+ global $orderby, $order, $totals, $status;
57
+ $order = 'DESC';
58
+ $page = isset( $_GET[ 'paged' ] ) ? absint( $_GET[ 'paged' ] ) : 1;
59
+ $orderby = 'Name';
60
+
61
+ /**
62
+ * Filter the full array of plugins to list in the Plugins list table.
63
+ *
64
+ * @since 3.0.0
65
+ *
66
+ * @see get_plugins()
67
+ *
68
+ * @param array $plugins An array of plugins to display in the list table.
69
+ */
70
+ $plugins = array(
71
+ 'all' => apply_filters( 'all_plugins', get_plugins() ),
72
+ 'update_enabled' => array(),
73
+ 'update_disabled' => array(),
74
+ 'automatic' => array()
75
+ );
76
+
77
+ $screen = $this->screen;
78
+
79
+
80
+ $plugin_info = get_site_transient( 'update_plugins' );
81
+
82
+ $plugin_options = MPSUM_Updates_Manager::get_options( 'plugins' );
83
+ $plugin_automatic_options = MPSUM_Updates_Manager::get_options( 'plugins_automatic' );
84
+ foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) {
85
+ // Extra info if known. array_merge() ensures $plugin_data has precedence if keys collide.
86
+ if ( isset( $plugin_info->response[ $plugin_file ] ) ) {
87
+ $plugins['all'][ $plugin_file ] = $plugin_data = array_merge( (array) $plugin_info->response[ $plugin_file ], $plugin_data );
88
+ } elseif ( isset( $plugin_info->no_update[ $plugin_file ] ) ) {
89
+ $plugins['all'][ $plugin_file ] = $plugin_data = array_merge( (array) $plugin_info->no_update[ $plugin_file ], $plugin_data );
90
+ }
91
+
92
+
93
+ if ( false !== $key = array_search( $plugin_file, $plugin_options ) ) {
94
+ $plugins[ 'update_disabled' ][ $plugin_file ] = $plugin_data;
95
+ } else {
96
+ $plugins[ 'update_enabled' ][ $plugin_file ] = $plugin_data;
97
+ if ( in_array( $plugin_file, $plugin_automatic_options ) ) {
98
+ $plugins[ 'automatic' ][ $plugin_file ] = $plugin_data;
99
+ }
100
+ }
101
+ }
102
+
103
+ $totals = array();
104
+ foreach ( $plugins as $type => $list )
105
+ $totals[ $type ] = count( $list );
106
+
107
+ //Disable the automatic updates view
108
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
109
+ if ( isset( $core_options[ 'automatic_plugin_updates' ] ) && 'individual' !== $core_options[ 'automatic_plugin_updates' ] ) {
110
+ unset( $totals[ 'automatic' ] );
111
+ $plugins[ 'automatic' ] = array();
112
+ }
113
+
114
+ if ( empty( $plugins[ $status ] ) )
115
+ $status = 'all';
116
+
117
+ $this->items = array();
118
+ foreach ( $plugins[ $status ] as $plugin_file => $plugin_data ) {
119
+ // Translate, Don't Apply Markup, Sanitize HTML
120
+ remove_action( "after_plugin_row_$plugin_file", 'wp_plugin_update_row', 10, 2 );
121
+ $this->items[$plugin_file] = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, false, true );
122
+ }
123
+
124
+ $total_this_page = $totals[ $status ];
125
+
126
+ $plugins_per_page = 999;
127
+
128
+ $start = ( $page - 1 ) * $plugins_per_page;
129
+
130
+ if ( $total_this_page > $plugins_per_page )
131
+ $this->items = array_slice( $this->items, $start, $plugins_per_page );
132
+
133
+ $this->set_pagination_args( array(
134
+ 'total_items' => $total_this_page,
135
+ 'per_page' => $plugins_per_page,
136
+ ) );
137
+ }
138
+
139
+ /**
140
+ * @staticvar string $term
141
+ * @param array $plugin
142
+ * @return boolean
143
+ */
144
+ public function _search_callback( $plugin ) {
145
+ static $term;
146
+ if ( is_null( $term ) )
147
+ $term = wp_unslash( $_REQUEST['s'] );
148
+
149
+ foreach ( $plugin as $value ) {
150
+ if ( false !== stripos( strip_tags( $value ), $term ) ) {
151
+ return true;
152
+ }
153
+ }
154
+
155
+ return false;
156
+ }
157
+
158
+ /**
159
+ * @global string $orderby
160
+ * @global string $order
161
+ * @param array $plugin_a
162
+ * @param array $plugin_b
163
+ * @return int
164
+ */
165
+ public function _order_callback( $plugin_a, $plugin_b ) {
166
+ global $orderby, $order;
167
+
168
+ $a = $plugin_a[$orderby];
169
+ $b = $plugin_b[$orderby];
170
+
171
+ if ( $a == $b )
172
+ return 0;
173
+
174
+ if ( 'DESC' == $order )
175
+ return ( $a < $b ) ? 1 : -1;
176
+ else
177
+ return ( $a < $b ) ? -1 : 1;
178
+ }
179
+
180
+ public function no_items() {
181
+ global $plugins;
182
+
183
+ if ( !empty( $plugins['all'] ) )
184
+ _e( 'No plugins found.' );
185
+ else
186
+ _e( 'You do not appear to have any plugins available at this time.' );
187
+ }
188
+
189
+ public function get_columns() {
190
+ global $status;
191
+
192
+ return array(
193
+ 'cb' => !in_array( $status, array( 'mustuse', 'dropins' ) ) ? '<input type="checkbox" />' : '',
194
+ 'name' => __( 'Plugin' ),
195
+ 'description' => __( 'Description' ),
196
+ );
197
+ }
198
+
199
+ protected function get_sortable_columns() {
200
+ return array();
201
+ }
202
+
203
+ protected function get_views() {
204
+ global $totals, $status;
205
+
206
+ $status_links = array();
207
+ foreach ( $totals as $type => $count ) {
208
+ if ( !$count )
209
+ continue;
210
+
211
+ switch ( $type ) {
212
+ case 'all':
213
+ $text = _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $count, 'plugins' );
214
+ break;
215
+ case 'update_enabled':
216
+ $text = _n( 'Updates Enabled <span class="count">(%s)</span>', 'Updates Enabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates' );
217
+ break;
218
+ case 'update_disabled':
219
+ $text = _n( 'Updates Disabled <span class="count">(%s)</span>', 'Updates Disabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates' );
220
+ break;
221
+ case 'automatic':
222
+ $text = _n( 'Automatic Updates <span class="count">(%s)</span>', 'Automatic Updates <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates' );
223
+ break;
224
+ }
225
+
226
+ if ( 'search' != $type ) {
227
+ $plugin_url = MPSUM_Admin::get_url();
228
+ $query_args = array(
229
+ 'tab' => $this->tab,
230
+ 'plugin_status' => $type
231
+ );
232
+ $status_links[$type] = sprintf( "<a href='%s' %s>%s</a>",
233
+ add_query_arg( $query_args, $plugin_url ),
234
+ ( $type == $status ) ? ' class="current"' : '',
235
+ sprintf( $text, number_format_i18n( $count ) )
236
+ );
237
+ }
238
+ }
239
+
240
+ return $status_links;
241
+ }
242
+
243
+ protected function get_bulk_actions() {
244
+ global $status;
245
+
246
+ $actions = array();
247
+
248
+ $actions[ 'allow-update-selected' ] = esc_html__( 'Allow Updates', 'disable-plugin-and-theme-updates' );
249
+ $actions[ 'disallow-update-selected' ] = esc_html__( 'Disallow Updates', 'disable-plugin-and-theme-updates' );
250
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
251
+ if ( isset( $core_options[ 'automatic_plugin_updates' ] ) && 'individual' == $core_options[ 'automatic_plugin_updates' ] ) {
252
+ $actions[ 'allow-automatic-selected' ] = esc_html__( 'Allow Automatic Updates', 'disable-plugin-and-theme-updates' );
253
+ $actions[ 'disallow-automatic-selected' ] = esc_html__( 'Disallow Automatic Updates', 'disable-plugin-and-theme-updates' );
254
+ }
255
+
256
+ return $actions;
257
+ }
258
+
259
+ /**
260
+ * @global string $status
261
+ * @param string $which
262
+ * @return null
263
+ */
264
+ public function bulk_actions( $which = '' ) {
265
+ global $status;
266
+
267
+ if ( in_array( $status, array( 'mustuse', 'dropins' ) ) )
268
+ return;
269
+
270
+ parent::bulk_actions( $which );
271
+ }
272
+
273
+ /**
274
+ * @global string $status
275
+ * @param string $which
276
+ * @return null
277
+ */
278
+ protected function extra_tablenav( $which ) {
279
+ global $status;
280
+
281
+ if ( ! in_array($status, array('recently_activated', 'mustuse', 'dropins') ) )
282
+ return;
283
+
284
+ echo '<div class="alignleft actions">';
285
+
286
+ if ( ! $this->screen->in_admin( 'network' ) && 'recently_activated' == $status )
287
+ submit_button( __( 'Clear List' ), 'button', 'clear-recent-list', false );
288
+ elseif ( 'top' == $which && 'mustuse' == $status )
289
+ echo '<p>' . sprintf( __( 'Files in the <code>%s</code> directory are executed automatically.' ), str_replace( ABSPATH, '/', WPMU_PLUGIN_DIR ) ) . '</p>';
290
+ elseif ( 'top' == $which && 'dropins' == $status )
291
+ echo '<p>' . sprintf( __( 'Drop-ins are advanced plugins in the <code>%s</code> directory that replace WordPress functionality when present.' ), str_replace( ABSPATH, '', WP_CONTENT_DIR ) ) . '</p>';
292
+
293
+ echo '</div>';
294
+ }
295
+
296
+ public function current_action() {
297
+ if ( isset($_POST['clear-recent-list']) )
298
+ return 'clear-recent-list';
299
+
300
+ return parent::current_action();
301
+ }
302
+
303
+ public function display_rows() {
304
+ global $status;
305
+
306
+ if ( is_multisite() && ! $this->screen->in_admin( 'network' ) && in_array( $status, array( 'mustuse', 'dropins' ) ) )
307
+ return;
308
+
309
+ foreach ( $this->items as $plugin_file => $plugin_data )
310
+ $this->single_row( array( $plugin_file, $plugin_data ) );
311
+ }
312
+
313
+ /**
314
+ * @global string $status
315
+ * @global int $page
316
+ * @global string $s
317
+ * @global array $totals
318
+ * @param array $item
319
+ */
320
+ public function single_row( $item ) {
321
+ global $status, $page, $s, $totals;
322
+
323
+ list( $plugin_file, $plugin_data ) = $item;
324
+ $context = 'all';
325
+ $screen = $this->screen;
326
+
327
+ /**
328
+ * Filter the action links that show up under each plugin row.
329
+ *
330
+ * @since 5.0.0
331
+ *
332
+ * @param string Relative plugin file path
333
+ * @param array $plugin_data An array of plugin data.
334
+ * @param string $status Status of the plugin.
335
+ */
336
+ $actions = apply_filters( 'mpsum_plugin_action_links', array(), $plugin_file, $plugin_data, $status );
337
+
338
+ $class = 'active';
339
+ $plugin_options = MPSUM_Updates_Manager::get_options( 'plugins' );
340
+ if ( false !== $key = array_search( $plugin_file, $plugin_options ) ) {
341
+ $class = 'inactive';
342
+ }
343
+ $checkbox_id = "checkbox_" . md5($plugin_data['Name']);
344
+ $checkbox = "<label class='screen-reader-text' for='" . $checkbox_id . "' >" . sprintf( __( 'Select %s' ), $plugin_data['Name'] ) . "</label>"
345
+ . "<input type='checkbox' name='checked[]' value='" . esc_attr( $plugin_file ) . "' id='" . $checkbox_id . "' />";
346
+ $description = '<p>' . ( $plugin_data['Description'] ? $plugin_data['Description'] : '&nbsp;' ) . '</p>';
347
+ $plugin_name = $plugin_data['Name'];
348
+
349
+ $id = sanitize_title( $plugin_name );
350
+
351
+ echo "<tr id='$id' class='$class'>";
352
+
353
+ list( $columns, $hidden ) = $this->get_column_info();
354
+
355
+ foreach ( $columns as $column_name => $column_display_name ) {
356
+ $style = '';
357
+ if ( in_array( $column_name, $hidden ) )
358
+ $style = ' style="display:none;"';
359
+
360
+ switch ( $column_name ) {
361
+ case 'cb':
362
+ echo "<th scope='row' class='check-column'>$checkbox</th>";
363
+ break;
364
+ case 'name':
365
+ echo "<td class='plugin-title'$style><strong>$plugin_name</strong>";
366
+ echo $this->row_actions( $actions, true );
367
+ echo "</td>";
368
+ break;
369
+ case 'description':
370
+ echo "<td class='column-description desc'$style>
371
+ <div class='plugin-description'>$description</div>
372
+ <div class='$class second plugin-version-author-uri'>";
373
+
374
+ $plugin_meta = array();
375
+ if ( !empty( $plugin_data['Version'] ) )
376
+ $plugin_meta[] = sprintf( __( 'Version %s' ), $plugin_data['Version'] );
377
+ if ( !empty( $plugin_data['Author'] ) ) {
378
+ $author = $plugin_data['Author'];
379
+ if ( !empty( $plugin_data['AuthorURI'] ) )
380
+ $author = '<a href="' . $plugin_data['AuthorURI'] . '">' . $plugin_data['Author'] . '</a>';
381
+ $plugin_meta[] = sprintf( __( 'By %s' ), $author );
382
+ }
383
+
384
+ // Details link using API info, if available
385
+ if ( isset( $plugin_data['slug'] ) && current_user_can( 'install_plugins' ) ) {
386
+ $plugin_meta[] = sprintf( '<a href="%s" class="thickbox" aria-label="%s" data-title="%s">%s</a>',
387
+ esc_url( network_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $plugin_data['slug'] .
388
+ '&TB_iframe=true&width=600&height=550' ) ),
389
+ esc_attr( sprintf( __( 'More information about %s' ), $plugin_name ) ),
390
+ esc_attr( $plugin_name ),
391
+ __( 'View details' )
392
+ );
393
+ } elseif ( ! empty( $plugin_data['PluginURI'] ) ) {
394
+ $plugin_meta[] = sprintf( '<a href="%s">%s</a>',
395
+ esc_url( $plugin_data['PluginURI'] ),
396
+ __( 'Visit plugin site' )
397
+ );
398
+ }
399
+
400
+ /**
401
+ * Filter the array of row meta for each plugin in the Plugins list table.
402
+ *
403
+ * @since 2.8.0
404
+ *
405
+ * @param array $plugin_meta An array of the plugin's metadata,
406
+ * including the version, author,
407
+ * author URI, and plugin URI.
408
+ * @param string $plugin_file Path to the plugin file, relative to the plugins directory.
409
+ * @param array $plugin_data An array of plugin data.
410
+ * @param string $status Status of the plugin. Defaults are 'All', 'Active',
411
+ * 'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
412
+ * 'Drop-ins', 'Search'.
413
+ */
414
+ $plugin_meta = apply_filters( 'plugin_row_meta', $plugin_meta, $plugin_file, $plugin_data, $status );
415
+ echo implode( ' | ', $plugin_meta );
416
+
417
+ echo "</div></td>";
418
+ break;
419
+ default:
420
+ echo "<td class='$column_name column-$column_name'$style>";
421
+
422
+ /**
423
+ * Fires inside each custom column of the Plugins list table.
424
+ *
425
+ * @since 3.1.0
426
+ *
427
+ * @param string $column_name Name of the column.
428
+ * @param string $plugin_file Path to the plugin file.
429
+ * @param array $plugin_data An array of plugin data.
430
+ */
431
+ do_action( 'manage_plugins_custom_column', $column_name, $plugin_file, $plugin_data );
432
+ echo "</td>";
433
+ }
434
+ }
435
+
436
+ echo "</tr>";
437
+
438
+ /**
439
+ * Fires after each row in the Plugins list table.
440
+ *
441
+ * @since 2.3.0
442
+ *
443
+ * @param string $plugin_file Path to the plugin file, relative to the plugins directory.
444
+ * @param array $plugin_data An array of plugin data.
445
+ * @param string $status Status of the plugin. Defaults are 'All', 'Active',
446
+ * 'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
447
+ * 'Drop-ins', 'Search'.
448
+ */
449
+ do_action( 'after_plugin_row', $plugin_file, $plugin_data, $status );
450
+
451
+ /**
452
+ * Fires after each specific row in the Plugins list table.
453
+ *
454
+ * The dynamic portion of the hook name, `$plugin_file`, refers to the path
455
+ * to the plugin file, relative to the plugins directory.
456
+ *
457
+ * @since 2.7.0
458
+ *
459
+ * @param string $plugin_file Path to the plugin file, relative to the plugins directory.
460
+ * @param array $plugin_data An array of plugin data.
461
+ * @param string $status Status of the plugin. Defaults are 'All', 'Active',
462
+ * 'Inactive', 'Recently Activated', 'Upgrade', 'Must-Use',
463
+ * 'Drop-ins', 'Search'.
464
+ */
465
+ do_action( "after_plugin_row_$plugin_file", $plugin_file, $plugin_data, $status );
466
+ }
467
+ }
includes/MPSUM_Themes_List_Table.php ADDED
@@ -0,0 +1,411 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Easy Updates Manager Themes List Table class.
4
+ *
5
+ * @package Easy Updates Manager
6
+ * @subpackage MPSUM_List_Table
7
+ * @since 5.0.0
8
+ * @access private
9
+ */
10
+ class MPSUM_Themes_List_Table extends MPSUM_List_Table {
11
+
12
+ public $site_id;
13
+ public $is_site_themes;
14
+ private $tab = '';
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @since 3.1.0
20
+ * @access public
21
+ *
22
+ * @see WP_List_Table::__construct() for more information on default arguments.
23
+ *
24
+ * @param array $args An associative array of arguments.
25
+ */
26
+ public function __construct( $args = array() ) {
27
+ global $status, $page;
28
+
29
+ parent::__construct( array(
30
+ 'plural' => 'themes',
31
+ 'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
32
+ ) );
33
+
34
+ $this->tab = isset( $args[ 'tab' ] ) ? $args[ 'tab' ] : '';
35
+
36
+ $status = isset( $_REQUEST['theme_status'] ) ? $_REQUEST['theme_status'] : 'all';
37
+ if ( !in_array( $status, array( 'all', 'update_disabled', 'update_enabled', 'automatic' ) ) )
38
+ $status = 'all';
39
+
40
+ $page = $this->get_pagenum();
41
+
42
+ $this->is_site_themes = ( 'site-themes-network' == $this->screen->id ) ? true : false;
43
+
44
+ if ( $this->is_site_themes )
45
+ $this->site_id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : 0;
46
+ }
47
+
48
+ protected function get_table_classes() {
49
+ // todo: remove and add CSS for .themes
50
+ return array( 'widefat', 'plugins' );
51
+ }
52
+
53
+ public function ajax_user_can() {
54
+ if ( $this->is_site_themes )
55
+ return current_user_can( 'manage_sites' );
56
+ else
57
+ return current_user_can( 'manage_network_themes' );
58
+ }
59
+
60
+ public function prepare_items() {
61
+ global $totals, $status;
62
+ $order = 'DESC';
63
+ $page = isset( $_GET[ 'paged' ] ) ? absint( $_GET[ 'paged' ] ) : 1;
64
+ $orderby = 'Name';
65
+
66
+ $themes = array(
67
+ /**
68
+ * Filter the full array of WP_Theme objects to list in the Multisite
69
+ * themes list table.
70
+ *
71
+ * @since 3.1.0
72
+ *
73
+ * @param array $all An array of WP_Theme objects to display in the list table.
74
+ */
75
+ 'all' => apply_filters( 'all_themes', wp_get_themes() ),
76
+ 'update_enabled' => array(),
77
+ 'update_disabled' => array(),
78
+ 'automatic' => array()
79
+
80
+ );
81
+
82
+
83
+ $maybe_update = current_user_can( 'update_themes' ) && ! $this->is_site_themes && $current = get_site_transient( 'update_themes' );
84
+ $theme_options = MPSUM_Updates_Manager::get_options( 'themes' );
85
+ $theme_automatic_options = MPSUM_Updates_Manager::get_options( 'themes_automatic' );
86
+ foreach ( (array) $themes['all'] as $theme => $theme_data ) {
87
+ if ( false !== $key = array_search( $theme, $theme_options ) ) {
88
+ $themes[ 'update_disabled' ][ $theme ] = $theme_data;
89
+ } else {
90
+ $themes[ 'update_enabled' ][ $theme ] = $theme_data;
91
+ if ( in_array( $theme, $theme_automatic_options ) ) {
92
+ $themes[ 'automatic' ][ $theme ] = $theme_data;
93
+ }
94
+ }
95
+ }
96
+
97
+ $totals = array();
98
+
99
+ foreach ( $themes as $type => $list )
100
+ $totals[ $type ] = count( $list );
101
+
102
+ //Disable the automatic updates view
103
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
104
+ if ( isset( $core_options[ 'automatic_theme_updates' ] ) && 'individual' !== $core_options[ 'automatic_theme_updates' ] ) {
105
+ unset( $totals[ 'automatic' ] );
106
+ $themes[ 'automatic' ] = array();
107
+ }
108
+
109
+ if ( empty( $themes[ $status ] ) )
110
+ $status = 'all';
111
+
112
+ $this->items = $themes[ $status ];
113
+ WP_Theme::sort_by_name( $this->items );
114
+
115
+ $this->has_items = ! empty( $themes['all'] );
116
+ $total_this_page = $totals[ $status ];
117
+
118
+ if ( $orderby ) {
119
+ $orderby = ucfirst( $orderby );
120
+ $order = strtoupper( $order );
121
+
122
+ if ( $orderby == 'Name' ) {
123
+ if ( 'ASC' == $order )
124
+ $this->items = array_reverse( $this->items );
125
+ } else {
126
+ uasort( $this->items, array( $this, '_order_callback' ) );
127
+ }
128
+ }
129
+ $total_this_page = count( $themes[ 'all' ] );
130
+ $themes_per_page = 999;
131
+
132
+ $start = ( $page - 1 ) * $themes_per_page;
133
+
134
+ if ( $total_this_page > $themes_per_page )
135
+ $this->items = array_slice( $this->items, $start, $themes_per_page, true );
136
+
137
+ $this->set_pagination_args( array(
138
+ 'total_items' => $total_this_page,
139
+ 'per_page' => $themes_per_page,
140
+ ) );
141
+ }
142
+
143
+ /**
144
+ * @staticvar string $term
145
+ * @param WP_Theme $theme
146
+ * @return bool
147
+ */
148
+ public function _search_callback( $theme ) {
149
+ static $term;
150
+ if ( is_null( $term ) )
151
+ $term = wp_unslash( $_REQUEST['s'] );
152
+
153
+ foreach ( array( 'Name', 'Description', 'Author', 'Author', 'AuthorURI' ) as $field ) {
154
+ // Don't mark up; Do translate.
155
+ if ( false !== stripos( $theme->display( $field, false, true ), $term ) )
156
+ return true;
157
+ }
158
+
159
+ if ( false !== stripos( $theme->get_stylesheet(), $term ) )
160
+ return true;
161
+
162
+ if ( false !== stripos( $theme->get_template(), $term ) )
163
+ return true;
164
+
165
+ return false;
166
+ }
167
+
168
+ // Not used by any core columns.
169
+ /**
170
+ * @global string $orderby
171
+ * @global string $order
172
+ * @param array $theme_a
173
+ * @param array $theme_b
174
+ * @return int
175
+ */
176
+ public function _order_callback( $theme_a, $theme_b ) {
177
+ global $orderby, $order;
178
+
179
+ $a = $theme_a[ $orderby ];
180
+ $b = $theme_b[ $orderby ];
181
+
182
+ if ( $a == $b )
183
+ return 0;
184
+
185
+ if ( 'DESC' == $order )
186
+ return ( $a < $b ) ? 1 : -1;
187
+ else
188
+ return ( $a < $b ) ? -1 : 1;
189
+ }
190
+
191
+ public function no_items() {
192
+ if ( ! $this->has_items )
193
+ _e( 'No themes found.' );
194
+ else
195
+ _e( 'You do not appear to have any themes available at this time.' );
196
+ }
197
+
198
+ public function get_columns() {
199
+ global $status;
200
+
201
+ return array(
202
+ 'cb' => '<input type="checkbox" />',
203
+ 'name' => __( 'Theme' ),
204
+ 'description' => __( 'Description' ),
205
+ );
206
+ }
207
+
208
+ protected function get_sortable_columns() {
209
+ return array();
210
+ }
211
+
212
+ protected function get_views() {
213
+ global $totals, $status;
214
+
215
+ $status_links = array();
216
+ foreach ( $totals as $type => $count ) {
217
+ if ( !$count )
218
+ continue;
219
+
220
+ switch ( $type ) {
221
+ case 'all':
222
+ $text = _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $count, 'themes' );
223
+ break;
224
+ case 'update_disabled':
225
+ $text = _n( 'Updates Disabled <span class="count">(%s)</span>', 'Updates Disabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates' );
226
+ break;
227
+ case 'update_enabled':
228
+ $text = _n( 'Updates Enabled <span class="count">(%s)</span>', 'Updates Enabled <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates' );
229
+ break;
230
+ case 'automatic':
231
+ $text = _n( 'Automatic Updates <span class="count">(%s)</span>', 'Automatic Updates <span class="count">(%s)</span>', $count, 'stops-core-theme-and-plugin-updates' );
232
+ break;
233
+ }
234
+
235
+ if ( 'search' != $type ) {
236
+ $theme_url = MPSUM_Admin::get_url();
237
+ $query_args = array(
238
+ 'tab' => $this->tab,
239
+ 'theme_status' => $type
240
+ );
241
+
242
+ $status_links[$type] = sprintf( "<a href='%s' %s>%s</a>",
243
+ add_query_arg( $query_args, $theme_url ),
244
+ ( $type == $status ) ? ' class="current"' : '',
245
+ sprintf( $text, number_format_i18n( $count ) )
246
+ );
247
+ }
248
+ }
249
+
250
+ return $status_links;
251
+ }
252
+
253
+ protected function get_bulk_actions() {
254
+ global $status;
255
+
256
+ $actions = array();
257
+
258
+ $actions[ 'allow-update-selected' ] = esc_html__( 'Allow Updates', 'disable-plugin-and-theme-updates' );
259
+ $actions[ 'disallow-update-selected' ] = esc_html__( 'Disallow Updates', 'disable-plugin-and-theme-updates' );
260
+ $core_options = MPSUM_Updates_Manager::get_options( 'core' );
261
+ if ( isset( $core_options[ 'automatic_theme_updates' ] ) && 'individual' == $core_options[ 'automatic_theme_updates' ] ) {
262
+ $actions[ 'allow-automatic-selected' ] = esc_html__( 'Allow Automatic Updates', 'disable-plugin-and-theme-updates' );
263
+ $actions[ 'disallow-automatic-selected' ] = esc_html__( 'Disallow Automatic Updates', 'disable-plugin-and-theme-updates' );
264
+ }
265
+
266
+ return $actions;
267
+ }
268
+
269
+ public function display_rows() {
270
+ foreach ( $this->items as $theme )
271
+ $this->single_row( $theme );
272
+ }
273
+
274
+ /**
275
+ * @global string $status
276
+ * @global int $page
277
+ * @global string $s
278
+ * @global array $totals
279
+ * @param WP_Theme $theme
280
+ */
281
+ public function single_row( $theme ) {
282
+ $status = 'all';
283
+ $stylesheet = $theme->get_stylesheet();
284
+ remove_action( "after_theme_row_$stylesheet", 'wp_theme_update_row', 10, 2 );
285
+ $theme_key = urlencode( $stylesheet );
286
+
287
+ /**
288
+ * Filter the action links that show up under each theme row.
289
+ *
290
+ * @since 5.0.0
291
+ *
292
+ * @param array Array of action links
293
+ * @param WP_Theme $theme WP_Theme object
294
+ * @param string $status Status of the theme.
295
+ */
296
+ $actions = apply_filters( 'mpsum_theme_action_links', array(), $theme, 'all' );
297
+
298
+ $checkbox_id = "checkbox_" . md5( $theme->get('Name') );
299
+ $checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr( $stylesheet ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $theme->display('Name') . "</label>";
300
+
301
+ $id = sanitize_html_class( $theme->get_stylesheet() );
302
+ $class = 'active';
303
+ $theme_options = MPSUM_Updates_Manager::get_options( 'themes' );
304
+ if ( false !== $key = array_search( $stylesheet, $theme_options ) ) {
305
+ $class = 'inactive';
306
+ }
307
+ echo "<tr id='$id' class='$class'>";
308
+
309
+ list( $columns, $hidden ) = $this->get_column_info();
310
+
311
+ foreach ( $columns as $column_name => $column_display_name ) {
312
+ $style = '';
313
+ if ( in_array( $column_name, $hidden ) )
314
+ $style = ' style="display:none;"';
315
+
316
+ switch ( $column_name ) {
317
+ case 'cb':
318
+ echo "<th scope='row' class='check-column'>$checkbox</th>";
319
+ break;
320
+ case 'name':
321
+ echo "<td class='theme-title'$style><strong>" . $theme->display('Name') . "</strong>";
322
+ echo $this->row_actions( $actions, true );
323
+ echo "</td>";
324
+ break;
325
+ case 'description':
326
+ echo "<td class='column-description desc'$style>";
327
+ if ( $theme->errors() ) {
328
+ $pre = $status == 'broken' ? __( 'Broken Theme:' ) . ' ' : '';
329
+ echo '<p><strong class="attention">' . $pre . $theme->errors()->get_error_message() . '</strong></p>';
330
+ }
331
+ echo "<div class='theme-description'><p>" . $theme->display( 'Description' ) . "</p></div>
332
+ <div class='second theme-version-author-uri'>";
333
+
334
+ $theme_meta = array();
335
+
336
+ if ( $theme->get('Version') )
337
+ $theme_meta[] = sprintf( __( 'Version %s' ), $theme->display('Version') );
338
+
339
+ $theme_meta[] = sprintf( __( 'By %s' ), $theme->display('Author') );
340
+
341
+ if ( $theme->get('ThemeURI') )
342
+ $theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__( 'Visit theme homepage' ) . '">' . __( 'Visit Theme Site' ) . '</a>';
343
+
344
+ /**
345
+ * Filter the array of row meta for each theme in the Multisite themes
346
+ * list table.
347
+ *
348
+ * @since 3.1.0
349
+ *
350
+ * @param array $theme_meta An array of the theme's metadata,
351
+ * including the version, author, and
352
+ * theme URI.
353
+ * @param string $stylesheet Directory name of the theme.
354
+ * @param WP_Theme $theme WP_Theme object.
355
+ * @param string $status Status of the theme.
356
+ */
357
+ $theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $stylesheet, $theme, $status );
358
+ echo implode( ' | ', $theme_meta );
359
+
360
+ echo "</div></td>";
361
+ break;
362
+
363
+ default:
364
+ echo "<td class='$column_name column-$column_name'$style>";
365
+
366
+ /**
367
+ * Fires inside each custom column of the Multisite themes list table.
368
+ *
369
+ * @since 3.1.0
370
+ *
371
+ * @param string $column_name Name of the column.
372
+ * @param string $stylesheet Directory name of the theme.
373
+ * @param WP_Theme $theme Current WP_Theme object.
374
+ */
375
+ do_action( 'manage_themes_custom_column', $column_name, $stylesheet, $theme );
376
+ echo "</td>";
377
+ }
378
+ }
379
+
380
+ echo "</tr>";
381
+
382
+ if ( $this->is_site_themes )
383
+ remove_action( "after_theme_row_$stylesheet", 'wp_theme_update_row' );
384
+
385
+ /**
386
+ * Fires after each row in the Multisite themes list table.
387
+ *
388
+ * @since 3.1.0
389
+ *
390
+ * @param string $stylesheet Directory name of the theme.
391
+ * @param WP_Theme $theme Current WP_Theme object.
392
+ * @param string $status Status of the theme.
393
+ */
394
+ do_action( 'after_theme_row', $stylesheet, $theme, $status );
395
+
396
+ /**
397
+ * Fires after each specific row in the Multisite themes list table.
398
+ *
399
+ * The dynamic portion of the hook name, `$stylesheet`, refers to the
400
+ * directory name of the theme, most often synonymous with the template
401
+ * name of the theme.
402
+ *
403
+ * @since 3.5.0
404
+ *
405
+ * @param string $stylesheet Directory name of the theme.
406
+ * @param WP_Theme $theme Current WP_Theme object.
407
+ * @param string $status Status of the theme.
408
+ */
409
+ do_action( "after_theme_row_$stylesheet", $stylesheet, $theme, $status );
410
+ }
411
+ }
languages/disable-updates-manager.pot DELETED
@@ -1,122 +0,0 @@
1
- # Loco Gettext template
2
- #, fuzzy
3
- msgid ""
4
- msgstr ""
5
- "Project-Id-Version: Disable Updates Manager\n"
6
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/stops-core-theme-and-plugin-"
7
- "updates\n"
8
- "POT-Creation-Date: 2014-07-30 15:30:14+00:00\n"
9
- "POT-Revision-Date: Wed Dec 10 2014 12:20:38 GMT-0500 (Eastern Standard Time)\n"
10
- "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
11
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12
- "Language-Team: LANGUAGE <LL@li.org>\n"
13
- "Language: \n"
14
- "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n"
15
- "MIME-Version: 1.0\n"
16
- "Content-Type: text/plain; charset=UTF-8\n"
17
- "Content-Transfer-Encoding: 8bit\n"
18
- "X-Poedit-SourceCharset: UTF-8\n"
19
- "X-Poedit-Basepath: .\n"
20
- "X-Poedit-SearchPath-0: ..\n"
21
- "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
22
- "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
23
- "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
24
- "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
25
- "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
26
- "X-Generator: Loco - https://localise.biz/"
27
-
28
- #: Function.php:80
29
- msgid "Disable Updates Globally"
30
- msgstr ""
31
-
32
- #: Function.php:81
33
- msgid "Other"
34
- msgstr ""
35
-
36
- #: Function.php:83
37
- msgid "Disable Themes"
38
- msgstr ""
39
-
40
- #: Function.php:84
41
- msgid "Disable Plugins"
42
- msgstr ""
43
-
44
- #: Function.php:140 Function.php:901
45
- msgid "Disable Updates Manager"
46
- msgstr ""
47
-
48
- #: Function.php:160
49
- msgid "Configure"
50
- msgstr ""
51
-
52
- #: Function.php:677
53
- msgid "Overview"
54
- msgstr ""
55
-
56
- #: Function.php:683
57
- msgid "Layout"
58
- msgstr ""
59
-
60
- #: Function.php:689
61
- msgid "Tutorials"
62
- msgstr ""
63
-
64
- #: Function.php:695
65
- msgid "Help"
66
- msgstr ""
67
-
68
- #: Function.php:713
69
- msgid "Disable All Updates"
70
- msgstr ""
71
-
72
- #: Function.php:728
73
- msgid "Disable All Plugin Updates"
74
- msgstr ""
75
-
76
- #: Function.php:736
77
- msgid "Disable All Theme Updates"
78
- msgstr ""
79
-
80
- #: Function.php:744
81
- msgid "Disable WordPress Core Update"
82
- msgstr ""
83
-
84
- #: Function.php:761
85
- msgid "Remove Updates Page"
86
- msgstr ""
87
-
88
- #: Function.php:773
89
- msgid "Remove Out of Date Browser Nag"
90
- msgstr ""
91
-
92
- #: Function.php:786
93
- msgid "Remove WordPress Core Version from Footer"
94
- msgstr ""
95
-
96
- #: Function.php:798
97
- msgid "Disable Automatic Background Updates"
98
- msgstr ""
99
-
100
- #: Function.php:817
101
- msgid "Disable Themes Individually"
102
- msgstr ""
103
-
104
- #: Function.php:833
105
- msgid "Select themes to disable..."
106
- msgstr ""
107
-
108
- #: Function.php:862
109
- msgid "Disable Plugins Individually"
110
- msgstr ""
111
-
112
- #: Function.php:879
113
- msgid "Select plugins to disable..."
114
- msgstr ""
115
-
116
- #: Function.php:908
117
- msgid "You do not have permissions to access this page."
118
- msgstr ""
119
-
120
- #: Function.php:943
121
- msgid "Update Settings"
122
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/stops-core-theme-and-plugin-updates.pot ADDED
@@ -0,0 +1,641 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # WordPress Blank Pot
2
+ # Copyright (C) 2014 ...
3
+ # This file is distributed under the GNU General Public License v2 or later.
4
+ msgid ""
5
+ msgstr ""
6
+ "Project-Id-Version: Easy Updates Manager v1.0.0\n"
7
+ "Report-Msgid-Bugs-To: Ronald Huereca <ronalfy@gmail.com>\n"
8
+ "POT-Creation-Date: 2015-03-24 16:55-0600\n"
9
+ "PO-Revision-Date: \n"
10
+ "Last-Translator: Ronald Huereca <ron@ronalfy.com>\n"
11
+ "Language-Team: Ronald Huereca <ronalfy@gmail.com>\n"
12
+ "Language: en_US\n"
13
+ "MIME-Version: 1.0\n"
14
+ "Content-Type: text/plain; charset=UTF-8\n"
15
+ "Content-Transfer-Encoding: 8bit\n"
16
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
17
+ "X-Textdomain-Support: yesX-Generator: Poedit 1.6.4\n"
18
+ "X-Poedit-SourceCharset: UTF-8\n"
19
+ "X-Poedit-KeywordsList: __;_e;esc_html_e;esc_html_x:1,2c;esc_html__;"
20
+ "esc_attr_e;esc_attr_x:1,2c;esc_attr__;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;"
21
+ "_x:1,2c;_n:1,2;_n_noop:1,2;__ngettext:1,2;__ngettext_noop:1,2;_c,_nc:4c,1,2\n"
22
+ "X-Poedit-Basepath: ../\n"
23
+ "X-Generator: Poedit 1.5.3\n"
24
+ "X-Poedit-SearchPath-0: .\n"
25
+
26
+ #: includes/MPSUM_Admin.php:164 includes/MPSUM_Admin.php:180
27
+ msgid "Update Options"
28
+ msgstr ""
29
+
30
+ #: includes/MPSUM_Admin.php:198
31
+ msgid "Manage Updates"
32
+ msgstr ""
33
+
34
+ #: includes/MPSUM_Admin.php:205 includes/MPSUM_Admin_Help.php:51
35
+ msgid "General"
36
+ msgstr ""
37
+
38
+ #: includes/MPSUM_Admin.php:211 includes/MPSUM_Admin_Help.php:52
39
+ msgid "Plugins"
40
+ msgstr ""
41
+
42
+ #: includes/MPSUM_Admin.php:217 includes/MPSUM_Admin_Help.php:53
43
+ msgid "Themes"
44
+ msgstr ""
45
+
46
+ #: includes/MPSUM_Admin.php:223 includes/MPSUM_Admin_Help.php:54
47
+ msgid "Advanced"
48
+ msgstr ""
49
+
50
+ #: includes/MPSUM_Admin.php:279
51
+ msgid "Configure"
52
+ msgstr ""
53
+
54
+ #: includes/MPSUM_Admin_Advanced.php:113 includes/MPSUM_Admin_Core.php:130
55
+ msgid "Options saved."
56
+ msgstr ""
57
+
58
+ #: includes/MPSUM_Admin_Advanced.php:122
59
+ msgid "Exclude Users"
60
+ msgstr ""
61
+
62
+ #: includes/MPSUM_Admin_Advanced.php:123
63
+ msgid ""
64
+ "Select which users to be excluded from the settings of this plugin. Default "
65
+ "WordPress behavior will be used."
66
+ msgstr ""
67
+
68
+ #: includes/MPSUM_Admin_Advanced.php:124
69
+ msgid ""
70
+ "This option is useful if, for example, you would like to disable updates, "
71
+ "but have a user account that can still update WordPress."
72
+ msgstr ""
73
+
74
+ #: includes/MPSUM_Admin_Advanced.php:127
75
+ msgid "Users to be Excluded"
76
+ msgstr ""
77
+
78
+ #: includes/MPSUM_Admin_Advanced.php:166
79
+ msgid "Save Users"
80
+ msgstr ""
81
+
82
+ #: includes/MPSUM_Admin_Advanced.php:171
83
+ msgid "Reset Options"
84
+ msgstr ""
85
+
86
+ #: includes/MPSUM_Admin_Advanced.php:172
87
+ msgid ""
88
+ "This will reset all options to as if you have just installed the plugin."
89
+ msgstr ""
90
+
91
+ #: includes/MPSUM_Admin_Advanced.php:177
92
+ msgid "Reset All Options"
93
+ msgstr ""
94
+
95
+ #: includes/MPSUM_Admin_Core.php:139
96
+ msgid "Global Settings"
97
+ msgstr ""
98
+
99
+ #: includes/MPSUM_Admin_Core.php:142
100
+ msgid "All Updates"
101
+ msgstr ""
102
+
103
+ #: includes/MPSUM_Admin_Core.php:144 includes/MPSUM_Admin_Core.php:152
104
+ #: includes/MPSUM_Admin_Core.php:160 includes/MPSUM_Admin_Core.php:167
105
+ #: includes/MPSUM_Admin_Core.php:174 includes/MPSUM_Admin_Core.php:185
106
+ #: includes/MPSUM_Admin_Core.php:193 includes/MPSUM_Admin_Core.php:201
107
+ #: includes/MPSUM_Admin_Core.php:209 includes/MPSUM_Admin_Core.php:218
108
+ #: includes/MPSUM_Admin_Core.php:227 includes/MPSUM_Admin_Core.php:238
109
+ #: includes/MPSUM_Admin_Core.php:249 includes/MPSUM_Admin_Core.php:257
110
+ msgid "Enabled"
111
+ msgstr ""
112
+
113
+ #: includes/MPSUM_Admin_Core.php:145 includes/MPSUM_Admin_Core.php:153
114
+ #: includes/MPSUM_Admin_Core.php:161 includes/MPSUM_Admin_Core.php:168
115
+ #: includes/MPSUM_Admin_Core.php:175 includes/MPSUM_Admin_Core.php:186
116
+ #: includes/MPSUM_Admin_Core.php:194 includes/MPSUM_Admin_Core.php:202
117
+ #: includes/MPSUM_Admin_Core.php:210 includes/MPSUM_Admin_Core.php:219
118
+ #: includes/MPSUM_Admin_Core.php:228 includes/MPSUM_Admin_Core.php:239
119
+ #: includes/MPSUM_Admin_Core.php:250 includes/MPSUM_Admin_Core.php:258
120
+ msgid "Disabled"
121
+ msgstr ""
122
+
123
+ #: includes/MPSUM_Admin_Core.php:146
124
+ msgid "If this option is disabled, this will override all settings."
125
+ msgstr ""
126
+
127
+ #: includes/MPSUM_Admin_Core.php:150
128
+ msgid "WordPress Core Updates"
129
+ msgstr ""
130
+
131
+ #: includes/MPSUM_Admin_Core.php:154
132
+ msgid "Prevents WordPress from showing it needs to be updated."
133
+ msgstr ""
134
+
135
+ #: includes/MPSUM_Admin_Core.php:158
136
+ msgid "All Plugin Updates"
137
+ msgstr ""
138
+
139
+ #: includes/MPSUM_Admin_Core.php:165
140
+ msgid "All Theme Updates"
141
+ msgstr ""
142
+
143
+ #: includes/MPSUM_Admin_Core.php:172
144
+ msgid "All Translation Updates"
145
+ msgstr ""
146
+
147
+ #: includes/MPSUM_Admin_Core.php:179
148
+ msgid "Automatic Updates"
149
+ msgstr ""
150
+
151
+ #: includes/MPSUM_Admin_Core.php:180
152
+ msgid ""
153
+ "These options will enable or disable automatic updates (background updates) "
154
+ "of certain parts of WordPress."
155
+ msgstr ""
156
+
157
+ #: includes/MPSUM_Admin_Core.php:183
158
+ msgid "Major Releases"
159
+ msgstr ""
160
+
161
+ #: includes/MPSUM_Admin_Core.php:187
162
+ msgid "Automatically update to major releases (e.g., 4.1, 4.2, 4.3)."
163
+ msgstr ""
164
+
165
+ #: includes/MPSUM_Admin_Core.php:191
166
+ msgid "Minor Releases"
167
+ msgstr ""
168
+
169
+ #: includes/MPSUM_Admin_Core.php:195
170
+ msgid "Automatically update to minor releases (e.g., 4.1.1, 4.1.2, 4.1.3)."
171
+ msgstr ""
172
+
173
+ #: includes/MPSUM_Admin_Core.php:199
174
+ msgid "Development Updates"
175
+ msgstr ""
176
+
177
+ #: includes/MPSUM_Admin_Core.php:203
178
+ msgid "Update automatically to Bleeding Edge releases."
179
+ msgstr ""
180
+
181
+ #: includes/MPSUM_Admin_Core.php:207
182
+ msgid "Automatic Plugin Updates"
183
+ msgstr ""
184
+
185
+ #: includes/MPSUM_Admin_Core.php:211 includes/MPSUM_Admin_Core.php:220
186
+ msgid "Select Individually"
187
+ msgstr ""
188
+
189
+ #: includes/MPSUM_Admin_Core.php:212
190
+ msgid ""
191
+ "Automatically update your plugins. Select always on, always off, or select "
192
+ "plugins individually."
193
+ msgstr ""
194
+
195
+ #: includes/MPSUM_Admin_Core.php:216
196
+ msgid "Automatic Theme Updates"
197
+ msgstr ""
198
+
199
+ #: includes/MPSUM_Admin_Core.php:221
200
+ msgid ""
201
+ "Automatically update your themes. Select always on, always off, or select "
202
+ "themes individually."
203
+ msgstr ""
204
+
205
+ #: includes/MPSUM_Admin_Core.php:225
206
+ msgid "Translation Updates"
207
+ msgstr ""
208
+
209
+ #: includes/MPSUM_Admin_Core.php:229
210
+ msgid "Automatically update your translations."
211
+ msgstr ""
212
+
213
+ #: includes/MPSUM_Admin_Core.php:233
214
+ msgid "Notifications"
215
+ msgstr ""
216
+
217
+ #: includes/MPSUM_Admin_Core.php:236
218
+ msgid "Core Update E-mails"
219
+ msgstr ""
220
+
221
+ #: includes/MPSUM_Admin_Core.php:240
222
+ msgid ""
223
+ "Disable e-mails that are sent when your site has been upgraded automatically."
224
+ msgstr ""
225
+
226
+ #: includes/MPSUM_Admin_Core.php:244
227
+ msgid "Miscellaneous"
228
+ msgstr ""
229
+
230
+ #: includes/MPSUM_Admin_Core.php:247
231
+ msgid "Browser Nag"
232
+ msgstr ""
233
+
234
+ #: includes/MPSUM_Admin_Core.php:251
235
+ msgid "Removes the browser nag for people using older browsers."
236
+ msgstr ""
237
+
238
+ #: includes/MPSUM_Admin_Core.php:255
239
+ msgid "WordPress Version in Footer"
240
+ msgstr ""
241
+
242
+ #: includes/MPSUM_Admin_Core.php:259
243
+ msgid "Removes the WordPress version in the footer."
244
+ msgstr ""
245
+
246
+ #: includes/MPSUM_Admin_Core.php:267
247
+ msgid "Save Changes"
248
+ msgstr ""
249
+
250
+ #: includes/MPSUM_Admin_Core.php:269
251
+ msgid "Reset to Defaults"
252
+ msgstr ""
253
+
254
+ #: includes/MPSUM_Admin_Help.php:27
255
+ msgid ""
256
+ "This is the Easy Updates Manager settings help tab. In here you will find "
257
+ "helpful information on what Easy Updates Manager does and how to use it."
258
+ msgstr ""
259
+
260
+ #: includes/MPSUM_Admin_Help.php:29
261
+ msgid "Please Note!"
262
+ msgstr ""
263
+
264
+ #: includes/MPSUM_Admin_Help.php:29
265
+ msgid ""
266
+ "If either your WordPress core, theme, or plugins get too out of date, you "
267
+ "may run into compatibility problems. Check the capability tab for more "
268
+ "information."
269
+ msgstr ""
270
+
271
+ #: includes/MPSUM_Admin_Help.php:31
272
+ msgid "Please see our Wiki for documentation and videos."
273
+ msgstr ""
274
+
275
+ #: includes/MPSUM_Admin_Help.php:34
276
+ msgid "Our Website"
277
+ msgstr ""
278
+
279
+ #: includes/MPSUM_Admin_Help.php:35
280
+ msgid "Support on WordPress"
281
+ msgstr ""
282
+
283
+ #: includes/MPSUM_Admin_Help.php:36
284
+ msgid "GitHub Repository"
285
+ msgstr ""
286
+
287
+ #: includes/MPSUM_Admin_Help.php:37
288
+ msgid "Official Documentation"
289
+ msgstr ""
290
+
291
+ #: includes/MPSUM_Admin_Help.php:50
292
+ msgid "You will see four tabs where you can configure the update options."
293
+ msgstr ""
294
+
295
+ #: includes/MPSUM_Admin_Help.php:51
296
+ msgid ""
297
+ "Use this screen to finely tune which updates and automatic updates you would "
298
+ "like to see."
299
+ msgstr ""
300
+
301
+ #: includes/MPSUM_Admin_Help.php:52
302
+ msgid ""
303
+ "If plugin updates are enabled and/or automatic updates for plugins are "
304
+ "enabled, you can configure which plugins will receive updates and/or "
305
+ "automatic updates."
306
+ msgstr ""
307
+
308
+ #: includes/MPSUM_Admin_Help.php:53
309
+ msgid ""
310
+ "If theme updates are enabled and/or automatic updates for themes are "
311
+ "enabled, you can configure which themes will receive updates and/or "
312
+ "automatic updates."
313
+ msgstr ""
314
+
315
+ #: includes/MPSUM_Admin_Help.php:54
316
+ msgid ""
317
+ "Reset all options or allow certain users to see all updates regardless of "
318
+ "what settings you have set."
319
+ msgstr ""
320
+
321
+ #: includes/MPSUM_Admin_Help.php:79
322
+ msgid "Contributors:"
323
+ msgstr ""
324
+
325
+ #: includes/MPSUM_Admin_Help.php:94
326
+ msgid ""
327
+ "WordPress encourages you to update your plugins, themes, and core to make "
328
+ "sure that there are no bugs. Even though you most likely want to disable all "
329
+ "the updates and never think about updating again, you should still consider "
330
+ "updating every once in a while to avoid major bugs and errors on your "
331
+ "WordPress website."
332
+ msgstr ""
333
+
334
+ #: includes/MPSUM_Admin_Help.php:95
335
+ msgid "This plugin is tested so there are no known major issues."
336
+ msgstr ""
337
+
338
+ #: includes/MPSUM_Admin_Help.php:97
339
+ msgid "Tested with WordPress 4.1.1."
340
+ msgstr ""
341
+
342
+ #: includes/MPSUM_Admin_Help.php:98
343
+ msgid "Tested with popular plugins to ensure that there are no conflicts."
344
+ msgstr ""
345
+
346
+ #: includes/MPSUM_Admin_Help.php:99
347
+ msgid "Tested with popular themes to ensure that there are no conflicts."
348
+ msgstr ""
349
+
350
+ #: includes/MPSUM_Admin_Help.php:105
351
+ msgid "Overview"
352
+ msgstr ""
353
+
354
+ #: includes/MPSUM_Admin_Help.php:111
355
+ msgid "Tabs"
356
+ msgstr ""
357
+
358
+ #: includes/MPSUM_Admin_Help.php:117
359
+ msgid "Documentation"
360
+ msgstr ""
361
+
362
+ #: includes/MPSUM_Admin_Help.php:123
363
+ msgid "Capability"
364
+ msgstr ""
365
+
366
+ #: includes/MPSUM_Admin_Help.php:129
367
+ msgid "Troubleshooting"
368
+ msgstr ""
369
+
370
+ #: includes/MPSUM_Admin_Plugins.php:135 includes/MPSUM_Admin_Themes.php:252
371
+ #: includes/MPSUM_Plugins_List_Table.php:248
372
+ #: includes/MPSUM_Themes_List_Table.php:258
373
+ msgid "Allow Updates"
374
+ msgstr ""
375
+
376
+ #: includes/MPSUM_Admin_Plugins.php:139 includes/MPSUM_Admin_Themes.php:257
377
+ #: includes/MPSUM_Plugins_List_Table.php:249
378
+ #: includes/MPSUM_Themes_List_Table.php:259
379
+ msgid "Disallow Updates"
380
+ msgstr ""
381
+
382
+ #: includes/MPSUM_Admin_Plugins.php:148 includes/MPSUM_Admin_Themes.php:266
383
+ #: includes/MPSUM_Plugins_List_Table.php:253
384
+ #: includes/MPSUM_Themes_List_Table.php:263
385
+ msgid "Disallow Automatic Updates"
386
+ msgstr ""
387
+
388
+ #: includes/MPSUM_Admin_Plugins.php:152 includes/MPSUM_Admin_Themes.php:270
389
+ msgid "Enable Automatic Updates"
390
+ msgstr ""
391
+
392
+ #: includes/MPSUM_Admin_Plugins.php:237
393
+ msgid "The selected plugin updates have been enabled."
394
+ msgstr ""
395
+
396
+ #: includes/MPSUM_Admin_Plugins.php:239
397
+ msgid "The selected plugin updates have been disabled."
398
+ msgstr ""
399
+
400
+ #: includes/MPSUM_Admin_Plugins.php:255
401
+ msgid "Plugin Update Options"
402
+ msgstr ""
403
+
404
+ #: includes/MPSUM_Admin_Plugins.php:259
405
+ msgid "All plugin updates have been disabled."
406
+ msgstr ""
407
+
408
+ #: includes/MPSUM_Admin_Themes.php:198
409
+ msgid "The selected theme updates have been enabled."
410
+ msgstr ""
411
+
412
+ #: includes/MPSUM_Admin_Themes.php:200
413
+ msgid "The selected theme updates have been disabled."
414
+ msgstr ""
415
+
416
+ #: includes/MPSUM_Admin_Themes.php:217
417
+ msgid "Theme Update Options"
418
+ msgstr ""
419
+
420
+ #: includes/MPSUM_Admin_Themes.php:222
421
+ msgid "All theme updates have been disabled."
422
+ msgstr ""
423
+
424
+ #: includes/MPSUM_List_Table.php:130
425
+ msgid "List View"
426
+ msgstr ""
427
+
428
+ #: includes/MPSUM_List_Table.php:131
429
+ msgid "Excerpt View"
430
+ msgstr ""
431
+
432
+ #: includes/MPSUM_List_Table.php:287
433
+ msgid "No items found."
434
+ msgstr ""
435
+
436
+ #: includes/MPSUM_List_Table.php:413
437
+ msgid "Select bulk action"
438
+ msgstr ""
439
+
440
+ #: includes/MPSUM_List_Table.php:415
441
+ msgid "Bulk Actions"
442
+ msgstr ""
443
+
444
+ #: includes/MPSUM_List_Table.php:425
445
+ msgid "Apply"
446
+ msgstr ""
447
+
448
+ #: includes/MPSUM_List_Table.php:513
449
+ msgid "Filter by date"
450
+ msgstr ""
451
+
452
+ #: includes/MPSUM_List_Table.php:515
453
+ msgid "All dates"
454
+ msgstr ""
455
+
456
+ #: includes/MPSUM_List_Table.php:528
457
+ #, php-format
458
+ msgid "%1$s %2$d"
459
+ msgstr ""
460
+
461
+ #: includes/MPSUM_List_Table.php:575
462
+ #, php-format
463
+ msgid "%s pending"
464
+ msgstr ""
465
+
466
+ #: includes/MPSUM_List_Table.php:654 includes/MPSUM_List_Table.php:1076
467
+ #, php-format
468
+ msgid "1 item"
469
+ msgid_plural "%s items"
470
+ msgstr[0] ""
471
+ msgstr[1] ""
472
+
473
+ #: includes/MPSUM_List_Table.php:673
474
+ msgid "Go to the first page"
475
+ msgstr ""
476
+
477
+ #: includes/MPSUM_List_Table.php:680
478
+ msgid "Go to the previous page"
479
+ msgstr ""
480
+
481
+ #: includes/MPSUM_List_Table.php:689
482
+ msgid "Select Page"
483
+ msgstr ""
484
+
485
+ #: includes/MPSUM_List_Table.php:690
486
+ msgid "Current page"
487
+ msgstr ""
488
+
489
+ #: includes/MPSUM_List_Table.php:696
490
+ #, php-format
491
+ msgctxt "paging"
492
+ msgid "%1$s of %2$s"
493
+ msgstr ""
494
+
495
+ #: includes/MPSUM_List_Table.php:700
496
+ msgid "Go to the next page"
497
+ msgstr ""
498
+
499
+ #: includes/MPSUM_List_Table.php:707
500
+ msgid "Go to the last page"
501
+ msgstr ""
502
+
503
+ #: includes/MPSUM_List_Table.php:844
504
+ msgid "Select All"
505
+ msgstr ""
506
+
507
+ #: includes/MPSUM_Plugins_List_Table.php:184
508
+ msgid "No plugins found."
509
+ msgstr ""
510
+
511
+ #: includes/MPSUM_Plugins_List_Table.php:186
512
+ msgid "You do not appear to have any plugins available at this time."
513
+ msgstr ""
514
+
515
+ #: includes/MPSUM_Plugins_List_Table.php:194
516
+ msgid "Plugin"
517
+ msgstr ""
518
+
519
+ #: includes/MPSUM_Plugins_List_Table.php:195
520
+ #: includes/MPSUM_Themes_List_Table.php:204
521
+ msgid "Description"
522
+ msgstr ""
523
+
524
+ #: includes/MPSUM_Plugins_List_Table.php:213
525
+ #, php-format
526
+ msgctxt "plugins"
527
+ msgid "All <span class=\"count\">(%s)</span>"
528
+ msgid_plural "All <span class=\"count\">(%s)</span>"
529
+ msgstr[0] ""
530
+ msgstr[1] ""
531
+
532
+ #: includes/MPSUM_Plugins_List_Table.php:216
533
+ #: includes/MPSUM_Themes_List_Table.php:228
534
+ #, php-format
535
+ msgid "Updates Enabled <span class=\"count\">(%s)</span>"
536
+ msgid_plural "Updates Enabled <span class=\"count\">(%s)</span>"
537
+ msgstr[0] ""
538
+ msgstr[1] ""
539
+
540
+ #: includes/MPSUM_Plugins_List_Table.php:219
541
+ #: includes/MPSUM_Themes_List_Table.php:225
542
+ #, php-format
543
+ msgid "Updates Disabled <span class=\"count\">(%s)</span>"
544
+ msgid_plural "Updates Disabled <span class=\"count\">(%s)</span>"
545
+ msgstr[0] ""
546
+ msgstr[1] ""
547
+
548
+ #: includes/MPSUM_Plugins_List_Table.php:222
549
+ #: includes/MPSUM_Themes_List_Table.php:231
550
+ #, php-format
551
+ msgid "Automatic Updates <span class=\"count\">(%s)</span>"
552
+ msgid_plural "Automatic Updates <span class=\"count\">(%s)</span>"
553
+ msgstr[0] ""
554
+ msgstr[1] ""
555
+
556
+ #: includes/MPSUM_Plugins_List_Table.php:252
557
+ #: includes/MPSUM_Themes_List_Table.php:262
558
+ msgid "Allow Automatic Updates"
559
+ msgstr ""
560
+
561
+ #: includes/MPSUM_Plugins_List_Table.php:287
562
+ msgid "Clear List"
563
+ msgstr ""
564
+
565
+ #: includes/MPSUM_Plugins_List_Table.php:289
566
+ #, php-format
567
+ msgid "Files in the <code>%s</code> directory are executed automatically."
568
+ msgstr ""
569
+
570
+ #: includes/MPSUM_Plugins_List_Table.php:291
571
+ #, php-format
572
+ msgid ""
573
+ "Drop-ins are advanced plugins in the <code>%s</code> directory that replace "
574
+ "WordPress functionality when present."
575
+ msgstr ""
576
+
577
+ #: includes/MPSUM_Plugins_List_Table.php:344
578
+ #, php-format
579
+ msgid "Select %s"
580
+ msgstr ""
581
+
582
+ #: includes/MPSUM_Plugins_List_Table.php:376
583
+ #: includes/MPSUM_Themes_List_Table.php:337
584
+ #, php-format
585
+ msgid "Version %s"
586
+ msgstr ""
587
+
588
+ #: includes/MPSUM_Plugins_List_Table.php:381
589
+ #: includes/MPSUM_Themes_List_Table.php:339
590
+ #, php-format
591
+ msgid "By %s"
592
+ msgstr ""
593
+
594
+ #: includes/MPSUM_Plugins_List_Table.php:389
595
+ #, php-format
596
+ msgid "More information about %s"
597
+ msgstr ""
598
+
599
+ #: includes/MPSUM_Plugins_List_Table.php:391
600
+ msgid "View details"
601
+ msgstr ""
602
+
603
+ #: includes/MPSUM_Plugins_List_Table.php:396
604
+ msgid "Visit plugin site"
605
+ msgstr ""
606
+
607
+ #: includes/MPSUM_Themes_List_Table.php:193
608
+ msgid "No themes found."
609
+ msgstr ""
610
+
611
+ #: includes/MPSUM_Themes_List_Table.php:195
612
+ msgid "You do not appear to have any themes available at this time."
613
+ msgstr ""
614
+
615
+ #: includes/MPSUM_Themes_List_Table.php:203
616
+ msgid "Theme"
617
+ msgstr ""
618
+
619
+ #: includes/MPSUM_Themes_List_Table.php:222
620
+ #, php-format
621
+ msgctxt "themes"
622
+ msgid "All <span class=\"count\">(%s)</span>"
623
+ msgid_plural "All <span class=\"count\">(%s)</span>"
624
+ msgstr[0] ""
625
+ msgstr[1] ""
626
+
627
+ #: includes/MPSUM_Themes_List_Table.php:299
628
+ msgid "Select"
629
+ msgstr ""
630
+
631
+ #: includes/MPSUM_Themes_List_Table.php:328
632
+ msgid "Broken Theme:"
633
+ msgstr ""
634
+
635
+ #: includes/MPSUM_Themes_List_Table.php:342
636
+ msgid "Visit theme homepage"
637
+ msgstr ""
638
+
639
+ #: includes/MPSUM_Themes_List_Table.php:342
640
+ msgid "Visit Theme Site"
641
+ msgstr ""
License.txt → license.txt RENAMED
@@ -1,343 +1,338 @@
1
- GNU GENERAL PUBLIC LICENSE
2
- Version 2, June 1991
3
-
4
- Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
5
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
- Everyone is permitted to copy and distribute verbatim copies
7
- of this license document, but changing it is not allowed.
8
-
9
- Preamble
10
-
11
- The licenses for most software are designed to take away your
12
- freedom to share and change it. By contrast, the GNU General Public
13
- License is intended to guarantee your freedom to share and change free
14
- software--to make sure the software is free for all its users. This
15
- General Public License applies to most of the Free Software
16
- Foundation's software and to any other program whose authors commit to
17
- using it. (Some other Free Software Foundation software is covered by
18
- the GNU Lesser General Public License instead.) You can apply it to
19
- your programs, too.
20
-
21
- When we speak of free software, we are referring to freedom, not
22
- price. Our General Public Licenses are designed to make sure that you
23
- have the freedom to distribute copies of free software (and charge for
24
- this service if you wish), that you receive source code or can get it
25
- if you want it, that you can change the software or use pieces of it
26
- in new free programs; and that you know you can do these things.
27
-
28
- To protect your rights, we need to make restrictions that forbid
29
- anyone to deny you these rights or to ask you to surrender the rights.
30
- These restrictions translate to certain responsibilities for you if you
31
- distribute copies of the software, or if you modify it.
32
-
33
- For example, if you distribute copies of such a program, whether
34
- gratis or for a fee, you must give the recipients all the rights that
35
- you have. You must make sure that they, too, receive or can get the
36
- source code. And you must show them these terms so they know their
37
- rights.
38
-
39
- We protect your rights with two steps: (1) copyright the software, and
40
- (2) offer you this license which gives you legal permission to copy,
41
- distribute and/or modify the software.
42
-
43
- Also, for each author's protection and ours, we want to make certain
44
- that everyone understands that there is no warranty for this free
45
- software. If the software is modified by someone else and passed on, we
46
- want its recipients to know that what they have is not the original, so
47
- that any problems introduced by others will not reflect on the original
48
- authors' reputations.
49
-
50
- Finally, any free program is threatened constantly by software
51
- patents. We wish to avoid the danger that re-distributors of a free
52
- program will individually obtain patent licenses, in effect making the
53
- program proprietary. To prevent this, we have made it clear that any
54
- patent must be licensed for everyone's free use or not licensed at all.
55
-
56
- The precise terms and conditions for copying, distribution and
57
- modification follow.
58
-
59
- GNU GENERAL PUBLIC LICENSE
60
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
-
62
- 0. This License applies to any program or other work which contains
63
- a notice placed by the copyright holder saying it may be distributed
64
- under the terms of this General Public License. The "Program", below,
65
- refers to any such program or work, and a "work based on the Program"
66
- means either the Program or any derivative work under copyright law:
67
- that is to say, a work containing the Program or a portion of it,
68
- either verbatim or with modifications and/or translated into another
69
- language. (Hereinafter, translation is included without limitation in
70
- the term "modification".) Each licensee is addressed as "you".
71
-
72
- Activities other than copying, distribution and modification are not
73
- covered by this License; they are outside its scope. The act of
74
- running the Program is not restricted, and the output from the Program
75
- is covered only if its contents constitute a work based on the
76
- Program (independent of having been made by running the Program).
77
- Whether that is true depends on what the Program does.
78
-
79
- 1. You may copy and distribute verbatim copies of the Program's
80
- source code as you receive it, in any medium, provided that you
81
- conspicuously and appropriately publish on each copy an appropriate
82
- copyright notice and disclaimer of warranty; keep intact all the
83
- notices that refer to this License and to the absence of any warranty;
84
- and give any other recipients of the Program a copy of this License
85
- along with the Program.
86
-
87
- You may charge a fee for the physical act of transferring a copy, and
88
- you may at your option offer warranty protection in exchange for a fee.
89
-
90
- 2. You may modify your copy or copies of the Program or any portion
91
- of it, thus forming a work based on the Program, and copy and
92
- distribute such modifications or work under the terms of Section 1
93
- above, provided that you also meet all of these conditions:
94
-
95
- a) You must cause the modified files to carry prominent notices
96
- stating that you changed the files and the date of any change.
97
-
98
- b) You must cause any work that you distribute or publish, that in
99
- whole or in part contains or is derived from the Program or any
100
- part thereof, to be licensed as a whole at no charge to all third
101
- parties under the terms of this License.
102
-
103
- c) If the modified program normally reads commands interactively
104
- when run, you must cause it, when started running for such
105
- interactive use in the most ordinary way, to print or display an
106
- announcement including an appropriate copyright notice and a
107
- notice that there is no warranty (or else, saying that you provide
108
- a warranty) and that users may redistribute the program under
109
- these conditions, and telling the user how to view a copy of this
110
- License. (Exception: if the Program itself is interactive but
111
- does not normally print such an announcement, your work based on
112
- the Program is not required to print an announcement.)
113
-
114
- These requirements apply to the modified work as a whole. If
115
- identifiable sections of that work are not derived from the Program,
116
- and can be reasonably considered independent and separate works in
117
- themselves, then this License, and its terms, do not apply to those
118
- sections when you distribute them as separate works. But when you
119
- distribute the same sections as part of a whole which is a work based
120
- on the Program, the distribution of the whole must be on the terms of
121
- this License, whose permissions for other licensees extend to the
122
- entire whole, and thus to each and every part regardless of who wrote it.
123
-
124
- Thus, it is not the intent of this section to claim rights or contest
125
- your rights to work written entirely by you; rather, the intent is to
126
- exercise the right to control the distribution of derivative or
127
- collective works based on the Program.
128
-
129
- In addition, mere aggregation of another work not based on the Program
130
- with the Program (or with a work based on the Program) on a volume of
131
- a storage or distribution medium does not bring the other work under
132
- the scope of this License.
133
-
134
- 3. You may copy and distribute the Program (or a work based on it,
135
- under Section 2) in object code or executable form under the terms of
136
- Sections 1 and 2 above provided that you also do one of the following:
137
-
138
- a) Accompany it with the complete corresponding machine-readable
139
- source code, which must be distributed under the terms of Sections
140
- 1 and 2 above on a medium customarily used for software interchange; or,
141
-
142
- b) Accompany it with a written offer, valid for at least three
143
- years, to give any third party, for a charge no more than your
144
- cost of physically performing source distribution, a complete
145
- machine-readable copy of the corresponding source code, to be
146
- distributed under the terms of Sections 1 and 2 above on a medium
147
- customarily used for software interchange; or,
148
-
149
- c) Accompany it with the information you received as to the offer
150
- to distribute corresponding source code. (This alternative is
151
- allowed only for non-commercial distribution and only if you
152
- received the program in object code or executable form with such
153
- an offer, in accord with Subsection b above.)
154
-
155
- The source code for a work means the preferred form of the work for
156
- making modifications to it. For an executable work, complete source
157
- code means all the source code for all modules it contains, plus any
158
- associated interface definition files, plus the scripts used to
159
- control compilation and installation of the executable. However, as a
160
- special exception, the source code distributed need not include
161
- anything that is normally distributed (in either source or binary
162
- form) with the major components (compiler, kernel, and so on) of the
163
- operating system on which the executable runs, unless that component
164
- itself accompanies the executable.
165
-
166
- If distribution of executable or object code is made by offering
167
- access to copy from a designated place, then offering equivalent
168
- access to copy the source code from the same place counts as
169
- distribution of the source code, even though third parties are not
170
- compelled to copy the source along with the object code.
171
-
172
- 4. You may not copy, modify, sub-license, or distribute the Program
173
- except as expressly provided under this License. Any attempt
174
- otherwise to copy, modify, sub-license or distribute the Program is
175
- void, and will automatically terminate your rights under this License.
176
- However, parties who have received copies, or rights, from you under
177
- this License will not have their licenses terminated so long as such
178
- parties remain in full compliance.
179
-
180
- 5. You are not required to accept this License, since you have not
181
- signed it. However, nothing else grants you permission to modify or
182
- distribute the Program or its derivative works. These actions are
183
- prohibited by law if you do not accept this License. Therefore, by
184
- modifying or distributing the Program (or any work based on the
185
- Program), you indicate your acceptance of this License to do so, and
186
- all its terms and conditions for copying, distributing or modifying
187
- the Program or works based on it.
188
-
189
- 6. Each time you redistribute the Program (or any work based on the
190
- Program), the recipient automatically receives a license from the
191
- original licensor to copy, distribute or modify the Program subject to
192
- these terms and conditions. You may not impose any further
193
- restrictions on the recipients' exercise of the rights granted herein.
194
- You are not responsible for enforcing compliance by third parties to
195
- this License.
196
-
197
- 7. If, as a consequence of a court judgement or allegation of patent
198
- infringement or for any other reason (not limited to patent issues),
199
- conditions are imposed on you (whether by court order, agreement or
200
- otherwise) that contradict the conditions of this License, they do not
201
- excuse you from the conditions of this License. If you cannot
202
- distribute so as to satisfy simultaneously your obligations under this
203
- License and any other pertinent obligations, then as a consequence you
204
- may not distribute the Program at all. For example, if a patent
205
- license would not permit royalty-free redistribution of the Program by
206
- all those who receive copies directly or indirectly through you, then
207
- the only way you could satisfy both it and this License would be to
208
- refrain entirely from distribution of the Program.
209
-
210
- If any portion of this section is held invalid or unenforceable under
211
- any particular circumstance, the balance of the section is intended to
212
- apply and the section as a whole is intended to apply in other
213
- circumstances.
214
-
215
- It is not the purpose of this section to induce you to infringe any
216
- patents or other property right claims or to contest validity of any
217
- such claims; this section has the sole purpose of protecting the
218
- integrity of the free software distribution system, which is
219
- implemented by public license practices. Many people have made
220
- generous contributions to the wide range of software distributed
221
- through that system in reliance on consistent application of that
222
- system; it is up to the author/donor to decide if he or she is willing
223
- to distribute software through any other system and a licensee cannot
224
- impose that choice.
225
-
226
- This section is intended to make thoroughly clear what is believed to
227
- be a consequence of the rest of this License.
228
-
229
- 8. If the distribution and/or use of the Program is restricted in
230
- certain countries either by patents or by copyrighted interfaces, the
231
- original copyright holder who places the Program under this License
232
- may add an explicit geographical distribution limitation excluding
233
- those countries, so that distribution is permitted only in or among
234
- countries not thus excluded. In such case, this License incorporates
235
- the limitation as if written in the body of this License.
236
-
237
- 9. The Free Software Foundation may publish revised and/or new versions
238
- of the General Public License from time to time. Such new versions will
239
- be similar in spirit to the present version, but may differ in detail to
240
- address new problems or concerns.
241
-
242
- Each version is given a distinguishing version number. If the Program
243
- specifies a version number of this License which applies to it and "any
244
- later version", you have the option of following the terms and conditions
245
- either of that version or of any later version published by the Free
246
- Software Foundation. If the Program does not specify a version number of
247
- this License, you may choose any version ever published by the Free Software
248
- Foundation.
249
-
250
- 10. If you wish to incorporate parts of the Program into other free
251
- programs whose distribution conditions are different, write to the author
252
- to ask for permission. For software which is copyrighted by the Free
253
- Software Foundation, write to the Free Software Foundation; we sometimes
254
- make exceptions for this. Our decision will be guided by the two goals
255
- of preserving the free status of all derivatives of our free software and
256
- of promoting the sharing and reuse of software generally.
257
-
258
- NO WARRANTY
259
-
260
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
- REPAIR OR CORRECTION.
269
-
270
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
- POSSIBILITY OF SUCH DAMAGES.
279
-
280
- END OF TERMS AND CONDITIONS
281
-
282
- How to Apply These Terms to Your New Programs
283
-
284
- If you develop a new program, and you want it to be of the greatest
285
- possible use to the public, the best way to achieve this is to make it
286
- free software which everyone can redistribute and change under these terms.
287
-
288
- To do so, attach the following notices to the program. It is safest
289
- to attach them to the start of each source file to most effectively
290
- convey the exclusion of warranty; and each file should have at least
291
- the "copyright" line and a pointer to where the full notice is found.
292
-
293
- Copyright (C) {2014} {Matthew Sparrow}
294
-
295
- This program is free software; you can redistribute it and/or modify
296
- it under the terms of the GNU General Public License as published by
297
- the Free Software Foundation; either version 2 of the License, or
298
- (at your option) any later version.
299
-
300
- This program is distributed in the hope that it will be useful,
301
- but WITHOUT ANY WARRANTY; without even the implied warranty of
302
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303
- GNU General Public License for more details.
304
-
305
- You should have received a copy of the GNU General Public License along
306
- with this program; if not, write to the Free Software Foundation, Inc.,
307
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
308
-
309
- Also add information on how to contact you by electronic and paper mail.
310
-
311
- If the program is interactive, make it output a short notice like this
312
- when it starts in an interactive mode:
313
-
314
- Gnomovision version 69, Copyright (C) year name of author
315
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
316
- This is free software, and you are welcome to redistribute it
317
- under certain conditions; type `show c' for details.
318
-
319
- The hypothetical commands `show w' and `show c' should show the appropriate
320
- parts of the General Public License. Of course, the commands you use may
321
- be called something other than `show w' and `show c'; they could even be
322
- mouse-clicks or menu items--whatever suits your program.
323
-
324
- You should also get your employer (if you work as a programmer) or your
325
- school, if any, to sign a "copyright disclaimer" for the program, if
326
- necessary. Here is a sample; alter the names:
327
-
328
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
329
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
330
-
331
- {signature of Ty Coon}, 1 April 1989
332
- Ty Coon, President of Vice
333
-
334
- This General Public License does not permit incorporating your program into
335
- proprietary programs. If your program is a subroutine library, you may
336
- consider it more useful to permit linking proprietary applications with the
337
- library. If this is what you want to do, use the GNU Lesser General
338
- Public License instead of this License.
339
-
340
- Name: Matthew
341
- Company: MPS Plugins
342
- E-mail: mpsplugins@gmail.com
343
- @Copyright 2014
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., http://fsf.org/
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that re-distributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for non-commercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sub-license, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sub-license or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgement or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ Copyright (C) {2014} {Matthew Sparrow}
294
+
295
+ This program is free software; you can redistribute it and/or modify
296
+ it under the terms of the GNU General Public License as published by
297
+ the Free Software Foundation; either version 2 of the License, or
298
+ (at your option) any later version.
299
+
300
+ This program is distributed in the hope that it will be useful,
301
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
302
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303
+ GNU General Public License for more details.
304
+
305
+ You should have received a copy of the GNU General Public License along
306
+ with this program; if not, write to the Free Software Foundation, Inc.,
307
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
308
+
309
+ Also add information on how to contact you by electronic and paper mail.
310
+
311
+ If the program is interactive, make it output a short notice like this
312
+ when it starts in an interactive mode:
313
+
314
+ Gnomovision version 69, Copyright (C) year name of author
315
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
316
+ This is free software, and you are welcome to redistribute it
317
+ under certain conditions; type `show c' for details.
318
+
319
+ The hypothetical commands `show w' and `show c' should show the appropriate
320
+ parts of the General Public License. Of course, the commands you use may
321
+ be called something other than `show w' and `show c'; they could even be
322
+ mouse-clicks or menu items--whatever suits your program.
323
+
324
+ You should also get your employer (if you work as a programmer) or your
325
+ school, if any, to sign a "copyright disclaimer" for the program, if
326
+ necessary. Here is a sample; alter the names:
327
+
328
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
329
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
330
+
331
+ {signature of Ty Coon}, 1 April 1989
332
+ Ty Coon, President of Vice
333
+
334
+ This General Public License does not permit incorporating your program into
335
+ proprietary programs. If your program is a subroutine library, you may
336
+ consider it more useful to permit linking proprietary applications with the
337
+ library. If this is what you want to do, use the GNU Lesser General
338
+ Public License instead of this License.
 
 
 
 
 
main.php CHANGED
@@ -1,1034 +1,332 @@
1
- <?php
2
- /*
3
- @package Disable Updates Manager
4
- @author MPS Plugins
5
- @email mpsplugins@gmail.com
6
- @version 4.7.0
7
- */
8
- /*
9
- Plugin Name: Disable Updates Manager
10
- Plugin URI: http://www.mpswp.wordpress.com
11
- Version: 4.7.0
12
- Description: A configurable plugin that disables updates for you. Easy, clean and helpful.
13
- Author: MPS Plugins
14
- Author URI: http://www.mpswp.wordpress.com
15
- Author Email: mpsplugins@gmail.com
16
- License: GPL2
17
- Text Domain: disable-updates-manager
18
- Domain Path: languages
19
-
20
- @Copyright 2013 - 2014 MPS Plugins (email: mpsplugins@gmail.com)
21
-
22
- This program is free software; you can redistribute it and/or modify
23
- it under the terms of the GNU General Public License, version 2, as
24
- published by the Free Software Foundation.
25
-
26
- This program is distributed in the hope that it will be useful,
27
- but WITHOUT ANY WARRANTY; without even the implied warranty of
28
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29
- GNU General Public License for more details.
30
-
31
- You should have received a copy of the GNU General Public License
32
- along with this program; if not, write to the Free Software
33
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34
-
35
- Go to the license.txt in the trunk for more information.
36
- */
37
-
38
- class Disable_Updates {
39
-
40
- /* Description: Define version. */
41
- const VERSION = '4.7.0';
42
-
43
- private static $page_hook = '';
44
-
45
- function __construct() {
46
-
47
- /* Description: load textdomain. */
48
- add_action( 'init', array( __CLASS__ , 'load_textdomain' ) );
49
-
50
- /* Description: Add menu page. */
51
- add_action( 'admin_menu', array( __CLASS__, 'add_submenu' ) );
52
-
53
- /* Description: Settings API. */
54
- add_action( 'admin_init', array( __CLASS__, 'register_setting' ) );
55
-
56
- /* Description: Add action links. */
57
- add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( __CLASS__, 'action_links' ) );
58
-
59
- /* Description: Add meta links. */
60
- add_filter( 'plugin_row_meta', array( __CLASS__, 'meta_links' ), 10, 2 );
61
-
62
- /* Description: Load the values recorded. */
63
- $this->load_disable_updates();
64
-
65
- }
66
-
67
- static function load_textdomain() {
68
-
69
- load_plugin_textdomain( 'disable-updates-manager', FALSE, basename( dirname( __FILE__ ) ) . '/lang' );
70
- }
71
-
72
- static function page_actions() {
73
-
74
- do_action( 'add_meta_boxes_' . self::$page_hook, NULL );
75
- do_action( 'add_meta_boxes', self::$page_hook, NULL );
76
-
77
- /* Description: Users can choose between 1 or 2 columns (default is 2 columns). */
78
- add_screen_option('layout_columns', array('max' => 2, 'default' => 2) );
79
-
80
- add_meta_box( 'dum-global', __( 'Disable Updates Globally', 'disable-updates-manager' ), array( __CLASS__, 'metabox_global' ), self::$page_hook, 'left', 'core' );
81
- add_meta_box( 'dum-themes', __( 'Disable Theme Updates', 'disable-updates-manager' ), array( __CLASS__, 'metabox_themes' ), self::$page_hook, 'left', 'core' );
82
-
83
- add_meta_box( 'dum-other', __( 'Other Settings', 'disable-updates-manager' ), array( __CLASS__, 'metabox_other' ), self::$page_hook, 'right', 'core' );
84
- add_meta_box( 'dum-plugins', __( 'Disable Plugin Updates', 'disable-updates-manager' ), array( __CLASS__, 'metabox_plugins' ), self::$page_hook, 'right', 'core' );
85
-
86
- }
87
-
88
- static function enqueue_css() {
89
-
90
- /* Description: If SCRIPT_DEBUG is set and TRUE load the non-minified files, otherwise, load the minified files. */
91
- $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
92
-
93
- wp_register_style( 'dum-chosen', plugins_url( "vendor/chosen/chosen$min.css", __FILE__ ), array(), '1.1.0' );
94
-
95
- wp_enqueue_style( 'disable-updates-manager', plugins_url( "assets/style$min.css", __FILE__ ), array( 'dum-chosen' ), self::VERSION );
96
-
97
- }
98
-
99
- static function enqueue_js() {
100
-
101
- /* Description: If SCRIPT_DEBUG is set and TRUE load the non-minified files, otherwise, load the minified files. */
102
- $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
103
-
104
- wp_register_script( 'dum-admin-js', plugins_url( "assets/admin$min.js", __FILE__ ), array( 'postbox' ), self::VERSION );
105
-
106
- wp_enqueue_script( 'dum-chosen-js', plugins_url( "vendor/chosen/chosen.jquery$min.js", __FILE__ ), array( 'dum-admin-js' ), '1.1.0' );
107
-
108
- }
109
-
110
- static function footer_scripts() {
111
-
112
- ?>
113
- <script> postboxes.add_postbox_toggles(pagenow);</script>
114
- <?php
115
-
116
- }
117
-
118
- /* Description: Register settings. */
119
- static function register_setting() {
120
-
121
- register_setting( '_disable_updates', '_disable_updates', array( __CLASS__, 'validate_settings' ) );
122
-
123
- }
124
-
125
- static function validate_settings( $value ) {
126
-
127
- if ( isset( $value['plugins'] ) ) {
128
-
129
- /* Description: Since the blocked plugins are stored in a different option, we need to update that option. */
130
- $blocked_plugins = $value['plugins'];
131
-
132
- /* Description: Convert the data to match the way the options are stored. */
133
- $blocked_plugins = array_fill_keys( $blocked_plugins, TRUE );
134
-
135
- } else {
136
-
137
- $blocked_plugins = array();
138
-
139
- }
140
-
141
- /* Description: Update the blocked plugins options. */
142
- update_option( 'disable_updates_blocked', $blocked_plugins );
143
-
144
- return $value;
145
-
146
- }
147
-
148
- static function add_submenu() {
149
-
150
- $page_hook = add_submenu_page( 'options-general.php', 'Disable Updates Manager', __( 'Disable Updates Manager', 'disable-updates-manager' ), 'manage_options', 'disable-updates-manager', array( __CLASS__, 'display_page' ) );
151
-
152
- /* Description: Enqueue the admin CSS for this page only. */
153
- add_action( "load-$page_hook", array( __CLASS__, 'enqueue_css' ) );
154
-
155
- /* Description: Enqueue the admin JavaScript for this page only. */
156
- add_action( "load-$page_hook", array( __CLASS__, 'enqueue_js' ) );
157
-
158
- /* Description: Add callbacks for this page only. */
159
- add_action( "load-$page_hook", array( __CLASS__, 'page_actions' ), 9 );
160
- add_action( "admin_footer-$page_hook" , array( __CLASS__ , 'footer_scripts' ) );
161
- add_action( "load-$page_hook", array( __CLASS__, 'help_tab' ) );
162
-
163
- self::$page_hook = $page_hook;
164
-
165
- }
166
-
167
- static function action_links( $links ) {
168
-
169
- return array_merge(
170
- array(
171
- 'settings' => '<a href="' . add_query_arg( array( 'page' => 'disable-updates-manager' ), admin_url( 'options-general.php' ) ) . '">' . __( 'Configure', 'disable-updates-manager' ) . '</a>',
172
- ),
173
- $links
174
- );
175
-
176
- }
177
-
178
- static function meta_links( $links, $file ) {
179
-
180
- $plugin = plugin_basename( __FILE__ );
181
-
182
- if ( $file == $plugin ) {
183
-
184
- return array_merge(
185
- $links,
186
- array( '<a href="http://www.wordpress.org/support/plugin/stops-core-theme-and-plugin-updates">Support</a>' ),
187
- array( '<a href="https://github.com/Websiteguy/disable-updates-manager">GitHub</a>' )
188
- );
189
- }
190
-
191
- return $links;
192
-
193
- }
194
-
195
- /* Description: Functions for the plugins settings. */
196
- static function load_disable_updates() {
197
-
198
- $status = get_option( '_disable_updates' );
199
-
200
- if ( ! $status ) {
201
- return;
202
- }
203
-
204
- foreach ( $status as $id => $value ) {
205
-
206
- switch ( $id ) {
207
-
208
- /* Description: Disable Plugin Updates */
209
- case 'plugin' :
210
-
211
- self::disable_plugin_updates();
212
-
213
- break;
214
-
215
- /* Description: Disable theme updates. */
216
- case 'theme' :
217
-
218
- self::disable_theme_updates();
219
-
220
- break;
221
-
222
- /* Description: Disable WordPress core updates. */
223
- case 'core' :
224
-
225
- self::disable_core_updates();
226
-
227
- break;
228
-
229
- /* Description: Remove the updates and home submenu. */
230
- case 'page' :
231
-
232
- /* Description: Updates submenu. */
233
- add_action( 'admin_init', create_function( '', 'remove_submenu_page( \'index.php\', \'update-core.php\' );' ) );
234
-
235
- /* Description: Home submenu. */
236
- add_action( 'admin_init', create_function( '', 'remove_submenu_page( \'index.php\', \'index.php\' );' ) );
237
-
238
- break;
239
-
240
- /* Description: Disable all updates. */
241
- case 'all' :
242
-
243
- /* Description: Disable plugin updates only. */
244
- self::disable_plugin_updates();
245
-
246
- /* Description: Disable theme updates only. */
247
- self::disable_theme_updates();
248
-
249
- /* Description: Disable WordPress core updates only. */
250
- self::disable_core_updates();
251
-
252
- /* Description: Disable debug e-mails. */
253
- add_filter( 'automatic_updates_send_debug_email ', '__return_false', 1 );
254
-
255
- /* Description: Disable WordPress automatic updates. */
256
- define( 'AUTOMATIC_UPDATER_DISABLED', TRUE );
257
- define( 'WP_AUTO_UPDATE_CORE', FALSE );
258
-
259
- break;
260
-
261
- /* Description: Remove WordPress version number from footer in dashboard. */
262
- case 'wpv' :
263
-
264
- add_filter( 'update_footer', '__return_empty_string', 11 );
265
-
266
- break;
267
-
268
- /* Description: Disable plugins individually. */
269
- case 'ip' :
270
-
271
- if ( defined( 'disable_updates_loaded' ) ) {
272
- return;
273
- }
274
-
275
- define( 'disable_updates_loaded', 1 );
276
-
277
- add_action( 'init', array( __CLASS__, 'update_plugin_block_status' ) );
278
- add_filter( 'site_transient_update_plugins', array( __CLASS__, 'remove_plugin_update_notification' ) );
279
- add_filter( 'plugin_action_links', array( __CLASS__, 'plugin_block_action_link' ), 10, 4 );
280
-
281
- /* Description: Remove plugins from being checked for updates at wordpress.org. */
282
- add_filter( 'http_request_args', array( __CLASS__, 'http_request_args_plugins_filter' ), 5, 2 );
283
-
284
- break;
285
-
286
- /* Description: Remove browser nag. */
287
- case 'bnag' :
288
-
289
- if ( ! function_exists( 'c2c_no_browser_nag' ) ) :
290
-
291
- function c2c_no_browser_nag() {
292
- $key = md5( $_SERVER['HTTP_USER_AGENT'] );
293
- add_filter( 'site_transient_browser_' . $key, '__return_null' );
294
- }
295
- endif;
296
- add_action( 'admin_init', 'c2c_no_browser_nag' );
297
-
298
- break;
299
-
300
- /* Description: Disable themes individually. */
301
- case 'it':
302
-
303
- add_filter( 'site_transient_update_themes', array( __CLASS__, 'remove_theme_update_notification' ) );
304
-
305
- /* Description: Remove blocked themes from being checked for updates at wordpress.org. */
306
- add_filter( 'http_request_args', array( __CLASS__, 'http_request_args_themes_filter' ), 5, 2 );
307
-
308
- break;
309
-
310
- /* Description: Disable automatic background updates. */
311
- case 'abup' :
312
-
313
- wp_clear_scheduled_hook( 'wp_maybe_auto_update' );
314
-
315
- break;
316
-
317
- /* Description: Disables minor core updates in the Disable Updates Manager settings. */
318
- case 'minor-core-updates' :
319
-
320
- /* TO BE ADDED */
321
-
322
- break;
323
-
324
- /* Description: Disables major core updates in the Disable Updates Manager settings. */
325
- case 'major-core-updates' :
326
-
327
- /* TO BE ADDED */
328
-
329
- break;
330
-
331
- /* Description: Disables auto translation updates in the Disable Updates Manager settings. */
332
- case 'auto-translation-updates' :
333
-
334
- add_filter( 'auto_update_translation', '__return_false' );
335
-
336
- break;
337
-
338
- /* Description: Disables auto core e-mails in the Disable Updates Manager settings. */
339
- case 'auto-core-emails' :
340
-
341
- add_filter( 'auto_core_update_send_email', '__return_false' );
342
-
343
- break;
344
-
345
- }
346
- }
347
- }
348
-
349
- static function update_plugin_block_status() {
350
-
351
- if ( ! current_user_can( 'update_plugins' ) ) {
352
- return;
353
- }
354
-
355
- /* Description: See if there are actions to process. */
356
- if ( ! isset( $_GET[ 'disable_updates' ] ) || ! isset( $_GET[ '_wpnonce' ] ) ) {
357
- return;
358
- }
359
-
360
- if ( ! wp_verify_nonce( $_GET[ '_wpnonce' ], 'disable_updates' ) ) {
361
- return;
362
- }
363
-
364
- $blocked = get_option( 'disable_updates_blocked' );
365
-
366
- if ( isset( $_GET[ 'block' ] ) ) {
367
-
368
- $blocked[ $_GET[ 'block' ] ] = TRUE;
369
- }
370
-
371
- if ( isset( $_GET[ 'unblock' ] ) ) {
372
-
373
- unset( $blocked[ $_GET[ 'unblock' ] ] );
374
- }
375
-
376
- update_option( 'disable_updates_blocked', $blocked );
377
-
378
- }
379
-
380
- static function remove_plugin_update_notification( $plugins ) {
381
-
382
- if ( ! isset( $plugins->response ) || count( $plugins->response ) == 0 ) {
383
-
384
- return $plugins;
385
- }
386
-
387
- $blocked = (array) get_option( 'disable_updates_blocked' );
388
-
389
- foreach ( $blocked as $filename => $plugin ) {
390
-
391
- if ( isset( $plugins->response[ $filename ] ) && $plugin == TRUE ) {
392
-
393
- $plugins->disable_updates[ $filename ] = $plugins->response[ $filename ];
394
- unset( $plugins->response[ $filename ] );
395
- }
396
- }
397
-
398
- return $plugins;
399
-
400
- }
401
-
402
- static function remove_theme_update_notification( $themes ) {
403
-
404
- $options = get_option( '_disable_updates' );
405
-
406
- if ( FALSE === $options ) {
407
-
408
- return $themes;
409
- }
410
-
411
- if ( isset( $options['themes'] ) ) {
412
-
413
- $blocked = $options['themes'];
414
-
415
- } else {
416
-
417
- return $themes;
418
- }
419
-
420
- if ( 0 === (int) count( $blocked ) ) {
421
-
422
- return $themes;
423
- }
424
-
425
- if ( ! isset( $themes->response ) || count( $themes->response ) == 0 ) {
426
-
427
- return $themes;
428
- }
429
-
430
- foreach ( $blocked as $theme ) {
431
-
432
- if ( isset( $themes->response[ $theme ] ) ) {
433
-
434
- $themes->disable_updates[ $theme ] = $themes->response[ $theme ];
435
- unset( $themes->response[ $theme ] );
436
- }
437
- }
438
-
439
- return $themes;
440
-
441
- }
442
-
443
- static function last_checked() {
444
- global $wp_version;
445
-
446
- return (object) array(
447
- 'last_checked' => time(),
448
- 'updates' => array(),
449
- 'version_checked' => $wp_version,
450
- );
451
-
452
- }
453
-
454
- /* Description: Disable WordPress core updates. */
455
- static function disable_core_updates() {
456
-
457
- /* Description: 2.3 to 2.7. */
458
- add_action( 'init', create_function( '', 'remove_action( \'init\', \'wp_version_check\' );' ), 2 );
459
- add_filter( 'pre_option_update_core', '__return_null' );
460
-
461
- /* Description: 2.8 to 3.0. */
462
- remove_action( 'wp_version_check', 'wp_version_check' );
463
- remove_action( 'admin_init', '_maybe_update_core' );
464
- add_filter( 'pre_transient_update_core', array( __CLASS__,'last_checked' ) );
465
-
466
- /* Description: >3.0. */
467
- remove_action( 'load-update-core.php', 'wp_update_core' );
468
- add_filter( 'pre_site_transient_update_core', array( __CLASS__,'last_checked' ) );
469
-
470
- /* Description: Hide update notices in admin dashboard. */
471
- add_action( 'admin_menu', create_function( '', 'remove_action( \'admin_notices\', \'update_nag\', 3 );' ) );
472
-
473
- wp_clear_scheduled_hook( 'wp_version_check' );
474
-
475
- /* Description: Disable e-mails. */
476
- add_filter( 'auto_core_update_send_email', '__return_false' );
477
-
478
- }
479
-
480
- /* Description: Disable plugin updates. */
481
- static function disable_plugin_updates() {
482
-
483
- /* Description: 2.3 to 2.7. */
484
- add_filter( 'pre_option_update_plugins', '__return_null' );
485
-
486
- /* Description: 2.8 to 3.0. */
487
- remove_action( 'load-plugins.php', 'wp_update_plugins' );
488
- remove_action( 'load-update.php', 'wp_update_plugins' );
489
- remove_action( 'admin_init', '_maybe_update_plugins' );
490
- remove_action( 'wp_update_plugins', 'wp_update_plugins' );
491
- add_filter( 'pre_transient_update_plugins', array( __CLASS__,'last_checked' ) );
492
-
493
- /* Description: >3.0. */
494
- remove_action( 'load-update-core.php', 'wp_update_plugins' );
495
- add_filter( 'pre_site_transient_update_plugins', array( __CLASS__,'last_checked' ) );
496
-
497
- wp_clear_scheduled_hook( 'wp_update_plugins' );
498
-
499
- }
500
-
501
- /* Description: Disable theme updates. */
502
- static function disable_theme_updates() {
503
-
504
- /* Description: 2.3 to 2.7. */
505
- add_filter( 'pre_option_update_themes', '__return_null' );
506
-
507
- /* Description: 2.8 to 3.0. */
508
- remove_action( 'load-themes.php', 'wp_update_themes' );
509
- remove_action( 'load-update.php', 'wp_update_themes' );
510
- remove_action( 'admin_init', '_maybe_update_themes' );
511
- remove_action( 'wp_update_themes', 'wp_update_themes' );
512
- add_filter( 'pre_transient_update_themes', array( __CLASS__,'last_checked' ) );
513
-
514
- /* Description: >3.0. */
515
- remove_action( 'load-update-core.php', 'wp_update_themes' );
516
- add_filter( 'pre_site_transient_update_themes', array( __CLASS__,'last_checked' ) );
517
-
518
- wp_clear_scheduled_hook( 'wp_update_themes' );
519
-
520
- }
521
-
522
- static function plugin_block_action_link( $actions, $plugin_file, $plugin_data, $context ) {
523
-
524
- $blocked = get_option( 'disable_updates_blocked' );
525
-
526
- if ( $blocked !== FALSE && array_key_exists( $plugin_file, $blocked ) ) {
527
-
528
- $actions[] = '<a class="delete" href="plugins.php?_wpnonce=' . wp_create_nonce( 'disable_updates' ) . '&disable_updates&unblock=' . $plugin_file . '"><small>Updates Blocked</a>';
529
-
530
- } else {
531
-
532
- $actions[] = '<a class="delete" href="plugins.php?_wpnonce=' . wp_create_nonce( 'disable_updates' ) . '&disable_updates&block=' . $plugin_file . '"><small>Updates Allowed</small></a>';
533
- }
534
-
535
- return $actions;
536
-
537
- }
538
-
539
- static function http_request_args_plugins_filter( $r, $url ) {
540
-
541
- if ( 0 !== strpos( $url, 'https://api.wordpress.org/plugins/update-check/1.1/' ) ) {
542
-
543
- return $r;
544
- }
545
-
546
- $blocked = get_option( 'disable_updates_blocked' );
547
- $blocked = (array) array_keys( $blocked );
548
-
549
- if ( 0 === (int) count( $blocked ) ) {
550
-
551
- return $r;
552
- }
553
-
554
- if ( ! isset( $r['body']['plugins'] ) ) {
555
-
556
- return $r;
557
- }
558
-
559
- $plugins = json_decode( $r['body']['plugins'], TRUE );
560
-
561
- foreach ( $blocked as $p ) {
562
-
563
- if ( isset( $plugins['plugins'][ $p ] ) ) unset( $plugins['plugins'][ $p ] );
564
- if ( FALSE !== $key = array_search( $p, $plugins['active'] ) ) unset( $plugins['active'][ $key ] );
565
- }
566
-
567
- $r['body']['plugins'] = json_encode( $plugins );
568
-
569
- return $r;
570
-
571
- }
572
-
573
- static function http_request_args_themes_filter( $r, $url ) {
574
-
575
- if ( 0 !== strpos( $url, 'https://api.wordpress.org/themes/update-check/1.1/' ) ) {
576
-
577
- return $r;
578
- }
579
-
580
- $options = get_option( '_disable_updates' );
581
-
582
- if ( FALSE === $options ) {
583
-
584
- return $r;
585
- }
586
-
587
- if ( isset( $options['themes'] ) ) {
588
-
589
- $blocked = $options['themes'];
590
-
591
- } else {
592
-
593
- return $r;
594
- }
595
-
596
- if ( 0 === (int) count( $blocked ) ) {
597
-
598
- return $r;
599
- }
600
-
601
- if ( ! isset( $r['body']['themes'] ) ) {
602
-
603
- return $r;
604
- }
605
-
606
- $themes = json_decode( $r['body']['themes'], TRUE );
607
-
608
- foreach ( $blocked as $t ) {
609
-
610
- if ( isset( $themes['themes'][ $t ] ) ) unset( $themes['themes'][ $t ] );
611
- }
612
-
613
- $r['body']['themes'] = json_encode( $themes );
614
-
615
- return $r;
616
-
617
- }
618
-
619
- /* Description: Help tab. */
620
- static function help_tab() {
621
- global $test_help_page;
622
-
623
- $screen = get_current_screen();
624
- $content1 = <<<CONTENT1
625
- <p>
626
- This is the Disable Updates Manager settings help tab. In here you will find helpful information on what Disable Updates Manager does and how to use it.
627
- </p>
628
-
629
- <div class="error" id="error">
630
- <p><strong>Please Note! - </strong>If either your WordPress core, theme, or plugins get too out
631
- of date, you may run into compatibility problems. Check the capability tab for more information.</p>
632
- </div>
633
-
634
- CONTENT1;
635
-
636
- $content2 = <<<CONTENT2
637
- <div><br></div>
638
- <div id="acolumn1">
639
- <iframe width="310" height="174" src="//www.youtube.com/embed/VYEQg-hZd58?rel=0" frameborder="0" allowfullscreen></iframe>
640
- <iframe width="310" height="174" src="//www.youtube.com/embed/Kd4s3EOcUtw?rel=0" frameborder="0" allowfullscreen></iframe>
641
- </div>
642
-
643
- <div id="acolumn2">
644
- <iframe width="310" height="174" src="//www.youtube.com/embed/1R-be48AvrE?rel=0" frameborder="0" allowfullscreen></iframe>
645
- <iframe width="310" height="174" src="//www.youtube.com/embed/mYznDVsbVBk?rel=0" frameborder="0" allowfullscreen></iframe>
646
- </div>
647
-
648
- CONTENT2;
649
-
650
- $content3 = <<<CONTENT3
651
- <p>
652
- <a href="http://mpswp.wordpress.com" class="button">Our Website</a>
653
- <a href="http://wordpress.org/support/plugin/stops-core-theme-and-plugin-updates" class="button">Support on WordPress</a>
654
- <a href="https://github.com/Websiteguy/disable-updates-manager" class="button">GitHub Repository</a>
655
- </p>
656
-
657
- CONTENT3;
658
-
659
- $content4 = <<<CONTENT4
660
- <p>
661
- Use the following features to customize the settings page as to suit your work-flow.
662
- <br>
663
- <br>
664
- <strong>Screen Options</strong> - Use the Screen Options tab to choose which metaboxes you would like to display.
665
- <br>
666
- <br>
667
- <strong>Drag and Drop</strong> - To rearrange the boxes, drag and drop by clicking on the title bar of the selected metabox and releasing when you see a gray dotted-line appear in the location you want to place the box.
668
- <br>
669
- <br>
670
- <strong>Box Controls</strong> - Click the title bar of the box to expand or collapse the contents.
671
- <br>
672
- <br>
673
- <strong>Chosen</strong> - Check the Disable Themes Individually setting and/or the Disable Plugins Individually settings to enable the chosen multiply select box.
674
- <br>
675
- <br>
676
- <strong>Tooltips</strong> - If you are having trouble figuring out how a setting works, just wave over the "?". It will display a little bubble with helpful information.
677
- </p>
678
-
679
- CONTENT4;
680
-
681
- $content5 = <<<CONTENT5
682
-
683
- <p style="align: center;">
684
- <h3>Contributors:</h3>
685
- <ul>
686
- <li><a href="http://profiles.wordpress.org/kidsguide/">Matthew</a></li>
687
- <li><a href="http://profiles.wordpress.org/mps-plugins/">MPS Plugins</a></li>
688
- <li><a href="http://profiles.wordpress.org/shazahm1hotmailcom/">Shazahm1</a></li>
689
- <li><a href="http://profiles.wordpress.org/szepeviktor/">szepe.viktor</a></li>
690
- </ul>
691
- </p>
692
-
693
- CONTENT5;
694
-
695
- $content6 = <<<CONTENT6
696
- <p>
697
- WordPress encourages you to update your plugins, themes, and core to make sure that there are no bugs. Even though you most likely want to disable all the updates and never think about updating again, you should still consider updating every once in a while to avoid major bugs and errors on your WordPress website.
698
-
699
- <h3>This plugin is tested so there are no problems.</h3>
700
- <ul>
701
- <li>Tested with WordPress 4.1.</li>
702
- <li>Tested with popular plugins to ensure that there are no conflicts.</li>
703
- <li>Tested with popular themes to ensure that there are no conflicts.</li>
704
- </ul>
705
- </p>
706
-
707
- CONTENT6;
708
-
709
- $screen->add_help_tab(array(
710
- 'id' => 'help_tab_content_1',
711
- 'title' => __('Overview'),
712
- 'content' => $content1,
713
- ));
714
-
715
- $screen->add_help_tab(array(
716
- 'id' => 'help_tab_content_4',
717
- 'title' => __('Layout'),
718
- 'content' => $content4,
719
- ));
720
-
721
- $screen->add_help_tab(array(
722
- 'id' => 'help_tab_content_2',
723
- 'title' => __('Tutorials'),
724
- 'content' => $content2,
725
- ));
726
-
727
- $screen->add_help_tab(array(
728
- 'id' => 'help_tab_content_6',
729
- 'title' => __('Capability'),
730
- 'content' => $content6,
731
- ));
732
-
733
- $screen->add_help_tab(array(
734
- 'id' => 'help_tab_content_3',
735
- 'title' => __('Troubleshooting'),
736
- 'content' => $content3,
737
- ));
738
-
739
- $screen->set_help_sidebar($content5);
740
-
741
- }
742
-
743
- static function metabox_global( $status ) {
744
-
745
- ?>
746
- <div>
747
- <p>
748
- <div class="showonhover">
749
- <label for="all_notify">
750
- <input
751
- type="checkbox" <?php checked( 1, ( isset( $status['all'] ) ? (int) $status['all'] : 0 ), TRUE ); ?>
752
- value="1" id="all_notify"
753
- name="_disable_updates[all]"> <?php _e( 'Disable All Updates', 'disable-updates-manager' ) ?>
754
- </label>
755
- <span>
756
- <a href="#" class="viewdescription">?</a>
757
- <span class="hovertext">Disables core, theme, and plugin updates.</span>
758
- </span>
759
- </div>
760
- </p>
761
- </div>
762
-
763
- <div style="padding-left: 12px;">
764
- <p>
765
- <div>
766
- <label for="plugins_notify">
767
- <input type="checkbox" <?php checked( 1, ( isset( $status['plugin'] ) && ! isset( $status['all'] ) ? (int) $status['plugin'] : 0 ), TRUE ); ?>
768
- value="1" id="plugins_notify"
769
- name="_disable_updates[plugin]"
770
- <?php disabled( 1, ( isset( $status['all'] ) ? (int) $status['all'] : 0 ) ) ?>> <?php _e( 'Disable All Plugin Updates', 'disable-updates-manager' ) ?>
771
- </label>
772
- </div>
773
- <br>
774
- <div>
775
- <label for="themes_notify">
776
- <input type="checkbox" <?php checked( 1, ( isset( $status['theme'] ) && ! isset( $status['all'] ) ? (int) $status['theme'] : 0 ), TRUE ); ?>
777
- value="1" id="themes_notify"
778
- name="_disable_updates[theme]"
779
- <?php disabled( 1, ( isset( $status['all'] ) ? (int) $status['all'] : 0 ) ) ?>> <?php _e( 'Disable All Theme Updates', 'disable-updates-manager' ) ?>
780
- </label>
781
- </div>
782
- <br>
783
- <div>
784
- <label for="core_notify">
785
- <input type="checkbox" <?php checked( 1, ( isset( $status['core'] ) && ! isset( $status['all'] ) ? (int) $status['core'] : 0 ), TRUE ); ?>
786
- value="1" id="core_notify"
787
- name="_disable_updates[core]"
788
- <?php disabled( 1, ( isset( $status['all'] ) ? (int) $status['all'] : 0 ) ) ?>> <?php _e( 'Disable All WordPress Core Update', 'disable-updates-manager' ) ?>
789
- </label>
790
- </div>
791
- <div style="padding-left:20px;">
792
- <br>
793
- <small>Disable major and minor core feature coming soon...<small>
794
- </div>
795
- </p>
796
- </div>
797
- <?php
798
-
799
- }
800
-
801
- static function metabox_other( $status ) {
802
-
803
- ?>
804
- <div>
805
- <p>
806
- <div class="showonhover">
807
- <label for="page_notify">
808
- <input
809
- type="checkbox" <?php checked( 1, ( isset( $status['page'] ) ? (int) $status['page'] : 0 ), TRUE ); ?>
810
- value="1" id="page_notify"
811
- name="_disable_updates[page]"> <?php _e( 'Remove the Updates Page', 'disable-updates-manager' ) ?>
812
- </label>
813
- <span>
814
- <a href="#" class="viewdescription">?</a></a>
815
- <span class="hovertext">The page under the Dashboard tab.</span>
816
- </span>
817
- </div>
818
- <br>
819
- <div class="showonhover">
820
- <label for="bnag_notify">
821
- <input type="checkbox" <?php checked( 1, ( isset( $status['bnag'] ) ? (int) $status['bnag'] : 0 ), TRUE ); ?>
822
- value="1" id="bnag_notify"
823
- name="_disable_updates[bnag]"> <?php _e( 'Disable Out of Date Browser Nag', 'disable-updates-manager' ) ?>
824
- </label>
825
- <span>
826
- <a href="#" class="viewdescription">?</a>
827
- <span class="hovertext">Removes the browsers is out of date notification in you WordPress dashboard.</span>
828
- </span>
829
- </div>
830
- <br>
831
- <div class="showonhover">
832
- <label for="wpv_notify">
833
- <input
834
- type="checkbox" <?php checked( 1, ( isset( $status['wpv'] ) ? (int) $status['wpv'] : 0 ), TRUE ); ?>
835
- value="1" id="wpv_notify"
836
- name="_disable_updates[wpv]"> <?php _e( 'Disable WordPress Core Version from Footer', 'disable-updates-manager' ) ?>
837
- </label>
838
- <span>
839
- <a href="#" class="viewdescription">?</a>
840
- <span class="hovertext">Removes it for all users.</span>
841
- </span>
842
- </div>
843
- <br>
844
- <div class="showonhover">
845
- <label for="auto-translation-updates_notify">
846
- <input type="checkbox" <?php checked( 1, ( isset( $status['auto-translation-updates'] ) ? (int) $status['auto-translation-updates'] : 0 ), TRUE ); ?>
847
- value="1" id="auto-translation-updates_notify"
848
- name="_disable_updates[auto-translation-updates]"> <?php _e( 'Disable Automatic Translation Updates', 'disable-updates-manager' ) ?>
849
- </label>
850
- <span>
851
- <a href="#" class="viewdescription">?</a>
852
- <span class="hovertext">Disables the automatic translation updates for you.</span>
853
- </span>
854
- </div>
855
- <br>
856
- <div class="showonhover">
857
- <label for="auto-core-emails_notify">
858
- <input
859
- type="checkbox" <?php checked( 1, ( isset( $status['auto-core-emails'] ) ? (int) $status['auto-core-emails'] : 0 ), TRUE ); ?>
860
- value="1" id="auto-core-emails_notify"
861
- name="_disable_updates[auto-core-emails]"> <?php _e( 'Disable Core Update E-mails', 'disable-updates-manager' ) ?>
862
- </label>
863
- <span>
864
- <a href="#" class="viewdescription">?</a>
865
- <span class="hovertext">Disables the core update e-mails so that they will not be sent to you.</span>
866
- </span>
867
- </div>
868
- <br>
869
- <div>
870
- <label for="abup_notify">
871
- <input type="checkbox" <?php checked( 1, ( isset( $status['abup'] ) ? (int) $status['abup'] : 0 ), TRUE ); ?>
872
- value="1" id="abup_notify"
873
- name="_disable_updates[abup]"> <?php _e( 'Disable Automatic Background Updates', 'disable-updates-manager' ) ?>
874
- </label>
875
- </div>
876
- </p>
877
- </div>
878
- <?php
879
-
880
- }
881
-
882
- static function metabox_themes( $status ) {
883
-
884
- ?>
885
- <div>
886
- <p>
887
- <div class="showonhover">
888
- <label for="dum-disable-themes">
889
- <input type="checkbox" <?php checked( 1, ( isset( $status['it'] ) && ! isset( $status['all'] ) ? (int) $status['it'] : 0 ), TRUE ); ?>
890
- id="dum-disable-themes"
891
- value="1"
892
- name="_disable_updates[it]"
893
- <?php disabled( 1, ( isset( $status['all'] ) ? (int) $status['all'] : 0 ) ) ?>> <?php _e( 'Disable Themes Individually', 'disable-updates-manager' ) ?>
894
- </label>
895
- <span>
896
- <a href="#" class="viewdescription">?</a>
897
- <span class="hovertext">Enabling this option will show the list of themes to disable updates.</span>
898
- </span>
899
- </div>
900
- </p>
901
- </div>
902
- <?php
903
-
904
- $themes = wp_get_themes( array( 'allowed' => TRUE ) );
905
-
906
- if ( ! empty( $themes ) ) {
907
-
908
- echo '<select class="dum-enhanced-select" id="dum-disable-themes-select" name="_disable_updates[themes][]" data-placeholder="' . __( 'Select theme(s) to disable...', 'disable-updates-manager' ) . '" multiple' . ( isset( $status['it'] ) && ! isset( $status['all'] ) ? '' : ' disabled' ) . '>';
909
-
910
- echo '<option value=""></option>';
911
-
912
- foreach ( $themes as $slug => $theme ) {
913
-
914
- printf( '<option value="%1$s"%2$s>%3$s</option>',
915
- esc_attr( $slug ),
916
- ! isset( $status['all'] ) && isset( $status['it'] ) && isset( $status['themes'] ) && in_array( $slug, $status['themes'] ) ? ' SELECTED' : '',
917
- esc_html( $theme->name )
918
- );
919
- }
920
-
921
- echo '</select>';
922
- }
923
-
924
- }
925
-
926
- static function metabox_plugins( $status ) {
927
-
928
- ?>
929
- <div>
930
- <p>
931
- <div class="showonhover">
932
- <label for="dum-disable-plugins">
933
- <input type="checkbox" <?php checked( 1, ( isset( $status['ip'] ) && ! isset( $status['all'] ) ? (int) $status['ip'] : 0 ), TRUE ); ?>
934
- id="dum-disable-plugins"
935
- value="1"
936
- name="_disable_updates[ip]"
937
- <?php disabled( 1, ( isset( $status['all'] ) ? (int) $status['all'] : 0 ) ) ?>> <?php _e( 'Disable Plugins Individually', 'disable-updates-manager' ) ?>
938
- </label>
939
- <span>
940
- <a href="#" class="viewdescription">?</a>
941
- <span class="hovertext">Enabling this option will show the list of plugins to disable updates.</span>
942
- </span>
943
- </div>
944
- </p>
945
- </div>
946
- <?php
947
-
948
- $plugins = get_plugins();
949
- $blocked = get_option( 'disable_updates_blocked' );
950
-
951
- if ( ! empty( $plugins ) ) {
952
-
953
- echo '<select class="dum-enhanced-select" id="dum-disable-plugins-select" name="_disable_updates[plugins][]" data-placeholder="' . __( 'Select plugin(s) to disable...', 'disable-updates-manager' ) . '" multiple' . ( isset( $status['ip'] ) && ! isset( $status['all'] ) ? '' : ' disabled' ) . '>';
954
-
955
- echo '<option value=""></option>';
956
-
957
- foreach ( $plugins as $slug => $plugin ) {
958
-
959
- printf( '<option value="%1$s"%2$s>%3$s</option>',
960
- esc_attr( $slug ),
961
- ! isset( $status['all'] ) && isset( $status['ip'] ) && array_key_exists( $slug, (array) $blocked ) ? ' SELECTED' : '',
962
- esc_attr( $plugin['Name'] )
963
- );
964
- }
965
-
966
- echo '</select>';
967
- }
968
-
969
- }
970
-
971
- static function display_page() {
972
- ?>
973
-
974
- <h2><?php _e( 'Disable Updates Manager', 'disable-updates-manager' ); ?></h2>
975
-
976
- <?php
977
-
978
- if ( !current_user_can('manage_options') ) {
979
- wp_die('You do not have sufficient permissions to access this page.');
980
- }
981
-
982
- if ( current_user_can('manage_options') ) {
983
-
984
- $status = get_option( '_disable_updates' );
985
-
986
- ?>
987
- <div class="dashboard-widgets-wrap">
988
-
989
- <div id="dashboard-widgets" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
990
-
991
- <form name="dum-options" method="post" action="options.php">
992
- <input type="hidden" name="action" value="dum-update-options">
993
- <?php wp_nonce_field( 'dum-update-options-nonce' );
994
-
995
- /* Description: Used to save closed metaboxes and their order */
996
- wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', FALSE );
997
- wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', FALSE ); ?>
998
-
999
- <div class="postbox-container">
1000
- <?php do_meta_boxes( self::$page_hook, 'left', $status ); ?>
1001
- </div>
1002
-
1003
- <div class="postbox-container">
1004
- <?php do_meta_boxes( self::$page_hook, 'right', $status ); ?>
1005
- </div>
1006
-
1007
- <?php settings_fields( '_disable_updates' ); ?>
1008
-
1009
- <p class="submit clear">
1010
- <input type="submit" class="button-primary" value="<?php _e( 'Update Settings' ) ?>"/>
1011
- <a href="https://wordpress.org/support/view/plugin-reviews/stops-core-theme-and-plugin-updates?#postform" style="background-color:#ffff7f" class="button">Rate Plugin</a>
1012
- <a href="http://sparrowkids2.polldaddy.com/s/disable-updates-manager-feedbeck" class="button">Feedback Survey</a>
1013
- </p>
1014
-
1015
- </form>
1016
-
1017
- </div>
1018
-
1019
- </div>
1020
- <?php
1021
- }
1022
- }
1023
- }
1024
-
1025
- global $Disable_Updates;
1026
- $Disable_Updates = new Disable_Updates();
1027
-
1028
- if ( ! function_exists( 'printr' ) ) {
1029
- function printr( $txt ) {
1030
- echo '<pre>';
1031
- print_r( $txt );
1032
- echo '</pre>';
1033
- }
1034
- }
1
+ <?php
2
+ /*
3
+ Plugin Name: Easy Updates Manager
4
+ Plugin URI: https://wordpress.org/plugins/stops-core-theme-and-plugin-updates/
5
+ Description: Manage and disable WordPress updates, including core, plugin, theme, and automatic updates - Works with Multisite
6
+ Author: MPS Plugins, kidsguide, ronalfy
7
+ Version: 5.0.0
8
+ Requires at least: 4.0
9
+ Author URI: https://wordpress.org/plugins/stops-core-theme-and-plugin-updates/
10
+ Contributors: MPS Plugins, kidsguide, ronalfy
11
+ Text Domain: stops-core-theme-and-plugin-updates
12
+ Domain Path: /languages
13
+ Updates: true
14
+ Network: true
15
+ */
16
+ /**
17
+ * Main plugin class
18
+ *
19
+ * Initializes auto-loader, internationalization, and plugin dependencies.
20
+ *
21
+ * @since 5.0.0
22
+ *
23
+ * @package WordPress
24
+ */
25
+ class MPSUM_Updates_Manager {
26
+
27
+ /**
28
+ * Holds the class instance.
29
+ *
30
+ * @since 5.0.0
31
+ * @access static
32
+ * @var MPSUM_Updates_Manager $instance
33
+ */
34
+ private static $instance = null;
35
+
36
+ /**
37
+ * Stores the plugin's options
38
+ *
39
+ * @since 5.0.0
40
+ * @access static
41
+ * @var array $options
42
+ */
43
+ private static $options = false;
44
+
45
+ /**
46
+ * Retrieve a class instance.
47
+ *
48
+ * Retrieve a class instance.
49
+ *
50
+ * @since 5.0.0
51
+ * @access static
52
+ *
53
+ * @return MPSUM_Updates_Manager Instance of the class.
54
+ */
55
+ public static function get_instance() {
56
+ if ( null == self::$instance ) {
57
+ self::$instance = new self;
58
+ }
59
+ return self::$instance;
60
+ } //end get_instance
61
+
62
+ /**
63
+ * Retrieve the plugin basename.
64
+ *
65
+ * Retrieve the plugin basename.
66
+ *
67
+ * @since 5.0.0
68
+ * @access static
69
+ *
70
+ * @return string plugin basename
71
+ */
72
+ public static function get_plugin_basename() {
73
+ return plugin_basename( __FILE__ );
74
+ }
75
+
76
+ /**
77
+ * Class constructor.
78
+ *
79
+ * Set up internationalization, auto-loader, and plugin initialization.
80
+ *
81
+ * @since 5.0.0
82
+ * @access private
83
+ *
84
+ */
85
+ private function __construct() {
86
+ /* Localization Code */
87
+ load_plugin_textdomain( 'stops-core-theme-and-plugin-updates', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
88
+
89
+ spl_autoload_register( array( $this, 'loader' ) );
90
+
91
+ add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
92
+ } //end constructor
93
+
94
+ /**
95
+ * Return the absolute path to an asset.
96
+ *
97
+ * Return the absolute path to an asset based on a relative argument.
98
+ *
99
+ * @since 5.0.0
100
+ * @access static
101
+ *
102
+ * @param string $path Relative path to the asset.
103
+ * @return string Absolute path to the relative asset.
104
+ */
105
+ public static function get_plugin_dir( $path = '' ) {
106
+ $dir = rtrim( plugin_dir_path(__FILE__), '/' );
107
+ if ( !empty( $path ) && is_string( $path) )
108
+ $dir .= '/' . ltrim( $path, '/' );
109
+ return $dir;
110
+ }
111
+
112
+ /**
113
+ * Return the web path to an asset.
114
+ *
115
+ * Return the web path to an asset based on a relative argument.
116
+ *
117
+ * @since 5.0.0
118
+ * @access static
119
+ *
120
+ * @param string $path Relative path to the asset.
121
+ * @return string Web path to the relative asset.
122
+ */
123
+ public static function get_plugin_url( $path = '' ) {
124
+ $dir = rtrim( plugin_dir_url(__FILE__), '/' );
125
+ if ( !empty( $path ) && is_string( $path) )
126
+ $dir .= '/' . ltrim( $path, '/' );
127
+ return $dir;
128
+ }
129
+
130
+ /**
131
+ * Retrieve the plugin's options
132
+ *
133
+ * Retrieve the plugin's options based on context
134
+ *
135
+ * @since 5.0.0
136
+ * @access static
137
+ *
138
+ * @param string $context Context to retrieve options for. This is used as an array key.
139
+ * @param bool $force_reload Whether to retrieve cached options or forcefully retrieve from the database.
140
+ * @return array All options if no context, or associative array if context is set. Empty array if no options.
141
+ */
142
+ public static function get_options( $context = '', $force_reload = false ) {
143
+ //Try to get cached options
144
+ $options = self::$options;
145
+ if ( false === $options || true === $force_reload ) {
146
+ $options = get_site_option( 'MPSUM', false, false );
147
+ }
148
+
149
+ if ( false === $options ) {
150
+ $options = self::maybe_migrate_options();
151
+ }
152
+
153
+ //Store options
154
+ if ( !is_array( $options ) ) {
155
+ $options = array();
156
+ }
157
+ self::$options = $options;
158
+
159
+ //Attempt to get context
160
+ if ( !empty( $context ) && is_string( $context ) ) {
161
+ if ( array_key_exists( $context, $options ) ) {
162
+ return (array)$options[ $context ];
163
+ } else {
164
+ return array();
165
+ }
166
+ }
167
+
168
+
169
+ return $options;
170
+ } //get_options
171
+
172
+ /**
173
+ * Auto-loads classes.
174
+ *
175
+ * Auto-load classes that belong to this plugin.
176
+ *
177
+ * @since 5.0.0
178
+ * @access private
179
+ *
180
+ * @param string $class_name The name of the class.
181
+ */
182
+ private function loader( $class_name ) {
183
+ if ( class_exists( $class_name, false ) || false === strpos( $class_name, 'MPSUM' ) ) {
184
+ return;
185
+ }
186
+ $file = MPSUM_Updates_Manager::get_plugin_dir( "includes/{$class_name}.php" );
187
+ if ( file_exists( $file ) ) {
188
+ include_once( $file );
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Determine whether to migrate options from an older version of the plugin.
194
+ *
195
+ * Migrate old options to new plugin format.
196
+ *
197
+ * @since 5.0.0
198
+ * @access private
199
+ *
200
+ * @return bool|array false if no migration, associative array of options if migration successful
201
+ */
202
+ public static function maybe_migrate_options() {
203
+ $options = false;
204
+ $original_options = get_option( '_disable_updates', false );
205
+
206
+ if ( false !== $original_options && is_array( $original_options ) ) {
207
+ $options = array(
208
+ 'core' => array(),
209
+ 'plugins' => array(),
210
+ 'themes' => array()
211
+ );
212
+ //Global WP Updates
213
+ if ( isset( $original_options[ 'all' ] ) && "1" === $original_options[ 'all' ] ) {
214
+ $options[ 'core' ][ 'all_updates' ] = 'off';
215
+ }
216
+ //Global Plugin Updates
217
+ if ( isset( $original_options[ 'plugin' ] ) && "1" === $original_options[ 'plugin' ] ) {
218
+ $options[ 'core' ][ 'plugin_updates' ] = 'off';
219
+ }
220
+ //Global Theme Updates
221
+ if ( isset( $original_options[ 'theme' ] ) && "1" === $original_options[ 'theme' ] ) {
222
+ $options[ 'core' ][ 'theme_updates' ] = 'off';
223
+ }
224
+ //Global Core Updates
225
+ if ( isset( $original_options[ 'core' ] ) && "1" === $original_options[ 'core' ] ) {
226
+ $options[ 'core' ][ 'core_updates' ] = 'off';
227
+ }
228
+ //Global Individual Theme Updates
229
+ if ( isset( $original_options[ 'it' ] ) && "1" === $original_options[ 'it' ] ) {
230
+ if ( isset( $original_options[ 'themes' ] ) && is_array( $original_options[ 'themes' ] ) ) {
231
+ $options[ 'themes' ] = $original_options[ 'themes' ];
232
+ }
233
+ }
234
+ //Global Individual Plugin Updates
235
+ if ( isset( $original_options[ 'ip' ] ) && "1" === $original_options[ 'ip' ] ) {
236
+ if ( isset( $original_options[ 'plugins' ] ) && is_array( $original_options[ 'plugins' ] ) ) {
237
+ $options[ 'plugins' ] = $original_options[ 'plugins' ];
238
+ }
239
+ }
240
+ //Browser Nag
241
+ if ( isset( $original_options[ 'bnag' ] ) && "1" === $original_options[ 'bnag' ] ) {
242
+ $options[ 'core' ][ 'misc_browser_nag' ] = 'off';
243
+ }
244
+ //WordPress Version
245
+ if ( isset( $original_options[ 'wpv' ] ) && "1" === $original_options[ 'wpv' ] ) {
246
+ $options[ 'core' ][ 'misc_wp_footer' ] = 'off';
247
+ }
248
+ //Translation Updates
249
+ if ( isset( $original_options[ 'auto-translation-updates' ] ) && "1" === $original_options[ 'auto-translation-updates' ] ) {
250
+ $options[ 'core' ][ 'automatic_translation_updates' ] = 'off';
251
+ }
252
+ //Translation Updates
253
+ if ( isset( $original_options[ 'auto-core-emails' ] ) && "1" === $original_options[ 'auto-core-emails' ] ) {
254
+ $options[ 'core' ][ 'notification_core_update_emails' ] = 'off';
255
+ }
256
+ //Automatic Updates
257
+ if ( isset( $original_options[ 'abup' ] ) && "1" === $original_options[ 'abup' ] ) {
258
+ $options[ 'core' ][ 'automatic_major_updates' ] = 'off';
259
+ $options[ 'core' ][ 'automatic_minor_updates' ] = 'off';
260
+ $options[ 'core' ][ 'automatic_plugin_updates' ] = 'off';
261
+ $options[ 'core' ][ 'automatic_theme_updates' ] = 'off';
262
+ }
263
+
264
+ delete_option( '_disable_updates' );
265
+ delete_site_option( '_disable_updates' );
266
+ update_site_option( 'MPSUM', $options );
267
+
268
+ }
269
+ return $options;
270
+ }
271
+
272
+ /**
273
+ * Initialize the plugin and its dependencies.
274
+ *
275
+ * Initialize the plugin and its dependencies.
276
+ *
277
+ * @since 5.0.0
278
+ * @access public
279
+ * @see __construct
280
+ * @internal Uses plugins_loaded action
281
+ *
282
+ */
283
+ public function plugins_loaded() {
284
+ //Skip disable updates if a user is excluded
285
+ $disable_updates_skip = false;
286
+ if ( current_user_can( 'update_core' ) ) {
287
+ $current_user = wp_get_current_user();
288
+ $current_user_id = $current_user->ID;
289
+ $excluded_users = MPSUM_Updates_Manager::get_options( 'excluded_users' );
290
+ if ( in_array( $current_user_id, $excluded_users ) ) {
291
+ $disable_updates_skip = true;
292
+ }
293
+ }
294
+ if ( false === $disable_updates_skip ) {
295
+ MPSUM_Disable_Updates::run();
296
+ }
297
+
298
+
299
+ $not_doing_ajax = ( !defined( 'DOING_AJAX' ) || !DOING_AJAX );
300
+ $not_admin_disabled = ( !defined( 'MPSUM_DISABLE_ADMIN' ) || !MPSUM_DISABLE_ADMIN );
301
+ if ( is_admin() && $not_doing_ajax && $not_admin_disabled ) {
302
+ MPSUM_Admin::run();
303
+ }
304
+ }
305
+
306
+ /**
307
+ * Save plugin options.
308
+ *
309
+ * Saves the plugin options based on context. If no context is provided, updates all options.
310
+ *
311
+ * @since 5.0.0
312
+ * @access static
313
+ *
314
+ * @param array $options Associative array of plugin options.
315
+ * @param string $context Array key of which options to update
316
+ */
317
+ public static function update_options( $options = array(), $context = '' ) {
318
+ $options_to_save = self::get_options();
319
+
320
+ if ( !empty( $context ) && is_string( $context ) ) {
321
+ $options_to_save[ $context ] = $options;
322
+ } else {
323
+ $options_to_save = $options;
324
+ }
325
+
326
+ self::$options = $options_to_save;
327
+ update_site_option( 'MPSUM', $options_to_save );
328
+ }
329
+
330
+ } //end class MPSUM_Updates_Manager
331
+
332
+ MPSUM_Updates_Manager::get_instance();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,434 +1,81 @@
1
- === Disable Updates Manager ===
2
- Contributors: MPS Plugins, kidsguide, shazahm1@hotmail.com, szepe.viktor
3
- Tags: Disable All Updates, Disable Plugin Updates, Disable Theme Updates, Disable WordPress Core Updates, Disable Core Updates, Disable Updates Settings, Disable Updates, Disable All WordPress Updates, Disable All WordPress Updates Settings, Disable Updates Manager, Disable All Updates Manager, Disable Updates Manager Settings, Update Check, No Browser Nag, MPS Plugins, Manager, Disable, Updates
4
- Requires at least: 2.3
5
- Tested up to: 4.1
6
- Stable tag: trunk
7
-
8
- A configurable plugin that disables updates for you. Easy, clean and helpful + Great Support.
9
-
10
- == Description ==
11
- This plugin is configurable! Check the type of update(s) you would like to disable in the settings page along with other helpful settings. Watch the video tutorial below for more information.
12
-
13
- = Features Include =
14
- <ul>
15
- <ol>Disable Update Manager is the first plugin to offer a feature to both disable plugins and themes individually.</ol>
16
- <ol>Disable Updates Manager makes disabling all core, theme, and/or plugin updates easy. Just check the checkboxes and save the settings.</ol>
17
- <ol>Disable Updates Manager includes lots of other settings to disable background updates and lots of other things.</ol>
18
- </ul>
19
-
20
- = Blog =
21
- <a href="http://www.mpswp.wordpress.com">Check our blog for more information about Disable Updates Manager</a>.
22
-
23
- = Survey =
24
- Take the feedback survey to give your feedback on this plugin. <a href="http://sparrowkids2.polldaddy.com/s/disable-updates-manager-feedbeck">http://sparrowkids2.polldaddy.com/s/disable-updates-manager-feedbeck</a>
25
-
26
- = There are several ways you can get involved to help make Disable Updates Manager better =
27
- <ol>
28
- <li>=Report Bugs:= If you find a bug, error or other problem, please report it on <a href="https://github.com/Websiteguy/disable-updates-manager/issues/new">GitHub</a> or in the <a href="https://wordpress.org/support/plugin/stops-core-theme-and-plugin-updates">WordPress Support Forum</a>!</li>
29
- <li>=Suggest New Features:= Have an awesome new feature that you would like to be added? Please share it on <a href="https://github.com/Websiteguy/disable-updates-manager/issues/new">GitHub</a> or the <a href="https://wordpress.org/support/plugin/stops-core-theme-and-plugin-updates">WordPress Support Forum</a>!</li>
30
- <li>=Reply to Support:= The easiest way to get involved is to help out on issues already reported in <a href="https://github.com/Websiteguy/disable-updates-manager/compare">GitHub</a> or the <a href="https://wordpress.org/support/plugin/stops-core-theme-and-plugin-updates">WordPress Support Forum</a>.</li>
31
- </ol>
32
-
33
- = Video Tutorials =
34
- [youtube https://www.youtube.com/watch?v=VYEQg-hZd58]
35
- [youtube https://www.youtube.com/watch?v=mYznDVsbVBk]
36
- [youtube https://www.youtube.com/watch?v=1R-be48AvrE]
37
- [youtube https://www.youtube.com/watch?v=Kd4s3EOcUtw]
38
-
39
- == Screenshots ==
40
- 1. Disable Updates Globally
41
- 2. Other Settings
42
- 3. Disable Plugin Updates
43
- 4. Disable Theme Updates
44
- 5. Screen Options
45
- 6. Help Tab
46
-
47
- == FAQ ==
48
- <strong>Q: What is a safe way to update the WordPress Core if I ever need to?</strong>
49
- A: Check out this post on our blog. http://mpswp.wordpress.com/2014/11/26/great-steps-to-follow-before-updating-your-wordpress-core/
50
-
51
- <strong>Q: If I have an automatic plugin updating plugin installed at the same time as disabling plugin updates, what will happen?</strong>
52
- A: Disable Updates Manager disables the parts of the update system depending on which settings update have checked. If you have the Disable All Plugin Updates setting checked at the same time as having a automatic plugin update plugin installed, then Disable Updates Manager overrides it to disable updates no matter what.
53
-
54
- == Installation ==
55
- <strong>Installing Disable Updates Manager</strong>
56
-
57
- 1. Install Disable Updates Manager either via the WordPress.org plugin page and uploading the files to your FTP manually, or going to the and new plugins section in your dashboard.
58
-
59
- 2. Activate Disable Updates Manager by MPS Plugins.
60
-
61
- 3. Click on the configure button next to the plugin or go to the plugin settings page under the settings section in your dashboard.
62
-
63
- == Changelog ==
64
- = <a href="https://github.com/Websiteguy/disable-updates-manager/pull/37">4.7.0</a> =
65
- * Slight change in metabox order. https://github.com/Websiteguy/disable-updates-manager/issues/47
66
- * Change description in the readme.txt. https://github.com/Websiteguy/disable-updates-manager/issues/41
67
- * Works with WordPress Version 4.1. https://github.com/Websiteguy/disable-updates-manager/issues/35 , https://github.com/Websiteguy/disable-updates-manager/issues/38
68
- * Added back the FAQ in the readme.txt. https://github.com/Websiteguy/disable-updates-manager/issues/45
69
- * Fixed small typo in license.txt. https://github.com/Websiteguy/disable-updates-manager/issues/46
70
- * Redid translation files. https://github.com/Websiteguy/disable-updates-manager/issues/40
71
- * Remove home submenu when removing update submenu. https://github.com/Websiteguy/disable-updates-manager/issues/42
72
- * Changed some stuff in the help tab. https://github.com/Websiteguy/disable-updates-manager/issues/43
73
- * Combine video tutorials into one. https://github.com/Websiteguy/disable-updates-manager/issues/39
74
- * Added proper file spacing in all files. https://github.com/Websiteguy/disable-updates-manager/issues/44
75
- * Added proper file notes. https://github.com/Websiteguy/disable-updates-manager/issues/48
76
- * Add 2.3 to 2.7 disable updates to themes. https://github.com/Websiteguy/disable-updates-manager/issues/50
77
-
78
- = 4.6.0 =
79
- * Removed unknown character to fix debug error.
80
- * Updated screenshots.
81
- * Works with WordPress 4.0.1 and 4.1beta1.
82
- * Fixed error that didn't remove rate notice in help tab.
83
- * Updated some help tab content.
84
-
85
- = 4.5.0* =
86
- * Added rate plugin button.
87
- * Added Feedback survey button.
88
- * Removed rate plugin notice in help tab.
89
- * Edited disable plugins individually text display on plugin page when activated.
90
- * Removed disable major and minor core feature. It wasn't working but we hope to get it back there in a later version of Disable Updates Manager.
91
- * Edited plugin description a little.
92
- * Edited help tab information.
93
- * Updated screenshots.
94
- * Removed FAQ link on plugin page.
95
-
96
- = 4.4.1.2* =
97
- * Attempt 3 at fixing the major and minor core updates setting.
98
-
99
- = 4.4.1.1* =
100
- * Attempt 2 at fixing the major and minor core updates setting.
101
- * Renamed function.php to main.php.
102
- * Removed random image in repository.
103
-
104
- = 4.4.1* =
105
- * Fixed disable major and minor settings.
106
-
107
- = 4.4.0.1* =
108
- * Fixed video tutorial typo.
109
- * Fixed readme.txt typo.
110
-
111
- = 4.4.0* =
112
- * Removed title /* */ from chosen.min.css to make it more compressed.
113
- * Added disable auto translation updates setting.
114
- * Added disable auto core update e-mails setting.
115
- * Added disable minor core updates setting.
116
- * Added disable major core updates setting.
117
- * Added better GitHub links to readme.txt.
118
- * Removed FAQ in readme.txt.
119
- * Edited description in readme.txt.
120
- * Fixed typo in the Disable Plugins Individually setting.
121
- * Fixed typo in the Disable Themes Individually setting.
122
- * Added Settings Layout video tutorial.
123
- * Added Disable Update Types video tutorial.
124
- * Added Disable Plugins and Themes Individually video tutorial.
125
- * Added Other Settings video tutorial.
126
- * Removed old tutorials.
127
- * Edited contributor section in the settings help tab.
128
- * Few minor note changes in files.
129
-
130
- = 4.3.13 =
131
- * Fixed contributor issue.
132
- * Updated description in readme.txt.
133
- * Removed unnecessary versions (0.5 - 1.9.0).
134
-
135
- = 4.3.12.2* =
136
- * Fixed screenshot 5 showing incorrect information.
137
- * Search Exclude 1.1.0 fixes capability with Disable Updates Manager.
138
-
139
- = 4.3.12 =
140
- * Updated readme.txt to make it easier to understand.
141
-
142
- = 4.3.11* =
143
- * Added some better screenshots.
144
-
145
- = 4.3.10 =
146
- * WordPress 4.0 capability added.
147
- * Fixed plugin icon not showing.
148
-
149
- = 4.3.0 =
150
- * Added custom plugin installer icon.
151
- * Tested with WordPress 4.0RC1 (4.0 to be released September 4, 2014).
152
- * Modified some help tab content.
153
- * Added proper CSS for columns in help tab.
154
- * Modified settings alignment.
155
- * Changed metaboxes arrangement in screen options.
156
- * Changed metaboxes titles.
157
- * Removed some versions in changelog.
158
-
159
- = 4.2.24 =
160
- * New Video Promo!
161
- * Tested with WordPress 4.0 beta4.
162
- * Made help tab rate notice display on all tabs.
163
- * Rearranged the tutorials.
164
-
165
- = 4.2.23* =
166
- * Fixed debug error
167
-
168
- = 4.2.22* =
169
- * Fixed debug to make true.
170
- * Moved settings notice into help tab.
171
- * Added extra content to notice in settings.
172
- * Added new notice in help tab.
173
- * Added new tags to readme.txt.
174
-
175
- = 4.2.21 =
176
- * Added capability section to help tab.
177
- * Added and removed a few minor things.
178
-
179
- = 4.2.20* =
180
- * Removed double style.css (removed the one that was not in assets).
181
- * Changed License.txt.
182
- * Added new contributor to help tab.
183
- * Added capability with WordPress 3.9.2, 4.0 beta, and 4.0.
184
- * Reformatted tooltips.
185
- * Added some <code><br></code> and <code><div></code> classes to the settings for better spacing.
186
- * Updated settings security.
187
-
188
- = 4.2.12 =
189
- * New contributor!
190
- * Fixed unable to chosen which plugins to disable.
191
-
192
- = 4.2.11* =
193
- * Fixed screenshots.
194
- * Fixed broken links.
195
- * Added the language files again (this should fix the language issue).
196
-
197
- = 4.2.10* =
198
- * Changed blog address to <a target="_blank" href="http://mpswp.wordpress.com/">mpswp.wordpress.com</a>
199
- * Uploaded version 4.2.10 on <a target="_blank" href="https://github.com/Websiteguy/disable-updates-manager">GitHub</a>.
200
- * Added better documentation in readme.txt.
201
- * Fixed changelog error in readme.txt.
202
- * Fixed installation text in readme.txt.
203
- * Fixed error code "Warning: array_key_exists() expects parameter 2 to be array, boolean given in .../wp-content/plugins/stops-core-theme-and-plugin-updates/Function.php on line 431". Thanks for the support topics "Warning: array_key_exists() expects parameter 2 to be array..." and "Receive error message when selecting disable individual plugins" along with help from the contributors.
204
- * Fixed error code "Warning: array_fill_keys() expects parameter 1 to be array, null given in .../wp-content/plugins/stops-core-theme-and-plugin-updates/Function.php on line 126".
205
- * Fixed error code "Warning: Cannot modify header information - headers already sent by (output started at .../wp-content/plugins/stops-core-theme-and-plugin-updates/Function.php:126) in .../wp-includes/pluggable.php on line 1121".
206
- * Added chosen to the settings for extra awesomeness
207
- * Modified the Disable Plugins Individually setting.
208
- * Added some disable settings values.
209
- * Added drag and drop metaboxes with screen options.
210
- * Added a helpful help tab.
211
- * Changed some tooltips.
212
- * Updated all languages + made it better.
213
- * Changed some metaboxes titles.
214
- * Updated new video tutorial.
215
- * Works with WordPress version 4.0 beta
216
- * New feature to disable the browser nag in the WordPress Dashboard.
217
- * Did some other minor fixes.
218
-
219
- = 4.1.10 =
220
- * Uploaded version 4.1.10 on <a target="_blank" href="https://github.com/Websiteguy/disable-updates-manager">GitHub</a>.
221
- * Fixed error code "Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Disable_Updates' does not have a method 'plugin_unblock_link' in .../wp-includes/plugin.php on line 470".
222
- * Updated website address to <a target="_blank" href="http://devwpp.wordpress.com/">devwpp.wordpress.com</a>
223
- * Changed official name to devWPP in all files.
224
- * Changed some notes in the code.
225
-
226
- = 4.1.0 =
227
- * <strong>BIG:</strong> code clean-up (moved code, fixed code, etc.). - Thanks <a href="https://github.com/Websiteguy/disable-updates-manager/pull/4">GitHub Pull Request</a> and other help!!!
228
- * Added: version 4.1.0 on GitHub (including the lang file).
229
- * New Contributor: shazahm1!
230
- * New: video tutroial.
231
- * New: disable themes individually.
232
- * New: wp-cli compatiblity. - Thanks <a href="https://github.com/Websiteguy/disable-updates-manager/issues/2">GitHub Issue</a>!
233
- * Fixed: changelog footnote star error.
234
- * Updated: disable plugin updates.
235
- * Updated: installation section.
236
- * Updated: screenshots.
237
- * Renamed: files. - Thanks <a href="https://github.com/Websiteguy/disable-updates-manager/issues/11">GitHub Issue</a>!
238
-
239
- = 4.0.3 =
240
- * Fixed: FAQ spelling mistakes.
241
- * Fixed: changelog star error.
242
- * Fixed: error with no lang file in version 4.0.
243
- * Added: version 4.0.3 on GitHub.
244
- * Added: name to license.txt file.
245
- * Cleaned: css files (having trouble with php files).
246
- * Changed: description.
247
- * Renamed: remove WordPress version from footer in settings.
248
-
249
- = 4.0.2 =
250
- * Fixed: unchecked error in settings.
251
- * Added: version 4.0.2 to GitHub.
252
- * Removed: code format (will add in version 4.0.3 which will be released soon).
253
- * Added: 4.0 available for download.
254
- * Added: footnote at bottom of changelog.
255
-
256
- = 4.0.1* =
257
- * Updated: code to make it way easier to understand. - Thanks szepe.viktor!
258
- * Updated/Added: video tutorials.
259
- * Added: version 4.0.1 to GitHub.
260
- * Added: capability with WordPress version 3.9.1.
261
-
262
- = 4.0 =
263
- * Fixed: output problems.
264
- * Fixed: remove WordPress version code (removing all footer text now only removes version).
265
- * Fixed: tooltips CSS; fixed overlapping errors.
266
- * Updated: readme.txt.
267
- * Updated: video tutorial (added music). Note: new video tutorial coming soon!
268
- * Updated: GitHub version to 4.0 (Note: We did not put the lang file in GitHub). - Thanks szepe.viktor!
269
- * Updated: link box CSS in settings.
270
- * Updated: settings notice CSS.
271
- * Updated: tooltips text.
272
- * Renamed: settings page from Disable Updates to Disable Updates Manager.
273
- * Moved: settings error notice in php.
274
- * Moved: settings page to Settings section in admin area.
275
- * Added: some <?php and ?> tags at the end of the files.
276
- * Added: Settings saved notice in settings.
277
- * Added: disable core, theme and plugin updates e-mails debug true - Thanks szepe.viktor!
278
- * Added: license.txt
279
- * Added: capability with WordPress 3.8.2, 3.8.3, and 3.9.
280
- * Added: GitHub link in settings.
281
- * Added: GitHub link under plugin on plugin list.
282
- * Added: Afrikaans translation.
283
- * Added: Catatla/Espanya translation.
284
- * Added: Dansk translation.
285
- * Added: Deutsch translation.
286
- * Added: English (Canada) translation.
287
- * Added: English (UK) translation.
288
- * Added: Espanol translation.
289
- * Added: Francais (Canada) translation.
290
- * Added: Francais (France) translation.
291
- * Added: Italiano translation.
292
- * Added: Romana translation.
293
- * Removed: "New format coming soon!" sign under Disable Plugins Individually setting.
294
- = Notes =
295
- * If you have any languages that you would like use to add, please post a support topic on wordpress.org or post it on <a href="https://github.com/Websiteguy/disable-updates-manager">GitHub</a>.
296
-
297
- = 3.6.0 =
298
- * Updated: tutorial link (forgot last update).
299
- * Updated: notice CSS to make auto size.
300
- * Fixed: old name for settings page (in URL).
301
- * Added: style.css.
302
- * Added: uninstall.php.
303
- * Added: "Other Notes" in readme.txt.
304
- * Removed: CSS from function.php.
305
-
306
- = 3.5.0 =
307
- * Added: "Disable Plugins Individually" postbox.
308
- * Removed: "Disable Updates Individually" section.
309
- * Updated: screenshots.
310
- * Updated: video tutorial.
311
- * Updated: readme.txt description.
312
- * Updated: code notes.
313
- * Changed: "Disable Plugin Updates Individually" format (working on better format for upcoming versions).
314
- * Changed: postbox format.
315
- * Changed: "Please Note" border box to proper notice.
316
- * Moved: CSS script.
317
-
318
- = second update =
319
- * Fixed: screenshot error.
320
- * Fixed: changelog error.
321
- * Fixed: contributor error.
322
-
323
- (Sorry for all these errors)
324
-
325
- = 3.4.0 =
326
- * Added "Disable Plugins Individually" Setting and Section
327
- * Added Help Postbox to Settings
328
- * Updated Screenshots
329
- * Added Tooltips to some Settings
330
- * Added Better License
331
- * Updated Description
332
-
333
- = 3.3.0 =
334
- * Fixed Error with Remove WordPress Version from Footer in Admin
335
- * Added Help Spot in Settings
336
- * Added border-radius Code to Postboxes and Boxes
337
- * Updated Screenshots
338
- * FAQ Updated
339
-
340
- = 3.2.0 =
341
- * Fixed Please Note Spelling Mistake
342
- * Fixed Readme.txt Spelling Mistakes
343
- * Works with WordPress 3.8.1
344
- * Changed Video Tutorial Link
345
- * Added CSS to Postboxes and Please Note Box (changed width, added padding, moved around)
346
-
347
- = 3.1.0 =
348
- * Added "Disable Automatic Background Updates" Setting
349
- * Removed "Please Note!" Postbox
350
- * Added "Please Note" Notice in Settings
351
- * Moved Around Other Settings
352
- * Screenshots Updated
353
- * Removed Settings (combined into "Disable All Updates" setting)
354
- * Fixed "Other Settings" Postbox "<span>" Code for Settings
355
- * Updated Video Tutorial (using version 3.1.0)
356
-
357
- = 3.0.0 =
358
- * Updated Readme.txt Description
359
- * Removed "Other Notes" in Readme.txt
360
- * Added More Readme.txt Tags
361
- * Added "Disable Debug E-mails" Setting
362
- * Added "Disable Update E-mails" Setting
363
- * Added "Disable WordPress Automatic Updates" Setting
364
- * Added "Remove WordPress Core Version" Setting
365
- * Added "Please Note" Postbox
366
- * Combined "Disable All Updates" Postbox with "Disable Updates" Postbox
367
- * Fixed Half Screen Display
368
- * Removed Language Translate <small>(didn't work)</small>
369
-
370
- = 2.7.0 =
371
- * Updated Readme.txt Description
372
- * Fixed function in settings.
373
-
374
- = 2.6.0 =
375
- * Added Better Settings Description
376
- * Fixed Disable All Updates Setting Error <strong>(Thanks conservativeread!)</strong>
377
- * Remove the Updates Page Setting from Disable All Updates Setting <strong>(Thanks again conservativeread!)</strong>
378
-
379
- = 2.5.1 =
380
- * Changed Save Button Text
381
- * HTML Notes Updated
382
- * Fixed Changelog Errors
383
- * Updated Description
384
-
385
- = 2.5.0 =
386
- * Added Postboxes
387
- * Remove Delete Files Setting
388
- * Added Disable All Updates Setting
389
- * Renamed Name on Settings Page
390
- * HTML Notes Updated
391
- * Delete Translation .mo File
392
- * Readme.txt Error Fixed
393
-
394
- = 2.4.0 =
395
- * Plugin Name Changed (Disable Updates Manager)
396
- * Tags Updated (Make it easier to find this plugin)
397
- * Fixed Some HTML
398
- * Added Translation (Test)
399
-
400
- = 2.3.0 =
401
- * Remove File Setting Added
402
- * Fixed up Settings Page
403
- * Updated Readme.txt
404
- * Removed Tutorial on Settings Page (their is a link to the tutorial in the plugin page)
405
-
406
- = 2.2.1 =
407
- * Fixed Readme.txt Errors with Boxes
408
-
409
- = 2.2.0 =
410
- * Settings Page Updated (Added Tutorial to Settings Page)
411
- * Video Tutorial Updated
412
- * New Settings Page Name (Disable Updates)
413
-
414
- = 2.1.0 =
415
- * Settings Page Updated (under Dashboard and with more settings)
416
- * Fixed Disable Plugin, Theme, and Core Disabling Problem
417
- * Updated Readme.txt
418
- * Removed Hide Updates Notice Setting
419
- * Remove Admin Notice <strong>(Thanks conservativeread!)</strong>
420
-
421
- = 2.0.0 =
422
- * Settings Page Added
423
- * Disable One, Two, or Three Feature Added
424
- * Updated Screenshots
425
- * Updated Readme.txt
426
-
427
- = 0.1* =
428
- * Published on Wordpress.org
429
- (September 1, 2013)
430
-
431
- = Note =
432
- Versions 0.2 to 1.9.0 are not listed in this changelog.
433
-
434
- = * versions not available for download. =
1
+ === Easy Updates Manager ===
2
+ Contributors: kidsguide, ronalfy
3
+ Tags: updates manager, easy updates manager, disable updates manager, disable updates, update control, plugin updates, theme updates, core updates, automatic updates
4
+ Requires at least: 4.0
5
+ Tested up to: 4.2
6
+ Stable tag: 5.0.0
7
+ License: GPLv2 or later
8
+
9
+ Manage all your WordPress updates, including individual plugin/theme updates, automatic updates, and loads more. Also works with WordPress Multisite.
10
+
11
+ == Description ==
12
+ Easy Updates Manager is a light yet powerful plugin which enables you to manage all types of updates on your single site install or in WordPress Multisite. With loads of settings making endless possibilities for configuration, Easy Updates Manager is an obvious choice for anyone wanting to take control of their websites updates.
13
+
14
+ [youtube https://www.youtube.com/watch?v=MmNrNAkCI0g]
15
+
16
+ = Features Include =
17
+ <ul>
18
+ <li>All Updates - This setting quite easily just overrides all other settings and disables everything.</li>
19
+ <li>WordPress Core Updates- This setting is used to toggle on and off the WordPress core updates.</li>
20
+ <li>Plugin Updates - This setting is used to disable all plugin updates on your website.</li>
21
+ <li>Theme Updates - This setting is used to disable all theme updates on your website.</li>
22
+ <li>Major Releases - This setting toggles whether or not you want the major WordPress core versions to automatically update themselves.</li>
23
+ <li>Minor Releases - This setting toggles whether or not you want the minor WordPress core versions to automatically update themselves.</li>
24
+ <li>Development Updates - This setting toggles whether or not you want the bleeding edge version of WordPress to automatically update itself.</li>
25
+ <li>Plugin Updates - This setting can either automatically update all your plugins, or automatically update any select plugins you want.</li>
26
+ <li>Theme Updates - This setting can either automatically update all your themes, or automatically update any select themes you want.</li>
27
+ <li>Translation Updates - This setting can unable automatic updating or translation updates.</li>
28
+ <li>Core Update E-mails - This setting disables the core update e-mails.</li>
29
+ <li>Browser Nag - This setting removes the WordPress browser nag which appears when you are using an older browser.</li>
30
+ <li>WordPress Version in Footer - This setting will remove the WordPress version in the admin footer on your website.</li>
31
+ <li>Disable plugin updates and automatic updates individually by selecting which plugins on a table. Also able to bulk select plugins.</li>
32
+ <li>Disable theme updates and automatic updates individually by selecting which themes on a table. Also able to bulk select themes.</li>
33
+ <li>The ability to block users from configuring the settings.</li>
34
+ <li>The ability to select which users can still see and perform updates.</li>
35
+ </ul>
36
+
37
+ For more information on how to use this plugin and where to get support, check out our new <a href="https://github.com/easy-updates-manager/easy-updates-manager/wiki">wiki</a>.
38
+
39
+ == Screenshots ==
40
+ 1. Easy Updates Manager on Single-Site Plugins Screen with Shortcut Configure Option
41
+ 2. Easy Updates Manager Options are Under Dashboard on Single-Site
42
+ 3. Easy Updates Manager on Multisite Plugins Screen with Shortcut Configure Option
43
+ 4. Easy Updates Manager Options are Under Updates on Multisite
44
+ 5. General Options Allow You to Enable or Disable Updates
45
+ 6. Plugin Options Allow You to Enable or Disable Updates Per Plugin
46
+ 7. Theme Options Allow You to Enable or Disable Updates Per Theme
47
+ 8. Advanced Options Allow You to Exclude Users or Reset All Options
48
+ 9. Help Screen Provides Helpful Links
49
+
50
+ == Installation ==
51
+ <strong>Installing Easy Updates Manager through FTP</strong>
52
+
53
+ 1. Upload the Easy Updates Manager folder to the '/wp-content/plugins/' directory (make sure it is unzipped)
54
+ 2. Activate the Easy Updates Manager plugin through the 'Plugins' menu in WordPress
55
+ 3. Configure the plugin by going to the 'Update Options' section in your admin area under the Dashboard
56
+
57
+ <strong>Installing Easy Updates Manager in your WordPress Dashboard</strong> (recommended)
58
+
59
+ 1. You can also upload it by going into your 'Plugins' section and selecting add a new plugin
60
+ 2. Search for the plugin by typing 'Easy Updates Manager' into the search bar
61
+ 3. Install and activate the plugin by pushing the 'Install' button and then the 'activate plugin' link
62
+ 4. Configure the plugin by going to the 'Update Options' section in your admin area under the Dashboard
63
+
64
+ Activate the plugin after installation. If you are on Multisite, the plugin must be network-activated.
65
+
66
+ == Changelog ==
67
+ = 5.0.0 =
68
+ Updated 2015-04-23 to ensure WordPress 4.2 compatibility
69
+ Released 2015-03-24
70
+
71
+ In version 5.0.0 we completely re-wrote the plugin to offer a faster and more secure experience. You will also notice that we added lots more settings to cover almost every aspect of managing updates.
72
+
73
+ * Complete re-write of Disable Updates Manager with new user interface.
74
+ * Now compatible with WordPress Multisite installations.
75
+ * New name: Easy Updates Manager
76
+ * New contributor: <a href="https://profiles.wordpress.org/ronalfy">ronalfy</a>
77
+
78
+ == Upgrade Notice ==
79
+
80
+ = 5.0.0 =
81
+ Major plugin rewrite and update. Updating will port over your old options. We recommend you perform a backup of your site before updating. Now you can configure just about any aspect of WordPress updates.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
uninstall.php CHANGED
@@ -1,7 +1,17 @@
1
  <?php
2
-
3
- /* Description: Removes all data when deleted. */
 
 
 
 
 
 
 
4
  if (!defined( 'WP_UNINSTALL_PLUGIN' )) {
5
  exit ();
6
  }
7
- delete_option('_disable_updates');
 
 
 
1
  <?php
2
+ /**
3
+ * Uninstall script
4
+ *
5
+ * Uninstall script for Easy Updates Manager.
6
+ *
7
+ * @since 5.0.0
8
+ *
9
+ * @package WordPress
10
+ */
11
  if (!defined( 'WP_UNINSTALL_PLUGIN' )) {
12
  exit ();
13
  }
14
+ delete_option( '_disable_updates' );
15
+ delete_site_option( '_disable_updates' );
16
+ delete_option( 'MPSUM' );
17
+ delete_site_option( 'MPSUM' );
vendor/chosen/Thumbs.db DELETED
Binary file
vendor/chosen/chosen-sprite.png DELETED
Binary file
vendor/chosen/chosen-sprite@2x.png DELETED
Binary file
vendor/chosen/chosen.css DELETED
@@ -1,435 +0,0 @@
1
- /*!
2
- Chosen, a Select Box Enhancer for jQuery and Prototype
3
- by Patrick Filler for Harvest, http://getharvest.com
4
-
5
- Version 1.1.0
6
- Full source at https://github.com/harvesthq/chosen
7
- Copyright (c) 2011 Harvest http://getharvest.com
8
-
9
- MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
- This file is generated by `grunt build`, do not edit it by hand.
11
- */
12
-
13
- /* @group Base */
14
- .chosen-container {
15
- position: relative;
16
- display: inline-block;
17
- vertical-align: middle;
18
- font-size: 13px;
19
- zoom: 1;
20
- *display: inline;
21
- -webkit-user-select: none;
22
- -moz-user-select: none;
23
- user-select: none;
24
- }
25
- .chosen-container .chosen-drop {
26
- position: absolute;
27
- top: 100%;
28
- left: -9999px;
29
- z-index: 1010;
30
- -webkit-box-sizing: border-box;
31
- -moz-box-sizing: border-box;
32
- box-sizing: border-box;
33
- width: 100%;
34
- border: 1px solid #aaa;
35
- border-top: 0;
36
- background: #fff;
37
- box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
38
- }
39
- .chosen-container.chosen-with-drop .chosen-drop {
40
- left: 0;
41
- }
42
- .chosen-container a {
43
- cursor: pointer;
44
- }
45
-
46
- /* @end */
47
- /* @group Single Chosen */
48
- .chosen-container-single .chosen-single {
49
- position: relative;
50
- display: block;
51
- overflow: hidden;
52
- padding: 0 0 0 8px;
53
- height: 23px;
54
- border: 1px solid #aaa;
55
- border-radius: 5px;
56
- background-color: #fff;
57
- background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
58
- background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
59
- background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
60
- background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
61
- background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
62
- background-clip: padding-box;
63
- box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
64
- color: #444;
65
- text-decoration: none;
66
- white-space: nowrap;
67
- line-height: 24px;
68
- }
69
- .chosen-container-single .chosen-default {
70
- color: #999;
71
- }
72
- .chosen-container-single .chosen-single span {
73
- display: block;
74
- overflow: hidden;
75
- margin-right: 26px;
76
- text-overflow: ellipsis;
77
- white-space: nowrap;
78
- }
79
- .chosen-container-single .chosen-single-with-deselect span {
80
- margin-right: 38px;
81
- }
82
- .chosen-container-single .chosen-single abbr {
83
- position: absolute;
84
- top: 6px;
85
- right: 26px;
86
- display: block;
87
- width: 12px;
88
- height: 12px;
89
- background: url('chosen-sprite.png') -42px 1px no-repeat;
90
- font-size: 1px;
91
- }
92
- .chosen-container-single .chosen-single abbr:hover {
93
- background-position: -42px -10px;
94
- }
95
- .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
96
- background-position: -42px -10px;
97
- }
98
- .chosen-container-single .chosen-single div {
99
- position: absolute;
100
- top: 0;
101
- right: 0;
102
- display: block;
103
- width: 18px;
104
- height: 100%;
105
- }
106
- .chosen-container-single .chosen-single div b {
107
- display: block;
108
- width: 100%;
109
- height: 100%;
110
- background: url('chosen-sprite.png') no-repeat 0px 2px;
111
- }
112
- .chosen-container-single .chosen-search {
113
- position: relative;
114
- z-index: 1010;
115
- margin: 0;
116
- padding: 3px 4px;
117
- white-space: nowrap;
118
- }
119
- .chosen-container-single .chosen-search input[type="text"] {
120
- -webkit-box-sizing: border-box;
121
- -moz-box-sizing: border-box;
122
- box-sizing: border-box;
123
- margin: 1px 0;
124
- padding: 4px 20px 4px 5px;
125
- width: 100%;
126
- height: auto;
127
- outline: 0;
128
- border: 1px solid #aaa;
129
- background: white url('chosen-sprite.png') no-repeat 100% -20px;
130
- background: url('chosen-sprite.png') no-repeat 100% -20px;
131
- font-size: 1em;
132
- font-family: sans-serif;
133
- line-height: normal;
134
- border-radius: 0;
135
- }
136
- .chosen-container-single .chosen-drop {
137
- margin-top: -1px;
138
- border-radius: 0 0 4px 4px;
139
- background-clip: padding-box;
140
- }
141
- .chosen-container-single.chosen-container-single-nosearch .chosen-search {
142
- position: absolute;
143
- left: -9999px;
144
- }
145
-
146
- /* @end */
147
- /* @group Results */
148
- .chosen-container .chosen-results {
149
- position: relative;
150
- overflow-x: hidden;
151
- overflow-y: auto;
152
- margin: 0 4px 4px 0;
153
- padding: 0 0 0 4px;
154
- max-height: 240px;
155
- -webkit-overflow-scrolling: touch;
156
- }
157
- .chosen-container .chosen-results li {
158
- display: none;
159
- margin: 0;
160
- padding: 5px 6px;
161
- list-style: none;
162
- line-height: 15px;
163
- -webkit-touch-callout: none;
164
- }
165
- .chosen-container .chosen-results li.active-result {
166
- display: list-item;
167
- cursor: pointer;
168
- }
169
- .chosen-container .chosen-results li.disabled-result {
170
- display: list-item;
171
- color: #ccc;
172
- cursor: default;
173
- }
174
- .chosen-container .chosen-results li.highlighted {
175
- background-color: #3875d7;
176
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
177
- background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
178
- background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
179
- background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
180
- background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
181
- color: #fff;
182
- }
183
- .chosen-container .chosen-results li.no-results {
184
- display: list-item;
185
- background: #f4f4f4;
186
- }
187
- .chosen-container .chosen-results li.group-result {
188
- display: list-item;
189
- font-weight: bold;
190
- cursor: default;
191
- }
192
- .chosen-container .chosen-results li.group-option {
193
- padding-left: 15px;
194
- }
195
- .chosen-container .chosen-results li em {
196
- font-style: normal;
197
- text-decoration: underline;
198
- }
199
-
200
- /* @end */
201
- /* @group Multi Chosen */
202
- .chosen-container-multi .chosen-choices {
203
- position: relative;
204
- overflow: hidden;
205
- -webkit-box-sizing: border-box;
206
- -moz-box-sizing: border-box;
207
- box-sizing: border-box;
208
- margin: 0;
209
- padding: 0;
210
- width: 100%;
211
- height: auto !important;
212
- height: 1%;
213
- border: 1px solid #aaa;
214
- background-color: #fff;
215
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
216
- background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
217
- background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
218
- background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
219
- background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
220
- cursor: text;
221
- }
222
- .chosen-container-multi .chosen-choices li {
223
- float: left;
224
- list-style: none;
225
- }
226
- .chosen-container-multi .chosen-choices li.search-field {
227
- margin: 0;
228
- padding: 0;
229
- white-space: nowrap;
230
- }
231
- .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
232
- margin: 1px 0;
233
- padding: 5px;
234
- height: 15px;
235
- outline: 0;
236
- border: 0 !important;
237
- background: transparent !important;
238
- box-shadow: none;
239
- color: #666;
240
- font-size: 100%;
241
- font-family: sans-serif;
242
- line-height: normal;
243
- border-radius: 0;
244
- }
245
- .chosen-container-multi .chosen-choices li.search-field .default {
246
- color: #999;
247
- }
248
- .chosen-container-multi .chosen-choices li.search-choice {
249
- position: relative;
250
- margin: 3px 0 3px 5px;
251
- padding: 3px 20px 3px 5px;
252
- border: 1px solid #aaa;
253
- border-radius: 3px;
254
- background-color: #e4e4e4;
255
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
256
- background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
257
- background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
258
- background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
259
- background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
260
- background-clip: padding-box;
261
- box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
262
- color: #333;
263
- line-height: 13px;
264
- cursor: default;
265
- }
266
- .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
267
- position: absolute;
268
- top: 4px;
269
- right: 3px;
270
- display: block;
271
- width: 12px;
272
- height: 12px;
273
- background: url('chosen-sprite.png') -42px 1px no-repeat;
274
- font-size: 1px;
275
- }
276
- .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
277
- background-position: -42px -10px;
278
- }
279
- .chosen-container-multi .chosen-choices li.search-choice-disabled {
280
- padding-right: 5px;
281
- border: 1px solid #ccc;
282
- background-color: #e4e4e4;
283
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
284
- background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
285
- background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
286
- background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
287
- background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
288
- color: #666;
289
- }
290
- .chosen-container-multi .chosen-choices li.search-choice-focus {
291
- background: #d4d4d4;
292
- }
293
- .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
294
- background-position: -42px -10px;
295
- }
296
- .chosen-container-multi .chosen-results {
297
- margin: 0;
298
- padding: 0;
299
- }
300
- .chosen-container-multi .chosen-drop .result-selected {
301
- display: list-item;
302
- color: #ccc;
303
- cursor: default;
304
- }
305
-
306
- /* @end */
307
- /* @group Active */
308
- .chosen-container-active .chosen-single {
309
- border: 1px solid #5897fb;
310
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
311
- }
312
- .chosen-container-active.chosen-with-drop .chosen-single {
313
- border: 1px solid #aaa;
314
- -moz-border-radius-bottomright: 0;
315
- border-bottom-right-radius: 0;
316
- -moz-border-radius-bottomleft: 0;
317
- border-bottom-left-radius: 0;
318
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
319
- background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
320
- background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
321
- background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
322
- background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
323
- box-shadow: 0 1px 0 #fff inset;
324
- }
325
- .chosen-container-active.chosen-with-drop .chosen-single div {
326
- border-left: none;
327
- background: transparent;
328
- }
329
- .chosen-container-active.chosen-with-drop .chosen-single div b {
330
- background-position: -18px 2px;
331
- }
332
- .chosen-container-active .chosen-choices {
333
- border: 1px solid #5897fb;
334
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
335
- }
336
- .chosen-container-active .chosen-choices li.search-field input[type="text"] {
337
- color: #111 !important;
338
- }
339
-
340
- /* @end */
341
- /* @group Disabled Support */
342
- .chosen-disabled {
343
- opacity: 0.5 !important;
344
- cursor: default;
345
- }
346
- .chosen-disabled .chosen-single {
347
- cursor: default;
348
- }
349
- .chosen-disabled .chosen-choices .search-choice .search-choice-close {
350
- cursor: default;
351
- }
352
-
353
- /* @end */
354
- /* @group Right to Left */
355
- .chosen-rtl {
356
- text-align: right;
357
- }
358
- .chosen-rtl .chosen-single {
359
- overflow: visible;
360
- padding: 0 8px 0 0;
361
- }
362
- .chosen-rtl .chosen-single span {
363
- margin-right: 0;
364
- margin-left: 26px;
365
- direction: rtl;
366
- }
367
- .chosen-rtl .chosen-single-with-deselect span {
368
- margin-left: 38px;
369
- }
370
- .chosen-rtl .chosen-single div {
371
- right: auto;
372
- left: 3px;
373
- }
374
- .chosen-rtl .chosen-single abbr {
375
- right: auto;
376
- left: 26px;
377
- }
378
- .chosen-rtl .chosen-choices li {
379
- float: right;
380
- }
381
- .chosen-rtl .chosen-choices li.search-field input[type="text"] {
382
- direction: rtl;
383
- }
384
- .chosen-rtl .chosen-choices li.search-choice {
385
- margin: 3px 5px 3px 0;
386
- padding: 3px 5px 3px 19px;
387
- }
388
- .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
389
- right: auto;
390
- left: 4px;
391
- }
392
- .chosen-rtl.chosen-container-single-nosearch .chosen-search,
393
- .chosen-rtl .chosen-drop {
394
- left: 9999px;
395
- }
396
- .chosen-rtl.chosen-container-single .chosen-results {
397
- margin: 0 0 4px 4px;
398
- padding: 0 4px 0 0;
399
- }
400
- .chosen-rtl .chosen-results li.group-option {
401
- padding-right: 15px;
402
- padding-left: 0;
403
- }
404
- .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
405
- border-right: none;
406
- }
407
- .chosen-rtl .chosen-search input[type="text"] {
408
- padding: 4px 5px 4px 20px;
409
- background: white url('chosen-sprite.png') no-repeat -30px -20px;
410
- background: url('chosen-sprite.png') no-repeat -30px -20px;
411
- direction: rtl;
412
- }
413
- .chosen-rtl.chosen-container-single .chosen-single div b {
414
- background-position: 6px 2px;
415
- }
416
- .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
417
- background-position: -12px 2px;
418
- }
419
-
420
- /* @end */
421
- /* @group Retina compatibility */
422
- @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
423
- .chosen-rtl .chosen-search input[type="text"],
424
- .chosen-container-single .chosen-single abbr,
425
- .chosen-container-single .chosen-single div b,
426
- .chosen-container-single .chosen-search input[type="text"],
427
- .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
428
- .chosen-container .chosen-results-scroll-down span,
429
- .chosen-container .chosen-results-scroll-up span {
430
- background-image: url('chosen-sprite@2x.png') !important;
431
- background-size: 52px 37px !important;
432
- background-repeat: no-repeat !important;
433
- }
434
- }
435
- /* @end */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/chosen/chosen.jquery.js DELETED
@@ -1,1211 +0,0 @@
1
- /*!
2
- Chosen, a Select Box Enhancer for jQuery and Prototype
3
- by Patrick Filler for Harvest, http://getharvest.com
4
-
5
- Version 1.1.0
6
- Full source at https://github.com/harvesthq/chosen
7
- Copyright (c) 2011 Harvest http://getharvest.com
8
-
9
- MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
- This file is generated by `grunt build`, do not edit it by hand.
11
- */
12
-
13
- (function() {
14
- var $, AbstractChosen, Chosen, SelectParser, _ref,
15
- __hasProp = {}.hasOwnProperty,
16
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
17
-
18
- SelectParser = (function() {
19
- function SelectParser() {
20
- this.options_index = 0;
21
- this.parsed = [];
22
- }
23
-
24
- SelectParser.prototype.add_node = function(child) {
25
- if (child.nodeName.toUpperCase() === "OPTGROUP") {
26
- return this.add_group(child);
27
- } else {
28
- return this.add_option(child);
29
- }
30
- };
31
-
32
- SelectParser.prototype.add_group = function(group) {
33
- var group_position, option, _i, _len, _ref, _results;
34
- group_position = this.parsed.length;
35
- this.parsed.push({
36
- array_index: group_position,
37
- group: true,
38
- label: this.escapeExpression(group.label),
39
- children: 0,
40
- disabled: group.disabled
41
- });
42
- _ref = group.childNodes;
43
- _results = [];
44
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
45
- option = _ref[_i];
46
- _results.push(this.add_option(option, group_position, group.disabled));
47
- }
48
- return _results;
49
- };
50
-
51
- SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
52
- if (option.nodeName.toUpperCase() === "OPTION") {
53
- if (option.text !== "") {
54
- if (group_position != null) {
55
- this.parsed[group_position].children += 1;
56
- }
57
- this.parsed.push({
58
- array_index: this.parsed.length,
59
- options_index: this.options_index,
60
- value: option.value,
61
- text: option.text,
62
- html: option.innerHTML,
63
- selected: option.selected,
64
- disabled: group_disabled === true ? group_disabled : option.disabled,
65
- group_array_index: group_position,
66
- classes: option.className,
67
- style: option.style.cssText
68
- });
69
- } else {
70
- this.parsed.push({
71
- array_index: this.parsed.length,
72
- options_index: this.options_index,
73
- empty: true
74
- });
75
- }
76
- return this.options_index += 1;
77
- }
78
- };
79
-
80
- SelectParser.prototype.escapeExpression = function(text) {
81
- var map, unsafe_chars;
82
- if ((text == null) || text === false) {
83
- return "";
84
- }
85
- if (!/[\&\<\>\"\'\`]/.test(text)) {
86
- return text;
87
- }
88
- map = {
89
- "<": "&lt;",
90
- ">": "&gt;",
91
- '"': "&quot;",
92
- "'": "&#x27;",
93
- "`": "&#x60;"
94
- };
95
- unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
96
- return text.replace(unsafe_chars, function(chr) {
97
- return map[chr] || "&amp;";
98
- });
99
- };
100
-
101
- return SelectParser;
102
-
103
- })();
104
-
105
- SelectParser.select_to_array = function(select) {
106
- var child, parser, _i, _len, _ref;
107
- parser = new SelectParser();
108
- _ref = select.childNodes;
109
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
110
- child = _ref[_i];
111
- parser.add_node(child);
112
- }
113
- return parser.parsed;
114
- };
115
-
116
- AbstractChosen = (function() {
117
- function AbstractChosen(form_field, options) {
118
- this.form_field = form_field;
119
- this.options = options != null ? options : {};
120
- if (!AbstractChosen.browser_is_supported()) {
121
- return;
122
- }
123
- this.is_multiple = this.form_field.multiple;
124
- this.set_default_text();
125
- this.set_default_values();
126
- this.setup();
127
- this.set_up_html();
128
- this.register_observers();
129
- }
130
-
131
- AbstractChosen.prototype.set_default_values = function() {
132
- var _this = this;
133
- this.click_test_action = function(evt) {
134
- return _this.test_active_click(evt);
135
- };
136
- this.activate_action = function(evt) {
137
- return _this.activate_field(evt);
138
- };
139
- this.active_field = false;
140
- this.mouse_on_container = false;
141
- this.results_showing = false;
142
- this.result_highlighted = null;
143
- this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
144
- this.disable_search_threshold = this.options.disable_search_threshold || 0;
145
- this.disable_search = this.options.disable_search || false;
146
- this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
147
- this.group_search = this.options.group_search != null ? this.options.group_search : true;
148
- this.search_contains = this.options.search_contains || false;
149
- this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
150
- this.max_selected_options = this.options.max_selected_options || Infinity;
151
- this.inherit_select_classes = this.options.inherit_select_classes || false;
152
- this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
153
- return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
154
- };
155
-
156
- AbstractChosen.prototype.set_default_text = function() {
157
- if (this.form_field.getAttribute("data-placeholder")) {
158
- this.default_text = this.form_field.getAttribute("data-placeholder");
159
- } else if (this.is_multiple) {
160
- this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
161
- } else {
162
- this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
163
- }
164
- return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
165
- };
166
-
167
- AbstractChosen.prototype.mouse_enter = function() {
168
- return this.mouse_on_container = true;
169
- };
170
-
171
- AbstractChosen.prototype.mouse_leave = function() {
172
- return this.mouse_on_container = false;
173
- };
174
-
175
- AbstractChosen.prototype.input_focus = function(evt) {
176
- var _this = this;
177
- if (this.is_multiple) {
178
- if (!this.active_field) {
179
- return setTimeout((function() {
180
- return _this.container_mousedown();
181
- }), 50);
182
- }
183
- } else {
184
- if (!this.active_field) {
185
- return this.activate_field();
186
- }
187
- }
188
- };
189
-
190
- AbstractChosen.prototype.input_blur = function(evt) {
191
- var _this = this;
192
- if (!this.mouse_on_container) {
193
- this.active_field = false;
194
- return setTimeout((function() {
195
- return _this.blur_test();
196
- }), 100);
197
- }
198
- };
199
-
200
- AbstractChosen.prototype.results_option_build = function(options) {
201
- var content, data, _i, _len, _ref;
202
- content = '';
203
- _ref = this.results_data;
204
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
205
- data = _ref[_i];
206
- if (data.group) {
207
- content += this.result_add_group(data);
208
- } else {
209
- content += this.result_add_option(data);
210
- }
211
- if (options != null ? options.first : void 0) {
212
- if (data.selected && this.is_multiple) {
213
- this.choice_build(data);
214
- } else if (data.selected && !this.is_multiple) {
215
- this.single_set_selected_text(data.text);
216
- }
217
- }
218
- }
219
- return content;
220
- };
221
-
222
- AbstractChosen.prototype.result_add_option = function(option) {
223
- var classes, option_el;
224
- if (!option.search_match) {
225
- return '';
226
- }
227
- if (!this.include_option_in_results(option)) {
228
- return '';
229
- }
230
- classes = [];
231
- if (!option.disabled && !(option.selected && this.is_multiple)) {
232
- classes.push("active-result");
233
- }
234
- if (option.disabled && !(option.selected && this.is_multiple)) {
235
- classes.push("disabled-result");
236
- }
237
- if (option.selected) {
238
- classes.push("result-selected");
239
- }
240
- if (option.group_array_index != null) {
241
- classes.push("group-option");
242
- }
243
- if (option.classes !== "") {
244
- classes.push(option.classes);
245
- }
246
- option_el = document.createElement("li");
247
- option_el.className = classes.join(" ");
248
- option_el.style.cssText = option.style;
249
- option_el.setAttribute("data-option-array-index", option.array_index);
250
- option_el.innerHTML = option.search_text;
251
- return this.outerHTML(option_el);
252
- };
253
-
254
- AbstractChosen.prototype.result_add_group = function(group) {
255
- var group_el;
256
- if (!(group.search_match || group.group_match)) {
257
- return '';
258
- }
259
- if (!(group.active_options > 0)) {
260
- return '';
261
- }
262
- group_el = document.createElement("li");
263
- group_el.className = "group-result";
264
- group_el.innerHTML = group.search_text;
265
- return this.outerHTML(group_el);
266
- };
267
-
268
- AbstractChosen.prototype.results_update_field = function() {
269
- this.set_default_text();
270
- if (!this.is_multiple) {
271
- this.results_reset_cleanup();
272
- }
273
- this.result_clear_highlight();
274
- this.results_build();
275
- if (this.results_showing) {
276
- return this.winnow_results();
277
- }
278
- };
279
-
280
- AbstractChosen.prototype.reset_single_select_options = function() {
281
- var result, _i, _len, _ref, _results;
282
- _ref = this.results_data;
283
- _results = [];
284
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
285
- result = _ref[_i];
286
- if (result.selected) {
287
- _results.push(result.selected = false);
288
- } else {
289
- _results.push(void 0);
290
- }
291
- }
292
- return _results;
293
- };
294
-
295
- AbstractChosen.prototype.results_toggle = function() {
296
- if (this.results_showing) {
297
- return this.results_hide();
298
- } else {
299
- return this.results_show();
300
- }
301
- };
302
-
303
- AbstractChosen.prototype.results_search = function(evt) {
304
- if (this.results_showing) {
305
- return this.winnow_results();
306
- } else {
307
- return this.results_show();
308
- }
309
- };
310
-
311
- AbstractChosen.prototype.winnow_results = function() {
312
- var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
313
- this.no_results_clear();
314
- results = 0;
315
- searchText = this.get_search_text();
316
- escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
317
- regexAnchor = this.search_contains ? "" : "^";
318
- regex = new RegExp(regexAnchor + escapedSearchText, 'i');
319
- zregex = new RegExp(escapedSearchText, 'i');
320
- _ref = this.results_data;
321
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
322
- option = _ref[_i];
323
- option.search_match = false;
324
- results_group = null;
325
- if (this.include_option_in_results(option)) {
326
- if (option.group) {
327
- option.group_match = false;
328
- option.active_options = 0;
329
- }
330
- if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
331
- results_group = this.results_data[option.group_array_index];
332
- if (results_group.active_options === 0 && results_group.search_match) {
333
- results += 1;
334
- }
335
- results_group.active_options += 1;
336
- }
337
- if (!(option.group && !this.group_search)) {
338
- option.search_text = option.group ? option.label : option.html;
339
- option.search_match = this.search_string_match(option.search_text, regex);
340
- if (option.search_match && !option.group) {
341
- results += 1;
342
- }
343
- if (option.search_match) {
344
- if (searchText.length) {
345
- startpos = option.search_text.search(zregex);
346
- text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
347
- option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
348
- }
349
- if (results_group != null) {
350
- results_group.group_match = true;
351
- }
352
- } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
353
- option.search_match = true;
354
- }
355
- }
356
- }
357
- }
358
- this.result_clear_highlight();
359
- if (results < 1 && searchText.length) {
360
- this.update_results_content("");
361
- return this.no_results(searchText);
362
- } else {
363
- this.update_results_content(this.results_option_build());
364
- return this.winnow_results_set_highlight();
365
- }
366
- };
367
-
368
- AbstractChosen.prototype.search_string_match = function(search_string, regex) {
369
- var part, parts, _i, _len;
370
- if (regex.test(search_string)) {
371
- return true;
372
- } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
373
- parts = search_string.replace(/\[|\]/g, "").split(" ");
374
- if (parts.length) {
375
- for (_i = 0, _len = parts.length; _i < _len; _i++) {
376
- part = parts[_i];
377
- if (regex.test(part)) {
378
- return true;
379
- }
380
- }
381
- }
382
- }
383
- };
384
-
385
- AbstractChosen.prototype.choices_count = function() {
386
- var option, _i, _len, _ref;
387
- if (this.selected_option_count != null) {
388
- return this.selected_option_count;
389
- }
390
- this.selected_option_count = 0;
391
- _ref = this.form_field.options;
392
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
393
- option = _ref[_i];
394
- if (option.selected) {
395
- this.selected_option_count += 1;
396
- }
397
- }
398
- return this.selected_option_count;
399
- };
400
-
401
- AbstractChosen.prototype.choices_click = function(evt) {
402
- evt.preventDefault();
403
- if (!(this.results_showing || this.is_disabled)) {
404
- return this.results_show();
405
- }
406
- };
407
-
408
- AbstractChosen.prototype.keyup_checker = function(evt) {
409
- var stroke, _ref;
410
- stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
411
- this.search_field_scale();
412
- switch (stroke) {
413
- case 8:
414
- if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
415
- return this.keydown_backstroke();
416
- } else if (!this.pending_backstroke) {
417
- this.result_clear_highlight();
418
- return this.results_search();
419
- }
420
- break;
421
- case 13:
422
- evt.preventDefault();
423
- if (this.results_showing) {
424
- return this.result_select(evt);
425
- }
426
- break;
427
- case 27:
428
- if (this.results_showing) {
429
- this.results_hide();
430
- }
431
- return true;
432
- case 9:
433
- case 38:
434
- case 40:
435
- case 16:
436
- case 91:
437
- case 17:
438
- break;
439
- default:
440
- return this.results_search();
441
- }
442
- };
443
-
444
- AbstractChosen.prototype.clipboard_event_checker = function(evt) {
445
- var _this = this;
446
- return setTimeout((function() {
447
- return _this.results_search();
448
- }), 50);
449
- };
450
-
451
- AbstractChosen.prototype.container_width = function() {
452
- if (this.options.width != null) {
453
- return this.options.width;
454
- } else {
455
- return "" + this.form_field.offsetWidth + "px";
456
- }
457
- };
458
-
459
- AbstractChosen.prototype.include_option_in_results = function(option) {
460
- if (this.is_multiple && (!this.display_selected_options && option.selected)) {
461
- return false;
462
- }
463
- if (!this.display_disabled_options && option.disabled) {
464
- return false;
465
- }
466
- if (option.empty) {
467
- return false;
468
- }
469
- return true;
470
- };
471
-
472
- AbstractChosen.prototype.search_results_touchstart = function(evt) {
473
- this.touch_started = true;
474
- return this.search_results_mouseover(evt);
475
- };
476
-
477
- AbstractChosen.prototype.search_results_touchmove = function(evt) {
478
- this.touch_started = false;
479
- return this.search_results_mouseout(evt);
480
- };
481
-
482
- AbstractChosen.prototype.search_results_touchend = function(evt) {
483
- if (this.touch_started) {
484
- return this.search_results_mouseup(evt);
485
- }
486
- };
487
-
488
- AbstractChosen.prototype.outerHTML = function(element) {
489
- var tmp;
490
- if (element.outerHTML) {
491
- return element.outerHTML;
492
- }
493
- tmp = document.createElement("div");
494
- tmp.appendChild(element);
495
- return tmp.innerHTML;
496
- };
497
-
498
- AbstractChosen.browser_is_supported = function() {
499
- if (window.navigator.appName === "Microsoft Internet Explorer") {
500
- return document.documentMode >= 8;
501
- }
502
- if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
503
- return false;
504
- }
505
- if (/Android/i.test(window.navigator.userAgent)) {
506
- if (/Mobile/i.test(window.navigator.userAgent)) {
507
- return false;
508
- }
509
- }
510
- return true;
511
- };
512
-
513
- AbstractChosen.default_multiple_text = "Select Some Options";
514
-
515
- AbstractChosen.default_single_text = "Select an Option";
516
-
517
- AbstractChosen.default_no_result_text = "No results match";
518
-
519
- return AbstractChosen;
520
-
521
- })();
522
-
523
- $ = jQuery;
524
-
525
- $.fn.extend({
526
- chosen: function(options) {
527
- if (!AbstractChosen.browser_is_supported()) {
528
- return this;
529
- }
530
- return this.each(function(input_field) {
531
- var $this, chosen;
532
- $this = $(this);
533
- chosen = $this.data('chosen');
534
- if (options === 'destroy' && chosen) {
535
- chosen.destroy();
536
- } else if (!chosen) {
537
- $this.data('chosen', new Chosen(this, options));
538
- }
539
- });
540
- }
541
- });
542
-
543
- Chosen = (function(_super) {
544
- __extends(Chosen, _super);
545
-
546
- function Chosen() {
547
- _ref = Chosen.__super__.constructor.apply(this, arguments);
548
- return _ref;
549
- }
550
-
551
- Chosen.prototype.setup = function() {
552
- this.form_field_jq = $(this.form_field);
553
- this.current_selectedIndex = this.form_field.selectedIndex;
554
- return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
555
- };
556
-
557
- Chosen.prototype.set_up_html = function() {
558
- var container_classes, container_props;
559
- container_classes = ["chosen-container"];
560
- container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
561
- if (this.inherit_select_classes && this.form_field.className) {
562
- container_classes.push(this.form_field.className);
563
- }
564
- if (this.is_rtl) {
565
- container_classes.push("chosen-rtl");
566
- }
567
- container_props = {
568
- 'class': container_classes.join(' '),
569
- 'style': "width: " + (this.container_width()) + ";",
570
- 'title': this.form_field.title
571
- };
572
- if (this.form_field.id.length) {
573
- container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
574
- }
575
- this.container = $("<div />", container_props);
576
- if (this.is_multiple) {
577
- this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
578
- } else {
579
- this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
580
- }
581
- this.form_field_jq.hide().after(this.container);
582
- this.dropdown = this.container.find('div.chosen-drop').first();
583
- this.search_field = this.container.find('input').first();
584
- this.search_results = this.container.find('ul.chosen-results').first();
585
- this.search_field_scale();
586
- this.search_no_results = this.container.find('li.no-results').first();
587
- if (this.is_multiple) {
588
- this.search_choices = this.container.find('ul.chosen-choices').first();
589
- this.search_container = this.container.find('li.search-field').first();
590
- } else {
591
- this.search_container = this.container.find('div.chosen-search').first();
592
- this.selected_item = this.container.find('.chosen-single').first();
593
- }
594
- this.results_build();
595
- this.set_tab_index();
596
- this.set_label_behavior();
597
- return this.form_field_jq.trigger("chosen:ready", {
598
- chosen: this
599
- });
600
- };
601
-
602
- Chosen.prototype.register_observers = function() {
603
- var _this = this;
604
- this.container.bind('mousedown.chosen', function(evt) {
605
- _this.container_mousedown(evt);
606
- });
607
- this.container.bind('mouseup.chosen', function(evt) {
608
- _this.container_mouseup(evt);
609
- });
610
- this.container.bind('mouseenter.chosen', function(evt) {
611
- _this.mouse_enter(evt);
612
- });
613
- this.container.bind('mouseleave.chosen', function(evt) {
614
- _this.mouse_leave(evt);
615
- });
616
- this.search_results.bind('mouseup.chosen', function(evt) {
617
- _this.search_results_mouseup(evt);
618
- });
619
- this.search_results.bind('mouseover.chosen', function(evt) {
620
- _this.search_results_mouseover(evt);
621
- });
622
- this.search_results.bind('mouseout.chosen', function(evt) {
623
- _this.search_results_mouseout(evt);
624
- });
625
- this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
626
- _this.search_results_mousewheel(evt);
627
- });
628
- this.search_results.bind('touchstart.chosen', function(evt) {
629
- _this.search_results_touchstart(evt);
630
- });
631
- this.search_results.bind('touchmove.chosen', function(evt) {
632
- _this.search_results_touchmove(evt);
633
- });
634
- this.search_results.bind('touchend.chosen', function(evt) {
635
- _this.search_results_touchend(evt);
636
- });
637
- this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
638
- _this.results_update_field(evt);
639
- });
640
- this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
641
- _this.activate_field(evt);
642
- });
643
- this.form_field_jq.bind("chosen:open.chosen", function(evt) {
644
- _this.container_mousedown(evt);
645
- });
646
- this.form_field_jq.bind("chosen:close.chosen", function(evt) {
647
- _this.input_blur(evt);
648
- });
649
- this.search_field.bind('blur.chosen', function(evt) {
650
- _this.input_blur(evt);
651
- });
652
- this.search_field.bind('keyup.chosen', function(evt) {
653
- _this.keyup_checker(evt);
654
- });
655
- this.search_field.bind('keydown.chosen', function(evt) {
656
- _this.keydown_checker(evt);
657
- });
658
- this.search_field.bind('focus.chosen', function(evt) {
659
- _this.input_focus(evt);
660
- });
661
- this.search_field.bind('cut.chosen', function(evt) {
662
- _this.clipboard_event_checker(evt);
663
- });
664
- this.search_field.bind('paste.chosen', function(evt) {
665
- _this.clipboard_event_checker(evt);
666
- });
667
- if (this.is_multiple) {
668
- return this.search_choices.bind('click.chosen', function(evt) {
669
- _this.choices_click(evt);
670
- });
671
- } else {
672
- return this.container.bind('click.chosen', function(evt) {
673
- evt.preventDefault();
674
- });
675
- }
676
- };
677
-
678
- Chosen.prototype.destroy = function() {
679
- $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
680
- if (this.search_field[0].tabIndex) {
681
- this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
682
- }
683
- this.container.remove();
684
- this.form_field_jq.removeData('chosen');
685
- return this.form_field_jq.show();
686
- };
687
-
688
- Chosen.prototype.search_field_disabled = function() {
689
- this.is_disabled = this.form_field_jq[0].disabled;
690
- if (this.is_disabled) {
691
- this.container.addClass('chosen-disabled');
692
- this.search_field[0].disabled = true;
693
- if (!this.is_multiple) {
694
- this.selected_item.unbind("focus.chosen", this.activate_action);
695
- }
696
- return this.close_field();
697
- } else {
698
- this.container.removeClass('chosen-disabled');
699
- this.search_field[0].disabled = false;
700
- if (!this.is_multiple) {
701
- return this.selected_item.bind("focus.chosen", this.activate_action);
702
- }
703
- }
704
- };
705
-
706
- Chosen.prototype.container_mousedown = function(evt) {
707
- if (!this.is_disabled) {
708
- if (evt && evt.type === "mousedown" && !this.results_showing) {
709
- evt.preventDefault();
710
- }
711
- if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
712
- if (!this.active_field) {
713
- if (this.is_multiple) {
714
- this.search_field.val("");
715
- }
716
- $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
717
- this.results_show();
718
- } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
719
- evt.preventDefault();
720
- this.results_toggle();
721
- }
722
- return this.activate_field();
723
- }
724
- }
725
- };
726
-
727
- Chosen.prototype.container_mouseup = function(evt) {
728
- if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
729
- return this.results_reset(evt);
730
- }
731
- };
732
-
733
- Chosen.prototype.search_results_mousewheel = function(evt) {
734
- var delta;
735
- if (evt.originalEvent) {
736
- delta = -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
737
- }
738
- if (delta != null) {
739
- evt.preventDefault();
740
- if (evt.type === 'DOMMouseScroll') {
741
- delta = delta * 40;
742
- }
743
- return this.search_results.scrollTop(delta + this.search_results.scrollTop());
744
- }
745
- };
746
-
747
- Chosen.prototype.blur_test = function(evt) {
748
- if (!this.active_field && this.container.hasClass("chosen-container-active")) {
749
- return this.close_field();
750
- }
751
- };
752
-
753
- Chosen.prototype.close_field = function() {
754
- $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
755
- this.active_field = false;
756
- this.results_hide();
757
- this.container.removeClass("chosen-container-active");
758
- this.clear_backstroke();
759
- this.show_search_field_default();
760
- return this.search_field_scale();
761
- };
762
-
763
- Chosen.prototype.activate_field = function() {
764
- this.container.addClass("chosen-container-active");
765
- this.active_field = true;
766
- this.search_field.val(this.search_field.val());
767
- return this.search_field.focus();
768
- };
769
-
770
- Chosen.prototype.test_active_click = function(evt) {
771
- var active_container;
772
- active_container = $(evt.target).closest('.chosen-container');
773
- if (active_container.length && this.container[0] === active_container[0]) {
774
- return this.active_field = true;
775
- } else {
776
- return this.close_field();
777
- }
778
- };
779
-
780
- Chosen.prototype.results_build = function() {
781
- this.parsing = true;
782
- this.selected_option_count = null;
783
- this.results_data = SelectParser.select_to_array(this.form_field);
784
- if (this.is_multiple) {
785
- this.search_choices.find("li.search-choice").remove();
786
- } else if (!this.is_multiple) {
787
- this.single_set_selected_text();
788
- if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
789
- this.search_field[0].readOnly = true;
790
- this.container.addClass("chosen-container-single-nosearch");
791
- } else {
792
- this.search_field[0].readOnly = false;
793
- this.container.removeClass("chosen-container-single-nosearch");
794
- }
795
- }
796
- this.update_results_content(this.results_option_build({
797
- first: true
798
- }));
799
- this.search_field_disabled();
800
- this.show_search_field_default();
801
- this.search_field_scale();
802
- return this.parsing = false;
803
- };
804
-
805
- Chosen.prototype.result_do_highlight = function(el) {
806
- var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
807
- if (el.length) {
808
- this.result_clear_highlight();
809
- this.result_highlight = el;
810
- this.result_highlight.addClass("highlighted");
811
- maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
812
- visible_top = this.search_results.scrollTop();
813
- visible_bottom = maxHeight + visible_top;
814
- high_top = this.result_highlight.position().top + this.search_results.scrollTop();
815
- high_bottom = high_top + this.result_highlight.outerHeight();
816
- if (high_bottom >= visible_bottom) {
817
- return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
818
- } else if (high_top < visible_top) {
819
- return this.search_results.scrollTop(high_top);
820
- }
821
- }
822
- };
823
-
824
- Chosen.prototype.result_clear_highlight = function() {
825
- if (this.result_highlight) {
826
- this.result_highlight.removeClass("highlighted");
827
- }
828
- return this.result_highlight = null;
829
- };
830
-
831
- Chosen.prototype.results_show = function() {
832
- if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
833
- this.form_field_jq.trigger("chosen:maxselected", {
834
- chosen: this
835
- });
836
- return false;
837
- }
838
- this.container.addClass("chosen-with-drop");
839
- this.results_showing = true;
840
- this.search_field.focus();
841
- this.search_field.val(this.search_field.val());
842
- this.winnow_results();
843
- return this.form_field_jq.trigger("chosen:showing_dropdown", {
844
- chosen: this
845
- });
846
- };
847
-
848
- Chosen.prototype.update_results_content = function(content) {
849
- return this.search_results.html(content);
850
- };
851
-
852
- Chosen.prototype.results_hide = function() {
853
- if (this.results_showing) {
854
- this.result_clear_highlight();
855
- this.container.removeClass("chosen-with-drop");
856
- this.form_field_jq.trigger("chosen:hiding_dropdown", {
857
- chosen: this
858
- });
859
- }
860
- return this.results_showing = false;
861
- };
862
-
863
- Chosen.prototype.set_tab_index = function(el) {
864
- var ti;
865
- if (this.form_field.tabIndex) {
866
- ti = this.form_field.tabIndex;
867
- this.form_field.tabIndex = -1;
868
- return this.search_field[0].tabIndex = ti;
869
- }
870
- };
871
-
872
- Chosen.prototype.set_label_behavior = function() {
873
- var _this = this;
874
- this.form_field_label = this.form_field_jq.parents("label");
875
- if (!this.form_field_label.length && this.form_field.id.length) {
876
- this.form_field_label = $("label[for='" + this.form_field.id + "']");
877
- }
878
- if (this.form_field_label.length > 0) {
879
- return this.form_field_label.bind('click.chosen', function(evt) {
880
- if (_this.is_multiple) {
881
- return _this.container_mousedown(evt);
882
- } else {
883
- return _this.activate_field();
884
- }
885
- });
886
- }
887
- };
888
-
889
- Chosen.prototype.show_search_field_default = function() {
890
- if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
891
- this.search_field.val(this.default_text);
892
- return this.search_field.addClass("default");
893
- } else {
894
- this.search_field.val("");
895
- return this.search_field.removeClass("default");
896
- }
897
- };
898
-
899
- Chosen.prototype.search_results_mouseup = function(evt) {
900
- var target;
901
- target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
902
- if (target.length) {
903
- this.result_highlight = target;
904
- this.result_select(evt);
905
- return this.search_field.focus();
906
- }
907
- };
908
-
909
- Chosen.prototype.search_results_mouseover = function(evt) {
910
- var target;
911
- target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
912
- if (target) {
913
- return this.result_do_highlight(target);
914
- }
915
- };
916
-
917
- Chosen.prototype.search_results_mouseout = function(evt) {
918
- if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
919
- return this.result_clear_highlight();
920
- }
921
- };
922
-
923
- Chosen.prototype.choice_build = function(item) {
924
- var choice, close_link,
925
- _this = this;
926
- choice = $('<li />', {
927
- "class": "search-choice"
928
- }).html("<span>" + item.html + "</span>");
929
- if (item.disabled) {
930
- choice.addClass('search-choice-disabled');
931
- } else {
932
- close_link = $('<a />', {
933
- "class": 'search-choice-close',
934
- 'data-option-array-index': item.array_index
935
- });
936
- close_link.bind('click.chosen', function(evt) {
937
- return _this.choice_destroy_link_click(evt);
938
- });
939
- choice.append(close_link);
940
- }
941
- return this.search_container.before(choice);
942
- };
943
-
944
- Chosen.prototype.choice_destroy_link_click = function(evt) {
945
- evt.preventDefault();
946
- evt.stopPropagation();
947
- if (!this.is_disabled) {
948
- return this.choice_destroy($(evt.target));
949
- }
950
- };
951
-
952
- Chosen.prototype.choice_destroy = function(link) {
953
- if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
954
- this.show_search_field_default();
955
- if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
956
- this.results_hide();
957
- }
958
- link.parents('li').first().remove();
959
- return this.search_field_scale();
960
- }
961
- };
962
-
963
- Chosen.prototype.results_reset = function() {
964
- this.reset_single_select_options();
965
- this.form_field.options[0].selected = true;
966
- this.single_set_selected_text();
967
- this.show_search_field_default();
968
- this.results_reset_cleanup();
969
- this.form_field_jq.trigger("change");
970
- if (this.active_field) {
971
- return this.results_hide();
972
- }
973
- };
974
-
975
- Chosen.prototype.results_reset_cleanup = function() {
976
- this.current_selectedIndex = this.form_field.selectedIndex;
977
- return this.selected_item.find("abbr").remove();
978
- };
979
-
980
- Chosen.prototype.result_select = function(evt) {
981
- var high, item;
982
- if (this.result_highlight) {
983
- high = this.result_highlight;
984
- this.result_clear_highlight();
985
- if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
986
- this.form_field_jq.trigger("chosen:maxselected", {
987
- chosen: this
988
- });
989
- return false;
990
- }
991
- if (this.is_multiple) {
992
- high.removeClass("active-result");
993
- } else {
994
- this.reset_single_select_options();
995
- }
996
- item = this.results_data[high[0].getAttribute("data-option-array-index")];
997
- item.selected = true;
998
- this.form_field.options[item.options_index].selected = true;
999
- this.selected_option_count = null;
1000
- if (this.is_multiple) {
1001
- this.choice_build(item);
1002
- } else {
1003
- this.single_set_selected_text(item.text);
1004
- }
1005
- if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
1006
- this.results_hide();
1007
- }
1008
- this.search_field.val("");
1009
- if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1010
- this.form_field_jq.trigger("change", {
1011
- 'selected': this.form_field.options[item.options_index].value
1012
- });
1013
- }
1014
- this.current_selectedIndex = this.form_field.selectedIndex;
1015
- return this.search_field_scale();
1016
- }
1017
- };
1018
-
1019
- Chosen.prototype.single_set_selected_text = function(text) {
1020
- if (text == null) {
1021
- text = this.default_text;
1022
- }
1023
- if (text === this.default_text) {
1024
- this.selected_item.addClass("chosen-default");
1025
- } else {
1026
- this.single_deselect_control_build();
1027
- this.selected_item.removeClass("chosen-default");
1028
- }
1029
- return this.selected_item.find("span").text(text);
1030
- };
1031
-
1032
- Chosen.prototype.result_deselect = function(pos) {
1033
- var result_data;
1034
- result_data = this.results_data[pos];
1035
- if (!this.form_field.options[result_data.options_index].disabled) {
1036
- result_data.selected = false;
1037
- this.form_field.options[result_data.options_index].selected = false;
1038
- this.selected_option_count = null;
1039
- this.result_clear_highlight();
1040
- if (this.results_showing) {
1041
- this.winnow_results();
1042
- }
1043
- this.form_field_jq.trigger("change", {
1044
- deselected: this.form_field.options[result_data.options_index].value
1045
- });
1046
- this.search_field_scale();
1047
- return true;
1048
- } else {
1049
- return false;
1050
- }
1051
- };
1052
-
1053
- Chosen.prototype.single_deselect_control_build = function() {
1054
- if (!this.allow_single_deselect) {
1055
- return;
1056
- }
1057
- if (!this.selected_item.find("abbr").length) {
1058
- this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1059
- }
1060
- return this.selected_item.addClass("chosen-single-with-deselect");
1061
- };
1062
-
1063
- Chosen.prototype.get_search_text = function() {
1064
- if (this.search_field.val() === this.default_text) {
1065
- return "";
1066
- } else {
1067
- return $('<div/>').text($.trim(this.search_field.val())).html();
1068
- }
1069
- };
1070
-
1071
- Chosen.prototype.winnow_results_set_highlight = function() {
1072
- var do_high, selected_results;
1073
- selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1074
- do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1075
- if (do_high != null) {
1076
- return this.result_do_highlight(do_high);
1077
- }
1078
- };
1079
-
1080
- Chosen.prototype.no_results = function(terms) {
1081
- var no_results_html;
1082
- no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
1083
- no_results_html.find("span").first().html(terms);
1084
- this.search_results.append(no_results_html);
1085
- return this.form_field_jq.trigger("chosen:no_results", {
1086
- chosen: this
1087
- });
1088
- };
1089
-
1090
- Chosen.prototype.no_results_clear = function() {
1091
- return this.search_results.find(".no-results").remove();
1092
- };
1093
-
1094
- Chosen.prototype.keydown_arrow = function() {
1095
- var next_sib;
1096
- if (this.results_showing && this.result_highlight) {
1097
- next_sib = this.result_highlight.nextAll("li.active-result").first();
1098
- if (next_sib) {
1099
- return this.result_do_highlight(next_sib);
1100
- }
1101
- } else {
1102
- return this.results_show();
1103
- }
1104
- };
1105
-
1106
- Chosen.prototype.keyup_arrow = function() {
1107
- var prev_sibs;
1108
- if (!this.results_showing && !this.is_multiple) {
1109
- return this.results_show();
1110
- } else if (this.result_highlight) {
1111
- prev_sibs = this.result_highlight.prevAll("li.active-result");
1112
- if (prev_sibs.length) {
1113
- return this.result_do_highlight(prev_sibs.first());
1114
- } else {
1115
- if (this.choices_count() > 0) {
1116
- this.results_hide();
1117
- }
1118
- return this.result_clear_highlight();
1119
- }
1120
- }
1121
- };
1122
-
1123
- Chosen.prototype.keydown_backstroke = function() {
1124
- var next_available_destroy;
1125
- if (this.pending_backstroke) {
1126
- this.choice_destroy(this.pending_backstroke.find("a").first());
1127
- return this.clear_backstroke();
1128
- } else {
1129
- next_available_destroy = this.search_container.siblings("li.search-choice").last();
1130
- if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1131
- this.pending_backstroke = next_available_destroy;
1132
- if (this.single_backstroke_delete) {
1133
- return this.keydown_backstroke();
1134
- } else {
1135
- return this.pending_backstroke.addClass("search-choice-focus");
1136
- }
1137
- }
1138
- }
1139
- };
1140
-
1141
- Chosen.prototype.clear_backstroke = function() {
1142
- if (this.pending_backstroke) {
1143
- this.pending_backstroke.removeClass("search-choice-focus");
1144
- }
1145
- return this.pending_backstroke = null;
1146
- };
1147
-
1148
- Chosen.prototype.keydown_checker = function(evt) {
1149
- var stroke, _ref1;
1150
- stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1151
- this.search_field_scale();
1152
- if (stroke !== 8 && this.pending_backstroke) {
1153
- this.clear_backstroke();
1154
- }
1155
- switch (stroke) {
1156
- case 8:
1157
- this.backstroke_length = this.search_field.val().length;
1158
- break;
1159
- case 9:
1160
- if (this.results_showing && !this.is_multiple) {
1161
- this.result_select(evt);
1162
- }
1163
- this.mouse_on_container = false;
1164
- break;
1165
- case 13:
1166
- evt.preventDefault();
1167
- break;
1168
- case 38:
1169
- evt.preventDefault();
1170
- this.keyup_arrow();
1171
- break;
1172
- case 40:
1173
- evt.preventDefault();
1174
- this.keydown_arrow();
1175
- break;
1176
- }
1177
- };
1178
-
1179
- Chosen.prototype.search_field_scale = function() {
1180
- var div, f_width, h, style, style_block, styles, w, _i, _len;
1181
- if (this.is_multiple) {
1182
- h = 0;
1183
- w = 0;
1184
- style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1185
- styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1186
- for (_i = 0, _len = styles.length; _i < _len; _i++) {
1187
- style = styles[_i];
1188
- style_block += style + ":" + this.search_field.css(style) + ";";
1189
- }
1190
- div = $('<div />', {
1191
- 'style': style_block
1192
- });
1193
- div.text(this.search_field.val());
1194
- $('body').append(div);
1195
- w = div.width() + 25;
1196
- div.remove();
1197
- f_width = this.container.outerWidth();
1198
- if (w > f_width - 10) {
1199
- w = f_width - 10;
1200
- }
1201
- return this.search_field.css({
1202
- 'width': w + 'px'
1203
- });
1204
- }
1205
- };
1206
-
1207
- return Chosen;
1208
-
1209
- })(AbstractChosen);
1210
-
1211
- }).call(this);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/chosen/chosen.jquery.min.js DELETED
@@ -1,2 +0,0 @@
1
- /* Chosen v1.1.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
2
- !function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&amp;"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b;return a.search_match||a.group_match?a.active_options>0?(b=document.createElement("li"),b.className="group-result",b.innerHTML=a.search_text,this.outerHTML(b)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(this.no_results_clear(),e=0,g=this.get_search_text(),a=g.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),d=this.search_contains?"":"^",c=new RegExp(d+a,"i"),j=new RegExp(a,"i"),m=this.results_data,k=0,l=m.length;l>k;k++)b=m[k],b.search_match=!1,f=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(f=this.results_data[b.group_array_index],0===f.active_options&&f.search_match&&(e+=1),f.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(e+=1),b.search_match?(g.length&&(h=b.search_text.search(j),i=b.search_text.substr(0,h+g.length)+"</em>"+b.search_text.substr(h+g.length),b.search_text=i.substr(0,h)+"<em>"+i.substr(h)),null!=f&&(f.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>e&&g.length?(this.update_results_content(""),this.no_results(g)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d?d.destroy():d||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+b.html+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this);
 
 
vendor/chosen/chosen.min.css DELETED
@@ -1,35 +0,0 @@
1
- .chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}
2
- .chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,0.15)}
3
- .chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:23px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px white inset,0 1px 1px rgba(0,0,0,0.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}
4
- .chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}
5
- .chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url('chosen-sprite.png') -42px 1px no-repeat;font-size:1px}
6
- .chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}
7
- .chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url('chosen-sprite.png') no-repeat 0 2px}
8
- .chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type="text"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:white url('chosen-sprite.png') no-repeat 100% -20px;background:url('chosen-sprite.png') no-repeat 100% -20px;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}
9
- .chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}
10
- .chosen-container .chosen-results{position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}
11
- .chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}
12
- .chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}
13
- .chosen-container .chosen-results li.no-results{display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:bold;cursor:default}
14
- .chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}
15
- .chosen-container-multi .chosen-choices{position:relative;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}
16
- .chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}
17
- .chosen-container-multi .chosen-choices li.search-field input[type="text"]{margin:1px 0;padding:5px;height:15px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#666;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}
18
- .chosen-container-multi .chosen-choices li.search-field .default{color:#999}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 0 3px 5px;padding:3px 20px 3px 5px;border:1px solid #aaa;border-radius:3px;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-clip:padding-box;box-shadow:0 0 2px white inset,0 1px 0 rgba(0,0,0,0.05);color:#333;line-height:13px;cursor:default}
19
- .chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url('chosen-sprite.png') -42px 1px no-repeat;font-size:1px}
20
- .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}
21
- .chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}
22
- .chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}
23
- .chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,0.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}
24
- .chosen-container-active.chosen-with-drop .chosen-single div{border-left:none;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}
25
- .chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,0.3)}.chosen-container-active .chosen-choices li.search-field input[type="text"]{color:#111!important}
26
- .chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}
27
- .chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}
28
- .chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}
29
- .chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type="text"]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}
30
- .chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}
31
- .chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}
32
- .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type="text"]{padding:4px 5px 4px 20px;background:white url('chosen-sprite.png') no-repeat -30px -20px;background:url('chosen-sprite.png') no-repeat -30px -20px;direction:rtl}
33
- .chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}
34
- @media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-rtl .chosen-search input[type="text"],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type="text"],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url('chosen-sprite@2x.png')!important;background-size:52px 37px!important;background-repeat:no-repeat!important}
35
- }