Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for WP personal data exporter & eraser #1355 #1356

Merged
merged 15 commits into from
Oct 21, 2023
Merged
18 changes: 16 additions & 2 deletions src/Model/Booking.php
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,6 @@ public function bookingLinkUrl(): string {
* Returns true when booking is cancelled. This might not correctly reflect the status of the booking when $this->cancel() has been called.
* In order to correctly reflect this, you need to call wp_cache_flush() before calling this function.
*
*
*
* @return bool
*/
public function isCancelled(): bool {
Expand Down Expand Up @@ -586,4 +584,20 @@ public function isConfirmed() : bool {
public function isUnconfirmed() : bool {
return $this->post_status === 'unconfirmed';
}

/**
* Will get the status of a booking as a human-readable string
* @return string
*/
public function getStatus() : string {
if ( $this->isConfirmed() ) {
return __( 'Confirmed', 'commonsbooking' );
} elseif ( $this->isUnconfirmed() ) {
return __( 'Unconfirmed', 'commonsbooking' );
} elseif ( $this->isCancelled() ) {
return __( 'Cancelled', 'commonsbooking' );
} else {
return __( 'Unknown', 'commonsbooking' );
}
}
}
2 changes: 1 addition & 1 deletion src/Model/CustomPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public function getDate() {

/**
* Returns user data.
* @return mixed
* @return false|\WP_User
*/
public function getUserData() {
return get_userdata( $this->post_author );
Expand Down
36 changes: 36 additions & 0 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,36 @@ public static function registerAdminOptions() {
}
}

/**
* Registers all user data exporters ({@link https://developer.wordpress.org/plugins/privacy/adding-the-personal-data-exporter-to-your-plugin/}).
*
* @param array $exporters
*
* @return mixed
*/
public static function registerUserDataExporters( $exporters ) {
$exporters[COMMONSBOOKING_PLUGIN_SLUG] = array(
'exporter_friendly_name' => __( 'CommonsBooking Bookings', 'commonsbooking' ),
'callback' => array( \CommonsBooking\Wordpress\CustomPostType\Booking::class, 'exportUserBookingsByEmail' ),
);
return $exporters;
}

/**
* Registers all user data erasers ({@link https://developer.wordpress.org/plugins/privacy/adding-the-personal-data-eraser-to-your-plugin/}).
*
* @param $erasers
*
* @return mixed
*/
public static function registerUserDataErasers( $erasers ) {
$erasers[COMMONSBOOKING_PLUGIN_SLUG] = array(
'eraser_friendly_name' => __( 'CommonsBooking Bookings', 'commonsbooking' ),
'callback' => array( \CommonsBooking\Wordpress\CustomPostType\Booking::class, 'removeUserBookingsByEmail'),
);
return $erasers;
}

/**
* Gets location position for locations without coordinates.
*/
Expand Down Expand Up @@ -608,6 +638,12 @@ function ( $plugin_data ) {
return (COMMONSBOOKING_PLUGIN_URL . '/vendor/ed-itsolutions/cmb2-field-ajax-search/');
});

//hook into WordPress personal data exporter
add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'registerUserDataExporters' ) );

//hook into WordPress personal data eraser
add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'registerUserDataErasers' ) );

// iCal rewrite
iCalendar::initRewrite();

Expand Down
120 changes: 77 additions & 43 deletions src/Repository/Booking.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,26 +77,7 @@ public static function getEndingBookingsByDate( int $timestamp, array $customArg
// Overwrite args with passed custom args
$args = array_merge( $args, $customArgs );

$query = new WP_Query( $args );
if ( $query->have_posts() ) {
$posts = $query->get_posts();

// Filter by post_status, query seems not to work reliable
$posts = array_filter(
$posts,
function ( $post ) use ( $args ) {
return in_array( $post->post_status, $args['post_status'] );
}
);

foreach ( $posts as &$post ) {
$post = new \CommonsBooking\Model\Booking( $post );
}

return $posts;
}

return [];
return self::getModelsFromQuery( $args );
}

/**
Expand Down Expand Up @@ -293,27 +274,7 @@ public static function getByTimerange(
$args = array_merge( $args, $customArgs );



$query = new WP_Query( $args );
if ( $query->have_posts() ) {
$posts = $query->get_posts();

// Filter by post_status, query seems not to work reliable
$posts = array_filter(
$posts,
function ( $post ) use ( $args ) {
return in_array( $post->post_status, $args['post_status'] );
}
);

foreach ( $posts as &$post ) {
$post = new \CommonsBooking\Model\Booking( $post );
}

return $posts;
}

return [];
return self::getModelsFromQuery( $args );
}

/**
Expand All @@ -325,7 +286,7 @@ function ( $post ) use ( $args ) {
* @return array
* @throws Exception
*/
public static function getForUser( $user, bool $asModel = false, $startDate = null ): array {
public static function getForUser( \WP_User $user, bool $asModel = false, $startDate = null ): array {
$customId = $user->ID;

$cacheItem = Plugin::getCacheItem( $customId );
Expand Down Expand Up @@ -380,7 +341,8 @@ public static function getForCurrentUser( bool $asModel = false, $startDate = nu
}

/**
* Returns bookings.
* Returns bookings. This uses the CommonsBooking\Repository\Timeframe::get() method which
* is not based on the WP_Query class but will perform its own SQL query.
*
* @param array $locations
* @param array $items
Expand Down Expand Up @@ -411,6 +373,47 @@ public static function get(
);
}

/**
* We use this function instead of the getForUser() function when we need to paginate the results.
* This is to prevent timeouts for bigger queries such as data exports. As opposed to the getForUser() function,
* this function will use the WP_Query class to perform the query allowing us to use the pagination features of WP_Query.
*
* @param \WP_User $user The user for which to get the bookings.
* @param int $page The current page that is processed.
* @param int $perPage The number of bookings per page. A lower number will result in faster queries.
* @param array $customArgs Valid WP_Query args array.
*
* @return Booking[] An array of Booking models.
*/
public static function getForUserPaginated(
\WP_User $user,
int $page = 1,
int $perPage = 10,
$customArgs = [],
$postStatus = [ 'confirmed', 'unconfirmed', 'canceled' , 'publish', 'inherit' ]
): array {
$args = array(
'author' => $user->ID,
'post_type' => \CommonsBooking\Wordpress\CustomPostType\Booking::$postType,
'meta_query' => array(
array(
'key' => 'type',
'value' => Timeframe::BOOKING_ID,
'compare' => '=',
),
),
'post_status' => $postStatus,
'posts_per_page' => $perPage,
'paged' => $page,
'orderby' => 'ID',
'order' => 'ASC',
);
// Overwrite args with passed custom args
$args = array_merge( $args, $customArgs );

return self::getModelsFromQuery( $args );
}

/**
* Gets all bookings that are affected by the given restriction.
*
Expand Down Expand Up @@ -467,4 +470,35 @@ public static function getExistingBookings( $itemId, $locationId, $startDate, $e

}

/**
* Will take a valid WP_Query args array and return an array of Booking models.
*
* @param array $args
*
* @return \CommonsBooking\Model\Booking[]
* @throws Exception
*/
private static function getModelsFromQuery( array $args ): array {
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
$posts = $query->get_posts();

// Filter by post_status, query seems not to work reliable
$posts = array_filter(
$posts,
function ( $post ) use ( $args ) {
return in_array( $post->post_status, $args['post_status'] );
}
);

foreach ( $posts as &$post ) {
$post = new \CommonsBooking\Model\Booking( $post );
}

return $posts;
}

return [];
}

}
35 changes: 19 additions & 16 deletions src/Repository/Timeframe.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ public static function getBookableForCurrentUser(
* In this case we need this function.
* Other functions use this one as base function for more specialized searches.
*
* TODO: Investigate
* This function is not based on the WP_Query class, probably because of performance reasons.
*
* @param array $locations
* @param array $items
* @param array $types
Expand Down Expand Up @@ -202,7 +205,7 @@ public static function getPostIdsByType( array $types = [], array $items = [], a

// Query for item(s)
if ( count( $items ) > 0 ) {
$itemQuery = "
$itemQuery = "
INNER JOIN $table_postmeta pm2 ON
pm2.post_id = pm1.post_id AND
pm2.meta_key = 'item-id' AND
Expand All @@ -213,7 +216,7 @@ public static function getPostIdsByType( array $types = [], array $items = [], a
// Query for location(s)
$locationQuery = "";
if ( count( $locations ) > 0 ) {
$locationQuery = "
$locationQuery = "
INNER JOIN $table_postmeta pm3 ON
pm3.post_id = pm1.post_id AND
pm3.meta_key = 'location-id' AND
Expand All @@ -223,11 +226,11 @@ public static function getPostIdsByType( array $types = [], array $items = [], a

// Complete query, including types
$query = "
SELECT DISTINCT pm1.post_id from $table_postmeta pm1
SELECT DISTINCT pm1.post_id from $table_postmeta pm1
" .
$itemQuery .
$locationQuery .
"
"
WHERE
pm1.meta_key = 'type' AND
pm1.meta_value IN (" . implode( ',', $types ) . ")
Expand Down Expand Up @@ -332,7 +335,7 @@ private static function getFilterByDateQuery( string $table_postmeta, string $da
"INNER JOIN $table_postmeta pm4 ON
pm4.post_id = pm1.id AND
pm4.meta_key = %s AND
pm4.meta_value BETWEEN 0 AND %d
pm4.meta_value BETWEEN 0 AND %d
INNER JOIN $table_postmeta pm5 ON
pm5.post_id = pm1.id AND (
(
Expand All @@ -341,12 +344,12 @@ private static function getFilterByDateQuery( string $table_postmeta, string $da
) OR
(
pm1.id not in (
SELECT post_id FROM $table_postmeta
WHERE
SELECT post_id FROM $table_postmeta
WHERE
meta_key = '" . \CommonsBooking\Model\Timeframe::REPETITION_END . "'
)
)
)
)
",
\CommonsBooking\Model\Timeframe::REPETITION_START,
strtotime( $date . 'T23:59' ),
Expand All @@ -369,13 +372,13 @@ private static function getFilterFromDateQuery( string $table_postmeta, int $min
return $wpdb->prepare(
"INNER JOIN $table_postmeta pm4 ON
pm4.post_id = pm1.id AND (
(
(
pm4.meta_key = '" . \CommonsBooking\Model\Timeframe::REPETITION_END . "' AND
pm4.meta_value >= %d
) OR
(
pm1.id not in (
SELECT post_id FROM $table_postmeta
SELECT post_id FROM $table_postmeta
WHERE
meta_key = '" . \CommonsBooking\Model\Timeframe::REPETITION_END . "'
)
Expand All @@ -399,21 +402,21 @@ private static function getTimerangeQuery( string $table_postmeta, int $minTimes
"INNER JOIN $table_postmeta pm4 ON
pm4.post_id = pm1.id AND (
pm4.meta_key = %s AND
pm4.meta_value <= %d
pm4.meta_value <= %d
)
INNER JOIN $table_postmeta pm5 ON
pm5.post_id = pm1.id AND (
(
pm5.post_id = pm1.id AND (
(
pm5.meta_key = %s AND
pm5.meta_value >= %d
) OR (
NOT EXISTS (
SELECT * FROM $table_postmeta
NOT EXISTS (
SELECT * FROM $table_postmeta
WHERE
meta_key = %s AND
post_id = pm5.post_id
)
)
)
)
",
\CommonsBooking\Model\Timeframe::REPETITION_START,
Expand Down
9 changes: 8 additions & 1 deletion src/View/Booking.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ public static function getTemplateData(): void {
}

/**
* @param int $postsPerPage
* @param \WP_User|null $user
*
* @return array|false|mixed
* @throws Exception
*/
public static function getBookingListData($postsPerPage = 6, $user = null) {
public static function getBookingListData( int $postsPerPage = 6, \WP_User $user = null) {

//sets selected user to current user when no specific user is passed
if ($user == null) {
Expand Down Expand Up @@ -326,6 +329,10 @@ public static function getBookingListiCal($user = null):String{

$user = get_user_by('id', $user);

if (!$user){
return false;
}

$bookingList = self::getBookingListData(999,$user);

//returns false when booking list is empty
Expand Down
Loading