1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Escopecz\MauticFormSubmit\Mautic; |
4
|
|
|
|
5
|
|
|
use Escopecz\MauticFormSubmit\Mautic; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Mautic form |
9
|
|
|
*/ |
10
|
|
|
class Form |
11
|
|
|
{ |
12
|
|
|
/** |
13
|
|
|
* @var Mautic |
14
|
|
|
*/ |
15
|
|
|
protected $mautic; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Form ID |
19
|
|
|
* |
20
|
|
|
* @var int |
21
|
|
|
*/ |
22
|
|
|
protected $id; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Constructor |
26
|
|
|
* |
27
|
|
|
* @param Mautic $mautic |
28
|
|
|
* @param int $id |
29
|
|
|
*/ |
30
|
14 |
|
public function __construct(Mautic $mautic, $id) |
31
|
|
|
{ |
32
|
14 |
|
$this->mautic = $mautic; |
33
|
14 |
|
$this->id = $id; |
34
|
14 |
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Submit the $data array to the Mautic form |
38
|
|
|
* Returns array containing info about the request, response and cookie |
39
|
|
|
* |
40
|
|
|
* @param array $data |
41
|
|
|
* |
42
|
|
|
* @return array |
43
|
|
|
*/ |
44
|
|
|
public function submit(array $data) |
45
|
|
|
{ |
46
|
|
|
$originalCookie = $this->mautic->getCookie()->getSuperGlobalCookie(); |
47
|
|
|
$response = []; |
48
|
|
|
$request = $this->prepareRequest($data); |
49
|
|
|
|
50
|
|
|
$ch = curl_init($request['url']); |
51
|
|
|
curl_setopt($ch, CURLOPT_POST, 1); |
52
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $request['query']); |
53
|
|
|
|
54
|
|
|
if (isset($request['header'])) { |
55
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $request['header']); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
if (isset($request['referer'])) { |
59
|
|
|
curl_setopt($ch, CURLOPT_REFERER, $request['referer']); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
if (isset($request['cookie'])) { |
63
|
|
|
curl_setopt($ch, CURLOPT_COOKIEFILE, $this->mautic->getCookie()->createCookieFile()); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
67
|
|
|
curl_setopt($ch, CURLOPT_VERBOSE, 1); |
68
|
|
|
curl_setopt($ch, CURLOPT_HEADER, 1); |
69
|
|
|
list($header, $content) = explode("\r\n\r\n", curl_exec($ch), 2); |
70
|
|
|
$response['header'] = $header; |
71
|
|
|
$response['content'] = htmlentities($content); |
72
|
|
|
$response['info'] = curl_getinfo($ch); |
73
|
|
|
curl_close($ch); |
74
|
|
|
|
75
|
|
|
$contact = $this->mautic->getContact(); |
76
|
|
|
|
77
|
|
|
if ($sessionId = $this->getSessionIdFromHeader($response['header'])) { |
78
|
|
|
$contact->setSessionId($sessionId); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
if ($contactId = $this->getContactIdFromHeader($response['header'], $sessionId)) { |
82
|
|
|
$contact->setId($contactId); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
return [ |
86
|
|
|
'original_cookie' => $originalCookie, |
87
|
|
|
'new_cookie' => $this->mautic->getCookie()->toArray(), |
88
|
|
|
'request' => $request, |
89
|
|
|
'response' => $response, |
90
|
|
|
]; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Finds the session ID hash in the response header |
95
|
|
|
* |
96
|
|
|
* @param string $headers |
97
|
|
|
* |
98
|
|
|
* @return string|null |
99
|
|
|
*/ |
100
|
2 |
View Code Duplication |
public function getSessionIdFromHeader($headers) |
|
|
|
|
101
|
|
|
{ |
102
|
2 |
|
if (!$headers) { |
103
|
2 |
|
return null; |
104
|
|
|
} |
105
|
|
|
|
106
|
2 |
|
preg_match("/mautic_session_id=(.+?);/", $headers, $matches); |
107
|
|
|
|
108
|
2 |
|
if (isset($matches[1])) { |
109
|
2 |
|
return $matches[1]; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
return null; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Finds the Mautic Contact ID hash in the response header |
117
|
|
|
* |
118
|
|
|
* @param string $headers |
119
|
|
|
* @param string $sessionId |
120
|
|
|
* |
121
|
|
|
* @return int|null |
122
|
|
|
*/ |
123
|
2 |
View Code Duplication |
public function getContactIdFromHeader($headers, $sessionId) |
|
|
|
|
124
|
|
|
{ |
125
|
2 |
|
if (!$headers || !$sessionId) { |
126
|
2 |
|
return null; |
127
|
|
|
} |
128
|
|
|
|
129
|
2 |
|
preg_match("/$sessionId=(.+?);/", $headers, $matches); |
130
|
|
|
|
131
|
2 |
|
if (isset($matches[1])) { |
132
|
2 |
|
return (int) $matches[1]; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
return null; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Prepares data for CURL request based on provided form data, $_COOKIE and $_SERVER |
140
|
|
|
* |
141
|
|
|
* @param array $data |
142
|
|
|
* |
143
|
|
|
* @return array |
144
|
|
|
*/ |
145
|
2 |
|
public function prepareRequest(array $data) |
|
|
|
|
146
|
|
|
{ |
147
|
2 |
|
$contact = $this->mautic->getContact(); |
148
|
2 |
|
$request = ['header']; |
149
|
|
|
|
150
|
2 |
|
$data['formId'] = $this->id; |
151
|
|
|
|
152
|
|
|
// return has to be part of the form data array so Mautic would accept the submission |
153
|
2 |
|
if (!isset($data['return'])) { |
154
|
2 |
|
$data['return'] = ''; |
155
|
|
|
} |
156
|
|
|
|
157
|
2 |
|
$request['url'] = $this->getUrl(); |
158
|
2 |
|
$request['data'] = ['mauticform' => $data]; |
159
|
|
|
|
160
|
2 |
|
if ($contactId = $contact->getId()) { |
161
|
|
|
$request['data']['mtc_id'] = $contactId; |
162
|
|
|
} |
163
|
|
|
|
164
|
2 |
|
if ($contactIp = $contact->getIp()) { |
165
|
|
|
$request['header'][] = "X-Forwarded-For: $contactIp"; |
166
|
|
|
} |
167
|
|
|
|
168
|
2 |
|
if ($sessionId = $contact->getSessionId()) { |
169
|
|
|
$request['header'][] = "Cookie: mautic_session_id=$sessionId"; |
170
|
|
|
} |
171
|
|
|
|
172
|
2 |
|
if (isset($_SERVER['HTTP_REFERER'])) { |
173
|
|
|
$request['referer'] = $_SERVER["HTTP_REFERER"]; |
174
|
|
|
} |
175
|
|
|
|
176
|
2 |
|
$request['query'] = http_build_query($request['data']); |
177
|
|
|
|
178
|
2 |
|
return $request; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Builds the form URL |
183
|
|
|
* |
184
|
|
|
* @return string |
185
|
|
|
*/ |
186
|
4 |
|
public function getUrl() |
187
|
|
|
{ |
188
|
4 |
|
return sprintf('%s/form/submit?formId=%d', $this->mautic->getBaseUrl(), $this->id); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Returns the Form ID |
193
|
|
|
* |
194
|
|
|
* @return int |
195
|
|
|
*/ |
196
|
6 |
|
public function getId() |
197
|
|
|
{ |
198
|
6 |
|
return $this->id; |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.