Last active
April 11, 2025 20:03
-
-
Save yuriinalivaiko/159e70319723247b7e80c0e7ca2cfdbc to your computer and use it in GitHub Desktop.
Ticket 97389: Integration of Google Maps API for Custom Radius-Based Notification System
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Add custom email notifications. | |
add_filter( 'um_email_notifications', 'onemec_email_notifications', 10, 1 ); | |
// Call action when a new Job is published. | |
add_action( 'jb_job_published', 'onemec_job_submitted', 10, 2 ); | |
/** | |
* Extend Ultimate Member email notifications. | |
* | |
* @link https://docs.ultimatemember.com/article/1515-how-to-add-and-use-custom-email-templates | |
* | |
* @param array $emails Email notifications. | |
* @return array | |
*/ | |
function onemec_email_notifications( $emails ) { | |
// New email templates. | |
$custom_emails = array( | |
array( | |
'key' => 'new_service', | |
'title' => __( 'New service', 'ultimate-member' ), | |
'description' => __( 'Send a notification to user when a new service in the specified radius is posted', 'ultimate-member' ), | |
'recipient' => 'user', | |
'default_active' => true, | |
'subject' => 'New service on {site_name}', | |
'body' => 'New service has been added on {site_name}<br /><br />' | |
. 'To view a job click here: {view_job_url}<br /><br />' | |
. 'To view your profile click here: {user_profile_link}<br /><br />' | |
. 'Thank You!<br />' | |
. '{site_name}', | |
), | |
); | |
foreach ( $custom_emails as $email ) { | |
// Default settings. | |
$email_option_on = UM()->options()->get( $email['key'] . '_on' ); | |
$email_option_sub = UM()->options()->get( $email['key'] . '_sub' ); | |
if ( '' === $email_option_on ) { | |
$email_on = empty( $email['default_active'] ) ? 0 : 1; | |
UM()->options()->update( $email['key'] . '_on', $email_on ); | |
} | |
if ( '' === $email_option_sub ) { | |
$email_sub = empty( $email['subject'] ) ? $email['key'] : $email['subject']; | |
UM()->options()->update( $email['key'] . '_sub', $email_sub ); | |
} | |
// Template file. | |
$template = locate_template( | |
array( | |
'ultimate-member/email/' . trailingslashit( get_current_blog_id() ) . $email['key'] . '.php', | |
'ultimate-member/email/' . $email['key'] . '.php', | |
) | |
); | |
if ( ! $template ) { | |
$template = wp_normalize_path( STYLESHEETPATH . '/ultimate-member/email/' . $email['key'] . '.php' ); | |
} | |
if ( ! file_exists( $template ) ) { | |
wp_mkdir_p( dirname( $template ) ); | |
file_put_contents( $template, $email['body'] ); | |
} | |
$emails[ $email['key'] ] = $email; | |
} | |
return $emails; | |
} | |
/** | |
* Send the "New service" email when a new Job is published. | |
* | |
* @link https://ultimatemember.github.io/jobboardwp/hooks/jb_job_published.html | |
* | |
* @param int $job_id Job post ID. | |
* @param WP_Post $job Job post object. | |
* @return void | |
*/ | |
function onemec_job_submitted( $job_id, $job ) { | |
$lat = get_post_meta( $job_id, 'jb-location-lat', true ); | |
$lng = get_post_meta( $job_id, 'jb-location-long', true ); | |
if ( $lat && $lng ) { | |
// Set your location and service radius fields here. | |
$meta_location = 'local_oficina'; | |
$meta_radius = 'service_radius_km'; | |
$users = onemec_search_users( $lat, $lng, $meta_location, $meta_radius ); | |
foreach( $users as $user_id ) { | |
um_fetch_user( $user_id ); | |
$email = um_user( 'user_email' ); | |
$args = array( | |
'tags' => array( | |
'{view_job_url}' | |
), | |
'tags_replace' => array( | |
get_permalink( $job_id ) | |
), | |
); | |
UM()->mail()->send( $email, 'new_service', $args ); | |
} | |
} | |
} | |
/** | |
* Search users to send the "New service" email. | |
* | |
* @link https://en.wikipedia.org/wiki/Great-circle_distance#Formulae | |
* | |
* @global wpdb $wpdb WordPress database access abstraction class. | |
* | |
* @param float $lat Job latitude. | |
* @param float $lng Job longitude. | |
* @param string $meta_location User location field meta key. | |
* @param string $meta_radius User service radius field meta key. | |
* @param string $unit Units to measure a distance: 'km' or 'mile'. | |
* @return array User IDs. | |
*/ | |
function onemec_search_users( $lat, $lng, $meta_location, $meta_radius, $unit = 'km' ) { | |
global $wpdb; | |
$sql = $wpdb->prepare( | |
"SELECT `um_rad`.`user_id` " | |
. "FROM ( SELECT * FROM %i WHERE `meta_key`=%s ) AS `um_rad` " | |
. "INNER JOIN %i AS `um_lat` ON ( `um_rad`.`user_id`=`um_lat`.`user_id` AND `um_lat`.`meta_key`=%s ) " | |
. "INNER JOIN %i AS `um_lng` ON ( `um_rad`.`user_id`=`um_lng`.`user_id` AND `um_lng`.`meta_key`=%s ) " | |
. "WHERE ( %d * ACOS( COS( RADIANS( `um_lat`.`meta_value` ) ) * COS( RADIANS( %f ) ) * COS( RADIANS( %f ) - RADIANS( `um_lng`.`meta_value` ) ) + SIN( RADIANS( `um_lat`.`meta_value` ) ) * SIN( RADIANS( %f ) ) ) ) < `um_rad`.`meta_value`", | |
$wpdb->usermeta, | |
$meta_radius, | |
$wpdb->usermeta, | |
$meta_location . '_lat', | |
$wpdb->usermeta, | |
$meta_location . '_lng', | |
absint( 'km' === $unit ? 6371 : 3959 ), | |
(float) $lat, | |
(float) $lng, | |
(float) $lat | |
); | |
$users = $wpdb->get_col( $sql ); | |
return $users; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment