][\x89\xbd]|[\x94][\xb1]|[\x95][\x8b\xa5]|[\x96][\x99\xb3]|[\x97][\x8d\xa7]|[\x98][\x81\x9b\xb5]|[\x99][\x8f\xa9]|[\x9a][\x83\x9d\xbb]|[\x9b][\x95\xb5]|[\x9c][\x8f\xaf]|[\x9d][\x89\xa9]|[\x9e][\x83\xa3\xbd]))(?:[hH\xb9\xc7]|[\xc4][\xa4\xa5\xa6\xa7]|[\xce][\x89\x97]|[\xcf][\xa6]|[\xd0][\x8a\x8b\x9d\xbd]|[\xd1][\x92\x9b]|[\xd2][\x94\x95\xa2\xa3\xa4\xa5\xba\xbb]|[\xd3][\x87\x88\x89\x8a]|[\xd4][\xbb]|[\xd5][\xab\xb0]|(?:2(?:22[3-6]|9[2-5])|54[23]|1(?:0(?:53|85)|18[6-9]|8(?:0(?:8[89]|9[0-5])|1(?:38[89]|340)))|919);|[\xe1](?:[\xb8][\xa2-\xab]|[\xba][\x96]|[\xbc][\xa8-\xaf]|[\xbe][\x98-\x9f]|[\xbf][\x8a-\x8c])|[\xf0][\x9d](?:[\x90][\x87\xa1\xbb]|[\x91][\x95\xaf]|[\x92][\x89\xa3\xbd]|[\x93][\x97\xb1]|[\x94][\xbf]|[\x95][\x99]|[\x96][\xa7]|[\x97][\x81\x9b\xb5]|[\x98][\x8f\xa9]|[\x99][\x83\x9d\xb7]|[\x9a][\x91\xae]|[\x9b][\xa8]|[\x9c][\xa2]|[\x9d][\x9c]|[\x9e][\x96]))(?:[iIl|!1y?\xcc\xcd\xce\xcf\xec\xed\xee\xef\xe9\xba\xc0\xc9\xda\xdf\xfa]|[\xc3][\x8c\x8d\x8e\x8f\xac\xad\xae\xaf]|[\xc4][\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1]|[\xc7][\x8f\x90]|[\xce][\x8a\x90\x99\xaa\xaf\xb9]|[\xcf][\x8a]|[\xd0][\x86\x87]|[\xd1][\x96\x97]|[\xd3][\x80\x8f]|[\xd5][\xac]|(?:1(?:03[01]|11[01]|216|231)|2(?:0[4-7]|16|3[6-9]|9[6-9])|3(?:0[0-5])|4(?:0[67]|6[34])|52[0-3]);|[\xe1](?:[\xb8][\xac-\xaf]|[\xbb][\x88-\x8b]|[\xbc][\xb0-\xbf]|[\xbd][\xb6\xb7]|[\xbf][\x90-\x9b])|[\xf0][\x9d](?:[\x90][\x88\xa2\xbc]|[\x91][\x96\xb0]|[\x92][\x8a\xa4\xbe]|[\x93][\x98\xb2]|[\x94][\xa6]|[\x95][\x80\x9a]|[\x96][\x8e\xa8]|[\x97][\x82\x9c\xb6]|[\x98][\x90\xaa]|[\x99][\x84\x9e\xb8]|[\x9a][\x92\xb0]|[\x9b][\xaa]|[\x9c][\xa4]|[\x9d][\x9e]|[\x9e][\x98]))(?:[sSz\xa6\xa7]|[\xc5][\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1]|[\xc6][\xbe]|[\xd0][\x85]|[\xd1][\x95]|[\xd5][\x8f]|[\xe1](?:[\xb9][\xa0-\xa9])|[\xf0][\x9d](?:[\x90][\x92\xac]|[\x91][\x86\xa0\xba]|[\x92][\x94]|[\x94][\xb0]|[\x95][\x8a\xa4]|[\x96][\xb2]|[\x97][\x8c\xa6]|[\x98][\x80\x9a\xb4]|[\x99][\x8e\xa8]|[\x9a][\x82\x9c]))\s(?:(?:[bB8\xc2\xe2]|[\xce][\x92\xb2]|[\xcf][\x90\xb8]|[\xc3][\x9f]|[\xc6][\x80\x81\x82\x83\x84\x85]|[\xce][\x92\xb2]|[\xcf][\x90]|[\xd0][\x91\x92\xac\xb1\xb2]|[\xd1][\x8a\x8c\xa2\xa3]|[\xd2][\x8c\x8d]|[\xe1](?:[\xb8][\x82-\x87]|[\xba][\x9e])|[\xf0][\x9d](?:[\x90][\x81\x9b\xb5]|[\x91][\x8f\xa9]|[\x92][\x83\x9d\xb7]|[\x93][\x91\xab]|[\x94][\x85\x9f\xb9]|[\x95][\x93\xad]|[\x96][\x87\xa1\xbb]|[\x97][\x95\xaf]|[\x98][\x89\xa3\xbd]|[\x99][\x97\xb1]|[\x9a][\x8b\xa9]|[\x9b][\x83\xa3\xbd]|[\x9c][\x9d\xb7]|[\x9d][\x97\xb1]|[\x9e][\x91\xab]))(?:[iIl|!1y?\xcc\xcd\xce\xcf\xec\xed\xee\xef\xe9\xba\xc0\xc9\xda\xdf\xfa]|[\xc3][\x8c\x8d\x8e\x8f\xac\xad\xae\xaf]|[\xc4][\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1]|[\xc7][\x8f\x90]|[\xce][\x8a\x90\x99\xaa\xaf\xb9]|[\xcf][\x8a]|[\xd0][\x86\x87]|[\xd1][\x96\x97]|[\xd3][\x80\x8f]|[\xd5][\xac]|(?:1(?:03[01]|11[01]|216|231)|2(?:0[4-7]|16|3[6-9]|9[6-9])|3(?:0[0-5])|4(?:0[67]|6[34])|52[0-3]);|[\xe1](?:[\xb8][\xac-\xaf]|[\xbb][\x88-\x8b]|[\xbc][\xb0-\xbf]|[\xbd][\xb6\xb7]|[\xbf][\x90-\x9b])|[\xf0][\x9d](?:[\x90][\x88\xa2\xbc]|[\x91][\x96\xb0]|[\x92][\x8a\xa4\xbe]|[\x93][\x98\xb2]|[\x94][\xa6]|[\x95][\x80\x9a]|[\x96][\x8e\xa8]|[\x97][\x82\x9c\xb6]|[\x98][\x90\xaa]|[\x99][\x84\x9e\xb8]|[\x9a][\x92\xb0]|[\x9b][\xaa]|[\x9c][\xa4]|[\x9d][\x9e]|[\x9e][\x98]))(?:[tT\xc3\xd4\xf4]|[\xc5][\xa2\xa3\xa4\xa5\xa6\xa7]|[\xcd][\xb2\xb3]|[\xce][\xa4]|[\xcf][\x84\xae\xaf]|[\xd0][\x93\xa2]|[\xd1][\x82]|[\xd2][\x90\xac\xad]|[\xd3][\xb6]|[\xd4][\xb5\xb7]|[\xd5][\x92\xa7]|[\xe1](?:[\xb9][\xaa-\xb1]|[\xba][\x97])|[\xf0][\x9d](?:[\x90][\x93\xad]|[\x91][\x87\xa1\xbb]|[\x92][\x95]|[\x93][\x89\xbd]|[\x94][\xb1]|[\x95][\x8b\xa5]|[\x96][\x99\xb3]|[\x97][\x8d\xa7]|[\x98][\x81\x9b\xb5]|[\x99][\x8f\xa9]|[\x9a][\x83\x9d\xbb]|[\x9b][\x95\xb5]|[\x9c][\x8f\xaf]|[\x9d][\x89\xa9]|[\x9e][\x83\xa3\xbd]))(?:[cCk\xc7\xe7\xf2@]|[\xc3][\x87\xa7]|[\xc4][\x86\x87\x88\x89\x8a\x8b\x8c\x8d]|[\xc6][\x87\x88]|[\xcf][\x82\x9a\x9b\xb2\xb9\xbe]|[\xd0][\xa1]|[\xd1][\x81]|[\xd2][\x80\x81\xaa\xab]|[\xd5][\x87]|(?:1(?:0(?:10|17|2[123]|57|89)|1(?:52|53|94|95)|99)|2(?:31|6[2-9])|39[12]|x(?:3(?:f2|f9|fe)|4(?:21|41|80|81|aa|ab)));|[\xe1](?:[\xb8]ewal_url,
'message' => $message,
]
);
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
/**
* Get base data to display in the banners
*
* @since 3.7.5
*
* @return array
*/
private function get_banner_data() {
$price = esc_html( '$' . number_format_i18n( $this->get_price(), 2 ) );
$message = sprintf(
// translators: %1$s = , %2$s = , %3$s = discount price.
esc_html__( 'Renew before it is too late, you will pay %1$s%3$s%2$s.', 'rocket' ),
'',
'',
$price
);
if ( $this->is_grandfather() ) {
$message = sprintf(
// translators: %1$s = , %2$s = discount percentage, %3$s = , %4$s = discount price.
esc_html__( 'Renew with a %1$s%2$s discount%3$s before it is too late, you will only pay %1$s%4$s%3$s!', 'rocket' ),
'',
esc_html( $this->get_discount_percent() . '%' ),
'',
$price
);
}
return [
'message' => $message,
'renewal_url' => $this->user->get_renewal_url(),
];
}
/**
* AJAX callback to dismiss the renewal banner for expired users
*
* @since 3.7.5
*
* @return void
*/
public function dismiss_renewal_expired_banner() {
check_ajax_referer( 'rocket-ajax', 'nonce', true );
if ( ! current_user_can( 'rocket_manage_options' ) ) {
return;
}
$transient = 'rocket_renewal_banner_' . get_current_user_id();
if ( false !== get_transient( $transient ) ) {
return;
}
set_transient( $transient, 1, MONTH_IN_SECONDS );
wp_send_json_success();
}
/**
* Adds the license expiration time to WP Rocket localize script data
*
* @since 3.7.5
*
* @param array $data Localize script data.
* @return array
*/
public function add_localize_script_data( array $data ) {
if ( $this->user->is_license_expired() ) {
return $data;
}
if ( ! $this->is_expired_soon() ) {
return $data;
}
$data['license_expiration'] = $this->user->get_license_expiration();
return $data;
}
/**
* Checks if the license expires in less than 30 days
*
* @since 3.7.5
*
* @return boolean
*/
private function is_expired_soon() {
if ( $this->user->is_auto_renew() ) {
return false;
}
$expiration_delay = $this->user->get_license_expiration() - time();
return 30 * DAY_IN_SECONDS > $expiration_delay;
}
/**
* Gets the discount corresponding to the current user status
*
* @since 3.7.5
*
* @return int
* @phpstan-ignore-next-line
*/
private function get_discount_percent() {
$prices = $this->get_license_pricing_data();
$renewals = $this->get_user_renewal_status();
if ( ! isset( $prices->prices, $prices->prices->renewal ) ) {
return 0;
}
$prices = $prices->prices;
if ( $renewals['is_grandfather'] ) {
return $renewals['discount_percent']->is_grandfather;
}
return 0;
}
/**
* Is user grandfathered
*
* @return bool
*/
private function is_grandfather(): bool {
$renewals = $this->get_user_renewal_status();
return key_exists( 'is_grandfather', $renewals ) && $renewals['is_grandfather'];
}
/**
* Is user grandmothered
*
* @return bool
* @phpstan-ignore-next-line
*/
private function has_grandmother(): bool {
$renewals = $this->get_user_renewal_status();
return key_exists( 'is_grandmother', $renewals ) && $renewals['is_grandmother'];
}
/**
* Gets the price corresponding to the current user status
*
* @since 3.7.5
*
* @return int
*/
private function get_price() {
$renewals = $this->get_user_renewal_status();
$license = $this->get_license_pricing_data();
if (
$renewals['is_grandfather']
&&
! $renewals['is_expired']
) {
return isset( $license->prices->renewal->is_grandfather ) ? $license->prices->renewal->is_grandfather : 0;
}
if ( $renewals['is_grandmother'] &&
! $renewals['is_expired'] ) {
return isset( $license->prices->renewal->is_grandmother ) ? $license->prices->renewal->is_grandmother : 0;
}
return isset( $license->prices->renewal->not_grandfather ) ? $license->prices->renewal->not_grandfather : 0;
}
/**
* Gets the user renewal status
*
* @since 3.7.5
*
* @return array
*/
private function get_user_renewal_status(): array {
$renewals = $this->pricing->get_renewals_data();
if ( ! isset( $renewals->extra_days, $renewals->grandfather_date, $renewals->discount_percent, $renewals->grandmother_date ) ) {
return [];
}
return [
'discount_percent' => $renewals->discount_percent,
'is_expired' => time() > ( $this->user->get_license_expiration() + ( $renewals->extra_days * DAY_IN_SECONDS ) ),
'is_grandfather' => $renewals->grandfather_date > $this->user->get_creation_date(),
'is_grandmother' => $renewals->grandmother_date > $this->user->get_creation_date(),
];
}
/**
* Gets the license pricing data corresponding to the user license
*
* @since 3.7.5
*
* @return object|null
*/
private function get_license_pricing_data() {
$license = $this->user->get_license_type();
$plus_websites = $this->pricing->get_plus_websites_count();
if ( $license === $plus_websites ) {
return $this->pricing->get_plus_pricing();
} elseif (
$license >= $this->pricing->get_single_websites_count()
&&
$license < $plus_websites
) {
return $this->pricing->get_single_pricing();
}
return $this->pricing->get_infinite_pricing();
}
/**
* Gets the countdown data to display for the renewal soon banner
*
* @since 3.7.5
*
* @return array
*/
private function get_countdown_data() {
$data = [
'days' => 0,
'hours' => 0,
'minutes' => 0,
'seconds' => 0,
];
if ( rocket_get_constant( 'WP_ROCKET_IS_TESTING', false ) ) {
return $data;
}
$expiration = $this->user->get_license_expiration();
if ( 0 === $expiration ) {
return $data;
}
$now = date_create();
$end = date_timestamp_set( date_create(), $expiration );
if ( $now > $end ) {
return $data;
}
$remaining = date_diff( $now, $end );
$format = explode( ' ', $remaining->format( '%d %H %i %s' ) );
$data['days'] = $format[0];
$data['hours'] = $format[1];
$data['minutes'] = $format[2];
$data['seconds'] = $format[3];
return $data;
}
/**
* Add license expiring warning to OCD label
*
* @param array $args Setting field arguments.
*
* @return array
*/
public function add_license_expire_warning( $args ): array {
if ( 'optimize_css_delivery' !== $args['id'] ) {
return $args;
}
if ( ! $this->user->is_license_expired() ) {
return $args;
}
$ocd = $this->options->get( 'optimize_css_delivery', 0 );
$whitelabel = rocket_get_constant( 'WP_ROCKET_WHITE_LABEL_ACCOUNT', false );
$expired_since = ( time() - $this->user->get_license_expiration() ) / DAY_IN_SECONDS;
$message = ' ';
if (
(
$whitelabel
&&
15 > $expired_since
&&
$ocd
)
||
(
! $whitelabel
&&
$this->user->is_auto_renew()
&&
4 > $expired_since
)
||
(
$whitelabel
&&
$this->user->is_auto_renew()
&&
4 > $expired_since
&&
! $ocd
)
) {
return $args;
} elseif (
! $whitelabel
&&
15 > $expired_since
&&
$ocd
) {
$message .= sprintf(
// translators: %1$s = , %2$s = .
__( 'You need a valid license to continue using this feature. %1$sRenew now%2$s before losing access.', 'rocket' ),
'',
''
);
} elseif (
(
! $whitelabel
&&
15 < $expired_since
)
||
(
! $whitelabel
&&
15 > $expired_since
&&
! $ocd
)
) {
$message .= sprintf(
// translators: %1$s = , %2$s = .
__( 'You need an active license to enable this option. %1$sRenew now%2$s.', 'rocket' ),
'',
''
);
} elseif (
(
$whitelabel
&&
15 < $expired_since
)
||
(
$whitelabel
&&
15 > $expired_since
&&
! $ocd
)
) {
$doc = 'https://docs.wp-rocket.me/article/1711-what-happens-if-my-license-expires';
$locale = current( array_slice( explode( '_', get_user_locale() ), 0, 1 ) );
if ( 'fr' === $locale ) {
$doc = 'https://fr.docs.wp-rocket.me/article/1712-que-se-passe-t-il-si-ma-licence-expire';
}
$message .= sprintf(
// translators: %1$s = , %2$s = .
__( 'You need an active license to enable this option. %1$sMore info%2$s.', 'rocket' ),
'',
''
);
}
$message .= '';
$args['label'] = $args['label'] . $message;
return $args;
}
/**
* Adds the notification bubble to WP Rocket menu item when expired
*
* @param string $menu_title Menu title.
*
* @return string
*/
public function add_expired_bubble( $menu_title ): string {
if ( rocket_get_constant( 'WP_ROCKET_WHITE_LABEL_ACCOUNT', false ) ) {
return $menu_title;
}
if ( ! $this->user->is_license_expired() ) {
return $menu_title;
}
if ( false !== get_transient( 'wpr_dashboard_seen_' . get_current_user_id() ) ) {
return $menu_title;
}
$expired_since = ( time() - $this->user->get_license_expiration() ) / DAY_IN_SECONDS;
$auto_renew = $this->user->is_auto_renew();
$ocd_enabled = $this->options->get( 'optimize_css_delivery', 0 );
if (
$ocd_enabled
&&
$auto_renew
&&
4 > $expired_since
) {
return $menu_title;
}
if (
! $auto_renew
&&
! $ocd_enabled
&&
4 < $expired_since
) {
return $menu_title;
}
if (
$auto_renew
&&
! $ocd_enabled
&&
(
4 > $expired_since
||
15 < $expired_since
)
) {
return $menu_title;
}
return $menu_title . ' !';
}
/**
* Sets the dashboard seen transient to hide the expired bubble
*
* @return void
*/
public function set_dashboard_seen_transient() {
if ( ! $this->user->is_license_expired() ) {
return;
}
if ( ! $this->options->get( 'optimize_css_delivery', 0 ) ) {
return;
}
$current_user = get_current_user_id();
if ( false !== get_transient( "wpr_dashboard_seen_{$current_user}" ) ) {
return;
}
$expired_since = ( time() - $this->user->get_license_expiration() ) / DAY_IN_SECONDS;
if ( 15 > $expired_since ) {
set_transient( "wpr_dashboard_seen_{$current_user}", 1, 15 * DAY_IN_SECONDS );
} elseif ( 15 < $expired_since ) {
set_transient( "wpr_dashboard_seen_{$current_user}", 1, YEAR_IN_SECONDS );
}
}
/**
* Disable optimize CSS delivery setting
*
* @param array $args Array of setting field arguments.
*
* @return array
*/
public function maybe_disable_ocd( $args ) {
if ( 'optimize_css_delivery' !== $args['id'] ) {
return $args;
}
if ( ! $this->user->is_license_expired() ) {
return $args;
}
$expired_since = ( time() - $this->user->get_license_expiration() ) / DAY_IN_SECONDS;
if (
15 > $expired_since
||
(
$this->user->is_auto_renew()
&&
4 > $expired_since
)
) {
return $args;
}
$args['value'] = 0;
if (
isset( $args['container_class'] )
&&
! in_array( 'wpr-isDisabled', $args['container_class'], true )
) {
$args['container_class'][] = 'wpr-isDisabled';
}
$args['input_attr']['disabled'] = 1;
return $args;
}
/**
* Disables the RUCSS & Async CSS options if license is expired since more than 15 days
*
* @param mixed $value Current option value.
*
* @return mixed
*/
public function maybe_disable_option( $value ) {
$expired_since = ( time() - $this->user->get_license_expiration() ) / DAY_IN_SECONDS;
if ( 15 > $expired_since ) {
return $value;
}
return 0;
}
}