context = array( 'themes', $domain, $locale ); unset( $this->lock[$domain] ); return $locale; } /** * `plugin_locale` filter callback. * Signals the beginning of a "load_plugin_textdomain" process */ public function filter_plugin_locale( $locale, $domain = '' ){ $this->context = array( 'plugins', $domain, $locale ); unset( $this->lock[$domain] ); return $locale; } /** * `unload_textdomain` action callback. * Lets us release lock so that custom file may be loaded again (hopefully for another locale) */ public function on_unload_textdomain( $domain ){ unset( $this->lock[$domain] ); } /** * `load_textdomain` action callback. * Lets us load our custom translations before WordPress loads what it was going to anyway. * We're deliberately not stopping WordPress loading $mopath, if it exists it will be merged on top of our custom strings. * @return void */ public function on_load_textdomain( $domain, $mopath ){ $key = ''; // domains may be split into multiple files $name = pathinfo( $mopath, PATHINFO_FILENAME ); if( $lpos = strrpos( $name, '-') ){ $slug = substr( $name, 0, $lpos ); if( $slug !== $domain ){ $key = $slug; } } // avoid recursion when we've already handled this domain/slug if( isset($this->lock[$domain][$key]) ){ return; } // language roots $wp_lang_dir = trailingslashit( loco_constant('WP_LANG_DIR') ); $lc_lang_dir = trailingslashit( loco_constant('LOCO_LANG_DIR') ); // if context is set, then a theme or plugin initialized the loading process properly if( is_array($this->context) ){ list( $subdir, $_domain, $locale ) = $this->context; $this->context = null; // It shouldn't be possible to catch a different domain after setting context, but we'd better bail just in case if( $_domain !== $domain ){ return; } $mopath = $lc_lang_dir.$subdir.'/'.$domain.'-'.$locale.'.mo'; } // else load_textdomain must have been called directly to bypass locale filters else { $snip = strlen($wp_lang_dir); // direct file loads must be under WP_LANG_DIR if we are to map them if( substr( dirname($mopath).'/', 0, $snip ) === $wp_lang_dir ){ $mopath = substr_replace( $mopath, $lc_lang_dir, 0, $snip ); } // else no way to map files from WP_LANG_DIR to LOCO_LANG_DIR else { return; } } // Load our custom translations avoiding recursion back into this hook $this->lock[$domain][$key] = true; load_textdomain( $domain, $mopath ); } /** * `load_textdomain_mofile` filter callback * @return string */ public function filter_load_textdomain_mofile( $mopath, $domain ){ // 2.0.14 changed text domain from "loco" to "loco-translate" // so if file doesn't exist, there's no harm in trying the legacy file name if( 'loco-translate' === $domain && ! file_exists($mopath) ){ $mopath = str_replace('/loco-translate-','/loco-',$mopath); } return $mopath; } }