bookmark-pages/Classes/Service/RichSnippetService.php

443 lines
12 KiB
PHP
Raw Permalink Normal View History

2021-08-17 19:45:38 +02:00
<?php
/*
* This file is part of the package thucke/th-rating.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
namespace WapplerSystems\BookmarksLikesRatings\Service;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Log\LogLevel;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
/**
* The voter
*/
class RichSnippetService extends AbstractExtensionService
{
/**
* Instances of AggregateRating may appear as properties of the following types
* This list derives from Google's information about supported types in aggregateRating (20 May 2021)
* (see https://developers.google.com/search/docs/data-types/review-snippet#aggregated-rating-type-definition)
* @const array
*/
protected const VALID_AGGREGATE_RATING_SCHEMA_TYPES = [
'Book',
'Audiobook',
'Course',
'CreativeWorkSeason',
'PodcastSeason',
'RadioSeason',
'TVSeason',
'CreativeWorkSeries',
'BookSeries',
'MovieSeries',
'Periodical',
'ComicSeries',
'Newspaper',
'PodcastSeries',
'RadioSeries',
'TVSeries',
'VideoGameSeries',
'Episode',
'PodcastEpisode',
'RadioEpisode',
'TVEpisode',
'Event',
'BusinessEvent',
'ChildrensEvent',
'ComedyEvent',
'CourseInstance',
'DanceEvent',
'DeliveryEvent',
'EducationEvent',
'EventSeries',
'ExhibitionEvent',
'Festival',
'FoodEvent',
'Hackathon',
'LiteraryEvent',
'MusicEvent',
'PublicationEvent',
'BroadcastEvent',
'OnDemandEvent',
'SaleEvent',
'ScreeningEvent',
'SocialEvent',
'SportsEvent',
'TheaterEvent',
'VisualArtsEvent',
'Game',
'VideoGame',
'HowTo',
'Recipe',
'AnimalShelter',
'ArchiveOrganization',
'AutomotiveBusiness',
'AutoBodyShop',
'AutoDealer',
'AutoRental',
'AutoRepair',
'AutoWash',
'GasStation',
'MotorcycleDealer',
'MotorcycleRepair',
'ChildCare',
'DryCleaningOrLaundry',
'EmergencyService',
'FireStation',
'Hospital',
'PoliceStation',
'EmploymentAgency',
'EntertainmentBusiness',
'AdultEntertainment',
'AmusementPark',
'ArtGallery',
'Casino',
'ComedyClub',
'MovieTheater',
'NightClub',
'FinancialService',
'AccountingService',
'AutomatedTeller',
'BankOrCreditUnion',
'InsuranceAgency',
'FoodEstablishment',
'Bakery',
'BarOrPub',
'Brewery',
'CafeOrCoffeeShop',
'Distillery',
'FastFoodRestaurant',
'IceCreamShop',
'Restaurant',
'Winery',
'GovernmentOffice',
'PostOffice',
'HealthAndBeautyBusiness',
'BeautySalon',
'DaySpa',
'HairSalon',
'NailSalon',
'TattooParlor',
'HomeAndConstructionBusiness',
'Electrician',
'GeneralContractor',
'HVACBusiness',
'HousePainter',
'Locksmith',
'MovingCompany',
'Plumber',
'RoofingContractor',
'InternetCafe',
'LegalService',
'Attorney',
'Notary',
'Library',
'LodgingBusiness',
'BedAndBreakfast',
'Campground',
'Hostel',
'Hotel',
'Motel',
'Resort',
'MedicalBusiness',
'CovidTestingFacility',
'Optician',
'Pharmacy',
'Physician',
'ProfessionalService',
'RadioStation',
'RealEstateAgent',
'RecyclingCenter',
'SelfStorage',
'ShoppingCenter',
'SportsActivityLocation',
'BowlingAlley',
'ExerciseGym',
'GolfCourse',
'HealthClub',
'PublicSwimmingPool',
'SkiResort',
'SportsClub',
'StadiumOrArena',
'TennisComplex',
'Store',
'AutoPartsStore',
'BikeStore',
'BookStore',
'ClothingStore',
'ComputerStore',
'ConvenienceStore',
'DepartmentStore',
'ElectronicsStore',
'Florist',
'FurnitureStore',
'GardenStore',
'GroceryStore',
'HardwareStore',
'HobbyShop',
'HomeGoodsStore',
'JewelryStore',
'LiquorStore',
'MensClothingStore',
'MobilePhoneStore',
'MovieRentalStore',
'MusicStore',
'OfficeEquipmentStore',
'OutletStore',
'PawnShop',
'PetStore',
'ShoeStore',
'SportingGoodsStore',
'TireShop',
'ToyStore',
'WholesaleStore',
'TelevisionStation',
'TouristInformationCenter',
'TravelAgency',
'MediaObject',
'3DModel',
'AudioObject',
'DataDownload',
'ImageObject',
'Barcode',
'LegislationObject',
'MusicVideoObject',
'VideoObject',
'Movie',
'MusicPlaylist',
'MusicAlbum',
'MusicRelease',
'MusicRecording',
'Organization',
'Airline',
'Consortium',
'Corporation',
'EducationalOrganization',
'CollegeOrUniversity',
'ElementarySchool',
'HighSchool',
'MiddleSchool',
'Preschool',
'School',
'FundingScheme',
'GovernmentOrganization',
'LibrarySystem',
'LocalBusiness',
'MedicalOrganization',
'NGO',
'NewsMediaOrganization',
'Dentist',
'DiagnosticLab',
'MedicalClinic',
'VeterinaryCare',
'PerformingGroup',
'DanceGroup',
'MusicGroup',
'TheaterGroup',
'Project',
'FundingAgency',
'ResearchProject',
'SportsOrganization',
'SportsTeam',
'WorkersUnion',
'Product',
'IndividualProduct',
'ProductCollection',
'ProductGroup',
'ProductModel',
'SomeProducts',
'Vehicle',
'BusOrCoach',
'Car',
'Motorcycle',
'MotorizedBicycle',
'SoftwareApplication',
'MobileApplication',
'WebApplication'
];
/**
* @var string
*/
protected $schema = 'Product';
/**
* @var string
*/
protected $anchor;
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $description;
/**
* @var array
*/
protected $richSnippetConfig;
/**
* @param array $settings
* @return bool
*/
public function setRichSnippetConfig(array $settings): bool
{
$this->logger->log(LogLevel::DEBUG, 'setRichSnippetConfig Entry point', $settings);
$this->richSnippetConfig['tablename'] = $settings['ratetable'];
$this->richSnippetConfig['richSnippetFields'] = $settings['richSnippetFields'];
if (is_array($this->richSnippetConfig['richSnippetFields'])) {
$this->logger->log(
LogLevel::DEBUG,
'setRichSnippetConfig Exit point',
$this->richSnippetConfig['richSnippetFields']
);
return true;
}
$this->logger->log(LogLevel::DEBUG, 'setRichSnippetConfig Exit point');
return false;
}
/**
* @return string|false
*/
public function getRichSnippetConfig()
{
return GeneralUtility::makeInstance(\WapplerSystems\BookmarksLikesRatings\Service\JsonService::class)
->encodeToJson($this->richSnippetConfig);
}
/**
* @return string
*/
public function getSchema(): string
{
return $this->schema;
}
/**
* @param string|null $schema
* @throws \WapplerSystems\BookmarksLikesRatings\Exception\InvalidAggregateRatingSchemaTypeException if parameter is invalid
*/
public function setSchema(?string $schema): void
{
if (!empty($schema)) {
if (in_array($schema, self::VALID_AGGREGATE_RATING_SCHEMA_TYPES, true)) {
$this->schema = $schema;
} else {
throw new \WapplerSystems\BookmarksLikesRatings\Exception\InvalidAggregateRatingSchemaTypeException(
LocalizationUtility::translate(
'error.richSnippetConfiguration.AggregateRatingPropertySchema',
'ThRating'
),
1521487362
);
}
}
}
/**
* @return string
*/
public function getAnchor(): string
{
return $this->anchor;
}
/**
* @param string $anchor
*/
public function setAnchor(string $anchor): void
{
$this->anchor = $anchor;
}
/**
* @param string|null $name
*/
public function setName(?string $name): void
{
$this->name = $name;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @return string|null
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* @param string|null $description
*/
public function setDescription(?string $description): void
{
$this->description = $description;
}
/**
* @param int $uid
* @return RichSnippetService
*@throws \WapplerSystems\BookmarksLikesRatings\Exception\InvalidAggregateRatingSchemaTypeException
*/
public function getRichSnippetObject(int $uid): self
{
$this->logger->log(LogLevel::DEBUG, 'getRichSnippetObject Entry point');
$this->setSchema($this->richSnippetConfig['richSnippetFields']['aggregateRatingSchemaType']);
if (empty($this->richSnippetConfig['richSnippetFields']['name'])) {
$this->logger->log(LogLevel::INFO, 'No name field defined - skipping database access');
unset($this->name, $this->description);
throw new \TYPO3\CMS\Core\Exception();
} else {
/** @var QueryBuilder $queryBuilder */
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable($this->richSnippetConfig['tablename']);
//fetch whole row from database
/** @var array $row */
$row = $queryBuilder
->select('*')
->from($this->richSnippetConfig['tablename'])
->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid)))
->execute()
->fetch();
$this->logger->log(LogLevel::DEBUG, 'Data fetched', $row);
$this->setName($row[$this->richSnippetConfig['richSnippetFields']['name']]);
$contentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
$this->setDescription($row[$this->richSnippetConfig['richSnippetFields']['description']]);
//$this->setDescription($contentObjectRenderer->cObjGetSingle('TEXT', $this->richSnippetConfig['richSnippetFields']['description']));
//$this->setDescription($contentObjectRenderer->render($this->richSnippetConfig['richSnippetFields']['description']));
}
$this->logger->log(LogLevel::DEBUG, 'getRichSnippetObject Exit point', (array)$this);
return $this;
}
}