/** * Execute native msgfmt command * @param string po source * @return string binary mo source */ public static function msgfmt_native($po) { try { $conf = Loco::config(); loco_require('build/gettext-compiled'); $gen_hash = (bool) $conf['gen_hash']; $use_fuzzy = (bool) $conf['use_fuzzy']; $mo = loco_msgfmt($po, $gen_hash, $use_fuzzy); } catch (Exception $Ex) { error_log($Ex->getMessage(), 0); } if (!$mo) { throw new Exception(sprintf(Loco::__('Failed to compile MO file with built-in compiler'))); } return $mo; }
<?php /** * Admin ajax action wrapper */ try { // no errors ruining json response please if (false === ini_set('display_errors', 0)) { error_reporting(0); } if (!function_exists('current_user_can') || !class_exists('LocoAdmin')) { throw new Exception('Ajax action only'); } if (!current_user_can(Loco::CAPABILITY)) { throw new Exception(Loco::__('User does not have permission to manage translations'), 403); } $incphp = isset($action) ? dirname(__FILE__) . '/' . $action . '.php' : ''; if (!$incphp || !file_exists($incphp)) { throw new Exception('Bad Ajax action'); } // Ajax action can only exit 200 try { $response = (include $incphp); } catch (Exception $Ex) { $response = array('error' => array('code' => $Ex->getCode(), 'message' => $Ex->getMessage())); } if (!is_array($response)) { throw new Exception('Ajax action did not return a response'); } // json ok $body = json_encode($response);
/** * Get package errors, or things that may cause problems displaying translations */ public function get_author_warnings() { $warn = array(); $type = $this->get_type(); if ('core' !== $type) { $camelType = strtoupper($type[0]) . substr($type, 1); // check package declares Text Domain $domain = $this->get_original('TextDomain'); if (!$domain) { $domain = $this->get_domain(); $warn[] = sprintf(Loco::__('%s does not declare a "Text Domain"'), $camelType) . ' .. ' . sprintf(Loco::__('Loco has guessed "%s"'), $domain); } // check package declares "Domain Path" $path = $this->get_original('Domain Path'); if (!$domain) { $warn[] = sprintf(Loco::__('%s does not declare a "Domain Path"'), $camelType) . ' .. ' . sprintf(Loco::__('Loco has guessed "%s"'), $this->domainpath); } // check POT exists and looks correct $path = $this->get_pot($domain); if (!$path) { $warn[] = sprintf(Loco::__('%s has no POT file. Create one at "%s/%s.pot" if you need one.'), $camelType, $this->domainpath, $domain); } else { if ($domain . '.pot' !== basename($path)) { $warn[] = sprintf(Loco::__('%s has a strange POT file name (%s). A better name would be "%s.pot"'), $camelType, basename($path), $domain); } } // TODO check references to other domains in xgettext } // Check if any locale codes are not an official WordPress languages $meta = $this->meta(); foreach ($meta['po'] as $po_data) { $wplang = $po_data['locale']->get_code() or $wplang = $po_data['locale']->get_name(); if (!LocoLocale::is_valid_wordpress($wplang)) { $warn[] = sprintf(Loco::__('%s is not an official WordPress language'), $wplang); } } return $warn; }
<?php /** * Polyfiller for missing PHP json extension. * Simply avoids fatal errors. Doesn't attempt to really replace the functionality */ function loco_compat_json_encode($value) { return '{"error":{"code":-1,"message":"json extension is not installed"}}'; } if (!extension_loaded('json_encode') && WP_DEBUG && (!defined('DOING_AJAX') || !DOING_AJAX)) { LocoAdmin::warning(sprintf(Loco::__('PHP extension "%s" is not installed. If you experience problems you should install it'), 'json_encode')); } if (!function_exists('json_encode')) { function json_encode($value = '') { return loco_compat_json_encode($value); } }
"> <?php Loco::h($label); ?> </a><?php } } ?> <a href="https://localise.biz/about/gettext?<?php Loco::h(Loco::utm_query('nav')); ?> " class="nav-tab nav-tab-loco" target="_blank"> <?php Loco::h(Loco::__('Powered by')); ?> <?php Loco::h(Loco::__('Loco, Translation Management')); ?> </a> </h2> <!--[if lt IE 9]><?php LocoAdmin::warning(__($ignore = 'Your browser is out of date!') . ' ' . Loco::html(Loco::__('Loco may not work as expected'))); ?> <![endif]-->
public function get_name() { return empty($this->label) ? Loco::__('Unknown language') : $this->label; }
/** * Get package errors, or things that may cause problems displaying translations */ public function get_author_warnings() { $warn = array(); $type = $this->get_type(); if ('core' === $type) { // no tests for core packages } else { $camelType = strtoupper($type[0]) . substr($type, 1); // check package declares Text Domain $domain = $this->get_original('TextDomain'); if (!$domain) { $domain = $this->get_domain(); $warn[] = sprintf(Loco::__('%s does not declare a "Text Domain"'), $camelType) . ' .. ' . sprintf(Loco::__('Loco has guessed "%s"'), $domain); } // check package declares "Domain Path" $path = $this->get_original('Domain Path'); if (!$domain) { $warn[] = sprintf(Loco::__('%s does not declare a "Domain Path"'), $camelType) . ' .. ' . sprintf(Loco::__('Loco has guessed "%s"'), $this->domainpath); } // check POT exists and looks correct $path = $this->get_pot($domain); if (!$path) { $warn[] = sprintf(Loco::__('%s has no POT file. Create one at "%s/%s.pot" if you need one.'), $camelType, $this->domainpath, $domain); } else { if ($domain . '.pot' !== basename($path)) { $warn[] = sprintf(Loco::__('%s has a strange POT file name (%s). A better name would be "%s.pot"'), $camelType, basename($path), $domain); } } // TODO check references to other domains in xgettext } return $warn; }
// fall through to try source code } else { $pot = basename($pot_path); break; } } } // Extract from sources by default if (!$package->has_source_dirs()) { throw new Exception(Loco::__('No source directories in this package, cannot sync from source code')); } if ($exp = LocoAdmin::xgettext($package, dirname($path))) { $pot = ''; break; } throw new Exception(Loco::__('No strings could be extracted from source files')); } // sync selected headers $headers = array(); if ('' === $exp[0]['source']) { $keep = array('Project-Id-Version', 'Language-Team', 'POT-Creation-Date', 'POT-Revision-Date'); $head = loco_parse_po_headers($exp[0]['target']); $headers = array_intersect_key($head->to_array(), array_flip($keep)); /*/ add prefixed header keys that can't be included above foreach( $head as $key => $value ){ if( 0 === strpos($key, 'X-Poedit-' ) ){ $headers[$key] = $value; } }*/ $exp[0] = array(); }
<?php /** * Admin ajax include that returns compiled-in data * Included by loco-ajax.php during Ajax action */ DOING_AJAX or die; // default is single locale response if (isset($locale)) { loco_require('loco-locales'); $data = loco_locale_resolve($locale); return array('locales' => array($locale => $data->export())); } throw new Exception(Loco::__('Invalid data posted to server'), 422);
// attempt to compile MO direct to file via shell if ($msgfmt = LocoAdmin::msgfmt_command()) { try { $bytes = 0; loco_require('build/shell-compiled'); define('WHICH_MSGFMT', $msgfmt); $mopath = loco_compile_mo_file($path, $mopath); $bytes = $mopath && file_exists($mopath) ? filesize($mopath) : 0; } catch (Exception $Ex) { error_log($Ex->getMessage(), 0); } if (!$bytes) { throw new Exception(sprintf(Loco::__('Failed to compile MO file with %s, check your settings'), WHICH_MSGFMT)); } $response['compiled'] = $bytes; break; } // Fall back to in-built MO compiler - requires PO is parsed too $mo = LocoAdmin::msgfmt_native($po); $bytes = file_put_contents($mopath, $mo); if (!$bytes) { throw new Exception(Loco::__('Failed to write MO file')); } $response['compiled'] = $bytes; break; } catch (Exception $e) { $response['compiled'] = $e->getMessage(); break; } } return $response;
try { loco_require('build/shell-compiled'); define('WHICH_MSGFMT', $msgfmt); // use temp file if possible, due to stdin size restrictions if ($popath = tempnam(sys_get_temp_dir(), 'loco-')) { register_shutdown_function('unlink', $popath); file_put_contents($popath, $po); $mopath = loco_compile_mo_file($popath, $mopath); register_shutdown_function('unlink', $mopath); $mo = file_get_contents($mopath); } else { $mo = loco_compile_mo($po); } } catch (Exception $Ex) { error_log($Ex->getMessage(), 0); } if (!$mo) { throw new Exception(sprintf(Loco::__('Failed to compile MO file with %s, check your settings'), WHICH_MSGFMT)); } } else { $mo = LocoAdmin::msgfmt_native($po); } // exit with binary MO header('Content-Type: application/x-gettext-translation; charset=UTF-8', true); header('Content-Length: ' . strlen($mo), true); header('Content-Disposition: attachment; filename=' . $name, true); echo $mo; exit(0); } catch (Exception $Ex) { require dirname(__FILE__) . '/loco-fatal.php'; }
/** * Get file permission for every important file path in package */ public function get_permission_errors() { $dirs = array(); // add common directories $base = $this->get_root(); $dirs[$base] = 1; $dirs[$base . $this->domainpath] = 1; $dirs[$this->lang_dir()] = 1; $dirs[$this->global_lang_dir()] = 1; // add and check files, collecting additional directories along the way $paths = array(); foreach ($this->pot as $path) { $dirs[dirname($path)] = 1; $paths[$path] = is_writable($path) ? '' : Loco::__('POT file not writable'); } foreach ($this->po as $pos) { foreach ($pos as $path) { $dirs[dirname($path)] = 1; $paths[$path] = is_writable($path) ? '' : Loco::__('PO file not writable'); $path = preg_replace('/\\.po$/', '.mo', $path); $paths[$path] = file_exists($path) ? is_writeable($path) ? '' : Loco::__('MO file not writable') : Loco::__('MO file not found'); } } // run directory checks and sort final list alphabetically foreach (array_keys($dirs) as $dir) { $paths[$dir] = is_writable($dir) ? '' : (is_dir($dir) ? Loco::__('Folder not writable') : Loco::__('Folder not found')); } ksort($paths); return $paths; }
</li><?php } ?> </ul> </td> <td> <ul><?php try { $package->check_permissions(); ?> <li class="loco-ok"> <?php echo LocoAdmin::fscheck_link($package, $domain, Loco::__('OK')); ?> </li><?php } catch (Exception $Ex) { ?> <li class="loco-warning"> <?php echo LocoAdmin::fscheck_link($package, $domain, $Ex->getMessage()); ?> </li><?php } ?>
<input type="hidden" name="<?php Loco::h($k); ?> " value="<?php Loco::h($v); ?> " /><?php } ?> <p> <select name="common-locale"> <option value=""> <?php Loco::h(Loco::__('Select from common languages')); ?> </option><?php foreach ($locales as $code => $name) { ?> <option value="<?php echo $code; ?> "> <?php Loco::h($name); ?> </option><?php
"> <?php Loco::h(Loco::__('Upgrade to version %s of Loco Translate'), $update); ?> </a> </p> </div><?php } // main tabbed navigation Loco::render('admin-nav', compact('nav')); ?> <h3 class="title"> <?php Loco::h(Loco::__('Select a plugin or theme to translate')); ?> </h3><?php // Theme packages // if ($themes) { ?> <div class="icon32 icon-appearance"><br /></div> <h2 class="dashicons-admin-appearance"> <?php Loco::h(Loco::_x('Themes', 'Package list header')); ?> </h2>
<ul class="loco-details"> <li title="<?php Loco::h($domain); ?> "> <strong><?php Loco::h($package->get_name()); ?> </strong> </li><?php if (isset($parent)) { ?> <li> <?php Loco::h(Loco::__('Extends: %s'), $parent); ?> </li><?php } ?> <li><?php Loco::h(Loco::_n('1 language', '%u languages', $n), $n); ?> </li><?php if ($mtime) { ?> <li class="loco-mtime">
?> /loco-fail.php"> <button class="button loco-fuzzy" data-loco="fuzzy" disabled> <span><?php Loco::h(Loco::_x('Fuzzy', 'Editor button')); ?> </span> </button> </form> <form action="<?php echo $phpbase; ?> /loco-fail.php" id="loco-filter"> <div class="loco-clearable"> <input type="text" maxlength="100" name="q" id="loco-search" placeholder="<?php Loco::h(Loco::__('Filter translations')); ?> " autocomplete="off" disabled /> </div> </form> <form action="http://wordpress.org/support/plugin/<?php echo Loco::NS; ?> " target="_blank" class="loco-right"> <button class="button loco-help" data-loco="help" type="submit"> <span><?php Loco::h(Loco::_x('Help', 'Editor button')); ?> </span> </button> </form>
</legend> <p> <label for="loco--enable-core"> <input type="checkbox" name="loco[enable_core]" value="1" id="loco--enable-core"<?php echo $enable_core ? ' checked' : ''; ?> /> <?php Loco::h(Loco::__('Enable WordPress core translations')); ?> </label> </p> </fieldset> </td> </tr> </tbody> </table> <p class="submit"> <input type="submit" class="button-primary" value="<?php Loco::h(Loco::__('Save settings')); ?> " /> <a class="button" href="https://localise.biz/help/wordpress/translate-plugin/support" target="_blank"><?php Loco::h(Loco::__('Get help')); ?> </a> </p> </form> </div>
<?php /** * Warns about missing PHP glob functionality under Solaris */ if (!defined('GLOB_BRACE') && (!defined('DOING_AJAX') || !DOING_AJAX)) { define('GLOB_BRACE', 0); LocoAdmin::warning(Loco::__("Loco Translate will not work properly on this server's operating system")); }