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,34 @@
<?php
namespace WPML\TranslationRoles;
use WPML\API\Sanitize;
use WPML\Collect\Support\Collection;
use WPML\Ajax\IHandler;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\FP\Lst;
use WPML\FP\Obj;
use function WPML\FP\invoke;
class FindAvailableByRole implements IHandler {
const USER_SEARCH_LIMIT = 10;
/**
* @inheritDoc
*/
public function run( Collection $data ) {
$search = Sanitize::string( $data->get( 'search' ) );
$records = [
'translator' => \WPML_Translator_Records::class,
'manager' => \WPML_Translation_Manager_Records::class,
];
return Either::of( $data->get( 'role' ) )
->filter( Lst::includes( Fns::__, Obj::keys( $records ) ) )
->map( Obj::prop( Fns::__, $records ) )
->map( Fns::make() )
->map( invoke( 'search_for_users_without_capability' )->with( $search, self::USER_SEARCH_LIMIT ) );
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
use WPML\Ajax\IHandler;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\FP\Lst;
use WPML\FP\Obj;
use WPML\LIB\WP\User;
use function WPML\Container\make;
use function WPML\FP\pipe;
class GetManagerRecords implements IHandler {
/**
* @inheritDoc
*/
public function run( Collection $data ) {
$managers = make( \WPML_Translation_Manager_Records::class )->get_users_with_capability();
return Either::of(
[ 'managers' => Fns::map( User::withAvatar(), $managers ) ]
);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
use WPML\Ajax\IHandler;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\LIB\WP\User;
use function WPML\Container\make;
class GetTranslatorRecords implements IHandler {
/**
* @inheritDoc
*/
public function run( Collection $data ) {
$translators = make( \WPML_Translator_Records::class )->get_users_with_capability();
return Either::of(
[ 'translators' => Fns::map( User::withAvatar(), $translators ) ]
);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
use WPML\Ajax\IHandler;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\FP\Lst;
use WPML\FP\Obj;
use WPML\LIB\WP\User;
use function WPML\Container\make;
use function WPML\FP\invoke;
use function WPML\FP\pipe;
abstract class Remove implements IHandler {
/**
* @inheritDoc
*/
public function run( Collection $data ) {
// $removeRole :: WP_user -> WP_user
$removeRole = Fns::tap( invoke( 'remove_cap' )->with( static::getCap() ) );
// $removeOnlyI :: WP_user -> WP_user
$removeOnlyI = Fns::tap( pipe( Obj::prop( 'ID' ), User::deleteMeta( Fns::__, \WPML_TM_Wizard_Options::ONLY_I_USER_META ) ) );
// $doActions :: WP_user -> WP_user
$doActions = Fns::tap( function ( $user ) {
do_action( 'wpml_tm_remove_translation_role', $user, static::getCap() );
} );
return Either::fromNullable( $data->get( 'ID' ) )
->map( User::get() )
->filter( invoke( 'exists' ) )
->map( $removeRole )
->map( $removeOnlyI )
->map( $doActions )
->bimap( Fns::always( $this->msgUserNotFound() ), Fns::always( true ) );
}
abstract protected static function getCap();
protected function msgUserNotFound() {
return __( 'User not found', 'sitepress' );
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
class RemoveManager extends Remove {
/**
* @inheritDoc
*/
public function run( Collection $data ) {
$result = parent::run( $data );
do_action( 'wpml_tm_ate_synchronize_managers' );
return $result;
}
protected static function getCap() {
return \WPML_Manage_Translations_Role::CAPABILITY;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\FP\Obj;
use WPML\LIB\WP\User;
use function WPML\Container\make;
use function WPML\FP\invoke;
use function WPML\FP\pipe;
class RemoveTranslator extends Remove {
/**
* @inheritDoc
*/
public function run( Collection $data ) {
// $removeLanguagePairs :: WP_user -> WP_user
$removeLanguagePairs = Fns::tap( pipe( Obj::prop( 'ID' ), [ make( \WPML_Language_Pair_Records::class ), 'remove_all' ] ) );
// $resignFromUnfinishedJobs :: WP_user -> WP_user
$resignFromUnfinishedJobs = Fns::tap( [ make( \TranslationManagement::class ), 'resign_translator_from_unfinished_jobs' ] );
$runParentRemove = function() use ( $data ) {
return parent::run( $data );
};
return Either::fromNullable( $data->get( 'ID' ) )
->map( User::get() )
->filter( invoke( 'exists' ) )
->map( $removeLanguagePairs )
->map( $resignFromUnfinishedJobs )
->bichain(
pipe( Fns::always( $this->msgUserNotFound() ), Either::left() ),
$runParentRemove
)
->map( function( $result ) {
do_action( 'wpml_tm_ate_synchronize_translators' );
return $result;
} );
}
protected static function getCap() {
return \WPML_Translator_Role::CAPABILITY;
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
use WPML\FP\Fns;
use WPML\LIB\WP\Hooks;
use WPML\LIB\WP\User;
use function WPML\Container\make;
use function WPML\FP\invoke;
use function WPML\FP\partial;
class SaveManager extends SaveUser {
const TRANSLATION_MANAGER_INSTRUCTIONS_TEMPLATE = 'notification/translation-manager-instructions.twig';
/**
* @inheritDoc
*/
public function run( Collection $data ) {
// $setRole :: WP_User -> WP_User
$setRole = Fns::tap( invoke( 'add_cap' )->with( \WPML_Manage_Translations_Role::CAPABILITY ) );
return self::getUser( $data )
->map( $setRole )
->map( [ self::class, 'sendInstructions' ] )
->map( function( $user ) {
do_action( 'wpml_tm_ate_synchronize_managers' );
return true;
} );
}
public static function sendInstructions( \WP_User $manager ) {
$siteName = get_option( 'blogname' );
$translationSetupUrl = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php' );
$adminUser = User::getCurrent();
$model = [
'setup_url' => esc_url( $translationSetupUrl ),
'username' => $manager->display_name,
'intro_message_1' => sprintf( __( 'You are the Translation Manager for %s. This role lets you manage everything related to translation for this site.', 'sitepress' ), $siteName ),
'intro_message_2' => __( 'Before you can start sending content to translation, you need to complete a short setup.', 'sitepress' ),
'setup' => __( 'Set-up the translation', 'sitepress' ),
'reminder' => sprintf( __( '* Remember, your login name for %1$s is %2$s. If you need help with your password, use the password reset in the login page.', 'sitepress' ), $siteName, $manager->user_login ),
'at_your_service' => __( 'At your service', 'sitepress' ),
'admin_name' => $adminUser->display_name,
'admin_for_site' => sprintf( __( 'Administrator for %s', 'sitepress' ), $siteName ),
];
$to = $manager->display_name . ' <' . $manager->user_email . '>';
$message = make( \WPML_TM_Email_Notification_View::class )->render_model(
$model,
self::TRANSLATION_MANAGER_INSTRUCTIONS_TEMPLATE
);
$subject = sprintf( __( 'You are now the Translation Manager for %s - action needed', 'sitepress' ), $siteName );
$headers = array(
'MIME-Version: 1.0',
'Content-type: text/html; charset=UTF-8',
'Reply-To: ' . $adminUser->display_name . ' <' . $adminUser->user_email . '>',
);
$forceDisplayName = Fns::always( $adminUser->display_name );
$sendMail = partial( 'wp_mail', $to, $subject, $message, $headers );
Hooks::callWithFilter( $sendMail, 'wp_mail_from_name', $forceDisplayName );
return true;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
use WPML\FP\Fns;
use WPML\FP\Lst;
use WPML\FP\Obj;
use function WPML\Container\make;
use function WPML\FP\invoke;
use function WPML\FP\partial;
use function WPML\FP\partialRight;
use function WPML\FP\pipe;
class SaveTranslator extends SaveUser {
/**
* @inheritDoc
*/
public function run( Collection $data ) {
$pairs = wpml_collect( $data->get( 'pairs' ) )
->filter( pipe( Obj::prop( 'to' ), Lst::length() ) )
->mapWithKeys( function ( $pair ) { return [ $pair['from'] => $pair['to'] ]; } )
->toArray();
// $setRole :: WP_User -> WP_User
$setRole = Fns::tap( invoke( 'add_cap' )->with( \WPML_Translator_Role::CAPABILITY ) );
// $storePairs :: int -> int
$storePairs = Fns::tap( partialRight( [ make( \WPML_Language_Pair_Records::class ), 'store' ], $pairs ) );
return self::getUser( $data )
->map( $setRole )
->map( Obj::prop( 'ID' ) )
->map( $storePairs )
->map( function( $user ) {
do_action( 'wpml_update_translator' );
return $user;
} )
->map( Fns::always( true ) );
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace WPML\TranslationRoles;
use WPML\Collect\Support\Collection;
use WPML\Ajax\IHandler;
use WPML\FP\Either;
use WPML\FP\Fns;
use WPML\FP\Left;
use WPML\FP\Lst;
use WPML\FP\Obj;
use WPML\FP\Right;
use WPML\LIB\WP\User;
use WPML\TM\Menu\TranslationRoles\RoleValidator;
use WPML\LIB\WP\WordPress;
use function WPML\FP\invoke;
use function WPML\FP\partial;
abstract class SaveUser implements IHandler {
/**
* @param Collection $data
*
* @return Left|Right
*/
protected static function getUser( Collection $data ) {
$createNew = partial( [ self::class, 'createNewWpUser' ], $data );
return Either::fromNullable( Obj::path( [ 'user', 'ID' ], $data ) )
->map( User::get() )
->bichain( $createNew, Either::of() );
}
/**
* @param Collection $data
*
* @return Left|Right
*/
public static function createNewWpUser( Collection $data ) {
$get = Obj::prop( Fns::__, $data->get( 'user' ) );
$firstName = $get( 'first' );
$lastName = $get( 'last' );
$email = filter_var( $get( 'email' ), FILTER_SANITIZE_EMAIL );
$userName = $get( 'userName' );
if ( ! RoleValidator::isValid( $get( 'wpRole' ) ) ) {
return Either::left( __( 'The role was not found.', 'sitepress' ) );
}
$role = RoleValidator::getTheHighestPossibleIfNotValid( $get( 'wpRole' ) );
if ( $email && $userName && $role ) {
$userId = User::insert(
[
'first_name' => $firstName,
'last_name' => $lastName,
'user_email' => $email,
'user_login' => $userName,
'role' => $role,
'user_pass' => wp_generate_password(),
]
);
return WordPress::handleError( $userId )
->bimap( invoke( 'get_error_messages' ), User::notifyNew() )
->bimap( Lst::join( ', ' ), User::get() );
} else {
return Either::left( __( 'The user could not be created', 'sitepress' ) );
}
}
}