<?
/**
 * VoiceOne Settings/Plugin/manage
 *
 * Frontend to provide access to the plugin system in voiceone.
 * Allows to manage plugins: Activate/Deactivate, Delete, and Export/Import.
 * Multiple versions of the same plugin can exist in parallel, but only one version can be activ at a time.
 * Messages are written into DIV elements via xajax, thus avoiding classic post/get via forms except uploads.
 * @author Wolfgang Alper
 * @package voiceone
 * @subpackage settings_plugin
 */
  
include ("../../../admin/config/cfg.php");
global $cwlang, $cwLanguage, $absBasePath, $absPluginPath;
require_once("$absBasePath/lib/xajax/xajax.inc.php");
  
// ===================== xajax main functions start =================================

/**
 * xajax - Show Info about the selected plugin. 
 * 
 * Offers Download Link and a close Link
 * @param string $area DIV element to use for display
 * @param string $pluginPackage name of pluginPackage
 * @param integer $state  1=enable 0=disable
 * @see showPluginContent
 * @return xajax getXML
 */
function showPluginInfo($area, $plugin, $state) {
  
  $objResponse = new xajaxResponse();
  
  if ($state == 0) {
    // we just need to  hide the details
    $objResponse->addAssign($area, "innerHTML", "");
    $objResponse->addAssign($area, "style.display", "none");
    return $objResponse->getXML();
  }
  
  // read the plugin information
  // return arr[pluginpackage][xml2array structure]
  $ret = readPluginInfo($plugin);
  $pli = xmlArray2Hash($ret[$plugin][0]['elements']);  
  
  // get download URL. becaues we get an array back, we need to add a 2nd step.
  $ret = readPluginArchiveURL($plugin);
  $plURL = $ret[$plugin];
  
  $msg = <<<EODHeader
  <center><strong><p>Info about Plugin: {$pli['packageName']} - <a href="$plURL"> Download</a></p></strong></center>
  
  <table cellspacing="0">  
    <tr><td><strong>Label:</strong></td><td>{$pli['label']}</td></tr>
    <tr><td><strong>Short Name:</strong></td><td>{$pli['name']}</td></tr>
    <tr><td><strong>Full Name:</strong></td><td>{$pli['packageName']}</td></tr>
    <tr><td><strong>Version:</strong></td><td>{$pli['version']}</td></tr>
    <tr><td><strong>Date:</strong></td><td>{$pli['date']}</td></tr>
    <tr><td><strong>Description:</strong></td><td>{$pli['description']}</td></tr>
    <tr><td><strong>Author Name:</strong></td><td>{$pli['authorName']}</td></tr>
    <tr><td><strong>Author Email:</strong></td><td>{$pli['authorEmail']}</td></tr>
    <tr><td><strong>Author Website:</strong></td><td>{$pli['authorWebsite']}</td></tr>
    <tr><td><strong>Plugin Archive MD5:</strong></td><td>{$pli['md5']}</td></tr>
    <tr><td><strong>VoiceOne Version:</strong></td><td>{$pli['voVersion']}</td></tr>
    <tr><td><strong>Pluginsystem Version:</td><td>{$pli['voPlVersion']}</td></tr>
    <tr><td><strong>Objects included:</td><td>{$pli['elementCount']}</td></tr>
  </table>
  <br />  
EODHeader;


  $msg .= '<center><table cellspacing="0" border="1">';
  $msg .= '<tr><th colspan="2"><center><strong>' . "Included Files" . '</strong></center></th></tr>';
  $msg .= '<tr><th><strong>' . "Filename" . '</strong></th><th><strong>' . "MD5" . '</strong></th></tr>';
  // get attached files
  foreach ($pli['content'] as $files=>$fileRoot) {
    $plc = xmlArray2Hash($fileRoot['elements']);     
    $msg .= "<tr><td>{$plc['filename']}</td><td>{$plc['md5']}</td></tr>";
  }
  $msg .= '</table></center>';

  $msg .= <<<EODFooter
  <br /> 
<center>
    <a href="#" onclick="xajax_showPluginInfo('$area', '', 0); return false;">Close</a>
</center>
EODFooter;


  // show the info
  $objResponse->addAssign($area, "innerHTML", $msg);
  $objResponse->addAssign($area, "style.display", "");
  // jump to top
  $objResponse->addScript("scroll(0,300);");

  
  return $objResponse->getXML(); 
}




