← All changes
|
app/Services/Integrations/FluentCRM/CrmContactService.php
+110
-0
2.2.0
→
2.5.0
View file →
| @@ -190,8 +190,118 @@ | ||
| 190 | 190 | 'list_ids' => self::taxonomyIds($contact, 'lists'), |
| 191 | 191 | ]; |
| 192 | 192 | } |
| 193 | 193 | |
| 194 | + /** | |
| 195 | + * Create (or reuse) a tag/list definition in FluentCRM. Idempotent on | |
| 196 | + * slug, so typing an existing name returns that existing tag/list. | |
| 197 | + * | |
| 198 | + * @param string $type 'tags' | 'lists' | |
| 199 | + * @return array|null {id, title} or null when inactive / empty title. | |
| 200 | + */ | |
| 201 | + public static function createTaxonomy($type, $title) | |
| 202 | + { | |
| 203 | + if (!self::isActive()) { | |
| 204 | + return null; | |
| 205 | + } | |
| 206 | + | |
| 207 | + $title = trim((string) $title); | |
| 208 | + if ($title === '') { | |
| 209 | + return null; | |
| 210 | + } | |
| 211 | + | |
| 212 | + $model = self::taxonomyModel($type); | |
| 213 | + $slug = sanitize_title($title); | |
| 214 | + | |
| 215 | + if ($slug === '') { | |
| 216 | + return null; | |
| 217 | + } | |
| 218 | + | |
| 219 | + $item = $model::firstOrCreate(['slug' => $slug], ['title' => $title]); | |
| 220 | + | |
| 221 | + if ($item->wasRecentlyCreated) { | |
| 222 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- FluentCRM's own hook names, fired so CRM listeners see parity with native tag/list creation | |
| 223 | + do_action($type === 'tags' ? 'fluent_crm/tag_created' : 'fluent_crm/list_created', $item); | |
| 224 | + } | |
| 225 | + | |
| 226 | + return [ | |
| 227 | + 'id' => (int) $item->id, | |
| 228 | + 'title' => $item->title, | |
| 229 | + ]; | |
| 230 | + } | |
| 231 | + | |
| 232 | + /** | |
| 233 | + * The contact a note can be copied to, or null when FluentCRM is inactive, | |
| 234 | + * the email has no contact, or the current user cannot manage contacts. | |
| 235 | + * | |
| 236 | + * @param string $email | |
| 237 | + * @return array|null {contact_id, name, profile_url} | |
| 238 | + */ | |
| 239 | + public static function getNoteTarget($email) | |
| 240 | + { | |
| 241 | + if (!self::canWriteNotes()) { | |
| 242 | + return null; | |
| 243 | + } | |
| 244 | + | |
| 245 | + $contact = self::getContact($email); | |
| 246 | + | |
| 247 | + if (!$contact) { | |
| 248 | + return null; | |
| 249 | + } | |
| 250 | + | |
| 251 | + return [ | |
| 252 | + 'contact_id' => (int) $contact->id, | |
| 253 | + 'name' => trim((string) $contact->full_name) ?: (string) $contact->email, | |
| 254 | + 'profile_url' => fluentcrm_menu_url_base() . 'subscribers/' . $contact->id, | |
| 255 | + ]; | |
| 256 | + } | |
| 257 | + | |
| 258 | + /** | |
| 259 | + * Add a note to the contact's FluentCRM profile, as FluentCRM's own | |
| 260 | + * "Add note" does: same permission, same sanitizer, same hook. | |
| 261 | + * | |
| 262 | + * @param string $email | |
| 263 | + * @param string $title Plain text. | |
| 264 | + * @param string $description HTML. Passed through wp_kses_post. | |
| 265 | + * @param string $type A FluentCRM activity type (fluentcrm_activity_types()). | |
| 266 | + * @return int|\WP_Error The new note id. | |
| 267 | + */ | |
| 268 | + public static function addContactNote($email, $title, $description, $type = 'note') | |
| 269 | + { | |
| 270 | + if (!self::canWriteNotes()) { | |
| 271 | + return new \WP_Error('crm_permission', __('You do not have permission to add notes to CRM contacts.', 'fluent-booking')); | |
| 272 | + } | |
| 273 | + | |
| 274 | + $contact = self::getContact($email); | |
| 275 | + | |
| 276 | + if (!$contact) { | |
| 277 | + return new \WP_Error('crm_contact_not_found', __('No CRM contact found for this booking.', 'fluent-booking')); | |
| 278 | + } | |
| 279 | + | |
| 280 | + $data = \FluentCrm\App\Services\Sanitize::contactNote([ | |
| 281 | + 'subscriber_id' => (int) $contact->id, | |
| 282 | + 'title' => (string) $title, | |
| 283 | + 'description' => (string) $description, | |
| 284 | + 'type' => $type, | |
| 285 | + 'created_at' => current_time('mysql'), | |
| 286 | + ]); | |
| 287 | + | |
| 288 | + $data['created_by'] = get_current_user_id(); | |
| 289 | + | |
| 290 | + $note = \FluentCrm\App\Models\SubscriberNote::create($data); | |
| 291 | + | |
| 292 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- FluentCRM's own hook, fired so CRM automations see a note added from here like one added in the CRM | |
| 293 | + do_action('fluent_crm/note_added', $note, $contact, $data); | |
| 294 | + | |
| 295 | + return (int) $note->id; | |
| 296 | + } | |
| 297 | + | |
| 298 | + private static function canWriteNotes() | |
| 299 | + { | |
| 300 | + return self::isActive() | |
| 301 | + && \FluentCrm\App\Services\PermissionManager::currentUserCan('fcrm_manage_contacts'); | |
| 302 | + } | |
| 303 | + | |
| 194 | 304 | private static function getContact($email) |
| 195 | 305 | { |
| 196 | 306 | if (!self::isActive() || !$email) { |
| 197 | 307 | return null; |