<?php
declare(strict_types=1);
/*
* Copyright (C) Office National de Publication et de Communication - All Rights Reserved
*
* Unauthorized copying of this file, via any medium is strictly prohibited by law
* This file is proprietary and confidential
*/
namespace App\Twig;
use stdClass;
use App\Entity\Video;
use Twig\Environment;
use Twig\TwigFunction;
use App\Entity\Actualite;
use App\Service\PathBuilder;
use App\Entity\Etablissement;
use App\Entity\DiaporamaPhoto;
use App\Entity\DonneeComplementaire;
use Symfony\Component\Asset\Package;
use Twig\Extension\AbstractExtension;
use App\Twig\DonneeComplementaireExtension;
use Symfony\Component\Routing\RouterInterface;
use \Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
final class JsonLdExtension extends AbstractExtension
{
/** @var RouterInterface */
private $router;
/** @var PathBuilder */
private $pathBuilder;
/** @var CacheManager */
private $imagineCacheManager;
/** @var Environment */
private $twig;
public function __construct(RouterInterface $router, PathBuilder $pathBuilder, CacheManager $imagineCacheManager, Environment $twig)
{
$this->router = $router;
$this->pathBuilder = $pathBuilder;
$this->imagineCacheManager = $imagineCacheManager;
$this->twig = $twig;
}
public function getFunctions()
{
return [
new TwigFunction('jsonLdActualite', [$this, 'actualite']),
new TwigFunction('jsonLdEtablissement', [$this, 'etablissement']),
new TwigFunction('jsonLdDiplomes', [$this, 'diplomes']),
new TwigFunction('jsonLdOnpc', [$this, 'onpc']),
new TwigFunction('jsonLdWebsite', [$this, 'website']),
new TwigFunction('jsonLdVideo', [$this, 'video']),
new TwigFunction('jsonLdDiapo', [$this, 'diapo']),
new TwigFunction('jsonLdFaq', [$this, 'generateFaqJsonLd']),
];
}
public function actualite(Actualite $actualite): stdClass
{
$etablissement = $actualite->getEtablissement();
$logoUrl = $this->imagineCacheManager->getBrowserPath('/images/jouve/logo-fiche/' . $etablissement->getLogoFiche(), 'etab_fiche_logo');
$imageUrl = $actualite->getUrlImage();
return (object) array_filter([
'@context' => 'https://schema.org/',
'@type' => 'NewsArticle',
// 'url' => $this->pathBuilder->buildFiche($etablissement),
// 'author' => $etablissement->getDenomination(),
'headline' => $actualite->getTitre(),
'datePublished' => $actualite->getDatePublication()->format('c'),
'dateModified' => $actualite->getDateActualisation()->format('c'),
'description' => $actualite->getResume(),
'publisher' => $etablissement ? (object) array_filter([
'@type' => 'Organization',
'name' => $etablissement->getDenomination(),
'logo' => $logoUrl ? (object) [
'@type' => 'ImageObject',
'url' => $logoUrl,
] : null,
'url' => $etablissement->getUrl(),
]) : null,
'image' => $imageUrl ? (object) [
'@type' => 'ImageObject',
'url' => $imageUrl,
] : null,
]);
}
public function etablissement(Etablissement $etablissement, $noLogoPath): stdClass
{
$ville = $etablissement->getVille();
return (object) [
'@context' => 'http://schema.org/',
'@type' => 'School',
'name' => $etablissement->getDenomination(),
'legalName' => $etablissement->getDenomination(),
'url' => $etablissement->getUrl() ?? $this->router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL).'fiche/'.$etablissement->getId(),
/*'sameAs' => // Ajouter réseau sociaux */
'logo' => null !== $etablissement->getLogoFiche()
? $this->imagineCacheManager->getBrowserPath('/images/jouve/logo-fiche/' . $etablissement->getLogoFiche(), 'etab_fiche_logo')
: $this->router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL).$noLogoPath ,
'email' => $etablissement->getEmailPrincipal(),
'faxNumber' => $etablissement->getFax(),
'telephone' => $etablissement->getTelephonePrincipal(),
'address' => (object) [
'@type' => 'PostalAddress',
'addressCountry' => 'France',
'addressLocality' => $ville ? $ville->getLibelle() : null,
'postalCode' => $etablissement->getCodePostal(),
'streetAddress' => $etablissement->getAdresse1().' '.$etablissement->getAdresse2().' '.$etablissement->getAdresse3(),
'email' => $etablissement->getEmailPrincipal(),
'faxNumber' => $etablissement->getFax(),
'telephone' => $etablissement->getTelephonePrincipal(),
'name' => $etablissement->getDenomination(),
],
'location' => (object) [
'@type' => 'Place',
'geo' => (object) [
'@type' => 'GeoCoordinates',
'latitude' => $etablissement->getLatitude(),
'longitude' => $etablissement->getLongitude(),
],
],
];
}
public function diplomes($lesFormations, $donneeComplementaire, $etablissement) {
// Regrouper les diplomes par formations
try {
$niveauxFormation = [
"-CAP-" => "Niveau CAP",
"-BACP-" => "Niveau BAC Pro",
"-BAC2-" => "Niveau Bac+2",
"-PREPA-" => "Classes Prépas",
"-BAC3-" => "Niveau Bac+3",
"-BAC45-" => "Niveau Bac+4/5",
"-ING-" => "Diplômes d'ingénieurs",
"-FPC-" => "Formation Professionnelle Continue",
"-BACTECH-" => "Bac Techno (Agricole)",
"-DIPCOMP-" => "Diplômes complémentaires"
];
$formations = array();
foreach ($niveauxFormation as $idFormation => $libFormation) {
foreach ($lesFormations as $ItemsInsertion) {
if (stristr($ItemsInsertion->getIdentifiant(), $idFormation)) {
// Données compléentaires :
$dcTexte = DonneeComplementaireExtension::donneeComplementaireStatic($donneeComplementaire, $ItemsInsertion->getIdentifiant(), 'texte' );
$formations[$libFormation][] = $ItemsInsertion->getLibelle() . "#" . $ItemsInsertion->getLibelleSpecifique() . "#" . $dcTexte;
}
}
}
// Construire l'object json
$courseJsonld = [];
foreach ($formations as $niveau => $formationsNiveau) {
$course = [
'@context' => 'http://schema.org/',
"@type" => "Course",
"name" => $niveau,
"description" => $niveau,
"hasCourseInstance" => [
"@type" => "CourseInstance",
"courseMode" => "onsite",
"name" => $niveau,
"courseWorkload" => "PT30H" // "PT" indique que c'est une durée. "30H" signifie 30 heures.
],
"offers" => [
"@type" => "Offer",
"price" => "0.00",
"priceCurrency" => "EUR",
"category" => "Education"
],
"provider" => [
"@type" => "Organization",
"name" => $etablissement->getDenomination(),
"url" => $etablissement->getUrl() ?? $this->router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL).'fiche/'.$etablissement->getId()
],
"educationalCredentialAwarded" => []
];
foreach ($formationsNiveau as $formation) {
list($libelle, $libelleSpecifique, $complement) = explode("#", $formation);
$course["educationalCredentialAwarded"][] = [
'@context' => 'http://schema.org/',
"@type" => "EducationalOccupationalCredential",
"name" => $libelle,
"alternateName" => $libelleSpecifique ?? null,
"description" => $complement ?? null,
"educationalLevel" => str_replace("Niveau ", "", $niveau)
];
}
$courseJsonld[] = $course;
}
} catch (\Exception $e) {
$courseJsonld = null;
}
return json_encode($courseJsonld, JSON_UNESCAPED_UNICODE);
}
public function onpc(): stdClass
{
return (object) [
'@context' => 'http://schema.org/',
'@type' => 'Organization',
'name' => 'Office National de Publication et de Communication',
'alternateName' => 'ONPC',
'url' => 'http://www.onpc.fr',
'logo' => (object) [
'@type' => 'ImageObject',
'url' => 'http://www.onpc.fr/onpc/mes-docs/uploads/2016/10/logo-SVG.svg',
],
];
}
public function website(): stdClass
{
return (object) [
'@context' => 'http://schema.org/',
'@type' => 'WebSite',
'@id' => '#website',
'name' => "L'annuaire officiel de l'enseignement privé",
'about' => "L'annuaire officiel de l'enseignement privé: retrouvez toutes les informations sur les établissements privés catholiques et laïques de France. Ecole primaire, collèges privés, lycées privés, lycées technologiques, enseignement supérieur. Un outil de recherche indispensable pour l'orientation scolaire",
'url' => $this->router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL),
'author' => $this->onpc(),
'potentialAction' => (object) [
'@type' => 'SearchAction',
'target' => $this->router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL) . 'annuaire/{quoi}/{ou}', /*$this->pathBuilder->buildAnnuaire('{quoi}', '{ou}'),*/
'query-input' => 'required name=quoi name=ou',
],
];
}
public function video(Video $video): stdClass
{
return (object) [
'@context' => 'http://schema.org/',
'@type' => 'VideoObject',
'name' => $video->getTitre(),
'url' => $video->getUrl(),
'description' => $video->getTexte() != null ? $video->getTexte() : $video->getEtablissements()[0]->getDenomination(),
'uploadDate' => $video->getDateCrea()->format('c'),
'thumbnailUrl' =>$this->router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL).'storage/video/'.$video->getFileName()
];
}
public function diapo(DiaporamaPhoto $diaporamaPhoto): stdClass
{
return (object) [
'@context' => 'http://schema.org/',
'@type' => 'ImageObject',
'name' => $diaporamaPhoto->getTitre(),
'url' => $this->router->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL).'storage/diaporama_photo/'.$diaporamaPhoto->getFileName(),
// 'url' => $this->imagineCacheManager->getBrowserPath('/images/jouve/photo/' . $diaporamaPhoto->getFileName(), 'etab_fiche')
];
}
public function generateFaqJsonLd(array $faqs): ?string
{
if (count($faqs) == 0)
return null;
$data = [
"@context" => "https://schema.org",
"@type" => "FAQPage",
"mainEntity" => [],
];
foreach ($faqs as $faq) {
$data['mainEntity'][] = [
"@type" => "Question",
"name" => $faq->getQuestion(),
"acceptedAnswer" => [
"@type" => "Answer",
"text" => strip_tags($faq->getReponse()),
],
];
}
// return json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
return json_encode($data, JSON_UNESCAPED_UNICODE);
}
}