Menu="Share:1"
Title="Share Settings"
Tag="share-alt-square"
---
<?PHP
/* Copyright 2005-2021, Lime Technology
 * Copyright 2012-2021, Bergware International.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2,
 * as published by the Free Software Foundation.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 */
?>
<?
$width = [123,300];

if ($name == "") {
  /* default values when adding new share */
  $share = ["nameOrig"   => "",
            "name"       => "",
            "comment"    => "",
            "allocator"  => "highwater",
            "floor"      => "",
            "splitLevel" => "",
            "include"    => "",
            "exclude"    => "",
            "useCache"   => "no",
            "cachePool"  => "cache",
            "cow"        => "auto"];
} elseif (array_key_exists($name, $shares)) {
  /* edit existing share */
  $share = $shares[$name];
} else {
  /* handle share deleted case */
  echo "<p class='notice'>"._('Share')." '".htmlspecialchars($name)."' "._('has been deleted').".</p><input type='button' value=\""._('Done')."\" onclick='done()'>";
  return;
}

/* check for empty share */
function shareEmpty($name) {
  return (($files = @scandir("/mnt/user/$name")) && (count($files) <= 2));
}

function globalInclude($name) {
  global $var;
  return substr($name,0,4)=='disk' && (!$var['shareUserInclude'] || strpos("{$var['shareUserInclude']},","$name,")!==false);
}

// global shares include/exclude
$myDisks = array_filter(array_diff(array_keys(array_filter($disks,'my_disks')), explode(',',$var['shareUserExclude'])), 'globalInclude');
?>
:share_edit_global1_help:
<?if ($name):?>
:share_edit_global2_help:
<?endif;?>

<div id="" class="clone1">
<span class="clone">_(Read settings from)_</span><i class="fa fa-arrow-left fa-fw"></i>
<span class="wrap"><select name="readshare" class="clone" onchange="toggleButton('readshare',false)">
<option disabled selected>_(select)_...</option>
<?
foreach ($shares as $list) if ($list['name']!=$name || !$name) echo mk_option("", $list['name'], compress($list['name']));
?>
</select></span><input type="button" id="readshare" value="_(Read)_" class="clone" onclick="readShare()" disabled>
</div>
<?if ($name):?>
<div id="" class="clone2">
<span class="clone">_(Write settings to)_</span><i class="fa fa-arrow-right fa-fw"></i>
<span class="wrap"><select id="s3" name="writeshare" multiple="multiple" style="display:none" onchange="toggleButton('writeshare',this.id)">
<?
$rows = [];
foreach ($shares as $list) if ($list['name']!=$name) $rows[] = mk_option("", $list['name'], compress($list['name']));
if ($rows) echo "<option>("._('All').")</option>";
foreach ($rows as $row) echo $row;
?>
</select></span><input type="button" id="writeshare" value="_(Write)_" class="clone" onclick="writeShare()" disabled>
</div>
<?endif;?>

<form markdown="1" name="share_edit" method="POST" action="/update.htm" target="progressFrame" onsubmit="return prepareEdit(this)"<?=$name?" onchange=\"toggleButton('writeshare',true);$('#s3').dropdownchecklist('disable')\">":">"?>
<input type="hidden" name="shareNameOrig" value="<?=htmlspecialchars($share['nameOrig'])?>">

_(Share name)_:
: <input type="text" name="shareName" maxlength="40" value="<?=htmlspecialchars($name)?>">

:share_edit_name_help:

_(Comments)_:
: <input type="text" name="shareComment" maxlength="256" value="<?=htmlspecialchars($share['comment'])?>">

:share_edit_comments_help:

_(Use cache pool (for new files/directories))_:
: <span class="input"><select name="shareUseCache" onchange="updateScreen(this.value)"<?=$pool_devices?'':' disabled'?>>
  <?=mk_option($share['useCache'], "no", _('No'))?>
  <?=mk_option($share['useCache'], "yes", _('Yes'))?>
  <?=mk_option($share['useCache'], "prefer", _('Prefer'))?>
  <?=mk_option($share['useCache'], "only", _('Only'))?>
  </select></span><span id="moverAction"></span>

