Ejemplo n.º 1
0
 /**
  * Generate the exports page contents.
  *
  * @since 0.2.0
  * @return void
  */
 public function generateExportPage()
 {
     wp_enqueue_script('pikaday');
     wp_enqueue_style('pikaday');
     wp_enqueue_style('wprsrv-export');
     $exportTemplate = [\Wprsrv\wprsrv()->pluginDirectory, 'includes', 'templates', 'admin', 'export.php'];
     $exportTemplate = implode(RDS, $exportTemplate);
     require_once $exportTemplate;
 }
Ejemplo n.º 2
0
 /**
  * Handle a requested export. Takes the request params and dumps the export data.
  *
  * @since 0.2.0
  * @return void
  */
 public function handleExport()
 {
     if (!$this->validateExportRequest()) {
         return;
     }
     $args = $_POST['wprsrv'];
     try {
         $exportParams = $this->getExportParameters($args);
         $exporter = ExporterFactory::create($exportParams['format'], $exportParams['reservable'], $exportParams['date_range']);
         $exporter->dumpExport();
     } catch (\OutOfBoundsException $oobe) {
         wp_die(__('The selected date range has no reservation data to export.', 'wprsrv'));
     } catch (\Exception $e) {
         \Wprsrv\wprsrv()->logger->alert('Could not generate export: {msg}', ['msg' => $e->getMessage()]);
         wp_die(__('There was an error with the export, please try again.', 'wprsrv'));
     }
 }
Ejemplo n.º 3
0
 /**
  * Create a new instance of Reservation from given data.
  *
  * @fixme Validate single day mode works.
  * @todo Extract some functionality elsewhere to make this simpler.
  * @since 0.1.0
  *
  * @param mixed[] $postData Post data values to use. Passed to wp_insert_post.
  * @param mixed[] $metaData Metadata values to use.
  * @param \Wprsrv\PostTypes\Objects\Reservable|null $reservable The reservable
  *                                                              being reserved.
  *
  * @return \Wprsrv\PostTypes\Objects\Reservation|Boolean
  */
 public static function create(array $postData, array $metaData, Reservable $reservable = null)
 {
     // Force post type and status.
     $postData['post_type'] = 'reservation';
     $postData['post_status'] = 'reservation_pending';
     if (!isset($metaData['reservable_id']) && $reservable === null) {
         throw new \InvalidArgumentException('Could not create a new reservation with the given post data.');
     } elseif ($reservable !== null) {
         $metaData['reservable_id'] = $reservable->ID;
     }
     $metaErrors = static::validateMeta($metaData);
     if (!empty($metaErrors)) {
         $_POST['reservation_notice'] = sprintf('<ul><li>%s</li></ul>', implode('</li><li>', $metaErrors));
         return false;
     }
     $id = wp_insert_post($postData);
     if (!$id || is_wp_error($id)) {
         if (is_wp_error($id)) {
             \Wprsrv\wprsrv()->logger->alert('Could not create a new reservation: {msg}', ['msg' => array_shift($id->get_error_messages())]);
         }
         throw new \InvalidArgumentException('Could not create a new reservation with the given post data.');
     }
     $self = new static($id);
     $date = new \DateTime('now');
     $year = new \DateInterval('P1Y');
     $pruneDate = $date->add($year);
     $metaData['prune_date'] = $pruneDate->format('Y-m-d H:i:s');
     // Save meta values.
     foreach ($metaData as $key => $data) {
         if ($key == 'reservation_date_start') {
             $data = preg_replace('%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$%', '00:00:00', $data);
         } elseif ($key == 'reservation_date_end') {
             $data = preg_replace('%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$%', '23:59:59', $data);
         }
         $self->setMeta($key, $data);
     }
     $self->getReservable()->flushCache();
     do_action('wprsrv/reservation/created', $self->ID, $self);
     return $self;
 }
