Overview

Namespaces

  • None
  • Quform
    • Traduttore_Registry

Classes

  • Quform
  • Quform_Admin_InsertForm
  • Quform_Admin_Page
  • Quform_Admin_Page_Controller
  • Quform_Admin_Page_Dashboard
  • Quform_Admin_Page_Entries
  • Quform_Admin_Page_Entries_Edit
  • Quform_Admin_Page_Entries_List
  • Quform_Admin_Page_Entries_View
  • Quform_Admin_Page_Factory
  • Quform_Admin_Page_Forms_Add
  • Quform_Admin_Page_Forms_Edit
  • Quform_Admin_Page_Forms_List
  • Quform_Admin_Page_Help
  • Quform_Admin_Page_Preview
  • Quform_Admin_Page_Settings
  • Quform_Admin_Page_Tools
  • Quform_Admin_Page_Tools_ExportEntries
  • Quform_Admin_Page_Tools_ExportForm
  • Quform_Admin_Page_Tools_Home
  • Quform_Admin_Page_Tools_ImportForm
  • Quform_Admin_Page_Tools_Migrate
  • Quform_Admin_Page_Tools_Uninstall
  • Quform_Api
  • Quform_Block
  • Quform_Builder
  • Quform_Captcha
  • Quform_ClassLoader
  • Quform_Confirmation
  • Quform_Container
  • Quform_Dashboard_Widget
  • Quform_Dispatcher
  • Quform_Element
  • Quform_Element_Captcha
  • Quform_Element_Checkbox
  • Quform_Element_Column
  • Quform_Element_Container
  • Quform_Element_Container_Iterator
  • Quform_Element_Date
  • Quform_Element_Email
  • Quform_Element_Factory
  • Quform_Element_Field
  • Quform_Element_File
  • Quform_Element_Group
  • Quform_Element_Hidden
  • Quform_Element_Honeypot
  • Quform_Element_Html
  • Quform_Element_Multi
  • Quform_Element_Multiselect
  • Quform_Element_Name
  • Quform_Element_Page
  • Quform_Element_Password
  • Quform_Element_Radio
  • Quform_Element_Recaptcha
  • Quform_Element_Row
  • Quform_Element_Select
  • Quform_Element_Submit
  • Quform_Element_Text
  • Quform_Element_Textarea
  • Quform_Element_Time
  • Quform_Entry_Controller
  • Quform_Entry_Exporter
  • Quform_Entry_List_Settings
  • Quform_Entry_List_Table
  • Quform_Entry_Processor
  • Quform_Entry_UserSearcher
  • Quform_Filter_Abstract
  • Quform_Filter_Alpha
  • Quform_Filter_AlphaNumeric
  • Quform_Filter_Digits
  • Quform_Filter_Regex
  • Quform_Filter_Static
  • Quform_Filter_StripTags
  • Quform_Filter_Trim
  • Quform_Form
  • Quform_Form_Controller
  • Quform_Form_Exporter
  • Quform_Form_Factory
  • Quform_Form_Importer
  • Quform_Form_Iterator
  • Quform_Form_List_Settings
  • Quform_Form_List_Table
  • Quform_Form_Processor
  • Quform_License
  • Quform_Migrator
  • Quform_NonceRefresher
  • Quform_Notification
  • Quform_Notification_Resender
  • Quform_Options
  • Quform_Permissions
  • Quform_Repository
  • Quform_ScriptLoader
  • Quform_Session
  • Quform_Settings
  • Quform_Shortcode
  • Quform_Themes
  • Quform_TokenReplacer
  • Quform_Toolbar
  • Quform_Translations
  • Quform_Updater
  • Quform_Upgrader
  • Quform_Uploader
  • Quform_Validator_Abstract
  • Quform_Validator_Alpha
  • Quform_Validator_AlphaNumeric
  • Quform_Validator_Array
  • Quform_Validator_Captcha
  • Quform_Validator_Date
  • Quform_Validator_Digits
  • Quform_Validator_Duplicate
  • Quform_Validator_Email
  • Quform_Validator_FileUpload
  • Quform_Validator_GreaterThan
  • Quform_Validator_Honeypot
  • Quform_Validator_Identical
  • Quform_Validator_InArray
  • Quform_Validator_Length
  • Quform_Validator_LessThan
  • Quform_Validator_Recaptcha
  • Quform_Validator_Regex
  • Quform_Validator_Required
  • Quform_Validator_Static
  • Quform_Validator_Time
  • Quform_View
  • Quform_ViewFactory
  • Quform_Widget_Form
  • Quform_Widget_Popup

