Files
VITEC-website/packages/vitec/Classes/Domain/Model/Solution.php
T
orascheandClaude Fable 5 6811463343 Product texts: mapping completed; product model: solutions + resources
Two work packages, one deploy.

Workbook field mapping completed (2026-09-18)
- highlights <- g:Technical Highlight (new spec-row component of the
  full agency delivery; composeGroup() is generic, no change needed)
- applications <- g:Why Choose Card (benefit cards as one block)
- seometa <- new composed source x:seometa (Introduction body trimmed
  at a word boundary to ~155 chars - the SEO sheet ships no meta
  description, a trimmed intro beats an empty tag)
- teaser stays the hero one-liner, settling the varchar(255) question
- fix: "Save mapping" now merges over the stored mapping instead of
  overwriting it - an empty dropdown no longer wipes a stored selector

Product model: solutions relation and Resources tab (2026-09-24)
- closes the gaps the full workbook walkthrough exposed (rows the
  import deliberately skips because the model had no place for them)
- solutions: MM multi select to tx_vitec_domain_model_solution
  (tx_vitec_product_solution_mm, relatedprodukt pattern), emitted by
  both product renderers as solution cards in the shared shape
- Resources tab: inline child table tx_vitec_product_resource - per
  entry a type (documentation/support), an editable card title/text,
  an icon (free text with a value-picker seed set) and one link
  (page/url/file/record via the link wizard). Deliberately no Extbase
  model: only the UserFunc path reads the rows.
- datasheets: own MM selection of download records below the resource
  list (tx_vitec_product_datasheet_mm); emitted into the SAME
  resources envelope as ready-made type=datasheet cards (title/teaser/
  icon from the record, url = the public /download/<slug> route, uid
  fallback - private/hidden downloads 404 as everywhere)
- JSON `resources` (detail payload only, like heroimage): list envelope
  {layout, items[]}; a hand-written card whose link is empty or
  unresolvable is not emitted; layout switches to carousel above three
  cards in total
- solutions hybrid (same day, after analysing all 100 workbooks: their
  Solution Cards reference the 8 GROUPS in 98% of cases): new is_group
  flag on the solution model, new idempotent CLI
  vitec:create-solution-groups (8 group records; title source is
  AlignSolutionsCommand::TARGET - now public -, category = the group's
  own category, detail_page = the /solutions group page with -N
  disambiguation). Group records are invisible to the solution list
  and to vitec:align-solutions and only selectable in the product
  relation; product solution cards carry isGroup
- spec raised to v1.18 (7.15 member table, 7.13.3 note, revision row;
  the footer had been stuck at v1.15 since 1.16/1.17)

Requires on the server:
    vendor/bin/typo3 database:updateschema "*.add,*.change"
    vendor/bin/typo3 cache:flush

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-24 14:47:04 +02:00

226 lines
4.3 KiB
PHP

<?php
namespace Evomedien\Vitec\Domain\Model;
use TYPO3\CMS\Extbase\Domain\Model\Category;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
class Solution extends AbstractEntity
{
/**
* @var string
*/
protected $title = '';
/**
* @var string
*/
protected $slug = '';
/**
* Page uid presenting this solution (TCA type "group", allowed: pages).
*
* @var int
*/
protected $detailPage = 0;
/**
* @var string
*/
protected $subtitle = '';
/**
* @var string
*/
protected $teaser = '';
/**
* @var string
*/
protected $description = '';
/**
* @var \TYPO3\CMS\Extbase\Domain\Model\FileReference
* @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove")
*/
protected $image = null;
/**
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\Category>
* @TYPO3\CMS\Extbase\Annotation\ORM\Lazy
*/
protected $categories;
public function __construct()
{
$this->categories = new ObjectStorage();
}
/* ---------------------------------------------- */
/* Getter und Setter */
/* ---------------------------------------------- */
/**
* @return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle(string $title): void
{
$this->title = $title;
}
/**
* @return string
*/
public function getSlug(): string
{
return $this->slug;
}
/**
* @param string $slug
*/
public function setSlug(string $slug): void
{
$this->slug = $slug;
}
/**
* @return int
*/
public function getDetailPage(): int
{
return $this->detailPage;
}
/**
* @param int $detailPage
*/
public function setDetailPage(int $detailPage): void
{
$this->detailPage = $detailPage;
}
/**
* @return string
*/
public function getSubtitle(): string
{
return $this->subtitle;
}
/**
* @param string $subtitle
*/
public function setSubtitle(string $subtitle): void
{
$this->subtitle = $subtitle;
}
/**
* @return string
*/
public function getTeaser(): string
{
return $this->teaser;
}
/**
* @param string $teaser
*/
public function setTeaser(string $teaser): void
{
$this->teaser = $teaser;
}
/**
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription(string $description): void
{
$this->description = $description;
}
/**
* @return \TYPO3\CMS\Extbase\Domain\Model\FileReference|null
*/
public function getImage()
{
return $this->image;
}
/**
* @param \TYPO3\CMS\Extbase\Domain\Model\FileReference $image
*/
public function setImage(\TYPO3\CMS\Extbase\Domain\Model\FileReference $image): void
{
$this->image = $image;
}
/**
* @param Category $category
*/
public function addCategory(Category $category): void
{
$this->categories->attach($category);
}
/**
* @param Category $categoryToRemove
*/
public function removeCategory(Category $categoryToRemove): void
{
$this->categories->detach($categoryToRemove);
}
/**
* @return ObjectStorage<Category>
*/
public function getCategories(): ObjectStorage
{
return $this->categories;
}
/**
* @param ObjectStorage<Category> $categories
*/
public function setCategories(ObjectStorage $categories): void
{
$this->categories = $categories;
}
/**
* Group-level record (one of the 8 solution groups) - hybrid decision
* 2026-09-24. Excluded from lists; selectable in product relations.
*
* @var bool
*/
protected $isGroup = false;
public function getIsGroup(): bool
{
return $this->isGroup;
}
public function setIsGroup(bool $isGroup): void
{
$this->isGroup = $isGroup;
}
}