type' => 'string', 'description' => __( 'Only responses before this date (ISO8601 format).', 'jetpack-forms' ), 'format' => 'date-time', ), 'after' => array( 'type' => 'string', 'description' => __( 'Only responses after this date (ISO8601 format).', 'jetpack-forms' ), 'format' => 'date-time', ), ), 'additionalProperties' => false, ), 'execute_callback' => array( __CLASS__, 'get_form_responses' ), 'permission_callback' => array( __CLASS__, 'can_edit_pages' ), 'meta' => array( 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true, ), 'show_in_rest' => true, ), ) ); } /** * Register ability to update a form response. * * @return void */ private static function register_update_response_ability() { wp_register_ability( 'jetpack-forms/update-response', array( 'label' => __( 'Update form response', 'jetpack-forms' ), 'description' => __( 'Modify a form response. Use to mark as spam, move to trash, restore from trash, or toggle read/unread state.', 'jetpack-forms' ), 'category' => self::CATEGORY_SLUG, 'input_schema' => array( 'type' => 'object', 'required' => array( 'id' ), 'properties' => array( 'id' => array( 'type' => 'integer', 'description' => __( 'The response ID to update.', 'jetpack-forms' ), ), 'status' => array( 'type' => 'string', 'description' => __( 'New status: "publish" (restore), "spam" (mark spam), "trash" (soft delete).', 'jetpack-forms' ), 'enum' => array( 'publish', 'draft', 'spam', 'trash' ), ), 'is_unread' => array( 'type' => 'boolean', 'description' => __( 'Set false to mark as read, true to mark as unread.', 'jetpack-forms' ), ), ), 'additionalProperties' => false, ), 'execute_callback' => array( __CLASS__, 'update_form_response' ), 'permission_callback' => array( __CLASS__, 'can_edit_pages' ), 'meta' => array( 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true, ), 'show_in_rest' => true, ), ) ); } /** * Register ability to get status counts. * * @return void */ private static function register_get_status_counts_ability() { wp_register_ability( 'jetpack-forms/get-status-counts', array( 'label' => __( 'Get response status counts', 'jetpack-forms' ), 'description' => __( 'Get a summary of form responses grouped by status. Returns counts for inbox (active), spam, and trash. Useful for dashboard stats or checking if there are new responses.', 'jetpack-forms' ), 'category' => self::CATEGORY_SLUG, 'input_schema' => array( 'type' => 'object', 'default' => array(), 'properties' => array( 'search' => array( 'type' => 'string', 'description' => __( 'Only count responses matching this search term.', 'jetpack-forms' ), ), 'parent' => array( 'type' => 'integer', 'description' => __( 'Only count responses from a specific page or post.', 'jetpack-forms' ), ), 'before' => array( 'type' => 'string', 'description' => __( 'Only count responses before this date (ISO8601 format).', 'jetpack-forms' ), 'format' => 'date-time', ), 'after' => array( 'type' => 'string', 'description' => __( 'Only count responses after this date (ISO8601 format).', 'jetpack-forms' ), 'format' => 'date-time', ), 'is_unread' => array( 'type' => 'boolean', 'description' => __( 'Set true to count only unread, false for only read.', 'jetpack-forms' ), ), ), 'additionalProperties' => false, ), 'execute_callback' => array( __CLASS__, 'get_status_counts' ), 'permission_callback' => array( __CLASS__, 'can_edit_pages' ), 'meta' => array( 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true, ), 'show_in_rest' => true, ), ) ); } /** * Check if user can edit pages. * * @return bool */ public static function can_edit_pages() { return current_user_can( 'edit_pages' ); } /** * Helper to set multiple parameters on a request from args array. * * @param \WP_REST_Request $request The request object. * @param array $args The arguments array. * @param array $keys The keys to copy from args to request. * @return void */ private static function set_params_from_args( $request, $args, $keys ) { foreach ( $keys as $key ) { if ( isset( $args[ $key ] ) ) { $request->set_param( $key, $args[ $key ] ); } } } /** * Get form responses callback. * * @param array $args Arguments from the ability input. * @return array|\WP_Error Returns array of responses or WP_Error on failure. */ public static function get_form_responses( $args = array() ) { $args = is_array( $args ) ? $args : array(); $endpoint = new Contact_Form_Endpoint( 'feedback' ); $request = new \WP_REST_Request( 'GET', '/wp/v2/feedback' ); self::set_params_from_args( $request, $args, array( 'page', 'per_page', 'parent', 'status', 'is_unread', 'search', 'before', 'after' ) ); // Filter by specific IDs if provided if ( isset( $args['ids'] ) && is_array( $args['ids'] ) ) { $request->set_param( 'include', $args['ids'] ); } $response = $endpoint->get_items( $request ); if ( is_wp_error( $response ) ) { return $response; } return $response->get_data(); } /** * Update form response callback. * * @param array $args Arguments from the ability input. * @return array|\WP_Error Returns updated response data or WP_Error on failure. */ public static function update_form_response( $args ) { if ( ! isset( $args['id'] ) ) { return new \WP_Error( 'missing_id', __( 'Response ID is required.', 'jetpack-forms' ) ); } $endpoint = new Contact_Form_Endpoint( 'feedback' ); $result = array(); // Update status if provided if ( isset( $args['status'] ) ) { $request = new \WP_REST_Request( 'POST', '/wp/v2/feedback/' . $args['id'] ); $request->set_url_params( array( 'id' => $args['id'] ) ); $request->set_body_params( array( 'status' => $args['status'] ) ); $response = $endpoint->update_item( $request ); if ( is_wp_error( $response ) ) { return $response; } $result = $response->get_data(); } // Update read status if provided if ( isset( $args['is_unread'] ) ) { $request = new \WP_REST_Request( 'POST', '/wp/v2/feedback/' . $args['id'] . '/read' ); $request->set_url_params( array( 'id' => $args['id'] ) ); $request->set_body_params( array( 'is_unread' => $args['is_unread'] ) ); $response = $endpoint->update_read_status( $request ); if ( is_wp_error( $response ) ) { return $response; } $result = array_merge( $result, $response->get_data() ); } return $result; } /** * Get status counts callback. * * @param array $args Arguments from the ability input. * @return array|\WP_Error Returns status counts or WP_Error on failure. */ public static function get_status_counts( $args = array() ) { $args = is_array( $args ) ? $args : array(); $endpoint = new Contact_Form_Endpoint( 'feedback' ); $request = new \WP_REST_Request( 'GET', '/wp/v2/feedback/counts' ); self::set_params_from_args( $request, $args, array( 'search', 'parent', 'before', 'after', 'is_unread' ) ); $response = $endpoint->get_status_counts( $request ); if ( $response instanceof \WP_Error ) { return $response; } return (array) $response->get_data(); } }
Fatal error: Uncaught Error: Class "Automattic\Jetpack\Forms\Abilities\Forms_Abilities" not found in /htdocs/wp-content/plugins/jetpack/jetpack_vendor/automattic/jetpack-forms/src/class-jetpack-forms.php:43 Stack trace: #0 /htdocs/wp-content/plugins/jetpack/modules/contact-form.php(30): Automattic\Jetpack\Forms\Jetpack_Forms::load_contact_form() #1 /htdocs/wp-content/plugins/jetpack/class.jetpack.php(1686): include_once('/htdocs/wp-cont...') #2 /htdocs/wp-includes/class-wp-hook.php(341): Jetpack::load_modules('') #3 /htdocs/wp-includes/class-wp-hook.php(365): WP_Hook->apply_filters('', Array) #4 /htdocs/wp-includes/plugin.php(522): WP_Hook->do_action(Array) #5 /htdocs/wp-settings.php(720): do_action('after_setup_the...') #6 /htdocs/wp-config.php(94): require_once('/htdocs/wp-sett...') #7 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #8 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #9 /htdocs/index.php(17): require('/htdocs/wp-blog...') #10 {main} thrown in /htdocs/wp-content/plugins/jetpack/jetpack_vendor/automattic/jetpack-forms/src/class-jetpack-forms.php on line 43