Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/court-reservation/admin/class-courtres-admin.php
+++ b/court-reservation/admin/class-courtres-admin.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* The admin-specific functionality of the plugin.
@@ -271,7 +274,7 @@
$timeStep->add( new DateInterval( 'PT30M' ) );
}
- $dateStr = date( 'Y-m-d', strtotime( '+' . (int) $_REQUEST['day'] . ' day', $nowTZTS ) );
+ $dateStr = gmdate( 'Y-m-d', strtotime( '+' . (int) $_REQUEST['day'] . ' day', $nowTZTS ) );
$timeStep = clone $timeStart;
for ( $minStep = 30; $minStep <= $minuteplus; $minStep += 30 ) {
// check for blocks
@@ -281,7 +284,7 @@
$dayWeek = (int) $datetime->format( 'N' );
foreach ( $eventsBlocks as $eventBlock ) {
if ( $eventBlock->weekly_repeat == 1 ) {
- $dayWeekEvent = (int) date( 'N', strtotime( $eventBlock->event_date ) );
+ $dayWeekEvent = (int) gmdate( 'N', strtotime( $eventBlock->event_date ) );
if ( $dayWeekEvent != $dayWeek ) {
continue;
}
@@ -828,8 +831,12 @@
public function getCourtByID( $courtID ) {
global $wpdb;
+ $courtID = absint( $courtID );
+ if ( 0 === $courtID ) {
+ return null;
+ }
$table_courts = $this->getTable( 'courts' );
- return $wpdb->get_row( "SELECT * FROM $table_courts WHERE id = $courtID" );
+ return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_courts WHERE id = %d", $courtID ) );
}
/**
@@ -851,66 +858,59 @@
$order_by = $sql_where = $sql_wpuser_join = $sql_wpuser_select = '';
$sql_and_conditions = array();
- /* Order by */
+ $way_safe = in_array( strtoupper( $way ), array( 'ASC', 'DESC' ), true ) ? strtoupper( $way ) : 'DESC';
switch ( $order ) {
case 'court':
- $order_by = $this->getTable( 'courts' ) . '.name ';
+ $order_by = $this->getTable( 'courts' ) . '.name ' . $way_safe;
break;
case 'player':
- $order_by = $wpdb->users . '.display_name ';
+ $order_by = $wpdb->users . '.display_name ' . $way_safe;
break;
case 'date':
- $order_by = "reservations.date $way, reservations.time $way, reservations.minute";
+ $order_by = "reservations.date $way_safe, reservations.time $way_safe, reservations.minute $way_safe";
break;
case 'type':
- $order_by = 'reservations.type ';
+ $order_by = 'reservations.type ' . $way_safe;
break;
default:
- $order_by = "reservations.date $way, reservations.time $way, reservations.minute";
+ $order_by = "reservations.date $way_safe, reservations.time $way_safe, reservations.minute $way_safe";
}
- /*
- Filter */
- // if start_date is selected
+ $where_parts = array();
+ $prepare_args = array();
if ( $start_date ) {
- $start_date = date_i18n( 'Y-m-d H:i:s', strtotime( $start_date ), false );
- $sql_and_conditions[] = "`reservations`.date >= '$start_date'";
+ $where_parts[] = 'reservations.date >= %s';
+ $prepare_args[] = date_i18n( 'Y-m-d H:i:s', strtotime( $start_date ), false );
}
-
- // if start_date is selected
if ( $final_date ) {
- $final_date = date_i18n( 'Y-m-d H:i:s', strtotime( $final_date ), false );
- $sql_and_conditions[] = "`reservations`.date <= '$final_date'";
+ $where_parts[] = 'reservations.date <= %s';
+ $prepare_args[] = date_i18n( 'Y-m-d H:i:s', strtotime( $final_date ), false );
}
-
- // if reservation gid is selected
if ( $gid ) {
- $sql_and_conditions[] = "`reservations`.gid = '$gid'";
+ $where_parts[] = 'reservations.gid = %s';
+ $prepare_args[] = $gid;
}
+ $sql_where = $where_parts ? 'WHERE ' . implode( ' AND ', $where_parts ) : '';
- $sql_where = $sql_and_conditions ? 'WHERE ' . implode( ' AND ', $sql_and_conditions ) : '';
-
- /* Joins */
- $sql_courts_join = sprintf( ' LEFT JOIN %1$s ON %1$s.id = %2$s.courtid', $this->getTable( 'courts' ), 'reservations' );
- $sql_courts_select = sprintf( ', %1$s.name AS courtname', $this->getTable( 'courts' ) );
- $sql_rp_join = sprintf( ' LEFT JOIN %1$s ON %1$s.reservation_gid = %2$s.gid', $this->getTable( 'reserv_players' ), 'reservations' );
- $sql_rp_select = sprintf( ', GROUP_CONCAT(%1$s.player_id) AS players, GROUP_CONCAT(%1$s.is_author) AS is_author', $this->getTable( 'reserv_players' ) );
- $sql_wpuser_join = sprintf( ' LEFT JOIN %1$s ON %1$s.ID = %2$s.userid', $wpdb->users, 'reservations' );
- $sql_wpuser_select = sprintf( ', %1$s.display_name AS user_display_name', $wpdb->users );
-
- $group_by = ' GROUP BY `reservations`.id';
-
- /* Get reservations query */
- $res = $wpdb->get_results(
- "SELECT reservations.*{$sql_courts_select}{$sql_rp_select}{$sql_wpuser_select}
- FROM {$this->getTable('reservations')} as reservations
- {$sql_courts_join}
- {$sql_rp_join}
- {$sql_wpuser_join}
- {$sql_where}
- {$group_by}
- ORDER BY " . $order_by . ' ' . $way
- );
+ $table_reservations = $this->getTable( 'reservations' );
+ $table_courts = $this->getTable( 'courts' );
+ $table_reserv_players = $this->getTable( 'reserv_players' );
+ $base_sql = "SELECT reservations.*, {$table_courts}.name AS courtname, GROUP_CONCAT({$table_reserv_players}.player_id) AS players, GROUP_CONCAT({$table_reserv_players}.is_author) AS is_author, {$wpdb->users}.display_name AS user_display_name
+ FROM {$table_reservations} as reservations
+ LEFT JOIN {$table_courts} ON {$table_courts}.id = reservations.courtid
+ LEFT JOIN {$table_reserv_players} ON {$table_reserv_players}.reservation_gid = reservations.gid
+ LEFT JOIN {$wpdb->users} ON {$wpdb->users}.ID = reservations.userid
+ {$sql_where}
+ GROUP BY reservations.id
+ ORDER BY {$order_by}";
+
+ if ( $prepare_args ) {
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $base_sql built from trusted sources, placeholders in prepare_args
+ $res = $wpdb->get_results( $wpdb->prepare( $base_sql, $prepare_args ) );
+ } else {
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- no user input when prepare_args empty
+ $res = $wpdb->get_results( $base_sql );
+ }
// fppr($wpdb->last_query, __FILE__.' $wpdb->last_query');
// fppr($res, __FILE__.' $res');
@@ -941,12 +941,12 @@
public function getReservationByID( $reservationID ) {
global $wpdb;
- return $wpdb->get_row( "SELECT * FROM {$this->getTable('reservations')} WHERE id = $reservationID" );
+ return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$this->getTable('reservations')} WHERE id = %d", absint( $reservationID ) ) );
}
public function getReservationsByGID( $gid ) {
global $wpdb;
- return $wpdb->get_results( "SELECT * FROM {$this->getTable('reservations')} WHERE `gid` = '$gid'" );
+ return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$this->getTable('reservations')} WHERE `gid` = %s", $gid ) );
}
public function getReservationByUser( $userID ) {
@@ -985,7 +985,7 @@
if ( $res ) {
$reservations = $this->getReservationsByGID( $r->gid );
if ( ! count( $reservations ) ) {
- $wpdb->query( "DELETE FROM {$this->getTable('reserv_players')} WHERE `reservation_gid` = '" . $r->gid . "'" );
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->getTable('reserv_players')} WHERE `reservation_gid` = %s", $r->gid ) );
}
}
// < from 1.5.0
@@ -994,12 +994,10 @@
public function deleteReservationByDateGid( $sdt, $gid ) {
global $wpdb;
- $res = $wpdb->query( "DELETE FROM {$this->getTable('reservations')} WHERE DATE(date) = '$sdt' AND gid = '$gid'" );
- // from 1.5.0 >
+ $res = $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->getTable('reservations')} WHERE DATE(date) = %s AND gid = %s", $sdt, $gid ) );
if ( $res ) {
- $wpdb->query( "DELETE FROM {$this->getTable('reserv_players')} WHERE `reservation_gid` = '$gid'" );
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->getTable('reserv_players')} WHERE `reservation_gid` = %s", $gid ) );
}
- // < from 1.5.0
}
public function cleanUpReservations() {
@@ -1015,16 +1013,19 @@
// $wpdb->get_results('SET @@time_zone = "'.$theTime["offset"].'";');
return $wpdb->get_results(
- "SELECT * FROM {$this->getTable('reservations')} WHERE courtid = $courtID AND
+ $wpdb->prepare(
+ "SELECT * FROM {$this->getTable('reservations')} WHERE courtid = %d AND
date >= CURDATE()
- ORDER BY date, time"
+ ORDER BY date, time",
+ absint( $courtID )
+ )
);
}
public function getBlocksByID( $courtID ) {
global $wpdb;
$table_blocks = $this->getTable( 'events' );
- return $wpdb->get_results( "SELECT * FROM $table_blocks WHERE courtid = $courtID ORDER BY dow" );
+ return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $table_blocks WHERE courtid = %d ORDER BY dow", absint( $courtID ) ) );
}
private function getWeekdays() {
@@ -1142,7 +1143,7 @@
public function getOption( $name ) {
global $wpdb;
$table_name = $this->getTable( 'settings' );
- $res = $wpdb->get_row( "SELECT * FROM $table_name WHERE option_name = '" . $name . "'" );
+ $res = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE option_name = %s", $name ) );
return $res;
}
@@ -1273,7 +1274,7 @@
if ( $params['is_event_weekly_repeat'] == 1 ) {
$curEventDateWeek = $params['event_date_week'];
- $last_sundy = date( 'Y-m-d', strtotime( 'last sunday' ) );
+ $last_sundy = gmdate( 'Y-m-d', strtotime( 'last sunday' ) );
$event_timestamp = strtotime( $last_sundy . '+ ' . $curEventDateWeek . ' days' );
$params['event_date'] = date_i18n( 'Y-m-d', $event_timestamp );
}
@@ -1401,8 +1402,13 @@
case 'events':
global $wpdb;
- $sql_where = sprintf( ' WHERE events.end_ts < %d AND weekly_repeat = 0', (int) current_time( 'timestamp' ) );
- $results = $wpdb->get_results( sprintf( 'SELECT events.* FROM %s as events%s ORDER BY `end_ts` DESC', $this->getTable( 'events' ), $sql_where ) );
+ $results = $wpdb->get_results(
+ $wpdb->prepare(
+ 'SELECT events.* FROM %i as events WHERE events.end_ts < %d AND weekly_repeat = 0 ORDER BY end_ts DESC',
+ $this->getTable( 'events' ),
+ (int) current_time( 'timestamp' )
+ )
+ );
break;
case 'challenges':
--- a/court-reservation/admin/partials/__courtres-settings.php
+++ b/court-reservation/admin/partials/__courtres-settings.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -463,7 +466,7 @@
$option_is_email_template_updated->option_name = 'option_is_email_template_updated';
$option_is_email_template_updated->option_value = true;
$message_type = 'warning';
- $message = __( 'Court Reservation Plugin: You need to update your template for E-Mail notifications!', 'courtres' );
+ $message = __( 'Court Reservation Plugin: You need to update your template for E-Mail notifications!', 'court-reservation' );
}
// option_email_template
--- a/court-reservation/admin/partials/courtres-challenges.php
+++ b/court-reservation/admin/partials/courtres-challenges.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -98,8 +101,8 @@
<div class="wrap">
<h1 class="wp-heading-inline"><?php echo esc_html__( 'Challenges', 'court-reservation' ); ?></h1>
<div class="cr-head-right">
- <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-challenges&view-expired=1' )); ?>" class="button button-secondary action<?php echo ( $is_view_expired ? ' active' : '' ); ?>"><?php esc_html_e( 'View Expired', 'courtres' ); ?></a>
- <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-challenges' )); ?>" class="button button-secondary action"><span class="dashicons dashicons-no-alt" style="vertical-align: -5px;"></span><?php esc_html_e( 'Clear Filter', 'courtres' ); ?></a>
+ <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-challenges&view-expired=1' )); ?>" class="button button-secondary action<?php echo ( $is_view_expired ? ' active' : '' ); ?>"><?php esc_html_e( 'View Expired', 'court-reservation' ); ?></a>
+ <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-challenges' )); ?>" class="button button-secondary action"><span class="dashicons dashicons-no-alt" style="vertical-align: -5px;"></span><?php esc_html_e( 'Clear Filter', 'court-reservation' ); ?></a>
<form method="post" action="<?php echo esc_url(admin_url( 'admin-ajax.php' )); ?>">
<?php wp_nonce_field( 'export_expired', 'export_expired_nonce' ); ?>
<input type="hidden" name="target" value="challenges" />
--- a/court-reservation/admin/partials/courtres-court.php
+++ b/court-reservation/admin/partials/courtres-court.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -128,7 +131,7 @@
if (isset($courtID) && is_numeric($courtID))
{
$courtres_option_closed_name = "option_closed_court_" . (int) $courtID;
- $database_closed_court = $wpdb->get_row( "SELECT * FROM $table_settings WHERE option_name = '$courtres_option_closed_name' ORDER BY `option_id` DESC LIMIT 1" );
+ $database_closed_court = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_settings WHERE option_name = %s ORDER BY `option_id` DESC LIMIT 1", $courtres_option_closed_name ) );
if ( $database_closed_court !== null && $form_closed_court != '' ) {
$wpdb->update(
@@ -180,7 +183,7 @@
$courtres_option_payment = "option_payment_" . (int) $courtID;
- $database_payment = $wpdb->get_row( "SELECT * FROM $table_settings WHERE option_name = '$courtres_option_payment' ORDER BY `option_id` DESC LIMIT 1" );
+ $database_payment = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_settings WHERE option_name = %s ORDER BY `option_id` DESC LIMIT 1", $courtres_option_payment ) );
if ( $database_payment !== null && $form_payment != '' ) {
$wpdb->update(
@@ -230,7 +233,7 @@
}
$courtres_option_payment_id = "option_payment_id_" . (int) $courtID;
- $database_payment_id = $wpdb->get_row( "SELECT * FROM $table_settings WHERE option_name = '$courtres_option_payment_id' ORDER BY `option_id` DESC LIMIT 1" );
+ $database_payment_id = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_settings WHERE option_name = %s ORDER BY `option_id` DESC LIMIT 1", $courtres_option_payment_id ) );
if ( $database_payment_id !== null && $form_payment_id != '' ) {
$wpdb->update(
@@ -281,7 +284,7 @@
}
if ( isset( $courtID ) && $courtID > 0 ) {
- $court = $wpdb->get_row( "SELECT * FROM $table_name WHERE id = $courtID" );
+ $court = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", absint( $courtID ) ) );
}
if ( ! isset( $court ) ) {
--- a/court-reservation/admin/partials/courtres-courts.php
+++ b/court-reservation/admin/partials/courtres-courts.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-emailtemplate.php
+++ b/court-reservation/admin/partials/courtres-emailtemplate.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-emailtemplatepreview.php
+++ b/court-reservation/admin/partials/courtres-emailtemplatepreview.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-event.php
+++ b/court-reservation/admin/partials/courtres-event.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -231,13 +234,13 @@
// Defaults
$event = false;
if ( isset( $eventID ) && $eventID ) {
- $event = $wpdb->get_row( "SELECT * FROM $table_name WHERE id = $eventID" );
+ $event = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", absint( $eventID ) ) );
}
if ( $event ) {
$event->event_date = $event->event_date == '0000-00-00' ? '' : mysql2date( 'd-m-Y', $event->event_date );
$event->start_m = $event->start_ts ? date_i18n( 'i', $event->start_ts ) : '';
$event->end_m = $event->end_ts ? date_i18n( 'i', $event->end_ts ) : '';
- if ($event->weekly_repeat!=1) { $event->dow = $event->dow ? $event->dow : date( 'w', strtotime( $event->event_date ) ); }
+ if ($event->weekly_repeat!=1) { $event->dow = $event->dow ? $event->dow : gmdate( 'w', strtotime( $event->event_date ) ); }
if ( $event->type == 'challenge' ) {
$message_errors[] = __( 'You can not edit challenges here' );
}
@@ -397,19 +400,19 @@
<select name="weekly_start_<?php echo $courtres_weekly_2; ?>" id="weekly_start_<?php echo $courtres_weekly_2; ?>">
<?php
- if (date('l') == $courtres_weekly_3) { $courtres_weekly_5 = "today"; }
+ if (gmdate('l') == $courtres_weekly_3) { $courtres_weekly_5 = "today"; }
else { $courtres_weekly_5 = "Next " . $courtres_weekly_3; }
$courtres_weekly_6 = strtotime($courtres_weekly_5, time());
if (isset($event->event_first_date) && $event->event_first_date != "")
{ $event_first_date = $event->event_first_date; } else { $event_first_date = "1970-01-01"; }
?>
- <option value="<?php echo date('Y-m-d', $courtres_weekly_6); ?>" <?php selected( date('Y-m-d', $courtres_weekly_6), $event_first_date ); ?>><?php echo date('d. m. Y. ', $courtres_weekly_6); ?></option>
+ <option value="<?php echo gmdate('Y-m-d', $courtres_weekly_6); ?>" <?php selected( gmdate('Y-m-d', $courtres_weekly_6), $event_first_date ); ?>><?php echo gmdate('d. m. Y. ', $courtres_weekly_6); ?></option>
<?php for ($weeks=1;$weeks<=51;$weeks++)
{
$courtres_weekly_6 = strtotime('+1 Week', $courtres_weekly_6); ?>
- <option value="<?php echo date('Y-m-d', $courtres_weekly_6); ?>" <?php selected( date('Y-m-d', $courtres_weekly_6), $event_first_date ); ?> ><?php echo date('d. m. Y. ', $courtres_weekly_6); ?></option>
+ <option value="<?php echo gmdate('Y-m-d', $courtres_weekly_6); ?>" <?php selected( gmdate('Y-m-d', $courtres_weekly_6), $event_first_date ); ?> ><?php echo gmdate('d. m. Y. ', $courtres_weekly_6); ?></option>
<?php } ?>
</select>
@@ -426,12 +429,12 @@
{ $event_last_date = $event->event_last_date; } else { $event_last_date = "1970-01-01"; }
?>
- <option value="<?php echo date('Y-m-d', $courtres_weekly_7); ?>" <?php selected( date('Y-m-d', $courtres_weekly_7), $event_last_date ); ?>><?php echo date('d. m. Y. ', $courtres_weekly_7); ?></option>
+ <option value="<?php echo gmdate('Y-m-d', $courtres_weekly_7); ?>" <?php selected( gmdate('Y-m-d', $courtres_weekly_7), $event_last_date ); ?>><?php echo gmdate('d. m. Y. ', $courtres_weekly_7); ?></option>
<?php for ($weeks=1;$weeks<=51;$weeks++)
{
$courtres_weekly_7 = strtotime('+1 Week', $courtres_weekly_7); ?>
- <option value="<?php echo date('Y-m-d', $courtres_weekly_7); ?>" <?php selected( date('Y-m-d', $courtres_weekly_7), $event_last_date ); ?>><?php echo date('d. m. Y. ', $courtres_weekly_7); ?></option>
+ <option value="<?php echo gmdate('Y-m-d', $courtres_weekly_7); ?>" <?php selected( gmdate('Y-m-d', $courtres_weekly_7), $event_last_date ); ?>><?php echo gmdate('d. m. Y. ', $courtres_weekly_7); ?></option>
<?php } ?>
</select>
--- a/court-reservation/admin/partials/courtres-events.php
+++ b/court-reservation/admin/partials/courtres-events.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -157,7 +160,7 @@
$period .= ' - ' . date_i18n( 'H:i', $item->end_ts );
}
?>
- <tr class="<?php echo ( ( $item->weekly_repeat != 1 ) && $item->event_date < date( 'Y-m-d' ) ) ? 'event-expired' : ''; ?>">
+ <tr class="<?php echo ( ( $item->weekly_repeat != 1 ) && $item->event_date < gmdate( 'Y-m-d' ) ) ? 'event-expired' : ''; ?>">
<td>
<?php echo esc_html( $item->name ); ?>
</td>
@@ -165,7 +168,7 @@
<?php
if ( $tab == '1' ) {
?>
- <td><?php echo esc_html($days[ date( 'w', strtotime( $item->event_date ) ) ]); ?></td>
+ <td><?php echo esc_html($days[ gmdate( 'w', strtotime( $item->event_date ) ) ]); ?></td>
<?php
} else {
?>
--- a/court-reservation/admin/partials/courtres-members.php
+++ b/court-reservation/admin/partials/courtres-members.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-notice-message.php
+++ b/court-reservation/admin/partials/courtres-notice-message.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide notice for message in admin view
--- a/court-reservation/admin/partials/courtres-notice-upgrade.php
+++ b/court-reservation/admin/partials/courtres-notice-upgrade.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide notice for pro-upgrade in admin view
--- a/court-reservation/admin/partials/courtres-piramid.php
+++ b/court-reservation/admin/partials/courtres-piramid.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-piramids.php
+++ b/court-reservation/admin/partials/courtres-piramids.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-reservations.php
+++ b/court-reservation/admin/partials/courtres-reservations.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -109,9 +112,9 @@
<label for="datepicker-final-date">Gid</label>
<input id="gid" name="gid" class="" type="text" placeholder="Enter gid" value="<?php echo ( isset( $get_gid ) && $get_gid != '' ) ? esc_attr( $get_gid ) : ''; ?>" autocomplete="off">
- <input type="submit" id="datepicker-doaction" class="button action" value="<?php esc_html_e( 'Filter', 'courtres' ); ?>">
- <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-reservations&view-expired=1' )); ?>" class="button button-secondary action<?php echo ( $is_view_expired ? ' active' : '' ); ?>"><?php esc_html_e( 'View Expired', 'courtres' ); ?></a>
- <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-reservations' )); ?>" class="button button-secondary action"><span class="dashicons dashicons-no-alt" style="vertical-align: -5px;"></span><?php esc_html_e( 'Clear Filter', 'courtres' ); ?></a>
+ <input type="submit" id="datepicker-doaction" class="button action" value="<?php esc_html_e( 'Filter', 'court-reservation' ); ?>">
+ <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-reservations&view-expired=1' )); ?>" class="button button-secondary action<?php echo ( $is_view_expired ? ' active' : '' ); ?>"><?php esc_html_e( 'View Expired', 'court-reservation' ); ?></a>
+ <a href="<?php echo esc_url(admin_url( 'admin.php?page=courtres-reservations' )); ?>" class="button button-secondary action"><span class="dashicons dashicons-no-alt" style="vertical-align: -5px;"></span><?php esc_html_e( 'Clear Filter', 'court-reservation' ); ?></a>
</form>
<p> </p>
</div>
--- a/court-reservation/admin/partials/courtres-settings.php
+++ b/court-reservation/admin/partials/courtres-settings.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -533,7 +536,7 @@
$reservationTypes = unserialize( $option_reservation_types->option_value );
$mlReservationTypes = array();
foreach ( $reservationTypes as $type ) {
- $mlReservationTypes[] = esc_html__( $type, 'court-reservation' );
+ $mlReservationTypes[] = esc_html( translate( $type, 'court-reservation' ) );
}
// Available reservation types
@@ -557,7 +560,7 @@
$option_is_email_template_updated->option_name = 'option_is_email_template_updated';
$option_is_email_template_updated->option_value = true;
$message_type = 'warning';
- $message = __( 'Court Reservation Plugin: You need to update your template for E-Mail notifications!', 'courtres' );
+ $message = __( 'Court Reservation Plugin: You need to update your template for E-Mail notifications!', 'court-reservation' );
}
// option_email_template
@@ -829,7 +832,7 @@
<ul class="cr-reserv-type-list">
<?php foreach ( $reservationTypes as $type ) : ?>
<li>
- <label for="<?php echo esc_attr( $type ); ?>"><span><?php echo esc_html_e( $type, 'court-reservation' ); ?></span></label>
+ <label for="<?php echo esc_attr( $type ); ?>"><span><?php echo esc_html( translate( $type, 'court-reservation' ) ); ?></span></label>
<label class="switch">
<input type="checkbox" id="<?php echo esc_attr( $type ); ?>" name="option_available_reservation_types[<?php echo esc_attr( $type ); ?>]" <?php if (is_array($availableReservationTypes)) { checked( in_array( $type, $availableReservationTypes ) ); } ?> value="<?php echo esc_attr( $type ); ?>">
<span class="slider round"></span>
--- a/court-reservation/admin/partials/courtres-ui.php
+++ b/court-reservation/admin/partials/courtres-ui.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-upgrade.php
+++ b/court-reservation/admin/partials/courtres-upgrade.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-user.php
+++ b/court-reservation/admin/partials/courtres-user.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
--- a/court-reservation/admin/partials/courtres-users.php
+++ b/court-reservation/admin/partials/courtres-users.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide a admin area view for the plugin
@@ -263,10 +266,13 @@
}
$users_have_content = false;
- if ( $wpdb->get_var( "SELECT ID FROM {$wpdb->posts} WHERE post_author IN( " . implode( ',', $userids ) . ' ) LIMIT 1' ) ) {
- $users_have_content = true;
- } elseif ( $wpdb->get_var( "SELECT link_id FROM {$wpdb->links} WHERE link_owner IN( " . implode( ',', $userids ) . ' ) LIMIT 1' ) ) {
- $users_have_content = true;
+ if ( ! empty( $userids ) ) {
+ $placeholders = implode( ',', array_fill( 0, count( $userids ), '%d' ) );
+ if ( $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM %i WHERE post_author IN ($placeholders) LIMIT 1", $wpdb->posts, ...$userids ) ) ) {
+ $users_have_content = true;
+ } elseif ( $wpdb->get_var( $wpdb->prepare( "SELECT link_id FROM %i WHERE link_owner IN ($placeholders) LIMIT 1", $wpdb->links, ...$userids ) ) ) {
+ $users_have_content = true;
+ }
}
if ( $users_have_content ) {
--- a/court-reservation/admin/partials/courtres-widget-upgrade.php
+++ b/court-reservation/admin/partials/courtres-widget-upgrade.php
@@ -1,4 +1,7 @@
<?php
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
/**
* Provide notice for pro-upgrade in admin view
--- a/court-reservation/courtres.php
+++ b/court-reservation/courtres.php
@@ -16,7 +16,7 @@
* Plugin Name: Court Reservation
* Plugin URI: https://www.courtreservation.io
* Description: Reservation system for tennis, squash and badminton
- * Version: 1.10.11
+ * Version: 1.10.12
* Author: Webmühle e.U.
* Author URI: https://www.webmuehle.at
* License: GPL-2.0+
@@ -30,88 +30,17 @@
die;
}
-// Auto deactivation of free when premium is active
+// Auto deactivation of free when premium is active (premium defines cr_fs first)
if ( function_exists( 'cr_fs' ) ) {
cr_fs()->set_basename( true, __FILE__ );
return;
}
-// Integration of Freemius SDK
+// WordPress.org build: Freemius stub (no custom updater). Premium build uses full Freemius SDK.
if ( ! function_exists( 'cr_fs' ) ) {
- // Create a helper function for easy SDK access.
+ require_once dirname( __FILE__ ) . '/includes/class-courtres-freemius-stub.php';
function cr_fs() {
- global $cr_fs;
-
- if ( ! isset( $cr_fs ) ) {
- // Include Freemius SDK.
- require_once dirname( __FILE__ ) . '/freemius/start.php';
-
- $cr_fs = fs_dynamic_init(
- array(
- 'id' => '3086',
- 'slug' => 'court-reservation',
- 'type' => 'plugin',
- 'public_key' => 'pk_b5c504d97853f6130b63fd7344155',
- 'is_premium' => true,
- 'premium_suffix' => 'Premium',
- // If your plugin is a serviceware, set this option to false.
- 'has_premium_version' => true,
- 'has_addons' => false,
- 'has_paid_plans' => true,
- 'show_monthly_switch' => true,
- 'menu' => array(
- 'first-path' => 'plugins.php',
- 'contact' => false,
- 'support' => false,
- ),
- // Set the SDK to work in a sandbox mode (for development & testing).
- // IMPORTANT: MAKE SURE TO REMOVE SECRET KEY BEFORE DEPLOYMENT.
- 'secret_key' => 'sk_GyAY<fJ+WHceE6Qzp{N+RYJk4BH%8',
- )
- );
- }
-
- return $cr_fs;
- }
-
- // Init Freemius.
- cr_fs();
- // Signal that SDK was initiated.
- do_action( 'cr_fs_loaded' );
-}
-
-// Uninstalling
-if ( function_exists( 'cr_fs' ) ) {
- cr_fs()->add_action( 'after_uninstall', 'cr_fs_uninstall_cleanup' );
- function cr_fs_uninstall_cleanup() {
- remove_role( 'player' );
- remove_role( 'guest_player' );
-
- $role = get_role( 'administrator' );
- $role->remove_cap( 'place_reservation', true );
-
- // remove tables
- global $wpdb;
-
- // courts table
- $table_name = $wpdb->prefix . 'courtres_settings';
- $sql = "DROP TABLE IF EXISTS $table_name";
- $wpdb->query( $sql );
-
- // reservations table
- $table_name = $wpdb->prefix . 'courtres_reservations';
- $sql = "DROP TABLE IF EXISTS $table_name";
- $wpdb->query( $sql );
-
- // events table
- $table_name = $wpdb->prefix . 'courtres_events';
- $sql = "DROP TABLE IF EXISTS $table_name";
- $wpdb->query( $sql );
-
- // courts table
- $table_name = $wpdb->prefix . 'courtres_courts';
- $sql = "DROP TABLE IF EXISTS $table_name";
- $wpdb->query( $sql );
+ return Courtres_Freemius_Stub::instance();
}
}
@@ -120,7 +49,7 @@
* Start at version 1.0.4 and use SemVer - https://semver.org
* Rename this for your plugin and update it as you release new versions.
*/
-define( 'Court_Reservation', '1.10.11' );
+define( 'Court_Reservation', '1.10.12' );
require_once plugin_dir_path( __FILE__ ) . 'functions.php';
--- a/court-reservation/freemius/includes/class-freemius.php
+++ b/court-reservation/freemius/includes/class-freemius.php
@@ -110,6 +110,12 @@
private $_enable_anonymous = true;
/**
+ * @since 2.9.1
+ * @var string|null Hints the SDK whether the plugin supports parallel activation mode, preventing the auto-deactivation of the free version when the premium version is activated, and vice versa.
+ */
+ private $_premium_plugin_basename_from_parallel_activation;
+
+ /**
* @since 1.1.7.5
* @var bool Hints the SDK if plugin should run in anonymous mode (only adds feedback form).
*/
@@ -1651,6 +1657,31 @@
);
}
}
+
+ if (
+ $this->is_user_in_admin() &&
+ $this->is_parallel_activation() &&
+ $this->_premium_plugin_basename !== $this->_premium_plugin_basename_from_parallel_activation
+ ) {
+ $this->_premium_plugin_basename = $this->_premium_plugin_basename_from_parallel_activation;
+
+ register_activation_hook(
+ dirname( $this->_plugin_dir_path ) . '/' . $this->_premium_plugin_basename,
+ array( &$this, '_activate_plugin_event_hook' )
+ );
+ }
+ }
+
+ /**
+ * Determines if a plugin is running in parallel activation mode.
+ *
+ * @author Leo Fajardo (@leorw)
+ * @since 2.9.1
+ *
+ * @return bool
+ */
+ private function is_parallel_activation() {
+ return ! empty( $this->_premium_plugin_basename_from_parallel_activation );
}
/**
@@ -3598,7 +3629,7 @@
$this->delete_current_install( false );
- $license_key = false;
+ $license = null;
if (
is_object( $this->_license ) &&
@@ -3606,20 +3637,21 @@
( WP_FS__IS_LOCALHOST_FOR_SERVER || FS_Site::is_localhost_by_address( self::get_unfiltered_site_url() ) )
)
) {
- $license_key = $this->_license->secret_key;
+ $license = $this->_license;
}
return $this->opt_in(
false,
false,
false,
- $license_key,
+ ( is_object( $license ) ? $license->secret_key : false ),
false,
false,
false,
null,
array(),
- false
+ false,
+ ( is_object( $license ) ? $license->user_id : null )
);
}
@@ -4463,33 +4495,31 @@
return;
}
- if ( $this->has_api_connectivity() ) {
- if ( self::is_cron() ) {
- $this->hook_callback_to_sync_cron();
- } else if ( $this->is_user_in_admin() ) {
- /**
- * Schedule daily data sync cron if:
- *
- * 1. User opted-in (for tracking).
- * 2. If skipped, but later upgraded (opted-in via upgrade).
- *
- * @author Vova Feldman (@svovaf)
- * @since 1.1.7.3
- *
- */
- if ( $this->is_registered() && $this->is_tracking_allowed() ) {
- $this->maybe_schedule_sync_cron();
- }
+ $this->hook_callback_to_sync_cron();
- /**
- * Check if requested for manual blocking background sync.
- */
- if ( fs_request_has( 'background_sync' ) ) {
- self::require_pluggable_essentials();
- self::wp_cookie_constants();
+ if ( $this->has_api_connectivity() && ! self::is_cron() && $this->is_user_in_admin() ) {
+ /**
+ * Schedule daily data sync cron if:
+ *
+ * 1. User opted-in (for tracking).
+ * 2. If skipped, but later upgraded (opted-in via upgrade).
+ *
+ * @author Vova Feldman (@svovaf)
+ * @since 1.1.7.3
+ *
+ */
+ if ( $this->is_registered() && $this->is_tracking_allowed() ) {
+ $this->maybe_schedule_sync_cron();
+ }
- $this->run_manual_sync();
- }
+ /**
+ * Check if requested for manual blocking background sync.
+ */
+ if ( fs_request_has( 'background_sync' ) ) {
+ self::require_pluggable_essentials();
+ self::wp_cookie_constants();
+
+ $this->run_manual_sync();
}
}
@@ -5155,11 +5185,35 @@
$this->_plugin :
new FS_Plugin();
+ $is_premium = $this->get_bool_option( $plugin_info, 'is_premium', true );
$premium_suffix = $this->get_option( $plugin_info, 'premium_suffix', '(Premium)' );
+ $module_type = $this->get_option( $plugin_info, 'type', $this->_module_type );
+
+ $parallel_activation = $this->get_option( $plugin_info, 'parallel_activation' );
+
+ if (
+ ! $is_premium &&
+ is_array( $parallel_activation ) &&
+ ( WP_FS__MODULE_TYPE_PLUGIN === $module_type ) &&
+ $this->get_bool_option( $parallel_activation, 'enabled' )
+ ) {
+ $premium_basename = $this->get_option( $parallel_activation, 'premium_version_basename' );
+
+ if ( empty( $premium_basename ) ) {
+ throw new Exception('You need to specify the premium version basename to enable parallel version activation.');
+ }
+
+ $this->_premium_plugin_basename_from_parallel_activation = $premium_basename;
+
+ if ( is_plugin_active( $premium_basename ) ) {
+ $is_premium = true;
+ }
+ }
+
$plugin->update( array(
'id' => $id,
- 'type' => $this->get_option( $plugin_info, 'type', $this->_module_type ),
+ 'type' => $module_type,
'public_key' => $public_key,
'slug' => $this->_slug,
'premium_slug' => $this->get_option( $plugin_info, 'premium_slug', "{$this->_slug}-premium" ),
@@ -5167,7 +5221,7 @@
'version' => $this->get_plugin_version(),
'title' => $this->get_plugin_name( $premium_suffix ),
'file' => $this->_plugin_basename,
- 'is_premium' => $this->get_bool_option( $plugin_info, 'is_premium', true ),
+ 'is_premium' => $is_premium,
'premium_suffix' => $premium_suffix,
'is_live' => $this->get_bool_option( $plugin_info, 'is_live', true ),
'affiliate_moderation' => $this->get_option( $plugin_info, 'has_affiliation' ),
@@ -5236,7 +5290,14 @@
$this->_anonymous_mode = false;
} else {
$this->_enable_anonymous = $this->get_bool_option( $plugin_info, 'enable_anonymous', true );
- $this->_anonymous_mode = $this->get_bool_option( $plugin_info, 'anonymous_mode', false );
+ $this->_anonymous_mode = (
+ $this->get_bool_option( $plugin_info, 'anonymous_mode', false ) ||
+ (
+ $this->apply_filters( 'playground_anonymous_mode', true ) &&
+ ! empty( $_SERVER['HTTP_HOST'] ) &&
+ FS_Site::is_playground_wp_environment_by_host( $_SERVER['HTTP_HOST'] )
+ )
+ );
}
$this->_permissions = $this->get_option( $plugin_info, 'permissions', array() );
$this->_is_bundle_license_auto_activation_enabled = $this->get_option( $plugin_info, 'bundle_license_auto_activation', false );
@@ -5444,7 +5505,7 @@
if ( $this->is_registered() ) {
// Schedule code type changes event.
- $this->schedule_install_sync();
+ $this->maybe_schedule_install_sync_cron();
}
/**
@@ -6508,6 +6569,33 @@
}
/**
+ * Instead of running blocking install sync event, execute non blocking scheduled cron job.
+ *
+ * @param int $except_blog_id Since 2.0.0 when running in a multisite network environment, the cron execution is consolidated. This param allows excluding specified blog ID from being the cron job executor.
+ *
+ * @author Leo Fajardo (@leorw)
+ * @since 2.9.1
+ */
+ private function maybe_schedule_install_sync_cron( $except_blog_id = 0 ) {
+ if ( ! $this->is_user_in_admin() ) {
+ return;
+ }
+
+ if ( $this->is_clone() ) {
+ return;
+ }
+
+ if (
+ // The event has been properly scheduled, so no need to reschedule it.
+ is_numeric( $this->next_install_sync() )
+ ) {
+ return;
+ }
+
+ $this->schedule_cron( 'install_sync', 'install_sync', 'single', WP_FS__SCRIPT_START_TIME, false, $except_blog_id );
+ }
+
+ /**
* @author Vova Feldman (@svovaf)
* @since 1.1.7.3
*
@@ -6605,22 +6693,6 @@
}
/**
- * Instead of running blocking install sync event, execute non blocking scheduled wp-cron.
- *
- * @author Vova Feldman (@svovaf)
- * @since 1.1.7.3
- *
- * @param int $except_blog_id Since 2.0.0 when running in a multisite network environment, the cron execution is consolidated. This param allows excluding excluded specified blog ID from being the cron executor.
- */
- private function schedule_install_sync( $except_blog_id = 0 ) {
- if ( $this->is_clone() ) {
- return;
- }
-
- $this->schedule_cron( 'install_sync', 'install_sync', 'single', WP_FS__SCRIPT_START_TIME, false, $except_blog_id );
- }
-
- /**
* Unix timestamp for previous install sync cron execution or false if never executed.
*
* @todo There's some very strange bug that $this->_storage->install_sync_timestamp value is not being updated. But for sure the sync event is working.
@@ -7411,7 +7483,7 @@
*/
if (
is_plugin_active( $other_version_basename ) &&
- $this->apply_filters( 'deactivate_on_activation', true )
+ $this->apply_filters( 'deactivate_on_activation', ! $this->is_parallel_activation() )
) {
deactivate_plugins( $other_version_basename );
}
@@ -7425,7 +7497,7 @@
// Schedule re-activation event and sync.
// $this->sync_install( array(), true );
- $this->schedule_install_sync();
+ $this->maybe_schedule_install_sync_cron();
// If activating the premium module version, add an admin notice to congratulate for an upgrade completion.
if ( $is_premium_version_activation ) {
@@ -7586,7 +7658,14 @@
$parent_fs->get_current_or_network_user()->email,
false,
false,
- $license->secret_key
+ $license->secret_key,
+ false,
+ false,
+ false,
+ null,
+ array(),
+ true,
+ $license->user_id
);
} else {
// Activate the license.
@@ -7650,7 +7729,9 @@
false,
false,
null,
- $sites
+ $sites,
+ true,
+ $license->user_id
);
} else {
$blog_2_install_map = array();
@@ -7704,7 +7785,7 @@
* @param array $sites
* @param int $blog_id
*/
- private function maybe_activate_bundle_license( FS_Plugin_License $license = null, $sites = array(), $blog_id = 0 ) {
+ private function maybe_activate_bundle_license( $license = null, $sites = array(), $blog_id = 0 ) {
if ( ! is_object( $license ) && $this->has_active_valid_license() ) {
$license = $this->_license;
}
@@ -7876,7 +7957,8 @@
null,
null,
$sites,
- ( $current_blog_id > 0 ? $current_blog_id : null )
+ ( $current_blog_id > 0 ? $current_blog_id : null ),
+ $license->user_id
);
}
}
@@ -8616,7 +8698,7 @@
return;
}
- $this->schedule_install_sync();
+ $this->maybe_schedule_install_sync_cron();
// $this->sync_install( array(), true );
}
@@ -8757,8 +8839,13 @@
isset( $site_active_plugins[ $basename ] )
) {
// Plugin was site level activated.
- $site_active_plugins_cache->plugins[ $basename ] = $network_plugins[ $basename ];
- $site_active_plugins_cache->plugins[ $basename ]['is_active'] = true;
+ $site_active_plugins_cache->plugins[ $basename ] = array(
+ 'slug' => $network_plugins[ $basename ]['slug'],
+ 'version' => $network_plugins[ $basename ]['Version'],
+ 'title' => $network_plugins[ $basename ]['Name'],
+ 'is_active' => $is_active,
+ 'is_uninstalled' => false,
+ );
} else if ( isset( $site_active_plugins_cache->plugins[ $basename ] ) &&
! isset( $site_active_plugins[ $basename ] )
) {
@@ -11503,7 +11590,7 @@
continue;
}
- $missing_plan = self::_get_plan_by_id( $plan_id );
+ $missing_plan = self::_get_plan_by_id( $plan_id, false );
if ( is_object( $missing_plan ) ) {
$plans[] = $missing_plan;
@@ -11665,10 +11752,10 @@
*
* @return FS_Plugin_Plan|false
*/
- function _get_plan_by_id( $id ) {
+ function _get_plan_by_id( $id, $allow_sync = true ) {
$this->_logger->entrance();
- if ( ! is_array( $this->_plans ) || 0 === count( $this->_plans ) ) {
+ if ( $allow_sync && ( ! is_array( $this->_plans ) || 0 === count( $this->_plans ) ) ) {
$this->_sync_plans();
}
@@ -12312,7 +12399,7 @@
*
* @param FS_Plugin_License $license
*/
- private function set_license( FS_Plugin_License $license = null ) {
+ private function set_license( $license = null ) {
$this->_license = $license;
$this->maybe_update_whitelabel_flag( $license );
@@ -13412,7 +13499,8 @@
fs_request_get( 'module_id', null, 'post' ),
fs_request_get( 'user_id', null ),
fs_request_get_bool( 'is_extensions_tracking_allowed', null ),
- fs_request_get_bool( 'is_diagnostic_tracking_allowed', null )
+ fs_request_get_bool( 'is_diagnostic_tracking_allowed', null ),
+ fs_request_get( 'license_owner_id', null )
);
if (
@@ -13561,6 +13649,7 @@
* @param null|number $plugin_id
* @param array $sites
* @param int $blog_id
+ * @param null|number $license_owner_id
*
* @return array {
* @var bool $success
@@ -13575,7 +13664,8 @@
$is_marketing_allowed = null,
$plugin_id = null,
$sites = array(),
- $blog_id = null
+ $blog_id = null,
+ $license_owner_id = null
) {
$this->_logger->entrance();
@@ -13586,7 +13676,11 @@
$sites,
$is_marketing_allowed,
$blog_id,
- $plugin_id
+ $plugin_id,
+ null,
+ null,
+ null,
+ $license_owner_id
);
// No need to show the sticky after license activation notice after migrating a license.
@@ -13660,9 +13754,10 @@
* @param null|bool $is_marketing_allowed
* @param null|int $blog_id
* @param null|number $plugin_id
- * @param null|number $license_owner_id
+ * @param null|number $user_id
* @param bool|null $is_extensions_tracking_allowed
* @param bool|null $is_diagnostic_tracking_allowed Since 2.5.0.2 to allow license activation with minimal data footprint.
+ * @param null|number $license_owner_id
*
*
* @return array {
@@ -13677,9 +13772,10 @@
$is_marketing_allowed = null,
$blog_id = null,
$plugin_id = null,
- $license_owner_id = null,
+ $user_id = null,
$is_extensions_tracking_allowed = null,
- $is_diagnostic_tracking_allowed = null
+ $is_diagnostic_tracking_allowed = null,
+ $license_owner_id = null
) {
$this->_logger->entrance();
@@ -13768,10 +13864,10 @@
$install_ids = array();
- $change_owner = FS_User::is_valid_id( $license_owner_id );
+ $change_owner = FS_User::is_valid_id( $user_id );
if ( $change_owner ) {
- $params['user_id'] = $license_owner_id;
+ $params['user_id'] = $user_id;
$installs_info_by_slug_map = $fs->get_parent_and_addons_installs_info();
@@ -13847,7 +13943,9 @@
false,
false,
$is_marketing_allowed,
- $sites
+ $sites,
+ true,
+ $license_owner_id
);
if ( isset( $next_page->error ) ) {
@@ -13936,6 +14034,10 @@
$result['next_page'] = $next_page;
}
+ if ( $result['success'] ) {
+ $this->do_action( 'after_license_activation' );
+ }
+
return $result;
}
@@ -15557,7 +15659,7 @@
*
* @return bool Since 2.3.1 returns if a switch was made.
*/
- function switch_to_blog( $blog_id, FS_Site $install = null, $flush = false ) {
+ function switch_to_blog( $blog_id, $install = null, $flush = false ) {
if ( ! is_numeric( $blog_id ) ) {
return false;
}
@@ -15684,6 +15786,10 @@
function get_site_info( $site = null, $load_registration = false ) {
$this->_logger->entrance();
+ $fs_hook_snapshot = new FS_Hook_Snapshot();
+ // Remove all filters from `switch_blog`.
+ $fs_hook_snapshot->remove( 'switch_blog' );
+
$switched = false;
$registration_date = null;
@@ -15743,6 +15849,9 @@
restore_current_blog();
}
+ // Add the filters back to `switch_blog`.
+ $fs_hook_snapshot->restore( 'switch_blog' );
+
return $info;
}
@@ -15974,7 +16083,7 @@
if ( $this->is_install_sync_scheduled() &&
$context_blog_id == $this->get_install_sync_cron_blog_id()
) {
- $this->schedule_install_sync( $context_blog_id );
+ $this->maybe_schedule_install_sync_cron( $context_blog_id );
}
}
@@ -16863,14 +16972,13 @@
*
* @param array $override_with
* @param bool|int|null $network_level_or_blog_id If true, return params for network level opt-in. If integer, get params for specified blog in the network.
+ * @param bool $skip_user_info
*
* @return array
*/
- function get_opt_in_params( $override_with = array(), $network_level_or_blog_id = null ) {
+ function get_opt_in_params( $override_with = array(), $network_level_or_blog_id = null, $skip_user_info = false ) {
$this->_logger->entrance();
- $current_user = self::_get_current_wp_user();
-
$activation_action = $this->get_unique_affix() . '_activate_new';
$return_url = $this->is_anonymous() ?
// If skipped already, then return to the account page.
@@ -16881,9 +16989,6 @@
$versions = $this->get_versions();
$params = array_merge( $versions, array(
- 'user_firstname' => $current_user->user_firstname,
- 'user_lastname' => $current_user->user_lastname,
- 'user_email' => $current_user->user_email,
'plugin_slug' => $this->_slug,
'plugin_id' => $this->get_id(),
'plugin_public_key' => $this->get_public_key(),
@@ -16899,6 +17004,21 @@
'is_localhost' => WP_FS__IS_LOCALHOST,
) );
+ if (
+ ! $skip_user_info &&
+ (
+ empty( $override_with['user_firstname'] ) ||
+ empty( $override_with['user_lastname'] ) ||
+ empty( $override_with['user_email'] )
+ )
+ ) {
+ $current_user = self::_get_current_wp_user();
+
+ $params['user_firstname'] = $current_user->user_firstname;
+ $params['user_lastname'] = $current_user->user_lastname;
+ $params['user_email'] = $current_user->user_email;
+ }
+
if ( $this->is_addon() ) {
$parent_fs = $this->get_parent_instance();
@@ -16978,6 +17098,7 @@
* @param null|bool $is_marketing_allowed
* @param array $sites If network-level opt-in, an array of containing details of sites.
* @param bool $redirect
+ * @param null|number $license_owner_id
*
* @return string|object
* @use WP_Error
@@ -16992,15 +17113,11 @@
$is_disconnected = false,
$is_marketing_allowed = null,
$sites = array(),
- $redirect = true
+ $redirect = true,
+ $license_owner_id = null
) {
$this->_logger->entrance();
- if ( false === $email ) {
- $current_user = self::_get_current_wp_user();
- $email = $current_user->user_email;
- }
-
/**
* @since 1.2.1 If activating with license key, ignore the context-user
* since the user will be automatically loaded from the license.
@@ -17010,6 +17127,11 @@
$this->_storage->remove( 'pending_license_key' );
if ( ! $is_uninstall ) {
+ if ( false === $email ) {
+ $current_user = self::_get_current_wp_user();
+ $email = $current_user->user_email;
+ }
+
$fs_user = Freemius::_get_user_by_email( $email );
if ( is_object( $fs_user ) && ! $this->is_pending_activation() ) {
return $this->install_with_user(
@@ -17024,15 +17146,22 @@
}
}
+ $skip_user_info = ( ! empty( $license_key ) && FS_User::is_valid_id( $license_owner_id ) );
+
$user_info = array();
- if ( ! empty( $email ) ) {
- $user_info['user_email'] = $email;
- }
- if ( ! empty( $first ) ) {
- $user_info['user_firstname'] = $first;
- }
- if ( ! empty( $last ) ) {
- $user_info['user_lastname'] = $last;
+
+ if ( ! $skip_user_info ) {
+ if ( ! empty( $email ) ) {
+ $user_info['user_email'] = $email;
+ }
+
+ if ( ! empty( $first ) ) {
+ $user_info['user_firstname'] = $first;
+ }
+
+ if ( ! empty( $last ) ) {
+ $user_info['user_lastname'] = $last;
+ }
}
if ( ! empty( $sites ) ) {
@@ -17043,7 +17172,7 @@
$is_network = false;
}
- $params = $this->get_opt_in_params( $user_info, $is_network );
+ $params = $this->get_opt_in_params( $user_info, $is_network, $skip_user_info );
$filtered_license_key = false;
if ( is_string( $license_key ) ) {
@@ -18039,7 +18168,7 @@
private function _activate_addon_account(
Freemius $parent_fs,
$network_level_or_blog_id = null,
- FS_Plugin_License $bundle_license = null
+ $bundle_license = null
) {
if ( $this->is_registered() ) {
// Already activated.
@@ -18672,7 +18801,7 @@
* @return bool
*/
function is_pricing_page_visible() {
- return (
+ $visible = (
// Has at least one paid plan.
$this->has_paid_plan() &&
// Didn't ask to hide the pricing page.
@@ -18680,6 +18809,8 @@
// Don't have a valid active license or has more than one plan.
( ! $this->is_paying() || ! $this->is_single_plan( true ) )
);
+
+ return $this->apply_filters( 'is_pricing_page_visible', $visible );
}
/**
@@ -19635,7 +19766,7 @@
* @param null|int $network_level_or_blog_id Since 2.0.0
* @param FS_Site $site Since 2.0.0
*/
- private function _store_site( $store = true, $network_level_or_blog_id = null, FS_Site $site = null, $is_backup = false ) {
+ private function _store_site( $store = true, $network_level_or_blog_id = null, $site = null, $is_backup = false ) {
$this->_logger->entrance();
if ( is_null( $site ) ) {
@@ -20488,11 +20619,18 @@
* @param bool $flush Since 1.1.7.3
* @param int $expiration Since 1.2.2.7
* @param bool|string $newer_than Since 2.2.1
+ * @param bool $fetch_upgrade_notice Since 2.12.1
*
* @return object|false New plugin tag info if exist.
*/
- private function _fetch_newer_version( $plugin_id = false, $flush = true, $expiration = WP_FS__TIME_24_HOURS_IN_SEC, $newer_than = false ) {
- $latest_tag = $this->_fetch_latest_version( $plugin_id, $flush, $expiration, $newer_than );
+ private function _fetch_newer_version(
+ $plugin_id = false,
+ $flush = true,
+ $expiration = WP_FS__TIME_24_HOURS_IN_SEC,
+ $newer_than = false,
+ $fetch_upgrade_notice = true
+ ) {
+ $latest_tag = $this->_fetch_latest_version( $plugin_id, $flush, $expiration, $newer_than, false, $fetch_upgrade_notice );
if ( ! is_object( $latest_tag ) ) {
return false;
@@ -20525,19 +20663,18 @@
*
* @param bool|number $plugin_id
* @param bool $flush Since 1.1.7.3
- * @param int $expiration Since 1.2.2.7
- * @param bool|string $newer_than Since 2.2.1