From 38a1d4b3c119c4c6d9d3606b0b8790d5e7ead1a5 Mon Sep 17 00:00:00 2001 From: romanetar Date: Fri, 16 Jan 2026 12:36:59 +0100 Subject: [PATCH] feat: marketplace new orm mappings and serializers Signed-off-by: romanetar --- .../CompanyServiceResourceSerializer.php | 32 ++++++ .../Marketplace/CompanyServiceSerializer.php | 41 ++++++- .../CustomerCaseStudySerializer.php | 32 ++++++ .../Marketplace/RegionalSupportSerializer.php | 45 ++++---- app/ModelSerializers/SerializerRegistry.php | 6 + .../Foundation/Marketplace/CompanyService.php | 18 ++- .../Marketplace/CustomerCaseStudy.php | 108 ++++++++++++++++++ .../Marketplace/RegionalSupport.php | 11 ++ .../model/Version20260115181251.php | 59 ++++++++++ 9 files changed, 328 insertions(+), 24 deletions(-) create mode 100644 app/ModelSerializers/Marketplace/CompanyServiceResourceSerializer.php create mode 100644 app/ModelSerializers/Marketplace/CustomerCaseStudySerializer.php create mode 100644 app/Models/Foundation/Marketplace/CustomerCaseStudy.php create mode 100644 database/migrations/model/Version20260115181251.php diff --git a/app/ModelSerializers/Marketplace/CompanyServiceResourceSerializer.php b/app/ModelSerializers/Marketplace/CompanyServiceResourceSerializer.php new file mode 100644 index 000000000..c1e347394 --- /dev/null +++ b/app/ModelSerializers/Marketplace/CompanyServiceResourceSerializer.php @@ -0,0 +1,32 @@ + 'name:json_string', + 'Uri' => 'uri:json_string', + 'Order' => 'order:json_int', + ]; +} \ No newline at end of file diff --git a/app/ModelSerializers/Marketplace/CompanyServiceSerializer.php b/app/ModelSerializers/Marketplace/CompanyServiceSerializer.php index 4c87f9f32..92e691101 100644 --- a/app/ModelSerializers/Marketplace/CompanyServiceSerializer.php +++ b/app/ModelSerializers/Marketplace/CompanyServiceSerializer.php @@ -37,8 +37,11 @@ class CompanyServiceSerializer extends SilverStripeSerializer protected static $allowed_relations = [ 'company', - 'reviews', 'type', + 'case_studies', + 'videos', + 'reviews', + 'resources', ]; /** @@ -54,6 +57,22 @@ public function serialize($expand = null, array $fields = [], array $relations = if(!$company_service instanceof CompanyService) return []; $values = parent::serialize($expand, $fields, $relations, $params); + if(in_array('case_studies', $relations) && !isset($values['case_studies'])) { + $case_studies = []; + foreach ($company_service->getCaseStudies() as $c) { + $case_studies[] = $c->getId(); + } + $values['case_studies'] = $case_studies; + } + + if(in_array('videos', $relations) && !isset($values['videos'])) { + $videos = []; + foreach ($company_service->getVideos() as $v) { + $videos[] = $v->getId(); + } + $values['videos'] = $videos; + } + if(in_array('reviews', $relations) && !isset($values['reviews'])) { $reviews = []; foreach ($company_service->getApprovedReviews() as $r) { @@ -62,14 +81,34 @@ public function serialize($expand = null, array $fields = [], array $relations = $values['reviews'] = $reviews; } + if(in_array('resources', $relations) && !isset($values['resources'])) { + $resources = []; + foreach ($company_service->getResources() as $r) { + $resources[] = $r->getId(); + } + $values['resources'] = $resources; + } + return $values; } protected static $expand_mappings = [ + 'case_studies' => [ + 'type' => Many2OneExpandSerializer::class, + 'getter' => 'getCaseStudies', + ], 'reviews' => [ 'type' => Many2OneExpandSerializer::class, 'getter' => 'getApprovedReviews', ], + 'resources' => [ + 'type' => Many2OneExpandSerializer::class, + 'getter' => 'getResources', + ], + 'videos' => [ + 'type' => Many2OneExpandSerializer::class, + 'getter' => 'getVideos', + ], 'company' => [ 'type' => One2ManyExpandSerializer::class, 'original_attribute' => 'company_id', diff --git a/app/ModelSerializers/Marketplace/CustomerCaseStudySerializer.php b/app/ModelSerializers/Marketplace/CustomerCaseStudySerializer.php new file mode 100644 index 000000000..be8f01fb3 --- /dev/null +++ b/app/ModelSerializers/Marketplace/CustomerCaseStudySerializer.php @@ -0,0 +1,32 @@ + 'name:json_string', + 'Uri' => 'uri:json_string', + 'Order' => 'order:json_int', + ]; +} \ No newline at end of file diff --git a/app/ModelSerializers/Marketplace/RegionalSupportSerializer.php b/app/ModelSerializers/Marketplace/RegionalSupportSerializer.php index bcbbbfcbf..b143cb9e8 100644 --- a/app/ModelSerializers/Marketplace/RegionalSupportSerializer.php +++ b/app/ModelSerializers/Marketplace/RegionalSupportSerializer.php @@ -14,6 +14,8 @@ * limitations under the License. **/ use App\Models\Foundation\Marketplace\RegionalSupport; +use Libs\ModelSerializers\Many2OneExpandSerializer; +use Libs\ModelSerializers\One2ManyExpandSerializer; use ModelSerializers\SerializerRegistry; use ModelSerializers\SilverStripeSerializer; @@ -23,8 +25,12 @@ */ class RegionalSupportSerializer extends SilverStripeSerializer { + protected static $array_mappings = [ + 'RegionId' => 'region_id:json_int', + ]; protected static $allowed_relations = [ + 'region', 'supported_channel_types', ]; @@ -37,34 +43,31 @@ class RegionalSupportSerializer extends SilverStripeSerializer */ public function serialize($expand = null, array $fields = [], array $relations = [], array $params = []) { - $regional_support = $this->object; if(!$regional_support instanceof RegionalSupport) return []; $values = parent::serialize($expand, $fields, $relations, $params); - if(in_array('supported_channel_types', $relations)){ - $res = []; - foreach ($regional_support->getSupportedChannelTypes() as $channel_type){ - $res[] = SerializerRegistry::getInstance() - ->getSerializer($channel_type) - ->serialize(); + if(in_array('supported_channel_types', $relations) && !isset($values['supported_channel_types'])) { + $supported_channel_types = []; + foreach ($regional_support->getSupportedChannelTypes() as $c) { + $supported_channel_types[] = $c->getId(); } - $values['supported_channel_types'] = $res; + $values['supported_channel_types'] = $supported_channel_types; } - if (!empty($expand)) { - $exp_expand = explode(',', $expand); - foreach ($exp_expand as $relation) { - switch (trim($relation)) { - case 'region': - unset($values['region_id']); - $values['region'] = SerializerRegistry::getInstance() - ->getSerializer($regional_support->getRegion()) - ->serialize(); - break; - } - } - } return $values; } + + protected static $expand_mappings = [ + 'supported_channel_types' => [ + 'type' => Many2OneExpandSerializer::class, + 'getter' => 'getSupportedChannelTypes', + ], + 'region' => [ + 'type' => One2ManyExpandSerializer::class, + 'original_attribute' => 'region_id', + 'getter' => 'getRegion', + 'has' => 'hasRegion' + ], + ]; } \ No newline at end of file diff --git a/app/ModelSerializers/SerializerRegistry.php b/app/ModelSerializers/SerializerRegistry.php index 46f16efd7..3ad4a44b5 100644 --- a/app/ModelSerializers/SerializerRegistry.php +++ b/app/ModelSerializers/SerializerRegistry.php @@ -34,10 +34,13 @@ use App\ModelSerializers\Locations\SummitRoomReservationSerializer; use App\ModelSerializers\Marketplace\ApplianceSerializer; use App\ModelSerializers\Marketplace\CloudServiceOfferedSerializer; +use App\ModelSerializers\Marketplace\CompanyServiceResourceSerializer; +use App\ModelSerializers\Marketplace\CompanyServiceSerializer; use App\ModelSerializers\Marketplace\ConfigurationManagementTypeSerializer; use App\ModelSerializers\Marketplace\ConsultantClientSerializer; use App\ModelSerializers\Marketplace\ConsultantSerializer; use App\ModelSerializers\Marketplace\ConsultantServiceOfferedTypeSerializer; +use App\ModelSerializers\Marketplace\CustomerCaseStudySerializer; use App\ModelSerializers\Marketplace\DataCenterLocationSerializer; use App\ModelSerializers\Marketplace\DataCenterRegionSerializer; use App\ModelSerializers\Marketplace\DistributionSerializer; @@ -636,8 +639,11 @@ private function __construct() $this->registry['RegionalSupport'] = RegionalSupportSerializer::class; $this->registry['SupportChannelType'] = SupportChannelTypeSerializer::class; $this->registry['Office'] = OfficeSerializer::class; + $this->registry['CompanyService'] = CompanyServiceSerializer::class; + $this->registry['CompanyServiceResource'] = CompanyServiceResourceSerializer::class; $this->registry['Consultant'] = ConsultantSerializer::class; $this->registry['ConsultantClient'] = ConsultantClientSerializer::class; + $this->registry['CustomerCaseStudy'] = CustomerCaseStudySerializer::class; $this->registry['SpokenLanguage'] = SpokenLanguageSerializer::class; $this->registry['ConfigurationManagementType'] = ConfigurationManagementTypeSerializer::class; $this->registry['ServiceOfferedType'] = ServiceOfferedTypeSerializer::class; diff --git a/app/Models/Foundation/Marketplace/CompanyService.php b/app/Models/Foundation/Marketplace/CompanyService.php index 43a1276c1..46ae65dd8 100644 --- a/app/Models/Foundation/Marketplace/CompanyService.php +++ b/app/Models/Foundation/Marketplace/CompanyService.php @@ -101,12 +101,17 @@ class CompanyService extends SilverstripeBaseModel /** * @ORM\OneToMany(targetEntity="CompanyServiceResource", mappedBy="company_service", cascade={"persist"}, orphanRemoval=true) - * @ORM\OrderBy({"name" = "order"}) + * @ORM\OrderBy({"order" = "ASC"}) * @var CompanyServiceResource[] */ protected $resources; - + /** + * @ORM\OneToMany(targetEntity="CustomerCaseStudy", mappedBy="company_service", cascade={"persist"}, orphanRemoval=true) + * @ORM\OrderBy({"order" = "ASC"}) + * @var CustomerCaseStudy[] + */ + protected $case_studies; use One2ManyPropertyTrait; @@ -128,6 +133,7 @@ public function __construct() $this->reviews = new ArrayCollection(); $this->videos = new ArrayCollection(); $this->resources = new ArrayCollection(); + $this->case_studies = new ArrayCollection(); } /** @@ -226,4 +232,12 @@ public function getResources() { return $this->resources->toArray(); } + + /** + * @return CustomerCaseStudy[] + */ + public function getCaseStudies() + { + return $this->case_studies->toArray(); + } } \ No newline at end of file diff --git a/app/Models/Foundation/Marketplace/CustomerCaseStudy.php b/app/Models/Foundation/Marketplace/CustomerCaseStudy.php new file mode 100644 index 000000000..e407fd15b --- /dev/null +++ b/app/Models/Foundation/Marketplace/CustomerCaseStudy.php @@ -0,0 +1,108 @@ +name; + } + + public function setName(string $name): self + { + $this->name = trim($name); + return $this; + } + + public function getUri(): ?string + { + return $this->uri; + } + + public function setUri(?string $uri): self + { + $this->uri = $uri !== null ? trim($uri) : null; + return $this; + } + + public function getOrder(): int + { + return $this->order; + } + + public function setOrder(int $order): self + { + $this->order = $order; + return $this; + } + + /** + * @return CompanyService + */ + public function getOwner(): CompanyService + { + return $this->company_service; + } + + public function setOwner(CompanyService $new_owner): self + { + $this->company_service = $new_owner; + return $this; + } +} diff --git a/app/Models/Foundation/Marketplace/RegionalSupport.php b/app/Models/Foundation/Marketplace/RegionalSupport.php index b1be0eadf..a27d3f433 100644 --- a/app/Models/Foundation/Marketplace/RegionalSupport.php +++ b/app/Models/Foundation/Marketplace/RegionalSupport.php @@ -13,6 +13,7 @@ **/ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping AS ORM; +use models\utils\One2ManyPropertyTrait; use models\utils\SilverstripeBaseModel; /** * @ORM\Entity @@ -22,6 +23,16 @@ */ class RegionalSupport extends SilverstripeBaseModel { + use One2ManyPropertyTrait; + + protected $getIdMappings = [ + 'getRegionId' => 'region', + ]; + + protected $hasPropertyMappings = [ + 'hasRegion' => 'region', + ]; + /** * @ORM\Column(name="Order", type="integer") * @var int diff --git a/database/migrations/model/Version20260115181251.php b/database/migrations/model/Version20260115181251.php new file mode 100644 index 000000000..92544e85d --- /dev/null +++ b/database/migrations/model/Version20260115181251.php @@ -0,0 +1,59 @@ +string("Name")->setLength(250)->setNotnull(true); + $table->string("Uri")->setLength(250)->setNotnull(false); + $table->integer("`Order`" )->setNotnull(true)->setDefault(1); + + // FK + $table->integer("OwnerID", false, false)->setNotnull(true); + $table->index("OwnerID", "OwnerID"); + $table->foreign("CompanyService", "OwnerID", "ID", ["onDelete" => "CASCADE"]); + + $table->unique(['Name', 'OwnerID']); + }); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema): void + { + $schema->dropTable(self::TableName); + } +}