Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/loco-translate/lib/data/locales.php
+++ b/loco-translate/lib/data/locales.php
@@ -2,4 +2,4 @@
/**
* Compiled data. Do not edit.
*/
-return ['af'=>[0=>'Afrikaans',1=>'Afrikaans'],'am'=>[0=>'Amharic',1=>'አማርኛ'],'arg'=>[0=>'Aragonese',1=>'Aragonés'],'ar'=>[0=>'Arabic',1=>'العربية'],'ary'=>[0=>'Moroccan Arabic',1=>'العربية المغربية'],'as'=>[0=>'Assamese',1=>'অসমীয়া'],'azb'=>[0=>'South Azerbaijani',1=>'گؤنئی آذربایجان'],'az'=>[0=>'Azerbaijani',1=>'Azərbaycan dili'],'bel'=>[0=>'Belarusian',1=>'Беларуская мова'],'bg_BG'=>[0=>'Bulgarian',1=>'Български'],'bn_BD'=>[0=>'Bengali (Bangladesh)',1=>'বাংলা'],'bo'=>[0=>'Tibetan',1=>'བོད་ཡིག'],'bs_BA'=>[0=>'Bosnian',1=>'Bosanski'],'ca'=>[0=>'Catalan',1=>'Català'],'ceb'=>[0=>'Cebuano',1=>'Cebuano'],'cs_CZ'=>[0=>'Czech',1=>'Čeština'],'cy'=>[0=>'Welsh',1=>'Cymraeg'],'da_DK'=>[0=>'Danish',1=>'Dansk'],'de_AT'=>[0=>'German (Austria)',1=>'Deutsch (Österreich)'],'de_DE'=>[0=>'German',1=>'Deutsch'],'de_DE_formal'=>[0=>'German (Formal)',1=>'Deutsch (Sie)'],'de_CH'=>[0=>'German (Switzerland)',1=>'Deutsch (Schweiz)'],'de_CH_informal'=>[0=>'German (Switzerland, Informal)',1=>'Deutsch (Schweiz, Du)'],'dsb'=>[0=>'Lower Sorbian',1=>'Dolnoserbšćina'],'dzo'=>[0=>'Dzongkha',1=>'རྫོང་ཁ'],'el'=>[0=>'Greek',1=>'Ελληνικά'],'en_CA'=>[0=>'English (Canada)',1=>'English (Canada)'],'en_GB'=>[0=>'English (UK)',1=>'English (UK)'],'en_NZ'=>[0=>'English (New Zealand)',1=>'English (New Zealand)'],'en_AU'=>[0=>'English (Australia)',1=>'English (Australia)'],'en_ZA'=>[0=>'English (South Africa)',1=>'English (South Africa)'],'eo'=>[0=>'Esperanto',1=>'Esperanto'],'es_MX'=>[0=>'Spanish (Mexico)',1=>'Español de México'],'es_CO'=>[0=>'Spanish (Colombia)',1=>'Español de Colombia'],'es_ES'=>[0=>'Spanish (Spain)',1=>'Español'],'es_CR'=>[0=>'Spanish (Costa Rica)',1=>'Español de Costa Rica'],'es_PE'=>[0=>'Spanish (Peru)',1=>'Español de Perú'],'es_VE'=>[0=>'Spanish (Venezuela)',1=>'Español de Venezuela'],'es_EC'=>[0=>'Spanish (Ecuador)',1=>'Español de Ecuador'],'es_DO'=>[0=>'Spanish (Dominican Republic)',1=>'Español de República Dominicana'],'es_UY'=>[0=>'Spanish (Uruguay)',1=>'Español de Uruguay'],'es_PR'=>[0=>'Spanish (Puerto Rico)',1=>'Español de Puerto Rico'],'es_GT'=>[0=>'Spanish (Guatemala)',1=>'Español de Guatemala'],'es_AR'=>[0=>'Spanish (Argentina)',1=>'Español de Argentina'],'es_CL'=>[0=>'Spanish (Chile)',1=>'Español de Chile'],'et'=>[0=>'Estonian',1=>'Eesti'],'eu'=>[0=>'Basque',1=>'Euskara'],'fa_IR'=>[0=>'Persian',1=>'فارسی'],'fa_AF'=>[0=>'Persian (Afghanistan)',1=>'(فارسی (افغانستان'],'fi'=>[0=>'Finnish',1=>'Suomi'],'fr_CA'=>[0=>'French (Canada)',1=>'Français du Canada'],'fr_FR'=>[0=>'French (France)',1=>'Français'],'fr_BE'=>[0=>'French (Belgium)',1=>'Français de Belgique'],'fur'=>[0=>'Friulian',1=>'Friulian'],'fy'=>[0=>'Frisian',1=>'Frysk'],'gd'=>[0=>'Scottish Gaelic',1=>'Gàidhlig'],'gl_ES'=>[0=>'Galician',1=>'Galego'],'gu'=>[0=>'Gujarati',1=>'ગુજરાતી'],'haz'=>[0=>'Hazaragi',1=>'هزاره گی'],'he_IL'=>[0=>'Hebrew',1=>'עִבְרִית'],'hi_IN'=>[0=>'Hindi',1=>'हिन्दी'],'hr'=>[0=>'Croatian',1=>'Hrvatski'],'hsb'=>[0=>'Upper Sorbian',1=>'Hornjoserbšćina'],'hu_HU'=>[0=>'Hungarian',1=>'Magyar'],'hy'=>[0=>'Armenian',1=>'Հայերեն'],'id_ID'=>[0=>'Indonesian',1=>'Bahasa Indonesia'],'is_IS'=>[0=>'Icelandic',1=>'Íslenska'],'it_IT'=>[0=>'Italian',1=>'Italiano'],'ja'=>[0=>'Japanese',1=>'日本語'],'jv_ID'=>[0=>'Javanese',1=>'Basa Jawa'],'ka_GE'=>[0=>'Georgian',1=>'ქართული'],'kab'=>[0=>'Kabyle',1=>'Taqbaylit'],'kk'=>[0=>'Kazakh',1=>'Қазақ тілі'],'km'=>[0=>'Khmer',1=>'ភាសាខ្មែរ'],'kn'=>[0=>'Kannada',1=>'ಕನ್ನಡ'],'ko_KR'=>[0=>'Korean',1=>'한국어'],'ckb'=>[0=>'Kurdish (Sorani)',1=>'كوردی'],'kir'=>[0=>'Kyrgyz',1=>'Кыргызча'],'lo'=>[0=>'Lao',1=>'ພາສາລາວ'],'lt_LT'=>[0=>'Lithuanian',1=>'Lietuvių kalba'],'lv'=>[0=>'Latvian',1=>'Latviešu valoda'],'mk_MK'=>[0=>'Macedonian',1=>'Македонски јазик'],'ml_IN'=>[0=>'Malayalam',1=>'മലയാളം'],'mn'=>[0=>'Mongolian',1=>'Монгол'],'mr'=>[0=>'Marathi',1=>'मराठी'],'ms_MY'=>[0=>'Malay',1=>'Bahasa Melayu'],'my_MM'=>[0=>'Myanmar (Burmese)',1=>'ဗမာစာ'],'nb_NO'=>[0=>'Norwegian (Bokmål)',1=>'Norsk bokmål'],'ne_NP'=>[0=>'Nepali',1=>'नेपाली'],'nl_BE'=>[0=>'Dutch (Belgium)',1=>'Nederlands (België)'],'nl_NL'=>[0=>'Dutch',1=>'Nederlands'],'nl_NL_formal'=>[0=>'Dutch (Formal)',1=>'Nederlands (Formeel)'],'nn_NO'=>[0=>'Norwegian (Nynorsk)',1=>'Norsk nynorsk'],'oci'=>[0=>'Occitan',1=>'Occitan'],'pa_IN'=>[0=>'Panjabi (India)',1=>'ਪੰਜਾਬੀ'],'pl_PL'=>[0=>'Polish',1=>'Polski'],'ps'=>[0=>'Pashto',1=>'پښتو'],'pt_BR'=>[0=>'Portuguese (Brazil)',1=>'Português do Brasil'],'pt_AO'=>[0=>'Portuguese (Angola)',1=>'Português de Angola'],'pt_PT'=>[0=>'Portuguese (Portugal)',1=>'Português'],'pt_PT_ao90'=>[0=>'Portuguese (Portugal, AO90)',1=>'Português (AO90)'],'rhg'=>[0=>'Rohingya',1=>'Ruáinga'],'ro_RO'=>[0=>'Romanian',1=>'Română'],'ru_RU'=>[0=>'Russian',1=>'Русский'],'sah'=>[0=>'Sakha',1=>'Сахалыы'],'snd'=>[0=>'Sindhi',1=>'سنڌي'],'si_LK'=>[0=>'Sinhala',1=>'සිංහල'],'sk_SK'=>[0=>'Slovak',1=>'Slovenčina'],'skr'=>[0=>'Saraiki',1=>'سرائیکی'],'sl_SI'=>[0=>'Slovenian',1=>'Slovenščina'],'sq'=>[0=>'Albanian',1=>'Shqip'],'sr_RS'=>[0=>'Serbian',1=>'Српски језик'],'sv_SE'=>[0=>'Swedish',1=>'Svenska'],'sw'=>[0=>'Swahili',1=>'Kiswahili'],'szl'=>[0=>'Silesian',1=>'Ślōnskŏ gŏdka'],'ta_IN'=>[0=>'Tamil',1=>'தமிழ்'],'ta_LK'=>[0=>'Tamil (Sri Lanka)',1=>'தமிழ்'],'te'=>[0=>'Telugu',1=>'తెలుగు'],'th'=>[0=>'Thai',1=>'ไทย'],'tl'=>[0=>'Tagalog',1=>'Tagalog'],'tr_TR'=>[0=>'Turkish',1=>'Türkçe'],'tt_RU'=>[0=>'Tatar',1=>'Татар теле'],'tah'=>[0=>'Tahitian',1=>'Reo Tahiti'],'ug_CN'=>[0=>'Uighur',1=>'ئۇيغۇرچە'],'uk'=>[0=>'Ukrainian',1=>'Українська'],'ur'=>[0=>'Urdu',1=>'اردو'],'uz_UZ'=>[0=>'Uzbek',1=>'O‘zbekcha'],'vi'=>[0=>'Vietnamese',1=>'Tiếng Việt'],'zh_CN'=>[0=>'Chinese (China)',1=>'简体中文'],'zh_TW'=>[0=>'Chinese (Taiwan)',1=>'繁體中文'],'zh_HK'=>[0=>'Chinese (Hong Kong)',1=>'香港中文']];
No newline at end of file
+return ['af'=>[0=>'Afrikaans',1=>'Afrikaans'],'am'=>[0=>'Amharic',1=>'አማርኛ'],'arg'=>[0=>'Aragonese',1=>'Aragonés'],'ar'=>[0=>'Arabic',1=>'العربية'],'ary'=>[0=>'Moroccan Arabic',1=>'العربية المغربية'],'as'=>[0=>'Assamese',1=>'অসমীয়া'],'azb'=>[0=>'South Azerbaijani',1=>'گؤنئی آذربایجان'],'az'=>[0=>'Azerbaijani',1=>'Azərbaycan dili'],'bel'=>[0=>'Belarusian',1=>'Беларуская мова'],'bg_BG'=>[0=>'Bulgarian',1=>'Български'],'bn_BD'=>[0=>'Bengali (Bangladesh)',1=>'বাংলা'],'bo'=>[0=>'Tibetan',1=>'བོད་ཡིག'],'bs_BA'=>[0=>'Bosnian',1=>'Bosanski'],'ca'=>[0=>'Catalan',1=>'Català'],'ceb'=>[0=>'Cebuano',1=>'Cebuano'],'cs_CZ'=>[0=>'Czech',1=>'Čeština'],'cy'=>[0=>'Welsh',1=>'Cymraeg'],'da_DK'=>[0=>'Danish',1=>'Dansk'],'de_AT'=>[0=>'German (Austria)',1=>'Deutsch (Österreich)'],'de_DE'=>[0=>'German',1=>'Deutsch'],'de_DE_formal'=>[0=>'German (Formal)',1=>'Deutsch (Sie)'],'de_CH'=>[0=>'German (Switzerland)',1=>'Deutsch (Schweiz)'],'de_CH_informal'=>[0=>'German (Switzerland, Informal)',1=>'Deutsch (Schweiz, Du)'],'dsb'=>[0=>'Lower Sorbian',1=>'Dolnoserbšćina'],'dzo'=>[0=>'Dzongkha',1=>'རྫོང་ཁ'],'el'=>[0=>'Greek',1=>'Ελληνικά'],'en_CA'=>[0=>'English (Canada)',1=>'English (Canada)'],'en_GB'=>[0=>'English (UK)',1=>'English (UK)'],'en_NZ'=>[0=>'English (New Zealand)',1=>'English (New Zealand)'],'en_AU'=>[0=>'English (Australia)',1=>'English (Australia)'],'en_ZA'=>[0=>'English (South Africa)',1=>'English (South Africa)'],'eo'=>[0=>'Esperanto',1=>'Esperanto'],'es_MX'=>[0=>'Spanish (Mexico)',1=>'Español de México'],'es_CO'=>[0=>'Spanish (Colombia)',1=>'Español de Colombia'],'es_ES'=>[0=>'Spanish (Spain)',1=>'Español'],'es_CR'=>[0=>'Spanish (Costa Rica)',1=>'Español de Costa Rica'],'es_PE'=>[0=>'Spanish (Peru)',1=>'Español de Perú'],'es_VE'=>[0=>'Spanish (Venezuela)',1=>'Español de Venezuela'],'es_EC'=>[0=>'Spanish (Ecuador)',1=>'Español de Ecuador'],'es_DO'=>[0=>'Spanish (Dominican Republic)',1=>'Español de República Dominicana'],'es_UY'=>[0=>'Spanish (Uruguay)',1=>'Español de Uruguay'],'es_PR'=>[0=>'Spanish (Puerto Rico)',1=>'Español de Puerto Rico'],'es_GT'=>[0=>'Spanish (Guatemala)',1=>'Español de Guatemala'],'es_AR'=>[0=>'Spanish (Argentina)',1=>'Español de Argentina'],'es_CL'=>[0=>'Spanish (Chile)',1=>'Español de Chile'],'et'=>[0=>'Estonian',1=>'Eesti'],'eu'=>[0=>'Basque',1=>'Euskara'],'fa_IR'=>[0=>'Persian',1=>'فارسی'],'fa_AF'=>[0=>'Persian (Afghanistan)',1=>'(فارسی (افغانستان'],'fi'=>[0=>'Finnish',1=>'Suomi'],'fr_CA'=>[0=>'French (Canada)',1=>'Français du Canada'],'fr_FR'=>[0=>'French (France)',1=>'Français'],'fr_BE'=>[0=>'French (Belgium)',1=>'Français de Belgique'],'fur'=>[0=>'Friulian',1=>'Friulian'],'fy'=>[0=>'Frisian',1=>'Frysk'],'gd'=>[0=>'Scottish Gaelic',1=>'Gàidhlig'],'gl_ES'=>[0=>'Galician',1=>'Galego'],'gu'=>[0=>'Gujarati',1=>'ગુજરાતી'],'haz'=>[0=>'Hazaragi',1=>'هزاره گی'],'he_IL'=>[0=>'Hebrew',1=>'עִבְרִית'],'hi_IN'=>[0=>'Hindi',1=>'हिन्दी'],'hr'=>[0=>'Croatian',1=>'Hrvatski'],'hsb'=>[0=>'Upper Sorbian',1=>'Hornjoserbšćina'],'hu_HU'=>[0=>'Hungarian',1=>'Magyar'],'hy'=>[0=>'Armenian',1=>'Հայերեն'],'id_ID'=>[0=>'Indonesian',1=>'Bahasa Indonesia'],'is_IS'=>[0=>'Icelandic',1=>'Íslenska'],'it_IT'=>[0=>'Italian',1=>'Italiano'],'ja'=>[0=>'Japanese',1=>'日本語'],'jv_ID'=>[0=>'Javanese',1=>'Basa Jawa'],'ka_GE'=>[0=>'Georgian',1=>'ქართული'],'kab'=>[0=>'Kabyle',1=>'Taqbaylit'],'kk'=>[0=>'Kazakh',1=>'Қазақ тілі'],'km'=>[0=>'Khmer',1=>'ភាសាខ្មែរ'],'kn'=>[0=>'Kannada',1=>'ಕನ್ನಡ'],'ko_KR'=>[0=>'Korean',1=>'한국어'],'ckb'=>[0=>'Kurdish (Sorani)',1=>'كوردی'],'kir'=>[0=>'Kyrgyz',1=>'Кыргызча'],'lo'=>[0=>'Lao',1=>'ພາສາລາວ'],'lt_LT'=>[0=>'Lithuanian',1=>'Lietuvių kalba'],'lv'=>[0=>'Latvian',1=>'Latviešu valoda'],'mk_MK'=>[0=>'Macedonian',1=>'Македонски јазик'],'ml_IN'=>[0=>'Malayalam',1=>'മലയാളം'],'mn'=>[0=>'Mongolian',1=>'Монгол'],'mr'=>[0=>'Marathi',1=>'मराठी'],'ms_MY'=>[0=>'Malay',1=>'Bahasa Melayu'],'my_MM'=>[0=>'Myanmar (Burmese)',1=>'ဗမာစာ'],'nb_NO'=>[0=>'Norwegian (Bokmål)',1=>'Norsk bokmål'],'ne_NP'=>[0=>'Nepali',1=>'नेपाली'],'nl_NL_formal'=>[0=>'Dutch (Formal)',1=>'Nederlands (Formeel)'],'nl_BE'=>[0=>'Dutch (Belgium)',1=>'Nederlands (België)'],'nl_NL'=>[0=>'Dutch',1=>'Nederlands'],'nn_NO'=>[0=>'Norwegian (Nynorsk)',1=>'Norsk nynorsk'],'oci'=>[0=>'Occitan',1=>'Occitan'],'pa_IN'=>[0=>'Panjabi (India)',1=>'ਪੰਜਾਬੀ'],'pl_PL'=>[0=>'Polish',1=>'Polski'],'ps'=>[0=>'Pashto',1=>'پښتو'],'pt_BR'=>[0=>'Portuguese (Brazil)',1=>'Português do Brasil'],'pt_AO'=>[0=>'Portuguese (Angola)',1=>'Português de Angola'],'pt_PT'=>[0=>'Portuguese (Portugal)',1=>'Português'],'pt_PT_ao90'=>[0=>'Portuguese (Portugal, AO90)',1=>'Português (AO90)'],'rhg'=>[0=>'Rohingya',1=>'Ruáinga'],'ro_RO'=>[0=>'Romanian',1=>'Română'],'ru_RU'=>[0=>'Russian',1=>'Русский'],'sah'=>[0=>'Sakha',1=>'Сахалыы'],'snd'=>[0=>'Sindhi',1=>'سنڌي'],'si_LK'=>[0=>'Sinhala',1=>'සිංහල'],'sk_SK'=>[0=>'Slovak',1=>'Slovenčina'],'skr'=>[0=>'Saraiki',1=>'سرائیکی'],'sl_SI'=>[0=>'Slovenian',1=>'Slovenščina'],'sq'=>[0=>'Albanian',1=>'Shqip'],'sr_RS'=>[0=>'Serbian',1=>'Српски језик'],'sv_SE'=>[0=>'Swedish',1=>'Svenska'],'sw'=>[0=>'Swahili',1=>'Kiswahili'],'szl'=>[0=>'Silesian',1=>'Ślōnskŏ gŏdka'],'ta_IN'=>[0=>'Tamil',1=>'தமிழ்'],'ta_LK'=>[0=>'Tamil (Sri Lanka)',1=>'தமிழ்'],'te'=>[0=>'Telugu',1=>'తెలుగు'],'th'=>[0=>'Thai',1=>'ไทย'],'tl'=>[0=>'Tagalog',1=>'Tagalog'],'tr_TR'=>[0=>'Turkish',1=>'Türkçe'],'tt_RU'=>[0=>'Tatar',1=>'Татар теле'],'tah'=>[0=>'Tahitian',1=>'Reo Tahiti'],'ug_CN'=>[0=>'Uighur',1=>'ئۇيغۇرچە'],'uk'=>[0=>'Ukrainian',1=>'Українська'],'ur'=>[0=>'Urdu',1=>'اردو'],'uz_UZ'=>[0=>'Uzbek',1=>'O‘zbekcha'],'vi'=>[0=>'Vietnamese',1=>'Tiếng Việt'],'zh_CN'=>[0=>'Chinese (China)',1=>'简体中文'],'zh_HK'=>[0=>'Chinese (Hong Kong)',1=>'香港中文'],'zh_TW'=>[0=>'Chinese (Taiwan)',1=>'繁體中文']];
No newline at end of file
--- a/loco-translate/loco.php
+++ b/loco-translate/loco.php
@@ -4,10 +4,10 @@
Plugin URI: https://wordpress.org/plugins/loco-translate/
Description: Translate themes and plugins directly in WordPress
Author: Tim Whitlock
-Version: 2.8.2
+Version: 2.8.3
Requires at least: 6.6
Requires PHP: 7.4
-Tested up to: 6.9.1
+Tested up to: 6.9.4
Author URI: https://localise.biz/wordpress/plugin
Text Domain: loco-translate
Domain Path: /languages/
@@ -31,7 +31,7 @@
* Get version of this plugin
*/
function loco_plugin_version(): string {
- return '2.8.2';
+ return '2.8.3';
}
--- a/loco-translate/src/admin/config/VersionController.php
+++ b/loco-translate/src/admin/config/VersionController.php
@@ -22,6 +22,7 @@
$title = __('Plugin settings','loco-translate');
$breadcrumb = new Loco_admin_Navigation;
$breadcrumb->add( $title );
+ $this->setLocoUpdate('0');
// current plugin version
$version = loco_plugin_version();
@@ -40,42 +41,31 @@
$this->set( 'devel', true );
}
-
- // check PHP version, noting that we want to move to minimum version 5.6 as per latest WordPress
+ // check PHP version is at least 7.4
$phpversion = PHP_VERSION;
if( version_compare($phpversion,'7.4.0','<') ){
$this->set('phpupdate','7.4');
}
-
// check WordPress version, No plans to increase this until WP bumps their min PHP requirement.
$wpversion = $GLOBALS['wp_version'];
- /*if( version_compare($wpversion,'5.2','<') ){
- $this->setWpUpdate('5.2');
- }*/
-
return $this->view('admin/config/version', compact('breadcrumb','version','phpversion','wpversion') );
}
- /**
- * @param string version
- */
- private function setLocoUpdate( $version ){
- $action = 'upgrade-plugin_'.loco_plugin_self();
- $link = admin_url( 'update.php?action=upgrade-plugin&plugin='.rawurlencode(loco_plugin_self()) );
- $this->set('update', $version );
- $this->set('update_href', wp_nonce_url( $link, $action ) );
- }
-
- /**
- * @param string minimum recommended version
- *
- private function setWpUpdate( $version ){
- $this->set('wpupdate',$version);
- $this->set('wpupdate_href', admin_url('update-core.php') );
- }*/
+ private function setLocoUpdate( string $version ){
+ if( $version ){
+ $action = 'upgrade-plugin_'.loco_plugin_self();
+ $link = admin_url( 'update.php?action=upgrade-plugin&plugin='.rawurlencode(loco_plugin_self()) );
+ $this->set('update', $version );
+ $this->set('update_href', wp_nonce_url( $link, $action ) );
+ }
+ else {
+ $this->set('update','');
+ $this->set('update_href','');
+ }
+ }
}
No newline at end of file
--- a/loco-translate/src/ajax/FsReferenceController.php
+++ b/loco-translate/src/ajax/FsReferenceController.php
@@ -112,9 +112,9 @@
// find file or fail
$srcfile = $this->findSourceFile($refpath);
- // deny access to sensitive files
- if( 'wp-config.php' === $srcfile->basename() ){
- throw new InvalidArgumentException('File access disallowed');
+ // Search utility only checks that reference exists, not whether it's actually a file
+ if( $srcfile->isDirectory() ){
+ throw new InvalidArgumentException('File is a directory');
}
// validate allowed source file types, including custom aliases
@@ -124,6 +124,11 @@
throw new InvalidArgumentException('File extension disallowed, '.$ext );
}
+ // Deny access to files outside wp-content and WordPress root, plus sensitive files in the root
+ if( 'wp-config.php' === $srcfile->basename() || ! ( $srcfile->underContentDirectory() || $srcfile->underWordPressDirectory() ) ){
+ throw new InvalidArgumentException('File access disallowed');
+ }
+
// source code will be HTML-tokenized into multiple lines
$code = [];
--- a/loco-translate/src/fs/Locations.php
+++ b/loco-translate/src/fs/Locations.php
@@ -103,7 +103,7 @@
*/
public static function getThemes(){
if( ! self::$theme ){
- $roots = isset($GLOBALS['wp_theme_directories']) ? $GLOBALS['wp_theme_directories'] : [];
+ $roots = $GLOBALS['wp_theme_directories'] ?? [];
if( ! $roots ){
$roots[] = trailingslashit( loco_constant('WP_CONTENT_DIR') ).'themes';
}
--- a/loco-translate/src/mvc/View.php
+++ b/loco-translate/src/mvc/View.php
@@ -34,7 +34,7 @@
* Name of current output buffer
* @var string
*/
- private $block;
+ private $name;
/**
@@ -66,7 +66,7 @@
* Clean up if something abruptly stopped rendering before graceful end
*/
public function __destruct(){
- if( $this->block ){
+ if( $this->name ){
ob_end_clean();
}
}
@@ -106,7 +106,7 @@
private function start( string $name ):void {
$this->stop();
$this->scope[$name] = null;
- $this->block = $name;
+ $this->name = $name;
}
@@ -117,13 +117,26 @@
private function stop(){
$content = ob_get_contents();
ob_clean();
- if( $b = $this->block ){
+ if( $b = $this->name ){
if( isset($this->scope[$b]) ){
$content = $this->scope[$b].$content;
}
$this->scope[$b] = new _LocoViewBuffer($content);
}
- $this->block = '_trash';
+ $this->name = '_trash';
+ }
+
+
+ /**
+ * Output a captured block buffer, as long as it's valid
+ */
+ private function block( string $name ):void {
+ if( $this->has($name) ){
+ $view = $this->get($name);
+ if( $view instanceof _LocoViewBuffer ){
+ echo $view->__toString();
+ }
+ }
}
@@ -146,8 +159,7 @@
/**
- * @param string $prop
- * @return bool
+ * Test if a view argument exists
*/
public function has( string $prop ):bool {
return $this->scope->offsetExists($prop);
@@ -156,7 +168,6 @@
/**
* Get property after checking with self::has
- * @param string $prop
* @return mixed
*/
public function get( string $prop ){
@@ -166,10 +177,6 @@
/**
* Set a view argument
- * @param string $prop
- * @param mixed $value
- *
- * @return Loco_mvc_View
*/
public function set( string $prop, $value ):self {
$this->scope[$prop] = $value;
@@ -177,6 +184,13 @@
}
+ /**
+ * Remove a view argument
+ */
+ public function unset( string $prop ):void {
+ $this->scope->offsetUnset($prop);
+ }
+
/**
* Main entry to rendering complete template
@@ -185,7 +199,7 @@
* @param self|null $parent parent view rendering this view
*/
public function render( string $tpl, ?array $args = null, ?Loco_mvc_View $parent = null ):string {
- if( $this->block ){
+ if( $this->name ){
return $this->fork()->render( $tpl, $args, $this );
}
$this->setTemplate($tpl);
@@ -213,7 +227,7 @@
$this->start('_trash');
$this->execTemplate( $this->template );
$this->stop();
- $this->block = null;
+ $this->name = null;
// decorate via parent view if there is one
if( $this->parent ){
$this->parent->scope = clone $this->scope;
@@ -294,9 +308,9 @@
*/
class _LocoViewBuffer {
- private $s;
+ private string $s;
- public function __construct( $s ){
+ public function __construct( string $s ){
$this->s = $s;
}
--- a/loco-translate/src/mvc/ViewParams.php
+++ b/loco-translate/src/mvc/ViewParams.php
@@ -65,30 +65,35 @@
/**
* @internal
- * @param string $p property name
* @return mixed
*/
- public function __get( $p ){
+ public function __get( string $p ){
return $this->offsetExists($p) ? $this->offsetGet($p) : null;
}
/**
* Test if a property exists, even if null
- * @param string $p property name
- * @return bool
*/
- public function has( $p ){
+ public function has( string $p ):bool {
return $this->offsetExists($p);
}
/**
+ * Test if a property exists and is truthy
+ */
+ public function truthy( string $p ):bool {
+ return $this->offsetExists($p) && $this->offsetGet($p);
+ }
+
+
+ /**
* Print escaped property value
* @param string $p property key
* @return string empty string
*/
- public function e( $p ){
+ public function e( string $p ):string {
$text = $this->__get($p);
echo $this->escape( $text );
return '';
--- a/loco-translate/tpl/admin/bundle/conf.php
+++ b/loco-translate/tpl/admin/bundle/conf.php
@@ -144,6 +144,7 @@
<a class="button button-link has-icon icon-cog" href="<?php $parent->e('href')?>"><?php esc_html_e('Parent theme','loco-translate')?></a><?php
endif?>
<a class="button button-link has-icon icon-download" href="<?php $params->e('xmlUrl')?>"><?php esc_html_e('XML','loco-translate')?></a>
+ <a class="button button-link has-icon icon-help" href="<?php $params->e('manUrl')?>" target="_blank"><?php esc_html_e('Help','loco-translate')?></a>
</p>
</footer>
--- a/loco-translate/tpl/admin/bundle/setup.php
+++ b/loco-translate/tpl/admin/bundle/setup.php
@@ -4,8 +4,7 @@
* See setup/*.php for header definitions
*/
$this->extend('../layout');
-
- echo $header;
+$this->block('header');
/* @var Loco_mvc_ViewParams $params */
--- a/loco-translate/tpl/admin/config/version.php
+++ b/loco-translate/tpl/admin/config/version.php
@@ -3,9 +3,9 @@
* Plugin version information
*/
$this->extend('../layout');
-
+ /* @var Loco_mvc_ViewParams $params */
// Loco Translate version:
- if( $params->has('update') ):?>
+ if( $params->truthy('update') && $params->truthy('update_href') ):?>
<div class="panel panel-warning">
<h3 class="has-icon">
<?php self::e( __('Version %s','loco-translate'), $version )?>
@@ -14,7 +14,7 @@
<?php esc_html_e('A newer version of Loco Translate is available for download','loco-translate')?>.
</p>
<p class="submit">
- <a class="button button-primary" href="<?php echo $update_href?>" target="_blank"><?php self::e(__('Upgrade to %s','loco-translate'), 'v'.$update )?></a>
+ <a class="button button-primary" href="<?php echo esc_url($update_href)?>" target="_blank"><?php self::e(__('Upgrade to %s','loco-translate'), 'v'.$update )?></a>
<a class="button button-link has-icon icon-ext" href="https://wordpress.org/plugins/loco-translate/installation/" target="_blank"><?php esc_html_e('Install manually','loco-translate')?></a>
</p>
</div><?php
--- a/loco-translate/tpl/admin/debug/debug-layout.php
+++ b/loco-translate/tpl/admin/debug/debug-layout.php
@@ -14,11 +14,9 @@
</style>
<?php
-/* @var Loco_mvc_View $params */
-/* @var string $header */
-$params->has('header') and print $header;
-
+$this->block('header');
+/* @var Loco_mvc_View $params */
/* @var ArrayIterator|null $log */
if( $params->has('log') ):?>
<div class="panel" id="loco-log">
--- a/loco-translate/tpl/admin/file/editor.php
+++ b/loco-translate/tpl/admin/file/editor.php
@@ -3,8 +3,9 @@
* Editor layout for PO and POT files
*/
+/* @var Loco_mvc_View $this */
$this->extend('../layout');
-echo $header;
+$this->block('header');
/* @var Loco_mvc_ViewParams $js */
/* @var Loco_mvc_ViewParams $ui */
--- a/loco-translate/tpl/admin/file/info.php
+++ b/loco-translate/tpl/admin/file/info.php
@@ -3,7 +3,7 @@
* File information for any type of file. Extended by specific views for supported types
*/
$this->extend('../layout');
-echo $header;
+$this->block('header');
/* @var Loco_mvc_FileParams $file */
?>
--- a/loco-translate/tpl/admin/file/view.php
+++ b/loco-translate/tpl/admin/file/view.php
@@ -2,5 +2,6 @@
/**
* Source view - displays file in raw form if possible
*/
+/* @var Loco_mvc_View $this */
$this->extend('../layout');
-echo $source;
No newline at end of file
+$this->block('source');