/** * Returns the database data relevant for the provided weekday. * * @param int $day: the weekday (sunday = 0, monday = 1) */ function wcs3_get_day_schedule($day, $location_id = NULL, $limit = NULL) { global $wpdb; $wcs3_settings = wcs3_load_settings(); $format = $wcs3_settings['24_hour_mode'] == 'yes' ? 'G:i' : 'g:i a'; $table = wcs3_get_table_name(); $results = array(); $query = "SELECT * FROM {$table} WHERE weekday = %d "; $query_arr = array($day); if ($location_id !== NULL) { $query .= "AND location_id = %d "; $query_arr[] = $location_id; } $query .= "ORDER BY start_hour "; if ($limit !== NULL) { $query .= "LIMIT %d"; $query_arr[] = $limit; } $r = $wpdb->get_results($wpdb->prepare($query, $query_arr)); if (!empty($r)) { foreach ($r as $entry) { $results[] = array('class' => get_post($entry->class_id)->post_title, 'instructor' => get_post($entry->instructor_id)->post_title, 'location' => get_post($entry->location_id)->post_title, 'start_hour' => date($format, strtotime($entry->start_hour)), 'end_hour' => date($format, strtotime($entry->end_hour)), 'visible' => $entry->visible == 1 ? __('Visible', 'wcs3') : __('Hidden', 'wcs3'), 'id' => $entry->id); } return $results; } else { return FALSE; } }
/** * Injecting our custom CSS */ function wcs3_load_dynamic_css() { $wcs3_options = wcs3_load_settings(); $base_color = $wcs3_options['color_base']; $details_box = $wcs3_options['color_details_box']; $text = $wcs3_options['color_text']; $border = $wcs3_options['color_border']; $heading_text = $wcs3_options['color_heading_text']; $heading_bg = $wcs3_options['color_headings_background']; $bg = $wcs3_options['color_background']; $qtip_bg = $wcs3_options['color_qtip_background']; $links = $wcs3_options['color_links']; echo ''; /* ------------- CSS ------------ */ $dynamic_css = <<<CSS <style> \t.wcs3-class-container { \t background-color: #{$base_color}; \t color: #{$text}; \t} \t.wcs3-class-container a { \t color: #{$links}; \t} \t.wcs3-details-box-container { \t background-color: #{$details_box}; \t} \tbody .wcs3-qtip-tip { \t background-color: #{$qtip_bg}; \t border-color: #{$border}; \t} \t.wcs3-schedule-wrapper table th { \t background-color: #{$heading_bg}; \t color: #{$heading_text}; \t} \t.wcs3-schedule-wrapper table { \t\t background-color: #{$bg}; \t} \t.wcs3-schedule-wrapper table, \t.wcs3-schedule-wrapper table td, \t.wcs3-schedule-wrapper table th { \t border-color: #{$border}; \t} </style> CSS; /* ------------- END ------------ */ echo $dynamic_css; }
/** * Renders list layout * * @param array $classes: classes array as returned by wcs3_get_classes(). * @param string $location: location to render. * @param int $first_day_of_week: index. */ function wcs3_render_list_schedule($classes, $location, $weekdays) { if (empty($classes)) { $output = '<div class="wcs3-no-classes-message">' . __('No classes scheduled') . '</div>'; return $output; } $wcs3_options = wcs3_load_settings(); $weekdays_dict = wcs3_get_weekdays(); $template = $wcs3_options['details_template']; $output = '<div class="wcs3-schedule-list-layout">'; // Classes are grouped by indexed weekdays. foreach ($weekdays as $day => $index) { $day = $weekdays_dict[$index]; $day_classes = $classes[$index]; if (!empty($day_classes)) { $output .= "<h3>{$day}</h3>"; $output .= '<ul class="wcs3-weekday-list wcs3-weekday-list-' . $index . '">'; foreach ($day_classes as $class) { $output .= '<li class="wcs3-list-item-class">'; $output .= wcs3_process_template($class, $template); $output .= '</li>'; } $output .= '</ul>'; echo ''; } } $output .= '</div>'; return $output; }
/** * Add or update schedule entry handler. */ function wcs3_add_or_update_schedule_entry_callback() { wcs3_verify_nonce(); global $wpdb; $response = __('Schedule entry added successfully', 'wcs3'); $result = 'updated'; $update_request = FALSE; $row_id = NULL; $days_to_update = array(); $table = wcs3_get_table_name(); $required = array('class_id' => __('Class ID'), 'instructor_id' => __('Instructor ID'), 'location_id' => __('Location ID'), 'weekday' => __('Weekday'), 'start_hour' => __('Start Hour'), 'start_minute' => __('Start Minute'), 'end_hour' => __('End Hour'), 'end_minute' => __('End Minute'), 'visible' => __('Visible')); wcs3_verify_required_fields($required); if (isset($_POST['row_id'])) { // This is an update request and not an insert. $update_request = TRUE; $row_id = sanitize_text_field($_POST['row_id']); } $wcs3_options = wcs3_load_settings(); $class_id = sanitize_text_field($_POST['class_id']); $instructor_id = sanitize_text_field($_POST['instructor_id']); $location_id = sanitize_text_field($_POST['location_id']); $weekday = sanitize_text_field($_POST['weekday']); $start_hour = sanitize_text_field($_POST['start_hour']); $start_minute = sanitize_text_field($_POST['start_minute']); $end_hour = sanitize_text_field($_POST['end_hour']); $end_minute = sanitize_text_field($_POST['end_minute']); $visible = sanitize_text_field($_POST['visible']); $notes = ''; // Check if we need to sanitize the notes or leave as is. if ($_POST['notes'] != NULL) { if ($wcs3_options['allow_html_in_notes'] == 'yes') { $notes = stripslashes_deep($_POST['notes']); $notes = stripslashes_deep($notes); } else { global $wcs3_allowed_html; $notes = wp_kses($_POST['notes'], $wcs3_allowed_html); } } $start = $start_hour . ':' . $start_minute . ':00'; $end = $end_hour . ':' . $end_minute . ':00'; $days_to_update[$weekday] = TRUE; // Validate time logic $timezone = wcs3_get_system_timezone(); $tz = new DateTimeZone($timezone); $start_dt = new DateTime(WCS3_BASE_DATE . ' ' . $start, $tz); $end_dt = new DateTime(WCS3_BASE_DATE . ' ' . $end, $tz); $wcs3_settings = wcs3_load_settings(); echo ''; if ($wcs3_settings['location_collision'] == 'yes') { // Validate location collision (if applicable) $location_collision = $wpdb->get_col($wpdb->prepare("\n \t\tSELECT id FROM {$table}\n \t\tWHERE location_id = %d AND weekday = %d\n \t\tAND %s < end_hour AND %s > start_hour\n \t\tAND id != %d\n \t\t", array($location_id, $weekday, $start, $end, $row_id))); } if ($wcs3_settings['instructor_collision'] == 'yes') { // Validate instructor collision (if applicable) $instructor_collision = $wpdb->get_col($wpdb->prepare("\n \t\tSELECT id FROM {$table}\n \t\tWHERE instructor_id = %d AND weekday = %d\n \t\tAND %s < end_hour AND %s > start_hour\n \t\tAND id != %d\n \t\t", array($instructor_id, $weekday, $start, $end, $row_id))); } // Prepare response if ($wcs3_settings['location_collision'] == 'yes' && !empty($location_collision)) { $response = __('Location is not available at this time', 'wcs3'); $result = 'error'; } else { if ($wcs3_settings['instructor_collision'] == 'yes' && !empty($instructor_collision)) { $response = __('Instructor is not available at this time', 'wcs3'); $result = 'error'; } else { if ($start_dt >= $end_dt) { // Invalid class time $response = __('A class cannot start before it ends', 'wcs3'); $result = 'error'; } else { $data = array('class_id' => $class_id, 'instructor_id' => $instructor_id, 'location_id' => $location_id, 'weekday' => $weekday, 'start_hour' => $start, 'end_hour' => $end, 'timezone' => $timezone, 'visible' => $visible == 'visible' ? 1 : 0, 'notes' => $notes); if ($update_request) { $old_weekday = $wpdb->get_var($wpdb->prepare("\n \t\tSELECT weekday FROM {$table}\n \t\tWHERE id = %d;\n \t\t", array($row_id))); $days_to_update[$old_weekday] = TRUE; $r = $wpdb->update($table, $data, array('id' => $row_id), array('%d', '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s'), array('%d')); if ($r === FALSE) { $response = __('Failed to update schedule entry', 'wcs3'); $result = 'error'; } else { $response = __('Schedule entry updated successfully'); } } else { $r = $wpdb->insert($table, $data, array('%d', '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s')); if ($r === FALSE) { $response = __('Failed to add schedule entry', 'wcs3'); $result = 'error'; } } } } } wcs3_json_response(array('response' => $response, 'result' => $result, 'days_to_update' => $days_to_update)); die; }
/** * Settings page. */ function wcs3_standard_settings_page_callback() { $wcs3_options = wcs3_load_settings(); if (isset($_POST['wcs3_options_nonce'])) { // We got a submission $nonce = sanitize_text_field($_POST['wcs3_options_nonce']); $valid = wp_verify_nonce($nonce, 'wcs3_save_options'); if ($valid === FALSE) { // Nonce verification failed. wcs3_options_message(__('Nonce verification failed', 'wcs3'), 'error'); } else { wcs3_options_message(__('Options updated', 'wcs3')); // Create a validataion fields array: // id_of_field => validation_function_callback $fields = array('first_day_of_week' => 'wcs3_validate_weekday', '24_hour_mode' => 'wcs3_validate_yes_no', 'location_collision' => 'wcs3_validate_yes_no', 'instructor_collision' => 'wcs3_validate_yes_no', 'details_template' => 'wcs3_validate_html', 'allow_html_in_notes' => 'wcs3_validate_yes_no', 'color_base' => 'wcs3_validate_color', 'color_details_box' => 'wcs3_validate_color', 'color_text' => 'wcs3_validate_color', 'color_border' => 'wcs3_validate_color', 'color_headings_text' => 'wcs3_validate_color', 'color_headings_background' => 'wcs3_validate_color', 'color_background' => 'wcs3_validate_color', 'color_qtip_background' => 'wcs3_validate_color', 'color_links' => 'wcs3_validate_color'); $wcs3_options = wcs3_perform_validation($fields, $wcs3_options); wcs3_save_settings($wcs3_options); } } ?> <h2><?php _e('Weekly Class Schedule Settings', 'wcs3'); ?> </h2> <h4><?php _e('Using Weekly Class Schedule', 'wcs3'); ?> </h4> <p> <?php _e('To display all the classes in a single schedule, simply enter the shortcode', 'wcs3'); ?> <code>[wcs]</code> <?php _e('inside a page or a post.', 'wcs3 '); ?> <?php _e('It\'s also possible to output the schedule as a list using the list layout:', 'wcs3'); ?> <code>[wcs layout=list]</code>. <?php _e('In order to filter a schedule by a specific class, instructor, location, or any other combination of the three, use the class, instructor, and location attributes. For example:'); ?> <ul> <li> <div><code>[wcs location="Classroom A"]</code> (<?php _e('Only display "Classroom A"'); ?> )</div> <div><code>[wcs instructor="John Doe"]</code> (<?php _e('Only display classes by "John Doe"'); ?> )</div> <div><code>[wcs class="Yoga"]</code> (<?php _e('Only display "Yoga" classes'); ?> )</div> </li> </ul> </p> <p> <?php _e('A finalized shortcode may look something like', 'wcs3'); ?> <code>[wcs location="Classroom A" layout=list]</code> </p> <form action="<?php $_SERVER['PHP_SELF']; ?> " method="post" name="wcs3_general_settings"> <h3> <?php _e('General Settings', 'wcs3'); ?> </h3> <table class="form-table"> <tr> <th> <?php _e('First day of week', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('The day the schedule will start in', 'wcs3'); ?> </div> </th> <td><?php echo wcs3_generate_weekday_select_list('wcs3_first_day_of_week', $wcs3_options['first_day_of_week']); ?> </td> </tr> <tr> <th> <?php _e('Enable 24-hour mode', 'wcs3'); ?> <div class="wcs3-description"><?php _e('Enabling this will display all the hours on the front-end in a 24 hour clock mode as opposed to 12 hour clock mode (AM/PM).', 'wcs3'); ?> </div> </th> <td><?php wcs3_bool_checkbox('wcs3_24_hour_mode', $wcs3_options['24_hour_mode'], __('Yes')); ?> </td> </tr> <tr> <th> <?php _e('Detect location collisions', 'wcs3'); ?> <div class="wcs3-description"><?php _e('Enabling this feature will prevent scheduling of multiple classes at the same location at the same time.', 'wcs3'); ?> </div> </th> <td><?php wcs3_bool_checkbox('wcs3_location_collision', $wcs3_options['location_collision'], __('Yes')); ?> </td> </tr> <tr> <th> <?php _e('Detect instructor collisions', 'wcs3'); ?> <div class="wcs3-description"><?php _e('Enabling this feature will prevent the scheduling of an instructor for multiple classes at the same.', 'wcs3'); ?> </div> </th> <td><?php wcs3_bool_checkbox('wcs3_instructor_collision', $wcs3_options['instructor_collision'], __('Yes')); ?> </td> </tr> <tr> <th> <?php _e('Class Details Template', 'wcs3'); ?> <div class="wcs3-description"><?php _e('Use placheolders to design the way the class details appear in the schedule. Certain HTML tags are allowed (to customize edit $wcs3_allowed_html in wcs.php).', 'wcs3'); ?> </div> <br/> <div class="wcs3-description"><strong><?php _e('Available placeholders:', 'wcs3'); ?> </strong> [class], [instructor], [location], [start hour], [end hour], [notes].</div> </th> <td> <textarea name="wcs3_details_template" cols="40" rows="6"><?php echo $wcs3_options['details_template']; ?> </textarea> </td> </tr> <tr> <th> <?php _e('Allow all HTML in notes', 'wcs3'); ?> <div class="wcs3-description"><?php _e('Allow all HTML tags in notes field. PLEASE NOTE: Allowing all HTML tags has security implications so use at your own risk.', 'wcs3'); ?> </div> </th> <td><?php wcs3_bool_checkbox('wcs3_allow_html_in_notes', $wcs3_options['allow_html_in_notes'], __('Yes')); ?> </td> </tr> </table> <?php if (!is_plugin_active('wcs-expansion-pack-1/wcs-ex1.php')) { ?> <div class="ex1-link-box"> <p>Check out the new <a href="http://pulsarwebdesign.com/downloads/weekly-class-schedule-expansion-pack-1" target="_blank">Expansion Pack</a> for additional features such as graphical representation of class duration, per class/instructor/location color customization, responsive layout, and more.</p> <p> <img src="<?php echo WCS3_PLUGIN_URL; ?> /img/expansion-pack-1-graphic-624x315.jpg" alt="Expansion pack 1 graphic" /> </p> <p style="text-align: center"> <a class="button button-primary" href="http://pulsarwebdesign.com/downloads/weekly-class-schedule-expansion-pack-1" target="_blank">Check it out!</a> </p> </div> <?php } ?> <h3> <?php _e('Appearance Settings', 'wcs3'); ?> </h3> <table class="form-table"> <tr> <th> <?php _e('Base class', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('The default background color for classes in the schedule.', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_base', $wcs3_options['color_base']); ?> </td> </tr> <tr> <th> <?php _e('Class details box', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('Background color of the class details box which appears when hovering over a class.', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_details_box', $wcs3_options['color_details_box']); ?> </td> </tr> <tr> <th> <?php _e('Text', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('Text color of schedule entries/classes.', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_text', $wcs3_options['color_text']); ?> </td> </tr> <tr> <th> <?php _e('Border', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('This color is used for all borders in the schedule output.', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_border', $wcs3_options['color_border']); ?> </td> </tr> <tr> <th> <?php _e('Schedule headings color', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('Text color of the schedule headings (weekdays, hours).', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_headings_text', $wcs3_options['color_headings_text']); ?> </td> </tr> <tr> <th> <?php _e('Schedule headings background', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('Background color of the schedule headings (weekdays, hours).', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_headings_background', $wcs3_options['color_headings_background']); ?> </td> </tr> <tr> <th> <?php _e('Background', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('Background color for the entire schedule.', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_background', $wcs3_options['color_background']); ?> </td> </tr> <tr> <th> <?php _e('qTip background', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('Background color of the qTip pop-up box.', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_qtip_background', $wcs3_options['color_qtip_background']); ?> </td> </tr> <tr> <th> <?php _e('Links', 'wcs3'); ?> <br/> <div class="wcs3-description"><?php _e('The color of the links which appear in the class details box.', 'wcs3'); ?> </div> </th> <td><?php wcs3_colorpicker('wcs3_color_links', $wcs3_options['color_links']); ?> </td> </tr> </table> <?php if (!is_plugin_active('wcs-expansion-pack-2/wcs-ex2.php')) { ?> <div class="ex1-link-box" style="max-width: 420px;"> <p>Check out <a href="http://pulsarwebdesign.com/downloads/weekly-class-schedule-expansion-pack-2" target="_blank">Expansion Pack 2</a> for additional styling options such as shadows and border radius:</p> <p style="text-align: center;"> <img style="border: 1px solid #B7B7B7; border-radius: 7px;" src="<?php echo WCS3_PLUGIN_URL; ?> /img/wcs-ex2-demo.gif" alt="Expansion pack 2 graphic" /> </p> <p style="text-align: center"> <a class="button button-primary" href="http://pulsarwebdesign.com/downloads/weekly-class-schedule-expansion-pack-2" target="_blank">Check it out!</a> </p> </div> <?php } ?> <?php submit_button(__('Save Settings')); ?> <?php wp_nonce_field('wcs3_save_options', 'wcs3_options_nonce'); ?> </form> <?php }