active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( $_GET['tab'] ) : self::GDPRESS_ADMIN_SECTION_MANAGE; $this->admin_page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : ''; parent::__construct(); $this->init(); } /** * Action & Filter hooks. * * @return void */ private function init() { // Global add_action( 'admin_menu', [ $this, 'create_menu' ] ); add_filter( 'plugin_action_links_' . plugin_basename( GDPRESS_PLUGIN_FILE ), [ $this, 'add_settings_link' ] ); if ( $this->admin_page !== self::GDPRESS_ADMIN_PAGE ) { return; } // Scripts add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_assets' ] ); // Footer Text add_filter( 'admin_footer_text', [ $this, 'set_footer_text_left' ], 99 ); add_filter( 'update_footer', [ $this, 'set_footer_text_right' ], 11 ); // Tabs add_action( 'gdpress_settings_tab', [ $this, 'add_manage_tab' ], 1 ); add_action( 'gdpress_settings_tab', [ $this, 'add_help_tab' ], 2 ); // Settings Screen Content add_action( 'gdpress_settings_content', [ $this, 'set_content' ], 1 ); } /** * Adds the Manage Tab to the settings screen. * * @return void */ public function add_help_tab() { $this->generate_tab( self::GDPRESS_ADMIN_SECTION_HELP, 'dashicons-editor-help', __( 'Help', 'gdpr-press' ) ); } /** * @param $id * @param null $icon * @param null $label */ private function generate_tab( $id, $icon = null, $label = null ) { ?> generate_tab( self::GDPRESS_ADMIN_SECTION_MANAGE, 'dashicons-download', __( 'Manage External Requests', 'gdpr-press' ) ); } /** * Add settings link to plugin overview * * @param $links * * @return mixed */ public function add_settings_link( $links ) { $adminUrl = admin_url() . 'options-general.php?page=' . self::GDPRESS_ADMIN_PAGE; $settingsLink = "" . __( 'Settings', 'gdpr-press' ) . ''; array_push( $links, $settingsLink ); return $links; } /** * Create WP menu-item */ public function create_menu() { add_options_page( 'GDPRess', 'GDPRess', 'manage_options', self::GDPRESS_ADMIN_PAGE, [ $this, 'settings_page' ] ); add_action( 'admin_init', [ $this, 'register_settings' ] ); } /** * We add the assets directly to the head to avoid ad blockers blocking the URLs cause they include 'analytics'. * * @return void */ public function enqueue_admin_assets() { wp_enqueue_script( self::GDPRESS_ADMIN_JS_HANDLE, plugin_dir_url( GDPRESS_PLUGIN_FILE ) . 'assets/js/gdpress-admin.js', [ 'jquery' ], GDPRESS_STATIC_VERSION, true ); wp_enqueue_style( self::GDPRESS_ADMIN_CSS_HANDLE, plugin_dir_url( GDPRESS_PLUGIN_FILE ) . 'assets/css/gdpress-admin.css', [], GDPRESS_STATIC_VERSION ); } /** * Register all settings when we're on the Manage tab. */ public function register_settings() { if ( $this->active_tab !== self::GDPRESS_ADMIN_SECTION_MANAGE ) { return; } foreach ( $this->get_settings() as $value ) { register_setting( $this->active_tab, $value ); } } /** * Get all settings for the current section using the constants in this class. * * @return array */ private function get_settings() { $reflection = new \ReflectionClass( $this ); $constants = apply_filters( 'gdpress_register_settings', $reflection->getConstants() ); $needle = apply_filters( 'gdpress_register_settings_needle', 'GDPRESS_MANAGE_SETTING' ); return array_filter( $constants, function ( $key ) use ( $needle ) { return str_contains( $key, $needle ); }, ARRAY_FILTER_USE_KEY ); } /** * Render active content. */ public function set_content() { echo apply_filters( str_replace( '-', '_', esc_attr( $this->active_tab ) ) . '_content', '' ); } /** * Changes footer text. * * @return string */ public function set_footer_text_left() { $text = __( 'Coded with ❤️ in The Netherlands @ Daan.dev.', 'gdpr-press' ); return ''; } /** * All logic to generate the news reel in the bottom right of the footer on GDPRess' settings pages. * * Includes multiple checks to make sure the reel is only shown if a recent post is available. * * @param mixed $text * * @return mixed */ public function set_footer_text_right( $text ) { if ( ! extension_loaded( 'simplexml' ) || ! extension_loaded( 'mbstring' ) ) { return $text; } /** * If a WordPress update is available, show the original text. */ $update_core = get_site_transient( 'update_core' ); $update = is_object( $update_core ) && ! empty( $update_core->updates ) && isset( $update_core->updates[0]->response ) && 'upgrade' === $update_core->updates[0]->response; if ( $update ) { return $text; } // Prevents bashing the API. $xml = get_transient( self::GDPRESS_TRANSIENT_NEWS_REEL ); if ( ! $xml ) { $response = wp_safe_remote_get( 'https://daan.dev/blog/tag/gdpr/feed', [ 'timeout' => 3, 'redirection' => 3, ] ); if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) { $xml = wp_remote_retrieve_body( $response ); // Refresh the feed once a day to prevent bashing of the API. set_transient( self::GDPRESS_TRANSIENT_NEWS_REEL, $xml, DAY_IN_SECONDS ); } } if ( ! $xml ) { return $text; } /** * Make sure the XML is properly encoded. */ $previous = libxml_use_internal_errors( true ); $xml = mb_convert_encoding( $xml, 'UTF-8' ); $xml = simplexml_load_string( $xml ); libxml_clear_errors(); libxml_use_internal_errors( $previous ); if ( ! $xml ) { return $text; } $items = $xml->channel->item ?? []; if ( empty( $items ) ) { return $text; } $text = sprintf( __( 'Recently tagged #GDPR on my blog:', 'gdpr-press' ), 'https://daan.dev/blog/tag/gdpr' ) . ' '; $text .= ''; $i = 0; foreach ( $items as $item ) { if ( $i > 4 ) { break; } $hide = $i > 0 ? 'style="display: none;"' : ''; $text .= "" . sprintf( '%s', esc_url( (string) $item->link ), esc_html( (string) $item->title ) ) . ''; $i ++; } $text .= ''; return $text; } /** * Create the settings page */ public function settings_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( __( "You're not cool enough to access this page.", 'gdpr-press' ) ); } ?>