Zwischenstand
This commit is contained in:
442
Classes/Service/RichSnippetService.php
Normal file
442
Classes/Service/RichSnippetService.php
Normal file
@@ -0,0 +1,442 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user