PluginProbe
Property Hive / 1.4.62
Property Hive v1.4.62
2.3.1 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 All 261 releases
propertyhive / includes / class-ph-install.php

class-ph-install.php in Property Hive 1.4.62, at includes/class-ph-install.php

811 lines 24.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Installation related functions and actions.
4 *
5 * @author PropertyHive
6 * @category Admin
7 * @package PropertyHive/Classes
8 * @version 1.0.0
9 */
10
11 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
12
13 if ( ! class_exists( 'PH_Install' ) ) :
14
15 /**
16 * PH_Install Class
17 */
18 class PH_Install {
19
20 /**
21 * Hook in tabs.
22 */
23 public function __construct() {
24 register_activation_hook( PH_PLUGIN_FILE, array( $this, 'install' ) );
25 register_deactivation_hook( PH_PLUGIN_FILE, array( $this, 'deactivate' ) );
26
27 add_action( 'admin_init', array( $this, 'install_actions' ) );
28 add_action( 'admin_init', array( $this, 'check_version' ), 5 );
29
30 add_filter( 'cron_schedules', array( $this, 'custom_cron_recurrence' ) );
31 //add_action( 'in_plugin_update_message-propertyhive/propertyhive.php', array( $this, 'in_plugin_update_message' ) );
32 }
33
34 /**
35 * check_version function.
36 *
37 * @access public
38 * @return void
39 */
40 public function check_version() {
41 if ( ! defined( 'IFRAME_REQUEST' ) && ( get_option( 'propertyhive_version' ) != PH()->version || get_option( 'propertyhive_db_version' ) != PH()->version ) ) {
42 $this->install();
43
44 do_action( 'propertyhive_updated' );
45 }
46 }
47
48 /**
49 * Install actions such as installing pages when a button is clicked.
50 */
51 public function install_actions() {
52
53
54 }
55
56 /**
57 * Install Property Hive
58 */
59 public function install() {
60
61 $this->create_options();
62 $this->create_tables();
63 $this->create_roles();
64
65 // Register post types
66 include_once( 'class-ph-post-types.php' );
67 PH_Post_types::register_post_types();
68 PH_Post_types::register_taxonomies();
69
70 $this->create_primary_office();
71 $this->create_cron_jobs();
72
73 // Clear transient cache
74
75 // Queue upgrades
76 $current_version = get_option( 'propertyhive_version', null );
77 $current_db_version = get_option( 'propertyhive_db_version', null );
78
79 // No existing version set. This must be a new fresh install
80 if ( is_null( $current_version ) && is_null( $current_db_version ) )
81 {
82 $this->create_terms();
83 set_transient( '_ph_activation_redirect', 1, 30 );
84 }
85
86 update_option( 'propertyhive_db_version', PH()->version );
87
88 // Check if pages are needed
89 if ( ph_get_page_id( 'search_results' ) < 1 ) {
90 update_option( '_ph_needs_pages', 1 );
91 }
92
93 // Update version
94 update_option( 'propertyhive_version', PH()->version );
95
96 // Flush rules after install
97 flush_rewrite_rules();
98 }
99
100 /**
101 * Deactivate Property Hive
102 */
103 public function deactivate() {
104 // Cron jobs
105 wp_clear_scheduled_hook( 'propertyhive_update_currency_exchange_rates' );
106 wp_clear_scheduled_hook( 'propertyhive_process_email_log' );
107 wp_clear_scheduled_hook( 'propertyhive_auto_email_match' );
108 wp_clear_scheduled_hook( 'propertyhive_check_licenses' );
109 }
110
111 /**
112 * Handle updates
113 */
114 public function update() {
115 // Do updates
116 $current_db_version = get_option( 'propertyhive_db_version' );
117
118 /*if ( version_compare( $current_db_version, '1.4', '<' ) ) {
119 include( 'updates/propertyhive-update-1.4.php' );
120 update_option( 'propertyhive_db_version', '1.4' );
121 }
122
123 if ( version_compare( $current_db_version, '2.1.0', '<' ) || PH_VERSION == '2.1-bleeding' ) {
124 include( 'updates/propertyhive-update-2.1.php' );
125 update_option( 'propertyhive_db_version', '2.1.0' );
126 }*/
127
128 update_option( 'propertyhive_db_version', PH()->version );
129 }
130
131 /**
132 * Create cron jobs (clear them first)
133 */
134 private function create_cron_jobs() {
135
136 // Cron jobs
137 wp_clear_scheduled_hook( 'propertyhive_update_currency_exchange_rates' );
138 wp_clear_scheduled_hook( 'propertyhive_process_email_log' );
139 wp_clear_scheduled_hook( 'propertyhive_auto_email_match' );
140 wp_clear_scheduled_hook( 'propertyhive_check_licenses' );
141
142 $ve = get_option( 'gmt_offset' ) > 0 ? '+' : '-';
143
144 // Schedule for midnight as it's likely traffic will be quieter at that time
145 wp_schedule_event( strtotime( '00:00 tomorrow ' . $ve . get_option( 'gmt_offset' ) . ' HOURS' ), 'daily', 'propertyhive_update_currency_exchange_rates' );
146
147 wp_schedule_event( time(), 'every_fifteen_minutes', 'propertyhive_process_email_log' );
148
149 $auto_property_match_enabled = get_option( 'propertyhive_auto_property_match', '' );
150
151 if ( $auto_property_match_enabled == 'yes' )
152 {
153 wp_schedule_event( strtotime( '02:00 tomorrow ' . $ve . get_option( 'gmt_offset' ) . ' HOURS' ), 'daily', 'propertyhive_auto_email_match' );
154 }
155
156 // Schedule for 1am as it's likely traffic will be quieter at that time
157 // 1am so it doesn't run at exactly the same time as the exchange rate cron
158 wp_schedule_event( strtotime( '01:00 tomorrow ' . $ve . get_option( 'gmt_offset' ) . ' HOURS' ), 'daily', 'propertyhive_check_licenses' );
159 }
160
161 public function custom_cron_recurrence( $schedules )
162 {
163 $schedules['every_fifteen_minutes'] = array(
164 'interval' => 900,
165 'display' => __( 'Every 15 Minutes', 'textdomain' )
166 );
167
168 return $schedules;
169 }
170
171 /**
172 * Create pages that the plugin relies on
173 *
174 * @access public
175 * @return void
176 */
177 public static function create_pages() {
178
179 // Create page object
180 $my_post = array(
181 'post_title' => __( 'Property Search', 'propertyhive' ),
182 'post_content' => '',
183 'post_status' => 'publish',
184 'post_type' => 'page',
185 'comment_status' => 'closed',
186 'ping_status' => 'closed',
187 );
188
189 // Insert the post into the database
190 $page_id = wp_insert_post( $my_post );
191
192 update_option( 'propertyhive_search_results_page_id', $page_id );
193 }
194
195 /**
196 * Add the default terms for PH taxonomies - property types, tenures etc. Modify this at your own risk.
197 *
198 * @access public
199 * @return void
200 */
201 private function create_terms() {
202
203 $taxonomies = array(
204 'availability' => array(
205 array(
206 'name' => 'For Sale',
207 'departments' => array('residential-sales', 'commercial')
208 ),
209 array(
210 'name' => 'Under Offer',
211 'departments' => array('residential-sales', 'commercial')
212 ),
213 array(
214 'name' => 'Sold STC',
215 'departments' => array('residential-sales', 'commercial')
216 ),
217 array(
218 'name' => 'Sold',
219 'departments' => array('residential-sales', 'commercial')
220 ),
221 array(
222 'name' => 'To Let',
223 'departments' => array('residential-lettings', 'commercial')
224 ),
225 array(
226 'name' => 'Let Agreed',
227 'departments' => array('residential-lettings', 'commercial')
228 ),
229 array(
230 'name' => 'Let',
231 'departments' => array('residential-lettings', 'commercial')
232 ),
233 ),
234 'property_type' => array(
235 // HOUSE
236 array(
237 'name' => 'House'
238 ),
239 array(
240 'name' => 'Detached House',
241 'child_of_previous' => true
242 ),
243 array(
244 'name' => 'Semi-Detached House',
245 'child_of_previous' => true
246 ),
247 array(
248 'name' => 'Terraced House',
249 'child_of_previous' => true
250 ),
251 array(
252 'name' => 'End of Terrace House',
253 'child_of_previous' => true
254 ),
255 array(
256 'name' => 'Mews',
257 'child_of_previous' => true
258 ),
259 array(
260 'name' => 'Link Detached House',
261 'child_of_previous' => true
262 ),
263 array(
264 'name' => 'Town House',
265 'child_of_previous' => true
266 ),
267 array(
268 'name' => 'Cottage',
269 'child_of_previous' => true
270 ),
271 // BUNGALOW
272 array(
273 'name' => 'Bungalow'
274 ),
275 array(
276 'name' => 'Detached Bungalow',
277 'child_of_previous' => true
278 ),
279 array(
280 'name' => 'Semi-Detached Bungalow',
281 'child_of_previous' => true
282 ),
283 array(
284 'name' => 'Terraced Bungalow',
285 'child_of_previous' => true
286 ),
287 array(
288 'name' => 'End of Terrace House',
289 'child_of_previous' => true
290 ),
291 // FLATS
292 array(
293 'name' => 'Flat / Apartment'
294 ),
295 array(
296 'name' => 'Flat',
297 'child_of_previous' => true
298 ),
299 array(
300 'name' => 'Apartment',
301 'child_of_previous' => true
302 ),
303 array(
304 'name' => 'Maisonette',
305 'child_of_previous' => true
306 ),
307 array(
308 'name' => 'Studio',
309 'child_of_previous' => true
310 ),
311 array(
312 'name' => 'Penthouse',
313 'child_of_previous' => true
314 ),
315 array(
316 'name' => 'Duplex',
317 'child_of_previous' => true
318 ),
319 array(
320 'name' => 'Triplex',
321 'child_of_previous' => true
322 ),
323 // OTHER
324 array(
325 'name' => 'Other'
326 ),
327 array(
328 'name' => 'Commercial',
329 'child_of_previous' => true
330 ),
331 array(
332 'name' => 'Land',
333 'child_of_previous' => true
334 ),
335 array(
336 'name' => 'Garage',
337 'child_of_previous' => true
338 ),
339 ),
340 'commercial_property_type' => array(
341 array(
342 'name' => 'Office'
343 ),
344 array(
345 'name' => 'Industrial'
346 ),
347 array(
348 'name' => 'Retail'
349 ),
350 array(
351 'name' => 'Land'
352 ),
353 array(
354 'name' => 'Health'
355 ),
356 array(
357 'name' => 'Motoring'
358 ),
359 array(
360 'name' => 'Leisure'
361 ),
362 array(
363 'name' => 'Investment'
364 ),
365 ),
366 'outside_space' => array(
367 array(
368 'name' => 'Balcony'
369 ),
370 array(
371 'name' => 'South Facing Garden'
372 ),
373 ),
374 'parking' => array(
375 array(
376 'name' => 'On Road Parking'
377 ),
378 array(
379 'name' => 'Off Road Parking'
380 ),
381 array(
382 'name' => 'Driveway'
383 ),
384 array(
385 'name' => 'Single Garage'
386 ),
387 array(
388 'name' => 'Double Garage'
389 ),
390 array(
391 'name' => 'Triple Garage'
392 ),
393 array(
394 'name' => 'Carport'
395 ),
396 ),
397 'price_qualifier' => array(
398 array(
399 'name' => 'Guide Price'
400 ),
401 array(
402 'name' => 'Fixed Price'
403 ),
404 array(
405 'name' => 'Offers Over'
406 ),
407 array(
408 'name' => 'OIRO'
409 )
410 ),
411 'sale_by' => array(
412 array(
413 'name' => 'Tender'
414 ),
415 array(
416 'name' => 'Private Treaty'
417 ),
418 array(
419 'name' => 'Auction'
420 ),
421 ),
422 'tenure' => array(
423 array(
424 'name' => 'Freehold'
425 ),
426 array(
427 'name' => 'Leasehold'
428 )
429 ),
430 'commercial_tenure' => array(
431 array(
432 'name' => 'Freehold'
433 ),
434 array(
435 'name' => 'Leasehold'
436 )
437 ),
438 'furnished' => array(
439 array(
440 'name' => 'Furnished'
441 ),
442 array(
443 'name' => 'Part Furnished'
444 ),
445 array(
446 'name' => 'Unfurnished'
447 )
448 ),
449 'marketing_flag' => array(
450 array(
451 'name' => 'New Instruction'
452 ),
453 array(
454 'name' => 'Chain Free'
455 )
456 ),
457 );
458
459 $availability_departments = get_option( 'propertyhive_availability_departments', array() );
460 if ( !is_array($availability_departments) ) { $availability_departments = array(); }
461
462 $previous_term_id = '';
463 foreach ( $taxonomies as $taxonomy => $terms )
464 {
465 // Make sure no terms for this taxonomy exist already
466 $existing_terms = get_terms( $taxonomy );
467 if ( is_wp_error( $existing_terms ) || (!is_wp_error( $existing_terms ) && empty( $existing_terms ) ) )
468 {
469 foreach ( $terms as $term )
470 {
471 if ( ! get_term_by( 'slug', sanitize_title( $term['name'] ), $taxonomy ) )
472 {
473 $args = array();
474 if ( isset($term['child_of_previous']) && $term['child_of_previous'] === true )
475 {
476 $args = array('parent' => $previous_term_id);
477 }
478 $return = wp_insert_term( $term['name'], $taxonomy, $args );
479 if ( !is_wp_error($return) )
480 {
481 if ( !isset($term['child_of_previous']) || (isset($term['child_of_previous']) && !$term['child_of_previous']) )
482 {
483 $previous_term_id = $return['term_id'];
484 }
485
486 if ( $taxonomy == 'availability' && is_array($term['departments']) && !empty($term['departments']) )
487 {
488 $availability_departments[$return['term_id']] = $term['departments'];
489 }
490 }
491 else
492 {
493 // Hmm... an error occurred
494 // $error_string = $result->get_error_message(); // do something with this?
495 }
496 }
497 }
498 }
499 }
500
501 update_option( 'propertyhive_availability_departments', $availability_departments );
502 }
503
504 /**
505 * Add the first office so at least one exists
506 *
507 * @access public
508 * @return void
509 */
510 function create_primary_office() {
511
512 $args = array(
513 'post_type' => 'office'
514 );
515 $office_query = new WP_Query($args);
516 if (!$office_query->have_posts())
517 {
518 // Insert office
519 $office_post = array(
520 'post_title' => 'My Office',
521 'post_content' => '',
522 'post_status' => 'publish',
523 'post_type' => 'office',
524 );
525
526 // Insert the post into the database
527 $office_post_id = wp_insert_post( $office_post );
528
529 update_post_meta($office_post_id, 'primary', '1');
530 }
531 }
532
533 /**
534 * Default options
535 *
536 * Sets up the default options used on the settings page
537 *
538 * @access public
539 */
540 function create_options() {
541
542 add_option( 'propertyhive_active_departments_sales', 'yes', '', 'yes' );
543 add_option( 'propertyhive_active_departments_lettings', 'yes', '', 'yes' );
544 add_option( 'propertyhive_primary_department', 'residential-sales', '', 'yes' );
545
546 add_option( 'propertyhive_default_country', 'GB', '', 'yes' );
547 add_option( 'propertyhive_countries', array('GB'), '', 'yes' );
548
549 add_option( 'propertyhive_applicant_match_price_range_percentage_lower', 20, '', 'no' );
550 add_option( 'propertyhive_applicant_match_price_range_percentage_higher', 5, '', 'no' );
551
552 add_option( 'propertyhive_install_timestamp', time(), '', 'no' );
553 add_option( 'propertyhive_review_prompt_due_timestamp', strtotime('+30 days'), '', 'no' );
554
555 add_option( 'propertyhive_enquiry_auto_responder_email_subject', __( 'Thank you for your enquiry', 'propertyhive' ), '', 'no' );
556 add_option( 'propertyhive_enquiry_auto_responder_email_body', __( "Thank you for your recent property enquiry about [property_address_hyperlinked]. A member of our team will be in touch shortly.
557
558 Kind regards,
559
560 " . get_bloginfo('name') . "
561
562 [similar_properties]", 'propertyhive' ), '', 'no' );
563
564 add_option( 'propertyhive_property_match_default_email_subject', __( 'We found [property_count] that might be of interest to you', 'propertyhive' ), '', 'no' );
565 add_option( 'propertyhive_property_match_default_email_body', __( "Hi [contact_name],
566
567 Based on your requirements, we've found [property_count] below that we believe might be suitable for you:
568
569 [properties]
570
571 If you have any questions or require more information about any of the properties shown above please let me know.
572
573 Kind regards,
574
575 " . get_bloginfo('name'), 'propertyhive' ), '', 'no' );
576
577 add_option( 'propertyhive_viewing_applicant_booking_confirmation_email_subject', 'Your Viewing On [property_address]', '', 'no' );
578 add_option( 'propertyhive_viewing_applicant_booking_confirmation_email_body', "Dear [applicant_name],
579
580 This is confirmation that your viewing on [property_address] has been booked for [viewing_time] on [viewing_date].
581
582 Should you need to cancel or amend your booking please do not hesitate to contact us.
583
584 " . get_bloginfo('name'), '', 'no' );
585
586 add_option( 'propertyhive_viewing_owner_booking_confirmation_email_subject', 'Viewing Booked On [property_address]', '', 'no' );
587 add_option( 'propertyhive_viewing_owner_booking_confirmation_email_body', "Dear [owner_name],
588
589 This is confirmation that a viewing has been booked at your property, [property_address], for [viewing_time] on [viewing_date].
590
591 Should you need to cancel or amend this viewing please do not hesitate to contact us.
592
593 " . get_bloginfo('name'), '', 'no' );
594
595 }
596
597 /**
598 * Set up the database tables which the plugin needs to function.
599 *
600 * Tables:
601 * ph_email_log - Queueing table for emails
602 *
603 * @access public
604 * @return void
605 */
606 private function create_tables() {
607 global $wpdb, $propertyhive;
608
609 $wpdb->hide_errors();
610
611 $collate = '';
612
613 if ( $wpdb->has_cap( 'collation' ) ) {
614 $collate = $wpdb->get_charset_collate();
615 }
616
617 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
618
619 $tables = "
620 CREATE TABLE {$wpdb->prefix}ph_email_log (
621 email_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
622 contact_id bigint(20) unsigned NOT NULL,
623 property_ids text NOT NULL,
624 applicant_profile_id tinyint(3) unsigned NOT NULL,
625 to_email_address varchar(255) NOT NULL,
626 from_name varchar(255) NOT NULL,
627 from_email_address varchar(255) NOT NULL,
628 subject varchar(255) NOT NULL,
629 body longtext NOT NULL,
630 lock_id varchar(23) NOT NULL,
631 locked_at datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
632 status varchar(5) NOT NULL,
633 send_at datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
634 sent_by bigint(20) unsigned NOT NULL,
635 PRIMARY KEY (email_id)
636 ) $collate;";
637
638 dbDelta( $tables );
639 }
640
641 /**
642 * Create roles and capabilities
643 */
644 public function create_roles() {
645 global $wp_roles;
646
647 if ( ! class_exists( 'WP_Roles' ) ) {
648 return;
649 }
650
651 if ( ! isset( $wp_roles ) ) {
652 $wp_roles = new WP_Roles();
653 }
654
655 // Property Hive Contact role
656 add_role( 'property_hive_contact', __( 'Property Hive Contact', 'propertyhive' ), array(
657 'read' => true,
658 ) );
659
660 if ( is_object( $wp_roles ) ) {
661
662 $capabilities = $this->get_core_capabilities();
663
664 foreach ( $capabilities as $cap_group ) {
665 foreach ( $cap_group as $cap ) {
666 $wp_roles->add_cap( 'administrator', $cap );
667 $wp_roles->add_cap( 'editor', $cap );
668 }
669 }
670 }
671 }
672
673 /**
674 * Get capabilities for PropertyHive - these are assigned to admin/shop manager during installation or reset
675 *
676 * @access public
677 * @return array
678 */
679 public function get_core_capabilities() {
680 $capabilities = array();
681
682 $capabilities['core'] = array(
683 'manage_propertyhive'/*,
684 'view_propertyhive_reports'*/
685 );
686
687 return $capabilities;
688 }
689
690 /**
691 * propertyhive_remove_roles function.
692 *
693 * @access public
694 * @return void
695 */
696 public function remove_roles() {
697 /*global $wp_roles;
698
699 if ( class_exists( 'WP_Roles' ) ) {
700 if ( ! isset( $wp_roles ) ) {
701 $wp_roles = new WP_Roles();
702 }
703 }*/
704 }
705
706 /**
707 * Create files/directories
708 */
709 private function create_files() {
710 // Install files and folders for uploading files and prevent hotlinking
711 $upload_dir = wp_upload_dir();
712
713 /*$files = array(
714 array(
715 'base' => $upload_dir['basedir'] . '/propertyhive_uploads',
716 'file' => '.htaccess',
717 'content' => 'deny from all'
718 ),
719 array(
720 'base' => $upload_dir['basedir'] . '/propertyhive_uploads',
721 'file' => 'index.html',
722 'content' => ''
723 ),
724 array(
725 'base' => WP_PLUGIN_DIR . "/" . plugin_basename( dirname( dirname( __FILE__ ) ) ) . '/logs',
726 'file' => '.htaccess',
727 'content' => 'deny from all'
728 ),
729 array(
730 'base' => WP_PLUGIN_DIR . "/" . plugin_basename( dirname( dirname( __FILE__ ) ) ) . '/logs',
731 'file' => 'index.html',
732 'content' => ''
733 )
734 );
735
736 foreach ( $files as $file ) {
737 if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
738 if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
739 fwrite( $file_handle, $file['content'] );
740 fclose( $file_handle );
741 }
742 }
743 }*/
744 }
745
746 /**
747 * Active plugins pre update option filter
748 *
749 * @param string $new_value
750 * @return string
751 */
752 function pre_update_option_active_plugins( $new_value ) {
753 /*$old_value = (array) get_option( 'active_plugins' );
754
755 if ( $new_value !== $old_value && in_array( W3TC_FILE, (array) $new_value ) && in_array( W3TC_FILE, (array) $old_value ) ) {
756 $this->_config->set( 'notes.plugins_updated', true );
757 try {
758 $this->_config->save();
759 } catch( Exception $ex ) {}
760 }
761
762 return $new_value;*/
763 }
764
765 /**
766 * Show plugin changes. Code adapted from W3 Total Cache.
767 *
768 * @return void
769 */
770 function in_plugin_update_message( $args ) {
771 /*$transient_name = 'ph_upgrade_notice_' . $args['Version'];
772
773 if ( false === ( $upgrade_notice = get_transient( $transient_name ) ) ) {
774
775 $response = wp_remote_get( 'https://plugins.svn.wordpress.org/propertyhive/trunk/readme.txt' );
776
777 if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
778
779 // Output Upgrade Notice
780 $matches = null;
781 $regexp = '~==\s*Upgrade Notice\s*==\s*=\s*(.*)\s*=(.*)(=\s*' . preg_quote( PH_VERSION ) . '\s*=|$)~Uis';
782 $upgrade_notice = '';
783
784 if ( preg_match( $regexp, $response['body'], $matches ) ) {
785 $version = trim( $matches[1] );
786 $notices = (array) preg_split('~[\r\n]+~', trim( $matches[2] ) );
787
788 if ( version_compare( PH_VERSION, $version, '<' ) ) {
789
790 $upgrade_notice .= '<div class="ph_plugin_upgrade_notice">';
791
792 foreach ( $notices as $index => $line ) {
793 $upgrade_notice .= wp_kses_post( preg_replace( '~\[([^\]]*)\]\(([^\)]*)\)~', '<a href="${2}">${1}</a>', $line ) );
794 }
795
796 $upgrade_notice .= '</div> ';
797 }
798 }
799
800 set_transient( $transient_name, $upgrade_notice, DAY_IN_SECONDS );
801 }
802 }
803
804 echo wp_kses_post( $upgrade_notice );*/
805 }
806 }
807
808 endif;
809
810 return new PH_Install();
811