<commit_before><?php

// Editor component for company records
$editor = new Editor(translate('Collection'), 'collection');
param_to_global('id', 'int', 'old_id', 'collection_id' );
param_to_global('user_no', 'int' );
param_to_global('principal_id', 'int' );
param_to_global('collection_name', '{^.+$}' );
if ( isset($user_no) ) $usr = getUserByID($user_no);
if ( isset($principal_id) ) $usr = getPrincipalByID($principal_id);
$editor->SetLookup( 'timezone', 'SELECT \'\', \'*** Unknown ***\' UNION SELECT tz_id, tz_locn FROM time_zone WHERE tz_id = tz_locn AND length(tz_spec) > 100 ORDER BY 1' );
$editor->SetLookup( 'schedule_transp', 'SELECT \'opaque\', \'Opaque\' UNION SELECT \'transp\', \'Transparent\'' );


$editor->AddAttribute('timezone', 'id', 'fld_timezone' );
$editor->AddAttribute('schedule_transp', 'id', 'fld_schedule_transp' );
$editor->AddAttribute('is_calendar', 'id', 'fld_is_calendar');
$editor->AddAttribute('is_addressbook', 'id', 'fld_is_addressbook');
$editor->AddAttribute('is_calendar', 'onclick', 'toggle_enabled(\'fld_is_calendar\',\'=fld_timezone\',\'=fld_schedule_transp\',\'!fld_is_addressbook\',\'=fld_ics_file\');');
$editor->AddAttribute('is_addressbook', 'onclick', 'toggle_enabled(\'fld_is_addressbook\',\'!fld_is_calendar\');');

$editor->AddField('use_default_privs','default_privileges IS NULL');
$editor->AddAttribute('use_default_privs', 'id', 'fld_use_default_privs');
$editor->AddAttribute('use_default_privs', 'onclick', 'toggle_visible(\'fld_use_default_privs\',\'!privileges_settings\');');

$editor->AddField('ics_file', "''");
$editor->AddAttribute('ics_file', 'title', translate('Upload a .ics calendar in iCalendar format to initialise or replace this calendar.'));
$editor->AddAttribute('ics_file', 'id', 'fld_ics_file');

$editor->SetWhere( 'collection_id='.$id );

$privilege_names = array( 'read', 'write-properties', 'write-content', 'unlock', 'read-acl', 'read-current-user-privilege-set',
                         'bind', 'unbind', 'write-acl', 'read-free-busy', 'schedule-deliver-invite', 'schedule-deliver-reply',
                         'schedule-query-freebusy', 'schedule-send-invite', 'schedule-send-reply', 'schedule-send-freebusy' );

$params = array(
  ':session_principal' => $session->principal_id,
  ':scan_depth'        => $c->permission_scan_depth
);
$is_update = ( $_POST['_editor_action'][$editor->Id] == 'update' );
if ( isset($collection_name) ) $collection_name = trim(str_replace( '/', '', $collection_name));
if ( !$is_update && isset($collection_name) && $collection_name != '' && is_object($usr) ) {
  $_POST['dav_name'] = sprintf('/%s/%s/', $usr->username, $collection_name );
  $_POST['parent_container'] = sprintf('/%s/', $usr->username );
  $params[':collection_path'] = $_POST['dav_name'];
  $privsql = 'SELECT path_privs( :session_principal, :collection_path, :scan_depth) AS priv';
}
else if ( $id > 0 ) {
  $params[':collection_id'] = $id;
  $privsql = 'SELECT path_privs( :session_principal, dav_name, :scan_depth) AS priv FROM collection WHERE collection_id = :collection_id';
}
else {
  if ( $editor->IsSubmit() && !$is_update && isset($collection_name) && $collection_name == '' ) {
    $c->messages[] =  i18n('The collection name may not be blank.');
  }
}

if ( isset($privsql) ) {
  $privqry = new AwlQuery( $privsql, $params );
  $privqry->Exec('admin-collection-edit',__LINE__,__FILE__);
  $permissions = $privqry->Fetch();
  $can_write_collection = ($session->AllowedTo('Admin') || (bindec($permissions->priv) & privilege_to_bits('DAV::bind')) );
}

dbg_error_log('collection-edit', "Can write collection: %s", ($can_write_collection? 'yes' : 'no') );

