Example #1
0
 /**
  * Gather all reservations.
  *
  * @since 0.2.0
  * @access protected
  * @return \Wprsrv\PostTypes\Objects\Reservation[]
  */
 protected function getReservations()
 {
     $reservations = [];
     $rargs = ['post_type' => 'reservation', 'post_status' => ['reservation_pending', 'reservation_accepted', 'reservation_declined'], 'posts_per_page' => -1, 'nopaging' => 1, 'no_found_rows' => true, 'meta_key' => '_wprsrv_reservable_id'];
     if ($this->reservable) {
         $reservations = $this->reservable->getReservations();
     } else {
         $reservationsQuery = new \WP_Query($rargs);
         foreach ($reservationsQuery->posts as $rpost) {
             $reservations[] = new Reservation($rpost);
         }
     }
     return $reservations;
 }
Example #2
0
 /**
  * Render the form. The included template has $this available.
  *
  * The rendered template file can be overridden by themes by making a theme
  * directory `wprsrv` and creating a file named `reservation-form.php` inside it.
  *
  * The template file can be filtered to pick any other file which is needed.
  *
  * @since 0.1.0
  * @return void
  */
 public function render()
 {
     if (!$this->reservable->isActive()) {
         $this->reservationDisabledNotice();
         return;
     }
     if (!is_user_logged_in() && $this->reservable->isLoginRequired()) {
         $this->reservationRestrictedNotice();
         return;
     }
     try {
         $this->formFieldMarkup = $this->generateFormFieldsMarkup();
     } catch (\Exception $e) {
         \Wprsrv\wprsrv()->logger->critical('Cannot render reservation form: {msg}', ['msg' => $e->getMessage()]);
         return;
     }
     $themeTemplateFile = get_stylesheet_directory() . RDS . 'wprsrv' . 'reservation-form.php';
     $pluginTemplateFile = \Wprsrv\wprsrv()->templateDirectory . RDS . 'frontend' . RDS . 'reservation-form.php';
     // If a theme overrides the template file, load it. Otherwise use the plugin's own template.
     if (file_exists($themeTemplateFile)) {
         $templateFile = $themeTemplateFile;
     } else {
         $templateFile = $pluginTemplateFile;
     }
     /**
      * Filter the reservation form template file absolute path.
      *
      * @since 0.1.0
      *
      * @param String $templateFile Absolute path to template file.
      */
     $templateFile = apply_filters('wprsrv/reservation_form/template_file', $templateFile);
     include $templateFile;
 }
Example #3
0
 /**
  * Generate a table cell for a single day.
  *
  * @todo Validate reservations are shown correctly for overlapping
  *        reservation dates.
  *
  * @since 0.1.0
  * @access protected
  *
  * @param \DateTime $date Datetime for the day to generate.
  *
  * @return String
  */
 protected function generateDayCell(\DateTime $date, $weekdayNum)
 {
     $day = $date->format('d');
     $dayReserved = $this->reservable->isDayReserved($date, false);
     if (!$dayReserved) {
         return '<td class="single-day"><span class="day-num">' . $day . '</span></td>';
     }
     $reservations = $this->reservable->getReservationsForDate($date);
     $reservationLabel = $this->generateDayCellReservationsData($reservations, $date, $weekdayNum);
     $dayNum = sprintf('<span class="day-num">%s</span>', $day);
     $tdClasses[] = 'single-day';
     return sprintf('<td class="%s">%s %s</td>', implode(' ', $tdClasses), $dayNum, $reservationLabel);
 }
Example #4
0
 *
 * @since 0.1.0
 * @return void
 */
add_action('wp_ajax_wprsrv_flush_reservable_cache', function () {
    if (!isset($_POST) || !isset($_POST['post_id'])) {
        echo 1;
        exit;
    }
    $post = $_POST;
    $postId = $post['post_id'];
    if (!$postId) {
        echo 1;
        exit;
    }
    $reservable = new Reservable($postId);
    $reservable->flushCache();
    echo 0;
    exit;
});
/**
 * AJAX
 * Get a reservation calendar for a certain month and reservable.
 *
 * @since 0.4.0
 * @return void
 */
