wpdb = $wpdb; $this->jobs = wpml_collect( [] ); } /** * This method will retrieve data from the ATE job ID. * Beware of the returned data shape which is not standard. * * @param int $ateJobId * * @return array|null */ public function get_data_from_ate_job_id( $ateJobId ) { $ateJobId = (int) $ateJobId; $this->warmCache( [], [ $ateJobId ] ); $job = $this->jobs->first( function( JobRecord $job ) use ( $ateJobId ) { return $job->ateJobId === $ateJobId; } ); if ( $job ) { /** @var JobRecord $job */ return [ 'wpml_job_id' => $job->wpmlJobId, 'ate_job_data' => [ 'ate_job_id' => $job->ateJobId, ], ]; } return null; } /** * @param int $wpmlJobId * @param array $ateJobData */ public function store( $wpmlJobId, array $ateJobData ) { $ateJobData['job_id'] = (int) $wpmlJobId; $this->warmCache( [ $wpmlJobId ] ); $job = $this->jobs->get( $wpmlJobId ); if ( ! $job ) { $job = new JobRecord(); $job->wpmlJobId = (int) $wpmlJobId; } if ( isset( $ateJobData[ self::FIELD_ATE_JOB_ID ] ) ) { $job->ateJobId = $ateJobData[ self::FIELD_ATE_JOB_ID ]; } $this->persist( $job ); } /** * @param JobRecord $job */ public function persist( JobRecord $job ) { $this->jobs->put( $job->wpmlJobId, $job ); $this->wpdb->update( $this->wpdb->prefix . 'icl_translate_job', [ 'editor_job_id' => $job->ateJobId ], [ 'job_id' => $job->wpmlJobId ], [ '%d' ], [ '%d' ] ); } /** * This method will load in-memory the required jobs. * * @param array $wpmlJobIds * @param array $ateJobIds */ public function warmCache( array $wpmlJobIds, array $ateJobIds = [] ) { $wpmlJobIds = wpml_collect( $wpmlJobIds )->reject( $this->isAlreadyLoaded( 'wpmlJobId' ) )->toArray(); $ateJobIds = wpml_collect( $ateJobIds )->reject( $this->isAlreadyLoaded( 'ateJobId' ) )->toArray(); $where = []; if ( $wpmlJobIds ) { $where[] = 'job_id IN(' . wpml_prepare_in( $wpmlJobIds, '%d' ) . ')'; } if ( $ateJobIds ) { $where[] = 'editor_job_id IN(' . wpml_prepare_in( $ateJobIds, '%d' ) . ')'; } if ( ! $where ) { return; } $whereHasJobIds = implode( ' OR ', $where ); $rows = $this->wpdb->get_results( " SELECT job_id, editor_job_id FROM {$this->wpdb->prefix}icl_translate_job WHERE editor = '" . WPML_TM_Editors::ATE . "' AND ({$whereHasJobIds}) " ); foreach ( $rows as $row ) { $job = new JobRecord( $row ); $this->jobs->put( $job->wpmlJobId, $job ); } } /** * @param $idPropertyName * * @return \Closure */ private function isAlreadyLoaded( $idPropertyName ) { $loadedIds = $this->jobs->pluck( $idPropertyName )->values()->toArray(); return function( $jobId ) use ( $loadedIds ) { return in_array( $jobId, $loadedIds, true ); }; } /** * @param int $wpmlJobId * * @return int */ public function get_ate_job_id( $wpmlJobId ) { return $this->get( $wpmlJobId )->ateJobId; } /** * @param int $wpmlJobId * * @return bool */ public function is_editing_job( $wpmlJobId ) { return $this->get( $wpmlJobId )->isEditing(); } /** * @param $wpmlJobId * * @return JobRecord */ public function get( $wpmlJobId ) { if ( ! $this->jobs->has( $wpmlJobId ) ) { $this->warmCache( [ (int) $wpmlJobId ] ); } /** @var null|JobRecord $job */ $job = $this->jobs->get( $wpmlJobId ); if ( ! $job || ! $job->ateJobId ) { $this->restoreJobDataFromATE( $wpmlJobId ); $job = $this->jobs->get( $wpmlJobId, new JobRecord() ); } return $job; } /** * This method will try to recover the job data from ATE server, * and persist it in the local repository. * * @param int $wpmlJobId */ private function restoreJobDataFromATE( $wpmlJobId ) { $data = apply_filters( 'wpml_tm_ate_job_data_fallback', [], $wpmlJobId ); if ( $data ) { try { $this->store( $wpmlJobId, $data ); } catch ( Exception $e ) { $error_log = new WPML_TM_ATE_API_Error(); $error_log->log( $e->getMessage() ); } } } }