$pwstars = '@@@@@@@@@@';
if ( $can_write_collection && $editor->IsSubmit() ) {
  $editor->WhereNewRecord( "collection_id=(SELECT CURRVAL('dav_id_seq'))" );
  if ( $_POST['use_default_privs'] == 'on' ) {
    $_POST['default_privileges'] = '';
  }
  else if ( isset($_POST['default_privileges']) ) {
    $privilege_bitpos = array_flip($privilege_names);
    $priv_names = array_keys($_POST['default_privileges']);
    $privs = privilege_to_bits($priv_names);
    $_POST['default_privileges'] = sprintf('%024s',decbin($privs));
    $editor->Assign('default_privileges', $privs_dec);
  }
  $is_update = ( $_POST['_editor_action'][$editor->Id] == 'update' );
  if ( $_POST['timezone'] == '' ) unset($_POST['timezone']);
  $resourcetypes = '<DAV::collection/>';
  if ( isset($_POST['is_calendar'])    && $_POST['is_calendar'] == 'on' )    $resourcetypes .= '<urn:ietf:params:xml:ns:caldav:calendar/>';
  if ( isset($_POST['is_addressbook']) && $_POST['is_addressbook'] == 'on' ) $resourcetypes .= '<urn:ietf:params:xml:ns:carddav:addressbook/>';
  $_POST['resourcetypes'] = $resourcetypes;
  if ( $editor->IsCreate() ) {
    $c->messages[] = i18n("Creating new Collection.");
  }
  else {
    $c->messages[] = i18n("Updating Collection record.");
  }
  $editor->Write();
  if ( isset($_FILES['ics_file']['tmp_name']) && $_FILES['ics_file']['tmp_name'] != '' ) {
    /**
    * If the user has uploaded a .ics file as a calendar, we fake this out
    * as if it were a "PUT" request against a collection.  This is something
    * of a hack.  It works though :-)
    */
    $ics = trim(file_get_contents($_FILES['ics_file']['tmp_name']));
    dbg_error_log('collection-edit',':Write: Loaded %d bytes from %s', strlen($ics), $_FILES['ics_file']['tmp_name'] );
    include_once('check_UTF8.php');
    if ( !check_string($ics) ) $ics = force_utf8($ics);

    if ( check_string($ics) ) {
      $path = $editor->Value('dav_name');
      $user_no = $editor->Value('user_no');
      $username = $editor->Value('username');
      include_once('caldav-PUT-functions.php');
      controlRequestContainer( $username, $user_no, $path, false, ($publicly_readable == 'on' ? true : false));
      import_collection( $ics, $user_no, $path, $session->user_no );
      $c->messages[] = sprintf(translate('Calendar "%s" was loaded from file.'), $path);
    }
    else {
      $c->messages[] =  i18n('The file is not UTF-8 encoded, please check the error for more details.');
    }
  }
}
else {
  $editor->GetRecord();
  if ( $editor->IsSubmit() ) {
    $c->messages[] = i18n('You do not have permission to modify this record.');
  }
}
if ( $editor->Available() ) {
  $c->page_title = $editor->Title(translate('Collection').': '.$editor->Value('dav_displayname'));
  $entryqry = new AwlQuery( 'SELECT count(*) as count from caldav_data where collection_id='.$editor->Value('collection_id')  );
  $entryqry->Exec('admin-collection-edit');
  $entries = $entryqry->Fetch();  $entries = $entries->count;
}
else {
  $c->page_title = $editor->Title(translate('Create New Collection'));
  $privs = decbin(privilege_to_bits($c->default_privileges));
  $editor->Assign('default_privileges', $privs);
  $editor->Assign('username', $usr->username);
  $editor->Assign('user_no', $usr->user_no);
  $editor->Assign('is_calendar', 't' );
  $editor->Assign('use_default_privs', 't');
  $entries = 0;
}


