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 / AJAX / AJAX.php
independent-analytics / IAWP / AJAX Last commit date
AJAX.php 3 months ago AJAX_Manager.php 5 days ago Archive_Link.php 3 months ago Clear_Favorite_Report.php 5 days ago Click_Tracking_Cache_Cleared.php 3 months ago Configure_Pruner.php 3 months ago Copy_Report.php 3 months ago Create_Campaign.php 2 years ago Create_Report.php 3 months ago Delete_Campaign.php 2 years ago Delete_Data.php 3 months ago Delete_Link.php 3 months ago Delete_Module.php 3 months ago Delete_Report.php 3 months ago Dismiss_Notice.php 1 year ago Edit_Link.php 3 months ago Edit_Module.php 3 months ago Export_Report_Statistics.php 2 months ago Export_Report_Table.php 9 months ago Export_Reports.php 5 days ago FetchRealTimeData.php 5 days ago Filter.php 2 months ago Get_Journey_Timeline.php 6 months ago Get_Markup_For_Module.php 1 year ago Get_Markup_For_Modules.php 3 months ago Import_Reports.php 3 months ago Migration_Status.php 3 months ago Pause_Email_Reports.php 3 months ago Preview_Email.php 2 months ago Refresh_Modules.php 3 months ago Rename_Report.php 3 months ago Reorder_Modules.php 3 months ago Reset_Analytics.php 3 months ago Reset_Overview.php 3 months ago SaveRealTimePreferences.php 5 days ago Save_Module.php 3 months ago Save_Report.php 3 months ago Set_Favorite_Report.php 1 year ago Set_WooCommerce_Statuses_To_Track.php 3 months ago Sort_Links.php 3 months ago Sort_Reports.php 3 months ago Test_Email.php 2 months ago Update_Capabilities.php 3 months ago Update_User_Settings.php 3 months ago
AJAX.php
169 lines
1 <?php
2
3 namespace IAWP\AJAX;
4
5 use IAWP\Capability_Manager;
6 use IAWP\Migrations;
7 use IAWP\Utils\Security;
8 use IAWP\Utils\Server;
9 /** @internal */
10 abstract class AJAX
11 {
12 public function __construct()
13 {
14 if (\IAWPSCOPED\iawp_is_pro() || !$this->requires_pro()) {
15 \add_action('wp_ajax_' . $this->action_name(), [$this, 'intercept_ajax']);
16 }
17 }
18 /**
19 * Classes must define an action name for the ajax request
20 *
21 * The required nonce for the ajax request will be the action name with a "_nonce" postfix
22 * Example: "iawp_delete_data" require a "iawp_delete_data_nonce" nonce field
23 *
24 * @return string
25 */
26 protected abstract function action_name() : string;
27 /**
28 * Classes must define an action callback to run when an ajax request is made
29 *
30 * @return void
31 */
32 protected abstract function action_callback() : void;
33 /**
34 * This is the direct handler for ajax requests.
35 * Permissions and nonce values are checked before executing the ajax action_callback function.
36 *
37 * @return void
38 */
39 public function intercept_ajax() : void
40 {
41 \check_ajax_referer($this->action_name(), 'nonce');
42 $is_not_migrating = $this->allowed_during_migrations() || !Migrations\Migrations::is_migrating();
43 $valid_fields = !$this->missing_fields();
44 $has_permission = $this->requires_write_access() ? Capability_Manager::can_edit() : Capability_Manager::can_view();
45 if ($is_not_migrating && $valid_fields && $has_permission) {
46 Server::increase_max_execution_time();
47 $this->action_callback();
48 } else {
49 \wp_send_json_error(['errorMessage' => 'Unable to process IAWP AJAX request'], 400);
50 }
51 \wp_die();
52 }
53 public function get_action_signature() : array
54 {
55 $shorthand_name = $this->action_name();
56 if (\strpos($this->action_name(), "iawp_") === 0) {
57 $shorthand_name = \substr($this->action_name(), 5);
58 }
59 return [$shorthand_name => ['action' => $this->action_name(), 'nonce' => \wp_create_nonce($this->action_name())]];
60 }
61 /**
62 * Classes can define a set of required fields for an ajax request
63 *
64 * @return array
65 */
66 protected function action_required_fields() : array
67 {
68 return [];
69 }
70 /**
71 * Override method to allow the AJAX request to run during migrations
72 *
73 * @return bool false by default
74 */
75 protected function allowed_during_migrations() : bool
76 {
77 return \false;
78 }
79 protected function requires_pro() : bool
80 {
81 return \false;
82 }
83 protected function requires_write_access() : bool
84 {
85 return \false;
86 }
87 /**
88 * Get a field value. This method supports text and arrays. Returns array if no field found.
89 *
90 * @param $field
91 *
92 * @return array|string|null
93 */
94 protected function get_field($field)
95 {
96 if (!\array_key_exists($field, $_POST)) {
97 return null;
98 }
99 $type = \gettype($_POST[$field]);
100 if ($type == 'array') {
101 if ($this->array_is_list($_POST[$field])) {
102 return \rest_sanitize_array($_POST[$field]);
103 } else {
104 return \rest_sanitize_object($_POST[$field]);
105 }
106 } else {
107 return \stripslashes(\sanitize_text_field($_POST[$field]));
108 }
109 }
110 protected function get_int_field($field) : ?int
111 {
112 if (!\array_key_exists($field, $_POST)) {
113 return null;
114 }
115 $type = \gettype($_POST[$field]);
116 if ($type === 'int') {
117 return $_POST[$field];
118 } elseif ($type === 'string') {
119 return \ctype_digit($_POST[$field]) ? (int) $_POST[$field] : null;
120 } else {
121 return null;
122 }
123 }
124 protected function get_boolean_field($field) : ?bool
125 {
126 if (!\array_key_exists($field, $_POST)) {
127 return null;
128 }
129 $type = \gettype($_POST[$field]);
130 if ($type === 'string') {
131 return $_POST[$field] === 'true';
132 } else {
133 return null;
134 }
135 }
136 protected function get_array_field($field) : ?array
137 {
138 if (!\array_key_exists($field, $_POST)) {
139 return null;
140 }
141 $value = $_POST[$field];
142 if (!\is_array($value)) {
143 return null;
144 }
145 return Security::array($value);
146 }
147 // This is the recommended polyfill: https://wiki.php.net/rfc/is_list
148 private function array_is_list(array $array) : bool
149 {
150 $expectedKey = 0;
151 foreach ($array as $i => $_) {
152 if ($i !== $expectedKey) {
153 return \false;
154 }
155 $expectedKey++;
156 }
157 return \true;
158 }
159 private function missing_fields() : bool
160 {
161 foreach ($this->action_required_fields() as $required_field) {
162 if (!\array_key_exists($required_field, $_POST)) {
163 return \true;
164 }
165 }
166 return \false;
167 }
168 }
169