insert( $wpdb->prefix . self::TABLE, array( 'user_id' => $user_id, 'description' => sprintf( 'Nyxify - API (%s)', gmdate( 'Y-m-d H:i:s' ) ), 'permissions' => self::PERMISSIONS, 'consumer_key' => wc_api_hash( $consumer_key ), 'consumer_secret' => $consumer_secret, 'truncated_key' => substr( $consumer_key, -7 ), ), array( '%d', '%s', '%s', '%s', '%s', '%s' ) ); $key_id = (int) $wpdb->insert_id; if ( 1 !== $inserted || $key_id <= 0 ) { return null; } return new RestKey( $key_id, $consumer_key, $consumer_secret ); } /** * Deletes a key the plugin created. * * @param int $key_id Row id. * @return bool False on a database error; a key that is already gone counts as deleted. */ public function delete( int $key_id ): bool { global $wpdb; if ( $key_id <= 0 ) { return false; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Same delete as WC_Admin_API_Keys::remove_key(); WooCommerce doesn't cache keys. $deleted = $wpdb->delete( $wpdb->prefix . self::TABLE, array( 'key_id' => $key_id ), array( '%d' ) ); return false !== $deleted; } /** * Id of the key the plugin created last. * * @return int|null Null when none is remembered. */ public function current_id(): ?int { $value = get_option( self::OPTION_KEY_ID, null ); if ( ! is_numeric( $value ) ) { return null; } $key_id = (int) $value; return $key_id > 0 ? $key_id : null; } /** * The user who owns the key the plugin created (the core writes as this user, and so do pulled changes). * * @return int|null Null when no key is remembered or its row is gone. */ public function user_id(): ?int { $key_id = $this->current_id(); if ( null === $key_id ) { return null; } global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- WooCommerce's own table; read once per pull. $user_id = $wpdb->get_var( $wpdb->prepare( 'SELECT user_id FROM %i WHERE key_id = %d', $wpdb->prefix . self::TABLE, $key_id ) ); return is_numeric( $user_id ) && (int) $user_id > 0 ? (int) $user_id : null; } /** * Remembers the id of the key the plugin created. * * @param int $key_id Row id. * @return bool Whether the option holds that id afterwards. */ public function remember( int $key_id ): bool { if ( $key_id <= 0 ) { return false; } // update_option() returns false when nothing changes. if ( $this->current_id() === $key_id ) { return true; } return update_option( self::OPTION_KEY_ID, $key_id, false ); } /** * Forgets the remembered key id (the key itself is deleted with delete()). * * @return void */ public function forget(): void { delete_option( self::OPTION_KEY_ID ); } }