Skip to content

Instantly share code, notes, and snippets.

@yuriinalivaiko
Last active April 11, 2025 20:03
Show Gist options
  • Save yuriinalivaiko/159e70319723247b7e80c0e7ca2cfdbc to your computer and use it in GitHub Desktop.
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
<?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