$privilege_xlate = array(
  'read' => translate('Read'),
  'write-properties' => translate('Write Metadata'),
  'write-content' => translate('Write Data'),
  'unlock' => translate('Override a Lock'),
  'read-acl' => translate('Read Access Controls'),
  'read-current-user-privilege-set' => translate('Read Current User\'s Access'),<commit_msg>[collection-edit] Handle duplicate key error properly. Avoid SQL error on new.<commit_after><?php

// Editor component for company records
$editor = new Editor(translate('Collection'), 'collection');
param_to_global('id', 'int', 'old_id', 'collection_id' );
param_to_global('user_no', 'int' );
param_to_global('principal_id', 'int' );
param_to_global('collection_name', '{^.+$}' );
if ( isset($user_no) ) $usr = getUserByID($user_no);
if ( isset($principal_id) ) $usr = getPrincipalByID($principal_id);
$editor->SetLookup( 'timezone', 'SELECT \'\', \'*** Unknown ***\' UNION SELECT tz_id, tz_locn FROM time_zone WHERE tz_id = tz_locn AND length(tz_spec) > 100 ORDER BY 1' );
$editor->SetLookup( 'schedule_transp', 'SELECT \'opaque\', \'Opaque\' UNION SELECT \'transp\', \'Transparent\'' );


$editor->AddAttribute('timezone', 'id', 'fld_timezone' );
$editor->AddAttribute('schedule_transp', 'id', 'fld_schedule_transp' );
$editor->AddAttribute('is_calendar', 'id', 'fld_is_calendar');
$editor->AddAttribute('is_addressbook', 'id', 'fld_is_addressbook');
$editor->AddAttribute('is_calendar', 'onclick', 'toggle_enabled(\'fld_is_calendar\',\'=fld_timezone\',\'=fld_schedule_transp\',\'!fld_is_addressbook\',\'=fld_ics_file\');');
$editor->AddAttribute('is_addressbook', 'onclick', 'toggle_enabled(\'fld_is_addressbook\',\'!fld_is_calendar\');');

$editor->AddField('use_default_privs','default_privileges IS NULL');
$editor->AddAttribute('use_default_privs', 'id', 'fld_use_default_privs');
$editor->AddAttribute('use_default_privs', 'onclick', 'toggle_visible(\'fld_use_default_privs\',\'!privileges_settings\');');

$editor->AddField('ics_file', "''");
$editor->AddAttribute('ics_file', 'title', translate('Upload a .ics calendar in iCalendar format to initialise or replace this calendar.'));
$editor->AddAttribute('ics_file', 'id', 'fld_ics_file');

$editor->SetWhere( 'collection_id='.$id );

$privilege_names = array( 'read', 'write-properties', 'write-content', 'unlock', 'read-acl', 'read-current-user-privilege-set',
                         'bind', 'unbind', 'write-acl', 'read-free-busy', 'schedule-deliver-invite', 'schedule-deliver-reply',
                         'schedule-query-freebusy', 'schedule-send-invite', 'schedule-send-reply', 'schedule-send-freebusy' );

$params = array(
  ':session_principal' => $session->principal_id,
  ':scan_depth'        => $c->permission_scan_depth
);
$is_update = ( $_POST['_editor_action'][$editor->Id] == 'update' );
if ( isset($collection_name) ) $collection_name = trim(str_replace( '/', '', $collection_name));
if ( !$is_update && isset($collection_name) && $collection_name != '' && is_object($usr) ) {
  $_POST['dav_name'] = sprintf('/%s/%s/', $usr->username, $collection_name );
  $_POST['parent_container'] = sprintf('/%s/', $usr->username );
  $params[':collection_path'] = $_POST['dav_name'];
  $privsql = 'SELECT path_privs( :session_principal, :collection_path, :scan_depth) AS priv';
}
else if ( $id > 0 ) {
  $params[':collection_id'] = $id;
  $privsql = 'SELECT path_privs( :session_principal, dav_name, :scan_depth) AS priv FROM collection WHERE collection_id = :collection_id';
}
else {
  if ( $editor->IsSubmit() && !$is_update && isset($collection_name) && $collection_name == '' ) {
    $c->messages[] =  i18n('The collection name may not be blank.');
  }
}

if ( isset($privsql) ) {
  $privqry = new AwlQuery( $privsql, $params );
  $privqry->Exec('admin-collection-edit',__LINE__,__FILE__);
  $permissions = $privqry->Fetch();
  $can_write_collection = ($session->AllowedTo('Admin') || (bindec($permissions->priv) & privilege_to_bits('DAV::bind')) );
}

dbg_error_log('collection-edit', "Can write collection: %s", ($can_write_collection? 'yes' : 'no') );

$pwstars = '@@@@@@@@@@';
if ( $can_write_collection && $editor->IsSubmit() ) {
  $editor->WhereNewRecord( "collection_id=(SELECT CURRVAL('dav_id_seq'))" );
  if ( $_POST['use_default_privs'] == 'on' ) {
    $_POST['default_privileges'] = '';
  }
  else if ( isset($_POST['default_privileges']) ) {
    $privilege_bitpos = array_flip($privilege_names);
    $priv_names = array_keys($_POST['default_privileges']);
    $privs = privilege_to_bits($priv_names);
    $_POST['default_privileges'] = sprintf('%024s',decbin($privs));
    $editor->Assign('default_privileges', $privs_dec);
  }
  $is_update = ( $_POST['_editor_action'][$editor->Id] == 'update' );
  if ( $_POST['timezone'] == '' ) unset($_POST['timezone']);
  $resourcetypes = '<DAV::collection/>';
  if ( isset($_POST['is_calendar'])    && $_POST['is_calendar'] == 'on' )    $resourcetypes .= '<urn:ietf:params:xml:ns:caldav:calendar/>';
  if ( isset($_POST['is_addressbook']) && $_POST['is_addressbook'] == 'on' ) $resourcetypes .= '<urn:ietf:params:xml:ns:carddav:addressbook/>';
  $_POST['resourcetypes'] = $resourcetypes;
  if ( $editor->IsCreate() ) {
    $c->messages[] = i18n("Creating new Collection.");
  }
  else {
    $c->messages[] = i18n("Updating Collection record.");
  }
  if ( !$editor->Write() ) { 
    $c->messages[] = i18n("Failed to write collection.");
    if ( $id > 0 ) $editor->GetRecord();
  }
  else if ( isset($_FILES['ics_file']['tmp_name']) && $_FILES['ics_file']['tmp_name'] != '' ) {
    /**
    * If the user has uploaded a .ics file as a calendar, we fake this out
    * as if it were a "PUT" request against a collection.  This is something
    * of a hack.  It works though :-)
    */
    $ics = trim(file_get_contents($_FILES['ics_file']['tmp_name']));
    dbg_error_log('collection-edit',':Write: Loaded %d bytes from %s', strlen($ics), $_FILES['ics_file']['tmp_name'] );
    include_once('check_UTF8.php');
    if ( !check_string($ics) ) $ics = force_utf8($ics);

    if ( check_string($ics) ) {
      $path = $editor->Value('dav_name');
      $user_no = $editor->Value('user_no');
      $username = $editor->Value('username');
      include_once('caldav-PUT-functions.php');
      controlRequestContainer( $username, $user_no, $path, false, ($publicly_readable == 'on' ? true : false));
      import_collection( $ics, $user_no, $path, $session->user_no );
      $c->messages[] = sprintf(translate('Calendar "%s" was loaded from file.'), $path);
    }
    else {
      $c->messages[] =  i18n('The file is not UTF-8 encoded, please check the error for more details.');
    }
  }
}
else {
  if ( $id > 0 ) $editor->GetRecord();
  if ( $editor->IsSubmit() ) {
    $c->messages[] = i18n('You do not have permission to modify this record.');
  }
}
if ( $editor->Available() ) {
  $c->page_title = $editor->Title(translate('Collection').': '.$editor->Value('dav_displayname'));
  $entryqry = new AwlQuery( 'SELECT count(*) as count from caldav_data where collection_id='.$editor->Value('collection_id')  );
  $entryqry->Exec('admin-collection-edit');
  $entries = $entryqry->Fetch();  $entries = $entries->count;
}
else {
  $c->page_title = $editor->Title(translate('Create New Collection'));
  $privs = decbin(privilege_to_bits($c->default_privileges));
  $editor->Assign('default_privileges', $privs);
  $editor->Assign('username', $usr->username);
  $editor->Assign('user_no', $usr->user_no);
  $editor->Assign('is_calendar', 't' );
  $editor->Assign('use_default_privs', 't');
  $entries = 0;
}


$privilege_xlate = array(
  'read' => translate('Read'),
  'write-properties' => translate('Write Metadata'),
  'write-content' => translate('Write Data'),
  'unlock' => translate('Override a Lock'),
  'read-acl' => translate('Read Access Controls'),
  'read-current-user-privilege-set' => translate('Read Current User\'s Access'),
{'fraction_non_alphanumeric': 0.20653340488328414, 'fraction_numerical': 0.0032197477864233967, 'mean_word_length': 5.406961753330468, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 155, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4907730', 'n_tokens_mistral': 5194, 'n_tokens_neox': 5106, 'n_words': 913}