Ejemplo n.º 4
0
 /**
  * Get the data for all disabled days for a reservable item. This includes
  * blocked time which has been already reserved.
  *
  * @since 0.1.0
  *
  * @param Boolean $forFrontendCalendar Optional. Get disabled days for the front-end
  *                                     calendar?
  *
  * @return mixed
  */
 public function getDisabledDaysData($forFrontendCalendar = false)
 {
     // Get cached disabled days data.
     $ranges = get_transient($this->cachePrefix . 'disdays_' . strval($forFrontendCalendar));
     if ($ranges !== false) {
         return $ranges;
     }
     $disabledRanges = $this->getDisabledDaysAdminData();
     $disabledWeekdays = $this->getDisabledWeekdaysData();
     $reservations = $this->getReservations();
     $weekInterval = new \DateInterval('P1W');
     $dayInterval = new \DateInterval('P1D');
     if (!empty($disabledWeekdays)) {
         foreach ($disabledWeekdays as $weekday) {
             $wdayDate = new \DateTime('now');
             $wdayDate->modify($weekday);
             // Pad to two years.
             for ($i = 0; $i < 105; $i++) {
                 $range = ['start' => $wdayDate->format('Y-m-d'), 'end' => $wdayDate->format('Y-m-d')];
                 $disabledRanges[] = $range;
                 $wdayDate->add($weekInterval);
             }
         }
     }
     $overlapAdjusted = [];
     foreach ($reservations as $reservation) {
         if (!$reservation->isPending() && !$reservation->isAccepted()) {
             continue;
         }
         try {
             $startDate = $reservation->getStartDate('object');
             $endDate = $reservation->getEndDate('object');
             // If we allow overlapping reservations, allow users to pick dates
             // Where a reservation either starts or ends.
             if ($this->allowsOverlappingReservations() && $forFrontendCalendar) {
                 $overlapAdjusted[] = $startDate->format('Y-m-d');
                 $overlapAdjusted[] = $endDate->format('Y-m-d');
                 $startDate->add($dayInterval);
                 $endDate->sub($dayInterval);
             }
             $start = $startDate->format('Y-m-d');
             $end = $endDate->format('Y-m-d');
             // Don't get "expired" dates.
             if ($end < date('Y-m-d')) {
                 continue;
             }
             $range = ['start' => $start, 'end' => $end, 'reservation_id' => $reservation->ID];
             $disabledRanges[] = $range;
         } catch (\Exception $e) {
             \Wprsrv\wprsrv()->logger->alert('Invalid date data for reservation {id}', ['id' => $reservation->ID]);
         }
     }
     $overlapValCounts = array_count_values($overlapAdjusted);
     // See which dates have two reservations overlapping and disable them too.
     foreach ($overlapValCounts as $value => $count) {
         if ($count < 2) {
             continue;
         }
         $range = ['start' => $value, 'end' => $value, 'reservation_id' => 0];
         $disabledRanges[] = $range;
     }
     set_transient($this->cachePrefix . 'disdays_' . strval($forFrontendCalendar), $disabledRanges, HOUR_IN_SECONDS * 4);
     return $disabledRanges;
 }
Ejemplo n.º 5
0
 /**
  * Create a new reservation from the form.
  *
  * @access protected
  * @since 0.1.0
  * @todo Pickle this up to smaller methods and pass some control over to the
  *       reservation object class.
  *
  * @param mixed[] $data Data for reservation.
  *
  * @return void
  */
 protected function createReservation($data)
 {
     $reservable = $this->reservable;
     $reservation_meta_data = ['reservable_id' => $reservable->ID, 'reserver_email' => $data['wprsrv-reserver-email'], 'reserver_name' => $data['wprsrv-reserver-name']];
     if ($reservable->isSingleDay()) {
         $reservation_meta_data['start_date'] = $data['wprsrv-reservation-date'];
         $reservation_meta_data['end_date'] = $data['wprsrv-reservation-date'];
         $reservation_meta_data['reservation_date'] = $data['wprsrv-reservation-date'];
     } else {
         $reservation_meta_data['start_date'] = $data['wprsrv-reservation-date-start'];
         $reservation_meta_data['end_date'] = $data['wprsrv-reservation-date-end'];
     }
     if ($reservable->isSingleDay()) {
         $reservationTitle = [$reservable->post_title, ': ', $reservation_meta_data['start_date'], ', by ', $reservation_meta_data['reserver_email']];
     } else {
         $reservationTitle = [$reservable->post_title, ': ', $reservation_meta_data['start_date'], ' to ', $reservation_meta_data['end_date'], ', by ', $reservation_meta_data['reserver_email']];
     }
     $reservationTitle = implode('', $reservationTitle);
     $reservation_post_data = ['post_type' => 'reservation', 'post_title' => $reservationTitle, 'post_status' => 'reservation_pending', 'post_content' => $data['wprsrv-reservation-description']];
     try {
         $reservation = Reservation::create($reservation_post_data, $reservation_meta_data, $reservable);
     } catch (\InvalidArgumentException $iae) {
         $_POST['reservation_notice'] = _x('The data you gave looked invalid, please check your fields and try again.', 'reservation form error', 'wprsrv');
         return;
     } catch (\Exception $e) {
         \Wprsrv\wprsrv()->logger->critical('Could not create new reservation: {msg}', ['msg' => print_r($e, true)]);
         $_POST['reservation_notice'] = _x('Sorry, something went wrong in the reservation system, please try again.', 'reservation form error', 'wprsrv');
         return;
     }
     if ($reservation instanceof Reservation) {
         $this->reservation = $reservation;
     } else {
         return;
     }
     $_POST['reservation_success'] = _x('Thank you for your reservation. You will get a confirmation email in a few moments.', 'reservation form success', 'wprsrv');
 }
