> $request */ public function can_edit_post( WP_REST_Request $request ): bool { return current_user_can( 'edit_post', (int) $request['id'] ); } /** Machine translation spends the site's API key: Authors and up, not Contributors. */ public static function can_machine_translate(): bool { return current_user_can( 'publish_posts' ); } /** @param WP_REST_Request> $request */ public function can_machine_translate_post( WP_REST_Request $request ): bool { return $this->can_edit_post( $request ) && self::can_machine_translate(); } public function can_manage(): bool { return current_user_can( 'manage_options' ); } /** @return array> */ protected static function id_arg(): array { return array( 'id' => array( 'type' => 'integer', 'required' => true, ), ); } /** * A route callback that turns a PHP error into a readable REST error: a plain * message for everyone, and the technical details (class, message, file and * line) for the "Show technical details" toggle. The routes already require * an editor or administrator. * * @param callable(WP_REST_Request>): mixed $callback * @return \Closure(WP_REST_Request>): mixed */ protected function safely( callable $callback ): \Closure { return static function ( WP_REST_Request $request ) use ( $callback ): mixed { try { return $callback( $request ); } catch ( \Throwable $e ) { return self::php_error( $e ); } }; } public static function php_error( \Throwable $e ): WP_Error { $file = str_replace( wp_normalize_path( WP_CONTENT_DIR ), 'wp-content', wp_normalize_path( $e->getFile() ) ); return new WP_Error( 'blocklingo_php_error', __( 'The site ran into a PHP error.', 'blocklingo' ), array( 'status' => 500, 'details' => sprintf( '%s: %s in %s:%d', get_class( $e ), $e->getMessage(), $file, $e->getLine() ), ) ); } /** Attach an HTTP status to a service error. */ protected static function fail( WP_Error $error, int $status ): WP_Error { $error->add_data( array( 'status' => $status ) ); return $error; } /** Machine translation can take minutes on long pages. */ protected static function allow_long_request(): void { if ( function_exists( 'set_time_limit' ) ) { @set_time_limit( 300 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- may be disabled by the host. } } }