chore: sync module from working instance and add install guide
This commit is contained in:
@@ -42,6 +42,8 @@ class AnimalsController extends ContentContainerController
|
||||
'add-medical-visit' => ['post'],
|
||||
'add-progress-update' => ['post'],
|
||||
'add-gallery-images' => ['post'],
|
||||
'add-gallery-images-inline' => ['get', 'post'],
|
||||
'transfer-inline' => ['get', 'post'],
|
||||
'remove-gallery-image' => ['post'],
|
||||
'transfer-respond' => ['post'],
|
||||
'transfer-complete' => ['post'],
|
||||
@@ -55,7 +57,7 @@ class AnimalsController extends ContentContainerController
|
||||
protected function getAccessRules()
|
||||
{
|
||||
return [
|
||||
[ContentContainerControllerAccess::RULE_USER_GROUP_ONLY => [Space::USERGROUP_OWNER, Space::USERGROUP_ADMIN, Space::USERGROUP_MODERATOR], 'actions' => ['create', 'edit', 'delete', 'transfer', 'add-medical-visit', 'add-medical-visit-inline', 'edit-medical-visit', 'add-progress-update', 'add-progress-update-inline', 'edit-progress-update', 'add-gallery-images', 'remove-gallery-image', 'transfer-respond', 'transfer-complete', 'transfer-cancel']],
|
||||
[ContentContainerControllerAccess::RULE_USER_GROUP_ONLY => [Space::USERGROUP_OWNER, Space::USERGROUP_ADMIN, Space::USERGROUP_MODERATOR], 'actions' => ['create', 'edit', 'delete', 'transfer', 'transfer-inline', 'add-medical-visit', 'add-medical-visit-inline', 'edit-medical-visit', 'add-progress-update', 'add-progress-update-inline', 'edit-progress-update', 'add-gallery-images', 'add-gallery-images-inline', 'remove-gallery-image', 'transfer-respond', 'transfer-complete', 'transfer-cancel']],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -68,9 +70,13 @@ class AnimalsController extends ContentContainerController
|
||||
GalleryIntegrationService::syncSpaceAnimalGalleries($this->contentContainer);
|
||||
}
|
||||
$viewMode = trim((string)Yii::$app->request->get('view', 'tiles'));
|
||||
if (!in_array($viewMode, ['tiles', 'table'], true)) {
|
||||
if (!in_array($viewMode, ['tiles', 'tiles2', 'rows', 'tablet', 'table'], true)) {
|
||||
$viewMode = 'tiles';
|
||||
}
|
||||
$isFocusModeRequest = trim((string)Yii::$app->request->get('focus', '')) === '1';
|
||||
if ($isFocusModeRequest) {
|
||||
$viewMode = 'tablet';
|
||||
}
|
||||
|
||||
$sortKey = trim((string)Yii::$app->request->get('sort', 'updated_at'));
|
||||
$sortDirection = strtolower(trim((string)Yii::$app->request->get('direction', 'desc'))) === 'asc' ? 'asc' : 'desc';
|
||||
@@ -165,6 +171,33 @@ class AnimalsController extends ContentContainerController
|
||||
return (int)$animal->id;
|
||||
}, $animals);
|
||||
|
||||
$animalDonationGoalsByAnimal = [];
|
||||
$donationGoalClass = 'humhub\\modules\\donations\\models\\DonationGoal';
|
||||
if (!empty($animalIds)
|
||||
&& $this->contentContainer instanceof Space
|
||||
&& $this->contentContainer->moduleManager->isEnabled('donations')
|
||||
&& class_exists($donationGoalClass)
|
||||
&& Yii::$app->db->schema->getTableSchema($donationGoalClass::tableName(), true) !== null
|
||||
) {
|
||||
$donationGoals = $donationGoalClass::find()
|
||||
->where([
|
||||
'contentcontainer_id' => $this->contentContainer->contentcontainer_id,
|
||||
'goal_type' => $donationGoalClass::TYPE_ANIMAL,
|
||||
])
|
||||
->andWhere(['target_animal_id' => $animalIds])
|
||||
->orderBy(['is_active' => SORT_DESC, 'id' => SORT_DESC])
|
||||
->all();
|
||||
|
||||
foreach ($donationGoals as $goal) {
|
||||
$animalId = (int)$goal->target_animal_id;
|
||||
if ($animalId <= 0 || isset($animalDonationGoalsByAnimal[$animalId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$animalDonationGoalsByAnimal[$animalId] = $goal;
|
||||
}
|
||||
}
|
||||
|
||||
$animalImageUrls = $this->resolveAnimalImageUrls($animalIds, ['profile_image_url', 'profile_image', 'photo_url', 'image_url', 'photo'], false);
|
||||
$tileFieldOverrides = $this->resolveDisplayFieldOverrides($animalIds, 'tile_display_fields');
|
||||
|
||||
@@ -245,6 +278,7 @@ class AnimalsController extends ContentContainerController
|
||||
'animalImageUrls' => $animalImageUrls,
|
||||
'tileFields' => $this->getTileFieldSettings(),
|
||||
'tileFieldOverrides' => $tileFieldOverrides,
|
||||
'animalDonationGoalsByAnimal' => $animalDonationGoalsByAnimal,
|
||||
'space' => $this->contentContainer,
|
||||
'canManage' => $this->canManageAnimals(),
|
||||
'incomingTransfers' => $incomingTransfers,
|
||||
@@ -257,6 +291,10 @@ class AnimalsController extends ContentContainerController
|
||||
{
|
||||
$animal = $this->findAnimal($id);
|
||||
$canManage = $this->canManageAnimals();
|
||||
$layoutMode = trim((string)Yii::$app->request->get('layout', 'default'));
|
||||
if (!in_array($layoutMode, ['default', 'tablet'], true)) {
|
||||
$layoutMode = 'default';
|
||||
}
|
||||
|
||||
if ($this->contentContainer instanceof Space) {
|
||||
GalleryIntegrationService::ensureAnimalGallery($animal, $this->contentContainer);
|
||||
@@ -279,8 +317,10 @@ class AnimalsController extends ContentContainerController
|
||||
$transferEvents = $animal->getTransferEvents()->orderBy(['id' => SORT_DESC])->limit(100)->all();
|
||||
$galleryItems = $animal->getGalleryItems()->orderBy(['id' => SORT_DESC])->limit(120)->all();
|
||||
$customFieldValues = $animal->getCustomFieldDisplayValues($canManage);
|
||||
$animalImageUrls = $this->resolveAnimalImageUrls([(int)$animal->id], ['cover_image_url', 'image_url', 'photo_url', 'photo'], false);
|
||||
$animalCoverImageUrl = trim((string)($animalImageUrls[(int)$animal->id] ?? ''));
|
||||
$animalCoverImageUrls = $this->resolveAnimalImageUrls([(int)$animal->id], ['cover_image_url', 'image_url', 'photo_url', 'photo'], false);
|
||||
$animalProfileImageUrls = $this->resolveAnimalImageUrls([(int)$animal->id], ['profile_image_url', 'profile_image', 'image_url', 'photo_url', 'photo'], false);
|
||||
$animalCoverImageUrl = trim((string)($animalCoverImageUrls[(int)$animal->id] ?? ''));
|
||||
$animalProfileImageUrl = trim((string)($animalProfileImageUrls[(int)$animal->id] ?? ''));
|
||||
$detailHeroFields = $this->getDetailHeroFieldSettings();
|
||||
$heroOverrides = $this->resolveDisplayFieldOverrides([(int)$animal->id], 'hero_display_fields');
|
||||
if (!empty($heroOverrides[(int)$animal->id])) {
|
||||
@@ -298,7 +338,9 @@ class AnimalsController extends ContentContainerController
|
||||
'galleryItems' => $galleryItems,
|
||||
'customFieldValues' => $customFieldValues,
|
||||
'animalCoverImageUrl' => $animalCoverImageUrl,
|
||||
'animalProfileImageUrl' => $animalProfileImageUrl,
|
||||
'detailHeroFields' => $detailHeroFields,
|
||||
'layoutMode' => $layoutMode,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -352,6 +394,7 @@ class AnimalsController extends ContentContainerController
|
||||
public function actionCreate()
|
||||
{
|
||||
$model = new AnimalForm(['contentContainer' => $this->contentContainer]);
|
||||
$intakeGoalPayload = (array)Yii::$app->request->post('IntakeGoal', []);
|
||||
|
||||
if (Yii::$app->request->isPost) {
|
||||
$model->load(Yii::$app->request->post());
|
||||
@@ -368,6 +411,11 @@ class AnimalsController extends ContentContainerController
|
||||
if ($this->contentContainer instanceof Space) {
|
||||
GalleryIntegrationService::ensureAnimalGallery($savedAnimal, $this->contentContainer);
|
||||
}
|
||||
|
||||
$goalError = $this->createIntakeAnimalGoal($savedAnimal, $intakeGoalPayload);
|
||||
if ($goalError !== null) {
|
||||
$this->view->error($goalError);
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', 'Animal created.'));
|
||||
@@ -379,6 +427,7 @@ class AnimalsController extends ContentContainerController
|
||||
'space' => $this->contentContainer,
|
||||
'isEdit' => false,
|
||||
'animal' => null,
|
||||
'showIntakeGoalSection' => $this->canUseIntakeGoalSection(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -460,6 +509,7 @@ class AnimalsController extends ContentContainerController
|
||||
public function actionTransfer(int $id)
|
||||
{
|
||||
$animal = $this->findAnimal($id);
|
||||
$returnTo = (string)Yii::$app->request->post('returnTo', Yii::$app->request->get('returnTo', 'view'));
|
||||
|
||||
$form = new TransferRequestForm([
|
||||
'animal' => $animal,
|
||||
@@ -468,107 +518,74 @@ class AnimalsController extends ContentContainerController
|
||||
|
||||
if ($form->load(Yii::$app->request->post()) && $form->save()) {
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', 'Transfer request sent.'));
|
||||
return $this->redirect($this->contentContainer->createUrl('/animal_management/animals/view', ['id' => $animal->id]));
|
||||
return $this->redirectToAnimalPage((int)$animal->id, $returnTo);
|
||||
}
|
||||
|
||||
return $this->render('transfer', [
|
||||
'space' => $this->contentContainer,
|
||||
'animal' => $animal,
|
||||
'model' => $form,
|
||||
'isInline' => false,
|
||||
'returnTo' => $returnTo,
|
||||
]);
|
||||
}
|
||||
|
||||
public function actionTransferInline(int $id)
|
||||
{
|
||||
$animal = $this->findAnimal($id);
|
||||
$returnTo = (string)Yii::$app->request->post('returnTo', Yii::$app->request->get('returnTo', 'view'));
|
||||
$isInline = (int)Yii::$app->request->get('inline', 1) === 1;
|
||||
|
||||
$form = new TransferRequestForm([
|
||||
'animal' => $animal,
|
||||
'sourceSpace' => $this->contentContainer,
|
||||
]);
|
||||
|
||||
if ($form->load(Yii::$app->request->post()) && $form->save()) {
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', 'Transfer request sent.'));
|
||||
if ($isInline) {
|
||||
return $this->renderAjax('inline-edit-result', [
|
||||
'collapseId' => 'transfer-add-inline',
|
||||
'refreshSelectors' => ['#animal-transfer-panel'],
|
||||
]);
|
||||
}
|
||||
return $this->redirectToAnimalPage((int)$animal->id, $returnTo);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'space' => $this->contentContainer,
|
||||
'animal' => $animal,
|
||||
'model' => $form,
|
||||
'isInline' => $isInline,
|
||||
'returnTo' => $returnTo,
|
||||
];
|
||||
|
||||
if ($isInline) {
|
||||
return $this->renderAjax('transfer', $params);
|
||||
}
|
||||
|
||||
return $this->render('transfer', $params);
|
||||
}
|
||||
|
||||
public function actionAddGalleryImages(int $id)
|
||||
{
|
||||
$animal = $this->findAnimal($id);
|
||||
$uploadedFiles = UploadedFile::getInstancesByName('galleryImages');
|
||||
$maxUploadCount = 10;
|
||||
$result = $this->processGalleryUploads($animal);
|
||||
|
||||
if (empty($uploadedFiles)) {
|
||||
if (!$result['hadSelection']) {
|
||||
$this->view->error(Yii::t('AnimalManagementModule.base', 'No gallery images were selected.'));
|
||||
return $this->redirect($this->contentContainer->createUrl('/animal_management/animals/view', ['id' => $animal->id]) . '#animal-gallery');
|
||||
}
|
||||
|
||||
if (count($uploadedFiles) > $maxUploadCount) {
|
||||
$uploadedFiles = array_slice($uploadedFiles, 0, $maxUploadCount);
|
||||
$this->view->info(Yii::t('AnimalManagementModule.base', 'Only the first {count} selected images were processed.', ['count' => $maxUploadCount]));
|
||||
if ($result['wasLimited']) {
|
||||
$this->view->info(Yii::t('AnimalManagementModule.base', 'Only the first {count} selected images were processed.', ['count' => $result['maxUploadCount']]));
|
||||
}
|
||||
|
||||
$allowedExtensions = array_map('strtolower', UploadStandards::imageExtensions());
|
||||
$allowedMimeTypes = array_map('strtolower', UploadStandards::imageMimeTypes());
|
||||
$maxBytes = (int)UploadStandards::IMAGE_MAX_BYTES;
|
||||
$existingItems = AnimalGalleryItem::find()->where(['animal_id' => (int)$animal->id])->all();
|
||||
$existingHashes = [];
|
||||
foreach ($existingItems as $existingItem) {
|
||||
$existingUrl = trim((string)$existingItem->getImageUrl());
|
||||
if ($existingUrl === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hash = $this->computeImageContentHash($existingUrl);
|
||||
if ($hash !== null) {
|
||||
$existingHashes[$hash] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$added = 0;
|
||||
foreach ($uploadedFiles as $uploadedFile) {
|
||||
if (!$uploadedFile instanceof UploadedFile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extension = strtolower((string)$uploadedFile->extension);
|
||||
$mimeType = strtolower((string)$uploadedFile->type);
|
||||
|
||||
if (!in_array($extension, $allowedExtensions, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($mimeType !== '' && !in_array($mimeType, $allowedMimeTypes, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($uploadedFile->size > $maxBytes) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$storedPath = $this->storeGalleryUpload($animal, $uploadedFile);
|
||||
if ($storedPath === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$storedHash = $this->computeImageContentHash($storedPath);
|
||||
|
||||
$exactExists = AnimalGalleryItem::find()
|
||||
->where(['animal_id' => (int)$animal->id, 'file_path' => $storedPath])
|
||||
->exists();
|
||||
|
||||
if ($exactExists || ($storedHash !== null && isset($existingHashes[$storedHash]))) {
|
||||
$absolute = Yii::getAlias('@webroot') . $storedPath;
|
||||
if (is_file($absolute)) {
|
||||
@unlink($absolute);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = new AnimalGalleryItem();
|
||||
$item->animal_id = (int)$animal->id;
|
||||
$item->file_path = $storedPath;
|
||||
$item->source_type = 'upload';
|
||||
$item->created_by = Yii::$app->user->isGuest ? null : (int)Yii::$app->user->id;
|
||||
if ($item->save()) {
|
||||
$added++;
|
||||
if ($storedHash !== null) {
|
||||
$existingHashes[$storedHash] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($added > 0) {
|
||||
if ($result['added'] > 0) {
|
||||
if ($this->contentContainer instanceof Space) {
|
||||
GalleryIntegrationService::ensureAnimalGallery($animal, $this->contentContainer);
|
||||
}
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', '{count} image(s) added to gallery.', ['count' => $added]));
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', '{count} image(s) added to gallery.', ['count' => $result['added']]));
|
||||
} else {
|
||||
$this->view->error(Yii::t('AnimalManagementModule.base', 'No gallery images were added. Check image type/size requirements.'));
|
||||
}
|
||||
@@ -576,6 +593,63 @@ class AnimalsController extends ContentContainerController
|
||||
return $this->redirect($this->contentContainer->createUrl('/animal_management/animals/view', ['id' => $animal->id]) . '#animal-gallery');
|
||||
}
|
||||
|
||||
public function actionAddGalleryImagesInline(int $id)
|
||||
{
|
||||
$animal = $this->findAnimal($id);
|
||||
$returnTo = (string)Yii::$app->request->post('returnTo', Yii::$app->request->get('returnTo', 'view'));
|
||||
$isInline = (int)Yii::$app->request->get('inline', 1) === 1;
|
||||
$maxUploadCount = 10;
|
||||
$errorMessage = '';
|
||||
$infoMessage = '';
|
||||
|
||||
if (Yii::$app->request->isPost) {
|
||||
$result = $this->processGalleryUploads($animal);
|
||||
|
||||
if (!$result['hadSelection']) {
|
||||
$errorMessage = Yii::t('AnimalManagementModule.base', 'No gallery images were selected.');
|
||||
} else {
|
||||
if ($result['wasLimited']) {
|
||||
$infoMessage = Yii::t('AnimalManagementModule.base', 'Only the first {count} selected images were processed.', ['count' => $result['maxUploadCount']]);
|
||||
}
|
||||
|
||||
if ($result['added'] > 0) {
|
||||
if ($this->contentContainer instanceof Space) {
|
||||
GalleryIntegrationService::ensureAnimalGallery($animal, $this->contentContainer);
|
||||
}
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', '{count} image(s) added to gallery.', ['count' => $result['added']]));
|
||||
if ($isInline) {
|
||||
return $this->renderAjax('inline-edit-result', [
|
||||
'collapseId' => 'gallery-add-inline',
|
||||
'refreshSelectors' => ['#animal-gallery-panel'],
|
||||
]);
|
||||
}
|
||||
return $this->redirectToAnimalPage((int)$animal->id, $returnTo);
|
||||
}
|
||||
|
||||
$errorMessage = Yii::t('AnimalManagementModule.base', 'No gallery images were added. Check image type/size requirements.');
|
||||
}
|
||||
}
|
||||
|
||||
$galleryItems = $animal->getGalleryItems()->orderBy(['id' => SORT_DESC])->limit(120)->all();
|
||||
|
||||
$params = [
|
||||
'space' => $this->contentContainer,
|
||||
'animal' => $animal,
|
||||
'galleryItems' => $galleryItems,
|
||||
'isInline' => $isInline,
|
||||
'returnTo' => $returnTo,
|
||||
'maxUploadCount' => $maxUploadCount,
|
||||
'errorMessage' => $errorMessage,
|
||||
'infoMessage' => $infoMessage,
|
||||
];
|
||||
|
||||
if ($isInline) {
|
||||
return $this->renderAjax('add-gallery-images-inline', $params);
|
||||
}
|
||||
|
||||
return $this->render('add-gallery-images-inline', $params);
|
||||
}
|
||||
|
||||
public function actionRemoveGalleryImage(int $id, int $galleryId)
|
||||
{
|
||||
$animal = $this->findAnimal($id);
|
||||
@@ -646,6 +720,9 @@ class AnimalsController extends ContentContainerController
|
||||
$animal = $this->findAnimal($id);
|
||||
$this->ensureMedicalMediaFieldDefinition();
|
||||
$form = new AnimalMedicalVisitForm(['animal' => $animal]);
|
||||
if (trim((string)$form->visit_at) === '') {
|
||||
$form->visit_at = date('Y-m-d\TH:i');
|
||||
}
|
||||
$returnTo = (string)Yii::$app->request->post('returnTo', Yii::$app->request->get('returnTo', 'medical-visits'));
|
||||
$isInline = (int)Yii::$app->request->get('inline', 1) === 1;
|
||||
|
||||
@@ -1258,6 +1335,105 @@ class AnimalsController extends ContentContainerController
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function processGalleryUploads(Animal $animal): array
|
||||
{
|
||||
$uploadedFiles = UploadedFile::getInstancesByName('galleryImages');
|
||||
$maxUploadCount = 10;
|
||||
$hadSelection = !empty($uploadedFiles);
|
||||
$wasLimited = false;
|
||||
|
||||
if (!$hadSelection) {
|
||||
return [
|
||||
'hadSelection' => false,
|
||||
'wasLimited' => false,
|
||||
'maxUploadCount' => $maxUploadCount,
|
||||
'added' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
if (count($uploadedFiles) > $maxUploadCount) {
|
||||
$uploadedFiles = array_slice($uploadedFiles, 0, $maxUploadCount);
|
||||
$wasLimited = true;
|
||||
}
|
||||
|
||||
$allowedExtensions = array_map('strtolower', UploadStandards::imageExtensions());
|
||||
$allowedMimeTypes = array_map('strtolower', UploadStandards::imageMimeTypes());
|
||||
$maxBytes = (int)UploadStandards::IMAGE_MAX_BYTES;
|
||||
$existingItems = AnimalGalleryItem::find()->where(['animal_id' => (int)$animal->id])->all();
|
||||
$existingHashes = [];
|
||||
foreach ($existingItems as $existingItem) {
|
||||
$existingUrl = trim((string)$existingItem->getImageUrl());
|
||||
if ($existingUrl === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hash = $this->computeImageContentHash($existingUrl);
|
||||
if ($hash !== null) {
|
||||
$existingHashes[$hash] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$added = 0;
|
||||
foreach ($uploadedFiles as $uploadedFile) {
|
||||
if (!$uploadedFile instanceof UploadedFile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extension = strtolower((string)$uploadedFile->extension);
|
||||
$mimeType = strtolower((string)$uploadedFile->type);
|
||||
|
||||
if (!in_array($extension, $allowedExtensions, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($mimeType !== '' && !in_array($mimeType, $allowedMimeTypes, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($uploadedFile->size > $maxBytes) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$storedPath = $this->storeGalleryUpload($animal, $uploadedFile);
|
||||
if ($storedPath === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$storedHash = $this->computeImageContentHash($storedPath);
|
||||
|
||||
$exactExists = AnimalGalleryItem::find()
|
||||
->where(['animal_id' => (int)$animal->id, 'file_path' => $storedPath])
|
||||
->exists();
|
||||
|
||||
if ($exactExists || ($storedHash !== null && isset($existingHashes[$storedHash]))) {
|
||||
$absolute = Yii::getAlias('@webroot') . $storedPath;
|
||||
if (is_file($absolute)) {
|
||||
@unlink($absolute);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = new AnimalGalleryItem();
|
||||
$item->animal_id = (int)$animal->id;
|
||||
$item->file_path = $storedPath;
|
||||
$item->source_type = 'upload';
|
||||
$item->created_by = Yii::$app->user->isGuest ? null : (int)Yii::$app->user->id;
|
||||
if ($item->save()) {
|
||||
$added++;
|
||||
if ($storedHash !== null) {
|
||||
$existingHashes[$storedHash] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'hadSelection' => true,
|
||||
'wasLimited' => $wasLimited,
|
||||
'maxUploadCount' => $maxUploadCount,
|
||||
'added' => $added,
|
||||
];
|
||||
}
|
||||
|
||||
private function storeGalleryUpload(Animal $animal, UploadedFile $file): ?string
|
||||
{
|
||||
$random = Yii::$app->security->generateRandomString(8);
|
||||
@@ -1707,4 +1883,74 @@ class AnimalsController extends ContentContainerController
|
||||
$item->created_by = Yii::$app->user->isGuest ? null : (int)Yii::$app->user->id;
|
||||
$item->save();
|
||||
}
|
||||
|
||||
private function canUseIntakeGoalSection(): bool
|
||||
{
|
||||
if (!($this->contentContainer instanceof Space)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->contentContainer->moduleManager->isEnabled('donations')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$goalFormClass = 'humhub\\modules\\donations\\models\\forms\\DonationGoalForm';
|
||||
$goalClass = 'humhub\\modules\\donations\\models\\DonationGoal';
|
||||
|
||||
if (!class_exists($goalFormClass) || !class_exists($goalClass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Yii::$app->db->schema->getTableSchema($goalClass::tableName(), true) !== null;
|
||||
}
|
||||
|
||||
private function createIntakeAnimalGoal(Animal $animal, array $payload): ?string
|
||||
{
|
||||
if ((int)($payload['enabled'] ?? 0) !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$this->canUseIntakeGoalSection()) {
|
||||
return Yii::t('AnimalManagementModule.base', 'Animal was created, but donation goal setup is not available in this space.');
|
||||
}
|
||||
|
||||
$goalFormClass = 'humhub\\modules\\donations\\models\\forms\\DonationGoalForm';
|
||||
$goalClass = 'humhub\\modules\\donations\\models\\DonationGoal';
|
||||
|
||||
$targetAmount = max(0.0, (float)($payload['target_amount'] ?? 0));
|
||||
if ($targetAmount <= 0) {
|
||||
return Yii::t('AnimalManagementModule.base', 'Animal was created, but the intake donation goal target must be greater than zero.');
|
||||
}
|
||||
|
||||
$title = trim((string)($payload['title'] ?? ''));
|
||||
if ($title === '') {
|
||||
$title = Yii::t('AnimalManagementModule.base', '{animalName} Care Fund', ['animalName' => $animal->getDisplayName()]);
|
||||
}
|
||||
|
||||
$description = trim((string)($payload['description'] ?? ''));
|
||||
$imagePath = trim((string)($payload['image_path'] ?? ''));
|
||||
$isActive = (int)($payload['is_active'] ?? 1) === 1;
|
||||
|
||||
$goalForm = new $goalFormClass();
|
||||
$goalForm->contentContainer = $this->contentContainer;
|
||||
$goalForm->goal_type = $goalClass::TYPE_ANIMAL;
|
||||
$goalForm->target_animal_id = (int)$animal->id;
|
||||
$goalForm->title = $title;
|
||||
$goalForm->description = $description;
|
||||
$goalForm->target_amount = $targetAmount;
|
||||
$goalForm->is_active = $isActive;
|
||||
|
||||
if ($imagePath !== '') {
|
||||
$goalForm->imageGalleryPath = $imagePath;
|
||||
}
|
||||
|
||||
$savedGoal = $goalForm->save();
|
||||
if ($savedGoal === null) {
|
||||
$firstErrors = $goalForm->getFirstErrors();
|
||||
$errorText = !empty($firstErrors) ? implode(' ', array_values($firstErrors)) : Yii::t('AnimalManagementModule.base', 'Unknown donation goal error.');
|
||||
return Yii::t('AnimalManagementModule.base', 'Animal was created, but donation goal could not be saved: {error}', ['error' => $errorText]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ namespace humhub\modules\animal_management\controllers;
|
||||
use humhub\modules\animal_management\models\Animal;
|
||||
use humhub\modules\animal_management\models\forms\DisplaySettingsForm;
|
||||
use humhub\modules\animal_management\models\forms\FieldDefinitionSettingsForm;
|
||||
use humhub\modules\animal_management\services\ModuleSetupService;
|
||||
use humhub\modules\content\components\ContentContainerController;
|
||||
use humhub\modules\content\components\ContentContainerControllerAccess;
|
||||
use humhub\modules\rescue_foundation\widgets\RescueSettingsMenu;
|
||||
use humhub\modules\space\models\Space;
|
||||
use Yii;
|
||||
use yii\web\BadRequestHttpException;
|
||||
|
||||
class SettingsController extends ContentContainerController
|
||||
{
|
||||
@@ -53,6 +55,37 @@ class SettingsController extends ContentContainerController
|
||||
'animalCount' => (int)$animalCount,
|
||||
'fieldSettingsForm' => $fieldSettingsForm,
|
||||
'displaySettingsForm' => $displaySettingsForm,
|
||||
'space' => $this->contentContainer,
|
||||
]);
|
||||
}
|
||||
|
||||
public function actionSetup()
|
||||
{
|
||||
if (!Yii::$app->request->isPost) {
|
||||
throw new BadRequestHttpException('Invalid request method.');
|
||||
}
|
||||
|
||||
if (!$this->contentContainer instanceof Space) {
|
||||
$this->view->error(Yii::t('AnimalManagementModule.base', 'Setup can only be run inside a space.'));
|
||||
return $this->redirect($this->contentContainer->createUrl('/animal_management/settings'));
|
||||
}
|
||||
|
||||
try {
|
||||
$result = ModuleSetupService::runForSpace($this->contentContainer);
|
||||
$appliedCount = count($result['applied'] ?? []);
|
||||
|
||||
if ($appliedCount > 0) {
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', 'Setup completed. Applied {count} migration(s).', [
|
||||
'count' => $appliedCount,
|
||||
]));
|
||||
} else {
|
||||
$this->view->success(Yii::t('AnimalManagementModule.base', 'Setup completed. No pending migrations were found.'));
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
Yii::error($e, 'animal_management.setup');
|
||||
$this->view->error(Yii::t('AnimalManagementModule.base', 'Setup failed. Please check logs and try again.'));
|
||||
}
|
||||
|
||||
return $this->redirect($this->contentContainer->createUrl('/animal_management/settings'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user