]> Kevux Git Server - koopa/commitdiff
Progress: continuing development, updated test example, added language testing, misce...
authorKevin Day <thekevinday@gmail.com>
Fri, 3 Mar 2017 07:23:53 +0000 (01:23 -0600)
committerKevin Day <thekevinday@gmail.com>
Fri, 3 Mar 2017 07:23:53 +0000 (01:23 -0600)
Did some testing and made sure the test example was working.

Added some languages for testing.
- I specifically added japanese as a language to test for error messages because it is so different from english.
- It is not practical to implement the error messages class for many languages right now because I expect major refactoring as I continue coding.
- Another simple language test is added, testing the languages: russian, spanish, japanese, and english.

More work done on in developing the database.

Other fixes and changes.

19 files changed:
common/base/classes/base_error.php
common/base/classes/base_error_messages_english.php
common/base/classes/base_error_messages_japanese.php [new file with mode: 0644]
common/base/classes/base_http.php
common/base/classes/base_languages.php
common/base/classes/base_session.php
common/theme/classes/theme_markup.php
database/sql/reservation/base-dates.sql [new file with mode: 0644]
database/sql/reservation/base-fields.sql
database/sql/reservation/base-legal.sql [new file with mode: 0644]
database/sql/reservation/base-log_problems.sql
database/sql/reservation/base-log_types.sql
database/sql/reservation/base-paths.sql
database/sql/reservation/base-requests.sql
database/sql/reservation/base-statistics.sql
database/sql/reservation/base-users.sql
examples/test.php
program/reservation/reservation_paths.php
program/reservation/reservation_session.php