Ejemplo n.º 6
0
 /**
  * Prune all reservations that have expired according to their `prune_date` meta
  * value.
  *
  * @since 0.1.0
  * @see self::pruning()
  * @return void
  */
 public function pruneReservations()
 {
     global $wpdb;
     // Posts statuses to prune.
     $pruneStatuses = ['"reservation_pending"', '"reservation_declined"'];
     // Query for reservations which have `prune_date` set and where `prune_date` is less than today.
     $query = vsprintf('SELECT ID FROM %s p LEFT JOIN %s pm ON (p.ID = pm.post_id) WHERE p.post_type = "%s" AND p.post_status IN (%s) AND pm.meta_key = "%s" AND pm.meta_value < "%s"', [$wpdb->posts, $wpdb->postmeta, 'reservation', implode(', ', $pruneStatuses), '_wprsrv_prune_date', date('Y-m-d H:i:s')]);
     $reservationIds = $wpdb->get_col($query);
     foreach ($reservationIds as $id) {
         /**
          * Should a reservation be pruned although prunde date has passed.
          *
          * Allows skipping pruning for single reservations.
          *
          * @since 0.1.0
          *
          * @param Boolean $shouldBePruned True to allow pruning, false to
          *                                disallow.
          * @param Integer $id The reservation post ID.
          */
         $shouldBePruned = (bool) apply_filters('wprsrv/reservation/prune_reservation', true, $id);
         /**
          * Set the method of deletion for pruned reservations.
          *
          * If returns true, pruned reservations will be trashed instead of fully
          * deleted. Returning false (default) will delete pruned reservations
          * completely.
          *
          * @since 0.1.0
          *
          * @param Boolean $trashInstead Trash it on true, delete on false.
          * @param Integer $id Reservation post ID.
          */
         $trashInstead = (bool) apply_filters('wprsrv/reservation/prune_to_trash', false, $id);
         if ($shouldBePruned) {
             // Force delete the reservation, skipping trash unless set to trash.
             $deleted = wp_delete_post($id, !$trashInstead);
             if ($deleted === false) {
                 \Wprsrv\wprsrv()->logger->error('Could not prune reservation {id}: wp_delete_post failed.', ['id' => $id]);
             }
         }
     }
 }
Ejemplo n.º 7
0
 /**
  * Spawn metaboxes for the post type.
  *
  * @since 0.1.0
  * @access protected
  *
  * @param $string
  * @param $reservable
  *
  * @return void
  */
 protected function metaBoxCallback($string, $reservable)
 {
     $tmplBase = \Wprsrv\wprsrv()->templateDirectory . RDS . 'admin' . RDS . 'reservables' . RDS;
     $templateFiles = ['settings' => $tmplBase . 'settings-metabox.php', 'calendars' => $tmplBase . 'calendars-metabox.php', 'actions' => $tmplBase . 'actions-metabox.php'];
     include $templateFiles[$string];
 }