From d2e8b01e308e6dbd960cfd4d6277a4289ed0440c Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 31 Jul 2019 14:46:31 +0200 Subject: [PATCH 01/22] - codeigniter-restserver is now provided and loaded via composer (libraries/REST_Controller.php, config/rest.php, language/english/rest_controller_lang.php, libraries/Format.php, etc) - Added new core controller core/RESTFul_Controller.php that extends REST_Controller and partially overrides part of the latter - Changed application/config/rest.php to keep the minimal useful set of configs - Controllers core/APIv1_Controller, controllers/api/v1/CheckUserAuth.php and controllers/api/v1/Test.php now extend core/RESTFul_Controller - Changed method _remap interface for core/APIv1_Controller - Removed application/core/REST_Controller.php - Removed application/libraries/Format.php - Removed application/language/english/rest_controller_lang.php --- application/config/rest.php | 391 +-- application/config/routes.php | 20 +- .../controllers/api/v1/CheckUserAuth.php | 2 +- application/controllers/api/v1/Test.php | 2 +- application/core/APIv1_Controller.php | 11 +- application/core/RESTFul_Controller.php | 215 ++ application/core/REST_Controller.php | 2166 ----------------- .../language/english/rest_controller_lang.php | 17 - application/libraries/Format.php | 531 ---- composer.json | 1 + composer.lock | 63 +- 11 files changed, 305 insertions(+), 3114 deletions(-) create mode 100644 application/core/RESTFul_Controller.php delete mode 100644 application/core/REST_Controller.php delete mode 100644 application/language/english/rest_controller_lang.php delete mode 100644 application/libraries/Format.php diff --git a/application/config/rest.php b/application/config/rest.php index 9bbbf40ef..833a99881 100644 --- a/application/config/rest.php +++ b/application/config/rest.php @@ -1,6 +1,6 @@ '1234', 'test' => 'test']; - -/* -|-------------------------------------------------------------------------- -| Global IP Whitelisting -|-------------------------------------------------------------------------- -| -| Limit connections to your REST server to whitelisted IP addresses +| Limit connections to your REST server to White-listed IP addresses | | Usage: | 1. Set to TRUE and select an auth option for extreme security (client's IP -| address must be in whitelist and they must also log in) -| 2. Set to TRUE with auth set to FALSE to allow whitelisted IPs access with no login -| 3. Set to FALSE but set 'auth_override_class_method' to 'whitelist' to -| restrict certain methods to IPs in your whitelist +| address must be in white-list and they must also log in) +| 2. Set to TRUE with auth set to FALSE to allow White-listed IPs access with no login +| 3. Set to FALSE but set 'auth_override_class_method' to 'white-list' to +| restrict certain methods to IPs in your white-list | */ $config['rest_ip_whitelist_enabled'] = TRUE; /* |-------------------------------------------------------------------------- -| REST IP Whitelist +| REST IP White-list |-------------------------------------------------------------------------- | | Limit connections to your REST server with a comma separated @@ -240,42 +107,6 @@ $config['rest_ip_whitelist_enabled'] = TRUE; */ $config['rest_ip_whitelist'] = '127.0.0.1'; -/* -|-------------------------------------------------------------------------- -| Global IP Blacklisting -|-------------------------------------------------------------------------- -| -| Prevent connections to the REST server from blacklisted IP addresses -| -| Usage: -| 1. Set to TRUE and add any IP address to 'rest_ip_blacklist' -| -*/ -$config['rest_ip_blacklist_enabled'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| REST IP Blacklist -|-------------------------------------------------------------------------- -| -| Prevent connections from the following IP addresses -| -| e.g: '123.456.789.0, 987.654.32.1' -| -*/ -$config['rest_ip_blacklist'] = ''; - -/* -|-------------------------------------------------------------------------- -| REST Database Group -|-------------------------------------------------------------------------- -| -| Connect to a database group for keys, logging, etc. It will only connect -| if you have any of these features enabled -| -*/ -$config['rest_database_group'] = 'default'; - /* |-------------------------------------------------------------------------- | REST API Keys Table Name @@ -298,6 +129,7 @@ $config['rest_keys_table'] = 'ci_apikey'; | Default table schema: | CREATE TABLE `keys` ( | `id` INT(11) NOT NULL AUTO_INCREMENT, +| `user_id` INT(11) NOT NULL, | `key` VARCHAR(40) NOT NULL, | `level` INT(2) NOT NULL, | `ignore_limits` TINYINT(1) NOT NULL DEFAULT '0', @@ -310,45 +142,6 @@ $config['rest_keys_table'] = 'ci_apikey'; */ $config['rest_enable_keys'] = TRUE; -/* -|-------------------------------------------------------------------------- -| REST Table Key Column Name -|-------------------------------------------------------------------------- -| -| If not using the default table schema in 'rest_enable_keys', specify the -| column name to match e.g. my_key -| -*/ -$config['rest_key_column'] = 'key'; - -/* -|-------------------------------------------------------------------------- -| REST API Limits method -|-------------------------------------------------------------------------- -| -| Specify the method used to limit the API calls -| -| Available methods are : -| $config['rest_limits_method'] = 'API_KEY'; // Put a limit per api key -| $config['rest_limits_method'] = 'METHOD_NAME'; // Put a limit on method calls -| $config['rest_limits_method'] = 'ROUTED_URL'; // Put a limit on the routed URL -| -*/ -$config['rest_limits_method'] = 'ROUTED_URL'; - -/* -|-------------------------------------------------------------------------- -| REST Key Length -|-------------------------------------------------------------------------- -| -| Length of the created keys. Check your default database schema on the -| maximum length allowed -| -| Note: The maximum length is 40 -| -*/ -$config['rest_key_length'] = 40; - /* |-------------------------------------------------------------------------- | REST API Key Variable @@ -364,156 +157,10 @@ $config['rest_key_name'] = 'FHC-API-KEY'; /* |-------------------------------------------------------------------------- -| REST Enable Logging +| REST Methods name format |-------------------------------------------------------------------------- | -| When set to TRUE, the REST API will log actions based on the column names 'key', 'date', -| 'time' and 'ip_address'. This is a general rule that can be overridden in the -| $this->method array for each controller -| -| Default table schema: -| CREATE TABLE `logs` ( -| `id` INT(11) NOT NULL AUTO_INCREMENT, -| `uri` VARCHAR(255) NOT NULL, -| `method` VARCHAR(6) NOT NULL, -| `params` TEXT DEFAULT NULL, -| `api_key` VARCHAR(40) NOT NULL, -| `ip_address` VARCHAR(45) NOT NULL, -| `time` INT(11) NOT NULL, -| `rtime` FLOAT DEFAULT NULL, -| `authorized` VARCHAR(1) NOT NULL, -| `response_code` smallint(3) DEFAULT '0', -| PRIMARY KEY (`id`) -| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +| REST Controllers methods name format | */ -$config['rest_enable_logging'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| REST API Logs Table Name -|-------------------------------------------------------------------------- -| -| If not using the default table schema in 'rest_enable_logging', specify the -| table name to match e.g. my_logs -| -*/ -$config['rest_logs_table'] = 'logs'; - -/* -|-------------------------------------------------------------------------- -| REST Method Access Control -|-------------------------------------------------------------------------- -| When set to TRUE, the REST API will check the access table to see if -| the API key can access that controller. 'rest_enable_keys' must be enabled -| to use this -| -| Default table schema: -| CREATE TABLE `access` ( -| `id` INT(11) unsigned NOT NULL AUTO_INCREMENT, -| `key` VARCHAR(40) NOT NULL DEFAULT '', -| `controller` VARCHAR(50) NOT NULL DEFAULT '', -| `date_created` DATETIME DEFAULT NULL, -| `date_modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -| PRIMARY KEY (`id`) -| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -| -*/ -$config['rest_enable_access'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| REST API Access Table Name -|-------------------------------------------------------------------------- -| -| If not using the default table schema in 'rest_enable_access', specify the -| table name to match e.g. my_access -| -*/ -$config['rest_access_table'] = 'access'; - -/* -|-------------------------------------------------------------------------- -| REST API Param Log Format -|-------------------------------------------------------------------------- -| -| When set to TRUE, the REST API log parameters will be stored in the database as JSON -| Set to FALSE to log as serialized PHP -| -*/ -$config['rest_logs_json_params'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| REST Enable Limits -|-------------------------------------------------------------------------- -| -| When set to TRUE, the REST API will count the number of uses of each method -| by an API key each hour. This is a general rule that can be overridden in the -| $this->method array in each controller -| -| Default table schema: -| CREATE TABLE `limits` ( -| `id` INT(11) NOT NULL AUTO_INCREMENT, -| `uri` VARCHAR(255) NOT NULL, -| `count` INT(10) NOT NULL, -| `hour_started` INT(11) NOT NULL, -| `api_key` VARCHAR(40) NOT NULL, -| PRIMARY KEY (`id`) -| ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -| -| To specify the limits within the controller's __construct() method, add per-method -| limits with: -| -| $this->method['METHOD_NAME']['limit'] = [NUM_REQUESTS_PER_HOUR]; -| -| See application/controllers/api/example.php for examples -*/ -$config['rest_enable_limits'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| REST API Limits Table Name -|-------------------------------------------------------------------------- -| -| If not using the default table schema in 'rest_enable_limits', specify the -| table name to match e.g. my_limits -| -*/ -$config['rest_limits_table'] = 'limits'; - -/* -|-------------------------------------------------------------------------- -| REST Ignore HTTP Accept -|-------------------------------------------------------------------------- -| -| Set to TRUE to ignore the HTTP Accept and speed up each request a little. -| Only do this if you are using the $this->rest_format or /format/xml in URLs -| -*/ -$config['rest_ignore_http_accept'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| REST AJAX Only -|-------------------------------------------------------------------------- -| -| Set to TRUE to allow AJAX requests only. Set to FALSE to accept HTTP requests -| -| Note: If set to TRUE and the request is not AJAX, a 505 response with the -| error message 'Only AJAX requests are accepted.' will be returned. -| -| Hint: This is good for production environments -| -*/ -$config['rest_ajax_only'] = FALSE; - -/* -|-------------------------------------------------------------------------- -| REST Language File -|-------------------------------------------------------------------------- -| -| Language file to load from the language directory -| -*/ -$config['rest_language'] = 'english'; +$config['rest_methods_name_format'] = '%2$s%1$s'; diff --git a/application/config/routes.php b/application/config/routes.php index 791b6d03c..36bfdcb1e 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -1,5 +1,6 @@ my_controller/index -| my-controller/my-method -> my_controller/my_method +| Examples: my-controller/index -> my_controller/index +| my-controller/my-method -> my_controller/my_method */ $route['default_controller'] = 'Vilesci'; -$route['404_override'] = ''; $route['translate_uri_dashes'] = FALSE; // Class name conflicts @@ -59,4 +59,4 @@ $route['api/v1/organisation/[F|f]achbereich/(:any)'] = 'api/v1/organisation/fach $route['api/v1/organisation/[G|g]eschaeftsjahr/(:any)'] = 'api/v1/organisation/geschaeftsjahr2/$1'; $route['api/v1/organisation/[O|o]rganisationseinheit/(:any)'] = 'api/v1/organisation/organisationseinheit2/$1'; $route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/betriebsmittelperson2/$1'; -$route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1'; \ No newline at end of file +$route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1'; diff --git a/application/controllers/api/v1/CheckUserAuth.php b/application/controllers/api/v1/CheckUserAuth.php index 4d6522fe2..ee751e886 100644 --- a/application/controllers/api/v1/CheckUserAuth.php +++ b/application/controllers/api/v1/CheckUserAuth.php @@ -2,7 +2,7 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); -class CheckUserAuth extends REST_Controller +class CheckUserAuth extends RESTFul_Controller { /** * Course API constructor. diff --git a/application/controllers/api/v1/Test.php b/application/controllers/api/v1/Test.php index 41feb1a16..c9918f52b 100644 --- a/application/controllers/api/v1/Test.php +++ b/application/controllers/api/v1/Test.php @@ -5,7 +5,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** * Testing class for REST calls and authentication */ -class Test extends REST_Controller +class Test extends RESTFul_Controller { public function __construct() { diff --git a/application/core/APIv1_Controller.php b/application/core/APIv1_Controller.php index 6432c87db..da9848f01 100644 --- a/application/core/APIv1_Controller.php +++ b/application/core/APIv1_Controller.php @@ -1,9 +1,11 @@ isEntitled * - Checks if the caller is allowed to access to this content with the given permissions * if it is not allowed will set the HTTP header with code 401 * - Calls the parent (REST_Controller) _remap method to performs other checks + * NOTE: this methods override the parent method!!! */ - public function _remap($object_called, $arguments) + public function _remap($object_called, $arguments = []) { if (isset($this->authlib)) // if set then the authentication is ok { diff --git a/application/core/RESTFul_Controller.php b/application/core/RESTFul_Controller.php new file mode 100644 index 000000000..984f193de --- /dev/null +++ b/application/core/RESTFul_Controller.php @@ -0,0 +1,215 @@ +load->helper('hlp_return_object'); + + // Loads helper session to manage the php session + $this->load->helper('hlp_session'); + + // Loads helper with generic utility function + $this->load->helper('hlp_common'); + } + + /** + * Totally overrode parent's _perform_library_auth method to keep file and class name + * for AuthLib and to call AuthLib with the extra parameter + */ + protected function _perform_library_auth($username = '', $password = NULL) + { + if (empty($username)) + { + log_message('error', 'Library Auth: Failure, empty username'); + return FALSE; + } + + $auth_library_class = $this->config->item('auth_library_class'); + $auth_library_function = $this->config->item('auth_library_function'); + + if (empty($auth_library_class)) + { + log_message('debug', 'Library Auth: Failure, empty auth_library_class'); + return FALSE; + } + + if (empty($auth_library_function)) + { + log_message('debug', 'Library Auth: Failure, empty auth_library_function'); + return FALSE; + } + + if (is_callable([$auth_library_class, $auth_library_function]) === FALSE) + { + $this->load->library($auth_library_class, array(false)); + } + + return $this->{strtolower($auth_library_class)}->$auth_library_function($username, $password); + } + + /** + * Totally overrode parent's _remap method to change the naming convention of controllers methods + */ + public function _remap($object_called, $arguments = []) + { + // Should we answer if not over SSL? + if ($this->config->item('force_https') && $this->request->ssl === FALSE) + { + $this->response([ + $this->config->item('rest_status_field_name') => FALSE, + $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unsupported') + ], self::HTTP_FORBIDDEN); + + $this->is_valid_request = false; + } + + // Remove the supported format from the function name e.g. index.json => index + $object_called = preg_replace('/^(.*)\.(?:'.implode('|', array_keys($this->_supported_formats)).')$/', '$1', $object_called); + + // NOTE: START changes + $controller_method = $object_called.'_'.$this->request->method; // Method name fallback + // If the config entry rest_methods_name_format is provided and is not empty then use it to produce the method name + if (!empty($this->config->item('rest_methods_name_format'))) + { + $controller_method = sprintf($this->config->item('rest_methods_name_format'), $object_called, $this->request->method); + } + // END changes + + // Does this method exist? If not, try executing an index method + if (!method_exists($this, $controller_method)) { + $controller_method = "index_" . $this->request->method; + array_unshift($arguments, $object_called); + } + + // Do we want to log this method (if allowed by config)? + $log_method = ! (isset($this->methods[$controller_method]['log']) && $this->methods[$controller_method]['log'] === FALSE); + + // Use keys for this method? + $use_key = ! (isset($this->methods[$controller_method]['key']) && $this->methods[$controller_method]['key'] === FALSE); + + // They provided a key, but it wasn't valid, so get them out of here + if ($this->config->item('rest_enable_keys') && $use_key && $this->_allow === FALSE) + { + if ($this->config->item('rest_enable_logging') && $log_method) + { + $this->_log_request(); + } + + // fix cross site to option request error + if($this->request->method == 'options') { + exit; + } + + $this->response([ + $this->config->item('rest_status_field_name') => FALSE, + $this->config->item('rest_message_field_name') => sprintf($this->lang->line('text_rest_invalid_api_key'), $this->rest->key) + ], self::HTTP_FORBIDDEN); + + $this->is_valid_request = false; + } + + // Check to see if this key has access to the requested controller + if ($this->config->item('rest_enable_keys') && $use_key && empty($this->rest->key) === FALSE && $this->_check_access() === FALSE) + { + if ($this->config->item('rest_enable_logging') && $log_method) + { + $this->_log_request(); + } + + $this->response([ + $this->config->item('rest_status_field_name') => FALSE, + $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_unauthorized') + ], self::HTTP_UNAUTHORIZED); + + $this->is_valid_request = false; + } + + // Sure it exists, but can they do anything with it? + if (! method_exists($this, $controller_method)) + { + $this->response([ + $this->config->item('rest_status_field_name') => FALSE, + $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unknown_method') + ], self::HTTP_METHOD_NOT_ALLOWED); + + $this->is_valid_request = false; + } + + // Doing key related stuff? Can only do it if they have a key right? + if ($this->config->item('rest_enable_keys') && empty($this->rest->key) === FALSE) + { + // Check the limit + if ($this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === FALSE) + { + $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_time_limit')]; + $this->response($response, self::HTTP_UNAUTHORIZED); + + $this->is_valid_request = false; + } + + // If no level is set use 0, they probably aren't using permissions + $level = isset($this->methods[$controller_method]['level']) ? $this->methods[$controller_method]['level'] : 0; + + // If no level is set, or it is lower than/equal to the key's level + $authorized = $level <= $this->rest->level; + // IM TELLIN! + if ($this->config->item('rest_enable_logging') && $log_method) + { + $this->_log_request($authorized); + } + if($authorized === FALSE) + { + // They don't have good enough perms + $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_permissions')]; + $this->response($response, self::HTTP_UNAUTHORIZED); + + $this->is_valid_request = false; + } + } + + //check request limit by ip without login + elseif ($this->config->item('rest_limits_method') == "IP_ADDRESS" && $this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === FALSE) + { + $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_address_time_limit')]; + $this->response($response, self::HTTP_UNAUTHORIZED); + + $this->is_valid_request = false; + } + + // No key stuff, but record that stuff is happening + elseif ($this->config->item('rest_enable_logging') && $log_method) + { + $this->_log_request($authorized = TRUE); + } + + // Call the controller method and passed arguments + try + { + if ($this->is_valid_request) { + call_user_func_array([$this, $controller_method], $arguments); + } + } + catch (Exception $ex) + { + if ($this->config->item('rest_handle_exceptions') === FALSE) { + throw $ex; + } + + // If the method doesn't exist, then the error will be caught and an error response shown + $_error = &load_class('Exceptions', 'core'); + $_error->show_exception($ex); + } + } +} diff --git a/application/core/REST_Controller.php b/application/core/REST_Controller.php deleted file mode 100644 index 9cd276556..000000000 --- a/application/core/REST_Controller.php +++ /dev/null @@ -1,2166 +0,0 @@ - 'application/json', - 'array' => 'application/json', - 'csv' => 'application/csv', - 'html' => 'text/html', - 'jsonp' => 'application/javascript', - 'php' => 'text/plain', - 'serialized' => 'application/vnd.php.serialized', - 'xml' => 'application/xml' - ]; - - /** - * Information about the current API user - * - * @var object - */ - protected $_apiuser; - - /** - * Enable XSS flag - * Determines whether the XSS filter is always active when - * GET, OPTIONS, HEAD, POST, PUT, DELETE and PATCH data is encountered. - * Set automatically based on config setting - * - * @var bool - */ - protected $_enable_xss = FALSE; - - /** - * HTTP status codes and their respective description - * Note: Only the widely used HTTP status codes are used - * - * @var array - * @link http://www.restapitutorial.com/httpstatuscodes.html - */ - protected $http_status_codes = [ - self::HTTP_OK => 'OK', - self::HTTP_CREATED => 'CREATED', - self::HTTP_NO_CONTENT => 'NO CONTENT', - self::HTTP_NOT_MODIFIED => 'NOT MODIFIED', - self::HTTP_BAD_REQUEST => 'BAD REQUEST', - self::HTTP_UNAUTHORIZED => 'UNAUTHORIZED', - self::HTTP_FORBIDDEN => 'FORBIDDEN', - self::HTTP_NOT_FOUND => 'NOT FOUND', - self::HTTP_METHOD_NOT_ALLOWED => 'METHOD NOT ALLOWED', - self::HTTP_NOT_ACCEPTABLE => 'NOT ACCEPTABLE', - self::HTTP_CONFLICT => 'CONFLICT', - self::HTTP_INTERNAL_SERVER_ERROR => 'INTERNAL SERVER ERROR', - self::HTTP_NOT_IMPLEMENTED => 'NOT IMPLEMENTED' - ]; - - /** - * Extend this function to apply additional checking early on in the process - * - * @access protected - * @return void - */ - protected function early_checks() - { - // Loads helper message to manage returning messages - $this->load->helper('hlp_return_object'); - - // Loads helper session to manage the php session - $this->load->helper('hlp_session'); - - // Loads helper with generic utility function - $this->load->helper('hlp_common'); - } - - /** - * Constructor for the REST API - * - * @access public - * @param string $config Configuration filename minus the file extension - * e.g: my_rest.php is passed as 'my_rest' - * @return void - */ - public function __construct($config = 'rest') - { - parent::__construct(); - - // Disable XML Entity (security vulnerability) - libxml_disable_entity_loader(TRUE); - - // Check to see if PHP is equal to or greater than 5.4.x - if (is_php('5.4') === FALSE) - { - // CodeIgniter 3 is recommended for v5.4 or above - throw new Exception('Using PHP v' . PHP_VERSION . ', though PHP v5.4 or greater is required'); - } - - // Check to see if this is CI 3.x - $ci_version_number = explode('.', CI_VERSION, 2); - if ($ci_version_number[0] < 3) - { - throw new Exception('REST Server requires CodeIgniter 3.x'); - } - - // Set the default value of global xss filtering. Same approach as CodeIgniter 3 - $this->_enable_xss = ($this->config->item('global_xss_filtering') === TRUE); - - // Don't try to parse template variables like {elapsed_time} and {memory_usage} - // when output is displayed for not damaging data accidentally - $this->output->parse_exec_vars = FALSE; - - // Start the timer for how long the request takes - $this->_start_rtime = microtime(TRUE); - - // Load the rest.php configuration file - $this->load->config($config); - - // At present the library is bundled with REST_Controller 2.5+, but will eventually be part of CodeIgniter (no citation) - $this->load->library('format'); - - // Determine supported output formats from configiguration. - $supported_formats = $this->config->item('rest_supported_formats'); - - // Validate the configuration setting output formats - if (empty($supported_formats)) - { - $supported_formats = []; - } - - if (!is_array($supported_formats)) - { - $supported_formats = [$supported_formats]; - } - - // Add silently the default output format if it is missing. - $default_format = $this->_get_default_output_format(); - if (!in_array($default_format, $supported_formats)) - { - $supported_formats[] = $default_format; - } - - // Now update $this->_supported_formats - $this->_supported_formats = array_intersect_key($this->_supported_formats, array_flip($supported_formats)); - - // Get the language - $language = $this->config->item('rest_language'); - if ($language === NULL) - { - $language = 'en-US'; - } - - // Load the language file - $this->lang->load('rest_controller', $language); - - // Initialise the response, request and rest objects - $this->request = new stdClass(); - $this->response = new stdClass(); - $this->rest = new stdClass(); - - // Check to see if the current IP address is blacklisted - if ($this->config->item('rest_ip_blacklist_enabled') === TRUE) - { - $this->_check_blacklist_auth(); - } - - // Determine whether the connection is HTTPS - $this->request->ssl = is_https(); - - // How is this request being made? GET, POST, PATCH, DELETE, INSERT, PUT, HEAD or OPTIONS - $this->request->method = $this->_detect_method(); - - // Create an argument container if it doesn't exist e.g. _get_args - if (isset($this->{'_' . $this->request->method . '_args'}) === FALSE) - { - $this->{'_' . $this->request->method . '_args'} = []; - } - - // Set up the query parameters - $this->_parse_query(); - - // Set up the GET variables - $this->_get_args = array_merge($this->_get_args, $this->uri->ruri_to_assoc()); - - // Try to find a format for the request (means we have a request body) - $this->request->format = $this->_detect_input_format(); - - // Not all methods have a body attached with them - $this->request->body = NULL; - - $this->{'_parse_' . $this->request->method}(); - - // Now we know all about our request, let's try and parse the body if it exists - if ($this->request->format && $this->request->body) - { - $this->request->body = $this->format->factory($this->request->body, $this->request->format)->to_array(); - // Assign payload arguments to proper method container - $this->{'_' . $this->request->method . '_args'} = $this->request->body; - } - - // Merge both for one mega-args variable - $this->_args = array_merge( - $this->_get_args, - $this->_options_args, - $this->_patch_args, - $this->_head_args, - $this->_put_args, - $this->_post_args, - $this->_delete_args, - $this->{'_' . $this->request->method . '_args'} - ); - - // Which format should the data be returned in? - $this->response->format = $this->_detect_output_format(); - - // Which language should the data be returned in? - $this->response->lang = $this->_detect_lang(); - - // Extend this function to apply additional checking early on in the process - $this->early_checks(); - - // Load DB if its enabled - if ($this->config->item('rest_database_group') && ($this->config->item('rest_enable_keys') || $this->config->item('rest_enable_logging'))) - { - $this->rest->db = $this->load->database($this->config->item('rest_database_group'), TRUE); - } - - // Use whatever database is in use (isset returns FALSE) - elseif (property_exists($this, 'db')) - { - $this->rest->db = $this->db; - } - - // Check if there is a specific auth type for the current class/method - // _auth_override_check could exit so we need $this->rest->db initialized before - $this->auth_override = $this->_auth_override_check(); - - // Checking for keys? GET TO WorK! - // Skip keys test for $config['auth_override_class_method']['class'['method'] = 'none' - if ($this->config->item('rest_enable_keys') && $this->auth_override !== TRUE) - { - $this->_allow = $this->_detect_api_key(); - } - - // Only allow ajax requests - if ($this->input->is_ajax_request() === FALSE && $this->config->item('rest_ajax_only')) - { - // Display an error response - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ajax_only') - ], self::HTTP_NOT_ACCEPTABLE); - } - - // When there is no specific override for the current class/method, use the default auth value set in the config - if ($this->auth_override === FALSE && ($this->config->item('rest_enable_keys') && $this->_allow === TRUE)) - { - $rest_auth = strtolower($this->config->item('rest_auth')); - switch ($rest_auth) - { - case 'basic': - $this->_prepare_basic_auth(); - break; - case 'digest': - $this->_prepare_digest_auth(); - break; - case 'session': - $this->_check_php_session(); - break; - } - if ($this->config->item('rest_ip_whitelist_enabled') === TRUE) - { - $this->_check_whitelist_auth(); - } - } - } - - /** - * Deconstructor - * - * @author Chris Kacerguis - * @access public - * @return void - */ - public function __destruct() - { - // Get the current timestamp - $this->_end_rtime = microtime(TRUE); - - // Log the loading time to the log table - if ($this->config->item('rest_enable_logging') === TRUE) - { - $this->_log_access_time(); - } - } - - /** - * Requests are not made to methods directly, the request will be for - * an "object". This simply maps the object and method to the correct - * Controller method - * - * @access public - * @param string $object_called - * @param array $arguments The arguments passed to the controller method - */ - public function _remap($object_called, $arguments) - { - // Should we answer if not over SSL? - if ($this->config->item('force_https') && $this->request->ssl === FALSE) - { - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unsupported') - ], self::HTTP_FORBIDDEN); - } - - // Remove the supported format from the function name e.g. index.json => index - $object_called = preg_replace('/^(.*)\.(?:' . implode('|', array_keys($this->_supported_formats)) . ')$/', '$1', $object_called); - - //$controller_method = $object_called . '_' . $this->request->method; - // CamelCase compliant - $controller_method = $this->request->method.ucfirst($object_called); - - // Do we want to log this method (if allowed by config)? - $log_method = !(isset($this->methods[$controller_method]['log']) && $this->methods[$controller_method]['log'] === FALSE); - - // Use keys for this method? - $use_key = !(isset($this->methods[$controller_method]['key']) && $this->methods[$controller_method]['key'] === FALSE); - - // They provided a key, but it wasn't valid, so get them out of here - if ($this->config->item('rest_enable_keys') && $use_key && $this->_allow === FALSE) - { - if ($this->config->item('rest_enable_logging') && $log_method) - { - $this->_log_request(); - } - - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => sprintf($this->lang->line('text_rest_invalid_api_key'), $this->rest->key) - ], self::HTTP_FORBIDDEN); - } - - // Check to see if this key has access to the requested controller - if ($this->config->item('rest_enable_keys') && $use_key && empty($this->rest->key) === FALSE && $this->_check_access() === FALSE) - { - if ($this->config->item('rest_enable_logging') && $log_method) - { - $this->_log_request(); - } - - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_unauthorized') - ], self::HTTP_UNAUTHORIZED); - } - - // Sure it exists, but can they do anything with it? - if (method_exists($this, $controller_method) === FALSE) - { - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unknown_method') - ], self::HTTP_NOT_FOUND); - } - - // Doing key related stuff? Can only do it if they have a key right? - if ($this->config->item('rest_enable_keys') && empty($this->rest->key) === FALSE) - { - // Check the limit - if ($this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === FALSE) - { - $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_time_limit')]; - $this->response($response, self::HTTP_UNAUTHORIZED); - } - - // If no level is set use 0, they probably aren't using permissions - $level = isset($this->methods[$controller_method]['level']) ? $this->methods[$controller_method]['level'] : 0; - - // If no level is set, or it is lower than/equal to the key's level - $authorized = $level <= $this->rest->level; - - // IM TELLIN! - if ($this->config->item('rest_enable_logging') && $log_method) - { - $this->_log_request($authorized); - } - - // They don't have good enough perms - $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_permissions')]; - $authorized || $this->response($response, self::HTTP_UNAUTHORIZED); - } - - // No key stuff, but record that stuff is happening - elseif ($this->config->item('rest_enable_logging') && $log_method) - { - $this->_log_request($authorized = TRUE); - } - - // Call the controller method and passed arguments - try - { - call_user_func_array([$this, $controller_method], $arguments); - } - catch (Exception $ex) - { - // If the method doesn't exist, then the error will be caught and an error response shown - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => [ - 'classname' => get_class($ex), - 'message' => $ex->getMessage() - ] - ], self::HTTP_INTERNAL_SERVER_ERROR); - } - } - - /** - * Takes mixed data and optionally a status code, then creates the response - * - * @access public - * @param array|NULL $data Data to output to the user - * @param int|NULL $http_code HTTP status code - * @param bool $continue TRUE to flush the response to the client and continue - * running the script; otherwise, exit - */ - public function response($data = NULL, $http_code = NULL, $continue = FALSE) - { - // If the HTTP status is not NULL, then cast as an integer - if ($http_code !== NULL) - { - // So as to be safe later on in the process - $http_code = (int) $http_code; - } - - // Set the output as NULL by default - $output = NULL; - // If data is NULL and no HTTP status code provided, then display, error and exit - if ($data === NULL && $http_code === NULL) - { - $http_code = self::HTTP_NOT_FOUND; - } - - // If data is not NULL and a HTTP status code provided, then continue - elseif ($data !== NULL) - { - // If the format method exists, call and return the output in that format - if (method_exists($this->format, 'to_' . $this->response->format)) - { - // Set the format header - $this->output->set_content_type($this->_supported_formats[$this->response->format], strtolower($this->config->item('charset'))); - $output = $this->format->factory($data)->{'to_' . $this->response->format}(); - - // An array must be parsed as a string, so as not to cause an array to string error - // Json is the most appropriate form for such a datatype - if ($this->response->format === 'array') - { - $output = $this->format->factory($output)->{'to_json'}(); - } - } - else - { - // If an array or object, then parse as a json, so as to be a 'string' - if (is_array($data) || is_object($data)) - { - $data = $this->format->factory($data)->{'to_json'}(); - } - // Format is not supported, so output the raw data as a string - $output = $data; - } - } - - // If not greater than zero, then set the HTTP status code as 200 by default - // Though perhaps 500 should be set instead, for the developer not passing a - // correct HTTP status code - $http_code > 0 || $http_code = self::HTTP_OK; - - $this->output->set_status_header($http_code); - - // JC: Log response code only if rest logging enabled - if ($this->config->item('rest_enable_logging') === TRUE) - { - $this->_log_response_code($http_code); - } - - // Output the data - $this->output->set_output($output); - - if ($continue === FALSE) - { - // Display the data and exit execution - $this->output->_display(); - exit; - } - - // Otherwise dump the output automatically - } - - /** - * Takes mixed data and optionally a status code, then creates the response - * within the buffers of the Output class. The response is sent to the client - * lately by the framework, after the current controller's method termination. - * All the hooks after the controller's method termination are executable - * - * @access public - * @param array|NULL $data Data to output to the user - * @param int|NULL $http_code HTTP status code - */ - public function set_response($data = NULL, $http_code = NULL) - { - $this->response($data, $http_code, TRUE); - } - - /** - * Get the input format e.g. json or xml - * - * @access protected - * @return string|NULL Supported input format; otherwise, NULL - */ - protected function _detect_input_format() - { - // Get the CONTENT-TYPE value from the SERVER variable - $content_type = $this->input->server('CONTENT_TYPE'); - - if (empty($content_type) === FALSE) - { - // Check all formats against the HTTP_ACCEPT header - foreach ($this->_supported_formats as $key => $value) - { - // $key = format e.g. csv - // $value = mime type e.g. application/csv - - // If a semi-colon exists in the string, then explode by ; and get the value of where - // the current array pointer resides. This will generally be the first element of the array - $content_type = (strpos($content_type, ';') !== FALSE ? current(explode(';', $content_type)) : $content_type); - - // If both the mime types match, then return the format - if ($content_type === $value) - { - return $key; - } - } - } - - return NULL; - } - - /** - * Gets the default format from the configuration. Fallbacks to 'json'. - * if the corresponding configuration option $config['rest_default_format'] - * is missing or is empty. - * - * @access protected - * @return string The default supported input format - */ - protected function _get_default_output_format() - { - $default_format = (string) $this->config->item('rest_default_format'); - return $default_format === '' ? 'json' : $default_format; - } - - /** - * Detect which format should be used to output the data - * - * @access protected - * @return mixed|NULL|string Output format - */ - protected function _detect_output_format() - { - // Concatenate formats to a regex pattern e.g. \.(csv|json|xml) - $pattern = '/\.(' . implode('|', array_keys($this->_supported_formats)) . ')($|\/)/'; - $matches = []; - - // Check if a file extension is used e.g. http://example.com/api/index.json?param1=param2 - if (preg_match($pattern, $this->uri->uri_string(), $matches)) - { - return $matches[1]; - } - - // Get the format parameter named as 'format' - if (isset($this->_get_args['format'])) - { - $format = strtolower($this->_get_args['format']); - - if (isset($this->_supported_formats[$format]) === TRUE) - { - return $format; - } - } - - // Get the HTTP_ACCEPT server variable - $http_accept = $this->input->server('HTTP_ACCEPT'); - - // Otherwise, check the HTTP_ACCEPT server variable - if ($this->config->item('rest_ignore_http_accept') === FALSE && $http_accept !== NULL) - { - // Check all formats against the HTTP_ACCEPT header - foreach (array_keys($this->_supported_formats) as $format) - { - // Has this format been requested? - if (strpos($http_accept, $format) !== FALSE) - { - if ($format !== 'html' && $format !== 'xml') - { - // If not HTML or XML assume it's correct - return $format; - } - elseif ($format === 'html' && strpos($http_accept, 'xml') === FALSE) - { - // HTML or XML have shown up as a match - // If it is truly HTML, it wont want any XML - return $format; - } - else if ($format === 'xml' && strpos($http_accept, 'html') === FALSE) - { - // If it is truly XML, it wont want any HTML - return $format; - } - } - } - } - - // Check if the controller has a default format - if (empty($this->rest_format) === FALSE) - { - return $this->rest_format; - } - - // Obtain the default format from the configuration - return $this->_get_default_output_format(); - } - - /** - * Get the HTTP request string e.g. get or post - * - * @access protected - * @return string|NULL Supported request method as a lowercase string; otherwise, NULL if not supported - */ - protected function _detect_method() - { - // Declare a variable to store the method - $method = NULL; - - // Determine whether the 'enable_emulate_request' setting is enabled - if ($this->config->item('enable_emulate_request') === TRUE) - { - $method = $this->input->post('_method'); - if ($method === NULL) - { - $method = $this->input->server('HTTP_X_HTTP_METHOD_OVERRIDE'); - } - - $method = strtolower($method); - } - - if (empty($method)) - { - // Get the request method as a lowercase string - $method = $this->input->method(); - } - - return in_array($method, $this->allowed_http_methods) && method_exists($this, '_parse_' . $method) ? $method : 'get'; - } - - /** - * See if the user has provided an API key - * - * @access protected - * @return bool - */ - protected function _detect_api_key() - { - // Get the api key name variable set in the rest config file - $api_key_variable = $this->config->item('rest_key_name'); - - // Work out the name of the SERVER entry based on config - $key_name = 'HTTP_' . strtoupper(str_replace('-', '_', $api_key_variable)); - - $this->rest->key = NULL; - $this->rest->level = NULL; - $this->rest->user_id = NULL; - $this->rest->ignore_limits = FALSE; - - // Find the key from server or arguments - if (($key = isset($this->_args[$api_key_variable]) ? $this->_args[$api_key_variable] : $this->input->server($key_name))) - { - if (!($row = $this->rest->db->where($this->config->item('rest_key_column'), $key)->get($this->config->item('rest_keys_table'))->row())) - { - return FALSE; - } - - $this->rest->key = $row->{$this->config->item('rest_key_column')}; - - isset($row->user_id) && $this->rest->user_id = $row->user_id; - isset($row->level) && $this->rest->level = $row->level; - isset($row->ignore_limits) && $this->rest->ignore_limits = $row->ignore_limits; - - $this->_apiuser = $row; - - /* - * If "is private key" is enabled, compare the ip address with the list - * of valid ip addresses stored in the database - */ - if (empty($row->is_private_key) === FALSE) - { - // Check for a list of valid ip addresses - if (isset($row->ip_addresses)) - { - // multiple ip addresses must be separated using a comma, explode and loop - $list_ip_addresses = explode(',', $row->ip_addresses); - $found_address = FALSE; - - foreach ($list_ip_addresses as $ip_address) - { - if ($this->input->ip_address() === trim($ip_address)) - { - // there is a match, set the the value to TRUE and break out of the loop - $found_address = TRUE; - break; - } - } - - return $found_address; - } - else - { - // There should be at least one IP address for this private key - return FALSE; - } - } - - return TRUE; - } - - // No key has been sent - return FALSE; - } - - /** - * Preferred return language - * - * @access protected - * @return string|NULL The language code - */ - protected function _detect_lang() - { - $lang = $this->input->server('HTTP_ACCEPT_LANGUAGE'); - if ($lang === NULL) - { - return NULL; - } - - // It appears more than one language has been sent using a comma delimiter - if (strpos($lang, ',') !== FALSE) - { - $langs = explode(',', $lang); - - $return_langs = []; - foreach ($langs as $lang) - { - // Remove weight and trim leading and trailing whitespace - list($lang) = explode(';', $lang); - $return_langs[] = trim($lang); - } - - return $return_langs; - } - - // Otherwise simply return as a string - return $lang; - } - - /** - * Add the request to the log table - * - * @access protected - * @param bool $authorized TRUE the user is authorized; otherwise, FALSE - * @return bool TRUE the data was inserted; otherwise, FALSE - */ - protected function _log_request($authorized = FALSE) - { - // Insert the request into the log table - $is_inserted = $this->rest->db - ->insert( - $this->config->item('rest_logs_table'), [ - 'uri' => $this->uri->uri_string(), - 'method' => $this->request->method, - 'params' => $this->_args ? ($this->config->item('rest_logs_json_params') === TRUE ? json_encode($this->_args) : serialize($this->_args)) : NULL, - 'api_key' => isset($this->rest->key) ? $this->rest->key : '', - 'ip_address' => $this->input->ip_address(), - 'time' => time(), - 'authorized' => $authorized - ]); - - // Get the last insert id to update at a later stage of the request - $this->_insert_id = $this->rest->db->insert_id(); - - return $is_inserted; - } - - /** - * Check if the requests to a controller method exceed a limit - * - * @access protected - * @param string $controller_method The method being called - * @return bool TRUE the call limit is below the threshold; otherwise, FALSE - */ - protected function _check_limit($controller_method) - { - // They are special, or it might not even have a limit - if (empty($this->rest->ignore_limits) === FALSE) - { - // Everything is fine - return TRUE; - } - - switch ($this->config->item('rest_limits_method')) - { - case 'API_KEY': - $limited_uri = 'api-key:' . (isset($this->rest->key) ? $this->rest->key : ''); - $limited_method_name = isset($this->rest->key) ? $this->rest->key : ''; - break; - - case 'METHOD_NAME': - $limited_uri = 'method-name:' . $controller_method; - $limited_method_name = $controller_method; - break; - - case 'ROUTED_URL': - default: - $limited_uri = $this->uri->ruri_string(); - if (strpos(strrev($limited_uri), strrev($this->response->format)) === 0) - { - $limited_uri = substr($limited_uri,0, -strlen($this->response->format) - 1); - } - $limited_uri = 'uri:' . $limited_uri . ':' . $this->request->method; // It's good to differentiate GET from PUT - $limited_method_name = $controller_method; - break; - } - - if (isset($this->methods[$limited_method_name]['limit']) === FALSE ) - { - // Everything is fine - return TRUE; - } - - // How many times can you get to this method in a defined time_limit (default: 1 hour)? - $limit = $this->methods[$limited_method_name]['limit']; - - $time_limit = (isset($this->methods[$limited_method_name]['time']) ? $this->methods[$limited_method_name]['time'] : 3600); // 3600 = 60 * 60 - - // Get data about a keys' usage and limit to one row - $result = $this->rest->db - ->where('uri', $limited_uri) - ->where('api_key', $this->rest->key) - ->get($this->config->item('rest_limits_table')) - ->row(); - - // No calls have been made for this key - if ($result === NULL) - { - // Create a new row for the following key - $this->rest->db->insert($this->config->item('rest_limits_table'), [ - 'uri' => $limited_uri, - 'api_key' => isset($this->rest->key) ? $this->rest->key : '', - 'count' => 1, - 'hour_started' => time() - ]); - } - - // Been a time limit (or by default an hour) since they called - elseif ($result->hour_started < (time() - $time_limit)) - { - // Reset the started period and count - $this->rest->db - ->where('uri', $limited_uri) - ->where('api_key', isset($this->rest->key) ? $this->rest->key : '') - ->set('hour_started', time()) - ->set('count', 1) - ->update($this->config->item('rest_limits_table')); - } - - // They have called within the hour, so lets update - else - { - // The limit has been exceeded - if ($result->count >= $limit) - { - return FALSE; - } - - // Increase the count by one - $this->rest->db - ->where('uri', $limited_uri) - ->where('api_key', $this->rest->key) - ->set('count', 'count + 1', FALSE) - ->update($this->config->item('rest_limits_table')); - } - - return TRUE; - } - - /** - * Check if there is a specific auth type set for the current class/method/HTTP-method being called - * - * @access protected - * @return bool - */ - protected function _auth_override_check() - { - // Assign the class/method auth type override array from the config - $auth_override_class_method = $this->config->item('auth_override_class_method'); - - // Check to see if the override array is even populated - if (!empty($auth_override_class_method)) - { - // check for wildcard flag for rules for classes - if (!empty($auth_override_class_method[$this->router->class]['*'])) // Check for class overrides - { - // None auth override found, prepare nothing but send back a TRUE override flag - if ($auth_override_class_method[$this->router->class]['*'] === 'none') - { - return TRUE; - } - - // Basic auth override found, prepare basic - if ($auth_override_class_method[$this->router->class]['*'] === 'basic') - { - $this->_prepare_basic_auth(); - - return TRUE; - } - - // Digest auth override found, prepare digest - if ($auth_override_class_method[$this->router->class]['*'] === 'digest') - { - $this->_prepare_digest_auth(); - - return TRUE; - } - - // Session auth override found, check session - if ($auth_override_class_method[$this->router->class]['*'] === 'session') - { - $this->_check_php_session(); - - return TRUE; - } - - // Whitelist auth override found, check client's ip against config whitelist - if ($auth_override_class_method[$this->router->class]['*'] === 'whitelist') - { - $this->_check_whitelist_auth(); - - return TRUE; - } - } - - // Check to see if there's an override value set for the current class/method being called - if (!empty($auth_override_class_method[$this->router->class][$this->router->method])) - { - // None auth override found, prepare nothing but send back a TRUE override flag - if ($auth_override_class_method[$this->router->class][$this->router->method] === 'none') - { - return TRUE; - } - - // Basic auth override found, prepare basic - if ($auth_override_class_method[$this->router->class][$this->router->method] === 'basic') - { - $this->_prepare_basic_auth(); - - return TRUE; - } - - // Digest auth override found, prepare digest - if ($auth_override_class_method[$this->router->class][$this->router->method] === 'digest') - { - $this->_prepare_digest_auth(); - - return TRUE; - } - - // Session auth override found, check session - if ($auth_override_class_method[$this->router->class][$this->router->method] === 'session') - { - $this->_check_php_session(); - - return TRUE; - } - - // Whitelist auth override found, check client's ip against config whitelist - if ($auth_override_class_method[$this->router->class][$this->router->method] === 'whitelist') - { - $this->_check_whitelist_auth(); - - return TRUE; - } - } - } - - // Assign the class/method/HTTP-method auth type override array from the config - $auth_override_class_method_http = $this->config->item('auth_override_class_method_http'); - - // Check to see if the override array is even populated - if (!empty($auth_override_class_method_http)) - { - // check for wildcard flag for rules for classes - if (!empty($auth_override_class_method_http[$this->router->class]['*'][$this->request->method])) - { - // None auth override found, prepare nothing but send back a TRUE override flag - if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'none') - { - return TRUE; - } - - // Basic auth override found, prepare basic - if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'basic') - { - $this->_prepare_basic_auth(); - - return TRUE; - } - - // Digest auth override found, prepare digest - if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'digest') - { - $this->_prepare_digest_auth(); - - return TRUE; - } - - // Session auth override found, check session - if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'session') - { - $this->_check_php_session(); - - return TRUE; - } - - // Whitelist auth override found, check client's ip against config whitelist - if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'whitelist') - { - $this->_check_whitelist_auth(); - - return TRUE; - } - } - - // Check to see if there's an override value set for the current class/method/HTTP-method being called - if (!empty($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method])) - { - // None auth override found, prepare nothing but send back a TRUE override flag - if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'none') - { - return TRUE; - } - - // Basic auth override found, prepare basic - if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'basic') - { - $this->_prepare_basic_auth(); - - return TRUE; - } - - // Digest auth override found, prepare digest - if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'digest') - { - $this->_prepare_digest_auth(); - - return TRUE; - } - - // Session auth override found, check session - if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'session') - { - $this->_check_php_session(); - - return TRUE; - } - - // Whitelist auth override found, check client's ip against config whitelist - if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'whitelist') - { - $this->_check_whitelist_auth(); - - return TRUE; - } - } - } - return FALSE; - } - - /** - * Parse the GET request arguments - * - * @access protected - * @return void - */ - protected function _parse_get() - { - // Merge both the URI segments and query parameters - $this->_get_args = array_merge($this->_get_args, $this->_query_args); - } - - /** - * Parse the POST request arguments - * - * @access protected - * @return void - */ - protected function _parse_post() - { - $this->_post_args = $_POST; - - if ($this->request->format) - { - $this->request->body = $this->input->raw_input_stream; - } - } - - /** - * Parse the PUT request arguments - * - * @access protected - * @return void - */ - protected function _parse_put() - { - if ($this->request->format) - { - $this->request->body = $this->input->raw_input_stream; - } - else if ($this->input->method() === 'put') - { - // If no filetype is provided, then there are probably just arguments - $this->_put_args = $this->input->input_stream(); - } - } - - /** - * Parse the HEAD request arguments - * - * @access protected - * @return void - */ - protected function _parse_head() - { - // Parse the HEAD variables - parse_str(parse_url($this->input->server('REQUEST_URI'), PHP_URL_QUERY), $head); - - // Merge both the URI segments and HEAD params - $this->_head_args = array_merge($this->_head_args, $head); - } - - /** - * Parse the OPTIONS request arguments - * - * @access protected - * @return void - */ - protected function _parse_options() - { - // Parse the OPTIONS variables - parse_str(parse_url($this->input->server('REQUEST_URI'), PHP_URL_QUERY), $options); - - // Merge both the URI segments and OPTIONS params - $this->_options_args = array_merge($this->_options_args, $options); - } - - /** - * Parse the PATCH request arguments - * - * @access protected - * @return void - */ - protected function _parse_patch() - { - // It might be a HTTP body - if ($this->request->format) - { - $this->request->body = $this->input->raw_input_stream; - } - else if ($this->input->method() === 'patch') - { - // If no filetype is provided, then there are probably just arguments - $this->_patch_args = $this->input->input_stream(); - } - } - - /** - * Parse the DELETE request arguments - * - * @access protected - * @return void - */ - protected function _parse_delete() - { - // These should exist if a DELETE request - if ($this->input->method() === 'delete') - { - $this->_delete_args = $this->input->input_stream(); - } - } - - /** - * Parse the query parameters - * - * @access protected - * @return void - */ - protected function _parse_query() - { - $this->_query_args = $this->input->get(); - } - - // INPUT FUNCTION -------------------------------------------------------------- - - /** - * Retrieve a value from a GET request - * - * @access public - * @param NULL $key Key to retrieve from the GET request - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the GET request; otherwise, NULL - */ - public function get($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_get_args; - } - - return isset($this->_get_args[$key]) ? $this->_xss_clean($this->_get_args[$key], $xss_clean) : NULL; - } - - /** - * Retrieve a value from a OPTIONS request - * - * @access public - * @param NULL $key Key to retrieve from the OPTIONS request. - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the OPTIONS request; otherwise, NULL - */ - public function options($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_options_args; - } - - return isset($this->_options_args[$key]) ? $this->_xss_clean($this->_options_args[$key], $xss_clean) : NULL; - } - - /** - * Retrieve a value from a HEAD request - * - * @access public - * @param NULL $key Key to retrieve from the HEAD request - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the HEAD request; otherwise, NULL - */ - public function head($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_head_args; - } - - return isset($this->_head_args[$key]) ? $this->_xss_clean($this->_head_args[$key], $xss_clean) : NULL; - } - - /** - * Retrieve a value from a POST request - * - * @access public - * @param NULL $key Key to retrieve from the POST request - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the POST request; otherwise, NULL - */ - public function post($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_post_args; - } - - return isset($this->_post_args[$key]) ? $this->_xss_clean($this->_post_args[$key], $xss_clean) : NULL; - } - - /** - * Retrieve a value from a PUT request - * - * @access public - * @param NULL $key Key to retrieve from the PUT request - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the PUT request; otherwise, NULL - */ - public function put($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_put_args; - } - - return isset($this->_put_args[$key]) ? $this->_xss_clean($this->_put_args[$key], $xss_clean) : NULL; - } - - /** - * Retrieve a value from a DELETE request - * - * @access public - * @param NULL $key Key to retrieve from the DELETE request - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the DELETE request; otherwise, NULL - */ - public function delete($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_delete_args; - } - - return isset($this->_delete_args[$key]) ? $this->_xss_clean($this->_delete_args[$key], $xss_clean) : NULL; - } - - /** - * Retrieve a value from a PATCH request - * - * @access public - * @param NULL $key Key to retrieve from the PATCH request - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the PATCH request; otherwise, NULL - */ - public function patch($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_patch_args; - } - - return isset($this->_patch_args[$key]) ? $this->_xss_clean($this->_patch_args[$key], $xss_clean) : NULL; - } - - /** - * Retrieve a value from the query parameters - * - * @access public - * @param NULL $key Key to retrieve from the query parameters - * If NULL an array of arguments is returned - * @param NULL $xss_clean Whether to apply XSS filtering - * @return array|string|NULL Value from the query parameters; otherwise, NULL - */ - public function query($key = NULL, $xss_clean = NULL) - { - if ($key === NULL) - { - return $this->_query_args; - } - - return isset($this->_query_args[$key]) ? $this->_xss_clean($this->_query_args[$key], $xss_clean) : NULL; - } - - /** - * Sanitizes data so that Cross Site Scripting Hacks can be - * prevented - * - * @access protected - * @param string $value Input data - * @param bool $xss_clean Whether to apply XSS filtering - * @return string - */ - protected function _xss_clean($value, $xss_clean) - { - is_bool($xss_clean) || $xss_clean = $this->_enable_xss; - - return $xss_clean === TRUE ? $this->security->xss_clean($value) : $value; - } - - /** - * Retrieve the validation errors - * - * @access public - * @return array - */ - public function validation_errors() - { - $string = strip_tags($this->form_validation->error_string()); - - return explode(PHP_EOL, trim($string, PHP_EOL)); - } - - // SECURITY FUNCTIONS --------------------------------------------------------- - - /** - * Perform LDAP Authentication - * - * @access protected - * @param string $username The username to validate - * @param string $password The password to validate - * @return bool - */ - protected function _perform_ldap_auth($username = '', $password = NULL) - { - if (empty($username)) - { - log_message('debug', 'LDAP Auth: failure, empty username'); - return FALSE; - } - - log_message('debug', 'LDAP Auth: Loading configuration'); - - $this->config->load('ldap.php', TRUE); - - $ldap = [ - 'timeout' => $this->config->item('timeout', 'ldap'), - 'host' => $this->config->item('server', 'ldap'), - 'port' => $this->config->item('port', 'ldap'), - 'rdn' => $this->config->item('binduser', 'ldap'), - 'pass' => $this->config->item('bindpw', 'ldap'), - 'basedn' => $this->config->item('basedn', 'ldap'), - ]; - - log_message('debug', 'LDAP Auth: Connect to ' . (isset($ldaphost) ? $ldaphost : '[ldap not configured]')); - - // Connect to the ldap server - $ldapconn = ldap_connect($ldap['host'], $ldap['port']); - if ($ldapconn) - { - log_message('debug', 'Setting timeout to ' . $ldap['timeout'] . ' seconds'); - - ldap_set_option($ldapconn, LDAP_OPT_NETWORK_TIMEOUT, $ldap['timeout']); - - log_message('debug', 'LDAP Auth: Binding to ' . $ldap['host'] . ' with dn ' . $ldap['rdn']); - - // Binding to the ldap server - $ldapbind = ldap_bind($ldapconn, $ldap['rdn'], $ldap['pass']); - - // Verify the binding - if ($ldapbind === FALSE) - { - log_message('error', 'LDAP Auth: bind was unsuccessful'); - return FALSE; - } - - log_message('debug', 'LDAP Auth: bind successful'); - } - - // Search for user - if (($res_id = ldap_search($ldapconn, $ldap['basedn'], "uid=$username")) === FALSE) - { - log_message('error', 'LDAP Auth: User ' . $username . ' not found in search'); - return FALSE; - } - - if (ldap_count_entries($ldapconn, $res_id) !== 1) - { - log_message('error', 'LDAP Auth: Failure, username ' . $username . 'found more than once'); - return FALSE; - } - - if (($entry_id = ldap_first_entry($ldapconn, $res_id)) === FALSE) - { - log_message('error', 'LDAP Auth: Failure, entry of search result could not be fetched'); - return FALSE; - } - - if (($user_dn = ldap_get_dn($ldapconn, $entry_id)) === FALSE) - { - log_message('error', 'LDAP Auth: Failure, user-dn could not be fetched'); - return FALSE; - } - - // User found, could not authenticate as user - if (($link_id = ldap_bind($ldapconn, $user_dn, $password)) === FALSE) - { - log_message('error', 'LDAP Auth: Failure, username/password did not match: ' . $user_dn); - return FALSE; - } - - log_message('debug', 'LDAP Auth: Success ' . $user_dn . ' authenticated successfully'); - - $this->_user_ldap_dn = $user_dn; - - ldap_close($ldapconn); - - return TRUE; - } - - /** - * Perform Library Authentication - Override this function to change the way the library is called - * - * @access protected - * @param string $username The username to validate - * @param string $password The password to validate - * @return bool - */ - protected function _perform_library_auth($username = '', $password = NULL) - { - if (empty($username)) - { - log_message('error', 'Library Auth: Failure, empty username'); - return FALSE; - } - - $auth_library_class = $this->config->item('auth_library_class'); - $auth_library_function = $this->config->item('auth_library_function'); - - if (empty($auth_library_class)) - { - log_message('debug', 'Library Auth: Failure, empty auth_library_class'); - return FALSE; - } - - if (empty($auth_library_function)) - { - log_message('debug', 'Library Auth: Failure, empty auth_library_function'); - return FALSE; - } - - if (is_callable([$auth_library_class, $auth_library_function]) === FALSE) - { - $this->load->library($auth_library_class, array(false)); - } - - return $this->{strtolower($auth_library_class)}->$auth_library_function($username, $password); - } - - /** - * Check if the user is logged in - * - * @access protected - * @param string $username The user's name - * @param bool|string $password The user's password - * @return bool - */ - protected function _check_login($username = NULL, $password = FALSE) - { - if (empty($username)) - { - return FALSE; - } - - $auth_source = strtolower($this->config->item('auth_source')); - $rest_auth = strtolower($this->config->item('rest_auth')); - $valid_logins = $this->config->item('rest_valid_logins'); - - if (!$this->config->item('auth_source') && $rest_auth === 'digest') - { - // For digest we do not have a password passed as argument - return md5($username . ':' . $this->config->item('rest_realm') . ':' . (isset($valid_logins[$username]) ? $valid_logins[$username] : '')); - } - - if ($password === FALSE) - { - return FALSE; - } - - if ($auth_source === 'ldap') - { - log_message('debug', "Performing LDAP authentication for $username"); - - return $this->_perform_ldap_auth($username, $password); - } - - if ($auth_source === 'library') - { - log_message('debug', "Performing Library authentication for $username"); - - return $this->_perform_library_auth($username, $password); - } - - if (array_key_exists($username, $valid_logins) === FALSE) - { - return FALSE; - } - - if ($valid_logins[$username] !== $password) - { - return FALSE; - } - - return TRUE; - } - - /** - * Check to see if the user is logged in with a PHP session key - * - * @access protected - * @return void - */ - protected function _check_php_session() - { - // Get the auth_source config item - $key = $this->config->item('auth_source'); - - // If falsy, then the user isn't logged in - if (!$this->session->userdata($key)) - { - // Display an error response - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unauthorized') - ], self::HTTP_UNAUTHORIZED); - } - } - - /** - * Prepares for basic authentication - * - * @access protected - * @return void - */ - protected function _prepare_basic_auth() - { - // If whitelist is enabled it has the first chance to kick them out - if ($this->config->item('rest_ip_whitelist_enabled')) - { - $this->_check_whitelist_auth(); - } - - // Returns NULL if the SERVER variables PHP_AUTH_USER and HTTP_AUTHENTICATION don't exist - $username = $this->input->server('PHP_AUTH_USER'); - $http_auth = $this->input->server('HTTP_AUTHENTICATION'); - - $password = NULL; - if ($username !== NULL) - { - $password = $this->input->server('PHP_AUTH_PW'); - } - elseif ($http_auth !== NULL) - { - // If the authentication header is set as basic, then extract the username and password from - // HTTP_AUTHORIZATION e.g. my_username:my_password. This is passed in the .htaccess file - if (strpos(strtolower($http_auth), 'basic') === 0) - { - // Search online for HTTP_AUTHORIZATION workaround to explain what this is doing - list($username, $password) = explode(':', base64_decode(substr($this->input->server('HTTP_AUTHORIZATION'), 6))); - } - } - - // Check if the user is logged into the system - if ($this->_check_login($username, $password) === FALSE) - { - $this->_force_login(); - } - } - - /** - * Prepares for digest authentication - * - * @access protected - * @return void - */ - protected function _prepare_digest_auth() - { - // If whitelist is enabled it has the first chance to kick them out - if ($this->config->item('rest_ip_whitelist_enabled')) - { - $this->_check_whitelist_auth(); - } - - // We need to test which server authentication variable to use, - // because the PHP ISAPI module in IIS acts different from CGI - $digest_string = $this->input->server('PHP_AUTH_DIGEST'); - if ($digest_string === NULL) - { - $digest_string = $this->input->server('HTTP_AUTHORIZATION'); - } - - $unique_id = uniqid(); - - // The $_SESSION['error_prompted'] variable is used to ask the password - // again if none given or if the user enters wrong auth information - if (empty($digest_string)) - { - $this->_force_login($unique_id); - } - - // We need to retrieve authentication data from the $digest_string variable - $matches = []; - preg_match_all('@(username|nonce|uri|nc|cnonce|qop|response)=[\'"]?([^\'",]+)@', $digest_string, $matches); - $digest = (empty($matches[1]) || empty($matches[2])) ? [] : array_combine($matches[1], $matches[2]); - - // For digest authentication the library function should return - // already stored password for that username, even if it is hashed - $username = $this->_check_login($digest['username'], TRUE); - // If there no password - if (array_key_exists('username', $digest) === FALSE || $username === FALSE || $username === NULL) - { - $this->_force_login($unique_id); - } - // If the password was found for this username, generete the string md5('USERNAME:REALM:PASSWORD') - else - { - $username = md5($digest['username'].":".$this->config->item('rest_realm').":".$username); - } - - $md5 = md5(strtoupper($this->request->method) . ':' . $digest['uri']); - $valid_response = md5($username . ':' . $digest['nonce'] . ':' . $digest['nc'] . ':' . $digest['cnonce'] . ':' . $digest['qop'] . ':' . $md5); - - // Check if the string don't compare (case-insensitive) - if (strcasecmp($digest['response'], $valid_response) !== 0) - { - // Display an error response - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_invalid_credentials') - ], self::HTTP_UNAUTHORIZED); - } - } - - /** - * Checks if the client's ip is in the 'rest_ip_blacklist' config and generates a 401 response - * - * @access protected - * @return void - */ - protected function _check_blacklist_auth() - { - // Match an ip address in a blacklist e.g. 127.0.0.0, 0.0.0.0 - $pattern = sprintf('/(?:,\s*|^)\Q%s\E(?=,\s*|$)/m', $this->input->ip_address()); - - // Returns 1, 0 or FALSE (on error only). Therefore implicitly convert 1 to TRUE - if (preg_match($pattern, $this->config->item('rest_ip_blacklist'))) - { - // Display an error response - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_denied') - ], self::HTTP_UNAUTHORIZED); - } - } - - /** - * Check if the client's ip is in the 'rest_ip_whitelist' config and generates a 401 response - * - * @access protected - * @return void - */ - protected function _check_whitelist_auth() - { - $whitelist = explode(',', $this->config->item('rest_ip_whitelist')); - - array_push($whitelist, '127.0.0.1', '0.0.0.0'); - - foreach ($whitelist as &$ip) - { - // As $ip is a reference, trim leading and trailing whitespace, then store the new value - // using the reference - $ip = trim($ip); - } - - if (in_array($this->input->ip_address(), $whitelist) === FALSE) - { - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_unauthorized') - ], self::HTTP_UNAUTHORIZED); - } - } - - /** - * Force logging in by setting the WWW-Authenticate header - * - * @access protected - * @param string $nonce A server-specified data string which should be uniquely generated - * each time - * @return void - */ - protected function _force_login($nonce = '') - { - $rest_auth = $this->config->item('rest_auth'); - $rest_realm = $this->config->item('rest_realm'); - if (strtolower($rest_auth) === 'basic') - { - // See http://tools.ietf.org/html/rfc2617#page-5 - header('WWW-Authenticate: Basic realm="' . $rest_realm . '"'); - } - elseif (strtolower($rest_auth) === 'digest') - { - // See http://tools.ietf.org/html/rfc2617#page-18 - header( - 'WWW-Authenticate: Digest realm="' . $rest_realm - . '", qop="auth", nonce="' . $nonce - . '", opaque="' . md5($rest_realm) . '"'); - } - - // Display an error response - $this->response([ - $this->config->item('rest_status_field_name') => FALSE, - $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unauthorized') - ], self::HTTP_UNAUTHORIZED); - } - - /** - * Updates the log table with the total access time - * - * @access protected - * @author Chris Kacerguis - * @return bool TRUE log table updated; otherwise, FALSE - */ - protected function _log_access_time() - { - $payload['rtime'] = $this->_end_rtime - $this->_start_rtime; - - return $this->rest->db->update( - $this->config->item('rest_logs_table'), $payload, [ - 'id' => $this->_insert_id - ]); - } - - /** - * Updates the log table with HTTP response code - * - * @access protected - * @author Justin Chen - * @param $http_code int HTTP status code - * @return bool TRUE log table updated; otherwise, FALSE - */ - protected function _log_response_code($http_code) - { - $payload['response_code'] = $http_code; - - return $this->rest->db->update( - $this->config->item('rest_logs_table'), $payload, [ - 'id' => $this->_insert_id - ]); - } - - /** - * Check to see if the API key has access to the controller and methods - * - * @access protected - * @return bool TRUE the API key has access; otherwise, FALSE - */ - protected function _check_access() - { - // If we don't want to check access, just return TRUE - if ($this->config->item('rest_enable_access') === FALSE) - { - return TRUE; - } - - // Fetch controller based on path and controller name - $controller = implode( - '/', [ - $this->router->directory, - $this->router->class - ]); - - // Remove any double slashes for safety - $controller = str_replace('//', '/', $controller); - - // Query the access table and get the number of results - return $this->rest->db - ->where('key', $this->rest->key) - ->where('controller', $controller) - ->get($this->config->item('rest_access_table')) - ->num_rows() > 0; - } -} diff --git a/application/language/english/rest_controller_lang.php b/application/language/english/rest_controller_lang.php deleted file mode 100644 index 1c665bdc5..000000000 --- a/application/language/english/rest_controller_lang.php +++ /dev/null @@ -1,17 +0,0 @@ -_CI = &get_instance(); - - // Load the inflector helper - $this->_CI->load->helper('inflector'); - - // If the provided data is already formatted we should probably convert it to an array - if ($from_type !== NULL) - { - if (method_exists($this, '_from_' . $from_type)) - { - $data = call_user_func([$this, '_from_' . $from_type], $data); - } - else - { - throw new Exception('Format class does not support conversion from "' . $from_type . '".'); - } - } - - // Set the member variable to the data passed - $this->_data = $data; - } - - /** - * Create an instance of the format class - * e.g: echo $this->format->factory(['foo' => 'bar'])->to_csv(); - * - * @param mixed $data Data to convert/parse - * @param string $from_type Type to convert from e.g. json, csv, html - * - * @return object Instance of the format class - */ - public function factory($data, $from_type = NULL) - { - // $class = __CLASS__; - // return new $class(); - - return new static($data, $from_type); - } - - // FORMATTING OUTPUT --------------------------------------------------------- - - /** - * Format data as an array - * - * @param mixed|NULL $data Optional data to pass, so as to override the data passed - * to the constructor - * @return array Data parsed as an array; otherwise, an empty array - */ - public function to_array($data = NULL) - { - // If no data is passed as a parameter, then use the data passed - // via the constructor - if ($data === NULL && func_num_args() === 0) - { - $data = $this->_data; - } - - // Cast as an array if not already - if (is_array($data) === FALSE) - { - $data = (array) $data; - } - - $array = []; - foreach ((array) $data as $key => $value) - { - if (is_object($value) === TRUE || is_array($value) === TRUE) - { - $array[$key] = $this->to_array($value); - } - else - { - $array[$key] = $value; - } - } - - return $array; - } - - /** - * Format data as XML - * - * @param mixed|NULL $data Optional data to pass, so as to override the data passed - * to the constructor - * @param NULL $structure - * @param string $basenode - * @return mixed - */ - public function to_xml($data = NULL, $structure = NULL, $basenode = 'xml') - { - if ($data === NULL && func_num_args() === 0) - { - $data = $this->_data; - } - - // turn off compatibility mode as simple xml throws a wobbly if you don't. - if (ini_get('zend.ze1_compatibility_mode') == 1) - { - ini_set('zend.ze1_compatibility_mode', 0); - } - - if ($structure === NULL) - { - $structure = simplexml_load_string("<$basenode />"); - } - - // Force it to be something useful - if (is_array($data) === FALSE && is_object($data) === FALSE) - { - $data = (array) $data; - } - - foreach ($data as $key => $value) - { - - //change false/true to 0/1 - if (is_bool($value)) - { - $value = (int) $value; - } - - // no numeric keys in our xml please! - if (is_numeric($key)) - { - // make string key... - $key = (singular($basenode) != $basenode) ? singular($basenode) : 'item'; - } - - // replace anything not alpha numeric - $key = preg_replace('/[^a-z_\-0-9]/i', '', $key); - - if ($key === '_attributes' && (is_array($value) || is_object($value))) - { - $attributes = $value; - if (is_object($attributes)) - { - $attributes = get_object_vars($attributes); - } - - foreach ($attributes as $attribute_name => $attribute_value) - { - $structure->addAttribute($attribute_name, $attribute_value); - } - } - // if there is another array found recursively call this function - elseif (is_array($value) || is_object($value)) - { - $node = $structure->addChild($key); - - // recursive call. - $this->to_xml($value, $node, $key); - } - else - { - // add single node. - $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'); - - $structure->addChild($key, $value); - } - } - - return $structure->asXML(); - } - - /** - * Format data as HTML - * - * @param mixed|NULL $data Optional data to pass, so as to override the data passed - * to the constructor - * @return mixed - */ - public function to_html($data = NULL) - { - // If no data is passed as a parameter, then use the data passed - // via the constructor - if ($data === NULL && func_num_args() === 0) - { - $data = $this->_data; - } - - // Cast as an array if not already - if (is_array($data) === FALSE) - { - $data = (array) $data; - } - - // Check if it's a multi-dimensional array - if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) - { - // Multi-dimensional array - $headings = array_keys($data[0]); - } - else - { - // Single array - $headings = array_keys($data); - $data = [$data]; - } - - // Load the table library - $this->_CI->load->library('table'); - - $this->_CI->table->set_heading($headings); - - foreach ($data as $row) - { - // Suppressing the "array to string conversion" notice - // Keep the "evil" @ here - $row = @array_map('strval', $row); - - $this->_CI->table->add_row($row); - } - - return $this->_CI->table->generate(); - } - - /** - * @link http://www.metashock.de/2014/02/create-csv-file-in-memory-php/ - * @param mixed|NULL $data Optional data to pass, so as to override the data passed - * to the constructor - * @param string $delimiter The optional delimiter parameter sets the field - * delimiter (one character only). NULL will use the default value (,) - * @param string $enclosure The optional enclosure parameter sets the field - * enclosure (one character only). NULL will use the default value (") - * @return string A csv string - */ - public function to_csv($data = NULL, $delimiter = ',', $enclosure = '"') - { - // Use a threshold of 1 MB (1024 * 1024) - $handle = fopen('php://temp/maxmemory:1048576', 'w'); - if ($handle === FALSE) - { - return NULL; - } - - // If no data is passed as a parameter, then use the data passed - // via the constructor - if ($data === NULL && func_num_args() === 0) - { - $data = $this->_data; - } - - // If NULL, then set as the default delimiter - if ($delimiter === NULL) - { - $delimiter = ','; - } - - // If NULL, then set as the default enclosure - if ($enclosure === NULL) - { - $enclosure = '"'; - } - - // Cast as an array if not already - if (is_array($data) === FALSE) - { - $data = (array) $data; - } - - // Check if it's a multi-dimensional array - if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) - { - // Multi-dimensional array - $headings = array_keys($data[0]); - } - else - { - // Single array - $headings = array_keys($data); - $data = [$data]; - } - - // Apply the headings - fputcsv($handle, $headings, $delimiter, $enclosure); - - foreach ($data as $record) - { - // If the record is not an array, then break. This is because the 2nd param of - // fputcsv() should be an array - if (is_array($record) === FALSE) - { - break; - } - - // Suppressing the "array to string conversion" notice. - // Keep the "evil" @ here. - $record = @ array_map('strval', $record); - - // Returns the length of the string written or FALSE - fputcsv($handle, $record, $delimiter, $enclosure); - } - - // Reset the file pointer - rewind($handle); - - // Retrieve the csv contents - $csv = stream_get_contents($handle); - - // Close the handle - fclose($handle); - - return $csv; - } - - /** - * Encode data as json - * - * @param mixed|NULL $data Optional data to pass, so as to override the data passed - * to the constructor - * @return string Json representation of a value - */ - public function to_json($data = NULL) - { - // If no data is passed as a parameter, then use the data passed - // via the constructor - if ($data === NULL && func_num_args() === 0) - { - $data = $this->_data; - } - - // Get the callback parameter (if set) - $callback = $this->_CI->input->get('callback'); - - if (empty($callback) === TRUE) - { - return json_encode($data); - } - - // We only honour a jsonp callback which are valid javascript identifiers - elseif (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback)) - { - // Return the data as encoded json with a callback - return $callback . '(' . json_encode($data) . ');'; - } - - // An invalid jsonp callback function provided. - // Though I don't believe this should be hardcoded here - $data['warning'] = 'INVALID JSONP CALLBACK: ' . $callback; - - return json_encode($data); - } - - /** - * Encode data as a serialized array - * - * @param mixed|NULL $data Optional data to pass, so as to override the data passed - * to the constructor - * @return string Serialized data - */ - public function to_serialized($data = NULL) - { - // If no data is passed as a parameter, then use the data passed - // via the constructor - if ($data === NULL && func_num_args() === 0) - { - $data = $this->_data; - } - - return serialize($data); - } - - /** - * Format data using a PHP structure - * - * @param mixed|NULL $data Optional data to pass, so as to override the data passed - * to the constructor - * @return mixed String representation of a variable - */ - public function to_php($data = NULL) - { - // If no data is passed as a parameter, then use the data passed - // via the constructor - if ($data === NULL && func_num_args() === 0) - { - $data = $this->_data; - } - - return var_export($data, TRUE); - } - - // INTERNAL FUNCTIONS - - /** - * @param $data XML string - * @return SimpleXMLElement XML element object; otherwise, empty array - */ - protected function _from_xml($data) - { - return $data ? (array) simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA) : []; - } - - /** - * @param string $data CSV string - * @param string $delimiter The optional delimiter parameter sets the field - * delimiter (one character only). NULL will use the default value (,) - * @param string $enclosure The optional enclosure parameter sets the field - * enclosure (one character only). NULL will use the default value (") - * @return array A multi-dimensional array with the outer array being the number of rows - * and the inner arrays the individual fields - */ - protected function _from_csv($data, $delimiter = ',', $enclosure = '"') - { - // If NULL, then set as the default delimiter - if ($delimiter === NULL) - { - $delimiter = ','; - } - - // If NULL, then set as the default enclosure - if ($enclosure === NULL) - { - $enclosure = '"'; - } - - return str_getcsv($data, $delimiter, $enclosure); - } - - /** - * @param $data Encoded json string - * @return mixed Decoded json string with leading and trailing whitespace removed - */ - protected function _from_json($data) - { - return json_decode(trim($data)); - } - - /** - * @param string Data to unserialized - * @return mixed Unserialized data - */ - protected function _from_serialize($data) - { - return unserialize(trim($data)); - } - - /** - * @param $data Data to trim leading and trailing whitespace - * @return string Data with leading and trailing whitespace removed - */ - protected function _from_php($data) - { - return trim($data); - } - -} diff --git a/composer.json b/composer.json index d763dc5ad..62f92a963 100644 --- a/composer.json +++ b/composer.json @@ -228,6 +228,7 @@ "borgar/textile-js": "2.0.4", "BlackrockDigital/startbootstrap-sb-admin-2": "^3.3", + "chriskacerguis/codeigniter-restserver": "^3.0", "christianbach/tablesorter": "^1.0", "codeigniter/framework": "3.*", "components/jquery": "^3.2", diff --git a/composer.lock b/composer.lock index 8fc88ce07..f0e841788 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "ddbbad487c655512e6983408339cb85f", - "content-hash": "b5902c71fe21cd14397101dba5a3080c", + "hash": "44a02c1e72626f05e682de2030c8adad", + "content-hash": "e0898c2ba3d18593851989029e54bedb", "packages": [ { "name": "BlackrockDigital/startbootstrap-sb-admin-2", @@ -71,6 +71,45 @@ }, "type": "library" }, + { + "name": "chriskacerguis/codeigniter-restserver", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/chriskacerguis/codeigniter-restserver.git", + "reference": "3a5ba0dffdebd24cc215ef714b72208c88304203" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chriskacerguis/codeigniter-restserver/zipball/3a5ba0dffdebd24cc215ef714b72208c88304203", + "reference": "3a5ba0dffdebd24cc215ef714b72208c88304203", + "shasum": "" + }, + "require": { + "codeigniter/framework": "^3.0.4", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "application/libraries/Format.php", + "application/libraries/REST_Controller.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Kacerguis", + "role": "Developer" + } + ], + "description": "REST Server for the CodeIgniter framework", + "homepage": "https://github.com/chriskacerguis/codeigniter-restserver", + "time": "2017-09-23 16:44:55" + }, { "name": "christianbach/tablesorter", "version": "1.0.1", @@ -1305,28 +1344,28 @@ "authors": [ { "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" + "role": "Lead Developer", + "email": "terrafrost@php.net" }, { "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" + "role": "Developer", + "email": "pm@datasphere.ch" }, { "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" + "role": "Developer", + "email": "bantu@phpbb.com" }, { "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" + "role": "Developer", + "email": "petrich@tronic-media.com" }, { "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" + "role": "Developer", + "email": "graham@alt-three.com" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", From 18a36ea497a2417815e9e029a4eb3dbe32fe3adf Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 19 Sep 2019 14:33:02 +0200 Subject: [PATCH 02/22] Fixed controller api/v1/person/Benutzer --- application/controllers/api/v1/person/Benutzer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/controllers/api/v1/person/Benutzer.php b/application/controllers/api/v1/person/Benutzer.php index 23fcdadac..f1ea4f149 100644 --- a/application/controllers/api/v1/person/Benutzer.php +++ b/application/controllers/api/v1/person/Benutzer.php @@ -37,7 +37,7 @@ class Benutzer extends APIv1_Controller if (isset($uid)) { - $result = $this->BenutzerModel->load($uid); + $result = $this->BenutzerModel->load(array('uid' => $uid)); $this->response($result, REST_Controller::HTTP_OK); } From b5c1285fb48c787758bfb1f73aa920d0c9af2f48 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 2 Oct 2019 15:48:42 +0200 Subject: [PATCH 03/22] =?UTF-8?q?-=20Infocenter=20filter=20dataset=20is=20?= =?UTF-8?q?reloaded=20anytime=20Infocenter=20menu=20is=20clicked=20for=20?= =?UTF-8?q?=C3=9Cbersicht,=20Frreigegeben=20or=20Reihungstestabsolviert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/infocenter/InfoCenter.php | 20 +++++++++++++------ .../infocenter/infocenterFreigegebenData.php | 1 + .../infocenterReihungstestAbsolviertData.php | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index c803520ed..e14a34d8f 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -24,6 +24,7 @@ class InfoCenter extends Auth_Controller const FILTER_ID = 'filter_id'; const PREV_FILTER_ID = 'prev_filter_id'; + const RELOAD_DATASET = 'reloadDataset'; private $_uid; // contains the UID of the logged user @@ -234,7 +235,7 @@ class InfoCenter extends Auth_Controller $redirectLink = '/'.self::INFOCENTER_URI.'?'.self::FHC_CONTROLLER_ID.'='.$this->getControllerId(); // Force reload of Dataset after Unlock - $redirectLink .= '&reloadDataset=true'; + $redirectLink .= '&'.self::RELOAD_DATASET.'=true'; $currentFilterId = $this->input->get(self::FILTER_ID); if (isset($currentFilterId)) @@ -894,10 +895,16 @@ class InfoCenter extends Auth_Controller $freigegebenLink = site_url(self::INFOCENTER_URI.'/'.self::FREIGEGEBEN_PAGE); $reihungstestAbsolviertLink = site_url(self::INFOCENTER_URI.'/'.self::REIHUNGSTESTABSOLVIERT_PAGE); $currentFilterId = $this->input->get(self::FILTER_ID); + $reloadDatasetParam = self::RELOAD_DATASET.'=true'; if (isset($currentFilterId)) { - $freigegebenLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId; - $reihungstestAbsolviertLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId; + $freigegebenLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId.'&'.$reloadDatasetParam; + $reihungstestAbsolviertLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId.'&'.$reloadDatasetParam; + } + else + { + $freigegebenLink .= '?'.$reloadDatasetParam; + $reihungstestAbsolviertLink .= '?'.$reloadDatasetParam; } $this->navigationlib->setSessionMenu( @@ -993,9 +1000,10 @@ class InfoCenter extends Auth_Controller $this->load->library('NavigationLib', array(self::NAVIGATION_PAGE => self::INFOCENTER_URI.'/'.$page)); // Generate the home link with the eventually loaded filter - $homeLink = site_url(self::INFOCENTER_URI.'/'.self::INDEX_PAGE); - $freigegebenLink = site_url(self::INFOCENTER_URI.'/'.self::FREIGEGEBEN_PAGE); - $absolviertLink = site_url(self::INFOCENTER_URI.'/'.self::REIHUNGSTESTABSOLVIERT_PAGE); + $reloadDatasetParam = '?'.self::RELOAD_DATASET.'=true'; + $homeLink = site_url(self::INFOCENTER_URI.'/'.self::INDEX_PAGE.$reloadDatasetParam); + $freigegebenLink = site_url(self::INFOCENTER_URI.'/'.self::FREIGEGEBEN_PAGE.$reloadDatasetParam); + $absolviertLink = site_url(self::INFOCENTER_URI.'/'.self::REIHUNGSTESTABSOLVIERT_PAGE.$reloadDatasetParam); $prevFilterId = $this->input->get(self::PREV_FILTER_ID); if (isset($prevFilterId)) { diff --git a/application/views/system/infocenter/infocenterFreigegebenData.php b/application/views/system/infocenter/infocenterFreigegebenData.php index 89ba2ec38..13a2c0563 100644 --- a/application/views/system/infocenter/infocenterFreigegebenData.php +++ b/application/views/system/infocenter/infocenterFreigegebenData.php @@ -235,6 +235,7 @@ 'filter_id' => $this->input->get('filter_id'), 'requiredPermissions' => 'infocenter', 'datasetRepresentation' => 'tablesorter', + 'reloadDataset' => ($this->input->get('reloadDataset')=='true'?true:false), 'checkboxes' => 'PersonId', 'additionalColumns' => array('Details'), 'columnsAliases' => array( diff --git a/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php b/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php index 22b122bb0..652ab4887 100644 --- a/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php +++ b/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php @@ -204,6 +204,7 @@ 'filter_id' => $this->input->get('filter_id'), 'requiredPermissions' => 'infocenter', 'datasetRepresentation' => 'tablesorter', + 'reloadDataset' => ($this->input->get('reloadDataset')=='true'?true:false), 'checkboxes' => 'PersonId', 'additionalColumns' => array('Details'), 'columnsAliases' => array( From bc9a5b4b06c5a301a880419846f524e650c7eb9d Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 2 Oct 2019 16:33:44 +0200 Subject: [PATCH 04/22] Added new functions getAuthFirstname and getAuthSurname to helper hlp_authentication_helper --- .../helpers/hlp_authentication_helper.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/application/helpers/hlp_authentication_helper.php b/application/helpers/hlp_authentication_helper.php index 740823ff9..194f0b249 100644 --- a/application/helpers/hlp_authentication_helper.php +++ b/application/helpers/hlp_authentication_helper.php @@ -34,3 +34,31 @@ function getAuthUID() return isLogged() ? ($ci->authlib->getAuthObj())->{AuthLib::AO_USERNAME} : null; } + +/** + * If the user is NOT logged then a null value is returned. + * If the user is alredy logged, then it is possible to access to the authentication object + * that contains the firstname of the logged user + * NOTE: if the user is logged with a "foreign" method (ex. Bewerbungstool), + * then it is possible that the firstname is null! + */ +function getAuthFirstname() +{ + $ci =& get_instance(); // get CI instance + + return isLogged() ? ($ci->authlib->getAuthObj())->{AuthLib::AO_NAME} : null; +} + +/** + * If the user is NOT logged then a null value is returned. + * If the user is alredy logged, then it is possible to access to the authentication object + * that contains the surname of the logged user + * NOTE: if the user is logged with a "foreign" method (ex. Bewerbungstool), + * then it is possible that the surname is null! + */ +function getAuthSurname() +{ + $ci =& get_instance(); // get CI instance + + return isLogged() ? ($ci->authlib->getAuthObj())->{AuthLib::AO_SURNAME} : null; +} From 38ae98cc36e11d75da9105e57207fe265f3e2e6e Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 2 Oct 2019 17:19:31 +0200 Subject: [PATCH 05/22] - Infocenter Details: possible to set persons on hold, i.e. person is out of workflow temporalily (e.g. when waiting for info), but this can only be undone manually --- .../system/infocenter/InfoCenter.php | 54 ++- application/libraries/PersonLogLib.php | 138 +++++-- .../system/infocenter/infocenterDetails.php | 9 +- public/css/infocenter/infocenterDetails.css | 5 + public/js/infocenter/infocenterDetails.js | 353 +++++++++++------- system/phrasesupdate.php | 100 +++++ 6 files changed, 505 insertions(+), 154 deletions(-) diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index e14a34d8f..7197b014c 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -101,9 +101,11 @@ class InfoCenter extends Auth_Controller 'reloadNotizen' => 'infocenter:r', 'reloadLogs' => 'infocenter:r', 'outputAkteContent' => 'infocenter:r', - 'getParkedDate' => 'infocenter:r', + 'getPostponeDate' => 'infocenter:r', 'park' => 'infocenter:rw', 'unpark' => 'infocenter:rw', + 'setOnHold' => 'infocenter:rw', + 'removeOnHold' => 'infocenter:rw', 'getStudienjahrEnd' => 'infocenter:r', 'setNavigationMenuArrayJson' => 'infocenter:r' ) @@ -712,11 +714,32 @@ class InfoCenter extends Auth_Controller * Gets the date until which a person is parked * @param $person_id */ - public function getParkedDate($person_id) + public function getPostponeDate($person_id) { + $result = array( + 'type' => null, + 'date' => null + ); + $parkedDate = $this->personloglib->getParkedDate($person_id); - $this->outputJsonSuccess(array($parkedDate)); + if (isset($parkedDate)) + { + $result['type'] = 'parked'; + $result['date'] = $parkedDate; + } + else + { + $onholdDate = $this->personloglib->getOnHoldDate($person_id); + + if (isset($onholdDate)) + { + $result['type'] = 'onhold'; + $result['date'] = $onholdDate; + } + } + + $this->outputJsonSuccess($result); } /** @@ -744,6 +767,31 @@ class InfoCenter extends Auth_Controller $this->outputJson($result); } + /** + * Sets a person on hold ("zurückstellen") + */ + public function setOnHold() + { + $person_id = $this->input->post('person_id'); + $date = $this->input->post('onholddate'); + + $result = $this->personloglib->setOnHold($person_id, date_format(date_create($date), 'Y-m-d'), self::TAETIGKEIT, self::APP, null, $this->_uid); + + $this->outputJson($result); + } + + /** + * Removed on hold status of a person + */ + public function removeOnHold() + { + $person_id = $this->input->post('person_id'); + + $result = $this->personloglib->removeOnHold($person_id); + + $this->outputJson($result); + } + /** * Gets the End date of the current Studienjahr */ diff --git a/application/libraries/PersonLogLib.php b/application/libraries/PersonLogLib.php index b56937dfe..ed530ef34 100644 --- a/application/libraries/PersonLogLib.php +++ b/application/libraries/PersonLogLib.php @@ -8,6 +8,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); class PersonLogLib { const PARKED_LOGNAME = 'Parked'; + const ONHOLD_LOGNAME = 'Onhold'; /** * Constructor @@ -91,26 +92,20 @@ class PersonLogLib */ public function park($person_id, $date, $taetigkeit_kurzbz, $app = 'core', $oe_kurzbz = null, $user = null) { - $logdata = array( + $onhold = $this->getOnHoldDate($person_id); + + if (hasData($onhold)) + return error("Person already on hold"); + + $logjson = array( 'name' => self::PARKED_LOGNAME ); - $data = array( - 'person_id' => $person_id, - 'zeitpunkt' => $date, - 'taetigkeit_kurzbz' => $taetigkeit_kurzbz, - 'app' => $app, - 'oe_kurzbz' => $oe_kurzbz, - 'logtype_kurzbz' => 'Processstate', - 'logdata' => json_encode($logdata), - 'insertvon' => $user - ); - - return $this->ci->PersonLogModel->insert($data); + return $this->_saveLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app, $oe_kurzbz, $user); } /** - * Unparks a person, i.e. removes all log entries in the future + * Unparks a person, i.e. removes all log entries in the future with logname for parking * @param $person_id * @return array with deleted logids */ @@ -131,17 +126,9 @@ class PersonLogLib { $deleted[] = $log->log_id; } - else - { - return $delresult; - } } } } - else - { - return $result; - } return success($deleted); } @@ -172,4 +159,111 @@ class PersonLogLib return $parkeddate; } + + /** + * Sets person on hold, i.e. marks a person so no actions are expected for the person (e.g. as a prestudent). + * Done by adding a logentry with a special name. can be undone only manually by clicking button. + * @param $person_id + * @param $date + * @param $taetigkeit_kurzbz + * @param string $app + * @param null $oe_kurzbz + * @param null $user + * @return array + */ + public function setOnHold($person_id, $date, $taetigkeit_kurzbz, $app = 'core', $oe_kurzbz = null, $user = null) + { + $parked = $this->getParkedDate($person_id); + + if (hasData($parked)) + return error("Person already parked"); + + $logjson = array( + 'name' => self::ONHOLD_LOGNAME + ); + + return $this->_saveLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app, $oe_kurzbz, $user); + } + + /** + * Removes on hold status, i.e. removes all log entries with logname for on hold + * @param $person_id + * @return array + */ + public function removeOnHold($person_id) + { + $deleted = array(); + + $result = $this->ci->PersonLogModel->filterLog($person_id); + if (hasData($result)) + { + foreach ($result->retval as $log) + { + $logdata = json_decode($log->logdata); + if (isset($logdata->name) && $logdata->name === self::ONHOLD_LOGNAME) + { + $delresult = $this->ci->PersonLogModel->deleteLog($log->log_id); + if (isSuccess($delresult)) + { + $deleted[] = $log->log_id; + } + } + } + } + return success($deleted); + } + + /** + * Gets date until which a person is on hold + * @param $person_id + * @return the date if person is on hold, null otherwise + */ + public function getOnHoldDate($person_id) + { + $result = $this->ci->PersonLogModel->filterLog($person_id); + + $onholddate = null; + + if (hasData($result)) + { + foreach ($result->retval as $log) + { + $logdata = json_decode($log->logdata); + if (isset($logdata->name) && $logdata->name === self::ONHOLD_LOGNAME) + { + $onholddate = $log->zeitpunkt; + break; + } + } + } + + return $onholddate; + } + + /** + * Saves a log with specified parameters, including a specified log date. + * @param $person_id + * @param $date + * @param $taetigkeit_kurzbz + * @param $logjson + * @param string $app + * @param null $oe_kurzbz + * @param null $user + * @return mixed + */ + private function _saveLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app = 'core', $oe_kurzbz = null, $user = null) + { + $data = array( + 'person_id' => $person_id, + 'zeitpunkt' => $date, + 'taetigkeit_kurzbz' => $taetigkeit_kurzbz, + 'app' => $app, + 'oe_kurzbz' => $oe_kurzbz, + 'logtype_kurzbz' => 'Processstate', + 'logdata' => json_encode($logjson), + 'insertvon' => $user + ); + + return $this->ci->PersonLogModel->insert($data); + } } diff --git a/application/views/system/infocenter/infocenterDetails.php b/application/views/system/infocenter/infocenterDetails.php index 9e708d076..68b6c760e 100644 --- a/application/views/system/infocenter/infocenterDetails.php +++ b/application/views/system/infocenter/infocenterDetails.php @@ -34,7 +34,12 @@ 'nichtsZumAusparken', 'fehlerBeimAusparken', 'fehlerBeimParken', - 'bewerberGeparktBis' + 'bewerberGeparktBis', + 'bewerberOnHold', + 'bewerberOnHoldEntfernen', + 'bewerberOnHoldBis', + 'nichtsZumEntfernen', + 'fehlerBeimEntfernen', ), 'ui' => array( 'gespeichert', @@ -176,7 +181,7 @@
-
+
load->view('system/infocenter/logs.php'); ?>
diff --git a/public/css/infocenter/infocenterDetails.css b/public/css/infocenter/infocenterDetails.css index b8bdc84bf..1586fd52d 100644 --- a/public/css/infocenter/infocenterDetails.css +++ b/public/css/infocenter/infocenterDetails.css @@ -65,4 +65,9 @@ #scrollToTop:hover{ background-color: lightgrey; +} + +#postponedate{ + height: 25px; + width: 99px } \ No newline at end of file diff --git a/public/js/infocenter/infocenterDetails.js b/public/js/infocenter/infocenterDetails.js index a43b36df8..09d2b3447 100644 --- a/public/js/infocenter/infocenterDetails.js +++ b/public/js/infocenter/infocenterDetails.js @@ -10,111 +10,113 @@ const STGFREIGABE_MESSAGE_VORLAGE = "InfocenterSTGfreigegeben"; //Statusgründe for which no Studiengang Freigabe Message should be sent const FIT_PROGRAMM_STUDIENGAENGE = [10021, 10027]; +const PARKEDNAME = 'parked'; +const ONHOLDNAME = 'onhold'; + /** * javascript file for infocenterDetails page */ $(document).ready(function () { - //initialise table sorter - Tablesort.addTablesorter("doctable", [[2, 1], [1, 0]], ["zebra"]); - Tablesort.addTablesorter("nachgdoctable", [[2, 0], [1, 1]], ["zebra"]); + //initialise table sorter + Tablesort.addTablesorter("doctable", [[2, 1], [1, 0]], ["zebra"]); + Tablesort.addTablesorter("nachgdoctable", [[2, 0], [1, 1]], ["zebra"]); - InfocenterDetails._formatMessageTable(); - InfocenterDetails._formatNotizTable(); - InfocenterDetails._formatLogTable(); + InfocenterDetails._formatMessageTable(); + InfocenterDetails._formatNotizTable(); + InfocenterDetails._formatLogTable(); - var personid = $("#hiddenpersonid").val(); - - //add submit event to message send link - $("#sendmsglink").click(function () - { - $("#sendmsgform").submit(); - }); - - //add click events to "formal geprüft" checkboxes - $(".prchbox").click(function () - { - var boxid = this.id; - var akteid = boxid.substr(boxid.indexOf("_") + 1); - var checked = this.checked; - InfocenterDetails.saveFormalGeprueft(personid, akteid, checked) - }); - - //add click events to zgv Prüfung section - InfocenterDetails._addZgvPruefungEvents(personid); - - MessageList.initMessageList(); - - //save notiz - $("#notizform").on("submit", function (e) - { - e.preventDefault(); - var notizid = $("#notizform :input[name='hiddenNotizId']").val(); - var formdata = $(this).serializeArray(); - var data = {}; - - data.person_id = personid; - - for (var i = 0; i < formdata.length; i++) - { - data[formdata[i].name] = formdata[i].value; - } - - $("#notizmsg").empty(); - - if (notizid !== '') - { - InfocenterDetails.updateNotiz(notizid, data); - } - else - { - InfocenterDetails.saveNotiz(personid, data); - } - } - ); - - //update notiz - autofill notizform - $(document).on("click", "#notiztable tbody tr", function () - { - $("#notizmsg").empty(); - - var notizid = $(this).find("td.hiddennotizid").html(); - - InfocenterDetails.getNotiz(notizid); - } - ); - - //update notiz - abbrechen-button: reset styles - $("#notizform :input[type='reset']").click(function () - { - InfocenterDetails._resetNotizFields(); - } - ); - - //check if person is parked and display it - InfocenterDetails.getParkedDate(personid); - - if ($(document).scrollTop() > 20) - $("#scrollToTop").show(); - - //scroll to top button - $(window).scroll(function() - { - if ($(document).scrollTop() > 20) - $("#scrollToTop").show(); - else - $("#scrollToTop").hide(); - } - ); - - $("#scrollToTop").click(function() - { - $('html,body').animate({scrollTop:0},250,'linear'); - } - ) + var personid = $("#hiddenpersonid").val(); + //add submit event to message send link + $("#sendmsglink").click(function () + { + $("#sendmsgform").submit(); }); + //add click events to "formal geprüft" checkboxes + $(".prchbox").click(function () + { + var boxid = this.id; + var akteid = boxid.substr(boxid.indexOf("_") + 1); + var checked = this.checked; + InfocenterDetails.saveFormalGeprueft(personid, akteid, checked) + }); + + //add click events to zgv Prüfung section + InfocenterDetails._addZgvPruefungEvents(personid); + + MessageList.initMessageList(); + + //save notiz + $("#notizform").on("submit", function (e) + { + e.preventDefault(); + var notizid = $("#notizform :input[name='hiddenNotizId']").val(); + var formdata = $(this).serializeArray(); + var data = {}; + + data.person_id = personid; + + for (var i = 0; i < formdata.length; i++) + { + data[formdata[i].name] = formdata[i].value; + } + + $("#notizmsg").empty(); + + if (notizid !== '') + { + InfocenterDetails.updateNotiz(notizid, data); + } + else + { + InfocenterDetails.saveNotiz(personid, data); + } + } + ); + + //update notiz - autofill notizform + $(document).on("click", "#notiztable tbody tr", function () + { + $("#notizmsg").empty(); + + var notizid = $(this).find("td.hiddennotizid").html(); + + InfocenterDetails.getNotiz(notizid); + } + ); + + //update notiz - abbrechen-button: reset styles + $("#notizform :input[type='reset']").click(function () + { + InfocenterDetails._resetNotizFields(); + } + ); + + //check if person is postponed (parked, on hold...) and display it + InfocenterDetails.getPostponeDate(personid); + + if ($(document).scrollTop() > 20) + $("#scrollToTop").show(); + + //scroll to top button + $(window).scroll(function() + { + if ($(document).scrollTop() > 20) + $("#scrollToTop").show(); + else + $("#scrollToTop").hide(); + } + ); + + $("#scrollToTop").click(function() + { + $('html,body').animate({scrollTop:0},250,'linear'); + } + ) +}); + var InfocenterDetails = { openZgvInfoForPrestudent: function(prestudent_id) @@ -397,7 +399,7 @@ var InfocenterDetails = { { var engdate = $.datepicker.parseDate("yy-mm-dd", FHC_AjaxClient.getData(data)[0]); var gerdate = $.datepicker.formatDate("dd.mm.yy", engdate); - $("#parkdate").val(gerdate); + $("#postponedate").val(gerdate); } }, errorCallback: function() @@ -408,19 +410,19 @@ var InfocenterDetails = { } ); }, - getParkedDate: function(personid) + getPostponeDate: function(personid) { FHC_AjaxClient.ajaxCallGet( - CALLED_PATH + "/getParkedDate/"+encodeURIComponent(personid), + CALLED_PATH + "/getPostponeDate/"+encodeURIComponent(personid), null, { successCallback: function(data, textStatus, jqXHR) { if (FHC_AjaxClient.hasData(data)) { - var parkedDate = FHC_AjaxClient.getData(data)[0]; - InfocenterDetails._refreshParking(parkedDate); + var postponeobj = FHC_AjaxClient.getData(data); + InfocenterDetails._refreshPostpone(postponeobj); InfocenterDetails._refreshLog(); - if (parkedDate === null) + if (postponeobj === null || postponeobj.type === null) InfocenterDetails.getStudienjahrEnd(); } }, @@ -435,7 +437,7 @@ var InfocenterDetails = { parkPerson: function(personid, date) { var parkError = function(){ - $("#parkmsg").text(" Fehler beim Parken!"); + $("#postponemsg").text(" Fehler beim Parken!"); }; FHC_AjaxClient.ajaxCallPost( @@ -447,7 +449,7 @@ var InfocenterDetails = { { successCallback: function(data, textStatus, jqXHR) { if (FHC_AjaxClient.hasData(data)) - InfocenterDetails.getParkedDate(personid); + InfocenterDetails.getPostponeDate(personid); else { parkError(); @@ -469,13 +471,62 @@ var InfocenterDetails = { successCallback: function(data, textStatus, jqXHR) { if (FHC_AjaxClient.hasData(data)) { - InfocenterDetails.getParkedDate(personid); + InfocenterDetails.getPostponeDate(personid); } else - $("#unparkmsg").removeClass().addClass("text-warning").text(FHC_PhrasesLib.t('infocenter', 'nichtsZumAusparken')); + $("#unpostponemsg").removeClass().addClass("text-warning").text(FHC_PhrasesLib.t('infocenter', 'nichtsZumAusparken')); }, errorCallback: function(){ - $("#unparkmsg").removeClass().addClass("text-danger").text(FHC_PhrasesLib.t('infocenter', 'fehlerBeimAusparken')); + $("#unpostponemsg").removeClass().addClass("text-danger").text(FHC_PhrasesLib.t('infocenter', 'fehlerBeimAusparken')); + }, + veilTimeout: 0 + } + ); + }, + setPersonOnHold: function(personid, date) + { + var onHoldError = function(){ + $("#postponemsg").text(" Fehler beim Setzen auf On Hold!"); + }; + + FHC_AjaxClient.ajaxCallPost( + CALLED_PATH + '/setOnHold', + { + "person_id": personid, + "onholddate": date + }, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.hasData(data)) + InfocenterDetails.getPostponeDate(personid); + else + { + onHoldError(); + } + }, + errorCallback: onHoldError, + veilTimeout: 0 + } + ); + }, + removePersonOnHold: function(personid) + { + FHC_AjaxClient.ajaxCallPost( + CALLED_PATH + '/removeOnHold', + { + "person_id": personid + }, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.hasData(data)) + { + InfocenterDetails.getPostponeDate(personid); + } + else + $("#unpostponemsg").removeClass().addClass("text-warning").text(FHC_PhrasesLib.t('infocenter', 'nichtsZumEntfernen')); + }, + errorCallback: function(){ + $("#unpostponemsg").removeClass().addClass("text-danger").text(FHC_PhrasesLib.t('infocenter', 'fehlerBeimEntfernen')); }, veilTimeout: 0 } @@ -864,50 +915,98 @@ var InfocenterDetails = { } ); }, - _refreshParking: function(date) + _refreshPostpone: function(postponeobj) { - if (date === null) + var personid = $("#hiddenpersonid").val(); + if (postponeobj === null || postponeobj.date === null || postponeobj.type === null) { - $("#parking").html( + //show both park and on hold buttons if not parked and not on hold + $("#postponing").html( '
'+ '     '+ + '     '+ FHC_PhrasesLib.t('global', 'bis') + '  '+ - ' '+ - ''+ + ' '+ + ' '+ + ''+ '
'); - $("#parkdate").datepicker({ + $("#postponedate").datepicker({ "dateFormat": "dd.mm.yy", "minDate": 0 }); + $("#parklink").click( function () { - var personid = $("#hiddenpersonid").val(); - var date = $("#parkdate").val(); - + //console.log(date); + var date = $("#postponedate").val(); InfocenterDetails.parkPerson(personid, date); } ); + + $("#onholdlink").click( + + function () + { + var date = $("#postponedate").val(); + InfocenterDetails.setPersonOnHold(personid, date); + } + ); } else { - var parkdate = $.datepicker.parseDate("yy-mm-dd", date); - var gerparkdate = $.datepicker.formatDate("dd.mm.yy", parkdate); - $("#parking").html( - FHC_PhrasesLib.t('infocenter', 'bewerberGeparktBis')+'  '+gerparkdate+'     '+ - ' '+ - '' + //info if parked/on hold and possibility to undo parking/on hold + var postponedate = $.datepicker.parseDate("yy-mm-dd", postponeobj.date); + var gerpostponedate = $.datepicker.formatDate("dd.mm.yy", postponedate); + + //var postponehtml = ""; + var callbackforundo = null; + var removePhrase = ""; + var postponedPhrase = ""; + var postponedtext = ""; + + if (postponeobj.type === PARKEDNAME) + { + removePhrase = 'bewerberAusparken'; + postponedtext = FHC_PhrasesLib.t('infocenter', 'bewerberGeparktBis')+'  '+gerpostponedate; + + callbackforundo = function () + { + InfocenterDetails.unparkPerson(personid); + } + } + else if (postponeobj.type === ONHOLDNAME) + { + removePhrase = 'bewerberOnHoldEntfernen'; + postponedtext = FHC_PhrasesLib.t('infocenter', 'bewerberOnHoldBis')+'  '+gerpostponedate; + + var currdate = new Date(); + + if (currdate > postponedate) + postponedtext = ""+postponedtext+""; + + callbackforundo = function () + { + InfocenterDetails.removePersonOnHold(personid); + } + } + + var postponehtml = postponedtext+'     '+ + ' '+ + ''; + + + $("#postponing").html( + postponehtml ); - $("#unparklink").click( - function () - { - var personid = $("#hiddenpersonid").val(); - InfocenterDetails.unparkPerson(personid, date); - } + $("#unpostponelink").click( + callbackforundo ); } }, diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 0ee2aeda5..b38aebb2c 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -3450,6 +3450,106 @@ $phrases = array( 'insertvon' => 'system' ) ) + ), + array( + 'app' => 'infocenter', + 'category' => 'infocenter', + 'phrase' => 'bewerberOnHold', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'BewerberIn zurückstellen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Put applicant on hold', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'infocenter', + 'category' => 'infocenter', + 'phrase' => 'bewerberOnHoldEntfernen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zurückstellung entfernen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Remove on hold state', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'infocenter', + 'category' => 'infocenter', + 'phrase' => 'bewerberOnHoldBis', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'BewerberIn zurückgestellt bis', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Applicant on hold until', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'infocenter', + 'category' => 'infocenter', + 'phrase' => 'nichtsZumEntfernen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nichts zum Entfernen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Nothing to remove', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'infocenter', + 'category' => 'infocenter', + 'phrase' => 'fehlerBeimEntfernen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Fehler beim Entfernen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Error when removing', + 'description' => '', + 'insertvon' => 'system' + ) + ) ) ); From 73e248534b58ac2e2aa23f98401d868ce30a14a9 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 3 Oct 2019 10:15:10 +0200 Subject: [PATCH 06/22] - infocenterDetails: added phrases rueckstelldatumUeberschritten and parkenZurueckstellenInfo --- .../system/infocenter/infocenterDetails.php | 2 + public/js/infocenter/infocenterDetails.js | 7 +-- system/phrasesupdate.php | 45 ++++++++++++++++++- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/application/views/system/infocenter/infocenterDetails.php b/application/views/system/infocenter/infocenterDetails.php index 68b6c760e..ab4e3533e 100644 --- a/application/views/system/infocenter/infocenterDetails.php +++ b/application/views/system/infocenter/infocenterDetails.php @@ -40,6 +40,8 @@ 'bewerberOnHoldBis', 'nichtsZumEntfernen', 'fehlerBeimEntfernen', + 'rueckstelldatumUeberschritten', + 'parkenZurueckstellenInfo' ), 'ui' => array( 'gespeichert', diff --git a/public/js/infocenter/infocenterDetails.js b/public/js/infocenter/infocenterDetails.js index 09d2b3447..96975d179 100644 --- a/public/js/infocenter/infocenterDetails.js +++ b/public/js/infocenter/infocenterDetails.js @@ -927,9 +927,7 @@ var InfocenterDetails = { '     '+ FHC_PhrasesLib.t('global', 'bis') + '  '+ ' '+ - ' '+ + ' '+ ''+ '
'); @@ -943,7 +941,6 @@ var InfocenterDetails = { function () { - //console.log(date); var date = $("#postponedate").val(); InfocenterDetails.parkPerson(personid, date); } @@ -988,7 +985,7 @@ var InfocenterDetails = { var currdate = new Date(); if (currdate > postponedate) - postponedtext = ""+postponedtext+""; + postponedtext = ""+postponedtext+""; callbackforundo = function () { diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index b38aebb2c..65206c9e9 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -3550,8 +3550,51 @@ $phrases = array( 'insertvon' => 'system' ) ) + ), + array( + 'app' => 'infocenter', + 'category' => 'infocenter', + 'phrase' => 'rueckstelldatumUeberschritten', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zurückstelldatum überschritten!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Exceeded date for on hold!', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'infocenter', + 'category' => 'infocenter', + 'phrase' => 'parkenZurueckstellenInfo', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Geparkte und zurückgestellte BewerberInnen werden von der Bearbeitung temporär ausgenommen. +Geparkte BewerberInnen werden zum angegebenen Datum automatisch entparkt, während zurückgestellte BewerberInnen nur manuell durch Drücken des Buttons den Zurückgestellt-Status verlieren. +Bei einer Zurückstellung dient das Datum nur der Erinnerung.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Parked applicants and applicants on hold are temporarily excluded from the infocenter workflow. +Parked applicants are unparked automatically, whereas applicants on hold loose the status only when clicking the button manually. +When on hold, the date is only a reminder.', + 'description' => '', + 'insertvon' => 'system' + ) + ) ) - ); From fce3659573f13ccabd4fc2d035c24eb9f8580f3c Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 3 Oct 2019 15:22:54 +0200 Subject: [PATCH 07/22] =?UTF-8?q?-=20Infocenter=20=C3=9Cbersicht:=20zur?= =?UTF-8?q?=C3=BCckgestellte=20BewerberInnen=20werden=20gr=C3=BCn=20markie?= =?UTF-8?q?rt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/infocenter/infocenterData.php | 21 +++++++++++++++++++ .../js/infocenter/infocenterPersonDataset.js | 3 ++- system/phrasesupdate.php | 20 ++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/application/views/system/infocenter/infocenterData.php b/application/views/system/infocenter/infocenterData.php index 04b99b057..49f0c7af6 100644 --- a/application/views/system/infocenter/infocenterData.php +++ b/application/views/system/infocenter/infocenterData.php @@ -7,6 +7,7 @@ $TAETIGKEIT_KURZBZ = '\'bewerbung\', \'kommunikation\''; $LOGDATA_NAME = '\'Login with code\', \'Login with user\', \'New application\', \'Interessent rejected\''; $LOGDATA_NAME_PARKED = '\'Parked\''; + $LOGDATA_NAME_ONHOLD = '\'Onhold\''; $LOGTYPE_KURZBZ = '\'Processstate\''; $STATUS_KURZBZ = '\'Wartender\', \'Bewerber\', \'Aufgenommener\', \'Student\''; $ADDITIONAL_STG = '10021,10027'; @@ -24,6 +25,7 @@ pl.zeitpunkt AS "LockDate", pl.lockuser AS "LockUser", pd.parkdate AS "ParkDate", + ohd.onholddate AS "OnholdDate", ( SELECT l.zeitpunkt FROM system.tbl_log l @@ -228,6 +230,14 @@ AND l.logdata->>\'name\' = '.$LOGDATA_NAME_PARKED.' AND l.zeitpunkt >= NOW() ) pd USING(person_id) + LEFT JOIN ( + SELECT l.person_id, + l.zeitpunkt AS onholddate + FROM system.tbl_log l + WHERE l.logtype_kurzbz = '.$LOGTYPE_KURZBZ.' + AND l.logdata->>\'name\' = '.$LOGDATA_NAME_ONHOLD.' + AND l.zeitpunkt >= NOW() + ) ohd USING(person_id) WHERE EXISTS ( SELECT 1 @@ -278,6 +288,7 @@ ucfirst($this->p->t('global', 'sperrdatum')), ucfirst($this->p->t('global', 'gesperrtVon')), ucfirst($this->p->t('global', 'parkdatum')), + ucfirst($this->p->t('global', 'rueckstelldatum')), ucfirst($this->p->t('global', 'letzteAktion')), 'Aktionstyp', 'AnzahlAktePflicht', @@ -340,6 +351,11 @@ $datasetRaw->{'ParkDate'} = '-'; } + if ($datasetRaw->{'OnholdDate'} == null) + { + $datasetRaw->{'OnholdDate'} = '-'; + } + if ($datasetRaw->{'StgAbgeschickt'} == null) { $datasetRaw->{'StgAbgeschickt'} = '-'; @@ -376,6 +392,11 @@ $mark = FilterWidget::DEFAULT_MARK_ROW_CLASS; } + if ($datasetRaw->OnholdDate != null) + { + $mark = "text-success"; + } + // Parking has priority over locking if ($datasetRaw->ParkDate != null) { diff --git a/public/js/infocenter/infocenterPersonDataset.js b/public/js/infocenter/infocenterPersonDataset.js index 54933165d..8f0fcaf4b 100644 --- a/public/js/infocenter/infocenterPersonDataset.js +++ b/public/js/infocenter/infocenterPersonDataset.js @@ -50,7 +50,8 @@ var InfocenterPersonDataset = { ' Nachricht senden'; var legendHtml = ' Gesperrt    ' + - ' Geparkt'; + ' Geparkt    ' + + ' Zurückgestellt'; // userdefined Semestervariable shown independently of personcount, // it is possible to change the semester diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 65206c9e9..58bbdd755 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -3291,6 +3291,26 @@ $phrases = array( ) ) ), + array( + 'app' => 'core', + 'category' => 'global', + 'phrase' => 'rueckstelldatum', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'rückstelldatum', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'on hold date', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'infocenter', 'category' => 'infocenter', From 854dcb7cea1a984122ee0df5686d3f56f95d6d65 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 3 Oct 2019 16:23:19 +0200 Subject: [PATCH 08/22] =?UTF-8?q?-=20Infocenter:=20dataset=20in=20=C3=9Cbe?= =?UTF-8?q?rsicht=20is=20reloaded=20when=20clicking=20on=20back=20button?= =?UTF-8?q?=20from=20details=20page.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/controllers/system/infocenter/InfoCenter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index e14a34d8f..7d005489d 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -970,7 +970,7 @@ class InfoCenter extends Auth_Controller $prevFilterId = $this->input->get(self::PREV_FILTER_ID); if (isset($prevFilterId)) { - $link .= '?'.self::FILTER_ID.'='.$prevFilterId; + $link .= '?'.self::FILTER_ID.'='.$prevFilterId.'&'.self::RELOAD_DATASET.'=true'; } $this->navigationlib->setSessionMenu( From 5ef7fa21121e0db5f08585eb96b44dfef5b2bbb6 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 3 Oct 2019 17:16:27 +0200 Subject: [PATCH 09/22] - PersonLogLib: rename _saveLog function to _savePsLog (processtate log) --- application/libraries/PersonLogLib.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application/libraries/PersonLogLib.php b/application/libraries/PersonLogLib.php index ed530ef34..299fc8ce2 100644 --- a/application/libraries/PersonLogLib.php +++ b/application/libraries/PersonLogLib.php @@ -101,7 +101,7 @@ class PersonLogLib 'name' => self::PARKED_LOGNAME ); - return $this->_saveLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app, $oe_kurzbz, $user); + return $this->_savePsLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app, $oe_kurzbz, $user); } /** @@ -182,7 +182,7 @@ class PersonLogLib 'name' => self::ONHOLD_LOGNAME ); - return $this->_saveLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app, $oe_kurzbz, $user); + return $this->_savePsLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app, $oe_kurzbz, $user); } /** @@ -241,7 +241,7 @@ class PersonLogLib } /** - * Saves a log with specified parameters, including a specified log date. + * Saves a processstate log with specified parameters, including a specified log date. * @param $person_id * @param $date * @param $taetigkeit_kurzbz @@ -251,7 +251,7 @@ class PersonLogLib * @param null $user * @return mixed */ - private function _saveLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app = 'core', $oe_kurzbz = null, $user = null) + private function _savePsLog($person_id, $date, $taetigkeit_kurzbz, $logjson, $app = 'core', $oe_kurzbz = null, $user = null) { $data = array( 'person_id' => $person_id, From ee199236f1146431748ad15dc39b54ebf8cd151e Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 7 Oct 2019 10:09:47 +0200 Subject: [PATCH 10/22] CIS profil Funktionen: - added Wochenstunden column - added Wochenstunden and Vertragsstunden Summe - removed semester and institut column - --- cis/private/profile/index.php | 45 +++++++-- locale/de-AT/profil.php | 167 +++++++++++++++++----------------- locale/en-US/profil.php | 163 ++++++++++++++++----------------- locale/it-IT/profil.php | 125 ++++++++++++------------- 4 files changed, 268 insertions(+), 232 deletions(-) diff --git a/cis/private/profile/index.php b/cis/private/profile/index.php index 5f93930cc..d1d6c96b5 100644 --- a/cis/private/profile/index.php +++ b/cis/private/profile/index.php @@ -507,7 +507,7 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN $qry = "SELECT *, tbl_benutzerfunktion.oe_kurzbz as oe_kurzbz, tbl_organisationseinheit.bezeichnung as oe_bezeichnung, tbl_benutzerfunktion.semester, tbl_benutzerfunktion.bezeichnung as bf_bezeichnung, - tbl_benutzerfunktion.datum_von, tbl_benutzerfunktion.datum_bis + tbl_benutzerfunktion.wochenstunden, tbl_benutzerfunktion.datum_von, tbl_benutzerfunktion.datum_bis FROM public.tbl_benutzerfunktion JOIN public.tbl_funktion USING(funktion_kurzbz) @@ -526,14 +526,15 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN '.$p->t('global/bezeichnung').' '.$p->t('global/organisationseinheit').' - '.$p->t('global/semester').' - '.$p->t('global/institut').' '.$p->t('profil/gueltigvon').' '.$p->t('profil/gueltigbis').' + '.$p->t('profil/wochenstunden').' '; + $wochenstunden_sum = 0.00; + while($row_funktion = $db->db_fetch_object($result_funktion)) { echo " @@ -544,13 +545,45 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN echo ' - '.$row_funktion->bf_bezeichnung; echo " ".$row_funktion->organisationseinheittyp_kurzbz.' '.$row_funktion->oe_bezeichnung." - $row_funktion->semester - $row_funktion->fachbereich_kurzbz ".$datum_obj->formatDatum($row_funktion->datum_von,'d.m.Y')." ".$datum_obj->formatDatum($row_funktion->datum_bis,'d.m.Y')." + ".$row_funktion->wochenstunden." "; + + if(isset($row_funktion->wochenstunden)) + $wochenstunden_sum += (double)$row_funktion->wochenstunden; } - echo '
'; + echo '
'; + + //vertragsstunden + $vertragsstunden = 0.00; + $qry = "SELECT sum(vertragsstunden) AS vertragsstdsumme from bis.tbl_bisverwendung + WHERE mitarbeiter_uid = ".$db->db_add_param($uid)." + AND (ende > now() OR ende IS NULL)"; + + if ($result_vertragsstd = $db->db_query($qry)) + { + if ($db->db_num_rows($result_vertragsstd) > 0) + { + while($row_vertragsstd = $db->db_fetch_object($result_vertragsstd)) + { + $vertragsstunden = $row_vertragsstd->vertragsstdsumme; + } + } + } + + echo " + + + + + Summe Wochenstunden (Vertragsstunden) +  ".number_format($wochenstunden_sum,2). + " (".number_format($vertragsstunden,2).") + + "; + echo ""; + } } } diff --git a/locale/de-AT/profil.php b/locale/de-AT/profil.php index 52f1c439d..61c89784e 100644 --- a/locale/de-AT/profil.php +++ b/locale/de-AT/profil.php @@ -1,83 +1,84 @@ -phrasen['profil/profil']='Profil'; -$this->phrasen['profil/mitarbeiter']='MitarbeiterIn'; -$this->phrasen['profil/home']='HOME'; -$this->phrasen['profil/meinCis']='Mein CIS'; -$this->phrasen['profil/bildHochladen']='Profilfoto hochladen'; -$this->phrasen['profil/email']='eMail'; -$this->phrasen['profil/kontaktPrivat']='Private Kontakte'; -$this->phrasen['profil/mobil']='Mobil'; -$this->phrasen['profil/telefon']='Telefon'; -$this->phrasen['profil/intern']='Intern'; -$this->phrasen['profil/alias']='Alias'; -$this->phrasen['profil/homepage']='Homepage'; -$this->phrasen['profil/student']='StudentIn'; -$this->phrasen['profil/martrikelnummer']='Personenkennzeichen'; -$this->phrasen['profil/leistungsbeurteilung']='Leistungsbeurteilung'; -$this->phrasen['profil/kurzzeichen']='Kurzzeichen'; -$this->phrasen['profil/telefonTw']='Telefon'; -$this->phrasen['profil/faxTw']='Fax'; -$this->phrasen['profil/zeitwuensche']='Zeitwünsche'; -$this->phrasen['profil/funktionen']='Funktionen'; -$this->phrasen['profil/entlehnteBetriebsmittel']='Entlehnte Betriebsmittel'; -$this->phrasen['profil/betriebsmittel']='Betriebsmittel'; -$this->phrasen['profil/nummer']='Nummer'; -$this->phrasen['profil/ausgegebenAm']='Ausgegeben am'; -$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='Sie sind Mitglied in folgenden Verteilern'; -$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'Der User %s ist Mitglied in folgenden Verteilern'; -$this->phrasen['profil/alleStudentenVon']='Alle StudentInnen von'; -$this->phrasen['profil/kurzbeschreibungFuerOeh']='Kurzbeschreibung für die ÖH-Kandidatur'; -$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die zuständige Assistenz'; -$this->phrasen['profil/esWurdenKeineProfileGefunden']='Es wurden keine oder mehrere Profile für Ihren Useraccount gefunden'; -$this->phrasen['profil/adminstration']='Administration'; -$this->phrasen['profil/zustaendigeAssistenz']='zuständige Assistenz'; -$this->phrasen['profil/wendenSieSichAn']='Bitte wenden Sie sich an die'; -$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die'; -$this->phrasen['profil/buero']='Büro'; -$this->phrasen['profil/zeitsperrenVon']='Zeitsperren von'; -$this->phrasen['profil/lvplanVon']='LV-Plan von'; - -$this->phrasen['profil/AccountInaktiv']='Achtung: Dieser Account ist nicht mehr aktiv'; -$this->phrasen['profil/inaktivStudent']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz -deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

-Sollte innerhalb von 6 Monaten (für Studierende) bzw. 3 Wochen (für AbbrecherInnen) nach der Deaktivierung keine -neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
-- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, -sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; - -$this->phrasen['profil/inaktivMitarbeiter']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz -deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

-Sollte innerhalb von 12 Monaten nach der Deaktivierung keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
-- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
-- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, -sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; - -$this->phrasen['profil/inaktivSonstige']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz -deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

-Sollte innerhalb der nächsten Tagen keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
-- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
-- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, -sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; - -$this->phrasen['profil/nurJPGBilder']='Derzeit können nur Bilder im JPG Format hochgeladen werden'; -$this->phrasen['profil/BilduploadInfotext']='Derzeit können nur Bilder im JPG Format mit einer Maximalgröße von 15MB hochgeladen werden!

Bitte beachten Sie die Richtlinien für den Bildupload'; -$this->phrasen['profil/Bild']='Profilfoto'; -$this->phrasen['profil/Bildupload']='Bildupload'; -$this->phrasen['profil/fotofreigeben']='Sperre des Profilfotos aufheben'; -$this->phrasen['profil/fotosperren']='Profilfoto sperren'; -$this->phrasen['profil/infotextSperre']='Gesperrte Profilbilder werden nur für Zutrittskarten verwendet und scheinen nicht auf Anwesenheitslisten oder in der Personensuche auf'; -$this->phrasen['profil/profilfotoGesperrt']='Profilfoto gesperrt'; -$this->phrasen['profil/profilfotoUploadGesperrt']='Der Upload des Profilfotos ist nicht mehr möglich'; -$this->phrasen['profil/fhausweisStatus']='FH-Ausweis Status'; -$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Der FH Ausweis ist am %s ausgegeben worden.'; -$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Laden Sie bitte ein gültiges Foto hoch'; -$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Foto wurde noch nicht akzeptiert'; -$this->phrasen['profil/fhausweisGedrucktAm']='FH-Ausweis gedruckt am'; -$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='FH-Ausweis abholbereit am Empfang ab'; -$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='FH-Ausweis wurde noch nicht gedruckt'; -$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Ihr Foto wurde noch nicht geprüft'; -$this->phrasen['profil/fotoAuswählen']='Klicken Sie auf das Bild um ein Foto hochzuladen'; -$this->phrasen['profil/bildSpeichern']='Bild speichern'; -$this->phrasen['profil/gueltigvon']='Gültig von'; -$this->phrasen['profil/gueltigbis']='Gültig bis'; -?> +phrasen['profil/profil']='Profil'; +$this->phrasen['profil/mitarbeiter']='MitarbeiterIn'; +$this->phrasen['profil/home']='HOME'; +$this->phrasen['profil/meinCis']='Mein CIS'; +$this->phrasen['profil/bildHochladen']='Profilfoto hochladen'; +$this->phrasen['profil/email']='eMail'; +$this->phrasen['profil/kontaktPrivat']='Private Kontakte'; +$this->phrasen['profil/mobil']='Mobil'; +$this->phrasen['profil/telefon']='Telefon'; +$this->phrasen['profil/intern']='Intern'; +$this->phrasen['profil/alias']='Alias'; +$this->phrasen['profil/homepage']='Homepage'; +$this->phrasen['profil/student']='StudentIn'; +$this->phrasen['profil/martrikelnummer']='Personenkennzeichen'; +$this->phrasen['profil/leistungsbeurteilung']='Leistungsbeurteilung'; +$this->phrasen['profil/kurzzeichen']='Kurzzeichen'; +$this->phrasen['profil/telefonTw']='Telefon'; +$this->phrasen['profil/faxTw']='Fax'; +$this->phrasen['profil/zeitwuensche']='Zeitwünsche'; +$this->phrasen['profil/funktionen']='Funktionen'; +$this->phrasen['profil/entlehnteBetriebsmittel']='Entlehnte Betriebsmittel'; +$this->phrasen['profil/betriebsmittel']='Betriebsmittel'; +$this->phrasen['profil/nummer']='Nummer'; +$this->phrasen['profil/ausgegebenAm']='Ausgegeben am'; +$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='Sie sind Mitglied in folgenden Verteilern'; +$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'Der User %s ist Mitglied in folgenden Verteilern'; +$this->phrasen['profil/alleStudentenVon']='Alle StudentInnen von'; +$this->phrasen['profil/kurzbeschreibungFuerOeh']='Kurzbeschreibung für die ÖH-Kandidatur'; +$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die zuständige Assistenz'; +$this->phrasen['profil/esWurdenKeineProfileGefunden']='Es wurden keine oder mehrere Profile für Ihren Useraccount gefunden'; +$this->phrasen['profil/adminstration']='Administration'; +$this->phrasen['profil/zustaendigeAssistenz']='zuständige Assistenz'; +$this->phrasen['profil/wendenSieSichAn']='Bitte wenden Sie sich an die'; +$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die'; +$this->phrasen['profil/buero']='Büro'; +$this->phrasen['profil/zeitsperrenVon']='Zeitsperren von'; +$this->phrasen['profil/lvplanVon']='LV-Plan von'; + +$this->phrasen['profil/AccountInaktiv']='Achtung: Dieser Account ist nicht mehr aktiv'; +$this->phrasen['profil/inaktivStudent']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz +deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

+Sollte innerhalb von 6 Monaten (für Studierende) bzw. 3 Wochen (für AbbrecherInnen) nach der Deaktivierung keine +neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
+- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, +sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; + +$this->phrasen['profil/inaktivMitarbeiter']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz +deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

+Sollte innerhalb von 12 Monaten nach der Deaktivierung keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
+- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
+- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, +sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; + +$this->phrasen['profil/inaktivSonstige']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz +deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

+Sollte innerhalb der nächsten Tagen keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
+- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
+- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, +sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; + +$this->phrasen['profil/nurJPGBilder']='Derzeit können nur Bilder im JPG Format hochgeladen werden'; +$this->phrasen['profil/BilduploadInfotext']='Derzeit können nur Bilder im JPG Format mit einer Maximalgröße von 15MB hochgeladen werden!

Bitte beachten Sie die Richtlinien für den Bildupload'; +$this->phrasen['profil/Bild']='Profilfoto'; +$this->phrasen['profil/Bildupload']='Bildupload'; +$this->phrasen['profil/fotofreigeben']='Sperre des Profilfotos aufheben'; +$this->phrasen['profil/fotosperren']='Profilfoto sperren'; +$this->phrasen['profil/infotextSperre']='Gesperrte Profilbilder werden nur für Zutrittskarten verwendet und scheinen nicht auf Anwesenheitslisten oder in der Personensuche auf'; +$this->phrasen['profil/profilfotoGesperrt']='Profilfoto gesperrt'; +$this->phrasen['profil/profilfotoUploadGesperrt']='Der Upload des Profilfotos ist nicht mehr möglich'; +$this->phrasen['profil/fhausweisStatus']='FH-Ausweis Status'; +$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Der FH Ausweis ist am %s ausgegeben worden.'; +$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Laden Sie bitte ein gültiges Foto hoch'; +$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Foto wurde noch nicht akzeptiert'; +$this->phrasen['profil/fhausweisGedrucktAm']='FH-Ausweis gedruckt am'; +$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='FH-Ausweis abholbereit am Empfang ab'; +$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='FH-Ausweis wurde noch nicht gedruckt'; +$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Ihr Foto wurde noch nicht geprüft'; +$this->phrasen['profil/fotoAuswählen']='Klicken Sie auf das Bild um ein Foto hochzuladen'; +$this->phrasen['profil/bildSpeichern']='Bild speichern'; +$this->phrasen['profil/gueltigvon']='Gültig von'; +$this->phrasen['profil/gueltigbis']='Gültig bis'; +$this->phrasen['profil/wochenstunden']='Wochenstunden'; +?> diff --git a/locale/en-US/profil.php b/locale/en-US/profil.php index 30ea23f1a..538c1d1e4 100644 --- a/locale/en-US/profil.php +++ b/locale/en-US/profil.php @@ -1,81 +1,82 @@ -phrasen['profil/home']='HOME'; -$this->phrasen['profil/profil']='Profile'; -$this->phrasen['profil/mitarbeiter']='Employee'; -$this->phrasen['profil/meinCis']='My CIS'; -$this->phrasen['profil/bildHochladen']='Upload picture'; -$this->phrasen['profil/email']='eMail'; -$this->phrasen['profil/kontaktPrivat']='Private Contacts'; -$this->phrasen['profil/intern']='Intern'; -$this->phrasen['profil/alias']='Alias'; -$this->phrasen['profil/homepage']='Homepage'; -$this->phrasen['profil/student']='Student'; -$this->phrasen['profil/martrikelnummer']='matriculation number'; -$this->phrasen['profil/leistungsbeurteilung']='Performance assessment'; -$this->phrasen['profil/kurzzeichen']='Abbreviation'; -$this->phrasen['profil/telefonTw']='Telephone'; -$this->phrasen['profil/faxTw']='Fax'; -$this->phrasen['profil/zeitwuensche']='Preferred teaching times'; -$this->phrasen['profil/funktionen']='Functions'; -$this->phrasen['profil/entlehnteBetriebsmittel']='Borrowed equipment'; -$this->phrasen['profil/betriebsmittel']='Equipment'; -$this->phrasen['profil/nummer']='Number'; -$this->phrasen['profil/ausgegebenAm']='Issued on'; -$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='You are member of the following mailing lists'; -$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'User %s is a member of the following mailing lists'; -$this->phrasen['profil/alleStudentenVon']='All students from'; -$this->phrasen['profil/kurzbeschreibungFuerOeh']='Brief description for the Austian Student Union candidacy'; -$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible assistant'; -$this->phrasen['profil/esWurdenKeineProfileGefunden']='No profile ore multiple profiles were found for your user account'; -$this->phrasen['profil/adminstration']='Administration'; -$this->phrasen['profil/zustaendigeAssistenz']='Administrative Assistant'; -$this->phrasen['profil/wendenSieSichAn']='Please contact the'; -$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible'; -$this->phrasen['profil/buero']='Office'; -$this->phrasen['profil/zeitsperrenVon']='Unavailabilities of'; -$this->phrasen['profil/lvplanVon']='Schedule from'; - -$this->phrasen['profil/AccountInaktiv']='NOTICE: This account is no longer active'; -$this->phrasen['profil/inaktivStudent']='NOTICE!
We would like to remind you that your user record has been deactivated. -You were also removed from all e-mail distribution lists when your account was deactivated.

-If your user account is not reactivated within 6 months (for students) or 3 weeks (for dropouts) of being deactivated, the following data will be automatically deleted:
-- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

-If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; - -$this->phrasen['profil/inaktivMitarbeiter']='NOTICE!
We would like to remind you that your user record has been deactivated. -You were also removed from all e-mail distribution lists when your account was deactivated.

-If your user account is not reactivated within 12 months of being deactivated, the following data will be automatically deleted:
-- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

-If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; - -$this->phrasen['profil/inaktivSonstige']='NOTICE!
We would like to remind you that your user record has been deactivated. -You were also removed from all e-mail distribution lists when your account was deactivated.

-If your user account is not reactivated within the next days of being deactivated, the following data will be automatically deleted:
-- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

-If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; - - - - -$this->phrasen['profil/nurJPGBilder']='Currently it is only possible to upload JPEG images'; -$this->phrasen['profil/BilduploadInfotext']='Currently it is only possible to upload JPG images with a maximum size of 15MB!

Please follow the guidelines for uploading images'; -$this->phrasen['profil/Bild']='Picture'; -$this->phrasen['profil/Bildupload']='Upload Picture'; -$this->phrasen['profil/fotofreigeben']='Unlock your profile photo'; -$this->phrasen['profil/fotosperren']='Lock your profile photo'; -$this->phrasen['profil/infotextSperre']='Locked profile photos are only used for access cards, and do not appear on attendance lists or in the people search'; -$this->phrasen['profil/profilfotoGesperrt']='Profile photo locked'; -$this->phrasen['profil/profilfotoUploadGesperrt']='It is no longer possible to upload a profile photo'; -$this->phrasen['profil/fhausweisStatus']='UAS ID card status'; -$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='UAS ID card has already been issued on %s.'; -$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Please upload a valid photo'; -$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Photo has not yet been accepted'; -$this->phrasen['profil/fhausweisGedrucktAm']='UAS ID card printed on'; -$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='UAS ID card will be ready for pick-up at the information desk on'; -$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='UAS ID card has not yet been printed'; -$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Your photo has not yet been approved'; -$this->phrasen['profil/fotoAuswählen']='Click on the image below to upload a photo'; -$this->phrasen['profil/bildSpeichern']='Save image'; -$this->phrasen['profil/gueltigvon']='Valid from'; -$this->phrasen['profil/gueltigbis']='Valid to'; -?> +phrasen['profil/home']='HOME'; +$this->phrasen['profil/profil']='Profile'; +$this->phrasen['profil/mitarbeiter']='Employee'; +$this->phrasen['profil/meinCis']='My CIS'; +$this->phrasen['profil/bildHochladen']='Upload picture'; +$this->phrasen['profil/email']='eMail'; +$this->phrasen['profil/kontaktPrivat']='Private Contacts'; +$this->phrasen['profil/intern']='Intern'; +$this->phrasen['profil/alias']='Alias'; +$this->phrasen['profil/homepage']='Homepage'; +$this->phrasen['profil/student']='Student'; +$this->phrasen['profil/martrikelnummer']='matriculation number'; +$this->phrasen['profil/leistungsbeurteilung']='Performance assessment'; +$this->phrasen['profil/kurzzeichen']='Abbreviation'; +$this->phrasen['profil/telefonTw']='Telephone'; +$this->phrasen['profil/faxTw']='Fax'; +$this->phrasen['profil/zeitwuensche']='Preferred teaching times'; +$this->phrasen['profil/funktionen']='Functions'; +$this->phrasen['profil/entlehnteBetriebsmittel']='Borrowed equipment'; +$this->phrasen['profil/betriebsmittel']='Equipment'; +$this->phrasen['profil/nummer']='Number'; +$this->phrasen['profil/ausgegebenAm']='Issued on'; +$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='You are member of the following mailing lists'; +$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'User %s is a member of the following mailing lists'; +$this->phrasen['profil/alleStudentenVon']='All students from'; +$this->phrasen['profil/kurzbeschreibungFuerOeh']='Brief description for the Austian Student Union candidacy'; +$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible assistant'; +$this->phrasen['profil/esWurdenKeineProfileGefunden']='No profile ore multiple profiles were found for your user account'; +$this->phrasen['profil/adminstration']='Administration'; +$this->phrasen['profil/zustaendigeAssistenz']='Administrative Assistant'; +$this->phrasen['profil/wendenSieSichAn']='Please contact the'; +$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible'; +$this->phrasen['profil/buero']='Office'; +$this->phrasen['profil/zeitsperrenVon']='Unavailabilities of'; +$this->phrasen['profil/lvplanVon']='Schedule from'; + +$this->phrasen['profil/AccountInaktiv']='NOTICE: This account is no longer active'; +$this->phrasen['profil/inaktivStudent']='NOTICE!
We would like to remind you that your user record has been deactivated. +You were also removed from all e-mail distribution lists when your account was deactivated.

+If your user account is not reactivated within 6 months (for students) or 3 weeks (for dropouts) of being deactivated, the following data will be automatically deleted:
+- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

+If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; + +$this->phrasen['profil/inaktivMitarbeiter']='NOTICE!
We would like to remind you that your user record has been deactivated. +You were also removed from all e-mail distribution lists when your account was deactivated.

+If your user account is not reactivated within 12 months of being deactivated, the following data will be automatically deleted:
+- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

+If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; + +$this->phrasen['profil/inaktivSonstige']='NOTICE!
We would like to remind you that your user record has been deactivated. +You were also removed from all e-mail distribution lists when your account was deactivated.

+If your user account is not reactivated within the next days of being deactivated, the following data will be automatically deleted:
+- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

+If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; + + + + +$this->phrasen['profil/nurJPGBilder']='Currently it is only possible to upload JPEG images'; +$this->phrasen['profil/BilduploadInfotext']='Currently it is only possible to upload JPG images with a maximum size of 15MB!

Please follow the guidelines for uploading images'; +$this->phrasen['profil/Bild']='Picture'; +$this->phrasen['profil/Bildupload']='Upload Picture'; +$this->phrasen['profil/fotofreigeben']='Unlock your profile photo'; +$this->phrasen['profil/fotosperren']='Lock your profile photo'; +$this->phrasen['profil/infotextSperre']='Locked profile photos are only used for access cards, and do not appear on attendance lists or in the people search'; +$this->phrasen['profil/profilfotoGesperrt']='Profile photo locked'; +$this->phrasen['profil/profilfotoUploadGesperrt']='It is no longer possible to upload a profile photo'; +$this->phrasen['profil/fhausweisStatus']='UAS ID card status'; +$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='UAS ID card has already been issued on %s.'; +$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Please upload a valid photo'; +$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Photo has not yet been accepted'; +$this->phrasen['profil/fhausweisGedrucktAm']='UAS ID card printed on'; +$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='UAS ID card will be ready for pick-up at the information desk on'; +$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='UAS ID card has not yet been printed'; +$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Your photo has not yet been approved'; +$this->phrasen['profil/fotoAuswählen']='Click on the image below to upload a photo'; +$this->phrasen['profil/bildSpeichern']='Save image'; +$this->phrasen['profil/gueltigvon']='Valid from'; +$this->phrasen['profil/gueltigbis']='Valid to'; +$this->phrasen['profil/wochenstunden']='week hours'; +?> diff --git a/locale/it-IT/profil.php b/locale/it-IT/profil.php index 72bd47e65..14636a082 100644 --- a/locale/it-IT/profil.php +++ b/locale/it-IT/profil.php @@ -1,62 +1,63 @@ -phrasen['profil/AccountInaktiv']='Attenzione: questo account non è più attivo'; -$this->phrasen['profil/adminstration']='Gestione notizie'; -$this->phrasen['profil/alias']='alias'; -$this->phrasen['profil/alleStudentenVon']='Tutti gli studenti di'; -$this->phrasen['profil/ausgegebenAm']=''; -$this->phrasen['profil/betriebsmittel']=''; -$this->phrasen['profil/Bild']=''; -$this->phrasen['profil/bildHochladen']=''; -$this->phrasen['profil/bildSpeichern']=''; -$this->phrasen['profil/Bildupload']=''; -$this->phrasen['profil/BilduploadInfotext']=''; -$this->phrasen['profil/buero']=''; -$this->phrasen['profil/derUserIstInFolgendenVerteilern ']=''; -$this->phrasen['profil/email']='Email'; -$this->phrasen['profil/entlehnteBetriebsmittel']=''; -$this->phrasen['profil/esWurdenKeineProfileGefunden']='Nessun profilo o più profili per l\'utente richiesto'; -$this->phrasen['profil/faxTw']='fax'; -$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']=''; -$this->phrasen['profil/fhausweisGedrucktAm']=''; -$this->phrasen['profil/fhausweisStatus']=''; -$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Tesserino consegnato il %s.'; -$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']=''; -$this->phrasen['profil/fotoAuswählen']=''; -$this->phrasen['profil/fotofreigeben']=''; -$this->phrasen['profil/fotosperren']=''; -$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']=''; -$this->phrasen['profil/funktionen']=''; -$this->phrasen['profil/home']=''; -$this->phrasen['profil/homepage']=''; -$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']=''; -$this->phrasen['profil/inaktivMitarbeiter']=''; -$this->phrasen['profil/inaktivSonstige']=''; -$this->phrasen['profil/inaktivStudent']=''; -$this->phrasen['profil/infotextSperre']=''; -$this->phrasen['profil/intern']='E-mail di Ateneo'; -$this->phrasen['profil/kontaktPrivat']='Contatti Personali'; -$this->phrasen['profil/kurzbeschreibungFuerOeh']=''; -$this->phrasen['profil/kurzzeichen']='ID breve'; -$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']=''; -$this->phrasen['profil/leistungsbeurteilung']=''; -$this->phrasen['profil/lvplanVon']=''; -$this->phrasen['profil/martrikelnummer']='Codice Persona'; -$this->phrasen['profil/meinCis']=''; -$this->phrasen['profil/mitarbeiter']=''; -$this->phrasen['profil/mobil']='Cellulare'; -$this->phrasen['profil/nummer']=''; -$this->phrasen['profil/nurJPGBilder']=''; -$this->phrasen['profil/profil']=''; -$this->phrasen['profil/profilfotoGesperrt']=''; -$this->phrasen['profil/profilfotoUploadGesperrt']=''; -$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']=''; -$this->phrasen['profil/solltenDatenNichtStimmen']='La preghiamo di rivolgersi alla segreteria nel caso i dati non risultino essere corretti.'; -$this->phrasen['profil/student']='Studente'; -$this->phrasen['profil/telefon']=''; -$this->phrasen['profil/telefonTw']=''; -$this->phrasen['profil/wendenSieSichAn']=''; -$this->phrasen['profil/zeitsperrenVon']=''; -$this->phrasen['profil/zeitwuensche']=''; -$this->phrasen['profil/zustaendigeAssistenz']=''; - -?> +phrasen['profil/AccountInaktiv']='Attenzione: questo account non è più attivo'; +$this->phrasen['profil/adminstration']='Gestione notizie'; +$this->phrasen['profil/alias']='alias'; +$this->phrasen['profil/alleStudentenVon']='Tutti gli studenti di'; +$this->phrasen['profil/ausgegebenAm']=''; +$this->phrasen['profil/betriebsmittel']=''; +$this->phrasen['profil/Bild']=''; +$this->phrasen['profil/bildHochladen']=''; +$this->phrasen['profil/bildSpeichern']=''; +$this->phrasen['profil/Bildupload']=''; +$this->phrasen['profil/BilduploadInfotext']=''; +$this->phrasen['profil/buero']=''; +$this->phrasen['profil/derUserIstInFolgendenVerteilern ']=''; +$this->phrasen['profil/email']='Email'; +$this->phrasen['profil/entlehnteBetriebsmittel']=''; +$this->phrasen['profil/esWurdenKeineProfileGefunden']='Nessun profilo o più profili per l\'utente richiesto'; +$this->phrasen['profil/faxTw']='fax'; +$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']=''; +$this->phrasen['profil/fhausweisGedrucktAm']=''; +$this->phrasen['profil/fhausweisStatus']=''; +$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Tesserino consegnato il %s.'; +$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']=''; +$this->phrasen['profil/fotoAuswählen']=''; +$this->phrasen['profil/fotofreigeben']=''; +$this->phrasen['profil/fotosperren']=''; +$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']=''; +$this->phrasen['profil/funktionen']=''; +$this->phrasen['profil/home']=''; +$this->phrasen['profil/homepage']=''; +$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']=''; +$this->phrasen['profil/inaktivMitarbeiter']=''; +$this->phrasen['profil/inaktivSonstige']=''; +$this->phrasen['profil/inaktivStudent']=''; +$this->phrasen['profil/infotextSperre']=''; +$this->phrasen['profil/intern']='E-mail di Ateneo'; +$this->phrasen['profil/kontaktPrivat']='Contatti Personali'; +$this->phrasen['profil/kurzbeschreibungFuerOeh']=''; +$this->phrasen['profil/kurzzeichen']='ID breve'; +$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']=''; +$this->phrasen['profil/leistungsbeurteilung']=''; +$this->phrasen['profil/lvplanVon']=''; +$this->phrasen['profil/martrikelnummer']='Codice Persona'; +$this->phrasen['profil/meinCis']=''; +$this->phrasen['profil/mitarbeiter']=''; +$this->phrasen['profil/mobil']='Cellulare'; +$this->phrasen['profil/nummer']=''; +$this->phrasen['profil/nurJPGBilder']=''; +$this->phrasen['profil/profil']=''; +$this->phrasen['profil/profilfotoGesperrt']=''; +$this->phrasen['profil/profilfotoUploadGesperrt']=''; +$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']=''; +$this->phrasen['profil/solltenDatenNichtStimmen']='La preghiamo di rivolgersi alla segreteria nel caso i dati non risultino essere corretti.'; +$this->phrasen['profil/student']='Studente'; +$this->phrasen['profil/telefon']=''; +$this->phrasen['profil/telefonTw']=''; +$this->phrasen['profil/wendenSieSichAn']=''; +$this->phrasen['profil/zeitsperrenVon']=''; +$this->phrasen['profil/zeitwuensche']=''; +$this->phrasen['profil/zustaendigeAssistenz']=''; +$this->phrasen['profil/wochenstunden']=''; + +?> From fa4667baa7b6212c7c27ac89915de8d589155a20 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 7 Oct 2019 15:21:10 +0200 Subject: [PATCH 11/22] CIS profil (cis/private/profile) Funktionen: separate blocks for current and future funktionen --- cis/private/profile/index.php | 67 +++++++++++++++++++++-------------- locale/de-AT/profil.php | 2 ++ locale/en-US/profil.php | 2 ++ locale/it-IT/profil.php | 3 +- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/cis/private/profile/index.php b/cis/private/profile/index.php index d1d6c96b5..1273c517b 100644 --- a/cis/private/profile/index.php +++ b/cis/private/profile/index.php @@ -156,12 +156,7 @@ echo ' $(document).ready(function() { - $("#t1").tablesorter( - { - sortList: [[0,0]], - widgets: ["zebra"] - }); - $("#t2").tablesorter( + $("#t1, #t2, #tfuture").tablesorter( { sortList: [[0,0]], widgets: ["zebra"] @@ -504,7 +499,7 @@ echo ' if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN) { //Funktionen - $qry = "SELECT + $baseqry = "SELECT *, tbl_benutzerfunktion.oe_kurzbz as oe_kurzbz, tbl_organisationseinheit.bezeichnung as oe_bezeichnung, tbl_benutzerfunktion.semester, tbl_benutzerfunktion.bezeichnung as bf_bezeichnung, tbl_benutzerfunktion.wochenstunden, tbl_benutzerfunktion.datum_von, tbl_benutzerfunktion.datum_bis @@ -513,15 +508,33 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN JOIN public.tbl_funktion USING(funktion_kurzbz) JOIN public.tbl_organisationseinheit USING(oe_kurzbz) WHERE - uid=".$db->db_add_param($uid)." AND - (tbl_benutzerfunktion.datum_bis is null OR tbl_benutzerfunktion.datum_bis>=now())"; + uid=".$db->db_add_param($uid); - if ($result_funktion = $db->db_query($qry)) + $currfunkqry = $baseqry . " AND ((tbl_benutzerfunktion.datum_bis is null OR tbl_benutzerfunktion.datum_bis>=now()) + AND (tbl_benutzerfunktion.datum_von is null OR tbl_benutzerfunktion.datum_von<=now()))"; + $futurefunkqry = $baseqry . " AND (tbl_benutzerfunktion.datum_von>now())"; + + printFunctionsTable($currfunkqry, 'profil/funktionen', 't1', true); + printFunctionsTable($futurefunkqry, 'profil/zukuenftigeFunktionen', 'tfuture'); +} + +/** + * Print html table containing user functions. + * @param $query string execute for getting data + * @param $tableid string html table id + * @param $showVertragsstunden bool show Vertragsstunden sum near Wochenstunden sum + */ +function printFunctionsTable($query, $headingphrase, $tableid, $showVertragsstunden = false) +{ + global $db, $p, $datum_obj, $uid; + + if ($result_funktion = $db->db_query($query)) { if ($db->db_num_rows($result_funktion) > 0) { - echo ''.$p->t('profil/funktionen').' - + echo ''.$p->t($headingphrase).''; + echo ' +
@@ -547,7 +560,7 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN - + "; if(isset($row_funktion->wochenstunden)) @@ -556,18 +569,21 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN echo '
'; //vertragsstunden - $vertragsstunden = 0.00; - $qry = "SELECT sum(vertragsstunden) AS vertragsstdsumme from bis.tbl_bisverwendung - WHERE mitarbeiter_uid = ".$db->db_add_param($uid)." - AND (ende > now() OR ende IS NULL)"; - - if ($result_vertragsstd = $db->db_query($qry)) + if ($showVertragsstunden === true) { - if ($db->db_num_rows($result_vertragsstd) > 0) + $vertragsstunden = 0.00; + $qry = "SELECT sum(vertragsstunden) AS vertragsstdsumme from bis.tbl_bisverwendung + WHERE mitarbeiter_uid = ".$db->db_add_param($uid)." + AND (ende > now() OR ende IS NULL)"; + + if ($result_vertragsstd = $db->db_query($qry)) { - while($row_vertragsstd = $db->db_fetch_object($result_vertragsstd)) + if ($db->db_num_rows($result_vertragsstd) > 0) { - $vertragsstunden = $row_vertragsstd->vertragsstdsumme; + while($row_vertragsstd = $db->db_fetch_object($result_vertragsstd)) + { + $vertragsstunden = $row_vertragsstd->vertragsstdsumme; + } } } } @@ -577,13 +593,12 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN - - + + "; echo "
'.$p->t('global/bezeichnung').'".$row_funktion->organisationseinheittyp_kurzbz.' '.$row_funktion->oe_bezeichnung." ".$datum_obj->formatDatum($row_funktion->datum_von,'d.m.Y')." ".$datum_obj->formatDatum($row_funktion->datum_bis,'d.m.Y')."".$row_funktion->wochenstunden."".number_format($row_funktion->wochenstunden, 2)."
Summe Wochenstunden (Vertragsstunden) ".number_format($wochenstunden_sum,2). - " (".number_format($vertragsstunden,2).")Summe Wochenstunden".($showVertragsstunden === true ? " (".$p->t('profil/vertragsstunden').")" : "")." ".number_format($wochenstunden_sum,2).($showVertragsstunden === true ? + " (".number_format($vertragsstunden,2).")" : "")."
"; - } } } diff --git a/locale/de-AT/profil.php b/locale/de-AT/profil.php index 61c89784e..bf999ce96 100644 --- a/locale/de-AT/profil.php +++ b/locale/de-AT/profil.php @@ -81,4 +81,6 @@ $this->phrasen['profil/bildSpeichern']='Bild speichern'; $this->phrasen['profil/gueltigvon']='Gültig von'; $this->phrasen['profil/gueltigbis']='Gültig bis'; $this->phrasen['profil/wochenstunden']='Wochenstunden'; +$this->phrasen['profil/vertragsstunden']='Vertragsstunden'; +$this->phrasen['profil/zukuenftigeFunktionen']='Zukünftige Funktionen'; ?> diff --git a/locale/en-US/profil.php b/locale/en-US/profil.php index 538c1d1e4..ef8380d8a 100644 --- a/locale/en-US/profil.php +++ b/locale/en-US/profil.php @@ -79,4 +79,6 @@ $this->phrasen['profil/bildSpeichern']='Save image'; $this->phrasen['profil/gueltigvon']='Valid from'; $this->phrasen['profil/gueltigbis']='Valid to'; $this->phrasen['profil/wochenstunden']='week hours'; +$this->phrasen['profil/vertragsstunden']='contract hours'; +$this->phrasen['profil/zukuenftigeFunktionen']='Future functions'; ?> diff --git a/locale/it-IT/profil.php b/locale/it-IT/profil.php index 14636a082..27f52566f 100644 --- a/locale/it-IT/profil.php +++ b/locale/it-IT/profil.php @@ -59,5 +59,6 @@ $this->phrasen['profil/zeitsperrenVon']=''; $this->phrasen['profil/zeitwuensche']=''; $this->phrasen['profil/zustaendigeAssistenz']=''; $this->phrasen['profil/wochenstunden']=''; - +$this->phrasen['profil/vertragsstunden']=''; +$this->phrasen['profil/zukuenftigeFunktionen']=''; ?> From 72a3c2845f8244e955592f7f0f01d17563860339 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 7 Oct 2019 18:30:06 +0200 Subject: [PATCH 12/22] =?UTF-8?q?tablesorter=20filters=20saved=20in=20loca?= =?UTF-8?q?l=20storage=20in=20infocenter=20=C3=9Cbersicht=20are=20not=20de?= =?UTF-8?q?leted=20when=20using=20zur=C3=BCck=20button=20or=20freigegeben?= =?UTF-8?q?=20on=20infocenter=20details=20page.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/system/infocenter/InfoCenter.php | 7 ++++--- public/js/FilterWidget.js | 13 ++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index 7d005489d..3a8d51aee 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -25,6 +25,7 @@ class InfoCenter extends Auth_Controller const FILTER_ID = 'filter_id'; const PREV_FILTER_ID = 'prev_filter_id'; const RELOAD_DATASET = 'reloadDataset'; + const KEEP_TABLESORTER_FILTER = 'keepTsFilter'; private $_uid; // contains the UID of the logged user @@ -235,7 +236,7 @@ class InfoCenter extends Auth_Controller $redirectLink = '/'.self::INFOCENTER_URI.'?'.self::FHC_CONTROLLER_ID.'='.$this->getControllerId(); // Force reload of Dataset after Unlock - $redirectLink .= '&'.self::RELOAD_DATASET.'=true'; + $redirectLink .= '&'.self::RELOAD_DATASET.'=true&'.self::KEEP_TABLESORTER_FILTER.'=true'; $currentFilterId = $this->input->get(self::FILTER_ID); if (isset($currentFilterId)) @@ -957,7 +958,7 @@ class InfoCenter extends Auth_Controller $origin_page = $this->input->get(self::ORIGIN_PAGE); - $link = site_url(self::INFOCENTER_URI.'/'.self::INDEX_PAGE); + $link = site_url(self::INFOCENTER_URI); if ($origin_page == self::FREIGEGEBEN_PAGE) { $link = site_url(self::INFOCENTER_URI.'/'.self::FREIGEGEBEN_PAGE); @@ -970,7 +971,7 @@ class InfoCenter extends Auth_Controller $prevFilterId = $this->input->get(self::PREV_FILTER_ID); if (isset($prevFilterId)) { - $link .= '?'.self::FILTER_ID.'='.$prevFilterId.'&'.self::RELOAD_DATASET.'=true'; + $link .= '?'.self::FILTER_ID.'='.$prevFilterId.'&'.self::RELOAD_DATASET.'=true&'.self::KEEP_TABLESORTER_FILTER.'=true'; } $this->navigationlib->setSessionMenu( diff --git a/public/js/FilterWidget.js b/public/js/FilterWidget.js index 6aad74562..dccc8893c 100644 --- a/public/js/FilterWidget.js +++ b/public/js/FilterWidget.js @@ -413,6 +413,7 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { + FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrRefresh(data, textStatus, jqXHR); } } @@ -488,6 +489,7 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { + FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrReload(data, textStatus, jqXHR); } } @@ -507,6 +509,7 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { + FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrReload(data, textStatus, jqXHR); } } @@ -935,9 +938,13 @@ var FHC_FilterWidget = { } }); - // Reset filter storage if there is a filter id in url TODO: find better solution - var filter_id = FHC_AjaxClient.getUrlParameter("filter_id"); - if (typeof filter_id !== "undefined") FHC_FilterWidget._cleanTablesorterLocalStorage(); + // Reset filter storage if not specified by get parameter + var keepTsFilter = FHC_AjaxClient.getUrlParameter("keepTsFilter"); + + if (typeof keepTsFilter === "undefined" || keepTsFilter !== "true") + { + FHC_FilterWidget._cleanTablesorterLocalStorage(); + } $.tablesorter.updateAll($("#filterTableDataset")[0].config, true, null); } From 39dec7bb971e36e0873b5f1f284dc21e586e64de Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 8 Oct 2019 18:07:09 +0200 Subject: [PATCH 13/22] Make Dieter Dummy lecturer seemingly disappear - deactivate profile page (error message is shown) - removed from CIS search results - no profile link in lvplan --- cis/private/lvplan/stpl_detail.php | 15 +- cis/private/profile/index.php | 3 + cis/private/tools/suche.php | 3 +- include/benutzer.class.php | 1044 ++++++++++++++-------------- include/mitarbeiter.class.php | 3 +- locale/de-AT/profil.php | 167 ++--- locale/en-US/profil.php | 163 ++--- locale/it-IT/profil.php | 125 ++-- 8 files changed, 772 insertions(+), 751 deletions(-) diff --git a/cis/private/lvplan/stpl_detail.php b/cis/private/lvplan/stpl_detail.php index 3aecd1fa6..3612a15db 100644 --- a/cis/private/lvplan/stpl_detail.php +++ b/cis/private/lvplan/stpl_detail.php @@ -35,6 +35,7 @@ require_once('../../../include/ort.class.php'); require_once('../../../include/functions.inc.php'); require_once('../../../include/datum.class.php'); require_once('../../../include/phrasen.class.php'); +require_once('../../../include/mitarbeiter.class.php'); $sprache = getSprache(); $p = new phrasen($sprache); @@ -231,11 +232,21 @@ if ($num_rows_stpl>0) $titel = trim($row->titel); $gesamtanzahl = ($anzahl_grp!=0?$anzahl_grp:$anzahl_lvb); $ort->load($ortkurzbz); - + + // no profile link for fake Mitarbeiter like Dummylektor, Personalnr must be > 0 + $profileLink = true; + $mitarbeiter = new mitarbeiter(); + + if ($mitarbeiter->load($row->uid)) + { + if (isset($mitarbeiter->personalnummer) && is_numeric($mitarbeiter->personalnummer) && (int)$mitarbeiter->personalnummer < 0) + $profileLink = false; + } + echo ' '.$db->convert_html_chars($unr).' - '.$db->convert_html_chars($titelpre.' '.$pers_vorname.' '.$pers_nachname.' '.$titelpost).' + '.($profileLink ? '' : '').$db->convert_html_chars($titelpre.' '.$pers_vorname.' '.$pers_nachname.' '.$titelpost).($profileLink ? '' : '').' '.(!empty($ortkurzbz)?($ort->content_id!=''?''.$db->convert_html_chars($ortkurzbz).'':$db->convert_html_chars($ortkurzbz)):$db->convert_html_chars($ortkurzbz)).' '.$db->convert_html_chars($lehrfachkurzbz).' '.$db->convert_html_chars($bezeichnung).' diff --git a/cis/private/profile/index.php b/cis/private/profile/index.php index 5f93930cc..92bb787bb 100644 --- a/cis/private/profile/index.php +++ b/cis/private/profile/index.php @@ -127,6 +127,9 @@ if (!$user->load($uid)) if ($type == 'mitarbeiter') { + if (isset($user->personalnummer) && is_numeric($user->personalnummer) && (int)$user->personalnummer < 0) + die($p->t('profil/keinGueltigesProfil')); + $vorwahl = ''; $kontakt = new kontakt(); $kontakt->loadFirmaKontakttyp($user->standort_id,'telefon'); diff --git a/cis/private/tools/suche.php b/cis/private/tools/suche.php index f5a1ae591..ecc072d81 100644 --- a/cis/private/tools/suche.php +++ b/cis/private/tools/suche.php @@ -113,7 +113,8 @@ function searchPerson($searchItems) { global $db, $p, $noalias, $uid; $bn = new benutzer(); - $bn->search($searchItems, 21); + //search only active and Mitarbeiter with positive Personalnr + $bn->search($searchItems, 21, true, true); if(count($bn->result)>0) { diff --git a/include/benutzer.class.php b/include/benutzer.class.php index 102c28a4b..ff0ee3c6b 100644 --- a/include/benutzer.class.php +++ b/include/benutzer.class.php @@ -1,520 +1,524 @@ -, - * Andreas Oesterreicher and - * Rudolf Hangl . - */ -require_once(dirname(__FILE__).'/person.class.php'); - -class benutzer extends person -{ - //Tabellenspalten - public $uid; // varchar(32) - public $bnaktiv=true; // boolean - public $alias; // varchar(256) - public $bn_ext_id; - public $aktivierungscode; - public $result = array(); - public $updateaktivam; - public $updateaktivvon; - - /** - * Konstruktor - Uebergibt die Connection und laedt optional einen Benutzer - * @param $uid Benutzer der geladen werden soll (default=null) - */ - public function __construct($uid=null) - { - parent::__construct(); - - if($uid != null) - $this->load($uid); - } - - /** - * Laedt Benutzer mit der uebergebenen ID - * @param $uid ID der Person die geladen werden soll - */ - public function load($uid = null) - { - if (empty($uid)) - { - $this->errormsg = "UID not set!"; - return false; - } - - $qry = "SELECT * FROM public.tbl_benutzer WHERE uid=".$this->db_add_param($uid); - - if($this->db_query($qry)) - { - if($row = $this->db_fetch_object()) - { - $this->uid = $row->uid; - $this->bnaktiv = $this->db_parse_bool($row->aktiv); - $this->alias = $row->alias; - $this->aktivierungscode = $row->aktivierungscode; - $this->updateaktivam = $row->updateaktivam; - $this->updateaktivvon = $row->updateaktivvon; - - if(!person::load($row->person_id)) - return false; - else - return true; - } - else - { - $this->errormsg = "Benutzer nicht gefunden"; - return false; - } - } - else - { - $this->errormsg = "Fehler beim Laden der Benutzerdaten"; - return false; - } - } - - /** - * Prueft die Variablen vor dem Speichern - * auf Gueltigkeit. - * @return true wenn ok, false im Fehlerfall - */ - public function validate() - { - if(mb_strlen($this->uid)>32) - { - $this->errormsg = 'UID darf nicht laenger als 32 Zeichen sein'; - return false; - } - if($this->uid == '') - { - $this->errormsg = 'UID muss eingegeben werden'; - return false; - } - if(mb_strlen($this->alias)>256) - { - $this->errormsg = 'Alias darf nicht laenger als 256 Zeichen sein'; - return false; - } - if(!is_numeric($this->person_id)) - { - $this->errormsg = 'person_id muss eine gueltige Zahl sein'; - return false; - } - if(!is_bool($this->bnaktiv)) - { - $this->errormsg = 'aktiv muss ein boolscher wert sein'; - return false; - } - - if($this->alias!='') - { - $qry = "SELECT * FROM public.tbl_benutzer WHERE alias=".$this->db_add_param($this->alias)." AND uid!=".$this->db_add_param($this->uid); - if($this->db_query($qry)) - { - if($this->db_num_rows()>0) - { - $this->errormsg = 'Dieser Alias ist bereits vergeben'; - return false; - } - } - else - { - $this->errormsg = 'Fehler beim Pruefen des Alias'; - return false; - } - } - return true; - } - - /** - * Speichert die Benutzerdaten in die Datenbank - * Wenn $new auf true gesetzt ist wird ein neuer Datensatz angelegt - * ansonsten der Datensatz mit $uid upgedated - * @return true wenn erfolgreich, false im Fehlerfall - */ - public function save($new=null, $saveperson=true) - { - if($saveperson) - { - //Personen Datensatz speichern - if(!person::save()) - return false; - } - - if($new==null) - $new = $this->new; - - //Variablen auf Gueltigkeit pruefen - if(!benutzer::validate()) - return false; - - if($new) //Wenn new true ist dann ein INSERT absetzen ansonsten ein UPDATE - { - $qry = 'INSERT INTO public.tbl_benutzer (uid, aktiv, alias, person_id, insertamum, insertvon, updateamum, updatevon, aktivierungscode) VALUES('. - $this->db_add_param($this->uid).",". - $this->db_add_param($this->bnaktiv,FHC_BOOLEAN).",". - $this->db_add_param($this->alias).",". - $this->db_add_param($this->person_id, FHC_INTEGER).",". - $this->db_add_param($this->insertamum).",". - $this->db_add_param($this->insertvon).",". - $this->db_add_param($this->updateamum).",". - $this->db_add_param($this->updatevon).",". - $this->db_add_param($this->aktivierungscode).");"; - } - else - { - //Wenn der Aktiv Status geaendert wurde, dann auch updateaktivamum und updateaktivvon setzen - $upd=''; - $qry = "SELECT aktiv FROM public.tbl_benutzer WHERE uid=".$this->db_add_param($this->uid); - if($this->db_query($qry)) - { - if($row = $this->db_fetch_object()) - { - $aktiv = $this->db_parse_bool($row->aktiv); - - if($aktiv!=$this->bnaktiv) - $upd =" updateaktivam=".$this->db_add_param($this->updateamum).", updateaktivvon=".$this->db_add_param($this->updatevon).","; - } - } - - $qry = 'UPDATE public.tbl_benutzer SET'. - ' aktiv='.$this->db_add_param($this->bnaktiv, FHC_BOOLEAN).','. - ' alias='.$this->db_add_param($this->alias).','. - ' person_id='.$this->db_add_param($this->person_id).','. - ' updateamum='.$this->db_add_param($this->updateamum).','.$upd. - ' updatevon='.$this->db_add_param($this->updatevon). - ' WHERE uid='.$this->db_add_param($this->uid).';'; - } - - if($this->db_query($qry)) - { - //Log schreiben - return true; - } - else - { - $this->errormsg = 'Fehler beim Speichern des Benutzer-Datensatzes'; - return false; - } - } - - - /** - * Löscht den Benutzer mit der übergebenen uid. Da beim Speichern auch - * eine Person angelegt wird, muss eventuell auch diese gelöscht werden. - * Das kann durch Aufruf der geerbten Methode {@link person::delete()} - * erledigt werden. Damit die Klasse Abwärtskombatibel bleibt, wurde die - * Methode delete() absichtlich nicht überschrieben. - * @param $uid - */ - public function deleteBenutzer($uid) - { - $qry = "DELETE from public.tbl_benutzer where uid = ".$this->db_add_param($uid).";"; - - if($this->db_query($qry)) - { - return true; - } - else - { - $this->errormsg = "Es ist ein Fehler beim Löschen des Benutzers aufgetreten"; - return false; - } - } - - - - /** - * Prueft ob die UID bereits existiert - * @param uid - */ - public function uid_exists($uid) - { - $qry = "SELECT * FROM public.tbl_benutzer WHERE uid=".$this->db_add_param($uid); - - if($this->db_query($qry)) - { - if($this->db_num_rows()>0) - { - $this->errormsg = ''; - return true; - } - else - { - $this->errormsg = ''; - return false; - } - - } - else - { - $this->errormsg = 'Fehler bei DatenbankAbfrage'; - return false; - } - - } - - /** - * Prueft ob der alias bereits existiert - * @param $alias - */ - public function alias_exists($alias) - { - $qry = "SELECT * FROM public.tbl_benutzer WHERE alias=".$this->db_add_param($alias); - - if($this->db_query($qry)) - { - if($this->db_num_rows()>0) - { - $this->errormsg = ''; - return true; - } - else - { - $this->errormsg = ''; - return false; - } - - } - else - { - $this->errormsg = 'Fehler bei DatenbankAbfrage'; - return false; - } - } - - /** - * Sucht nach Benutzern. Limit optional. Aktiv optional. - * - * @param $limit (optional) - * @param $aktiv (optional). Default true. Wenn false werden nur inaktive benutzer geladen, wenn null dann alle - */ - public function search($searchItems, $limit=null, $aktiv=true) - { - $qry = "SELECT * FROM ( - SELECT - distinct on (uid) vorname, nachname, uid, mitarbeiter_uid, titelpre, titelpost, lektor, fixangestellt, alias, tbl_benutzer.aktiv, anrede, - (SELECT UPPER - (tbl_studiengang.typ || tbl_studiengang.kurzbz) - FROM public.tbl_student - JOIN public.tbl_studiengang USING(studiengang_kz) - WHERE student_uid=tbl_benutzer.uid) as studiengang, - - (SELECT studiengang_kz FROM public.tbl_student - WHERE student_uid=tbl_benutzer.uid) as studiengang_kz, - - (SELECT tbl_kontakt.kontakt || ' - ' ||telefonklappe - FROM public.tbl_mitarbeiter - LEFT JOIN public.tbl_kontakt USING(standort_id) - WHERE - mitarbeiter_uid=tbl_benutzer.uid - AND (tbl_kontakt.kontakttyp='telefon' OR tbl_kontakt.kontakttyp is null) - limit 1) as klappe, - - (SELECT planbezeichnung FROM public.tbl_mitarbeiter - LEFT JOIN public.tbl_ort USING (ort_kurzbz) - WHERE mitarbeiter_uid=tbl_benutzer.uid) as raum, - - (SELECT 1 - FROM PUBLIC.tbl_mitarbeiter - WHERE mitarbeiter_uid = tbl_benutzer.uid - ) AS is_mitarbeiter - FROM - public.tbl_person - JOIN public.tbl_benutzer USING(person_id) - LEFT JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) - WHERE"; - if(is_null($aktiv)) - $qry.=" ("; - elseif($aktiv==true) - $qry.=" tbl_benutzer.aktiv=true AND ("; - elseif($aktiv==false) - $qry.=" tbl_benutzer.aktiv=false AND ("; - - $qry.=" lower(vorname || ' ' || nachname) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; - $qry.=" OR lower(nachname || ' ' || vorname) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; - $qry.=" OR lower(uid) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; - $qry.=" OR lower(telefonklappe) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; - - foreach($searchItems as $value) - { - $qry.=" OR lower(uid) = lower(".$this->db_add_param($value).")"; - } - $qry.=")) a ORDER BY is_mitarbeiter, nachname, vorname"; - - if(!is_null($limit) && is_numeric($limit)) - $qry.=" LIMIT ".$limit; - - if($result = $this->db_query($qry)) - { - while($row = $this->db_fetch_object($result)) - { - $obj = new benutzer(); - - $obj->titelpre = $row->titelpre; - $obj->vorname = $row->vorname; - $obj->nachname = $row->nachname; - $obj->titelpost = $row->titelpost; - $obj->uid = $row->uid; - $obj->mitarbeiter_uid = $row->mitarbeiter_uid; - $obj->studiengang = $row->studiengang; - $obj->studiengang_kz = $row->studiengang_kz; - $obj->telefonklappe = $row->klappe; - $obj->raum = $row->raum; - $obj->alias = $row->alias; - $obj->lektor = $row->lektor; - $obj->fixangestellt = $row->fixangestellt; - $obj->aktiv = $this->db_parse_bool($row->aktiv); - $obj->anrede = $row->anrede; - - $this->result[] = $obj; - } - $this->errormsg = $qry; - return true; - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Laedt alle Benutzer einer Person - * @param $person_id - * @param $aktiv optional wenn true werden nur aktive benutzer geladen, sonst alle - */ - function getBenutzerFromPerson($person_id, $aktiv=true) - { - $qry = "SELECT - person_id, titelpre, vorname, nachname, titelpost, uid - FROM - public.tbl_benutzer - JOIN public.tbl_person USING(person_id) - WHERE - person_id=".$this->db_add_param($person_id, FHC_INTEGER); - if($aktiv) - $qry.=" AND tbl_benutzer.aktiv=true "; - - $qry .= " ORDER BY tbl_person.insertamum"; - - if($result = $this->db_query($qry)) - { - while($row = $this->db_fetch_object($result)) - { - $obj = new benutzer(); - - $obj->person_id = $row->person_id; - $obj->titelpre = $row->titelpre; - $obj->vorname = $row->vorname; - $obj->nachname = $row->nachname; - $obj->titelpost = $row->titelpost; - $obj->uid = $row->uid; - - $this->result[] = $obj; - } - return true; - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Entfernt den Aktivierungscode eines Users - * @param $username - */ - public function DeleteAktivierungscode($username) - { - $qry = "UPDATE public.tbl_benutzer SET aktivierungscode=null WHERE uid=".$this->db_add_param($username); - if($this->db_query($qry)) - return true; - else - { - $this->errormsg = 'Fehler beim Loeschen des Aktivierungscodes'; - return false; - } - } - - /** - * Baut die Datenstruktur für senden als JSON Objekt auf - */ - public function cleanResult() - { - $values = array(); - if (count($this->result) > 0) - { - foreach ($this->result as $ben) - { - $obj = new stdClass(); - $obj->uid = $ben->uid; - $obj->vorname = $ben->vorname; - $obj->nachname = $ben->nachname; - $values[] = $obj; - - } - } - else - { - $obj = new stdClass(); - $obj->uid = $this->uid; - $obj->vorname = $this->vorname; - $obj->nachname = $this->nachname; - $values[] = $obj; - } - return $values; - } - - /** - * Laedt Benutzer anhand des Alias - * @param $alias Alias der Person die geladen werden soll - */ - public function loadAlias($alias) - { - $qry = "SELECT * FROM public.tbl_benutzer WHERE alias=".$this->db_add_param($alias); - - if($this->db_query($qry)) - { - if($row = $this->db_fetch_object()) - { - $this->uid = $row->uid; - $this->bnaktiv = $this->db_parse_bool($row->aktiv); - $this->alias = $row->alias; - $this->aktivierungscode = $row->aktivierungscode; - - if(!person::load($row->person_id)) - return false; - else - return true; - } - else - { - $this->errormsg = "Benutzer nicht gefunden"; - return false; - } - } - else - { - $this->errormsg = "Fehler beim Laden der Benutzerdaten"; - return false; - } - } -} -?> +, + * Andreas Oesterreicher and + * Rudolf Hangl . + */ +require_once(dirname(__FILE__).'/person.class.php'); + +class benutzer extends person +{ + //Tabellenspalten + public $uid; // varchar(32) + public $bnaktiv=true; // boolean + public $alias; // varchar(256) + public $bn_ext_id; + public $aktivierungscode; + public $result = array(); + public $updateaktivam; + public $updateaktivvon; + + /** + * Konstruktor - Uebergibt die Connection und laedt optional einen Benutzer + * @param $uid Benutzer der geladen werden soll (default=null) + */ + public function __construct($uid=null) + { + parent::__construct(); + + if($uid != null) + $this->load($uid); + } + + /** + * Laedt Benutzer mit der uebergebenen ID + * @param $uid ID der Person die geladen werden soll + */ + public function load($uid = null) + { + if (empty($uid)) + { + $this->errormsg = "UID not set!"; + return false; + } + + $qry = "SELECT * FROM public.tbl_benutzer WHERE uid=".$this->db_add_param($uid); + + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + $this->uid = $row->uid; + $this->bnaktiv = $this->db_parse_bool($row->aktiv); + $this->alias = $row->alias; + $this->aktivierungscode = $row->aktivierungscode; + $this->updateaktivam = $row->updateaktivam; + $this->updateaktivvon = $row->updateaktivvon; + + if(!person::load($row->person_id)) + return false; + else + return true; + } + else + { + $this->errormsg = "Benutzer nicht gefunden"; + return false; + } + } + else + { + $this->errormsg = "Fehler beim Laden der Benutzerdaten"; + return false; + } + } + + /** + * Prueft die Variablen vor dem Speichern + * auf Gueltigkeit. + * @return true wenn ok, false im Fehlerfall + */ + public function validate() + { + if(mb_strlen($this->uid)>32) + { + $this->errormsg = 'UID darf nicht laenger als 32 Zeichen sein'; + return false; + } + if($this->uid == '') + { + $this->errormsg = 'UID muss eingegeben werden'; + return false; + } + if(mb_strlen($this->alias)>256) + { + $this->errormsg = 'Alias darf nicht laenger als 256 Zeichen sein'; + return false; + } + if(!is_numeric($this->person_id)) + { + $this->errormsg = 'person_id muss eine gueltige Zahl sein'; + return false; + } + if(!is_bool($this->bnaktiv)) + { + $this->errormsg = 'aktiv muss ein boolscher wert sein'; + return false; + } + + if($this->alias!='') + { + $qry = "SELECT * FROM public.tbl_benutzer WHERE alias=".$this->db_add_param($this->alias)." AND uid!=".$this->db_add_param($this->uid); + if($this->db_query($qry)) + { + if($this->db_num_rows()>0) + { + $this->errormsg = 'Dieser Alias ist bereits vergeben'; + return false; + } + } + else + { + $this->errormsg = 'Fehler beim Pruefen des Alias'; + return false; + } + } + return true; + } + + /** + * Speichert die Benutzerdaten in die Datenbank + * Wenn $new auf true gesetzt ist wird ein neuer Datensatz angelegt + * ansonsten der Datensatz mit $uid upgedated + * @return true wenn erfolgreich, false im Fehlerfall + */ + public function save($new=null, $saveperson=true) + { + if($saveperson) + { + //Personen Datensatz speichern + if(!person::save()) + return false; + } + + if($new==null) + $new = $this->new; + + //Variablen auf Gueltigkeit pruefen + if(!benutzer::validate()) + return false; + + if($new) //Wenn new true ist dann ein INSERT absetzen ansonsten ein UPDATE + { + $qry = 'INSERT INTO public.tbl_benutzer (uid, aktiv, alias, person_id, insertamum, insertvon, updateamum, updatevon, aktivierungscode) VALUES('. + $this->db_add_param($this->uid).",". + $this->db_add_param($this->bnaktiv,FHC_BOOLEAN).",". + $this->db_add_param($this->alias).",". + $this->db_add_param($this->person_id, FHC_INTEGER).",". + $this->db_add_param($this->insertamum).",". + $this->db_add_param($this->insertvon).",". + $this->db_add_param($this->updateamum).",". + $this->db_add_param($this->updatevon).",". + $this->db_add_param($this->aktivierungscode).");"; + } + else + { + //Wenn der Aktiv Status geaendert wurde, dann auch updateaktivamum und updateaktivvon setzen + $upd=''; + $qry = "SELECT aktiv FROM public.tbl_benutzer WHERE uid=".$this->db_add_param($this->uid); + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + $aktiv = $this->db_parse_bool($row->aktiv); + + if($aktiv!=$this->bnaktiv) + $upd =" updateaktivam=".$this->db_add_param($this->updateamum).", updateaktivvon=".$this->db_add_param($this->updatevon).","; + } + } + + $qry = 'UPDATE public.tbl_benutzer SET'. + ' aktiv='.$this->db_add_param($this->bnaktiv, FHC_BOOLEAN).','. + ' alias='.$this->db_add_param($this->alias).','. + ' person_id='.$this->db_add_param($this->person_id).','. + ' updateamum='.$this->db_add_param($this->updateamum).','.$upd. + ' updatevon='.$this->db_add_param($this->updatevon). + ' WHERE uid='.$this->db_add_param($this->uid).';'; + } + + if($this->db_query($qry)) + { + //Log schreiben + return true; + } + else + { + $this->errormsg = 'Fehler beim Speichern des Benutzer-Datensatzes'; + return false; + } + } + + + /** + * Löscht den Benutzer mit der übergebenen uid. Da beim Speichern auch + * eine Person angelegt wird, muss eventuell auch diese gelöscht werden. + * Das kann durch Aufruf der geerbten Methode {@link person::delete()} + * erledigt werden. Damit die Klasse Abwärtskombatibel bleibt, wurde die + * Methode delete() absichtlich nicht überschrieben. + * @param $uid + */ + public function deleteBenutzer($uid) + { + $qry = "DELETE from public.tbl_benutzer where uid = ".$this->db_add_param($uid).";"; + + if($this->db_query($qry)) + { + return true; + } + else + { + $this->errormsg = "Es ist ein Fehler beim Löschen des Benutzers aufgetreten"; + return false; + } + } + + + + /** + * Prueft ob die UID bereits existiert + * @param uid + */ + public function uid_exists($uid) + { + $qry = "SELECT * FROM public.tbl_benutzer WHERE uid=".$this->db_add_param($uid); + + if($this->db_query($qry)) + { + if($this->db_num_rows()>0) + { + $this->errormsg = ''; + return true; + } + else + { + $this->errormsg = ''; + return false; + } + + } + else + { + $this->errormsg = 'Fehler bei DatenbankAbfrage'; + return false; + } + + } + + /** + * Prueft ob der alias bereits existiert + * @param $alias + */ + public function alias_exists($alias) + { + $qry = "SELECT * FROM public.tbl_benutzer WHERE alias=".$this->db_add_param($alias); + + if($this->db_query($qry)) + { + if($this->db_num_rows()>0) + { + $this->errormsg = ''; + return true; + } + else + { + $this->errormsg = ''; + return false; + } + + } + else + { + $this->errormsg = 'Fehler bei DatenbankAbfrage'; + return false; + } + } + + /** + * Sucht nach Benutzern. Limit optional. Aktiv optional. + * + * @param $searchItems + * @param $limit (optional) + * @param bool $aktiv (optional). Default true. Wenn false werden nur inaktive benutzer geladen, wenn null dann alle + * @param bool $positivePersonalnr (optional). Default false. Wenn true, nur Mitarbeiter mit positiver Personalnr laden. + * @return bool + */ + public function search($searchItems, $limit=null, $aktiv=true, $positivePersonalnr=false) + { + $qry = "SELECT * FROM ( + SELECT + distinct on (uid) vorname, nachname, uid, mitarbeiter_uid, personalnummer, titelpre, titelpost, lektor, fixangestellt, alias, tbl_benutzer.aktiv, anrede, + (SELECT UPPER + (tbl_studiengang.typ || tbl_studiengang.kurzbz) + FROM public.tbl_student + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE student_uid=tbl_benutzer.uid) as studiengang, + + (SELECT studiengang_kz FROM public.tbl_student + WHERE student_uid=tbl_benutzer.uid) as studiengang_kz, + + (SELECT tbl_kontakt.kontakt || ' - ' ||telefonklappe + FROM public.tbl_mitarbeiter + LEFT JOIN public.tbl_kontakt USING(standort_id) + WHERE + mitarbeiter_uid=tbl_benutzer.uid + AND (tbl_kontakt.kontakttyp='telefon' OR tbl_kontakt.kontakttyp is null) + limit 1) as klappe, + + (SELECT planbezeichnung FROM public.tbl_mitarbeiter + LEFT JOIN public.tbl_ort USING (ort_kurzbz) + WHERE mitarbeiter_uid=tbl_benutzer.uid) as raum, + + (SELECT 1 + FROM PUBLIC.tbl_mitarbeiter + WHERE mitarbeiter_uid = tbl_benutzer.uid + ) AS is_mitarbeiter + FROM + public.tbl_person + JOIN public.tbl_benutzer USING(person_id) + LEFT JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) + WHERE"; + if($aktiv===true) + $qry.=" tbl_benutzer.aktiv=true AND"; + elseif($aktiv===false) + $qry.=" tbl_benutzer.aktiv=false AND"; + + if($positivePersonalnr === true) + $qry.=" (personalnummer >= 0 OR personalnummer IS NULL) AND"; + + $qry.=" (lower(vorname || ' ' || nachname) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; + $qry.=" OR lower(nachname || ' ' || vorname) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; + $qry.=" OR lower(uid) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; + $qry.=" OR lower(telefonklappe) like lower('%".$this->db_escape(implode(' ',$searchItems))."%')"; + + foreach($searchItems as $value) + { + $qry.=" OR lower(uid) = lower(".$this->db_add_param($value).")"; + } + $qry.=")) a ORDER BY is_mitarbeiter, nachname, vorname"; + + if(!is_null($limit) && is_numeric($limit)) + $qry.=" LIMIT ".$limit; + + if($result = $this->db_query($qry)) + { + while($row = $this->db_fetch_object($result)) + { + $obj = new benutzer(); + + $obj->titelpre = $row->titelpre; + $obj->vorname = $row->vorname; + $obj->nachname = $row->nachname; + $obj->titelpost = $row->titelpost; + $obj->uid = $row->uid; + $obj->mitarbeiter_uid = $row->mitarbeiter_uid; + $obj->studiengang = $row->studiengang; + $obj->studiengang_kz = $row->studiengang_kz; + $obj->telefonklappe = $row->klappe; + $obj->raum = $row->raum; + $obj->alias = $row->alias; + $obj->lektor = $row->lektor; + $obj->fixangestellt = $row->fixangestellt; + $obj->aktiv = $this->db_parse_bool($row->aktiv); + $obj->anrede = $row->anrede; + + $this->result[] = $obj; + } + $this->errormsg = $qry; + return true; + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Laedt alle Benutzer einer Person + * @param $person_id + * @param $aktiv optional wenn true werden nur aktive benutzer geladen, sonst alle + */ + function getBenutzerFromPerson($person_id, $aktiv=true) + { + $qry = "SELECT + person_id, titelpre, vorname, nachname, titelpost, uid + FROM + public.tbl_benutzer + JOIN public.tbl_person USING(person_id) + WHERE + person_id=".$this->db_add_param($person_id, FHC_INTEGER); + if($aktiv) + $qry.=" AND tbl_benutzer.aktiv=true "; + + $qry .= " ORDER BY tbl_person.insertamum"; + + if($result = $this->db_query($qry)) + { + while($row = $this->db_fetch_object($result)) + { + $obj = new benutzer(); + + $obj->person_id = $row->person_id; + $obj->titelpre = $row->titelpre; + $obj->vorname = $row->vorname; + $obj->nachname = $row->nachname; + $obj->titelpost = $row->titelpost; + $obj->uid = $row->uid; + + $this->result[] = $obj; + } + return true; + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Entfernt den Aktivierungscode eines Users + * @param $username + */ + public function DeleteAktivierungscode($username) + { + $qry = "UPDATE public.tbl_benutzer SET aktivierungscode=null WHERE uid=".$this->db_add_param($username); + if($this->db_query($qry)) + return true; + else + { + $this->errormsg = 'Fehler beim Loeschen des Aktivierungscodes'; + return false; + } + } + + /** + * Baut die Datenstruktur für senden als JSON Objekt auf + */ + public function cleanResult() + { + $values = array(); + if (count($this->result) > 0) + { + foreach ($this->result as $ben) + { + $obj = new stdClass(); + $obj->uid = $ben->uid; + $obj->vorname = $ben->vorname; + $obj->nachname = $ben->nachname; + $values[] = $obj; + + } + } + else + { + $obj = new stdClass(); + $obj->uid = $this->uid; + $obj->vorname = $this->vorname; + $obj->nachname = $this->nachname; + $values[] = $obj; + } + return $values; + } + + /** + * Laedt Benutzer anhand des Alias + * @param $alias Alias der Person die geladen werden soll + */ + public function loadAlias($alias) + { + $qry = "SELECT * FROM public.tbl_benutzer WHERE alias=".$this->db_add_param($alias); + + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + $this->uid = $row->uid; + $this->bnaktiv = $this->db_parse_bool($row->aktiv); + $this->alias = $row->alias; + $this->aktivierungscode = $row->aktivierungscode; + + if(!person::load($row->person_id)) + return false; + else + return true; + } + else + { + $this->errormsg = "Benutzer nicht gefunden"; + return false; + } + } + else + { + $this->errormsg = "Fehler beim Laden der Benutzerdaten"; + return false; + } + } +} +?> diff --git a/include/mitarbeiter.class.php b/include/mitarbeiter.class.php index 70dff1aac..b58c84415 100644 --- a/include/mitarbeiter.class.php +++ b/include/mitarbeiter.class.php @@ -865,7 +865,7 @@ class mitarbeiter extends benutzer * Nachname, Vorname, UID $filter enthaelt * @param $filter */ - public function search($filter, $limit=null, $aktiv=true) + public function search($filter, $limit=null, $aktiv=true, $positivePersonalnr=false) { $qry = "SELECT vorname, nachname, titelpre, titelpost, kurzbz, vornamen, uid FROM campus.vw_mitarbeiter @@ -880,7 +880,6 @@ class mitarbeiter extends benutzer if(!is_null($limit) && is_numeric($limit)) $qry.=" LIMIT ".$limit; - //echo $qry; if($this->db_query($qry)) { while($row = $this->db_fetch_object()) diff --git a/locale/de-AT/profil.php b/locale/de-AT/profil.php index 52f1c439d..8ad0bb749 100644 --- a/locale/de-AT/profil.php +++ b/locale/de-AT/profil.php @@ -1,83 +1,84 @@ -phrasen['profil/profil']='Profil'; -$this->phrasen['profil/mitarbeiter']='MitarbeiterIn'; -$this->phrasen['profil/home']='HOME'; -$this->phrasen['profil/meinCis']='Mein CIS'; -$this->phrasen['profil/bildHochladen']='Profilfoto hochladen'; -$this->phrasen['profil/email']='eMail'; -$this->phrasen['profil/kontaktPrivat']='Private Kontakte'; -$this->phrasen['profil/mobil']='Mobil'; -$this->phrasen['profil/telefon']='Telefon'; -$this->phrasen['profil/intern']='Intern'; -$this->phrasen['profil/alias']='Alias'; -$this->phrasen['profil/homepage']='Homepage'; -$this->phrasen['profil/student']='StudentIn'; -$this->phrasen['profil/martrikelnummer']='Personenkennzeichen'; -$this->phrasen['profil/leistungsbeurteilung']='Leistungsbeurteilung'; -$this->phrasen['profil/kurzzeichen']='Kurzzeichen'; -$this->phrasen['profil/telefonTw']='Telefon'; -$this->phrasen['profil/faxTw']='Fax'; -$this->phrasen['profil/zeitwuensche']='Zeitwünsche'; -$this->phrasen['profil/funktionen']='Funktionen'; -$this->phrasen['profil/entlehnteBetriebsmittel']='Entlehnte Betriebsmittel'; -$this->phrasen['profil/betriebsmittel']='Betriebsmittel'; -$this->phrasen['profil/nummer']='Nummer'; -$this->phrasen['profil/ausgegebenAm']='Ausgegeben am'; -$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='Sie sind Mitglied in folgenden Verteilern'; -$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'Der User %s ist Mitglied in folgenden Verteilern'; -$this->phrasen['profil/alleStudentenVon']='Alle StudentInnen von'; -$this->phrasen['profil/kurzbeschreibungFuerOeh']='Kurzbeschreibung für die ÖH-Kandidatur'; -$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die zuständige Assistenz'; -$this->phrasen['profil/esWurdenKeineProfileGefunden']='Es wurden keine oder mehrere Profile für Ihren Useraccount gefunden'; -$this->phrasen['profil/adminstration']='Administration'; -$this->phrasen['profil/zustaendigeAssistenz']='zuständige Assistenz'; -$this->phrasen['profil/wendenSieSichAn']='Bitte wenden Sie sich an die'; -$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die'; -$this->phrasen['profil/buero']='Büro'; -$this->phrasen['profil/zeitsperrenVon']='Zeitsperren von'; -$this->phrasen['profil/lvplanVon']='LV-Plan von'; - -$this->phrasen['profil/AccountInaktiv']='Achtung: Dieser Account ist nicht mehr aktiv'; -$this->phrasen['profil/inaktivStudent']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz -deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

-Sollte innerhalb von 6 Monaten (für Studierende) bzw. 3 Wochen (für AbbrecherInnen) nach der Deaktivierung keine -neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
-- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, -sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; - -$this->phrasen['profil/inaktivMitarbeiter']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz -deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

-Sollte innerhalb von 12 Monaten nach der Deaktivierung keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
-- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
-- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, -sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; - -$this->phrasen['profil/inaktivSonstige']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz -deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

-Sollte innerhalb der nächsten Tagen keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
-- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
-- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, -sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; - -$this->phrasen['profil/nurJPGBilder']='Derzeit können nur Bilder im JPG Format hochgeladen werden'; -$this->phrasen['profil/BilduploadInfotext']='Derzeit können nur Bilder im JPG Format mit einer Maximalgröße von 15MB hochgeladen werden!

Bitte beachten Sie die Richtlinien für den Bildupload'; -$this->phrasen['profil/Bild']='Profilfoto'; -$this->phrasen['profil/Bildupload']='Bildupload'; -$this->phrasen['profil/fotofreigeben']='Sperre des Profilfotos aufheben'; -$this->phrasen['profil/fotosperren']='Profilfoto sperren'; -$this->phrasen['profil/infotextSperre']='Gesperrte Profilbilder werden nur für Zutrittskarten verwendet und scheinen nicht auf Anwesenheitslisten oder in der Personensuche auf'; -$this->phrasen['profil/profilfotoGesperrt']='Profilfoto gesperrt'; -$this->phrasen['profil/profilfotoUploadGesperrt']='Der Upload des Profilfotos ist nicht mehr möglich'; -$this->phrasen['profil/fhausweisStatus']='FH-Ausweis Status'; -$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Der FH Ausweis ist am %s ausgegeben worden.'; -$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Laden Sie bitte ein gültiges Foto hoch'; -$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Foto wurde noch nicht akzeptiert'; -$this->phrasen['profil/fhausweisGedrucktAm']='FH-Ausweis gedruckt am'; -$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='FH-Ausweis abholbereit am Empfang ab'; -$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='FH-Ausweis wurde noch nicht gedruckt'; -$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Ihr Foto wurde noch nicht geprüft'; -$this->phrasen['profil/fotoAuswählen']='Klicken Sie auf das Bild um ein Foto hochzuladen'; -$this->phrasen['profil/bildSpeichern']='Bild speichern'; -$this->phrasen['profil/gueltigvon']='Gültig von'; -$this->phrasen['profil/gueltigbis']='Gültig bis'; -?> +phrasen['profil/profil']='Profil'; +$this->phrasen['profil/mitarbeiter']='MitarbeiterIn'; +$this->phrasen['profil/home']='HOME'; +$this->phrasen['profil/meinCis']='Mein CIS'; +$this->phrasen['profil/bildHochladen']='Profilfoto hochladen'; +$this->phrasen['profil/email']='eMail'; +$this->phrasen['profil/kontaktPrivat']='Private Kontakte'; +$this->phrasen['profil/mobil']='Mobil'; +$this->phrasen['profil/telefon']='Telefon'; +$this->phrasen['profil/intern']='Intern'; +$this->phrasen['profil/alias']='Alias'; +$this->phrasen['profil/homepage']='Homepage'; +$this->phrasen['profil/student']='StudentIn'; +$this->phrasen['profil/martrikelnummer']='Personenkennzeichen'; +$this->phrasen['profil/leistungsbeurteilung']='Leistungsbeurteilung'; +$this->phrasen['profil/kurzzeichen']='Kurzzeichen'; +$this->phrasen['profil/telefonTw']='Telefon'; +$this->phrasen['profil/faxTw']='Fax'; +$this->phrasen['profil/zeitwuensche']='Zeitwünsche'; +$this->phrasen['profil/funktionen']='Funktionen'; +$this->phrasen['profil/entlehnteBetriebsmittel']='Entlehnte Betriebsmittel'; +$this->phrasen['profil/betriebsmittel']='Betriebsmittel'; +$this->phrasen['profil/nummer']='Nummer'; +$this->phrasen['profil/ausgegebenAm']='Ausgegeben am'; +$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='Sie sind Mitglied in folgenden Verteilern'; +$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'Der User %s ist Mitglied in folgenden Verteilern'; +$this->phrasen['profil/alleStudentenVon']='Alle StudentInnen von'; +$this->phrasen['profil/kurzbeschreibungFuerOeh']='Kurzbeschreibung für die ÖH-Kandidatur'; +$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die zuständige Assistenz'; +$this->phrasen['profil/esWurdenKeineProfileGefunden']='Es wurden keine oder mehrere Profile für Ihren Useraccount gefunden'; +$this->phrasen['profil/keinGueltigesProfil']='Kein gültiges Profil'; +$this->phrasen['profil/adminstration']='Administration'; +$this->phrasen['profil/zustaendigeAssistenz']='zuständige Assistenz'; +$this->phrasen['profil/wendenSieSichAn']='Bitte wenden Sie sich an die'; +$this->phrasen['profil/solltenDatenNichtStimmen']='Sollten Ihre Daten nicht stimmen, wenden Sie sich bitte an die'; +$this->phrasen['profil/buero']='Büro'; +$this->phrasen['profil/zeitsperrenVon']='Zeitsperren von'; +$this->phrasen['profil/lvplanVon']='LV-Plan von'; + +$this->phrasen['profil/AccountInaktiv']='Achtung: Dieser Account ist nicht mehr aktiv'; +$this->phrasen['profil/inaktivStudent']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz +deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

+Sollte innerhalb von 6 Monaten (für Studierende) bzw. 3 Wochen (für AbbrecherInnen) nach der Deaktivierung keine +neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
+- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, +sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; + +$this->phrasen['profil/inaktivMitarbeiter']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz +deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

+Sollte innerhalb von 12 Monaten nach der Deaktivierung keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
+- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
+- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, +sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; + +$this->phrasen['profil/inaktivSonstige']='Achtung!
Wir möchten Sie darauf aufmerksam machen, dass Ihr Benutzerdatensatz +deaktiviert wurde.Durch diese Deaktivierung wurden Sie auch aus allen Email-Verteilern gelöscht.

+Sollte innerhalb der nächsten Tagen keine neuerliche Aktivierung Ihres Benutzerdatensatzes erfolgen, dann werden automatisch auch
+- Ihr Account,
- Ihre Mailbox (inkl. aller E-Mails) und
+- Ihr Home-Verzeichnis (inkl. aller Dateien) gelöscht.

Falls es sich bei der Deaktivierung um einen Irrtum handelt, würden wir Sie bitten, +sich umgehend mit Ihrer Studiengangsassistenz in Verbindung zu setzen.
'; + +$this->phrasen['profil/nurJPGBilder']='Derzeit können nur Bilder im JPG Format hochgeladen werden'; +$this->phrasen['profil/BilduploadInfotext']='Derzeit können nur Bilder im JPG Format mit einer Maximalgröße von 15MB hochgeladen werden!

Bitte beachten Sie die Richtlinien für den Bildupload'; +$this->phrasen['profil/Bild']='Profilfoto'; +$this->phrasen['profil/Bildupload']='Bildupload'; +$this->phrasen['profil/fotofreigeben']='Sperre des Profilfotos aufheben'; +$this->phrasen['profil/fotosperren']='Profilfoto sperren'; +$this->phrasen['profil/infotextSperre']='Gesperrte Profilbilder werden nur für Zutrittskarten verwendet und scheinen nicht auf Anwesenheitslisten oder in der Personensuche auf'; +$this->phrasen['profil/profilfotoGesperrt']='Profilfoto gesperrt'; +$this->phrasen['profil/profilfotoUploadGesperrt']='Der Upload des Profilfotos ist nicht mehr möglich'; +$this->phrasen['profil/fhausweisStatus']='FH-Ausweis Status'; +$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Der FH Ausweis ist am %s ausgegeben worden.'; +$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Laden Sie bitte ein gültiges Foto hoch'; +$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Foto wurde noch nicht akzeptiert'; +$this->phrasen['profil/fhausweisGedrucktAm']='FH-Ausweis gedruckt am'; +$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='FH-Ausweis abholbereit am Empfang ab'; +$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='FH-Ausweis wurde noch nicht gedruckt'; +$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Ihr Foto wurde noch nicht geprüft'; +$this->phrasen['profil/fotoAuswählen']='Klicken Sie auf das Bild um ein Foto hochzuladen'; +$this->phrasen['profil/bildSpeichern']='Bild speichern'; +$this->phrasen['profil/gueltigvon']='Gültig von'; +$this->phrasen['profil/gueltigbis']='Gültig bis'; +?> diff --git a/locale/en-US/profil.php b/locale/en-US/profil.php index 30ea23f1a..8f58fd089 100644 --- a/locale/en-US/profil.php +++ b/locale/en-US/profil.php @@ -1,81 +1,82 @@ -phrasen['profil/home']='HOME'; -$this->phrasen['profil/profil']='Profile'; -$this->phrasen['profil/mitarbeiter']='Employee'; -$this->phrasen['profil/meinCis']='My CIS'; -$this->phrasen['profil/bildHochladen']='Upload picture'; -$this->phrasen['profil/email']='eMail'; -$this->phrasen['profil/kontaktPrivat']='Private Contacts'; -$this->phrasen['profil/intern']='Intern'; -$this->phrasen['profil/alias']='Alias'; -$this->phrasen['profil/homepage']='Homepage'; -$this->phrasen['profil/student']='Student'; -$this->phrasen['profil/martrikelnummer']='matriculation number'; -$this->phrasen['profil/leistungsbeurteilung']='Performance assessment'; -$this->phrasen['profil/kurzzeichen']='Abbreviation'; -$this->phrasen['profil/telefonTw']='Telephone'; -$this->phrasen['profil/faxTw']='Fax'; -$this->phrasen['profil/zeitwuensche']='Preferred teaching times'; -$this->phrasen['profil/funktionen']='Functions'; -$this->phrasen['profil/entlehnteBetriebsmittel']='Borrowed equipment'; -$this->phrasen['profil/betriebsmittel']='Equipment'; -$this->phrasen['profil/nummer']='Number'; -$this->phrasen['profil/ausgegebenAm']='Issued on'; -$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='You are member of the following mailing lists'; -$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'User %s is a member of the following mailing lists'; -$this->phrasen['profil/alleStudentenVon']='All students from'; -$this->phrasen['profil/kurzbeschreibungFuerOeh']='Brief description for the Austian Student Union candidacy'; -$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible assistant'; -$this->phrasen['profil/esWurdenKeineProfileGefunden']='No profile ore multiple profiles were found for your user account'; -$this->phrasen['profil/adminstration']='Administration'; -$this->phrasen['profil/zustaendigeAssistenz']='Administrative Assistant'; -$this->phrasen['profil/wendenSieSichAn']='Please contact the'; -$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible'; -$this->phrasen['profil/buero']='Office'; -$this->phrasen['profil/zeitsperrenVon']='Unavailabilities of'; -$this->phrasen['profil/lvplanVon']='Schedule from'; - -$this->phrasen['profil/AccountInaktiv']='NOTICE: This account is no longer active'; -$this->phrasen['profil/inaktivStudent']='NOTICE!
We would like to remind you that your user record has been deactivated. -You were also removed from all e-mail distribution lists when your account was deactivated.

-If your user account is not reactivated within 6 months (for students) or 3 weeks (for dropouts) of being deactivated, the following data will be automatically deleted:
-- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

-If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; - -$this->phrasen['profil/inaktivMitarbeiter']='NOTICE!
We would like to remind you that your user record has been deactivated. -You were also removed from all e-mail distribution lists when your account was deactivated.

-If your user account is not reactivated within 12 months of being deactivated, the following data will be automatically deleted:
-- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

-If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; - -$this->phrasen['profil/inaktivSonstige']='NOTICE!
We would like to remind you that your user record has been deactivated. -You were also removed from all e-mail distribution lists when your account was deactivated.

-If your user account is not reactivated within the next days of being deactivated, the following data will be automatically deleted:
-- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

-If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; - - - - -$this->phrasen['profil/nurJPGBilder']='Currently it is only possible to upload JPEG images'; -$this->phrasen['profil/BilduploadInfotext']='Currently it is only possible to upload JPG images with a maximum size of 15MB!

Please follow the guidelines for uploading images'; -$this->phrasen['profil/Bild']='Picture'; -$this->phrasen['profil/Bildupload']='Upload Picture'; -$this->phrasen['profil/fotofreigeben']='Unlock your profile photo'; -$this->phrasen['profil/fotosperren']='Lock your profile photo'; -$this->phrasen['profil/infotextSperre']='Locked profile photos are only used for access cards, and do not appear on attendance lists or in the people search'; -$this->phrasen['profil/profilfotoGesperrt']='Profile photo locked'; -$this->phrasen['profil/profilfotoUploadGesperrt']='It is no longer possible to upload a profile photo'; -$this->phrasen['profil/fhausweisStatus']='UAS ID card status'; -$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='UAS ID card has already been issued on %s.'; -$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Please upload a valid photo'; -$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Photo has not yet been accepted'; -$this->phrasen['profil/fhausweisGedrucktAm']='UAS ID card printed on'; -$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='UAS ID card will be ready for pick-up at the information desk on'; -$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='UAS ID card has not yet been printed'; -$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Your photo has not yet been approved'; -$this->phrasen['profil/fotoAuswählen']='Click on the image below to upload a photo'; -$this->phrasen['profil/bildSpeichern']='Save image'; -$this->phrasen['profil/gueltigvon']='Valid from'; -$this->phrasen['profil/gueltigbis']='Valid to'; -?> +phrasen['profil/home']='HOME'; +$this->phrasen['profil/profil']='Profile'; +$this->phrasen['profil/mitarbeiter']='Employee'; +$this->phrasen['profil/meinCis']='My CIS'; +$this->phrasen['profil/bildHochladen']='Upload picture'; +$this->phrasen['profil/email']='eMail'; +$this->phrasen['profil/kontaktPrivat']='Private Contacts'; +$this->phrasen['profil/intern']='Intern'; +$this->phrasen['profil/alias']='Alias'; +$this->phrasen['profil/homepage']='Homepage'; +$this->phrasen['profil/student']='Student'; +$this->phrasen['profil/martrikelnummer']='matriculation number'; +$this->phrasen['profil/leistungsbeurteilung']='Performance assessment'; +$this->phrasen['profil/kurzzeichen']='Abbreviation'; +$this->phrasen['profil/telefonTw']='Telephone'; +$this->phrasen['profil/faxTw']='Fax'; +$this->phrasen['profil/zeitwuensche']='Preferred teaching times'; +$this->phrasen['profil/funktionen']='Functions'; +$this->phrasen['profil/entlehnteBetriebsmittel']='Borrowed equipment'; +$this->phrasen['profil/betriebsmittel']='Equipment'; +$this->phrasen['profil/nummer']='Number'; +$this->phrasen['profil/ausgegebenAm']='Issued on'; +$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']='You are member of the following mailing lists'; +$this->phrasen['profil/derUserIstInFolgendenVerteilern'] = 'User %s is a member of the following mailing lists'; +$this->phrasen['profil/alleStudentenVon']='All students from'; +$this->phrasen['profil/kurzbeschreibungFuerOeh']='Brief description for the Austian Student Union candidacy'; +$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible assistant'; +$this->phrasen['profil/esWurdenKeineProfileGefunden']='No profile ore multiple profiles were found for your user account'; +$this->phrasen['profil/keinGueltigesProfil']='Not a valid profile'; +$this->phrasen['profil/adminstration']='Administration'; +$this->phrasen['profil/zustaendigeAssistenz']='Administrative Assistant'; +$this->phrasen['profil/wendenSieSichAn']='Please contact the'; +$this->phrasen['profil/solltenDatenNichtStimmen']='If your data is incorrect, please contact the responsible'; +$this->phrasen['profil/buero']='Office'; +$this->phrasen['profil/zeitsperrenVon']='Unavailabilities of'; +$this->phrasen['profil/lvplanVon']='Schedule from'; + +$this->phrasen['profil/AccountInaktiv']='NOTICE: This account is no longer active'; +$this->phrasen['profil/inaktivStudent']='NOTICE!
We would like to remind you that your user record has been deactivated. +You were also removed from all e-mail distribution lists when your account was deactivated.

+If your user account is not reactivated within 6 months (for students) or 3 weeks (for dropouts) of being deactivated, the following data will be automatically deleted:
+- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

+If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; + +$this->phrasen['profil/inaktivMitarbeiter']='NOTICE!
We would like to remind you that your user record has been deactivated. +You were also removed from all e-mail distribution lists when your account was deactivated.

+If your user account is not reactivated within 12 months of being deactivated, the following data will be automatically deleted:
+- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

+If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; + +$this->phrasen['profil/inaktivSonstige']='NOTICE!
We would like to remind you that your user record has been deactivated. +You were also removed from all e-mail distribution lists when your account was deactivated.

+If your user account is not reactivated within the next days of being deactivated, the following data will be automatically deleted:
+- Your account
- Your mailbox (including all e-mails) and
- Your home directory (including all files).

+If your account has been deactivated by mistake, please contact the administrative assistant for your degree program immediately.
'; + + + + +$this->phrasen['profil/nurJPGBilder']='Currently it is only possible to upload JPEG images'; +$this->phrasen['profil/BilduploadInfotext']='Currently it is only possible to upload JPG images with a maximum size of 15MB!

Please follow the guidelines for uploading images'; +$this->phrasen['profil/Bild']='Picture'; +$this->phrasen['profil/Bildupload']='Upload Picture'; +$this->phrasen['profil/fotofreigeben']='Unlock your profile photo'; +$this->phrasen['profil/fotosperren']='Lock your profile photo'; +$this->phrasen['profil/infotextSperre']='Locked profile photos are only used for access cards, and do not appear on attendance lists or in the people search'; +$this->phrasen['profil/profilfotoGesperrt']='Profile photo locked'; +$this->phrasen['profil/profilfotoUploadGesperrt']='It is no longer possible to upload a profile photo'; +$this->phrasen['profil/fhausweisStatus']='UAS ID card status'; +$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='UAS ID card has already been issued on %s.'; +$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']='Please upload a valid photo'; +$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']='Photo has not yet been accepted'; +$this->phrasen['profil/fhausweisGedrucktAm']='UAS ID card printed on'; +$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']='UAS ID card will be ready for pick-up at the information desk on'; +$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']='UAS ID card has not yet been printed'; +$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']='Your photo has not yet been approved'; +$this->phrasen['profil/fotoAuswählen']='Click on the image below to upload a photo'; +$this->phrasen['profil/bildSpeichern']='Save image'; +$this->phrasen['profil/gueltigvon']='Valid from'; +$this->phrasen['profil/gueltigbis']='Valid to'; +?> diff --git a/locale/it-IT/profil.php b/locale/it-IT/profil.php index 72bd47e65..c3413af65 100644 --- a/locale/it-IT/profil.php +++ b/locale/it-IT/profil.php @@ -1,62 +1,63 @@ -phrasen['profil/AccountInaktiv']='Attenzione: questo account non è più attivo'; -$this->phrasen['profil/adminstration']='Gestione notizie'; -$this->phrasen['profil/alias']='alias'; -$this->phrasen['profil/alleStudentenVon']='Tutti gli studenti di'; -$this->phrasen['profil/ausgegebenAm']=''; -$this->phrasen['profil/betriebsmittel']=''; -$this->phrasen['profil/Bild']=''; -$this->phrasen['profil/bildHochladen']=''; -$this->phrasen['profil/bildSpeichern']=''; -$this->phrasen['profil/Bildupload']=''; -$this->phrasen['profil/BilduploadInfotext']=''; -$this->phrasen['profil/buero']=''; -$this->phrasen['profil/derUserIstInFolgendenVerteilern ']=''; -$this->phrasen['profil/email']='Email'; -$this->phrasen['profil/entlehnteBetriebsmittel']=''; -$this->phrasen['profil/esWurdenKeineProfileGefunden']='Nessun profilo o più profili per l\'utente richiesto'; -$this->phrasen['profil/faxTw']='fax'; -$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']=''; -$this->phrasen['profil/fhausweisGedrucktAm']=''; -$this->phrasen['profil/fhausweisStatus']=''; -$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Tesserino consegnato il %s.'; -$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']=''; -$this->phrasen['profil/fotoAuswählen']=''; -$this->phrasen['profil/fotofreigeben']=''; -$this->phrasen['profil/fotosperren']=''; -$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']=''; -$this->phrasen['profil/funktionen']=''; -$this->phrasen['profil/home']=''; -$this->phrasen['profil/homepage']=''; -$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']=''; -$this->phrasen['profil/inaktivMitarbeiter']=''; -$this->phrasen['profil/inaktivSonstige']=''; -$this->phrasen['profil/inaktivStudent']=''; -$this->phrasen['profil/infotextSperre']=''; -$this->phrasen['profil/intern']='E-mail di Ateneo'; -$this->phrasen['profil/kontaktPrivat']='Contatti Personali'; -$this->phrasen['profil/kurzbeschreibungFuerOeh']=''; -$this->phrasen['profil/kurzzeichen']='ID breve'; -$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']=''; -$this->phrasen['profil/leistungsbeurteilung']=''; -$this->phrasen['profil/lvplanVon']=''; -$this->phrasen['profil/martrikelnummer']='Codice Persona'; -$this->phrasen['profil/meinCis']=''; -$this->phrasen['profil/mitarbeiter']=''; -$this->phrasen['profil/mobil']='Cellulare'; -$this->phrasen['profil/nummer']=''; -$this->phrasen['profil/nurJPGBilder']=''; -$this->phrasen['profil/profil']=''; -$this->phrasen['profil/profilfotoGesperrt']=''; -$this->phrasen['profil/profilfotoUploadGesperrt']=''; -$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']=''; -$this->phrasen['profil/solltenDatenNichtStimmen']='La preghiamo di rivolgersi alla segreteria nel caso i dati non risultino essere corretti.'; -$this->phrasen['profil/student']='Studente'; -$this->phrasen['profil/telefon']=''; -$this->phrasen['profil/telefonTw']=''; -$this->phrasen['profil/wendenSieSichAn']=''; -$this->phrasen['profil/zeitsperrenVon']=''; -$this->phrasen['profil/zeitwuensche']=''; -$this->phrasen['profil/zustaendigeAssistenz']=''; - -?> +phrasen['profil/AccountInaktiv']='Attenzione: questo account non è più attivo'; +$this->phrasen['profil/adminstration']='Gestione notizie'; +$this->phrasen['profil/alias']='alias'; +$this->phrasen['profil/alleStudentenVon']='Tutti gli studenti di'; +$this->phrasen['profil/ausgegebenAm']=''; +$this->phrasen['profil/betriebsmittel']=''; +$this->phrasen['profil/Bild']=''; +$this->phrasen['profil/bildHochladen']=''; +$this->phrasen['profil/bildSpeichern']=''; +$this->phrasen['profil/Bildupload']=''; +$this->phrasen['profil/BilduploadInfotext']=''; +$this->phrasen['profil/buero']=''; +$this->phrasen['profil/derUserIstInFolgendenVerteilern ']=''; +$this->phrasen['profil/email']='Email'; +$this->phrasen['profil/entlehnteBetriebsmittel']=''; +$this->phrasen['profil/esWurdenKeineProfileGefunden']='Nessun profilo o più profili per l\'utente richiesto'; +$this->phrasen['profil/keinGueltigesProfil']=''; +$this->phrasen['profil/faxTw']='fax'; +$this->phrasen['profil/fhausweisAbholbereitAmEmpfangAb']=''; +$this->phrasen['profil/fhausweisGedrucktAm']=''; +$this->phrasen['profil/fhausweisStatus']=''; +$this->phrasen['profil/fhausweisWurdeBereitsAusgegeben']='Tesserino consegnato il %s.'; +$this->phrasen['profil/fhausweisWurdeNochNichtGedruckt']=''; +$this->phrasen['profil/fotoAuswählen']=''; +$this->phrasen['profil/fotofreigeben']=''; +$this->phrasen['profil/fotosperren']=''; +$this->phrasen['profil/fotoWurdeNochNichtAkzeptiert']=''; +$this->phrasen['profil/funktionen']=''; +$this->phrasen['profil/home']=''; +$this->phrasen['profil/homepage']=''; +$this->phrasen['profil/ihrFotoWurdeNochNichtGeprueft']=''; +$this->phrasen['profil/inaktivMitarbeiter']=''; +$this->phrasen['profil/inaktivSonstige']=''; +$this->phrasen['profil/inaktivStudent']=''; +$this->phrasen['profil/infotextSperre']=''; +$this->phrasen['profil/intern']='E-mail di Ateneo'; +$this->phrasen['profil/kontaktPrivat']='Contatti Personali'; +$this->phrasen['profil/kurzbeschreibungFuerOeh']=''; +$this->phrasen['profil/kurzzeichen']='ID breve'; +$this->phrasen['profil/ladenSieBitteEinGueltigesFotoHoch']=''; +$this->phrasen['profil/leistungsbeurteilung']=''; +$this->phrasen['profil/lvplanVon']=''; +$this->phrasen['profil/martrikelnummer']='Codice Persona'; +$this->phrasen['profil/meinCis']=''; +$this->phrasen['profil/mitarbeiter']=''; +$this->phrasen['profil/mobil']='Cellulare'; +$this->phrasen['profil/nummer']=''; +$this->phrasen['profil/nurJPGBilder']=''; +$this->phrasen['profil/profil']=''; +$this->phrasen['profil/profilfotoGesperrt']=''; +$this->phrasen['profil/profilfotoUploadGesperrt']=''; +$this->phrasen['profil/sieSindMitgliedInFolgendenVerteilern']=''; +$this->phrasen['profil/solltenDatenNichtStimmen']='La preghiamo di rivolgersi alla segreteria nel caso i dati non risultino essere corretti.'; +$this->phrasen['profil/student']='Studente'; +$this->phrasen['profil/telefon']=''; +$this->phrasen['profil/telefonTw']=''; +$this->phrasen['profil/wendenSieSichAn']=''; +$this->phrasen['profil/zeitsperrenVon']=''; +$this->phrasen['profil/zeitwuensche']=''; +$this->phrasen['profil/zustaendigeAssistenz']=''; + +?> From 19d69fdb59e488633bbddc2522f2fd9c31e6bf88 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 11 Oct 2019 15:55:16 +0200 Subject: [PATCH 14/22] Personen zusammenlegen (vilesci/stammdaten/personen_wartung.php): When merging prestudent, prueflinge are transferred from deleted prestudent to remaining prestudent. --- include/pruefling.class.php | 36 +++++++++++++++++++- vilesci/stammdaten/personen_wartung.php | 44 ++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/pruefling.class.php b/include/pruefling.class.php index f3859e531..3c5244067 100644 --- a/include/pruefling.class.php +++ b/include/pruefling.class.php @@ -165,7 +165,7 @@ class pruefling extends basis_db } /** - * Laedt einen Puefling anhand der Prestudent_id + * Laedt einen Pruefling anhand der Prestudent_id * * @param $prestudent_id * @return boolean @@ -199,6 +199,40 @@ class pruefling extends basis_db } } + /** + * Laedt alle Prueflinge anhand der Prestudent_id + * + * @param $prestudent_id + * @return boolean + */ + public function getPrueflinge($prestudent_id) + { + $qry = "SELECT * FROM testtool.tbl_pruefling WHERE prestudent_id=".$this->db_add_param($prestudent_id, FHC_INTEGER); + + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + $obj = new pruefling(); + + $obj->pruefling_id = $row->pruefling_id; + $obj->studiengang_kz = $row->studiengang_kz; + $obj->idnachweis = $row->idnachweis; + $obj->registriert = $row->registriert; + $obj->prestudent_id = $row->prestudent_id; + $obj->semester = $row->semester; + + $this->result[] = $obj; + } + return true; + } + else + { + $this->errormsg = "Fehler beim Laden"; + return false; + } + } + /** * Ermittelt den aktuellen Level (schwierigkeitsgrad der Frage) * des Prueflings fuer das uebergebene Gebiet diff --git a/vilesci/stammdaten/personen_wartung.php b/vilesci/stammdaten/personen_wartung.php index 2f38206a8..c143a1390 100644 --- a/vilesci/stammdaten/personen_wartung.php +++ b/vilesci/stammdaten/personen_wartung.php @@ -41,6 +41,7 @@ require_once ('../../include/fotostatus.class.php'); require_once ('../../include/kontakt.class.php'); require_once ('../../include/dokument.class.php'); require_once ('../../include/reihungstest.class.php'); +require_once ('../../include/pruefling.class.php'); if (! $db = new basis_db()) @@ -560,7 +561,7 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p */ $prestudenten = new prestudent(); $prestudenten->getPrestudenten($personToKeep); - $statusArrayWichtigeWichtige = array(); // Array mit allen PreStudentStatus die NICHT Interessent oder Abgewiesener sind + $statusArrayWichtige = array(); // Array mit allen PreStudentStatus die NICHT Interessent oder Abgewiesener sind foreach ($prestudenten->result AS $key => $value) { @@ -673,6 +674,7 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p $studiengang_kz = ''; $anmerkung = ''; $prestudentLoeschArray = array(); + $prueflingTransferArray = array(); $warningList = array(); $i = 0; foreach ($prestudentenArray AS $key => $value) @@ -715,6 +717,7 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p // Wenn kein Status außer Interessent und Abgewiesener mehr vorhanden ist, löschen if (!isset($statusArrayWichtige[$value['prestudent_id']])) { + setPrueflingTransfer($value['prestudent_id'], $prestudentId, $prueflingTransferArray); unset($prestudentenArray[$key]); $prestudentLoeschArray[] = $value['prestudent_id']; } @@ -732,6 +735,7 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p // Wenn kein Status außer Interessent und Abgewiesener mehr vorhanden ist, löschen if (!isset($statusArrayWichtige[$value['prestudent_id']])) { + setPrueflingTransfer($value['prestudent_id'], $prestudentId, $prueflingTransferArray); unset($prestudentenArray[$key]); $prestudentLoeschArray[] = $value['prestudent_id']; } @@ -748,6 +752,7 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p $prestudentenArray[$previousKey]['zgvort'] = $zgvort = $value['zgvort']; $prestudentenArray[$previousKey]['zgvdatum'] = $zgvdatum = $value['zgvdatum']; $prestudentenArray[$previousKey]['zgvnation'] = $zgvnation = $value['zgvnation']; + setPrueflingTransfer($value['prestudent_id'], $prestudentId, $prueflingTransferArray); unset($prestudentenArray[$key]); $prestudentLoeschArray[] = $value['prestudent_id']; continue; @@ -761,6 +766,7 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p $warningList['zgvUnklar'][$prestudentId][$i]['zgvort'] = $value['zgvort']; $warningList['zgvUnklar'][$prestudentId][$i]['zgvdatum'] = $value['zgvdatum']; $warningList['zgvUnklar'][$prestudentId][$i]['zgvnation'] = $value['zgvnation']; + setPrueflingTransfer($value['prestudent_id'], $prestudentId, $prueflingTransferArray); unset($prestudentenArray[$key]); $prestudentLoeschArray[] = $value['prestudent_id']; $i++; @@ -769,6 +775,7 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p } } } + setPrueflingTransfer($value['prestudent_id'], $prestudentId, $prueflingTransferArray); unset($prestudentenArray[$key]); $prestudentLoeschArray[] = $value['prestudent_id']; continue; @@ -834,6 +841,19 @@ if (isset($personToDelete) && isset($personToKeep) && $personToDelete >= 0 && $p $msg_warning[] = $messageOutput; + //Wenn Prüfling auf zu löschenden Prestudenten zeigt und ggf auf bleibenden umhängen. + foreach ($prueflingTransferArray as $pruefling_id => $prestudent_id) + { + $transferqry = "UPDATE testtool.tbl_pruefling SET prestudent_id=" . $db->db_add_param($prestudent_id, FHC_INTEGER) . " WHERE pruefling_id=" . $db->db_add_param($pruefling_id, FHC_INTEGER) . ";"; + + if (!$db->db_query($transferqry)) + { + $msg_error[] = 'Fehler beim Aktualisieren des Prüflings '.$pruefling_id; + } + else + $msg_warning[] = 'Prüfling '.$pruefling_id.' auf prestudent '.$prestudent_id.' aktualisiert'; + } + // Prestudenten in $prestudentLoeschArray löschen foreach ($prestudentLoeschArray AS $key => $value) { @@ -884,6 +904,28 @@ if ((isset($personToDelete) && ! isset($personToKeep)) || (! isset($personToDele { $msg_info[] = "Es muß je ein Radio-Button pro Tabelle angeklickt werden"; } + +/** + * Holt sich Prüflinge zu einem zu löschenden Prestudenten, + * speichert auf welchen Prestudenten die Prüflinge "umgehängt" werden sollen. + * @param $prestudentIdToDelete prestudent_id des zu löschenden Prestudenten + * @param $prestudentIdToKeep prestudent_id des behaltenen Prestundenten + * @param $prueflingTransferArray zum Speichern, form [pruefling_id] => neue_prestudent_id + */ +function setPrueflingTransfer($prestudentIdToDelete, $prestudentIdToKeep, &$prueflingTransferArray) +{ + $pruefling = new pruefling(); + + if (is_numeric($prestudentIdToDelete) && is_numeric($prestudentIdToKeep) && + $pruefling->getPrueflinge($prestudentIdToDelete)) + { + foreach ($pruefling->result as $pr) + { + $prueflingTransferArray[$pr->pruefling_id] = (int)$prestudentIdToKeep; + } + } +} + function resize($base64, $width, $height) // 828 x 1104 -> 240 x 320 { ob_start(); From 4de5f1533ff1c5339a725a6d2880e07f97c3958a Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 24 Oct 2019 11:29:38 +0200 Subject: [PATCH 15/22] =?UTF-8?q?-=20parking=20and=20zur=C3=BCckstellen=20?= =?UTF-8?q?date=20and=20buttons:=20adapted=20layout=20for=20correct=20line?= =?UTF-8?q?=20breaking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/infocenter/infocenterDetails.css | 24 ++++++++++++++++++++- public/js/infocenter/infocenterDetails.js | 9 ++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/public/css/infocenter/infocenterDetails.css b/public/css/infocenter/infocenterDetails.css index 1586fd52d..38a7824fa 100644 --- a/public/css/infocenter/infocenterDetails.css +++ b/public/css/infocenter/infocenterDetails.css @@ -70,4 +70,26 @@ #postponedate{ height: 25px; width: 99px -} \ No newline at end of file +} + +#postponedatelabel{ + font-weight: normal; +} + +@media screen and (max-width: 1510px) +{ + #postponing{ + text-align: center; + } + #postponedatelabel{ + display: block; + margin-top: 20px; + } +} + +@media screen and (max-width: 768px) +{ + #postponedate { + display: inline-block + } +} diff --git a/public/js/infocenter/infocenterDetails.js b/public/js/infocenter/infocenterDetails.js index 96975d179..b99d28993 100644 --- a/public/js/infocenter/infocenterDetails.js +++ b/public/js/infocenter/infocenterDetails.js @@ -437,7 +437,7 @@ var InfocenterDetails = { parkPerson: function(personid, date) { var parkError = function(){ - $("#postponemsg").text(" Fehler beim Parken!"); + $("#postponemsg").text(" Fehler beim Parken!"); }; FHC_AjaxClient.ajaxCallPost( @@ -486,7 +486,7 @@ var InfocenterDetails = { setPersonOnHold: function(personid, date) { var onHoldError = function(){ - $("#postponemsg").text(" Fehler beim Setzen auf On Hold!"); + $("#postponemsg").text(" Fehler beim Setzen auf On Hold!"); }; FHC_AjaxClient.ajaxCallPost( @@ -925,9 +925,9 @@ var InfocenterDetails = { '
'+ '     '+ '     '+ - FHC_PhrasesLib.t('global', 'bis') + '  '+ + ''+ ''+ '
'); @@ -936,7 +936,6 @@ var InfocenterDetails = { "minDate": 0 }); - $("#parklink").click( function () From fbec49a663a1aaf141f19653601abc721a5b2c43 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 24 Oct 2019 11:43:10 +0200 Subject: [PATCH 16/22] =?UTF-8?q?-=20bugfix:=20parking=20&=20zur=C3=BCckst?= =?UTF-8?q?ellen=20datepicker:=20current=20day=20cannot=20be=20selected,?= =?UTF-8?q?=20because=20default=20time=20is=2000:00,=20and=20it=20would=20?= =?UTF-8?q?be=20immediately=20exceeded?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/infocenter/infocenterDetails.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/infocenter/infocenterDetails.js b/public/js/infocenter/infocenterDetails.js index b99d28993..0bcb88124 100644 --- a/public/js/infocenter/infocenterDetails.js +++ b/public/js/infocenter/infocenterDetails.js @@ -933,7 +933,7 @@ var InfocenterDetails = { $("#postponedate").datepicker({ "dateFormat": "dd.mm.yy", - "minDate": 0 + "minDate": 1 }); $("#parklink").click( From 1971ec8ed117589e37e25b312d46a90528da69df Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 25 Oct 2019 10:20:56 +0200 Subject: [PATCH 17/22] - Infocenter.php bugfix: GET parameter list is separated by "&" and not by ? (params filter_id, reloadDataset) --- application/controllers/system/infocenter/InfoCenter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index 3a8d51aee..3fb97f887 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -1008,7 +1008,7 @@ class InfoCenter extends Auth_Controller $prevFilterId = $this->input->get(self::PREV_FILTER_ID); if (isset($prevFilterId)) { - $homeLink .= '?'.self::FILTER_ID.'='.$prevFilterId; + $homeLink .= '&'.self::FILTER_ID.'='.$prevFilterId; } $this->navigationlib->setSessionElementMenu( From 89ad21b1ef09f89cca028be7f721a0bdcaf40598 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 25 Oct 2019 10:26:54 +0200 Subject: [PATCH 18/22] - Infocenter uebersicht bugfix: tablesorter filter storage is the same for homepage with and without "/index" (for keeping tablesorter filter when coming back from details page) --- public/js/FilterWidget.js | 28 ++++++++----------- .../js/infocenter/infocenterPersonDataset.js | 22 +++++++++++++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/public/js/FilterWidget.js b/public/js/FilterWidget.js index dccc8893c..a9e0f6cf9 100644 --- a/public/js/FilterWidget.js +++ b/public/js/FilterWidget.js @@ -84,7 +84,7 @@ var FHC_FilterWidget = { // Public methods /** - * To display the FilterWidget using the loaded data prenset in the session + * To display the FilterWidget using the loaded data present in the session */ display: function() { @@ -392,7 +392,6 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { - FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrRefresh(data, textStatus, jqXHR); } } @@ -413,7 +412,6 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { - FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrRefresh(data, textStatus, jqXHR); } } @@ -454,7 +452,6 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { - FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrRefresh(data, textStatus, jqXHR); } } @@ -489,7 +486,6 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { - FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrReload(data, textStatus, jqXHR); } } @@ -509,7 +505,6 @@ var FHC_FilterWidget = { }, { successCallback: function(data, textStatus, jqXHR) { - FHC_FilterWidget._cleanTablesorterLocalStorage(); FHC_FilterWidget._failOrReload(data, textStatus, jqXHR); } } @@ -840,6 +835,14 @@ var FHC_FilterWidget = { */ _renderDatasetTablesorter: function(data) { + //clear tablesorter filter storage + var keepTsFilter = FHC_AjaxClient.getUrlParameter("keepTsFilter"); + + if (typeof keepTsFilter === "undefined" || keepTsFilter !== "true") + { + FHC_FilterWidget._clearTablesorterLocalStorage(); + } + if (data.hasOwnProperty("checkboxes") && data.checkboxes!=null && data.checkboxes.trim() != "") { $("#filterTableDataset > thead > tr").append("Select"); @@ -938,14 +941,6 @@ var FHC_FilterWidget = { } }); - // Reset filter storage if not specified by get parameter - var keepTsFilter = FHC_AjaxClient.getUrlParameter("keepTsFilter"); - - if (typeof keepTsFilter === "undefined" || keepTsFilter !== "true") - { - FHC_FilterWidget._cleanTablesorterLocalStorage(); - } - $.tablesorter.updateAll($("#filterTableDataset")[0].config, true, null); } }, @@ -1064,9 +1059,8 @@ var FHC_FilterWidget = { /** * Tablesorter filter local storage clean */ - _cleanTablesorterLocalStorage: function() { - - $("#filterTableDataset").trigger("filterResetSaved"); + _clearTablesorterLocalStorage: function() { + localStorage.removeItem("tablesorter-filters"); }, /** diff --git a/public/js/infocenter/infocenterPersonDataset.js b/public/js/infocenter/infocenterPersonDataset.js index 54933165d..816dd2fda 100644 --- a/public/js/infocenter/infocenterPersonDataset.js +++ b/public/js/infocenter/infocenterPersonDataset.js @@ -148,6 +148,28 @@ var InfocenterPersonDataset = { trs.find("input[name=PersonId\\[\\]]").prop("checked", false); } ); + + //make sure tablesorter local storage for homepage url with and without "/index" shares same values + $("#filterTableDataset").bind('filterEnd', function() + { + if (FHC_JS_DATA_STORAGE_OBJECT.called_method === 'index') + { + var pathname = window.location.pathname; + var storageobj = localStorage.getItem("tablesorter-filters"); + var parsed = JSON.parse(storageobj); + var regex = new RegExp(/\/index(?!\.ci\.php)/); + if (regex.test(pathname)) + { + parsed[pathname.replace(regex, "")] = parsed[pathname]; + } + else + { + parsed[pathname + "/index"] = parsed[pathname]; + } + storageobj = JSON.stringify(parsed); + localStorage.setItem("tablesorter-filters", storageobj); + } + }); }, /** From 2d68d2ffebfe1d3ed215671190b4413fef7f5c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Mon, 28 Oct 2019 14:43:05 +0100 Subject: [PATCH 19/22] Adapted Header and Background Style for CIS-CI Pages --- public/css/fhcomplete.css | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/public/css/fhcomplete.css b/public/css/fhcomplete.css index 1f8de48b9..d2bcf0579 100644 --- a/public/css/fhcomplete.css +++ b/public/css/fhcomplete.css @@ -2,22 +2,36 @@ margin: 10px 0 5px; } h1 { + margin-top: 0px; font-size: 2rem; } h2 { + margin-top: 0px; font-size: 1.8rem; } h3 { + margin-top: 0px; font-size: 1.6rem; } h4 { + margin-top: 0px; font-size: 1.4rem; } h5 { + margin-top: 0px; font-size: 1.2rem; } h6 { + margin-top: 0px; font-size: 1rem; } +body +{ + background-color: white; + color: black; + font-family: Arial, Helvetica, sans-serif; + font-size: 13px; + line-height: 1; +} From 4d248f3a1e5578bb1d9a88b7978fa543f4aa58c5 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 28 Oct 2019 17:29:09 +0100 Subject: [PATCH 20/22] - cis/private/profile/index.php: Wochenstunden on profile are only shown to own user or admin --- cis/private/profile/index.php | 44 ++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/cis/private/profile/index.php b/cis/private/profile/index.php index 1273c517b..bb4433910 100644 --- a/cis/private/profile/index.php +++ b/cis/private/profile/index.php @@ -66,6 +66,9 @@ if (isset($_GET['uid']) && $_GET['uid'] != $uid) $uid = stripslashes($_GET['uid']); $ansicht = true; } + +$adminOrOwnUser = $rechte->isBerechtigt('admin') || !$ansicht; + if ($rechte->isBerechtigt('basis/kontakt')) $ansicht = false; @@ -526,7 +529,7 @@ if (!defined('CIS_PROFIL_FUNKTIONEN_ANZEIGEN') || CIS_PROFIL_FUNKTIONEN_ANZEIGEN */ function printFunctionsTable($query, $headingphrase, $tableid, $showVertragsstunden = false) { - global $db, $p, $datum_obj, $uid; + global $db, $p, $datum_obj, $uid, $adminOrOwnUser; if ($result_funktion = $db->db_query($query)) { @@ -540,9 +543,9 @@ function printFunctionsTable($query, $headingphrase, $tableid, $showVertragsstun '.$p->t('global/bezeichnung').' '.$p->t('global/organisationseinheit').' '.$p->t('profil/gueltigvon').' - '.$p->t('profil/gueltigbis').' - '.$p->t('profil/wochenstunden').' - + '.$p->t('profil/gueltigbis').''. + ($adminOrOwnUser ? ''.$p->t('profil/wochenstunden').'' : ''). + ' '; @@ -559,17 +562,17 @@ function printFunctionsTable($query, $headingphrase, $tableid, $showVertragsstun echo " ".$row_funktion->organisationseinheittyp_kurzbz.' '.$row_funktion->oe_bezeichnung." ".$datum_obj->formatDatum($row_funktion->datum_von,'d.m.Y')." - ".$datum_obj->formatDatum($row_funktion->datum_bis,'d.m.Y')." - ".number_format($row_funktion->wochenstunden, 2)." - "; + ".$datum_obj->formatDatum($row_funktion->datum_bis,'d.m.Y')."". + ($adminOrOwnUser ? "".number_format($row_funktion->wochenstunden, 2)."" : ""). + ""; - if(isset($row_funktion->wochenstunden)) + if(isset($row_funktion->wochenstunden) && $adminOrOwnUser) $wochenstunden_sum += (double)$row_funktion->wochenstunden; } echo '
'; //vertragsstunden - if ($showVertragsstunden === true) + if ($showVertragsstunden === true && $adminOrOwnUser) { $vertragsstunden = 0.00; $qry = "SELECT sum(vertragsstunden) AS vertragsstdsumme from bis.tbl_bisverwendung @@ -588,16 +591,19 @@ function printFunctionsTable($query, $headingphrase, $tableid, $showVertragsstun } } - echo " - - - - - Summe Wochenstunden".($showVertragsstunden === true ? " (".$p->t('profil/vertragsstunden').")" : "")." -  ".number_format($wochenstunden_sum,2).($showVertragsstunden === true ? - " (".number_format($vertragsstunden,2).")" : "")." - - "; + if ($adminOrOwnUser) + { + echo " + + + + + Summe Wochenstunden".($showVertragsstunden === true ? " (".$p->t('profil/vertragsstunden').")" : "")." +  ".number_format($wochenstunden_sum, 2).($showVertragsstunden === true ? + " (".number_format($vertragsstunden, 2).")" : "")." + + "; + } echo ""; } } From 22a517b88d31eaf07e3edd6bc13564ff48fe0f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Tue, 29 Oct 2019 06:51:36 +0100 Subject: [PATCH 21/22] Added LogsViewer to CI Menu --- application/config/navigation.php | 7 +++++++ application/controllers/system/LogsViewer.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/application/config/navigation.php b/application/config/navigation.php index d6f4b8452..1d8efb4c5 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -82,6 +82,13 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 10, 'requiredPermissions' => 'admin:r' + ), + 'logsviewer' => array( + 'link' => site_url('system/LogsViewer'), + 'description' => 'Logs', + 'expand' => true, + 'sort' => 20, + 'requiredPermissions' => 'system/developer:r' ) ) ) diff --git a/application/controllers/system/LogsViewer.php b/application/controllers/system/LogsViewer.php index 55cf38d82..8caf9f3a7 100644 --- a/application/controllers/system/LogsViewer.php +++ b/application/controllers/system/LogsViewer.php @@ -14,7 +14,7 @@ class LogsViewer extends Auth_Controller { parent::__construct( array( - 'index' => 'admin:r' + 'index' => 'system/developer:r' ) ); From 5be68be408ab4e17acb74cbb4bca517ae5f7518a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Tue, 29 Oct 2019 14:49:35 +0100 Subject: [PATCH 22/22] Added Anti-Cache Functionality --- application/config/config.php | 12 ++++++++++++ application/helpers/hlp_header_helper.php | 10 ++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/application/config/config.php b/application/config/config.php index 1c0993c92..591b84f2c 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -503,3 +503,15 @@ $config['rewrite_short_tags'] = FALSE; | Array: array('10.0.1.200', '192.168.5.0/24') */ $config['proxy_ips'] = ''; + +/* +|-------------------------------------------------------------------------- +| FHComplete Build Version +|-------------------------------------------------------------------------- +| +| Version Number of the Current Build +| This is used to invalidate Cache for JS and CSS Files +| +| Example: 2019102901 +*/ +$config['fhcomplete_build_version'] = '2019102903'; diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index 611325722..1a0d9dc49 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -46,13 +46,16 @@ function generateCSSsInclude($CSSs) { $cssLink = ''; + $ci =& get_instance(); + $cachetoken = '?'.$ci->config->item('fhcomplete_build_version'); + if (isset($CSSs)) { $tmpCSSs = is_array($CSSs) ? $CSSs : array($CSSs); for ($tmpCSSsCounter = 0; $tmpCSSsCounter < count($tmpCSSs); $tmpCSSsCounter++) { - $toPrint = sprintf($cssLink, base_url($tmpCSSs[$tmpCSSsCounter])).PHP_EOL; + $toPrint = sprintf($cssLink, base_url($tmpCSSs[$tmpCSSsCounter]).$cachetoken).PHP_EOL; if ($tmpCSSsCounter > 0) $toPrint = "\t\t".$toPrint; @@ -108,13 +111,16 @@ function generateJSsInclude($JSs) { $jsInclude = ''; + $ci =& get_instance(); + $cachetoken = '?'.$ci->config->item('fhcomplete_build_version'); + if (isset($JSs)) { $tmpJSs = is_array($JSs) ? $JSs : array($JSs); for ($tmpJSsCounter = 0; $tmpJSsCounter < count($tmpJSs); $tmpJSsCounter++) { - $toPrint = sprintf($jsInclude, base_url($tmpJSs[$tmpJSsCounter])).PHP_EOL; + $toPrint = sprintf($jsInclude, base_url($tmpJSs[$tmpJSsCounter].$cachetoken)).PHP_EOL; if ($tmpJSsCounter > 0) $toPrint = "\t\t".$toPrint;