/**
 * xajax - Show Content of the selected plugin. 
 * 
 * Offers Download Link and a close Link
 * @param string $area DIV element to use for display
 * @param string $pluginPackage name of pluginPackage
 * @param integer $state  1=enable 0=disable
 * @see showPluginInfo
 * @return xajax getXML
 */
function showPluginContent($area, $plugin, $state) {
  
  $objResponse = new xajaxResponse();
  
  if ($state == 0) {
    // we just need to  hide the details
    $objResponse->addAssign($area, "innerHTML", "");
    $objResponse->addAssign($area, "style.display", "none");
    return $objResponse->getXML();
  }
  
  // get download URL. becaues we get an array back, we need to add a 2nd step.
  $ret = readPluginArchiveURL($plugin);
  $plURL = $ret[$plugin];
  
  $msg = <<<EODHeader
  <center><strong><p>Content of Plugin: {$plugin} - <a href="$plURL"> Download</a></p></strong></center>
  <br />
EODHeader;
  
  $msg .= '<center><table cellspacing="0" border="1">';
  //$msg .= '<tr><th colspan="3"><center><strong>' . "Content" . '</strong></center></th></tr>';
  $msg .= '<tr><th><strong>' . T_("Type") . '</strong></th><th><strong>' . T_("Name") . '</strong></th><th><strong>' . T_("Label") . '</strong></th></tr>';

  // get attached files
  // return arr[pluginpackage][xml2array structure]
  $ret = readPluginData($plugin);  
  foreach ($ret[$plugin][0]['elements'] as $content=>$contentRoot) {
    $plc = xmlArray2Hash($contentRoot['elements']);     
    $msg .= "<tr><td>{$contentRoot['name']}</td><td>{$plc['name']}</td><td>{$plc['label']}</td></tr>";
  }  
  $msg .= '</table></center>';

  $msg .= <<<EODFooter
  <br /> 
<center>
    <a href="#" onclick="xajax_showPluginContent('$area', '', 0); return false;">Close</a>
</center>
EODFooter;


  // show the details
  $objResponse->addAssign($area, "innerHTML", $msg);
  $objResponse->addAssign($area, "style.display", "");
  // jump to top
  $objResponse->addScript("scroll(0,300);");

  
  return $objResponse->getXML(); 
}

/**
 * xajax - Show an alert / info message on in a specific DIV by enabling that div
 *
 * @param integer $type defined as constant. Can be GOOD or BAD
 * @param string $div ID of DIV element
 * @param string $msg content that is written to the innerHTML attribute
 * @return xajax getXML
 */
function setAlert($type, $msg, $div="alertInfo") {

  $objResponse = new xajaxResponse();
  
  switch ($type) {
    case GOOD:
      $style = "AlertGood";
    break;
    
    case BAD:
      $style = "AlertBad";
    break;
  }
  
  $objResponse->addAssign($div, "className", $style);
  $objResponse->addAssign($div, "style.display", "");
  $objResponse->addAssign($div, "innerHTML", $msg);
  
  return $objResponse->getXML(); 
}



/**
 * xajax - read plugin cache directory and plugin database for installed plugins and write elements to a table
 *
 * @param string $tableID ID to add rows for each plugin
 * @return xajax getXML
 * @todo put formatting in stylesheet
 */
