/**
 * delete the current attachment
 * this function is registered in xajax
 * @param int $attachment_id
 * @param string $attachment_specifications specifications of attachment
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_delete_attachment($attachment_id, $attachment_specifications)
{
    global $logging;
    global $user;
    global $user_start_time_array;
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******", attachment_id={$attachment_id}, attachment_specs={$attachment_specifications})");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    # create necessary objects
    $response = new xajaxResponse();
    $db_field_name = ListTable::_get_db_field_name(DB_ATTACHMENTS_NAME);
    # set name and id of input
    $input_id = $db_field_name . GENERAL_SEPARATOR . FIELD_TYPE_DEFINITION_ATTACHMENTS . GENERAL_SEPARATOR . $attachment_id;
    # uncover the specifications
    $attachment_array = explode("|", $attachment_specifications);
    $tmp_file_name = $attachment_array[0];
    $file_type = $attachment_array[1];
    $file_size = $attachment_array[2];
    $file_name = $attachment_array[3];
    if ($tmp_file_name == LISTTABLEATTACHMENT_EXISTING_ATTACHMENT) {
        $attachment_str = LISTTABLEATTACHMENT_DELETE_ATTACHMENT . "|{$file_type}|{$file_size}|{$file_name}";
        $response->script("\$('#{$input_id}').val('{$attachment_str}'); ");
        $response->script("\$('#attachment_{$attachment_id}').addClass('invisible_collapsed'); ");
    } else {
        $response->script("\$('#attachment_{$attachment_id}').remove()");
    }
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}
/**
 * cancel current action and substitute current html with new html
 * this function is registered in xajax
 * @param string $title title of page
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_cancel_user_admin_action($title)
{
    global $logging;
    global $user;
    global $user_admin_table_configuration;
    global $user_start_time_array;
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******", title={$title})");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    # create necessary objects
    $response = new xajaxResponse();
    $html_database_table = new HtmlDatabaseTable($user_admin_table_configuration);
    # set action pane
    $html_str = $html_database_table->get_action_bar($title, "");
    $response->custom_response->assign_with_effect("action_pane", $html_str);
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}
/**
 * set list filter string (function is called when user hits filter button)
 * this function is registered in xajax
 * @param string $list_title title of list
 * @param string $filter_str filter string that user has set
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_set_list_filter($list_title, $filter_str)
{
    global $logging;
    global $user;
    global $list_state;
    global $list_table_configuration;
    global $user_start_time_array;
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******", list_title={$list_title}, filter_str={$filter_str})");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    # create necessary objects
    $result = new Result();
    $response = new xajaxResponse();
    $html_database_table = new HtmlDatabaseTable($list_table_configuration);
    # check if filter_str is well formed
    if (str_is_well_formed("filter_str", $filter_str) == FALSE_RETURN_STRING) {
        set_error_message("filter_form", "below", "ERROR_NOT_WELL_FORMED_STRING", "", "", $response);
        return $response;
    }
    # create list table object
    $list_table = new ListTable($list_title);
    if ($list_table->get_is_valid() == FALSE) {
        $logging->warn("create list object returns false");
        $error_message_str = $list_table->get_error_message_str();
        $error_log_str = $list_table->get_error_log_str();
        $error_str = $list_table->get_error_str();
        set_error_message("filter_form", "below", $error_message_str, $error_log_str, $error_str, $response);
        return $response;
    }
    # set filter value
    $user->get_list_state($list_table->get_table_name());
    $list_state->set_filter_str($filter_str);
    $list_state->set_filter_str_sql("");
    $user->set_list_state();
    # set content
    $html_database_table->get_content($list_table, $list_title, "", DATABASETABLE_UNKWOWN_PAGE, $result);
    $response->custom_response->assign_with_effect(LIST_CSS_NAME_PREFIX . "content_pane", $result->get_result_str());
    # check post conditions
    if (check_postconditions($result, $response) == FALSE) {
        return $response;
    }
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}
/**
 * update a user record
 * this function is registered in xajax
 * @param string $title title of page
 * @param string $key_string comma separated name value pairs
 * @param array $form_values values of new record (array of name value pairs)
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_update_user_settings_record($title, $key_string, $form_values)
{
    global $logging;
    global $user;
    global $user_settings_table_configuration;
    global $firstthingsfirst_field_descriptions;
    global $user_start_time_array;
    # WARNING: this function is almost identical to function UserAdministration::action_update_user_admin_record
    # changes in this function should also lead to changes in that function
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******", title={$title}, key_string={$key_string})");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    $html_str = "";
    $name_keys = array_keys($form_values);
    $new_form_values = array();
    $fields = $user->get_fields();
    $field_keys = array_keys($fields);
    # create necessary objects
    $result = new Result();
    $response = new xajaxResponse();
    $html_database_table = new HtmlDatabaseTable($user_settings_table_configuration);
    foreach ($name_keys as $name_key) {
        $value_array = explode(GENERAL_SEPARATOR, $name_key);
        $db_field_name = $value_array[0];
        $field_type = $value_array[1];
        $field_number = $value_array[2];
        $check_functions = explode(" ", $firstthingsfirst_field_descriptions[$field_type][FIELD_DESCRIPTION_FIELD_INPUT_CHECKS]);
        $result->reset();
        $logging->debug("field (name=" . $db_field_name . ", type=" . $field_type . ", number=" . $field_number . ")");
        # check field values (check password field only when new password has been set)
        if ($db_field_name != USER_PW_FIELD_NAME || $db_field_name == USER_PW_FIELD_NAME && strlen($form_values[$name_key]) > 0) {
            check_field($check_functions, $db_field_name, $form_values[$name_key], $user->get_date_format(), $result);
            if (strlen($result->get_error_message_str()) > 0) {
                set_error_message($name_key, "right", $result->get_error_message_str(), "", "", $response);
                return $response;
            }
        }
        # set new value
        $new_form_values[$db_field_name] = $result->get_result_str();
        $logging->debug("setting new form value (db_field_name=" . $db_field_name . ", result=" . $result->get_result_str() . ")");
    }
    # check if someone tries to change user admin
    if ($user->get_name() == "admin") {
        # check if the name of user admin is changed
        if ($new_form_values[USER_NAME_FIELD_NAME] != "admin") {
            set_error_message("record_contents_buttons", "right", "ERROR_CANNOT_UPDATE_NAME_USER_ADMIN", "", "", $response);
            return $response;
        }
    }
    # display error when insertion returns false
    if (!$user->update($key_string, $new_form_values, TRUE)) {
        $logging->warn("update user settings record returns false");
        $error_message_str = $user->get_error_message_str();
        $error_log_str = $user->get_error_log_str();
        $error_str = $user->get_error_str();
        set_error_message("record_contents_buttons", "right", $error_message_str, $error_log_str, $error_str, $response);
        return $response;
    }
    # redirect to portal page with new user settings activated
    $response->script("window.location.assign('index.php?action=" . ACTION_GET_PORTAL_PAGE . "')");
    # check post conditions not necessary
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}
/**
 * create a new list
 * this function is registered in xajax
 * @todo check if all fields are unique
 * @param string $title title of the new list
 * @param string $description description of the new list
 * @param array $definition defintion of current list that is being build
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_create_list($title, $description, $definition)
{
    global $logging;
    global $user;
    global $list_table_description;
    global $user_start_time_array;
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******", title={$title})");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    # create necessary objects
    $response = new xajaxResponse();
    # check if title and description have been given
    if (!check_title_and_description($title, $description, $response)) {
        return $response;
    }
    # check if the new definition is correct
    $new_definition = check_definition($definition, $response);
    if (count($new_definition) == 0) {
        return $response;
    }
    # transform the new definition to the correct format
    $correct_definition = array();
    foreach ($new_definition as $field_definition) {
        $correct_definition[$field_definition[0]] = array($field_definition[1], $field_definition[2], $field_definition[3]);
    }
    $name_values_array = array();
    $name_values_array[LISTTABLEDESCRIPTION_TITLE_FIELD_NAME] = $title;
    $name_values_array[LISTTABLEDESCRIPTION_DESCRIPTION_FIELD_NAME] = $description;
    $name_values_array[LISTTABLEDESCRIPTION_DEFINITION_FIELD_NAME] = $correct_definition;
    $name_values_array[LISTTABLEDESCRIPTION_ACTIVE_RECORDS_FIELD_NAME] = 0;
    $name_values_array[LISTTABLEDESCRIPTION_ARCHIVED_RECORDS_FIELD_NAME] = 0;
    $name_values_array[LISTTABLEDESCRIPTION_CREATOR_FIELD_NAME] = 0;
    $name_values_array[LISTTABLEDESCRIPTION_MODIFIER_FIELD_NAME] = 0;
    # insert new description
    if ($list_table_description->insert($name_values_array) == FALSE) {
        $logging->warn("insert list description returns false");
        $error_message_str = $list_table_description->get_error_message_str();
        $error_log_str = $list_table_description->get_error_log_str();
        $error_str = $list_table_description->get_error_str();
        set_error_message("action_bar_button_create", "above", $error_message_str, $error_log_str, $error_str, $response);
        return $response;
    }
    # create new list_table
    $list_table = new ListTable($title);
    if ($list_table->get_is_valid() == FALSE || $list_table->create() == FALSE) {
        $logging->warn("create list returns false");
        $error_message_str = $list_table->get_error_message_str();
        $error_log_str = $list_table->get_error_log_str();
        $error_str = $list_table->get_error_str();
        set_error_message("action_bar_button_create", "above", $error_message_str, $error_log_str, $error_str, $response);
        return $response;
    }
    set_info_message("action_bar_button_create", "above", "LABEL_NEW_LIST_CREATED", $response);
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}
/**
 * delete a list table
 * this function is registered in xajax
 * @param string $list_title title of list table
 * @param string $key_string comma separated name value pairs
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_delete_portal_record($list_title)
{
    global $logging;
    global $user;
    global $list_table_description;
    global $portal_table_configuration;
    global $user_start_time_array;
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******", list_title={$list_title})");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    # create necessary objects
    $result = new Result();
    $response = new xajaxResponse();
    $list_table = new ListTable($list_title);
    if ($list_table->get_is_valid() == FALSE) {
        $logging->warn("create list object returns false");
        $error_message_str = $list_table->get_error_message_str();
        $error_log_str = $list_table->get_error_log_str();
        $error_str = $list_table->get_error_str();
        set_error_message("tab_portal_id", "below", $error_message_str, $error_log_str, $error_str, $response);
        return $response;
    }
    $html_database_table = new HtmlDatabaseTable($portal_table_configuration);
    # display error when delete returns false
    if ($list_table->drop() == FALSE) {
        $logging->warn("drop list returns false");
        $error_message_str = $list_table->get_error_message_str();
        $error_log_str = $list_table->get_error_log_str();
        $error_str = $list_table->get_error_str();
        set_error_message("tab_portal_id", "below", $error_message_str, $error_log_str, $error_str, $response);
        return $response;
    }
    # set content
    $html_database_table->get_content($list_table_description, $list_title, "", DATABASETABLE_ALL_PAGES, $result);
    $response->custom_response->assign_with_effect(PORTAL_CSS_NAME_PREFIX . "content_pane", $result->get_result_str());
    # reset current list name only when active list has been removed
    if ($list_title == $user->get_current_list_name()) {
        $user->set_current_list_name("");
    }
    # set page navigation and login status to update old 'list' links
    $page_navigation_str = get_page_navigation(PAGE_TYPE_PORTAL);
    $response->assign("navigation_container", "innerHTML", $page_navigation_str);
    # check post conditions
    if (check_postconditions($result, $response) == FALSE) {
        return $response;
    }
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}
/**
 * delete the current note
 * this function is registered in xajax
 * @param string $db_field_name name of the field that contains the notes
 * @param int $current_note_number note number of current note
 * @param int $previous_note_number note number of previous note
 * @param int $next_note_number note number of next note
 * @param int $has_add_button indicates if this note has an add button
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_delete_note($db_field_name, $current_note_number, $previous_note_number, $next_note_number, $has_add_button)
{
    global $logging;
    global $user;
    global $user_start_time_array;
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******", db_field_name={$db_field_name}, current={$current_note_number}, previous={$previous_note_number}, next={$next_note_number}, add={$has_add_button})");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    # create necessary objects
    $response = new xajaxResponse();
    $current_id_str = $db_field_name . "_" . $current_note_number;
    $previous_id_str = $db_field_name . "_" . $previous_note_number;
    $next_id_str = $db_field_name . "_" . $next_note_number;
    # if this is the first existing note
    if ($previous_note_number == -1) {
        # set the previous button of the next note
        $response->script("\$('#" . $next_id_str . "_previous').html(\$('#" . $current_id_str . "_previous').html()); ");
        # show the next note
        $response->script("\$('#{$next_id_str}').removeClass('invisible_collapsed'); ");
    } else {
        # show the previous note
        $response->script("\$('#{$previous_id_str}').removeClass('invisible_collapsed'); ");
        # set ref_next from current note to ref_next of previous note
        $response->script("\$('#" . $previous_id_str . "_ref_next').html(\$('#" . $current_id_str . "_ref_next').html()); ");
        # check if current note has an add button
        if ($has_add_button == 1) {
            # change the next button of the previous note to an add button
            $next_html_str = get_href(get_onclick(ACTION_ADD_NOTE, HTML_NO_PERMISSION_CHECK, "", "", "('{$db_field_name}', {$previous_note_number}, \$('#" . $previous_id_str . "_ref_next').html())"), translate("BUTTON_ADD_NOTE"), "icon_add");
            $response->assign($previous_id_str . "_next", "innerHTML", $next_html_str);
        }
    }
    # hide current node
    $response->script("\$('#{$current_id_str}').addClass('invisible_collapsed'); ");
    # set message in current note
    $response->script("\$('#" . $current_id_str . "_note').html('" . LISTTABLENOTE_EMPTY_NOTE . "'); ");
    # set ref_prev from current note to ref_prev of next note
    $response->script("\$('#" . $next_id_str . "_ref_prev').html(\$('#" . $current_id_str . "_ref_prev').html()); ");
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}
/**
 * logout a user
 * this function is registered in xajax
 * @return xajaxResponse every xajax registered function needs to return this object
 */
function action_logout()
{
    global $logging;
    global $user;
    global $user_start_time_array;
    $logging->info("USER_ACTION " . __METHOD__ . " (user="******")");
    # store start time
    $user_start_time_array[__METHOD__] = microtime(TRUE);
    # create necessary objects
    $response = new xajaxResponse();
    $user->logout();
    # redirect to login page
    $response->script("window.location.assign('index.php?action=" . ACTION_GET_LOGIN_PAGE . "')");
    # log total time for this function
    $logging->info(get_function_time_str(__METHOD__));
    return $response;
}