Skip to content

Commit

Permalink
endpoint for uploading files from file fields against #2766
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Pollock committed Oct 24, 2018
1 parent 93b3f13 commit 4ff1985
Show file tree
Hide file tree
Showing 33 changed files with 940 additions and 57 deletions.
29 changes: 29 additions & 0 deletions cf2/RestApi/CalderaRestApiContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php


namespace calderawp\calderaforms\cf2\RestApi;


interface CalderaRestApiContract
{


/**
* Get the namespace for Caldera Forms REST API
*
* @since 1.8.0
*
* @return string
*/
public function getNamespace();

/**
* Initialize the endpoints
*
* @since 1.8.0
*
* @return $this
*
*/
public function initEndpoints();
}
58 changes: 58 additions & 0 deletions cf2/RestApi/Endpoint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php


namespace calderawp\calderaforms\cf2\RestApi;


abstract class Endpoint implements \Caldera_Forms_API_Route
{

/**
* @var array
*/
private $form;
// @phpcs:disable
final public function add_routes($namespace)
// @phpcs:enable
{
register_rest_route( $namespace, $this->getUri(), $this->getArgs() );
}

/**
* Get route URI
*
* @since 1.8.0
*
* @return string
*/
abstract protected function getUri();

/**
* Get route arguments
*
* @since 1.8.0
*
* @return string
*/
abstract protected function getArgs();


/**
* @param string$formId
* @return $this
*/
protected function setFormById( $formId )
{
$this->form = \Caldera_Forms_Forms::get_form($formId );
return $this;
}

/**
* @return array
*/
protected function getForm()
{
return $this->form;
}

}
154 changes: 154 additions & 0 deletions cf2/RestApi/File/CreateFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php


namespace calderawp\calderaforms\cf2\RestApi\File;


use calderawp\calderaforms\cf2\Fields\FieldTypes\FileFieldType;

class CreateFile extends File
{

/** @inheritdoc */
protected function getArgs()
{
return [

'methods' => 'POST',
'callback' => [$this, 'createItem'],
'permission_callback' => [$this, 'permissionsCallback' ],
'args' => [
'hashes' => [
'description' => __('MD5 has of files to upload, should have same order as files arg', 'caldera-forms')
],
'verify' => [
'type' => 'string',
'description' => __('Verification token (nonce) for form', 'caldera-forms'),
'required' => true,
],
'formId' => [
'type' => 'string',
'description' => __('ID for form field belongs to', 'caldera-forms'),
'required' => true,
],
'fieldId' => [
'type' => 'string',
'description' => __('ID for field files are submitted to', 'caldera-forms'),
'required' => true,
],
'control' => [
'type' => 'string',
'description' => __('Unique control string for field', 'caldera-forms'),
'required' => true,
]
]
];
}

/**
* Permissions check for file field uploads
*
* @since 1.8.0
*
* @param \WP_REST_Request $request Request object
*
* @return bool
*/
public function permissionsCallback(\WP_REST_Request $request ){
$form = \Caldera_Forms_Forms::get_form($request->get_param( 'formId' ) );
if( FileFieldType::getCf1Identifier() !== \Caldera_Forms_Field_Util::get_type( $request->get_param( 'fieldId' ), $form ) ){
return false;
}

return \Caldera_Forms_Render_Nonce::verify_nonce(
$request->get_param( 'verify'),
$request->get_param( 'formId' )
);
}

/**
* Upload file for cf2 file field
*
* @since 1.8.0
*
* @param \WP_REST_Request $request
* @return mixed|\WP_Error|\WP_REST_Response
*/
public function createItem(\WP_REST_Request $request)
{

$files = $request->get_file_params();
$formId = $request->get_param('formId');
$this->setFormById($formId);
$fieldId = $request->get_param('fieldId');
$field = \Caldera_Forms_Field_Util::get_field($fieldId,$this->getForm());
$uploads = [];
$uploader = $this->getUploader($field);
$hashes = $request->get_param( 'hashes');
$controlCode = $request->get_param( 'control' );
$transdata = \Caldera_Forms_Transient::get_transient($controlCode);
if( ! is_array( $transdata ) ){
$transdata = [];
}

$i = 0;
foreach ($files as $file) {
if (!\Caldera_Forms_Files::is_private($field)) {
$uploadArgs = array(
'private' => false,
'field_id' => $field['ID'],
'form_id' => $this->getForm()['ID']
);
} else {
$uploadArgs = array(
'private' => true,
'field_id' => $field['ID'],
'form_id' => $this->getForm()['ID']
);
}

$expected = $hashes[$i];
$actual = md5_file( $file['tmp_name'] );

if ( $expected !== $actual ) {
return new \WP_Error( 'rest_upload_hash_mismatch', __( 'Content hash did not match expected.' ), array( 'status' => 412 ) );
}


$upload = wp_handle_upload($file, array( 'test_form' => false, 'action' => 'foo' ) );
if( !empty( $field['config']['media_lib'] ) ){
\Caldera_Forms_Files::add_to_media_library( $upload, $field );
}


$uploads[] = $upload['url'];
$i++;

}

\Caldera_Forms_Transient::set_transient($controlCode, array_merge( $transdata, $uploads ), DAY_IN_SECONDS);

$response = rest_ensure_response([
'control' => $controlCode
]);
$response->set_status(201);

return $response;
}

/**
* @param $field
* @return callable|\WP_Error
*/
protected function getUploader($field)
{
$uploader = \Caldera_Forms_Files::get_upload_handler( $this->getForm(), $field );
if( ! is_callable( $uploader) ){
return new \WP_Error( 'invalid-upload-handler', sprintf( __( 'Invalid file upload handler. See %s', 'caldera-forms'), 'https://calderaforms.com/doc/alternative-file-upload-directory/') );
}

return $uploader;
}


}
18 changes: 18 additions & 0 deletions cf2/RestApi/File/File.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php


