1 | <?php |
||||
2 | |||||
3 | namespace SilverCommerce\ContactAdmin\Helpers; |
||||
4 | |||||
5 | use DateTime; |
||||
6 | use LogicException; |
||||
7 | use SilverStripe\Security\Member; |
||||
8 | use SilverStripe\Core\Config\Configurable; |
||||
9 | use SilverStripe\Core\Injector\Injectable; |
||||
10 | use SilverCommerce\ContactAdmin\Model\Contact; |
||||
11 | use SilverStripe\Security\Group; |
||||
12 | |||||
13 | class ContactHelper |
||||
14 | { |
||||
15 | use Injectable, Configurable; |
||||
16 | |||||
17 | /** |
||||
18 | * The field that is shared between Members and Contacts. |
||||
19 | * |
||||
20 | * Defaults to "Email" |
||||
21 | * |
||||
22 | * @var string |
||||
23 | * @config |
||||
24 | */ |
||||
25 | private static $common_field = "Email"; |
||||
26 | |||||
27 | /** |
||||
28 | * Fields that can be synced between members and contacts |
||||
29 | * |
||||
30 | * @var array |
||||
31 | */ |
||||
32 | private static $sync_fields = [ |
||||
33 | "FirstName", |
||||
34 | "Surname", |
||||
35 | "Company", |
||||
36 | "Phone", |
||||
37 | "Mobile", |
||||
38 | "Email" |
||||
39 | ]; |
||||
40 | |||||
41 | /** |
||||
42 | * Automatically sync users and contacts on save and auto create contacts for existing users |
||||
43 | * |
||||
44 | * @var boolean |
||||
45 | */ |
||||
46 | private static $auto_sync = true; |
||||
47 | |||||
48 | /** |
||||
49 | * Add codes for default groups linked user accounts are added to |
||||
50 | * |
||||
51 | * @var array |
||||
52 | */ |
||||
53 | private static $default_user_groups = [ |
||||
54 | 'contact_users' => 'Contact Users' |
||||
55 | ]; |
||||
56 | |||||
57 | /** |
||||
58 | * @var Contact |
||||
59 | */ |
||||
60 | private $contact; |
||||
61 | |||||
62 | /** |
||||
63 | * @var Member |
||||
64 | */ |
||||
65 | private $member; |
||||
66 | |||||
67 | /** |
||||
68 | * Create a member from the provided contact |
||||
69 | * |
||||
70 | * @return Member |
||||
71 | */ |
||||
72 | public function findOrMakeMember() |
||||
73 | { |
||||
74 | $contact = $this->getContact(); |
||||
75 | |||||
76 | if (empty($contact)) { |
||||
77 | throw new LogicException('Must set a Contact'); |
||||
78 | } |
||||
79 | |||||
80 | // First off see if the member from the contact is available |
||||
81 | $member = $contact->Member(); |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
82 | $link = false; |
||||
83 | |||||
84 | // If no member assigned, try to find one with matching field |
||||
85 | if (empty($member) || !$member->exists()) { |
||||
86 | $common_field = $this->config()->common_field; |
||||
87 | $member = Member::get()->find($common_field, $contact->{$common_field}); |
||||
88 | $link = true; |
||||
89 | } |
||||
90 | |||||
91 | // Finally, if still no member found, then create a new one, link to the contact |
||||
92 | // and pass the relevent data |
||||
93 | if (empty($member)) { |
||||
94 | $member = Member::create(); |
||||
95 | self::pushFields($contact, $member); |
||||
96 | $member->write(); |
||||
97 | $link = true; |
||||
98 | } |
||||
99 | |||||
100 | if ($link) { |
||||
101 | $contact->MemberID = $member->ID; |
||||
0 ignored issues
–
show
The property
MemberID does not exist on SilverCommerce\ContactAdmin\Model\Contact . Since you implemented __set , consider adding a @property annotation.
![]() |
|||||
102 | $contact->write(); |
||||
103 | } |
||||
104 | |||||
105 | return $member; |
||||
106 | } |
||||
107 | |||||
108 | /** |
||||
109 | * Find or create a Contact from the provided member |
||||
110 | * |
||||
111 | * @return Contact |
||||
112 | */ |
||||
113 | public function findOrMakeContact() |
||||
114 | { |
||||
115 | $member = $this->getMember(); |
||||
116 | |||||
117 | if (empty($member)) { |
||||
118 | throw new LogicException('Must set a Member'); |
||||
119 | } |
||||
120 | |||||
121 | // First off see if the contact is available as relation |
||||
122 | $contact = $member->Contact(); |
||||
123 | $link = false; |
||||
124 | |||||
125 | // If no member assigned, try to find one with matching field |
||||
126 | if (empty($contact) || !$contact->exists()) { |
||||
127 | $common_field = $this->config()->common_field; |
||||
128 | $contact = Contact::get()->find($common_field, $member->{$common_field}); |
||||
129 | $link = true; |
||||
130 | } |
||||
131 | |||||
132 | // Finally, if still no member found, then create a new one, link to the contact |
||||
133 | // and pass the relevent data |
||||
134 | if (empty($contact)) { |
||||
135 | $contact = Contact::create(); |
||||
136 | self::pushFields($member, $contact); |
||||
137 | $link = true; |
||||
138 | } |
||||
139 | |||||
140 | if ($link) { |
||||
141 | $contact->MemberID = $member->ID; |
||||
142 | $contact->write(); |
||||
143 | } |
||||
144 | |||||
145 | return $contact; |
||||
146 | } |
||||
147 | |||||
148 | /** |
||||
149 | * Update an associated member with the data from this contact |
||||
150 | * |
||||
151 | * @todo Currently sync is pretty basic (pushes data from one object to another). This could be more intilligent. |
||||
152 | * |
||||
153 | * @param bool $write Write the syncronised record |
||||
154 | * |
||||
155 | * @return void |
||||
156 | */ |
||||
157 | public function syncContactAndMember(bool $write = true) |
||||
0 ignored issues
–
show
The parameter
$write is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
158 | { |
||||
159 | $member = $this->getMember(); |
||||
160 | $contact = $this->getContact(); |
||||
161 | $changes = []; |
||||
162 | |||||
163 | if (empty($member) || empty($contact)) { |
||||
164 | throw new LogicException('Must set a Member AND a Contact'); |
||||
165 | } |
||||
166 | |||||
167 | // Find out which object just changed and sync in the correct direction |
||||
168 | $member_changed = $member->getChangedFields(); |
||||
169 | $contact_changed = $contact->getChangedFields(); |
||||
170 | |||||
171 | if (count($contact_changed) > 0) { |
||||
172 | $changes = self::pushChangedFields($contact, $member); |
||||
173 | $obj_to_write = $contact; |
||||
174 | } elseif (count($member_changed) > 0) { |
||||
175 | $changes = self::pushChangedFields($member, $contact); |
||||
176 | $obj_to_write = $member; |
||||
177 | } |
||||
178 | |||||
179 | if (count($changes) > 0) { |
||||
180 | $obj_to_write->write(); |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
181 | } |
||||
182 | |||||
183 | return $this; |
||||
184 | } |
||||
185 | |||||
186 | /** |
||||
187 | * Push any fields relevent fields changed on the origin obvject, to the destination, |
||||
188 | * if the destination is different. |
||||
189 | * |
||||
190 | * @var DataObject $origin |
||||
191 | * @var DataObject $destination |
||||
192 | * |
||||
193 | * @return array |
||||
194 | */ |
||||
195 | public static function pushChangedFields($origin, $destination) |
||||
196 | { |
||||
197 | $sync = self::config()->sync_fields; |
||||
198 | $changes = []; |
||||
199 | |||||
200 | foreach ($origin->getChangedFields() as $field => $change) { |
||||
201 | if (in_array($field, $sync) && !empty($origin->$field) && $origin->$field != $destination->$field) { |
||||
202 | $destination->$field = $origin->$field; |
||||
203 | $changes[$field] = $origin->$field; |
||||
204 | } |
||||
205 | } |
||||
206 | |||||
207 | return $changes; |
||||
208 | } |
||||
209 | |||||
210 | /** |
||||
211 | * Push the field values from the origin object and the destination object |
||||
212 | * (if values do not match) |
||||
213 | * |
||||
214 | * Return a list of fields pushed |
||||
215 | * |
||||
216 | * @var DataObject $origin |
||||
217 | * @var DataObject $destination |
||||
218 | * |
||||
219 | * @return array |
||||
220 | */ |
||||
221 | public static function pushFields($origin, $destination) |
||||
222 | { |
||||
223 | $sync = self::config()->sync_fields; |
||||
224 | $changes = []; |
||||
225 | |||||
226 | foreach ($sync as $field) { |
||||
227 | if ($origin->$field != $destination->$field) { |
||||
228 | $destination->$field = $origin->$field; |
||||
229 | $changes[$field] = $origin->$field; |
||||
230 | } |
||||
231 | } |
||||
232 | |||||
233 | return $changes; |
||||
234 | } |
||||
235 | |||||
236 | /** |
||||
237 | * Link the set member to all the groups specified via config |
||||
238 | * |
||||
239 | * Return the number of groups added |
||||
240 | * |
||||
241 | * @return int |
||||
242 | */ |
||||
243 | public function linkMemberToGroups() |
||||
244 | { |
||||
245 | $member = $this->getMember(); |
||||
246 | $groups = $this->config()->get('default_user_groups'); |
||||
247 | $count = 0; |
||||
248 | |||||
249 | if (empty($member)) { |
||||
250 | throw new LogicException('Must set a Member'); |
||||
251 | } |
||||
252 | |||||
253 | if (empty($groups)) { |
||||
254 | return $count; |
||||
255 | } |
||||
256 | |||||
257 | foreach (array_keys($groups) as $code) { |
||||
258 | $group = Group::get()->filter('Code', $code)->first(); |
||||
259 | |||||
260 | if (!empty($group)) { |
||||
261 | $member->Groups()->add($group); |
||||
262 | $count++; |
||||
263 | } |
||||
264 | } |
||||
265 | |||||
266 | return $count; |
||||
267 | } |
||||
268 | |||||
269 | /** |
||||
270 | * Get the value of contact. If not assigned directly, try to get from the member |
||||
271 | * |
||||
272 | * @return Contact |
||||
273 | */ |
||||
274 | public function getContact() |
||||
275 | { |
||||
276 | $contact = $this->contact; |
||||
277 | |||||
278 | if (empty($contact) && !empty($this->getMember())) { |
||||
279 | $contact = $this->getMember()->Contact(); |
||||
280 | } |
||||
281 | |||||
282 | return $contact; |
||||
283 | } |
||||
284 | |||||
285 | /** |
||||
286 | * Set the value of contact |
||||
287 | * |
||||
288 | * @param Contact $contact |
||||
289 | * |
||||
290 | * @return self |
||||
291 | */ |
||||
292 | public function setContact(Contact $contact) |
||||
293 | { |
||||
294 | $this->contact = $contact; |
||||
295 | return $this; |
||||
296 | } |
||||
297 | |||||
298 | /** |
||||
299 | * Get the value of member. If not assigned directly, try to get from Contact |
||||
300 | * |
||||
301 | * @return Member |
||||
302 | */ |
||||
303 | public function getMember() |
||||
304 | { |
||||
305 | $member = $this->member; |
||||
306 | |||||
307 | if (empty($member) && !empty($this->getContact())) { |
||||
308 | $member = $this->getContact()->Member(); |
||||
309 | } |
||||
310 | |||||
311 | return $member; |
||||
312 | } |
||||
313 | |||||
314 | /** |
||||
315 | * Set the value of member |
||||
316 | * |
||||
317 | * @param Member $member |
||||
318 | * |
||||
319 | * @return self |
||||
320 | */ |
||||
321 | public function setMember(Member $member) |
||||
322 | { |
||||
323 | $this->member = $member; |
||||
324 | return $this; |
||||
325 | } |
||||
326 | } |
||||
327 |