PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.13.5
Independent Analytics – WordPress Analytics Plugin v2.13.5
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / iawp-bootstrap.php
independent-analytics Last commit date
IAWP 9 months ago dist 9 months ago freemius 10 months ago img 9 months ago javascript-source 10 months ago languages 9 months ago vendor 9 months ago views 9 months ago iawp-bootstrap.php 9 months ago iawp-click-endpoint.php 1 year ago iawp.php 9 months ago readme.txt 9 months ago
iawp-bootstrap.php
393 lines
1 <?php
2
3 namespace IAWPSCOPED;
4
5 use IAWP\Click_Tracking\Click_Processing_Job;
6 use IAWP\Click_Tracking\Config_File_Manager;
7 use IAWP\Cron\Unscheduler;
8 use IAWP\Custom_WordPress_Columns\Views_Column;
9 use IAWP\Dashboard_Options;
10 use IAWP\Data_Pruning\Pruning_Scheduler;
11 use IAWP\Database;
12 use IAWP\Date_Range\Exact_Date_Range;
13 use IAWP\Ecommerce\SureCart_Event_Sync_Job;
14 use IAWP\Ecommerce\SureCart_Store;
15 use IAWP\Env;
16 use IAWP\Geo_Database_Health_Check_Job;
17 use IAWP\Geo_Database_Manager;
18 use IAWP\Independent_Analytics;
19 use IAWP\Interrupt;
20 use IAWP\MainWP;
21 use IAWP\Migration_Fixer_Job;
22 use IAWP\Migrations;
23 use IAWP\Overview\Module_Refresh_Job;
24 use IAWP\Overview\Modules\Module;
25 use IAWP\Overview\Sync_Module_Background_Job;
26 use IAWP\Patch;
27 use IAWP\Public_API\Analytics;
28 use IAWP\Public_API\Singular_Analytics;
29 use IAWP\Public_API\Top_Posts;
30 use IAWP\Utils\BladeOne;
31 use IAWP\WP_Option_Cache_Bust;
32 \define( 'IAWP_DIRECTORY', \rtrim( \plugin_dir_path( __FILE__ ), \DIRECTORY_SEPARATOR ) );
33 \define( 'IAWP_URL', \rtrim( \plugin_dir_url( __FILE__ ), '/' ) );
34 \define( 'IAWP_VERSION', '2.13.5' );
35 \define( 'IAWP_DATABASE_VERSION', '52' );
36 \define( 'IAWP_LANGUAGES_DIRECTORY', \dirname( \plugin_basename( __FILE__ ) ) . '/languages' );
37 \define( 'IAWP_PLUGIN_FILE', __DIR__ . '/iawp.php' );
38 if ( \file_exists( \IAWPSCOPED\iawp_path_to( 'vendor/scoper-autoload.php' ) ) ) {
39 require_once \IAWPSCOPED\iawp_path_to( 'vendor/scoper-autoload.php' );
40 } else {
41 require_once \IAWPSCOPED\iawp_path_to( 'vendor/autoload.php' );
42 }
43 /**
44 * @param $log
45 *
46 * @return void
47 * @internal
48 */
49 function iawp_log( $log ) : void {
50 if ( \WP_DEBUG === \true && \WP_DEBUG_LOG === \true ) {
51 if ( \is_array( $log ) || \is_object( $log ) ) {
52 \error_log( \print_r( $log, \true ) );
53 } else {
54 \error_log( $log );
55 }
56 }
57 }
58
59 /** @internal */
60 function iawp_path_to( string $path ) : string {
61 $path = \trim( $path, \DIRECTORY_SEPARATOR );
62 return \implode( \DIRECTORY_SEPARATOR, [\IAWP_DIRECTORY, $path] );
63 }
64
65 /** @internal */
66 function iawp_url_to( string $path ) : string {
67 $path = \trim( $path, '/' );
68 return \implode( '/', [\IAWP_URL, $path] );
69 }
70
71 /**
72 * add_filter('iawp_temp_directory_path', function ($value) {
73 * return '/Users/andrew/site/wp-content/uploads/iawp';
74 * });
75 *
76 * @param string $path
77 *
78 * @return string
79 * @throws Exception
80 * @internal
81 */
82 function iawp_temp_path_to( string $path ) : string {
83 $temp_directory = ( \defined( 'IAWP_TEMP_DIR' ) ? \IAWP_TEMP_DIR : \apply_filters( 'iawp_temp_directory_path', 'temp' ) );
84 $path = \rtrim( $path, \DIRECTORY_SEPARATOR );
85 if ( $temp_directory === 'temp' ) {
86 return \IAWPSCOPED\iawp_path_to( \implode( \DIRECTORY_SEPARATOR, [$temp_directory, $path] ) );
87 }
88 $temp_directory = \rtrim( $temp_directory, \DIRECTORY_SEPARATOR );
89 if ( !\is_writable( $temp_directory ) ) {
90 \wp_mkdir_p( $temp_directory );
91 // Separate condition to see if wp_mkdir_p call fixed the issue
92 if ( !\is_writable( $temp_directory ) ) {
93 throw new \Exception('The temp directory set with the iawp_temp_directory_path filter is missing or is not writable: ' . $temp_directory);
94 }
95 }
96 return \implode( \DIRECTORY_SEPARATOR, [$temp_directory, $path] );
97 }
98
99 /**
100 * @param string $path
101 * @param bool $prefer_parent_site_upload_path If it's a multisite installation, use the parent sites upload folder
102 * @return string
103 * @internal
104 */
105 function iawp_upload_path_to( string $path, bool $prefer_parent_site_upload_path = \false ) : string {
106 $path = \trim( $path, \DIRECTORY_SEPARATOR );
107 $upload_directory = \wp_upload_dir()['basedir'];
108 if ( $prefer_parent_site_upload_path && \is_multisite() ) {
109 $site = \get_site();
110 if ( $site !== null ) {
111 \switch_to_blog( \intval( $site->site_id ) );
112 $upload_directory = \wp_upload_dir()['basedir'];
113 \restore_current_blog();
114 }
115 }
116 return \implode( \DIRECTORY_SEPARATOR, [$upload_directory, $path] );
117 }
118
119 /** @internal */
120 function iawp_upload_url_to( string $path ) : string {
121 $upload_url = \wp_upload_dir()['baseurl'];
122 $path = \trim( $path, '/' );
123 return \implode( '/', [$upload_url, $path] );
124 }
125
126 /**
127 * Determines if the user is running a licensed pro version
128 *
129 * @return bool
130 * @internal
131 */
132 function iawp_is_pro() : bool {
133 return \false;
134 }
135
136 /**
137 * Determines if the user is running a free version or an unlicensed pro version
138 * @return bool
139 * @internal
140 */
141 function iawp_is_free() : bool {
142 return !\IAWPSCOPED\iawp_is_pro();
143 }
144
145 /** @internal */
146 function iawp_dashboard_url( array $query_arguments = [] ) : string {
147 $default_query_arguments = [
148 'page' => 'independent-analytics',
149 ];
150 return \add_query_arg( \array_merge( $default_query_arguments, $query_arguments ), \admin_url( 'admin.php' ) );
151 }
152
153 /** @internal */
154 function iawp_blade() {
155 if ( !\file_exists( \IAWPSCOPED\iawp_temp_path_to( 'template-cache' ) ) ) {
156 \wp_mkdir_p( \IAWPSCOPED\iawp_temp_path_to( 'template-cache' ) );
157 }
158 $blade = BladeOne::create();
159 $blade->share( 'env', new Env() );
160 $blade->share( 'is_pro', \IAWPSCOPED\iawp_is_pro() );
161 $blade->share( 'security', new \IAWP\Utils\Security() );
162 return $blade;
163 }
164
165 /** @internal */
166 function iawp_render( string $view, array $variables = [] ) : string {
167 if ( !\file_exists( \IAWPSCOPED\iawp_temp_path_to( 'template-cache' ) ) ) {
168 \wp_mkdir_p( \IAWPSCOPED\iawp_temp_path_to( 'template-cache' ) );
169 }
170 $blade = BladeOne::create();
171 $blade->share( 'env', new Env() );
172 $blade->share( 'is_pro', \IAWPSCOPED\iawp_is_pro() );
173 $blade->share( 'security', new \IAWP\Utils\Security() );
174 return $blade->run( $view, $variables );
175 }
176
177 /** @internal */
178 function iawp_icon( string $icon ) : string {
179 try {
180 return \IAWPSCOPED\iawp_blade()->run( 'icons.plugins.' . $icon );
181 } catch ( \Throwable $e ) {
182 return '';
183 }
184 }
185
186 /**
187 * Get the currently installed database version
188 *
189 * @return int
190 * @internal
191 */
192 function iawp_db_version() : int {
193 return \intval( \get_option( 'iawp_db_version', '0' ) );
194 }
195
196 /** @internal */
197 function iawp_intify( $value ) {
198 if ( \is_string( $value ) && \ctype_digit( $value ) ) {
199 return \intval( $value );
200 }
201 return $value;
202 }
203
204 /** @internal */
205 function iawp_custom_log( $line ) {
206 try {
207 $filePath = \IAWPSCOPED\iawp_path_to( 'public-custom-log.txt' );
208 // Normalize line endings
209 $line = \rtrim( $line, "\r\n" );
210 // Append the line
211 \file_put_contents( $filePath, $line . \PHP_EOL, \FILE_APPEND );
212 } catch ( \Throwable $e ) {
213 }
214 }
215
216 /**
217 * iawp_singular_analytics('60', new DateTime('-3 days'), new DateTime());
218 *
219 * @param string|int $singular_id
220 * @param DateTime $from
221 * @param DateTime $to
222 *
223 * @return Singular_Analytics|null
224 * @internal
225 */
226 function iawp_singular_analytics( $singular_id, \DateTime $from, \DateTime $to ) : ?Singular_Analytics {
227 $date_range = new Exact_Date_Range($from, $to);
228 return Singular_Analytics::for( $singular_id, $date_range );
229 }
230
231 /**
232 * iawp_top_posts();
233 *
234 * Retrieves top posts with customizable options.
235 *
236 * @param array{
237 * post_type: string, // Default: 'post'
238 * category: ?int, // Default: null
239 * limit: int, // Default: 10
240 * from: \DateTimeInterface, // Default: 30 days ago
241 * to: \DateTimeInterface, // Default: today
242 * sort_by: string, // Default: 'views' - supports 'views', 'visitors', or 'sessions'
243 * } $options
244 *
245 * @return array
246 * @internal
247 */
248 function iawp_top_posts( array $options = [] ) : array {
249 return ( new Top_Posts($options) )->get();
250 }
251
252 /**
253 * iawp_analytics(new DateTime('-3 days'), new DateTime());
254 *
255 * @param DateTime $from
256 * @param DateTime $to
257 *
258 * @return Analytics
259 * @internal
260 */
261 function iawp_analytics( \DateTime $from, \DateTime $to ) : Analytics {
262 $date_range = new Exact_Date_Range($from, $to);
263 return Analytics::for( $date_range );
264 }
265
266 if ( !\extension_loaded( 'pdo' ) || !\extension_loaded( 'pdo_mysql' ) ) {
267 $interrupt = new Interrupt('interrupt.pdo');
268 $interrupt->render();
269 return;
270 }
271 if ( \IAWPSCOPED\iawp_db_version() === 0 && !Database::has_correct_database_privileges() ) {
272 $interrupt = new Interrupt('interrupt.missing-database-permissions');
273 $interrupt->render( [
274 'missing_privileges' => Database::missing_database_privileges(),
275 ] );
276 return;
277 }
278 global $wpdb;
279 if ( \strlen( $wpdb->prefix ) > 25 ) {
280 $interrupt = new Interrupt('interrupt.database-prefix-too-long');
281 $interrupt->render( [
282 'prefix' => $wpdb->prefix,
283 'length' => \strlen( $wpdb->prefix ),
284 ] );
285 return;
286 }
287 if ( Migrations\Migrations::is_database_ahead_of_plugin() ) {
288 $interrupt = new Interrupt('interrupt.database-ahead-of-plugin');
289 $interrupt->render();
290 return;
291 }
292 if ( \get_option( 'iawp_missing_tables' ) === '1' ) {
293 if ( \IAWPSCOPED\iawp_db_version() === 0 ) {
294 \delete_option( 'iawp_missing_tables' );
295 } else {
296 $interrupt = new Interrupt('interrupt.missing-database-tables');
297 $interrupt->render();
298 return;
299 }
300 }
301 // These can be updated in background jobs. Always get the actual value from the database.
302 WP_Option_Cache_Bust::register( 'iawp_is_migrating' );
303 WP_Option_Cache_Bust::register( 'iawp_should_refresh_modules' );
304 WP_Option_Cache_Bust::register( 'iawp_migration_started_at' );
305 WP_Option_Cache_Bust::register( 'iawp_is_database_downloading' );
306 WP_Option_Cache_Bust::register( 'iawp_db_version' );
307 WP_Option_Cache_Bust::register( 'iawp_geo_database_version' );
308 WP_Option_Cache_Bust::register( 'iawp_overview_modules' );
309 WP_Option_Cache_Bust::register( 'iawp_default_modules_added' );
310 /** @internal */
311 function iawp() {
312 return Independent_Analytics::getInstance();
313 }
314
315 \IAWPSCOPED\iawp();
316 \register_activation_hook( \IAWP_PLUGIN_FILE, function () {
317 \wp_mkdir_p( \IAWPSCOPED\iawp_temp_path_to( 'template-cache' ) );
318 if ( \IAWPSCOPED\iawp_db_version() === 0 ) {
319 // If there is no database installed, run migration on current process
320 Migrations\Migrations::create_or_migrate();
321 } else {
322 // If there is a database, run migration in a background process
323 Migrations\Migration_Job::maybe_dispatch();
324 }
325 ( new Geo_Database_Manager() )->health_check();
326 \update_option( 'iawp_need_clear_cache', \true, \true );
327 if ( \get_option( 'iawp_show_gsg' ) == '' ) {
328 \update_option( 'iawp_show_gsg', '1', \true );
329 }
330 \IAWPSCOPED\iawp()->cron_manager->schedule_refresh_salt();
331 ( new Pruning_Scheduler() )->schedule();
332 if ( \IAWPSCOPED\iawp_is_pro() ) {
333 \IAWPSCOPED\iawp()->email_reports->schedule();
334 }
335 // Set current version for changelog notifications
336 \update_option( 'iawp_last_update_viewed', \IAWP_VERSION, \true );
337 if ( \IAWPSCOPED\iawp_db_version() > 0 && Database::is_missing_all_tables() ) {
338 \update_option( 'iawp_missing_tables', '1', \true );
339 }
340 } );
341 \register_deactivation_hook( \IAWP_PLUGIN_FILE, function () {
342 Unscheduler::unschedule_all_events();
343 ( new Geo_Database_Manager() )->delete_database();
344 \wp_delete_file( \trailingslashit( \WPMU_PLUGIN_DIR ) . 'iawp-performance-boost.php' );
345 \delete_option( 'iawp_must_use_directory_not_writable' );
346 } );
347 // This fires for the original version of the plugin and not the updated version of the plugin
348 \add_action( 'upgrader_process_complete', function () {
349 // Trigger the click processing cron job so no clicks are lost
350 \do_action( 'iawp_click_processing' );
351 } );
352 \add_action( 'init', function () {
353 Config_File_Manager::ensure();
354 ( new Geo_Database_Health_Check_Job() )->schedule();
355 ( new Migration_Fixer_Job() )->schedule();
356 if ( \IAWPSCOPED\iawp_is_pro() ) {
357 ( new Click_Processing_Job() )->schedule();
358 ( new Module_Refresh_Job() )->schedule();
359 }
360 if ( \IAWPSCOPED\iawp()->is_surecart_support_enabled() ) {
361 ( new SureCart_Event_Sync_Job() )->schedule();
362 }
363 if ( \IAWPSCOPED\iawp()->is_surecart_support_enabled() && \in_array( \get_option( 'iawp_surecart_currency_code' ), ['', \false] ) ) {
364 SureCart_Store::cache_currency_code();
365 }
366 } );
367 \add_action( 'admin_init', function () {
368 Migrations\Migrations::handle_migration_18_error();
369 Migrations\Migrations::handle_migration_22_error();
370 Migrations\Migrations::handle_migration_29_error();
371 Migrations\Migrations::handle_migration_45_collation_error();
372 Migrations\Migrations::handle_migration_46_error();
373 Patch::patch_2_6_2_incorrect_email_report_schedule();
374 Patch::patch_2_8_7_potential_duplicates();
375 Config_File_Manager::ensure();
376 $options = Dashboard_Options::getInstance();
377 $options->maybe_redirect();
378 new Migrations\Migration_Job();
379 if ( \get_option( 'iawp_db_version', '0' ) === '0' ) {
380 // If there is no database installed, run migration on current process
381 Migrations\Migrations::create_or_migrate();
382 } else {
383 // If there is a database, run migration in a background process
384 Migrations\Migration_Job::maybe_dispatch();
385 }
386 if ( \get_option( 'iawp_should_refresh_modules', '0' ) === '1' ) {
387 \update_option( 'iawp_should_refresh_modules', '0', \true );
388 Module::queue_full_module_refresh();
389 }
390 } );
391 new Sync_Module_Background_Job();
392 Views_Column::initialize();
393 MainWP::initialize();