PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.14.1
Independent Analytics – WordPress Analytics Plugin v2.14.1
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 / Independent_Analytics.php
independent-analytics / IAWP Last commit date
AJAX 7 months ago Admin_Page 7 months ago Click_Tracking 9 months ago ColumnOptions 7 months ago Cron 10 months ago Custom_WordPress_Columns 9 months ago Data_Pruning 9 months ago Date_Picker 1 year ago Date_Range 1 year ago Ecommerce 7 months ago Email_Reports 7 months ago Examiner 1 year ago Favicon 7 months ago Form_Submissions 7 months ago Integrations 7 months ago Interval 1 year ago Journey 7 months ago Migrations 7 months ago Models 7 months ago Overview 9 months ago Public_API 10 months ago Rows 7 months ago Statistics 7 months ago Tables 7 months ago Utils 7 months ago Views 7 months ago WooCommerceOrderMetaBox 7 months ago Admin_Bar_Stats.php 7 months ago Appearance.php 1 year ago Campaign_Builder.php 1 year ago Capability_Manager.php 1 year ago Chart.php 10 months ago Chart_Data.php 1 year ago Click_Tracking.php 1 year ago Cron_Job.php 7 months ago Cron_Manager.php 7 months ago Current_Traffic_Finder.php 1 year ago Dashboard_Options.php 7 months ago Dashboard_Widget.php 2 years ago Database.php 10 months ago Database_Manager.php 7 months ago Empty_Report_Option.php 2 years ago Env.php 7 months ago Examiner_Config.php 1 year ago FetchFaviconsJob.php 7 months ago Filters.php 7 months ago Geo_Database_Health_Check_Job.php 10 months ago Geo_Database_Manager.php 7 months ago Geoposition.php 1 year ago Icon_Directory.php 7 months ago Icon_Directory_Factory.php 2 years ago Illuminate_Builder.php 1 year ago Independent_Analytics.php 7 months ago Interrupt.php 1 year ago Known_Referrers.php 7 months ago MainWP.php 1 year ago Map.php 10 months ago Map_Data.php 1 year ago Migration_Fixer_Job.php 9 months ago Patch.php 1 year ago Payload_Validator.php 10 months ago Plugin_Conflict_Detector.php 7 months ago Plugin_Group.php 7 months ago Plugin_Group_Option.php 2 years ago Query.php 1 year ago Query_Taps.php 7 months ago Quick_Stats.php 1 year ago REST_API.php 7 months ago Real_Time.php 10 months ago Report.php 1 year ago Report_Finder.php 7 months ago Report_Options_Parser.php 10 months ago Resource_Identifier.php 10 months ago Settings.php 7 months ago Sort_Configuration.php 10 months ago Tables.php 9 months ago Track_Resource_Changes.php 1 year ago View_Counter.php 7 months ago Views_Over_Time_Finder.php 1 year ago VisitorSaltRefreshInterval.php 7 months ago WP_Option_Cache_Bust.php 2 years ago
Independent_Analytics.php
639 lines
1 <?php
2
3 namespace IAWP;
4
5 use IAWPSCOPED\Carbon\CarbonImmutable;
6 use IAWPSCOPED\Carbon\CarbonInterval;
7 use IAWP\Admin_Page\Analytics_Page;
8 use IAWP\Admin_Page\Campaign_Builder_Page;
9 use IAWP\Admin_Page\Click_Tracking_Page;
10 use IAWP\Admin_Page\Debug_Page;
11 use IAWP\Admin_Page\Integrations_Pages;
12 use IAWP\Admin_Page\Settings_Page;
13 use IAWP\Admin_Page\Support_Page;
14 use IAWP\Admin_Page\Updates_Page;
15 use IAWP\Admin_Page\Visitor_Page;
16 use IAWP\AJAX\AJAX_Manager;
17 use IAWP\Click_Tracking\Click_Processing_Job;
18 use IAWP\Data_Pruning\Pruner;
19 use IAWP\Ecommerce\EDD_Order;
20 use IAWP\Ecommerce\Fluent_Cart_Order;
21 use IAWP\Ecommerce\PMPro_Order;
22 use IAWP\Ecommerce\SureCart_Event_Sync_Job;
23 use IAWP\Ecommerce\SureCart_Order;
24 use IAWP\Ecommerce\SureCart_Store;
25 use IAWP\Ecommerce\WooCommerce_Order;
26 use IAWP\Email_Reports\Email_Reports;
27 use IAWP\Form_Submissions\Form;
28 use IAWP\Form_Submissions\Submission_Listener;
29 use IAWP\Journey\JourneyStatisticsJob;
30 use IAWP\Migrations\Migrations;
31 use IAWP\Overview\Module_Refresh_Job;
32 use IAWP\Utils\Plugin;
33 use IAWP\Utils\Request;
34 use IAWP\Utils\Singleton;
35 use IAWP\Utils\Timezone;
36 use IAWP\WooCommerceOrderMetaBox\WooCommerceOrderMetaBox;
37 use IAWPSCOPED\Illuminate\Support\Carbon;
38 use IAWPSCOPED\Illuminate\Support\Str;
39 /** @internal */
40 class Independent_Analytics
41 {
42 use Singleton;
43 public $settings;
44 public $email_reports;
45 public $cron_manager;
46 private $is_woocommerce_support_enabled;
47 private $is_surecart_support_enabled;
48 private $is_edd_support_enabled;
49 private $is_pmpro_support_enabled;
50 private $is_fluent_cart_support_enabled;
51 private $is_form_submission_support_enabled;
52 // This is where we attach functions to WP hooks
53 private function __construct()
54 {
55 $this->configure_carbon();
56 $this->settings = new \IAWP\Settings();
57 new \IAWP\REST_API();
58 new \IAWP\Dashboard_Widget();
59 new \IAWP\View_Counter();
60 new Submission_Listener();
61 Pruner::register_hook();
62 AJAX_Manager::getInstance();
63 if (!Migrations::is_migrating()) {
64 new \IAWP\Track_Resource_Changes();
65 \IAWP\Admin_Bar_Stats::register();
66 WooCommerce_Order::register_hooks();
67 EDD_Order::register_hooks();
68 PMPro_Order::register_hooks();
69 SureCart_Order::register_hooks();
70 Fluent_Cart_Order::register_hooks();
71 }
72 \IAWP\Cron_Job::register_custom_intervals();
73 \IAWP\Database_Manager::register_actions();
74 $this->cron_manager = new \IAWP\Cron_Manager();
75 (new SureCart_Event_Sync_Job())->register_handler();
76 (new JourneyStatisticsJob())->register_handler();
77 (new \IAWP\FetchFaviconsJob())->register_handler();
78 (new Click_Processing_Job())->register_handler();
79 (new Module_Refresh_Job())->register_handler();
80 (new \IAWP\Migration_Fixer_Job())->register_handler();
81 (new \IAWP\Geo_Database_Health_Check_Job())->register_handler();
82 if (\IAWPSCOPED\iawp_is_pro()) {
83 $this->email_reports = new Email_Reports();
84 new \IAWP\Campaign_Builder();
85 WooCommerceOrderMetaBox::register();
86 }
87 \add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts_and_styles'], 110);
88 // Called at 110 to dequeue other scripts
89 \add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts_and_styles_front_end']);
90 \add_action('admin_menu', [$this, 'add_admin_menu_pages']);
91 \add_action('admin_init', [$this, 'remove_freemius_pricing_menu']);
92 \add_filter('plugin_action_links_independent-analytics/iawp.php', [$this, 'plugin_action_links']);
93 \add_action('init', [$this, 'polylang_translations']);
94 \add_action('init', [$this, 'load_text_domain']);
95 // Freemius adjustments
96 \IAWP_FS()->add_filter('pricing_url', [$this, 'change_freemius_pricing_url'], 10);
97 \IAWP_FS()->add_filter('show_affiliate_program_notice', '__return_false');
98 \IAWP_FS()->add_filter('show_deactivation_feedback_form', function () {
99 return \false;
100 });
101 \IAWP_FS()->add_filter('connect-header', [$this, 'freemius_optin_heading']);
102 \IAWP_FS()->add_filter('connect_message', [$this, 'freemius_optin_text']);
103 if (\function_exists('IAWPSCOPED\\fs_override_i18n')) {
104 fs_override_i18n(['opt-in-connect' => \__('Subscribe & Go To Analytics', 'independent-analytics'), 'skip' => \__('No, thanks', 'independent-analytics')], 'independent-analytics');
105 }
106 // Other hooks
107 \add_action('admin_init', [$this, 'maybe_delete_mu_plugin']);
108 \add_action('admin_body_class', [$this, 'add_body_class']);
109 \add_filter('sgs_whitelist_wp_content', [$this, 'whitelist_click_endpoint']);
110 \add_filter('cmplz_whitelisted_script_tags', [$this, 'whitelist_script_tag_for_complianz']);
111 \add_filter('plugin_action_links_independent-analytics/iawp.php', [$this, 'add_upgrade_link_in_plugins_menu'], 999);
112 \add_filter('plugin_row_meta', [$this, 'add_docs_link_in_plugins_menu'], 10, 2);
113 \add_action('admin_footer', [$this, 'attach_system_appearance_script'], 99, 0);
114 \add_filter('sgo_javascript_combine_excluded_inline_content', [$this, 'exclude_tracking_script_from_speed_optimizer'], 10, 1);
115 \add_action('admin_init', [$this, 'maybe_add_cookie']);
116 }
117 public function add_upgrade_link_in_plugins_menu($links)
118 {
119 if (\IAWPSCOPED\iawp_is_pro()) {
120 return $links;
121 }
122 $upgrade_link = '<a target="_blank" style="color:#36B366;font-weight:700;"
123 href="https://independentwp.com/pro/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Plugin+Settings+Link"
124 >' . \esc_html__('Upgrade to Pro', 'independent-analytics') . '</a>';
125 \array_unshift($links, $upgrade_link);
126 return $links;
127 }
128 public function add_docs_link_in_plugins_menu($plugin_meta, $plugin_file)
129 {
130 if ($plugin_file == 'independent-analytics/iawp.php' || $plugin_file == 'independent-analytics-pro/iawp.php') {
131 $plugin_meta[] = '<a target="_blank" href="https://independentwp.com/knowledgebase/">' . \esc_html__('Knowledge Base', 'independent-analytics') . '</a>';
132 }
133 return $plugin_meta;
134 }
135 /**
136 * Attach some JavaScript to manage the color scheme for admin pages.
137 *
138 * @return void
139 */
140 public function attach_system_appearance_script() : void
141 {
142 ?>
143 <script>
144 ;(() => {
145 try {
146 const isLightMode = document.body.classList.contains('iawp-light-mode')
147 const isDarkMode = document.body.classList.contains('iawp-dark-mode')
148 const isSystem = !isLightMode && !isDarkMode
149
150 // Stop if they're not using the systems color scheme
151 if(!isSystem) {
152 return
153 }
154
155 // Switch to dark mode if dark is the system color scheme preference
156 if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
157 document.body.classList.add('iawp-dark-mode')
158 }
159
160 // Watching for changes is a nice idea, but it's more complicated than just
161 // adding or removing a class from the body. There are elements like
162 // charts that cannot adapt without a rendered. Holding off on this.
163
164 // window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
165 // if(event.matches) {
166 // document.body.classList.remove('iawp-light-mode')
167 // document.body.classList.add('iawp-dark-mode')
168 // } else {
169 // document.body.classList.remove('iawp-dark-mode')
170 // document.body.classList.add('iawp-light-mode')
171 // }
172 // });
173 } catch (error) {
174
175 }
176 })();
177
178 </script>
179 <?php
180 }
181 public function add_body_class(string $classes) : string
182 {
183 $newClasses = [];
184 if (\IAWP\Appearance::is_light()) {
185 $newClasses[] = 'iawp-light-mode';
186 } elseif (\IAWP\Appearance::is_dark()) {
187 $newClasses[] = 'iawp-dark-mode';
188 }
189 $page = \IAWP\Env::get_page();
190 if (\is_string($page)) {
191 $newClasses[] = $page;
192 }
193 if (\array_key_exists('examiner', $_GET)) {
194 $newClasses[] = 'iawp-in-examiner';
195 }
196 return $classes . ' ' . \implode(' ', $newClasses) . ' ';
197 }
198 /**
199 * At one point in time, there was a must-use plugin that was created. The plugin file and the
200 * option need to get cleaned up.
201 * @return void
202 */
203 public function maybe_delete_mu_plugin()
204 {
205 $already_attempted = \get_option('iawp_attempted_to_delete_mu_plugin', '0');
206 if ($already_attempted === '1') {
207 return;
208 }
209 if (\get_option('iawp_must_use_directory_not_writable', '0') === '1') {
210 \delete_option('iawp_must_use_directory_not_writable');
211 }
212 $mu_plugin_file = \trailingslashit(\WPMU_PLUGIN_DIR) . 'iawp-performance-boost.php';
213 if (\file_exists($mu_plugin_file)) {
214 \unlink($mu_plugin_file);
215 }
216 \update_option('iawp_attempted_to_delete_mu_plugin', '1', \true);
217 }
218 public function load_text_domain()
219 {
220 \load_plugin_textdomain('independent-analytics', \false, \IAWP_LANGUAGES_DIRECTORY);
221 // Freemius overrides must happen after the text domain is loaded
222 \IAWP_FS()->override_i18n(['yee-haw' => \__('Success', 'independent-analytics')]);
223 }
224 public function polylang_translations()
225 {
226 if (\function_exists('IAWPSCOPED\\pll_register_string')) {
227 pll_register_string('view_counter', 'Views:', 'Independent Analytics');
228 }
229 }
230 // Changes the URL for the "Upgrade" tab in the Account menu
231 public function change_freemius_pricing_url()
232 {
233 return 'https://independentwp.com/pro/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Upgrade+to+Pro&utm_content=Account';
234 }
235 public function freemius_optin_heading()
236 {
237 return '<h2>' . \esc_html__('Congratulations on Your New Analytics! 🎉', 'independent-analytics') . '</h2>';
238 }
239 public function freemius_optin_text()
240 {
241 $html = '<p>' . \esc_html__("You've just taken the first step towards building a better website.", "independent-analytics") . '</p>';
242 $html .= '<br />';
243 $html .= '<p>' . \esc_html__("If you signup for our free email course, we’ll walk you through each feature in Independent Analytics, so you can learn how to analyze and optimize your website for growth.", "independent-analytics") . '</p>';
244 $html .= '<br />';
245 $html .= '<p><strong>' . \esc_html_x("Subscribe now and you'll receive our:", "What follows is a list of benefits", "independent-analytics") . '</strong></p>';
246 $html .= '<ul>';
247 $html .= '<li><span class="dashicons dashicons-yes-alt"></span> ' . \esc_html__('Free email tutorial series', 'independent-analytics') . '</li>';
248 $html .= '<li><span class="dashicons dashicons-yes-alt"></span> ' . \esc_html__('Subscriber-only sales announcements', 'independent-analytics') . '</li>';
249 $html .= '<li><span class="dashicons dashicons-yes-alt"></span> ' . \esc_html__('New feature updates', 'independent-analytics') . '</li>';
250 $html .= '<li><span class="dashicons dashicons-yes-alt"></span> ' . \esc_html__('Security alerts', 'independent-analytics') . '</li>';
251 $html .= '</ul>';
252 $html .= '<p>' . \esc_html('Subscribing will also share some basic info about your WordPress site with us, which helps us make Independent Analytics an even better plugin for everyone.', 'independent-analytics') . '</p>';
253 $html .= '<p class="rating">' . \sprintf(\esc_html__('Rated %s and trusted by over 100,000+ WordPress websites.', 'independent-analytics'), '<span class="star-container"><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span></span>') . '</p>';
254 $html .= '<img src="' . \IAWPSCOPED\iawp_url_to('img/email-review.png') . '" />';
255 return $html;
256 }
257 public function add_admin_menu_pages()
258 {
259 $title = \IAWP\Capability_Manager::show_white_labeled_ui() ? \esc_html__('Analytics', 'independent-analytics') : 'Independent Analytics';
260 \add_menu_page($title, \esc_html__('Analytics', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics', function () {
261 $analytics_page = new Analytics_Page();
262 $analytics_page->render();
263 }, $this->get_menu_icon(), 3);
264 if (\IAWP\Capability_Manager::can_edit()) {
265 \add_submenu_page('independent-analytics', \esc_html__('Settings', 'independent-analytics'), \esc_html__('Settings', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-settings', function () {
266 $settings_page = new Settings_Page();
267 $settings_page->render(\false);
268 });
269 }
270 if (\IAWPSCOPED\iawp_is_pro()) {
271 \add_submenu_page('independent-analytics', \esc_html__('Campaign Builder', 'independent-analytics'), \esc_html__('Campaign Builder', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-campaign-builder', function () {
272 $campaign_builder_page = new Campaign_Builder_Page();
273 $campaign_builder_page->render(\false);
274 });
275 if (\IAWP\Capability_Manager::can_edit()) {
276 \add_submenu_page('independent-analytics', \esc_html__('Click Tracking', 'independent-analytics'), \esc_html__('Click Tracking', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-click-tracking', function () {
277 $click_tracking_page = new Click_Tracking_Page();
278 $click_tracking_page->render(\false);
279 });
280 }
281 }
282 if (\IAWP\Capability_Manager::show_branded_ui()) {
283 \add_submenu_page('independent-analytics', \esc_html__('Help & Support', 'independent-analytics'), \esc_html__('Help & Support', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-support-center', function () {
284 $support_page = new Support_Page();
285 $support_page->render(\false);
286 });
287 }
288 if (\IAWP\Capability_Manager::show_branded_ui()) {
289 \add_submenu_page('independent-analytics', \esc_html__('Integrations', 'independent-analytics'), \esc_html__('Integrations', 'independent-analytics'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-integrations', function () {
290 $integrations_page = new Integrations_Pages();
291 $integrations_page->render(\false);
292 });
293 }
294 if (\IAWP\Capability_Manager::show_branded_ui()) {
295 $menu_html = '<span class="menu-name">' . \esc_html__('Changelog', 'independent-analytics') . '</span>';
296 $menu_html = $this->changelog_viewed_since_update() ? $menu_html . ' <span class="menu-counter">' . \esc_html__('New', 'independent-analytics') . '</span>' : $menu_html;
297 \add_submenu_page('independent-analytics', \esc_html__('Changelog', 'independent-analytics'), $menu_html, \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-updates', function () {
298 $updates_page = new Updates_Page();
299 $updates_page->render(\false);
300 });
301 }
302 if (\IAWPSCOPED\iawp_is_free() && \IAWP\Capability_Manager::show_branded_ui()) {
303 \add_submenu_page('independent-analytics', \esc_html__('Upgrade to Pro &rarr;', 'independent-analytics'), '<span style="color: #F69D0A;">' . \esc_html__('Upgrade to Pro &rarr;', 'independent-analytics') . '</span>', \IAWP\Capability_Manager::menu_page_capability_string(), \esc_url('https://independentwp.com/pro/?utm_source=User+Dashboard&utm_medium=WP+Admin&utm_campaign=Upgrade+to+Pro&utm_content=Sidebar'));
304 }
305 if (\IAWP\Capability_Manager::can_edit()) {
306 \add_submenu_page('options.php', \__('Independent Analytics Debug'), \__('Independent Analytics Debug'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-debug', function () {
307 $debug_page = new Debug_Page();
308 $debug_page->render(\false);
309 });
310 }
311 if (\IAWPSCOPED\iawp_is_pro() && \IAWP\Capability_Manager::can_view()) {
312 \add_submenu_page('options.php', \__('Journey'), \__('Journey'), \IAWP\Capability_Manager::menu_page_capability_string(), 'independent-analytics-visitor', function () {
313 $page = new Visitor_Page();
314 $page->render();
315 });
316 }
317 }
318 // The menu link is removed in the SDK setup, but this makes it completely inaccessible
319 public function remove_freemius_pricing_menu()
320 {
321 \remove_submenu_page('independent-analytics', 'independent-analytics-pricing');
322 }
323 public function register_scripts_and_styles() : void
324 {
325 \wp_register_style('iawp-styles', \IAWPSCOPED\iawp_url_to('dist/styles/style.css'), [], \IAWP_VERSION);
326 \wp_register_style('iawp-dashboard-widget-styles', \IAWPSCOPED\iawp_url_to('dist/styles/dashboard_widget.css'), [], \IAWP_VERSION);
327 \wp_register_style('iawp-freemius-notice-styles', \IAWPSCOPED\iawp_url_to('dist/styles/freemius_notice_styles.css'), [], \IAWP_VERSION);
328 \wp_register_style('iawp-posts-menu-styles', \IAWPSCOPED\iawp_url_to('dist/styles/posts_menu.css'), [], \IAWP_VERSION);
329 \wp_register_style('iawp-wc-order-box-styles', \IAWPSCOPED\iawp_url_to('dist/styles/wc_order_box.css'), [], \IAWP_VERSION);
330 \wp_register_script('iawp-javascript', \IAWPSCOPED\iawp_url_to('dist/js/index.js'), ['wp-i18n'], \IAWP_VERSION);
331 \wp_set_script_translations('iawp-javascript', 'independent-analytics');
332 \wp_register_script('iawp-dashboard-widget-javascript', \IAWPSCOPED\iawp_url_to('dist/js/dashboard_widget.js'), ['wp-i18n'], \IAWP_VERSION);
333 \wp_set_script_translations('iawp-dashboard-widget-javascript', 'independent-analytics');
334 \wp_register_script('iawp-layout-javascript', \IAWPSCOPED\iawp_url_to('dist/js/layout.js'), ['wp-i18n'], \IAWP_VERSION);
335 \wp_set_script_translations('iawp-layout-javascript', 'independent-analytics');
336 \wp_register_script('iawp-settings-javascript', \IAWPSCOPED\iawp_url_to('dist/js/settings.js'), ['wp-color-picker', 'wp-i18n'], \IAWP_VERSION);
337 \wp_set_script_translations('iawp-settings-javascript', 'independent-analytics');
338 \wp_register_script('iawp-click-tracking-menu-javascript', \IAWPSCOPED\iawp_url_to('dist/js/click-tracking-menu.js'), ['wp-i18n'], \IAWP_VERSION);
339 \wp_set_script_translations('iawp-click-tracking-menu-javascript', 'independent-analytics');
340 if (\IAWP\Admin_Bar_Stats::is_option_enabled()) {
341 \wp_register_style('iawp-admin-bar-stats', \IAWPSCOPED\iawp_url_to('dist/styles/admin_bar_stats.css'), [], \IAWP_VERSION);
342 }
343 if (\is_rtl()) {
344 \wp_register_style('iawp-styles-rtl', \IAWPSCOPED\iawp_url_to('dist/styles/rtl.css'), [], \IAWP_VERSION);
345 }
346 }
347 public function enqueue_scripts_and_styles($hook)
348 {
349 $this->register_scripts_and_styles();
350 $page = \IAWP\Env::get_page();
351 $this->enqueue_translations();
352 $this->enqueue_nonces();
353 \wp_enqueue_style('iawp-freemius-notice-styles');
354 if (\is_string($page)) {
355 \wp_enqueue_style('iawp-styles');
356 \wp_enqueue_script('iawp-javascript');
357 \wp_enqueue_script('iawp-layout-javascript');
358 $this->dequeue_bad_actors();
359 $this->maybe_override_adminify_styles();
360 if (\is_rtl()) {
361 \wp_enqueue_style('iawp-styles-rtl');
362 }
363 }
364 if ($page === 'independent-analytics-settings') {
365 \wp_enqueue_style('wp-color-picker');
366 \wp_enqueue_script('iawp-settings-javascript');
367 } elseif ($page === 'independent-analytics-click-tracking') {
368 \wp_enqueue_script('iawp-click-tracking-menu-javascript');
369 } elseif ($hook === 'index.php') {
370 \wp_enqueue_script('iawp-dashboard-widget-javascript');
371 \wp_enqueue_style('iawp-dashboard-widget-styles');
372 } elseif ($hook === 'edit.php') {
373 \wp_enqueue_style('iawp-posts-menu-styles');
374 } elseif (\IAWPSCOPED\iawp_is_pro() && $this->is_woocommerce_support_enabled() && $hook == 'woocommerce_page_wc-orders') {
375 \wp_enqueue_style('iawp-wc-order-box-styles');
376 }
377 if (\IAWP\Admin_Bar_Stats::is_option_enabled()) {
378 \wp_enqueue_style('iawp-admin-bar-stats');
379 }
380 }
381 public function enqueue_scripts_and_styles_front_end()
382 {
383 if (\IAWP\Admin_Bar_Stats::is_option_enabled()) {
384 \wp_register_style('iawp-admin-bar-stats', \IAWPSCOPED\iawp_url_to('dist/styles/admin_bar_stats.css'), [], \IAWP_VERSION);
385 \wp_enqueue_style('iawp-admin-bar-stats');
386 }
387 }
388 public function enqueue_translations()
389 {
390 \wp_register_script('iawp-translations', '');
391 \wp_enqueue_script('iawp-translations');
392 \wp_add_inline_script('iawp-translations', 'const iawpText = ' . \json_encode(['views' => \__('Views', 'independent-analytics'), 'visitors' => \__('Visitors', 'independent-analytics'), 'sessions' => \__('Sessions', 'independent-analytics'), 'exactDates' => \__('Apply Exact Dates', 'independent-analytics'), 'relativeDates' => \__('Apply Relative Dates', 'independent-analytics'), 'copied' => \__('Copied', 'independent-analytics'), 'exportingPages' => \__('Exporting Pages...', 'independent-analytics'), 'exportPages' => \__('Export Pages', 'independent-analytics'), 'exportingReferrers' => \__('Exporting Referrers...', 'independent-analytics'), 'exportReferrers' => \__('Export Referrers', 'independent-analytics'), 'exportingGeolocations' => \__('Exporting Geolocations...', 'independent-analytics'), 'exportGeolocations' => \__('Export Geolocations', 'independent-analytics'), 'exportingDevices' => \__('Exporting Devices...', 'independent-analytics'), 'exportDevices' => \__('Export Devices', 'independent-analytics'), 'exportingCampaigns' => \__('Exporting Campaigns...', 'independent-analytics'), 'exportCampaigns' => \__('Export Campaigns', 'independent-analytics'), 'exportingClicks' => \__('Exporting Clicks', 'independent-analytics'), 'exportClicks' => \__('Export Clicks', 'independent-analytics'), 'invalidReportArchive' => \__('This report archive is invalid. Please export your reports and try again.', 'independent-analytics'), 'openMobileMenu' => \__('Open menu', 'independent-analytics'), 'closeMobileMenu' => \__('Close menu', 'independent-analytics'), 'noComparison' => \__('No Comparison', 'independent-analytics')]), 'before');
393 }
394 public function enqueue_nonces()
395 {
396 \wp_register_script('iawp-nonces', '');
397 \wp_enqueue_script('iawp-nonces');
398 \wp_add_inline_script('iawp-nonces', 'const iawpActions = ' . \json_encode(AJAX_Manager::getInstance()->get_action_signatures()), 'before');
399 }
400 public function get_option($name, $default)
401 {
402 $option = \get_option($name, $default);
403 return $option === '' ? $default : $option;
404 }
405 public function date_i18n(string $format, \DateTime $date) : string
406 {
407 return \date_i18n($format, $date->setTimezone(Timezone::site_timezone())->getTimestamp() + Timezone::site_offset_in_seconds($date));
408 }
409 public function plugin_action_links($links)
410 {
411 // Create the link
412 $settings_link = '<a class="calendar-link" href="' . \esc_url(\IAWPSCOPED\iawp_dashboard_url()) . '">' . \esc_html__('Analytics Dashboard', 'independent-analytics') . '</a>';
413 // Add the link to the start of the array
414 \array_unshift($links, $settings_link);
415 return $links;
416 }
417 public function pagination_page_size()
418 {
419 return 50;
420 }
421 public function dequeue_bad_actors()
422 {
423 // https://wordpress.org/plugins/comment-link-remove/
424 \wp_dequeue_style('qc_clr_admin_style_css');
425 // https://wordpress.org/plugins/webappick-pdf-invoice-for-woocommerce/
426 \wp_dequeue_style('woo-invoice');
427 // https://wordpress.org/plugins/wp-media-files-name-rename/
428 \wp_dequeue_style('wpcmp_bootstrap_css');
429 // https://wordpress.org/plugins/morepuzzles/
430 \wp_dequeue_style('bscss');
431 \wp_dequeue_style('mypluginstyle');
432 }
433 public function maybe_override_adminify_styles()
434 {
435 if (\is_plugin_active('adminify/adminify.php')) {
436 $settings = \get_option('_wpadminify');
437 if ($settings) {
438 if (\array_key_exists('admin_ui', $settings)) {
439 if ($settings['admin_ui']) {
440 \wp_register_style('iawp-adminify-styles', \IAWPSCOPED\iawp_url_to('dist/styles/adminify.css'), [], \IAWP_VERSION);
441 \wp_enqueue_style('iawp-adminify-styles');
442 }
443 }
444 }
445 }
446 }
447 public function maybe_add_cookie()
448 {
449 if (Request::is_blocked_user_role() && $this->get_option('iawp_ignore_via_cookie', \false)) {
450 if (!isset($_COOKIE['iawp_ignore_visitor'])) {
451 \setcookie('iawp_ignore_visitor', '1', \time() + 365 * 24 * 60 * 60, \COOKIEPATH, \COOKIE_DOMAIN);
452 }
453 }
454 }
455 public function changelog_viewed_since_update() : bool
456 {
457 if (\number_format(\floatval(\IAWP_VERSION), 1) > \floatval($this->get_option('iawp_last_update_viewed', '0'))) {
458 return \true;
459 }
460 return \false;
461 }
462 public function is_form_submission_support_enabled() : bool
463 {
464 if (!\is_bool($this->is_form_submission_support_enabled)) {
465 $this->is_form_submission_support_enabled = \IAWPSCOPED\iawp_is_pro() && Form::has_active_form_plugin() && \IAWP\Capability_Manager::can_view_all_analytics();
466 }
467 return $this->is_form_submission_support_enabled;
468 }
469 public function is_woocommerce_support_enabled() : bool
470 {
471 if (!\is_bool($this->is_woocommerce_support_enabled)) {
472 $this->is_woocommerce_support_enabled = $this->actually_check_if_woocommerce_support_is_enabled();
473 }
474 return $this->is_woocommerce_support_enabled;
475 }
476 public function is_surecart_support_enabled() : bool
477 {
478 if (!\is_bool($this->is_surecart_support_enabled)) {
479 $this->is_surecart_support_enabled = $this->actually_check_if_surecart_support_is_enabled();
480 }
481 return $this->is_surecart_support_enabled;
482 }
483 public function is_edd_support_enabled() : bool
484 {
485 if (!\is_bool($this->is_edd_support_enabled)) {
486 $this->is_edd_support_enabled = $this->actually_check_if_edd_support_is_enabled();
487 }
488 return $this->is_edd_support_enabled;
489 }
490 public function is_pmpro_support_enabled() : bool
491 {
492 if (!\is_bool($this->is_pmpro_support_enabled)) {
493 $this->is_pmpro_support_enabled = $this->actually_check_if_pmpro_support_is_enabled();
494 }
495 return $this->is_pmpro_support_enabled;
496 }
497 public function is_fluent_cart_support_enabled() : bool
498 {
499 if (!\is_bool($this->is_fluent_cart_support_enabled)) {
500 $this->is_fluent_cart_support_enabled = $this->actually_check_if_fluent_cart_support_is_enabled();
501 }
502 return $this->is_fluent_cart_support_enabled;
503 }
504 public function is_ecommerce_support_enabled() : bool
505 {
506 return $this->is_woocommerce_support_enabled() || $this->is_surecart_support_enabled() || $this->is_edd_support_enabled() || $this->is_pmpro_support_enabled() || $this->is_fluent_cart_support_enabled();
507 }
508 public function get_currency_code() : ?string
509 {
510 if ($this->is_woocommerce_support_enabled()) {
511 return get_woocommerce_currency();
512 }
513 if ($this->is_surecart_support_enabled()) {
514 return SureCart_Store::get_currency_code();
515 }
516 if ($this->is_edd_support_enabled()) {
517 return \edd_get_currency();
518 }
519 if ($this->is_pmpro_support_enabled()) {
520 global $pmpro_default_currency;
521 return $pmpro_default_currency;
522 }
523 if ($this->is_fluent_cart_support_enabled()) {
524 $settings = new \FluentCart\Api\StoreSettings();
525 return $settings->getCurrency();
526 }
527 return null;
528 }
529 // This is for compatibility with the "Lock and Protect System Folders" setting in the Security Optimizer plugin
530 public function whitelist_click_endpoint($whitelist)
531 {
532 if (\IAWPSCOPED\iawp_is_free()) {
533 return $whitelist;
534 }
535 $whitelist[] = 'iawp-click-endpoint.php';
536 return $whitelist;
537 }
538 public function exclude_tracking_script_from_speed_optimizer($exclude_list)
539 {
540 $exclude_list[] = '// Do not change this comment line otherwise Speed Optimizer won\'t be able to detect this script';
541 return $exclude_list;
542 }
543 // This whitelists our plugin with the "Complianz" plugin
544 public function whitelist_script_tag_for_complianz($scripts)
545 {
546 $scripts[] = '/wp-json/iawp/search';
547 return $scripts;
548 }
549 public function prefers_24_hour_clock() : bool
550 {
551 $time_format = \IAWPSCOPED\iawp()->get_option('time_format', 'g:i a');
552 if (Str::contains($time_format, 'a') || Str::contains($time_format, 'A')) {
553 return \false;
554 }
555 return \true;
556 }
557 private function actually_check_if_woocommerce_support_is_enabled() : bool
558 {
559 global $wpdb;
560 if (\IAWPSCOPED\iawp_is_free()) {
561 return \false;
562 }
563 if (\IAWP\Capability_Manager::can_only_view_authored_analytics()) {
564 return \false;
565 }
566 if (!\is_plugin_active('woocommerce/woocommerce.php')) {
567 return \false;
568 }
569 $table_name = $wpdb->prefix . 'wc_order_stats';
570 $order_stats_table = $wpdb->get_row($wpdb->prepare('
571 SELECT * FROM INFORMATION_SCHEMA.TABLES
572 WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s
573 ', $wpdb->dbname, $table_name));
574 if (\is_null($order_stats_table)) {
575 return \false;
576 }
577 return \true;
578 }
579 private function actually_check_if_surecart_support_is_enabled() : bool
580 {
581 if (\IAWPSCOPED\iawp_is_free()) {
582 return \false;
583 }
584 if (\IAWP\Capability_Manager::can_only_view_authored_analytics()) {
585 return \false;
586 }
587 return \is_plugin_active('surecart/surecart.php');
588 }
589 private function actually_check_if_edd_support_is_enabled() : bool
590 {
591 if (\IAWPSCOPED\iawp_is_free()) {
592 return \false;
593 }
594 if (\IAWP\Capability_Manager::can_only_view_authored_analytics()) {
595 return \false;
596 }
597 return \is_plugin_active('easy-digital-downloads/easy-digital-downloads.php') || \is_plugin_active('easy-digital-downloads-pro/easy-digital-downloads.php');
598 }
599 private function actually_check_if_pmpro_support_is_enabled() : bool
600 {
601 if (\IAWPSCOPED\iawp_is_free()) {
602 return \false;
603 }
604 if (\IAWP\Capability_Manager::can_only_view_authored_analytics()) {
605 return \false;
606 }
607 return \is_plugin_active('paid-memberships-pro-dev/paid-memberships-pro.php') || \is_plugin_active('paid-memberships-pro/paid-memberships-pro.php');
608 }
609 private function actually_check_if_fluent_cart_support_is_enabled() : bool
610 {
611 if (\IAWPSCOPED\iawp_is_free()) {
612 return \false;
613 }
614 if (\IAWP\Capability_Manager::can_only_view_authored_analytics()) {
615 return \false;
616 }
617 return \is_plugin_active('fluent-cart/fluent-cart.php');
618 }
619 private function get_menu_icon()
620 {
621 if (\is_null(\IAWP\Env::get_page())) {
622 return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iMjU0cHgiIHZpZXdCb3g9IjAgMCA1MTMgMjU0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPkljb248L3RpdGxlPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ik1lbnUtSWNvbiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyNiwgLTIyOCkiIGZpbGw9IiNBN0FBQUQiPgogICAgICAgICAgICA8ZyBpZD0iV2hpdGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDgyLCA1NSkiPgogICAgICAgICAgICAgICAgPGcgaWQ9Ikljb24iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0LjUsIDE3MykiPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQwMi44MDU3LCAxMDguNjEyNSkgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTQwMi44MDU3LCAtMTA4LjYxMjUpIiBwb2ludHM9IjM5MS4xNjkzNTYgNTYuMjQ4ODI1OSA0MTQuNDQyMDgzIDU2LjI0ODgyNTkgNDE0LjQ0MjA4MyAxNjAuOTc2MDk5IDM5MS4xNjkzNTYgMTYwLjk3NjA5OSI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1NiwgMTI1LjY3MjcpIHJvdGF0ZSgtNjApIHRyYW5zbGF0ZSgtMjU2LCAtMTI1LjY3MjcpIiBwb2ludHM9IjI0NC4zNjM2MzYgNzMuMzA5MDkwOSAyNjcuNjM2MzY0IDczLjMwOTA5MDkgMjY3LjYzNjM2NCAxNzguMDM2MzY0IDI0NC4zNjM2MzYgMTc4LjAzNjM2NCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwOS41Njk0LCAxNDQuNjg1Mikgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTEwOS41Njk0LCAtMTQ0LjY4NTIpIiBwb2ludHM9Ijk3LjkzMjk5MjMgOTIuMzIxNTUzMiAxMjEuMjA1NzIgOTIuMzIxNTUzMiAxMjEuMjA1NzIgMTk3LjA0ODgyNiA5Ny45MzI5OTIzIDE5Ny4wNDg4MjYiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC00IiBjeD0iNDY4Ljk0NTQ1NSIgY3k9IjQzLjA1NDU0NTUiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgaWQ9IlBvaW50LTMiIGN4PSIzMzYuMjkwOTA5IiBjeT0iMTczLjM4MTgxOCIgcj0iNDMuMDU0NTQ1NSI+PC9jaXJjbGU+CiAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBpZD0iUG9pbnQtMiIgY3g9IjE3NS43MDkwOTEiIGN5PSI3OS4xMjcyNzI3IiByPSI0My4wNTQ1NDU1Ij48L2NpcmNsZT4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC0xIiBjeD0iNDMuMDU0NTQ1NSIgY3k9IjIxMC42MTgxODIiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=';
623 } else {
624 return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTEzcHgiIGhlaWdodD0iMjU0cHgiIHZpZXdCb3g9IjAgMCA1MTMgMjU0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPkljb248L3RpdGxlPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ik1lbnUtSWNvbiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTc3NSwgLTIyOSkiIGZpbGw9IiNGRkZGRkYiPgogICAgICAgICAgICA8ZyBpZD0iV2hpdGUtQ29weSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzMxLCA1NikiPgogICAgICAgICAgICAgICAgPGcgaWQ9Ikljb24iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0LjUsIDE3MykiPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQwMi44MDU3LCAxMDguNjEyNSkgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTQwMi44MDU3LCAtMTA4LjYxMjUpIiBwb2ludHM9IjM5MS4xNjkzNTYgNTYuMjQ4ODI1OSA0MTQuNDQyMDgzIDU2LjI0ODgyNTkgNDE0LjQ0MjA4MyAxNjAuOTc2MDk5IDM5MS4xNjkzNTYgMTYwLjk3NjA5OSI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1NiwgMTI1LjY3MjcpIHJvdGF0ZSgtNjApIHRyYW5zbGF0ZSgtMjU2LCAtMTI1LjY3MjcpIiBwb2ludHM9IjI0NC4zNjM2MzYgNzMuMzA5MDkwOSAyNjcuNjM2MzY0IDczLjMwOTA5MDkgMjY3LjYzNjM2NCAxNzguMDM2MzY0IDI0NC4zNjM2MzYgMTc4LjAzNjM2NCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJOZWNrLTEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwOS41Njk0LCAxNDQuNjg1Mikgcm90YXRlKDQ1KSB0cmFuc2xhdGUoLTEwOS41Njk0LCAtMTQ0LjY4NTIpIiBwb2ludHM9Ijk3LjkzMjk5MjMgOTIuMzIxNTUzMiAxMjEuMjA1NzIgOTIuMzIxNTUzMiAxMjEuMjA1NzIgMTk3LjA0ODgyNiA5Ny45MzI5OTIzIDE5Ny4wNDg4MjYiPjwvcG9seWdvbj4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC00IiBjeD0iNDY4Ljk0NTQ1NSIgY3k9IjQzLjA1NDU0NTUiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgaWQ9IlBvaW50LTMiIGN4PSIzMzYuMjkwOTA5IiBjeT0iMTczLjM4MTgxOCIgcj0iNDMuMDU0NTQ1NSI+PC9jaXJjbGU+CiAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBpZD0iUG9pbnQtMiIgY3g9IjE3NS43MDkwOTEiIGN5PSI3OS4xMjcyNzI3IiByPSI0My4wNTQ1NDU1Ij48L2NpcmNsZT4KICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGlkPSJQb2ludC0xIiBjeD0iNDMuMDU0NTQ1NSIgY3k9IjIxMC42MTgxODIiIHI9IjQzLjA1NDU0NTUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=';
625 }
626 }
627 private function configure_carbon()
628 {
629 $locale = \get_locale();
630 // Carbon will throw an error if de_DE_Formal is used
631 if ('de_de_formal' === \strtolower($locale)) {
632 $locale = 'de_DE';
633 }
634 Carbon::setLocale($locale);
635 CarbonImmutable::setLocale($locale);
636 CarbonInterval::setLocale($locale);
637 }
638 }
639