Skip to content

Commit

Permalink
seperate file upload logic from rest api handler #2766
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Pollock committed Oct 25, 2018
1 parent 626b610 commit f371307
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 43 deletions.
85 changes: 85 additions & 0 deletions cf2/Fields/Handlers/FileUpload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php


namespace calderawp\calderaforms\cf2\Fields\Handlers;
use calderawp\calderaforms\cf2\Transients\TransientApiContract;


class FileUpload
{

/**
* @var array
*/
protected $field;
/**
* @var array
*/
protected $form;

/**
* @var TransientApiContract
*/
protected $transientApi;
public function __construct(array $field, array $form, TransientApiContract $transientApi )
{
$this->field = $field;
$this->form = $form;
$this->transientApi = $transientApi;
}


/**
* @param array $files
* @param array $hashes
* @param $controlCode
* @return mixed
* @throws \Exception
*/
public function processFiles(array $files,array $hashes, $controlCode ){
$transdata = call_user_func([$this->transientApi, 'getTransient'],$controlCode);
if( ! is_array( $transdata ) ){
$transdata = [];
}

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

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

if ( $expected !== $actual ) {
throw new \Exception(__( 'Content hash did not match expected.' ), 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++;

}

call_user_func([$this->transientApi, 'setTransient'],$controlCode, array_merge( $transdata, $uploads ), 24 * 60 * 60 );


return $controlCode;
}
}
54 changes: 15 additions & 39 deletions cf2/RestApi/File/CreateFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@


use calderawp\calderaforms\cf2\Fields\FieldTypes\FileFieldType;
use calderawp\calderaforms\cf2\Fields\Handlers\FileUpload;
use calderawp\calderaforms\cf2\Transients\Cf1TransientsApi;

class CreateFile extends File
{
Expand Down Expand Up @@ -86,48 +88,21 @@ public function createItem(\WP_REST_Request $request)
$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++;
$handler = new FileUpload(
$field,
$this->getForm(),
new Cf1TransientsApi()
);
try{
$controlCode = $handler->processFiles($files,$hashes,$controlCode);
}catch( \Exception $e ){
return new \WP_REST_Response(['message' => $e->getMessage() ],$e->getCode() );

}

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

if( is_wp_error( $controlCode ) ){
return $controlCode;
}
$response = rest_ensure_response([
'control' => $controlCode
]);
Expand All @@ -151,4 +126,5 @@ protected function getUploader($field)
}



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


namespace calderawp\calderaforms\cf2\Transients;

/**
* Class Cf1TransientsApi
*
* Thin wrapper over CF 1.5+ Transients API wrapper
*
* @package calderawp\calderaforms\cf2\Transients
*/
class Cf1TransientsApi implements TransientApiContract
{ /**
* @inheritdoc
* @since 1.8.0
*/
public function getTransient($id){
return \Caldera_Forms_Transient::get_transient($id);
}
/**
* @inheritdoc
* @since 1.8.0
*/
public function setTransient($id, $data, $expires = null)
{
return \Caldera_Forms_Transient::set_transient($id,$data,$expires);
}
/**
* @inheritdoc
* @since 1.8.0
*/
public function deleteTransient($id){
return \Caldera_Forms_Transient::delete_transient($id);
}

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


namespace calderawp\calderaforms\cf2\Transients;


interface TransientApiContract
{

/**
* Get stored transient
*
* @since 1.8.0
*
* @param string $id Transient ID
* @param mixed $data Data
* @param null|int $expires Optional. Expiration time. Default is nul, which becomes 1 hour
*
* @return bool
*/
public function setTransient($id, $data, $expires = null);

/**
* Delete transient
*
* @since 1.8.0
*
* @param string $id Transient ID
*
* @return bool
*/
public function deleteTransient( $id );

/**
* Get a transient
*
* @since 1.8.0
*
* @param string $id Transient ID
*
* @return mixed
*/
public function getTransient( $id );

}
7 changes: 5 additions & 2 deletions classes/transient.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php

use calderawp\calderaforms\cf2\Transients\TransientApiContract;
/**
* Class Caldera_Forms_Transient
*
Expand All @@ -9,8 +9,9 @@
* Before 1.4.9.1 get/set_transient was used as a convention.
* In 1.4.9.1 This class was added as an API wrapping get/set_transient()
* In 1.5.6 This API switched to using get/update_option() with WordPress "CRON job" to delete if needed, which it should not be most of the time, transient should be deleted on caldera_forms_submit_complete aaction. Reasons explained in https://github.com/CalderaWP/Caldera-Forms/issues/1866
* In 1.8.0 Created calderawp\calderaforms\cf2\Transients\TransientApiContract as public API definition.
*/
class Caldera_Forms_Transient {
class Caldera_Forms_Transient {

/**
* Tracks the transients to be deleted at caldera_forms_submit_complete action
Expand Down Expand Up @@ -131,4 +132,6 @@ public static function submission_complete(){
}

}


}
3 changes: 1 addition & 2 deletions tests/Integration/RestApi/CreateFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public function testRouteCanBeRequest()
*
* @since 1.8.0
*
* @group now
* @group cf2
* @group file
* @group field
Expand Down Expand Up @@ -88,6 +87,7 @@ public function testCreateItem()
*
* @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
*
* @group now
* @group cf2
* @group file
* @group field
Expand Down Expand Up @@ -118,7 +118,6 @@ public function testInvalidHashes(){
*
* @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
*
* @group now
* @group cf2
* @group file
* @group field
Expand Down
28 changes: 28 additions & 0 deletions tests/Unit/Fields/Handlers/FileUpload/FileUploadTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace calderawp\calderaforms\Tests\Unit\Fields\Handlers\FileUpload;

use calderawp\calderaforms\cf2\Fields\Handlers\FileUpload;
use calderawp\calderaforms\cf2\Transients\Cf1TransientsApi;
use calderawp\calderaforms\Tests\Unit\TestCase;

class FileUploadTest extends TestCase
{

/**
* @cover \calderawp\calderaforms\cf2\Fields\Handlers\FileUpload::__construct()
* @cover \calderawp\calderaforms\cf2\Fields\Handlers\FileUpload::$field
* @cover \calderawp\calderaforms\cf2\Fields\Handlers\FileUpload::$form
* @cover \calderawp\calderaforms\cf2\Fields\Handlers\FileUpload::$transientApi
*/
public function test__construct()
{
$field = [ 'ID' => 'fld1'];
$form = ['ID' => 'cd1' ];
$transients = new Cf1TransientsApi();
$handler = new FileUpload($field,$form, $transients);
$this->assertAttributeEquals( $field,'field', $handler );
$this->assertAttributeEquals( $form,'form', $handler );
$this->assertAttributeEquals( $transients,'transientApi', $handler );
}
}

0 comments on commit f371307

Please sign in to comment.