Initial import of animal_management module
This commit is contained in:
306
widgets/SearchAnimalProfilesBlock.php
Normal file
306
widgets/SearchAnimalProfilesBlock.php
Normal file
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\animal_management\widgets;
|
||||
|
||||
use humhub\modules\animal_management\models\Animal;
|
||||
use humhub\modules\animal_management\models\AnimalFieldValue;
|
||||
use humhub\modules\animal_management\models\AnimalGalleryItem;
|
||||
use humhub\modules\animal_management\models\AnimalMedicalVisit;
|
||||
use humhub\modules\animal_management\models\forms\DisplaySettingsForm;
|
||||
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||
use humhub\modules\rescue_foundation\models\RescueFieldDefinition;
|
||||
use Yii;
|
||||
use yii\base\Widget;
|
||||
|
||||
class SearchAnimalProfilesBlock extends Widget
|
||||
{
|
||||
public ContentContainerActiveRecord $contentContainer;
|
||||
public int $limit = 10;
|
||||
|
||||
public function run()
|
||||
{
|
||||
if (!$this->contentContainer->moduleManager->isEnabled('animal_management')) {
|
||||
return '<div class="well well-sm" style="margin-bottom:0;">'
|
||||
. Yii::t('AnimalManagementModule.base', 'Animal profiles are not enabled for this rescue.')
|
||||
. '</div>';
|
||||
}
|
||||
|
||||
$queryValue = trim((string)Yii::$app->request->get('q', ''));
|
||||
$showAll = ((int)Yii::$app->request->get('animalFeedAll', 0)) === 1;
|
||||
$countParam = (int)Yii::$app->request->get('animalFeedCount', $this->limit);
|
||||
if ($countParam < $this->limit) {
|
||||
$countParam = $this->limit;
|
||||
}
|
||||
if ($countParam > 200) {
|
||||
$countParam = 200;
|
||||
}
|
||||
|
||||
$query = Animal::find()->where(['contentcontainer_id' => $this->contentContainer->contentcontainer_id]);
|
||||
|
||||
if ($queryValue !== '') {
|
||||
$query->andWhere([
|
||||
'or',
|
||||
['like', 'animal_uid', $queryValue],
|
||||
['like', 'name', $queryValue],
|
||||
['like', 'species', $queryValue],
|
||||
]);
|
||||
}
|
||||
|
||||
$totalCount = (int)$query->count();
|
||||
$displayCount = $showAll ? $totalCount : min($countParam, $totalCount);
|
||||
|
||||
$settings = Yii::$app->getModule('animal_management')->settings->contentContainer($this->contentContainer);
|
||||
$heading = trim((string)$settings->get('searchBlockHeading', DisplaySettingsForm::DEFAULT_SEARCH_BLOCK_HEADING));
|
||||
if ($heading === '') {
|
||||
$heading = DisplaySettingsForm::DEFAULT_SEARCH_BLOCK_HEADING;
|
||||
}
|
||||
|
||||
$tileFieldsRaw = $settings->get('tileFields', json_encode(DisplaySettingsForm::DEFAULT_TILE_FIELDS));
|
||||
$tileFields = $this->normalizeDisplayFields($tileFieldsRaw, DisplaySettingsForm::DEFAULT_TILE_FIELDS);
|
||||
|
||||
$animals = $query
|
||||
->orderBy(['updated_at' => SORT_DESC, 'id' => SORT_DESC])
|
||||
->limit($displayCount)
|
||||
->all();
|
||||
|
||||
$animalIds = array_map(static function (Animal $animal): int {
|
||||
return (int)$animal->id;
|
||||
}, $animals);
|
||||
|
||||
$latestMedicalVisitByAnimal = $this->resolveLatestMedicalVisits($animalIds);
|
||||
$animalImageUrls = $this->resolveAnimalImageUrls($animalIds, ['profile_image_url', 'profile_image', 'photo_url', 'image_url', 'photo'], false);
|
||||
$tileFieldOverrides = $this->resolveDisplayFieldOverrides($animalIds, 'tile_display_fields');
|
||||
|
||||
$hasMore = !$showAll && $displayCount < $totalCount;
|
||||
$nextCount = min($displayCount + $this->limit, $totalCount);
|
||||
|
||||
$viewFile = $this->getViewPath() . '/searchAnimalProfilesBlock.php';
|
||||
if (!is_file($viewFile)) {
|
||||
return '<div class="well well-sm" style="margin-bottom:0;">'
|
||||
. Yii::t('AnimalManagementModule.base', 'Animal search is temporarily unavailable.')
|
||||
. '</div>';
|
||||
}
|
||||
|
||||
return $this->render('searchAnimalProfilesBlock', [
|
||||
'animals' => $animals,
|
||||
'contentContainer' => $this->contentContainer,
|
||||
'queryValue' => $queryValue,
|
||||
'heading' => $heading,
|
||||
'tileFields' => $tileFields,
|
||||
'tileFieldOverrides' => $tileFieldOverrides,
|
||||
'latestMedicalVisitByAnimal' => $latestMedicalVisitByAnimal,
|
||||
'animalImageUrls' => $animalImageUrls,
|
||||
'totalCount' => $totalCount,
|
||||
'displayCount' => $displayCount,
|
||||
'hasMore' => $hasMore,
|
||||
'nextCount' => $nextCount,
|
||||
'showAll' => $showAll,
|
||||
]);
|
||||
}
|
||||
|
||||
private function normalizeDisplayFields($raw, array $default): array
|
||||
{
|
||||
if (is_string($raw)) {
|
||||
$decoded = json_decode($raw, true);
|
||||
if (!is_array($decoded)) {
|
||||
return $default;
|
||||
}
|
||||
$raw = $decoded;
|
||||
}
|
||||
|
||||
if (!is_array($raw)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$allowed = array_keys(DisplaySettingsForm::fieldOptions());
|
||||
$normalized = [];
|
||||
foreach ($raw as $field) {
|
||||
$field = trim((string)$field);
|
||||
if ($field === '' || !in_array($field, $allowed, true)) {
|
||||
continue;
|
||||
}
|
||||
if (!in_array($field, $normalized, true)) {
|
||||
$normalized[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return !empty($normalized) ? $normalized : $default;
|
||||
}
|
||||
|
||||
private function resolveLatestMedicalVisits(array $animalIds): array
|
||||
{
|
||||
$animalIds = array_values(array_unique(array_map('intval', $animalIds)));
|
||||
if (empty($animalIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$visits = AnimalMedicalVisit::find()
|
||||
->where(['animal_id' => $animalIds])
|
||||
->orderBy(['animal_id' => SORT_ASC, 'visit_at' => SORT_DESC, 'id' => SORT_DESC])
|
||||
->all();
|
||||
|
||||
$result = [];
|
||||
foreach ($visits as $visit) {
|
||||
$animalId = (int)$visit->animal_id;
|
||||
if (!isset($result[$animalId])) {
|
||||
$result[$animalId] = $visit;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function resolveAnimalImageUrls(array $animalIds, array $imageFieldOrder = [], bool $allowGalleryFallback = false): array
|
||||
{
|
||||
$animalIds = array_values(array_unique(array_map('intval', $animalIds)));
|
||||
if (empty($animalIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!class_exists(RescueFieldDefinition::class)
|
||||
|| Yii::$app->db->schema->getTableSchema('rescue_field_definition', true) === null
|
||||
|| Yii::$app->db->schema->getTableSchema('rescue_animal_field_value', true) === null
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (empty($imageFieldOrder)) {
|
||||
$imageFieldOrder = ['cover_image_url', 'profile_image_url', 'photo_url', 'image_url', 'profile_image', 'photo'];
|
||||
}
|
||||
|
||||
$definitions = RescueFieldDefinition::find()
|
||||
->select(['id', 'field_key'])
|
||||
->where([
|
||||
'module_id' => 'animal_management',
|
||||
'group_key' => 'animal_profile',
|
||||
'field_key' => $imageFieldOrder,
|
||||
'is_active' => 1,
|
||||
])
|
||||
->all();
|
||||
|
||||
if (empty($definitions)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$definitionPriority = [];
|
||||
foreach ($definitions as $definition) {
|
||||
$priority = array_search((string)$definition->field_key, $imageFieldOrder, true);
|
||||
$definitionPriority[(int)$definition->id] = $priority === false ? 999 : (int)$priority;
|
||||
}
|
||||
|
||||
if (empty($definitionPriority)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$valueRows = AnimalFieldValue::find()
|
||||
->where(['animal_id' => $animalIds, 'field_definition_id' => array_keys($definitionPriority)])
|
||||
->all();
|
||||
|
||||
$imageUrls = [];
|
||||
$chosenPriorityByAnimal = [];
|
||||
foreach ($valueRows as $valueRow) {
|
||||
$animalId = (int)$valueRow->animal_id;
|
||||
$valueText = trim((string)$valueRow->value_text);
|
||||
if ($valueText === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$priority = $definitionPriority[(int)$valueRow->field_definition_id] ?? 999;
|
||||
if (!isset($chosenPriorityByAnimal[$animalId]) || $priority < $chosenPriorityByAnimal[$animalId]) {
|
||||
$chosenPriorityByAnimal[$animalId] = $priority;
|
||||
$imageUrls[$animalId] = $valueText;
|
||||
}
|
||||
}
|
||||
|
||||
$missingAnimalIds = [];
|
||||
foreach ($animalIds as $animalId) {
|
||||
if (!isset($imageUrls[$animalId])) {
|
||||
$missingAnimalIds[] = (int)$animalId;
|
||||
}
|
||||
}
|
||||
|
||||
if ($allowGalleryFallback && !empty($missingAnimalIds) && Yii::$app->db->schema->getTableSchema('rescue_animal_gallery_item', true) !== null) {
|
||||
$galleryItems = AnimalGalleryItem::find()
|
||||
->where(['animal_id' => $missingAnimalIds])
|
||||
->orderBy(['animal_id' => SORT_ASC, 'id' => SORT_DESC])
|
||||
->all();
|
||||
|
||||
foreach ($galleryItems as $galleryItem) {
|
||||
$animalId = (int)$galleryItem->animal_id;
|
||||
if (isset($imageUrls[$animalId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = trim((string)$galleryItem->getImageUrl());
|
||||
if ($url === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$imageUrls[$animalId] = $url;
|
||||
}
|
||||
}
|
||||
|
||||
return $imageUrls;
|
||||
}
|
||||
|
||||
private function resolveDisplayFieldOverrides(array $animalIds, string $fieldKey): array
|
||||
{
|
||||
$animalIds = array_values(array_unique(array_map('intval', $animalIds)));
|
||||
if (empty($animalIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!class_exists(RescueFieldDefinition::class)
|
||||
|| Yii::$app->db->schema->getTableSchema('rescue_field_definition', true) === null
|
||||
|| Yii::$app->db->schema->getTableSchema('rescue_animal_field_value', true) === null
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$definition = RescueFieldDefinition::findOne([
|
||||
'module_id' => 'animal_management',
|
||||
'group_key' => 'animal_profile',
|
||||
'field_key' => $fieldKey,
|
||||
]);
|
||||
|
||||
if (!$definition instanceof RescueFieldDefinition) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = AnimalFieldValue::find()
|
||||
->where(['animal_id' => $animalIds, 'field_definition_id' => (int)$definition->id])
|
||||
->all();
|
||||
|
||||
$allowed = array_keys(DisplaySettingsForm::fieldOptions());
|
||||
$result = [];
|
||||
foreach ($rows as $row) {
|
||||
$raw = trim((string)$row->value_text);
|
||||
if ($raw === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$decoded = json_decode($raw, true);
|
||||
if (!is_array($decoded)) {
|
||||
$decoded = array_map('trim', explode(',', $raw));
|
||||
}
|
||||
|
||||
$normalized = [];
|
||||
foreach ($decoded as $field) {
|
||||
$field = trim((string)$field);
|
||||
if ($field === '' || !in_array($field, $allowed, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!in_array($field, $normalized, true)) {
|
||||
$normalized[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($normalized)) {
|
||||
$result[(int)$row->animal_id] = $normalized;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
26
widgets/stream/AnimalStreamEntryWallEntry.php
Normal file
26
widgets/stream/AnimalStreamEntryWallEntry.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace humhub\modules\animal_management\widgets\stream;
|
||||
|
||||
use humhub\modules\animal_management\models\AnimalStreamEntry;
|
||||
use humhub\modules\content\widgets\stream\WallStreamModuleEntryWidget;
|
||||
|
||||
class AnimalStreamEntryWallEntry extends WallStreamModuleEntryWidget
|
||||
{
|
||||
/**
|
||||
* @var AnimalStreamEntry
|
||||
*/
|
||||
public $model;
|
||||
|
||||
public function renderContent()
|
||||
{
|
||||
return $this->render('wall-entry', [
|
||||
'entry' => $this->model,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getTitle()
|
||||
{
|
||||
return $this->model->getContentDescription();
|
||||
}
|
||||
}
|
||||
228
widgets/stream/views/wall-entry.php
Normal file
228
widgets/stream/views/wall-entry.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
use humhub\modules\animal_management\helpers\DateDisplayHelper;
|
||||
use humhub\modules\animal_management\models\Animal;
|
||||
use humhub\modules\animal_management\models\AnimalMedicalVisit;
|
||||
use humhub\modules\animal_management\models\AnimalProgressUpdate;
|
||||
use humhub\modules\animal_management\models\AnimalStreamEntry;
|
||||
use yii\helpers\Html;
|
||||
|
||||
/* @var AnimalStreamEntry $entry */
|
||||
|
||||
$animal = $entry->animal;
|
||||
if (!$animal instanceof Animal) {
|
||||
return;
|
||||
}
|
||||
|
||||
$medicalVisit = $entry->medicalVisit;
|
||||
$progressUpdate = $entry->progressUpdate;
|
||||
$isMedical = (string)$entry->entry_type === AnimalStreamEntry::TYPE_MEDICAL && $medicalVisit instanceof AnimalMedicalVisit;
|
||||
$isProgress = (string)$entry->entry_type === AnimalStreamEntry::TYPE_PROGRESS && $progressUpdate instanceof AnimalProgressUpdate;
|
||||
|
||||
if (!$isMedical && !$isProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
$animalName = $animal->getDisplayName();
|
||||
|
||||
$mediaReference = '';
|
||||
$chipRows = [];
|
||||
$dateText = '';
|
||||
$detailRows = [];
|
||||
|
||||
if ($isProgress) {
|
||||
$customValues = $progressUpdate->getCustomFieldDisplayValues(true);
|
||||
$additionalFields = [];
|
||||
foreach ($customValues as $customField) {
|
||||
if ((string)($customField['field_key'] ?? '') === 'media_reference') {
|
||||
$mediaReference = trim((string)$customField['value']);
|
||||
continue;
|
||||
}
|
||||
|
||||
$additionalFields[] = [
|
||||
'label' => (string)$customField['label'],
|
||||
'value' => (string)$customField['value'],
|
||||
];
|
||||
}
|
||||
|
||||
$dateText = DateDisplayHelper::format((string)$progressUpdate->update_at);
|
||||
if (trim((string)$progressUpdate->weight) !== '') {
|
||||
$chipRows[] = Yii::t('AnimalManagementModule.base', 'Weight') . ': ' . trim((string)$progressUpdate->weight);
|
||||
}
|
||||
if (trim((string)$progressUpdate->vitals) !== '') {
|
||||
$chipRows[] = Yii::t('AnimalManagementModule.base', 'Vitals');
|
||||
}
|
||||
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Animal'), 'value' => $animalName];
|
||||
if (!empty($progressUpdate->vitals)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Vitals'), 'value' => (string)$progressUpdate->vitals];
|
||||
}
|
||||
if (!empty($progressUpdate->behavior_notes)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Behavior'), 'value' => (string)$progressUpdate->behavior_notes];
|
||||
}
|
||||
if (!empty($progressUpdate->meal_plan_changes)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Meal Plan'), 'value' => (string)$progressUpdate->meal_plan_changes];
|
||||
}
|
||||
if (!empty($progressUpdate->housing_changes)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Housing'), 'value' => (string)$progressUpdate->housing_changes];
|
||||
}
|
||||
if (!empty($progressUpdate->medical_concerns)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Medical Concerns'), 'value' => (string)$progressUpdate->medical_concerns];
|
||||
}
|
||||
if (!empty($additionalFields)) {
|
||||
$text = '';
|
||||
foreach ($additionalFields as $field) {
|
||||
$text .= $field['label'] . ': ' . $field['value'] . "\n";
|
||||
}
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Additional Fields'), 'value' => trim($text)];
|
||||
}
|
||||
} elseif ($isMedical) {
|
||||
$hiddenMedicalKeys = [
|
||||
'second_physician_name',
|
||||
'second_physician_business_name',
|
||||
'second_physician_street_address',
|
||||
'second_physician_city',
|
||||
'second_physician_state',
|
||||
'second_physician_zip',
|
||||
'second_physician_cell_phone',
|
||||
'second_physician_business_phone',
|
||||
'second_physician_license_number',
|
||||
'previous_physicians',
|
||||
];
|
||||
|
||||
$knownMedicalKeys = [
|
||||
'weight',
|
||||
'pulse',
|
||||
'blood_pressure',
|
||||
'oxygen',
|
||||
'chronic_conditions',
|
||||
'acute_conditions',
|
||||
'special_needs',
|
||||
'date_of_most_recent_medical_visit',
|
||||
'physician_name',
|
||||
'physician_business_name',
|
||||
'physician_street_address',
|
||||
'physician_city',
|
||||
'physician_state',
|
||||
'physician_zip',
|
||||
'physician_cell_phone',
|
||||
'physician_business_phone',
|
||||
'physician_license_number',
|
||||
'medical_media_reference',
|
||||
'media_reference',
|
||||
];
|
||||
|
||||
$vitalLabelOverrides = [
|
||||
'blood_pressure' => 'BP',
|
||||
'oxygen' => 'O₂',
|
||||
];
|
||||
|
||||
$fieldsByKey = [];
|
||||
$additionalFields = [];
|
||||
foreach ($medicalVisit->getCustomFieldDisplayValues(true) as $customField) {
|
||||
$fieldKey = (string)($customField['field_key'] ?? '');
|
||||
if (in_array($fieldKey, $hiddenMedicalKeys, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldValue = trim((string)($customField['value'] ?? ''));
|
||||
if ($fieldValue === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($fieldKey === 'medical_media_reference' || $fieldKey === 'media_reference') {
|
||||
$mediaReference = $fieldValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($fieldKey, $knownMedicalKeys, true)) {
|
||||
$fieldsByKey[$fieldKey] = [
|
||||
'label' => (string)($vitalLabelOverrides[$fieldKey] ?? ($customField['label'] ?? $fieldKey)),
|
||||
'value' => $fieldValue,
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
$additionalFields[] = [
|
||||
'label' => (string)($customField['label'] ?? $fieldKey),
|
||||
'value' => $fieldValue,
|
||||
];
|
||||
}
|
||||
|
||||
$dateText = DateDisplayHelper::format((string)$medicalVisit->visit_at);
|
||||
foreach (['weight', 'pulse', 'blood_pressure', 'oxygen'] as $vitalKey) {
|
||||
if (!empty($fieldsByKey[$vitalKey]['value'])) {
|
||||
$chipRows[] = $fieldsByKey[$vitalKey]['label'] . ': ' . $fieldsByKey[$vitalKey]['value'];
|
||||
}
|
||||
}
|
||||
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Animal'), 'value' => $animalName];
|
||||
if (!empty($medicalVisit->provider_name)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Provider'), 'value' => (string)$medicalVisit->provider_name];
|
||||
}
|
||||
if (!empty($medicalVisit->notes)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Clinical Notes'), 'value' => (string)$medicalVisit->notes];
|
||||
}
|
||||
if (!empty($medicalVisit->recommendations)) {
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Recommendations'), 'value' => (string)$medicalVisit->recommendations];
|
||||
}
|
||||
|
||||
foreach (['chronic_conditions', 'acute_conditions', 'special_needs'] as $conditionKey) {
|
||||
if (empty($fieldsByKey[$conditionKey]['value'])) {
|
||||
continue;
|
||||
}
|
||||
$detailRows[] = [
|
||||
'label' => (string)$fieldsByKey[$conditionKey]['label'],
|
||||
'value' => (string)$fieldsByKey[$conditionKey]['value'],
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($fieldsByKey['date_of_most_recent_medical_visit']['value'])) {
|
||||
$detailRows[] = [
|
||||
'label' => (string)$fieldsByKey['date_of_most_recent_medical_visit']['label'],
|
||||
'value' => DateDisplayHelper::format((string)$fieldsByKey['date_of_most_recent_medical_visit']['value']),
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($additionalFields)) {
|
||||
$text = '';
|
||||
foreach ($additionalFields as $field) {
|
||||
$text .= $field['label'] . ': ' . $field['value'] . "\n";
|
||||
}
|
||||
$detailRows[] = ['label' => Yii::t('AnimalManagementModule.base', 'Additional Fields'), 'value' => trim($text)];
|
||||
}
|
||||
}
|
||||
|
||||
$hasMediaImage = $mediaReference !== '' && (preg_match('/^https?:\/\//i', $mediaReference) || substr($mediaReference, 0, 1) === '/');
|
||||
?>
|
||||
|
||||
<div style="position:relative;overflow:hidden;border:1px solid #d5dfe8;border-radius:12px;background:#223446;margin:6px 0;min-height:240px;box-shadow:0 8px 22px rgba(12,24,36,0.16);">
|
||||
<?php if ($hasMediaImage): ?>
|
||||
<img src="<?= Html::encode($mediaReference) ?>" alt="<?= Yii::t('AnimalManagementModule.base', 'Animal stream media') ?>" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;">
|
||||
<?php endif; ?>
|
||||
<div style="position:absolute;inset:0;background:linear-gradient(110deg,rgba(10,18,28,0.28) 10%,rgba(10,18,28,0.55) 52%,rgba(10,18,28,0.75) 100%);"></div>
|
||||
<div style="position:relative;z-index:1;min-height:240px;padding:14px;display:flex;flex-direction:column;align-items:flex-end;gap:10px;">
|
||||
<div style="width:100%;display:flex;align-items:center;justify-content:space-between;gap:8px;">
|
||||
<span style="font-size:15px;font-weight:700;color:#ffffff;margin-right:auto;"><?= Html::encode($dateText) ?></span>
|
||||
<?php if (!empty($chipRows)): ?>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:0;justify-content:flex-end;">
|
||||
<?php foreach ($chipRows as $chip): ?>
|
||||
<span style="display:inline-block;border-radius:999px;border:1px solid rgba(255,255,255,0.3);background:rgba(255,255,255,0.16);color:#ffffff;font-size:12px;padding:4px 10px;"><?= Html::encode($chip) ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div style="width:55%;max-width:55%;min-width:0;margin-left:auto;border-radius:10px;border:1px solid rgba(255,255,255,0.22);background:rgba(10,18,28,0.5);backdrop-filter:blur(2px);padding:12px;color:#ecf2f8;">
|
||||
<div style="color:#ffffff;font-size:13px;font-weight:700;margin-bottom:8px;">
|
||||
<?= Html::encode($isMedical
|
||||
? Yii::t('AnimalManagementModule.base', 'Medical Visit')
|
||||
: Yii::t('AnimalManagementModule.base', 'Progress Update')) ?>
|
||||
</div>
|
||||
<?php foreach ($detailRows as $row): ?>
|
||||
<div style="font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:rgba(231,241,249,0.78);margin-bottom:4px;"><?= Html::encode((string)$row['label']) ?></div>
|
||||
<div style="color:#eff5fb;margin-bottom:10px;"><?= nl2br(Html::encode((string)$row['value'])) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
95
widgets/views/searchAnimalProfilesBlock.php
Normal file
95
widgets/views/searchAnimalProfilesBlock.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
use humhub\modules\animal_management\models\Animal;
|
||||
use humhub\modules\animal_management\models\AnimalMedicalVisit;
|
||||
use humhub\modules\content\components\ContentContainerActiveRecord;
|
||||
use yii\helpers\Html;
|
||||
|
||||
/* @var Animal[] $animals */
|
||||
/* @var ContentContainerActiveRecord $contentContainer */
|
||||
/* @var string $queryValue */
|
||||
/* @var string $heading */
|
||||
/* @var array $tileFields */
|
||||
/* @var array<int, array> $tileFieldOverrides */
|
||||
/* @var array<int, AnimalMedicalVisit> $latestMedicalVisitByAnimal */
|
||||
/* @var array<int, string> $animalImageUrls */
|
||||
/* @var int $totalCount */
|
||||
/* @var int $displayCount */
|
||||
/* @var bool $hasMore */
|
||||
/* @var int $nextCount */
|
||||
/* @var bool $showAll */
|
||||
|
||||
$moduleEnabled = $contentContainer->moduleManager->isEnabled('animal_management');
|
||||
$currentParams = Yii::$app->request->getQueryParams();
|
||||
$buildProfileUrl = static function (array $overrides) use ($contentContainer, $currentParams): string {
|
||||
$params = array_merge($currentParams, $overrides);
|
||||
return $contentContainer->createUrl('/space_profiles/profile/view', $params);
|
||||
};
|
||||
?>
|
||||
|
||||
<h4 style="margin-top:0;"><?= Html::encode($heading) ?></h4>
|
||||
|
||||
<?php if ($moduleEnabled): ?>
|
||||
<form method="get" action="<?= Html::encode($contentContainer->createUrl('/space_profiles/profile/view')) ?>" style="margin-bottom:12px;">
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
name="q"
|
||||
value="<?= Html::encode($queryValue) ?>"
|
||||
placeholder="<?= Html::encode(Yii::t('AnimalManagementModule.base', 'Search by name, species, or ID')) ?>"
|
||||
>
|
||||
<input type="hidden" name="animalFeedCount" value="10">
|
||||
<input type="hidden" name="animalFeedAll" value="0">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="submit"><?= Yii::t('AnimalManagementModule.base', 'Search') ?></button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<div class="well well-sm" style="margin-bottom:12px;">
|
||||
<?= Yii::t('AnimalManagementModule.base', 'Animal profiles are not enabled for this rescue.') ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($animals)): ?>
|
||||
<div class="text-muted" style="margin-bottom:10px;">
|
||||
<?= Yii::t('AnimalManagementModule.base', 'No matching animal profiles found.') ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="row" style="margin-bottom:6px;">
|
||||
<?php foreach ($animals as $animal): ?>
|
||||
<?php $animalId = (int)$animal->id; ?>
|
||||
<div class="col-xs-12" style="margin-bottom:12px;">
|
||||
<?= $this->renderFile(Yii::getAlias('@app/modules/animal_management/views/animals/_tile.php'), [
|
||||
'animal' => $animal,
|
||||
'contentContainer' => $contentContainer,
|
||||
'lastMedical' => $latestMedicalVisitByAnimal[$animalId] ?? null,
|
||||
'imageUrl' => $animalImageUrls[$animalId] ?? '',
|
||||
'tileFields' => $tileFieldOverrides[$animalId] ?? $tileFields,
|
||||
'showMedicalIcon' => true,
|
||||
]) ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($moduleEnabled): ?>
|
||||
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
|
||||
<?php if ($hasMore): ?>
|
||||
<a class="btn btn-default btn-sm" href="<?= Html::encode($buildProfileUrl(['animalFeedCount' => $nextCount, 'animalFeedAll' => 0])) ?>">
|
||||
<?= Yii::t('AnimalManagementModule.base', 'Show More') ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if (!$showAll && $totalCount > 0): ?>
|
||||
<a class="btn btn-default btn-sm" href="<?= Html::encode($buildProfileUrl(['animalFeedAll' => 1])) ?>">
|
||||
<?= Yii::t('AnimalManagementModule.base', 'Show All') ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if ($totalCount > 0): ?>
|
||||
<span class="text-muted" style="font-size:12px;">
|
||||
<?= Yii::t('AnimalManagementModule.base', '{shown} of {total} shown', ['shown' => $displayCount, 'total' => $totalCount]) ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
Reference in New Issue
Block a user