213 lines
6.2 KiB
PHP
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();
|
|
}
|
|
}
|