function showPlugins($tableID) {

  global $cwlang, $asterisk;
  
  $objResponse = new xajaxResponse();


  // need a tbody element to get IE to work!
  $tableBodyID = $tableID."Body";
  $objResponse->addCreate($tableID, "tbody", $tableBodyID);
  
  // build the table rows
  // use unique id's for DOM elements. Very important for IE to work!
  $id = "";
  $prefixRow="dataPluginList-";

  // read the plugin information for each plugin
  // return arr[pluginpackage][0][xmlarray structure]. I.e. arr['wake_up-call.1.1.10][0]['label']='plugininfo'
  $plArr=readPluginInfo("");
  
  foreach ($plArr as $plugin=>$plRoot) {
    
    // convert the xmlarray structure to a simple hash with unique keys
    $pli = xmlArray2Hash($plRoot[0]['elements']);
        
    // create some vars to make the code easier readable    
    // use pluginPackage as id because non-activated plugins do not have a unique id
    $id = $plugin;

    $plName = $pli['name'];
    $plLabel = $pli['label'];
    $plVersion = $pli['version'];
    $plDate = $pli['date'];
    $plAuthorName = $pli['authorName'];
    $plDescription = $pli['description'];
    $plState = $pli['state'];
    $ret = readPluginArchiveURL($plugin);
    $plURL = $ret[$plugin];
    
    // Create new row. We use $plPackageName as part of the id for new DOM elements    
    $objResponse->addCreate($tableBodyID, "tr", $prefixRow.$id);
    $objResponse->addAssign($prefixRow.$id, "className", "firstofgroup rule");
    
    // here we create the td elements und send them via xajax to the browsers DOM tree.
    // this would allow modification of each entry if required at any time.
    
    // delete a plugin (show link via icon)
    $prefixData = "del-";
    $ldel = "<a href=\"#\" onclick=\"xajax_deletePlugin('" . $plugin . "'); return false;\">";
    $ldel = "<a href=\"#\" onclick=\"if (confirm('".T_("Are your sure to delete Plugin?")."')) {xajax_deletePlugin('" . $plugin . "'); return false;} else return false;\">";
    
    
    $ldel.= "<img src=\"/voiceone/admin/public/img/trash.gif\" alt=\"Delete\" />";
    $ldel.= "</a>";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $ldel);
    
    // content of plugin (show link via icon)
    $prefixData = "infoIcon-";
    $linfo = "<a href=\"#\" onclick=\"xajax_showPluginContent('pluginDetails', '" . $plugin . "', 1); return false;\">";
    $linfo .= "<img src=\"/voiceone/admin/public/img/idea.gif\" alt=\"Info\" />";
    $linfo .= "</a>";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);
    
    // download a plugin (show link via icon)
    $prefixData = "dl-";
    $ldl = "<a href=\"" . $plURL . "\">";
    $ldl .= "<img src=\"/voiceone/admin/public/img/download.gif\" alt=\"Info\" />";
    $ldl .= "</a>"; 
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $ldl);
  
    // Create Label as link to info of plugin
    $prefixData = "infoLabel-";
    $linfo = "<a href=\"#\" onclick=\"xajax_showPluginInfo('pluginDetails', '" . $plugin . "', 1); return false;\">";
    $linfo .= $plLabel;
    $linfo .= "</a>";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);

    // Version and date of plugin
    $linfo = '<SPAN STYLE="font-size: 100%; font-weight:bold; white-space:nowrap;">' . $plVersion . '</SPAN>' . '<br />';
    $linfo .= '<SPAN STYLE="font-size: 75%; font-weight:normal; white-space:nowrap;">' . $plDate . '</SPAN>';
    $prefixData = "version-";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);

    // AuthorName of plugin
    $prefixData = "authorName-";
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $plAuthorName);

    // Description of plugin
    $prefixData = "description-";
    $msg = '<SPAN STYLE="font-size: 80%; font-weight:normal;">';
    $msg .= $plDescription;
    $msg .= '</SPAN>';
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $msg);

    // Create Label as link to activate / deactivate a plugin
    $prefixData = "activate-";
    if ($plState == STATE_SELECTED) {
      // plugin is activ
      $linfo = "Activ<br />"; 
      $linfo .= "<a href=\"#\" onclick=\"xajax_deactivate('" . $plugin . "'); return false;\">";
      $linfo .= "Deactivate";
      $linfo .= "</a>";
      $className = "green";
    } else { 
      // plugin is inactiv
      $linfo = "Inactiv<br />"; 
      $linfo .= "<a href=\"#\" onclick=\"xajax_activate('" . $plugin . "'); return false;\">";
      $linfo .= "Activate";
      $linfo .= "</a>";
      $className = "red";
    }
  
    $objResponse->addCreate($prefixRow.$id, "td", $prefixData.$id);
    $objResponse->addAssign($prefixData.$id, "className", $className);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);
    
  }
  return $objResponse->getXML(); 
}



/**
 * xajax - Delete a plugin from cache and from database
 * 
 * @param string $pluginPackage
 * @return xajax getXML
 * @todo add "do you really want to delete..." and get returncodes from deactivation 
 */
