true, 'errors' => []]; } // Skip parent validation for arrays - we'll validate in process() return ['valid' => true, 'errors' => []]; } // Single value - check if empty or invalid if (empty($phone) || trim((string)$phone) === '' || $phone === '0') { return ['valid' => true, 'errors' => []]; } return parent::validate($mapped); } public function resolve(array $mapped, array $context = []): mixed { $nu = $mapped['nu'] ?? null; $personId = $mapped['person_id'] ?? ($context['person']['entity']->id ?? null) ?? ($context['person']?->entity?->id ?? null); if (! $nu || ! $personId) { return null; } // Normalize phone number for comparison $normalizedNu = $this->normalizePhoneNumber($nu); // Find existing phone by normalized number for this person return PersonPhone::where('person_id', $personId) ->where('nu', $normalizedNu) ->first(); } public function process(Import $import, array $mapped, array $raw, array $context = []): array { // Handle multiple phones if nu is an array $phones = $mapped['nu'] ?? null; // If single value, convert to array for uniform processing if (!is_array($phones)) { $phones = [$phones]; } $results = []; $insertedCount = 0; $skippedCount = 0; foreach ($phones as $phone) { // Skip if phone number is empty or blank or '0' if (empty($phone) || trim((string)$phone) === '' || $phone === '0') { $skippedCount++; continue; } // Resolve person_id from context $personId = $mapped['person_id'] ?? $context['person']['entity']?->id ?? null; if (! $personId) { $skippedCount++; continue; } // Normalize phone number $normalizedPhone = $this->normalizePhoneNumber($phone); $existing = $this->resolvePhone($normalizedPhone, $personId); // Check for duplicates if configured if ($this->getOption('deduplicate', true) && $existing) { $skippedCount++; continue; } // Create new phone $payload = [ 'nu' => $normalizedPhone, 'person_id' => $personId, 'type_id' => 1, // Default to mobile ]; $phoneEntity = new PersonPhone; $phoneEntity->fill($payload); $phoneEntity->save(); $results[] = $phoneEntity; $insertedCount++; } if ($insertedCount === 0 && $skippedCount > 0) { return [ 'action' => 'skipped', 'message' => 'All phones empty, invalid or duplicates', ]; } return [ 'action' => 'inserted', 'entity' => $results[0] ?? null, 'entities' => $results, 'applied_fields' => ['nu', 'person_id'], 'count' => $insertedCount, ]; } protected function resolvePhone(string $normalizedPhone, int $personId): mixed { return PersonPhone::where('person_id', $personId) ->where('nu', $normalizedPhone) ->first(); } /** * Normalize phone number by removing spaces, dashes, and parentheses. */ protected function normalizePhoneNumber(string $phone): string { return preg_replace('/[\s\-\(\)]/', '', $phone); } }