PluginProbe
Property Hive / 2.3.0
Property Hive v2.3.0
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-viewing.php

class-ph-viewing.php in Property Hive 2.3.0, at includes/class-ph-viewing.php

343 lines 11.1 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' ) ) exit; // Exit if accessed directly
4
5 /**
6 * Viewing
7 *
8 * The Property Hive viewing class handles viewing data.
9 *
10 * @class PH_Viewing
11 * @version 1.0.0
12 * @package PropertyHive/Classes
13 * @category Class
14 * @author PropertyHive
15 */
16 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Legacy public global class PH_Viewing; preserving the existing PH_* class name is required for plugin and extension compatibility.
17 class PH_Viewing {
18
19 /** @public int Viewing (post) ID */
20 public $id;
21
22 /**
23 * Get the viewing if ID is passed, otherwise the viewing is new and empty.
24 *
25 * @access public
26 * @param string $id (default: '')
27 * @return void
28 */
29 public function __construct( $id = '' ) {
30 if ( $id > 0 ) {
31 $this->get_viewing( $id );
32 }
33 }
34
35 /**
36 * Gets a viewing from the database.
37 *
38 * @access public
39 * @param int $id (default: 0)
40 * @return bool
41 */
42 public function get_viewing( $id = 0 ) {
43 if ( ! $id ) {
44 return false;
45 }
46 if ( $result = get_post( $id ) ) {
47 $this->populate( $result );
48 return true;
49 }
50 return false;
51 }
52
53 /**
54 * __isset function.
55 *
56 * @access public
57 * @param mixed $key
58 * @return bool
59 */
60 public function __isset( $key ) {
61 if ( ! $this->id ) {
62 return false;
63 }
64 return metadata_exists( 'post', $this->id, '_' . $key );
65 }
66
67 /**
68 * __get function.
69 *
70 * @access public
71 * @param mixed $key
72 * @return mixed
73 */
74 public function __get( $key ) {
75 // Get values or default if not set
76 $value = get_post_meta( $this->id, $key, true );
77 if ($value == '')
78 {
79 $value = get_post_meta( $this->id, '_' . $key, true );
80 }
81 return $value;
82 }
83
84 /**
85 * Populates a viewing from the loaded post data.
86 *
87 * @access public
88 * @param mixed $result
89 * @return void
90 */
91 public function populate( $result ) {
92 // Standard post data
93 $this->id = $result->ID;
94 $this->post_title = $result->post_title;
95 $this->post_status = $result->post_status;
96 }
97
98 public function get_related_viewings()
99 {
100 $related_viewings = array(
101 'previous' => array(),
102 'next' => array(),
103 'all' => array()
104 );
105
106 $applicant_contact_ids = get_post_meta($this->id, '_applicant_contact_id');
107 $applicant_contact_ids = !empty($applicant_contact_ids) ? ( is_array($applicant_contact_ids) ? $applicant_contact_ids : array($applicant_contact_ids) ) : array();
108
109 $property_id = get_post_meta($this->id, '_property_id', TRUE);
110 $property_id = !empty($property_id) ? $property_id : '';
111
112 $primary_viewing_start_date_time = get_post_meta($this->id, '_start_date_time', TRUE);
113
114 $meta_query = array(
115 array(
116 'key' => '_property_id',
117 'value' => (int)$property_id,
118 ),
119 array(
120 'key' => '_status',
121 'value' => array('cancelled', 'no_show'),
122 'compare' => 'NOT IN',
123 ),
124 );
125 foreach ( $applicant_contact_ids as $applicant_contact_id )
126 {
127 $meta_query[] = array(
128 'key' => '_applicant_contact_id',
129 'value' => (int)$applicant_contact_id
130 );
131 }
132
133 $args = array(
134 'fields' => 'ids',
135 'post_type' => 'viewing',
136 'nopaging' => true,
137 'post_status' => 'publish',
138 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Related viewings require matching this property and every applicant while excluding cancelled/no-show statuses in the existing metadata schema.
139 'meta_query' => $meta_query,
140 // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- Excludes one current viewing ID so the related-viewing lists cannot contain themselves; this is not an unbounded exclusion list.
141 'post__not_in' => array($this->id),
142 'orderby' => 'none'
143 );
144
145 $viewings_query = new WP_Query( $args );
146
147 if ( $viewings_query->have_posts() )
148 {
149 while ( $viewings_query->have_posts() )
150 {
151 $viewings_query->the_post();
152
153 $viewing_start_date_time = get_post_meta(get_the_ID(), '_start_date_time', TRUE);
154
155 if ( strtotime($viewing_start_date_time) <= strtotime($primary_viewing_start_date_time) )
156 {
157 $related_viewings['previous'][] = get_the_ID();
158 }
159 else
160 {
161 $related_viewings['next'][] = get_the_ID();
162 }
163
164 $related_viewings['all'][] = get_the_ID();
165 }
166 }
167 wp_reset_postdata();
168
169 return $related_viewings;
170 }
171
172 public function get_applicant_ids()
173 {
174 $applicant_contact_ids = get_post_meta( $this->id, '_applicant_contact_id' );
175 if ( $applicant_contact_ids == '' )
176 {
177 $applicant_contact_ids = array();
178 }
179 if ( !is_array($applicant_contact_ids) && $applicant_contact_ids != '' && $applicant_contact_ids != 0 )
180 {
181 $applicant_contact_ids = array($applicant_contact_ids);
182 }
183
184 return $applicant_contact_ids;
185 }
186
187 /**
188 * Get the applicants
189 *
190 * @access public
191 * @return string
192 */
193 public function get_applicants( $add_hyperlinks = false, $additional_contact_details = false )
194 {
195 $applicant_contact_ids = get_post_meta($this->id, '_applicant_contact_id');
196 if (!empty($applicant_contact_ids))
197 {
198 $applicant_contacts = array();
199 foreach ($applicant_contact_ids as $applicant_contact_id)
200 {
201 $applicant_name = esc_html( get_the_title($applicant_contact_id) );
202 if ( $add_hyperlinks )
203 {
204 $edit_link = get_edit_post_link( $applicant_contact_id );
205 $applicant_name = '<a href="' . esc_url($edit_link) . '" target="' . esc_attr(apply_filters('propertyhive_subgrid_link_target', '')) . '">' . $applicant_name . '</a>';
206 }
207 if ( $additional_contact_details )
208 {
209 $contact_details = array();
210 $telephone_number = get_post_meta( $applicant_contact_id, '_telephone_number', true );
211 if( !empty($telephone_number) )
212 {
213 $contact_details[] = 'T: ' . esc_html($telephone_number);
214 }
215
216 $email_address = get_post_meta( $applicant_contact_id, '_email_address', true );
217 if( !empty($email_address) )
218 {
219 $contact_details[] = 'E: ' . esc_html($email_address);
220 }
221
222 $contact_details = apply_filters( 'propertyhive_viewing_applicant_contact_details', $contact_details, $applicant_contact_id );
223
224 if ( !empty($contact_details) )
225 {
226 $applicant_name .= '<div class="row-actions visible">' . implode( "<br>", $contact_details ) . '</div>';
227 }
228 }
229 $applicant_contacts[] = $applicant_name;
230 }
231 return implode('<br>', $applicant_contacts);
232 }
233 else
234 {
235 return'-';
236 }
237 }
238
239 /**
240 * Get the attending negotiator(s)
241 *
242 * @access public
243 * @return string
244 */
245 public function get_negotiators()
246 {
247 $negotiator_ids = get_post_meta($this->id, '_negotiator_id');
248 if ( !empty($negotiator_ids) )
249 {
250 $negotiators = array();
251 foreach ($negotiator_ids as $negotiator_id)
252 {
253 $userdata = get_userdata( $negotiator_id );
254 if ( $userdata !== FALSE )
255 {
256 $negotiators[] = $userdata->display_name;
257 }
258 else
259 {
260 $negotiators[] = '<em>' . __( 'Unknown user', 'propertyhive' ) . '</em>';
261 }
262 }
263 return implode(', ', $negotiators);
264 }
265 else
266 {
267 return 'Unattended';
268 }
269 }
270
271 /**
272 * Get the viewing status
273 *
274 * @access public
275 * @return string
276 */
277 public function get_status()
278 {
279 $status = $this->_status;
280 $status_items = array( propertyhive_get_status_label( $status ) );
281
282 if ( $status == 'pending' )
283 {
284 // confirmation status
285 if ( $this->_all_confirmed == 'yes' )
286 {
287 $status_items[] = __( 'All Parties Confirmed', 'propertyhive' );
288 }
289 else
290 {
291 $status_items[] = __( 'Awaiting Confirmation', 'propertyhive' );
292 }
293 }
294
295 if ( $status == 'carried_out' )
296 {
297 $feedback_status = $this->_feedback_status;
298 switch ( $feedback_status )
299 {
300 case "interested": { $status_items[] = __( 'Applicant Interested', 'propertyhive' ); break; }
301 case "not_interested": { $status_items[] = __( 'Applicant Not Interested', 'propertyhive' ); break; }
302 case "not_required": { $status_items[] = __( 'Feedback Not Required', 'propertyhive' ); break; }
303 default: { $status_items[] = __( 'Awaiting Feedback', 'propertyhive' ); }
304 }
305
306 if ( $feedback_status == 'interested' || $feedback_status == 'not_interested' )
307 {
308 $status_items[] = ($this->_feedback_passed_on == 'yes') ? __( 'Feedback Passed On', 'propertyhive' ) : __( 'Feedback Not Passed On', 'propertyhive' );
309 }
310 }
311
312 // Add text if this a second, third etc viewing
313 $related_viewings = get_post_meta( $this->id, '_related_viewings', TRUE );
314 if ( isset($related_viewings['previous']) && count($related_viewings['previous']) > 0 )
315 {
316 $status_items[] = ph_ordinal_suffix(count($related_viewings['previous'])+1) . ' ' . __( 'Viewing', 'propertyhive' );
317 }
318
319 return implode('<br>', array_map( 'esc_html', $status_items ));
320 }
321
322 /**
323 * Get the full address of the property attached to the viewing
324 *
325 * @access public
326 * @return string
327 */
328 public function get_property_address()
329 {
330 $property_id = (int)$this->_property_id;
331
332 if ( !empty($property_id) )
333 {
334 $property = new PH_Property( $property_id );
335 return '<a href="' . esc_url( get_edit_post_link( $property_id, '' ) ) . '" target="' . esc_attr( apply_filters('propertyhive_subgrid_link_target', '') ) . '">' . esc_html( $property->get_formatted_full_address() ) . '</a>';
336 }
337 else
338 {
339 return '-';
340 }
341 }
342 }
343