prepare() query inside $fetch, so every SQL * statement stays visible and prepared where it is written. * * @param string $id Unique id of the query and its arguments. * @param callable $fetch Returns the fresh value. * @return mixed */ protected static function remember( string $id, callable $fetch ) { $key = static::cache_key( $id ); $found = false; $value = wp_cache_get( $key, 'rentbaik', false, $found ); if ( ! $found ) { $value = $fetch(); wp_cache_set( $key, $value, 'rentbaik' ); } return $value; } /** * Find a row by ID. * * @param int $id Row ID. * @return array|null */ public static function find( int $id ): ?array { if ( $id <= 0 ) { return null; } $table = static::table(); $row = static::remember( 'find:' . $id, static function () use ( $table, $id ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table; cached by remember(). return $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM %i WHERE id = %d', $table, $id ), ARRAY_A ); } ); return is_array( $row ) ? $row : null; } /** * Insert a row. * * @param array $data Column => value. * @param string[] $format Value formats (%s, %d, %f). * @return int New row ID, 0 on failure. */ public static function insert( array $data, array $format ): int { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Custom table write; cache invalidated below. $ok = $wpdb->insert( static::table(), $data, $format ); // Read the ID before touch(): touch() writes an option, which changes $wpdb->insert_id. $id = $ok ? (int) $wpdb->insert_id : 0; static::touch(); return $id; } /** * Update a row by ID. * * @param int $id Row ID. * @param array $data Column => value. * @param string[] $format Value formats. * @return bool */ public static function update( int $id, array $data, array $format ): bool { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table write; cache invalidated below. $ok = $wpdb->update( static::table(), $data, array( 'id' => $id ), $format, array( '%d' ) ); static::touch(); return false !== $ok; } /** * Delete a row by ID. * * @param int $id Row ID. * @return bool */ public static function delete( int $id ): bool { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table write; cache invalidated below. $ok = $wpdb->delete( static::table(), array( 'id' => $id ), array( '%d' ) ); static::touch(); return false !== $ok; } /** * Current UTC time in MySQL format. * * @return string */ protected static function now(): string { return gmdate( 'Y-m-d H:i:s' ); } }