PluginProbe
Property Hive / 2.2.4
Property Hive v2.2.4
2.3.0 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 1.4.46 1.4.47 1.4.48 1.4.49 1.4.5 1.4.50 1.4.51 1.4.52 1.4.53 1.4.54 1.4.55 1.4.56 1.4.57 1.4.58 1.4.59 1.4.6 1.4.60 1.4.61 1.4.62 All 260 releases
propertyhive / includes / class-ph-aioseo.php

class-ph-aioseo.php in Property Hive 2.2.4, at includes/class-ph-aioseo.php

211 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 /**
8 * AIOSEO Compatibility
9 *
10 * @class PH_AIOSEO
11 * @version 1.0.0
12 * @package PropertyHive/Classes/
13 * @category Class
14 * @author PropertyHive
15 */
16 class PH_AIOSEO {
17
18 /** @var PH_AIOSEO The single instance of the class */
19 protected static $_instance = null;
20
21 /**
22 * Hook in methods
23 */
24 public static function init()
25 {
26 add_filter( 'aioseo_post_metabox_priority', array( __CLASS__, 'meta_box_to_bottom') );
27 add_filter( 'aioseo_sitemap_exclude_posts', array( __CLASS__, 'sitemap_exclude_off_market'), 10, 2 );
28
29 add_filter( 'aioseo_schema_output', [ __CLASS__, 'add_real_estate_listing_schema' ] );
30 }
31
32 public static function meta_box_to_bottom( $priority )
33 {
34 return 'low';
35 }
36
37 public static function sitemap_exclude_off_market( $ids, $type )
38 {
39 $ids = is_array( $ids ) ? $ids : [];
40
41 $off_market = get_posts(array(
42 'fields' => 'ids',
43 'posts_per_page' => -1,
44 'post_type' => 'property',
45 'meta_query' => array(
46 array(
47 'key' => '_on_market',
48 'value' => '',
49 )
50 )
51 ));
52
53 if ( $off_market ) {
54 $ids = array_merge( $ids, $off_market );
55 }
56 return array_values( array_unique( array_map( 'intval', $ids ) ) );
57 }
58
59 public static function add_real_estate_listing_schema( $graphs )
60 {
61 if ( ! is_singular( 'property' ) ) {
62 return $graphs;
63 }
64
65 $post_id = get_queried_object_id();
66 if ( ! $post_id ) {
67 return $graphs;
68 }
69
70 $property = new PH_Property($post_id);
71
72 // Common fields (adjust to your meta keys as needed).
73 $title = get_the_title( $post_id );
74 $url = get_permalink( $post_id );
75 $description = wp_strip_all_tags( get_the_excerpt( $post_id ) ?: '', true );
76 $datePosted = date("Y-m-d\TH:i:s", strtotime($property->_on_market_change_date)) . "+00:00";
77
78 $department = $property->_department;
79
80 $street = $property->_address_street;
81 $locality = $property->_address_two;
82 $region = $property->_address_three;
83 $postcode = $property->_address_postcode;
84 $country = $property->_address_country;
85 $lat = $property->_latitude;
86 $lng = $property->_longitude;
87
88 // Address bits (adjust to your meta keys).
89 $address = array_filter( [
90 '@type' => 'PostalAddress',
91 'streetAddress' => $street,
92 'addressLocality' => $locality,
93 'addressRegion' => $region,
94 'postalCode' => $postcode,
95 'addressCountry' => $country,
96 ] );
97
98 $bedrooms = (int)$property->_bedrooms;
99 $bathrooms = (int)$property->_bathrooms;
100
101 $images = array();
102 if ( get_option('propertyhive_images_stored_as', '') == 'urls' )
103 {
104 $photo_urls = $property->_photo_urls;
105 if ( !is_array($photo_urls) ) { $photo_urls = array(); }
106
107 if ( !empty($num_images) )
108 {
109 $photo_urls = array_slice($photo_urls, 0, $num_images);
110 }
111
112 foreach ( $photo_urls as $photo )
113 {
114 $images[] = isset($photo['url']) ? $photo['url'] : '';
115 }
116 }
117 else
118 {
119 $gallery_attachments = $property->get_gallery_attachment_ids();
120
121 if ( !empty($gallery_attachments) )
122 {
123 if ( !empty($num_images) )
124 {
125 $gallery_attachments = array_slice($gallery_attachments, 0, $num_images);
126 }
127
128 foreach ($gallery_attachments as $gallery_attachment)
129 {
130 $images[] = wp_get_attachment_url( $gallery_attachment );
131 }
132 }
133 }
134 $images = array_values( array_unique( array_filter( $images ) ) );
135
136 $types = array( 'Residence' );
137 if ( $department != 'commercial' && ph_get_custom_department_based_on($department) != 'commercial' )
138 {
139 $types[] = 'SingleFamilyResidence';
140 }
141 $item_offered = array_filter( [
142 '@type' => $types,
143 'address' => ! empty( $address ) ? $address : null,
144 ] );
145 if ( $lat && $lng ) {
146 $item_offered['geo'] = [
147 '@type' => 'GeoCoordinates',
148 'latitude' => (float)$lat,
149 'longitude' => (float)$lng,
150 ];
151 }
152 if ( $bedrooms && $department != 'commercial' && ph_get_custom_department_based_on($department) != 'commercial' ) { $item_offered['numberOfBedrooms'] = $bedrooms; }
153 if ( $bathrooms && $department != 'commercial' && ph_get_custom_department_based_on($department) != 'commercial' ) { $item_offered['numberOfBathroomsTotal'] = $bathrooms; }
154
155 // Attach an Offer (price, currency, availability) that points at the Residence
156 if ( $department == 'residential-sales' || ph_get_custom_department_based_on($department) == 'residential-sales' )
157 {
158 $offer = [
159 '@type' => 'Offer',
160 'price' => $property->_poa != 'yes' ? (float)$property->_price : '',
161 'priceCurrency' => $property->_currency,
162 // Use a schema.org ItemAvailability URL if you have one; default to InStock
163 //'availability' => $availability ?: 'https://schema.org/InStock',
164 'businessFunction' => 'https://purl.org/goodrelations/v1#Sell',
165 'itemOffered' => $item_offered,
166 'url' => $url
167 ];
168 }
169 elseif ( $department == 'residential-lettings' || ph_get_custom_department_based_on($department) == 'residential-lettings' )
170 {
171 $offer = [
172 '@type' => 'Offer',
173 'price' => $property->_poa != 'yes' ? (float)$property->_rent : '',
174 'priceCurrency' => $property->_currency,
175 'priceSpecification' => [
176 '@type' => 'UnitPriceSpecification',
177 'price' => $property->_poa != 'yes' ? (float)$property->_rent : '',
178 'priceCurrency' => $property->_currency,
179 'unitText' => $property->_rent_frequency,
180 ],
181 'businessFunction' => 'https://purl.org/goodrelations/v1#LeaseOut',
182 // Use a schema.org ItemAvailability URL if you have one; default to InStock
183 //'availability' => $availability ?: 'https://schema.org/InStock',
184 'itemOffered' => $item_offered,
185 'url' => $url
186 ];
187 }
188
189 $realEstateListing = array_filter( [
190 '@type' => 'RealEstateListing',
191 '@id' => trailingslashit( $url ) . '#realEstateListing',
192 'url' => $url,
193 'name' => $title,
194 'description' => $description,
195 'datePosted' => $datePosted,
196 'image' => ! empty( $images ) ? $images : null,
197 'mainEntityOfPage' => $url,
198 'offers' => $offer,
199 ] );
200
201 // Append (don’t replace) our graph.
202 if ( ! is_array( $graphs ) ) {
203 $graphs = [];
204 }
205 $graphs[] = $realEstateListing;
206
207 return $graphs;
208 }
209 }
210
211 PH_AIOSEO::init();