:share_edit_cache_pool_help:

_(Select cache pool)_:
: <select name="shareCachePool">
  <?foreach ($pools as $pool):?>
<?if ($disks[$pool]['devices']) echo mk_option($share['cachePool'],$pool,ucfirst($pool),$disks[$pool]['shareEnabled']=='yes'?"":"disabled")?>
  <?endforeach;?>
  </select>

_(Enable Copy-on-write)_:
: <span class="input"><select name="shareCOW"<?if ($name):?> disabled<?endif;?>>
  <?=mk_option($share['cow'], "no", _('No'))?>
  <?=mk_option($share['cow'], "auto", _('Auto'))?>
  </select></span><?if ($name):?>_(Set when adding new share only)_<?endif;?>

:share_edit_copy_on_write_help:

_(Allocation method)_:
: <select name="shareAllocator">
  <?=mk_option($share['allocator'], "highwater", _('High-water'))?>
  <?=mk_option($share['allocator'], "fillup", _('Fill-up'))?>
  <?=mk_option($share['allocator'], "mostfree", _('Most-free'))?>
  </select>

:share_edit_allocation_method_help:

_(Minimum free space)_:
: <input type="text" name="shareFloor" maxlength="16" class="narrow" value="<?=htmlspecialchars($share['floor'])?>">

:share_edit_free_space_help:

_(Split level)_:
: <select name="shareSplitLevel">
  <?=mk_option($share['splitLevel'], "", _('Automatically split any directory as required'))?>
  <?=mk_option($share['splitLevel'], "1", _('Automatically split only the top level directory as required'))?>
  <?=mk_option($share['splitLevel'], "2", _('Automatically split only the top two directory levels as required'))?>
  <?=mk_option($share['splitLevel'], "3", _('Automatically split only the top three directory levels as required'))?>
  <?=mk_option($share['splitLevel'], "4", _('Automatically split only the top four directory levels as required'))?>
  <?=mk_option($share['splitLevel'], "5", _('Automatically split only the top five directory levels as required'))?>
  <?=mk_option($share['splitLevel'], "0", _('Manual: do not automatically split directories'))?>
  </select>

:share_edit_split_level_help:

_(Included disk(s))_:
: <select id="s1" name="shareInclude" multiple="multiple" style="display:none">
  <?foreach ($myDisks as $disk):?>
  <?=mk_option_luks($disk, $share['include'], strstr($disks[$disk]['fsType'],':',true))?>
  <?endforeach;?>
  </select>

:share_edit_included_disks_help:

_(Excluded disk(s))_:
: <select id="s2" name="shareExclude" multiple="multiple" style="display:none">
  <?foreach ($myDisks as $disk):?>
  <?=mk_option_luks($disk, $share['exclude'], strstr($disks[$disk]['fsType'],':',true))?>
  <?endforeach;?>
  </select>

:share_edit_excluded_disks_help:

<?if (!$name):?>
&nbsp;
: <input type="submit" name="cmdEditShare" value="_(Add Share)_" onclick="this.value='Add Share'"><input type="button" value="_(Done)_" onclick="done()">
<?elseif (shareEmpty($name)):?>
_(Share status)_:
: _(Share is empty)_

:share_edit_status_help:

_(Delete)_<input type="checkbox" name="confirmDelete" onchange="chkDelete(this.form, this.form.cmdEditShare);">
: <input type="submit" name="cmdEditShare" value="_(Apply)_" onclick="if (this.value=='_(Delete)_') this.value='Delete'; else this.value='Apply'" disabled><input type="button" value="_(Done)_" onclick="done()">
<?else:?>
_(Share status)_:
: _(Share contains data)_

:share_edit_delete_help:

