190], [['species', 'breed', 'location_name'], 'string', 'max' => 120], [['sex', 'status'], 'string', 'max' => 32], [['city'], 'string', 'max' => 120], [['state'], 'string', 'max' => 2], [['zip'], 'string', 'max' => 10], [['animal_uid'], 'unique'], [['status'], 'in', 'range' => array_keys(self::statusOptions())], ]; } public function beforeValidate() { if (!parent::beforeValidate()) { return false; } if ($this->isNewRecord && empty($this->animal_uid)) { $this->animal_uid = $this->generateAnimalUid(); } if (empty($this->status)) { $this->status = self::STATUS_INTAKE; } return true; } public function beforeSave($insert) { if (!parent::beforeSave($insert)) { return false; } $now = date('Y-m-d H:i:s'); if ($insert && empty($this->created_at)) { $this->created_at = $now; } $this->updated_at = $now; return true; } public static function statusOptions(): array { return [ self::STATUS_INTAKE => Yii::t('AnimalManagementModule.base', 'Intake'), self::STATUS_ACTIVE => Yii::t('AnimalManagementModule.base', 'Active'), self::STATUS_TRANSFER_PENDING => Yii::t('AnimalManagementModule.base', 'Transfer Pending'), self::STATUS_TRANSFERRED => Yii::t('AnimalManagementModule.base', 'Transferred'), self::STATUS_ADOPTED => Yii::t('AnimalManagementModule.base', 'Adopted'), ]; } public function getDisplayName(): string { $name = trim((string)$this->name); return $name !== '' ? $name : (string)$this->animal_uid; } public function getTransfers() { return $this->hasMany(AnimalTransfer::class, ['animal_id' => 'id']); } public function getMedicalVisits() { return $this->hasMany(AnimalMedicalVisit::class, ['animal_id' => 'id']); } public function getProgressUpdates() { return $this->hasMany(AnimalProgressUpdate::class, ['animal_id' => 'id']); } public function getTransferEvents() { return $this->hasMany(AnimalTransferEvent::class, ['animal_id' => 'id']); } public function getFieldValues() { return $this->hasMany(AnimalFieldValue::class, ['animal_id' => 'id']); } public function getGalleryItems() { return $this->hasMany(AnimalGalleryItem::class, ['animal_id' => 'id']); } public function getCustomFieldDisplayValues(bool $includeRestricted = false): array { $values = []; foreach ($this->getFieldValues()->with('fieldDefinition')->all() as $fieldValue) { if (!$fieldValue instanceof AnimalFieldValue) { continue; } $definition = $fieldValue->fieldDefinition; if ($definition === null || (string)$definition->module_id !== 'animal_management') { continue; } if ((int)$definition->is_active !== 1 || (int)$definition->is_core === 1) { continue; } if ((string)$definition->group_key !== 'animal_profile') { continue; } if (in_array((string)$definition->field_key, [ 'cover_image_url', 'profile_image_url', 'photo_url', 'image_url', 'profile_image', 'photo', 'tile_display_fields', 'hero_display_fields', ], true)) { continue; } $visibility = (string)$definition->visibility; if (!$includeRestricted && $visibility !== 'public') { continue; } $raw = trim((string)$fieldValue->value_text); if ($raw === '') { continue; } $display = $raw; $inputType = (string)$definition->input_type; if ($inputType === 'boolean') { $display = in_array(strtolower($raw), ['1', 'true', 'yes', 'on'], true) ? Yii::t('AnimalManagementModule.base', 'Yes') : Yii::t('AnimalManagementModule.base', 'No'); } elseif ($inputType === 'select') { $display = $this->mapSelectDisplayValue((string)$definition->options, $raw); } $values[] = [ 'field_key' => (string)$definition->field_key, 'label' => trim((string)$definition->label) !== '' ? (string)$definition->label : (string)$definition->field_key, 'value' => $display, 'visibility' => $visibility, ]; } return $values; } private function mapSelectDisplayValue(string $options, string $raw): string { $options = trim($options); if ($options === '') { return $raw; } $decoded = Json::decode($options, true); if (!is_array($decoded)) { return $raw; } if (array_values($decoded) === $decoded) { return in_array($raw, $decoded, true) ? $raw : $raw; } return isset($decoded[$raw]) ? (string)$decoded[$raw] : $raw; } private function generateAnimalUid(): string { do { $candidate = 'ANI-' . date('Ymd') . '-' . strtoupper(substr(Yii::$app->security->generateRandomString(8), 0, 6)); $exists = static::find()->where(['animal_uid' => $candidate])->exists(); } while ($exists); return $candidate; } }