diff --git a/KNOWN_ISSUES.txt b/KNOWN_ISSUES.txt index d313328..dbb7746 100644 --- a/KNOWN_ISSUES.txt +++ b/KNOWN_ISSUES.txt @@ -4,14 +4,3 @@ MLP KNOWN ISSUES * If using the 'Power users can change a rendition's language or article' feature, if you change a rendition's language or article ID then the 'View' link will not be updated until you reload the article. - -* Older version of MLP sometimes lost track of changes to the textpattern -table made by other plugins such as glz_custom_fields. This manifests -itself when you save a rendition and the changes are reflected in the -admin side but _not_ in the public site. To fix this, find any plugin that -modifies the textpattern table and force it to make a change to the table. -For example, with glz_custom_fields, visit Extensions->Custom Fields and -either change an existing field's type, or create a new field. Make sure -you save the changes and then visit another admin panel which causes MLP -to resync the tables. You can then change your edited custom field back -the way it was, if you wish. diff --git a/plugins/sources/gbp_admin_library.php b/plugins/sources/gbp_admin_library.php index 834e2bc..dfb9430 100644 --- a/plugins/sources/gbp_admin_library.php +++ b/plugins/sources/gbp_admin_library.php @@ -17,7 +17,7 @@ // 1 = Plugin help is in raw HTML. Not recommended. # $plugin['allow_html_help'] = 1; -$plugin['version'] = '4.6.0.20160216'; +$plugin['version'] = '4.6.2.20170310'; $plugin['author'] = 'Graeme Porteous'; $plugin['author_uri'] = ''; $plugin['description'] = 'GBP Admin-Side Library'; @@ -416,7 +416,7 @@ public function render_tabs () { } $out[] = '

