first commit
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\Ajax;
|
||||
|
||||
use WPML\Collect\Support\Collection;
|
||||
use WPML\FP\Either;
|
||||
use WPML\FP\Fns;
|
||||
use WPML\FP\Json;
|
||||
use WPML\FP\Logic;
|
||||
use WPML\FP\Lst;
|
||||
use WPML\FP\Maybe;
|
||||
use WPML\FP\System\System;
|
||||
use WPML\LIB\WP\Hooks;
|
||||
use WPML\LIB\WP\Nonce;
|
||||
use function WPML\Container\execute;
|
||||
use function WPML\Container\make;
|
||||
use function WPML\FP\pipe;
|
||||
use function WPML\FP\System\getFilterFor as filter;
|
||||
use function WPML\FP\System\getValidatorFor as validate;
|
||||
|
||||
class Factory implements \IWPML_AJAX_Action {
|
||||
|
||||
public function add_hooks() {
|
||||
// :: Collection -> Collection
|
||||
$filterEndPoint = filter( 'endpoint' )->using( 'wp_unslash' );
|
||||
|
||||
// :: Collection -> Collection
|
||||
$decodeData = filter( 'data' )->using( Json::toCollection() )->defaultTo( 'wpml_collect' );
|
||||
|
||||
// :: Collection -> Either::Left( string ) | Either::Right( Collection )
|
||||
$validateData = validate( 'data' )->using( Logic::isNotNull() )->error( 'Invalid json data' );
|
||||
|
||||
// $handleRequest :: Collection -> Either::Left(string) | Either::Right(mixed)
|
||||
$handleRequest = function ( Collection $postData ) {
|
||||
try {
|
||||
return Maybe::of( $postData->get( 'endpoint' ) )
|
||||
->map( pipe( make(), Lst::makePair( Fns::__, 'run' ) ) )
|
||||
->map( execute( Fns::__, [ ':data' => $postData->get( 'data' ) ] ) )
|
||||
->getOrElse( Either::left( 'End point not found' ) );
|
||||
} catch ( \Exception $e ) {
|
||||
return Either::left( $e->getMessage() );
|
||||
}
|
||||
};
|
||||
|
||||
Hooks::onAction( 'wp_ajax_wpml_action' )
|
||||
->then( System::getPostData() ) // Either::right(Collection)
|
||||
->then( $filterEndPoint )
|
||||
->then( Nonce::verifyEndPoint() )
|
||||
->then( $decodeData )
|
||||
->then( $validateData )
|
||||
->then( $handleRequest )
|
||||
->then( 'wp_send_json_success' )
|
||||
->onError( 'wp_send_json_error' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\Ajax;
|
||||
|
||||
class Locale implements \IWPML_AJAX_Action, \IWPML_DIC_Action {
|
||||
|
||||
/** @var \SitePress */
|
||||
private $sitePress;
|
||||
|
||||
public function __construct( \SitePress $sitePress ) {
|
||||
$this->sitePress = $sitePress;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
if ( is_admin() && ! $this->sitePress->check_if_admin_action_from_referer() ) {
|
||||
add_filter( 'determine_locale', [ $this->sitePress, 'locale_filter' ], 10, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
abstract class WPML_Ajax_Factory {
|
||||
|
||||
public function add_route( WPML_Ajax_Route $route ) {
|
||||
$class_names = $this->get_class_names();
|
||||
foreach ( $class_names as $class_name ) {
|
||||
$route->add( $class_name );
|
||||
}
|
||||
}
|
||||
|
||||
abstract function get_class_names();
|
||||
abstract function create( $class_name );
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
class WPML_Ajax_Response {
|
||||
|
||||
private $success;
|
||||
private $response_data;
|
||||
|
||||
public function __construct( $success, $response_data ) {
|
||||
$this->success = $success;
|
||||
$this->response_data = $response_data;
|
||||
}
|
||||
|
||||
public function send_json() {
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
||||
if ( $this->success ) {
|
||||
wp_send_json_success( $this->response_data );
|
||||
} else {
|
||||
wp_send_json_error( $this->response_data );
|
||||
}
|
||||
} else {
|
||||
throw new WPML_Not_Doing_Ajax_On_Send_Exception( $this );
|
||||
}
|
||||
}
|
||||
|
||||
public function is_success() {
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function get_response() {
|
||||
return $this->response_data;
|
||||
}
|
||||
}
|
||||
|
||||
class WPML_Not_Doing_Ajax_On_Send_Exception extends Exception {
|
||||
|
||||
public $response;
|
||||
|
||||
public function __construct( $response ) {
|
||||
parent::__construct( 'Not doing AJAX' );
|
||||
$this->response = $response;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
class WPML_Ajax_Route {
|
||||
|
||||
const ACTION_PREFIX = 'wp_ajax_';
|
||||
const ACTION_PREFIX_LENGTH = 8;
|
||||
|
||||
/** @var WPML_Ajax_Factory $factory */
|
||||
private $factory;
|
||||
|
||||
public function __construct( WPML_Ajax_Factory $factory ) {
|
||||
$this->factory = $factory;
|
||||
$this->factory->add_route( $this );
|
||||
}
|
||||
|
||||
public function add( $class_name ) {
|
||||
add_action( self::ACTION_PREFIX . $class_name, array( $this, 'do_ajax' ) );
|
||||
}
|
||||
|
||||
public function do_ajax() {
|
||||
$action = current_filter();
|
||||
$class_name = substr( $action, self::ACTION_PREFIX_LENGTH );
|
||||
$ajax_handler = $this->factory->create( $class_name );
|
||||
$ajax_response = $ajax_handler->run();
|
||||
|
||||
$ajax_response->send_json();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_TM_AJAX {
|
||||
/**
|
||||
* @param string $action
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_valid_request( $action = '' ) {
|
||||
if ( ! $action ) {
|
||||
$action = array_key_exists( 'action', $_POST ) ? $_POST['action'] : '';
|
||||
}
|
||||
|
||||
if ( ! array_key_exists( 'nonce', $_POST ) || ! $action
|
||||
|| ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), $action ) ) {
|
||||
|
||||
wp_send_json_error(
|
||||
__(
|
||||
'You have attempted to submit data in a not legit way.',
|
||||
'wpml-translation-management'
|
||||
)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\Ajax\Endpoint;
|
||||
|
||||
use WPML\Ajax\IHandler;
|
||||
use WPML\Collect\Support\Collection;
|
||||
use WPML\FP\Either;
|
||||
use WPML\FP\Fns;
|
||||
use WPML\FP\Obj;
|
||||
use function WPML\FP\curryN;
|
||||
|
||||
class Upload implements IHandler {
|
||||
|
||||
public function run( Collection $data ) {
|
||||
|
||||
$upload = curryN( 2, function ( $path, $file ) {
|
||||
$upload_dir = function ( $uploads ) use ( $path ) {
|
||||
if ( $path ) {
|
||||
$uploads['path'] = $uploads['basedir'] . '/' . $path;
|
||||
$uploads['url'] = $uploads['baseurl'] . '/' . $path;
|
||||
$uploads['subdir'] = $path;
|
||||
}
|
||||
|
||||
return $uploads;
|
||||
};
|
||||
|
||||
add_filter( 'upload_dir', $upload_dir );
|
||||
$upload = wp_handle_upload( $file, [ 'test_form' => false ] );
|
||||
remove_filter( 'upload_dir', $upload_dir );
|
||||
|
||||
return $upload;
|
||||
} );
|
||||
|
||||
$resize = curryN( 2, function ( $settings, $file ) {
|
||||
list( $max_width, $max_height, $crop ) = Obj::props( [ 'max_w', 'max_h', 'crop' ], $settings );
|
||||
|
||||
if ( $max_width && $max_height && function_exists( 'wp_get_image_editor' ) && 'image/svg+xml' !== $file['type'] ) {
|
||||
$image = wp_get_image_editor( $file['file'] );
|
||||
if ( ! is_wp_error( $image ) ) {
|
||||
$image->resize( $max_width, $max_height, (bool) $crop );
|
||||
$image->save( $file['file'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $file;
|
||||
} );
|
||||
|
||||
$handleError = function ( $file ) {
|
||||
if ( Obj::has( 'error', $file ) ) {
|
||||
$error_message = __( 'There was an error uploading the file, please try again!', 'sitepress' );
|
||||
switch ( $file['error'] ) {
|
||||
case UPLOAD_ERR_INI_SIZE;
|
||||
$error_message = __( 'The uploaded file exceeds the upload_max_filesize directive in php.ini.', 'sitepress' );
|
||||
break;
|
||||
case UPLOAD_ERR_FORM_SIZE;
|
||||
$error_message = sprintf( __( 'The uploaded file exceeds %s bytes.', 'sitepress' ), 100000 );
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL;
|
||||
$error_message = __( 'The uploaded file was only partially uploaded.', 'sitepress' );
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE;
|
||||
$error_message = __( 'No file was uploaded.', 'sitepress' );
|
||||
break;
|
||||
case UPLOAD_ERR_NO_TMP_DIR;
|
||||
$error_message = __( 'Missing a temporary folder.', 'sitepress' );
|
||||
break;
|
||||
case UPLOAD_ERR_CANT_WRITE;
|
||||
$error_message = __( 'Failed to write file to disk.', 'sitepress' );
|
||||
break;
|
||||
case UPLOAD_ERR_EXTENSION;
|
||||
$error_message = __( 'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.', 'sitepress' );
|
||||
break;
|
||||
}
|
||||
|
||||
return Either::left( $error_message );
|
||||
} else {
|
||||
return Either::right( $file );
|
||||
}
|
||||
};
|
||||
|
||||
return Either::fromNullable( $data->get( 'name' ) )
|
||||
->map( Obj::prop( Fns::__, $_FILES ) )
|
||||
->map( $upload( $data->get( 'path' ) ) )
|
||||
->chain( $handleError )
|
||||
->map( $resize( $data->get( 'resize', [] ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
interface IWPML_AJAX_Action_Run {
|
||||
public function run();
|
||||
}
|
||||
Reference in New Issue
Block a user