&nbsp;
: <input type="submit" name="cmdEditShare" value="_(Apply)_" onclick="this.value='Apply'" disabled><input type="button" value="_(Done)_" onclick="done()">
<?endif;?>
</form>
<script>
$(function() {
  initDropdown(false,true);
<?if ($tabbed):?>
  $('#tab1').bind({click:function(){initDropdown(true,true);}});
<?endif;?>
  updateScreen(document.share_edit.shareUseCache.value);
  presetSpace(document.share_edit.shareFloor);
});
function initDropdown(remove,create) {
  if (remove) {
    $('#s1').dropdownchecklist('destroy');
    $('#s2').dropdownchecklist('destroy');
<?if ($name):?>
    $('#s3').dropdownchecklist('destroy');
<?endif;?>
  }
  if (create) {
    $('#s1').dropdownchecklist({emptyText:"_(All)_", width:<?=$width[1]?>, explicitClose:"..._(close)_"});
    $('#s2').dropdownchecklist({emptyText:"_(None)_", width:<?=$width[1]?>, explicitClose:"..._(close)_"});
<?if ($name):?>
    $("#s3").dropdownchecklist({firstItemChecksAll:true, emptyText:"_(select)_...", width:<?=$width[0]?>, explicitClose:"..._(close)_"});
<?endif;?>
  }
}
function updateScreen(cache) {
  switch (cache) {
  case 'yes':
    var textAction = "_(Mover transfers files from cache to array)_";
    break;
  case 'prefer':
    var textAction = "_(Mover transfers files from array to cache)_";
    break;
  default:
    var textAction = "_(Mover takes no action)_";
    break;
  }
  document.getElementById('moverAction').innerHTML = textAction;
  switch (cache) {
  case 'no':
    document.share_edit.shareCOW.disabled = true;
    document.share_edit.shareCachePool.disabled = true;
    document.share_edit.shareAllocator.disabled = false;
    document.share_edit.shareFloor.disabled = false;
    document.share_edit.shareSplitLevel.disabled = false;
    $('#s1').dropdownchecklist('enable');
    $('#s2').dropdownchecklist('enable');
    break;
  case 'only':
    document.share_edit.shareCOW.disabled = false;
    document.share_edit.shareCachePool.disabled = false;
    document.share_edit.shareAllocator.disabled = true;
    document.share_edit.shareFloor.disabled = true;
    document.share_edit.shareSplitLevel.disabled = true;
    $('#s1').dropdownchecklist('disable');
    $('#s2').dropdownchecklist('disable');
    break;
  default:
    document.share_edit.shareCOW.disabled = false;
    document.share_edit.shareCachePool.disabled = false;
    document.share_edit.shareAllocator.disabled = false;
    document.share_edit.shareFloor.disabled = false;
    document.share_edit.shareSplitLevel.disabled = false;
    $('#s1').dropdownchecklist('enable');
    $('#s2').dropdownchecklist('enable');
    break;
  }
}
function presetSpace(shareFloor) {
  var unit = ['KB','MB','GB','TB','PB'];
  var scale = shareFloor.value;
  if (scale.replace(/[0-9.,\s]/g,'').length>0) return;
  var base = scale>0 ? Math.floor(Math.log(scale)/Math.log(1000)):0;
  if (base>=unit.length) base = unit.length-1;
  shareFloor.value = (scale/Math.pow(1000, base))+unit[base];
}
// Compose input fields
function prepareEdit(form) {
// Test share name validity
  var share = form.shareName.value.trim();
  if (share.length==0) {
    swal({title:"_(Missing share name)_",text:"_(Enter a name for the share)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
    return false;
  }
  var reserved = [<?=implode(',',array_map('escapestring',explode(',',$var['reservedNames'])))?>];
  if (reserved.includes(share)) {
    swal({title:"_(Invalid share name)_",text:"_(Do not use reserved names)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
    return false;
  }
  var pools = [<?=implode(',',array_map('escapestring',$pools))?>];
  if (pools.includes(share)) {
    swal({title:"_(Invalid share name)_",text:"_(Do not use pool names)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
    return false;
  }
  if (share.match('[:\\\/*<>|"?]')) {
    swal({title:"_(Invalid Characters)_",text:"_(You cannot use the following within share names)_"+' : \\ / * < > | " ?',type:'error',html:true,confirmButtonText:"_(Ok)_"});
    return false;
  }
  form.shareName.value = share;
// Adjust minimum free space value to selected unit
  var unit = 'KB,MB,GB,TB,PB';
  var scale = form.shareFloor.value;
  var index = unit.indexOf(scale.replace(/[0-9.,\s]/g,'').toUpperCase());
  form.shareFloor.value = scale.replace(/[A-Z\s]/gi,'') * Math.pow(1000, (index>0 ? index/3 : 0))
// Return include as single line input
  var include = '';
  for (var i=0,item; item=form.shareInclude.options[i]; i++) {
    if (item.selected) {
      if (include.length) include += ',';
      include += item.value;
      item.selected = false;
    }
  }
  item = form.shareInclude.options[0];
  item.value = include;
  item.selected = true;
// Return exclude as single line input
  var exclude = '';
  for (var i=0,item; item=form.shareExclude.options[i]; i++) {
    if (item.selected) {
      if (exclude.length) exclude += ',';
      exclude += item.value;
      item.selected = false;
    }
  }
  item = form.shareExclude.options[0];
  item.value = exclude;
  item.selected = true;
  return true;
}
function readShare() {
  var form = document.share_edit;
  var name = $('select[name="readshare"]').val();
  initDropdown(true,false);
  $.get('/webGui/include/ShareData.php',{name:name},function(json) {
    var data = $.parseJSON(json);
    form.shareAllocator.value = data.allocator;
    form.shareFloor.value = data.floor;
    form.shareSplitLevel.value = data.splitLevel;
    form.shareInclude.value = data.include;
    form.shareExclude.value = data.exclude;
    form.shareUseCache.value = data.useCache;
    form.shareCOW.value = data.cow;
    for (var i=0,disk; disk=data.include.split(',')[i]; i++) for (var j=0,include; include=form.shareInclude.options[j]; j++) if (include.value==disk) include.selected=true;
    for (var i=0,disk; disk=data.exclude.split(',')[i]; i++) for (var j=0,exclude; exclude=form.shareExclude.options[j]; j++) if (exclude.value==disk) exclude.selected=true;
    initDropdown(false,true);
  });
  $(form).find('select').trigger('change');
}
function writeShare(data,n,i) {
  if (data) {
    if (n<i) {
      $.post('/update.htm',data[n], function(){setTimeout(function(){writeShare(data,++n,i);},3000);});
    } else {
      toggleButton('writeshare',false);
      $('div.spinner.fixed').hide();
    }
  } else {
    var data = [], i = 0;
    $('select#s3 option').map(function() {
      if ($(this).prop('selected')==true && $(this).val()!='(All)') {
        data[i] = {};
        data[i]['shareName'] = $(this).val();
        data[i]['shareNameOrig'] = $(this).val();
        data[i]['shareAllocator'] = '<?=addslashes(htmlspecialchars($share['allocator']))?>';
        data[i]['shareFloor'] = '<?=addslashes(htmlspecialchars($share['floor']))?>';
        data[i]['shareSplitLevel'] = '<?=addslashes(htmlspecialchars($share['splitLevel']))?>';
        data[i]['shareInclude'] = '<?=addslashes(htmlspecialchars($share['include']))?>';
        data[i]['shareExclude'] = '<?=addslashes(htmlspecialchars($share['exclude']))?>';
        data[i]['shareUseCache'] = '<?=addslashes(htmlspecialchars($share['useCache']))?>';
        data[i]['cmdEditShare'] = 'Apply';
        i++;
      }
    });
    toggleButton('writeshare',true);
    $('div.spinner.fixed').show('slow');
    writeShare(data,0,i);
  }
}
</script>
