From f14b556e931b861118d5166f3bba3b61c226e69c Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 19 Jan 2026 10:29:13 -0800 Subject: [PATCH 1/5] first pass at fix --- src/Controller/Inventory/RemoveBonusController.php | 1 + src/Service/MarketService.php | 2 ++ src/Service/PetActivity/PhilosophersStoneService.php | 1 + src/Service/PetActivity/SpecialLocations/BurntForestService.php | 1 + .../PetActivity/SpecialLocations/FructalPlaneService.php | 1 + 5 files changed, 6 insertions(+) diff --git a/src/Controller/Inventory/RemoveBonusController.php b/src/Controller/Inventory/RemoveBonusController.php index d3145d5c..9ca67aa8 100644 --- a/src/Controller/Inventory/RemoveBonusController.php +++ b/src/Controller/Inventory/RemoveBonusController.php @@ -37,6 +37,7 @@ public function removeBonus( if($inventory->getOwner()->getId() !== $user->getId()) throw new PSPNotFoundException('That item does not belong to you.'); + $em->remove($inventory->getEnchantmentData()); $inventory->setEnchantment(null); $em->flush(); diff --git a/src/Service/MarketService.php b/src/Service/MarketService.php index b62528f0..8539d614 100644 --- a/src/Service/MarketService.php +++ b/src/Service/MarketService.php @@ -106,6 +106,8 @@ public function transferItemToPlayer(Inventory $item, User $newOwner, int $locat $this->userStatsRepository->incrementStat($item->getOwner(), UserStat::ItemsSoldInMarket, 1); $this->userStatsRepository->incrementStat($newOwner, UserStat::ItemsBoughtInMarket, 1); + $this->em->remove($item->getEnchantmentData()); + $item ->setSpice(null) ->setEnchantment(null) diff --git a/src/Service/PetActivity/PhilosophersStoneService.php b/src/Service/PetActivity/PhilosophersStoneService.php index 96416717..e077f6a6 100644 --- a/src/Service/PetActivity/PhilosophersStoneService.php +++ b/src/Service/PetActivity/PhilosophersStoneService.php @@ -393,6 +393,7 @@ public function seekMerkabaOfAir(ComputedPetSkills $petWithSkills): ?PetActivity PetBadgeHelpers::awardBadge($this->em, $pet, PetBadgeEnum::FoundMerkabaOfAir, $activityLog); + $this->em->remove($pet->getTool()->getEnchantmentData()); $pet->getTool()->setEnchantment(null); $pet->addMerit(MeritRepository::findOneByName($this->em, MeritEnum::LIGHTNING_REINS)); diff --git a/src/Service/PetActivity/SpecialLocations/BurntForestService.php b/src/Service/PetActivity/SpecialLocations/BurntForestService.php index 65f9255a..087aec17 100644 --- a/src/Service/PetActivity/SpecialLocations/BurntForestService.php +++ b/src/Service/PetActivity/SpecialLocations/BurntForestService.php @@ -461,6 +461,7 @@ private function breakToolBonus(Pet $pet): PetActivityLog $this->petExperienceService->spendTime($pet, $this->rng->rngNextInt(30, 45), PetActivityStatEnum::OTHER, true); + $this->em->remove($pet->getTool()->getEnchantmentData()); $pet->getTool()->setEnchantment(null); return $activityLog; diff --git a/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php b/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php index 1ea8a589..2f7b1b61 100644 --- a/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php +++ b/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php @@ -107,6 +107,7 @@ public function adventure(ComputedPetSkills $petWithSkills): PetActivityLog $this->petExperienceService->gainExp($pet, count($loot), [ PetSkillEnum::Arcana ], $activityLog); $this->petExperienceService->spendTime($pet, 2, PetActivityStatEnum::UMBRA, true); + $this->em->remove($pet->getTool()->getEnchantmentData()); $pet->getTool()->setEnchantment(null); PetBadgeHelpers::awardBadge($this->em, $pet, PetBadgeEnum::VisitedTheFructalPlane, $activityLog); From 9be0ee4ce1f541d4c64de4740c803a7abe1fef66 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 19 Jan 2026 10:42:05 -0800 Subject: [PATCH 2/5] second pass --- src/Controller/Inventory/RemoveBonusController.php | 4 ++-- src/Functions/InventoryHelpers.php | 9 +++++++++ src/Service/MarketService.php | 4 ++-- src/Service/PetActivity/PhilosophersStoneService.php | 5 +++-- .../PetActivity/SpecialLocations/BurntForestService.php | 5 +++-- .../PetActivity/SpecialLocations/FructalPlaneService.php | 5 +++-- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Controller/Inventory/RemoveBonusController.php b/src/Controller/Inventory/RemoveBonusController.php index 9ca67aa8..727183a5 100644 --- a/src/Controller/Inventory/RemoveBonusController.php +++ b/src/Controller/Inventory/RemoveBonusController.php @@ -15,6 +15,7 @@ use App\Entity\Inventory; use App\Exceptions\PSPNotFoundException; +use App\Functions\InventoryHelpers; use App\Service\ResponseService; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\JsonResponse; @@ -37,8 +38,7 @@ public function removeBonus( if($inventory->getOwner()->getId() !== $user->getId()) throw new PSPNotFoundException('That item does not belong to you.'); - $em->remove($inventory->getEnchantmentData()); - $inventory->setEnchantment(null); + InventoryHelpers::removeEnchantment($em, $inventory); $em->flush(); diff --git a/src/Functions/InventoryHelpers.php b/src/Functions/InventoryHelpers.php index 395d91c0..5bdfb608 100644 --- a/src/Functions/InventoryHelpers.php +++ b/src/Functions/InventoryHelpers.php @@ -19,6 +19,15 @@ class InventoryHelpers { + public static function removeEnchantment(EntityManagerInterface $em, Inventory $inventory) + { + if(!$inventory->getEnchantmentData()) + return; + + $em->remove($inventory->getEnchantmentData()); + $inventory->setEnchantment(null); + } + public static function findOneToConsume(EntityManagerInterface $em, User $owner, string $itemName): ?Inventory { return $em->getRepository(Inventory::class)->createQueryBuilder('i') diff --git a/src/Service/MarketService.php b/src/Service/MarketService.php index 8539d614..a7062700 100644 --- a/src/Service/MarketService.php +++ b/src/Service/MarketService.php @@ -22,6 +22,7 @@ use App\Enum\LocationEnum; use App\Enum\UnlockableFeatureEnum; use App\Enum\UserStat; +use App\Functions\InventoryHelpers; use App\Functions\InventoryModifierFunctions; use App\Functions\MarketListingRepository; use App\Functions\UserQuestRepository; @@ -106,11 +107,10 @@ public function transferItemToPlayer(Inventory $item, User $newOwner, int $locat $this->userStatsRepository->incrementStat($item->getOwner(), UserStat::ItemsSoldInMarket, 1); $this->userStatsRepository->incrementStat($newOwner, UserStat::ItemsBoughtInMarket, 1); - $this->em->remove($item->getEnchantmentData()); + InventoryHelpers::removeEnchantment($this->em, $item); $item ->setSpice(null) - ->setEnchantment(null) ->changeOwner($newOwner, $newItemComment, $this->em) ->setLocation($location) ; diff --git a/src/Service/PetActivity/PhilosophersStoneService.php b/src/Service/PetActivity/PhilosophersStoneService.php index e077f6a6..78de6cce 100644 --- a/src/Service/PetActivity/PhilosophersStoneService.php +++ b/src/Service/PetActivity/PhilosophersStoneService.php @@ -23,6 +23,7 @@ use App\Enum\PetSkillEnum; use App\Functions\ActivityHelpers; use App\Functions\EquipmentFunctions; +use App\Functions\InventoryHelpers; use App\Functions\ItemRepository; use App\Functions\MeritRepository; use App\Functions\PetActivityLogFactory; @@ -393,8 +394,8 @@ public function seekMerkabaOfAir(ComputedPetSkills $petWithSkills): ?PetActivity PetBadgeHelpers::awardBadge($this->em, $pet, PetBadgeEnum::FoundMerkabaOfAir, $activityLog); - $this->em->remove($pet->getTool()->getEnchantmentData()); - $pet->getTool()->setEnchantment(null); + if($pet->getTool()) + InventoryHelpers::removeEnchantment($this->em, $pet->getTool()); $pet->addMerit(MeritRepository::findOneByName($this->em, MeritEnum::LIGHTNING_REINS)); diff --git a/src/Service/PetActivity/SpecialLocations/BurntForestService.php b/src/Service/PetActivity/SpecialLocations/BurntForestService.php index 087aec17..a57e454a 100644 --- a/src/Service/PetActivity/SpecialLocations/BurntForestService.php +++ b/src/Service/PetActivity/SpecialLocations/BurntForestService.php @@ -25,6 +25,7 @@ use App\Enum\StatusEffectEnum; use App\Functions\ActivityHelpers; use App\Functions\EnchantmentRepository; +use App\Functions\InventoryHelpers; use App\Functions\NumberFunctions; use App\Functions\PetActivityLogFactory; use App\Functions\PetActivityLogTagHelpers; @@ -461,8 +462,8 @@ private function breakToolBonus(Pet $pet): PetActivityLog $this->petExperienceService->spendTime($pet, $this->rng->rngNextInt(30, 45), PetActivityStatEnum::OTHER, true); - $this->em->remove($pet->getTool()->getEnchantmentData()); - $pet->getTool()->setEnchantment(null); + if($pet->getTool()) + InventoryHelpers::removeEnchantment($this->em, $pet->getTool()); return $activityLog; } diff --git a/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php b/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php index 2f7b1b61..b42d72ae 100644 --- a/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php +++ b/src/Service/PetActivity/SpecialLocations/FructalPlaneService.php @@ -21,6 +21,7 @@ use App\Enum\PetSkillEnum; use App\Functions\ActivityHelpers; use App\Functions\ArrayFunctions; +use App\Functions\InventoryHelpers; use App\Functions\PetActivityLogFactory; use App\Functions\PetActivityLogTagHelpers; use App\Functions\PetBadgeHelpers; @@ -107,8 +108,8 @@ public function adventure(ComputedPetSkills $petWithSkills): PetActivityLog $this->petExperienceService->gainExp($pet, count($loot), [ PetSkillEnum::Arcana ], $activityLog); $this->petExperienceService->spendTime($pet, 2, PetActivityStatEnum::UMBRA, true); - $this->em->remove($pet->getTool()->getEnchantmentData()); - $pet->getTool()->setEnchantment(null); + if($pet->getTool()) + InventoryHelpers::removeEnchantment($this->em, $pet->getTool()); PetBadgeHelpers::awardBadge($this->em, $pet, PetBadgeEnum::VisitedTheFructalPlane, $activityLog); From f4fd5a3b3a1c69d039003d5b627406e92541e3b0 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 19 Jan 2026 10:42:49 -0800 Subject: [PATCH 3/5] method return type & annotation --- src/Functions/InventoryHelpers.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Functions/InventoryHelpers.php b/src/Functions/InventoryHelpers.php index 5bdfb608..2d711c68 100644 --- a/src/Functions/InventoryHelpers.php +++ b/src/Functions/InventoryHelpers.php @@ -19,7 +19,10 @@ class InventoryHelpers { - public static function removeEnchantment(EntityManagerInterface $em, Inventory $inventory) + /** + * Removes an enchantment (bonus) from an inventory item. + */ + public static function removeEnchantment(EntityManagerInterface $em, Inventory $inventory): void { if(!$inventory->getEnchantmentData()) return; From 1fef144c87cc23ae124afd07209ec0474a3eaf52 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 19 Jan 2026 10:44:45 -0800 Subject: [PATCH 4/5] one more enchantment-related fix + minor tidying of phpstan baseline --- phpstan-baseline.neon | 24 -------------------- src/Service/PetActivity/GatheringService.php | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index bec45227..4a3dc0af 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -7116,12 +7116,6 @@ parameters: count: 2 path: src/Service/PetActivity/GatheringService.php - - - message: '#^Cannot call method setEnchantment\(\) on App\\Entity\\Inventory\|null\.$#' - identifier: method.nonObject - count: 1 - path: src/Service/PetActivity/GatheringService.php - - message: '#^Parameter \#3 \$species of method App\\Service\\PetFactory\:\:createPet\(\) expects App\\Entity\\PetSpecies, App\\Entity\\PetSpecies\|null given\.$#' identifier: argument.type @@ -7326,12 +7320,6 @@ parameters: count: 4 path: src/Service/PetActivity/PhilosophersStoneService.php - - - message: '#^Cannot call method setEnchantment\(\) on App\\Entity\\Inventory\|null\.$#' - identifier: method.nonObject - count: 1 - path: src/Service/PetActivity/PhilosophersStoneService.php - - message: '#^Cannot call method getName\(\) on App\\Entity\\Pet\|null\.$#' identifier: method.nonObject @@ -7434,12 +7422,6 @@ parameters: count: 3 path: src/Service/PetActivity/SpecialLocations/BurntForestService.php - - - message: '#^Cannot call method setEnchantment\(\) on App\\Entity\\Inventory\|null\.$#' - identifier: method.nonObject - count: 1 - path: src/Service/PetActivity/SpecialLocations/BurntForestService.php - - message: '#^Left side of && is always true\.$#' identifier: booleanAnd.leftAlwaysTrue @@ -7464,12 +7446,6 @@ parameters: count: 2 path: src/Service/PetActivity/SpecialLocations/FructalPlaneService.php - - - message: '#^Cannot call method setEnchantment\(\) on App\\Entity\\Inventory\|null\.$#' - identifier: method.nonObject - count: 1 - path: src/Service/PetActivity/SpecialLocations/FructalPlaneService.php - - message: '#^Offset ''message'' might not exist on array\{stat\: ''brawl''\|''crafts''\|''music'', value\: int, message\: non\-falsy\-string\}\|null\.$#' identifier: offsetAccess.notFound diff --git a/src/Service/PetActivity/GatheringService.php b/src/Service/PetActivity/GatheringService.php index 0c4e2662..6785f393 100644 --- a/src/Service/PetActivity/GatheringService.php +++ b/src/Service/PetActivity/GatheringService.php @@ -1337,7 +1337,7 @@ private function foundOldSettlement(ComputedPetSkills $petWithSkills): PetActivi { $item = $this->inventoryService->petCollectsItem($itemName, $pet, $pet->getName() . ' found this in a ruined settlement deep in the island\'s Micro-jungle.', $activityLog); - if($itemName === 'No Right Turns') + if($item && $itemName === 'No Right Turns') $item->setEnchantment(EnchantmentRepository::findOneByName($this->em, 'Thorn-covered')); } From 9ec57347eafec7cb60a8a88b7751f87b37fa92ee Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 19 Jan 2026 10:55:07 -0800 Subject: [PATCH 5/5] some more phpstan baseline fixes --- phpstan-baseline.neon | 38 +------------------ .../PetActivity/GizubisGardenService.php | 3 +- src/Service/PetActivity/GuildService.php | 32 ++++++++++------ 3 files changed, 23 insertions(+), 50 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4a3dc0af..05205358 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -7134,12 +7134,6 @@ parameters: count: 1 path: src/Service/PetActivity/GivingTreeGatheringService.php - - - message: '#^Cannot call method getGuild\(\) on App\\Entity\\GuildMembership\|null\.$#' - identifier: method.nonObject - count: 3 - path: src/Service/PetActivity/GizubisGardenService.php - - message: '#^Cannot call method getName\(\) on App\\Entity\\Guild\|null\.$#' identifier: method.nonObject @@ -7152,16 +7146,10 @@ parameters: count: 1 path: src/Service/PetActivity/GizubisGardenService.php - - - message: '#^Cannot call method increaseReputation\(\) on App\\Entity\\GuildMembership\|null\.$#' - identifier: method.nonObject - count: 1 - path: src/Service/PetActivity/GizubisGardenService.php - - message: '#^Cannot call method getGuild\(\) on App\\Entity\\GuildMembership\|null\.$#' identifier: method.nonObject - count: 31 + count: 2 path: src/Service/PetActivity/GuildService.php - @@ -7182,36 +7170,12 @@ parameters: count: 1 path: src/Service/PetActivity/GuildService.php - - - message: '#^Cannot call method getRank\(\) on App\\Entity\\GuildMembership\|null\.$#' - identifier: method.nonObject - count: 1 - path: src/Service/PetActivity/GuildService.php - - - - message: '#^Cannot call method getReputation\(\) on App\\Entity\\GuildMembership\|null\.$#' - identifier: method.nonObject - count: 1 - path: src/Service/PetActivity/GuildService.php - - message: '#^Cannot call method getStarterTool\(\) on App\\Entity\\Guild\|null\.$#' identifier: method.nonObject count: 2 path: src/Service/PetActivity/GuildService.php - - - message: '#^Cannot call method getTitle\(\) on App\\Entity\\GuildMembership\|null\.$#' - identifier: method.nonObject - count: 2 - path: src/Service/PetActivity/GuildService.php - - - - message: '#^Cannot call method increaseReputation\(\) on App\\Entity\\GuildMembership\|null\.$#' - identifier: method.nonObject - count: 9 - path: src/Service/PetActivity/GuildService.php - - message: '#^Method App\\Service\\PetActivity\\GuildService\:\:joinGuild\(\) has parameter \$possibilities with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue diff --git a/src/Service/PetActivity/GizubisGardenService.php b/src/Service/PetActivity/GizubisGardenService.php index f0a25ff9..379f691c 100644 --- a/src/Service/PetActivity/GizubisGardenService.php +++ b/src/Service/PetActivity/GizubisGardenService.php @@ -55,7 +55,8 @@ public function adventure(ComputedPetSkills $petWithSkills): PetActivityLog private function doRandomSeedlingadventure(ComputedPetSkills $petWithSkills): PetActivityLog { $pet = $petWithSkills->getPet(); - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); switch($this->rng->rngNextInt(1, 3)) { diff --git a/src/Service/PetActivity/GuildService.php b/src/Service/PetActivity/GuildService.php index 6519da5a..2e03dae3 100644 --- a/src/Service/PetActivity/GuildService.php +++ b/src/Service/PetActivity/GuildService.php @@ -120,7 +120,7 @@ public function doGuildActivity(ComputedPetSkills $petWithSkills): ?PetActivityL $activityLog = $this->pickGuildActivity($petWithSkills); - if($activityLog !== null) + if($activityLog) { $activityLog ->setChanges($changes->compare($petWithSkills->getPet())) @@ -136,9 +136,7 @@ private function pickGuildActivity(ComputedPetSkills $petWithSkills): ?PetActivi $pet = $petWithSkills->getPet(); if($pet->getGuildMembership()->getLevel() === 0) - { return $this->doGuildIntroductions($pet); - } return match ($pet->getGuildMembership()->getGuild()->getName()) { @@ -157,7 +155,9 @@ private function pickGuildActivity(ComputedPetSkills $petWithSkills): ?PetActivi private function doGuildIntroductions(Pet $pet): PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); + $collectStarterTool = false; switch($member->getReputation()) @@ -190,7 +190,8 @@ private function doGuildIntroductions(Pet $pet): PetActivityLog private function doTimesArrowMission(Pet $pet): PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); $message = $this->rng->rngNextFromArray([ '%pet:' . $pet->getId() . '.name% ' . $this->rng->rngNextFromArray([ 'picked up a book from', 'returned a book to' ]). ' the Library of Fire for one of their ' . $member->getGuild()->getName() . ' seniors.', @@ -210,7 +211,8 @@ private function doTimesArrowMission(Pet $pet): PetActivityLog private function doLightAndShadowMission(Pet $pet): PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); $message = $this->rng->rngNextFromArray([ $pet->getName() . ' ' . $this->rng->rngNextFromArray([ 'picked up a book from', 'returned a book to' ]). ' the Library of Fire for one of their ' . $member->getGuild()->getName() . ' seniors.', @@ -230,7 +232,8 @@ private function doLightAndShadowMission(Pet $pet): PetActivityLog private function doTapestriesMission(Pet $pet): PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); $message = $this->rng->rngNextFromArray([ $pet->getName() . ' ' . $this->rng->rngNextFromArray([ 'picked up a book from', 'returned a book to' ]). ' the Library of Fire for one of their ' . $member->getGuild()->getName() . ' seniors.', @@ -250,7 +253,8 @@ private function doTapestriesMission(Pet $pet): PetActivityLog private function doInnerSanctumMission(Pet $pet): PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); if($this->rng->rngNextInt(1, 3) === 1) { @@ -310,7 +314,8 @@ private function doInnerSanctumMission(Pet $pet): PetActivityLog private function doDwarfcraftMission(Pet $pet): PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); $message = $this->rng->rngNextFromArray([ $pet->getName() . ' picked up some Liquid-hot Magma for one of their ' . $member->getGuild()->getName() . ' seniors.', @@ -330,7 +335,8 @@ private function doDwarfcraftMission(Pet $pet): PetActivityLog private function doHighImpactMission(Pet $pet): ?PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); // High Impact members do other cool stuff, high up a magic bean stalks, and deep undersea if($member->getTitle() >= 3) @@ -354,7 +360,8 @@ private function doHighImpactMission(Pet $pet): ?PetActivityLog private function doTheUniverseForgetsMission(Pet $pet): PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); $message = $this->rng->rngNextFromArray([ $pet->getName() . ' ' . $this->rng->rngNextFromArray([ 'picked up a book from', 'returned a book to' ]). ' the Library of Fire for one of their ' . $member->getGuild()->getName() . ' seniors.', @@ -374,7 +381,8 @@ private function doTheUniverseForgetsMission(Pet $pet): PetActivityLog private function doCorrespondenceMission(Pet $pet): ?PetActivityLog { - $member = $pet->getGuildMembership(); + $member = $pet->getGuildMembership() + ?? throw new \RuntimeException('Pet is not in a guild?!'); // there are delivery messages that Correspondence members can do, during normal pet activities if($this->rng->rngNextInt(0, 2) < $member->getTitle())