first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
<?php
namespace WPML\ICLToATEMigration\Endpoints;
use WPML\Ajax\IHandler;
use WPML\Collect\Support\Collection;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\FP\Json;
use WPML\FP\Logic;
use WPML\ICLToATEMigration\ICLStatus;
use WPML\TM\API\TranslationServices;
use WPML\TM\TranslationProxy\Services\AuthorizationFactory;
class AuthenticateICL implements IHandler {
/** @var TranslationServices */
private $translationServices;
/** @var ICLStatus */
private $iclStatus;
/**
* @param TranslationServices $translationServices
*/
public function __construct( TranslationServices $translationServices ) {
$this->translationServices = $translationServices;
$this->iclStatus = new ICLStatus( $translationServices );
}
public function run( Collection $data ) {
return Either::of( $data->get( 'token' ) )
->chain( Logic::ifElse(
Fns::identity(),
Either::of(),
Fns::always( Either::left( __( 'Token is not defined', 'sitepress-multilingual-cms' ) ) )
) )
->chain( Logic::ifElse(
[ $this->iclStatus, 'isActivatedAndAuthorized' ],
Fns::always( Either::left( __( 'ICanLocalize.com is already active and authorized', 'sitepress-multilingual-cms' ) ) ),
Either::of()
) )
->map( Logic::ifElse(
$this->isAnotherServiceCurrentlyActive(),
Fns::tap( [ $this->translationServices, 'deselect' ] ),
Fns::identity()
) )
->chain( Logic::ifElse(
[ $this->iclStatus, 'isActivated' ],
Either::of(),
function ( $token ) {
return $this->translationServices->selectBySUID( ICLStatus::SUID )->map( Fns::always( $token ) );
}
) )
->chain( [ $this->translationServices, 'authorize' ] )
->bimap( $this->errorResponse(), $this->successResponse() );
}
private function successResponse() {
return Fns::always( __( 'Service activated.', 'sitepress-multilingual-cms' ) );
}
private function errorResponse() {
return function ( $errorDetails = '' ) {
return [
'message' => __( 'The authentication didn\'t work. Please make sure you entered your details correctly and try again.', 'sitepress-multilingual-cms' ),
'details' => $errorDetails
];
};
}
private function isAnotherServiceCurrentlyActive() {
return function () {
return $this->translationServices->isAnyActive() && ! $this->iclStatus->isActivated();
};
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace WPML\ICLToATEMigration\Endpoints;
use WPML\Ajax\IHandler;
use WPML\Collect\Support\Collection;
use WPML\FP\Either;
use WPML\ICLToATEMigration\Data;
class DeactivateICL implements IHandler {
public function run( Collection $data ) {
if ( \TranslationProxy::is_current_service_active_and_authenticated() ) {
\TranslationProxy::deselect_active_service();
global $sitepress_settings;
$translationServiceData = current( $sitepress_settings['icl_translation_projects'] );
Data::setICLDeactivated( true );
Data::saveICLCredentials( $translationServiceData );
}
return Either::of( true );
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace WPML\ICLToATEMigration\Endpoints\TranslationMemory;
use WPML\Ajax\IHandler;
use WPML\Collect\Support\Collection;
use WPML\FP\Either;
use WPML\ICLToATEMigration\Data;
use WPML_TM_ATE_API;
class CheckMigrationStatus implements IHandler {
/**
* @var WPML_TM_ATE_API
*/
private $apiClient;
/**
* @param WPML_TM_ATE_API $apiClient
*/
public function __construct( WPML_TM_ATE_API $apiClient ) {
$this->apiClient = $apiClient;
}
public function run( Collection $data ) {
$status = 'done';
if ( 'done' === $status ) {
Data::setMemoryMigrated( true );
}
return Either::of( [
'started_at' => null,
'finished_at' => null,
'status' => $status,
'last_imported_icl_id' => 15,
'imported_count' => 4
] );
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace WPML\ICLToATEMigration\Endpoints\TranslationMemory;
use WPML\Ajax\IHandler;
use WPML\Collect\Support\Collection;
use WPML\FP\Either;
use WPML_TM_ATE_API;
class StartMigration implements IHandler {
/**
* @var WPML_TM_ATE_API
*/
private $apiClient;
/**
* @param WPML_TM_ATE_API $apiClient
*/
public function __construct( WPML_TM_ATE_API $apiClient ) {
$this->apiClient = $apiClient;
}
public function run( Collection $data ) {
// call ATE endpoint to trigger translation memory migration
// This should be the final version I comment out because the api is not working as expected
/*$responde = $this->apiClient->start_translation_memory_migration();
return Either::of( $responde );*/
// I have mocked the return of the APi for now, will be removed for the final version
return Either::of( [
'started_at' => null,
'finished_at' => null,
'status' => 'in_progress',
'last_imported_icl_id' => 15,
'imported_count' => 4
] );
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace WPML\ICLToATEMigration\Endpoints\Translators;
use WPML\Ajax\IHandler;
use WPML\Collect\Support\Collection;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML_TM_ATE_API;
class GetFromICL implements IHandler {
/**
* @var WPML_TM_ATE_API
*/
private $apiClient;
public function __construct( WPML_TM_ATE_API $apiClient ) {
$this->apiClient = $apiClient;
}
public function run( Collection $data ) {
global $sitepress_settings;
$translationServiceData = current( $sitepress_settings['icl_translation_projects'] );
$result = $this->apiClient->import_icl_translators( $translationServiceData['ts_id'], $translationServiceData['ts_access_key'] );
if ( Fns::isLeft( $result ) ) {
return Either::left( __( 'Error happened! Please try again.', 'sitepress-multilingual-cms' ) );
}
return GetFromICLResponseMapper::map( $result->get()->records );
}
}

View File

@@ -0,0 +1,78 @@
<?php
// This is sample of data that mapper returns formatted data same as it.
// return Either::of( [
// 'translators' => [
// [
// 'user' => [
// 'id' => 1,
// 'first' => 'Translator',
// 'last' => 'First',
// 'email' => 'translator3@ytest.com',
// 'userName' => 'translator',
// 'wpRole' => 'author',
// ],
// 'languagePairs' => [
// 'en' => [ 'ar', 'bs'],
// ],
// ],
// ]
// ] );
namespace WPML\ICLToATEMigration\Endpoints\Translators;
use WPML\FP\Either;
use WPML\FP\Fns;
class GetFromICLResponseMapper {
/**
* Returns formatted data of translators.
*
* @param array $records
*
* @return callable|\WPML\FP\Right
*/
public static function map( $records ) {
return Either::of( [ 'translators' => Fns::map( [ self::class, 'constructUserData' ], $records ) ] );
}
/**
* Formats translator data
*
* @param object $record
*
* @return array
*/
public static function constructUserData( $record ) {
$user = get_user_by( 'email', $record->email );
return [
'user' => [
'id' => $record->icl_id,
'first' => $record->first_name,
'last' => $record->last_name,
'email' => $record->email,
'userName' => $user ? $user->data->user_login : strtolower( $record->first_name . '_' . $record->last_name ),
'wpRole' => $user ? current( $user->roles ) : 'subscriber'
],
'languagePairs' => self::constructUserLanguagePairs( $record->lang_pairs )
];
}
/**
* Formats translator language pairs data
*
* @param array $langPairs
*
* @return array
*/
public static function constructUserLanguagePairs( $langPairs ) {
$constructedLangPairs = [];
foreach ( $langPairs as $langPair ) {
$constructedLangPairs[ $langPair->from ][] = $langPair->to;
}
return $constructedLangPairs;
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace WPML\ICLToATEMigration\Endpoints\Translators;
use WPML\Ajax\IHandler;
use WPML\Collect\Support\Collection;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\FP\Left;
use WPML\FP\Lst;
use WPML\FP\Obj;
use WPML\FP\Logic;
use WPML\Element\API\Languages;
use WPML\FP\Right;
use function WPML\Container\make;
use function WPML\FP\invoke;
use function WPML\FP\partialRight;
use WPML\TranslationRoles\SaveUser;
use function WPML\FP\pipe;
class Save extends SaveUser {
const ERROR_MESSAGE_TRANSLATORS = 'There was an error when saving the following translators:';
const SUCCESS_MESSAGE_TRANSLATORS = 'The translators were saved successfully.';
/**
* @inheritDoc
*/
public function run( Collection $data ) {
return Either::of( $data )
->map( Fns::map( $this->createTranslator() ) )
->chain( $this->syncAteIfRequired() )
->chain( $this->handleErrors() );
}
/**
* Creates a translator and returns either an error or the translator email.
*
* @return callable(Collection):Either
*/
private function createTranslator() {
return function( $translator ) {
$handleError = function($error) use ($translator) {
return [ 'translator' => $translator, 'error' => $error ];
};
$translator = \wpml_collect( $translator );
return self::getUser( \wpml_collect( $translator ) )
->map( Fns::tap( invoke( 'add_cap' )->with( \WPML_Translator_Role::CAPABILITY ) ) )
->map( Obj::prop( 'ID' ) )
->map( Fns::tap( partialRight( [ make( \WPML_Language_Pair_Records::class ), 'store_active' ], $translator->get( 'languagePairs' ) ) ) )
->bimap( $handleError, Fns::always( $translator->get( 'user' )['email'] ) );
};
}
/**
* Synchronize ATE translators if one of the results was added.
*
* @return callable(Either[]):Either[]
*/
private function syncAteIfRequired() {
return function( $translatorResults ) {
foreach( $translatorResults as $translatorResult ) {
if ( $translatorResult instanceof Right ) {
do_action( 'wpml_update_translator' );
break;
}
}
return $translatorResults;
};
}
/**
* If any error happened, it prepares a message and the translators that failed.
*
* @return callable(Either[]):Either
*/
private function handleErrors() {
return function( $translatorResults ) {
$getErrorMsg = pipe( invoke( 'coalesce' )->with( Fns::identity(), Fns::identity() ), invoke( 'get' ) );
$getErrorDetails = pipe( Fns::filter( Fns::isLeft() ), Fns::map( $getErrorMsg ) );
$errorDetails = $getErrorDetails( $translatorResults );
if ( count( $errorDetails ) ) {
return Either::left( [
'message' => __( self::ERROR_MESSAGE_TRANSLATORS, 'sitepress' ),
'details' => $errorDetails
] );
}
return Either::right( __( self::SUCCESS_MESSAGE_TRANSLATORS, 'sitepress' ) );
};
}
}