<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity;
use App\Repository\EstateRepository;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\String\Inflector\FrenchInflector;
use function Symfony\Component\String\u;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use App\Utils\EmojiHelper;
/**
* @ORM\Entity(repositoryClass=EstateRepository::class)
* @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=false)
* @ORM\HasLifecycleCallbacks
* @UniqueEntity("refannonce")
*/
class Estate
{
use TimestampableEntity;
use SoftDeleteableEntity;
private $imagineCacheManager;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
*/
private $refannonce;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
*/
private $identifiant_technique;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private $numeromandat;
/**
* @var \DateTime
* @ORM\Column( type="datetime", nullable=true)
*/
private $mandatAt;
/**
* @ORM\Column(type="integer", options={"default":1})
* @Assert\NotBlank
*/
private $statut;
/**
* @ORM\Column(type="string", length=255, options={"default":"available"})
* @Assert\NotBlank
*/
private $statut_name;
/**
* @Gedmo\Slug(fields={"refannonce", "libelle"})
* @ORM\Column(type="string", length=255, unique=true)
*/
private $slug;
/**
* @ORM\Column(type="string", length=255)
*/
private $typebien;
/**
* @ORM\Column(type="boolean" , options={"default":0})
*/
private $si_mandatexclusif;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $libelle;
/**
* @ORM\Column(type="text", nullable=true, options={"collation": "utf8mb4_unicode_ci"})
*/
private $descriptif;
/**
* @ORM\Column(type="float", scale=2, nullable=true)
*/
private $prix;
/**
* @ORM\Column(type="float", scale=2, nullable=true)
*/
private $surface;
/**
* @ORM\Column(type="float", scale=2, nullable=true)
*/
private $surf_terrain;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private $nbpieces;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private $nbchambres;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $latitude;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $longitude;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $orientation;
/**
* @ORM\Column(type="json", nullable=true)
*/
private $photos = [];
/**
* @ORM\Column(type="json", nullable=true)
*/
private $features = [];
/**
* @ORM\Column(type="json", nullable=true)
*/
private $icones = [];
/**
* @ORM\ManyToOne(targetEntity=Agent::class, inversedBy="estates")
* @ORM\JoinColumn(nullable=true)
*/
private $agent;
/**
* @ORM\ManyToMany(targetEntity=Agent::class, inversedBy="share_estates" )
* @ORM\JoinTable(name="share_with_agents")
*/
private $share_with_agents;
/**
* @ORM\ManyToMany(targetEntity=User::class, mappedBy="favorites")
*/
private $users;
/**
* @ORM\ManyToMany(targetEntity=SearchNotification::class, mappedBy="estates")
*/
private $notifications;
/**
* @ORM\Column(type="boolean" , options={"default":0})
*/
private $is_new_checked;
/**
* @ORM\Column(type="boolean" , options={"default":0})
*/
private $is_delete_checked;
/**
* @ORM\Column(type="string", length=10)
*/
private $import_type;
private $orientations = ['si_orientenord' => false, 'si_orientesud' => false, 'si_orienteouest' => false, 'si_orienteest'=> false];
private $default_features = [
'localisation' => [
'adresse' => '',
'cp' => '',
'ville' => '',
'pays' => '',
'latitude' => '',
'longitude' => '',
'cp_reel' => '',
'ville_reelle' => '',
'nb_departement' => '',
'departement' => ''
]
];
/**
* @ORM\ManyToOne(targetEntity=SousType::class, inversedBy="estates")
* @ORM\JoinColumn(nullable=true)
*/
private $sous_type;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $ca;
/**
* @ORM\Column(type="float", nullable=true)
*/
private $ebe;
public function __construct()
{
$this->users = new ArrayCollection();
$this->notifications = new ArrayCollection();
$this->share_with_agents = new ArrayCollection();
}
public function __toString() {
return $this->refannonce;
}
public function setImagineCacheManager(CacheManager $imagineCacheManager) {
$this->imagineCacheManager = $imagineCacheManager;
}
public function getName(): ?string
{
return $this->refannonce;
}
public function getId(): ?int
{
return $this->id;
}
public function getRefannonce(): ?string
{
return $this->refannonce;
}
public function setRefannonce(string $refannonce): self
{
$this->refannonce = $refannonce;
return $this;
}
public function getIdentifiantTechnique(): ?string
{
return $this->identifiant_technique;
}
public function setIdentifiantTechnique(string $identifiant_technique): self
{
$this->identifiant_technique = $identifiant_technique;
return $this;
}
public function getNumeromandat(): ?int
{
return $this->numeromandat;
}
public function setNumeromandat(?int $numeromandat): self
{
$this->numeromandat = $numeromandat;
return $this;
}
public function getMandatAt(): ?\DateTimeInterface
{
return $this->mandatAt;
}
public function setMandatAt($mandatAt=null): self
{
if(!is_null($mandatAt)){
$mandatAt = new \DateTime ($mandatAt);
$mandatAt->setTime(0, 0, 0);
}
// Empêche la modification si la valeur est identique cat l'objet DateTime est diffrérent
if($mandatAt != $this->mandatAt){
$this->mandatAt = $mandatAt;
}
return $this;
}
public function setDateMandat($date): self
{
$this->setMandatAt($date);
return $this;
}
public function getMandatAtFormated()
{
$mandatAt = $this->getMandatAt();
return $mandatAt ? $mandatAt->format('d/m/Y') : null;
}
public function getStatut(): ?string
{
return $this->convertedValue('statut', $this->statut);
// return $this->statut;
}
public function getStatutRaw(): ?string
{
return $this->statut;
}
public function setStatut(int $statut): self
{
$this->statut = $statut;
return $this;
}
public function getStatutName(): ?string
{
return $this->convertedValue('statut_name', $this->statut_name);
// return $this->statut_name;
}
public function getStatutNameRaw(): ?string
{
return $this->statut_name;
}
public function setStatutName(string $statut_name): self
{
$this->statut_name = $statut_name;
return $this;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): self
{
$this->slug = $slug;
return $this;
}
public function getTypebienRaw(): ?string
{
return $this->typebien;
}
public function getTypebien(): ?string
{
$types = array_flip(self::getTypes());
return isset($types[$this->typebien])? $types[$this->typebien] : u( $this->typebien )->title();
}
public function setTypebien(string $typebien): self
{
$this->typebien = $typebien;
return $this;
}
public function getSiMandatexclusif(): ?bool
{
return $this->si_mandatexclusif;
}
public function setSiMandatexclusif(bool $si_mandatexclusif): self
{
$this->si_mandatexclusif = $si_mandatexclusif;
return $this;
}
public function getLibelle(): ?string
{
return $this->getTitle();
}
public function setLibelle(?string $libelle): self
{
$this->libelle = $libelle;
return $this;
}
public function getDescriptif(): ?string
{
//enleve les emoticons
// $this->descriptif = $this->removeEmojis($this->descriptif);
// $this->descriptif = strip_tags($this->descriptif, '<sup>,<br>,<p>');
return $this->descriptif;
}
public function setDescriptif(?string $descriptif): self
{
//corrections
$descriptif = str_replace('SOUS OFRE', 'SOUS OFFRE', $descriptif);
$mentions = [
'sous offre',
'sous compromis',
'vendu',
'en vente'
];
// Pour chaque mention, on supprime les variantes au début ou dans le texte avec la présence des signes : .:/-
foreach ($mentions as $mention) {
$descriptif = preg_replace(
// '#/?/?\s*' . preg_quote($mention, '#') . '\s*[.:/-]*\s*/?/?#i',
'#(?<=^|[\s/:\-\.])' . preg_quote($mention, '#') . '(?=[\s/:\-\.]|$)#i',
'',
$descriptif
);
}
//supprime les /// ou, /// avec ou sans espace
$descriptif = preg_replace('#\s*/{2,}\s*#', '', $descriptif);
//suppime les espaces double
$descriptif = trim(preg_replace('/\s{2,}/', ' ', $descriptif));
//supprime les sauts de ligne en début de chaine
$descriptif = preg_replace('#^(<br\s*/?>\s*)+#i', '', $descriptif);
//supprime les espaces au début et à la fin
$descriptif = trim($descriptif);
//ajoute un espace après un signe de ponctuation [.!?] suivi d'un caractère
$descriptif = preg_replace('#([.!?])(\S)#', '$1 $2', $descriptif);
//m2 => m²
$descriptif = preg_replace('#m2#', 'm²', $descriptif);
// Supprime uniquement les (et espaces normaux) en début de chaîne
$descriptif = preg_replace('/^(?: |\s)+/i', '', $descriptif);
//Netoyage HTL , mais conserve <sup>,<br>,<p>
$descriptif = strip_tags($descriptif, '<sup>,<br>,<p>');
// Supprimer les <p> vides ou contenant seulement <br> ou des espaces
$descriptif = preg_replace('#<p>\s*(<br\s*/?>)?\s*</p>#i','',$descriptif);
// Supprimer les multiples sauts de ligne inutiles
$descriptif = preg_replace("/\n\s*\n/", "\n", $descriptif);
$this->descriptif = $descriptif;
return $this;
}
private function containsEmoji(string $text): bool {
return preg_match(
'/[\x{1F600}-\x{1F64F}' . // Emoticons
'\x{1F300}-\x{1F5FF}' . // Symbols & pictographs
'\x{1F680}-\x{1F6FF}' . // Transport & map
'\x{1F1E0}-\x{1F1FF}' . // Flags
'\x{2600}-\x{26FF}' . // Misc symbols
'\x{2700}-\x{27BF}' . // Dingbats
'\x{1F900}-\x{1F9FF}' . // Supplemental symbols
'\x{1FA70}-\x{1FAFF}' . // Symbols & pictographs extended-A
'\x{1F018}-\x{1F270}' . // Playing cards, enclosed
'\x{238C}-\x{2454}' . // Misc technical
'\x{20D0}-\x{20FF}' . // Combining Diacritical Marks for Symbols
'\x{FE00}-\x{FE0F}' . // Variation Selectors
'\x{1F000}-\x{1F02F}' . // Mahjong & domino
'\x{1F1F2}-\x{1F1F4}' . // Flags (regional)
'\x{1F1E6}-\x{1F1FF}]' . // Country flags
'/u',$text);
}
private function removeEmojis(string $text): string {
return preg_replace(
'/[\x{1F600}-\x{1F64F}' . // Emoticons
'\x{1F300}-\x{1F5FF}' . // Symbols & pictographs
'\x{1F680}-\x{1F6FF}' . // Transport & map
'\x{1F1E0}-\x{1F1FF}' . // Flags
'\x{2600}-\x{26FF}' . // Misc symbols
'\x{2700}-\x{27BF}' . // Dingbats
'\x{1F900}-\x{1F9FF}' . // Supplemental symbols
'\x{1FA70}-\x{1FAFF}' . // Symbols & pictographs extended-A
'\x{1F018}-\x{1F270}' . // Playing cards, enclosed
'\x{238C}-\x{2454}' . // Misc technical
'\x{20D0}-\x{20FF}' . // Combining Diacritical Marks for Symbols
'\x{FE00}-\x{FE0F}' . // Variation Selectors
'\x{1F000}-\x{1F02F}' . // Mahjong & domino
'\x{1F1F2}-\x{1F1F4}' . // Flags (regional)
'\x{1F1E6}-\x{1F1FF}]' . // Country flags
'/u', '', $text);
}
public function getPrix(): ?float
{
return $this->prix;
}
public function setPrix(?float $prix): self
{
$this->prix = $prix;
return $this;
}
public function getSurface(): ?float
{
return $this->surface;
}
public function setSurface(?float $surface): self
{
$this->surface = $surface;
return $this;
}
public function getSurfTerrain(): ?float
{
return $this->surf_terrain;
}
public function setSurfTerrain(?float $surf_terrain): self
{
$this->surf_terrain = $surf_terrain;
return $this;
}
public function getNbpieces(): ?int
{
return $this->nbpieces;
}
public function setNbpieces(?int $nbpieces): self
{
$this->nbpieces = $nbpieces;
return $this;
}
public function getNbchambres(): ?int
{
return $this->nbchambres;
}
public function setNbchambres(?int $nbchambres): self
{
$this->nbchambres = $nbchambres;
return $this;
}
public function getLatitude(): ?string
{
// return $this->features['localisation']['latitude'];
return $this->latitude;
}
public function setLatitude(?float $latitude): self
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?string
{
// return $this->features['localisation']['longitude'];
return $this->longitude;
}
public function setLongitude(?float $longitude): self
{
$this->longitude = $longitude;
return $this;
}
public function getOrientation(): ?string
{
return $this->orientation;
}
public function setOrientation(?string $orientation): self
{
$this->orientation = $orientation;
return $this;
}
public function getPhotos(): ?array
{
return is_null($this->photos) ? [] : $this->photos;
}
public function setPhotos(?array $photos): self
{
$this->photos = $photos;
return $this;
}
public function getFeatures(): ?array
{
return $this->features;
}
public function setFeatures(?array $features): self
{
$this->features = $features;
return $this;
}
public function getIcones(): ?array
{
$this->icones['nbsdeau_sdb'] = (int) $this->icones['nbsdeau'] + (int) $this->icones['nbsdb'];
return $this->icones;
}
public function setIcones(?array $icones): self
{
$this->icones = $icones;
return $this;
}
public function getAgent(): ?Agent
{
return $this->agent;
}
public function setAgent(?Agent $agent): self
{
$this->agent = $agent;
return $this;
}
public function getIsNewChecked(): ?bool
{
return $this->is_new_checked;
}
public function setIsNewChecked(bool $is_new_checked): self
{
$this->is_new_checked = $is_new_checked;
return $this;
}
public function getIsDeleteChecked(): ?bool
{
return $this->is_delete_checked;
}
public function setIsDeleteChecked(bool $is_delete_checked): self
{
$this->is_delete_checked = $is_delete_checked;
return $this;
}
public function getImportType(): ?string
{
return $this->import_type;
}
public function setImportType(string $import_type): self
{
$this->import_type = $import_type;
return $this;
}
//METHODS --------------------------------------------------------------
public function getCountPhotos(): ?int
{
$photos = $this->getPhotos();
$nb_photos = is_countable($photos) ? count($photos) : 0;
return $nb_photos%2 != 0 ? $nb_photos : $nb_photos - 1;
}
public function getPhotoForStream($index): ?string
{
if( isset($this->photos[$index]) ){
//remove (http:// ou https://)
return preg_replace("#^[^:/.]*[:/]+#i", '',$this->photos[$index]);
}
else{
return null;
}
}
public function preparefirstPhoto(): ?array
{
$photo_path = $this->getPhotoForStream(0);
if (is_null($photo_path)) {
return null; // ou un placeholder par défaut
}
$formats = ['stream_estate_lazy','stream_estate_thumb','stream_estate_infobox_tiny'];
$browserPaths = [];
foreach($formats as $format){
$browserPaths[] = $this->imagineCacheManager->getBrowserPath($photo_path, $format);
}
return $browserPaths;
}
public function getCover(): ?string
{
return $this->getPhotoForStream(0);
}
public function getPhotoThumb($index, $format="stream_estate_thumb"): ?string
{
$photo_path = $this->getPhotoForStream($index);
if (is_null($photo_path)) {
return null; // ou un placeholder par défaut
}
return $this->imagineCacheManager->getBrowserPath($photo_path, $format);
}
public function getCoverThumb($format='stream_estate_thumb'): ?string
{
return $this->getPhotoThumb(0, $format);
}
public function getCoverLazyThumb($format='stream_estate_lazy'): ?string
{
return $this->getPhotoThumb(0, $format);
}
public function getCoverInfoBox(): ?string
{
return $this->getCoverThumb('stream_estate_infobox_tiny');
}
public function getPhotosThumb(): ?array
{
$thumbs = [];
$photos = $this->getPhotos();
foreach ($photos as $index => $photo) {
//il faut un nombre impair
if( $index == count($photos) - 1 && $index%2 != 0 ){
}
else{
$thumbs[] = [
'lazy' => $this->imagineCacheManager->getBrowserPath($this->getPhotoForStream($index),"stream_estate_lazy"),
'modal' => $this->imagineCacheManager->getBrowserPath($this->getPhotoForStream($index),"stream_estate_thumb"),
'large' => $this->imagineCacheManager->getBrowserPath($this->getPhotoForStream($index),"stream_estate_large"),
];
}
}
if(count($thumbs) > 0 && count($thumbs) < 7){
$less = 7 - count($thumbs) ;
for($i=0; $i<$less; $i++){
$thumbs[] = $thumbs[$i];
}
}
// dump($thumbs); die;
return $thumbs;
}
public function getPhotosCarousel(): ?array
{
$thumbs = [];
$photos = array_slice($this->getPhotos(),0,5);
foreach ($photos as $index => $photo) {
$thumbs[] = [
'lazy' => $this->imagineCacheManager->getBrowserPath($this->getPhotoForStream($index),"stream_estate_lazy"),
'thumb' => $this->imagineCacheManager->getBrowserPath($this->getPhotoForStream($index),"stream_estate_thumb"),
];
}
return $thumbs;
}
public function getAgentThumb($format='agent_thumb'): ?string
{
return $this->getAgent()->getThumb($format);
}
public function getAgentThumbMedium(): ?string
{
return $this->getAgentThumb('agent_thumb_medium');
}
public function getAgentThumbSmall(): ?string
{
return $this->getAgentThumb('agent_thumb_small');
}
public function initForImport($import_type){
$this->import_type = $import_type;
$this->features = $this->default_features;
$this->photos = [];
}
public function addFeature($key , $value){
$this->features[$key] = $value;
}
public function addIcone($key , $value){
if (substr($key, 0, 3) === 'si_') {
$value = ($value !== null && $value >= 1) ? true : false;
}
$this->icones[$key] = $value;
}
public function addPhoto( $value){
if(!empty($value) ){
$this->photos[] = $value;
}
}
public function addLocalisation($key , $value){
// if($key == 'cp_reel' && $value !='' ){
// $nb_departement = substr($value ,0,2);
// $this->features['localisation']['nb_departement'] = $nb_departement;
// $this->features['localisation']['departement'] = self::getDepartement($nb_departement);
// }
$this->features['localisation'][$key] = $value;
}
public function addOrientation($key , $value){
$this->orientations[$key] = $value;
$this->features['orientation'] = '';
$orientations = [];
foreach ($this->orientations as $key => $value) {
if($value){
$orientations[] = $this->convertedValue('orientation' , $key);
}
}
// $this->features['orientation'] = implode('/', $orientations);
$this->setOrientation(implode('/', $orientations));
}
public function addConvert($key , $value){
$value = $this->convertedValue( $key, $value);
$this->features[$key] = $value;
}
public function convertedValue($key , $value){
$values = [
"orientation" => [
'si_orientenord' => 'Nord',
'si_orientesud' => 'Sud',
'si_orienteouest' => 'Ouest',
'si_orienteest'=> 'Est'
],
"typechauffage" => [
"128" => "Par radiateur",
"256" => "Au sol",
"384" => "Sol et radiateurs",
"512" => "Gaz",
"640" => "Gaz - Radiateurs",
"768" => "Gaz - Au sol",
"896" => "Gaz - Sol et radiateurs",
"1024" => "Fuel",
"1152" => "Fuel - Radiateurs",
"1280" => "Fuel - Au sol",
"1408" => "Fuel - Sol et radiateurs",
"2048" => "Électrique",
"2176" => "Électrique - Radiateurs",
"2304" => "Électrique - Au sol",
"2432" => "Électrique - Sol et radiateurs",
"4096" => "Collectif",
"4224" => "Collectif par radiateur",
"4352" => "Collectif au sol",
"4480" => "Collectif au sol et radiateurs",
"4608" => "Collectif au gaz",
"4736" => "Collectif au gaz - Radiateurs",
"4864" => "Collectif au gaz - Au sol",
"4992" => "Collectif gaz - Sol & radiateurs",
"5120" => "Collectif au fuel",
"5248" => "Collectif au fuel - Radiateurs",
"5376" => "Collectif au fuel - Au sol",
"5504" => "Collectif fuel - Sol & radiateurs",
"6144" => "Collectif électrique",
"6272" => "Collectif électrique - Radiateurs",
"6400" => "Collectif électrique - Au sol",
"6528" => "Collectif électrique - Mixte",
"8192" => "Individuel",
"8320" => "Radiateurs",
"8576" => "Au sol & radiateurs",
"8704" => "Gaz",
"8832" => "Gaz - Radiateurs",
"8960" => "Gaz - Au sol",
"9088" => "Gaz - Sol & radiateurs",
"9216" => "Fuel",
"9344" => "Fuel - Radiateurs",
"9472" => "Fuel - Au sol",
"9600" => "Fuel - Sol & radiateurs",
"10240" => "Électrique",
"10368" => "Électrique - Radiateurs",
"10496" => "Électrique - Au sol",
"10624" => "Électrique - Sol et radiateurs",
"16384" => "Climatisation reversible",
"20480" => "Climatisation centralisée",
"24576" => "Climatisation Individuelle"
],
"typecuisine" => [
"1" => "Aucune",
"2" => "Ouverte",
"3" => "Séparée",
"4" => "Industrielle",
"5" => "Coin cuisine",
"6" => "Aménagée & équipée",
"7" => "Fermée",
"8" => "Coin cuisine équipé",
"9" => "Équipée",
],
"honoraires_charges_de" => [
"1" => "Acquéreur",
"2" => "Vendeur",
"3" => "Acquéreur ET Vendeur",
],
"statut_csv" => [ //csv
"1" => "En estimation", // (ne sera pas diffusé car champs 112 "mandat" sera Null), affiche le prix
"2" => "En vente", // affiche le prix
"3" => "Sous offre", // (bandeau Ribbon wrapped)
"4" => "Sous compromis", // (bandeau Ribbon wrapped)
"5" => "Vendu", // (bandeau Ribbon wrapped)
],
"statut" => [ //netty
"1" => "En vente", // En vente Sur le marché: affiche le prix
"2" => "Sous compromis", // (bandeau Ribbon wrapped)
"3" => "Vendu", // (bandeau Ribbon wrapped)
"4" => "Retiré", // non diffusé
"5" => "Réservé", // ???
"6" => "Sous offre", // (bandeau Ribbon wrapped)
"9" => "Archivé", // non diffusé
],
"statut_name" => [
"available" => "En vente", // Sur le marché: affiche le prix
"under_contract" => "Sous compromis", // (bandeau Ribbon wrapped)
"sold" => "Vendu", // (bandeau Ribbon wrapped)
"withdrawn" => "Retiré", // non diffusé
"reserved" => "Réservé", // ???
"under_offer" => "Sous offre", // (bandeau Ribbon wrapped)
"archived" => "Archivé", // non diffusé
'rented' => 'Loué',
'expired' => 'Expiré',
],
];
return isset($values[$key][$value]) ? $values[$key][$value] : "";
}
public static function getTypes($familly_type=null, $unsets=[]): ?array
{
switch ($familly_type){
case 'acheter';
$types = [
'Appartements' => 'appartement',
'Studios' => 'studio',
'Lofts / Ateliers' => 'loft/atelier/surface',
'Maisons' => 'maison/villa',
'Maisons' => 'maison',
'Terrains' => 'terrain',
'Parking/box' => 'parking/box',
'Immeubles' => 'immeuble',
'Châteaux' => 'chateau',
// 'Divers' => 'inconnu'
];
break;
case 'commerces':
$types = [
'Fonds de commerce'=> 'boutique',
'Entreprise' => 'entreprise',
'Bureaux'=> 'bureaux',
'Entrepôt' => 'entrepot',
'Locaux professionnels' => 'local',
// 'Divers' => 'inconnu'
];
break;
default:
$types = [
'Appartement' => 'appartement',
'Studio' => 'studio',
'Loft / Atelier' => 'loft/atelier/surface',
'Maison' => 'maison/villa',
'Maison' => 'maison',
'Terrain' => 'terrain',
'Parking/box' => 'parking/box',
'Immeuble' => 'immeuble',
'Château' => 'chateau',
'Fonds de commerce' => 'boutique',
'Local professionnel' => 'local',
'Bureau' => 'bureaux',
// 'Divers' => 'inconnu'
];
break;
}
if(count($unsets) > 0){
foreach($unsets as $unset){
unset($types[$unset]);
}
}
return $types;
}
public static function getIds($estates): ?array
{
$ids = [];
foreach($estates as $estate){
$ids[] = $estate->getId();
}
return $ids;
}
public static function encode($estates): ?array
{
$encoders = [new JsonEncoder()];
$defaultContext = [
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
return $object->getName();
},
];
$normalizers = [new ObjectNormalizer(null, null, null, null, null, null, $defaultContext)];
$serializer = new Serializer($normalizers, $encoders);
$normalized = $serializer->normalize($estates, null, [AbstractNormalizer::ATTRIBUTES => [
'id',
'numeromandat',
'refannonce',
'siNuPropriete',
'siMandatexclusif',
'slug',
'statut',
'statutName',
'typebien',
'title',
'libelle',
'libelleCourt',
'descriptif',
'descriptifCourt',
'prix',
'surface',
'surf_terrain',
'nbpieces',
'nbchambres',
'photosThumb',
'photosCarousel',
'features',
'icones',
'cover',
'countPhotos',
'countThumbPhotos',
'statut',
'coverThumb',
'coverLazyThumb',
'coverInfoBox',
'agentThumbSmall',
'agentThumbMedium',
'latitude',
'longitude',
'publicFeatures',
'publicIcones',
'pecLetters',
'location',
'withMap',
'agent' => ['id', 'name', 'slug', 'photo', 'email', 'telephone', 'whatsapp', 'rating', 'countReviews']
]]);
return $normalized;
}
public function getLocation()
{
$feats = $this->getFeatures();
$localisation = $feats['localisation'];
$nb_departement = substr($localisation['cp_reel'] ,0,2);
$departement = self::getDepartement($nb_departement);
return $localisation['ville'] != '' ? $localisation['ville'] : $departement;
}
public function getWithMap()
{
return !in_array($this->getTypebienRaw() , self::getTypes('commerces')) && $this->getLatitude() > 0;
}
public static function getDepartement($nb)
{
$departements = [
1 => "Ain",
2 => "Aisne",
3 => "Allier",
4 => "Alpes-de-Haute-Provence",
5 => "Hautes-Alpes",
6 => "Alpes-Maritimes",
7 => "Ardèche",
8 => "Ardennes",
9 => "Ariège",
10 => "Aube",
11 => "Aude",
12 => "Aveyron",
13 => "Bouches-du-Rhône",
14 => "Calvados",
15 => "Cantal",
16 => "Charente",
17 => "Charente-Maritime",
18 => "Cher",
19 => "Corrèze",
20 => "Corse",
21 => "Côte-d'Or",
22 => "Côtes-d'Armor",
23 => "Creuse",
24 => "Dordogne",
25 => "Doubs",
26 => "Drôme",
27 => "Eure",
28 => "Eure-et-Loir",
29 => "Finistère",
30 => "Gard",
31 => "Haute-Garonne",
32 => "Gers",
33 => "Gironde",
34 => "Hérault",
35 => "Ille-et-Vilaine",
36 => "Indre",
37 => "Indre-et-Loire",
38 => "Isère",
39 => "Jura",
40 => "Landes",
41 => "Loir-et-Cher",
42 => "Loire",
43 => "Haute-Loire",
44 => "Loire-Atlantique",
45 => "Loiret",
46 => "Lot",
47 => "Lot-et-Garonne",
48 => "Lozère",
49 => "Maine-et-Loire",
50 => "Manche",
51 => "Marne",
52 => "Haute-Marne",
53 => "Mayenne",
54 => "Meurthe-et-Moselle",
55 => "Meuse",
56 => "Morbihan",
57 => "Moselle",
58 => "Nièvre",
59 => "Nord",
60 => "Oise",
61 => "Orne",
62 => "Pas-de-Calais",
63 => "Puy-de-Dôme",
64 => "Pyrénées-Atlantiques",
65 => "Hautes-Pyrénées",
66 => "Pyrénées-Orientales",
67 => "Bas-Rhin",
68 => "Haut-Rhin",
69 => "Rhône",
70 => "Haute-Saône",
71 => "Saône-et-Loire",
72 => "Sarthe",
73 => "Savoie",
74 => "Haute-Savoie",
75 => "Paris",
76 => "Seine-Maritime",
77 => "Seine-et-Marne",
78 => "Yvelines",
79 => "Deux-Sèvres",
80 => "Somme",
81 => "Tarn",
82 => "Tarn-et-Garonne",
83 => "Var",
84 => "Vaucluse",
85 => "Vendée",
86 => "Vienne",
87 => "Haute-Vienne",
88 => "Vosges",
89 => "Yonne",
90 => "Territoire de Belfort",
91 => "Essonne",
92 => "Hauts-de-Seine",
93 => "Seine-Saint-Denis",
94 => "Val-de-Marne",
95 => "Val-d'Oise",
971 => "Guadeloupe",
972 => "Martinique",
973 => "Guyane",
974 => "La Réunion",
976 => "Mayotte"
];
return isset($departements[$nb]) ? $departements[$nb] : '';
}
public function getTitle(){
return trim(implode(' ', $this->getInfosTitle())) ;
}
public function getInfosTitle(){
$feats = $this->getFeatures();
$icones = $this->getIcones();
$infos_title[] = isset($feats['soustype_bien']) && $feats['soustype_bien'] != "" && $feats['soustype_bien'] != 'constructible' ? ucfirst($feats['soustype_bien'] ): $this->getTypebien();
//terrain
if($this->typebien == "terrain"){
if( isset($icones['si_constructible']) && $icones['si_constructible']){
$infos_title[] = 'constructible';
}
if($this->getSurfTerrain() != "0"){
$infos_title[] = $this->getSurfTerrain() .' m²';
}
}
//boutique -> activitescommerciales
elseif(in_array($this->typebien, self::getTypes('commerces')) ){
//1activitescommerciales, nature_activite, product_type_commercial
$infos_title = [];
$activitescommerciales = isset($feats['activitescommerciales']) ? $feats['activitescommerciales'] : '';
if(!in_array($activitescommerciales,['','Autre activité'])){
$activitescommerciales = explode(',', $activitescommerciales);
$premiersTermes = array_slice($activitescommerciales, 0, 3);
$infos_title[] = implode(' - ', $premiersTermes);
}
elseif(isset($feats['nature_activite']) && $feats['nature_activite'] != ''){
$infos_title[]= $feats['nature_activite'];
}
elseif(isset($feats['product_type_commercial']) && $feats['product_type_commercial'] != ''){
$infos_title[] = $feats['product_type_commercial'];
}
else{
$infos_title[] = $this->getTypebien();
}
//Surface
$not_surface = ['boutique'];
if($this->getSurface() != "0" && !in_array($this->typebien, $not_surface) ){
$infos_title[] = round($this->getSurface(),0, PHP_ROUND_HALF_DOWN) .' m²';
}
}
else{
if( $this->typebien == 'chateau' ){
if($feats['product_type_house'] != ''){
$infos_title = [$feats['product_type_house']];
}
}
//nombre de pièces
$not_nb_piece = ['maison contemporaine', 'maison traditionelle'];
if($this->getNbpieces() > 0 ) {
if(isset($feats['soustype_bien'])){
$infos_title[] = $this->getNbpieces() > 1 ? $this->getNbpieces() .' pièces' : $this->getNbpieces() .' pièce';
}
else{
$infos_title[] = $this->getNbpieces() > 1 ? $this->getNbpieces() .' pièces' : $this->getNbpieces() .' pièce';
}
}
//Surface
if($this->getSurface() != "0"){
$infos_title[] = round($this->getSurface(),0, PHP_ROUND_HALF_DOWN) .' m²';
}
}
return $infos_title ;
}
public function getLibelleCourt(): ?string
{
$string = trim(strip_tags($this->getLibelle(), '<sup>'));
$string = u( $string )->truncate(40, ' …', true);
return $string;
}
public function getDescriptifCourt(): ?string
{
$descriptif = $this->getDescriptif();
$descriptif = preg_replace('#<br\s*/?>#i',' ',$descriptif);
$string = trim(strip_tags($descriptif, '<sup>'));
return u( $string )->truncate(135, ' …', false);
}
public function getIcone($key): ?string
{
$icones = $this->getIcones();
return $icones[$key];
}
public function getPublicFeatures(): ?array
{
setlocale(LC_MONETARY, 'fr_FR');
$values = [];
$feats = $this->getFeatures();
// $icones = $this->getIcones();
// statut
// typebien
// si_mandatexclusif
// prix
// surface
// surf_terrain
// nbpieces
// nbchambres
// $values['Statut'] = $this->getStatut();
$values['Référence'] = $this->getRefannonce();
// $values['Type de bien'] = $this->getTypebien();
// $values['Prix'] = number_format( $this->getPrix(), 0, ',', ' ')." €";
if($this->getNumeromandat() != "0"){
$values['N° mandat'] = $this->getNumeromandat();
}
if($this->getSurface() != "0"){
$values['Surface'] = $this->getSurface() .' m²';
}
// if($this->getSurfTerrain() != "0"){
// $values['Surface TERRAIN'] = $this->getSurfTerrain() .' m²';
// }
if($this->getNbpieces() != "0"){
$values['Pièce(s)'] = $this->getNbpieces();
}
if($this->getNbchambres() != "0"){
$values['Chambre(s)'] = $this->getNbchambres();
}
if($this->getIcone('nbsdeau_sdb') > 0){
$values["Salle de bain / Salle d'eau"] = $this->getIcone('nbsdeau_sdb');
}
if($this->getSurfTerrain() != "0" && $this->typebien !='terrain'){
$values['Terrain'] = $this->getSurfTerrain() .' m²';
}
//contrainte sur l'affichage des honnoraires à la charge du vendeur
if( isset($feats['honoraires_charges_de']) && stripos($feats['honoraires_charges_de'], 'vendeur') !== false ){
if( isset($feats['honoraires']) ){
unset($feats['honoraires']);
}
if( isset($feats['prix_hors_honoraires']) ){
unset($feats['prix_hors_honoraires']);
}
}
if(in_array($this->typebien, ['boutique', 'terrain']) ){
unset($feats['typecuisine']);
}
// if($this->getCa() > 0 && (int) $feats['annee_reference_ca'] > 0 ){
// $feats['ca'] = $this->getCa();
// }
// if($this->getEbe() > 0 && (int) $feats['annee_reference_ebe'] > 0){
// $feats['ebe'] = $this->getEbe();
// }
if(isset($feats['surface_sol']) && $values['Surface'] == $feats['surface_sol'] ){
unset($feats['surface_sol']);
}
if($this->getCa() > 0 ){
$feats['ca'] = $this->getCa();
}
if($this->getEbe() > 0 ){
$feats['ebe'] = $this->getEbe();
}
if(isset($feats['ca_n_1']) && $feats['ca_n_1'] > 0 ){
// unset($feats['ca']);
}
if(isset($feats['ebe_reconstituted']) && $feats['ebe_reconstituted'] > 0 ){
unset($feats['ebe']);
}
$labels = [
'statut' => 'Statut',
'numeromandat' => 'N° mandat',
'surface' => 'Surface',
'surface_sol' => 'Surface au sol',
'pieces' => 'Pièce(s)',
'nbchambres' => 'Chambre(s)',
'nbsdeau_sdb' => "Salle de bain / Salle d'eau",
'typechauffage' => 'Chauffage',
'typecuisine' => 'Cuisine',
'fenetres' => "Fenêtres",
'assainissement' => 'Assainissement',
'annee_construction' => 'Année de construction',
'etage' => 'Étage',
'orientation' => 'Orientation',
'terrain' => 'Terrain',
'si_constructible' => 'Terrain constructible',
'si_viabilise' => 'Terrain viabilisé',
'date_dispo' => 'Date de disponibilité',
'loyer_annuel_global' => 'Loyer annuel',
// 'loyer_annuel_metre' => 'Loyer au m²', //euro
// 'charges_annuelles_globales' => 'Charges annuelles',
'charges' => 'Charges', //euro
'charges_annuelles' => 'Charges annuelles', //euro
'fermeture_hebdomadaire' => 'Fermeture', //?? non present
'horaires' => 'Horaires',
'si_logement_de_fonction' => 'Logement de fonction',
'si_copropriete' => 'Copropriété',
'nombre_lots' => 'Nombre de lots',
'si_syndic_procedure' => 'Procédure syndicat',
'detail_syndic_procedure' => 'Détail procédure',
// 'ca' => 'CA ' . $feats['annee_reference_ca'] ,
// 'ebe' => 'EBE '. $feats['annee_reference_ebe'],
'ca' => 'CA',
// 'ca_n_1' => 'CA n-1',
'ebe' => 'EBE',
'ebe_reconstituted' => 'EBE retraité' ,
'prix_hors_honoraires' => 'Prix hors honoraires', //euro
'honoraires' => 'Honoraires', //euro
'honoraires_charges_de' => 'Honoraires charge',
];
$suffix['surface'] = ' m²';
$suffix['surface_sol'] = ' m²';
$suffix['surf_terrain'] = ' m²';
$suffix['charges'] = ' €';
$suffix['charges_annuelles'] = ' €';
$suffix['prix_hors_honoraires'] = ' €';
$suffix['loyer_annuel_global'] = ' €';
$suffix['ca'] = ' €';
$suffix['ebe'] = ' €';
$suffix['ebe_reconstituted'] = ' €';
$suffix['honoraires'] = '%';
foreach ($feats as $key => $value) {
if(isset($labels[$key]) && $value!="" && $value!= "0" ){
$suf = isset($suffix[$key]) ? $suffix[$key] : '';
if(is_bool($value)){
$value = $value ? 'Oui': 'Non';
}
if( $suf == ' €'){
$value = number_format( (float) $value, 0, ',', '.');
}
if( $suf == '%'){
// $value = round( (float) $value, 1);
$value = number_format( (float) $value, 1, ',', ' ');
}
if($key == 'date_dispo'){
// $value = "24/02/2021";
$date_dispo = \DateTime::createFromFormat('d/m/Y', $value);
$now = new \DateTime();
$nb_day_diff = (int) $now->diff($date_dispo)->format('%R%a');
$value = $nb_day_diff <= 0 ? "Immédiate" : $value;
}
$values[$labels[$key]] = $value.$suf;
}
}
//TRI SELON L'ordre des labels
$order = array_values ($labels);
uksort($values, function($key1, $key2) use ($order) {
return ((array_search($key1, $order) > array_search($key2, $order)) ? 1 : -1);
});
return $values;
}
public function getPublicIcones(): ?array
{
$inflector = new FrenchInflector();
$icones = [];
// $values['m2_surface'] = $this->getSurface() ;
// $values['m2_surf_terrain'] = $this->getSurfTerrain();
// $values['nbpieces'] = $this->getNbpieces();
// $values['nbchambres'] = $this->getNbchambres();
$labels = [
// 'm2_surface' => "Surface",
// 'm2_surf_terrain' => "Terrain",
// 'nbpieces' => "Pièce",
// 'nbchambres' => "Chambre",
// 'nbsdb' => "Salle de bain",
// 'nbsdeau' => "Salle d'eau",
// 'nbsdeau_sdb' => "Salle d'eau",
'si_piscine' => "Piscine",
'si_terrasse' => "Terrasse",
'si_cheminee' => "Cheminée",
'nbboxes' => "Garage",
'nbparkings' => "Parking",
'si_cave' => "Cave",
'si_ascenseur' => "Ascenceur",
'si_digicode' => "Digicode",
'si_interphone' => "Interphone",
'si_gardien' => "Gardien",
'si_alarme' => "Alarme",
'si_cabletv' => "Cable TV",
'si_climatisation' => "Climatisation",
'si_amgnthandicapes' => "PMR",
'si_constructible' => 'Terrain constructible',
'si_viabilise' => 'Terrain viabilisé',
'si_sous_sol' => 'Sous sol'
];
// $icones = array_merge( $values, $this->getIcones() );
foreach ( $this->getIcones() as $key => $val) {
$value = false;
if(isset($labels[$key])){
if(preg_match('#^si_.+#' , $key , $match) && $val == true){ //Boolean
$value = $labels[$key];
}
elseif(preg_match('#^nb.+#' , $key , $match) && $val != "" && (int)$val > 0){ //Integer
$label = $labels[$key];
$label = (int)$val > 1 && !preg_match('#^Salle.+#', $label ) ? $inflector->pluralize( $label )[0] : $label;
$label = (int)$val > 1 && preg_match('#^Salle.+#', $label ) ? preg_replace('#^Salle(.+)#', 'Salles$1', $label) : $label;
$value = $val ." ". $label;
}
elseif(preg_match('#^m2_.+#' , $key , $match) && (int)$val > 0){ //Surface
$value = $labels[$key] . " ".$val;
}
if($value != false){
$suffix = isset($suffix[$key]) ? $suffix[$key] : '';
$icones[$key] = $value.$suffix;
}
}
}
if(isset($icones['si_cave']) && isset($icones['si_sous_sol']) ){
unset($icones['si_sous_sol']);
}
//TRI SELON L'ordre des labels
$order = array_keys($labels);
uksort($icones, function($key1, $key2) use ($order) {
return ((array_search($key1, $order) > array_search($key2, $order)) ? 1 : -1);
});
return $icones;
}
public function getPecLetters(): ?array
{
$pecLetters = [];
$feats = $this->getFeatures();
$letters = array_flip(range('A', 'G'));
if(isset($feats['bilanconsoenergie']) && isset($letters[$feats['bilanconsoenergie']]) && isset($letters[$feats['bilanemissionges']]) ){
// DPE (D) >= GES (B) : D,B
if( $letters[$feats['bilanconsoenergie']] >= $letters[$feats['bilanemissionges']]){
$pecLetters = ['dpe' => $feats['bilanconsoenergie'], 'gse' => $feats['bilanemissionges']];
}
//DPE (B) > GES (G) : G,G
else{
$pecLetters = ['dpe' => $feats['bilanemissionges'], 'gse' => $feats['bilanemissionges']];
}
if( in_array($pecLetters['dpe'] ,['F', 'G']) ){
// dump($this->getRefannonce());
$pecLetters['label'] = "Passoire energétique";
}
// $pecLetters['dpe'] = 'G';
}
return $pecLetters;
}
public function getSiNuPropriete(): ?bool
{
$patterns = [
'NUE-PROPRIÉTÉ',
'NUE-PROPRIETE',
];
return preg_match('#^(.+)'.implode('|', $patterns).'(.+)$#miu' , $this->descriptif , $match) ? true : false;
}
/**
* @return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}
public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
$user->addFavorite($this);
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->users->removeElement($user)) {
$user->removeFavorite($this);
}
return $this;
}
public static function createRange($numbers){
sort($numbers);
$min = min($numbers);
$max = max($numbers);
$seuils = [$min];
while(end($seuils) * 2 < $max){
$seuil = end($seuils) * 2;
$seuils[] = end($seuils) * 2;
}
$seuils[] = $max;
//arrondi
$rangeLimits =[];
foreach($seuils as $index => $seuil){
$nbdigit = mb_strlen($seuil) ;
$unit = substr($seuil, 0,1);
$diviseur = 1;
for($i=1; $i< $nbdigit; $i++){
$diviseur = $diviseur * 10;
}
$decimal = $seuil/$diviseur;
if($seuil == $min){
$decimal_round = floor($decimal*10)/10;
}
elseif($seuil == $max){
$decimal_round = ceil($decimal*10)/10;
}
else{
$decimal_round = round($decimal, 1);
}
$round = $decimal_round * $diviseur;
$rangeLimits[] = (int) number_format($round,0, '','');
}
$ranges = array();
for($i = 0; $i < count($rangeLimits); $i++){
if($i == count($rangeLimits)-1){
break;
}
$lowLimit = $rangeLimits[$i];
$highLimit = $rangeLimits[$i+1];
$ranges[$i]['ranges']['min'] = $lowLimit;
$ranges[$i]['ranges']['max'] = $highLimit;
$ranges[$i]['values'] = [];
foreach($numbers as $number){
if($number >= $lowLimit && $number <= $highLimit){
$ranges[$i]['values'][] = $number;
}
}
}
return $ranges;
}
public function getSousType(): ?SousType
{
return $this->sous_type;
}
public function setSousType(?SousType $sous_type): self
{
$this->sous_type = $sous_type;
return $this;
}
public function getCa(): ?float
{
return $this->ca;
}
public function setCa(?float $ca): self
{
$this->ca = $ca;
return $this;
}
public function getEbe(): ?float
{
return $this->ebe;
}
public function setEbe(?float $ebe): self
{
$this->ebe = $ebe;
return $this;
}
public function isSiMandatexclusif(): ?bool
{
return $this->si_mandatexclusif;
}
public function isIsNewChecked(): ?bool
{
return $this->is_new_checked;
}
public function isIsDeleteChecked(): ?bool
{
return $this->is_delete_checked;
}
/**
* @return Collection<int, SearchNotification>
*/
public function getNotifications(): Collection
{
return $this->notifications;
}
public function addNotification(SearchNotification $notification): self
{
if (!$this->notifications->contains($notification)) {
$this->notifications[] = $notification;
$notification->addEstate($this);
}
return $this;
}
public function removeNotification(SearchNotification $notification): self
{
if ($this->notifications->removeElement($notification)) {
$notification->removeEstate($this);
}
return $this;
}
/**
* @return Collection<int, Agent>
*/
public function getShareWithAgents(): Collection
{
return $this->share_with_agents;
}
public function setShareWithAgents(iterable $agents): self
{
foreach ($this->share_with_agents as $agent) {
$this->removeShareWithAgent($agent);
}
foreach ($agents as $agent) {
$this->addShareWithAgent($agent);
}
return $this;
}
public function addShareWithAgent(Agent $shareWithAgent): self
{
if (!$this->share_with_agents->contains($shareWithAgent)) {
$this->share_with_agents[] = $shareWithAgent;
}
return $this;
}
public function removeShareWithAgent(Agent $shareWithAgent): self
{
$this->share_with_agents->removeElement($shareWithAgent);
return $this;
}
}