'; - $out[] = '
'; + $out[] = '
'; echo join('', $out); } @@ -484,8 +484,7 @@ public function url ($vars = array(), $gp = false) { $out[] = $key.'='.urlencode($value); } - $script = hu.basename(txpath).'/index.php'; - return $script . (isset($out) + return (isset($out) ? '?'.join('&', $out) : ''); } diff --git a/plugins/sources/l10n.php b/plugins/sources/l10n.php index 1d9a062..fcbd4f7 100644 --- a/plugins/sources/l10n.php +++ b/plugins/sources/l10n.php @@ -17,9 +17,9 @@ // 1 = Plugin help is in raw HTML. Not recommended. # $plugin['allow_html_help'] = 1; -$plugin['version'] = '4.6.0.20160216'; -$plugin['author'] = 'Graeme Porteous, Steve Dickinson, Stef Dawson'; -$plugin['author_uri'] = 'http://txp-plugins.netcarving.com/plugins/mlp-plugin'; +$plugin['version'] = '4.6.2.20170316'; +$plugin['author'] = 'Graeme Porteous, Steve Dickinson, Stef Dawson, Dmitry Shovchko'; +$plugin['author_uri'] = 'https://github.com/Bloke/MLP'; $plugin['description'] = 'Multi-Lingual Publishing Package.'; // Plugin load order: @@ -542,7 +542,7 @@ function _l10n_textpattern_comment_submit() # The REQUEST_URI has to be maintained to ensure comments work and compatibility with # plugins... # - if ($prefs['l10n_l10n-url_default_lang_marker'] === '1' || isset($_SESSION['l10n_request_uri'])) + if ((isset($prefs['l10n_l10n-url_default_lang_marker']) && $prefs['l10n_l10n-url_default_lang_marker'] === '1') || isset($_SESSION['l10n_request_uri'])) { if (isset($_SESSION['l10n_request_uri'])) { $pretext['request_uri'] = $_SERVER['REQUEST_URI'] = $_SESSION['l10n_request_uri']; @@ -721,7 +721,7 @@ function _l10n_inject_lang_markers_cb( $matches ) $default_lang_long = $site_langs[0]; $default_lang_short = substr( $default_lang_long , 0 , 2 ); - if ( $prefs['l10n_l10n-url_default_lang_marker'] === '1' || ($callback_language_marker !== $default_lang_short) ) + if ( (isset($prefs['l10n_l10n-url_default_lang_marker']) && $prefs['l10n_l10n-url_default_lang_marker'] === '1') || ($callback_language_marker !== $default_lang_short) ) { $result = $l10n_replace_strings['start_rep'].$matches[1].'/'.$callback_language_marker.$extra.$matches[2].$l10n_replace_strings['stop_rep']; } @@ -746,6 +746,16 @@ function _l10n_inject_rss_lang_markers( $buffer ) _l10n_make_exclusion_list(); global $l10n_replace_strings; + + # Insert the language code into all permlinks... + $l10n_replace_strings['start'] = ' href=["|\']'; + $l10n_replace_strings['start_rep'] = ' href="'; + $l10n_replace_strings['stop'] = '["|\']'; + $l10n_replace_strings['stop_rep'] = '"'; + $l10n_replace_strings['insert_blank'] = true; + $pattern1 = _l10n_make_pattern(); + $buffer = _l10n_preg_replace_callback( $pattern1 , '_l10n_inject_lang_markers_cb' , $buffer ); + $l10n_replace_strings['start'] = $l10n_replace_strings['start_rep'] = ''; $l10n_replace_strings['stop'] = $l10n_replace_strings['stop_rep'] = ''; $l10n_replace_strings['insert_blank'] = true; @@ -845,6 +855,24 @@ function _l10n_inject_lang_markers( $buffer ) $pattern2 = _l10n_make_pattern(); $buffer = _l10n_preg_replace_callback( $pattern2 , '_l10n_inject_lang_markers_cb' , $buffer ); + $l10n_replace_strings['start'] = $l10n_replace_strings['start_rep'] = ''; + $l10n_replace_strings['stop'] = $l10n_replace_strings['stop_rep'] = ''; + $l10n_replace_strings['insert_blank'] = false; + $pattern3 = _l10n_make_pattern(); + $buffer = _l10n_preg_replace_callback( $pattern3 , '_l10n_inject_lang_markers_cb' , $buffer ); + + $l10n_replace_strings['start'] = $l10n_replace_strings['start_rep'] = ''; + $l10n_replace_strings['stop'] = $l10n_replace_strings['stop_rep'] = ''; + $l10n_replace_strings['insert_blank'] = false; + $pattern4 = _l10n_make_pattern(); + $buffer = _l10n_preg_replace_callback( $pattern4 , '_l10n_inject_lang_markers_cb' , $buffer ); + + $l10n_replace_strings['start'] = $l10n_replace_strings['start_rep'] = ''; + $l10n_replace_strings['stop'] = $l10n_replace_strings['stop_rep'] = ''; + $l10n_replace_strings['insert_blank'] = false; + $pattern5 = _l10n_make_pattern(); + $buffer = _l10n_preg_replace_callback( $pattern5 , '_l10n_inject_lang_markers_cb' , $buffer ); + if (0) #debug $buffer = 'Exclusions... :' . join( ', ' , $l10n_url_exclusions ) . $buffer; diff --git a/plugins/sources/zem_contact_lang-mlp.php b/plugins/sources/zem_contact_lang-mlp.php index 3ef0dae..05b396a 100644 --- a/plugins/sources/zem_contact_lang-mlp.php +++ b/plugins/sources/zem_contact_lang-mlp.php @@ -1,13 +1,74 @@ abc_myplugin-0.1.txt + +// Plugin name is optional. If unset, it will be extracted from the current +// file name. Plugin names should start with a three letter prefix which is +// unique and reserved for each plugin author ("abc" is just an example). +// Uncomment and edit this line to override: +$plugin['name'] = 'zem_contact_lang-mlp'; + +// Allow raw HTML help, as opposed to Textile. +// 0 = Plugin help is in Textile format, no raw HTML allowed (default). +// 1 = Plugin help is in raw HTML. Not recommended. +# $plugin['allow_html_help'] = 1; + +$plugin['version'] = '4.6.2.20170316'; +$plugin['author'] = 'Netcarver & the TXP Community'; +$plugin['author_uri'] = 'http://forum.textpattern.com/viewtopic.php?id=12956'; +$plugin['description'] = 'MLP strings plug-in for Zem Contact Reborn'; + +// Plugin load order: +// The default value of 5 would fit most plugins, while for instance comment +// spam evaluators or URL redirectors would probably want to run earlier +// (1...4) to prepare the environment for everything else that follows. +// Values 6...9 should be considered for plugins which would work late. +// This order is user-overrideable. +$plugin['order'] = '0'; + +// Plugin 'type' defines where the plugin is loaded +// 0 = public : only on the public side of the website (default) +// 1 = public+admin : on both the public and admin side +// 2 = library : only when include_plugin() or require_plugin() is called +// 3 = admin : only on the admin side (no AJAX) +// 4 = admin+ajax : only on the admin side (AJAX supported) +// 5 = public+admin+ajax : on both the public and admin side (AJAX supported) +$plugin['type'] = '0'; + +// Plugin "flags" signal the presence of optional capabilities to the core plugin loader. +// Use an appropriately OR-ed combination of these flags. +// The four high-order bits 0xf000 are available for this plugin's private use +if (!defined('PLUGIN_HAS_PREFS')) define('PLUGIN_HAS_PREFS', 0x0001); // This plugin wants to receive "plugin_prefs.{$plugin['name']}" events +if (!defined('PLUGIN_LIFECYCLE_NOTIFY')) define('PLUGIN_LIFECYCLE_NOTIFY', 0x0002); // This plugin wants to receive "plugin_lifecycle.{$plugin['name']}" events + +$plugin['flags'] = '0'; + +// Plugin 'textpack' is optional. It provides i18n strings to be used in conjunction with gTxt(). +// Syntax: +// ## arbitrary comment +// #@event +// #@language ISO-LANGUAGE-CODE +// abc_string_name => Localized String + +/** Uncomment me, if you need a textpack +$plugin['textpack'] = <<< EOT +#@admin +#@language en-gb +abc_sample_string => Sample String +abc_one_more => One more +#@language de-de +abc_sample_string => Beispieltext +abc_one_more => Noch einer +EOT; +**/ +// End of textpack + +if (!defined('txpinterface')) + @include_once('zem_tpl.php'); # --- BEGIN PLUGIN CODE --- # @@ -59,7 +120,8 @@ # Register the callback for the enumerate string event. # If the MLP pack is not present and active this will NOT get called. # -register_callback( 'zem_crl_enumerate_strings' , 'l10n.enumerate_strings' ); +if (defined('txpinterface')) + register_callback( 'zem_crl_enumerate_strings' , 'l10n.enumerate_strings' ); # # Here's a callback routine used to register the above strings with diff --git a/textpattern/l10n.css b/textpattern/l10n.css index 2cd076a..bb861d3 100644 --- a/textpattern/l10n.css +++ b/textpattern/l10n.css @@ -39,7 +39,7 @@ l10n styles for other tabs... .l10n_values_list { float: right; width: 50%; } .l10n_string_list { float: left; width: 25%; } -.l10n_subtab { padding: 0 30px; } +.l10n_subtab { padding: 0 30px; clear:both; } .l10n_list { float: left; width: 50%; } .l10n_edit { float: right; width: 50%; } .l10n_owner_list { float: left; width: 20%; } diff --git a/textpattern/lib/l10n_admin.php b/textpattern/lib/l10n_admin.php index 51180a8..60efb01 100644 --- a/textpattern/lib/l10n_admin.php +++ b/textpattern/lib/l10n_admin.php @@ -91,10 +91,6 @@ } } - register_callback('_l10n_category_extend', 'category_ui', 'extend_detail_form'); - register_callback('_l10n_image_extend', 'image_ui', 'extend_detail_form'); - register_callback('_l10n_link_extend', 'link_ui', 'extend_detail_form'); - if ($app_mode !== 'async') { ob_start('_l10n_process_admin_page'); } @@ -234,37 +230,9 @@ function _l10n_check_index() } function _l10n_post_save( $event , $step ) { - $fields = array(); - if ($event === 'section') - { - $fields[] = 'Section'; - } - else if ($event === 'category' && strpos($step, '_save') !== false) - { - $fields = array('Category1', 'Category2'); - } - - if (empty($fields)) - { - return false; - } - - $old_name = doSlash( ps('old_name') ); - $name = doSlash( sanitizeForUrl( ps('name') ) ); - - if( $name !== $old_name ) - { - $langs = MLPLanguageHandler::get_site_langs(); - foreach( $langs as $lang ) - { - $table = _l10n_make_textpattern_name(array('long'=>$lang)); - foreach ($fields as $field) - { - $clause = $field . " = '$old_name'" ; - safe_update( $table , $field . " = '$name'", $clause ); - } - } - } + # + # Nothing to do, when tables are replaced by views + # } function _l10n_list_filter( $event, $step ) @@ -306,7 +274,7 @@ function _l10n_list_filter( $event, $step ) } } $languages = join( ',' , $selected ); - _l10n_create_temp_textpattern( $languages ); +// _l10n_create_temp_textpattern( $languages ); break; default: break; @@ -875,38 +843,15 @@ function _l10n_article_buffer_processor( $buffer ) function _l10n_replace_rendition( $lang , $replace=false , $id='' ) { - $op = 'INSERT'; - if( $replace ) - $op = 'REPLACE'; - - if( empty($id) ) - { - if(!empty($GLOBALS['ID'])) - $id = intval($GLOBALS['ID']); - else - $id = gps('ID'); - } - - if( !MLPLanguageHandler::is_valid_code($lang) ) - { - echo br , "Invalid language code '$lang' calculated in _l10n_add_rendition()"; - return; - } - $table_name = safe_pfx( _l10n_make_textpattern_name($lang) ); - $safe_txp = safe_pfx( 'textpattern' ); - - $sql = $op." INTO $table_name SELECT * FROM $safe_txp WHERE $safe_txp.ID='$id' LIMIT 1"; - safe_query( $sql ); + # + # Nothing to do, when tables are replaced by views + # } function _l10n_remove_rendition( $lang , $id ) { - if( !MLPLanguageHandler::is_valid_code($lang) ) - { - echo br , "Invalid language code '$lang' calculated in _l10n_add_rendition()"; - return; - } - $table_name = safe_pfx( _l10n_make_textpattern_name($lang) ); - safe_delete( $table_name , "`ID`='$id'" ); + # + # Nothing to do, when tables are replaced by views + # } function _l10n_add_rendition_to_article_cb( $event , $step ) { @@ -1129,28 +1074,9 @@ function _l10n_pre_multi_edit_cb( $event , $step ) function _l10n_observe_table_changes( $event , $step ) { - static $l10n_hashes = array(); - - if (isset($l10n_hashes['textpattern'])) { - $rs = $l10n_hashes['textpattern']; - } else { - $rs = safe_show('COLUMNS', 'textpattern'); - $l10n_hashes['textpattern'] = $rs; - } - - $txp_table_hash = md5(serialize($l10n_hashes['textpattern'])); - $previous_hashes = unserialize(get_pref('l10n_hashes')); - - if ($previous_hashes['textpattern'] !== $txp_table_hash) { - _l10n_sync_table_definitions( $l10n_hashes ); -// _l10n_update_dirty_flag( 'DIRTY' ); - } - - // Regenerate the hash table and stash it - $hash_table = array(); - $hash_table['textpattern'] = $txp_table_hash; - - set_pref('l10n_hashes', serialize($hash_table), 'l10n', PREF_HIDDEN); + # + # Nothing to do, when tables are replaced by views + # } function _l10n_check_lang_code( $lang ) @@ -1200,25 +1126,39 @@ function _l10n_check_lang_table( $lang ) $code = $result; $table_name = _l10n_make_textpattern_name( $code ); - if( safe_query( "SHOW COLUMNS FROM `$table_name`" ) ) - { - return true; + $type = NULL; + if ( $r = safe_query( 'SHOW FULL TABLES') ) { + $type = 'NONE'; + if ( mysqli_num_rows( $r ) > 0 ) { + while ( $a = mysqli_fetch_row( $r ) ) { + if ( $a[0] === PFX.$table_name ) { + $type = strtoupper($a[1]); + } + } + + mysqli_free_result( $r ); } - return array($code, $table_name); + } + + return array($code, $table_name, $type); } function _l10n_generate_lang_table( $lang ) { $result = _l10n_check_lang_table( $lang ); if( !is_array($result) ) return $result; - list($code, $table_name) = $result; - $where = ' WHERE `'.L10N_COL_LANG."`='$lang'"; - - safe_query( 'LOCK TABLES `'.PFX.$table_name.'` WRITE' ); - safe_query( 'CREATE TABLE `'.PFX.$table_name.'` LIKE `'.PFX.'textpattern`' ); - safe_query( 'INSERT INTO `'.PFX.$table_name.'` SELECT * FROM `'.PFX.'textpattern`'.$where ); - safe_query( 'OPTIMIZE TABLE `'.PFX.$table_name.'`' ); - safe_query( 'UNLOCK TABLES' ); + list($code, $table_name, $type) = $result; + switch( $type ) { + case 'BASE TABLE': + safe_query( 'DROP TABLE `'.PFX.$table_name.'`' ); + + case 'NONE': + $where = ' WHERE `'.L10N_COL_LANG."`='$lang'"; + safe_query( 'CREATE VIEW `'.PFX.$table_name.'` AS SELECT * FROM `'.PFX.'textpattern`'.$where ); + + case 'VIEW': + default: + } } function _l10n_check_localise_table( $lang ) @@ -1293,88 +1233,9 @@ function _l10n_generate_localise_table_fields( $lang ) */ function _l10n_sync_table_definitions( $source = array() ) { - if (!is_array($source)) { - return false; - } - - foreach ($source as $table => $definition) - { -//dmp($definition); - switch ($table) - { - case 'textpattern': - $langs = MLPLanguageHandler::get_site_langs(); - - foreach ($langs as $lang) - { - $sql = array(); - $safe_lang = _l10n_check_lang_code( $lang ); - if( !is_string($safe_lang) ) continue; - - $table = _l10n_make_textpattern_name(array('long' => $lang)); - $rs = safe_show('COLUMNS', $table); - - foreach ($definition as $def) - { - $field = $def['Field']; - - $type = $def['Type']; - $null = $def['Null']; - $default = $def['Default']; - $extra = $def['Extra']; - - $found = false; - foreach ($rs as $idx => $lang_field) { - if ( $lang_field['Field'] === $field) { - $found = $idx; - break; - } - } - - // ID fields can't be altered here due to auto_increment differences - // This can't be done earlier as we don't know the position in the destination table until now - if ($field === 'ID') { - unset($rs[$found]); - continue; - } - - if ($found !== false) { - // Field exists in destination table so update its definition if anything's changed - $dest_type = $rs[$found]['Type']; - $dest_null = $rs[$found]['Null']; - $dest_default = $rs[$found]['Default']; - $dest_extra = $rs[$found]['Extra']; - - if ( $type !== $dest_type - || $null !== $dest_null - || $default !== $dest_default - || $extra !== $dest_extra ) - { - $sql[] = 'MODIFY ' .$field. ' ' .$type . ($null === 'NO' ? ' NOT NULL' : ' NULL') . ($default ? ' DEFAULT "'.$default.'"' : '') . ' ' .$extra; - } - - // Removing each found item from the destination table serves two purposes: - // 1) it speeds the loop up as things move forward - // 2) it means that any fields left over by the time the loop ends are fields that need removing - unset($rs[$found]); - - } else { - // New field (or possibly a renamed field, but if that happens there are more urgent things to worry about!) - $sql[] = 'ADD ' .$field. ' ' .$type . ($null === 'NO' ? ' NOT NULL' : ' NULL') . ($default ? ' DEFAULT "'.$default.'"' : '') . ' ' .$extra; - } - } - - // Extraneous fields: remove them - foreach ($rs as $def) { - $sql[] = 'DROP ' . $def['Field']; - } - foreach ($sql as $statement) { - safe_alter($table, $statement); - } - } - break; - } - } + # + # Nothing to do, when tables are replaced by views + # } function _l10n_pre_discuss_multi_edit( $event , $step ) @@ -1454,10 +1315,10 @@ function _l10n_build_sql_set( $table ) global $l10n_mappings; $langs = MLPLanguageHandler::get_site_langs(); $default = MLPLanguageHandler::get_site_default_lang(); - $set = ''; + $set = array(); if( !isset($l10n_mappings[$table]) ) - return $set; + return ''; $fields = $l10n_mappings[$table]; foreach( $fields as $field => $attributes ) @@ -1480,57 +1341,55 @@ function _l10n_build_sql_set( $table ) return join( ', ', $set ); } -function _l10n_category_extend ($evt, $stp, $data, $rs) { +function _l10n_category_paint( $page ) + { $default = MLPLanguageHandler::get_site_default_lang(); + # + # Insert the default title field's language's direction... + # + $dir = MLPLanguageHandler::get_lang_direction_markup( $default ) . ' '; + $f = '([^<]*<[^>]*>){8}/', $page, $m); + $f = $m[0][0]; + foreach( $fields as $field => $attributes ) { + $r = ''; foreach( $langs as $lang ) { $full_name = MLPLanguageHandler::get_native_name_of_lang( $lang ); $dir = MLPLanguageHandler::get_lang_direction_markup( $lang ); - if( $lang !== $default ) + + if( $lang !== $default ) { $field_name = _l10n_make_field_name( $field , $lang ); - $r .= '