namespace calderawp\calderaforms\cf2\RestApi\File;


use calderawp\calderaforms\cf2\RestApi\Endpoint;

abstract class File extends Endpoint
{

const URI = 'file';
/** @inheritdoc */
protected function getUri()
{
return self::URI;
}
}
48 changes: 48 additions & 0 deletions cf2/RestApi/Register.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php


namespace calderawp\calderaforms\cf2\RestApi;


use calderawp\calderaforms\cf2\RestApi\File\CreateFile;

class Register implements CalderaRestApiContract
{

/**
* Namespace for API routes being managed
*
* @since 1.8.0
*
* @var string
*/
private $namespace;


/**
* Register constructor.
*
*
* @since 1.8.0
*
*
* @param string $namespace Namespace for API being managed
*/
public function __construct($namespace)
{
$this->namespace = $namespace;
}

/** @inheritdoc */
public function getNamespace()
{
return $this->namespace;
}
/** @inheritdoc */
public function initEndpoints()
{
(new CreateFile() )->add_routes($this->getNamespace());
return $this;
}

}
11 changes: 7 additions & 4 deletions classes/api/util.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ class Caldera_Forms_API_Util {
*
* @since 1.4.4
*
* @param string $version Optional. API version. Default is v2. Can be v3 or v2 only
* @return string
*/
public static function api_namespace(){
return 'cf-api/v2';
public static function api_namespace($version = 'v2'){
$version = in_array( $version, ['v2', 'v3' ] ) ? $version : 'v2';
return "cf-api/$version";
}

/**
Expand All @@ -30,14 +32,15 @@ public static function api_namespace(){
*
* @param string $endpoint Optional. Endpoint.
* @param bool $add_nonce Optional. If true, _wp_nonce is set with WP REST API nonce. Default is false
* @param string $version Optional. @since 1.8.0
* @return string
*/
public static function url( $endpoint = '', $add_nonce = false ){
public static function url( $endpoint = '', $add_nonce = false, $version = 'v2' ){
if( ! function_exists( 'rest_url' ) ){
return '';
}

$url = rest_url( self::api_namespace() . '/' . $endpoint );
$url = rest_url( self::api_namespace($version) . '/' . $endpoint );
if( $add_nonce ){
$url = add_query_arg( '_wpnonce', self::get_core_nonce(), $url );
}
Expand Down
9 changes: 8 additions & 1 deletion classes/core.php
Original file line number Diff line number Diff line change
Expand Up @@ -4995,8 +4995,15 @@ public static function init_rest_api()
* Runs after Caldera Forms REST API is loaded
*
* @since 1.4.4
*
* @param Caldera_Forms_API_Load $api_v2 Caldera Forms REST API v2
* @param \calderawp\calderaforms\cf2\RestApi\Register $api_v3 Caldera Forms REST API v2
*/
do_action('caldera_forms_rest_api_init');
do_action('caldera_forms_rest_api_init',
self::$api,
(new \calderawp\calderaforms\cf2\RestApi\Register(Caldera_Forms_API_Util::api_namespace('v3' ) ) )
->initEndpoints()
);

}

Expand Down
Loading

0 comments on commit 4ff1985

Please sign in to comment.