PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.1.2
Fluent Support – Helpdesk & Customer Support Ticket System v2.1.2
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
← All changes | app/Models/Customer.php +17 -64 trunk2.1.2 View file →
@@ -66,10 +66,9 @@
66 66 */
67 67 public static function maybeCreateCustomer($customerData)
68 68 {
69 69 $customer = self::getCustomerFromData($customerData);
70 - $email = Arr::get($customerData, 'email');
71 - $user = $email ? get_user_by('email', $email) : false;
70 + $user = get_user_by('email', $customerData['email']);
72 71 if ($user) {
73 72 if ($user->first_name) {
74 73 $customerData['first_name'] = $user->first_name;
75 74 }
@@ -99,49 +98,16 @@
99 98 * @param object $customer
100 99 */
101 100 do_action('fluent_support/customer_created', $customer);
102 101
103 - return $customer;
102 + } else {
103 + if (!empty($customerData['user_id']) || !empty($customerData['remote_uid'])) {
104 + $customerData = array_filter($customerData);
105 + $customer->fill($customerData);
106 + $customer->save();
107 + }
104 108 }
105 109
106 - // An existing row may never be claimed for a WordPress account it is not
107 - // already linked to. Binding happens when the row is first created, when
108 - // the account registers (ProfileInfoService::onWPUserRegister), or when
109 - // an agent sets it explicitly from the customer profile. Allowing an
110 - // email match to write user_id here is what made a portal takeover
111 - // persistent.
112 - $incomingUserId = (int) Arr::get($customerData, 'user_id');
113 -
114 - if ($incomingUserId && $incomingUserId !== (int) $customer->user_id) {
115 - unset($customerData['user_id']);
116 - }
117 -
118 - // Intake may not move the contact address of a record that belongs to a
119 - // WordPress account. Every caller here builds its payload from an
120 - // address it has not verified -- most of them from the signed-in
121 - // account's own email, which WordPress lets that account change with no
122 - // confirmation at all.
123 - //
124 - // Without this, ProfileInfoService::onWPProfileUpdate holding the
125 - // address is worth nothing: it refuses the unverified change, and then
126 - // the next POST to /customer-portal/tickets resolves the same record
127 - // through here and writes the new address anyway. It also produced
128 - // duplicate rows on an address belonging to somebody else, without the
129 - // collision check the profile_update path applies.
130 - //
131 - // The address moves through the two paths that prove something instead:
132 - // EmailClaimService, where the customer opens a link sent to the address
133 - // being claimed, and an agent editing the record directly.
134 - if ((int) $customer->user_id) {
135 - unset($customerData['email']);
136 - }
137 -
138 - if (!empty($customerData['user_id']) || !empty($customerData['remote_uid'])) {
139 - $customerData = array_filter($customerData);
140 - $customer->fill($customerData);
141 - $customer->save();
142 - }
143 -
144 110 return $customer;
145 111 }
146 112
147 113
@@ -167,38 +133,25 @@
167 133 */
168 134 public static function getCustomerFromData($customerData)
169 135 {
170 136 $remoteUid = Arr::get($customerData, 'remote_uid');
171 - $email = Arr::get($customerData, 'email');
172 - $userId = (int) Arr::get($customerData, 'user_id');
137 + $email = $customerData['email'];
173 138
139 + $customer = false;
174 140 if ($remoteUid) {
175 141 $customer = self::where('remote_uid', $remoteUid)->first();
142 + }
176 143
177 - if ($customer) {
178 - return $customer;
144 + if (!$customer) {
145 + if (!empty($customerData['user_id'])) {
146 + $customer = self::where('user_id', $customerData['user_id'])->first();
179 147 }
148 + if (!$customer) {
149 + $customer = self::where('email', $email)->first();
150 + }
180 151 }
181 152
182 - // A WordPress user id is the only identity that can be trusted here. An
183 - // account email is editable by its own holder with no verification: the
184 - // REST users endpoint calls wp_update_user() directly and skips the
185 - // confirmation flow that profile.php runs. An email must therefore never
186 - // be able to reach a customer row that belongs to somebody else.
187 - // Both lookups order by id so the row that wins is always the oldest
188 - // match rather than whatever the storage engine returns first. The email
189 - // column carries a plain index, not a unique one, so duplicates are
190 - // possible and an inbound reply must keep threading onto the original
191 - // record. Helper::getCurrentPerson() orders for the same reason.
192 - if ($userId) {
193 - return self::where('user_id', $userId)->orderBy('id', 'ASC')->first() ?: false;
194 - }
195 -
196 - if ($email) {
197 - return self::where('email', $email)->orderBy('id', 'ASC')->first() ?: false;
198 - }
199 -
200 - return false;
153 + return $customer;
201 154 }
202 155
203 156 /**
204 157 * getTicketCounts method will return the number of tickets by a customer