'; - $r .= ''; - $r .= '

'.n; + $r .= '
'; + $r .= '
'; + $r .= '
'; + $r .= '
'; } } + $page = str_replace( $f , $f.n.$r , $page ); } - return $r; -} - -function _l10n_category_paint( $page ) - { - $default = MLPLanguageHandler::get_site_default_lang(); - - $id = gps( 'id' ); - assert_int($id); - $row = safe_row( '*' , 'txp_category' , "`id`='$id'" ); - - # - # Insert the default title field's language's direction... - # - $dir = MLPLanguageHandler::get_lang_direction_markup( $default ) . ' '; - $f = '([^<]*<[^>]*>){8}/', $page, $m); + $f = $m[0][0]; foreach( $fields as $field => $attributes ) { @@ -1579,34 +1449,23 @@ function _l10n_section_paint( $page ) { $full_name = MLPLanguageHandler::get_native_name_of_lang( $lang ); $dir = MLPLanguageHandler::get_lang_direction_markup( $lang ); + if( $lang !== $default ) { $field_name = _l10n_make_field_name( $field , $lang ); - $field_value = $row[$field_name]; - $r .= '

'; - $r .= '

'; + $r .= '
'; + $r .= '
'; + $r .= '
'; + $r .= '
'; } } $page = str_replace( $f , $f.n.$r , $page ); } } - # - # Insert the default title field's language's direction... - # - $dir = MLPLanguageHandler::get_lang_direction_markup( $default ) . ' '; - $f = 'id="section_title"'; - $page = str_replace( $f , $f.$dir , $page ); - - # - # Insert the default title field's language name... - # - $f = '">'.gTxt('section_longtitle'); - $r = '['.MLPLanguageHandler::get_native_name_of_lang( $default ) . ']'; - $page = str_replace( $f , $f.n.$r , $page ); - return $page; } + function _l10n_section_save( $event , $step ) { $id_name = 'name'; @@ -1621,6 +1480,20 @@ function _l10n_file_paint( $page ) { $default = MLPLanguageHandler::get_site_default_lang(); + # + # Insert the default description field's language name... + # + $f = '