Interfaces

  • Quform_Attachable
  • Quform_Element_Editable
  • Quform_Filter_Interface
  • Quform_Validator_Interface

Constants

  • Quform\Traduttore_Registry\TRANSIENT_KEY_PLUGIN
  • Quform\Traduttore_Registry\TRANSIENT_KEY_THEME

Functions

  • Quform\Traduttore_Registry\add_project
  • Quform\Traduttore_Registry\clean_translations_cache
  • Quform\Traduttore_Registry\get_available_locales
  • Quform\Traduttore_Registry\get_installed_translations
  • Quform\Traduttore_Registry\get_translations
  • Quform\Traduttore_Registry\register_clean_translations_cache
  • Quform\Traduttore_Registry\sanitize_date
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /**
  3:  * Main Traduttore Registry library.
  4:  *
  5:  * @since 1.0.0
  6:  *
  7:  * Copyright (c) 2018-2020 required (email: info@required.com)
  8:  *
  9:  * This program is free software; you can redistribute it and/or modify
 10:  * it under the terms of the GNU General Public License, version 2 or, at
 11:  * your discretion, any later version, as published by the Free
 12:  * Software Foundation.
 13:  *
 14:  * This program is distributed in the hope that it will be useful,
 15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17:  * GNU General Public License for more details.
 18:  *
 19:  * You should have received a copy of the GNU General Public License
 20:  * along with this program; if not, write to the Free Software
 21:  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 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:  * Adds a new project to load translations for.
 33:  *
 34:  * @since 1.0.0
 35:  *
 36:  * @param string $type    Project type. Either plugin or theme.
 37:  * @param string $slug    Project directory slug.
 38:  * @param string $api_url Full GlotPress API URL for the project.
 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:      * Short-circuits translations API requests for private projects.
 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:      * Filters the translations transients to include the private plugin or theme.
 63:      *
 64:      * @see wp_get_translation_updates()
 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:             /** This filter is documented in wp-includes/update.php */
 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:  * Registers actions for clearing translation caches.
117:  *
118:  * @since 1.1.0
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:  * Clears existing translation cache for a given type.
137:  *
138:  * @since 1.1.0
139:  *
140:  * @param string $type Project type. Either plugin or theme.
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:      * Don't delete the cache if the transient gets changed multiple times
152:      * during a single request. Set cache lifetime to maximum 15 seconds.
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:  * Gets the translations for a given project.
166:  *
167:  * @since 1.0.0
168:  *
169:  * @param string $type Project type. Either plugin or theme.
170:  * @param string $slug Project directory slug.
171:  * @param string $url  Full GlotPress API URL for the project.
172:  * @return array Translation data.
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:         // Cache an empty result in case of a failure
189:         // and retry on next update check.
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:  * Sanitizes a date string.
203:  *
204:  * DateTime fails to parse date strings that contain brackets, such as
205:  * “Tue Dec 22 2015 12:52:19 GMT+0100 (West-Europa)”, which appears in
206:  * PO-Revision-Date headers. Sanitization ensures such date headers are
207:  * parsed correctly into DateTime instances.
208:  *
209:  * @since 2.1.0
210:  *
211:  * @param string $date_string The date string to sanitize.
212:  * @return \DateTime Date from string if parsable, otherwise the Unix epoch.
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:  * Gets the installed translations.
229:  *
230:  * Results are cached.
231:  *
232:  * @since 2.2.0
233:  *
234:  * @see wp_get_installed_translations()
235:  *
236:  * @param string $type Project type. Either plugin or theme.
237:  * @return array Translation data.
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:  * Gets all available and installed locales.
251:  *
252:  * Results are cached.
253:  *
254:  * @since 2.2.0
255:  *
256:  * @see get_available_languages()
257:  *
258:  * @return array List of installed locales.
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: 
API documentation generated by ApiGen