/** * The new and improved schedule by location shortcode. * * We wanted a better code base that is more maintainable and performant that also supports our new location architecture. * To use, pass in the location_id attribute in the shortcode with the locations ID along with what faire you want applications from. Passing the faire is necessary for future archiving. * From there we'll query all events for each day and cache them. * Now we'll loop through each day spitting out all applications scheduled for those days from 10am to closing of that day. * * @param array $atts The attributes being passed through the shortcode * @return string */ function mf_display_schedule_by_location($atts) { global $mfform; $data = shortcode_atts(array('location_id' => '', 'faire' => MF_CURRENT_FAIRE), $atts); // Get the faire date array. If the $faire_date = mf_get_faire_date(sanitize_title($data['faire'])); // Make sure we actually passed a valid faire... if (empty($faire_date)) { return '<h3>Not a valid faire!</h3>'; } // Get the location object. $location = get_post(absint($data['location_id'])); // Get Saturday events by location $saturday = wp_cache_get(sanitize_title($location->post_title) . '_saturday_schedule_' . sanitize_title($data['faire']), 'locations'); if ($saturday === false) { $events_saturday_args = array('post_type' => 'event-items', 'orderby' => 'meta_value', 'order' => 'ASC', 'meta_key' => 'mfei_start', 'posts_per_page' => 30, 'faire' => sanitize_title($data['faire']), 'meta_query' => array(array('key' => 'mfei_day', 'value' => 'Saturday'), array('key' => 'faire_location', 'value' => serialize(array(absint($data['location_id'])))))); $saturday = new WP_Query($events_saturday_args); wp_cache_set(sanitize_title($location->post_title) . '_saturday_schedule_' . sanitize_title($data['faire']), $saturday, 'locations', 300); } // Get Sunday Events by location $sunday = wp_cache_get(sanitize_title($location->post_title) . '_sunday_schedule_' . sanitize_title($data['faire']), 'locations'); if ($sunday === false) { $events_sunday_args = array('post_type' => 'event-items', 'orderby' => 'meta_value', 'order' => 'ASC', 'meta_key' => 'mfei_start', 'posts_per_page' => 30, 'faire' => sanitize_title($data['faire']), 'meta_query' => array(array('key' => 'mfei_day', 'value' => 'Sunday'), array('key' => 'faire_location', 'value' => serialize(array(absint($data['location_id'])))))); $sunday = new WP_Query($events_sunday_args); wp_cache_set(sanitize_title($location->post_title) . '_sunday_schedule_' . sanitize_title($data['faire']), $sunday, 'locations', 300); } $output = '<div class="row"><div class="col-xs-11"><h2><a href="' . esc_url(get_permalink(absint($data['location_id'])) . '?faire=' . $data['faire']) . '">' . esc_html($location->post_title) . '</a></h2></div> <div class="col-xs-1 pull-right" style="position:relative; top:7px;"><a href="#" onclick="window.print();return false;"><img src="' . get_stylesheet_directory_uri() . '/images/print-ico.png" alt="Print this schedule" /></a></div></div>'; if (!empty($location->post_excerpt)) { $output .= '<div class="alert alert-info">' . wp_kses_post(Markdown($location->post_excerpt)) . '</div>'; } // Let's loop through each day and spit out a schedule? $days = array('saturday', 'sunday'); foreach ($days as $key => $day) { // Make sure something was actually returned if (${$day}->found_posts >= 1) { // Start the schedule $output .= '<table id="' . esc_attr($day) . '" class="table table-striped table-bordered table-schedule">'; $output .= '<thead><tr><th colspan="2">' . esc_html(date('l dS, Y', strtotime($faire_date[ucfirst($day)]))) . '</th></tr></thead>'; // Loop through the events and get the applications while (${$day}->have_posts()) { ${$day}->the_post(); $event_id = get_the_ID(); $meta = get_post_meta(absint(get_the_ID())); $app_obj = get_post(absint($meta['mfei_record'][0])); $app = json_decode(mf_convert_newlines(str_replace("\\'", "'", $app_obj->post_content))); $output .= '<tr>'; $output .= '<td width="150" style="max-width:150px;">'; $output .= '<h5>' . esc_html($meta['mfei_day'][0]) . '</h5>'; $output .= '<p>' . esc_html($meta['mfei_start'][0]) . ' — ' . esc_html($meta['mfei_stop'][0]) . '</p>'; if (isset($app->{$mfform->merge_fields('form_photo', $app->form_type)}) || has_post_thumbnail(absint($event_id)) || isset($app->{$mfform->merge_fields('user_photo', $app->form_type)})) { $output .= '<div class="pull-left">'; // We may want to over ride the photo of an application on the schedule page by checking if there is a featured image on the event item if (has_post_thumbnail(absint($event_id))) { $output .= get_the_post_thumbnail(absint($event_id), 'schedule-thumb'); } elseif ($app->form_type == 'performer' || $app->form_type == 'exhibit') { $output .= '<a href="' . get_permalink(absint($app_obj->ID)) . '"><img class="img-thumbnail" src="' . legacy_get_resized_remote_image_url($app->{$mfform->merge_fields('user_photo', $app->form_type)}, 140, 140) . '" alt="' . esc_attr($app_obj->post_title) . '"></a>'; } elseif (!empty($app->{$mfform->merge_fields('user_photo', $app->form_type)}[0])) { $output .= '<a href="' . get_permalink(absint($app_obj->ID)) . '"><img class="img-thumbnail" src="' . legacy_get_resized_remote_image_url($app->{$mfform->merge_fields('user_photo', $app->form_type)}[0], 140, 140) . '" alt="' . esc_attr($app_obj->post_title) . '"></a>'; } else { $output .= '<a href="' . get_permalink(absint($app_obj->ID)) . '"><img class="img-thumbnail" src="' . legacy_get_resized_remote_image_url(mf_get_the_maker_image($app), 140, 140) . '" alt="' . esc_attr($app_obj->post_title) . '"></a>'; } $output .= '</div>'; } $output .= '</td><td>'; $output .= '<h3><a href="' . get_permalink(absint($app_obj->ID)) . '">' . get_the_title(absint($app_obj->ID)) . '</a></h3>'; // Presenter Name(s) if (!empty($app->presenter_name)) { $output .= '<h4 class="maker-name">' . implode(', ', $app->presenter_name) . '</h4>'; } // Application Descriptions $description = $app->{$mfform->merge_fields('project_description', $app->form_type)}; if (!empty($description)) { $output .= Markdown(stripslashes(wp_filter_post_kses(mf_convert_newlines($description)))); } // Add our video link for video coverage if (!empty($meta['mfei_coverage'][0])) { $output .= '<p><a href="' . esc_url($meta['mfei_coverage'][0]) . '" class="btn btn-xs btn-primary">Watch Video</a></p>'; } $output .= '</td>'; $output .= '</tr>'; } $output .= '</table>'; wp_reset_postdata(); } } // OMG WTF JUST HAPPENED. LET'S JUST RETURN THIS. :P return $output; }
/** * Generates a configurable/canned email response to the presenter. * @param obj $meta The meta information assigned to our event * @return void */ function mf_email_presenter_schedule() { // Verify we have the right credentials if (isset($_POST['nonce']) && !wp_verify_nonce($_POST['nonce'], 'email-presenter-schedulees')) { wp_die(new WP_Error('security-check-failed', 'We couldn\'t validate your request. Try again.')); } // Get the application and the event schedule $schedule_meta = get_post_custom(absint($_POST['meta'])); $application = get_post(absint($schedule_meta['mfei_record'][0])); // Make sure we have an application if (empty($application)) { wp_die(new WP_Error('empty-application', 'We couldn\'t find the application #' . absint($schedule_meta['mfei_record'][0]))); } // Extract the application data $app = json_decode(str_replace("\\'", "'", $application->post_content)); $app_promo_code = get_post_meta(absint($application->ID), 'app-presenter-promo-code', true); // Fetch the locations and process our data into something useable $locations_raw = mf_get_locations(absint($_POST['meta']), true); $locations = array(); // Process the location objects into a comma separated lists if (!empty($locations_raw)) { $locations = ''; foreach ($locations_raw as $location) { $map_url = get_post_meta(absint($location->ID), 'location-map', true); $locations .= '<h2 style="margin-bottom:0;">LOCATION</h2>'; $locations .= '<p style="margin-top:0;">' . esc_html($location->post_title) . '<br /><strong>Map</strong>: <a href="' . esc_url($map_url) . '">' . esc_url($map_url) . '</a></p>'; $locations .= '<h2 style="margin-bottom:0;">AUDIO AND VISUAL EQUIPMENT</h2>'; $locations .= '<p style="margin-top:0;">' . wp_kses_post($location->post_content) . '</p>'; } } // Set some variables based on what type of application we are using $makers = array('names' => array(), 'emails' => array()); switch ($app->form_type) { case 'presenter': // Save each presenter name if (is_array($app->presenter_name) && !empty($app->presenter_name)) { foreach ($app->presenter_name as $name) { $makers['names'][] = $name; } } else { $makers['names'][] = $app->presenter_name; } // Save each presenter email if (is_array($app->presenter_email) && !empty($app->presenter_email)) { foreach ($app->presenter_email as $email) { $makers['emails'][] = $email; } } else { $makers['emails'][] = $email; } break; } // Send all emails in testing environments to one account. if (isset($_SERVER['HTTP_HOST']) && in_array($_SERVER['HTTP_HOST'], array('localhost', 'make.com', 'vip.dev', 'staging.makerfaire.com'))) { $makers = array('names' => array('Web Master'), 'emails' => array('*****@*****.**')); } // Fetch our email template $email_path = dirname(__DIR__) . '/maker-faire-forms/emails/schedule-event-presenter.html'; // Prevent Path Traversal if (strpos($email_path, '../') !== false || strpos($email_path, "..\\") !== false || strpos($email_path, '/..') !== false || strpos($email_path, '\\..') !== false) { return; } // Make sure the file exists... if (!file_exists($email_path)) { return; } // get the contents of the email_template as the body $email_temp = file_get_contents($email_path); // Update and send out an email for each maker $maker_count = count($makers['names']); for ($i = 0; $i <= $maker_count - 1; $i++) { // Save our email template into a new variable so we don't have to fetch it again $email_body = $email_temp; // Add our single maker name and email and prep them for email $maker = array('name' => $makers['names'][intval($i)], 'email' => $makers['emails'][intval($i)]); // Get full date $faire_date = mf_get_faire_date(MF_CURRENT_FAIRE); // Pair our custom variables found in the email to actual data. We will run a find and replace on it for a dynamic email $find_and_replace = array('$presenter_name' => esc_html($maker['name']), '$faire_name' => 'World Maker Faire New York 2014', '$app_name' => esc_html($application->post_title), '$scheduled_date' => date('l, F j, Y', strtotime($faire_date[$schedule_meta['mfei_day'][0]])), '$scheduled_start_time' => esc_html($schedule_meta['mfei_start'][0]), '$scheduled_end_time' => esc_html($schedule_meta['mfei_stop'][0]), '$location_information' => $locations, '$app_url' => get_permalink(absint($application->ID)), '$app_eb_promo_code' => sanitize_text_field($app_promo_code)); $body = force_balance_tags(str_replace(array_keys($find_and_replace), array_values($find_and_replace), $email_body)); // Email it baby! $results[$maker['name']] = wp_mail(esc_html($maker['name']) . ' <' . sanitize_email($maker['email']) . '>', 'Confirmation and logistics for your presentation @World Maker Faire New York 2014', $body, array('Content-Type: text/html', "From: Sabrina Merlo <*****@*****.**", "Bcc: sabrina@makerfaire.com")); } // Check each result of the email and see if any failed. foreach ($results as $key => $value) { if ($value) { $done = array('messages_sent' => true); // Update the post meta that emails have been sent to the presenters update_post_meta(absint($application->ID), 'app-emails-sent', 'true'); } else { $done = array('messages_sent' => false, 'failed_email' => esc_html($key)); } } // Return the results wp_die(json_encode($done)); }