PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 2.9.0
Admin and Site Enhancements (ASE) v2.9.0
9.1.1 9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 8.3.2 8.4.0 8.4.1 8.4.2 8.5.0 8.5.1 8.5.2 8.6.0 8.6.1 8.6.2 8.7.0 5.0.1 5.0.2 5.0.2.1 5.0.2.2 5.0.2.3 5.0.2.4 5.1.0 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.8.0 5.8.1 6.0.0 6.0.3 6.0.4 6.0.5 6.0.5.1 6.0.6 6.0.7 6.0.8.1 6.1.0 6.1.3 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.3.0 6.3.1 6.3.2 6.4.0 6.5.0 6.5.1 6.6.0 6.7.0 6.8.0 6.8.2 6.8.3 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13.1 6.9.13.2 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.2 7.0.2.1 7.0.2.2 7.0.2.3 7.0.3 7.1.0 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2.0 7.2.1 7.3.0 7.3.1 7.3.2 7.3.3 7.4.0 7.4.2 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.6.0 7.6.1 7.6.1.1 7.6.10 7.6.11 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.7.1 7.6.8 7.6.9 7.7.0 7.8.0 7.8.1 7.8.10 7.8.11 7.8.12 7.8.13 7.8.14 7.8.15 7.8.16 7.8.17 7.8.18 7.8.2 7.8.3 7.8.4 7.8.5 7.8.5.1 7.8.6 7.8.7 7.8.8 7.8.9 7.9.0 7.9.1 7.9.10 7.9.11 7.9.2 7.9.3 7.9.4 7.9.5 7.9.6 7.9.7 7.9.8 7.9.9 8.0.0 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.1.0 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.1 3.7.0 3.8.0 3.9.0 3.9.1 3.9.2 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.9.0 4.9.1 4.9.2 4.9.3 5.0.0
admin-site-enhancements / bootstrap.php
admin-site-enhancements Last commit date
assets 3 years ago classes 3 years ago vendor 3 years ago LICENSE.md 3 years ago README.md 3 years ago admin-site-enhancements.php 3 years ago bootstrap.php 3 years ago settings.php 3 years ago
bootstrap.php
319 lines
1 <?php
2
3 // We're using the singleton design pattern
4 // https://code.tutsplus.com/articles/design-patterns-in-wordpress-the-singleton-pattern--wp-31621
5 // https://carlalexander.ca/singletons-in-wordpress/
6 // https://torquemag.io/2016/11/singletons-wordpress-good-evil/
7
8 /**
9 * Main class of the plugin used to add functionalities
10 *
11 * @since 1.0.0
12 */
13 class Admin_Site_Enhancements {
14
15 // Refers to a single instance of this class
16 private static $instance = null;
17
18 /**
19 * Creates or returns a single instance of this class
20 *
21 * @return Admin_Site_Enhancements a single instance of this class
22 * @since 1.0.0
23 */
24 public static function get_instance() {
25
26 if ( null == self::$instance ) {
27
28 self::$instance = new self;
29
30 }
31
32 return self::$instance;
33
34 }
35
36 /**
37 * Initialize plugin functionalities
38 */
39 private function __construct() {
40
41 // Setup admin menu, admin page, settings, settings sections, sections fields, admin scripts, plugin action links, etc.
42
43 // Register admin menu and add the settings page.
44 add_action( 'admin_menu', 'asenha_register_admin_menu' );
45
46 // Register plugin settings
47
48 // Instantiate object for registration of settings section and fields
49 $settings = new ASENHA\Classes\Settings_Sections_Fields;
50
51 add_action( 'admin_init', [ $settings, 'register_sections_fields' ] );
52
53 // Suppress all notices on the plugin's main page. Then add notification for successful settings update.
54 add_action( 'admin_notices', 'asenha_suppress_notices', 5 );
55 add_action( 'all_admin_notices', 'asenha_suppress_generic_notices', 5 );
56
57 // Enqueue admin scripts and styles only on the plugin's main page
58 add_action( 'admin_enqueue_scripts', 'asenha_admin_scripts' );
59
60 // Add action links in plugins page
61 add_filter( 'plugin_action_links_' . ASENHA_SLUG . '/' . ASENHA_SLUG . '.php', 'asenha_plugin_action_links' );
62
63 // Update footer text
64 add_filter( 'admin_footer_text', 'asenha_footer_text' );
65
66 // ===== Activate features based on settings =====
67
68 // Get all WP Enhancements options, default to empty array in case it's not been created yet
69 $options = get_option( ASENHA_SLUG_U, array() );
70
71 // ===== CONTENT MANAGEMENT =====
72
73 // Instantiate object for Content Management features
74 $content_management = new ASENHA\Classes\Content_Management;
75
76 // Content Management >> Enable Page and Post Duplication
77 if ( array_key_exists( 'enable_duplication', $options ) && $options['enable_duplication'] ) {
78 add_action( 'admin_action_asenha_enable_duplication', [ $content_management, 'asenha_enable_duplication' ] );
79 add_filter( 'page_row_actions', [ $content_management, 'add_duplication_action_link' ], 10, 2 );
80 add_filter( 'post_row_actions', [ $content_management, 'add_duplication_action_link' ], 10, 2 );
81 }
82
83 // Content Management >> Enable Media Replacement
84 if ( array_key_exists( 'enable_media_replacement', $options ) && $options['enable_media_replacement'] ) {
85 add_filter( 'media_row_actions', [ $content_management, 'modify_media_list_table_edit_link' ], 10, 2 );
86 add_filter( 'attachment_fields_to_edit', [ $content_management, 'add_media_replacement_button' ] );
87 add_action( 'edit_attachment', [ $content_management, 'replace_media' ] );
88 add_filter( 'post_updated_messages', [ $content_management, 'attachment_updated_custom_message' ] );
89 }
90
91 // Content Management >> Enable SVG Upload
92 if ( array_key_exists( 'enable_svg_upload', $options ) && $options['enable_svg_upload'] && array_key_exists( 'enable_svg_upload_for', $options ) && isset( $options['enable_svg_upload_for'] ) ) {
93
94 global $roles_svg_upload_enabled;
95
96 $enable_svg_upload = $options['enable_svg_upload'];
97 $for_roles = $options['enable_svg_upload_for'];
98
99 // User has role(s). Do further checks.
100 if ( isset( $for_roles ) && ( count( $for_roles ) > 0 ) ) {
101
102 // Assemble single-dimensional array of roles for which SVG upload would be enabled
103 $roles_svg_upload_enabled = array();
104 foreach( $for_roles as $role_slug => $svg_upload_enabled ) {
105 if ( $svg_upload_enabled ) {
106 $roles_svg_upload_enabled[] = $role_slug;
107 }
108 }
109
110 }
111
112 add_filter( 'upload_mimes', [ $content_management, 'add_svg_mime' ] );
113 add_filter( 'wp_check_filetype_and_ext', [ $content_management, 'confirm_file_type_is_svg' ], 10, 4 );
114 add_filter( 'wp_handle_upload_prefilter', [ $content_management, 'sanitize_and_maybe_allow_svg_upload' ] );
115 add_filter( 'wp_generate_attachment_metadata', [ $content_management, 'generate_svg_metadata' ], 10, 3 );
116 add_action( 'wp_ajax_svg_get_attachment_url', [ $content_management, 'get_svg_attachment_url' ] );
117 add_filter( 'wp_prepare_attachment_for_js', [ $content_management, 'get_svg_url_in_media_library' ] );
118 }
119
120
121 // Content Management >> Enhance List Tables
122 if ( array_key_exists( 'enhance_list_tables', $options ) && $options['enhance_list_tables'] ) {
123
124 // Show Featured Image Column
125 if ( array_key_exists( 'show_featured_image_column', $options ) && $options['show_featured_image_column'] ) {
126 add_action( 'admin_init', [ $content_management, 'show_featured_image_column' ] );
127 }
128
129 // Show Excerpt Column
130 if ( array_key_exists( 'show_excerpt_column', $options ) && $options['show_excerpt_column'] ) {
131 add_action( 'admin_init', [ $content_management, 'show_excerpt_column' ] );
132 }
133
134 // Show ID Column
135 if ( array_key_exists( 'show_id_column', $options ) && $options['show_id_column'] ) {
136 add_action( 'admin_init', [ $content_management, 'show_id_column' ] );
137 }
138
139 // Hide Comments Column
140 if ( array_key_exists( 'hide_comments_column', $options ) && $options['hide_comments_column'] ) {
141 add_action( 'admin_init', [ $content_management, 'hide_comments_column' ] );
142 }
143
144 // Hide Post Tags Column
145 if ( array_key_exists( 'hide_post_tags_column', $options ) && $options['hide_post_tags_column'] ) {
146 add_action( 'admin_init', [ $content_management, 'hide_post_tags_column' ] );
147 }
148
149 // Show Custom Taxonomy Filters
150 if ( array_key_exists( 'show_custom_taxonomy_filters', $options ) && $options['show_custom_taxonomy_filters'] ) {
151 add_action( 'restrict_manage_posts', [ $content_management, 'show_custom_taxonomy_filters' ] );
152 }
153
154 }
155
156 // ===== ADMIN INTERFACE =====
157
158 // Instantiate object for Admin Interface features
159 $admin_interface = new ASENHA\Classes\Admin_Interface;
160
161 // Admin Interface >> Hide Admin Notices
162 if ( array_key_exists( 'hide_admin_notices', $options ) && $options['hide_admin_notices'] ) {
163 add_action( 'all_admin_notices', [ $admin_interface, 'admin_notices_wrapper' ] );
164 add_action( 'admin_bar_menu', [ $admin_interface, 'admin_notices_menu' ] );
165 add_action( 'admin_enqueue_scripts', [ $admin_interface, 'admin_notices_menu_inline_css' ] ); // wp-admin
166 }
167
168 // Admin Interface >> Hide Admin Bar
169 if ( array_key_exists( 'hide_admin_bar', $options ) && $options['hide_admin_bar'] && array_key_exists( 'hide_admin_bar_for', $options ) && isset( $options['hide_admin_bar_for'] ) ) {
170 add_filter( 'show_admin_bar', [ $admin_interface, 'hide_admin_bar_for_roles' ] );
171 }
172
173 // Admin Interface >> View Admin as Role
174 if ( array_key_exists( 'view_admin_as_role', $options ) && $options['view_admin_as_role'] ) {
175 add_action( 'admin_bar_menu', [ $admin_interface, 'view_admin_as_admin_bar_menu' ], 8 ); // Priority 8 so it is next to username section
176 add_action( 'init', [ $admin_interface, 'role_switcher_to_view_admin_as' ] );
177 add_action( 'wp_die_handler', [ $admin_interface, 'custom_error_page_on_switch_failure' ] );
178 }
179
180 // Admin Interface >> Hide or Modify Elements
181 if ( array_key_exists( 'hide_modify_elements', $options ) && $options['hide_modify_elements'] ) {
182 add_filter( 'admin_bar_menu', [ $admin_interface, 'modify_admin_bar_menu' ], 5 ); // priority 5 to execute earlier than the normal 10
183 }
184
185 // Admin Interface >> Customize Admin Menu
186
187 if ( array_key_exists( 'customize_admin_menu', $options ) && $options['customize_admin_menu'] ) {
188 // add_action( 'wp_ajax_save_custom_menu_order', [ $admin_interface, 'save_custom_menu_order' ] );
189 // add_action( 'wp_ajax_save_hidden_menu_items', [ $admin_interface, 'save_hidden_menu_items' ] );
190 add_filter( 'custom_menu_order', '__return_true' );
191 add_filter( 'menu_order', [ $admin_interface, 'render_custom_menu_order' ] );
192 add_action( 'admin_menu', [ $admin_interface, 'apply_custom_menu_item_titles' ], 888 );
193 add_action( 'admin_menu', [ $admin_interface, 'hide_menu_items' ], 999 );
194 add_action( 'admin_menu', [ $admin_interface, 'add_hidden_menu_toggle' ] );
195 add_action( 'admin_enqueue_scripts', [ $admin_interface, 'enqueue_toggle_hidden_menu_script' ] );
196 }
197
198 // ===== DISABLE COMPONENTS ======
199
200 // Instantiate object for Disable Components features
201 $disable_components = new ASENHA\Classes\Disable_Components;
202
203 // Disable Components >> Disable Gutenberg
204 if ( array_key_exists( 'disable_gutenberg', $options ) && $options['disable_gutenberg'] ) {
205 if ( array_key_exists( 'disable_gutenberg_for', $options ) && ! empty( $options['disable_gutenberg_for'] ) ) {
206 add_action( 'admin_init', [ $disable_components, 'disable_gutenberg_for_post_types_admin' ] );
207 if ( array_key_exists( 'disable_gutenberg_frontend_styles', $options ) && $options['disable_gutenberg_frontend_styles'] ) {
208 add_action( 'wp_enqueue_scripts', [ $disable_components, 'disable_gutenberg_for_post_types_frontend' ], 100 );
209 }
210 }
211 }
212
213 // Disable Components >> Disable Comments
214 if ( array_key_exists( 'disable_comments', $options ) && $options['disable_comments'] ) {
215 if ( array_key_exists( 'disable_comments_for', $options ) && ! empty( $options['disable_comments_for'] ) ) {
216 add_action( 'wp_loaded', [ $disable_components, 'disable_comments_for_post_types_edit' ] ); // also work with 'init' and 'admin_init' hooks
217 add_filter( 'comments_array', [ $disable_components, 'hide_existing_comments_on_frontend' ], 10, 2 ); // hide comments
218 add_filter( 'comments_open', [ $disable_components, 'close_commenting_on_frontend' ] ); // close commenting
219 }
220 }
221
222 // Disable Components >> Disable REST API
223 if ( array_key_exists( 'disable_rest_api', $options ) && $options['disable_rest_api'] ) {
224 if ( version_compare( get_bloginfo('version'), '4.7', '>=' ) ) {
225 add_filter( 'rest_authentication_errors', [ $disable_components, 'disable_rest_api' ] );
226 } else {
227 // REST API 1.x
228 add_filter( 'json_enabled', '__return_false' );
229 add_filter( 'json_jsonp_enabled', '__return_false' );
230 // REST API 2.x
231 add_filter( 'rest_enabled', '__return_false' );
232 add_filter( 'rest_jsonp_enabled', '__return_false' );
233 }
234 remove_action('wp_head', 'rest_output_link_wp_head', 10 ); // Disable REST API links in HTML <head>
235 remove_action( 'template_redirect', 'rest_output_link_header', 11, 0 ); // Disable REST API link in HTTP headers
236 remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' ); // Remove REST API URL from the WP RSD endpoint.
237 }
238
239 // ===== SECURITY =====
240
241 // Instantiate object for Security features
242 $security = new ASENHA\Classes\Security;
243
244 // Security >> Change Login URL
245 if ( array_key_exists( 'change_login_url', $options ) && $options['change_login_url'] ) {
246 if ( array_key_exists( 'custom_login_slug', $options ) && ! empty( $options['custom_login_slug'] ) ) {
247 add_action( 'init', [ $security, 'redirect_on_custom_login_url' ] );
248 add_action( 'login_head', [ $security, 'redirect_on_default_login_urls' ] );
249 add_action( 'wp_login_failed', [ $security, 'redirect_to_custom_login_url_on_login_fail' ] );
250 add_action( 'wp_logout', [ $security, 'redirect_to_custom_login_url_on_logout_success' ] );
251 }
252 }
253
254 // Security >> Limit Login Attempts
255 if ( array_key_exists( 'limit_login_attempts', $options ) && $options['limit_login_attempts'] ) {
256 add_filter( 'authenticate', [ $security, 'maybe_allow_login' ], 999, 3 ); // Very low priority so it is processed last
257 add_action( 'login_enqueue_scripts', [ $security, 'maybe_hide_login_form' ] );
258 add_action( 'wp_login_failed', [ $security, 'log_failed_login' ], 5 ); // Higher priority than one in Change Login URL
259 add_action( 'wp_login_errors', [ $security, 'login_error_handler' ], 999, 2 );
260 add_filter( 'login_message', [ $security, 'add_failed_login_message' ] );
261 add_action( 'wp_login', [ $security, 'clear_failed_login_log' ] );
262 }
263
264 // Security >> Obfuscate Author Slugs
265 if ( array_key_exists( 'obfuscate_author_slugs', $options ) && $options['obfuscate_author_slugs'] ) {
266 add_action( 'pre_get_posts', [ $security, 'alter_author_query' ], 10 );
267 add_filter( 'author_link', [ $security, 'alter_author_link' ], 10, 3 );
268 add_filter( 'rest_prepare_user', [ $security, 'alter_json_users' ], 10, 3 );
269 }
270
271 // Security >> Disable XML-RPC
272 if ( array_key_exists( 'disable_xmlrpc', $options ) && $options['disable_xmlrpc'] ) {
273 add_filter( 'xmlrpc_enabled', '__return_false' );
274 add_filter( 'wp_xmlrpc_server_class', [ $security, 'maybe_disable_xmlrpc' ] );
275 }
276
277 // ===== UTILITIES ======
278
279 // Instantiate object for Utilities features
280 $utilities = new ASENHA\Classes\Utilities;
281
282 // Utilities >> Redirect After Login
283 if ( array_key_exists( 'redirect_after_login', $options ) && $options['redirect_after_login'] ) {
284 if ( array_key_exists( 'redirect_after_login_to_slug', $options ) && ! empty( $options['redirect_after_login_to_slug'] ) ) {
285 if ( array_key_exists( 'redirect_after_login_for', $options ) && ! empty( $options['redirect_after_login_for'] ) ) {
286 add_filter( 'wp_login', [ $utilities, 'redirect_for_roles_after_login' ], 5, 2 );
287 }
288 }
289 }
290
291 // Utilities >> Redirect After Logout
292 if ( array_key_exists( 'redirect_after_logout', $options ) && $options['redirect_after_logout'] ) {
293 if ( array_key_exists( 'redirect_after_logout_to_slug', $options ) && ! empty( $options['redirect_after_logout_to_slug'] ) ) {
294 if ( array_key_exists( 'redirect_after_logout_for', $options ) && ! empty( $options['redirect_after_logout_for'] ) ) {
295 add_action( 'wp_logout', [ $utilities, 'redirect_after_logout' ], 5, 1 ); // load earlier than Change Login URL add_action
296 }
297 }
298 }
299
300 // Utilities >> Redirect 404 to Homepage
301 if ( array_key_exists( 'redirect_404_to_homepage', $options ) && $options['redirect_404_to_homepage'] ) {
302 add_filter( 'wp', [ $utilities, 'redirect_404_to_homepage' ] );
303 }
304
305 // Utilities >> Enable Custom Admin / Frontend CSS
306
307 if ( array_key_exists( 'enable_custom_admin_css', $options ) && $options['enable_custom_admin_css'] ) {
308 add_filter( 'admin_enqueue_scripts', [ $utilities, 'custom_admin_css' ] );
309 }
310
311 if ( array_key_exists( 'enable_custom_frontend_css', $options ) && $options['enable_custom_frontend_css'] ) {
312 add_filter( 'wp_enqueue_scripts', [ $utilities, 'custom_frontend_css' ] );
313 }
314
315 }
316
317 }
318
319 Admin_Site_Enhancements::get_instance();