PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.0
Independent Analytics – WordPress Analytics Plugin v2.15.0
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 3 days ago dist 3 days ago freemius 3 days ago img 2 months ago javascript-source 3 days ago languages 3 days ago vendor 3 days ago views 3 days ago iawp-bootstrap.php 3 days ago iawp-click-endpoint.php 3 days ago iawp-complianz.php 3 months ago iawp.php 3 days ago readme.txt 3 days ago
iawp-bootstrap.php
397 lines
1 <?php
2
3 namespace IAWPSCOPED;
4
5 use IAWP\ActivationLifecycle;
6 use IAWP\BreakdanceFormAction;
7 use IAWP\Click_Tracking\Click_Processing_Job;
8 use IAWP\Click_Tracking\Config_File_Manager;
9 use IAWP\ComplianzIntegration;
10 use IAWP\Dashboard_Options;
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\FetchFaviconsJob;
17 use IAWP\Geo_Database_Health_Check_Job;
18 use IAWP\Independent_Analytics;
19 use IAWP\Interrupt;
20 use IAWP\Journey\JourneyStatisticsJob;
21 use IAWP\MainWP;
22 use IAWP\Migration_Fixer_Job;
23 use IAWP\Migrations;
24 use IAWP\Overview\Module_Refresh_Job;
25 use IAWP\Overview\Modules\Module;
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\Report_Finder;
31 use IAWP\Utils\BladeOne;
32 use IAWP\ViewsColumn\ViewsColumn;
33 use IAWP\WP_Option_Cache_Bust;
34 \define( 'IAWP_DIRECTORY', \rtrim( \plugin_dir_path( __FILE__ ), \DIRECTORY_SEPARATOR ) );
35 \define( 'IAWP_URL', \rtrim( \plugin_dir_url( __FILE__ ), '/' ) );
36 \define( 'IAWP_VERSION', '2.15.0' );
37 \define( 'IAWP_DATABASE_VERSION', '52' );
38 \define( 'IAWP_LANGUAGES_DIRECTORY', \dirname( \plugin_basename( __FILE__ ) ) . '/languages' );
39 \define( 'IAWP_PLUGIN_FILE', __DIR__ . '/iawp.php' );
40 if ( \file_exists( \IAWPSCOPED\iawp_path_to( 'vendor/scoper-autoload.php' ) ) ) {
41 require_once \IAWPSCOPED\iawp_path_to( 'vendor/scoper-autoload.php' );
42 } else {
43 require_once \IAWPSCOPED\iawp_path_to( 'vendor/autoload.php' );
44 }
45 /**
46 * @param $log
47 *
48 * @return void
49 * @internal
50 */
51 function iawp_log( $log ) : void {
52 if ( \WP_DEBUG === \true && \WP_DEBUG_LOG === \true ) {
53 if ( \is_array( $log ) || \is_object( $log ) ) {
54 \error_log( \print_r( $log, \true ) );
55 } else {
56 \error_log( $log );
57 }
58 }
59 }
60
61 /** @internal */
62 function iawp_path_to( string $path ) : string {
63 $path = \trim( $path, \DIRECTORY_SEPARATOR );
64 return \implode( \DIRECTORY_SEPARATOR, [\IAWP_DIRECTORY, $path] );
65 }
66
67 /** @internal */
68 function iawp_url_to( string $path ) : string {
69 $path = \trim( $path, '/' );
70 return \implode( '/', [\IAWP_URL, $path] );
71 }
72
73 /**
74 * add_filter('iawp_temp_directory_path', function ($value) {
75 * return '/Users/andrew/site/wp-content/uploads/iawp';
76 * });
77 *
78 * @param string $path
79 *
80 * @return string
81 * @throws Exception
82 * @internal
83 */
84 function iawp_temp_path_to( string $path ) : string {
85 $temp_directory = ( \defined( 'IAWP_TEMP_DIR' ) ? \IAWP_TEMP_DIR : \apply_filters( 'iawp_temp_directory_path', 'temp' ) );
86 $path = \rtrim( $path, \DIRECTORY_SEPARATOR );
87 if ( $temp_directory === 'temp' ) {
88 return \IAWPSCOPED\iawp_path_to( \implode( \DIRECTORY_SEPARATOR, [$temp_directory, $path] ) );
89 }
90 $temp_directory = \rtrim( $temp_directory, \DIRECTORY_SEPARATOR );
91 if ( !\is_writable( $temp_directory ) ) {
92 \wp_mkdir_p( $temp_directory );
93 // Separate condition to see if wp_mkdir_p call fixed the issue
94 if ( !\is_writable( $temp_directory ) ) {
95 throw new \Exception('The temp directory set with the iawp_temp_directory_path filter is missing or is not writable: ' . $temp_directory);
96 }
97 }
98 return \implode( \DIRECTORY_SEPARATOR, [$temp_directory, $path] );
99 }
100
101 /**
102 * @param string $path
103 * @param bool $prefer_parent_site_upload_path If it's a multisite installation, use the parent sites upload folder
104 * @return string
105 * @internal
106 */
107 function iawp_upload_path_to( string $path, bool $prefer_parent_site_upload_path = \false ) : string {
108 $path = \trim( $path, \DIRECTORY_SEPARATOR );
109 $upload_directory = \wp_upload_dir()['basedir'];
110 if ( $prefer_parent_site_upload_path && \is_multisite() ) {
111 $site = \get_site();
112 if ( $site !== null ) {
113 \switch_to_blog( \intval( $site->site_id ) );
114 $upload_directory = \wp_upload_dir()['basedir'];
115 \restore_current_blog();
116 }
117 }
118 return \implode( \DIRECTORY_SEPARATOR, [$upload_directory, $path] );
119 }
120
121 /** @internal */
122 function iawp_upload_url_to( string $path ) : string {
123 $upload_url = \wp_upload_dir()['baseurl'];
124 $path = \trim( $path, '/' );
125 return \implode( '/', [$upload_url, $path] );
126 }
127
128 /**
129 * Determines if the user is running a licensed pro version
130 *
131 * @return bool
132 * @internal
133 */
134 function iawp_is_pro() : bool {
135 return \false;
136 }
137
138 /**
139 * Determines if the user is running a free version or an unlicensed pro version
140 * @return bool
141 * @internal
142 */
143 function iawp_is_free() : bool {
144 return !\IAWPSCOPED\iawp_is_pro();
145 }
146
147 /** @internal */
148 function iawp_dashboard_url( array $query_arguments = [] ) : string {
149 $default_query_arguments = [
150 'page' => 'independent-analytics',
151 ];
152 return \add_query_arg( \array_merge( $default_query_arguments, $query_arguments ), \admin_url( 'admin.php' ) );
153 }
154
155 /** @internal */
156 function iawp_render( string $view, array $variables = [] ) : string {
157 static $blade = null;
158 if ( $blade === null ) {
159 if ( !\file_exists( \IAWPSCOPED\iawp_temp_path_to( 'template-cache' ) ) ) {
160 \wp_mkdir_p( \IAWPSCOPED\iawp_temp_path_to( 'template-cache' ) );
161 }
162 $blade = BladeOne::create();
163 $blade->share( 'env', new Env() );
164 $blade->share( 'is_pro', \IAWPSCOPED\iawp_is_pro() );
165 $blade->share( 'security', new \IAWP\Utils\Security() );
166 }
167 return $blade->run( $view, $variables );
168 }
169
170 /** @internal */
171 function iawp_icon( string $icon ) : string {
172 try {
173 return \IAWPSCOPED\iawp_render( 'icons.plugins.' . $icon );
174 } catch ( \Throwable $e ) {
175 return '';
176 }
177 }
178
179 /**
180 * Get the currently installed database version
181 *
182 * @return int
183 * @internal
184 */
185 function iawp_db_version() : int {
186 return \intval( \get_option( 'iawp_db_version', '0' ) );
187 }
188
189 /** @internal */
190 function iawp_intify( $value ) {
191 if ( \is_string( $value ) && \ctype_digit( $value ) ) {
192 return \intval( $value );
193 }
194 return $value;
195 }
196
197 /** @internal */
198 function iawp_custom_log( $line ) {
199 try {
200 $filePath = \IAWPSCOPED\iawp_path_to( 'public-custom-log.txt' );
201 // Normalize line endings
202 $line = \rtrim( $line, "\r\n" );
203 // Append the line
204 \file_put_contents( $filePath, $line . \PHP_EOL, \FILE_APPEND );
205 } catch ( \Throwable $e ) {
206 }
207 }
208
209 /**
210 * iawp_singular_analytics('60', new DateTime('-3 days'), new DateTime());
211 *
212 * @param string|int $singular_id
213 * @param DateTime $from
214 * @param DateTime $to
215 *
216 * @return Singular_Analytics|null
217 * @internal
218 */
219 function iawp_singular_analytics( $singular_id, \DateTime $from, \DateTime $to ) : ?Singular_Analytics {
220 $date_range = new Exact_Date_Range($from, $to);
221 return Singular_Analytics::for( $singular_id, $date_range );
222 }
223
224 /**
225 * iawp_top_posts();
226 *
227 * Retrieves top posts with customizable options.
228 *
229 * @param array{
230 * post_type: string, // Default: 'post'
231 * category: ?int, // Default: null
232 * limit: int, // Default: 10
233 * from: \DateTimeInterface, // Default: 30 days ago
234 * to: \DateTimeInterface, // Default: today
235 * sort_by: string, // Default: 'views' - supports 'views', 'visitors', or 'sessions'
236 * } $options
237 *
238 * @return array
239 * @internal
240 */
241 function iawp_top_posts( array $options = [] ) : array {
242 return ( new Top_Posts($options) )->get();
243 }
244
245 /**
246 * iawp_analytics(new DateTime('-3 days'), new DateTime());
247 *
248 * @param DateTime $from
249 * @param DateTime $to
250 *
251 * @return Analytics
252 * @internal
253 */
254 function iawp_analytics( \DateTime $from, \DateTime $to ) : Analytics {
255 $date_range = new Exact_Date_Range($from, $to);
256 return Analytics::for( $date_range );
257 }
258
259 if ( !\extension_loaded( 'pdo' ) || !\extension_loaded( 'pdo_mysql' ) ) {
260 $interrupt = new Interrupt('interrupt.pdo');
261 $interrupt->render();
262 return;
263 }
264 if ( \IAWPSCOPED\iawp_db_version() === 0 && !Database::has_correct_database_privileges() ) {
265 $interrupt = new Interrupt('interrupt.missing-database-permissions');
266 $interrupt->render( [
267 'missing_privileges' => Database::missing_database_privileges(),
268 ] );
269 return;
270 }
271 global $wpdb;
272 if ( \strlen( $wpdb->prefix ) > 25 ) {
273 $interrupt = new Interrupt('interrupt.database-prefix-too-long');
274 $interrupt->render( [
275 'prefix' => $wpdb->prefix,
276 'length' => \strlen( $wpdb->prefix ),
277 ] );
278 return;
279 }
280 if ( Migrations\Migrations::is_database_ahead_of_plugin() ) {
281 $interrupt = new Interrupt('interrupt.database-ahead-of-plugin');
282 $interrupt->render();
283 return;
284 }
285 if ( \get_option( 'iawp_missing_tables' ) === '1' ) {
286 if ( \IAWPSCOPED\iawp_db_version() === 0 ) {
287 \delete_option( 'iawp_missing_tables' );
288 } else {
289 $interrupt = new Interrupt('interrupt.missing-database-tables');
290 $interrupt->render();
291 return;
292 }
293 }
294 // These can be updated in background jobs. Always get the actual value from the database.
295 WP_Option_Cache_Bust::register( 'iawp_is_migrating' );
296 WP_Option_Cache_Bust::register( 'iawp_should_refresh_modules' );
297 WP_Option_Cache_Bust::register( 'iawp_migration_started_at' );
298 WP_Option_Cache_Bust::register( 'iawp_is_database_downloading' );
299 WP_Option_Cache_Bust::register( 'iawp_db_version' );
300 WP_Option_Cache_Bust::register( 'iawp_geo_database_version' );
301 WP_Option_Cache_Bust::register( 'iawp_overview_modules' );
302 WP_Option_Cache_Bust::register( 'iawp_modules_refreshed_at' );
303 WP_Option_Cache_Bust::register( 'iawp_default_modules_added' );
304 /** @internal */
305 function iawp() {
306 return Independent_Analytics::getInstance();
307 }
308
309 \IAWPSCOPED\iawp();
310 // This fires when either the free or pro plugin versions are activated. This does not fire
311 // when transitioning from free-to-pro or pro-to-free via Freemius. The hooks below
312 // take care of that.
313 //
314 // What's up with the transient option iawp_activation_ran? The goal is to prevent
315 \register_activation_hook( \IAWP_PLUGIN_FILE, function () {
316 \set_transient( 'iawp_activation_ran', \true, 60 );
317 ActivationLifecycle::handle_activation();
318 } );
319 // This fires when transitioning from pro-to-free via Freemius. In that case, register_activation_hook
320 // will not fire. This hook is essential to make sure the free activation code runs.
321 \IAWP_FS()->add_action( 'after_free_version_reactivation', function () {
322 if ( \get_transient( 'iawp_activation_ran' ) ) {
323 return;
324 }
325 \set_transient( 'iawp_activation_ran', \true, 60 );
326 ActivationLifecycle::handle_activation();
327 } );
328 // This fires when transitioning from free-to-pro via Freemius. In that case, register_activation_hook
329 // will not fire. This hook is essential to make sure the pro activation code runs.
330 \IAWP_FS()->add_action( 'after_premium_version_activation', function () {
331 if ( \get_transient( 'iawp_activation_ran' ) ) {
332 return;
333 }
334 \set_transient( 'iawp_activation_ran', \true, 60 );
335 ActivationLifecycle::handle_activation();
336 } );
337 \register_deactivation_hook( \IAWP_PLUGIN_FILE, function () {
338 \delete_transient( 'iawp_activation_ran' );
339 ActivationLifecycle::handle_deactivation();
340 } );
341 // This fires for the original version of the plugin and not the updated version of the plugin
342 \add_action( 'upgrader_process_complete', function () {
343 // Trigger the click processing cron job so no clicks are lost
344 \do_action( 'iawp_click_processing' );
345 } );
346 \add_action( 'init', function () {
347 Config_File_Manager::ensure();
348 ( new Geo_Database_Health_Check_Job() )->schedule();
349 ( new Migration_Fixer_Job() )->schedule();
350 ( new FetchFaviconsJob() )->schedule();
351 BreakdanceFormAction::register();
352 if ( \IAWPSCOPED\iawp_is_pro() ) {
353 ( new Click_Processing_Job() )->schedule();
354 ( new Module_Refresh_Job() )->schedule();
355 ( new JourneyStatisticsJob() )->schedule();
356 }
357 if ( \IAWPSCOPED\iawp()->is_surecart_support_enabled() ) {
358 ( new SureCart_Event_Sync_Job() )->schedule();
359 }
360 if ( \IAWPSCOPED\iawp()->is_surecart_support_enabled() && \in_array( \get_option( 'iawp_surecart_currency_code' ), ['', \false] ) ) {
361 SureCart_Store::cache_currency_code();
362 }
363 } );
364 \add_action( 'admin_init', function () {
365 Migrations\Migrations::handle_migration_18_error();
366 Migrations\Migrations::handle_migration_22_error();
367 Migrations\Migrations::handle_migration_29_error();
368 Migrations\Migrations::handle_migration_45_collation_error();
369 Migrations\Migrations::handle_migration_46_error();
370 Patch::patch_2_6_2_incorrect_email_report_schedule();
371 Patch::patch_2_8_7_potential_duplicates();
372 Config_File_Manager::ensure();
373 $options = Dashboard_Options::getInstance();
374 $options->maybe_redirect();
375 new Migrations\Migration_Job();
376 if ( \get_option( 'iawp_db_version', '0' ) === '0' ) {
377 // If there is no database installed, run migration on current process
378 Migrations\Migrations::create_or_migrate();
379 } else {
380 // If there is a database, run migration in a background process
381 Migrations\Migration_Job::maybe_dispatch();
382 }
383 if ( \get_option( 'iawp_should_refresh_modules', '0' ) === '1' ) {
384 \update_option( 'iawp_should_refresh_modules', '0', \true );
385 Module::refresh_all_modules();
386 }
387 if ( \get_option( 'iawp_has_added_journey_default_reports', '0' ) === '0' ) {
388 \update_option( 'iawp_has_added_journey_default_reports', '1', \true );
389 $report_finder = new Report_Finder();
390 if ( empty( $report_finder->get_saved_reports_for_type( 'journeys' ) ) ) {
391 Report_Finder::insert_default_user_journey_reports();
392 }
393 }
394 } );
395 ViewsColumn::initialize();
396 MainWP::initialize();
397 ComplianzIntegration::initialize();