add_action('wp_ajax_wprsrv_get_reservation_calendar_view', function () {
    if (!isset($_POST) || !isset($_POST['reservable_id'])) {
        echo 1;
        exit;
Example #5
0
 /**
  * Validate given metadata for a new reservation.
  *
  * @static
  * @since 0.1.0
  * @todo Make this more usable for other parts of the plugin maybe?
  *
  * @param mixed[] $meta Metadata to validate.
  *
  * @return mixed[]
  */
 protected static function validateMeta($meta)
 {
     $required = ['reserver_email' => ['email', _x('email address', 'validation error label', 'wprsrv')], 'start_date' => ['date', _x('starting date or time', 'validation error label', 'wprsrv')], 'end_date' => ['date', _x('ending date or time', 'validation error label', 'wprsrv')]];
     $errors = [];
     foreach ($required as $key => $type) {
         if (!array_key_exists($key, $meta)) {
             $errors[] = sprintf(_x('Missing field: %s', 'validation error', 'wprsrv'), $type[1]);
         }
         $value = $meta[$key];
         switch ($type) {
             case 'integer':
                 if (!preg_match('%^[0-9]+$%', $value)) {
                     $errors[] = sprintf(_x('Invalid number value for %s', 'validation error', 'wprsrv'), $type[1]);
                 }
                 break;
             case 'date':
                 if (!is_numeric(strtotime($value)) || strtotime($value) < 1000) {
                     $errors[] = sprintf(_x('Invalid date or time value for %s', 'validation error', 'wprsrv'), $type[1]);
                 }
                 break;
             case 'email':
                 if (!is_email($value)) {
                     $errors[] = sprintf(_x('Invalid email value for %s', 'validation error', 'wprsrv'), $type[1]);
                 }
                 break;
         }
     }
     $reservable = new Reservable($meta['reservable_id']);
     $dayOverlapErrorMessage = _x('Given reservation date range contains a date that has already been reserved', 'validation error', 'wprsrv');
     if (!$reservable->allowsOverlappingReservations()) {
         if ($reservable->hasReservationInDateRange($meta['start_date'], $meta['end_date'])) {
             $errors[] = $dayOverlapErrorMessage;
         }
     } else {
         if (!$reservable->canReserveOverlapping($meta['start_date'], $meta['end_date'])) {
             $errors[] = $dayOverlapErrorMessage;
         }
     }
     return $errors;
 }
Example #6
0
 /**
  * Fired on WP plugin deactivation hook. No output allowed.
  *
  * @todo Refactor plugin cache flushing to a separate method, or maybe even a
  *       class.
  * @static
  * @since 0.1.0
  * @return void
  */
 public static function deactivate()
 {
     // Begin output buffering.
     ob_start();
     $self = new self(false);
     $self->logger->notice('Deactivating wprsrv plugin...');
     $reservables = new \WP_Query(['post_type' => 'reservable', 'post_status' => 'all', 'posts_per_page' => -1, 'no_found_rows' => 1, 'nopaging' => 1, 'fields' => 'ids']);
     if ($reservables->have_posts()) {
         foreach ($reservables->posts as $post_id) {
             $reservable = new Reservable($post_id);
             $reservable->flushCache();
         }
     }
     // Flush rewrite rules.
     flush_rewrite_rules();
     // Get rid of buffer.
     ob_end_clean();
 }
Example #7
0
<?php

namespace Wprsrv;

use Wprsrv\PostTypes\Objects\Reservable;
if (!$reservable && !empty($post)) {
    $reservable = $post;
}
if (!$reservable instanceof Reservable) {
    $reservable = new Reservable($reservable);
}
if ($reservable->hasReservations()) {
    $calDate = new \DateTime('now');
    $cal = new \Wprsrv\Admin\ReservableCalendar($reservable, $calDate);
    //FIXME
    $flushed = $reservable->calendarCacheFlushed();
    $cal->render(true);
    if (!!$flushed) {
        $reservable->clearCalendarFlush();
    }
} else {
    printf('<p class="empty-notice">%s</p>', __('This reservable has no reservations.', 'wprsrv'));
}
Example #8
0
<?php

namespace Wprsrv;

use Wprsrv\PostTypes\Objects\Reservable;
if (!$reservable && !empty($post)) {
    $reservable = $post;
}
if (!$reservable instanceof Reservable) {
    $reservable = new Reservable($reservable);
}
$weekdays = ['monday' => __('Monday'), 'tuesday' => __('Tuesday'), 'wednesday' => __('Wednesday'), 'thursday' => __('Thursday'), 'friday' => __('Friday'), 'saturday' => __('Saturday'), 'sunday' => __('Sunday')];
?>

<table summary="Reservable settings">
    <tbody>

        <tr>
            <th class="wprsrv-mainlabel" scope="row">
                <label for=""><?php 
_ex('Reservable active', 'reservable metabox form', 'wprsrv');
?>
</label>
                <em><?php 
_e('If the reservable is not active, it will be visible in the frontend but no reservation form will be shown.', 'wprsrv');
?>
</em>
            </th>
            <td>
                <label for="wprsrv-reservable-active">
                    <input type="checkbox" name="wprsrv[reservable_active]" <?php 
Example #9
0
 /**
  * Custom saving logic for reservables.
  *
  * @see self::addHooks()
  * @see:wphook save_post
  * @since 0.1.0
  * @todo Make this method simpler and extract some parts elsewhere.
  *
  * @param Integer $post_id Post ID being saved.
  * @param \WP_Post $post Post being saved.
  * @param Boolean $update Is this an update?
  *
  * @return void
  */
 public function saveReservable($post_id, $post, $update)
 {
     if (wp_is_post_revision($post_id)) {
         return;
     }
     if (get_post_type($post_id) !== 'reservable') {
         return;
     }
     $postData = $_POST;
     if (!isset($postData['wprsrv'])) {
         return;
     }
     $wprsrvData = $postData['wprsrv'];
     $reservable = new ReservableObj($post);
     $keysAvailable = ['reservable_active', 'reservable_singleday', 'reservable_disabled_days', 'reservable_disabled_weekdays', 'reservable_loggedin_only', 'reservable_overlapping_days'];
     // Set null values if not given on update.
     foreach ($keysAvailable as $key) {
         if (array_key_exists($key, $wprsrvData)) {
             continue;
         }
         switch ($key) {
             case 'reservable_active':
                 $reservable->setActive(false);
                 break;
             case 'reservable_singleday':
                 $reservable->setSingleDay(false);
                 break;
             case 'reservable_disabled_days':
                 $reservable->setDisabledDaysAdminData(false);
                 break;
             case 'reservable_disabled_weekdays':
                 $reservable->setDisabledWeekdaysData(false);
                 break;
             case 'reservable_loggedin_only':
                 $reservable->setLoginRequired(false);
                 break;
             case 'reservable_overlapping_days':
                 $reservable->setAllowOverlappingReservations(false);
                 break;
         }
     }
     // Update values with given POST.
     foreach ($wprsrvData as $key => $value) {
         switch ($key) {
             case 'reservable_active':
                 $reservable->setActive($value === 'on' ? true : false);
                 break;
             case 'reservable_singleday':
                 $reservable->setSingleDay($value === 'on' ? true : false);
                 break;
             case 'reservable_disabled_days':
                 $disabled = [];
                 for ($i = 0; $i < count($value['start']); $i++) {
                     if (empty($value['start'][$i])) {
                         continue;
                     }
                     $range = ['start' => $value['start'][$i], 'end' => $value['end'][$i], 'reservation_id' => 0];
                     $disabled[] = $range;
                 }
                 $reservable->setDisabledDaysAdminData($disabled);
                 break;
             case 'reservable_disabled_weekdays':
                 $wdays = array_map(function ($item) {
                     return preg_replace('%[^a-zöäå]%', '', $item);
                 }, $value);
                 $reservable->setDisabledWeekdaysData($wdays);
                 break;
             case 'reservable_loggedin_only':
                 $reservable->setLoginRequired($value === 'on' ? true : false);
                 break;
             case 'reservable_overlapping_days':
                 $reservable->setAllowOverlappingReservations($value === 'on' ? true : false);
                 break;
         }
     }
     // Flush caches on save.
     if ($update) {
         $reservable->flushCache();
     }
     /**
      * Hook fired when a reservable is saved to the database.
      *
      * Allows doing additional saving logic for reservables.
      *
      * @since 0.1.0
      *
      * @param Integer $id The reservable post ID.
      * @param ReservableObj $reservable The reservable object.
      * @param Boolean $update Is this an update or a new reservable?
      */
     do_action('wprsrv/reservable/save', $reservable->ID, $reservable, $update);
 }