function deletePlugin($plugin) {

  global $cwlang, $asterisk;

  $objResponse = new xajaxResponse();
  
  // deactivate the plugin first
  $ret = $asterisk->getPluginByPackageName($plugin);
  if (count($ret)) {
    // plugin is activated, so deactivate first
    $plId = $ret[0]['id'];
    $ret = $asterisk->delPlugin($plId);
  }
  
  
  // remove the cache and the archive
  if (deletePluginCache($plugin) > 0) {
    $msg = "<strong>" . T_("Plugin deleted successful") . "</strong>" . ": " . $plugin;
    $objResponse->loadXML(setAlert(GOOD, $msg, "alertInfo"));
    $objResponse->addRemove("dataPluginList-" . $plugin);
  } else {
    $msg = "<strong>" . T_("Plugin not deleted") . "</strong>" . ": " . $plugin;
    $objResponse->loadXML(setAlert(BAD, $msg, "alertInfo"));
  }
  
  return $objResponse->getXML(); 
}

/**
 * xajax - activate a plugin
 *
 * @param string $plugin 
 * @return xajax getXML
 * @todo implement errorhandling
 * @see deactivate
 */
function activate($plugin) {

  global $cwlang, $asterisk;
  
  $objResponse = new xajaxResponse();
  
  // check wether this plugin is already installed in a different version
  $ret = readPluginInfo($plugin);
  $pli = xmlArray2Hash($ret[$plugin][0]['elements']); 
  $ret = $asterisk->getPluginByName($pli['name']);
  if (count($ret)) {
    $msg = T_("Plugin is already installed in version").": ".$ret[0]['version'].". ".T_("Please deactivate first.");
    $objResponse->addAlert($msg);
    return $objResponse->getXML();
  }
  // read plugin info and plugin data
  $pi = readPluginInfoAsXML($plugin); 
  $pc = readPluginDataAsXML($plugin);
  // verify object extesnions
  $xmlArr=xml2array($pc);
  $ret=$asterisk->getExtension(0);
  if(is_array($ret)){
    foreach($ret as $e){
      $extArr[$e['entity_id']]=$e["extension"];
    }
  }
  if((is_array($xmlArr))&&(is_array($xmlArr[0]))){
    foreach($xmlArr[0] as $xml){
      if(is_array($xml)){
        foreach($xml as $objArr){
          if(is_array($objArr['elements'])){
            foreach($objArr['elements'] as $element){
              if($element['name']=='extension'){
                $extension=$element['text'];
                if(array_search($extension,$extArr)){
                  $msg = T_("An object in the plugin has in use extension")." (".$extension."). ".T_("Please free extension first.");
                  $objResponse->addAlert($msg);
                  return $objResponse->getXML();
                }
              }
            }
          }
        }
      }
    }
  }
  
  // allow to install new plugin or to reactivate an installed plugin in the same version
  $ret = $asterisk->putPlugin($pi, $pc);
 
  if ($ret > 0) {
    $msg = "<strong>" . T_("Plugin activated successful") . "</strong>" . ': ' . $plugin;  
    $objResponse->loadXML(setAlert(GOOD, $msg)); 
    // plugin is activ, change table
    $linfo = "Active<br />"; 
    $linfo .= "<a href=\"#\" onclick=\"xajax_deactivate('" . $plugin . "'); return false;\">";
    $linfo .= "Deactivate";
    $linfo .= "</a>";    
    $className = "green";     
    $prefixData = "activate-";
    $id = $plugin;
    $objResponse->addAssign($prefixData.$id, "className", $className);
    $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);    
  } else {
    $msg = "<strong>" . T_("Plugin not activated") . "</strong>" . ': ' . $plugin . '<br />';
    $msg .= T_("Contact the administrator. Ask to check the database, the plugin cache directory and the archive.");
    $objResponse->loadXML(setAlert(BAD, $msg));     
  }
      
  return $objResponse->getXML(); 
}


/**
 * xajax - deactivate a plugin
 *
 * @param string $plugin 
 * @return xajax getXML
 * @todo implement errorhandling
 * @see activate
 */
