Hooks and filters

EME provides a number of hooks and filters so you can customize a number of things to your liking. For a howto in general about hooks and filters, see here for actions and here for filters.

Hooks

As an example, if you would want to hook into eme_insert_rsvp_action, you would add something like this to your theme’s functions.php:


add_action('eme_insert_rsvp_action','do_my_stuff');
function do_my_stuff($booking) {
 ....
}

If the action hook or filter needs more than 1 variable, you need to specify the number of arguments (it is in the explanation) and the priority. Example (10 is the default priority, and the hook eme_insert_recurrence_action needs 2 arguments):


add_action('eme_insert_recurrence_action','do_my_stuff',10,2);
function do_my_stuff($event,$recurrence) {
 ....
}

The following hooks are available:

  • eme_insert_event_action (1 parameter: $event)
    An example for how to use this to send mail to all users for new events:

    
    add_action('eme_insert_event_action','eme_mail_event');
    function eme_mail_event ($event) {
       $contact = eme_get_event_contact ($event);
       $contact_email = $contact->user_email;
       $contact_name = $contact->display_name;
       $subject_format="This is the new event called ' #_EVENTNAME '";
       $body_format="This is the new event called ' #_EVENTNAME '";
    
       $subject=eme_replace_placeholders($subject_format, $event, "text");
       $body=eme_replace_placeholders($body_format, $event, "text");
       $blogusers = get_users();
       foreach ( $blogusers as $user ) {
          eme_send_mail($subject,$body, $user->user_email, $user->display_name, $contact_email, $contact_name);
       }
    }
    

    Or to send it to the EME group with ID 5:

    
    add_action('eme_insert_event_action','eme_mail_event');
    function eme_mail_event ($event) {
       $contact = eme_get_event_contact ($event);
       $contact_email = $contact->user_email;
       $contact_name = $contact->display_name;
       $subject_format="This is the new event called ' #_EVENTNAME '";
       $body_format="This is the new event called ' #_EVENTNAME '";
    
       $subject=eme_replace_placeholders($subject_format, $event, "text");
       $body=eme_replace_placeholders($body_format, $event, "text");
       $person_ids=eme_get_groups_person_ids(5);
       foreach ( $person_ids as $person_id ) {
          $person=eme_get_person($person_id);
          $person_name=eme_format_recipient_name($person['firstname'],$person['lastname']);
          eme_send_mail($subject,$body, $person['email'], $person_name, $contact_email, $contact_name);
       }
    }
    
  • eme_update_event_action (1 parameter: $event)
  • eme_delete_event_action (1 parameter: $event)
  • eme_insert_recurrence_action (2 parameters: $event,$recurrence)
  • eme_update_recurrence_action (2 parameters: $event,$recurrence)
  • eme_delete_recurrence_action (2 parameters: $event,$recurrence)
  • eme_insert_rsvp_action (1 parameter: $booking), executed after inserting rsvp info into the db.
    An example for how to use this to implement discounts (but please do use eme_discount_* filters to better implement discounts):

    
    add_action('eme_insert_rsvp_action', 'my_eme_discount_function',20,1);
    function my_eme_discount_function($booking) {
       global $wpdb;
       $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
       $where = array();
       $fields = array();
    
       $booking_id = $booking['booking_id'];
       $event_id = $booking['event_id'];
    
       if ($event_id == 5) {        /* put in the event_id that needs processing, or leave out this line to process all events */
          //echo 'EVENT ID='.$event_id .' Booking_id = '.$booking['booking_id'];
    
          $seats=$booking['booking_seats'];
    
          // more than 2 seats, then the discount is 5 per seat
          if ($seats> 1)
              $discount = 5*$seats;
    
            // below a small example to check own input
    	//$coupon = "";
            //$answers = eme_get_booking_post_answers($booking);
            //foreach ($answers as $answer) {
            //    if ($answer['field_name'] == "MY_FIELD_NAME") {
            //       $coupon = $answer['answer'];
            //    }
            //}
            // now check $coupon for your wanted value
    
          $fields['discount'] = $discount;
          $where['booking_id'] = $booking['booking_id'];
          $wpdb->update($bookings_table, $fields, $where);
       }
       return;
    }
    

    For multiseat events (and possibly multiprice), the discount code is similar:

    
    add_action('eme_insert_rsvp_action', 'my_eme_discount_function',20,1);
    function my_eme_discount_function($booking) {
       global $wpdb;
       $bookings_table = $wpdb->prefix.BOOKINGS_TBNAME;
       $where = array();
       $fields = array();
    
       $booking_id = $booking['booking_id'];
       $event_id = $booking['event_id'];
    
       if ($event_id == 5 && eme_is_event_multiseats($event_id)) {
          /* put in the event_id that needs processing, or leave out this line to process all events */
          $seats=eme_convert_multi2array($booking['booking_seats']); // $seats is now an array for the different seat categories defined
    
          // example: more than 2 seats in the first category and 3 seats in the second, then the discount is 2 per seat in the first
          // and 3 in the second, or in the case all prices are the same for the different seat categories, set the discount to 5 per seat
          if ($seats[0]> 2 && $seats[1]> 3) {
              if (eme_is_multi($booking['booking_price'])) {
                 $discount = 2*$seats[0];
                 $discount += 3*$seats[1];
              } else {
                 $discount = 5*eme_get_total($seats);
              }
          }
    
          $fields['discount'] = $discount;
          $where['booking_id'] = $booking['booking_id'];
          $wpdb->update($bookings_table, $fields, $where);
       }
       return;
    }
    
  • eme_update_rsvp_action (1 parameter: $booking), executed after updating booking info
  • eme_ipn_action (1 parameter: $booking), executed after a successfull IPN arrived from one of the payment gateways
  • eme_insert_member_action (1 parameter: $member), executed after a member signed up. In the defined function, you can also call eme_get_member_answers_all($member[‘memberid’])

