src/Aqarmap/Bundle/ListingBundle/Entity/Location.php line 50

  1. <?php
  2. namespace Aqarmap\Bundle\ListingBundle\Entity;
  3. use Aqarmap\Bundle\DiscussionBundle\Entity\Discussion;
  4. use Aqarmap\Bundle\ExchangeBundle\Entity\ExchangeRequest;
  5. use Aqarmap\Bundle\ListingBundle\Constant\LocationTypes;
  6. use Aqarmap\Bundle\ListingBundle\Constant\PhotoTypes;
  7. use Aqarmap\Bundle\ListingBundle\Repository\LocationRepository;
  8. use Aqarmap\Bundle\NeighborhoodBundle\Entity\LocationCompound;
  9. use Aqarmap\Bundle\NeighborhoodBundle\Entity\LocationStatistics;
  10. use Aqarmap\Bundle\NotifierBundle\Entity\Notifier;
  11. use Aqarmap\Bundle\UserBundle\Constant\UserInterestStatus;
  12. use Aqarmap\Bundle\UserBundle\Entity\UserInterest;
  13. use Doctrine\Common\Collections\ArrayCollection;
  14. use Doctrine\Common\Collections\Collection;
  15. use Doctrine\Common\Collections\Criteria;
  16. use Doctrine\ORM\Mapping as ORM;
  17. use Gedmo\Mapping\Annotation as Gedmo;
  18. use Gedmo\Sluggable\Handler\TreeSlugHandler;
  19. use Gedmo\Translatable\Translatable;
  20. use JMS\Serializer\Annotation as Serializer;
  21. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  22. use Symfony\Component\Serializer\Annotation\Groups;
  23. /**
  24. * Location.
  25. */
  26. #[UniqueEntity('slug')]
  27. #[ORM\Table(name: 'locations')]
  28. #[ORM\Index(columns: ['disabled'])]
  29. #[ORM\Index(columns: ['listings_counter'])]
  30. #[ORM\Index(columns: ['searchable'])]
  31. #[ORM\Index(columns: ['synced'])]
  32. #[ORM\Index(columns: ['lat'])]
  33. #[ORM\Index(columns: ['lon'])]
  34. #[ORM\Index(columns: ['root'])]
  35. #[ORM\Index(columns: ['root', '_left', '_right'])]
  36. #[ORM\Index(columns: ['home_filter', 'is_compound_location', 'listing_id'])]
  37. #[ORM\Entity(repositoryClass: LocationRepository::class)]
  38. #[ORM\Cache(usage: 'NONSTRICT_READ_WRITE', region: 'write_rare')]
  39. #[Gedmo\TranslationEntity(class: LocationTranslation::class)]
  40. #[Gedmo\Tree(type: 'nested')]
  41. #[Serializer\ExclusionPolicy('all')]
  42. class Location implements Translatable, \Stringable
  43. {
  44. /**
  45. * @var int
  46. */
  47. #[ORM\Column(name: 'id', type: 'integer')]
  48. #[ORM\Id]
  49. #[ORM\GeneratedValue(strategy: 'AUTO')]
  50. #[Serializer\Groups(['Default', 'listingDetails', 'List', 'MiniList', 'Data', 'Autocomplete', 'Details', 'Neighborhood', 'NeighborhoodStatistics', 'Discussion', 'Exchange', 'LocationFlat', 'Search', 'AutocompleteV3', 'DefaultV4', 'SearchV4', 'ProjectDetailsV4', 'Translation', 'SlugResolver', 'RelatedListingsV2', 'locationListingV2', 'leadsBank'])]
  51. #[Groups(['valuation:read'])]
  52. #[Serializer\Expose]
  53. private $id;
  54. #[ORM\Column(name: 'title', type: 'string', length: 50)]
  55. #[Gedmo\Translatable]
  56. #[Serializer\Groups(['Default', 'listingDetails', 'List', 'MiniList', 'Data', 'Details', 'Neighborhood', 'NeighborhoodStatistics', 'Discussion', 'Exchange', 'LocationFlat', 'Search', 'Translation', 'SlugResolver', 'Autocomplete', 'MyLeads', 'leadsBank', 'LocationStatistics'])]
  57. #[Serializer\Expose]
  58. private string $title;
  59. /**
  60. * @var string
  61. */
  62. #[ORM\Column(name: 'alias', type: 'string', length: 512, nullable: true)]
  63. #[Gedmo\Translatable]
  64. #[Serializer\Groups(['SlugResolver'])]
  65. #[Serializer\Expose]
  66. private $alias;
  67. /**
  68. * @var string
  69. */
  70. #[ORM\Column(name: 'description', type: 'text', length: 512, nullable: true)]
  71. #[Gedmo\Translatable]
  72. #[Serializer\Groups(['Neighborhood'])]
  73. #[Serializer\Expose]
  74. private $description;
  75. #[ORM\Column(length: 128, unique: true)]
  76. #[Gedmo\Slug(fields: ['title'])]
  77. #[Gedmo\SlugHandler(class: TreeSlugHandler::class, options: [
  78. 'parentRelationField' => 'parent',
  79. 'separator' => '/',
  80. ])]
  81. #[Serializer\Groups(['Default', 'listingDetails', 'List', 'MiniList', 'Data', 'Details', 'Neighborhood', 'LocationFlat', 'Autocomplete', 'AutocompleteV3', 'DefaultV4', 'SearchV4', 'SlugResolver', 'RelatedListingsV2'])]
  82. #[Groups(['valuation:read'])]
  83. #[Serializer\Expose]
  84. private string $slug = '';
  85. #[ORM\Column(name: 'lat', type: 'float', nullable: true)]
  86. #[Serializer\Groups(['DataJS', 'SSRData'])]
  87. #[Serializer\Since('v2.14')]
  88. #[Serializer\Expose]
  89. private ?float $lat = null;
  90. #[ORM\Column(name: 'lon', type: 'float', nullable: true)]
  91. #[Serializer\Groups(['DataJS', 'SSRData'])]
  92. #[Serializer\Since('v2.14')]
  93. #[Serializer\Expose]
  94. private ?float $lon = null;
  95. #[ORM\Column(name: 'zoom', type: 'smallint', nullable: true)]
  96. #[Serializer\Groups(['DataJS', 'SSRData'])]
  97. #[Serializer\Since('v2.14')]
  98. #[Serializer\Expose]
  99. private ?int $zoom = null;
  100. /**
  101. * @var array
  102. */
  103. #[ORM\Column(name: 'coordinates', type: 'array', nullable: true)]
  104. private $coordinates;
  105. #[ORM\Column(type: 'boolean')]
  106. #[Serializer\Expose]
  107. #[Serializer\Groups(['List', 'Data', 'Details', 'LocationFlat'])]
  108. private $searchable;
  109. #[ORM\Column(name: 'home_filter', type: 'boolean')]
  110. #[Serializer\Expose]
  111. #[Serializer\Groups(['Neighborhood'])]
  112. private $homeFilter = false;
  113. #[ORM\Column(name: 'statistics_filter', type: 'boolean')]
  114. #[Serializer\Expose]
  115. #[Serializer\Groups(['Neighborhood'])]
  116. private $statisticsFilter = false;
  117. #[ORM\Column(name: 'neighborhood_filter', type: 'boolean')]
  118. #[Serializer\Expose]
  119. #[Serializer\Groups(['Neighborhood'])]
  120. private $neighborhoodFilter = false;
  121. #[ORM\Column(name: 'compound_filter', type: 'boolean')]
  122. private $compoundFilter = false;
  123. #[ORM\Column(type: 'boolean')]
  124. #[Serializer\Expose]
  125. #[Serializer\Groups(['List', 'Data', 'Details', 'LocationFlat'])]
  126. private $estimate = false;
  127. #[ORM\Column(type: 'boolean')]
  128. #[Serializer\Expose]
  129. #[Serializer\Groups(['DefaultV4'])]
  130. private $disabled = false;
  131. #[ORM\Column(name: 'synced', type: 'boolean')]
  132. private $synced = false;
  133. #[ORM\Column(name: 'level', type: 'integer')]
  134. #[Gedmo\TreeLevel]
  135. #[Serializer\Expose]
  136. #[Serializer\Groups(['List', 'Data', 'LocationFlat', 'DefaultV4', 'SlugResolver'])]
  137. private $level;
  138. #[ORM\Column(name: '_left', type: 'integer')]
  139. #[Gedmo\TreeLeft]
  140. private $left;
  141. #[ORM\Column(name: '_right', type: 'integer')]
  142. #[Gedmo\TreeRight]
  143. private $right;
  144. #[ORM\Column(name: 'root', type: 'integer', nullable: true)]
  145. #[Gedmo\TreeRoot]
  146. private $root;
  147. #[ORM\Column(name: 'show_primary_only', type: 'boolean', options: ['default' => false])]
  148. #[Serializer\Expose]
  149. #[Serializer\Groups(['Autocomplete', 'List', 'Data', 'Details', 'LocationFlat', 'AutocompleteV3', 'Compound', 'SlugResolver'])]
  150. private $showPrimaryOnly = false;
  151. #[ORM\ManyToOne(targetEntity: Location::class, inversedBy: 'children')]
  152. #[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
  153. #[Gedmo\TreeParent]
  154. #[Serializer\Expose]
  155. #[Serializer\Groups(['DefaultV4', 'SearchV4', 'SlugResolver', 'RelatedListingsV2', 'listingDetails'])]
  156. #[Serializer\MaxDepth(1)]
  157. private $parent;
  158. #[ORM\OneToMany(targetEntity: Location::class, mappedBy: 'parent')]
  159. #[ORM\OrderBy(['left' => 'ASC'])]
  160. #[Serializer\Expose]
  161. #[Serializer\Groups(['List'])]
  162. #[Serializer\MaxDepth(2)]
  163. #[Serializer\Accessor(getter: 'getChildren')]
  164. private $children;
  165. #[ORM\ManyToMany(targetEntity: Location::class, cascade: ['persist'])]
  166. #[ORM\JoinTable(name: 'locations_nearestby', joinColumns: [new ORM\JoinColumn(name: 'nearest_location_id', referencedColumnName: 'id')], inverseJoinColumns: [new ORM\JoinColumn(name: 'location_id', referencedColumnName: 'id')])]
  167. protected $nearestLocations;
  168. #[ORM\OneToMany(targetEntity: LocationTranslation::class, mappedBy: 'object', cascade: ['persist', 'remove'])]
  169. private $translations;
  170. #[ORM\OneToMany(targetEntity: Listing::class, mappedBy: 'location')]
  171. protected $listings;
  172. #[ORM\ManyToMany(targetEntity: PropertyType::class)]
  173. protected $propertyTypes;
  174. #[ORM\OneToMany(targetEntity: \Aqarmap\Bundle\CRMBundle\Entity\Company::class, mappedBy: 'location')]
  175. protected $companies;
  176. #[ORM\OneToMany(targetEntity: LocationSupplyDemand::class, mappedBy: 'location')]
  177. protected $locationSupplyDemand;
  178. #[ORM\OneToMany(targetEntity: Notifier::class, mappedBy: 'location')]
  179. protected $notifiers;
  180. #[ORM\OneToMany(targetEntity: UserInterest::class, mappedBy: 'location', fetch: 'EXTRA_LAZY')]
  181. protected $interests;
  182. #[ORM\OneToMany(targetEntity: Rule::class, mappedBy: 'location')]
  183. protected $rules;
  184. #[ORM\OneToMany(targetEntity: LocationPhoto::class, mappedBy: 'location', cascade: ['persist', 'remove'])]
  185. #[Serializer\Expose]
  186. #[Serializer\Groups(['Neighborhood'])]
  187. protected $photos;
  188. #[ORM\OneToMany(targetEntity: LocationStatistics::class, mappedBy: 'location', fetch: 'EXTRA_LAZY')]
  189. #[Serializer\Expose]
  190. #[Serializer\Groups(['Neighborhood'])]
  191. protected $locationStatistics;
  192. #[ORM\OneToOne(targetEntity: LocationCompound::class, cascade: ['persist', 'remove'], mappedBy: 'location')]
  193. #[ORM\JoinColumn(name: 'location_compound_id', referencedColumnName: 'id')]
  194. protected $locationCompound;
  195. #[ORM\OneToMany(targetEntity: Discussion::class, mappedBy: 'location', fetch: 'EXTRA_LAZY')]
  196. protected $discussions;
  197. #[ORM\OneToMany(targetEntity: ExchangeRequest::class, mappedBy: 'location', fetch: 'EXTRA_LAZY')]
  198. protected $exchangeRequests;
  199. #[ORM\OneToOne(targetEntity: LocationRating::class, cascade: ['persist', 'remove'])]
  200. #[Serializer\Expose]
  201. #[Serializer\Groups(['Neighborhood'])]
  202. protected $rating;
  203. #[ORM\ManyToOne(targetEntity: Listing::class, cascade: ['persist', 'remove'])]
  204. #[ORM\JoinColumn(name: 'listing_id', referencedColumnName: 'id', nullable: true)]
  205. #[Serializer\Expose]
  206. #[Serializer\Groups(['Autocomplete'])]
  207. protected $listing;
  208. #[ORM\OneToMany(targetEntity: SearchTerm::class, mappedBy: 'location')]
  209. protected $searchTerms;
  210. #[Gedmo\Locale] // Used locale to override Translation listener`s locale
  211. private $locale;
  212. /**
  213. * @var int
  214. * Count number of leads for live listings
  215. */
  216. #[ORM\Column(name: 'leads_counter', type: 'integer', options: ['default' => 0])]
  217. #[Serializer\Groups(['Api'])]
  218. #[Serializer\Expose]
  219. private $leadsCounter = 0;
  220. /**
  221. * @var int
  222. * Count number of live listings
  223. */
  224. #[ORM\Column(name: 'listings_counter', type: 'integer', options: ['default' => 0])]
  225. #[Serializer\Groups(['Api', 'RelatedResults', 'MiniList'])]
  226. #[Serializer\Expose]
  227. private $listingsCounter = 0;
  228. /**
  229. * Project File.
  230. */
  231. protected $file;
  232. #[ORM\Column(name: 'keyword', type: 'text', nullable: true)]
  233. private $keyword;
  234. private $location;
  235. #[ORM\OneToMany(targetEntity: \Aqarmap\Bundle\ValueEngineBundle\Entity\ListingInsight::class, mappedBy: 'location')]
  236. protected $listingInsights;
  237. /**
  238. * @var string
  239. */
  240. #[ORM\Column(name: 'full_path', type: 'text', nullable: true)]
  241. private $fullPath;
  242. #[ORM\Column(name: 'reference_id', type: 'integer', nullable: true)]
  243. private $referenceId;
  244. /**
  245. * @var string
  246. */
  247. #[ORM\Column(name: 'type', type: 'string', length: 50)]
  248. #[Serializer\Groups(['listingDetails', 'listingDetailsWithLocationCompound'])]
  249. #[Serializer\Expose]
  250. private $type;
  251. /**
  252. * @var array
  253. */
  254. private $locationTranslations = [];
  255. /**
  256. * @var array
  257. */
  258. private $v4Translations = [];
  259. #[ORM\Column(name: 'eligible_for_mortgage', type: 'boolean')]
  260. #[Serializer\Groups(['listingDetails', 'listingDetailsWithLocationCompound'])]
  261. #[Serializer\Expose]
  262. protected $eligibleForMortgage = false;
  263. #[ORM\Column(name: 'is_compound_location', type: 'boolean')]
  264. #[Serializer\Expose]
  265. #[Serializer\Groups(['Autocomplete', 'List', 'Data', 'Details', 'LocationFlat', 'AutocompleteV3', 'Compound', 'SlugResolver'])]
  266. private $isCompoundLocation = false;
  267. #[ORM\OneToMany(targetEntity: Location::class, mappedBy: 'parent')]
  268. #[ORM\OrderBy(['id' => 'ASC'])]
  269. #[Serializer\Expose]
  270. #[Serializer\Groups(['Data'])]
  271. #[Serializer\MaxDepth(2)]
  272. #[Serializer\Accessor(getter: 'getChildrenSortedById')]
  273. #[Serializer\SerializedName('children')]
  274. private $childrenSortedById;
  275. #[Serializer\VirtualProperty]
  276. public function getLocation()
  277. {
  278. return $this->location;
  279. }
  280. public function getKeyword()
  281. {
  282. return $this->keyword;
  283. }
  284. /**
  285. * @param mixed $keyword
  286. */
  287. public function setKeyword(string $keyword): self
  288. {
  289. $this->keyword = $this->getKeyword() ? $this->getKeyword().','.$keyword : $keyword;
  290. return $this;
  291. }
  292. public function removeKeyword(string $keyword): self
  293. {
  294. $newKeyword = array_diff(explode(',', (string) $this->getKeyword()), [$keyword]);
  295. $this->keyword = implode(',', $newKeyword) ?? null;
  296. return $this;
  297. }
  298. public function getFile()
  299. {
  300. return $this->file;
  301. }
  302. public function setFile($file): void
  303. {
  304. $this->file = $file;
  305. }
  306. /**
  307. * Constructor.
  308. */
  309. public function __construct()
  310. {
  311. $this->children = new ArrayCollection();
  312. $this->translations = new ArrayCollection();
  313. $this->listings = new ArrayCollection();
  314. $this->notifiers = new ArrayCollection();
  315. $this->rules = new ArrayCollection();
  316. $this->locationStatistics = new ArrayCollection();
  317. $this->photos = new ArrayCollection();
  318. $this->discussions = new ArrayCollection();
  319. $this->propertyTypes = new ArrayCollection();
  320. $this->nearestLocations = new ArrayCollection();
  321. $this->interests = new ArrayCollection();
  322. $this->exchangeRequests = new ArrayCollection();
  323. }
  324. // ---------------------------------------------------------------------
  325. /**
  326. * Get id.
  327. *
  328. * @return int
  329. */
  330. public function getId()
  331. {
  332. return $this->id;
  333. }
  334. // ---------------------------------------------------------------------
  335. /**
  336. * Set title.
  337. *
  338. * @param string $title
  339. *
  340. * @return Location
  341. */
  342. public function setTitle($title)
  343. {
  344. $this->title = $title;
  345. return $this;
  346. }
  347. /**
  348. * Get title.
  349. *
  350. * @return string
  351. */
  352. public function getTitle()
  353. {
  354. return $this->title;
  355. }
  356. /**
  357. * Get a short path title (ie: New Cairo - 90th Street).
  358. */
  359. #[Groups(['valuation:list', 'valuation:read'])]
  360. public function getTitleShortPath(): string
  361. {
  362. $neighbourhood = $this->getParentByType(LocationTypes::NEIGHBORHOOD, true);
  363. if ($neighbourhood) {
  364. return $this->getTitle().' - '.$neighbourhood->getTitle();
  365. }
  366. return $this->getTitle();
  367. }
  368. /**
  369. * @return string
  370. */
  371. public function getIndentedTitle()
  372. {
  373. return str_repeat('--', $this->getLevel()).' '.$this->getTitle();
  374. }
  375. // ---------------------------------------------------------------------
  376. /**
  377. * Set description.
  378. *
  379. * @param string $description
  380. *
  381. * @return Location
  382. */
  383. public function setDescription($description)
  384. {
  385. $this->description = $description;
  386. return $this;
  387. }
  388. /**
  389. * Get description.
  390. *
  391. * @return string
  392. */
  393. public function getDescription()
  394. {
  395. return $this->description;
  396. }
  397. // ---------------------------------------------------------------------
  398. /**
  399. * Set slug.
  400. *
  401. * @param string $slug
  402. *
  403. * @return Location
  404. */
  405. public function setSlug($slug)
  406. {
  407. $this->slug = $slug;
  408. return $this;
  409. }
  410. /**
  411. * Get slug.
  412. */
  413. public function getSlug(): string
  414. {
  415. return $this->slug;
  416. }
  417. // ---------------------------------------------------------------------
  418. /**
  419. * Set centerLat.
  420. *
  421. * @param float $centerLat
  422. *
  423. * @return Location
  424. */
  425. public function setCenterLat($centerLat)
  426. {
  427. return $this->setLat($centerLat);
  428. }
  429. /**
  430. * @return float
  431. */
  432. #[Serializer\VirtualProperty]
  433. #[Serializer\Groups(['Map', 'Details', 'Neighborhood', 'LocationFlat', 'Autocomplete'])]
  434. #[Serializer\SerializedName('center_lat')]
  435. #[Serializer\Until('v2.13')]
  436. #[Serializer\Expose]
  437. public function getCenterLat()
  438. {
  439. return $this->getLat();
  440. }
  441. /**
  442. * @param float $latitude
  443. *
  444. * @return Location
  445. */
  446. public function setLat($latitude)
  447. {
  448. $this->lat = $latitude;
  449. return $this;
  450. }
  451. /**
  452. * @return float|null
  453. */
  454. public function getLat()
  455. {
  456. if (!$this->lat) {
  457. return null;
  458. }
  459. return (float) $this->lat;
  460. }
  461. // ---------------------------------------------------------------------
  462. /**
  463. * Set lon.
  464. *
  465. * @deprecated
  466. *
  467. * @param float $lon
  468. *
  469. * @return Location
  470. */
  471. public function setCenterLng($lon)
  472. {
  473. return $this->setLon($lon);
  474. }
  475. /**
  476. * @deprecated
  477. *
  478. * @return float|null
  479. */
  480. #[Serializer\VirtualProperty]
  481. #[Serializer\Groups(['Map', 'Details', 'Neighborhood', 'LocationFlat', 'Autocomplete'])]
  482. #[Serializer\SerializedName('center_lng')]
  483. #[Serializer\Until('v2.13')]
  484. #[Serializer\Expose]
  485. public function getCenterLng()
  486. {
  487. return $this->getLon();
  488. }
  489. /**
  490. * @param float $longitude
  491. *
  492. * @return Location
  493. */
  494. public function setLon($longitude)
  495. {
  496. $this->lon = $longitude;
  497. return $this;
  498. }
  499. /**
  500. * @return float|null
  501. */
  502. public function getLon()
  503. {
  504. if (!$this->lon) {
  505. return null;
  506. }
  507. return (float) $this->lon;
  508. }
  509. // ---------------------------------------------------------------------
  510. /**
  511. * Set zoom.
  512. *
  513. * @deprecated
  514. *
  515. * @param int $zoom
  516. *
  517. * @return Location
  518. */
  519. public function setZoomLevel($zoom)
  520. {
  521. return $this->setZoom($zoom);
  522. }
  523. /**
  524. * @deprecated
  525. *
  526. * @return int
  527. */
  528. #[Serializer\VirtualProperty]
  529. #[Serializer\Groups(['Map', 'Details', 'Neighborhood', 'LocationFlat', 'Autocomplete', 'AutocompleteV3', 'DefaultV4'])]
  530. #[Serializer\SerializedName('zoom_level')]
  531. #[Serializer\Until('v2.13')]
  532. #[Serializer\Expose]
  533. public function getZoomLevel()
  534. {
  535. return $this->getZoom();
  536. }
  537. public function setZoom(?int $level): self
  538. {
  539. $this->zoom = $level;
  540. return $this;
  541. }
  542. /**
  543. * @return int|null
  544. */
  545. #[Serializer\VirtualProperty]
  546. #[Serializer\SerializedName('zoom')]
  547. #[Serializer\Groups(['DataJS'])]
  548. public function getZoom()
  549. {
  550. return $this->zoom;
  551. }
  552. // ---------------------------------------------------------------------
  553. /**
  554. * Set coordinates.
  555. *
  556. * @param array $coordinates
  557. *
  558. * @return Location
  559. */
  560. public function setCoordinates($coordinates)
  561. {
  562. $this->coordinates = $coordinates;
  563. return $this;
  564. }
  565. /**
  566. * Get coordinates.
  567. *
  568. * @return array
  569. */
  570. public function getCoordinates()
  571. {
  572. return $this->coordinates;
  573. }
  574. // ---------------------------------------------------------------------
  575. /**
  576. * Set searchable.
  577. *
  578. * @param bool $searchable
  579. *
  580. * @return Location
  581. */
  582. public function setSearchable($searchable)
  583. {
  584. $this->searchable = $searchable;
  585. return $this;
  586. }
  587. /**
  588. * Get searchable.
  589. *
  590. * @return bool
  591. */
  592. public function getSearchable()
  593. {
  594. return $this->searchable;
  595. }
  596. // ---------------------------------------------------------------------
  597. /**
  598. * Set homeFilter.
  599. *
  600. * @param bool $homeFilter
  601. *
  602. * @return Location
  603. */
  604. public function setHomeFilter($homeFilter)
  605. {
  606. $this->homeFilter = $homeFilter;
  607. return $this;
  608. }
  609. /**
  610. * Get homeFilter.
  611. *
  612. * @return bool
  613. */
  614. public function getHomeFilter()
  615. {
  616. return $this->homeFilter;
  617. }
  618. // ---------------------------------------------------------------------
  619. /**
  620. * Set estimate.
  621. *
  622. * @param bool $estimate
  623. *
  624. * @return Location
  625. */
  626. public function setEstimate($estimate)
  627. {
  628. $this->estimate = $estimate;
  629. return $this;
  630. }
  631. /**
  632. * Get estimate.
  633. *
  634. * @return bool
  635. */
  636. public function getEstimate()
  637. {
  638. return $this->estimate;
  639. }
  640. // ---------------------------------------------------------------------
  641. /**
  642. * Set disabled.
  643. *
  644. * @param bool $disabled
  645. *
  646. * @return Location
  647. */
  648. public function setDisabled($disabled)
  649. {
  650. $this->disabled = $disabled;
  651. return $this;
  652. }
  653. /**
  654. * Get disabled.
  655. *
  656. * @return bool
  657. */
  658. public function getDisabled()
  659. {
  660. return $this->disabled;
  661. }
  662. // ---------------------------------------------------------------------
  663. /**
  664. * Set parent.
  665. *
  666. * @return Location
  667. */
  668. public function setParent(?self $parent = null)
  669. {
  670. $this->parent = $parent;
  671. return $this;
  672. }
  673. /**
  674. * Get parent.
  675. *
  676. * @return Location
  677. */
  678. public function getParent()
  679. {
  680. return $this->parent;
  681. }
  682. // ---------------------------------------------------------------------
  683. /**
  684. * Add children.
  685. *
  686. * @return Location
  687. */
  688. public function addChild(self $children)
  689. {
  690. $this->children[] = $children;
  691. return $this;
  692. }
  693. /**
  694. * Remove children.
  695. */
  696. public function removeChild(self $children): void
  697. {
  698. $this->children->removeElement($children);
  699. }
  700. /**
  701. * Get children.
  702. *
  703. * @return Collection
  704. */
  705. public function getChildren()
  706. {
  707. $criteria = Criteria::create()
  708. ->where(Criteria::expr()->eq('disabled', false));
  709. return $this->children->matching($criteria);
  710. }
  711. /**
  712. * Get children sorted by id.
  713. *
  714. * @return Collection
  715. */
  716. public function getChildrenSortedById($filters = [])
  717. {
  718. $criteria = Criteria::create()
  719. ->where(Criteria::expr()->eq('disabled', false));
  720. if (isset($filters['neighborhoodFilter'])) {
  721. $criteria->andWhere(Criteria::expr()->eq('neighborhoodFilter', $filters['neighborhoodFilter']));
  722. }
  723. return $this->childrenSortedById->matching($criteria);
  724. }
  725. /**
  726. * Get children.
  727. *
  728. * @return Collection
  729. */
  730. public function getChildrenArray()
  731. {
  732. $criteria = Criteria::create()
  733. ->where(Criteria::expr()->eq('disabled', false));
  734. return $this->children->matching($criteria)->toArray();
  735. }
  736. /**
  737. * Get neighborhoodchildren.
  738. *
  739. * @return Collection
  740. */
  741. public function getNeighborhoodChildren()
  742. {
  743. $criteria = Criteria::create()
  744. ->andWhere(Criteria::expr()->eq('disabled', false))
  745. ->andWhere(Criteria::expr()->eq('neighborhoodFilter', true));
  746. return $this->children->matching($criteria);
  747. }
  748. /**
  749. * Get leveled children.
  750. *
  751. * @return Collection
  752. */
  753. public function getLeveledChildren()
  754. {
  755. $criteria = Criteria::create()
  756. ->where(Criteria::expr()->eq('disabled', false))
  757. ->where(Criteria::expr()->lte('level', 2));
  758. return $this->children->matching($criteria);
  759. }
  760. /**
  761. * Set type.
  762. *
  763. * @param string $type
  764. *
  765. * @return Location
  766. */
  767. public function setType($type)
  768. {
  769. $this->type = $type;
  770. return $this;
  771. }
  772. /**
  773. * Get type.
  774. *
  775. * @return string
  776. */
  777. public function getType()
  778. {
  779. return $this->type;
  780. }
  781. public function getTypeLabel(): ?string
  782. {
  783. return LocationTypes::getLabel($this->getType());
  784. }
  785. // ---------------------------------------------------------------------
  786. /**
  787. * Get translations.
  788. *
  789. * @return ArrayCollection
  790. */
  791. public function getTranslations()
  792. {
  793. return $this->translations;
  794. }
  795. /**
  796. * Add translation.
  797. *
  798. * @return Location
  799. */
  800. public function addTranslation(LocationTranslation $translation)
  801. {
  802. if (!$this->translations->contains($translation)) {
  803. $this->translations->add($translation);
  804. $translation->setObject($this);
  805. }
  806. return $this;
  807. }
  808. /**
  809. * Remove translation.
  810. *
  811. * @return Location
  812. */
  813. public function removeTranslation(LocationTranslation $translation)
  814. {
  815. if ($this->translations->contains($translation)) {
  816. $this->translations->removeElement($translation);
  817. }
  818. return $this;
  819. }
  820. // ---------------------------------------------------------------------
  821. /**
  822. * Add listings.
  823. *
  824. * @return Location
  825. */
  826. public function addListing(Listing $listings)
  827. {
  828. $this->listings[] = $listings;
  829. return $this;
  830. }
  831. /**
  832. * Remove listings.
  833. */
  834. public function removeListing(Listing $listings): void
  835. {
  836. $this->listings->removeElement($listings);
  837. }
  838. /**
  839. * Get listings.
  840. *
  841. * @return Collection
  842. */
  843. public function getListings()
  844. {
  845. return $this->listings;
  846. }
  847. // ---------------------------------------------------------------------
  848. /**
  849. * Add notifiers.
  850. *
  851. * @return Location
  852. */
  853. public function addNotifier(Notifier $notifiers)
  854. {
  855. $this->notifiers[] = $notifiers;
  856. return $this;
  857. }
  858. /**
  859. * Remove notifiers.
  860. */
  861. public function removeNotifier(Notifier $notifiers): void
  862. {
  863. $this->notifiers->removeElement($notifiers);
  864. }
  865. /**
  866. * Get notifiers.
  867. *
  868. * @return Collection
  869. */
  870. public function getNotifiers()
  871. {
  872. return $this->notifiers;
  873. }
  874. // ---------------------------------------------------------------------
  875. /**
  876. * Add rules.
  877. *
  878. * @return Location
  879. */
  880. public function addRule(Rule $rules)
  881. {
  882. $this->rules[] = $rules;
  883. return $this;
  884. }
  885. /**
  886. * Remove rules.
  887. */
  888. public function removeRule(Rule $rules): void
  889. {
  890. $this->rules->removeElement($rules);
  891. }
  892. /**
  893. * Get rules.
  894. *
  895. * @return Collection
  896. */
  897. public function getRules()
  898. {
  899. return $this->rules;
  900. }
  901. // ---------------------------------------------------------------------
  902. /**
  903. * Get Nearest Searchable Location.
  904. */
  905. public function getNearestSearchable()
  906. {
  907. $location = $this;
  908. while ($location && !$location->getSearchable()) {
  909. $location = $location->getParent();
  910. }
  911. if (!$location) {
  912. return $this;
  913. }
  914. return $location;
  915. }
  916. // -----------------------------------------------------------------------------
  917. /**
  918. * Get Nearest Neighborhood Parent.
  919. */
  920. public function getNearestNeighborhood()
  921. {
  922. $location = $this;
  923. while (
  924. !$location->getNeighborhoodFilter()
  925. && $location->getParent()
  926. && 0 != $location->getParent()->getLevel()
  927. ) {
  928. $location = $location->getParent();
  929. }
  930. if (!$location->getNeighborhoodFilter() || 0 == $location->getLevel()) {
  931. return;
  932. }
  933. return $location;
  934. }
  935. /**
  936. * Get Nearest Location Custom Level .
  937. *
  938. * @param int $level
  939. *
  940. * @return Location
  941. */
  942. public function getNearestLeveledLocation($level = 1)
  943. {
  944. $location = $this;
  945. if (\in_array($location->getLevel(), [0, $level])) {
  946. return $location;
  947. }
  948. while ($location->getParent() && 0 != $location->getParent()->getLevel()) {
  949. $location = $location->getParent();
  950. }
  951. return $location;
  952. }
  953. /**
  954. * Get the nearest parent with the provided location type.
  955. */
  956. public function getParentByType(string $locationType, bool $rootFallback = false): ?self
  957. {
  958. $location = $this->getParent();
  959. $root = null;
  960. while ($location) {
  961. if ($location->getType() === $locationType) {
  962. return $location;
  963. }
  964. $root = $location;
  965. $location = $location->getParent();
  966. }
  967. return $rootFallback ? $root : null;
  968. }
  969. #[Serializer\VirtualProperty]
  970. #[Serializer\SerializedName('parent')]
  971. #[Serializer\Expose]
  972. #[Serializer\Groups(['LocationFlat'])]
  973. public function getVirtualParent()
  974. {
  975. $parent = $this->getParent();
  976. if ($parent) {
  977. return [
  978. 'id' => $parent->getId(),
  979. 'title' => $parent->getTitle(),
  980. ];
  981. }
  982. return null;
  983. }
  984. /**
  985. * Gets parent by level.
  986. *
  987. * @param int $level
  988. *
  989. * @return Location|null
  990. */
  991. public function getLeveledParent($level = 1)
  992. {
  993. $location = $this;
  994. while ($location = $location->getParent()) {
  995. if ($location->getLevel() == $level) {
  996. return $location;
  997. }
  998. }
  999. return null;
  1000. }
  1001. /**
  1002. * Get Nearest Location Custom Level .
  1003. *
  1004. * @return Location
  1005. */
  1006. public function getFirstParent()
  1007. {
  1008. $location = $this;
  1009. if (0 == $location->getLevel()) {
  1010. return $location;
  1011. }
  1012. while ($location = $location->getParent()) {
  1013. if (0 == $location->getLevel()) {
  1014. return $location;
  1015. }
  1016. }
  1017. return $location;
  1018. }
  1019. /**
  1020. * Set level.
  1021. *
  1022. * @param int $level
  1023. *
  1024. * @return Location
  1025. */
  1026. public function setLevel($level)
  1027. {
  1028. $this->level = $level;
  1029. return $this;
  1030. }
  1031. /**
  1032. * Get level.
  1033. *
  1034. * @return int
  1035. */
  1036. public function getLevel()
  1037. {
  1038. return $this->level;
  1039. }
  1040. /**
  1041. * Set left.
  1042. *
  1043. * @param int $left
  1044. *
  1045. * @return Location
  1046. */
  1047. public function setLeft($left)
  1048. {
  1049. $this->left = $left;
  1050. return $this;
  1051. }
  1052. /**
  1053. * Get left.
  1054. *
  1055. * @return int
  1056. */
  1057. public function getLeft()
  1058. {
  1059. return $this->left;
  1060. }
  1061. /**
  1062. * Set right.
  1063. *
  1064. * @param int $right
  1065. *
  1066. * @return Location
  1067. */
  1068. public function setRight($right)
  1069. {
  1070. $this->right = $right;
  1071. return $this;
  1072. }
  1073. /**
  1074. * Get right.
  1075. *
  1076. * @return int
  1077. */
  1078. public function getRight()
  1079. {
  1080. return $this->right;
  1081. }
  1082. /**
  1083. * Set root.
  1084. *
  1085. * @param int $root
  1086. *
  1087. * @return Location
  1088. */
  1089. public function setRoot($root)
  1090. {
  1091. $this->root = $root;
  1092. return $this;
  1093. }
  1094. /**
  1095. * Get root.
  1096. *
  1097. * @return int
  1098. */
  1099. public function getRoot()
  1100. {
  1101. return $this->root;
  1102. }
  1103. /**
  1104. * Add locationSupplyDemand.
  1105. *
  1106. * @return Location
  1107. */
  1108. public function addLocationSupplyDemand(LocationSupplyDemand $locationSupplyDemand)
  1109. {
  1110. $this->locationSupplyDemand[] = $locationSupplyDemand;
  1111. return $this;
  1112. }
  1113. /**
  1114. * Remove locationSupplyDemand.
  1115. */
  1116. public function removeLocationSupplyDemand(LocationSupplyDemand $locationSupplyDemand): void
  1117. {
  1118. $this->locationSupplyDemand->removeElement($locationSupplyDemand);
  1119. }
  1120. /**
  1121. * Get locationSupplyDemand.
  1122. *
  1123. * @return Collection
  1124. */
  1125. public function getLocationSupplyDemand()
  1126. {
  1127. return $this->locationSupplyDemand;
  1128. }
  1129. // ---------------------------------------------------------------------
  1130. /**
  1131. * Add photos.
  1132. *
  1133. * @return Location
  1134. */
  1135. public function addPhoto(LocationPhoto $photo)
  1136. {
  1137. $photo->setLocation($this);
  1138. $this->photos[] = $photo;
  1139. return $this;
  1140. }
  1141. /**
  1142. * Set photos.
  1143. *
  1144. * @return Location
  1145. */
  1146. public function setPhotos($photos)
  1147. {
  1148. foreach ($photos as $photo) {
  1149. $this->addPhoto($photo);
  1150. }
  1151. return $this;
  1152. }
  1153. /**
  1154. * Remove photos.
  1155. */
  1156. public function removePhoto(LocationPhoto $photo): void
  1157. {
  1158. $this->photos->removeElement($photo);
  1159. }
  1160. /**
  1161. * @return ArrayCollection
  1162. */
  1163. public function getPhotos()
  1164. {
  1165. return $this->photos;
  1166. }
  1167. /**
  1168. * @return mixed|null
  1169. */
  1170. #[Serializer\VirtualProperty]
  1171. #[Serializer\Groups(['Default', 'LocationFlat'])]
  1172. public function getMainPhoto()
  1173. {
  1174. // Important for API
  1175. if ($this->getPhotos()->count() <= 0) {
  1176. return;
  1177. }
  1178. /* @var Photo $photo */
  1179. $mainPhoto = $this->photos->filter(fn ($photo) => PhotoTypes::MAIN_PHOTO == $photo->getType());
  1180. return $mainPhoto->first() ?: $this->getPhotos()->first();
  1181. }
  1182. // ---------------------------------------------------------------------
  1183. public function __clone()
  1184. {
  1185. $this->id = null;
  1186. }
  1187. public function __toString(): string
  1188. {
  1189. return $this->title;
  1190. }
  1191. /**
  1192. * Set rating.
  1193. *
  1194. * @return Location
  1195. */
  1196. public function setRating(?LocationRating $rating = null)
  1197. {
  1198. $this->rating = $rating;
  1199. $this->rating->setLocation($this);
  1200. return $this;
  1201. }
  1202. /**
  1203. * Get rating.
  1204. *
  1205. * @return LocationRating
  1206. */
  1207. public function getRating()
  1208. {
  1209. return $this->rating;
  1210. }
  1211. /**
  1212. * Get rating of the nearest parent location that has one.
  1213. */
  1214. public function getNearestRating()
  1215. {
  1216. $location = $this;
  1217. while ($location) {
  1218. $rating = $location->getRating();
  1219. if (
  1220. $rating
  1221. && null !== $rating->getOverall()
  1222. && LocationTypes::CITY !== $location->getType()
  1223. ) {
  1224. return $rating;
  1225. }
  1226. $location = $location->getParent();
  1227. }
  1228. return null;
  1229. }
  1230. /**
  1231. * Set neighborhoodFilter.
  1232. *
  1233. * @param bool $neighborhoodFilter
  1234. *
  1235. * @return Location
  1236. */
  1237. public function setNeighborhoodFilter($neighborhoodFilter)
  1238. {
  1239. $this->neighborhoodFilter = $neighborhoodFilter;
  1240. return $this;
  1241. }
  1242. /**
  1243. * Get neighborhoodFilter.
  1244. *
  1245. * @return bool
  1246. */
  1247. public function getNeighborhoodFilter()
  1248. {
  1249. return $this->neighborhoodFilter;
  1250. }
  1251. /**
  1252. * Add locationStatistic.
  1253. *
  1254. * @return Location
  1255. */
  1256. public function addLocationStatistic(LocationStatistics $locationStatistic)
  1257. {
  1258. $this->locationStatistics[] = $locationStatistic;
  1259. return $this;
  1260. }
  1261. /**
  1262. * Remove locationStatistic.
  1263. */
  1264. public function removeLocationStatistic(LocationStatistics $locationStatistic): void
  1265. {
  1266. $this->locationStatistics->removeElement($locationStatistic);
  1267. }
  1268. /**
  1269. * Get locationStatistics.
  1270. *
  1271. * @return Collection
  1272. */
  1273. public function getLocationStatistics()
  1274. {
  1275. return $this->locationStatistics;
  1276. }
  1277. /**
  1278. * Get lowest Average Price.
  1279. *
  1280. * @return LocationStatistics $locationStatistic
  1281. */
  1282. public function getSingleStatistics(?PropertyType $propertyType = null)
  1283. {
  1284. $criteria = Criteria::create()
  1285. ->andWhere(Criteria::expr()->neq('avgPrice', null))
  1286. ->andWhere(Criteria::expr()->gt('avgPrice', 0))
  1287. ->orderBy(['avgPrice' => Criteria::ASC]);
  1288. if ($propertyType) {
  1289. $criteria
  1290. ->andWhere(Criteria::expr()->eq('propertyType', $propertyType));
  1291. }
  1292. return $this->locationStatistics->matching($criteria)->first();
  1293. }
  1294. /**
  1295. * Set statisticsFilter.
  1296. *
  1297. * @param bool $statisticsFilter
  1298. *
  1299. * @return Location
  1300. */
  1301. public function setStatisticsFilter($statisticsFilter)
  1302. {
  1303. $this->statisticsFilter = $statisticsFilter;
  1304. return $this;
  1305. }
  1306. /**
  1307. * Get statisticsFilter.
  1308. *
  1309. * @return bool
  1310. */
  1311. public function getStatisticsFilter()
  1312. {
  1313. return $this->statisticsFilter;
  1314. }
  1315. /**
  1316. * Add company.
  1317. *
  1318. * @return Location
  1319. */
  1320. public function addCompany(\Aqarmap\Bundle\CRMBundle\Entity\Company $company)
  1321. {
  1322. $this->companies[] = $company;
  1323. return $this;
  1324. }
  1325. /**
  1326. * Remove company.
  1327. */
  1328. public function removeCompany(\Aqarmap\Bundle\CRMBundle\Entity\Company $company): void
  1329. {
  1330. $this->companies->removeElement($company);
  1331. }
  1332. /**
  1333. * Get companies.
  1334. *
  1335. * @return Collection
  1336. */
  1337. public function getCompanies()
  1338. {
  1339. return $this->companies;
  1340. }
  1341. /**
  1342. * Add discussion.
  1343. *
  1344. * @return Location
  1345. */
  1346. public function addDiscussion(Discussion $discussion)
  1347. {
  1348. $this->discussions[] = $discussion;
  1349. return $this;
  1350. }
  1351. /**
  1352. * Remove discussion.
  1353. */
  1354. public function removeDiscussion(Discussion $discussion): void
  1355. {
  1356. $this->discussions->removeElement($discussion);
  1357. }
  1358. /**
  1359. * Get discussions.
  1360. *
  1361. * @return Collection
  1362. */
  1363. public function getDiscussions()
  1364. {
  1365. return $this->discussions;
  1366. }
  1367. /**
  1368. * Set compoundFilter.
  1369. *
  1370. * @param bool $compoundFilter
  1371. *
  1372. * @return Location
  1373. */
  1374. public function setCompoundFilter($compoundFilter)
  1375. {
  1376. $this->compoundFilter = $compoundFilter;
  1377. return $this;
  1378. }
  1379. /**
  1380. * Get compoundFilter.
  1381. *
  1382. * @return bool
  1383. */
  1384. public function getCompoundFilter()
  1385. {
  1386. return $this->compoundFilter;
  1387. }
  1388. /**
  1389. * Add propertyType.
  1390. *
  1391. * @return Location
  1392. */
  1393. public function addPropertyType(PropertyType $propertyType)
  1394. {
  1395. $this->propertyTypes[] = $propertyType;
  1396. return $this;
  1397. }
  1398. /**
  1399. * Remove propertyType.
  1400. */
  1401. public function removePropertyType(PropertyType $propertyType): void
  1402. {
  1403. $this->propertyTypes->removeElement($propertyType);
  1404. }
  1405. /**
  1406. * Get propertyTypes.
  1407. *
  1408. * @return Collection
  1409. */
  1410. public function getPropertyTypes()
  1411. {
  1412. return $this->propertyTypes;
  1413. }
  1414. /**
  1415. * Set listing.
  1416. *
  1417. * @return Location
  1418. */
  1419. public function setListing(?Listing $listing = null)
  1420. {
  1421. $this->listing = $listing;
  1422. return $this;
  1423. }
  1424. /**
  1425. * Set listing.
  1426. *
  1427. * @return Location
  1428. */
  1429. public function setListings(array $listings = [])
  1430. {
  1431. $this->listings = $listings;
  1432. return $this;
  1433. }
  1434. /**
  1435. * Get listing.
  1436. *
  1437. * @return Listing
  1438. */
  1439. public function getListing()
  1440. {
  1441. return $this->listing;
  1442. }
  1443. /**
  1444. * Set locationCompound.
  1445. *
  1446. * @return Location
  1447. */
  1448. public function setLocationCompound(?LocationCompound $locationCompound = null)
  1449. {
  1450. $this->locationCompound = $locationCompound;
  1451. $this->locationCompound->setLocation($this);
  1452. return $this;
  1453. }
  1454. /**
  1455. * Get locationCompound.
  1456. *
  1457. * @return LocationCompound
  1458. */
  1459. public function getLocationCompound()
  1460. {
  1461. return $this->locationCompound;
  1462. }
  1463. /**
  1464. * Add nearestLocation.
  1465. *
  1466. * @return Location
  1467. */
  1468. public function addNearestLocation(self $nearestLocation)
  1469. {
  1470. if (!$this->nearestLocations->contains($nearestLocation)) {
  1471. $this->nearestLocations->add($nearestLocation);
  1472. }
  1473. return $this;
  1474. }
  1475. /**
  1476. * Remove nearestLocation.
  1477. *
  1478. * @return Location
  1479. */
  1480. public function removeNearestLocation(self $nearestLocation)
  1481. {
  1482. if ($this->nearestLocations->contains($nearestLocation)) {
  1483. $this->nearestLocations->removeElement($nearestLocation);
  1484. }
  1485. return $this;
  1486. }
  1487. /**
  1488. * Get nearestLocations.
  1489. *
  1490. * @return Collection
  1491. */
  1492. public function getNearestLocations()
  1493. {
  1494. return $this->nearestLocations;
  1495. }
  1496. /**
  1497. * Add interest.
  1498. *
  1499. * @return Location
  1500. */
  1501. public function addInterest(UserInterest $interest)
  1502. {
  1503. $this->interests[] = $interest;
  1504. return $this;
  1505. }
  1506. /**
  1507. * Remove interest.
  1508. */
  1509. public function removeInterest(UserInterest $interest): void
  1510. {
  1511. $this->interests->removeElement($interest);
  1512. }
  1513. /**
  1514. * Get interests.
  1515. *
  1516. * @return Collection
  1517. */
  1518. public function getInterests()
  1519. {
  1520. return $this->interests;
  1521. }
  1522. /**
  1523. * Get interests.
  1524. *
  1525. * @return UserInterest
  1526. */
  1527. public function getLiveInterests()
  1528. {
  1529. $criteria = Criteria::create()
  1530. ->andwhere(Criteria::expr()->eq('status', UserInterestStatus::LIVE));
  1531. return $this->interests->matching($criteria);
  1532. }
  1533. public function setTranslatableLocale($locale): void
  1534. {
  1535. $this->locale = $locale;
  1536. }
  1537. /**
  1538. * Add exchangeRequest.
  1539. *
  1540. * @return Location
  1541. */
  1542. public function addExchangeRequest(ExchangeRequest $exchangeRequest)
  1543. {
  1544. $this->exchangeRequests[] = $exchangeRequest;
  1545. return $this;
  1546. }
  1547. /**
  1548. * Remove exchangeRequest.
  1549. */
  1550. public function removeExchangeRequest(ExchangeRequest $exchangeRequest): void
  1551. {
  1552. $this->exchangeRequests->removeElement($exchangeRequest);
  1553. }
  1554. /**
  1555. * Get exchangeRequests.
  1556. *
  1557. * @return Collection
  1558. */
  1559. public function getExchangeRequests()
  1560. {
  1561. return $this->exchangeRequests;
  1562. }
  1563. public function setSearchTerms($searchTerms): void
  1564. {
  1565. $this->searchTerms = $searchTerms;
  1566. }
  1567. public function getSearchTerms()
  1568. {
  1569. return $this->searchTerms;
  1570. }
  1571. /**
  1572. * @return int
  1573. */
  1574. public function getLeadsCounter()
  1575. {
  1576. return $this->leadsCounter;
  1577. }
  1578. /**
  1579. * @param int $leadsCounter
  1580. */
  1581. public function setLeadsCounter($leadsCounter): void
  1582. {
  1583. $this->leadsCounter = $leadsCounter;
  1584. }
  1585. /**
  1586. * @return int
  1587. */
  1588. public function getListingsCounter()
  1589. {
  1590. return $this->listingsCounter;
  1591. }
  1592. /**
  1593. * @param int $listingsCounter
  1594. *
  1595. * @return Location
  1596. */
  1597. public function setListingsCounter($listingsCounter)
  1598. {
  1599. $this->listingsCounter = $listingsCounter;
  1600. return $this;
  1601. }
  1602. /**
  1603. * @return int
  1604. */
  1605. public function getLocationParentLabel()
  1606. {
  1607. $parent = $this->getParent() ? $this->getParent()->getTitle().' / ' : null;
  1608. return $parent.$this->getTitle();
  1609. }
  1610. /**
  1611. * @return int
  1612. */
  1613. public function getLastSlug()
  1614. {
  1615. $segments = explode('/', $this->slug);
  1616. return end($segments);
  1617. }
  1618. /**
  1619. * @return bool
  1620. */
  1621. #[Serializer\VirtualProperty]
  1622. #[Serializer\SerializedName('has_children')]
  1623. #[Serializer\Expose]
  1624. #[Serializer\Groups(['LocationFlat', 'AutocompleteV3', 'DefaultV4'])]
  1625. public function getHasChildren()
  1626. {
  1627. return $this->getChildren()->isEmpty() ? false : true;
  1628. }
  1629. /**
  1630. * @return string
  1631. */
  1632. #[Serializer\VirtualProperty]
  1633. #[Serializer\SerializedName('text')]
  1634. #[Serializer\Groups(['Autocomplete'])]
  1635. #[Serializer\Expose]
  1636. public function getText()
  1637. {
  1638. return $this->getTitle();
  1639. }
  1640. /**
  1641. * Get Title FullPath
  1642. * e.g. takes 90th street and returns Greater Cairo / New Cairo / 90th Street.
  1643. */
  1644. #[Serializer\VirtualProperty]
  1645. #[Serializer\SerializedName('title_full_path')]
  1646. #[Serializer\Groups(['Autocomplete', 'listingDetails', 'AutocompleteV3', 'DefaultV4', 'SearchV4', 'ProjectDetailsV4', 'SlugResolver', 'RelatedListingsV2'])]
  1647. #[Serializer\Expose]
  1648. public function getTitleFullPath(): string
  1649. {
  1650. $location = $this;
  1651. $titlesFullPath[] = $this->getTitle();
  1652. while ($location = $location->getParent()) {
  1653. $titlesFullPath[] = $location->getTitle();
  1654. }
  1655. return implode(' / ', array_reverse($titlesFullPath ?? []));
  1656. }
  1657. /**
  1658. * Get searchable title keywords
  1659. * e.g. takes 90th street and returns Greater Cairo / New Cairo / 90th Street.
  1660. */
  1661. public function getSearchableTitle(): string
  1662. {
  1663. $location = $this;
  1664. $titlesFullPath = [];
  1665. $this->handleTitle($location, $titlesFullPath);
  1666. while ($location = $location->getParent()) {
  1667. $this->handleTitle($location, $titlesFullPath);
  1668. }
  1669. return implode(' / ', array_reverse($titlesFullPath ?? []));
  1670. }
  1671. /**
  1672. * Get Title FullPath started from children
  1673. * e.g. takes 90th street and returns Greater 90th Street - New Cairo - Cairo.
  1674. */
  1675. public function getTitleFullPathStartedFromChildren(): string
  1676. {
  1677. $location = $this;
  1678. $titlesFullPath[] = $this->getTitle();
  1679. while ($location = $location->getParent()) {
  1680. $titlesFullPath[] = $location->getTitle();
  1681. }
  1682. return implode(' - ', $titlesFullPath);
  1683. }
  1684. /**
  1685. * @return Location
  1686. */
  1687. public function setSynced($synced)
  1688. {
  1689. $this->synced = $synced;
  1690. return $this;
  1691. }
  1692. public function getSynced()
  1693. {
  1694. return $this->synced;
  1695. }
  1696. #[Serializer\VirtualProperty]
  1697. #[Serializer\Groups(['Autocomplete'])]
  1698. #[Serializer\Expose]
  1699. public function getTranslation(): array
  1700. {
  1701. $translations = [];
  1702. foreach ($this->getTranslations()->toArray() as $trans) {
  1703. $translations[$trans->getLocale()] = $trans->getContent();
  1704. }
  1705. return $translations;
  1706. }
  1707. /**
  1708. * @return string|null
  1709. */
  1710. public function getFullPath()
  1711. {
  1712. return $this->fullPath;
  1713. }
  1714. public function setFullPath(?string $fullPath = null): self
  1715. {
  1716. $this->fullPath = $fullPath;
  1717. return $this;
  1718. }
  1719. /**
  1720. * @return string
  1721. */
  1722. #[Serializer\VirtualProperty]
  1723. #[Serializer\SerializedName('name')]
  1724. #[Serializer\Groups(['AutocompleteV3', 'DefaultV4', 'SearchV4'])]
  1725. #[Serializer\Expose]
  1726. public function getName()
  1727. {
  1728. return $this->getTitle();
  1729. }
  1730. /**
  1731. * @return string
  1732. */
  1733. #[Serializer\VirtualProperty]
  1734. #[Serializer\SerializedName('latitude')]
  1735. #[Serializer\Groups(['AutocompleteV3', 'DefaultV4', 'ProjectDetailsV4'])]
  1736. #[Serializer\Expose]
  1737. public function getLatitude()
  1738. {
  1739. return $this->getLat();
  1740. }
  1741. /**
  1742. * @return string
  1743. */
  1744. #[Serializer\VirtualProperty]
  1745. #[Serializer\SerializedName('longitude')]
  1746. #[Serializer\Groups(['AutocompleteV3', 'DefaultV4', 'ProjectDetailsV4'])]
  1747. #[Serializer\Expose]
  1748. public function getLongitude()
  1749. {
  1750. return $this->getLon();
  1751. }
  1752. #[Serializer\VirtualProperty]
  1753. #[Serializer\Groups(['AutocompleteV3'])]
  1754. #[Serializer\SerializedName('translations')]
  1755. #[Serializer\Expose]
  1756. public function getLocationTranslations(): array
  1757. {
  1758. return $this->locationTranslations;
  1759. }
  1760. public function setLocationTranslations(array $translation): self
  1761. {
  1762. $this->locationTranslations = $translation;
  1763. return $this;
  1764. }
  1765. /**
  1766. * @return int|null
  1767. */
  1768. public function getReferenceId()
  1769. {
  1770. return $this->id;
  1771. }
  1772. /**
  1773. * @return self
  1774. */
  1775. public function setReferenceId(?int $referenceId)
  1776. {
  1777. $this->referenceId = $referenceId;
  1778. return $this;
  1779. }
  1780. /**
  1781. * @return int
  1782. */
  1783. #[Serializer\VirtualProperty]
  1784. #[Serializer\Groups(['DefaultV4'])]
  1785. #[Serializer\SerializedName('listingsCount')]
  1786. #[Serializer\Expose]
  1787. public function getListingsCount()
  1788. {
  1789. return $this->listingsCounter;
  1790. }
  1791. /**
  1792. * @return $this
  1793. */
  1794. public function setListingsCount(int $listingsCount): self
  1795. {
  1796. $this->listingsCounter = $listingsCount;
  1797. return $this;
  1798. }
  1799. #[Serializer\VirtualProperty]
  1800. #[Serializer\SerializedName('referenceId')]
  1801. #[Serializer\Expose]
  1802. #[Serializer\Groups(['DefaultV4', 'AutocompleteV3', 'SearchV4'])]
  1803. public function getReferencedV4Id()
  1804. {
  1805. return $this->getId();
  1806. }
  1807. /**
  1808. * @param array $translations
  1809. *
  1810. * @return self
  1811. */
  1812. public function setV4Translations($translations = [])
  1813. {
  1814. $this->v4Translations = $translations;
  1815. return $this;
  1816. }
  1817. /**
  1818. * Get translations.
  1819. *
  1820. * @return array
  1821. */
  1822. #[Serializer\VirtualProperty]
  1823. #[Serializer\Groups(['DefaultV4', 'MyListing', 'SearchV4'])]
  1824. #[Serializer\SerializedName('translations')]
  1825. #[Serializer\Expose]
  1826. public function getV4Translations()
  1827. {
  1828. return $this->v4Translations;
  1829. }
  1830. /**
  1831. * @return Location
  1832. */
  1833. public function setEligibleForMortgage(bool $eligibleForMortgage)
  1834. {
  1835. $this->eligibleForMortgage = $eligibleForMortgage;
  1836. return $this;
  1837. }
  1838. /**
  1839. * Get Eligible For Mortgage.
  1840. *
  1841. * @return bool
  1842. */
  1843. public function getEligibleForMortgage()
  1844. {
  1845. return $this->eligibleForMortgage;
  1846. }
  1847. /**
  1848. * Set isCompoundLocation.
  1849. *
  1850. * @param bool $isCompoundLocation
  1851. *
  1852. * @return Location
  1853. */
  1854. public function setIsCompoundLocation($isCompoundLocation)
  1855. {
  1856. $this->isCompoundLocation = $isCompoundLocation;
  1857. return $this;
  1858. }
  1859. /**
  1860. * Get isCompoundLocation.
  1861. *
  1862. * @return bool
  1863. */
  1864. public function getIsCompoundLocation()
  1865. {
  1866. return $this->isCompoundLocation;
  1867. }
  1868. /**
  1869. * Set showPrimaryOnly.
  1870. */
  1871. public function setShowPrimaryOnly(bool $showPrimaryOnly): self
  1872. {
  1873. $this->showPrimaryOnly = $showPrimaryOnly;
  1874. return $this;
  1875. }
  1876. /**
  1877. * Get showPrimaryOnly.
  1878. */
  1879. public function getShowPrimaryOnly(): bool
  1880. {
  1881. return $this->showPrimaryOnly;
  1882. }
  1883. /**
  1884. * @param self $location
  1885. * @param array &$titlesFullPath
  1886. */
  1887. private function handleTitle($location, &$titlesFullPath): void
  1888. {
  1889. $translations = $location->getTranslations() ? $location->getTranslations()->toArray() : [];
  1890. foreach ($translations as $trans) {
  1891. if ('en' == $trans->getLocale() && 'title' == $trans->getField()) {
  1892. $titlesFullPath[] = ucfirst((string) $trans->getContent());
  1893. }
  1894. }
  1895. $titlesFullPath[] = $location->getTitle();
  1896. }
  1897. private $listingOrNull;
  1898. #[Serializer\VirtualProperty]
  1899. #[Serializer\Groups(['SlugResolver', 'Compound', 'locationListingV2', 'homeCompoundV2', 'listingDetailsWithLocationCompound'])]
  1900. #[Serializer\SerializedName('compound_listing')]
  1901. #[Serializer\Expose]
  1902. public function getListingOrNull(): ?Listing
  1903. {
  1904. return $this->listingOrNull;
  1905. }
  1906. public function setListingOrNull(?Listing $listingOrNull): void
  1907. {
  1908. $this->listingOrNull = $listingOrNull;
  1909. }
  1910. public function getAlias(): string
  1911. {
  1912. return $this->alias;
  1913. }
  1914. public function setAlias(string $alias): void
  1915. {
  1916. $this->alias = $alias;
  1917. }
  1918. }