PluginProbe
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) / trunk
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) vtrunk
9.1.2 9.1.1 9.1.0 9.0.2 9.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 All 153 releases
wp-analytify / classes / analytify-logs.php

analytify-logs.php in Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) trunk, at classes/analytify-logs.php

214 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName -- File naming is acceptable for this plugin structure
2 /**
3 * Analytify Logs Class
4 *
5 * This class handles logging functionality for the Analytify plugin,
6 * including log file creation, log writing, and log management.
7 *
8 * @package WP_Analytify
9 * @since 1.0.0
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit; // Exit if accessed directly.
14 }
15
16 /**
17 * Analytify Logs Class
18 *
19 * @package WP_Analytify
20 * @since 1.0.0
21 */
22 class Analytify_Logs {
23
24
25 /**
26 * Constructor.
27 *
28 * @return void
29 */
30 public function __construct() {
31 $this->run_setup();
32 add_action( 'admin_menu', array( $this, 'log_page' ) );
33 add_action( 'admin_init', array( $this, 'buffer' ), 1 );
34 }
35
36
37 /**
38 * Run setup process.
39 *
40 * @return void
41 */
42 public function run_setup() {
43
44 // Run setup only once.
45 if ( get_option( 'analytify_logs_setup' ) ) {
46 return;
47 }
48
49 add_action( 'init', array( $this, 'create_cron_jobs' ) );
50 add_action( 'init', array( $this, 'create_files' ) );
51
52 update_option( 'analytify_logs_setup', true );
53 }
54
55 /**
56 * Create cron jobs.
57 *
58 * @return void
59 */
60 public function create_cron_jobs() {
61
62 if ( ! wp_next_scheduled( 'analytify_cleanup_logs' ) ) {
63 wp_schedule_event( time() + ( 3 * HOUR_IN_SECONDS ), 'daily', 'analytify_cleanup_logs' );
64 }
65 }
66
67
68 /**
69 * Create log files.
70 *
71 * @return void
72 */
73 public function create_files() {
74
75 // Install files and folders for uploading files and prevent hotlinking.
76 $upload_dir = wp_upload_dir();
77
78 $files = array(
79
80 array(
81 'base' => WP_ANALYTIFY_LOG_DIR,
82 'file' => '.htaccess',
83 'content' => 'deny from all',
84 ),
85 array(
86 'base' => WP_ANALYTIFY_LOG_DIR,
87 'file' => 'index.html',
88 'content' => '',
89 ),
90 );
91
92 foreach ( $files as $file ) {
93 if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
94 $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged,WordPress.WP.AlternativeFunctions.file_system_read_fopen,WordPress.PHP.NoSilencedErrors.Discouraged,WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- Direct file operations needed for log file creation
95 if ( $file_handle ) {
96 fwrite( $file_handle, $file['content'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fwrite,WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- Direct file operations needed for log file creation
97 fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose,WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- Direct file operations needed for log file creation
98 }
99 }
100 }
101 }
102
103 /**
104 * Add log page to admin menu.
105 *
106 * @return void
107 */
108 public function log_page() {
109 // Add submenu page for Analytify Logs.
110 add_submenu_page( 'admin.php', __( 'Analytify Logs', 'wp-analytify' ), __( 'Analytify Logs', 'wp-analytify' ), 'manage_options', 'analytify-logs', array( $this, 'add_logs_page' ) );
111 }
112
113 /**
114 * Display logs page.
115 *
116 * @return void
117 */
118 public function add_logs_page() {
119
120 $logs = self::scan_log_files();
121 $viewed_log = '';
122
123 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification handled by WordPress admin context
124 if ( ! empty( $_REQUEST['log_file'] ) && isset( $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ] ) ) { // WPCS: input var ok, CSRF ok.
125 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification handled by WordPress admin context
126 $viewed_log = $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ]; // WPCS: input var ok, CSRF ok.
127 } elseif ( ! empty( $logs ) ) {
128 $viewed_log = current( $logs );
129 }
130
131 $handle = ! empty( $viewed_log ) ? self::get_log_file_handle( $viewed_log ) : '';
132
133 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification handled by WordPress admin context
134 if ( ! empty( $_REQUEST['handle'] ) ) { // WPCS: input var ok, CSRF ok.
135 self::remove_log();
136 }
137
138 include WP_ANALYTIFY_PLUGIN_DIR . '/inc/analytify-logs.php';
139 }
140
141 /**
142 * Scan the log files.
143 *
144 * @return array<string, mixed>
145 */
146 public static function scan_log_files(): array {
147 // Check if class exists before calling.
148 if ( class_exists( 'ANALYTIFY_Log_Handler_File' ) ) {
149 return ANALYTIFY_Log_Handler_File::get_log_files();
150 }
151 return array();
152 }
153
154
155 /**
156 * Return the log file handle.
157 *
158 * @param string $filename Filename to get the handle for.
159 * @return string
160 */
161 public static function get_log_file_handle( $filename ) {
162 return substr( $filename, 0, strlen( $filename ) > 48 ? strlen( $filename ) - 48 : strlen( $filename ) - 4 );
163 }
164
165 /**
166 * Remove/delete the chosen log file.
167 *
168 * Verifies nonce, delegates to the file log handler, then clears output buffers
169 * and redirects so the Delete log button works when admin buffering is active.
170 *
171 * @return void
172 * @since 1.0.0
173 * @version 9.0.0
174 */
175 public static function remove_log() {
176 if ( ! current_user_can( 'manage_options' ) ) {
177 wp_die( esc_html__( 'You do not have permission to delete logs.', 'wp-analytify' ), '', array( 'response' => 403 ) );
178 }
179 if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'remove_log' ) ) { // WPCS: input var ok, sanitization ok.
180 wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'wp-analytify' ) );
181 }
182
183 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified above
184 if ( ! empty( $_REQUEST['handle'] ) && class_exists( 'ANALYTIFY_Log_Handler_File' ) ) {
185 $log_handler = new ANALYTIFY_Log_Handler_File();
186 $log_handler->remove( sanitize_text_field( wp_unslash( $_REQUEST['handle'] ) ) ); // WPCS: input var ok, sanitization ok.
187 }
188
189 // Clear any output buffer so redirect is sent (fixes Delete log button when buffering is active).
190 while ( ob_get_level() ) {
191 ob_end_clean();
192 }
193 wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=analytify-logs' ) ) );
194 exit();
195 }
196
197
198 /**
199 * Output buffering allows admin screens to make redirects later on.
200 *
201 * @return void
202 */
203 public function buffer() {
204 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification handled by WordPress admin context
205 if ( isset( $_GET['page'] ) && 'analytify-logs' === $_GET['page'] ) {
206 ob_start();
207 }
208 }
209 }
210
211 if ( class_exists( 'Analytify_Logs' ) ) {
212 new Analytify_Logs();
213 }
214