function deactivate($plugin) {

  global $cwlang, $asterisk;
  
  $objResponse = new xajaxResponse();
  
  $ret = $asterisk->getPluginByPackageName($plugin);
  if (!count($ret)) {
    // something went wrong. should not happen
    $msg = "<strong>" . T_("Error while deactiving Plugin") . ': ' . $plugin . "<br>" . T_("Please check your database.") . "</strong>";
    $objResponse->loadXML(setAlert(BAD, $msg));
    return $objResponse->getXML(); 
    
  }
  $plId = $ret[0]['id'];
  $ret = $asterisk->delPlugin($plId);
  if ($ret <= 0) {
    // something went wrong. should not happen
    $msg = "<strong>" . T_("Error while deactiving Plugin") . ': ' . $plugin . "<br>" . T_("Please check your database.") . "</strong>";
    $objResponse->loadXML(setAlert(BAD, $msg));
    return $objResponse->getXML(); 
    
  }
  
  $msg = "<strong>" . T_("Plugin deactivated successful") . "</strong>" . ': ' . $plugin;
  $objResponse->loadXML(setAlert(GOOD, $msg));
  
  // plugin is inactiv
  $linfo = "Inactive<br />"; 
  $linfo .= "<a href=\"#\" onclick=\"xajax_activate('" . $plugin . "'); return false;\">";
  $linfo .= "Activate";
  $linfo .= "</a>";
  $className = "red";
  $prefixData = "activate-";
  $id = $plugin;
  $objResponse->addAssign($prefixData.$id, "className", $className);
  $objResponse->addAssign($prefixData.$id, "innerHTML", $linfo);
  
  return $objResponse->getXML(); 
}




/**
 * xajax - Init the page. Initialize elements
 *
 * @return xajax getXML
 */
function initPage($startMsg) {

  $objResponse = new xajaxResponse();
  
  // we put the alert message in the alertInfo div and on a page reload we check wether to enable it
  if ($startMsg != "") $objResponse->addAssign('alertInfo', "style.display", "");
  
  $objResponse->addAssign('pluginDetails', "style.display", "none");

  // check preferences
  // check if "which", "zip" and "unzip" are installed
  $msg = "";
  $ret = shell_exec("which which");
  if ($ret == "") {$msg = T_("Missing cmd WHICH on the system.")."<br />";}
  $ret = shell_exec("which zip");
  if ($ret == "") {$msg .= T_("Missing cmd ZIP on the system.")."<br />";}
  $ret = shell_exec("which unzip");
  if ($ret == "") {$msg .= T_("Missing cmd UNZIP on the system.")."<br />";}
  
  if ($msg != "") {
    $msg = T_("Plugin creation will not work!")."<br />" . $msg;
    $objResponse->loadXML(setAlert(BAD, $msg, "alertInfo"));
  }
  
  $objResponse->loadXML(showPlugins('tablePluginList'));
  
  return $objResponse->getXML(); 
}

// ===================== xajax main functions end ===================================

$xajax = new xajax();
//$xajax->debugOn();
// test
$xajax->registerFunction("importPlugin");
$xajax->registerFunction("testxml2array");

// main
$xajax->registerFunction("showPluginInfo"); // show details about a plugin in a DIV
$xajax->registerFunction("showPluginContent"); // show Content about a plugin in a DIV
$xajax->registerFunction("showPlugins"); // list available plugins from cache and allow to manage
$xajax->registerFunction("setAlert"); // set Alert and Info Messages
$xajax->registerFunction("deletePlugin"); // delete a plugin from cache and from database if necessary
$xajax->registerFunction("activate"); // activate a plugin
$xajax->registerFunction("deactivate"); // deactivate a plugin
$xajax->registerFunction("initPage"); // init the page




$xajax->processRequests();
  
