File: //var/www/azvo/wp-content/plugins/sitepress-multilingual-cms/classes/jobs/Manual.php
<?php
namespace WPML\TM\Jobs;
use WPML\Element\API\PostTranslations;
use WPML\FP\Lst;
use WPML\FP\Maybe;
use WPML\FP\Obj;
use WPML\FP\Relation;
use WPML\LIB\WP\User;
use WPML\Records\Translations as TranslationRecords;
use WPML\TM\API\Jobs;
use function WPML\FP\pipe;
class Manual {
/**
* @param array $params
*
* @return \WPML_Translation_Job|null
*/
public function createOrReuse( array $params ) {
$jobId = (int) filter_var( Obj::propOr( 0, 'job_id', $params ), FILTER_SANITIZE_NUMBER_INT );
list( $jobId, $trid, $updateNeeded, $targetLanguageCode, $elementType ) = $this->get_job_data_for_restore( $jobId, $params );
$sourceLangCode = filter_var( Obj::prop( 'source_language_code', $params ), FILTER_SANITIZE_FULL_SPECIAL_CHARS );
if ( $trid && $targetLanguageCode && ( $updateNeeded || ! $jobId ) ) {
$postId = $this->getOriginalPostId( $trid );
// if $jobId is not a truthy value this means that a new translation is going to be created in $targetLanguageCode (the + icon is clicked in posts list page)
// and in this case we try to get the post id that exists in $sourceLangCode
// @see https://onthegosystems.myjetbrains.com/youtrack/issue/wpmldev-1934
if ( ! $jobId ) {
$postId = $this->getPostIdInLang( $trid, $sourceLangCode ) ?: $postId;
}
if ( $postId && $this->can_user_translate( $sourceLangCode, $targetLanguageCode, $postId ) ) {
return $this->markJobAsManual( $this->createLocalJob( $postId, $sourceLangCode, $targetLanguageCode, $elementType ) );
}
}
return $jobId ? $this->markJobAsManual( wpml_tm_load_job_factory()->get_translation_job_as_active_record( $jobId ) ) : null;
}
private function getOriginalPostId( $trid ) {
return Obj::prop( 'element_id', TranslationRecords::getSourceByTrid( $trid ) );
}
/**
* @param string|int $trid
* @param string $lang
*
* @return string|int
*/
private function getPostIdInLang( $trid, $lang ) {
$getElementId = pipe( Lst::find( Relation::propEq( 'language_code', $lang ) ), Obj::prop( 'element_id' ) );
return $getElementId( TranslationRecords::getByTrid( $trid ) );
}
/**
* @param $jobId
* @param array $params
*
* @return array ( job_id, trid, updated_needed, language_code, post_type )
*/
private function get_job_data_for_restore( $jobId, array $params ) {
$trid = (int) filter_var( Obj::prop( 'trid', $params ), FILTER_SANITIZE_NUMBER_INT );
$updateNeeded = (bool) filter_var( Obj::prop( 'update_needed', $params ), FILTER_SANITIZE_NUMBER_INT );
$languageCode = (string) filter_var( Obj::prop( 'language_code', $params ), FILTER_SANITIZE_FULL_SPECIAL_CHARS );
$job = null;
if ( $jobId ) {
$job = Jobs::get( $jobId );
} else if ( $trid && $languageCode ) {
$job = Jobs::getTridJob( $trid, $languageCode );
}
if ( is_object( $job ) ) {
return [
$jobId,
Obj::prop( 'trid', $job ),
Obj::prop( 'needs_update', $job ),
Obj::prop( 'language_code', $job ),
Obj::prop( 'original_post_type', $job )
];
}
$elementType = $trid ? Obj::path( [ 0, 'element_type' ], TranslationRecords::getByTrid( $trid ) ) : null;
return [ $jobId, $trid, $updateNeeded, $languageCode, $elementType, ];
}
/**
* @param string $sourceLangCode
* @param string $targetLangCode
* @param string $postId
*
* @return bool
*/
private function can_user_translate( $sourceLangCode, $targetLangCode, $postId ) {
$args = [
'lang_from' => $sourceLangCode,
'lang_to' => $targetLangCode,
'post_id' => $postId,
];
return wpml_tm_load_blog_translators()->is_translator( User::getCurrentId(), $args );
}
/**
* @param int $originalPostId
* @param string $sourceLangCode
* @param string $targetLangCode
* @param string $elementType
*
* @return \WPML_Translation_Job|null
*/
private function createLocalJob( $originalPostId, $sourceLangCode, $targetLangCode, $elementType ) {
$jobId = wpml_tm_load_job_factory()->create_local_job( $originalPostId, $targetLangCode, null, $elementType, Jobs::SENT_MANUALLY, $sourceLangCode );
return Maybe::fromNullable( $jobId )
->map( [ wpml_tm_load_job_factory(), 'get_translation_job_as_active_record' ] )
->map( $this->maybeAssignTranslator() )
->map( $this->maybeSetJobStatus() )
->getOrElse( null );
}
private function maybeAssignTranslator() {
return function ( $jobObject ) {
if ( $jobObject->get_translator_id() <= 0 ) {
$jobObject->assign_to( User::getCurrentId() );
}
return $jobObject;
};
}
private function maybeSetJobStatus() {
return function ( $jobObject ) {
if ( $this->isDuplicate( $jobObject ) ) {
Jobs::setStatus( (int) $jobObject->get_id(), ICL_TM_DUPLICATE );
} elseif ( (int) $jobObject->get_status_value() !== ICL_TM_COMPLETE ) {
Jobs::setStatus( (int) $jobObject->get_id(), ICL_TM_IN_PROGRESS );
}
return $jobObject;
};
}
private function markJobAsManual( $jobObject ) {
$jobObject && Jobs::clearAutomatic( $jobObject->get_id() );
return $jobObject;
}
private function isDuplicate( \WPML_Translation_Job $jobObject ) {
return Maybe::of( $jobObject->get_original_element_id() )
->map( PostTranslations::get() )
->map( Obj::prop( $jobObject->get_language_code() ) )
->map( Obj::prop( 'element_id' ) )
->map( [ wpml_get_post_status_helper(), 'is_duplicate' ] )
->getOrElse( false );
}
}