Hooks.php
4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php
namespace WPML\PB\AutoUpdate;
use WPML\FP\Fns;
use WPML\FP\Logic;
use WPML\FP\Lst;
use WPML\FP\Maybe;
use WPML\FP\Relation;
use WPML\PB\Shutdown\Hooks as ShutdownHooks;
use function WPML\FP\invoke;
use function WPML\FP\partialRight;
use function WPML\FP\pipe;
class Hooks implements \IWPML_Backend_Action, \IWPML_Frontend_Action, \IWPML_DIC_Action {
const HASH_SEP = '-';
/** @var \WPML_PB_Integration $pbIntegration */
private $pbIntegration;
/** @var \WPML_Translation_Element_Factory $elementFactory */
private $elementFactory;
/** @var \WPML_Page_Builders_Page_Built $pageBuilt */
private $pageBuilt;
/** @var array $translationStatusesUpdaters */
private $translationStatusesUpdaters = [];
public function __construct(
\WPML_PB_Integration $pbIntegration,
\WPML_Translation_Element_Factory $elementFactory,
\WPML_Page_Builders_Page_Built $pageBuilt
) {
$this->pbIntegration = $pbIntegration;
$this->elementFactory = $elementFactory;
$this->pageBuilt = $pageBuilt;
}
public function add_hooks() {
if ( Settings::isEnabled() && $this->isTmLoaded() ) {
add_filter( 'wpml_tm_delegate_translation_statuses_update', [ $this, 'enqueueTranslationStatusUpdate'], 10, 3 );
add_filter( 'wpml_tm_post_md5_content', [ $this, 'getMd5ContentFromPackageStrings' ], 10, 2 );
add_action( 'shutdown', [ $this, 'afterRegisterAllStringsInShutdown' ], ShutdownHooks::PRIORITY_REGISTER_STRINGS + 1 );
}
}
public function isTmLoaded() {
return defined( 'WPML_TM_VERSION' );
}
/**
* @param bool $isDelegated
* @param int $originalPostId
* @param callable $statusesUpdater
*
* @return bool
*/
public function enqueueTranslationStatusUpdate( $isDelegated, $originalPostId, $statusesUpdater ) {
$this->translationStatusesUpdaters[ $originalPostId ] = $statusesUpdater;
return true;
}
/**
* @param string $content
* @param \WP_Post $post
*
* @return string
*/
public function getMd5ContentFromPackageStrings( $content, $post ) {
// $joinPackageStringHashes :: \WPML_Package → string
$joinPackageStringHashes = pipe(
invoke( 'get_package_strings' )->with( true ),
Lst::pluck( 'value' ),
Lst::sort( Relation::gt() ),
Lst::join( self::HASH_SEP )
);
return Maybe::of( $post->ID )
->map( [ self::class, 'getPackages' ] )
->map( Fns::map( $joinPackageStringHashes ) )
->filter()
->map( Lst::join( self::HASH_SEP ) )
->getOrElse( $content );
}
/**
* @param int $postId
*
* @return \WPML_Package[]
*/
public static function getPackages( $postId ) {
return apply_filters( 'wpml_st_get_post_string_packages', [], $postId );
}
/**
* We need to update translation statuses after string registration
* to make sure we build the content hash with the new strings.
*/
public function afterRegisterAllStringsInShutdown() {
if ( $this->translationStatusesUpdaters ) {
do_action( 'wpml_cache_clear' );
foreach ( $this->translationStatusesUpdaters as $originalPostId => $translationStatusesUpdater ) {
if ( \get_post( $originalPostId ) ) {
call_user_func( $translationStatusesUpdater );
$this->resaveTranslations( $originalPostId );
}
}
}
}
/**
* @param int $postId
*/
private function resaveTranslations( $postId ) {
if ( ! $this->isPageBuilder( $postId ) ) {
return;
}
// $ifOriginal :: \WPML_Post_Element → bool
$ifOriginal = pipe( invoke( 'get_source_language_code' ), Logic::not() );
// $ifCompleted :: \WPML_Post_Element → bool
$ifCompleted = pipe( [ TranslationStatus::class, 'get' ], Relation::equals( ICL_TM_COMPLETE ) );
// $resaveElement :: \WPML_Post_Element → null
$resaveElement = \WPML\FP\Fns::unary( partialRight( [ $this->pbIntegration, 'resave_post_translation_in_shutdown' ], false ) );
wpml_collect( $this->elementFactory->create_post( $postId )->get_translations() )
->reject( $ifOriginal )
->filter( $ifCompleted )
->each( $resaveElement );
}
/**
* @param int $postId
*
* @return bool
*/
private function isPageBuilder( $postId ) {
$isPbPostWithoutStrings = function( $postId ) {
$post = get_post( $postId );
return $post instanceof \WP_Post
&& $this->pageBuilt->is_page_builder_page( $post );
};
return self::getPackages( $postId )
|| $isPbPostWithoutStrings( $postId );
}
}