// *********************************** xajax functions end ***********************************
   
   //================ PAGE LOGIC ================
   // get alert msg as stored in session var whith result of upload
   $alert=getAlert();
  //upload a plugin. Need to use regular POST because javascript (and therefore xajax) has no access to local filesystem
  if ($_POST["act"]=="upload") {
    $ftmp = $_FILES['filename']['tmp_name'];
    $fname = $_FILES['filename']['name'];
    $ret = array();
    //Basic test wether the file is a plugin. "application/zip" would be MIME confirm but is not always used ;-(
    $validTypes = array("application/zip", "application/x-zip", "application/x-compressed", "application/x-zip-compressed");
    foreach ($validTypes as $vt) {
      if ($_FILES["filename"]["type"] == $vt) {
        // use a temp name that wont exists as a real pluginfile
        $myfile = "newUploadedVOPlugin.zip";
        if (move_uploaded_file($ftmp, $absPluginPath.$myfile)) {
          // unpack and validate the package archive
          $ret = createPluginCachefromArchive($myfile);
          break;
        }
      }
    }
    // handle the result of createPluginCachefromArchive($myfile)
    if($ret['state']===true) $alert = "<div class=\"AlertGood\">" . $ret['msg'] . "</div>";
    else $alert = "<div class=\"AlertBad\">" . $ret['msg'] . "</div>";
    // Store $alert in _SESSION['alert'] to have it available after rebuilding the page and execute    
    goToMainPage($alert,"./");
  } // post upload
    
  //================ MAIN CONTENTS ================
  ob_start();
  $xajax->printJavascript("../../../admin/lib/xajax/");
  ?>
    <?$sel="plugin";include("../../tool/navigation.php");?>
    
    <!-- add javascript xajax helper functions -->
    <script type="text/javascript" src="../../../admin/lib/xajaxextend/xajaxextend.js"></script>
  
    <!-- show AlertGood or AlertBad type messages via xajax. Default is not-visible -->
    <!-- add $alert as returned with a message when doing an upload -->
    <div id="alertInfo" style="display: none"><?=$alert?></div>
    
    <div class="SectionHeader">
      <h1><?=T_("Manage Plugins")?></h1>
      <h3>
        <a href="../create" class="admin" ><?=T_("Create Plugin")?></a>
      </h3>
    </div>
  
    <div id="basic_form">
      <!-- form import upload a plugin -->
      <form name="uploadPlugin" id="uploadPlugin" enctype="multipart/form-data" action="<?=$PHP_SELF?>" method="post">
        <h2><?=T_("Import a plugin")?></h2>
          <div class="block">
          <table>
            <tr>
              <td><input type="file" name="filename" size="60" />&nbsp;<input type="submit" value="Send" size="10"/></td>
            </tr>  
          </table>
        </div>
        <input type="hidden" name="act" value="upload" />
      </form>
      <!-- show plugin status -->
      <h2><?=T_("Plugins status")?></h2>
      <!-- show plugin details on request. Default is not visible-->
      <div id="pluginDetails" class="AlertGood" style="display: none"></div>
      <div>
        <table id="tablePluginList" cellspacing="0" class="todolist">
          <!-- tbody tag is essential to get IE to work! when adding TR elements. Created via xajax so not here -->
            <tr id="headerPluginList">
              <th colspan="3"><?=T_("Action")?></th>
              <th><?=T_("Name")?></th>
              <th><?=T_("Version")?></th>
              <th><?=T_("Author")?></th>
              <th><?=T_("Description")?></th>
              <th><?=T_("State")?></th>
            </tr>
        </table>
      </div>
    </div>
  <?
  $contents=ob_get_contents();
  ob_end_clean();
  
  //================ SIDEBAR ================
  ob_start(); 
  ?>
    <div class="Sidebar">
      <h1><?=T_("Informations")?></h1>
      <p><?=T_("This page shows the plugins configured on the system. A plugin is a set of applications and macros that is possible to upload, export, activate and deactivate. In this page you can upload a plugin or manage the already uploaded ones. To create and export a plugin follow the link under the section title.")?></p>    
      <p><img src="<?=$relBasePath?>/public/img/package_add.gif" />
        <a href="http://www.voiceone.it/download/plugin/" target="_blank" ><?=T_("Search in our public repository")?></a>
        <?=T_("the already made plugins.")?>
      </p>
    </div>
  <?  
  $sidebar=ob_get_contents();
  ob_end_clean();
  
  //================ SETTINGS ================
  $smarty->assign("section", "application");
  $smarty->assign("subsection", "");
  $smarty->assign("templateType", "TwoColLeft");  //OneCol, TwoColLeft, TwoColRight
  $smarty->assign("contents", $contents);
  $smarty->assign("sidebar", $sidebar);
  $smarty->display('settings.tpl');
?>

  <!--  Init Page via xajax call -->
  <script>xajax_initPage('<?=$alert?>')</script>

