PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.5
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.5
2.4.5 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 All 69 releases
← All changes | app/Models/Customer.php +58 -34 1.10.4 → 2.4.5 View file →
@@ -58,17 +58,19 @@
58 58 ];
59 59 }
60 60
61 61 /**
62 - * maybeCreateCustomer method will update existing customer or create new
63 - * This method will get request to create customer, this will check existence, if exist it will update otherwise it will create new.
64 - * @param $customerData
62 + * Find the customer for this data or create one. An existing record is only
63 + * updated when the data carries a user_id or remote_uid.
64 + *
65 + * @param array $customerData
65 66 * @return false|Customer
66 67 */
67 68 public static function maybeCreateCustomer($customerData)
68 69 {
69 70 $customer = self::getCustomerFromData($customerData);
70 - $user = get_user_by('email', $customerData['email']);
71 + $email = Arr::get($customerData, 'email');
72 + $user = $email ? get_user_by('email', $email) : false;
71 73 if ($user) {
72 74 if ($user->first_name) {
73 75 $customerData['first_name'] = $user->first_name;
74 76 }
@@ -87,33 +89,49 @@
87 89 }
88 90
89 91 $customerData = self::explodeFullName($customerData);
90 92
91 - // we have to create customer
92 93 $customer = self::create($customerData);
93 94
94 - /*
95 - * Action on customer create
96 - *
97 - * @since v1.0.0
98 - * @param object $customer
99 - */
100 - do_action('fluent_support/customer_created', $customer);
95 + if ($customer && $customer->exists) {
96 + /*
97 + * Action on customer create
98 + *
99 + * @since v1.0.0
100 + * @param object $customer
101 + */
102 + do_action('fluent_support/customer_created', $customer);
103 + }
101 104
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 - }
105 + return $customer;
108 106 }
109 107
108 + // Never link an existing row to a different WP account by email match.
109 + // Linking happens on create, on registration, or by an agent.
110 + $incomingUserId = (int) Arr::get($customerData, 'user_id');
111 +
112 + if ($incomingUserId && $incomingUserId !== (int) $customer->user_id) {
113 + unset($customerData['user_id']);
114 + }
115 +
116 + // The incoming email is unverified (WP lets users change theirs without
117 + // confirmation), so it must not overwrite a linked customer's address.
118 + // That only changes via EmailClaimService or an agent edit.
119 + if ((int) $customer->user_id) {
120 + unset($customerData['email']);
121 + }
122 +
123 + if (!empty($customerData['user_id']) || !empty($customerData['remote_uid'])) {
124 + $customerData = array_filter($customerData);
125 + $customer->fill($customerData);
126 + $customer->save();
127 + }
128 +
110 129 return $customer;
111 130 }
112 131
113 132
114 133 /**
115 - * One2Many: Customer has to many Click Tickets
116 134 * @return Model Collection
117 135 */
118 136 public function tickets()
119 137 {
@@ -126,36 +144,43 @@
126 144 );
127 145 }
128 146
129 147 /**
130 - * getCustomerFromData method will return customer information by user id or email address
131 - * @param $customerData
132 - * @return false
148 + * Look up by remote_uid, then user_id, then email.
149 + *
150 + * @param array $customerData
151 + * @return false|Customer
133 152 */
134 153 public static function getCustomerFromData($customerData)
135 154 {
136 155 $remoteUid = Arr::get($customerData, 'remote_uid');
137 - $email = $customerData['email'];
156 + $email = Arr::get($customerData, 'email');
157 + $userId = (int) Arr::get($customerData, 'user_id');
138 158
139 - $customer = false;
140 159 if ($remoteUid) {
141 160 $customer = self::where('remote_uid', $remoteUid)->first();
161 +
162 + if ($customer) {
163 + return $customer;
164 + }
142 165 }
143 166
144 - if (!$customer) {
145 - if (!empty($customerData['user_id'])) {
146 - $customer = self::where('user_id', $customerData['user_id'])->first();
147 - }
148 - if (!$customer) {
149 - $customer = self::where('email', $email)->first();
150 - }
167 + // When a user id is given, don't fall back to email: a WP account's email
168 + // is unverified (the REST users endpoint skips confirmation), so it must
169 + // not reach another person's row. Email isn't unique, so take the oldest
170 + // match to keep replies threading onto the original record.
171 + if ($userId) {
172 + return self::where('user_id', $userId)->orderBy('id', 'ASC')->first() ?: false;
151 173 }
152 174
153 - return $customer;
175 + if ($email) {
176 + return self::where('email', $email)->orderBy('id', 'ASC')->first() ?: false;
177 + }
178 +
179 + return false;
154 180 }
155 181
156 182 /**
157 - * getTicketCounts method will return the number of tickets by a customer
158 183 * @return mixed
159 184 */
160 185 public function getTicketCounts()
161 186 {
@@ -162,9 +187,8 @@
162 187 return Ticket::where('customer_id', $this->id)->count();
163 188 }
164 189
165 190 /**
166 - * getResponseCounts will return the number of responses by a customer
167 191 * @return mixed
168 192 */
169 193 public function getResponseCounts()
170 194 {