From 364967b9c510243072eb2635117cf8a01a2baa5f Mon Sep 17 00:00:00 2001 From: CaMer0n Date: Tue, 14 Jul 2009 03:18:17 +0000 Subject: [PATCH] Theme manager can now install theme-recommended plugins without leaving the page. Notice removal. theme.xml spec modified slightly, to allow themers to provide links to external URLs of 'required' plugins. --- e107_admin/notify.php | 91 ++++++++++++--------- e107_admin/plugin.php | 26 +++--- e107_handlers/form_handler.php | 17 ++-- e107_handlers/plugin_class.php | 42 ++++++---- e107_handlers/theme_handler.php | 140 ++++++++++++++++++++++---------- e107_handlers/xml_class.php | 8 +- e107_themes/e107v4a/theme.xml | 6 +- 7 files changed, 203 insertions(+), 127 deletions(-) diff --git a/e107_admin/notify.php b/e107_admin/notify.php index a1c754fa8..93a98f9a3 100644 --- a/e107_admin/notify.php +++ b/e107_admin/notify.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_admin/notify.php,v $ -| $Revision: 1.7 $ -| $Date: 2009-07-10 14:25:22 $ +| $Revision: 1.8 $ +| $Date: 2009-07-14 03:18:16 $ | $Author: e107coders $ +----------------------------------------------------------------------------+ */ @@ -71,21 +71,24 @@ class notify_config $this -> notify_prefs = $eArrayStorage -> ReadArray($this -> notify_prefs); // load every e_notify.php file. - foreach($pref['e_notify_list'] as $val) + if($pref['e_notify_list']) { - if (!isset($this -> notify_prefs['plugins'][$val])) - { - $this -> notify_prefs['plugins'][$val] = TRUE; - if (is_readable(e_PLUGIN.$val."/e_notify.php")) + foreach($pref['e_notify_list'] as $val) + { + if (!isset($this -> notify_prefs['plugins'][$val])) { - require_once(e_PLUGIN.$val.'/e_notify.php'); - foreach ($config_events as $event_id => $event_text) - { - $this -> notify_prefs['event'][$event_id] = array('class' => '255', 'email' => ''); + $this -> notify_prefs['plugins'][$val] = TRUE; + if (is_readable(e_PLUGIN.$val."/e_notify.php")) + { + require_once(e_PLUGIN.$val.'/e_notify.php'); + foreach ($config_events as $event_id => $event_text) + { + $this -> notify_prefs['event'][$event_id] = array('class' => '255', 'email' => ''); + } + $recalibrate = true; } - $recalibrate = true; } - } + } } @@ -102,21 +105,15 @@ class notify_config global $ns, $rs, $frm, $emessage; $text = "
+
".NT_LAN_2.":
+ ".NU_LAN_1." - - - - - "; - - $text .= " - "; $text .= $this -> render_event('usersup', NU_LAN_2); @@ -124,47 +121,67 @@ class notify_config $text .= $this -> render_event('login', NU_LAN_4); $text .= $this -> render_event('logout', NU_LAN_5); - $text .= " - - "; + $text .= "
".NT_LAN_2.":
".NU_LAN_1."
".NS_LAN_1."
+
+ ".NS_LAN_1." + + + + + "; $text .= $this -> render_event('flood', NS_LAN_2); - $text .= " - - "; + $text .= "
".NN_LAN_1."
+
+ ".NN_LAN_1." + + + + + "; $text .= $this -> render_event('subnews', NN_LAN_2); $text .= $this -> render_event('newspost', NN_LAN_3); $text .= $this -> render_event('newsupd', NN_LAN_4); $text .= $this -> render_event('newsdel', NN_LAN_5); - $text .= " - - "; + $text .= "
".NF_LAN_1."
+
+ ".NF_LAN_1." + + + + + "; $text .= $this -> render_event('fileupload', NF_LAN_2); + $text .= "
"; + foreach ($this -> notify_prefs['plugins'] as $plugin_id => $plugin_settings) { if(is_readable(e_PLUGIN.$plugin_id.'/e_notify.php')) { require(e_PLUGIN.$plugin_id.'/e_notify.php'); - $text .= " - ".$config_category." - "; + $text .= "
+
+ ".$config_category." + + + + + "; foreach ($config_events as $event_id => $event_text) { $text .= $this -> render_event($event_id, $event_text); } + $text .= "
"; } } - $text .= " - - - + $text .= "
"; $text .= $frm->admin_button('update', LAN_UPDATE,'update'); $text .= " diff --git a/e107_admin/plugin.php b/e107_admin/plugin.php index f1815d374..08fb0d298 100644 --- a/e107_admin/plugin.php +++ b/e107_admin/plugin.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_admin/plugin.php,v $ -| $Revision: 1.30 $ -| $Date: 2009-07-13 09:31:19 $ +| $Revision: 1.31 $ +| $Date: 2009-07-14 03:18:16 $ | $Author: e107coders $ +----------------------------------------------------------------------------+ */ @@ -58,7 +58,7 @@ class pluginManager{ $tmp = explode('.', e_QUERY); $this -> action = ($tmp[0]) ? $tmp[0] : "installed"; - $this -> id = intval($tmp[1]); + $this -> id = varset($tmp[1]) ? intval($tmp[1]) : ""; $this-> fields = array( @@ -147,12 +147,6 @@ class pluginManager{ $this -> pluginUpload(); } - if($emessage->hasMessage) // Would prefer a method like this, but it doesn't work. - { - $emessage = &eMessage::getInstance(); - $ns->tablerender(NWSLAN_4, $emessage->render()); - } - if(isset($_POST['install-selected'])) { foreach($_POST['plugin_checkbox'] as $val) @@ -672,7 +666,7 @@ class pluginManager{ global $plugin,$ns,$frm; - $text .= " + $text = "
".NWSLAN_4." @@ -729,6 +723,8 @@ class pluginManager{ if (empty($pluginList)) return ''; + $text = ""; + foreach($pluginList as $plug) { $_path = e_PLUGIN.$plug['plugin_path'].'/'; @@ -757,7 +753,7 @@ class pluginManager{ $plugAuthor = varset($plug_vars['author']['@attributes']['name'],''); $plugURL = varset($plug_vars['author']['@attributes']['url'],''); $plugReadme = ""; - if($plug['plugin_installflag']) + if(varset($plug['plugin_installflag'])) { $plugName = "".$tp->toHTML($plug['plugin_name'], false, "defs,emotes_off, no_make_clickable").""; } @@ -765,18 +761,18 @@ class pluginManager{ { $plugName = $tp->toHTML($plug['plugin_name'], false, "defs,emotes_off, no_make_clickable"); } - if($plug_vars['readme']) // 0.7 plugin.php + if(varset($plug_vars['readme'])) // 0.7 plugin.php { $plugReadme = $plug_vars['readme']; } - if($plug_vars['readMe']) // 0.8 plugin.xml + if(varset($plug_vars['readMe'])) // 0.8 plugin.xml { $plugReadme = $plug_vars['readMe']; } $text .= ""; - if(is_array($this-> fields['plugin_checkboxes'])) + if(varset($this-> fields['plugin_checkboxes'])) { $rowid = "plugin_checkbox[".$plug['plugin_id']."]"; $text .= "".$frm->checkbox($rowid, $plug['plugin_id'])."\n"; @@ -793,7 +789,7 @@ class pluginManager{ $text .= (in_array("plugin_notes",$this->fieldpref)) ? "".($plugReadme ? "" : " ")."" : ""; $text .= (in_array("plugin_description",$this->fieldpref)) ? "".$tp->toHTML($plug_vars['description'], false, "defs,emotes_off, no_make_clickable")."" : ""; $text .= (in_array("plugin_compatible",$this->fieldpref)) ? "".varset($plug_vars['@attributes']['compatibility'],'')."" : ""; - $text .= (in_array("plugin_compliant",$this->fieldpref)) ? "".(($plug_vars['compliant'] || $plug_vars['@attributes']['xhtmlcompliant']=="true") ? ADMIN_TRUE_ICON : " ")."" : ""; + $text .= (in_array("plugin_compliant",$this->fieldpref)) ? "".((varset($plug_vars['compliant']) || varsettrue($plug_vars['@attributes']['xhtmlcompliant'])) ? ADMIN_TRUE_ICON : " ")."" : ""; // Plugin options Column -------------- diff --git a/e107_handlers/form_handler.php b/e107_handlers/form_handler.php index 10cb81fa3..ae9ded62a 100644 --- a/e107_handlers/form_handler.php +++ b/e107_handlers/form_handler.php @@ -9,8 +9,8 @@ * Form Handler * * $Source: /cvs_backup/e107_0.8/e107_handlers/form_handler.php,v $ - * $Revision: 1.30 $ - * $Date: 2009-07-08 06:58:00 $ + * $Revision: 1.31 $ + * $Date: 2009-07-14 03:18:16 $ * $Author: e107coders $ * */ @@ -583,7 +583,7 @@ class e_form foreach($columnsArray as $key=>$fld) { - if($fld['forced'] !== TRUE) + if(!varset($fld['forced'])) { $checked = (in_array($key,$columnsDefault)) ? TRUE : FALSE; $text .= $this->checkbox('e-columns[]', $key, $checked). $fld['title']."
\n"; @@ -600,10 +600,11 @@ class e_form function colGroup($fieldarray,$columnPref='') { + $text = ""; foreach($fieldarray as $key=>$val) { - if(in_array($key,$columnPref) || $key=='options' || $val['forced']==TRUE) + if(in_array($key,$columnPref) || $key=='options' || varsettrue($val['forced'])) { $text .= "\n"; } @@ -613,14 +614,14 @@ class e_form function thead($fieldarray,$columnPref='') { - + $text = ""; foreach($fieldarray as $key=>$val) { - if(in_array($key,$columnPref) || $key == "options" || ($val['forced']==TRUE)) + if(in_array($key,$columnPref) || $key == "options" || (varsettrue($val['forced']))) { - $cl = ($val['thclass']) ? "class='".$val['thclass']."'" : ""; + $cl = (varset($val['thclass'])) ? "class='".$val['thclass']."'" : ""; $text .= "\n\t"; - $text .= ($val['url']) ? "" : ""; // Really this column-sorting link should be auto-generated, or be autocreated via unobtrusive js. + $text .= (varset($val['url'])) ? "" : ""; // Really this column-sorting link should be auto-generated, or be autocreated via unobtrusive js. $text .= $val['title']; $text .= ($key == "options") ? $this->columnSelector($fieldarray,$columnPref) : ""; diff --git a/e107_handlers/plugin_class.php b/e107_handlers/plugin_class.php index 44a027db1..dbb48eac6 100644 --- a/e107_handlers/plugin_class.php +++ b/e107_handlers/plugin_class.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_handlers/plugin_class.php,v $ -| $Revision: 1.66 $ -| $Date: 2009-07-09 22:12:21 $ +| $Revision: 1.67 $ +| $Date: 2009-07-14 03:18:16 $ | $Author: e107coders $ +----------------------------------------------------------------------------+ */ @@ -1216,27 +1216,30 @@ class e107plugin { $pref_array = array($pref_array); } - foreach($pref_array as $k => $p) + if(is_array($pref_array)) { - $attrib = $p['@attributes']; - if(isset($attrib['type']) && $attrib['type'] == 'array') + foreach($pref_array as $k => $p) { - $name = $attrib['name']; - $tmp = $this->parse_prefs($pref_array[$k]['key']); - $ret['all'][$name] = $tmp['all']; - $ret['active'][$name] = $tmp['active']; - $ret['inactive'][$name] = $tmp['inactive']; - } - else - { - $ret['all'][$attrib['name']] = $attrib['value']; - if(!isset($attrib['active']) || $attrib['active'] == 'true') + $attrib = $p['@attributes']; + if(isset($attrib['type']) && $attrib['type'] == 'array') { - $ret['active'][$attrib['name']] = $attrib['value']; + $name = $attrib['name']; + $tmp = $this->parse_prefs($pref_array[$k]['key']); + $ret['all'][$name] = $tmp['all']; + $ret['active'][$name] = $tmp['active']; + $ret['inactive'][$name] = $tmp['inactive']; } else { - $ret['inactive'][$attrib['name']] = $attrib['value']; + $ret['all'][$attrib['name']] = $attrib['value']; + if(!isset($attrib['active']) || $attrib['active'] == 'true') + { + $ret['active'][$attrib['name']] = $attrib['value']; + } + else + { + $ret['inactive'][$attrib['name']] = $attrib['value']; + } } } } @@ -1253,7 +1256,7 @@ class e107plugin $plug['plug_action'] = 'install'; // $plug_vars = $this->parse_plugin_php($plug['plugin_path']); - include_once($_path.'plugin.php'); + include($_path.'plugin.php'); $func = $eplug_folder.'_install'; if (function_exists($func)) @@ -1276,6 +1279,7 @@ class e107plugin } } + if (is_array($eplug_prefs)) { $this->manage_prefs('add', $eplug_prefs); @@ -1339,6 +1343,8 @@ class e107plugin // install plugin ... $id = (int)$id; $plug = $this->getinfo($id); + + $plug['plug_action'] = 'install'; if ($plug['plugin_installflag'] == FALSE) diff --git a/e107_handlers/theme_handler.php b/e107_handlers/theme_handler.php index 50d8f4b18..b7c4efef7 100644 --- a/e107_handlers/theme_handler.php +++ b/e107_handlers/theme_handler.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_handlers/theme_handler.php,v $ -| $Revision: 1.34 $ -| $Date: 2009-07-12 14:44:56 $ +| $Revision: 1.35 $ +| $Date: 2009-07-14 03:18:16 $ | $Author: e107coders $ +----------------------------------------------------------------------------+ */ @@ -31,6 +31,8 @@ class themeHandler{ function themeHandler() { + global $emessage; + require_once(e_HANDLER."form_handler.php"); $this->frm = new e_form(); //enable inner tabindex counter @@ -85,6 +87,17 @@ class themeHandler{ } + if(isset($_POST['installplugin'])) + { + $key = key($_POST['installplugin']); + + include_lan(e_LANGUAGEDIR.e_LANGUAGE."/admin/lan_plugin.php"); + require_once(e_HANDLER."plugin_class.php"); + + $eplug = new e107plugin; + $message = $eplug->install_plugin($key); + $emessage->add($message, E_MESSAGE_SUCCESS); + } } @@ -211,7 +224,7 @@ class themeHandler{ if (!$_POST['ac'] == md5(ADMINPWCHANGE)) { exit; } - global $ns; + global $ns, $emessage; extract($_FILES); if(!is_writable(e_THEME)) { @@ -229,9 +242,10 @@ class themeHandler{ } else if (strstr($file_userfile['type'][0], "zip")) { $fileType = "zip"; } else { - $ns->tablerender(TPVLAN_16, TPVLAN_17); - require_once("footer.php"); - exit; + $emessage->add(TPVLAN_17, E_MESSAGE_ERROR); + // $ns->tablerender(TPVLAN_16, TPVLAN_17); + // require_once("footer.php"); + return; } if ($fileSize) { @@ -256,9 +270,10 @@ class themeHandler{ } else { $error = TPVLAN_47.PclErrorString().", ".TPVLAN_48.intval(PclErrorCode()); } - $ns->tablerender(TPVLAN_16, TPVLAN_18." ".$archiveName." ".$error); - require_once("footer.php"); - exit; + + $emessage->add(TPVLAN_18." ".$archiveName." ".$error, E_MESSAGE_ERROR); + // $ns->tablerender(TPVLAN_16, TPVLAN_18." ".$archiveName." ".$error); + return; } $folderName = substr($fileList[0]['stored_filename'], 0, (strpos($fileList[0]['stored_filename'], "/"))); @@ -271,9 +286,9 @@ class themeHandler{ function showThemes($mode='main') { - global $ns, $pref; + global $ns, $pref, $emessage; - echo "
+ echo "
\n"; @@ -287,7 +302,7 @@ class themeHandler{ } } - $ns->tablerender(TPVLAN_26." :: ".TPVLAN_33, $text); + $ns->tablerender(TPVLAN_26." :: ".TPVLAN_33, $emessage->render(). $text); } if($mode == "admin") // Show Admin Configuration @@ -300,7 +315,7 @@ class themeHandler{ $text = $this -> renderTheme(2, $theme); } } - $ns->tablerender(TPVLAN_26." :: ".TPVLAN_34, $text); + $ns->tablerender(TPVLAN_26." :: ".TPVLAN_34, $emessage->render(). $text); } @@ -318,7 +333,7 @@ class themeHandler{ $text .= $this -> renderTheme(FALSE, $theme); } $text .= "
 
"; - $ns->tablerender(TPVLAN_26." :: ".TPVLAN_39, $text); + $ns->tablerender(TPVLAN_26." :: ".TPVLAN_39, $emessage->render().$text); } @@ -328,9 +343,9 @@ class themeHandler{ function renderUploadForm() { - global $sql,$ns; + global $sql,$ns, $emessage; - if(!is_writable(e_THEME)) { + if(!is_writable(e_THEME)) { $ns->tablerender(TPVLAN_16, TPVLAN_15); $text = ""; } @@ -364,7 +379,7 @@ class themeHandler{
\n"; } - $ns->tablerender(TPVLAN_26." :: ".TPVLAN_38, $text); + $ns->tablerender(TPVLAN_26." :: ".TPVLAN_38,$emessage->render(). $text); } @@ -553,7 +568,7 @@ class themeHandler{ $this->loadThemeConfig(); // load customn theme configuration fieldss. - $menuPresetCount = 0; + $menuPresetCount = 0; foreach($theme['layouts'] as $key=>$val) { if($val['menuPresets']) @@ -611,9 +626,9 @@ class themeHandler{ ".TPVLAN_53." "; - foreach($theme['layouts'] as $key=>$val) + foreach($theme['pluginOptions'] as $key=>$val) { - $text .= $this->renderPlugins($val['@attributes']['plugins']); + $text .= $this->renderPlugins($theme['pluginOptions']); $text .= " "; } @@ -648,7 +663,7 @@ class themeHandler{ "; - $itext .= ($mode == 1) ? "" : ""; + $itext .= ($mode == 1) ? "" : ""; $itext .= " @@ -808,23 +823,36 @@ class themeHandler{ return $text; } - function renderPlugins($val) + function renderPlugins($tmp) { - $tmp = explode(",",$val); - $tmp = array_filter($tmp); + global $frm,$sql; + // $tmp = explode(",",$val); + // $tmp = array_filter($tmp); - foreach($tmp as $plug) + foreach($tmp['plugin'] as $p) { - $plug = trim($plug); + $plug = trim($p['@attributes']['name']); + if(plugInstalled($plug)) { $text .= $plug." ".ADMIN_TRUE_ICON; } else { - $text .= "".$plug." ".ADMIN_FALSE_ICON; + if($sql -> db_Select("plugin", "plugin_id", " plugin_path = '".$plug."' LIMIT 1 ")) + { + $row = $sql -> db_Fetch(MYSQL_ASSOC); + $name = "installplugin[".$row['plugin_id']."]"; + $text .= $this->frm->admin_button($name, ADLAN_121." ".$plug."",'delete'); + } + else + { + $text .= (isset($p['@attributes']['url']) && ($p['@attributes']['url']!='core')) ? "".$plug." " : "".$plug.""; + $text .= ADMIN_FALSE_ICON; + } + } - $text .= "  "; + $text .= "   "; } return $text; @@ -852,7 +880,7 @@ class themeHandler{ function setTheme() { - global $pref, $e107cache, $ns, $sql; + global $pref, $e107cache, $ns, $sql, $emessage; $themeArray = $this -> getThemes("id"); $pref['sitetheme'] = $themeArray[$this -> id]; @@ -864,10 +892,18 @@ class themeHandler{ $sql -> db_Delete("menus", "menu_layout !='' "); $e107cache->clear_sys(); - save_prefs(); + if(save_prefs()) + { + $emessage->add(TPVLAN_3." '".$themeArray[$this -> id]."'", E_MESSAGE_SUCCESS); + } + else + { + $emessage->add(TPVLAN_3." '".$themeArray[$this -> id]."'", E_MESSAGE_ERROR); + } $this->theme_adminlog('01',$pref['sitetheme'].', '.$pref['themecss']); - $ns->tablerender("Admin Message", "
".TPVLAN_3." '".$themeArray[$this -> id]."'.

"); + + // $ns->tablerender("Admin Message", "
".TPVLAN_3." '".$themeArray[$this -> id]."'.

"); } function findDefault($theme) @@ -903,42 +939,58 @@ class themeHandler{ function setAdminTheme() { - global $pref, $e107cache, $ns; + global $pref, $e107cache, $ns, $emessage; $themeArray = $this -> getThemes("id"); $pref['admintheme'] = $themeArray[$this -> id]; $pref['admincss'] = file_exists(THEME.'admin_style.css') ? 'admin_style.css' : 'style.css'; $e107cache->clear_sys(); - save_prefs(); - $this->theme_adminlog('02',$pref['admintheme'].', '.$pref['admincss']); - $ns->tablerender("Admin Message", "
".TPVLAN_40." '".$themeArray[$this -> id]."'.

"); + if(save_prefs()) + { + $emessage->add(TPVLAN_40." '".$themeArray[$this -> id]."'", E_MESSAGE_SUCCESS); // Default Message + $this->theme_adminlog('02',$pref['admintheme'].', '.$pref['admincss']); + } + + // $ns->tablerender("Admin Message", "
".TPVLAN_40." '".$themeArray[$this -> id]."'.

"); // $this->showThemes('admin'); } function setStyle() { - global $pref, $e107cache, $ns, $sql; + global $pref, $e107cache, $ns, $sql, $emessage; $pref['themecss'] = $_POST['themecss']; $pref['image_preload'] = $_POST['image_preload']; $pref['sitetheme_deflayout'] = $_POST['layout_default']; $e107cache->clear_sys(); - save_prefs(); - $this -> setThemeConfig(); - $this->theme_adminlog('03',$pref['image_preload'].', '.$pref['themecss']); - $ns->tablerender(TPVLAN_36, "
".TPVLAN_37.".

"); + if(save_prefs()) + { + $emessage->add(TPVLAN_37, E_MESSAGE_SUCCESS); // Default Message + $emessage->add($this -> setThemeConfig(),E_MESSAGE_SUCCESS); // Custom Message from theme config. + $this->theme_adminlog('03',$pref['image_preload'].', '.$pref['themecss']); + } + else + { + $emessage->add(TPVLAN_43, E_MESSAGE_ERROR); + } } function setAdminStyle() { - global $pref, $e107cache, $ns; + global $pref, $e107cache, $ns, $emessage; $pref['admincss'] = $_POST['admincss']; $pref['adminstyle'] = $_POST['adminstyle']; $e107cache->clear_sys(); - save_prefs(); - $this->theme_adminlog('04',$pref['adminstyle'].', '.$pref['admincss']); - $ns->tablerender(TPVLAN_36, "
".TPVLAN_43.".

"); + if(save_prefs()) + { + $emessage->add(TPVLAN_43, E_MESSAGE_SUCCESS); + $this->theme_adminlog('04',$pref['adminstyle'].', '.$pref['admincss']); + } + else + { + $emessage->add(TPVLAN_43, E_MESSAGE_ERROR); + } } function SetCustomPages($array) diff --git a/e107_handlers/xml_class.php b/e107_handlers/xml_class.php index e3a5984a4..7d3901ccf 100644 --- a/e107_handlers/xml_class.php +++ b/e107_handlers/xml_class.php @@ -11,9 +11,9 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_handlers/xml_class.php,v $ -| $Revision: 1.10 $ -| $Date: 2008-12-20 20:18:59 $ -| $Author: e107steved $ +| $Revision: 1.11 $ +| $Date: 2009-07-14 03:18:16 $ +| $Author: e107coders $ +----------------------------------------------------------------------------+ */ @@ -192,7 +192,7 @@ class xmlClass } $xml = false; - if(strpos($filename, '://') !== false) + if(strpos($fname, '://') !== false) { $this->getRemoteFile($fname); } diff --git a/e107_themes/e107v4a/theme.xml b/e107_themes/e107v4a/theme.xml index bc4804e05..943ddfebc 100644 --- a/e107_themes/e107v4a/theme.xml +++ b/e107_themes/e107v4a/theme.xml @@ -3,8 +3,12 @@ Classic e107 theme + + + + - +
".TPVLAN_55."".TPVLAN_55."".TPVLAN_52." ".TPVLAN_56."