get_current_user_id(), 'updated' => time(), 'job' => $job->to_array(), ), false ); $index = $this->get_index(); $index[ $token ] = time(); update_option( self::INDEX_OPTION, $index, false ); } /** * Loads a job owned by the current user. * * @param string $token Package token. * @return ImportJob|null */ public function load( string $token ): ?ImportJob { $stored = get_option( self::OPTION_PREFIX . $token ); if ( ! is_array( $stored ) || (int) ( $stored['user_id'] ?? -1 ) !== get_current_user_id() || ! is_array( $stored['job'] ?? null ) ) { return null; } return ImportJob::from_array( $stored['job'] ); } /** * Deletes a job and its lock. * * @param string $token Package token. * @return void */ public function delete( string $token ): void { delete_option( self::OPTION_PREFIX . $token ); delete_option( self::LOCK_PREFIX . $token ); $index = $this->get_index(); unset( $index[ $token ] ); update_option( self::INDEX_OPTION, $index, false ); } /** * Takes the job's lock. * * @param string $token Package token. * @return bool False if another request holds it. */ public function acquire_lock( string $token ): bool { if ( add_option( self::LOCK_PREFIX . $token, time(), '', false ) ) { return true; } $since = (int) get_option( self::LOCK_PREFIX . $token, 0 ); if ( $since > 0 && time() - $since < self::LOCK_TIMEOUT ) { return false; } // Abandoned lock: take it over. delete_option( self::LOCK_PREFIX . $token ); return add_option( self::LOCK_PREFIX . $token, time(), '', false ); } /** * Releases the job's lock. * * @param string $token Package token. * @return void */ public function release_lock( string $token ): void { delete_option( self::LOCK_PREFIX . $token ); } /** * Cron callback: deletes jobs not updated within the temp file lifetime. * * @return void */ public function run_scheduled_cleanup(): void { /** This filter is documented in src/Storage/TempStorage.php */ $lifetime = apply_filters( 'cherrylift_temp_file_lifetime', DAY_IN_SECONDS ); $lifetime = is_int( $lifetime ) && $lifetime > 0 ? $lifetime : DAY_IN_SECONDS; foreach ( $this->get_index() as $token => $updated ) { if ( (int) $updated < time() - $lifetime ) { $this->delete( (string) $token ); } } } /** * Returns the job index: token => last update time. * * @return array */ private function get_index(): array { $index = get_option( self::INDEX_OPTION, array() ); return is_array( $index ) ? $index : array(); } }