first commit
This commit is contained in:
@@ -0,0 +1,363 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data;
|
||||
|
||||
use Elementor\Core\Utils\Collection;
|
||||
use Elementor\Data\Base\Controller as Controller_Base;
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Query;
|
||||
use ElementorPro\Modules\Forms\Submissions\Data\Responses\Query_Failed_Response;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Controller extends Controller_Base {
|
||||
/**
|
||||
* @var \ElementorPro\Modules\Forms\Submissions\Database\Query
|
||||
*/
|
||||
private $query;
|
||||
|
||||
public function get_name() {
|
||||
return 'form-submissions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection params by 'additionalProperties' context.
|
||||
*
|
||||
* TODO Should move to base after merge with 'Sub controllers & Sub endpoints'.
|
||||
*
|
||||
* @param string $context
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_collection_params_by_additional_props_context( $context ) {
|
||||
$result = [];
|
||||
|
||||
$collection_params = $this->get_collection_params();
|
||||
|
||||
foreach ( $collection_params as $collection_param_key => $collection_param ) {
|
||||
if ( isset( $collection_param['additionalProperties']['context'] ) && $context === $collection_param['additionalProperties']['context'] ) {
|
||||
$result[ $collection_param_key ] = $collection_param;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function get_collection_params() {
|
||||
$default_collection_params = parent::get_collection_params();
|
||||
|
||||
return array_merge( $default_collection_params, [
|
||||
'page' => [
|
||||
'description' => 'Current page of the collection.',
|
||||
'type' => 'integer',
|
||||
'default' => 1,
|
||||
'minimum' => 1,
|
||||
'required' => false,
|
||||
],
|
||||
'per_page' => [
|
||||
'description' => 'Maximum number of items to be returned in result set.',
|
||||
'type' => 'integer',
|
||||
'default' => 50,
|
||||
'minimum' => 1,
|
||||
'maximum' => 100,
|
||||
'required' => false,
|
||||
],
|
||||
'order' => [
|
||||
'description' => 'Order sort attribute ascending or descending.',
|
||||
'type' => 'string',
|
||||
'default' => 'desc',
|
||||
'enum' => [
|
||||
'asc',
|
||||
'desc',
|
||||
],
|
||||
'required' => false,
|
||||
],
|
||||
'order_by' => [
|
||||
'description' => 'Sort collection by object attribute.',
|
||||
'type' => 'string',
|
||||
'default' => 'created_at',
|
||||
'enum' => [
|
||||
'created_at',
|
||||
'id',
|
||||
'main_meta_id',
|
||||
],
|
||||
'required' => false,
|
||||
],
|
||||
'status' => [
|
||||
'description' => 'Limit result set to submissions assigned one or more statuses.',
|
||||
'type' => 'string',
|
||||
'default' => 'all',
|
||||
'enum' => [
|
||||
'all',
|
||||
'unread',
|
||||
'read',
|
||||
'trash',
|
||||
],
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
'required' => false,
|
||||
],
|
||||
'search' => [
|
||||
'description' => 'Limit results to those matching a string.',
|
||||
'type' => 'string',
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
'form' => [
|
||||
'description' => 'Limit result set to submissions assigned to specific forms. The form id should follow this pattern {post_id}_{element_id} e.g: 10_476d0ce',
|
||||
'type' => 'string',
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
'referer' => [
|
||||
'description' => 'Limit result set to submissions assigned to specific referer.',
|
||||
'type' => 'string',
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
'after' => [
|
||||
'description' => 'Limit response to submissions sent after a given ISO8601 compliant date.',
|
||||
'type' => 'string',
|
||||
'format' => 'date',
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
'before' => [
|
||||
'description' => 'Limit response to submissions sent before a given ISO8601 compliant date.',
|
||||
'type' => 'string',
|
||||
'format' => 'date',
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
public function get_items( $request ) {
|
||||
$filters = [];
|
||||
|
||||
// Get & set filters with values.
|
||||
foreach ( $this->get_collection_params_by_additional_props_context( 'filter' ) as $collection_param_name => $collection_param_values ) {
|
||||
$request_filter_value = $request->get_param( $collection_param_name );
|
||||
|
||||
if ( null !== $request_filter_value ) {
|
||||
$collection_param_values['value'] = $request_filter_value;
|
||||
|
||||
$filters[ $collection_param_name ] = $collection_param_values;
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->query->get_submissions( [
|
||||
'page' => $request->get_param( 'page' ),
|
||||
'per_page' => $request->get_param( 'per_page' ),
|
||||
'filters' => $filters,
|
||||
'order' => [
|
||||
'order' => $request->get_param( 'order' ),
|
||||
'by' => $request->get_param( 'order_by' ),
|
||||
],
|
||||
] );
|
||||
|
||||
$result['meta']['count'] = $this->query
|
||||
->count_submissions_by_status( $filters )
|
||||
->all();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function get_item( $request ) {
|
||||
return $this->query->get_submission( (int) $request->get_param( 'id' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function delete_items( $request ) {
|
||||
return $this->delete(
|
||||
$request->get_param( 'ids' ),
|
||||
$request->get_param( 'force' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete single submission
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function delete_item( $request ) {
|
||||
return $this->delete(
|
||||
[ $request->get_param( 'id' ) ],
|
||||
$request->get_param( 'force' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single submission.
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function update_item( $request ) {
|
||||
return $this->update(
|
||||
[ (int) $request->get_param( 'id' ) ],
|
||||
$request
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update multiple submissions.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function update_items( $request ) {
|
||||
return $this->update(
|
||||
$request->get_param( 'ids' ),
|
||||
$request
|
||||
);
|
||||
}
|
||||
|
||||
public function get_permission_callback( $request ) {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
public function register_endpoints() {
|
||||
$this->register_endpoint( Endpoints\Restore::class );
|
||||
$this->register_endpoint( Endpoints\Export::class );
|
||||
$this->register_endpoint( Endpoints\Referer::class );
|
||||
}
|
||||
|
||||
protected function register_internal_endpoints() {
|
||||
// Register as internal to remove the default endpoint generated by the base controller.
|
||||
$this->register_endpoint( Endpoints\Index::class );
|
||||
}
|
||||
|
||||
protected function register() {
|
||||
parent::register();
|
||||
|
||||
$this->query = Query::get_instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more submissions.
|
||||
*
|
||||
* @param array $ids
|
||||
* @param false $force
|
||||
*
|
||||
* @return Query_Failed_Response|\WP_Error|\WP_REST_Response
|
||||
*/
|
||||
private function delete( array $ids, $force = false ) {
|
||||
$affected = 0;
|
||||
$failed = 0;
|
||||
|
||||
foreach ( $ids as $id ) {
|
||||
if ( $force ) {
|
||||
$affected_rows = $this->query->delete_submission( $id );
|
||||
} else {
|
||||
$affected_rows = $this->query->move_to_trash_submission( $id );
|
||||
}
|
||||
|
||||
if ( false === $affected_rows ) {
|
||||
$failed++;
|
||||
} else {
|
||||
$affected += $affected_rows;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $ids ) === $failed ) {
|
||||
return new Query_Failed_Response(
|
||||
$this->query->get_last_error()
|
||||
);
|
||||
}
|
||||
|
||||
if ( 1 === count( $ids ) && 0 === $affected ) {
|
||||
return new \WP_Error(
|
||||
'rest_not_found',
|
||||
__( 'Submission not found.', 'elementor-pro' ),
|
||||
[ 'status' => 404 ]
|
||||
);
|
||||
}
|
||||
|
||||
return new \WP_REST_Response( [
|
||||
'data' => [],
|
||||
'meta' => [
|
||||
'affected' => $affected,
|
||||
'failed' => $failed,
|
||||
],
|
||||
], 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one or more submissions.
|
||||
*
|
||||
* @param array $ids
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return Query_Failed_Response|\WP_Error|\WP_REST_Response
|
||||
*/
|
||||
private function update( array $ids, \WP_REST_Request $request ) {
|
||||
$allowed_args = ( new Collection( $request->get_attributes()['args'] ) )
|
||||
->except( [ 'id', 'ids', 'values' ] )
|
||||
->keys();
|
||||
|
||||
$data = ( new Collection( $request->get_body_params() ) )
|
||||
->only( $allowed_args )
|
||||
->all();
|
||||
|
||||
$values = $request->get_param( 'values' );
|
||||
|
||||
$affected = 0;
|
||||
$failed = 0;
|
||||
|
||||
foreach ( $ids as $id ) {
|
||||
$affected_rows = $this->query->update_submission( $id, $data, $values );
|
||||
|
||||
if ( false === $affected_rows ) {
|
||||
$failed++;
|
||||
} else {
|
||||
$affected += $affected_rows;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $ids ) === $failed ) {
|
||||
return new Query_Failed_Response(
|
||||
$this->query->get_last_error()
|
||||
);
|
||||
}
|
||||
|
||||
if ( 1 === count( $ids ) ) {
|
||||
if ( 0 === $affected ) {
|
||||
return new \WP_Error(
|
||||
'rest_not_found',
|
||||
__( 'Submission not found.', 'elementor-pro' ),
|
||||
[ 'status' => 404 ]
|
||||
);
|
||||
}
|
||||
|
||||
return new \WP_REST_Response( $this->query->get_submission( $ids[0] ) );
|
||||
}
|
||||
|
||||
return new \WP_REST_Response( [
|
||||
'data' => [],
|
||||
'meta' => [
|
||||
'affected' => $affected,
|
||||
'failed' => $failed,
|
||||
],
|
||||
], 200 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data\Endpoints;
|
||||
|
||||
use Elementor\Data\Base\Endpoint;
|
||||
use Elementor\Core\Utils\Collection;
|
||||
use ElementorPro\Modules\Forms\Submissions\Export\CSV_Export;
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Query;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* This logic should be under index.php::get_items method, but for now
|
||||
* the Data JS API does not support sending Headers like `Accept: text/csv`.
|
||||
*/
|
||||
class Export extends Endpoint {
|
||||
const EXPORT_BY_IDS = 'ids';
|
||||
const EXPORT_BY_FILTER = 'filter';
|
||||
|
||||
public function get_name() {
|
||||
return 'export';
|
||||
}
|
||||
|
||||
protected function register() {
|
||||
$this->register_route(
|
||||
'',
|
||||
\WP_REST_Server::READABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::READABLE, $request, true );
|
||||
},
|
||||
array_merge( $this->controller->get_collection_params(), [
|
||||
'ids' => [
|
||||
'description' => 'Unique identifiers for the objects.',
|
||||
'type' => 'array',
|
||||
'items' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
'format' => [
|
||||
'description' => 'The format of the export (for now only csv).',
|
||||
'types' => 'string',
|
||||
'enum' => [
|
||||
'csv',
|
||||
],
|
||||
'default' => 'csv',
|
||||
'required' => false,
|
||||
],
|
||||
'per_page' => [
|
||||
'description' => 'Maximum number of items to be returned in result set.',
|
||||
'type' => 'integer',
|
||||
'default' => 10,
|
||||
'minimum' => 1,
|
||||
'maximum' => 10000,
|
||||
'sanitize_callback' => 'absint',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
],
|
||||
] )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
wp_raise_memory_limit( 'admin' );
|
||||
|
||||
$submissions = new Collection(
|
||||
$this->get_submissions_by_filter( $request )
|
||||
);
|
||||
|
||||
if ( 0 === $submissions->count() ) {
|
||||
return new \WP_Error(
|
||||
'nothing_to_export',
|
||||
__( 'There is nothing to export.', 'elementor-pro' ),
|
||||
[ 'status' => 400 ]
|
||||
);
|
||||
}
|
||||
|
||||
$response = $submissions
|
||||
->group_by( 'element_id' )
|
||||
->map( function ( array $submissions_by_form ) {
|
||||
$exporter = new CSV_Export(
|
||||
new Collection( $submissions_by_form )
|
||||
);
|
||||
|
||||
return $exporter->prepare_for_json_response();
|
||||
} );
|
||||
|
||||
return new \WP_REST_Response([
|
||||
'data' => $response->values(),
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get submissions by filter.
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
private function get_submissions_by_filter( $request ) {
|
||||
$args = $request->get_attributes()['args'];
|
||||
|
||||
$filters = ( new Collection( $request->get_query_params() ) )
|
||||
->filter(function ( $value, $key ) use ( $args ) {
|
||||
return isset( $args[ $key ]['additionalProperties']['context'] ) &&
|
||||
'filter' === $args[ $key ]['additionalProperties']['context'];
|
||||
})
|
||||
->map( function ( $value ) use ( $request ) {
|
||||
return [ 'value' => $value ];
|
||||
} )
|
||||
->all();
|
||||
|
||||
return Query::get_instance()->get_submissions(
|
||||
[
|
||||
'page' => $request->get_param( 'page' ),
|
||||
'per_page' => $request->get_param( 'per_page' ),
|
||||
'filters' => $filters,
|
||||
'order' => [
|
||||
'order' => $request->get_param( 'order' ),
|
||||
'by' => $request->get_param( 'order_by' ),
|
||||
],
|
||||
'with_meta' => true,
|
||||
]
|
||||
)['data'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data\Endpoints;
|
||||
|
||||
use Elementor\Data\Base\Endpoint;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Forms_Index extends Endpoint {
|
||||
public function get_name() {
|
||||
return 'index';
|
||||
}
|
||||
|
||||
protected function register() {
|
||||
$this->register_route(
|
||||
'',
|
||||
\WP_REST_Server::READABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::READABLE, $request, true );
|
||||
},
|
||||
[
|
||||
'context' => [
|
||||
'description' => 'Scope under which the request is made, determines fields present in response. (only "options" available for now)',
|
||||
'type' => 'string',
|
||||
'enum' => [
|
||||
'options',
|
||||
],
|
||||
'default' => 'options',
|
||||
'required' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data\Endpoints;
|
||||
|
||||
use Elementor\Data\Base\Endpoint;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Index extends Endpoint {
|
||||
public function get_name() {
|
||||
return 'index';
|
||||
}
|
||||
|
||||
protected function register() {
|
||||
$this->register_route(
|
||||
'',
|
||||
\WP_REST_Server::READABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::READABLE, $request, true );
|
||||
},
|
||||
$this->controller->get_collection_params()
|
||||
);
|
||||
|
||||
$this->register_route(
|
||||
'(?P<id>[\d]+)/',
|
||||
\WP_REST_Server::READABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::READABLE, $request );
|
||||
},
|
||||
[
|
||||
'id' => [
|
||||
'description' => 'Unique identifier for the object.',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->register_route(
|
||||
'(?P<id>[\d]+)/',
|
||||
\WP_REST_Server::DELETABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::DELETABLE, $request );
|
||||
},
|
||||
[
|
||||
'id' => [
|
||||
'description' => 'Unique identifier for the object.',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
],
|
||||
'force' => [
|
||||
'description' => 'Delete the object permanently.',
|
||||
'type' => 'boolean',
|
||||
'required' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->register_route(
|
||||
'',
|
||||
\WP_REST_Server::DELETABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::DELETABLE, $request, true );
|
||||
},
|
||||
[
|
||||
'ids' => [
|
||||
'description' => 'Unique identifiers for the objects.',
|
||||
'type' => 'array',
|
||||
'items' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
'validate_callback' => function ( $param ) {
|
||||
return ! empty( $param );
|
||||
},
|
||||
'required' => true,
|
||||
],
|
||||
'force' => [
|
||||
'description' => 'Delete the object permanently.',
|
||||
'type' => 'boolean',
|
||||
'required' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->register_route(
|
||||
'(?P<id>[\d]+)/',
|
||||
\WP_REST_Server::EDITABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::EDITABLE, $request );
|
||||
},
|
||||
[
|
||||
'id' => [
|
||||
'description' => 'Unique identifier for the object.',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
],
|
||||
'is_read' => [
|
||||
'description' => 'mark whether the submission was read or not',
|
||||
'type' => 'boolean',
|
||||
'required' => false,
|
||||
],
|
||||
'values' => [
|
||||
'description' => 'Form field values, receive an array, the key should be the form field id and the value should be the value.',
|
||||
'type' => 'object',
|
||||
'required' => false,
|
||||
'sanitize_callback' => function ( $values ) {
|
||||
$result = [];
|
||||
|
||||
foreach ( $values as $key => $value ) {
|
||||
$result[ $key ] = sanitize_text_field( $value );
|
||||
}
|
||||
|
||||
return $result;
|
||||
},
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->register_route(
|
||||
'',
|
||||
\WP_REST_Server::EDITABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::EDITABLE, $request, true );
|
||||
},
|
||||
[
|
||||
'ids' => [
|
||||
'description' => 'Unique identifiers for the objects.',
|
||||
'type' => 'array',
|
||||
'items' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
'validate_callback' => function ( $param ) {
|
||||
return ! empty( $param );
|
||||
},
|
||||
'required' => true,
|
||||
],
|
||||
'is_read' => [
|
||||
'description' => 'mark whether the submission was read or not',
|
||||
'type' => 'boolean',
|
||||
'required' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data\Endpoints;
|
||||
|
||||
use Elementor\Data\Base\Endpoint;
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Query;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Referer extends Endpoint {
|
||||
public function get_name() {
|
||||
return 'referer';
|
||||
}
|
||||
|
||||
protected function register() {
|
||||
$this->register_route(
|
||||
'',
|
||||
\WP_REST_Server::READABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::READABLE, $request, true );
|
||||
},
|
||||
[
|
||||
'context' => [
|
||||
'description' => 'Scope under which the request is made, determines fields present in response. (only "options" available for now)',
|
||||
'type' => 'string',
|
||||
'enum' => [
|
||||
'options',
|
||||
],
|
||||
'default' => 'options',
|
||||
'required' => false,
|
||||
],
|
||||
'search' => [
|
||||
'description' => 'Limit results to those matching a string.',
|
||||
'type' => 'string',
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
'value' => [
|
||||
'description' => 'Limit results specific referer.',
|
||||
'type' => 'string',
|
||||
'required' => false,
|
||||
'additionalProperties' => [
|
||||
'context' => 'filter',
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function get_items( $request ) {
|
||||
$referrers = Query::get_instance()->get_referrers(
|
||||
$request->get_param( 'search' ),
|
||||
$request->get_param( 'value' )
|
||||
);
|
||||
|
||||
// For now return only as "options"
|
||||
return [
|
||||
'data' => $referrers->map(function ( $referer ) {
|
||||
return [
|
||||
'label' => $referer['referer_title'],
|
||||
'value' => $referer['referer'],
|
||||
];
|
||||
})->values(),
|
||||
'meta' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data\Endpoints;
|
||||
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Query;
|
||||
use Elementor\Data\Base\Endpoint;
|
||||
use ElementorPro\Modules\Forms\Submissions\Data\Responses\Query_Failed_Response;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Restore extends Endpoint {
|
||||
/**
|
||||
* @var Query
|
||||
*/
|
||||
private $query;
|
||||
|
||||
public function get_name() {
|
||||
return 'restore';
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a single trashed submission.
|
||||
*
|
||||
* @param string $id
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function update_item( $id, $request ) {
|
||||
return $this->restore(
|
||||
[ $request->get_param( 'id' ) ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore multiple trashed submissions.
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function update_items( $request ) {
|
||||
return $this->restore(
|
||||
$request->get_param( 'ids' )
|
||||
);
|
||||
}
|
||||
|
||||
protected function register() {
|
||||
$this->register_route(
|
||||
'/(?P<id>[\d]+)/',
|
||||
\WP_REST_Server::EDITABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::EDITABLE, $request );
|
||||
},
|
||||
[
|
||||
'id' => [
|
||||
'description' => 'Unique identifier for the object.',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->register_route(
|
||||
'',
|
||||
\WP_REST_Server::EDITABLE,
|
||||
function ( $request ) {
|
||||
return $this->base_callback( \WP_REST_Server::EDITABLE, $request, true );
|
||||
},
|
||||
[
|
||||
'ids' => [
|
||||
'description' => 'Unique identifiers for the objects.',
|
||||
'type' => 'array',
|
||||
'items' => [
|
||||
'type' => 'integer',
|
||||
],
|
||||
'validate_callback' => function ( $param ) {
|
||||
return ! empty( $param );
|
||||
},
|
||||
'required' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore on or more submissions.
|
||||
*
|
||||
* @param array $ids
|
||||
*
|
||||
* @return Query_Failed_Response|\WP_Error|\WP_REST_Response
|
||||
*/
|
||||
private function restore( array $ids ) {
|
||||
$affected = 0;
|
||||
$failed = 0;
|
||||
|
||||
foreach ( $ids as $id ) {
|
||||
$affected_rows = $this->query->restore( $id );
|
||||
|
||||
if ( false === $affected_rows ) {
|
||||
$failed++;
|
||||
} else {
|
||||
$affected += $affected_rows;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $ids ) === $failed ) {
|
||||
return new Query_Failed_Response(
|
||||
$this->query->get_last_error()
|
||||
);
|
||||
}
|
||||
|
||||
if ( 1 === count( $ids ) && 0 === $affected ) {
|
||||
return new \WP_Error(
|
||||
'rest_not_found',
|
||||
__( 'Submission not found or not in trash.', 'elementor-pro' ),
|
||||
[ 'status' => 404 ]
|
||||
);
|
||||
}
|
||||
|
||||
return new \WP_REST_Response( [
|
||||
'data' => [],
|
||||
'meta' => [
|
||||
'affected' => $affected,
|
||||
'failed' => $failed,
|
||||
],
|
||||
], 200 );
|
||||
}
|
||||
|
||||
public function __construct( $controller ) {
|
||||
$this->query = Query::get_instance();
|
||||
|
||||
parent::__construct( $controller );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data;
|
||||
|
||||
use Elementor\Data\Base\Controller as Controller_Base;
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Entities\Form_Snapshot;
|
||||
use ElementorPro\Modules\Forms\Submissions\Database\Repositories\Form_Snapshot_Repository;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Forms_Controller extends Controller_Base {
|
||||
public function get_name() {
|
||||
return 'forms';
|
||||
}
|
||||
|
||||
public function get_items( $request ) {
|
||||
$forms = Form_Snapshot_Repository::instance()->all();
|
||||
|
||||
// For now return only as "options"
|
||||
return [
|
||||
'data' => $forms->map(function ( Form_Snapshot $form ) {
|
||||
return [
|
||||
'label' => $form->get_label(),
|
||||
'value' => $form->get_key(),
|
||||
];
|
||||
})->values(),
|
||||
'meta' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function register_endpoints() {
|
||||
//
|
||||
}
|
||||
|
||||
protected function register_internal_endpoints() {
|
||||
// Register as internal to remove the default endpoint generated by the base controller.
|
||||
$this->register_endpoint( Endpoints\Forms_Index::class );
|
||||
}
|
||||
|
||||
public function get_permission_callback( $request ) {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace ElementorPro\Modules\Forms\Submissions\Data\Responses;
|
||||
|
||||
use ElementorPro\Plugin;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
class Query_Failed_Response extends \WP_Error {
|
||||
public function __construct( $query_error_message, $message = null ) {
|
||||
if ( ! $message ) {
|
||||
$message = esc_html__( 'Could not retrieve query data.', 'elementor-pro' );
|
||||
}
|
||||
|
||||
$this->log_error( $query_error_message );
|
||||
|
||||
parent::__construct(
|
||||
'rest_internal_error',
|
||||
$message,
|
||||
[ 'status' => 500 ]
|
||||
);
|
||||
}
|
||||
|
||||
private function log_error( $query_error_message ) {
|
||||
Plugin::elementor()->logger->error( $query_error_message );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user