Product text import from agency XLSX workbooks
VITEC Import module: Products tab is now a searchable/sortable product overview. "Edit Product" opens an XLSX upload with per-field source mapping (component + cell), old/new preview and checkbox apply via DataHandler; the mapping and manual matches are persisted and preselect the next workbook. Category workbooks are detected and rejected. - new: ProductXlsxReader (PhpSpreadsheet), ProductTextImportController, Products/ProductTexts templates, 4 module routes - related products: per-pair card text in new side table tx_vitec_product_related_text (survives MM rewrites), emitted as `cardtext` in the product JSON; missing MM relations added add-only - card copy read from Body Copy (D) with fallback to CTA/Card Copy (E) - the workbooks fill either depending on row type - product detail page <title> now uses seotitle with title fallback (provider made singleton and fed from the JSON renderer) - per-user recent-search badges; last loaded workbook stored per product (tx_vitec_product_workbook), Edit Product reopens on it - composer: add phpoffice/phpspreadsheet ^5.9 - diagnostics: migrations/check_workbook.php
This commit is contained in:
1 parent
12eb40614b
commit
7bd1161abf
28 files changed
+2594
-39
No files matched your search
@@ -720,6 +720,7 @@ class Product extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
$this->categories = new ObjectStorage();
|
||||
$this->productimage = new ObjectStorage();
|
||||
$this->heroimage = new ObjectStorage();
|
||||
$this->downloads = new ObjectStorage();
|
||||
}
|
||||
|
||||
@@ -977,6 +978,98 @@ class Product extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
{
|
||||
$this->relatedprodukt = $relatedprodukt;
|
||||
}
|
||||
/**
|
||||
* Hero images
|
||||
*
|
||||
* @var ObjectStorage<FileReference>
|
||||
* @TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove")
|
||||
*/
|
||||
protected $heroimage;
|
||||
|
||||
/**
|
||||
* Second description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description2 = '';
|
||||
|
||||
/**
|
||||
* Capabilities
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $capabilities = '';
|
||||
|
||||
/**
|
||||
* Portfolio link (typolink parameter)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $portfolio = '';
|
||||
|
||||
/**
|
||||
* @return ObjectStorage<FileReference>
|
||||
*/
|
||||
public function getHeroimage(): ObjectStorage
|
||||
{
|
||||
return $this->heroimage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectStorage<FileReference> $heroimage
|
||||
*/
|
||||
public function setHeroimage(ObjectStorage $heroimage): void
|
||||
{
|
||||
$this->heroimage = $heroimage;
|
||||
}
|
||||
|
||||
public function getDescription2(): string
|
||||
{
|
||||
return $this->description2;
|
||||
}
|
||||
|
||||
public function setDescription2(string $description2): void
|
||||
{
|
||||
$this->description2 = $description2;
|
||||
}
|
||||
|
||||
public function getCapabilities(): string
|
||||
{
|
||||
return $this->capabilities;
|
||||
}
|
||||
|
||||
public function setCapabilities(string $capabilities): void
|
||||
{
|
||||
$this->capabilities = $capabilities;
|
||||
}
|
||||
|
||||
public function getPortfolio(): string
|
||||
{
|
||||
return $this->portfolio;
|
||||
}
|
||||
|
||||
public function setPortfolio(string $portfolio): void
|
||||
{
|
||||
$this->portfolio = $portfolio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intro text above the related products
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $textrelatedproducts = '';
|
||||
|
||||
public function getTextrelatedproducts(): string
|
||||
{
|
||||
return $this->textrelatedproducts;
|
||||
}
|
||||
|
||||
public function setTextrelatedproducts(string $textrelatedproducts): void
|
||||
{
|
||||
$this->textrelatedproducts = $textrelatedproducts;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user