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' ) ); }; } }