| Server IP : 146.59.209.152 / Your IP : 216.73.216.152 Web Server : Apache System : Linux webm009.cluster131.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64 User : monpetu ( 144298) PHP Version : 7.4.33 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/monpetu/www/ipprint/wp-content/plugins/sureforms/inc/abilities/forms/ |
Upload File : |
<?php
/**
* List Forms Ability.
*
* @package sureforms
* @since 2.5.2
*/
namespace SRFM\Inc\Abilities\Forms;
use SRFM\Inc\Abilities\Abstract_Ability;
use SRFM\Inc\Helper;
use WP_Query;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* List_Forms ability class.
*
* Lists all SureForms forms with optional filtering.
*
* @since 2.5.2
*/
class List_Forms extends Abstract_Ability {
/**
* Constructor.
*
* @since 2.5.2
*/
public function __construct() {
$this->id = 'sureforms/list-forms';
$this->label = __( 'List SureForms Forms', 'sureforms' );
$this->description = __( 'Retrieve a list of SureForms forms with optional filtering by status, search query, and pagination.', 'sureforms' );
$this->capability = 'manage_options';
}
/**
* {@inheritDoc}
*/
public function get_annotations() {
return [
'readonly' => true,
'destructive' => false,
'idempotent' => true,
'priority' => 1.0,
'openWorldHint' => false,
];
}
/**
* {@inheritDoc}
*/
public function get_input_schema() {
return [
'type' => 'object',
'additionalProperties' => false,
'properties' => [
'status' => [
'type' => 'string',
'description' => __( 'Filter by form status. Defaults to "publish".', 'sureforms' ),
'enum' => [ 'publish', 'draft', 'trash', 'any' ],
'default' => 'any',
],
'search' => [
'type' => 'string',
'description' => __( 'Search forms by title.', 'sureforms' ),
],
'per_page' => [
'type' => 'integer',
'description' => __( 'Number of forms per page. Defaults to 10.', 'sureforms' ),
'default' => 10,
'minimum' => 1,
'maximum' => 100,
],
'page' => [
'type' => 'integer',
'description' => __( 'Page number for pagination. Defaults to 1.', 'sureforms' ),
'default' => 1,
'minimum' => 1,
],
],
];
}
/**
* {@inheritDoc}
*/
public function get_output_schema() {
return [
'type' => 'object',
'properties' => [
'forms' => [
'type' => 'array',
'items' => [
'type' => 'object',
'properties' => [
'id' => [ 'type' => 'integer' ],
'title' => [ 'type' => 'string' ],
'status' => [ 'type' => 'string' ],
'date' => [ 'type' => 'string' ],
'entry_count' => [ 'type' => 'integer' ],
],
],
],
'total' => [ 'type' => 'integer' ],
'pages' => [ 'type' => 'integer' ],
],
];
}
/**
* Execute the list-forms ability.
*
* @param array<string,mixed> $input Validated input data.
* @return array<string,mixed>|\WP_Error
*/
public function execute( $input ) {
$status = ! empty( $input['status'] ) ? sanitize_text_field( Helper::get_string_value( $input['status'] ) ) : 'any';
$search = ! empty( $input['search'] ) ? sanitize_text_field( Helper::get_string_value( $input['search'] ) ) : '';
$per_page = ! empty( $input['per_page'] ) ? Helper::get_integer_value( $input['per_page'] ) : 10;
$page = ! empty( $input['page'] ) ? Helper::get_integer_value( $input['page'] ) : 1;
$per_page = max( 1, min( 100, $per_page ) );
$query_args = [
'post_type' => SRFM_FORMS_POST_TYPE,
'post_status' => $status,
'posts_per_page' => $per_page,
'paged' => $page,
'orderby' => 'date',
'order' => 'DESC',
];
if ( ! empty( $search ) ) {
$query_args['s'] = $search;
}
$query = new WP_Query( $query_args );
$forms = [];
if ( $query->have_posts() ) {
$form_ids = wp_list_pluck( $query->posts, 'ID' );
$entry_counts = $this->get_entry_counts( $form_ids );
foreach ( $query->posts as $post ) {
if ( ! $post instanceof \WP_Post ) {
continue;
}
$forms[] = [
'id' => $post->ID,
'title' => $post->post_title,
'status' => $post->post_status,
'date' => $post->post_date,
'entry_count' => $entry_counts[ $post->ID ] ?? 0,
];
}
}
return [
'forms' => $forms,
'total' => $query->found_posts,
'pages' => $query->max_num_pages,
];
}
/**
* Get entry counts for multiple forms in a single query.
*
* @param array<int> $form_ids Array of form IDs.
* @since 2.5.2
* @return array<int,int> Map of form_id => entry count.
*/
private function get_entry_counts( array $form_ids ) {
if ( empty( $form_ids ) ) {
return [];
}
global $wpdb;
$table_name = $wpdb->prefix . 'srfm_entries';
$placeholders = implode( ',', array_fill( 0, count( $form_ids ), '%d' ) );
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Batch query to avoid N+1; table name from $wpdb->prefix and placeholders from array_fill() (not user input); results not cached as they reflect real-time entry counts.
$results = $wpdb->get_results(
$wpdb->prepare(
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Table name and placeholders are constructed from $wpdb->prefix and array_fill(), not user input.
"SELECT form_id, COUNT(*) as cnt FROM {$table_name} WHERE form_id IN ({$placeholders}) AND status != 'trash' GROUP BY form_id",
...$form_ids
),
ARRAY_A
);
$counts = [];
if ( is_array( $results ) ) {
foreach ( $results as $row ) {
$counts[ (int) $row['form_id'] ] = (int) $row['cnt'];
}
}
return $counts;
}
}