| @@ -17,8 +17,12 @@ | ||
| 17 | 17 | /** |
| 18 | 18 | * @var int $campaignId |
| 19 | 19 | */ |
| 20 | 20 | protected $campaignId; |
| 21 | + /** | |
| 22 | + * Cleanup idle IP entries action name. | |
| 23 | + */ | |
| 24 | + const CLEANUP_ACTION = "hurrytimer_evergreen_daily_cleanup"; | |
| 21 | 25 | |
| 22 | 26 | public function __construct( $campaignId ) |
| 23 | 27 | { |
| 24 | 28 | global $wpdb; |
| @@ -24,8 +28,10 @@ | ||
| 24 | 28 | global $wpdb; |
| 25 | 29 | |
| 26 | 30 | $this->table = "{$wpdb->prefix}hurrytimer_evergreen"; |
| 27 | 31 | $this->campaignId = $campaignId; |
| 32 | + add_action( self::CLEANUP_ACTION, [ $this, 'cleanup_idle_entries' ] ); | |
| 33 | + | |
| 28 | 34 | } |
| 29 | 35 | |
| 30 | 36 | |
| 31 | 37 | /** |
| @@ -145,9 +151,8 @@ | ||
| 145 | 151 | */ |
| 146 | 152 | public function create( $campaignId, $endDateTS ) |
| 147 | 153 | { |
| 148 | 154 | global $wpdb; |
| 149 | - | |
| 150 | 155 | // Auto-destroy after one month. |
| 151 | 156 | $destroy_at = Helpers::date_later( MONTH_IN_SECONDS ); |
| 152 | 157 | |
| 153 | 158 | $result = $wpdb->insert( |
| @@ -159,9 +164,15 @@ | ||
| 159 | 164 | 'destroy_at' => $destroy_at |
| 160 | 165 | ] |
| 161 | 166 | ); |
| 162 | 167 | |
| 163 | - return $result !== false; | |
| 168 | + if ( $result !== false ) { | |
| 169 | + $this->maybeScheduleDestroy(); | |
| 170 | + | |
| 171 | + return true; | |
| 172 | + } | |
| 173 | + | |
| 174 | + return false; | |
| 164 | 175 | } |
| 165 | 176 | |
| 166 | 177 | /** |
| 167 | 178 | * |
| @@ -222,8 +233,16 @@ | ||
| 222 | 233 | if ( $currentUser ) { |
| 223 | 234 | $where[ 'client_ip_address' ] = $this->fetchCurrentUserIpAddress(); |
| 224 | 235 | } |
| 225 | 236 | $wpdb->delete( $this->table, $where ); |
| 237 | + | |
| 238 | + // maybe clear scheduled cleanup | |
| 239 | + if ( !$currentUser ) { | |
| 240 | + if ( !$this->hasEntries() ) { | |
| 241 | + $this->clearScheduledDestroy(); | |
| 242 | + } | |
| 243 | + } | |
| 244 | + | |
| 226 | 245 | } |
| 227 | 246 | |
| 228 | 247 | function forgetAll( $currentUser = false ) |
| 229 | 248 | { |
| @@ -231,10 +250,73 @@ | ||
| 231 | 250 | if ( $currentUser ) { |
| 232 | 251 | $where[ 'client_ip_address' ] = $this->fetchCurrentUserIpAddress(); |
| 233 | 252 | $wpdb->delete( $this->table, $where ); |
| 234 | 253 | } else { |
| 235 | - $wpdb->query( "DELETE FROM `{$this->table}`" ); | |
| 254 | + $wpdb->query( "delete from {$this->table}" ); | |
| 236 | 255 | } |
| 237 | - | |
| 256 | + if ( !$this->hasEntries() ) { | |
| 257 | + $this->clearScheduledDestroy(); | |
| 258 | + } | |
| 238 | 259 | } |
| 239 | 260 | |
| 261 | + /** | |
| 262 | + * Clean up IP entries with passed `destroy_at`. | |
| 263 | + * | |
| 264 | + * @return void | |
| 265 | + */ | |
| 266 | + private function cleanup_idle_entries() | |
| 267 | + { | |
| 268 | + global $wpdb; | |
| 269 | + $now = current_time( 'mysql' ); | |
| 270 | + $sql = "DELETE FROM {$this->table} WHERE destroy_at < $now"; | |
| 271 | + $wpdb->query( $sql ); | |
| 272 | + } | |
| 273 | + | |
| 274 | + /** | |
| 275 | + * Check if there is at least one IP entry. | |
| 276 | + * | |
| 277 | + * @return bool | |
| 278 | + */ | |
| 279 | + private function hasEntries() | |
| 280 | + { | |
| 281 | + global $wpdb; | |
| 282 | + | |
| 283 | + try { | |
| 284 | + $count = $wpdb->get_var( "SELECT count(*) FROM {$this->table}" ); | |
| 285 | + | |
| 286 | + if ( is_null( $count ) ) { | |
| 287 | + return false; | |
| 288 | + } | |
| 289 | + | |
| 290 | + return $count > 0; | |
| 291 | + | |
| 292 | + } catch ( Exception $e ) { | |
| 293 | + return false; | |
| 294 | + } | |
| 295 | + } | |
| 296 | + | |
| 297 | + /** | |
| 298 | + * Schedule cleanup of IP entries with passed `destroy_at`. | |
| 299 | + * | |
| 300 | + * @return void | |
| 301 | + */ | |
| 302 | + private function maybeScheduleDestroy() | |
| 303 | + { | |
| 304 | + if ( !wp_next_scheduled( self::CLEANUP_ACTION ) ) { | |
| 305 | + wp_schedule_event( | |
| 306 | + current_time( 'timestamp' ), | |
| 307 | + 'daily', | |
| 308 | + self::CLEANUP_ACTION | |
| 309 | + ); | |
| 310 | + } | |
| 311 | + } | |
| 312 | + | |
| 313 | + /** | |
| 314 | + * Clear sheduled destroy event. | |
| 315 | + * | |
| 316 | + * @return void | |
| 317 | + */ | |
| 318 | + private function clearScheduledDestroy() | |
| 319 | + { | |
| 320 | + wp_clear_scheduled_hook( self::CLEANUP_ACTION ); | |
| 321 | + } | |
| 240 | 322 | } |