Initial commit - Typo3 11.5.41
This commit is contained in:
383
typo3conf/ext/news/Classes/Domain/Model/Category.php
Normal file
383
typo3conf/ext/news/Classes/Domain/Model/Category.php
Normal file
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Category Model
|
||||
*/
|
||||
class Category extends AbstractEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $sorting = 0;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $crdate;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $tstamp;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $starttime;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $endtime;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $hidden = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $sysLanguageUid = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $l10nParent = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var \GeorgRinger\News\Domain\Model\Category
|
||||
* @TYPO3\CMS\Extbase\Annotation\ORM\Lazy
|
||||
*/
|
||||
protected $parentcategory;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\GeorgRinger\News\Domain\Model\FileReference>
|
||||
* @TYPO3\CMS\Extbase\Annotation\ORM\Lazy
|
||||
*/
|
||||
protected $images;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $shortcut = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $singlePid = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $importId = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $importSource = '';
|
||||
|
||||
/**
|
||||
* keep it as string as it should be only used during imports
|
||||
* @var string
|
||||
*/
|
||||
protected $feGroup = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoTitle = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoDescription = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoHeadline = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoText = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $slug = '';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->images = new ObjectStorage();
|
||||
}
|
||||
|
||||
public function getSorting(): int
|
||||
{
|
||||
return $this->sorting;
|
||||
}
|
||||
|
||||
public function setSorting(int $sorting): void
|
||||
{
|
||||
$this->sorting = $sorting;
|
||||
}
|
||||
|
||||
public function getCrdate(): ?\DateTime
|
||||
{
|
||||
return $this->crdate;
|
||||
}
|
||||
|
||||
public function setCrdate(\DateTime $crdate): void
|
||||
{
|
||||
$this->crdate = $crdate;
|
||||
}
|
||||
|
||||
public function getTstamp(): ?\DateTime
|
||||
{
|
||||
return $this->tstamp;
|
||||
}
|
||||
|
||||
public function setTstamp(\DateTime $tstamp): void
|
||||
{
|
||||
$this->tstamp = $tstamp;
|
||||
}
|
||||
|
||||
public function getStarttime(): ?\DateTime
|
||||
{
|
||||
return $this->starttime;
|
||||
}
|
||||
|
||||
public function setStarttime(\DateTime $starttime): void
|
||||
{
|
||||
$this->starttime = $starttime;
|
||||
}
|
||||
|
||||
public function getEndtime(): ?\DateTime
|
||||
{
|
||||
return $this->endtime;
|
||||
}
|
||||
|
||||
public function setEndtime(\DateTime $endtime): void
|
||||
{
|
||||
$this->endtime = $endtime;
|
||||
}
|
||||
|
||||
public function getHidden(): bool
|
||||
{
|
||||
return $this->hidden;
|
||||
}
|
||||
|
||||
public function setHidden(bool $hidden): void
|
||||
{
|
||||
$this->hidden = $hidden;
|
||||
}
|
||||
|
||||
public function getSysLanguageUid(): int
|
||||
{
|
||||
// int cast is needed as $this->_languageUid is null by default
|
||||
return (int)$this->_languageUid;
|
||||
}
|
||||
|
||||
public function setSysLanguageUid(int $sysLanguageUid): void
|
||||
{
|
||||
$this->_languageUid = $sysLanguageUid;
|
||||
}
|
||||
|
||||
public function getL10nParent(): int
|
||||
{
|
||||
return $this->l10nParent;
|
||||
}
|
||||
|
||||
public function setL10nParent(int $l10nParent): void
|
||||
{
|
||||
$this->l10nParent = $l10nParent;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(string $description): void
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getParentcategory(): ?\GeorgRinger\News\Domain\Model\Category
|
||||
{
|
||||
return $this->parentcategory instanceof LazyLoadingProxy
|
||||
? $this->parentcategory->_loadRealInstance()
|
||||
: $this->parentcategory;
|
||||
}
|
||||
|
||||
public function setParentcategory(\GeorgRinger\News\Domain\Model\Category $category): void
|
||||
{
|
||||
$this->parentcategory = $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return ObjectStorage<FileReference>
|
||||
*/
|
||||
public function getImages(): ObjectStorage
|
||||
{
|
||||
return $this->images;
|
||||
}
|
||||
|
||||
public function setImages(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $images): void
|
||||
{
|
||||
$this->images = $images;
|
||||
}
|
||||
|
||||
public function addImage(FileReference $image): void
|
||||
{
|
||||
$this->images->attach($image);
|
||||
}
|
||||
|
||||
public function removeImage(FileReference $image): void
|
||||
{
|
||||
$this->images->detach($image);
|
||||
}
|
||||
|
||||
public function getFirstImage(): ?FileReference
|
||||
{
|
||||
$images = $this->getImages();
|
||||
$images->rewind();
|
||||
|
||||
return $images->valid() ? $images->current() : null;
|
||||
}
|
||||
|
||||
public function getShortcut(): int
|
||||
{
|
||||
return $this->shortcut;
|
||||
}
|
||||
|
||||
public function setShortcut(int $shortcut): void
|
||||
{
|
||||
$this->shortcut = $shortcut;
|
||||
}
|
||||
|
||||
public function getSinglePid(): int
|
||||
{
|
||||
return $this->singlePid;
|
||||
}
|
||||
|
||||
public function setSinglePid(int $singlePid): void
|
||||
{
|
||||
$this->singlePid = $singlePid;
|
||||
}
|
||||
|
||||
public function getImportId(): string
|
||||
{
|
||||
return $this->importId;
|
||||
}
|
||||
|
||||
public function setImportId(string $importId): void
|
||||
{
|
||||
$this->importId = $importId;
|
||||
}
|
||||
|
||||
public function getImportSource(): string
|
||||
{
|
||||
return $this->importSource;
|
||||
}
|
||||
|
||||
public function setImportSource(string $importSource): void
|
||||
{
|
||||
$this->importSource = $importSource;
|
||||
}
|
||||
|
||||
public function getFeGroup(): string
|
||||
{
|
||||
return $this->feGroup;
|
||||
}
|
||||
|
||||
public function setFeGroup(string $feGroup): void
|
||||
{
|
||||
$this->feGroup = $feGroup;
|
||||
}
|
||||
|
||||
public function getSeoTitle(): string
|
||||
{
|
||||
return $this->seoTitle;
|
||||
}
|
||||
|
||||
public function setSeoTitle(string $seoTitle): void
|
||||
{
|
||||
$this->seoTitle = $seoTitle;
|
||||
}
|
||||
|
||||
public function getSeoDescription(): string
|
||||
{
|
||||
return $this->seoDescription;
|
||||
}
|
||||
|
||||
public function setSeoDescription(string $seoDescription): void
|
||||
{
|
||||
$this->seoDescription = $seoDescription;
|
||||
}
|
||||
|
||||
public function getSeoHeadline(): string
|
||||
{
|
||||
return $this->seoHeadline;
|
||||
}
|
||||
|
||||
public function setSeoHeadline(string $seoHeadline): void
|
||||
{
|
||||
$this->seoHeadline = $seoHeadline;
|
||||
}
|
||||
|
||||
public function getSeoText(): string
|
||||
{
|
||||
return $this->seoText;
|
||||
}
|
||||
|
||||
public function setSeoText(string $seoText): void
|
||||
{
|
||||
$this->seoText = $seoText;
|
||||
}
|
||||
|
||||
public function getSlug(): string
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): void
|
||||
{
|
||||
$this->slug = $slug;
|
||||
}
|
||||
}
|
||||
17
typo3conf/ext/news/Classes/Domain/Model/DemandInterface.php
Normal file
17
typo3conf/ext/news/Classes/Domain/Model/DemandInterface.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Demanded repository interface
|
||||
*/
|
||||
interface DemandInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model\Dto;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Administration Demand model
|
||||
*/
|
||||
class AdministrationDemand extends NewsDemand
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $recursive = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $selectedCategories = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sortingField = 'datetime';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sortingDirection = 'desc';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $searchWord = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $hidden = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $archived = 0;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRecursive(): string
|
||||
{
|
||||
return $this->recursive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $recursive
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setRecursive(string $recursive): void
|
||||
{
|
||||
$this->recursive = $recursive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSelectedCategories(): array
|
||||
{
|
||||
return $this->selectedCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $selectedCategories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSelectedCategories($selectedCategories)
|
||||
{
|
||||
if ($selectedCategories === '0' || $selectedCategories === ['0']) {
|
||||
return;
|
||||
}
|
||||
if (is_string($selectedCategories)) {
|
||||
$selectedCategories = explode(',', $selectedCategories);
|
||||
}
|
||||
$this->selectedCategories = $selectedCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSortingField(): string
|
||||
{
|
||||
return $this->sortingField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sortingField
|
||||
* @return void
|
||||
*/
|
||||
public function setSortingField(string $sortingField): void
|
||||
{
|
||||
$this->sortingField = $sortingField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSortingDirection(): string
|
||||
{
|
||||
return $this->sortingDirection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sortingDirection
|
||||
* @return void
|
||||
*/
|
||||
public function setSortingDirection(string $sortingDirection): void
|
||||
{
|
||||
$this->sortingDirection = $sortingDirection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSearchWord(): string
|
||||
{
|
||||
return $this->searchWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $searchWord
|
||||
* @return void
|
||||
*/
|
||||
public function setSearchWord(string $searchWord): void
|
||||
{
|
||||
$this->searchWord = $searchWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getHidden(): int
|
||||
{
|
||||
return $this->hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $hidden
|
||||
* @return void
|
||||
*/
|
||||
public function setHidden(int $hidden): void
|
||||
{
|
||||
$this->hidden = $hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getArchived(): int
|
||||
{
|
||||
return $this->archived;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $archived
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setArchived(int $archived): void
|
||||
{
|
||||
$this->archived = $archived;
|
||||
}
|
||||
}
|
||||
188
typo3conf/ext/news/Classes/Domain/Model/Dto/EmConfiguration.php
Normal file
188
typo3conf/ext/news/Classes/Domain/Model/Dto/EmConfiguration.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model\Dto;
|
||||
|
||||
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extension Manager configuration
|
||||
*/
|
||||
class EmConfiguration
|
||||
{
|
||||
|
||||
/**
|
||||
* Fill the properties properly
|
||||
*
|
||||
* @param array $configuration em configuration
|
||||
*/
|
||||
public function __construct(array $configuration = [])
|
||||
{
|
||||
if (empty($configuration)) {
|
||||
try {
|
||||
$extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class);
|
||||
$configuration = $extensionConfiguration->get('news');
|
||||
} catch (\Exception $exception) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
foreach ($configuration as $key => $value) {
|
||||
if (property_exists(__CLASS__, $key)) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @var int */
|
||||
protected $tagPid = 0;
|
||||
|
||||
/** @var bool */
|
||||
protected $prependAtCopy = true;
|
||||
|
||||
/** @var string */
|
||||
protected $categoryRestriction = '';
|
||||
|
||||
/** @var bool */
|
||||
protected $categoryBeGroupTceFormsRestriction = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $contentElementRelation = true;
|
||||
|
||||
/** @var bool */
|
||||
protected $contentElementPreview = true;
|
||||
|
||||
/** @var bool */
|
||||
protected $manualSorting = false;
|
||||
|
||||
/** @var string */
|
||||
protected $archiveDate = 'date';
|
||||
|
||||
/** @var bool */
|
||||
protected $dateTimeNotRequired = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $showImporter = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $rteForTeaser = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $showAdministrationModule = true;
|
||||
|
||||
/** @var bool */
|
||||
protected $hidePageTreeForAdministrationModule = false;
|
||||
|
||||
/** @var int */
|
||||
protected $storageUidImporter = 1;
|
||||
|
||||
/** @var string */
|
||||
protected $resourceFolderImporter = '/news_import';
|
||||
|
||||
/** @var bool */
|
||||
protected $advancedMediaPreview = true;
|
||||
|
||||
/** @var string */
|
||||
protected $slugBehaviour = 'unique';
|
||||
|
||||
public function getTagPid(): int
|
||||
{
|
||||
return (int)$this->tagPid;
|
||||
}
|
||||
|
||||
public function getPrependAtCopy(): bool
|
||||
{
|
||||
return (bool)$this->prependAtCopy;
|
||||
}
|
||||
|
||||
public function getCategoryRestriction(): string
|
||||
{
|
||||
return $this->categoryRestriction;
|
||||
}
|
||||
|
||||
public function getCategoryBeGroupTceFormsRestriction(): bool
|
||||
{
|
||||
return (bool)$this->categoryBeGroupTceFormsRestriction;
|
||||
}
|
||||
|
||||
public function getContentElementRelation(): bool
|
||||
{
|
||||
return (bool)$this->contentElementRelation;
|
||||
}
|
||||
|
||||
public function getContentElementPreview(): bool
|
||||
{
|
||||
return (bool)$this->contentElementPreview;
|
||||
}
|
||||
|
||||
public function getManualSorting(): bool
|
||||
{
|
||||
return (bool)$this->manualSorting;
|
||||
}
|
||||
|
||||
public function getArchiveDate(): string
|
||||
{
|
||||
return $this->archiveDate;
|
||||
}
|
||||
|
||||
public function getShowImporter(): bool
|
||||
{
|
||||
return (bool)$this->showImporter;
|
||||
}
|
||||
|
||||
public function setShowAdministrationModule($showAdministrationModule): void
|
||||
{
|
||||
$this->showAdministrationModule = $showAdministrationModule;
|
||||
}
|
||||
|
||||
public function getShowAdministrationModule(): bool
|
||||
{
|
||||
return (bool)$this->showAdministrationModule;
|
||||
}
|
||||
|
||||
public function getRteForTeaser(): bool
|
||||
{
|
||||
return (bool)$this->rteForTeaser;
|
||||
}
|
||||
|
||||
public function getResourceFolderImporter(): string
|
||||
{
|
||||
return $this->resourceFolderImporter;
|
||||
}
|
||||
|
||||
public function getStorageUidImporter(): int
|
||||
{
|
||||
return (int)$this->storageUidImporter;
|
||||
}
|
||||
|
||||
public function getDateTimeNotRequired(): bool
|
||||
{
|
||||
return (bool)$this->dateTimeNotRequired;
|
||||
}
|
||||
|
||||
public function getDateTimeRequired(): bool
|
||||
{
|
||||
return !(bool)$this->dateTimeNotRequired;
|
||||
}
|
||||
|
||||
public function getHidePageTreeForAdministrationModule(): bool
|
||||
{
|
||||
return (bool)$this->hidePageTreeForAdministrationModule;
|
||||
}
|
||||
|
||||
public function isAdvancedMediaPreview(): bool
|
||||
{
|
||||
return (bool)$this->advancedMediaPreview;
|
||||
}
|
||||
|
||||
public function getSlugBehaviour(): string
|
||||
{
|
||||
return $this->slugBehaviour;
|
||||
}
|
||||
}
|
||||
734
typo3conf/ext/news/Classes/Domain/Model/Dto/NewsDemand.php
Normal file
734
typo3conf/ext/news/Classes/Domain/Model/Dto/NewsDemand.php
Normal file
@@ -0,0 +1,734 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model\Dto;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
use GeorgRinger\News\Domain\Model\DemandInterface;
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
|
||||
|
||||
/**
|
||||
* News Demand object which holds all information to get the correct news records.
|
||||
*/
|
||||
class NewsDemand extends AbstractEntity implements DemandInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $categories = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $categoryConjunction = '';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $includeSubCategories = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $author = '';
|
||||
|
||||
/** @var string */
|
||||
protected $tags = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $archiveRestriction = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $timeRestriction = '';
|
||||
|
||||
/** @var string */
|
||||
protected $timeRestrictionHigh = '';
|
||||
|
||||
/** @var int */
|
||||
protected $topNewsRestriction = 0;
|
||||
|
||||
/** @var string */
|
||||
protected $dateField = '';
|
||||
|
||||
/** @var int */
|
||||
protected $month = 0;
|
||||
|
||||
/** @var int */
|
||||
protected $year = 0;
|
||||
|
||||
/** @var int */
|
||||
protected $day = 0;
|
||||
|
||||
/** @var string */
|
||||
protected $searchFields = '';
|
||||
|
||||
/** @var Search */
|
||||
protected $search;
|
||||
|
||||
/** @var string */
|
||||
protected $order = '';
|
||||
|
||||
/** @var string */
|
||||
protected $orderByAllowed = '';
|
||||
|
||||
/** @var bool */
|
||||
protected $topNewsFirst = false;
|
||||
|
||||
/** @var string */
|
||||
protected $storagePage = '';
|
||||
|
||||
/** @var int */
|
||||
protected $limit = 0;
|
||||
|
||||
/** @var int */
|
||||
protected $offset = 0;
|
||||
|
||||
/** @var bool */
|
||||
protected $excludeAlreadyDisplayedNews = false;
|
||||
|
||||
/** @var string */
|
||||
protected $hideIdList = '';
|
||||
|
||||
/** @var string */
|
||||
protected $idList = '';
|
||||
|
||||
/** @var string */
|
||||
protected $action = '';
|
||||
|
||||
/** @var string */
|
||||
protected $class = '';
|
||||
|
||||
/**
|
||||
* List of allowed types
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $types = [];
|
||||
|
||||
/**
|
||||
* Holding custom data, use e.g. your ext key as array key
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_customSettings = [];
|
||||
|
||||
/**
|
||||
* Set archive settings
|
||||
*
|
||||
* @param string $archiveRestriction archive setting
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setArchiveRestriction(string $archiveRestriction): NewsDemand
|
||||
{
|
||||
$this->archiveRestriction = $archiveRestriction;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get archive setting
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getArchiveRestriction(): string
|
||||
{
|
||||
return $this->archiveRestriction;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of allowed categories
|
||||
*
|
||||
* @param array $categories categories
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setCategories(array $categories): NewsDemand
|
||||
{
|
||||
$this->categories = $categories;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed categories
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCategories(): array
|
||||
{
|
||||
return $this->categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set category mode
|
||||
*
|
||||
* @param string $categoryConjunction
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setCategoryConjunction(string $categoryConjunction): NewsDemand
|
||||
{
|
||||
$this->categoryConjunction = $categoryConjunction;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get category mode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCategoryConjunction(): string
|
||||
{
|
||||
return $this->categoryConjunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get include sub categories
|
||||
* @return bool
|
||||
*/
|
||||
public function getIncludeSubCategories(): bool
|
||||
{
|
||||
return (boolean)$this->includeSubCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includeSubCategories
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setIncludeSubCategories(bool $includeSubCategories): NewsDemand
|
||||
{
|
||||
$this->includeSubCategories = $includeSubCategories;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set author
|
||||
*
|
||||
* @param string $author
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setAuthor(string $author): NewsDemand
|
||||
{
|
||||
$this->author = $author;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get author
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthor(): string
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tags
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTags(): string
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Tags
|
||||
*
|
||||
* @param string $tags tags
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setTags(string $tags): NewsDemand
|
||||
{
|
||||
$this->tags = $tags;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set time limit low, either integer or string
|
||||
*
|
||||
* @param string|int $timeRestriction
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setTimeRestriction($timeRestriction): NewsDemand
|
||||
{
|
||||
$this->timeRestriction = $timeRestriction;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time limit low
|
||||
*
|
||||
* @return string|int
|
||||
*/
|
||||
public function getTimeRestriction()
|
||||
{
|
||||
return $this->timeRestriction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time limit high
|
||||
*
|
||||
* @return string|int
|
||||
*/
|
||||
public function getTimeRestrictionHigh()
|
||||
{
|
||||
return $this->timeRestrictionHigh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set time limit high
|
||||
*
|
||||
* @param string|int $timeRestrictionHigh
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setTimeRestrictionHigh($timeRestrictionHigh): NewsDemand
|
||||
{
|
||||
$this->timeRestrictionHigh = $timeRestrictionHigh;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order
|
||||
*
|
||||
* @param string $order order
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setOrder(string $order): NewsDemand
|
||||
{
|
||||
$this->order = $order;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrder(): string
|
||||
{
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order allowed
|
||||
*
|
||||
* @param string $orderByAllowed allowed fields for ordering
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setOrderByAllowed(string $orderByAllowed): NewsDemand
|
||||
{
|
||||
$this->orderByAllowed = $orderByAllowed;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed order fields
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrderByAllowed(): string
|
||||
{
|
||||
return $this->orderByAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order respect top news flag
|
||||
*
|
||||
* @param bool $topNewsFirst respect top news flag
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setTopNewsFirst(bool $topNewsFirst): NewsDemand
|
||||
{
|
||||
$this->topNewsFirst = $topNewsFirst;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order respect top news flag
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getTopNewsFirst(): bool
|
||||
{
|
||||
return $this->topNewsFirst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set search fields
|
||||
*
|
||||
* @param string $searchFields search fields
|
||||
*
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setSearchFields(string $searchFields): NewsDemand
|
||||
{
|
||||
$this->searchFields = $searchFields;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get search fields
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSearchFields(): string
|
||||
{
|
||||
return $this->searchFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set top news setting
|
||||
*
|
||||
* @param int $topNewsRestriction top news settings
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setTopNewsRestriction(int $topNewsRestriction): NewsDemand
|
||||
{
|
||||
$this->topNewsRestriction = $topNewsRestriction;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get top news setting
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTopNewsRestriction(): int
|
||||
{
|
||||
return $this->topNewsRestriction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of storage pages
|
||||
*
|
||||
* @param string $storagePage storage page list
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setStoragePage(string $storagePage): NewsDemand
|
||||
{
|
||||
$this->storagePage = $storagePage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of storage pages
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStoragePage(): string
|
||||
{
|
||||
return $this->storagePage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get day restriction
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getDay(): int
|
||||
{
|
||||
return $this->day;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set day restriction
|
||||
*
|
||||
* @param int $day
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setDay(int $day): NewsDemand
|
||||
{
|
||||
$this->day = (int)$day;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get month restriction
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getMonth(): int
|
||||
{
|
||||
return $this->month;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set month restriction
|
||||
*
|
||||
* @param int $month month
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setMonth(int $month): NewsDemand
|
||||
{
|
||||
$this->month = (int)$month;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get year restriction
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getYear(): int
|
||||
{
|
||||
return $this->year;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set year restriction
|
||||
*
|
||||
* @param int $year year
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setYear(int $year): NewsDemand
|
||||
{
|
||||
$this->year = (int)$year;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set limit
|
||||
*
|
||||
* @param int $limit limit
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setLimit(int $limit): NewsDemand
|
||||
{
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get limit
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit(): int
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set offset
|
||||
*
|
||||
* @param int $offset offset
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setOffset(int $offset): NewsDemand
|
||||
{
|
||||
$this->offset = $offset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getOffset(): int
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set date field which is used for datemenu
|
||||
*
|
||||
* @param string $dateField datefield
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setDateField(string $dateField): NewsDemand
|
||||
{
|
||||
$this->dateField = $dateField;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date field which is used for datemenu
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDateField(): string
|
||||
{
|
||||
if (in_array($this->dateField, ['datetime', 'archive'], true)
|
||||
|| isset($GLOBALS['TCA']['tx_news_domain_model_news']['columns'][$this->dateField])) {
|
||||
return $this->dateField;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get search object
|
||||
*
|
||||
* @return null|Search
|
||||
*/
|
||||
public function getSearch(): ?Search
|
||||
{
|
||||
return $this->search;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set search object
|
||||
*
|
||||
* @param null|Search $search search object
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setSearch(Search $search = null): NewsDemand
|
||||
{
|
||||
$this->search = $search;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flag if displayed news records should be excluded
|
||||
*
|
||||
* @param bool $excludeAlreadyDisplayedNews
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setExcludeAlreadyDisplayedNews(bool $excludeAlreadyDisplayedNews): NewsDemand
|
||||
{
|
||||
$this->excludeAlreadyDisplayedNews = $excludeAlreadyDisplayedNews;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get flag if displayed news records should be excluded
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getExcludeAlreadyDisplayedNews(): bool
|
||||
{
|
||||
return $this->excludeAlreadyDisplayedNews;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHideIdList(): string
|
||||
{
|
||||
return $this->hideIdList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hideIdList
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setHideIdList(string $hideIdList): NewsDemand
|
||||
{
|
||||
$this->hideIdList = $hideIdList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdList(): string
|
||||
{
|
||||
return $this->idList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $idList
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setIdList(string $idList): NewsDemand
|
||||
{
|
||||
$this->idList = $idList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAction(): string
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setAction(string $action): NewsDemand
|
||||
{
|
||||
$this->action = $action;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClass(): string
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setClass(string $class): NewsDemand
|
||||
{
|
||||
$this->class = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @param string $controller
|
||||
* @return NewsDemand
|
||||
*/
|
||||
public function setActionAndClass(string $action, string $controller): NewsDemand
|
||||
{
|
||||
$this->action = $action;
|
||||
$this->class = $controller;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTypes(): array
|
||||
{
|
||||
return $this->types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set allowed types
|
||||
*
|
||||
* @param array $types
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTypes(array $types): void
|
||||
{
|
||||
$this->types = $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCustomSettings(): array
|
||||
{
|
||||
return $this->_customSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $customSettings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCustomSettings(array $customSettings): void
|
||||
{
|
||||
$this->_customSettings = $customSettings;
|
||||
}
|
||||
}
|
||||
172
typo3conf/ext/news/Classes/Domain/Model/Dto/Search.php
Normal file
172
typo3conf/ext/news/Classes/Domain/Model/Dto/Search.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model\Dto;
|
||||
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* News Demand object which holds all information to get the correct
|
||||
* news records.
|
||||
*/
|
||||
class Search extends AbstractEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* Basic search word
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $subject = '';
|
||||
|
||||
/**
|
||||
* Search fields
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fields = '';
|
||||
|
||||
/**
|
||||
* Minimum date
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $minimumDate = '';
|
||||
|
||||
/**
|
||||
* Maximum date
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $maximumDate = '';
|
||||
|
||||
/**
|
||||
* Field using for date queries
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $dateField = '';
|
||||
|
||||
/** @var bool */
|
||||
protected $splitSubjectWords = false;
|
||||
|
||||
/**
|
||||
* Get the subject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSubject(): string
|
||||
{
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set subject
|
||||
*
|
||||
* @param string $subject
|
||||
*/
|
||||
public function setSubject(string $subject): void
|
||||
{
|
||||
$this->subject = $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fields
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFields(): string
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set fields
|
||||
*
|
||||
* @param string $fields
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFields(string $fields): void
|
||||
{
|
||||
$this->fields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $maximumDate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMaximumDate($maximumDate): void
|
||||
{
|
||||
$this->maximumDate = $maximumDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMaximumDate(): string
|
||||
{
|
||||
return $this->maximumDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $minimumDate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMinimumDate(string $minimumDate): void
|
||||
{
|
||||
$this->minimumDate = $minimumDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMinimumDate(): string
|
||||
{
|
||||
return $this->minimumDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dateField
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDateField($dateField): void
|
||||
{
|
||||
$this->dateField = $dateField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDateField(): string
|
||||
{
|
||||
return $this->dateField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSplitSubjectWords(): bool
|
||||
{
|
||||
return $this->splitSubjectWords;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $splitSubjectWords
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSplitSubjectWords($splitSubjectWords): void
|
||||
{
|
||||
$this->splitSubjectWords = $splitSubjectWords;
|
||||
}
|
||||
}
|
||||
184
typo3conf/ext/news/Classes/Domain/Model/FileReference.php
Normal file
184
typo3conf/ext/news/Classes/Domain/Model/FileReference.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* File Reference
|
||||
*/
|
||||
class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference
|
||||
{
|
||||
const VIEW_DETAIL_ONLY = 0;
|
||||
const VIEW_LIST_AND_DETAIL = 1;
|
||||
const VIEW_LIST_ONLY = 2;
|
||||
|
||||
/**
|
||||
* Obsolete when foreign_selector is supported by ExtBase persistence layer
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $uidLocal = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $alternative = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $link = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $showinpreview = 0;
|
||||
|
||||
/**
|
||||
* Set File uid
|
||||
*
|
||||
* @param int $fileUid
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFileUid($fileUid): void
|
||||
{
|
||||
$this->uidLocal = $fileUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get File UID
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFileUid(): int
|
||||
{
|
||||
return $this->uidLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set alternative
|
||||
*
|
||||
* @param string $alternative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAlternative($alternative): void
|
||||
{
|
||||
$this->alternative = $alternative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alternative
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAlternative(): string
|
||||
{
|
||||
return (string)($this->alternative !== '' ? $this->alternative : $this->getOriginalResource()->getAlternative());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set description
|
||||
*
|
||||
* @param string $description
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDescription($description): void
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return (string)($this->description !== '' ? $this->description : $this->getOriginalResource()->getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set link
|
||||
*
|
||||
* @param string $link
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLink($link): void
|
||||
{
|
||||
$this->link = $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
return (string)($this->link !== '' ? $this->link : $this->getOriginalResource()->getLink());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title
|
||||
*
|
||||
* @param string $title
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTitle($title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return (string)($this->title !== '' ? $this->title : $this->getOriginalResource()->getTitle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set showinpreview
|
||||
*
|
||||
* @param int $showinpreview
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setShowinpreview($showinpreview): void
|
||||
{
|
||||
$this->showinpreview = $showinpreview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get showinpreview
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getShowinpreview(): int
|
||||
{
|
||||
return $this->showinpreview;
|
||||
}
|
||||
}
|
||||
202
typo3conf/ext/news/Classes/Domain/Model/Link.php
Normal file
202
typo3conf/ext/news/Classes/Domain/Model/Link.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractValueObject;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Link model
|
||||
*/
|
||||
class Link extends AbstractValueObject
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $crdate;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $tstamp;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $uri = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $l10nParent = 0;
|
||||
|
||||
/**
|
||||
* Get creation date
|
||||
*
|
||||
* @return null|\DateTime
|
||||
*/
|
||||
public function getCrdate(): ?\DateTime
|
||||
{
|
||||
return $this->crdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set creation date
|
||||
*
|
||||
* @param \DateTime $crdate creation date
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCrdate($crdate): void
|
||||
{
|
||||
$this->crdate = $crdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timestamp
|
||||
*
|
||||
* @return null|\DateTime
|
||||
*/
|
||||
public function getTstamp(): ?\DateTime
|
||||
{
|
||||
return $this->tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timestamp
|
||||
*
|
||||
* @param \DateTime $tstamp timestamp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTstamp($tstamp): void
|
||||
{
|
||||
$this->tstamp = $tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title
|
||||
*
|
||||
* @param string $title title
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTitle($title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set description
|
||||
*
|
||||
* @param string $description description
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDescription($description): void
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uri
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUri(): string
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set uri
|
||||
*
|
||||
* @param string $uri uri
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUri($uri): void
|
||||
{
|
||||
$this->uri = $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sys language
|
||||
*
|
||||
* @param int $sysLanguageUid
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSysLanguageUid($sysLanguageUid): void
|
||||
{
|
||||
$this->_languageUid = $sysLanguageUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sys language
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSysLanguageUid(): int
|
||||
{
|
||||
return $this->_languageUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set l10n parent
|
||||
*
|
||||
* @param int $l10nParent
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setL10nParent($l10nParent): void
|
||||
{
|
||||
$this->l10nParent = $l10nParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get l10n parent
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getL10nParent(): int
|
||||
{
|
||||
return $this->l10nParent;
|
||||
}
|
||||
}
|
||||
1665
typo3conf/ext/news/Classes/Domain/Model/News.php
Normal file
1665
typo3conf/ext/news/Classes/Domain/Model/News.php
Normal file
File diff suppressed because it is too large
Load Diff
17
typo3conf/ext/news/Classes/Domain/Model/NewsDefault.php
Normal file
17
typo3conf/ext/news/Classes/Domain/Model/NewsDefault.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* News model for default news
|
||||
*/
|
||||
class NewsDefault extends News
|
||||
{
|
||||
}
|
||||
17
typo3conf/ext/news/Classes/Domain/Model/NewsExternal.php
Normal file
17
typo3conf/ext/news/Classes/Domain/Model/NewsExternal.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* News model for external news
|
||||
*/
|
||||
class NewsExternal extends News
|
||||
{
|
||||
}
|
||||
17
typo3conf/ext/news/Classes/Domain/Model/NewsInternal.php
Normal file
17
typo3conf/ext/news/Classes/Domain/Model/NewsInternal.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* News model for internal news
|
||||
*/
|
||||
class NewsInternal extends News
|
||||
{
|
||||
}
|
||||
212
typo3conf/ext/news/Classes/Domain/Model/Tag.php
Normal file
212
typo3conf/ext/news/Classes/Domain/Model/Tag.php
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractValueObject;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Tag model
|
||||
*/
|
||||
class Tag extends AbstractValueObject
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $crdate;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $tstamp;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoTitle = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoDescription = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoHeadline = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $seoText = '';
|
||||
|
||||
/** @var string */
|
||||
protected $slug = '';
|
||||
|
||||
/**
|
||||
* Get crdate
|
||||
*
|
||||
* @return null|\DateTime
|
||||
*/
|
||||
public function getCrdate(): ?\DateTime
|
||||
{
|
||||
return $this->crdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set crdate
|
||||
*
|
||||
* @param \DateTime $crdate crdate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCrdate($crdate): void
|
||||
{
|
||||
$this->crdate = $crdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tstamp
|
||||
*
|
||||
* @return null|\DateTime
|
||||
*/
|
||||
public function getTstamp(): ?\DateTime
|
||||
{
|
||||
return $this->tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set tstamp
|
||||
*
|
||||
* @param \DateTime $tstamp tstamp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTstamp($tstamp): void
|
||||
{
|
||||
$this->tstamp = $tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title
|
||||
*
|
||||
* @param string $title title
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTitle($title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSeoTitle(): string
|
||||
{
|
||||
return $this->seoTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $seoTitle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSeoTitle($seoTitle): void
|
||||
{
|
||||
$this->seoTitle = $seoTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSeoDescription(): string
|
||||
{
|
||||
return $this->seoDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $seoDescription
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSeoDescription($seoDescription): void
|
||||
{
|
||||
$this->seoDescription = $seoDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSeoHeadline(): string
|
||||
{
|
||||
return $this->seoHeadline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $seoHeadline
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSeoHeadline($seoHeadline): void
|
||||
{
|
||||
$this->seoHeadline = $seoHeadline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSeoText(): string
|
||||
{
|
||||
return $this->seoText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $seoText
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSeoText($seoText): void
|
||||
{
|
||||
$this->seoText = $seoText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSlug(): string
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSlug($slug): void
|
||||
{
|
||||
$this->slug = $slug;
|
||||
}
|
||||
}
|
||||
573
typo3conf/ext/news/Classes/Domain/Model/TtContent.php
Normal file
573
typo3conf/ext/news/Classes/Domain/Model/TtContent.php
Normal file
@@ -0,0 +1,573 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Model;
|
||||
|
||||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Model of tt_content
|
||||
*/
|
||||
class TtContent extends AbstractEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $crdate;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $tstamp;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $CType = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $header = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $headerPosition = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bodytext = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $colPos = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $image = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $imagewidth = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $imageorient = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $imagecaption = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $imagecols = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $imageborder = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $media = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $layout = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $cols = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $subheader = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $headerLink = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $imageLink = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $imageZoom = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $altText = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $titleText = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $headerLayout = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $listType = '';
|
||||
|
||||
/**
|
||||
* @return null|\DateTime
|
||||
*/
|
||||
public function getCrdate(): ?\DateTime
|
||||
{
|
||||
return $this->crdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $crdate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCrdate($crdate): void
|
||||
{
|
||||
$this->crdate = $crdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|\DateTime
|
||||
*/
|
||||
public function getTstamp(): ?\DateTime
|
||||
{
|
||||
return $this->tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $tstamp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTstamp($tstamp): void
|
||||
{
|
||||
$this->tstamp = $tstamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCType(): string
|
||||
{
|
||||
return $this->CType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ctype
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCType(string $ctype): void
|
||||
{
|
||||
$this->CType = $ctype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHeader(): string
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $header
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHeader(string $header): void
|
||||
{
|
||||
$this->header = $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHeaderPosition(): string
|
||||
{
|
||||
return $this->headerPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $headerPosition
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHeaderPosition(string $headerPosition): void
|
||||
{
|
||||
$this->headerPosition = $headerPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBodytext(): string
|
||||
{
|
||||
return $this->bodytext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $bodytext
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setBodytext(string $bodytext): void
|
||||
{
|
||||
$this->bodytext = $bodytext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the colpos
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getColPos(): int
|
||||
{
|
||||
return (int)$this->colPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set colpos
|
||||
*
|
||||
* @param int $colPos
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setColPos($colPos): void
|
||||
{
|
||||
$this->colPos = $colPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImage(): string
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $image
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImage(string $image): void
|
||||
{
|
||||
$this->image = $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getImagewidth(): int
|
||||
{
|
||||
return $this->imagewidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $imagewidth
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImagewidth(int $imagewidth): void
|
||||
{
|
||||
$this->imagewidth = $imagewidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getImageorient(): int
|
||||
{
|
||||
return $this->imageorient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $imageorient
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImageorient(int $imageorient): void
|
||||
{
|
||||
$this->imageorient = $imageorient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImagecaption(): string
|
||||
{
|
||||
return $this->imagecaption;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $imagecaption
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImagecaption(string $imagecaption): void
|
||||
{
|
||||
$this->imagecaption = $imagecaption;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getImagecols(): int
|
||||
{
|
||||
return $this->imagecols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $imagecols
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImagecols(int $imagecols): void
|
||||
{
|
||||
$this->imagecols = $imagecols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getImageborder(): int
|
||||
{
|
||||
return $this->imageborder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $imageborder
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImageborder(int $imageborder): void
|
||||
{
|
||||
$this->imageborder = $imageborder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMedia(): string
|
||||
{
|
||||
return $this->media;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $media
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMedia(string $media): void
|
||||
{
|
||||
$this->media = $media;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLayout(): string
|
||||
{
|
||||
return $this->layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $layout
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLayout(string $layout): void
|
||||
{
|
||||
$this->layout = $layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCols(): int
|
||||
{
|
||||
return $this->cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $cols
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCols(int $cols): void
|
||||
{
|
||||
$this->cols = $cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSubheader(): string
|
||||
{
|
||||
return $this->subheader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $subheader
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSubheader(string $subheader): void
|
||||
{
|
||||
$this->subheader = $subheader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHeaderLink(): string
|
||||
{
|
||||
return $this->headerLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $headerLink
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHeaderLink(string $headerLink): void
|
||||
{
|
||||
$this->headerLink = $headerLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImageLink(): string
|
||||
{
|
||||
return $this->imageLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $imageLink
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImageLink(string $imageLink): void
|
||||
{
|
||||
$this->imageLink = $imageLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getImageZoom(): string
|
||||
{
|
||||
return $this->imageZoom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $imageZoom
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setImageZoom(string $imageZoom): void
|
||||
{
|
||||
$this->imageZoom = $imageZoom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAltText(): string
|
||||
{
|
||||
return $this->altText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $altText
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAltText(string $altText): void
|
||||
{
|
||||
$this->altText = $altText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitleText(): string
|
||||
{
|
||||
return $this->titleText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $titleText
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTitleText(string $titleText): void
|
||||
{
|
||||
$this->titleText = $titleText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHeaderLayout(): string
|
||||
{
|
||||
return $this->headerLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $headerLayout
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHeaderLayout(string $headerLayout): void
|
||||
{
|
||||
$this->headerLayout = $headerLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getListType(): string
|
||||
{
|
||||
return $this->listType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $listType
|
||||
* @return void
|
||||
*/
|
||||
public function setListType(string $listType): void
|
||||
{
|
||||
$this->listType = $listType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
use GeorgRinger\News\Domain\Model\DemandInterface;
|
||||
use TYPO3\CMS\Core\Information\Typo3Version;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\Storage\BackendInterface;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract demanded repository
|
||||
*/
|
||||
abstract class AbstractDemandedRepository extends Repository implements DemandedRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Persistence\Generic\Storage\BackendInterface
|
||||
*/
|
||||
protected $storageBackend;
|
||||
|
||||
/**
|
||||
* @param \TYPO3\CMS\Extbase\Persistence\Generic\Storage\BackendInterface $storageBackend
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function injectStorageBackend(
|
||||
BackendInterface $storageBackend
|
||||
): void {
|
||||
$this->storageBackend = $storageBackend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of constraints created from a given demand object.
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
|
||||
* @param DemandInterface $demand
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface[]
|
||||
* @abstract
|
||||
*/
|
||||
abstract protected function createConstraintsFromDemand(
|
||||
QueryInterface $query,
|
||||
DemandInterface $demand
|
||||
): array;
|
||||
|
||||
/**
|
||||
* Returns an array of orderings created from a given demand object.
|
||||
*
|
||||
* @param DemandInterface $demand
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface[]
|
||||
* @abstract
|
||||
*/
|
||||
abstract protected function createOrderingsFromDemand(DemandInterface $demand): array;
|
||||
|
||||
/**
|
||||
* Returns the objects of this repository matching the demand.
|
||||
*
|
||||
* @param DemandInterface $demand
|
||||
* @param bool $respectEnableFields
|
||||
* @param bool $disableLanguageOverlayMode
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array
|
||||
*/
|
||||
public function findDemanded(DemandInterface $demand, $respectEnableFields = true, $disableLanguageOverlayMode = false)
|
||||
{
|
||||
$query = $this->generateQuery($demand, $respectEnableFields, $disableLanguageOverlayMode);
|
||||
|
||||
return $query->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database query to get the matching result
|
||||
*
|
||||
* @param DemandInterface $demand
|
||||
* @param bool $respectEnableFields
|
||||
* @param bool $disableLanguageOverlayMode
|
||||
* @return string
|
||||
*/
|
||||
public function findDemandedRaw(DemandInterface $demand, $respectEnableFields = true, $disableLanguageOverlayMode = false): string
|
||||
{
|
||||
$query = $this->generateQuery($demand, $respectEnableFields, $disableLanguageOverlayMode);
|
||||
$versionInformation = GeneralUtility::makeInstance(Typo3Version::class);
|
||||
if ($versionInformation->getMajorVersion() >= 11) {
|
||||
$queryParser = GeneralUtility::makeInstance(Typo3DbQueryParser::class);
|
||||
} else {
|
||||
$queryParser = $this->objectManager->get(Typo3DbQueryParser::class);
|
||||
}
|
||||
|
||||
$queryBuilder = $queryParser->convertQueryToDoctrineQueryBuilder($query);
|
||||
$queryParameters = $queryBuilder->getParameters();
|
||||
$params = [];
|
||||
foreach ($queryParameters as $key => $value) {
|
||||
// prefix array keys with ':'
|
||||
$params[':' . $key] = (is_numeric($value)) ? $value : "'" . $value . "'"; //all non numeric values have to be quoted
|
||||
unset($params[$key]);
|
||||
}
|
||||
// replace placeholders with real values
|
||||
$query = strtr($queryBuilder->getSQL(), $params);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DemandInterface $demand
|
||||
* @param bool $respectEnableFields
|
||||
* @param bool $disableLanguageOverlayMode
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\QueryInterface
|
||||
*/
|
||||
protected function generateQuery(DemandInterface $demand, $respectEnableFields = true, $disableLanguageOverlayMode = false): \TYPO3\CMS\Extbase\Persistence\QueryInterface
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
|
||||
if ($disableLanguageOverlayMode) {
|
||||
$query->getQuerySettings()->setLanguageOverlayMode(false);
|
||||
}
|
||||
|
||||
$constraints = $this->createConstraintsFromDemand($query, $demand);
|
||||
|
||||
// Call hook functions for additional constraints
|
||||
if ($hooks = $GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['Domain/Repository/AbstractDemandedRepository.php']['findDemanded'] ?? []) {
|
||||
$params = [
|
||||
'demand' => $demand,
|
||||
'respectEnableFields' => &$respectEnableFields,
|
||||
'query' => $query,
|
||||
'constraints' => &$constraints,
|
||||
];
|
||||
foreach ($hooks as $reference) {
|
||||
GeneralUtility::callUserFunction($reference, $params, $this);
|
||||
}
|
||||
}
|
||||
|
||||
if ($respectEnableFields === false) {
|
||||
$query->getQuerySettings()->setIgnoreEnableFields(true);
|
||||
|
||||
$constraints[] = $query->equals('deleted', 0);
|
||||
}
|
||||
|
||||
if (!empty($constraints)) {
|
||||
$query->matching(
|
||||
$query->logicalAnd($constraints)
|
||||
);
|
||||
}
|
||||
|
||||
if ($orderings = $this->createOrderingsFromDemand($demand)) {
|
||||
$query->setOrderings($orderings);
|
||||
}
|
||||
|
||||
// @todo consider moving this to a separate function as well
|
||||
if ($demand->getLimit() != null) {
|
||||
$query->setLimit((int)$demand->getLimit());
|
||||
}
|
||||
|
||||
// @todo consider moving this to a separate function as well
|
||||
if ($demand->getOffset() != null) {
|
||||
if (!$query->getLimit()) {
|
||||
$query->setLimit(PHP_INT_MAX);
|
||||
}
|
||||
$query->setOffset((int)$demand->getOffset());
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number objects of this repository matching the demand.
|
||||
*
|
||||
* @param DemandInterface $demand
|
||||
* @return int
|
||||
*/
|
||||
public function countDemanded(DemandInterface $demand, $respectEnableFields = true, $disableLanguageOverlayMode = false): int
|
||||
{
|
||||
$query = $this->generateQuery($demand, $respectEnableFields, $disableLanguageOverlayMode);
|
||||
|
||||
if ($constraints = $this->createConstraintsFromDemand($query, $demand)) {
|
||||
$query->matching(
|
||||
$query->logicalAnd($constraints)
|
||||
);
|
||||
}
|
||||
|
||||
$result = $query->execute();
|
||||
return $result->count();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Get data used in the administration view
|
||||
*/
|
||||
class AdministrationRepository
|
||||
{
|
||||
public function getTotalCounts(): array
|
||||
{
|
||||
$count = [];
|
||||
|
||||
$queryBuilder = $this->getQueryBuilder('tx_news_domain_model_news');
|
||||
$queryBuilder->getRestrictions()->removeAll();
|
||||
|
||||
$count['tx_news_domain_model_news'] = $queryBuilder
|
||||
->count('*')
|
||||
->from('tx_news_domain_model_news')
|
||||
->execute()->fetchColumn(0);
|
||||
|
||||
$queryBuilder = $this->getQueryBuilder('sys_category_record_mm');
|
||||
$count['category_relations'] = $queryBuilder
|
||||
->count('*')
|
||||
->from('sys_category_record_mm')
|
||||
->where($queryBuilder->expr()->like(
|
||||
'tablenames',
|
||||
$queryBuilder->createNamedParameter('tx_news_domain_model_news', \PDO::PARAM_STR)
|
||||
))
|
||||
->execute()->fetchColumn(0);
|
||||
|
||||
if ($count['tx_news_domain_model_news'] > 0 && $count['category_relations']) {
|
||||
$count['_both'] = true;
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
private function getConnection(string $table): Connection
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
|
||||
}
|
||||
|
||||
private function getQueryBuilder(string $table): QueryBuilder
|
||||
{
|
||||
return $this->getConnection($table)->createQueryBuilder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
use Doctrine\DBAL\Connection;
|
||||
use GeorgRinger\News\Domain\Model\Category;
|
||||
use GeorgRinger\News\Domain\Model\DemandInterface;
|
||||
use GeorgRinger\News\Service\CategoryService;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Information\Typo3Version;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
|
||||
|
||||
/**
|
||||
* Category repository with all callable functionality
|
||||
*/
|
||||
class CategoryRepository extends AbstractDemandedRepository
|
||||
{
|
||||
protected function createConstraintsFromDemand(QueryInterface $query, DemandInterface $demand): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function createOrderingsFromDemand(DemandInterface $demand): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find category by import source and import id
|
||||
*
|
||||
* @param string $importSource import source
|
||||
* @param int $importId import id
|
||||
* @param bool $asArray return result as array
|
||||
* @return Category|array
|
||||
*/
|
||||
public function findOneByImportSourceAndImportId($importSource, $importId, $asArray = false)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
$query->getQuerySettings()->setIgnoreEnableFields(true);
|
||||
|
||||
$result = $query->matching(
|
||||
$query->logicalAnd(
|
||||
$query->equals('importSource', $importSource),
|
||||
$query->equals('importId', $importId)
|
||||
)
|
||||
)->execute($asArray);
|
||||
if ($asArray) {
|
||||
if (isset($result[0])) {
|
||||
return $result[0];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return $result->getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find categories by a given pid
|
||||
*
|
||||
* @param int $pid pid
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array
|
||||
*/
|
||||
public function findParentCategoriesByPid($pid)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
return $query->matching(
|
||||
$query->logicalAnd(
|
||||
$query->equals('pid', (int)$pid),
|
||||
$query->equals('parentcategory', 0)
|
||||
)
|
||||
)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find category tree
|
||||
*
|
||||
* @param array $rootIdList list of id s
|
||||
* @return QueryInterface|array
|
||||
*/
|
||||
public function findTree(array $rootIdList, $startingPoint = null)
|
||||
{
|
||||
$subCategories = CategoryService::getChildrenCategories(implode(',', $rootIdList));
|
||||
|
||||
$idList = explode(',', $subCategories);
|
||||
if (empty($idList)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$ordering = ['sorting' => QueryInterface::ORDER_ASCENDING];
|
||||
$categories = $this->findByIdList($idList, $ordering, $startingPoint);
|
||||
$flatCategories = [];
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
$flatCategories[$category->getUid()] = [
|
||||
'item' => $category,
|
||||
'parent' => ($category->getParentcategory()) ? $category->getParentcategory()->getUid() : null
|
||||
];
|
||||
}
|
||||
|
||||
$tree = [];
|
||||
|
||||
// If leaves are selected without its parents selected, those are shown as parent
|
||||
foreach ($flatCategories as $id => &$flatCategory) {
|
||||
if (!isset($flatCategories[$flatCategory['parent']])) {
|
||||
$flatCategory['parent'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($flatCategories as $id => &$node) {
|
||||
if ($node['parent'] === null) {
|
||||
$tree[$id] = &$node;
|
||||
} else {
|
||||
$flatCategories[$node['parent']]['children'][$id] = &$node;
|
||||
}
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find categories by a given pid
|
||||
*
|
||||
* @param array $idList list of id s
|
||||
* @param array $ordering ordering
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array
|
||||
*/
|
||||
public function findByIdList(array $idList, array $ordering = [], $startingPoint = null)
|
||||
{
|
||||
if (empty($idList)) {
|
||||
throw new \InvalidArgumentException('The given id list is empty.', 1484823597);
|
||||
}
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
$query->getQuerySettings()->setRespectSysLanguage(true);
|
||||
|
||||
if (count($ordering) > 0) {
|
||||
$query->setOrderings($ordering);
|
||||
}
|
||||
$this->overlayTranslatedCategoryIds($idList);
|
||||
|
||||
$conditions = [];
|
||||
$conditions[] = $query->in('uid', $idList);
|
||||
|
||||
if (is_null($startingPoint) === false) {
|
||||
$conditions[] = $query->in('pid', GeneralUtility::trimExplode(',', $startingPoint, true));
|
||||
}
|
||||
|
||||
return $query->matching(
|
||||
$query->logicalAnd(
|
||||
$conditions
|
||||
)
|
||||
)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find categories by a given parent
|
||||
*
|
||||
* @param int $parent parent
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array
|
||||
*/
|
||||
public function findChildren($parent)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
return $query->matching(
|
||||
$query->logicalAnd(
|
||||
$query->equals('parentcategory', (int)$parent)
|
||||
)
|
||||
)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overlay the category ids with the ones from current language
|
||||
*
|
||||
* @param array $idList
|
||||
* return void
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function overlayTranslatedCategoryIds(array &$idList): void
|
||||
{
|
||||
$language = $this->getSysLanguageUid();
|
||||
if ($language > 0 && !empty($idList)) {
|
||||
if (isset($GLOBALS['TSFE']) && is_object($GLOBALS['TSFE'])) {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('sys_category');
|
||||
$rows = $queryBuilder
|
||||
->select('l10n_parent', 'uid', 'sys_language_uid')
|
||||
->from('sys_category')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter($language, \PDO::PARAM_INT)),
|
||||
$queryBuilder->expr()->in('l10n_parent', $queryBuilder->createNamedParameter($idList, Connection::PARAM_INT_ARRAY))
|
||||
)
|
||||
->execute()->fetchAll();
|
||||
|
||||
$idList = $this->replaceCategoryIds($idList, $rows);
|
||||
}
|
||||
// @todo currently only implemented for the frontend
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current sys language uid
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getSysLanguageUid(): int
|
||||
{
|
||||
$sysLanguage = 0;
|
||||
|
||||
if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() === 10) {
|
||||
$sysLanguage = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('language', 'id');
|
||||
} elseif (isset($GLOBALS['TSFE']) && is_object($GLOBALS['TSFE'])) {
|
||||
$sysLanguage = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('language', 'contentId');
|
||||
} elseif ((int)GeneralUtility::_GP('L')) {
|
||||
$sysLanguage = (int)GeneralUtility::_GP('L');
|
||||
}
|
||||
|
||||
return $sysLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace ids in array by the given ones
|
||||
*
|
||||
* @param array $idList
|
||||
* @param array $rows
|
||||
* @return array
|
||||
*/
|
||||
protected function replaceCategoryIds(array $idList, array $rows): array
|
||||
{
|
||||
foreach ($rows as $row) {
|
||||
$pos = array_search($row['l10n_parent'], $idList);
|
||||
if ($pos !== false) {
|
||||
$idList[$pos] = (int)$row['uid'];
|
||||
}
|
||||
}
|
||||
|
||||
return $idList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
use GeorgRinger\News\Domain\Model\DemandInterface;
|
||||
|
||||
/**
|
||||
* Demand domain model interface
|
||||
*/
|
||||
interface DemandedRepositoryInterface
|
||||
{
|
||||
public function findDemanded(DemandInterface $demand, $respectEnableFields = true);
|
||||
|
||||
public function countDemanded(DemandInterface $demand);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Repository for file objects
|
||||
*/
|
||||
class FileRepository extends Repository
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Repository for link objects
|
||||
*/
|
||||
class LinkRepository extends Repository
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Repository for media objects
|
||||
*/
|
||||
class MediaRepository extends Repository
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* News repository with all the callable functionality
|
||||
*/
|
||||
class NewsDefaultRepository extends NewsRepository
|
||||
{
|
||||
}
|
||||
519
typo3conf/ext/news/Classes/Domain/Repository/NewsRepository.php
Normal file
519
typo3conf/ext/news/Classes/Domain/Repository/NewsRepository.php
Normal file
@@ -0,0 +1,519 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
use GeorgRinger\News\Domain\Model\DemandInterface;
|
||||
use GeorgRinger\News\Domain\Model\Dto\NewsDemand;
|
||||
use GeorgRinger\News\Service\CategoryService;
|
||||
use GeorgRinger\News\Utility\ConstraintHelper;
|
||||
use GeorgRinger\News\Utility\Validation;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
|
||||
|
||||
/**
|
||||
* News repository with all the callable functionality
|
||||
*/
|
||||
class NewsRepository extends AbstractDemandedRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a category constraint created by
|
||||
* a given list of categories and a junction string
|
||||
*
|
||||
* @param QueryInterface $query
|
||||
* @param array $categories
|
||||
* @param string $conjunction
|
||||
* @param bool $includeSubCategories
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface|null
|
||||
*/
|
||||
protected function createCategoryConstraint(
|
||||
QueryInterface $query,
|
||||
$categories,
|
||||
$conjunction,
|
||||
$includeSubCategories = false
|
||||
): ?\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface {
|
||||
$constraint = null;
|
||||
$categoryConstraints = [];
|
||||
|
||||
// If "ignore category selection" is used, nothing needs to be done
|
||||
if (empty($conjunction)) {
|
||||
return $constraint;
|
||||
}
|
||||
|
||||
if (!is_array($categories)) {
|
||||
$categories = GeneralUtility::intExplode(',', $categories, true);
|
||||
}
|
||||
foreach ($categories as $category) {
|
||||
if ($includeSubCategories) {
|
||||
$subCategories = GeneralUtility::trimExplode(
|
||||
',',
|
||||
CategoryService::getChildrenCategories($category, 0, '', true),
|
||||
true
|
||||
);
|
||||
$subCategoryConstraint = [];
|
||||
$subCategoryConstraint[] = $query->contains('categories', $category);
|
||||
if (count($subCategories) > 0) {
|
||||
foreach ($subCategories as $subCategory) {
|
||||
$subCategoryConstraint[] = $query->contains('categories', $subCategory);
|
||||
}
|
||||
}
|
||||
if ($subCategoryConstraint) {
|
||||
$categoryConstraints[] = $query->logicalOr($subCategoryConstraint);
|
||||
}
|
||||
} else {
|
||||
$categoryConstraints[] = $query->contains('categories', $category);
|
||||
}
|
||||
}
|
||||
|
||||
if ($categoryConstraints) {
|
||||
switch (strtolower($conjunction)) {
|
||||
case 'or':
|
||||
$constraint = $query->logicalOr($categoryConstraints);
|
||||
break;
|
||||
case 'notor':
|
||||
$constraint = $query->logicalNot($query->logicalOr($categoryConstraints));
|
||||
break;
|
||||
case 'notand':
|
||||
$constraint = $query->logicalNot($query->logicalAnd($categoryConstraints));
|
||||
break;
|
||||
case 'and':
|
||||
default:
|
||||
$constraint = $query->logicalAnd($categoryConstraints);
|
||||
}
|
||||
}
|
||||
|
||||
return $constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of constraints created from a given demand object.
|
||||
*
|
||||
* @param QueryInterface $query
|
||||
* @param DemandInterface $demand
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return (\TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\NotInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface|null)[]
|
||||
*
|
||||
* @psalm-return array<string, \TYPO3\CMS\Extbase\Persistence\Generic\Qom\AndInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ComparisonInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\NotInterface|\TYPO3\CMS\Extbase\Persistence\Generic\Qom\OrInterface|null>
|
||||
*/
|
||||
protected function createConstraintsFromDemand(QueryInterface $query, DemandInterface $demand): array
|
||||
{
|
||||
/** @var NewsDemand $demand */
|
||||
$constraints = [];
|
||||
|
||||
if ($demand->getCategories() && $demand->getCategories() !== '0') {
|
||||
$constraints['categories'] = $this->createCategoryConstraint(
|
||||
$query,
|
||||
$demand->getCategories(),
|
||||
$demand->getCategoryConjunction(),
|
||||
$demand->getIncludeSubCategories()
|
||||
);
|
||||
}
|
||||
|
||||
if ($demand->getAuthor()) {
|
||||
$constraints['author'] = $query->equals('author', $demand->getAuthor());
|
||||
}
|
||||
|
||||
if ($demand->getTypes()) {
|
||||
$constraints['types'] = $query->in('type', $demand->getTypes());
|
||||
}
|
||||
|
||||
// archived
|
||||
if ($demand->getArchiveRestriction() === 'archived') {
|
||||
$constraints['archived'] = $query->logicalAnd(
|
||||
$query->lessThan('archive', $GLOBALS['SIM_EXEC_TIME']),
|
||||
$query->greaterThan('archive', 0)
|
||||
);
|
||||
} elseif ($demand->getArchiveRestriction() === 'active') {
|
||||
$constraints['active'] = $query->logicalOr(
|
||||
$query->greaterThanOrEqual('archive', $GLOBALS['SIM_EXEC_TIME']),
|
||||
$query->equals('archive', 0)
|
||||
);
|
||||
}
|
||||
|
||||
// Time restriction greater than or equal
|
||||
$timeRestrictionField = $demand->getDateField();
|
||||
$timeRestrictionField = (empty($timeRestrictionField)) ? 'datetime' : $timeRestrictionField;
|
||||
|
||||
if ($demand->getTimeRestriction()) {
|
||||
$timeLimit = ConstraintHelper::getTimeRestrictionLow($demand->getTimeRestriction());
|
||||
|
||||
$constraints['timeRestrictionGreater'] = $query->greaterThanOrEqual(
|
||||
$timeRestrictionField,
|
||||
$timeLimit
|
||||
);
|
||||
}
|
||||
|
||||
// Time restriction less than or equal
|
||||
if ($demand->getTimeRestrictionHigh()) {
|
||||
$timeLimit = ConstraintHelper::getTimeRestrictionHigh($demand->getTimeRestrictionHigh());
|
||||
|
||||
$constraints['timeRestrictionLess'] = $query->lessThanOrEqual(
|
||||
$timeRestrictionField,
|
||||
$timeLimit
|
||||
);
|
||||
}
|
||||
|
||||
// top news
|
||||
if ($demand->getTopNewsRestriction() == 1) {
|
||||
$constraints['topNews1'] = $query->equals('istopnews', 1);
|
||||
} elseif ($demand->getTopNewsRestriction() == 2) {
|
||||
$constraints['topNews2'] = $query->equals('istopnews', 0);
|
||||
}
|
||||
|
||||
// storage page
|
||||
if ($demand->getStoragePage()) {
|
||||
$pidList = GeneralUtility::intExplode(',', $demand->getStoragePage(), true);
|
||||
$constraints['pid'] = $query->in('pid', $pidList);
|
||||
}
|
||||
|
||||
// month & year OR year only
|
||||
if ($demand->getYear() > 0) {
|
||||
if (null === $demand->getDateField()) {
|
||||
throw new \InvalidArgumentException('No Datefield is set, therefore no Datemenu is possible!');
|
||||
}
|
||||
if ($demand->getMonth() > 0) {
|
||||
if ($demand->getDay() > 0) {
|
||||
$begin = mktime(0, 0, 0, $demand->getMonth(), $demand->getDay(), $demand->getYear());
|
||||
$end = mktime(23, 59, 59, $demand->getMonth(), $demand->getDay(), $demand->getYear());
|
||||
} else {
|
||||
$begin = mktime(0, 0, 0, $demand->getMonth(), 1, $demand->getYear());
|
||||
$end = mktime(23, 59, 59, ($demand->getMonth() + 1), 0, $demand->getYear());
|
||||
}
|
||||
} else {
|
||||
$begin = mktime(0, 0, 0, 1, 1, $demand->getYear());
|
||||
$end = mktime(23, 59, 59, 12, 31, $demand->getYear());
|
||||
}
|
||||
$constraints['datetime'] = $query->logicalAnd([
|
||||
$query->greaterThanOrEqual($demand->getDateField(), $begin),
|
||||
$query->lessThanOrEqual($demand->getDateField(), $end)
|
||||
]);
|
||||
}
|
||||
|
||||
// Tags
|
||||
$tags = $demand->getTags();
|
||||
if ($tags && is_string($tags)) {
|
||||
$tagList = explode(',', $tags);
|
||||
|
||||
$subConstraints = [];
|
||||
foreach ($tagList as $singleTag) {
|
||||
$subConstraints[] = $query->contains('tags', $singleTag);
|
||||
}
|
||||
if (count($subConstraints) > 0) {
|
||||
$constraints['tags'] = $query->logicalOr($subConstraints);
|
||||
}
|
||||
}
|
||||
|
||||
// Search
|
||||
$searchConstraints = $this->getSearchConstraints($query, $demand);
|
||||
if (!empty($searchConstraints)) {
|
||||
$constraints['search'] = $query->logicalAnd($searchConstraints);
|
||||
}
|
||||
|
||||
// Exclude already displayed
|
||||
if ($demand->getExcludeAlreadyDisplayedNews() && isset($GLOBALS['EXT']['news']['alreadyDisplayed']) && !empty($GLOBALS['EXT']['news']['alreadyDisplayed'])) {
|
||||
$constraints['excludeAlreadyDisplayedNews'] = $query->logicalNot(
|
||||
$query->in(
|
||||
'uid',
|
||||
$GLOBALS['EXT']['news']['alreadyDisplayed']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Hide id list
|
||||
$hideIdList = $demand->getHideIdList();
|
||||
if ($hideIdList) {
|
||||
$constraints['hideIdInList'] = $query->logicalNot(
|
||||
$query->in(
|
||||
'uid',
|
||||
GeneralUtility::intExplode(',', $hideIdList, true)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Id list
|
||||
$idList = $demand->getIdList();
|
||||
if ($idList) {
|
||||
$constraints['idList'] = $query->in('uid', GeneralUtility::intExplode(',', $idList, true));
|
||||
}
|
||||
|
||||
// Clean not used constraints
|
||||
foreach ($constraints as $key => $value) {
|
||||
if (null === $value) {
|
||||
unset($constraints[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of orderings created from a given demand object.
|
||||
*
|
||||
* @param DemandInterface $demand
|
||||
*
|
||||
* @return string[]
|
||||
*
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
protected function createOrderingsFromDemand(DemandInterface $demand): array
|
||||
{
|
||||
$orderings = [];
|
||||
if ($demand->getTopNewsFirst()) {
|
||||
$orderings['istopnews'] = QueryInterface::ORDER_DESCENDING;
|
||||
}
|
||||
|
||||
if (Validation::isValidOrdering($demand->getOrder(), $demand->getOrderByAllowed())) {
|
||||
$orderList = GeneralUtility::trimExplode(',', $demand->getOrder(), true);
|
||||
|
||||
if (!empty($orderList)) {
|
||||
// go through every order statement
|
||||
foreach ($orderList as $orderItem) {
|
||||
$orderSplit = GeneralUtility::trimExplode(' ', $orderItem, true);
|
||||
$orderField = $orderSplit[0];
|
||||
$ascDesc = $orderSplit[1] ?? '';
|
||||
if ($ascDesc) {
|
||||
$orderings[$orderField] = ((strtolower($ascDesc) === 'desc') ?
|
||||
QueryInterface::ORDER_DESCENDING :
|
||||
QueryInterface::ORDER_ASCENDING);
|
||||
} else {
|
||||
$orderings[$orderField] = QueryInterface::ORDER_ASCENDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $orderings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first news by import and source id
|
||||
*
|
||||
* @param string $importSource import source
|
||||
* @param int $importId import id
|
||||
* @param bool $asArray return result as array
|
||||
* @return \GeorgRinger\News\Domain\Model\News|array
|
||||
*/
|
||||
public function findOneByImportSourceAndImportId($importSource, $importId, $asArray = false)
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
$query->getQuerySettings()->setRespectSysLanguage(false);
|
||||
$query->getQuerySettings()->setIgnoreEnableFields(true);
|
||||
|
||||
$result = $query->matching(
|
||||
$query->logicalAnd(
|
||||
$query->equals('importSource', $importSource),
|
||||
$query->equals('importId', $importId)
|
||||
)
|
||||
)->execute($asArray);
|
||||
if ($asArray) {
|
||||
if (isset($result[0])) {
|
||||
return $result[0];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return $result->getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default findByUid function to enable also the option to turn of
|
||||
* the enableField setting
|
||||
*
|
||||
* @param int $uid id of record
|
||||
* @param bool $respectEnableFields if set to false, hidden records are shown
|
||||
* @return \GeorgRinger\News\Domain\Model\News|null
|
||||
*/
|
||||
public function findByUid($uid, $respectEnableFields = true): ?\GeorgRinger\News\Domain\Model\News
|
||||
{
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
$query->getQuerySettings()->setRespectSysLanguage(false);
|
||||
|
||||
if (!$respectEnableFields) {
|
||||
$query->getQuerySettings()->setIgnoreEnableFields(true);
|
||||
$query->getQuerySettings()->setLanguageOverlayMode(false);
|
||||
}
|
||||
|
||||
return $query->matching(
|
||||
$query->logicalAnd(
|
||||
$query->equals('uid', $uid),
|
||||
$query->equals('deleted', 0)
|
||||
)
|
||||
)->execute()->getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of news records by month/year and
|
||||
* returns the result compiled as array
|
||||
*
|
||||
* @param DemandInterface $demand
|
||||
* @return array
|
||||
*/
|
||||
public function countByDate(DemandInterface $demand): array
|
||||
{
|
||||
$data = [];
|
||||
$sql = $this->findDemandedRaw($demand);
|
||||
|
||||
// strip unwanted order by
|
||||
$sql = $this->stripOrderBy($sql);
|
||||
|
||||
// Get the month/year into the result
|
||||
$field = $demand->getDateField();
|
||||
$field = empty($field) ? 'datetime' : $field;
|
||||
|
||||
$sql = 'SELECT MONTH(FROM_UNIXTIME(0) + INTERVAL ' . $field . ' SECOND ) AS "_Month",' .
|
||||
' YEAR(FROM_UNIXTIME(0) + INTERVAL ' . $field . ' SECOND) AS "_Year" ,' .
|
||||
' count(MONTH(FROM_UNIXTIME(0) + INTERVAL ' . $field . ' SECOND )) as count_month,' .
|
||||
' count(YEAR(FROM_UNIXTIME(0) + INTERVAL ' . $field . ' SECOND)) as count_year' .
|
||||
' FROM tx_news_domain_model_news ' . substr($sql, strpos($sql, 'WHERE '));
|
||||
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getConnectionForTable('tx_news_domain_model_news');
|
||||
|
||||
if (TYPO3_MODE === 'FE') {
|
||||
$sql .= $GLOBALS['TSFE']->sys_page->enableFields('tx_news_domain_model_news');
|
||||
} else {
|
||||
$expressionBuilder = $connection
|
||||
->createQueryBuilder()
|
||||
->expr();
|
||||
$sql .= BackendUtility::BEenableFields('tx_news_domain_model_news') .
|
||||
' AND ' . $expressionBuilder->eq('deleted', 0);
|
||||
}
|
||||
|
||||
// group by custom month/year fields
|
||||
$orderDirection = strtolower($demand->getOrder());
|
||||
if ($orderDirection !== 'desc' && $orderDirection !== 'asc') {
|
||||
$orderDirection = 'asc';
|
||||
}
|
||||
$sql .= ' GROUP BY _Month, _Year ORDER BY _Year ' . $orderDirection . ', _Month ' . $orderDirection;
|
||||
|
||||
$res = $connection->query($sql);
|
||||
while ($row = $res->fetch()) {
|
||||
$month = strlen($row['_Month']) === 1 ? ('0' . $row['_Month']) : $row['_Month'];
|
||||
$data['single'][$row['_Year']][$month] = $row['count_month'];
|
||||
}
|
||||
|
||||
// Add totals
|
||||
if (is_array($data['single'])) {
|
||||
foreach ($data['single'] as $year => $months) {
|
||||
$countOfYear = 0;
|
||||
foreach ($months as $month) {
|
||||
$countOfYear += $month;
|
||||
}
|
||||
$data['total'][$year] = $countOfYear;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the search constraints
|
||||
*
|
||||
* @param QueryInterface $query
|
||||
* @param DemandInterface $demand
|
||||
* @return array
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
protected function getSearchConstraints(QueryInterface $query, DemandInterface $demand): array
|
||||
{
|
||||
$constraints = [];
|
||||
if ($demand->getSearch() === null) {
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/* @var $searchObject \GeorgRinger\News\Domain\Model\Dto\Search */
|
||||
$searchObject = $demand->getSearch();
|
||||
|
||||
$searchSubject = $searchObject->getSubject();
|
||||
if (!empty($searchSubject)) {
|
||||
$queryBuilder = $this->getQueryBuilder('tx_news_domain_model_news');
|
||||
|
||||
$searchFields = GeneralUtility::trimExplode(',', $searchObject->getFields(), true);
|
||||
$searchConstraints = [];
|
||||
|
||||
if (count($searchFields) === 0) {
|
||||
throw new \UnexpectedValueException('No search fields defined', 1318497755);
|
||||
}
|
||||
$searchSubjectSplitted = str_getcsv($searchSubject, ' ');
|
||||
if ($searchObject->isSplitSubjectWords()) {
|
||||
foreach ($searchFields as $field) {
|
||||
$subConstraints = [];
|
||||
foreach ($searchSubjectSplitted as $searchSubjectSplittedPart) {
|
||||
$searchSubjectSplittedPart = trim($searchSubjectSplittedPart);
|
||||
if ($searchSubjectSplittedPart) {
|
||||
$subConstraints[] = $query->like($field, '%' . $searchSubjectSplittedPart . '%');
|
||||
}
|
||||
}
|
||||
$searchConstraints[] = $query->logicalAnd($subConstraints);
|
||||
}
|
||||
if (count($searchConstraints)) {
|
||||
$constraints[] = $query->logicalOr($searchConstraints);
|
||||
}
|
||||
} else {
|
||||
if (!empty($searchSubject)) {
|
||||
foreach ($searchFields as $field) {
|
||||
$searchConstraints[] = $query->like($field, '%' . $searchSubject . '%');
|
||||
}
|
||||
}
|
||||
if (count($searchConstraints)) {
|
||||
$constraints[] = $query->logicalOr($searchConstraints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$minimumDate = strtotime($searchObject->getMinimumDate());
|
||||
if ($minimumDate) {
|
||||
$field = $searchObject->getDateField();
|
||||
if (empty($field)) {
|
||||
throw new \UnexpectedValueException('No date field is defined', 1396348732);
|
||||
}
|
||||
$constraints[] = $query->greaterThanOrEqual($field, $minimumDate);
|
||||
}
|
||||
$maximumDate = strtotime($searchObject->getMaximumDate());
|
||||
if ($maximumDate) {
|
||||
$field = $searchObject->getDateField();
|
||||
if (empty($field)) {
|
||||
throw new \UnexpectedValueException('No date field is defined', 1396348733);
|
||||
}
|
||||
$maximumDate += 86400;
|
||||
$constraints[] = $query->lessThanOrEqual($field, $maximumDate);
|
||||
}
|
||||
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table table name
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
protected function getQueryBuilder(string $table): QueryBuilder
|
||||
{
|
||||
return GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return stripped order sql
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
private function stripOrderBy(string $str): string
|
||||
{
|
||||
/** @noinspection NotOptimalRegularExpressionsInspection */
|
||||
return preg_replace('/(?:ORDER[[:space:]]*BY[[:space:]]*.*)+/i', '', trim($str));
|
||||
}
|
||||
}
|
||||
125
typo3conf/ext/news/Classes/Domain/Repository/TagRepository.php
Normal file
125
typo3conf/ext/news/Classes/Domain/Repository/TagRepository.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
use GeorgRinger\News\Domain\Model\DemandInterface;
|
||||
use GeorgRinger\News\Utility\Validation;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
|
||||
|
||||
/**
|
||||
* Repository for tag objects
|
||||
*/
|
||||
class TagRepository extends AbstractDemandedRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* Find categories by a given pid
|
||||
*
|
||||
* @param array $idList list of id s
|
||||
* @param array $ordering ordering
|
||||
* @param string $startingPoint starting point uid or comma separated list
|
||||
*
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array
|
||||
*/
|
||||
public function findByIdList(array $idList, array $ordering = [], $startingPoint = null)
|
||||
{
|
||||
if (empty($idList)) {
|
||||
throw new \InvalidArgumentException('The given id list is empty.', 1484823596);
|
||||
}
|
||||
$query = $this->createQuery();
|
||||
$query->getQuerySettings()->setRespectStoragePage(false);
|
||||
$query->getQuerySettings()->setRespectSysLanguage(false);
|
||||
|
||||
if (count($ordering) > 0) {
|
||||
$query->setOrderings($ordering);
|
||||
}
|
||||
|
||||
$conditions = [];
|
||||
$conditions[] = $query->in('uid', $idList);
|
||||
|
||||
if ($startingPoint !== null) {
|
||||
$conditions[] = $query->in('pid', GeneralUtility::trimExplode(',', $startingPoint, true));
|
||||
}
|
||||
|
||||
return $query->matching(
|
||||
$query->logicalAnd(
|
||||
$conditions
|
||||
)
|
||||
)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of constraints created from a given demand object.
|
||||
*
|
||||
* @param QueryInterface $query
|
||||
* @param DemandInterface $demand
|
||||
* @return \TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface[]
|
||||
*/
|
||||
protected function createConstraintsFromDemand(QueryInterface $query, DemandInterface $demand): array
|
||||
{
|
||||
$constraints = [];
|
||||
|
||||
// Storage page
|
||||
if ($demand->getStoragePage()) {
|
||||
$pidList = GeneralUtility::intExplode(',', $demand->getStoragePage(), true);
|
||||
$constraints[] = $query->in('pid', $pidList);
|
||||
}
|
||||
|
||||
// Tags
|
||||
if ($demand->getTags()) {
|
||||
$tagList = GeneralUtility::intExplode(',', $demand->getTags(), true);
|
||||
$constraints[] = $query->in('uid', $tagList);
|
||||
}
|
||||
|
||||
// Clean not used constraints
|
||||
foreach ($constraints as $key => $value) {
|
||||
if (is_null($value)) {
|
||||
unset($constraints[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of orderings created from a given demand object.
|
||||
*
|
||||
* @param DemandInterface $demand
|
||||
*
|
||||
* @return string[]
|
||||
*
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
protected function createOrderingsFromDemand(DemandInterface $demand): array
|
||||
{
|
||||
$orderings = [];
|
||||
|
||||
if (Validation::isValidOrdering($demand->getOrder(), $demand->getOrderByAllowed())) {
|
||||
$orderList = GeneralUtility::trimExplode(',', $demand->getOrder(), true);
|
||||
|
||||
if (!empty($orderList)) {
|
||||
// go through every order statement
|
||||
foreach ($orderList as $orderItem) {
|
||||
list($orderField, $ascDesc) = GeneralUtility::trimExplode(' ', $orderItem, true);
|
||||
// count == 1 means that no direction is given
|
||||
if ($ascDesc) {
|
||||
$orderings[$orderField] = ((strtolower($ascDesc) == 'desc') ?
|
||||
QueryInterface::ORDER_DESCENDING :
|
||||
QueryInterface::ORDER_ASCENDING);
|
||||
} else {
|
||||
$orderings[$orderField] = QueryInterface::ORDER_ASCENDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $orderings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Repository;
|
||||
|
||||
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
/**
|
||||
* Repository for tt_content objects
|
||||
*/
|
||||
class TtContentRepository extends Repository
|
||||
{
|
||||
protected $objectType = '\GeorgRinger\News\Domain\Model\Ttcontent';
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Service;
|
||||
|
||||
use GeorgRinger\News\Domain\Model\Dto\EmConfiguration;
|
||||
use GeorgRinger\News\Domain\Repository\CategoryRepository;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\Folder;
|
||||
use TYPO3\CMS\Core\Resource\Index\FileIndexRepository;
|
||||
use TYPO3\CMS\Core\Resource\ProcessedFile;
|
||||
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
||||
use TYPO3\CMS\Core\Resource\ResourceStorage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
class AbstractImportService implements LoggerAwareInterface
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
const UPLOAD_PATH = 'uploads/tx_news/';
|
||||
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @var PersistenceManager
|
||||
*/
|
||||
protected $persistenceManager;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $postPersistQueue = [];
|
||||
|
||||
/**
|
||||
* @var EmConfiguration
|
||||
*/
|
||||
protected $emSettings;
|
||||
|
||||
/**
|
||||
* @var Folder
|
||||
*/
|
||||
protected $importFolder;
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* @var CategoryRepository
|
||||
*/
|
||||
protected $categoryRepository;
|
||||
/**
|
||||
* AbstractImportService constructor.
|
||||
* @param PersistenceManager $persistenceManager
|
||||
* @param EmConfiguration $emSettings
|
||||
* @param ObjectManager $objectManager
|
||||
* @param CategoryRepository $categoryRepository
|
||||
* @param EventDispatcherInterface $eventDispatcher
|
||||
*/
|
||||
public function __construct(
|
||||
PersistenceManager $persistenceManager,
|
||||
ObjectManager $objectManager,
|
||||
CategoryRepository $categoryRepository,
|
||||
EventDispatcherInterface $eventDispatcher
|
||||
) {
|
||||
$this->emSettings = GeneralUtility::makeInstance(EmConfiguration::class);
|
||||
$this->persistenceManager = $persistenceManager;
|
||||
$this->objectManager = $objectManager;
|
||||
$this->categoryRepository = $categoryRepository;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares 2 files by using its filesize
|
||||
*
|
||||
* @param string $file1 Absolute path and filename to file1
|
||||
* @param string $file2 Absolute path and filename to file2
|
||||
* @return bool
|
||||
*/
|
||||
protected function filesAreEqual($file1, $file2): bool
|
||||
{
|
||||
return filesize($file1) === filesize($file2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a existing file by its hash
|
||||
*
|
||||
* @param string $hash
|
||||
*
|
||||
* @return File|ProcessedFile|null
|
||||
*/
|
||||
protected function findFileByHash($hash)
|
||||
{
|
||||
$file = null;
|
||||
|
||||
$files = $this->getFileIndexRepository()->findByContentHash($hash);
|
||||
if (count($files)) {
|
||||
foreach ($files as $fileInfo) {
|
||||
if ($fileInfo['storage'] > 0) {
|
||||
$file = $this->getResourceFactory()->getFileObjectByStorageAndIdentifier(
|
||||
$fileInfo['storage'],
|
||||
$fileInfo['identifier']
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get import Folder
|
||||
*
|
||||
* TODO: catch exception when storage/folder does not exist and return readable message to the user
|
||||
*
|
||||
* @return Folder
|
||||
*/
|
||||
protected function getImportFolder(): Folder
|
||||
{
|
||||
if ($this->importFolder === null) {
|
||||
$this->importFolder = $this->getResourceFactory()->getFolderObjectFromCombinedIdentifier($this->emSettings->getStorageUidImporter() . ':' . $this->emSettings->getResourceFolderImporter());
|
||||
}
|
||||
return $this->importFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the FileIndexRepository
|
||||
*
|
||||
* @return FileIndexRepository
|
||||
*/
|
||||
protected function getFileIndexRepository(): FileIndexRepository
|
||||
{
|
||||
return FileIndexRepository::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource storage
|
||||
*
|
||||
* @return ResourceStorage
|
||||
*/
|
||||
protected function getResourceStorage(): ResourceStorage
|
||||
{
|
||||
return $this->getResourceFactory()->getStorageObject($this->emSettings->getStorageUidImporter());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ResourceFactory
|
||||
*/
|
||||
protected function getResourceFactory(): ResourceFactory
|
||||
{
|
||||
/** @var ResourceFactory $resourceFactory */
|
||||
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
|
||||
return $resourceFactory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Service;
|
||||
|
||||
use GeorgRinger\News\Domain\Model\Category;
|
||||
use GeorgRinger\News\Domain\Model\Dto\EmConfiguration;
|
||||
use GeorgRinger\News\Domain\Model\FileReference;
|
||||
use GeorgRinger\News\Domain\Repository\CategoryRepository;
|
||||
use GeorgRinger\News\Event\CategoryImportPostHydrateEvent;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
class CategoryImportService extends AbstractImportService
|
||||
{
|
||||
const ACTION_SET_PARENT_CATEGORY = 1;
|
||||
const ACTION_CREATE_L10N_CHILDREN_CATEGORY = 2;
|
||||
|
||||
/**
|
||||
* CategoryImportService constructor.
|
||||
* @param PersistenceManager $persistenceManager
|
||||
* @param EmConfiguration $emSettings
|
||||
* @param ObjectManager $objectManager
|
||||
* @param CategoryRepository $categoryRepository
|
||||
* @param EventDispatcherInterface $eventDispatcher
|
||||
*/
|
||||
public function __construct(
|
||||
PersistenceManager $persistenceManager,
|
||||
ObjectManager $objectManager,
|
||||
CategoryRepository $categoryRepository,
|
||||
EventDispatcherInterface $eventDispatcher
|
||||
) {
|
||||
parent::__construct($persistenceManager, $objectManager, $categoryRepository, $eventDispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $importArray
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function import(array $importArray): void
|
||||
{
|
||||
$this->logger->info(sprintf('Starting import for %s categories', count($importArray)));
|
||||
|
||||
// Sort import array to import the default language first
|
||||
foreach ($importArray as $importItem) {
|
||||
$category = $this->hydrateCategory($importItem);
|
||||
|
||||
if (!empty($importItem['title_lang_ol'])) {
|
||||
$this->postPersistQueue[$importItem['import_id']] = [
|
||||
'category' => $category,
|
||||
'importItem' => $importItem,
|
||||
'action' => self::ACTION_CREATE_L10N_CHILDREN_CATEGORY,
|
||||
'titleLanguageOverlay' => $importItem['title_lang_ol']
|
||||
];
|
||||
}
|
||||
|
||||
if ($importItem['parentcategory']) {
|
||||
$this->postPersistQueue[$importItem['import_id']] = [
|
||||
'category' => $category,
|
||||
'action' => self::ACTION_SET_PARENT_CATEGORY,
|
||||
'parentCategoryOriginUid' => $importItem['parentcategory']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$this->persistenceManager->persistAll();
|
||||
|
||||
foreach ($this->postPersistQueue as $queueItem) {
|
||||
switch ($queueItem['action']) {
|
||||
case self::ACTION_SET_PARENT_CATEGORY:
|
||||
$this->setParentCategory($queueItem);
|
||||
break;
|
||||
case self::ACTION_CREATE_L10N_CHILDREN_CATEGORY:
|
||||
$this->createL10nChildrenCategory($queueItem);
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->persistenceManager->persistAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrate a category record with the given array
|
||||
*
|
||||
* @param array $importItem
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
protected function hydrateCategory(array $importItem)
|
||||
{
|
||||
$category = $this->categoryRepository->findOneByImportSourceAndImportId(
|
||||
$importItem['import_source'],
|
||||
$importItem['import_id']
|
||||
);
|
||||
|
||||
$this->logger->info(sprintf(
|
||||
'Import of category from source "%s" with id "%s"',
|
||||
$importItem['import_source'],
|
||||
$importItem['import_id']
|
||||
));
|
||||
|
||||
if (is_null($category)) {
|
||||
$this->logger->info('Category is new');
|
||||
|
||||
$category = GeneralUtility::makeInstance(Category::class);
|
||||
$this->categoryRepository->add($category);
|
||||
} else {
|
||||
$this->logger->info(sprintf('Category exists already with id "%s".', $category->getUid()));
|
||||
}
|
||||
|
||||
$category->setPid($importItem['pid']);
|
||||
$category->setHidden($importItem['hidden']);
|
||||
$category->setStarttime($importItem['starttime']);
|
||||
$category->setEndtime($importItem['endtime']);
|
||||
$category->setCrdate($importItem['crdate']);
|
||||
$category->setTstamp($importItem['tstamp']);
|
||||
$category->setTitle($importItem['title']);
|
||||
$category->setDescription($importItem['description']);
|
||||
if (!empty($importItem['image'])) {
|
||||
$this->setFileRelationFromImage($category, $importItem['image']);
|
||||
}
|
||||
$category->setShortcut($importItem['shortcut']);
|
||||
$category->setSinglePid($importItem['single_pid']);
|
||||
|
||||
$category->setImportId($importItem['import_id']);
|
||||
$category->setImportSource($importItem['import_source']);
|
||||
|
||||
$event = $this->eventDispatcher->dispatch(new CategoryImportPostHydrateEvent($this, $importItem, $category));
|
||||
|
||||
return $event->getCategory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add category image when not already present
|
||||
*
|
||||
* @param Category $category
|
||||
* @param $image
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setFileRelationFromImage($category, $image)
|
||||
{
|
||||
|
||||
// get fileObject by given identifier (file UID, combined identifier or path/filename)
|
||||
try {
|
||||
$newImage = $this->getResourceFactory()->retrieveFileOrFolderObject($image);
|
||||
} catch (ResourceDoesNotExistException $exception) {
|
||||
$newImage = false;
|
||||
}
|
||||
|
||||
// only proceed if image is found
|
||||
if (!$newImage instanceof File) {
|
||||
return;
|
||||
}
|
||||
|
||||
// new image found check if this isn't already
|
||||
$existingImages = $category->getImages();
|
||||
if (!is_null($existingImages) && $existingImages->count() !== 0) {
|
||||
/** @var $item FileReference */
|
||||
foreach ($existingImages as $item) {
|
||||
// only check already persisted items
|
||||
if ($item->getFileUid() === (int)$newImage->getUid()
|
||||
||
|
||||
($item->getUid() &&
|
||||
$item->getOriginalResource()->getName() === $newImage->getName() &&
|
||||
$item->getOriginalResource()->getSize() === (int)$newImage->getSize())
|
||||
) {
|
||||
$newImage = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($newImage) {
|
||||
// file not inside a storage then search for existing file or copy the one form storage 0 to the import folder
|
||||
if ($newImage->getStorage()->getUid() === 0) {
|
||||
|
||||
// search DB for same file based on hash (to prevent duplicates)
|
||||
$existingFile = $this->findFileByHash($newImage->getSha1());
|
||||
|
||||
// no exciting file then copy file to import folder
|
||||
if ($existingFile === null) {
|
||||
$newImage = $this->getResourceStorage()->copyFile($newImage, $this->getImportFolder());
|
||||
} else {
|
||||
$newImage = $existingFile;
|
||||
}
|
||||
}
|
||||
|
||||
$fileReference = GeneralUtility::makeInstance(FileReference::class);
|
||||
$fileReference->setFileUid($newImage->getUid());
|
||||
$fileReference->setPid($category->getPid());
|
||||
$category->addImage($fileReference);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent category
|
||||
*
|
||||
* @param array $queueItem
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setParentCategory(array $queueItem): void
|
||||
{
|
||||
/** @var $category Category */
|
||||
$category = $queueItem['category'];
|
||||
$parentCategoryOriginUid = $queueItem['parentCategoryOriginUid'];
|
||||
|
||||
if (is_null($parentCategory = $this->postPersistQueue[$parentCategoryOriginUid]['category'])) {
|
||||
$parentCategory = $this->categoryRepository->findOneByImportSourceAndImportId(
|
||||
$category->getImportSource(),
|
||||
$parentCategoryOriginUid
|
||||
);
|
||||
}
|
||||
|
||||
if ($parentCategory !== null) {
|
||||
$category->setParentcategory($parentCategory);
|
||||
$this->categoryRepository->update($category);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create l10n relation
|
||||
*
|
||||
* @param array $queueItem
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function createL10nChildrenCategory(array $queueItem): void
|
||||
{
|
||||
/** @var $category Category */
|
||||
$category = $queueItem['category'];
|
||||
$titleLanguageOverlay = GeneralUtility::trimExplode('|', $queueItem['titleLanguageOverlay']);
|
||||
|
||||
foreach ($titleLanguageOverlay as $key => $title) {
|
||||
$sysLanguageUid = $key + 1;
|
||||
|
||||
$importItem = $queueItem['importItem'];
|
||||
$importItem['import_id'] = $importItem['import_id'] . '|L:' . $sysLanguageUid;
|
||||
|
||||
/** @var $l10nChildrenCategory Category */
|
||||
$l10nChildrenCategory = $this->hydrateCategory($importItem);
|
||||
$this->categoryRepository->add($l10nChildrenCategory);
|
||||
|
||||
$l10nChildrenCategory->setTitle($title);
|
||||
$l10nChildrenCategory->setL10nParent((int)$category->getUid());
|
||||
$l10nChildrenCategory->setSysLanguageUid((int)$sysLanguageUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
411
typo3conf/ext/news/Classes/Domain/Service/NewsImportService.php
Normal file
411
typo3conf/ext/news/Classes/Domain/Service/NewsImportService.php
Normal file
@@ -0,0 +1,411 @@
|
||||
<?php
|
||||
|
||||
namespace GeorgRinger\News\Domain\Service;
|
||||
|
||||
use GeorgRinger\News\Domain\Model\Dto\EmConfiguration;
|
||||
use GeorgRinger\News\Domain\Model\FileReference;
|
||||
use GeorgRinger\News\Domain\Model\Link;
|
||||
use GeorgRinger\News\Domain\Model\News;
|
||||
use GeorgRinger\News\Domain\Repository\CategoryRepository;
|
||||
use GeorgRinger\News\Domain\Repository\NewsRepository;
|
||||
use GeorgRinger\News\Domain\Repository\TtContentRepository;
|
||||
use GeorgRinger\News\Event\NewsImportPostHydrateEvent;
|
||||
use GeorgRinger\News\Event\NewsImportPreHydrateEvent;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
|
||||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||
|
||||
/**
|
||||
* This file is part of the "news" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
class NewsImportService extends AbstractImportService
|
||||
{
|
||||
const ACTION_IMPORT_L10N_OVERLAY = 1;
|
||||
|
||||
/**
|
||||
* @var NewsRepository
|
||||
*/
|
||||
protected $newsRepository;
|
||||
|
||||
/**
|
||||
* @var TtContentRepository
|
||||
*/
|
||||
protected $ttContentRepository;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* NewsImportService constructor.
|
||||
* @param PersistenceManager $persistenceManager
|
||||
* @param EmConfiguration $emSettings
|
||||
* @param ObjectManager $objectManager
|
||||
* @param CategoryRepository $categoryRepository
|
||||
* @param EventDispatcherInterface $eventDispatcher
|
||||
* @param NewsRepository $newsRepository
|
||||
* @param TtContentRepository $ttContentRepository
|
||||
*/
|
||||
public function __construct(
|
||||
PersistenceManager $persistenceManager,
|
||||
ObjectManager $objectManager,
|
||||
CategoryRepository $categoryRepository,
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
NewsRepository $newsRepository,
|
||||
TtContentRepository $ttContentRepository
|
||||
) {
|
||||
parent::__construct($persistenceManager, $objectManager, $categoryRepository, $eventDispatcher);
|
||||
$this->newsRepository = $newsRepository;
|
||||
$this->ttContentRepository = $ttContentRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $importItem
|
||||
*
|
||||
* @return array|object
|
||||
*/
|
||||
protected function initializeNewsRecord(array $importItem)
|
||||
{
|
||||
$news = null;
|
||||
|
||||
$this->logger->info(sprintf(
|
||||
'Import of news from source "%s" with id "%s"',
|
||||
$importItem['import_source'],
|
||||
$importItem['import_id']
|
||||
));
|
||||
|
||||
if ($importItem['import_source'] && $importItem['import_id']) {
|
||||
$news = $this->newsRepository->findOneByImportSourceAndImportId(
|
||||
$importItem['import_source'],
|
||||
$importItem['import_id']
|
||||
);
|
||||
}
|
||||
|
||||
if ($news === null) {
|
||||
$news = GeneralUtility::makeInstance(News::class);
|
||||
$this->newsRepository->add($news);
|
||||
} else {
|
||||
$this->logger->info(sprintf('News exists already with id "%s".', $news->getUid()));
|
||||
$this->newsRepository->update($news);
|
||||
}
|
||||
|
||||
return $news;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param News $news
|
||||
* @param array $importItem
|
||||
* @param array $importItemOverwrite
|
||||
* @return News
|
||||
*/
|
||||
protected function hydrateNewsRecord(
|
||||
News $news,
|
||||
array $importItem,
|
||||
array $importItemOverwrite
|
||||
): News {
|
||||
if (!empty($importItemOverwrite)) {
|
||||
$importItem = array_merge($importItem, $importItemOverwrite);
|
||||
}
|
||||
$news->setPid($importItem['pid']);
|
||||
$news->setHidden($importItem['hidden']);
|
||||
if ($importItem['starttime']) {
|
||||
$news->setStarttime($importItem['starttime']);
|
||||
}
|
||||
if ($importItem['endtime']) {
|
||||
$news->setStarttime($importItem['endtime']);
|
||||
}
|
||||
if (!empty($importItem['fe_group'])) {
|
||||
$news->setFeGroup((string)$importItem['fe_group']);
|
||||
}
|
||||
$news->setTstamp($importItem['tstamp']);
|
||||
$news->setCrdate($importItem['crdate']);
|
||||
$news->setSysLanguageUid($importItem['sys_language_uid']);
|
||||
$news->setSorting((int)$importItem['sorting']);
|
||||
|
||||
$news->setTitle($importItem['title']);
|
||||
$news->setTeaser($importItem['teaser']);
|
||||
$news->setBodytext($importItem['bodytext']);
|
||||
|
||||
$news->setType((string)$importItem['type']);
|
||||
$news->setKeywords($importItem['keywords']);
|
||||
$news->setDescription($importItem['description']);
|
||||
$news->setDatetime(new \DateTime(date('Y-m-d H:i:sP', $importItem['datetime'])));
|
||||
$news->setArchive(new \DateTime(date('Y-m-d H:i:sP', $importItem['archive'])));
|
||||
|
||||
$contentElementUidArray = GeneralUtility::trimExplode(',', $importItem['content_elements'], true);
|
||||
foreach ($contentElementUidArray as $contentElementUid) {
|
||||
if (is_object($contentElement = $this->ttContentRepository->findByUid($contentElementUid))) {
|
||||
$news->addContentElement($contentElement);
|
||||
}
|
||||
}
|
||||
|
||||
$news->setInternalurl($importItem['internalurl']);
|
||||
$news->setExternalurl($importItem['externalurl']);
|
||||
|
||||
$news->setAuthor($importItem['author']);
|
||||
$news->setAuthorEmail($importItem['author_email']);
|
||||
|
||||
$news->setImportId($importItem['import_id']);
|
||||
$news->setImportSource($importItem['import_source']);
|
||||
|
||||
$news->setPathSegment($importItem['path_segment']);
|
||||
|
||||
if (is_array($importItem['categories'])) {
|
||||
foreach ($importItem['categories'] as $categoryUid) {
|
||||
if ($this->settings['findCategoriesByImportSource']) {
|
||||
$category = $this->categoryRepository->findOneByImportSourceAndImportId(
|
||||
$this->settings['findCategoriesByImportSource'],
|
||||
$categoryUid
|
||||
);
|
||||
} else {
|
||||
$category = $this->categoryRepository->findByUid($categoryUid);
|
||||
}
|
||||
|
||||
if ($category) {
|
||||
$news->addCategory($category);
|
||||
} else {
|
||||
$this->logger->warning(sprintf('Category with ID "%s" was not found', $categoryUid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// media relation
|
||||
if (is_array($importItem['media'])) {
|
||||
foreach ($importItem['media'] as $mediaItem) {
|
||||
// get fileobject by given identifier (file UID, combined identifier or path/filename)
|
||||
try {
|
||||
$file = $this->getResourceFactory()->retrieveFileOrFolderObject($mediaItem['image']);
|
||||
} catch (ResourceDoesNotExistException $exception) {
|
||||
$file = null;
|
||||
}
|
||||
|
||||
// no file found skip processing of this item
|
||||
if ($file === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// file not inside a storage then search for same file based on hash (to prevent duplicates)
|
||||
if ($file->getStorage()->getUid() === 0) {
|
||||
$existingFile = $this->findFileByHash($file->getSha1());
|
||||
if ($existingFile !== null) {
|
||||
$file = $existingFile;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var $media FileReference */
|
||||
if (!$media = $this->getIfFalRelationIfAlreadyExists($news->getFalMedia(), $file)) {
|
||||
|
||||
// file not inside a storage copy the one form storage 0 to the import folder
|
||||
if ($file->getStorage()->getUid() === 0) {
|
||||
$file = $this->getResourceStorage()->copyFile($file, $this->getImportFolder());
|
||||
}
|
||||
|
||||
$media = GeneralUtility::makeInstance(FileReference::class);
|
||||
$media->setFileUid($file->getUid());
|
||||
$news->addFalMedia($media);
|
||||
}
|
||||
|
||||
if ($media) {
|
||||
$media->setTitle($mediaItem['title']);
|
||||
$media->setAlternative($mediaItem['alt']);
|
||||
$media->setDescription($mediaItem['caption']);
|
||||
$media->setShowinpreview($mediaItem['showinpreview']);
|
||||
$media->setPid($importItem['pid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// related files
|
||||
if (is_array($importItem['related_files'])) {
|
||||
foreach ($importItem['related_files'] as $fileItem) {
|
||||
|
||||
// get fileObject by given identifier (file UID, combined identifier or path/filename)
|
||||
try {
|
||||
$file = $this->getResourceFactory()->retrieveFileOrFolderObject($fileItem['file']);
|
||||
} catch (ResourceDoesNotExistException $exception) {
|
||||
$file = null;
|
||||
}
|
||||
|
||||
// no file found skip processing of this item
|
||||
if ($file === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// file not inside a storage then search for same file based on hash (to prevent duplicates)
|
||||
if ($file->getStorage()->getUid() === 0) {
|
||||
$existingFile = $this->findFileByHash($file->getSha1());
|
||||
if ($existingFile !== null) {
|
||||
$file = $existingFile;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var $relatedFile FileReference */
|
||||
if (!$relatedFile = $this->getIfFalRelationIfAlreadyExists($news->getFalRelatedFiles(), $file)) {
|
||||
|
||||
// file not inside a storage copy the one form storage 0 to the import folder
|
||||
if ($file->getStorage()->getUid() === 0) {
|
||||
$file = $this->getResourceStorage()->copyFile($file, $this->getImportFolder());
|
||||
}
|
||||
|
||||
$relatedFile = GeneralUtility::makeInstance(FileReference::class);
|
||||
$relatedFile->setFileUid($file->getUid());
|
||||
$news->addFalRelatedFile($relatedFile);
|
||||
}
|
||||
|
||||
if ($relatedFile) {
|
||||
$relatedFile->setTitle($fileItem['title']);
|
||||
$relatedFile->setDescription($fileItem['description']);
|
||||
$relatedFile->setPid($importItem['pid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($importItem['related_links'])) {
|
||||
foreach ($importItem['related_links'] as $link) {
|
||||
/** @var $relatedLink Link */
|
||||
if (($relatedLink = $this->getRelatedLinkIfAlreadyExists($news, $link['uri'])) === false) {
|
||||
$relatedLink = GeneralUtility::makeInstance(Link::class);
|
||||
$relatedLink->setUri($link['uri']);
|
||||
$news->addRelatedLink($relatedLink);
|
||||
}
|
||||
$relatedLink->setTitle($link['title']);
|
||||
$relatedLink->setDescription($link['description']);
|
||||
$relatedLink->setPid($importItem['pid']);
|
||||
}
|
||||
}
|
||||
$event = $this->eventDispatcher->dispatch(new NewsImportPostHydrateEvent($this, $importItem, $news));
|
||||
|
||||
return $event->getNews();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import
|
||||
*
|
||||
* @param array $importData
|
||||
* @param array $importItemOverwrite
|
||||
* @param array $settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function import(array $importData, array $importItemOverwrite = [], $settings = []): void
|
||||
{
|
||||
$this->settings = $settings;
|
||||
$this->logger->info(sprintf('Starting import for %s news', count($importData)));
|
||||
|
||||
foreach ($importData as $importItem) {
|
||||
$event = $this->eventDispatcher->dispatch(new NewsImportPreHydrateEvent($this, $importItem));
|
||||
$importItem = $event->getImportItem();
|
||||
|
||||
// Store language overlay in post persist queue
|
||||
if ((int)$importItem['sys_language_uid'] > 0 && (string)$importItem['l10n_parent'] !== '0') {
|
||||
$this->postPersistQueue[$importItem['import_id']] = [
|
||||
'action' => self::ACTION_IMPORT_L10N_OVERLAY,
|
||||
'category' => null,
|
||||
'importItem' => $importItem
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
$news = $this->initializeNewsRecord($importItem);
|
||||
|
||||
$this->hydrateNewsRecord($news, $importItem, $importItemOverwrite);
|
||||
}
|
||||
|
||||
$this->persistenceManager->persistAll();
|
||||
|
||||
foreach ($this->postPersistQueue as $queueItem) {
|
||||
if ($queueItem['action'] == self::ACTION_IMPORT_L10N_OVERLAY) {
|
||||
$this->importL10nOverlay($queueItem, $importItemOverwrite);
|
||||
}
|
||||
}
|
||||
|
||||
$this->persistenceManager->persistAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $queueItem
|
||||
* @param array $importItemOverwrite
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function importL10nOverlay(array $queueItem, array $importItemOverwrite): void
|
||||
{
|
||||
$importItem = $queueItem['importItem'];
|
||||
$parentNews = $this->newsRepository->findOneByImportSourceAndImportId(
|
||||
$importItem['import_source'],
|
||||
$importItem['l10n_parent'],
|
||||
true
|
||||
);
|
||||
|
||||
if (!empty($parentNews)) {
|
||||
$news = $this->initializeNewsRecord($importItem);
|
||||
|
||||
$this->hydrateNewsRecord($news, $importItem, $importItemOverwrite);
|
||||
|
||||
$news->setSysLanguageUid($importItem['sys_language_uid']);
|
||||
$news->setL10nParent($parentNews['uid']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an existing items from the references that matches the file
|
||||
*
|
||||
* @param ObjectStorage $items
|
||||
* @param \TYPO3\CMS\Core\Resource\File $file
|
||||
*
|
||||
* @return bool|FileReference
|
||||
*/
|
||||
protected function getIfFalRelationIfAlreadyExists(
|
||||
ObjectStorage $items,
|
||||
File $file
|
||||
) {
|
||||
$result = false;
|
||||
if ($items->count() !== 0) {
|
||||
/** @var $item FileReference */
|
||||
foreach ($items as $item) {
|
||||
// only check already persisted items
|
||||
if ($item->getFileUid() === (int)$file->getUid()
|
||||
||
|
||||
($item->getUid() &&
|
||||
$item->getOriginalResource()->getName() === $file->getName() &&
|
||||
$item->getOriginalResource()->getSize() === (int)$file->getSize())
|
||||
) {
|
||||
$result = $item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an existing related link object
|
||||
*
|
||||
* @param News $news
|
||||
* @param string $uri
|
||||
* @return bool|Link
|
||||
*/
|
||||
protected function getRelatedLinkIfAlreadyExists(News $news, $uri)
|
||||
{
|
||||
$result = false;
|
||||
$links = $news->getRelatedLinks();
|
||||
|
||||
if (!empty($links) && $links->count() !== 0) {
|
||||
foreach ($links as $link) {
|
||||
if ($link->getUri() === $uri) {
|
||||
$result = $link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user