Hints:
– get the event from the booking id by using this: $event = eme_get_event_by_booking_id($booking['booking_id']);
– get the answer for a member by calling: $member_answers = eme_get_member_answers_all($member['memberid']);
– get the person from the booking by using $person = eme_get_person($booking['person_id']);
– get the member matching the current logged in user and membership id by calling: $person = eme_get_members_by_wpid_membershipid($wp_id, $membership_id);
– get the member based on the current booking: $member=eme_get_member_by_personid_membershipid($booking['person_id'],$membership_id);

Filters

Example usage


add_filter('eme_event_filter','do_my_stuff');
function do_my_stuff($event) {
 ....
}

If the filter needs more than 1 variable, you need to specify the number of arguments (it is in the explanation) and the priority. Example (10 is the default priority, and the hook eme_insert_recurrence_action needs 2 arguments):


add_filter('eme_eval_booking_form_filter','do_my_stuff',10,2);
function do_my_stuff($event,$booker) {
 ....
}

The following filters are available:

  • eme_event_filter (1 parameter: $event (array), return value should be modified array)
  • eme_event_list_filter (1 parameter: $events (array of events), return value should be modified array)
  • eme_location_filter (1 parameter: $location (array), return value should be modified array)
  • eme_location_list_filter (1 parameter: $locations (array of locations), return value should be modified array)
  • eme_directions_form_filter (1 parameter: generated html for the directions form, return value should be modified html)
  • eme_add_booking_form_filter and eme_cancel_booking_form_filter (1 parameter: generated html for the add or delete booking form, return value should be modified html)
  • eme_email_obfuscate_filter (1 parameter: email address or phone). If defined, the standard ascii obfuscating won’t take place and you can use your own filters, eg. from an obfuscating plugin, if you define it in functions.php:
    add_filter( ’eme_email_obfuscate_filter’, ‘c2c_obfuscate_email’ );
    This filter is used to alter the obfuscation for email address and phone in mails sent.
  • eme_eval_booking_form_post_filter and eme_eval_multibooking_form_post_filter, which happen just after the POST of the booking form (1 arg: $event for eme_eval_booking_form_post_filter, or $events for eme_eval_multibooking_form_post_filter; containing the event(s) details that are being booked for).
    The return should be an array, with the first element of that array indicating that your evaluation is successful or not (1 or 0) and the second parameter a string indicating the reason if not successfull. Returning the array happens like this for success:
    array(0=>1,1=>'');
    or for failure:
    array(0=>0,1=>'The eval failed because of ....');
    To simplify some more, a simple “return” or end-of-function is also considered as “success”
    For example, put the following in your theme functions.php to prevent double name/email combo’s to register twice (EME can check for this, but only if you require WP membership, otherwise it’s just too easy to change a letter in the name):

    
    add_filter('eme_eval_booking_form_post_filter','do_my_stuff');
    function do_my_stuff($event) {
        $event_id=$event['event_id'];
        $already_registered=0;
    
        // only do a specific event
        if ($event_id != 5) return;
    
        // get all attendees
        $attendees = eme_get_attendees_for($event_id);
        $booker = eme_get_person_by_post();
        if (!empty($booker)) {
           foreach ($attendees as $attendee) {
              if ($attendee['person_id']==$booker['person_id'])
                 $already_registered=1;
           }
        }
    
        if (!$already_registered) {
           // eval is success
           return array(0=>1,1=>'');
           // or just use return, is ok too
           // return;
        } else {
           // bad form entry
           return array(0=>0,1=>'Already registered');
        }
    }
    

    An example for multibooking, to check that at least 1 seat is booked in total:

    
    add_filter('eme_eval_multibooking_form_post_filter','do_my_stuff');
    function do_my_stuff($events) {
        // it is recommended to add a hidden field in your form, and we check on that
        if (!isset($_POST['my_hidden_field'])) return;
    
        // as an example, let's just count the number of seats booked in total, to be sure
        $total_booked=0;
        foreach ($_POST['bookings'] as $key=>$val) {
            // format posted: $_POST['bookings'][$event_id]['bookedSeats']
            $total_booked+=$_POST['bookings'][$key]['bookedSeats'];
        }
    
        // do something for all events being registered for
        // foreach ($events as $event) {
        // .... (see the example for eme_eval_booking_post_filter)
        // }
        if ($total_booked>0) {
           // eval is success
           return array(0=>1,1=>'');
        } else {
           // bad form entry
           return array(0=>0,1=>'Not enough seats registered');
        }
    }
    
  • eme_eval_booking_form_filter (2 parameters: $event, $booker). If defined, this function can do extra evaluations on the booking being done before it is recorded. You can use the $event, $booker and $_POST info for your evaluations. For the expected return code: see the filter eme_eval_booking_form_post_filter. The filter eme_eval_booking_form_filter differs from eme_eval_booking_form_post_filter in this sense that this filter happens after the booker (not the booking itself) has been created already (which is a bit stupid), while eme_eval_booking_form_post_filter happens immediately after the POST. The usage of this filter (eme_eval_booking_form_filter) is discouraged.
  • eme_event_preinsert_filter (1 parameter: $event), taking place just before the event is inserted in the DB. The return should be the modified $event array.
  • eme_event_preupdate_filter (1 parameter: $event), taking place just before the event is updated in the DB. The return should be the modified $event array.
  • eme_add_currencies (1 parameter: array of currencies), so you can add extra currencies to the list. Be aware that not all payment portals support all currencies.
    Example: to add Ghanaian Cedi (GHS) to the list of currencies, add the following to your theme’s functions.php:

    
      function my_eme_add_currencies($currencies){
          $currencies['GHS'] = 'Ghanaian Cedi';
          return $currencies;
      }
      add_filter('eme_add_currencies','my_eme_add_currencies');
  • eme_add_zero_decimal_currencies (1 parameter: array of currencies), to add your own definition of a currency to the list of currencies that don’t allow decimals.
    Example: to add the code for Ghanaian Cedi (GHS) to the list of currencies, add the following to your theme’s functions.php:

    
      function my_eme_add_zero_decimal_currencies($currencies){
          $currencies[] = 'GHS';
          return $currencies;
      }
      add_filter('eme_add_zero_decimal_currencies','my_eme_add_zero_decimal_currencies');
  • eme_add_currency_codes (1 parameter: array of currencies), so you can add extra currency codes to the list according to the ISO 417 standard (see https://en.wikipedia.org/wiki/ISO_4217 ). If you add currencies using the filter eme_add_currencies, you should also add the new currency code using this filter. Currently these codes are only used for FirstData payments.
    Example: to add the code for Ghanaian Cedi (GHS) to the list of currencies, add the following to your theme’s functions.php:

    
      function my_eme_add_currency_codes($currencies){
          $currencies['GHS'] = '936';
          return $currencies;
      }
      add_filter('eme_add_currency_codes','my_eme_add_currency_codes');
  • eme_categories_filter (1 parameter: array of categories) executed when searching for the categories (e.g. when creating an event). With this, you can e.g. limit the categories shown when creating an event or location or … .
  • eme_rsvp_email_body_text_filter and eme_rsvp_email_body_html_filter (1 parameter: mail body being sent), taking place just before a mail is being sent (all mails: pending, success, cancelled, to contact person or booker, …). The return should be the modified mail body. If the returned body is empty, no mail will be sent.
  • email filters eme_rsvp_email_text_xxx_filter and eme_rsvp_email_html_xxx_filter with “xxx” being one of:
    confirmed_body,updated_body,pending_body,denied_body,cancelled_body
    confirmed_subject,updated_subject,pending_subject,denied_subject,cancelled_subject
    contact_body,contact_cancelled_body,contact_pending_body
    contact_subject,contact_cancelled_subject,contact_pending_subject
    These filters also take 1 parameter (the mail body being sent), but allows finer control than eme_rsvp_email_body_text_filter and eme_rsvp_email_body_html_filter, since you can choose which type of mail to filter. Also: if the returned body is empty, no mail will be sent.
  • eme_events_format_prefilter (2 parameters: $format,$event): an initial filter for the events format, in case people want to change anything before the placeholders get replaced by EME.
  • eme_cal_format_prefilter (3 parameters: $format,$event,$calday): an initial filter for the calendar format, in case people want to change anything before the placeholders get replaced by EME.
  • eme_extra_event_headers_filter (2 parameters: $current_headers, $event): allows to change the headers of an event via extra code if needed ($current_headers and $event are both arrays).
  • eme_extra_event_headers_json_filter (2 parameters: $current_headers, $event): allows to change the google-related json+ld headers of an event via extra code if needed ($current_headers and $event are both arrays).
  • eme_csv_header_filter and me_csv_footer_filter (1 parameter: $event): used to add a first or last line to the CSV output, in case you want to add event info to the csv output
    
    function my_eme_csv_header($event) {
        $my_line=array();
        $my_line[]=$event['event_id'];
        $my_line[]=$event['event_name'];
        return $my_line;
    }
    add_filter('eme_csv_header_filter','my_eme_csv_header');
    
  • eme_csv_column_filter: takes 3 arguments: one line of the csv output of the bookings, the event, and the line number in the csv output (the filter is applied for each line of the csv output). This allows you to play with the rendered CSV output. Example:
    
    function my_eme_csv_column_filter($line,$event,$line_nbr) {
       // you can use $event to change the filtering based on the event id or category or whatever
       // you can use $line_nbr to change something on a specific line
       // example where we just switch columns 1 and 2 (index starts at 0)
       $out_line=$line;
       $out_line[1]=$line[2];
       $out_line[2]=$line[1];
       // we don't want column 5
       unset($out_line[5]);
       return $out_line;
    }
    add_filter('eme_csv_column_filter','my_eme_csv_column_filter',10,3);
    
  • discount filters: for discounts of type ‘code’ you can create a filter like ’eme_discount_xxx’ with ‘xxx’ being the name of the discount, see the chapter on discounts for this
  • eme_cal_full_yearmonth and eme_cal_small_yearmonth: used to change the header shown in the full/small calendar. Has 3 parameters: current string shown, selected month, selected year
  • eme_calday_url_class_filter: can be used to class for calendar day-urls (e.g. for setting “noindex” or so, searchbots don’t execute js so the class needs to be added via code). Has 1 parameter: the current class
  • eme_event_categories_sep_filter, eme_event_categorydescriptions_sep_filter, eme_linked_event_categories_sep_filter (1 parameter: the current separator): these control the separator for #_EVENTCATEGORIES (default: “, “), #_EVENTCATEGORYDESCRIPTIONS (default: “, “) and #_LINKEDEVENTCATEGORIES (default: “, “)
  • Payment description filters for RSVP and member signup: eme_rsvp_paymentform_description_filter and eme_member_paymentform_description_filter. These filters take 3 arguments: the current payment description, the payment and the gateway name. Example to modify:
    
    function my_eme_member_payment_descr($description,$payment,$gateway_name) {
        // $gateway_name is e.g. 'mollie', so you can change the description based on the gateway used if desired
        $member = eme_get_member($payment['member_id']);
        $membership = eme_get_membership($member['membership_id']);
        $person = eme_get_person($member['person_id']);
        $description = .... // change this
        return $description;
    }
    add_filter('eme_member_paymentform_description_filter','my_eme_member_payment_descr',10,3);
    function my_eme_rsvp_payment_descr($description,$payment,$gateway_name) {
        // $gateway_name is e.g. 'mollie', so you can change the description based on the gateway used if desired
        $booking_ids = eme_get_payment_booking_ids($payment['id']);
        $booking = eme_get_booking($booking_ids[0]);
        $event = eme_get_event($booking['event_id']);
        $person = eme_get_person($booking['person_id']);
        $description = .... // change this
        return $description;
    }
    add_filter('eme_rsvp_paymentform_description_filter','my_eme_rsvp_payment_descr',10,3);
    

    Based on the example above, you now have $person (which is an array containing the personal info), $event, etc … so if you want to change anything to the description: you can use anything to your liking now.

  • eme_field_value_filter and eme_admin_field_value_filter. These take 3 arguments: the formfield ($formfield, array), the form POST fieldname (a string) and the current value (a string). Using these filters (eme_admin_field_value_filter is applied only in the admin backend, eme_field_value_filter only in the frontend), you can change the value of certain form fields by looking up other info from other tables/posts and based on the formfield, the userid, …
    Example:

    
    function my_formfield_filter($formfield,$postfield_name,$value) {
        // do a print_r of $formfield, etc ... to see the content. Check the wordpress userid with wp_get_current_user() and do all magic you want :-)
        // as an example, let's change the value of a field if it is called 'testfield')
        if ($formfield['field_name']=='testfield') {
           return "EEE";
        } else {
           return $value;
        }
    }
    add_filter('eme_field_value_filter','my_formfield_filter',10,3);
    
  • eme_ical_filter. Takes one argument: the current ical-representation of a single event in a list of ical entries generated by the eme ical feed (generated with ICAL). This lets you influence each line of an ical entry in the ical feed of events, so you can add/remove/change lines per entry.
    Example where we add and remove a specific line (read the comments in the example):

    
    function my_ical_filter($ical_entry) {
        // do a print_r of $ical_entry to see the content
        // as an example, let's add a line "CLASS:PUBLIC"
        $ical_entry .= eme_esc_ical("CLASS:PUBLIC");
        // other example: remove lines that contains "ORGANIZER"
        $ical_entry = preg_replace('/ORGANIZER.*\r\n/','',$ical_entry);
        return $ical_entry; 
    }
    add_filter('eme_ical_filter','my_ical_filter');
    
  • eme_excerpt_length. Takes one argument: the excerpt length. Default length is 55 characters