PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.5
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.5
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / vendor / wpfluent / framework / src / WPFluent / Foundation / AsyncRequestTrait.php

AsyncRequestTrait.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.5, at vendor/wpfluent/framework/src/WPFluent/Foundation/AsyncRequestTrait.php

156 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\Framework\Foundation;
4
5 trait AsyncRequestTrait
6 {
7 protected $asyncActions = [];
8
9 protected $launchableActions = [];
10
11 public function addAsyncAction($action, $handler)
12 {
13 $this->asyncActions[$action] = $handler;
14 }
15
16 public function doAsyncAction($action, $data = [])
17 {
18 $this->launchableActions[$action] = $data;
19
20 }
21
22 protected function registerAsyncActions()
23 {
24 if ($this->hasAsyncActions()) {
25 $this->registerAdminPostAction(
26 $this->config->get('app.slug')
27 );
28 }
29 }
30
31 protected function hasAsyncActions()
32 {
33 return count($this->asyncActions) > 0;
34 }
35
36 protected function registerAdminPostAction($slug)
37 {
38 add_action("admin_post_wpfluent_async_$slug", [$this, 'callback']);
39 add_action("admin_post_nopriv_wpfluent_async_$slug", [$this, 'callback']);
40
41 if (!has_action('shutdown', [$this, 'launchPostRequest'])) {
42 add_action('shutdown', [$this, 'launchPostRequest']);
43 }
44 }
45
46 public function callback()
47 {
48 add_filter('wp_die_handler', function() { die(); });
49
50 try {
51 $this->verifyNonce();
52
53 foreach ($_POST['actions'] as $action => $data) {
54 try {
55 $handler = $this->parseHookHandler(
56 $this->asyncActions[$action]
57 );
58
59 $handler($data);
60 } catch (\Exception $e) {
61 continue;
62 }
63 }
64 } catch (\Exception $e) {
65 return;
66 }
67 }
68
69 public function launchPostRequest()
70 {
71 if (!$this->hasLaunchableActions()) {
72 return;
73 }
74
75 $args = [
76 'timeout' => 0.01,
77 'blocking' => false,
78 'sslverify' => apply_filters('https_local_ssl_verify', true),
79 'body' => $this->getData(),
80 'headers' => [
81 'cookie' => $this->getCookie(),
82 ],
83 ];
84
85 wp_remote_post(admin_url('admin-post.php'), $args);
86 }
87
88 protected function getData()
89 {
90 return [
91 '_nonce' => $this->createNonce(),
92 'action' => $this->getMainAction(),
93 'actions' => $this->launchableActions,
94 ];
95 }
96
97 protected function getCookie()
98 {
99 $cookies = [];
100
101 foreach ($_COOKIE as $name => $value) {
102 $cookies[] = "$name=" . urlencode(is_array($value) ? serialize($value) : $value);
103 }
104
105 return implode('; ', $cookies);
106 }
107
108 protected function hasLaunchableActions()
109 {
110 return count($this->launchableActions) > 0;
111 }
112
113 protected function createNonce()
114 {
115 $i = wp_nonce_tick();
116
117 $action = $this->getMainAction();
118
119 return wp_hash($i . $action, 'nonce');
120 }
121
122 protected function verifyNonce()
123 {
124 if (!isset($_POST['_nonce'])) {
125 throw new \Exception('Invalid Request.');
126 }
127
128 $nonce = $_POST['_nonce'];
129
130 $i = wp_nonce_tick();
131
132 $action = $this->getMainAction();
133
134 // Nonce generated 0-12 hours ago
135 if (wp_hash($i . $action, 'nonce') == $nonce) {
136 return 1;
137 }
138
139 // Nonce generated 12-24 hours ago
140 if (wp_hash(($i - 1) . $action , 'nonce') == $nonce) {
141 return 2;
142 }
143
144 // Invalid nonce
145 return false;
146 }
147
148 protected function getMainAction() {
149 $action = $this->config->get('app.slug');
150
151 $action = "wpfluent_async_$action";
152
153 return $action;
154 }
155 }
156