Files
doitinpoland.com/wp-content/plugins/sitepress-multilingual-cms/classes/automatic-translation/Actions.php
2023-09-12 21:41:04 +02:00

213 lines
6.2 KiB
PHP

<?php
namespace WPML\TM\AutomaticTranslation\Actions;
use WPML\Element\API\Languages;
use WPML\FP\Cast;
use WPML\FP\Fns;
use WPML\FP\Logic;
use WPML\FP\Lst;
use WPML\FP\Obj;
use WPML\LIB\WP\Hooks;
use WPML\LIB\WP\Post;
use WPML\Settings\PostType\Automatic;
use WPML\TM\API\ATE\LanguageMappings;
use WPML\TM\API\Job\Map;
use function WPML\FP\invoke;
use WPML\LIB\WP\User;
use function WPML\FP\partial;
use WPML\TM\API\Jobs;
use function WPML\FP\pipe;
use function WPML\FP\spreadArgs;
class Actions implements \IWPML_Action {
/** @see \WPML\PB\Shutdown\Hooks */
const PRIORITY_AFTER_PB_PROCESS = 100;
/** @var \WPML_Translation_Element_Factory */
private $translationElementFactory;
public function __construct(
\WPML_Translation_Element_Factory $translationElementFactory
) {
$this->translationElementFactory = $translationElementFactory;
}
public function add_hooks() {
Hooks::onAction( 'wpml_after_save_post', 100 )
->then( spreadArgs( Fns::memorize( [ $this, 'sendToTranslation' ] ) ) );
}
/**
* @param int $postId
*
* @throws \WPML\Auryn\InjectionException
*/
public function sendToTranslation( $postId ) {
if ( empty( $_POST['icl_minor_edit'] ) ) {
$postElement = $this->translationElementFactory->create_post( $postId );
if (
$postElement->is_translatable()
&& ! $postElement->is_display_as_translated()
&& Automatic::isAutomatic( $postElement->get_type() )
) {
Hooks::onAction( 'shutdown', self::PRIORITY_AFTER_PB_PROCESS )
->then( function() use ( $postId ) {
$postElement = $this->translationElementFactory->create_post( $postId );
if (
$postElement->get_wp_object()->post_status === 'publish'
&& $postElement->get_language_code() === Languages::getDefaultCode()
) {
$secondaryLanguageCodes = LanguageMappings::geCodesEligibleForAutomaticTranslations();
$this->cancelExistingTranslationJobs( $postElement, $secondaryLanguageCodes );
$this->createTranslationJobs( $postElement, $secondaryLanguageCodes );
}
} );
}
}
}
/**
* @param \WPML_Post_Element $postElement
* @param array $languages
*
* @throws \WPML\Auryn\InjectionException
*/
private function cancelExistingTranslationJobs( \WPML_Post_Element $postElement, $languages ) {
$getJobEntity = function ( $jobId ) {
return wpml_tm_get_jobs_repository()->get_job( Map::fromJobId( $jobId ), \WPML_TM_Job_Entity::POST_TYPE );
};
wpml_collect( $languages )
->map( Jobs::getPostJob( $postElement->get_element_id(), $postElement->get_type() ) )
->filter()
->reject( self::isCompleteAndUpToDateJob() )
->map( Obj::prop( 'job_id' ) )
->map( Jobs::clearReviewStatus() )
->map( Jobs::setNotTranslatedStatus() )
->map( Jobs::clearTranslated() )
->map( $getJobEntity )
->map( Fns::tap( partial( 'do_action', 'wpml_tm_job_cancelled' ) ) );
}
/**
* @return callable :: \stdClass -> bool
*/
private static function isCompleteAndUpToDateJob() {
return function ( $job ) {
return Cast::toInt( $job->needs_update ) !== 1 && Cast::toInt( $job->status ) === ICL_TM_COMPLETE;
};
}
public function createTranslationJobs( \WPML_Post_Element $postElement, $targetLanguages ) {
$isNotCompleteAndUpToDate = Logic::complement( self::isCompleteAndUpToDateJob() );
$sendToTranslation = function ( $language ) use ( $postElement, $isNotCompleteAndUpToDate ) {
/** @var \stdClass|false $job */
$job = Jobs::getPostJob( $postElement->get_element_id(), $postElement->get_type(), $language );
if (
! $job
|| (
$isNotCompleteAndUpToDate( $job )
&& $this->canJobBeReTranslatedAutomatically( $job->job_id )
)
) {
$this->createJob( $postElement, $language );
}
};
Fns::map( $sendToTranslation, $targetLanguages );
}
/**
* @param int $jobId
*
* @return bool
*/
private function canJobBeReTranslatedAutomatically( $jobId ) {
return wpml_tm_load_old_jobs_editor()->get( $jobId ) === \WPML_TM_Editors::ATE;
}
/**
* @param \WPML_Post_Element $postElement
* @param string $language
*/
private function createJob( \WPML_Post_Element $postElement, $language ) {
$batch = new \WPML_TM_Translation_Batch(
[
new \WPML_TM_Translation_Batch_Element(
$postElement->get_element_id(),
'post',
$postElement->get_language_code(),
[ $language => 1 ]
),
],
\TranslationProxy_Batch::get_generic_batch_name( true ),
[ $language => User::getCurrentId() ]
);
wpml_load_core_tm()->send_jobs( $batch, 'post', Jobs::SENT_AUTOMATICALLY );
}
/**
* @param $sourceLanguage
* @param array $elements E.g. [ [1, 'fr'], [1, 'de'], [2, 'fr'] ]
*/
public function createNewTranslationJobs( $sourceLanguage, array $elements ) {
$getTargetLang = Lst::nth( 1 );
$setTranslateAction = Obj::objOf( Fns::__, \TranslationManagement::TRANSLATE_ELEMENT_ACTION );
$setTranslatorId = Obj::objOf( Fns::__, User::getCurrentId() );
$targetLanguages = \wpml_collect( $elements )
->map( $getTargetLang )
->unique()
->mapWithKeys( $setTranslatorId )
->toArray();
$makeBatchElement = function ( $targetLanguages, $postId ) use ( $sourceLanguage ) {
return new \WPML_TM_Translation_Batch_Element(
$postId,
'post',
$sourceLanguage,
$targetLanguages->toArray()
);
};
$batchElements = \wpml_collect( $elements )
->groupBy( 0 )
->map( Fns::map( $getTargetLang ) )
->map( invoke( 'mapWithKeys' )->with( $setTranslateAction ) )
->map( $makeBatchElement )
->values()
->toArray();
$batch = new \WPML_TM_Translation_Batch(
$batchElements,
\TranslationProxy_Batch::get_generic_batch_name( true ),
$targetLanguages
);
wpml_load_core_tm()->send_jobs( $batch, 'post', Jobs::SENT_AUTOMATICALLY );
$getJobId = pipe(
Fns::converge( Jobs::getPostJob(), [
Obj::prop( 'postId' ),
Obj::prop( 'postType' ),
Obj::prop( 'lang' )
] ),
Obj::prop( 'job_id' ),
Fns::unary( 'intval' )
);
return \wpml_collect( $elements )
->map( Lst::zipObj( [ 'postId', 'lang' ] ) )
->map( Obj::addProp( 'postType', pipe( Obj::prop( 'postId' ), Post::getType() ) ) )
->map( Obj::addProp( 'jobId', $getJobId ) )
->toArray();
}
}