silvercommerce /
contact-admin
| 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
Loading history...
|
|||||
| 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.
Loading history...
|
|||||
| 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. Loading history...
|
|||||
| 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 |