1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
23:
24: namespace Quform\Traduttore_Registry;
25:
26: use DateTime;
27:
28: const TRANSIENT_KEY_PLUGIN = 'traduttore-registry-plugins';
29: const TRANSIENT_KEY_THEME = 'traduttore-registry-themes';
30:
31: 32: 33: 34: 35: 36: 37: 38: 39:
40: function add_project( $type, $slug, $api_url ) {
41: if ( ! has_action( 'init', __NAMESPACE__ . '\register_clean_translations_cache' ) ) {
42: add_action( 'init', __NAMESPACE__ . '\register_clean_translations_cache', 9999 );
43: }
44:
45: 46: 47:
48: add_filter(
49: 'translations_api',
50: static function ( $result, $requested_type, $args ) use ( $type, $slug, $api_url ) {
51: if ( $type . 's' === $requested_type && $slug === $args['slug'] ) {
52: return get_translations( $type, $args['slug'], $api_url );
53: }
54:
55: return $result;
56: },
57: 10,
58: 3
59: );
60:
61: 62: 63: 64: 65:
66: add_filter(
67: 'site_transient_update_' . $type . 's',
68: static function ( $value ) use ( $type, $slug, $api_url ) {
69: if ( ! $value ) {
70: $value = new \stdClass();
71: }
72:
73: if ( ! isset( $value->translations ) ) {
74: $value->translations = [];
75: }
76:
77: $translations = get_translations( $type, $slug, $api_url );
78:
79: if ( ! isset( $translations['translations'] ) ) {
80: return $value;
81: }
82:
83: $installed_translations = get_installed_translations( $type );
84: $locales = get_available_locales();
85:
86:
87: $locales = apply_filters( $type . 's_update_check_locales', $locales );
88: $active_locales = array_unique( $locales );
89:
90: foreach ( (array) $translations['translations'] as $translation ) {
91: if ( ! \in_array( $translation['language'], $active_locales, true ) ) {
92: continue;
93: }
94:
95: if ( $translation['updated'] && isset( $installed_translations[ $slug ][ $translation['language'] ] ) ) {
96: $local = sanitize_date( $installed_translations[ $slug ][ $translation['language'] ]['PO-Revision-Date'] );
97: $remote = new DateTime( $translation['updated'] );
98:
99: if ( $local >= $remote ) {
100: continue;
101: }
102: }
103:
104: $translation['type'] = $type;
105: $translation['slug'] = $slug;
106:
107: $value->translations[] = $translation;
108: }
109:
110: return $value;
111: }
112: );
113: }
114:
115: 116: 117: 118: 119:
120: function register_clean_translations_cache() {
121: $clear_plugin_translations = static function() {
122: clean_translations_cache( 'plugin' );
123: };
124: $clear_theme_translations = static function() {
125: clean_translations_cache( 'theme' );
126: };
127:
128: add_action( 'set_site_transient_update_plugins', $clear_plugin_translations );
129: add_action( 'delete_site_transient_update_plugins', $clear_plugin_translations );
130:
131: add_action( 'set_site_transient_update_themes', $clear_theme_translations );
132: add_action( 'delete_site_transient_update_themes', $clear_theme_translations );
133: }
134:
135: 136: 137: 138: 139: 140: 141:
142: function clean_translations_cache( $type ) {
143: $transient_key = constant( __NAMESPACE__ . '\TRANSIENT_KEY_' . strtoupper( $type ) );
144: $translations = get_site_transient( $transient_key );
145:
146: if ( ! \is_object( $translations ) ) {
147: return;
148: }
149:
150: 151: 152: 153:
154: $cache_lifespan = 15;
155: $time_not_changed = isset( $translations->_last_checked ) && ( time() - $translations->_last_checked ) > $cache_lifespan;
156:
157: if ( ! $time_not_changed ) {
158: return;
159: }
160:
161: delete_site_transient( $transient_key );
162: }
163:
164: 165: 166: 167: 168: 169: 170: 171: 172: 173:
174: function get_translations( $type, $slug, $url ) {
175: $transient_key = constant( __NAMESPACE__ . '\TRANSIENT_KEY_' . strtoupper( $type ) );
176: $translations = get_site_transient( $transient_key );
177:
178: if ( ! \is_object( $translations ) ) {
179: $translations = new \stdClass();
180: }
181:
182: if ( isset( $translations->{$slug} ) && \is_array( $translations->{$slug} ) ) {
183: return $translations->{$slug};
184: }
185:
186: $result = json_decode( wp_remote_retrieve_body( wp_remote_get( $url, [ 'timeout' => 2 ] ) ), true );
187: if ( ! \is_array( $result ) ) {
188:
189:
190: $result = [];
191: }
192:
193: $translations->{$slug} = $result;
194: $translations->_last_checked = time();
195:
196: set_site_transient( $transient_key, $translations );
197:
198: return $result;
199: }
200:
201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213:
214: function sanitize_date( $date_string ) {
215: $date_and_timezone = explode( '(', $date_string );
216: $date_no_timezone = trim( $date_and_timezone[0] );
217:
218: try {
219: $date = new DateTime( $date_no_timezone );
220: } catch ( \Exception $e ) {
221: return new DateTime( '1970-01-01' );
222: }
223:
224: return $date;
225: }
226:
227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238:
239: function get_installed_translations( $type ) {
240: static $cache = [];
241:
242: if ( ! isset( $cache[ $type ] ) ) {
243: $cache[ $type ] = wp_get_installed_translations( $type . 's' );
244: }
245:
246: return $cache[ $type ];
247: }
248:
249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259:
260: function get_available_locales() {
261: static $cache = null;
262:
263: if ( ! isset( $cache ) ) {
264: $cache = array_values( get_available_languages() );
265: }
266:
267: return $cache;
268: }
269: