PluginProbe
GDPRess | Eliminate external requests to increase GDPR compliance / trunk
GDPRess | Eliminate external requests to increase GDPR compliance vtrunk
trunk 1.0.2 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1
gdpr-press / src / Admin / Settings.php

Settings.php in GDPRess | Eliminate external requests to increase GDPR compliance trunk, at src/Admin/Settings.php

355 lines 10.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package GDPRess
4 * @author Daan van den Bergh
5 * https://daan.dev
6 */
7
8 namespace GDPRess\Admin;
9
10 use GDPRess\Admin;
11
12 class Settings extends Admin {
13
14 const GDPRESS_ADMIN_PAGE = 'gdpr-press';
15
16 const GDPRESS_ADMIN_SECTION_MANAGE = 'gdpress-manage';
17
18 const GDPRESS_ADMIN_SECTION_HELP = 'gdpress-help';
19
20 const GDPRESS_ADMIN_CSS_HANDLE = 'gdpress-admin-css';
21
22 const GDPRESS_ADMIN_JS_HANDLE = 'gdpress-admin-js';
23
24 /**
25 * Transients
26 */
27 const GDPRESS_TRANSIENT_NEWS_REEL = 'gdpress_news_reel';
28
29 /**
30 * Settings
31 */
32 const GDPRESS_MANAGE_SETTING_TEST_MODE = 'gdpress_test_mode';
33
34 const GDPRESS_MANAGE_SETTING_REQUESTS = 'gdpress_external_requests';
35
36 const GDPRESS_MANAGE_SETTING_LOCAL = 'gdpress_local_urls';
37
38 const GDPRESS_MANAGE_SETTING_EXCLUDED = 'gdpress_excluded_urls';
39
40 /** @var string $active_tab */
41 private $active_tab = '';
42
43 /** @var string $admin_page */
44 private $admin_page = '';
45
46 /**
47 * Set fields
48 *
49 * @return void
50 */
51 public function __construct() {
52 $this->active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( $_GET['tab'] ) : self::GDPRESS_ADMIN_SECTION_MANAGE;
53 $this->admin_page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';
54
55 parent::__construct();
56
57 $this->init();
58 }
59
60 /**
61 * Action & Filter hooks.
62 *
63 * @return void
64 */
65 private function init() {
66 // Global
67 add_action( 'admin_menu', [ $this, 'create_menu' ] );
68 add_filter( 'plugin_action_links_' . plugin_basename( GDPRESS_PLUGIN_FILE ), [ $this, 'add_settings_link' ] );
69
70 if ( $this->admin_page !== self::GDPRESS_ADMIN_PAGE ) {
71 return;
72 }
73
74 // Scripts
75 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_assets' ] );
76
77 // Footer Text
78 add_filter( 'admin_footer_text', [ $this, 'set_footer_text_left' ], 99 );
79 add_filter( 'update_footer', [ $this, 'set_footer_text_right' ], 11 );
80
81 // Tabs
82 add_action( 'gdpress_settings_tab', [ $this, 'add_manage_tab' ], 1 );
83 add_action( 'gdpress_settings_tab', [ $this, 'add_help_tab' ], 2 );
84
85 // Settings Screen Content
86 add_action( 'gdpress_settings_content', [ $this, 'set_content' ], 1 );
87 }
88
89 /**
90 * Adds the Manage Tab to the settings screen.
91 *
92 * @return void
93 */
94 public function add_help_tab() {
95 $this->generate_tab( self::GDPRESS_ADMIN_SECTION_HELP, 'dashicons-editor-help', __( 'Help', 'gdpr-press' ) );
96 }
97
98 /**
99 * @param $id
100 * @param null $icon
101 * @param null $label
102 */
103 private function generate_tab( $id, $icon = null, $label = null ) {
104 ?>
105 <a class="nav-tab dashicons-before <?php echo esc_attr( $icon ); ?> <?php echo $this->active_tab === $id ? 'nav-tab-active' : ''; ?>" href="<?php echo $this->generate_tab_link( $id ); ?>">
106 <?php echo esc_html( $label ); ?>
107 </a>
108 <?php
109 }
110
111 /**
112 * @param $tab
113 *
114 * @return string
115 */
116 private function generate_tab_link( $tab ) {
117 $admin_page = self::GDPRESS_ADMIN_PAGE;
118
119 return esc_url( admin_url( "options-general.php?page=$admin_page&tab=$tab" ) );
120 }
121
122 /**
123 * Adds the Manage Tab to the settings screen.
124 *
125 * @return void
126 */
127 public function add_manage_tab() {
128 $this->generate_tab( self::GDPRESS_ADMIN_SECTION_MANAGE, 'dashicons-download', __( 'Manage External Requests', 'gdpr-press' ) );
129 }
130
131 /**
132 * Add settings link to plugin overview
133 *
134 * @param $links
135 *
136 * @return mixed
137 */
138 public function add_settings_link( $links ) {
139 $adminUrl = admin_url() . 'options-general.php?page=' . self::GDPRESS_ADMIN_PAGE;
140 $settingsLink = "<a href='" . esc_url( $adminUrl ) . "'>" . __( 'Settings', 'gdpr-press' ) . '</a>';
141 array_push( $links, $settingsLink );
142
143 return $links;
144 }
145
146 /**
147 * Create WP menu-item
148 */
149 public function create_menu() {
150 add_options_page(
151 'GDPRess',
152 'GDPRess',
153 'manage_options',
154 self::GDPRESS_ADMIN_PAGE,
155 [ $this, 'settings_page' ]
156 );
157
158 add_action( 'admin_init', [ $this, 'register_settings' ] );
159 }
160
161 /**
162 * We add the assets directly to the head to avoid ad blockers blocking the URLs cause they include 'analytics'.
163 *
164 * @return void
165 */
166 public function enqueue_admin_assets() {
167 wp_enqueue_script( self::GDPRESS_ADMIN_JS_HANDLE, plugin_dir_url( GDPRESS_PLUGIN_FILE ) . 'assets/js/gdpress-admin.js', [ 'jquery' ], GDPRESS_STATIC_VERSION, true );
168 wp_enqueue_style( self::GDPRESS_ADMIN_CSS_HANDLE, plugin_dir_url( GDPRESS_PLUGIN_FILE ) . 'assets/css/gdpress-admin.css', [], GDPRESS_STATIC_VERSION );
169 }
170
171 /**
172 * Register all settings when we're on the Manage tab.
173 */
174 public function register_settings() {
175 if ( $this->active_tab !== self::GDPRESS_ADMIN_SECTION_MANAGE ) {
176 return;
177 }
178
179 foreach ( $this->get_settings() as $value ) {
180 register_setting(
181 $this->active_tab,
182 $value
183 );
184 }
185 }
186
187 /**
188 * Get all settings for the current section using the constants in this class.
189 *
190 * @return array
191 */
192 private function get_settings() {
193 $reflection = new \ReflectionClass( $this );
194 $constants = apply_filters( 'gdpress_register_settings', $reflection->getConstants() );
195 $needle = apply_filters( 'gdpress_register_settings_needle', 'GDPRESS_MANAGE_SETTING' );
196
197 return array_filter(
198 $constants,
199 function ( $key ) use ( $needle ) {
200 return str_contains( $key, $needle );
201 },
202 ARRAY_FILTER_USE_KEY
203 );
204 }
205
206 /**
207 * Render active content.
208 */
209 public function set_content() {
210 echo apply_filters( str_replace( '-', '_', esc_attr( $this->active_tab ) ) . '_content', '' );
211 }
212
213 /**
214 * Changes footer text.
215 *
216 * @return string
217 */
218 public function set_footer_text_left() {
219 $text = __( 'Coded with ❤️ in The Netherlands @ <strong>Daan.dev</strong>.', 'gdpr-press' );
220
221 return '<span id="footer-thankyou">' . $text . '</span>';
222 }
223
224 /**
225 * All logic to generate the news reel in the bottom right of the footer on GDPRess' settings pages.
226 *
227 * Includes multiple checks to make sure the reel is only shown if a recent post is available.
228 *
229 * @param mixed $text
230 *
231 * @return mixed
232 */
233 public function set_footer_text_right( $text ) {
234 if ( ! extension_loaded( 'simplexml' ) || ! extension_loaded( 'mbstring' ) ) {
235 return $text;
236 }
237
238 /**
239 * If a WordPress update is available, show the original text.
240 */
241 $update_core = get_site_transient( 'update_core' );
242 $update = is_object( $update_core )
243 && ! empty( $update_core->updates )
244 && isset( $update_core->updates[0]->response )
245 && 'upgrade' === $update_core->updates[0]->response;
246
247 if ( $update ) {
248 return $text;
249 }
250
251 // Prevents bashing the API.
252 $xml = get_transient( self::GDPRESS_TRANSIENT_NEWS_REEL );
253
254 if ( ! $xml ) {
255 $response = wp_safe_remote_get(
256 'https://daan.dev/blog/tag/gdpr/feed',
257 [
258 'timeout' => 3,
259 'redirection' => 3,
260 ]
261 );
262
263 if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
264 $xml = wp_remote_retrieve_body( $response );
265
266 // Refresh the feed once a day to prevent bashing of the API.
267 set_transient( self::GDPRESS_TRANSIENT_NEWS_REEL, $xml, DAY_IN_SECONDS );
268 }
269 }
270
271 if ( ! $xml ) {
272 return $text;
273 }
274
275 /**
276 * Make sure the XML is properly encoded.
277 */
278 $previous = libxml_use_internal_errors( true );
279 $xml = mb_convert_encoding( $xml, 'UTF-8' );
280 $xml = simplexml_load_string( $xml );
281 libxml_clear_errors();
282 libxml_use_internal_errors( $previous );
283
284 if ( ! $xml ) {
285 return $text;
286 }
287
288 $items = $xml->channel->item ?? [];
289
290 if ( empty( $items ) ) {
291 return $text;
292 }
293
294 $text = sprintf( __( 'Recently tagged <a target="_blank" rel="noopener noreferrer" href="%s"><strong>#GDPR</strong></a> on my blog:', 'gdpr-press' ), 'https://daan.dev/blog/tag/gdpr' ) . ' ';
295 $text .= '<span id="gdpress-ticker-wrap">';
296 $i = 0;
297
298 foreach ( $items as $item ) {
299 if ( $i > 4 ) {
300 break;
301 }
302
303 $hide = $i > 0 ? 'style="display: none;"' : '';
304 $text .= "<span class='ticker-item' $hide>" . sprintf(
305 '<a target="_blank" rel="noopener noreferrer" href="%s"><em>%s</em></a>',
306 esc_url( (string) $item->link ),
307 esc_html( (string) $item->title )
308 ) . '</span>';
309 $i ++;
310 }
311
312 $text .= '</span>';
313
314 return $text;
315 }
316
317 /**
318 * Create the settings page
319 */
320 public function settings_page() {
321 if ( ! current_user_can( 'manage_options' ) ) {
322 wp_die( __( "You're not cool enough to access this page.", 'gdpr-press' ) );
323 } ?>
324
325 <div class="wrap gdpress">
326 <h1><?php _e( 'GDPRess | Eliminate External Requests', 'gdpr-press' ); ?></h1>
327
328 <h2 class="gdpress-nav nav-tab-wrapper">
329 <?php do_action( 'gdpress_settings_tab' ); ?>
330 </h2>
331
332 <?php if ( $this->active_tab === self::GDPRESS_ADMIN_SECTION_MANAGE ) : ?>
333 <form id="<?php echo esc_attr( $this->active_tab ); ?>-form" method="post" action="options.php?tab=<?php echo esc_attr( $this->active_tab ); ?>">
334 <?php
335 settings_fields( $this->active_tab );
336 do_settings_sections( $this->active_tab );
337 ?>
338 <?php endif; ?>
339
340 <?php do_action( 'gdpress_settings_content' ); ?>
341
342 <?php
343 $current_section = str_replace( '-', '_', $this->active_tab );
344 do_action( "after_$current_section" );
345 ?>
346
347 <?php if ( $this->active_tab === self::GDPRESS_ADMIN_SECTION_MANAGE ) : ?>
348 <?php submit_button( __( 'Process changes', 'gdpr-press' ), 'primary', 'submit', false ); ?>
349 </form>
350 <?php endif; ?>
351 </div>
352 <?php
353 }
354 }
355