index 6d4b7492e2e19e7f7ac5527914dc6ed2bb853c0f..cdd1bfa13bfe13b1279ade5ff90e3feb1bfe4577 100644 (file)
@@ -138,7 +138,7 @@ class c_base_error {
     if (is_int($code)) {
       $entry->set_code($code);
     }
-    elseif (is_null($message)) {
+    elseif (is_null($code)) {
       $entry->set_code(0);
     }
 
@@ -344,7 +344,7 @@ class c_base_error {
    *   TRUE on success, FALSE otherwise.
    */
   public function set_code($code) {
-    if (!is_string($code)) {
+    if (!is_int($code)) {
       return FALSE;
     }
 
@@ -432,7 +432,7 @@ class c_base_error {
    * The backtrace will be stored as an object.
    *
    * @param int $count
-   *   (optional) Assign a custom count that is used to prevent unecessary function calls from being included in the backtrace.
+   *   (optional) Assign a custom count that is used to prevent unnecessary function calls from being included in the backtrace.
    *   This is essentially to remove the functions called to generate this backtrace, which do not matter.
    *   Instead, only the function where the error happens should the backtrace limit count apply.
    *   This does nothing when the limit is set to 0 (which means unlimited).
@@ -512,6 +512,7 @@ interface i_base_error_messages {
   const POSTGRESQL_CONNECTION_FAILURE = 14;
   const POSTGRESQL_NO_CONNECTION      = 15;
   const POSTGRESQL_NO_RESOURCE        = 16;
+  const SOCKET_FAILURE                = 17;
 
 
   /**
index 9ec232e274a8d979e80ac39574a286a8a4904f41..6e5cf0849ba1ed6bb2e2bc31c8619229bab97049 100644 (file)
@@ -10,7 +10,91 @@ require_once('common/base/classes/base_languages.php');
 /**
  * English language version of common error messages.
  */
-final class c_base_error_messages_english extends i_base_error_messages {
+final class c_base_error_messages_english implements i_base_error_messages {
+
+  /**
+   * Converts a given error message into a processed string.
+   *
+   * @param c_base_error $code
+   *   The error message code.
+   * @param bool $arguments
+   *   (optional) When TRUE, argument placeholders are added.
+   *   When FALSE, no placeholders are provided.
+   *   All placeholders should begin with a single colon ':'.
+   * @param bool $function_name
+   *   (optional) When TRUE, the function name is included with the message.
+   *   When FALSE, no funciton name is provided.
+   * @param bool $use_html
+   *   (optional) When TRUE, the message is escaped and then wrapped in HTML.
+   *   When FALSE, no HTML wrapping or escaping is peformed.
+   *
+   * @return c_base_return_string
+   *   A processed string is returned on success.
+   *   FALSE with error bit set is returned on error.
+   *
+   * @see: s_get_message()
+   */
+  static function s_render_error_message($error, $arguments = TRUE, $function_name = FALSE, $html = TRUE) {
+    if (!($error instanceof c_base_error)) {
+      return c_base_return_string::s_new('');
+    }
+
+    $code = $error->get_code();
+    if (is_null($code)) {
+      unset($code);
+      return c_base_return_string::s_new('');
+    }
+
+    $message = self::s_get_message($code, $arguments, $function_name)->get_value_exact();
+    if (empty($message)) {
+      unset($message);
+      unset($code);
+      return c_base_return_string::s_new('');
+    }
+    unset($code);
+
+    if ($arguments === FALSE) {
+      unset($arguments);
+
+      if ($html) {
+        return c_base_return_string::s_new('<div class="error_message error_message-' . $code . '">' . $message . '</div>');
+      }
+
+      return c_base_return_string::s_new($message);
+    }
+
+    $details = $error->get_details();
+    if (isset($details['arguments']) && is_array($details['arguments'])) {
+      if ($html) {
+        foreach ($details['arguments'] as $detail_name => $detail_value) {
+          $detail_name_css = 'error_message-argument-' . preg_replace('/[^[:word:]-]/i', '', $detail_name);
+          $message = preg_replace('/' . preg_quote($detail_name, '/') . '\b/i', '<div class="error_message-argument ' . $detail_name_css . '">' . htmlspecialchars($detail_value, ENT_HTML5 | ENT_COMPAT | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</div>', $message);
+        }
+        unset($detail_name_css);
+      }
+      else {
+        foreach ($details as $detail_name => $detail_value) {
+          $message = preg_replace('/' . preg_quote($detail_name, '/') . '\b/i', $detail_value, $message);
+        }
+      }
+      unset($detail_name);
+      unset($detail_value);
+      unset($details);
+
+      if ($html) {
+        return c_base_return_string::s_new('<div class="error_message error_message-' . $code . '">' . $message . '</div>');
+      }
+
+      return c_base_return_string::s_new($message);
+    }
+    unset($details);
+
+    if ($html) {
+      return c_base_return_string::s_new('<div class="error_message error_message-' . $code . '">' . $message . '</div>');
+    }
+
+    return c_base_return_string::s_new($message);
+  }
 
   /**
    * Returns a standard error message associated with the given code.
@@ -69,10 +153,10 @@ final class c_base_error_messages_english extends i_base_error_messages {
     }
     elseif ($code === self::OPERATION_UNECESSARY) {
       if ($arguments === TRUE) {
-        return c_base_return_string::s_new('Did not perform unecessary operation, :operation_name' . (is_null($function_name_string) ? '' : ',') . $function_name_string . '.');
+        return c_base_return_string::s_new('Did not perform unnecessary operation, :operation_name' . (is_null($function_name_string) ? '' : ',') . $function_name_string . '.');
       }
       else {
-        return c_base_return_string::s_new('Did not perform unecessary operation.');
+        return c_base_return_string::s_new('Did not perform unnecessary operation.');
       }
     }
     elseif ($code === self::FUNCTION_FAILURE) {
@@ -101,7 +185,7 @@ final class c_base_error_messages_english extends i_base_error_messages {
     }
     elseif ($code === self::NOT_FOUND_DIRECTORY) {
       if ($arguments === TRUE) {
-        return c_base_return_string::s_new('The directory, :direction_name, was not found or cannot be accessed' . $function_name_string . '.');
+        return c_base_return_string::s_new('The directory, :directory_name, was not found or cannot be accessed' . $function_name_string . '.');
       }
       else {
         return c_base_return_string::s_new('File not found or cannot be accessed.');
@@ -147,6 +231,14 @@ final class c_base_error_messages_english extends i_base_error_messages {
         return c_base_return_string::s_new('No database resource is available.');
       }
     }
+    elseif ($code === self::SOCKET_FAILURE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('Failed to perform socket operation, :operation_name, socket error (:socket_error) \':socket_error_message\'' . (is_null($function_name_string) ? '' : ',') . $function_name_string . '.');
+      }
+      else {
+        return c_base_return_string::s_new('Failed to perform socket operation.');
+      }
+    }
 
     return c_base_return_string::s_new('');
   }
diff --git a/common/base/classes/base_error_messages_japanese.php b/common/base/classes/base_error_messages_japanese.php
new file mode 100644 (file)
index 0000000..07a4d49
--- /dev/null
@@ -0,0 +1,250 @@
+<?php
+/**
+ * @file
+ * Implements japanese language support for common error messages.
+ *
+ * Disclaimer: This has been added as a test case.
+ *             I used translate.google.com to translate this.
+ *             I have also noticed that the presence of a period '.' at the end of the string changes translation.
+ *             This may require a completely different approach to generating than what works with english.
+ */
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+require_once('common/base/classes/base_languages.php');
+
+/**
+ * English language version of common error messages.
+ */
+final class c_base_error_messages_japanese implements i_base_error_messages {
+
+  /**
+   * Converts a given error message into a processed string.
+   *
+   * @param c_base_error $code
+   *   The error message code.
+   * @param bool $arguments
+   *   (optional) When TRUE, argument placeholders are added.
+   *   When FALSE, no placeholders are provided.
+   *   All placeholders should begin with a single colon ':'.
+   * @param bool $function_name
+   *   (optional) When TRUE, the function name is included with the message.
+   *   When FALSE, no funciton name is provided.
+   * @param bool $use_html
+   *   (optional) When TRUE, the message is escaped and then wrapped in HTML.
+   *   When FALSE, no HTML wrapping or escaping is peformed.
+   *
+   * @return c_base_return_string
+   *   A processed string is returned on success.
+   *   FALSE with error bit set is returned on error.
+   *
+   * @see: s_get_message()
+   */
+  static function s_render_error_message($error, $arguments = TRUE, $function_name = FALSE, $html = TRUE) {
+    if (!($error instanceof c_base_error)) {
+      return c_base_return_string::s_new('');
+    }
+
+    $code = $error->get_code();
+    if (is_null($code)) {
+      unset($code);
+      return c_base_return_string::s_new('');
+    }
+
+    $message = self::s_get_message($code, $arguments, $function_name)->get_value_exact();
+    if (empty($message)) {
+      unset($message);
+      unset($code);
+      return c_base_return_string::s_new('');
+    }
+    unset($code);
+
+    if ($arguments === FALSE) {
+      unset($arguments);
+
+      if ($html) {
+        return c_base_return_string::s_new('<div class="error_message error_message-' . $code . '">' . $message . '</div>');
+      }
+
+      return c_base_return_string::s_new($message);
+    }
+
+    $details = $error->get_details();
+    if (isset($details['arguments']) && is_array($details['arguments'])) {
+      if ($html) {
+        foreach ($details['arguments'] as $detail_name => $detail_value) {
+          $detail_name_css = 'error_message-argument-' . preg_replace('/[^[:word:]-]/i', '', $detail_name);
+          $message = preg_replace('/' . preg_quote($detail_name, '/') . '\b/i', '<div class="error_message-argument ' . $detail_name_css . '">' . htmlspecialchars($detail_value, ENT_HTML5 | ENT_COMPAT | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</div>', $message);
+        }
+        unset($detail_name_css);
+      }
+      else {
+        foreach ($details as $detail_name => $detail_value) {
+          $message = preg_replace('/' . preg_quote($detail_name, '/') . '\b/i', $detail_value, $message);
+        }
+      }
+      unset($detail_name);
+      unset($detail_value);
+      unset($details);
+
+      if ($html) {
+        return c_base_return_string::s_new('<div class="error_message error_message-' . $code . '">' . $message . '</div>');
+      }
+
+      return c_base_return_string::s_new($message);
+    }
+    unset($details);
+
+    if ($html) {
+      return c_base_return_string::s_new('<div class="error_message error_message-' . $code . '">' . $message . '</div>');
+    }
+
+    return c_base_return_string::s_new($message);
+  }
+
+  /**
+   * Returns a standard error message associated with the given code.
+   *
+   * @param int $code
+   *   The error message code.
+   * @param bool $arguments
+   *   (optional) When TRUE, argument placeholders are added.
+   *   When FALSE, no placeholders are provided.
+   *   All placeholders should begin with a single colon ':'.
+   * @param bool $function_name
+   *   (optional) When TRUE, the function name is included with the message.
+   *   When FALSE, no funciton name is provided.
+   *
+   * @return c_base_return_string
+   *   A processed string is returned on success.
+   *   FALSE with error bit set is returned on error.
+   */
+  static function s_get_message($code, $arguments = TRUE, $function_name = FALSE) {
+    $function_name_string = NULL;
+    if ($function_name) {
+      $function_name_string = ' :function_name を呼び出している間';
+    }
+
+    if ($code === self::INVALID_ARGUMENT) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('無効な引数 :argument_name が指定されています' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('無効な引数が指定されています' . $function_name_string . '。');
+      }
+    }
+    elseif ($code === self::INVALID_FORMAT) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('引数 :format_name の形式が無効です' . $function_name_string . '。:expected_format');
+      }
+      else {
+        return c_base_return_string::s_new('無効な形式が指定されています。');
+      }
+    }
+    elseif ($code === self::INVALID_VARIABLE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('変数 :variable_name は無効です' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('無効な変数が指定されています。');
+      }
+    }
+    elseif ($code === self::OPERATION_FAILURE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('操作の実行に失敗しました :operation_name' . (is_null($function_name_string) ? '' : '、') . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('操作を実行できませんでした。');
+      }
+    }
+    elseif ($code === self::OPERATION_UNECESSARY) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('不要な操作を実行しませんでした :operation_name' . (is_null($function_name_string) ? '' : '、') . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('不要な操作を実行しませんでした。');
+      }
+    }
+    elseif ($code === self::FUNCTION_FAILURE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('関数 :function_name は実行に失敗しました。');
+      }
+      else {
+        return c_base_return_string::s_new('関数の実行に失敗しました。');
+      }
+    }
+    elseif ($code === self::NOT_FOUND_ARRAY_INDEX) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('配列 :index_name に索引 :array_name が見つかりませんでした。' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('指定された配列内のインデックスの検索に失敗しました。');
+      }
+    }
+    elseif ($code === self::NOT_FOUND_FILE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('ファイル :file_name が見つかりませんでした、またはアクセスできません' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('ファイルが見つからないか、アクセスできません。');
+      }
+    }
+    elseif ($code === self::NOT_FOUND_DIRECTORY) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('ディレクトリ :directory_name が見つかりませんでした、またはアクセスできません' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('ファイルが見つからないか、アクセスできません。');
+      }
+    }
+    elseif ($code === self::NO_CONNECTION) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('リソース :resource_name は接続されていません' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('リソースが接続されていません。');
+      }
+    }
+    elseif ($code === self::NO_SUPPORT) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('機能 :functionality_name は現在サポートされていません。' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('要求された機能はサポートされていません。');
+      }
+    }
+    elseif ($code === self::POSTGRESQL_CONNECTION_FAILURE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('データベースへの接続に失敗しました。 :database_name' . (is_null($function_name_string) ? '' : '、') . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('データベースに接続できませんでした。');
+      }
+    }
+    elseif ($code === self::POSTGRESQL_NO_CONNECTION) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('データベース :database_name は接続されていません' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('データベースが接続されていません。');
+      }
+    }
+    elseif ($code === self::POSTGRESQL_NO_RESOURCE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('データベースリソースがありません' . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('データベースリソースは使用できません。.');
+      }
+    }
+    elseif ($code === self::SOCKET_FAILURE) {
+      if ($arguments === TRUE) {
+        return c_base_return_string::s_new('ソケット操作の実行に失敗しました。 :operation_name 、ソケットエラー(:socket_error) \':socket_error_message\'' . (is_null($function_name_string) ? '' : '、') . $function_name_string . '。');
+      }
+      else {
+        return c_base_return_string::s_new('ソケット操作を実行できませんでした。');
+      }
+    }
+
+    return c_base_return_string::s_new('');
+  }
+}
index 7da3494a4cf8eacf45986dbfe1a6f43001f2f8eb..e4478100e1392a80d151756b6053b02349dd6fd6 100644 (file)
@@ -132,7 +132,7 @@ class c_base_http extends c_base_rfc_string {
   const DELIMITER_ACCEPT_SUB_0 = 'q';
   const DELIMITER_ACCEPT_SUB_1 = '=';
 
-  const ACCEPT_LANGUAGE_CLASS_DEFAULT = 'c_base_language_us_limited';
+  const ACCEPT_LANGUAGE_CLASS_DEFAULT = 'c_base_language_limited';
 
   // cache control options
   const CACHE_CONTROL_NO_CACHE         = 1;
@@ -4269,7 +4269,6 @@ class c_base_http extends c_base_rfc_string {
       foreach ($this->request[self::REQUEST_ACCEPT_LANGUAGE]['data']['choices'] as $weight => &$choice) {
         foreach ($choice as $key => &$c) {
           $id = $languages->s_get_id_by_name($c['choice']);
-
           if ($id instanceof c_base_return_false) {
             $c['language'] = NULL;
           }
index 40495d419eec0aa5a04ac476ed012dfa2a060701..b893f9824deb1e9e4a673dd667dceaa86bead6e8 100644 (file)
@@ -789,14 +789,17 @@ final class c_base_language_us_only implements i_base_language {
  *
  * @see: http://www.loc.gov/standards/iso639-2/php/code_list.php
  */
-final class c_base_language_us_limited implements i_base_language {
+final class c_base_language_limited implements i_base_language {
 
   private static $s_aliases = array(
     self::ENGLISH_US              => array('en-us'),
     self::ENGLISH                 => array('eng', 'en'),
     self::FRENCH                  => array('fre', 'fra', 'fr'),
+    self::GAELIC                  => array('gla', 'gd'),
+    self::IRISH                   => array('gle', 'ga'),
     self::SPANISH                 => array('spa', 'es'),
     self::INDONESIAN              => array('ind', 'id'),
+    self::JAPANESE                => array('jpn', 'ja'),
     self::RUSSIAN                 => array('rus', 'ru'),
     self::CHINESE                 => array('chi', 'zho', 'zh'),
     self::UNDETERMINED            => array('und'),
@@ -807,8 +810,11 @@ final class c_base_language_us_limited implements i_base_language {
     self::ENGLISH_US              => array('US English'),
     self::ENGLISH                 => array('English'),
     self::FRENCH                  => array('French'),
+    self::GAELIC                  => array('Gaelic', 'Scottish Gaelic'),
+    self::IRISH                   => array('Irish'),
     self::SPANISH                 => array('Spanish', 'Castilian'),
     self::INDONESIAN              => array('Indonesian'),
+    self::JAPANESE                => array('Japanese'),
     self::RUSSIAN                 => array('Russian'),
     self::CHINESE                 => array('Chinese'),
     self::UNDETERMINED            => array('Undetermined'),
@@ -822,10 +828,16 @@ final class c_base_language_us_limited implements i_base_language {
     'fre'   => self::FRENCH,
     'fra'   => self::FRENCH,
     'fr'    => self::FRENCH,
+    'gla'   => self::GAELIC,
+    'ga'    => self::GAELIC,
+    'gle'   => self::IRISH,
+    'ga'    => self::IRISH,
     'spa'   => self::SPANISH,
     'es'    => self::SPANISH,
     'ind'   => self::INDONESIAN,
     'id'    => self::INDONESIAN,
+    'jpn'   => self::JAPANESE,
+    'ja'    => self::JAPANESE,
     'rus'   => self::RUSSIAN,
     'ru'    => self::RUSSIAN,
     'chi'   => self::CHINESE,
@@ -1002,7 +1014,7 @@ final class c_base_language_us_limited implements i_base_language {
  *
  * @see: http://www.loc.gov/standards/iso639-2/php/code_list.php
  */
-final class c_base_language_us_all implements i_base_language {
+final class c_base_language_all implements i_base_language {
 
   private static $s_aliases = array(
     self::ENGLISH_US              => array('en-us'),
index 28b57c34fb90347efc2656c6fd9045cd06995571..a3e0186437acad4179e81bfd3f99dff29d6c108c 100644 (file)
@@ -27,6 +27,7 @@ class c_base_session extends c_base_return {
   private $socket_directory;
   private $socket_path;
   private $socket_timeout;
+  private $socket_error;
 
   private $system_name;
 
@@ -55,6 +56,7 @@ class c_base_session extends c_base_return {
     $this->socket_directory = NULL;
     $this->socket_path = NULL;
     $this->socket_timeout = NULL;
+    $this->socket_error = NULL;
 
     $this->cookie = NULL;
 
@@ -87,6 +89,7 @@ class c_base_session extends c_base_return {
     unset($this->socket_directory);
     unset($this->socket_path);
     unset($this->socket_timeout);
+    unset($this->socket_error);
 
     unset($this->cookie);
 
@@ -154,7 +157,7 @@ class c_base_session extends c_base_return {
     }
 
     if (!is_dir($socket_directory)) {
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':direction_name' => $socket_directory, ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::NOT_FOUND_DIRECTORY);
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':directory_name' => $socket_directory, ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::NOT_FOUND_DIRECTORY);
       return c_base_return_error::s_false($error);
     }
 
@@ -779,13 +782,29 @@ class c_base_session extends c_base_return {
     if ($receive) {
       $this->socket_timeout['receive'] = array('seconds' => $seconds, 'microseconds' => $microseconds);
       if (is_resource($this->socket)) {
-        socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, $seconds, $microseconds);
+        $result = @socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, $seconds, $microseconds);
+        if ($result === FALSE) {
+          unset($result);
+
+          $this->socket_error = @socket_last_error($this->socket);
+          $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_set_option', ':socket_error' => $this->socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+          return c_base_return_error::s_false($error);
+        }
+        unset($result);
       }
     }
     else {
       $this->socket_timeout['send'] = array('seconds' => $seconds, 'microseconds' => $microseconds);
       if (is_resource($this->socket)) {
-        socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, $seconds, $microseconds);
+        $result = @socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, $seconds, $microseconds);
+        if ($result === FALSE) {
+          unset($result);
+
+          $this->socket_error = @socket_last_error($this->socket);
+          $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_set_option', ':socket_error' => $this->socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+          return c_base_return_error::s_false($error);
+        }
+        unset($result);
       }
     }
 
@@ -814,7 +833,7 @@ class c_base_session extends c_base_return {
    *
    * Use self::get_error() to get the error reported in the packet and not the socket.
    *
-   * @return c_base_return_int
+   * @return c_base_return_int|c_base_return_null
    *   Number representing the socket error or NULL if undefined.
    *   FALSE with the error bit set is returned on error.
    *
@@ -822,33 +841,11 @@ class c_base_session extends c_base_return {
    * @see: socket_last_error()
    */
   public function get_error_socket() {
-    if (!is_resource($this->socket)) {
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->socket', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE);
-      return c_base_return_error::s_false($error);
-    }
-
-    return c_base_return_int::s_new(@socket_last_error($this->socket));
-  }
-
-  /**
-   * This clears the error on the socket if any exist.
-   *
-   * @return c_base_return_status
-   *   TRUE on success, FALSE otherwise.
-   *   FALSE with the error bit set is returned on error.
-   *
-   * @see: self::get_error_socket()
-   * @see: socket_clear_error()
-   */
-  public function clear_error_socket() {
-    if (!is_resource($this->socket)) {
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->socket', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE);
-      return c_base_return_error::s_false($error);
+    if (is_null($this->socket_error)) {
+      return new c_base_return_null();
     }
 
-    @socket_clear_error($this->socket);
-
-    return new c_base_return_true();
+    return c_base_return_int::s_new($this->socket_error);
   }
 
   /**
@@ -874,20 +871,27 @@ class c_base_session extends c_base_return {
       return c_base_return_error::s_false($error);
     }
 
-    $this->socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
-    if ($this->socket === FALSE) {
-      $this->do_disconnect();
+    $this->socket = @socket_create(AF_UNIX, SOCK_STREAM, 0);
+    if (!is_resource($this->socket)) {
+      $this->socket = NULL;
+      $this->socket_error = @socket_last_error();
 
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_create', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::OPERATION_FAILURE);
+      @socket_clear_error();
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_create', ':socket_error' => $this->socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
       return c_base_return_error::s_false($error);
     }
 
     $connected = @socket_connect($this->socket, $this->socket_path, 0);
     if ($connected === FALSE) {
       unset($connected);
+
+      $this->socket_error = @socket_last_error($this->socket);
+      @socket_clear_error($this->socket);
+
       $this->do_disconnect();
 
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_connect', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::OPERATION_FAILURE);
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_connect', ':socket_error' => $this->socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
       return c_base_return_error::s_false($error);
     }
     unset($connected);
@@ -963,7 +967,7 @@ class c_base_session extends c_base_return {
       return c_base_return_error::s_false($error);
     }
 
-    if (!is_resource($this->socket) || @socket_last_error($this->socket) != 0) {
+    if (!is_resource($this->socket)) {
       $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->socket', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE);
       return c_base_return_error::s_false($error);
     }
@@ -1061,7 +1065,7 @@ class c_base_session extends c_base_return {
       return c_base_return_error::s_false($error);
     }
 
-    if (!is_resource($this->socket) || @socket_last_error($this->socket) != 0) {
+    if (!is_resource($this->socket)) {
       $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->socket', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE);
       return c_base_return_error::s_false($error);
     }
@@ -1139,7 +1143,7 @@ class c_base_session extends c_base_return {
       return c_base_return_error::s_false($error);
     }
 
-    if (!is_resource($this->socket) || @socket_last_error($this->socket) != 0) {
+    if (!is_resource($this->socket)) {
       $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->socket', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE);
       return c_base_return_error::s_false($error);
     }
@@ -1186,7 +1190,7 @@ class c_base_session extends c_base_return {
    * @see: self::p_transfer()
    */
   public function do_flush() {
-    if (!is_resource($this->socket) || @socket_last_error($this->socket) != 0) {
+    if (!is_resource($this->socket)) {
       $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->socket', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE);
       return c_base_return_error::s_false($error);
     }
@@ -1227,10 +1231,19 @@ class c_base_session extends c_base_return {
     $written = @socket_write($this->socket, $json);
     unset($json);
 
-    if ($written === FALSE || $written == 0) {
+    if ($written === FALSE) {
       unset($written);
 
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_write', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::OPERATION_FAILURE);
+      $this->socket_error = @socket_last_error($this->socket);
+      @socket_clear_error($this->socket);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_write', ':socket_error' => $this->socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      return c_base_return_error::s_false($error);
+    }
+    elseif ($written == 0) {
+      unset($written);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_write', ':socket_error' => NULL, ':socket_error_message' => 'No bytes written.', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
       return c_base_return_error::s_false($error);
     }
     unset($written);
@@ -1239,7 +1252,10 @@ class c_base_session extends c_base_return {
     if (!is_string($json) || mb_strlen($json) == 0) {
       unset($json);
 
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_read', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::OPERATION_FAILURE);
+      $this->socket_error = @socket_last_error($this->socket);
+      @socket_clear_error($this->socket);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_read', ':socket_error' => $this->socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
       return c_base_return_error::s_false($error);
     }
 
index fe0302b9716415216de701ecfb3f7a371f418e7d..5c391a017d4f6f43cd30a6a71f84006d8395b2a8 100644 (file)
@@ -164,7 +164,7 @@ class c_theme_tag {
     }
 
     // prevent the assigned text from including markup by translating everything to html entities.
-    $this->text = htmlspecialchars($text, ENT_HTML5 | ENT_NOQUOTES | ENT_IGNORE, 'UTF-8');
+    $this->text = htmlspecialchars($text, ENT_HTML5 | ENT_NOQUOTES | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8');
 
     return new c_base_return_true();
   }
@@ -1080,7 +1080,7 @@ class c_theme_tag {
     }
 
     // require the non-null string to not be empty.
-    // multi-byte is unecessary here because this is a test not for characters but instead for a non-empty string.
+    // multi-byte is unnecessary here because this is a test not for characters but instead for a non-empty string.
     if (!is_string($attribute_value) || strlen($attribute_value) < 1) {
       return c_base_return_error::s_false();
     }
diff --git a/database/sql/reservation/base-dates.sql b/database/sql/reservation/base-dates.sql
new file mode 100644 (file)
index 0000000..5708bae
--- /dev/null
@@ -0,0 +1,59 @@
+/** Standardized SQL Structure - Dates **/
+/** This depends on: base-main.sql **/
+start transaction;
+
+
+
+/** Custom database specific settings (do this on every connection made) **/
+set bytea_output to hex;
+set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public;
+set datestyle to us;
+
+
+
+/*** Dates: Contexts ***/
+create table managers.t_date_contexts (
+  id bigint not null,
+
+  name_machine varchar(128) not null,
+  name_human varchar(256) not null,
+
+  is_locked boolean default false not null,
+  is_deleted boolean default false not null,
+
+  date_created timestamp default localtimestamp not null,
+  date_changed timestamp default localtimestamp not null,
+  date_deleted timestamp,
+
+  constraint cu_date_contexts_id unique (id),
+  constraint cu_date_contexts_name_machine unique (name_machine),
+
+  constraint cc_date_contexts_id check (id >= 0)
+);
+
+create sequence managers.s_date_contexts_id owned by managers.t_date_contexts.id;
+alter table managers.t_date_contexts alter column id set default nextval('managers.s_date_contexts_id'::regclass);
+
+grant select,insert,update on managers.t_date_contexts to reservation_users_administer;
+grant select,insert,update on managers.t_date_contexts to reservation_users_manager;
+grant select on managers.t_date_contexts to reservation_users_auditor;
+grant select,usage on managers.s_date_contexts_id to reservation_users_administer;
+grant select,usage on managers.s_date_contexts_id to reservation_users_manager;
+
+create index ci_date_contexts_deleted_not on managers.t_date_contexts (id)
+  where is_deleted is not true;
+
+create index ci_date_contexts_public on managers.t_date_contexts (id)
+  where is_deleted is not true and is_locked is not true;
+
+
+create view requesters.v_date_contexts with (security_barrier=true) as
+  select id, name_machine, name_human from managers.t_date_contexts
+  where is_deleted is not true and is_locked is not true;
+
+grant select on requesters.v_date_contexts to reservation_users_requester;
+
+insert into managers.t_date_contexts (id, name_machine, name_human) values (0, 'none', 'None');
+insert into managers.t_date_contexts (name_machine, name_human) values ('rehearsal', 'Rehearsal / Setup');
+insert into managers.t_date_contexts (name_machine, name_human) values ('event', 'Event / Meeting');
+insert into managers.t_date_contexts (name_machine, name_human) values ('cleanup', 'Cleanup / Breakdown');
index 4d309d244736b3d6629e7b9b397021e6402acfe4..6f85710497053f22a422f251e232908d7498b58a 100644 (file)
@@ -41,7 +41,7 @@ grant select,usage on managers.s_field_affiliations_id to reservation_users_admi
 grant select,usage on managers.s_field_affiliations_id to reservation_users_manager;
 
 create view users.v_field_affiliations with (security_barrier=true) as
-  select id, id_external, name_machine, name_human from managers.t_field_affiliations
+  select id, id_external, name_machine, name_human, date_created, date_changed from managers.t_field_affiliations
   where is_deleted is false;
 
 grant select on users.v_field_affiliations to reservation_users;
@@ -78,7 +78,7 @@ grant select,usage on managers.s_field_classifications_id to reservation_users_a
 grant select,usage on managers.s_field_classifications_id to reservation_users_manager;
 
 create view users.v_field_classifications with (security_barrier=true) as
-  select id, id_external, name_machine, name_human from managers.t_field_classifications
+  select id, id_external, name_machine, name_human, date_created, date_changed from managers.t_field_classifications
   where is_deleted is false;
 
 grant select on users.v_field_classifications to reservation_users;
diff --git a/database/sql/reservation/base-legal.sql b/database/sql/reservation/base-legal.sql
new file mode 100644 (file)
index 0000000..ac01c05
--- /dev/null
@@ -0,0 +1,123 @@
+/** Standardized SQL Structure - Legal */
+/** This depends on: base-users.sql **/
+start transaction;
+
+
+
+/** Custom database specific settings (do this on every connection made) **/
+set bytea_output to hex;
+set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public;
+set datestyle to us;
+
+
+
+/*** Legal Types ***/
+create table managers.t_legal_types (
+  id bigint not null,
+  id_external bigint,
+
+  name_machine varchar(128) not null,
+  name_human varchar(256) not null,
+
+  is_locked boolean default false not null,
+  is_deleted boolean default false not null,
+
+  date_created timestamp default localtimestamp not null,
+  date_changed timestamp default localtimestamp not null,
+  date_deleted timestamp,
+
+  constraint cu_legal_types_id unique (id),
+  constraint cu_legal_types_name_machine unique (name_machine),
+
+  constraint cc_legal_types_id check (id >= 0)
+);
+
+create sequence managers.s_legal_types_id owned by managers.t_legal_types.id;
+alter table managers.t_legal_types alter column id set default nextval('managers.s_legal_types_id'::regclass);
+
+grant select,insert,update on managers.t_legal_types to reservation_users_administer;
+grant select,insert,update on managers.t_legal_types to reservation_users_manager;
+grant select on managers.t_legal_types to reservation_users_auditor;
+grant select,usage on managers.s_legal_types_id to reservation_users_administer;
+grant select,usage on managers.s_legal_types_id to reservation_users_manager;
+
+create index ci_legal_types_deleted_not on managers.t_legal_types (id)
+  where is_deleted is not true;
+
+create index ci_legal_types_public on managers.t_legal_types (id)
+  where is_deleted is not true and is_locked is not true;
+
+
+create view users.v_legal_types with (security_barrier=true) as
+  select id, id_external, name_machine, name_human from managers.t_legal_types
+  where is_deleted is not true and is_locked is not true;
+
+grant select on users.v_legal_types to reservation_users_requester;
+
+
+insert into managers.t_legal_types (id, name_machine, name_human) values (0, 'none', 'None');
+
+
+
+/*** Legal / Digital Signatures ***/
+create table managers.t_signatures (
+  id bigint not null,
+  id_type bigint not null,
+  id_signer bigint not null,
+  id_request bigint,
+
+  name_machine_signer varchar(128) not null,
+
+  is_deleted boolean default false not null,
+
+  date_created timestamp default localtimestamp not null,
+  date_deleted timestamp,
+
+  /* @todo: PGP/GPG based signatures are planned but not currently implemented, the columns (fingerprint and signature) are created but are subject to major change. */
+  fingerprint varchar(64),
+  signature text,
+
+  constraint cu_signatures_id unique (id),
+
+  constraint cc_signatures_id check (id > 0),
+
+  constraint cf_signatures_id_creator foreign key (id_signer, name_machine_signer) references administers.t_users (id, name_machine) on delete restrict on update cascade,
+  constraint cf_signatures_id_type foreign key (id_type) references managers.t_legal_types (id) on delete restrict on update cascade,
+  constraint cf_signatures_id_request foreign key (id_request) references managers.t_requests (id) on delete restrict on update cascade
+);
+
+create sequence managers.s_signatures_id owned by managers.t_signatures.id;
+alter table managers.t_signatures alter column id set default nextval('managers.s_signatures_id'::regclass);
+
+grant select,insert,update on managers.t_signatures to reservation_users_administer;
+grant select,insert,update on managers.t_signatures to reservation_users_manager;
+grant select on managers.t_signatures to reservation_users_auditor;
+grant select,usage on managers.s_signatures_id to reservation_users_administer;
+grant select,usage on managers.s_signatures_id to reservation_users_manager;
+grant usage on managers.s_signatures_id to reservation_users;
+
+create index ci_signatures_deleted_not on managers.t_signatures (id)
+  where is_deleted is not true;
+
+create index ci_signatures_approved on managers.t_signatures (id)
+  where is_deleted is not true and is_cancelled is not true and is_approved is true;
+
+create index ci_signatures_approved_cancelled on managers.t_signatures (id)
+  where is_deleted is not true and is_cancelled is true and is_approved is true;
+
+
+/*** provide current user access to their own information ***/
+create view users.v_signatures_self with (security_barrier=true) as
+  select id, id_type, id_request, date_created, fingerprint, signature from managers.t_signatures
+    where is_deleted is not true and (name_machine_signer)::text = (current_user)::text;
+
+grant select on users.v_signatures_self to reservation_users;
+
+
+/** provide current user access to insert their own associations **/
+create view users.v_signatures_self_insert with (security_barrier=true) as
+  select id, id_type, id_signer, name_machine_signer, id_request, fingerprint, signature from managers.t_signatures
+    where is_deleted is not true and (name_machine_signer)::text = (current_user)::text
+    with check option;
+
+grant insert on users.v_signatures_self_insert to reservation_users;
index abb1e255661139367ef50da58be49b35659b73a0..16439b385f11db4843799c766e7a68d4d82a3d73 100644 (file)
@@ -1,5 +1,6 @@
 /** Standardized SQL Structure - Logs - Problems */
 /** This depends on: base-users.sql **/
+/* The problem logs are intended for temporary reporting of problems and are meant to allow permanent deletion. */
 start transaction;
 
 
@@ -12,6 +13,7 @@ set datestyle to us;
 
 
 /** Provide a log of problems, which are defined by the software. **/
+/* @todo: shouldnt there be a problem type code? */
 create table managers.t_log_problems (
   id bigint not null,
 
@@ -20,7 +22,6 @@ create table managers.t_log_problems (
 
   date_created timestamp default localtimestamp not null,
   date_changed timestamp default localtimestamp not null,
-  date_deleted timestamp,
 
   constraint cp_log_problems_id primary key (id),
 
@@ -29,10 +30,12 @@ create table managers.t_log_problems (
   constraint cu_log_problems_name_machine unique (name_machine)
 );
 
-grant select on managers.t_log_problems to reservation_users_administer;
-grant select on managers.t_log_problems to reservation_users_manager;
+grant select,insert,update,delete on managers.t_log_problems to reservation_users_administer;
+grant select,insert,update,delete on managers.t_log_problems to reservation_users_manager;
 grant select on managers.t_log_problems to reservation_users_auditor;
 
+/* @todo: it seems the views for allowing users to insert/delete problems needs to be created. */
+
 
 
 /** Provide a log of problems, associated with a given user. **/
@@ -44,7 +47,6 @@ create table managers.t_log_problems_users (
 
   date_created timestamp default localtimestamp not null,
   date_changed timestamp default localtimestamp not null,
-  date_deleted timestamp,
 
   log_details json,
 
@@ -63,18 +65,20 @@ grant select on managers.t_log_problems_users to reservation_users_auditor;
 
 /** only allow select, insert, and delete for users when user id is current user **/
 create view users.v_log_problems_users_self with (security_barrier=true) as
-  select id_problem, id_user, date_created, log_details from managers.t_log_problems_users
+  select id_problem, id_user, date_created, date_changed, log_details from managers.t_log_problems_users
     where (name_machine_user)::text = (current_user)::text;
 
 grant select on users.v_log_problems_users_self to reservation_users;
 
+
 create view users.v_log_problems_users_self_insert with (security_barrier=true) as
-  select id_problem, id_user, name_machine_user, log_details from managers.t_log_problems_users
+  select id_problem, id_user, name_machine_user, date_changed, log_details from managers.t_log_problems_users
     where (name_machine_user)::text = (current_user)::text
     with check option;
 
 grant insert on users.v_log_problems_users_self_insert to reservation_users;
 
+
 create view users.v_log_problems_users_self_delete with (security_barrier=true) as
   select id_problem, id_user from managers.t_log_problems_users
     where (name_machine_user)::text = (current_user)::text
@@ -83,5 +87,21 @@ create view users.v_log_problems_users_self_delete with (security_barrier=true)
 grant delete on users.v_log_problems_users_self_delete to reservation_users;
 
 
+/** automatically delete problems deleted from the table managers.t_log_problems_users **/
+create function managers.f_log_problems_users_delete() returns trigger security definer as $$
+  begin
+    if (tg_op = 'DELETE') then
+      delete from managers.t_log_problems where id = old.id_problem;
+      return old;
+    end if;
+
+    return null;
+  end;
+$$ language plpgsql;
+
+create trigger tr_log_problems_users_delete
+  after delete on managers.t_log_problems_users
+    for each row execute procedure managers.f_log_problems_users_delete();
+
 
 commit transaction;
index 5ea2a47b044a79c6ef4107d7188c4208e2aa913a..ab4d90671c6a0af8caed605cd4c61cebaa51f835 100644 (file)
@@ -29,7 +29,7 @@ create table managers.t_log_types (
 
   constraint cu_log_types_user unique (name_machine),
 
-  constraint cc_log_types_id check (id > 0)
+  constraint cc_log_types_id check (id >= 0)
 );
 
 create sequence managers.s_log_types_id owned by managers.t_log_types.id;
@@ -60,6 +60,7 @@ alter sequence managers.s_log_types_id restart;
 
 
 /** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/
+insert into managers.t_log_types (id, name_machine, name_human) values (0, 'none', 'None');
 insert into managers.t_log_types (id, name_machine, name_human) values (1, 'php', 'PHP');
 insert into managers.t_log_types (id, name_machine, name_human) values (2, 'theme', 'Theme');
 insert into managers.t_log_types (id, name_machine, name_human) values (3, 'cache', 'Cache');
@@ -228,7 +229,7 @@ create table managers.t_log_severity_levels (
 
   constraint cu_log_severity_levels_user unique (name_machine),
 
-  constraint cc_log_severity_levels_id check (id > 0)
+  constraint cc_log_severity_levels_id check (id >= 0)
 );
 
 create sequence managers.s_log_severity_levels_id owned by managers.t_log_severity_levels.id;
@@ -253,6 +254,7 @@ alter sequence managers.s_log_severity_levels_id restart;
 
 
 /** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/
+insert into managers.t_log_severity_levels (id, name_machine, name_human) values (0, 'none', 'None');
 insert into managers.t_log_severity_levels (id, name_machine, name_human) values (1, 'information', 'Information');
 insert into managers.t_log_severity_levels (id, name_machine, name_human) values (2, 'notice', 'Notice');
 insert into managers.t_log_severity_levels (id, name_machine, name_human) values (3, 'debug', 'Debug');
index d263a9204ec6fadf4bd14579f553dc681bcafc6a..0dde69862a250b7b14476ae6c013eba6a4fb3298 100644 (file)
@@ -109,7 +109,7 @@ create index ci_paths_public on managers.t_paths (id)
 
 create view users.v_paths with (security_barrier=true) as
   with allowed_groups as (select id from users.v_groups_self)
-  select id, id_type, id_group, name_machine, name_human, is_private from managers.t_paths
+  select id, id_type, id_group, name_machine, name_human, is_private, date_created, date_changed from managers.t_paths
   where is_deleted is not true and (is_locked is not true or id_group in (select * from allowed_groups)) and (is_private is not true or (is_private is true and id_group in (select * from allowed_groups)));
 
 grant select on users.v_paths to reservation_users;
index 49279fd4b2322487b62832f8e0e72ed86f323803..0c07325c134a7f8410aa940e05bebc5102e24507 100644 (file)
@@ -29,7 +29,7 @@ create table managers.t_request_types (
   constraint cu_request_types_id unique (id),
   constraint cu_request_types_name_machine unique (name_machine),
 
-  constraint cc_request_types_id check (id > 0)
+  constraint cc_request_types_id check (id >= 0)
 );
 
 create sequence managers.s_request_types_id owned by managers.t_request_types.id;
@@ -47,6 +47,7 @@ create index ci_request_types_deleted_not on managers.t_request_types (id)
 create index ci_request_types_public on managers.t_request_types (id)
   where is_deleted is not true and is_locked is not true;
 
+
 create view requesters.v_request_types with (security_barrier=true) as
   select id, id_external, name_machine, name_human from managers.t_request_types
   where is_deleted is not true and is_locked is not true;
@@ -54,6 +55,7 @@ create view requesters.v_request_types with (security_barrier=true) as
 grant select on requesters.v_request_types to reservation_users_requester;
 
 /** @todo: consider creating default request types **/
+insert into managers.t_request_types (id, name_machine, name_human) values (0, 'none', 'None');
 
 
 
index 99a87791ea39776a3edecd77b4476b378c48aa8e..2b2751c6da2e9cba9651a44ee18faabcddadf436 100644 (file)
@@ -51,13 +51,15 @@ create function managers.f_statistics_http_status_codes_insert() returns trigger
     return null;
   end;
 $$ language plpgsql;
-reset role;
-revoke create on schema managers from reservation_users_manager;
 
-create trigger tr_statistics_http_status_codes_insert
+create trigger tr_log_activity_insert_statistics_http_status_codes
   after insert on managers.t_log_activity
     for each row execute procedure managers.f_statistics_http_status_codes_insert();
 
+create trigger tr_log_users_insert_statistics_http_status_codes
+  after insert on managers.t_log_users
+    for each row execute procedure managers.f_statistics_http_status_codes_insert();
+
 
 /** create all of the known codes, initializing them to 0. **/
 insert into managers.t_statistics_http_status_codes (code) values (0);
@@ -148,6 +150,7 @@ grant select on managers.t_statistics_request_path to reservation_users_administ
 grant select on managers.t_statistics_request_path to reservation_users_manager;
 grant select on managers.t_statistics_request_path to reservation_users_auditor;
 
+
 /** permissions prevent this from working as desired, so for now open up these stats to the following users (via a view) **/
 create view users.v_statistics_request_path with (security_barrier=true) as
   select path, count from managers.t_statistics_request_path
@@ -155,12 +158,14 @@ create view users.v_statistics_request_path with (security_barrier=true) as
 
 grant select,insert,update on users.v_statistics_request_path to reservation_users;
 
+
 create view public.v_statistics_request_path with (security_barrier=true) as
   select path, count from managers.t_statistics_request_path
     with check option;
 
 grant select,insert,update on public.v_statistics_request_path to public_users;
 
+
 /** create an auto-update trigger **/
 create function managers.f_statistics_request_path_insert() returns trigger as $$
   begin
index 4f7e1e64e936f7e256815a02c1eed408779e2c04..80d4c1a0e78ae2cae7e609fb8c77897d292aed7b 100644 (file)
@@ -105,7 +105,7 @@ insert into administers.t_users (id, name_machine, name_human, is_private) value
 /*** provide current user access to their own information ***/
 create view users.v_users_self with (security_barrier=true) as
   select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users
-    where is_deleted is not true and (name_machine)::text = (current_user)::text;
+    where (name_machine)::text = (current_user)::text;
 
 grant select on users.v_users_self to reservation_users;
 
@@ -118,7 +118,7 @@ grant insert on users.v_users_self_insert to reservation_users;
 
 create view users.v_users_self_update with (security_barrier=true) as
   select address_email, is_private, date_changed, date_synced, settings from administers.t_users
-    where is_deleted is not true and date_changed = localtimestamp and (date_synced is null or date_synced = localtimestamp) and (name_machine)::text = (current_user)::text
+    where date_changed = localtimestamp and (date_synced is null or date_synced = localtimestamp) and (name_machine)::text = (current_user)::text
     with check option;
 
 grant update on users.v_users_self_update to reservation_users;
@@ -127,7 +127,7 @@ grant update on users.v_users_self_update to reservation_users;
 /**** anonymous user has uid = 1 ****/
 create view public.v_users_self with (security_barrier=true) as
   select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users
-    where id = 1 and is_deleted is not true and id_sort = 0;
+    where id = 1 and id_sort = 0;
 
 grant select on public.v_users_self to public_users;
 
@@ -135,7 +135,7 @@ grant select on public.v_users_self to public_users;
 /**** system user has uid = 2 ****/
 create view system.v_users_self with (security_barrier=true) as
   select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users
-    where id = 2 and is_deleted is not true and id_sort = 0;
+    where id = 2 and id_sort = 0;
 
 grant select on system.v_users_self to reservation_user;
 
@@ -160,20 +160,19 @@ grant select on public.v_users_email to public_users;
 
 /*** provide managers with the ability to modify accounts ***/
 create view managers.v_users with (security_barrier=true) as
-  select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced from administers.t_users
+  select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users
     where is_deleted is not true;
 
 grant select on managers.v_users to reservation_users_manager;
 
 create view managers.v_users_insert with (security_barrier=true) as
-  select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator from administers.t_users
-    where is_deleted is not true
+  select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, settings from administers.t_users
     with check option;
 
 grant insert on managers.v_users_insert to reservation_users_manager;
 
 create view managers.v_users_update with (security_barrier=true) as
-  select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_changed, date_synced from administers.t_users
+  select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_changed, date_synced, settings from administers.t_users
     where is_deleted is not true and date_changed = localtimestamp and (date_synced is null or date_synced = localtimestamp)
     with check option;
 
@@ -224,40 +223,4 @@ grant select on administers.vm_users_date_synced_previous_year to reservation_us
 grant select on administers.vm_users_date_synced_previous_year to reservation_users_manager;
 
 
-
-/*** provide sequence id preservation table ***/
-create table administers.t_users_sequences (
-  id bigint not null,
-  id_user bigint not null,
-  name_machine varchar(128) not null,
-  is_locked boolean default true not null,
-  date_expire timestamp not null,
-
-  constraint cu_users_sequences_id unique (id),
-  constraint cu_users_sequences_name_machine unique (name_machine),
-
-  constraint cc_users_sequences_id check (id > 0),
-
-  constraint cf_users_sequences_user foreign key (id_user, name_machine) references administers.t_users (id, name_machine) on delete cascade on update cascade
-);
-
-grant select,insert,update,delete on administers.t_users_sequences to reservation_users_administer;
-grant select on administers.t_users_sequences to reservation_users_auditor;
-
-create view public.v_users_sequences_locked with (security_barrier=true) as
-  select id, id_user, name_machine, is_locked, date_expire from administers.t_users_sequences
-    where is_locked is true and date_expire >= current_timestamp and (name_machine)::text = (current_user)::text
-    with check option;
-
-grant select,insert,update,delete on v_users_sequences_locked to reservation_users;
-
-create view public.v_users_sequences_unlocked with (security_barrier=true) as
-  select id, id_user, name_machine, is_locked, date_expire from administers.t_users_sequences
-    where (is_locked is not true or date_expire < current_timestamp) and (name_machine)::text = (current_user)::text
-    with check option;
-
-grant select,update,delete on v_users_sequences_unlocked to reservation_users;
-
-
-
 commit transaction;
index b381058fa7bac4d971df4c688938b73a93dc255d..606dc7ecc48059d669d0a00b55f1b822929bc1e5 100755 (executable)
@@ -8,9 +8,59 @@
   require_once('common/base/classes/base_cookie.php');
   require_once('common/base/classes/base_database.php');
   require_once('common/base/classes/base_ldap.php');
+  require_once('common/base/classes/base_http.php');
 
 
-  function headers($stuff) {
+  // create an alias for the default language for error messages.
+  #class_alias('c_base_error_messages_english', 'c_base_error_messages');
+
+
+  function process_received_headers(&$stuff) {
+    $stuff['http'] = new c_base_http();
+    $stuff['http']->do_load_request();
+
+    // test error message handling using english or japanese.
+    $supported_languages = array(
+      i_base_language::ENGLISH => 'c_base_error_messages_english',
+      i_base_language::JAPANESE => 'c_base_error_messages_japanese',
+    );
+
+    $language_chosen = i_base_language::ENGLISH;
+    $languages_accepted = $stuff['http']->get_request(c_base_http::REQUEST_ACCEPT_LANGUAGE)->get_value();
+    if (isset($languages_accepted['data']['weight']) && is_array($languages_accepted['data']['weight'])) {
+      foreach ($languages_accepted['data']['weight'] as $weight => $language) {
+        $language_code = array_pop(array_keys($language));
+        if (array_key_exists($language_code, $supported_languages)) {
+          $language_chosen = $language_code;
+          break;
+        }
+      }
+      unset($weight);
+      unset($language);
+      unset($language_code);
+    }
+    unset($languages_accepted);
+
+    if ($language_chosen === i_base_language::ENGLISH) {
+      require_once('common/base/classes/base_error_messages_english.php');
+    }
+    elseif ($language_chosen === i_base_language::JAPANESE) {
+      require_once('common/base/classes/base_error_messages_japanese.php');
+    }
+
+    $stuff['error_messages'] = new $supported_languages[$language_chosen];
+
+    unset($supported_languages);
+    unset($language_chosen);
+  }
+
+  $stuff = array(
+    'resources' => array(
+      'time' => microtime(TRUE),
+     ),
+  );
+
+  function send_prepared_headers($stuff) {
     if (isset($stuff['cookie_existence']['cookie'])) {
       $stuff['cookie_existence']['cookie']->do_push();
     }
   }
 
   function theme($stuff) {
+    // @todo: call the appropriate http send function from $stuff['http']. this requires rewriting this entire theme function.
+    // note: not changing language here because most of the page is in english, regardless of the http accept-language setting.
+    print('<html lang="en-US">');
+    print('<head>');
+    print('<title>Testing Koopa</title>');
+    print('<meta content="A simple and rough test of various functionality provided by the koopa project." name="description">');
+    print('<meta content="text/html; charset=utf-8" http-equiv="Content-Type">');
+    print('<meta charset="UTF-8">');
+    print('<meta content="web" name="distribution">');
+    print('<meta content="INDEX,FOLLOW" name="robots">');
+    print('<meta content="width=device-width, initial-scale=1" name="viewport">');
+    print('<style type="text/css" rel="stylesheet" media="all">');
+    print('.error_message > .error_message-argument { display: inline-block; vertical-align: baseline; }');
+    print('</style>');
+    print('</head>');
+
+    print('<body>');
     print("<h1>Testing</h1>\n");
     print("The following is a test of the database design and base database and cookied functionality.<br>");
     print("<br>");
 
+    if (isset($stuff['errors'])) {
+      print("0) The following errors have been detected:<br>");
+      print('<ol>' . $stuff['errors'] . '</ol>');
+    }
+
     if (isset($_SERVER["HTTPS"])) {
       print("1) You are using HTTPS.<br>");
       print("<br>");
     unset($value);
     print("<br>");
 
+    print("3) Language Test: <br>");
+
+    // disclaimer: I used translate.google.com to generate the languages and provided only the default translation (expect translation errors).
+    $test_strings = array(
+      i_base_language::ENGLISH => 'This is a test using your browser default language. Currently english (default), spanish, japanese, and russian are tested.',
+      i_base_language::JAPANESE => 'これは、ブラウザのデフォルト言語を使用したテストです。 現在、英語(デフォルト)、スペイン語、日本語、ロシア語がテストされています。',
+      i_base_language::RUSSIAN => 'Это тест с помощью браузера по умолчанию язык. В настоящее время английский (по умолчанию), испанский, японский и русский тестируются.',
+      i_base_language::SPANISH => 'Se trata de una prueba que utiliza el idioma predeterminado de su navegador. Actualmente se ponen a prueba el inglés (predeterminado), el español, el japonés y el ruso.',
+    );
+
+    $language_chosen = i_base_language::ENGLISH;
+    $languages_accepted = $stuff['http']->get_request(c_base_http::REQUEST_ACCEPT_LANGUAGE)->get_value();
+    if (isset($languages_accepted['data']['weight']) && is_array($languages_accepted['data']['weight'])) {
+      foreach ($languages_accepted['data']['weight'] as $weight => $language) {
+        $language_code = array_pop(array_keys($language));
+        if (array_key_exists($language_code, $test_strings)) {
+          $language_chosen = $language_code;
+          break;
+        }
+      }
+      unset($weight);
+      unset($language);
+      unset($language_code);
+    }
+
+    print(' - ' . $test_strings[$language_chosen] . "<br>");
+    print("<br>");
+
+    unset($language_chosen);
+    unset($languages_accepted);
+    unset($test_strings);
+
     // Useful _SERVER Variables:
     //   REQUEST_TIME, REQUEST_TIME_FLOAT
     //   HTTPS, HTTP_HOST
 
     print("<h2>Cookie Test</h2>\n");
     if (isset($stuff['cookie_existence']['new'])) {
-      print("3) A new existence cookie has been created.<br>");
+      print("4) A new existence cookie has been created.<br>");
       print($stuff['cookie_existence']['new']);
     }
     elseif (isset($stuff['cookie_existence']['exists'])) {
-      print("3) The existence cookie has been loaded.<br>");
+      print("4) The existence cookie has been loaded.<br>");
       print($stuff['cookie_existence']['exists']);
     }
     else {
-      print("3) Disabled<br>");
+      print("4) Disabled<br>");
     }
 
 
     print("<h2>Login, Session, and Database Connection Test</h2>\n");
     if (isset($stuff['login']) && isset($_SERVER["HTTPS"])) {
-      print("4) Login<br>");
+      print("5) Login<br>");
       print($stuff['login']);
     }
     else {
-      print("4) Disabled<br>");
+      print("5) Disabled<br>");
     }
 
 
     print("<h2>LDAP Test</h2>\n");
     if (isset($stuff['ldap']) && isset($_SERVER["HTTPS"])) {
-      print("5) LDAP<br>");
+      print("6) LDAP<br>");
       if (isset($stuff['ldap']['markup'])) {
         print($stuff['ldap']['markup']);
       }
     }
     else {
-      print("5) Disabled<br>");
+      print("6) Disabled<br>");
     }
 
 
       $mp_2 = memory_get_peak_usage();
 
       print("<h2>Resources</h2>\n");
-      print("6) Time Taken: " . sprintf('%.10g', $difference_milli) . " milliseconds (" . sprintf('%.06g', $difference_seconds)  . " seconds).<br>");
-      print("7) Memory Usage (Real): " . $mu_1 . " bytes (" . sprintf('%.06g', $mu_1 / 1024 / 1024) . " megabytes).<br>");
-      print("8) Memory Usage (emalloc): " . $mu_2 . " bytes (" . sprintf('%.06g', $mu_2 / 1024 / 1024) . " megabytes)<br>");
-      print("9) Peak Memory Usage (Real): " . $mp_1 . " bytes (" . sprintf('%.06g', $mp_1 / 1024 / 1024) . " megabytes).<br>");
-      print("10) Peak Memory Usage (emalloc): " . $mp_2 . " bytes (" . sprintf('%.06g', $mp_2 / 1024 / 1024) . " megabytes).<br>");
+      print("7) Time Taken: " . sprintf('%.10g', $difference_milli) . " milliseconds (" . sprintf('%.06g', $difference_seconds)  . " seconds).<br>");
+      print("8) Memory Usage (Real): " . $mu_1 . " bytes (" . sprintf('%.06g', $mu_1 / 1024 / 1024) . " megabytes).<br>");
+      print("9) Memory Usage (emalloc): " . $mu_2 . " bytes (" . sprintf('%.06g', $mu_2 / 1024 / 1024) . " megabytes)<br>");
+      print("10) Peak Memory Usage (Real): " . $mp_1 . " bytes (" . sprintf('%.06g', $mp_1 / 1024 / 1024) . " megabytes).<br>");
+      print("11) Peak Memory Usage (emalloc): " . $mp_2 . " bytes (" . sprintf('%.06g', $mp_2 / 1024 / 1024) . " megabytes).<br>");
     }
+
+    print('</body>');
+    print('</html>');
   }
 
   function session(&$stuff) {
               $logged_in = TRUE;
 
               ldap($stuff, $session->get_name()->get_value_exact());
-              set_log_activity($database, $session->get_id_user()->get_value_exact());
-              get_database_data($database, $stuff, $session->get_id_user()->get_value_exact());
+              set_log_activity($database);
+              get_database_data($database, $stuff);
 
               if ($session->get_id_user()->get_value_exact() > 0) {
                 $log = get_log_activity($database);
           $session->set_password($_POST['login_password']);
 
           $user_data = array();
-          $account_exists = check_login_access($database, $_POST['login_name'], $_POST['login_password'], $session);
+          $account_exists = check_login_access($stuff, $database, $_POST['login_name'], $_POST['login_password'], $session);
           if (!$account_exists) {
             $user_id = 1;
             $session->set_name('public_user');
             $connected = connect_database($database);
 
             if ($connected) {
-              set_log_user($database, 'login_failure', $_POST['login_name'], 403);
+              set_log_user($database, 'login_failure', $_POST['login_name'], NULL, 401);
+              set_log_activity($database, 401);
 
               $stuff['login'] .= ' - Accessing database as: public_user' . '<br>' . "\n";
               $stuff['login'] .= ' - Your user id is: 1 ' . '<br>' . "\n";
               $stuff['login'] .= '<br>' . "\n";
               $logged_in = TRUE;
-
-              set_log_activity($database, $user_id);
             }
           }
           else {
             $failure = TRUE;
           }
           else {
-            set_log_user($database, 'login');
-
             $result = $session->do_connect();
             $failure = c_base_return::s_has_error($result);
           }
 
-          if (!$failure) {
+          // added '$user_id > 999' to ensure that anonymous and other system users do not generate a session cookie.
+          if (!$failure && $user_id > 999) {
             $result = $session->do_push(600, 1800); // (10 minutes, 30 minutes)
             $session->do_disconnect();
 
+            set_log_user($database, 'login', NULL, $session->get_timeout_expire()->get_value_exact());
+
             $session_expire = $session->get_timeout_expire()->get_value_exact();
             $session_max = $session->get_timeout_max()->get_value_exact();
             $expire_string = date("D, d M Y H:i:s T", $session_expire);
             if ($result instanceof c_base_return_true) {
               $data = array(
                 'session_id' => $session->get_session_id()->get_value_exact(),
-                'expire' => gmdate("D, d-M-Y H:i:s T", $session_expire), // unecessary, but provided for debug purposes.
+                'expire' => gmdate("D, d-M-Y H:i:s T", $session_expire), // unnecessary, but provided for debug purposes.
               );
               $cookie->set_value($data);
               $stuff['cookie_login']['cookie'] = $cookie;
                 ldap($stuff, $session->get_name()->get_value_exact());
               }
 
-              set_log_activity($database, $user_id);
-              get_database_data($database, $stuff, $user_id);
+              set_log_activity($database);
+              get_database_data($database, $stuff);
 
               if ($session->get_id_user()->get_value_exact() > 0) {
                 $log = get_log_activity($database);
                 unset($table);
               }
 
-              unset($user_id);
               unset($user_data);
             }
             else {
             }
           }
 
+          unset($user_id);
           unset($session);
         }
       }
     #$stuff['login'] .= '<br>' . "\n";
   }
 
-  function get_database_data(&$database, &$stuff, $user_id) {
+  function get_database_data(&$database, &$stuff) {
     $stuff['login'] .= 'query: "select * from v_users;"<br>' . "\n";
     $query_result = $database->do_query('select * from v_users');
     if ($query_result instanceof c_base_database_result) {
       unset($row);
       unset($row_number);
     }
-    $stuff['login'] .= '</ol><br>' . "\n";
+    else {
+      if (!isset($stuff['errors'])) {
+        $stuff['errors'] = '';
+      }
 
+      $stuff['errors'] .= '<li>' . $database->get_last_error()->get_value_exact() . '</li>';
+    }
+    unset($query_result);
+
+    $stuff['login'] .= '</ol><br>' . "\n";
     $stuff['login'] .= '<br>' . "\n";
   }
 
-  function check_login_access(&$database, $username, $password, $session) {
+  function check_login_access(&$stuff, &$database, $username, $password, $session) {
     if ($username == 'public_user') return FALSE;
 
     $database->set_session($session);
 
     // it is possible the user name might not exist, so try to create it.
     $ensure_result = ensure_user_account($_POST['login_name']);
+    if (c_base_return::s_has_error($ensure_result)) {
+      $errors = $ensure_result->get_error();
+      if (is_array($errors)) {
+        if (!isset($stuff['errors'])) {
+          $stuff['errors'] = '';
+        }
+
+        foreach ($errors as $error) {
+          if ($error instanceof c_base_error) {
+            $stuff['errors'] .= '<li>' . $stuff['error_messages']::s_render_error_message($error)->get_value_exact() . '</li>';
+          }
+        }
+        unset($error);
+      }
+      unset($errors);
+    }
+    unset($ensure_result);
 
     // try again now that the system has attempted to ensure the user account exists.
     $connected = connect_database($database);
     return TRUE;
   }
 
-  function set_log_user(&$database, $type, $user_name = NULL, $response_code = 200) {
+  function set_log_user(&$database, $type, $user_name = NULL, $expires = NULL, $response_code = 200) {
+    $extra_parameters = '';
+    $extra_values = '';
+
     $query_string = '';
-    #$query_string .= 'insert into v_log_users_self_insert (id_user, name_machine_user, log_title, log_type, log_severity, log_details, request_client, response_code)';
-    #$query_string .= ' values (coalesce((select id from v_users_self), 1), coalesce((select name_machine_user from v_users_self), \'unknown\'), $1, $2, $3, $4, ($5, $6, $7), $8); ';
-    $query_string .= 'insert into v_log_users_self_insert (id_user, log_title, log_type, log_severity, log_details, request_client, response_code)';
-    $query_string .= ' values (coalesce((select id from v_users_self), 1), $1, $2, $3, $4, ($5, $6, $7), $8); ';
+    $query_string .= 'insert into v_log_users_self_insert (id_user, name_machine_user, log_title, log_type, log_severity, request_client, response_code, log_details)';
+    $query_string .= ' values (coalesce((select id from v_users_self), 1), coalesce((select name_machine from v_users_self), \'unknown\'), $1, $2, $3, ($4, $5, $6), $7, $8); ';
 
     $query_parameters = array();
-    $query_parameters[4] = json_encode(NULL);
-    $query_parameters[5] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
-    $query_parameters[6] = isset($_SERVER['REMOTE_PORT']) ? $_SERVER['REMOTE_PORT'] : 0;
-    $query_parameters[7] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '' ; // @todo: test providing NULL.
-    $query_parameters[8] = $response_code;
-
-    if ($type == 'login' ) {
-      $query_parameters[1] = "Logging in to system.";
-      $query_parameters[2] = 17;
-      $query_parameters[3] = 1;
-    }
-    elseif ($type == 'logout' ) {
-      $query_parameters[1] = "Logging out of system.";
-      $query_parameters[2] = 18;
-      $query_parameters[3] = 1;
-    }
-    elseif ($type == 'create' ) {
-      $query_parameters[1] = "Created user account.";
-      $query_parameters[2] = 27;
-      $query_parameters[3] = 1;
-    }
-    elseif ($type == 'login_failure' ) {
-      $query_parameters[1] = "Failed to login as the user '" . $user_name . "'.";
-      $query_parameters[2] = 17;
-      $query_parameters[3] = 2;
-      $query_parameters[4] = json_encode(array('user_name' => $user_name));
+    $query_parameters[3] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
+    $query_parameters[4] = isset($_SERVER['REMOTE_PORT']) ? $_SERVER['REMOTE_PORT'] : 0;
+    $query_parameters[5] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '' ;
+    $query_parameters[6] = $response_code;
+
+    if ($type == 'login') {
+      $query_parameters[0] = "Logging in to the system.";
+      $query_parameters[1] = 17;
+      $query_parameters[2] = 1;
+      $query_parameters[7] = json_encode(array('expires' => $expires));
+    }
+    elseif ($type == 'logout') {
+      $query_parameters[0] = "Logging out of the system.";
+      $query_parameters[1] = 18;
+      $query_parameters[2] = 1;
+      $query_parameters[7] = NULL;
+    }
+    elseif ($type == 'create') {
+      $query_parameters[0] = "Created the user account.";
+      $query_parameters[1] = 27;
+      $query_parameters[2] = 1;
+      $query_parameters[7] = NULL;
+    }
+    elseif ($type == 'login_failure') {
+      $query_parameters[0] = "Failed to login as the user '" . $user_name . "'.";
+      $query_parameters[1] = 17;
+      $query_parameters[2] = 2;
+      $query_parameters[7] = json_encode(array('user_name' => $user_name));
     }
     else {
       return FALSE;
     unset($query_string);
     unset($query_parameters);
 
+    if ($query_result instanceof c_base_return_false) {
+      if (!isset($stuff['errors'])) {
+        $stuff['errors'] = '';
+      }
+
+      $stuff['errors'] .= '<li>' . $database->get_last_error()->get_value_exact() . '</li>';
+    }
+    unset($query_result);
+
     return TRUE;
   }
 
-  function set_log_activity(&$database, $user_id, $response_code = 200) {
+  function set_log_activity(&$database, $response_code = 200) {
     $connected = connect_database($database);
 
     if (!isset($stuff['login'])) {
     }
 
     if ($connected) {
-      $name_machine_user = 'current_user';
-      if (!is_int($user_id) || $user_id == 1) {
-        $user_id = 1;
-        $name_machine_user = '\'unknown\'';
-      }
-
       $query_string = '';
-      $query_string .= 'insert into v_log_activity_self_insert (id_user, name_machine_user, request_path, request_arguments, request_client, request_headers, response_headers, response_code) values ($1, ' . $name_machine_user . ', $2, $3, ($4, $5, $6), $7, $8, $9); ';
-
-      // @todo: populate headers.
-      $request_headers = json_encode(NULL);
-      $response_headers = json_encode(NULL);
+      $query_string .= 'insert into v_log_activity_self_insert (id_user, name_machine_user, request_path, request_arguments, request_client, response_code) values (coalesce((select id from v_users_self), 1), coalesce((select name_machine from v_users_self), \'unknown\'), $1, $2, ($3, $4, $5), $6); ';
 
       $query_parameters = array();
-      $query_parameters[] = $user_id;
       $query_parameters[] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
       $query_parameters[] = is_array($_GET) && !empty($_GET) ? print_r(array_keys($_GET), TRUE) : '';
       $query_parameters[] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
       $query_parameters[] = isset($_SERVER['REMOTE_PORT']) ? $_SERVER['REMOTE_PORT'] : 0;
       $query_parameters[] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : NULL;
-      $query_parameters[] = $request_headers;
-      $query_parameters[] = $response_headers;
       $query_parameters[] = $response_code;
       unset($response_headers);
       unset($request_headers);
       $query_result = $database->do_query($query_string, $query_parameters);
       unset($query_string);
       unset($query_parameters);
+
+      if ($query_result instanceof c_base_return_false) {
+        if (!isset($stuff['errors'])) {
+          $stuff['errors'] = '';
+        }
+
+        $stuff['errors'] .= '<li>' . $database->get_last_error()->get_value_exact() . '</li>';
+      }
+      unset($query_result);
     }
     else {
       return FALSE;
         }
       }
     }
+    else {
+      if (!isset($stuff['errors'])) {
+        $stuff['errors'] = '';
+      }
+
+      $stuff['errors'] .= '<li>' . htmlspecialchars($database->get_last_error()->get_value_exact(), ENT_HTML5 | ENT_NOQUOTES | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</li>';
+    }
+    unset($query_result);
 
     if (is_null($user_data['id_user'])) {
       if (is_null($ldap_data)) {
         $query_result = $database->do_query('insert into v_users_self_insert (id_sort, name_machine) values (' . $id_sort . ', user)');
+        if ($query_result instanceof c_base_return_false) {
+          if (!isset($stuff['errors'])) {
+            $stuff['errors'] = '';
+          }
+
+          $stuff['errors'] .= '<li>' . htmlspecialchars($database->get_last_error()->get_value_exact(), ENT_HTML5 | ENT_NOQUOTES | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</li>';
+        }
+        unset($query_result);
       }
       else {
         $email = explode('@', $ldap_data['mail']);
           $email[1],
           $ldap_data['employeenumber'],
         );
-        #$query_result = $database->do_query('insert into v_users_self_insert (id_sort, name_machine, name_human.first, name_human.last, name_human.complete, address_email.name, address_email.domain, address_email.private, id_external) values (' . $id_sort . ', user, $1, $2, $3, $4, $5, t, $6)', $parameters);
+
         $query_result = $database->do_query('insert into v_users_self_insert (id_sort, name_machine, name_human.first, name_human.last, name_human.complete, address_email, id_external) values (' . $id_sort . ', user, $1, $2, $3, ($4, $5, TRUE), $6)', $parameters);
+        if ($query_result instanceof c_base_return_false) {
+          if (!isset($stuff['errors'])) {
+            $stuff['errors'] = '';
+          }
+
+          $stuff['errors'] .= '<li>' . htmlspecialchars($database->get_last_error()->get_value_exact(), ENT_HTML5 | ENT_NOQUOTES | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</li>';
+        }
+        unset($query_result);
       }
 
       $user_data['id_user'] = 1;
           }
         }
       }
+      else {
+        if (!isset($stuff['errors'])) {
+          $stuff['errors'] = '';
+        }
+
+        $stuff['errors'] .= '<li>' . htmlspecialchars($database->get_last_error()->get_value_exact(), ENT_HTML5 | ENT_NOQUOTES | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</li>';
+      }
+      unset($query_result);
     }
 
     return $user_data;
         }
       }
     }
+    else {
+      if (!isset($stuff['errors'])) {
+        $stuff['errors'] = '';
+      }
+
+      $stuff['errors'] .= '<li>' . htmlspecialchars($database->get_last_error()->get_value_exact(), ENT_HTML5 | ENT_NOQUOTES | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</li>';
+    }
+    unset($query_result);
 
     return $values;
   }
         }
       }
     }
+    else {
+      if (!isset($stuff['errors'])) {
+        $stuff['errors'] = '';
+      }
+
+      $stuff['errors'] .= '<li>' . htmlspecialchars($database->get_last_error()->get_value_exact(), ENT_HTML5 | ENT_NOQUOTES | ENT_DISALLOWED | ENT_SUBSTITUTE, 'UTF-8') . '</li>';
+    }
+    unset($query_result);
 
     return $values;
   }
     $packet_size_target = 63;
     $packet_size_client = 1;
 
-    $socket = socket_create($socket_family, $socket_type, $socket_protocol);
-    if ($socket === FALSE) {
-      socket_close($socket);
-      return FALSE;
+    $socket = @socket_create($socket_family, $socket_type, $socket_protocol);
+    if (!is_resource($socket)) {
+      unset($socket);
+
+      $socket_error = @socket_last_error();
+
+      @socket_clear_error();
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_create', ':socket_error' => $socket_error, ':socket_error_message' => @socket_strerror($socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      unset($socket_error);
+
+      return c_base_return_error::s_false($error);
     }
-    unset($socket);
 
-    $connected = socket_connect($socket, $socket_path, $socket_port);
+    $connected = @socket_connect($socket, $socket_path, $socket_port);
     if ($connected === FALSE) {
-      socket_close($socket);
-      return FALSE;
+      unset($connected);
+
+      $socket_error = @socket_last_error($socket);
+      @socket_clear_error($socket);
+
+      @socket_close($socket);
+      unset($socket);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_connect', ':socket_error' => $socket_error, ':socket_error_message' => @socket_strerror($socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      unset($socket_error);
+
+      return c_base_return_error::s_false($error);
     }
     unset($connected);
 
       $packet = pack('a' . $name_length, $user_name);
     }
 
-    $written = socket_write($socket, $packet, $packet_size_target);
+    $written = @socket_write($socket, $packet, $packet_size_target);
     if ($written === FALSE) {
-      socket_close($socket);
-      return FALSE;
+      unset($written);
+
+      $socket_error = @socket_last_error($socket);
+      @socket_clear_error($socket);
+
+      @socket_close($socket);
+      unset($socket);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_write', ':socket_error' => $socket_error, ':socket_error_message' => @socket_strerror($socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      unset($socket_error);
+
+      return c_base_return_error::s_false($error);
     }
     unset($written);
 
-    $response = socket_read($socket, $packet_size_client);
-    socket_close($socket);
+    $response = @socket_read($socket, $packet_size_client);
+    if ($response === FALSE) {
+      unset($response);
+
+      $socket_error = @socket_last_error($socket);
+      @socket_clear_error($socket);
+
+      @socket_close($socket);
+      unset($socket);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_read', ':socket_error' => $socket_error, ':socket_error_message' => @socket_strerror($socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      unset($socket_error);
+
+      return c_base_return_error::s_false($error);
+    }
+    @socket_close($socket);
+    unset($socket);
+
     if (!is_string($response) || strlen($response) == 0) {
+      unset($response);
       return FALSE;
     }
     unset($response);
     //   10 = connection timed out when reading or writing.
     //   11 = the connection is being forced closed.
     //   12 = the connection is closing because the service is quitting.
-    return $response_value;
+    return c_base_return_int::s_new($response_value);
   }
 
   function ldap(&$stuff, $username) {
     unset($agent_string);
   }
 
-  $stuff = array(
-    'resources' => array(
-      'time' => microtime(TRUE),
-     ),
-  );
-
+  process_received_headers($stuff);
   existence_cookie($stuff);
   session($stuff);
-  headers($stuff);
+  send_prepared_headers($stuff);
   theme($stuff);
index aa7ba2c114399abfdcd1294e13005589fe3917b7..b75ca7860a16caf75daf24a16c75e0162ad3305d 100644 (file)
@@ -260,7 +260,15 @@ function reservation_attempt_login(&$database, &$settings, &$session) {
     if (c_base_return::s_has_error($result)) {
       // @todo: process each error message.
       $problem = new c_base_form_problem();
-      $problem->set_value('Failed to load session.');
+
+      $socket_error = $session->get_socket_error()->get_value();
+      if ($socket_error instanceof c_base_return_int) {
+        $problem->set_value('Failed to load session, due to socket error (' . $socket_error . '): ' . @socket_strerror($socket_error) . '.');
+      }
+      else {
+        $problem->set_value('Failed to load session.');
+      }
+      unset($socket_error);
 
       $problems[] = $problem;
       unset($problem);
@@ -297,6 +305,22 @@ function reservation_attempt_login(&$database, &$settings, &$session) {
       $session_expire = $session->get_timeout_expire()->get_value_exact();
       $cookie_login = $session->get_cookie();
 
+      if (c_base_return::s_has_error($pushed)) {
+        $problem = new c_base_form_problem();
+
+        $socket_error = $session->get_socket_error()->get_value();
+        if ($socket_error instanceof c_base_return_int) {
+          $problem->set_value('Failed to push session, due to socket error (' . $socket_error . '): ' . @socket_strerror($socket_error) . '.');
+        }
+        else {
+          $problem->set_value('Failed to push session.');
+        }
+        unset($socket_error);
+
+        $problems[] = $problem;
+        unset($problem);
+      }
+
       if ($cookie_login instanceof c_base_cookie) {
         $cookie_login->set_expires($session_expire);
         $cookie_login->set_max_age(NULL);
@@ -304,7 +328,7 @@ function reservation_attempt_login(&$database, &$settings, &$session) {
         if ($pushed instanceof c_base_return_true) {
           $data = array(
             'session_id' => $session->get_session_id()->get_value_exact(),
-            'expire' => gmdate("D, d-M-Y H:i:s T", $session_expire), // unecessary, but provided for debug purposes.
+            'expire' => gmdate("D, d-M-Y H:i:s T", $session_expire), // unnecessary, but provided for debug purposes.
           );
 
           $cookie_login->set_value($data);
index 083d11200593e778912e79cddce2b3a951393bf0..386f0cfece8a8df9b56f820693661dadd1f0b3e1 100644 (file)
       return c_base_return_error::s_false($error);
     }
 
-    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
-    if ($socket === FALSE) {
-      socket_close($socket);
+    $socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+    if (!is_resource($socket)) {
       unset($socket);
 
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_create', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::OPERATION_FAILURE);
+      $this->socket_error = @socket_last_error();
+      @socket_clear_error();
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_create', ':socket_error' => $this->socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
       return c_base_return_error::s_false($error);
     }
 
     $connected = @socket_connect($socket, $settings['database_create_account_host'], $settings['database_create_account_port']);
     if ($connected === FALSE) {
-      socket_close($socket);
+      $socket_error = @socket_last_error($socket);
+
+      @socket_close($socket);
+      @socket_clear_error();
+
       unset($socket);
       unset($connected);
 
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_connect', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::OPERATION_FAILURE);
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_connect', ':socket_error' => $socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      unset($socket_error);
+
       return c_base_return_error::s_false($error);
     }
 
       $packet = pack('a' . $name_length, $user_name);
     }
 
-    $written = socket_write($socket, $packet, $packet_size_target);
+    $written = @socket_write($socket, $packet, $packet_size_target);
 
     unset($packet);
     unset($packet_size_target);
     unset($difference);
 
     if ($written === FALSE) {
-      socket_close($socket);
       unset($written);
-      unset($socket);
       unset($packet_size_client);
 
-      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_write', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::OPERATION_FAILURE);
+      $socket_error = @socket_last_error($socket);
+
+      @socket_close($socket);
+      @socket_clear_error();
+
+      unset($socket);
+      unset($connected);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_write', ':socket_error' => $socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      unset($socket_error);
+
       return c_base_return_error::s_false($error);
     }
     unset($written);
 
     $response = @socket_read($socket, $packet_size_client);
-    socket_close($socket);
+    if ($response === FALSE) {
+      unset($response);
+      unset($packet_size_client);
+
+      $socket_error = @socket_last_error($socket);
+
+      @socket_close($socket);
+      @socket_clear_error();
+
+      unset($socket);
+      unset($connected);
+
+      $error = c_base_error::s_log(NULL, array('arguments' => array(':operation_name' => 'socket_read', ':socket_error' => $socket_error, ':socket_error_message' => @socket_strerror($this->socket_error), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::SOCKET_FAILURE);
+      unset($socket_error);
+
+      return c_base_return_error::s_false($error);
+    }
+
+    @socket_close($socket);
     unset($socket);
     unset($packet_size_client);